about summary refs log tree commit diff
path: root/nix/yants/tests/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nix/yants/tests/default.nix')
-rw-r--r--nix/yants/tests/default.nix156
1 files changed, 156 insertions, 0 deletions
diff --git a/nix/yants/tests/default.nix b/nix/yants/tests/default.nix
new file mode 100644
index 000000000000..9a0b2403e124
--- /dev/null
+++ b/nix/yants/tests/default.nix
@@ -0,0 +1,156 @@
+{ depot, pkgs, ... }:
+
+with depot.nix.yants;
+
+# Note: Derivations are not included in the tests below as they cause
+# issues with deepSeq.
+
+let
+
+  inherit (depot.nix.runTestsuite)
+    runTestsuite
+    it
+    assertEq
+    assertThrows
+    assertDoesNotThrow
+    ;
+
+  # this derivation won't throw if evaluated with deepSeq
+  # unlike most things even remotely related with nixpkgs
+  trivialDerivation = derivation {
+    name = "trivial-derivation";
+    inherit (pkgs.stdenv) system;
+    builder = "/bin/sh";
+    args = [ "-c" "echo hello > $out" ];
+  };
+
+  testPrimitives = it "checks that all primitive types match" [
+    (assertDoesNotThrow "unit type" (unit {}))
+    (assertDoesNotThrow "int type" (int 15))
+    (assertDoesNotThrow "bool type" (bool false))
+    (assertDoesNotThrow "float type" (float 13.37))
+    (assertDoesNotThrow "string type" (string "Hello!"))
+    (assertDoesNotThrow "function type" (function (x: x * 2)))
+    (assertDoesNotThrow "path type" (path /nix))
+    (assertDoesNotThrow "derivation type" (drv trivialDerivation))
+  ];
+
+  testPoly = it "checks that polymorphic types work as intended" [
+    (assertDoesNotThrow "option type" (option int null))
+    (assertDoesNotThrow "list type" (list string [ "foo" "bar" ]))
+    (assertDoesNotThrow "either type" (either int float 42))
+  ];
+
+  # Test that structures work as planned.
+  person = struct "person" {
+    name = string;
+    age  = int;
+
+    contact = option (struct {
+      email = string;
+      phone = option string;
+    });
+  };
+
+  testStruct = it "checks that structures work as intended" [
+    (assertDoesNotThrow "person struct" (person {
+      name = "Brynhjulf";
+      age  = 42;
+      contact.email = "brynhjulf@yants.nix";
+    }))
+  ];
+
+  # Test enum definitions & matching
+  colour = enum "colour" [ "red" "blue" "green" ];
+  colourMatcher = {
+    red = "It is in fact red!";
+    blue = "It should not be blue!";
+    green = "It should not be green!";
+  };
+
+  testEnum = it "checks enum definitions and matching" [
+    (assertEq "enum is matched correctly"
+      "It is in fact red!" (colour.match "red" colourMatcher))
+    (assertThrows "out of bounds enum fails"
+      (colour.match "alpha" (colourMatcher // {
+        alpha = "This should never happen";
+      }))
+    )
+  ];
+
+  # Test sum type definitions
+  creature = sum "creature" {
+    human = struct {
+      name = string;
+      age = option int;
+    };
+
+    pet = enum "pet" [ "dog" "lizard" "cat" ];
+  };
+  some-human = creature {
+    human = {
+      name = "Brynhjulf";
+      age = 42;
+    };
+  };
+
+  testSum = it "checks sum types definitions and matching" [
+    (assertDoesNotThrow "creature sum type" some-human)
+    (assertEq "sum type is matched correctly"
+      "It's a human named Brynhjulf" (creature.match some-human {
+        human = v: "It's a human named ${v.name}";
+        pet = v: "It's not supposed to be a pet!";
+      })
+    )
+  ];
+
+  # Test curried function definitions
+  func = defun [ string int string ]
+  (name: age: "${name} is ${toString age} years old");
+
+  testFunctions = it "checks function definitions" [
+    (assertDoesNotThrow "function application" (func "Brynhjulf" 42))
+  ];
+
+  # Test that all types are types.
+  assertIsType = name: t:
+    assertDoesNotThrow "${name} is a type" (type t);
+  testTypes = it "checks that all types are types" [
+    (assertIsType "any" any)
+    (assertIsType "bool" bool)
+    (assertIsType "drv" drv)
+    (assertIsType "float" float)
+    (assertIsType "int" int)
+    (assertIsType "string" string)
+    (assertIsType "path" path)
+
+    (assertIsType "attrs int" (attrs int))
+    (assertIsType "eitherN [ ... ]" (eitherN [ int string bool ]))
+    (assertIsType "either int string" (either int string))
+    (assertIsType "enum [ ... ]" (enum [ "foo" "bar" ]))
+    (assertIsType "list string" (list string))
+    (assertIsType "option int" (option int))
+    (assertIsType "option (list string)" (option (list string)))
+    (assertIsType "struct { ... }" (struct { a = int; b = option string; }))
+    (assertIsType "sum { ... }" (sum { a = int; b = option string; }))
+  ];
+
+  testRestrict = it "checks restrict types" [
+    (assertDoesNotThrow "< 42" ((restrict "< 42" (i: i < 42) int) 25))
+    (assertDoesNotThrow "list length < 3"
+      ((restrict "not too long" (l: builtins.length l < 3) (list int)) [ 1 2 ]))
+    (assertDoesNotThrow "list eq 5"
+      (list (restrict "eq 5" (v: v == 5) any) [ 5 5 5 ]))
+  ];
+
+in
+  runTestsuite "yants" [
+    testPrimitives
+    testPoly
+    testStruct
+    testEnum
+    testSum
+    testFunctions
+    testTypes
+    testRestrict
+  ]