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
|
<activity
|
||||||
android:name=".plot.PlotActivity"
|
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
|
<activity
|
||||||
android:name=".wizard.WizardActivity"
|
android:name=".wizard.WizardActivity"
|
||||||
|
@ -84,6 +84,7 @@ public abstract class BaseFunctionFragment extends BaseDialogFragment implements
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final KeyboardUser keyboardUser = new KeyboardUser();
|
private final KeyboardUser keyboardUser = new KeyboardUser();
|
||||||
@Bind(R.id.function_params)
|
@Bind(R.id.function_params)
|
||||||
|
public
|
||||||
FunctionParamsView paramsView;
|
FunctionParamsView paramsView;
|
||||||
@Bind(R.id.function_name_label)
|
@Bind(R.id.function_name_label)
|
||||||
TextInputLayout nameLabel;
|
TextInputLayout nameLabel;
|
||||||
|
@ -4,9 +4,7 @@ import android.os.Parcel;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
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.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -16,11 +14,18 @@ import org.solovyev.android.calculator.json.Jsonable;
|
|||||||
import org.solovyev.common.JBuilder;
|
import org.solovyev.common.JBuilder;
|
||||||
import org.solovyev.common.text.Strings;
|
import org.solovyev.common.text.Strings;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
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 class CppFunction implements Jsonable, Parcelable {
|
||||||
|
|
||||||
public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() {
|
public static final Json.Creator<CppFunction> JSON_CREATOR = new Json.Creator<CppFunction>() {
|
||||||
@ -230,6 +235,13 @@ public class CppFunction implements Jsonable, Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Builder withParameters(@Nonnull String... parameters) {
|
||||||
|
Check.isTrue(!built);
|
||||||
|
function.parameters.addAll(asList(parameters));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Builder withParameter(@Nonnull String parameter) {
|
public Builder withParameter(@Nonnull String parameter) {
|
||||||
Check.isTrue(!built);
|
Check.isTrue(!built);
|
||||||
|
@ -36,17 +36,23 @@ import android.view.Gravity;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
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.Check;
|
||||||
import org.solovyev.android.calculator.App;
|
import org.solovyev.android.calculator.App;
|
||||||
import org.solovyev.android.calculator.Preferences;
|
import org.solovyev.android.calculator.Preferences;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.MATCH_PARENT;
|
||||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
|
||||||
@ -63,6 +69,9 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
private final Preferences.Gui.Theme theme = App.getTheme();
|
private final Preferences.Gui.Theme theme = App.getTheme();
|
||||||
private int maxRowId = START_ROW_ID;
|
private int maxRowId = START_ROW_ID;
|
||||||
|
private int maxParams = Integer.MAX_VALUE;
|
||||||
|
@Nonnull
|
||||||
|
private LinearLayout headerView;
|
||||||
|
|
||||||
{
|
{
|
||||||
final Resources resources = getResources();
|
final Resources resources = getResources();
|
||||||
@ -91,8 +100,9 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
setOrientation(VERTICAL);
|
setOrientation(VERTICAL);
|
||||||
final Context context = getContext();
|
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);
|
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() {
|
addButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@ -187,9 +197,15 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
|
|
||||||
// for row is added at 0 position, the consequent rows
|
// for row is added at 0 position, the consequent rows
|
||||||
addView(rowView, Math.max(0, getChildCount() - 1), new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
addView(rowView, Math.max(0, getChildCount() - 1), new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||||
|
onParamsChanged();
|
||||||
return rowView;
|
return rowView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onParamsChanged() {
|
||||||
|
final boolean enabled = getParamsCount() < maxParams;
|
||||||
|
headerView.setVisibility(enabled ? VISIBLE : GONE);
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private LayoutParams makeButtonParams() {
|
private LayoutParams makeButtonParams() {
|
||||||
return new LayoutParams(imageButtonSize, imageButtonSize);
|
return new LayoutParams(imageButtonSize, imageButtonSize);
|
||||||
@ -224,19 +240,20 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private ViewGroup getRow(int index) {
|
private ViewGroup getRow(int index) {
|
||||||
Check.isTrue(index >= 0 && index < getChildCount() - FOOTERS);
|
Check.isTrue(index >= 0 && index < getParamsCount());
|
||||||
return (ViewGroup) getChildAt(index);
|
return (ViewGroup) getChildAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRow(@Nonnull ViewGroup row) {
|
public void removeRow(@Nonnull ViewGroup row) {
|
||||||
removeView(row);
|
removeView(row);
|
||||||
|
onParamsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public List<String> getParams() {
|
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 ViewGroup row = getRow(i);
|
||||||
final EditText paramView = getParamView(row);
|
final EditText paramView = getParamView(row);
|
||||||
params.add(paramView.getText().toString());
|
params.add(paramView.getText().toString());
|
||||||
@ -245,6 +262,15 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getParamsCount() {
|
||||||
|
return getChildCount() - FOOTERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxParams(int maxParams) {
|
||||||
|
this.maxParams = maxParams;
|
||||||
|
onParamsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private EditText getParamView(@Nonnull ViewGroup row) {
|
private EditText getParamView(@Nonnull ViewGroup row) {
|
||||||
final TextInputLayout paramLabel = getParamLabel(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.PlotViewFrame;
|
||||||
import org.solovyev.android.plotter.Plotter;
|
import org.solovyev.android.plotter.Plotter;
|
||||||
|
|
||||||
import butterknife.Bind;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
public class PlotActivity extends BaseActivity {
|
public class PlotActivity extends BaseActivity {
|
||||||
|
|
||||||
public static class MyFragment extends BaseFragment implements PlotViewFrame.Listener {
|
public static class MyFragment extends BaseFragment implements PlotViewFrame.Listener {
|
||||||
@ -79,7 +79,7 @@ public class PlotActivity extends BaseActivity {
|
|||||||
PlotFunctionsFragment.show(getActivity().getSupportFragmentManager());
|
PlotFunctionsFragment.show(getActivity().getSupportFragmentManager());
|
||||||
return true;
|
return true;
|
||||||
} else if (id == R.id.plot_add_function) {
|
} else if (id == R.id.plot_add_function) {
|
||||||
//App.getBus().post(new AddFunctionDialog.ShowEvent());
|
PlotEditFunctionFragment.show(null, getActivity().getSupportFragmentManager());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -111,6 +111,7 @@ public class PlotEditFunctionFragment extends BaseFunctionFragment
|
|||||||
|
|
||||||
final int[] colors = MeshSpec.LightColors.asIntArray();
|
final int[] colors = MeshSpec.LightColors.asIntArray();
|
||||||
colorPicker.setColors(colors);
|
colorPicker.setColors(colors);
|
||||||
|
paramsView.setMaxParams(2);
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
if (plotFunction != null) {
|
if (plotFunction != null) {
|
||||||
setupViews(plotFunction.meshSpec);
|
setupViews(plotFunction.meshSpec);
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package org.solovyev.android.calculator.plot;
|
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.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
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.DividerItemDecoration;
|
||||||
import org.solovyev.android.views.llm.LinearLayoutManager;
|
import org.solovyev.android.views.llm.LinearLayoutManager;
|
||||||
|
|
||||||
import butterknife.Bind;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
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 {
|
public class PlotFunctionsFragment extends BaseDialogFragment {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -120,7 +120,7 @@ public class PlotFunctionsFragment extends BaseDialogFragment {
|
|||||||
@Bind(R.id.function_icon)
|
@Bind(R.id.function_icon)
|
||||||
PlotIconView icon;
|
PlotIconView icon;
|
||||||
|
|
||||||
@Bind(R.id.fn_name_edittext)
|
@Bind(R.id.function_name)
|
||||||
TextView name;
|
TextView name;
|
||||||
private PlotFunction function;
|
private PlotFunction function;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/fn_name_edittext"
|
android:id="@+id/function_name"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
|
@ -73,4 +73,6 @@
|
|||||||
<item name="cpp_kb_button_close" type="id" />
|
<item name="cpp_kb_button_close" type="id" />
|
||||||
<item name="cpp_kb_button_change_case" type="id" />
|
<item name="cpp_kb_button_change_case" type="id" />
|
||||||
|
|
||||||
|
<item name="function_params_add" type="id" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user