1
0
Эх сурвалжийг харах

refactor(server): Extract variant generation method into shared function

Michael Bromley 7 жил өмнө
parent
commit
8245c6bf1f

+ 5 - 1
server/package.json

@@ -72,7 +72,11 @@
       "json",
       "ts"
     ],
-    "rootDir": "src",
+
+    "roots": [
+      "src",
+      "../shared"
+    ],
     "testRegex": ".spec.ts$",
     "transform": {
       "^.+\\.(t|j)s$": "ts-jest"

+ 2 - 31
server/src/service/product-variant.service.ts

@@ -3,6 +3,7 @@ import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 
 import { ID } from '../../../shared/shared-types';
+import { generateAllCombinations } from '../../../shared/shared-utils';
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
 import { ProductOption } from '../entity/product-option/product-option.entity';
 import { CreateProductVariantDto } from '../entity/product-variant/create-product-variant.dto';
@@ -60,7 +61,7 @@ export class ProductVariantService {
 
         const productName = defaultTranslation ? defaultTranslation.name : `product_${productId}`;
         const optionCombinations = product.optionGroups.length
-            ? this.optionCombinations(product.optionGroups.map(g => g.options))
+            ? generateAllCombinations(product.optionGroups.map(g => g.options))
             : [[]];
         const createVariants = optionCombinations.map(options => {
             const name = this.createVariantName(productName, options);
@@ -94,34 +95,4 @@ export class ProductVariantService {
 
         return options.length ? `${productName} ${optionsSuffix}` : productName;
     }
-
-    /**
-     * Given an array of option arrays `[['red, 'blue'], ['small', 'large']]`, this method returns a new array
-     * containing all the combinations of those options:
-     *
-     * [
-     *  ['red', 'small'],
-     *  ['red', 'large'],
-     *  ['blue', 'small'],
-     *  ['blue', 'large'],
-     * ]
-     */
-    private optionCombinations<T>(
-        optionGroups: T[][],
-        combination: T[] = [],
-        k: number = 0,
-        output: T[][] = [],
-    ): T[][] {
-        if (k === optionGroups.length) {
-            output.push(combination);
-            return [];
-        } else {
-            // tslint:disable:prefer-for-of
-            for (let i = 0; i < optionGroups[k].length; i++) {
-                this.optionCombinations(optionGroups, combination.concat(optionGroups[k][i]), k + 1, output);
-            }
-            // tslint:enable:prefer-for-of
-            return output;
-        }
-    }
 }

+ 38 - 0
shared/shared-utils.spec.ts

@@ -0,0 +1,38 @@
+/// <reference types="../server/node_modules/@types/jest" />
+
+import { generateAllCombinations } from './shared-utils';
+
+describe('generateAllCombinations()', () => {
+
+    it('works with an empty input array', () => {
+        const result = generateAllCombinations([]);
+        expect(result).toEqual([]);
+    });
+
+    it('works with an input of length 1', () => {
+        const result = generateAllCombinations([
+            ['red', 'green', 'blue'],
+        ]);
+        expect(result).toEqual([
+            ['red'],
+            ['green'],
+            ['blue'],
+        ]);
+    });
+
+    it('works with an input of length 2', () => {
+        const result = generateAllCombinations([
+            ['red', 'green', 'blue'],
+            ['small', 'large'],
+        ]);
+        expect(result).toEqual([
+            ['red', 'small'],
+            ['red', 'large'],
+            ['green', 'small'],
+            ['green', 'large'],
+            ['blue', 'small'],
+            ['blue', 'large'],
+        ]);
+    });
+
+});

+ 34 - 0
shared/shared-utils.ts

@@ -5,3 +5,37 @@
 export function notNullOrUndefined<T>(val: T | undefined | null): val is T {
     return val !== undefined && val !== null;
 }
+
+/**
+ * Given an array of option arrays `[['red, 'blue'], ['small', 'large']]`, this method returns a new array
+ * containing all the combinations of those options:
+ *
+ * @example
+ * ```
+ * generateAllCombinations([['red, 'blue'], ['small', 'large']]);
+ * // =>
+ * // [
+ * //  ['red', 'small'],
+ * //  ['red', 'large'],
+ * //  ['blue', 'small'],
+ * //  ['blue', 'large'],
+ * // ]
+ */
+export function generateAllCombinations<T>(
+    optionGroups: T[][],
+    combination: T[] = [],
+    k: number = 0,
+    output: T[][] = [],
+): T[][] {
+    if (k === optionGroups.length) {
+        output.push(combination);
+        return [];
+    } else {
+        // tslint:disable:prefer-for-of
+        for (let i = 0; i < optionGroups[k].length; i++) {
+            generateAllCombinations(optionGroups, combination.concat(optionGroups[k][i]), k + 1, output);
+        }
+        // tslint:enable:prefer-for-of
+        return output;
+    }
+}