Browse Source

add tests for ordered-unique-numbers, refactoring

Richard Köhl 3 years ago
parent
commit
4ab1d87d76
3 changed files with 201 additions and 29 deletions
  1. 157 0
      src/ordered-unique-numbers.class.test.ts
  2. 35 27
      src/ordered-unique-numbers.class.ts
  3. 9 2
      src/prime.class.ts

+ 157 - 0
src/ordered-unique-numbers.class.test.ts

@@ -0,0 +1,157 @@
+import {
+  assert,
+  assertEquals,
+} from "https://deno.land/std@0.161.0/testing/asserts.ts";
+import { OrderedUniqueNumbers } from "./ordered-unique-numbers.class.ts";
+
+Deno.test("OrderedUniqueNumbers class", async (t) => {
+  await t.step("getter list()", async (t) => {
+    await t.step("returns unmodified list of ordered unique numbers", () => {
+      const input = [2, 3, 5, 7, 11, 13];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.list, input);
+    });
+
+    await t.step("returns ascending ordered list of numbers", () => {
+      const input = [2, 13, 5, 7, 11, 3];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.list, [2, 3, 5, 7, 11, 13]);
+    });
+
+    await t.step("returns list of unique numbers", () => {
+      const input = [2, 2, 3, 5, 7, 11, 11, 11, 11, 13];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.list, [2, 3, 5, 7, 11, 13]);
+    });
+
+    await t.step("returns list of ordered unique numbers", () => {
+      const input = [11, 11, 2, 5, 7, 11, 11, 13, 2, 3];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.list, [2, 3, 5, 7, 11, 13]);
+    });
+  });
+
+  await t.step("getter max()", async (t) => {
+    await t.step("returns undefined for empty list", () => {
+      const input: number[] = [];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.max, undefined);
+    });
+
+    await t.step("returns only number in list", () => {
+      const input = [11];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.max, 11);
+    });
+
+    await t.step("returns greatest number in list", () => {
+      const input = [2, 3, 5, 7, 11, 13];
+      const numbers = new OrderedUniqueNumbers(input);
+      assertEquals(numbers.max, 13);
+    });
+  });
+
+  await t.step("method contains()", async (t) => {
+    await t.step("returns true if input is found in list", () => {
+      const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+      assert(numbers.contains(5));
+    });
+
+    await t.step("returns false if input is not found in list", () => {
+      const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+      assert(!numbers.contains(6));
+    });
+  });
+
+  await t.step("method add()", async (t) => {
+    await t.step(
+      "adds a larger number to the end of the list and returns it",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.add(15);
+        assertEquals(numbers.list, [2, 3, 5, 7, 11, 13, 15]);
+      },
+    );
+
+    await t.step(
+      "does not add number if already present and returns list",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.add(13);
+        assertEquals(numbers.list, [2, 3, 5, 7, 11, 13]);
+      },
+    );
+
+    await t.step(
+      "adds a smaller number to the start of the list and returns it",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.add(1);
+        assertEquals(numbers.list, [1, 2, 3, 5, 7, 11, 13]);
+      },
+    );
+
+    await t.step(
+      "inserts number to the proper position of the list and returns it",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.add(6);
+        assertEquals(numbers.list, [2, 3, 5, 6, 7, 11, 13]);
+      },
+    );
+  });
+
+  await t.step("method remove()", async (t) => {
+    await t.step(
+      "removes a number from the list and returns it",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.remove(7);
+        assertEquals(numbers.list, [2, 3, 5, 11, 13]);
+      },
+    );
+
+    await t.step(
+      "does not modify list if input is not present in list and returns it",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        numbers.remove(8);
+        assertEquals(numbers.list, [2, 3, 5, 7, 11, 13]);
+      },
+    );
+  });
+
+  await t.step("method findNextLargerValue()", async (t) => {
+    await t.step(
+      "returns the next larger number found in list",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        assertEquals(numbers.findNextLargerValue(6), 7);
+      },
+    );
+
+    await t.step(
+      "returns the next larger number found in list - even if input exists",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        assertEquals(numbers.findNextLargerValue(7), 11);
+      },
+    );
+
+    await t.step(
+      "returns the first number of list if input is smaller",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        assertEquals(numbers.findNextLargerValue(-5), 2);
+      },
+    );
+
+    await t.step(
+      "returns undefined if input is larger than largest in list",
+      () => {
+        const numbers = new OrderedUniqueNumbers([2, 3, 5, 7, 11, 13]);
+        assertEquals(numbers.findNextLargerValue(15), undefined);
+      },
+    );
+  });
+});

+ 35 - 27
src/ordered-unique-numbers.class.ts

@@ -6,6 +6,20 @@ export class OrderedUniqueNumbers {
     }
     }
   }
   }
 
 
+  private get isValid(): boolean {
+    for (const [index, number] of this.numbers.entries()) {
+      if (index > 0 && number < this.numbers[index - 1]) {
+        return false;
+      }
+    }
+
+    return this.isUnique;
+  }
+
+  private sort(): number[] {
+    return this.numbers.sort((a, b) => a - b);
+  }
+
   private static filterUnique(
   private static filterUnique(
     value: number,
     value: number,
     index: number,
     index: number,
@@ -14,6 +28,17 @@ export class OrderedUniqueNumbers {
     return numbers.indexOf(value) === index;
     return numbers.indexOf(value) === index;
   }
   }
 
 
+  private get isUnique(): boolean {
+    return this.numbers.filter(OrderedUniqueNumbers.filterUnique).length ===
+      this.numbers.length;
+  }
+
+  private makeUnique(): number[] {
+    this.numbers = this.numbers.filter(OrderedUniqueNumbers.filterUnique);
+
+    return this.numbers;
+  }
+
   public get list(): number[] {
   public get list(): number[] {
     return this.numbers;
     return this.numbers;
   }
   }
@@ -27,6 +52,10 @@ export class OrderedUniqueNumbers {
   }
   }
 
 
   public add(number: number): number[] {
   public add(number: number): number[] {
+    if (this.contains(number)) {
+      return this.list;
+    }
+
     const max = this.max;
     const max = this.max;
 
 
     this.numbers.push(number);
     this.numbers.push(number);
@@ -39,32 +68,11 @@ export class OrderedUniqueNumbers {
   }
   }
 
 
   public remove(number: number): number[] {
   public remove(number: number): number[] {
-    this.numbers = this.list.filter((n) => n !== number);
-
-    return this.numbers;
-  }
-
-  public get isValid(): boolean {
-    for (const [index, number] of this.numbers.entries()) {
-      if (index > 0 && number < this.numbers[index - 1]) {
-        return false;
-      }
+    if (!this.contains(number)) {
+      return this.list;
     }
     }
 
 
-    return this.isUnique;
-  }
-
-  public sort() {
-    return this.numbers.sort((a, b) => a - b);
-  }
-
-  public get isUnique(): boolean {
-    return this.numbers.filter(OrderedUniqueNumbers.filterUnique).length ===
-      this.numbers.length;
-  }
-
-  public makeUnique(): number[] {
-    this.numbers = this.numbers.filter(OrderedUniqueNumbers.filterUnique);
+    this.numbers = this.list.filter((n) => n !== number);
 
 
     return this.numbers;
     return this.numbers;
   }
   }
@@ -73,13 +81,13 @@ export class OrderedUniqueNumbers {
     number: number,
     number: number,
     fromIndex = 0,
     fromIndex = 0,
     toIndex = this.numbers.length,
     toIndex = this.numbers.length,
-  ): number {
+  ): number | undefined {
     if (this.list.length === 0) {
     if (this.list.length === 0) {
-      throw new Error(`the list is empty! nothing to find...`);
+      return undefined;
     }
     }
 
 
     if (number > this.max) {
     if (number > this.max) {
-      throw new Error(`there is no larger value than ${number} in this list!`);
+      return undefined;
     }
     }
 
 
     if (number < this.numbers[0]) {
     if (number < this.numbers[0]) {

+ 9 - 2
src/prime.class.ts

@@ -25,8 +25,15 @@ export class Prime {
 
 
   private static next(number: number): number {
   private static next(number: number): number {
     if (number < Prime.lastKnown) {
     if (number < Prime.lastKnown) {
-      // input is not a prime number, so we have to find the next larger entry
-      return Prime.values.findNextLargerValue(number);
+      // input is not a prime number,
+      // so we have to find the next larger entry
+      const result = Prime.values.findNextLargerValue(number);
+
+      if (result === undefined) {
+        throw new Error("does not exists. should not happen!");
+      }
+
+      return result;
     }
     }
 
 
     // input is larger than last known prime number in our list
     // input is larger than last known prime number in our list