allow float inputs
parent
dac2a81bcc
commit
c7bcde4778
|
@ -34,6 +34,7 @@ describe("<AxisInputBox/>", () => {
|
|||
}
|
||||
testInput("", undefined);
|
||||
testInput("1", 1);
|
||||
testInput("1.1", 1.1);
|
||||
testInput("e", undefined);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -50,6 +50,7 @@ export interface NumericMCUInputGroupProps {
|
|||
x: McuParamName;
|
||||
y: McuParamName;
|
||||
z: McuParamName;
|
||||
float?: boolean;
|
||||
intSize?: IntegerSize;
|
||||
gray?: Record<Xyz, boolean>;
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -164,6 +164,7 @@ export interface McuInputBoxProps {
|
|||
setting: McuParamName;
|
||||
dispatch: Function;
|
||||
intSize?: IntegerSize;
|
||||
float?: boolean;
|
||||
filter?: number;
|
||||
gray?: boolean;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
});
|
||||
|
|
|
@ -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)");
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue