Add immutability and concatenation of order builder
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 3 Jul 2018 11:06:09 +0000 (13:06 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 3 Jul 2018 11:06:09 +0000 (13:06 +0200)
Feature #13703

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/common/api/order-builder.test.ts
src/common/api/order-builder.ts

index c184ebce0036abe300a93ad63a857ae767984cdd..b80756d408ef55770727727f9f2f3b3095e4a03e 100644 (file)
@@ -6,11 +6,22 @@ import OrderBuilder from "./order-builder";
 
 describe("OrderBuilder", () => {
     it("should build correct order query", () => {
-        const orderBuilder = new OrderBuilder();
-        const order = orderBuilder
-            .addAsc("name")
-            .addDesc("modified_at")
-            .get();
-        expect(order).toEqual(["name asc","modified_at desc"]);
+        const order = OrderBuilder
+            .create()
+            .addAsc("kind")
+            .addDesc("modifiedAt")
+            .getOrder();
+        expect(order).toEqual(["kind asc", "modified_at desc"]);
+    });
+
+    it("should combine results with other builder", () => {
+        const order = OrderBuilder
+            .create()
+            .addAsc("kind")
+            .concat(OrderBuilder
+                .create("properties")
+                .addDesc("modifiedAt"))
+            .getOrder();
+        expect(order).toEqual(["kind asc", "properties.modified_at desc"]);
     });
 });
index cc3eadbb904ffb947c34121f8852a35fab256b18..08d17b18e9d5b3ed7adba85fd36e8074d5abaaae 100644 (file)
@@ -2,21 +2,46 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+import * as _ from "lodash";
+import { Resource } from "./common-resource-service";
 
-export default class OrderBuilder {
-    private order: string[] = [];
+export default class OrderBuilder<T extends Resource = Resource> {
 
-    addAsc(attribute: string) {
-        this.order.push(`${attribute} asc`);
-        return this;
+    static create<T extends Resource = Resource>(prefix?: string){
+        return new OrderBuilder<T>([], prefix);
     }
 
-    addDesc(attribute: string) {
-        this.order.push(`${attribute} desc`);
-        return this;
+    private constructor(
+        private order: string[] = [], 
+        private prefix = ""){}
+
+    private getRule (direction: string, attribute: keyof T) {
+        const prefix = this.prefix ? this.prefix + "." : "";
+        return `${prefix}${_.snakeCase(attribute.toString())} ${direction}`;
+    }
+
+    addAsc(attribute: keyof T) {
+        return new OrderBuilder<T>(
+            [...this.order, this.getRule("asc", attribute)],
+            this.prefix
+        );
+    }
+
+    addDesc(attribute: keyof T) {
+        return new OrderBuilder<T>(
+            [...this.order, this.getRule("desc", attribute)],
+            this.prefix
+        );
+    }
+
+    concat(orderBuilder: OrderBuilder){
+        return new OrderBuilder<T>(
+            this.order.concat(orderBuilder.getOrder()),
+            this.prefix
+        );
     }
 
-    get() {
-        return this.order;
+    getOrder() {
+        return this.order.slice();
     }
 }