diff --git a/flake.nix b/flake.nix index 6e716581..f9c5066c 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,13 @@ systems = import inputs.systems; imports = [ ./flake/templates + ./flake/tests ./flake/apps.nix + ./flake/develop.nix ./flake/legacyPackages.nix ./flake/overlays.nix ./flake/packages.nix - ./flake/develop.nix ]; flake = { diff --git a/flake/tests/checks/nixos.nix b/flake/tests/checks/nixos.nix new file mode 100644 index 00000000..85ec8b1e --- /dev/null +++ b/flake/tests/checks/nixos.nix @@ -0,0 +1,68 @@ +{ + testers, + nixosModules, + profiles, + ... +}: +testers.runNixOSTest { + name = "nvf-nixos-test"; + nodes.machine = {pkgs, ...}: { + imports = [ + profiles.minimal + nixosModules.nvf + ]; + + programs.nvf = { + enable = true; + + settings.vim = { + viAlias = true; + vimAlias = true; + + globals = { + editorconfig = true; + }; + + extraPackages = [pkgs.lazygit]; + }; + }; + }; + + testScript = + # python + '' + machine.start() + machine.wait_for_unit("multi-user.target") + + with subtest("Verify that Neovim can be run by the test user and displays its version"): + machine.succeed("runuser -l test -c 'nvim --version'") + + with subtest("Launch Neovim and immediately quit to verify it starts correctly"): + machine.succeed("runuser -l test -c 'nvim -c q'") + + with subtest("Create a test file and open it with Neovim"): + machine.succeed("runuser -l test -c 'echo \"test content\" > /home/test/testfile.txt'") + machine.succeed("runuser -l test -c 'nvim -c \"wq\" /home/test/testfile.txt'") + + with subtest("Verify the file was edited and saved correctly"): + machine.succeed("grep 'test content' /home/test/testfile.txt") + + with subtest("Run specific Neovim commands and verify the output"): + machine.succeed("runuser -l test -c 'nvim --headless +\\\":echo \\\"hello, world!\\\"\\\" +q > /home/test/output.txt'") + machine.succeed("grep 'hello, world!' /home/test/output.txt") + + with subtest("Test nvf-print-config-path commands"): + machine.succeed("runuser -l test -c 'nvf-print-config | grep \"vim.g.editorconfig = true\"'") + machine.succeed("runuser -l test -c 'nvf-print-config-path | grep /path/to/nix/store/config'") + + with subtest("Check for errors in startup messages"): + machine.succeed("runuser -l test -c 'nvim --headless --startuptime /home/test/startup.log +q'") + machine.fail("grep -i 'error' /home/test/startup.log") + + with subtest("Verify files in Neovim PATH to test extrapackages API"): + machine.succeed("runuser -l test -c 'nvim --headless +\\\":echo $VIMRUNTIME\\\" +q | grep /nix/store/'") + + with subtest("Verify extrapackages can be executed inside Neovim"): + machine.succeed("runuser -l test -c 'nvim --headless +\\\":!lazygit --version\\\" +q'") + ''; +} diff --git a/flake/tests/default.nix b/flake/tests/default.nix new file mode 100644 index 00000000..f41d66d1 --- /dev/null +++ b/flake/tests/default.nix @@ -0,0 +1,39 @@ +{ + inputs, + config, + lib, + ... +}: { + perSystem = { + pkgs, + self', + ... + }: let + inherit (lib.filesystem) packagesFromDirectoryRecursive; + inherit (lib.customisation) callPackageWith; + inherit (lib.attrsets) recursiveUpdate; + + # Attribute set containing paths to specific profiles. This is meant to be + # an easy path to where profiles are defined as the tests directory gets + # more complicated, and allow easier renames. + profiles = { + minimal = ./profiles/minimal.nix; + }; + + # Attributes to pass to all builder packages. + defaultInherits = { + inherit inputs profiles; + inherit (config.flake) homeManagerModules nixosModules; + }; + + callPackage = callPackageWith (recursiveUpdate pkgs defaultInherits); + in { + checks = packagesFromDirectoryRecursive { + inherit callPackage; + directory = ./checks; + }; + + # Expose checks as packages to be built + packages.test = self'.checks.home-manager-test.driverInteractive; + }; +} diff --git a/flake/tests/profiles/minimal.nix b/flake/tests/profiles/minimal.nix new file mode 100644 index 00000000..930b3fb5 --- /dev/null +++ b/flake/tests/profiles/minimal.nix @@ -0,0 +1,16 @@ +# The 'minimal' test profile for nvf. This exposes the bare minimum for defining the test +# VMs. If an addition is test-specific (e.g., targeting at a specific functionality) then +# it does not belong here. However machine configuration that must be propagated to *all* +# tests should be defined here. +{ + virtualisation = { + cores = 2; + memorySize = 2048; + qemu.options = ["-vga none -enable-kvm -device virtio-gpu-pci,xres=720,yres=1440"]; + }; + + users.users.test = { + isNormalUser = true; + password = ""; + }; +}