From 149ea73e00b0cf229a8b5e2f3ce99da489e2440c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Dec 2019 13:16:54 +0100 Subject: [PATCH] move comparators from scm-review-plugin to ui-components --- scm-ui/ui-components/src/comparators.test.ts | 126 ++++++++++++++++++ scm-ui/ui-components/src/comparators.ts | 75 +++++++++++ scm-ui/ui-components/src/index.ts | 2 + scm-ui/ui-components/src/table/TextColumn.tsx | 11 +- 4 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 scm-ui/ui-components/src/comparators.test.ts create mode 100644 scm-ui/ui-components/src/comparators.ts diff --git a/scm-ui/ui-components/src/comparators.test.ts b/scm-ui/ui-components/src/comparators.test.ts new file mode 100644 index 0000000000..345f3651e0 --- /dev/null +++ b/scm-ui/ui-components/src/comparators.test.ts @@ -0,0 +1,126 @@ +import { byKey, byValueLength, byNestedKeys } from "./comparators"; + +const createObject = (key: string, value?: string) => { + return { + [key]: value + }; +}; + +const createObjects = (key: string, values: Array) => { + return values.map(v => createObject(key, v)); +}; + +describe("key comparator tests", () => { + it("should sort array", () => { + const array = createObjects("key", ["z", "a", "y", "b"]); + array.sort(byKey("key")); + expect(array).toEqual(createObjects("key", ["a", "b", "y", "z"])); + }); + + it("should not fail if value is undefined", () => { + const array = createObjects("key", ["z", undefined, "a"]); + array.sort(byKey("key")); + expect(array).toEqual(createObjects("key", ["a", "z", undefined])); + }); + + it("should not fail if key is undefined", () => { + const array = createObjects("key", ["a"]); + array.push({}); + array.push(createObject("key", "z")); + array.sort(byKey("key")); + expect(array).toEqual([createObject("key", "a"), createObject("key", "z"), {}]); + }); + + it("should not fail if item is undefined", () => { + const array: any[] = createObjects("key", ["a"]); + array.push(undefined); + array.push(createObject("key", "z")); + array.sort(byKey("key")); + expect(array).toEqual([createObject("key", "a"), createObject("key", "z"), undefined]); + }); +}); + +describe("length comparator tests", () => { + it("should sort array", () => { + const array = createObjects("key", ["....", ".", "...", ".."]); + array.sort(byValueLength("key")); + expect(array).toEqual(createObjects("key", [".", "..", "...", "...."])); + }); + + it("should not fail if value is undefined", () => { + const array = createObjects("key", ["..", undefined, "."]); + array.sort(byValueLength("key")); + expect(array).toEqual(createObjects("key", [".", "..", undefined])); + }); + + it("should not fail if key is undefined", () => { + const array = createObjects("key", ["."]); + array.push({}); + array.push(createObject("key", "..")); + array.sort(byValueLength("key")); + expect(array).toEqual([createObject("key", "."), createObject("key", ".."), {}]); + }); + + it("should not fail if item is undefined", () => { + const array: any[] = createObjects("key", ["."]); + array.push(undefined); + array.push(createObject("key", "..")); + array.sort(byValueLength("key")); + expect(array).toEqual([createObject("key", "."), createObject("key", ".."), undefined]); + }); +}); + +describe("nested key comparator tests", () => { + const createObject = (key: string, nested?: string, value?: string) => { + if (!nested) { + return { + [key]: undefined + }; + } + return { + [key]: { + [nested]: value + } + }; + }; + + const createObjects = (key: string, nested: string, values: Array) => { + return values.map(v => createObject(key, nested, v)); + }; + + it("should sort array", () => { + const array = createObjects("key", "nested", ["z", "a", "y", "b"]); + array.sort(byNestedKeys("key", "nested")); + expect(array).toEqual(createObjects("key", "nested", ["a", "b", "y", "z"])); + }); + + it("should not fail if value is undefined", () => { + const array = createObjects("key", "nested", ["z", undefined, "a"]); + array.sort(byNestedKeys("key", "nested")); + expect(array).toEqual(createObjects("key", "nested", ["a", "z", undefined])); + }); + + it("should not fail if key is undefined", () => { + const array = createObjects("key", "nested", ["a"]); + array.push({}); + array.push(createObject("key", "nested", "z")); + array.sort(byNestedKeys("key", "nested")); + expect(array).toEqual([createObject("key", "nested", "a"), createObject("key", "nested", "z"), {}]); + }); + + it("should not fail if nested key is undefined", () => { + const array = createObjects("key", "nested", ["a"]); + array.push(createObject("key", undefined, "y")); + array.push(createObject("key", "nested", "z")); + array.sort(byNestedKeys("key", "nested")); + expect(array).toEqual([createObject("key", "nested", "a"), createObject("key", "nested", "z"), { key: undefined }]); + }); + + it("should not fail if item is undefined", () => { + const array: any[] = createObjects("key", "nested", ["a"]); + array.push(undefined); + array.push(createObject("key", "nested", "z")); + array.sort(byNestedKeys("key", "nested")); + expect(array).toEqual([createObject("key", "nested", "a"), createObject("key", "nested", "z"), undefined]); + }); +}); diff --git a/scm-ui/ui-components/src/comparators.ts b/scm-ui/ui-components/src/comparators.ts new file mode 100644 index 0000000000..e4d661c2fd --- /dev/null +++ b/scm-ui/ui-components/src/comparators.ts @@ -0,0 +1,75 @@ +const isUndefined = (o: any, key: string, nested?: string) => { + if (typeof o === "undefined" || typeof o[key] === "undefined") { + return true; + } + if (nested) { + return typeof o[key][nested] === "undefined"; + } + return false; +}; + +export const byKey = (key: string) => { + return (a: any, b: any) => { + if (isUndefined(a, key)) { + return 1; + } + + if (isUndefined(b, key)) { + return 0; + } + + if (a[key] < b[key]) { + return -1; + } else if (a[key] > b[key]) { + return 1; + } else { + return 0; + } + }; +}; + +export const byValueLength = (key: string) => { + return (a: any, b: any) => { + if (isUndefined(a, key)) { + return 1; + } + + if (isUndefined(b, key)) { + return 0; + } + + if (a[key].length < b[key].length) { + return -1; + } else if (a[key].length > b[key].length) { + return 1; + } else { + return 0; + } + }; +}; + +export const byNestedKeys = (key: string, nestedKey: string) => { + return (a: any, b: any) => { + if (isUndefined(a, key, nestedKey)) { + return 1; + } + + if (isUndefined(b, key, nestedKey)) { + return 0; + } + + if (a[key][nestedKey] < b[key][nestedKey]) { + return -1; + } else if (a[key][nestedKey] > b[key][nestedKey]) { + return 1; + } else { + return 0; + } + }; +}; + +export default { + byKey, + byValueLength, + byNestedKeys +}; diff --git a/scm-ui/ui-components/src/index.ts b/scm-ui/ui-components/src/index.ts index d37a04b2e5..e039411842 100644 --- a/scm-ui/ui-components/src/index.ts +++ b/scm-ui/ui-components/src/index.ts @@ -52,6 +52,8 @@ export { default as OverviewPageActions } from "./OverviewPageActions"; export { default as CardColumnGroup } from "./CardColumnGroup"; export { default as CardColumn } from "./CardColumn"; +export { default as comparators } from "./comparators"; + export { apiClient } from "./apiclient"; export * from "./errors"; diff --git a/scm-ui/ui-components/src/table/TextColumn.tsx b/scm-ui/ui-components/src/table/TextColumn.tsx index 0ad5375503..b2a19007bd 100644 --- a/scm-ui/ui-components/src/table/TextColumn.tsx +++ b/scm-ui/ui-components/src/table/TextColumn.tsx @@ -1,5 +1,6 @@ import React, { FC } from "react"; import { ColumnProps } from "./types"; +import comparators from "../comparators"; type Props = ColumnProps & { dataKey: string; @@ -11,15 +12,7 @@ const TextColumn: FC = ({ row, dataKey }) => { TextColumn.defaultProps = { createComparator: (props: Props) => { - return (a: any, b: any) => { - if (a[props.dataKey] < b[props.dataKey]) { - return -1; - } else if (a[props.dataKey] > b[props.dataKey]) { - return 1; - } else { - return 0; - } - }; + return comparators.byKey(props.dataKey); }, ascendingIcon: "sort-alpha-down-alt", descendingIcon: "sort-alpha-down"