Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions app/client/src/widgets/JSONFormWidget/schemaParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,7 @@ export const normalizeArrayValue = (data: any[]) => {
return data[0];
};

// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const fieldTypeFor = (value: any): FieldType => {
export const fieldTypeFor = (value: unknown): FieldType => {
const dataType = dataTypeFor(value);
const potentialFieldType = DATA_TYPE_POTENTIAL_FIELD[dataType];
const subDataType = subDataTypeFor(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,98 +4,120 @@ import type { JSONFormWidgetProps } from "../..";
import { defaultOptionValueValidation } from "./select";

describe(".defaultOptionValueValidation", () => {
it("return undefined when input is undefined", () => {
const input = undefined;
const expectedOutput = {
isValid: true,
parsed: undefined,
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});
describe("handling falsey values", () => {
it("return undefined when input is undefined", () => {
const input = undefined;
const expectedOutput = {
isValid: true,
parsed: undefined,
messages: [{ name: "", message: "" }],
};

it("return null when input is null", () => {
const input = null;
const expectedOutput = {
isValid: true,
parsed: null,
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

it("return empty string with empty string", () => {
const input = "";
const expectedOutput = {
isValid: true,
parsed: "",
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});
expect(response).toEqual(expectedOutput);
});

it("return null when input is null", () => {
const input = null;
const expectedOutput = {
isValid: true,
parsed: null,
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});

it("return empty string with empty string", () => {
const input = "";
const expectedOutput = {
isValid: true,
parsed: "",
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

it("return value with string", () => {
const input = "green";
const expectedOutput = {
isValid: true,
parsed: "green",
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
expect(response).toEqual(expectedOutput);
});
Comment on lines +8 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using test.each for falsey value tests

The falsey value tests follow the same pattern and could be more maintainable using test.each.

-  describe("handling falsey values", () => {
-    it("return undefined when input is undefined", () => {
-      const input = undefined;
-      const expectedOutput = {
-        isValid: true,
-        parsed: undefined,
-        messages: [{ name: "", message: "" }],
-      };
-      // ... similar pattern repeats
+  describe("handling falsey values", () => {
+    test.each([
+      ["undefined", undefined],
+      ["null", null],
+      ["empty string", ""]
+    ])("returns correct output for %s", (_, input) => {
+      const expectedOutput = {
+        isValid: true,
+        parsed: input,
+        messages: [{ name: "", message: "" }],
+      };
+      
+      const response = defaultOptionValueValidation(
+        input,
+        {} as JSONFormWidgetProps,
+        _,
+      );
+      
+      expect(response).toEqual(expectedOutput);
+    });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("return undefined when input is undefined", () => {
const input = undefined;
const expectedOutput = {
isValid: true,
parsed: undefined,
messages: [{ name: "", message: "" }],
};
it("return null when input is null", () => {
const input = null;
const expectedOutput = {
isValid: true,
parsed: null,
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
expect(response).toEqual(expectedOutput);
});
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
it("return empty string with empty string", () => {
const input = "";
const expectedOutput = {
isValid: true,
parsed: "",
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
expect(response).toEqual(expectedOutput);
});
expect(response).toEqual(expectedOutput);
});
it("return null when input is null", () => {
const input = null;
const expectedOutput = {
isValid: true,
parsed: null,
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
expect(response).toEqual(expectedOutput);
});
it("return empty string with empty string", () => {
const input = "";
const expectedOutput = {
isValid: true,
parsed: "",
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
it("return value with string", () => {
const input = "green";
const expectedOutput = {
isValid: true,
parsed: "green",
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
expect(response).toEqual(expectedOutput);
expect(response).toEqual(expectedOutput);
});
describe("handling falsey values", () => {
test.each([
["undefined", undefined],
["null", null],
["empty string", ""]
])("returns correct output for %s", (_, input) => {
const expectedOutput = {
isValid: true,
parsed: input,
messages: [{ name: "", message: "" }],
};
const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);
expect(response).toEqual(expectedOutput);
});
});

});

it("return value with stringified json", () => {
const input = `
describe("handling truthy values", () => {
it("return value with string", () => {
const input = "green";
const expectedOutput = {
isValid: true,
parsed: "green",
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});

it("return value with stringified json", () => {
const input = `
{
"label": "green",
"value": "green"
}
`;

const expectedOutput = {
isValid: true,
parsed: {
label: "green",
value: "green",
},
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
const expectedOutput = {
isValid: true,
parsed: {
label: "green",
value: "green",
},
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});

it("Edge Case: For very long numbers passed as string, don't parse it as number", () => {
const input =
"123456789012345678901234567890123456789012345678901234567890";
const expectedOutput = {
isValid: true,
parsed: "123456789012345678901234567890123456789012345678901234567890",
messages: [{ name: "", message: "" }],
};

const response = defaultOptionValueValidation(
input,
{} as JSONFormWidgetProps,
_,
);

expect(response).toEqual(expectedOutput);
});
});

it("should return isValid false with invalid values", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,13 @@ import type { ValidationResponse } from "constants/WidgetValidation";
import { ValidationTypes } from "constants/WidgetValidation";
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
import type { LoDashStatic } from "lodash";

export function defaultOptionValueValidation(
inputValue: unknown,
value: unknown,
props: JSONFormWidgetProps,
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_: any,
_: LoDashStatic,
): ValidationResponse {
const DEFAULT_ERROR_MESSAGE = {
name: "TypeError",
message:
'value should match: string | { "label": "label1", "value": "value1" }',
};
let value = inputValue;

const hasLabelValueProperties = (
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -38,21 +30,29 @@ export function defaultOptionValueValidation(

// If input value is empty string then we can fairly assume that the input
// was cleared out and can be treated as undefined.
if (inputValue === undefined || inputValue === null || inputValue === "") {
if (value === undefined || value === null || value === "") {
return {
isValid: true,
parsed: inputValue,
parsed: value,
messages: [{ name: "", message: "" }],
};
}

if (typeof inputValue === "string") {
if (typeof value === "string") {
try {
value = JSON.parse(inputValue);
const parsedValue = JSON.parse(value);

if (_.isObject(parsedValue)) {
value = parsedValue;
}
} catch (e) {}
}

if (_.isString(value) || _.isFinite(value)) {
if (
_.isString(value) ||
_.isFinite(value) ||
hasLabelValueProperties(value)
) {
// When value is "", "green", 444
return {
isValid: true,
Expand All @@ -61,19 +61,16 @@ export function defaultOptionValueValidation(
};
}

if (hasLabelValueProperties(value)) {
// When value is {label: "green", value: "green"}
return {
isValid: true,
parsed: value,
messages: [{ name: "", message: "" }],
};
}

return {
isValid: false,
parsed: {},
messages: [DEFAULT_ERROR_MESSAGE],
messages: [
{
name: "TypeError",
message:
'value should match: string | { "label": "label1", "value": "value1" }',
},
],
};
}

Expand Down