diff --git a/default.nix b/default.nix index 997ada4..010c70b 100644 --- a/default.nix +++ b/default.nix @@ -1,4 +1,8 @@ -{ lib, pkgs }: +{ + pkgs ? import { }, + lib ? pkgs.lib, + nix-unit ? pkgs.nix-unit, +}: let luaUtils = import ./pkgs/luaUtils.nix { inherit lib pkgs; }; @@ -12,6 +16,16 @@ in { # https://github.com/NixOS/rfcs/pull/166 formatter = pkgs.nixfmt-rfc-style; + apps = { + tests = { + type = "app"; + program = + (pkgs.writeScript "nix-unit" '' + ${nix-unit}/bin/nix-unit --flake '.#tests' + '').outPath; + }; + }; + inherit legacyPackages; packages = lib.filterAttrs (name: value: lib.isDerivation value) legacyPackages; } diff --git a/flake.nix b/flake.nix index cade818..d690ab0 100644 --- a/flake.nix +++ b/flake.nix @@ -3,16 +3,28 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs"; flake-utils.url = "github:numtide/flake-utils"; + # Cannot override nixpkgs input as nix-unit fails to build with nixVersions.git + nix-unit.url = "github:nix-community/nix-unit"; }; outputs = - { self, nixpkgs, flake-utils, ... }: + { + self, + nixpkgs, + flake-utils, + nix-unit, + ... + }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = nixpkgs.legacyPackages."${system}"; lib = nixpkgs.lib; + unit = nix-unit.packages."${system}".nix-unit; in - import ./default.nix { inherit pkgs lib; } + import ./default.nix { + inherit pkgs lib; + nix-unit = unit; + } ) // ({ nixosModules = { @@ -21,5 +33,6 @@ }; homeManagerModules.nvim-lazy = import ./modules/nvim-lazy/homeManager.nix; homeManagerModule = self.homeManagerModules.nvim-lazy; + tests = import ./tests { inherit (nixpkgs) lib; }; }); } diff --git a/tests/default.nix b/tests/default.nix new file mode 100644 index 0000000..1ba31f2 --- /dev/null +++ b/tests/default.nix @@ -0,0 +1,38 @@ +{ + lib ? (import { }).lib, +}: + +let + # pkgs stub to mock calls to pkgs + pkgs = rec { + writeTextFile = + { + name, + text, + executable ? false, + destination ? "", + checkPhase ? "", + meta ? { }, + allowSubstitutes ? false, + preferLocalBuild ? true, + derivationArgs ? { }, + }@set: + set; + writeTextDir = + path: text: + writeTextFile { + inherit text; + name = builtins.baseNameOf path; + destination = "/${path}"; + }; + symlinkJoin = { name, paths }@set: set; + stylua = ""; + vimPlugins.lazy-nvim = ""; + }; + luaUtils = import ../pkgs/luaUtils.nix { inherit lib pkgs; }; + lazyUtils = import ../pkgs/lazyUtils.nix { inherit lib pkgs luaUtils; }; +in +{ + luaUtils = import ./luaUtils.nix { inherit luaUtils; }; + lazyUtils = import ./lazyUtils.nix { inherit lazyUtils; }; +} diff --git a/tests/empty.txt b/tests/empty.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/lazyUtils.nix b/tests/lazyUtils.nix new file mode 100644 index 0000000..1ca9e9f --- /dev/null +++ b/tests/lazyUtils.nix @@ -0,0 +1,68 @@ +{ lazyUtils }: + +let + nullPlugin = { + name = null; + short = null; + dir = null; + }; + miniDrv = builtins.derivation { + name = "test"; + pname = "test"; + builder = "test"; + system = "test"; + }; +in +{ + helpers = { + getName = { + testName = { + expr = lazyUtils.helpers.getName (nullPlugin // { name = "nameTest"; }); + expected = "nameTest"; + }; + testShort = { + expr = lazyUtils.helpers.getName (nullPlugin // { short = "shortTest"; }); + expected = "shortTest"; + }; + testDir = { + expr = lazyUtils.helpers.getName (nullPlugin // { dir = ./empty.txt; }); + expected = "empty.txt"; + }; + testDrv = { + expr = lazyUtils.helpers.getName (nullPlugin // { dir = miniDrv; }); + expected = "test"; + }; + testInvalidInput = { + expr = lazyUtils.helpers.getName { }; + expectedError = { + type = "ThrownError"; + # For some reason there is whitespace after the newline + msg = "Could not determine a plugin name.\n +\\{\\}"; + }; + }; + }; + getKey = { }; + pluginWrapper = { + testShort = { + expr = lazyUtils.helpers.pluginWrapper "test"; + expected = { + short = "test"; + }; + }; + testDrv = { + expr = lazyUtils.helpers.pluginWrapper miniDrv; + expected = { + dir = miniDrv; + }; + }; + testSet = { + expr = lazyUtils.helpers.pluginWrapper { }; + expected = { }; + }; + testInvalidInput = { + expr = lazyUtils.helpers.pluginWrapper null; + expectedError.type = "AssertionError"; + }; + }; + }; +} diff --git a/tests/luaUtils.nix b/tests/luaUtils.nix new file mode 100644 index 0000000..da849a6 --- /dev/null +++ b/tests/luaUtils.nix @@ -0,0 +1,181 @@ +{ luaUtils }: + +let + miniDrv = builtins.derivation { + name = "test"; + builder = "test"; + system = "test"; + }; +in +{ + nullToLua = { + testNull = { + expr = luaUtils.nullToLua null; + expected = "nil"; + }; + testInvalidInput = { + expr = luaUtils.nullToLua { }; + expectedError.type = "AssertionError"; + }; + }; + boolToLua = { + testTrue = { + expr = luaUtils.boolToLua true; + expected = "true"; + }; + testFalse = { + expr = luaUtils.boolToLua false; + expected = "false"; + }; + testInvalidInput = { + expr = luaUtils.boolToLua { }; + expectedError.type = "AssertionError"; + }; + }; + stringToLua = { + testEmptyString = { + expr = luaUtils.stringToLua ""; + expected = ''""''; + }; + testSimpleString = { + expr = luaUtils.stringToLua "test"; + expected = ''"test"''; + }; + testPath = { + expr = luaUtils.stringToLua ./empty.txt; + expected = ''"/nix/store/sfmk8wid8fzwnvzcwvw8sgblj2xz4n58-empty.txt"''; + }; + testInvalidInput = { + expr = luaUtils.stringToLua { }; + expectedError.type = "AssertionError"; + }; + }; + functionToLua = { + testEmptyString = { + expr = luaUtils.functionToLua (_: ""); + expected = ""; + }; + testSimpleString = { + expr = luaUtils.functionToLua (_: "test"); + expected = "test"; + }; + testFunctionArgs = { + expr = luaUtils.functionToLua (lua: luaUtils == lua.luaUtils); + expected = true; + }; + testInvalidInput = { + expr = luaUtils.functionToLua { }; + expectedError.type = "AssertionError"; + }; + }; + numberToLua = { + testInt = { + expr = luaUtils.numberToLua 42; + expected = "42"; + }; + testNegativeInt = { + expr = luaUtils.numberToLua (-1); + expected = "-1"; + }; + testFloat = { + expr = luaUtils.numberToLua 3.141; + expected = "3.141"; + }; + testNegativeFloat = { + expr = luaUtils.numberToLua (-3.141); + expected = "-3.141"; + }; + # Nix cannot properly represent double precision floats + # builtins.toJSON cutoff point seems to be longer than lua rounding precision + # TODO: Check for smallest unrounded 64bit float. + # (nix) builtins.toJSON 3.1415926535897932 => "3.141592653589793" + # (lua) print(3.1415926535897932) => 3.1415926535898 + # https://github.com/NixOS/nix/issues/5733 + testFloatCutoff = { + expr = luaUtils.numberToLua 3.141592653589793; + expected = "3.141592653589793"; + }; + testInvalidInput = { + expr = luaUtils.numberToLua { }; + expectedError.type = "AssertionError"; + }; + }; + listToLua = { + testEmptyList = { + expr = luaUtils.listToLua [ ]; + expected = "{}"; + }; + testEmptyUnpackedList = { + expr = luaUtils.listToLua [ "__unpack" ]; + expected = ""; + }; + }; + setToLua = { + testEmptySet = { + expr = luaUtils.setToLua { }; + expected = "{}"; + }; + testEmptyUnpackedSet = { + expr = luaUtils.setToLua { __unpack = true; }; + expected = ""; + }; + testDerivation = { + expr = luaUtils.setToLua miniDrv; + expected = ''"/nix/store/x9sny7pilv8rdsvqlkf0skfqy30xpp2l-test"''; + }; + }; + toLua = { + testNull = { + expr = luaUtils.toLua null; + expected = "nil"; + }; + testBool = { + expr = luaUtils.toLua true; + expected = "true"; + }; + testString = { + expr = luaUtils.toLua ""; + expected = ''""''; + }; + testFunction = { + expr = luaUtils.toLua (_: ""); + expected = ""; + }; + testPath = { + expr = luaUtils.toLua ./empty.txt; + expected = ''"/nix/store/sfmk8wid8fzwnvzcwvw8sgblj2xz4n58-empty.txt"''; + }; + testInt = { + expr = luaUtils.toLua 42; + expected = "42"; + }; + testFloat = { + expr = luaUtils.toLua 3.141; + expected = "3.141"; + }; + testList = { + expr = luaUtils.toLua [ ]; + expected = "{}"; + }; + testSet = { + expr = luaUtils.toLua { }; + expected = "{}"; + }; + testDerivation = { + expr = luaUtils.setToLua miniDrv; + expected = ''"/nix/store/x9sny7pilv8rdsvqlkf0skfqy30xpp2l-test"''; + }; + }; + testWriteLuaFileDir = { + expr = luaUtils.writeLuaFileDir "lua/lazyWrapper/plugins/my_plugin" "return {}"; + expected = { + name = "my_plugin"; + destination = "/lua/lazyWrapper/plugins/my_plugin.lua"; + text = "return {}"; + # TODO: Check writeText function and remove duplicate '/' either in destination or checkPhase + checkPhase = '' + /bin/stylua $out//lua/lazyWrapper/plugins/my_plugin.lua + ''; + }; + }; +}