allow float inputs

pull/911/head
gabrielburnworth 2018-07-13 13:56:01 -07:00
parent dac2a81bcc
commit c7bcde4778
12 changed files with 72 additions and 20 deletions

View File

@ -34,6 +34,7 @@ describe("<AxisInputBox/>", () => {
}
testInput("", undefined);
testInput("1", 1);
testInput("1.1", 1.1);
testInput("e", undefined);
});
});

View File

@ -10,7 +10,7 @@ export let AxisInputBox = ({ onChange, value, axis }: AxisInputBoxProps) => {
type="number"
allowEmpty={true}
onCommit={e => {
const val = parseInt(e.currentTarget.value);
const val = parseFloat(e.currentTarget.value);
onChange(axis, isNaN(val) ? undefined : val);
}} />
</Col>;

View File

@ -1,24 +1,61 @@
jest.mock("farmbot-toastr", () => ({ warning: jest.fn() }));
jest.mock("../../actions", () => ({ updateMCU: jest.fn() }));
import * as React from "react";
import { McuInputBox } from "../mcu_input_box";
import { warning } from "farmbot-toastr";
import { shallow } from "enzyme";
import { McuInputBoxProps } from "../../interfaces";
import { bot } from "../../../__test_support__/fake_state/bot";
import { updateMCU } from "../../actions";
describe("McuInputBox", () => {
it("clamps numbers", () => {
beforeEach(() => {
jest.clearAllMocks();
const mib = new McuInputBox({
sourceFwConfig: jest.fn(),
});
const fakeProps = (): McuInputBoxProps => {
return {
sourceFwConfig: (x) => {
return { value: bot.hardware.mcu_params[x], consistent: true };
},
setting: "encoder_enabled_x",
dispatch: jest.fn()
});
};
};
it("clamps numbers", () => {
const mib = new McuInputBox(fakeProps());
const result = mib.clampInputAndWarn("-1", "short");
expect(result).toEqual(0);
expect(warning)
.toHaveBeenCalledWith("Must be a positive number. Rounding up to 0.");
jest.clearAllMocks();
});
it("clamps numbers", () => {
const mib = new McuInputBox(fakeProps());
expect(() => mib.clampInputAndWarn("QQQ", "short"))
.toThrowError("Bad input in mcu_input_box. Impossible?");
expect(warning)
.toHaveBeenCalledWith("Please enter a number between 0 and 32,000");
});
it("handles float", () => {
const p = fakeProps();
p.float = true;
const wrapper = shallow(<McuInputBox {...p} />);
wrapper.find("BlurableInput").simulate("commit",
{ currentTarget: { value: "5.5" } });
expect(updateMCU).toHaveBeenCalledWith("encoder_enabled_x", "5.5");
});
it("handles int", () => {
const p = fakeProps();
p.float = false;
const wrapper = shallow(<McuInputBox {...p} />);
wrapper.find("BlurableInput").simulate("commit",
{ currentTarget: { value: "5.5" } });
expect(updateMCU).toHaveBeenCalledWith("encoder_enabled_x", "5");
});
});

View File

@ -49,6 +49,7 @@ export function StepsPerMmSettings(props: MotorsProps) {
x={"movement_step_per_mm_x"}
y={"movement_step_per_mm_y"}
z={"movement_step_per_mm_z"}
float={true}
sourceFwConfig={sourceFwConfig}
dispatch={dispatch} />;
} else {

View File

@ -50,6 +50,7 @@ export interface NumericMCUInputGroupProps {
x: McuParamName;
y: McuParamName;
z: McuParamName;
float?: boolean;
intSize?: IntegerSize;
gray?: Record<Xyz, boolean>;
}

View File

@ -51,7 +51,9 @@ export class McuInputBox extends React.Component<McuInputBoxProps, {}> {
const { value } = e.currentTarget;
const actuallyDifferent = this.value !== value;
if (actuallyDifferent) {
const result = this.clampInputAndWarn(value, this.props.intSize);
const result = this.props.float
? Math.max(0, parseFloat(value))
: this.clampInputAndWarn(value, this.props.intSize);
this.props.dispatch(updateMCU(this.key, result.toString()));
}
}

View File

@ -6,7 +6,8 @@ import { Row, Col } from "../../ui/index";
export function NumericMCUInputGroup(props: NumericMCUInputGroupProps) {
const { sourceFwConfig, dispatch, tooltip, name, x, y, z, intSize, gray
const {
sourceFwConfig, dispatch, tooltip, name, x, y, z, intSize, gray, float
} = props;
return <Row>
<Col xs={6}>
@ -21,6 +22,7 @@ export function NumericMCUInputGroup(props: NumericMCUInputGroupProps) {
sourceFwConfig={sourceFwConfig}
dispatch={dispatch}
intSize={intSize}
float={float}
gray={gray && gray.x} />
</Col>
<Col xs={2}>
@ -29,6 +31,7 @@ export function NumericMCUInputGroup(props: NumericMCUInputGroupProps) {
sourceFwConfig={sourceFwConfig}
dispatch={dispatch}
intSize={intSize}
float={float}
gray={gray && gray.y} />
</Col>
<Col xs={2}>
@ -37,6 +40,7 @@ export function NumericMCUInputGroup(props: NumericMCUInputGroupProps) {
sourceFwConfig={sourceFwConfig}
dispatch={dispatch}
intSize={intSize}
float={float}
gray={gray && gray.z} />
</Col>
</Row>;

View File

@ -164,6 +164,7 @@ export interface McuInputBoxProps {
setting: McuParamName;
dispatch: Function;
intSize?: IntegerSize;
float?: boolean;
filter?: number;
gray?: boolean;
}

View File

@ -49,8 +49,12 @@ export interface ActiveMiddleProps extends SequenceEditorMiddleProps {
export type ChannelName = ALLOWED_CHANNEL_NAMES;
export const NUMERIC_FIELDS = ["milliseconds", "pin_mode", "pin_number",
"pin_value", "rhs", "sequence_id", "speed", "x", "y", "z"];
export const INT_NUMERIC_FIELDS = ["milliseconds", "pin_mode", "pin_number",
"pin_value", "rhs", "sequence_id", "speed"];
export const FLOAT_NUMERIC_FIELDS = ["x", "y", "z"];
export const NUMERIC_FIELDS = INT_NUMERIC_FIELDS.concat(FLOAT_NUMERIC_FIELDS);
export interface Sequence extends CeleryScriptSequence {
id?: number;

View File

@ -16,7 +16,7 @@ describe("<TileMoveAbsolute/>", () => {
location: {
kind: "coordinate",
args: {
x: 1,
x: 1.1,
y: 2,
z: 3
}
@ -25,7 +25,7 @@ describe("<TileMoveAbsolute/>", () => {
offset: {
kind: "coordinate",
args: {
x: 4,
x: 4.4,
y: 5,
z: 6
}
@ -62,11 +62,11 @@ describe("<TileMoveAbsolute/>", () => {
expect(inputs.first().props().placeholder).toEqual("Move Absolute");
expect(labels.at(0).text().toLowerCase()).toEqual("import coordinates from");
expect(buttons.at(0).text()).toEqual("None");
checkField(block, 1, "x (mm)", "1");
checkField(block, 1, "x (mm)", "1.1");
checkField(block, 2, "y (mm)", "2");
checkField(block, 3, "z (mm)", "3");
checkField(block, 4, "speed (%)", 100);
checkField(block, 5, "x-offset", "4");
checkField(block, 5, "x-offset", "4.4");
checkField(block, 6, "y-offset", "5");
checkField(block, 7, "z-offset", "6");
});

View File

@ -10,7 +10,7 @@ describe("<TileMoveRelative/>", () => {
const currentStep: MoveRelative = {
kind: "move_relative",
args: {
x: 1,
x: 1.1,
y: 2,
z: 3,
speed: 100
@ -34,7 +34,7 @@ describe("<TileMoveRelative/>", () => {
expect(labels.length).toEqual(4);
expect(inputs.first().props().placeholder).toEqual("Move Relative");
expect(labels.at(0).text().toLowerCase()).toEqual("x (mm)");
expect(inputs.at(1).props().value).toEqual(1);
expect(inputs.at(1).props().value).toEqual(1.1);
expect(labels.at(1).text().toLowerCase()).toEqual("y (mm)");
expect(inputs.at(2).props().value).toEqual(2);
expect(labels.at(2).text().toLowerCase()).toEqual("z (mm)");

View File

@ -1,6 +1,6 @@
import * as React from "react";
import { SequenceBodyItem as Step } from "farmbot";
import { NUMERIC_FIELDS } from "../interfaces";
import { FLOAT_NUMERIC_FIELDS, NUMERIC_FIELDS } from "../interfaces";
import { ExecuteBlock } from "./tile_execute";
import { StepParams, StepInputProps, StepTitleBarProps } from "../interfaces";
import { defensiveClone, move as arrayMover } from "../../util";
@ -115,9 +115,10 @@ export function updateStepTitle(props: StepTitleBarProps) {
}
function numericNonsense(val: string, copy: CeleryNode, field: LegalArgString) {
// Fix negative number issues.
const num = (val == "-") ? "-" : parseFloat(val);
return _.assign(copy.args, { [field]: num });
const parsedNumber = FLOAT_NUMERIC_FIELDS.includes(field)
? parseFloat(val)
: parseInt(val, 10);
return _.assign(copy.args, { [field]: parsedNumber });
}
export function renderCeleryNode(props: StepParams) {