Limit max parameters + add Espresso tests
This commit is contained in:
parent
c002e7caf9
commit
ea4d107b12
@ -0,0 +1,58 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.test.espresso.action.ViewActions;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.functions.CppFunction;
|
||||
import org.solovyev.android.calculator.functions.FunctionParamsView;
|
||||
|
||||
import static android.support.test.espresso.Espresso.onView;
|
||||
import static android.support.test.espresso.action.ViewActions.click;
|
||||
import static android.support.test.espresso.action.ViewActions.typeText;
|
||||
import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.hasFocus;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class BasePlotTest {
|
||||
@Rule
|
||||
public ActivityTestRule<PlotActivity> rule = new ActivityTestRule<>(PlotActivity.class);
|
||||
|
||||
protected void addFunction(@NonNull CppFunction function) {
|
||||
openFunctionEditor();
|
||||
|
||||
if (!TextUtils.isEmpty(function.getName())) {
|
||||
onView(withId(R.id.function_name)).perform(typeText(function.getName()));
|
||||
}
|
||||
|
||||
for (String parameter : function.getParameters()) {
|
||||
onView(withId(R.id.function_params_add)).perform(click());
|
||||
onView(allOf(hasFocus(), withTagValue(Matchers.<Object>equalTo(FunctionParamsView.PARAM_VIEW_TAG)))).perform(click(), typeTextIntoFocusedView(parameter));
|
||||
}
|
||||
|
||||
onView(withId(R.id.function_body)).perform(typeText(function.getBody()));
|
||||
onView(withText(R.string.ok)).perform(click());
|
||||
}
|
||||
|
||||
protected final void openFunctionEditor() {
|
||||
onView(withId(R.id.plot_view_frame)).perform(ViewActions.click());
|
||||
onView(withId(R.id.plot_add_function)).perform(click());
|
||||
}
|
||||
|
||||
protected final void openFunctionsList() {
|
||||
onView(withId(R.id.plot_view_frame)).perform(ViewActions.click());
|
||||
onView(withId(R.id.plot_functions)).perform(click());
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.functions.CppFunction;
|
||||
|
||||
import static android.support.test.espresso.Espresso.onView;
|
||||
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||
|
||||
public class PlotEditFunctionFragmentTest extends BasePlotTest {
|
||||
|
||||
@Test
|
||||
public void testShouldAddFunction() throws Exception {
|
||||
final CppFunction function = CppFunction.builder("", "x + y").withParameters("x", "y").build();
|
||||
addFunction(function);
|
||||
|
||||
openFunctionsList();
|
||||
onView(withId(R.id.function_name)).check(matches(withText("x+y")));
|
||||
}
|
||||
}
|
@ -119,7 +119,11 @@
|
||||
|
||||
<activity
|
||||
android:name=".plot.PlotActivity"
|
||||
android:label="@string/cpp_plotter" />
|
||||
android:label="@string/cpp_plotter">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".wizard.WizardActivity"
|
||||
|
@ -84,6 +84,7 @@ public abstract class BaseFunctionFragment extends BaseDialogFragment implements
|
||||
@NonNull
|
||||
private final KeyboardUser keyboardUser = new KeyboardUser();
|
||||
@Bind(R.id.function_params)
|
||||
public
|
||||
FunctionParamsView paramsView;
|
||||
@Bind(R.id.function_name_label)
|
||||
TextInputLayout nameLabel;
|
||||
|
@ -4,9 +4,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import jscl.math.function.CustomFunction;
|
||||
import jscl.math.function.Function;
|
||||
import jscl.math.function.IFunction;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@ -16,11 +14,18 @@ import org.solovyev.android.calculator.json.Jsonable;
|
||||
import org.solovyev.common.JBuilder;
|
||||
import org.solovyev.common.text.Strings;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import jscl.math.function.CustomFunction;
|
||||
import jscl.math.function.Function;
|
||||
import jscl.math.function.IFunction;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class CppFunction implements Jsonable, Parcelable {
|
||||
|
||||
public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() {
|
||||
@ -230,6 +235,13 @@ public class CppFunction implements Jsonable, Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Builder withParameters(@Nonnull String... parameters) {
|
||||
Check.isTrue(!built);
|
||||
function.parameters.addAll(asList(parameters));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Builder withParameter(@Nonnull String parameter) {
|
||||
Check.isTrue(!built);
|
||||
|
@ -36,17 +36,23 @@ import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.*;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.calculator.App;
|
||||
import org.solovyev.android.calculator.Preferences;
|
||||
import org.solovyev.android.calculator.R;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
@ -63,6 +69,9 @@ public class FunctionParamsView extends LinearLayout {
|
||||
@Nonnull
|
||||
private final Preferences.Gui.Theme theme = App.getTheme();
|
||||
private int maxRowId = START_ROW_ID;
|
||||
private int maxParams = Integer.MAX_VALUE;
|
||||
@Nonnull
|
||||
private LinearLayout headerView;
|
||||
|
||||
{
|
||||
final Resources resources = getResources();
|
||||
@ -91,8 +100,9 @@ public class FunctionParamsView extends LinearLayout {
|
||||
setOrientation(VERTICAL);
|
||||
final Context context = getContext();
|
||||
|
||||
final LinearLayout headerView = makeRowView(context);
|
||||
headerView = makeRowView(context);
|
||||
final ImageButton addButton = makeButton(theme.light ? R.drawable.ic_add_black_24dp : R.drawable.ic_add_white_24dp);
|
||||
addButton.setId(R.id.function_params_add);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@ -187,9 +197,15 @@ public class FunctionParamsView extends LinearLayout {
|
||||
|
||||
// for row is added at 0 position, the consequent rows
|
||||
addView(rowView, Math.max(0, getChildCount() - 1), new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||
onParamsChanged();
|
||||
return rowView;
|
||||
}
|
||||
|
||||
private void onParamsChanged() {
|
||||
final boolean enabled = getParamsCount() < maxParams;
|
||||
headerView.setVisibility(enabled ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private LayoutParams makeButtonParams() {
|
||||
return new LayoutParams(imageButtonSize, imageButtonSize);
|
||||
@ -224,19 +240,20 @@ public class FunctionParamsView extends LinearLayout {
|
||||
|
||||
@Nonnull
|
||||
private ViewGroup getRow(int index) {
|
||||
Check.isTrue(index >= 0 && index < getChildCount() - FOOTERS);
|
||||
Check.isTrue(index >= 0 && index < getParamsCount());
|
||||
return (ViewGroup) getChildAt(index);
|
||||
}
|
||||
|
||||
public void removeRow(@Nonnull ViewGroup row) {
|
||||
removeView(row);
|
||||
onParamsChanged();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<String> getParams() {
|
||||
final List<String> params = new ArrayList<>(getChildCount());
|
||||
final List<String> params = new ArrayList<>(getParamsCount());
|
||||
|
||||
for (int i = 0; i < getChildCount() - FOOTERS; i++) {
|
||||
for (int i = 0; i < getParamsCount(); i++) {
|
||||
final ViewGroup row = getRow(i);
|
||||
final EditText paramView = getParamView(row);
|
||||
params.add(paramView.getText().toString());
|
||||
@ -245,6 +262,15 @@ public class FunctionParamsView extends LinearLayout {
|
||||
return params;
|
||||
}
|
||||
|
||||
private int getParamsCount() {
|
||||
return getChildCount() - FOOTERS;
|
||||
}
|
||||
|
||||
public void setMaxParams(int maxParams) {
|
||||
this.maxParams = maxParams;
|
||||
onParamsChanged();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private EditText getParamView(@Nonnull ViewGroup row) {
|
||||
final TextInputLayout paramLabel = getParamLabel(row);
|
||||
|
@ -16,12 +16,12 @@ import org.solovyev.android.plotter.Dimensions;
|
||||
import org.solovyev.android.plotter.PlotViewFrame;
|
||||
import org.solovyev.android.plotter.Plotter;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class PlotActivity extends BaseActivity {
|
||||
|
||||
public static class MyFragment extends BaseFragment implements PlotViewFrame.Listener {
|
||||
@ -79,7 +79,7 @@ public class PlotActivity extends BaseActivity {
|
||||
PlotFunctionsFragment.show(getActivity().getSupportFragmentManager());
|
||||
return true;
|
||||
} else if (id == R.id.plot_add_function) {
|
||||
//App.getBus().post(new AddFunctionDialog.ShowEvent());
|
||||
PlotEditFunctionFragment.show(null, getActivity().getSupportFragmentManager());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -111,6 +111,7 @@ public class PlotEditFunctionFragment extends BaseFunctionFragment
|
||||
|
||||
final int[] colors = MeshSpec.LightColors.asIntArray();
|
||||
colorPicker.setColors(colors);
|
||||
paramsView.setMaxParams(2);
|
||||
if (savedInstanceState == null) {
|
||||
if (plotFunction != null) {
|
||||
setupViews(plotFunction.meshSpec);
|
||||
|
@ -1,8 +1,5 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
|
||||
import static android.view.Menu.NONE;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@ -32,14 +29,17 @@ import org.solovyev.android.plotter.Plotter;
|
||||
import org.solovyev.android.views.llm.DividerItemDecoration;
|
||||
import org.solovyev.android.views.llm.LinearLayoutManager;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
|
||||
import static android.view.Menu.NONE;
|
||||
|
||||
public class PlotFunctionsFragment extends BaseDialogFragment {
|
||||
|
||||
@Inject
|
||||
@ -120,7 +120,7 @@ public class PlotFunctionsFragment extends BaseDialogFragment {
|
||||
@Bind(R.id.function_icon)
|
||||
PlotIconView icon;
|
||||
|
||||
@Bind(R.id.fn_name_edittext)
|
||||
@Bind(R.id.function_name)
|
||||
TextView name;
|
||||
private PlotFunction function;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fn_name_edittext"
|
||||
android:id="@+id/function_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
|
@ -73,4 +73,6 @@
|
||||
<item name="cpp_kb_button_close" type="id" />
|
||||
<item name="cpp_kb_button_change_case" type="id" />
|
||||
|
||||
<item name="function_params_add" type="id" />
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user