From fd58344ca7173f7d66a19489657e1c21bb00efa9 Mon Sep 17 00:00:00 2001 From: technofab Date: Mon, 2 Jun 2025 13:34:59 +0200 Subject: [PATCH] docs: add documentation --- README.md | 21 ++++++++ docs/cli.md | 12 +++++ docs/examples.md | 4 ++ docs/images/favicon.png | Bin 0 -> 1449 bytes docs/images/logo.png | Bin 0 -> 3523 bytes docs/index.md | 10 ++++ docs/usage.md | 104 ++++++++++++++++++++++++++++++++++++ flake.lock | 46 +++++++++++++--- flake.nix | 113 +++++++++++++++++++++++++++++++++++++++- 9 files changed, 302 insertions(+), 8 deletions(-) create mode 100644 README.md create mode 100644 docs/cli.md create mode 100644 docs/examples.md create mode 100755 docs/images/favicon.png create mode 100755 docs/images/logo.png create mode 100644 docs/index.md create mode 100644 docs/usage.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..657bbed --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Nixtest + +[![built with nix](https://img.shields.io/static/v1?logo=nixos&logoColor=white&label=&message=Built%20with%20Nix&color=41439a)](https://builtwithnix.org) +[![pipeline status](https://gitlab.com/TECHNOFAB/nixtest/badges/main/pipeline.svg)](https://gitlab.com/TECHNOFAB/nixtest/-/commits/main) +![License: MIT](https://img.shields.io/gitlab/license/technofab/nix-gitlab-ci) +[![Latest Release](https://gitlab.com/TECHNOFAB/nixtest/-/badges/release.svg)](https://gitlab.com/TECHNOFAB/nixtest/-/releases) +[![Support me](https://img.shields.io/badge/Support-me-green)](https://tec.tf/#support) +[![Docs](https://img.shields.io/badge/Read-Docs-green)](https://nixtest.projects.tf) + +Flexible test runner for testing Nix code, written in Go. + +## Features + +- Snapshot, Unit (equal checks) and Script-Tests (unit tests with assertions you could say) +- Supports testing against raw Nix code or derivation output +- Simple and easy to read summary of test results +- Junit report support (eg. for displaying the results in GitLab etc.) + +## Usage + +See the [docs](https://nixtest.projects.tf/usage). diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 0000000..9c69c9c --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,12 @@ +# CLI + +```sh title="nix run .#nixtests:run -- --help" +Usage of nixtest: + --junit string Path to generate JUNIT report to, leave empty to disable + --pure Unset all env vars before running script tests + --skip string Regular expression to skip (e.g., 'test-.*|.*-b') + --snapshot-dir string Directory where snapshots are stored (default "./snapshots") + --tests string Path to JSON file containing tests + --update-snapshots Update all snapshots + --workers int Amount of tests to run in parallel (default 4) +``` diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..4e3ad41 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,4 @@ +# Example Configs + +- [TECHNOFAB/nix-gitlab-ci](https://gitlab.com/TECHNOFAB/nix-gitlab-ci) + see tests/ diff --git a/docs/images/favicon.png b/docs/images/favicon.png new file mode 100755 index 0000000000000000000000000000000000000000..4203f2a5d2e6c0ae9ef11f74519df55ae5b305e9 GIT binary patch literal 1449 zcmV;a1y=frP) zX>3$g6vuz(PU*s?wn`*mv9rFtu(F73s8SVq6f>goqd^2&07=!n9Ref*6(5 z4HT0mqUkWj1yYP{2NfbJ0#O9px|`?!(<- zn4a00JAg+44qLfX9Ab3RE|x0*K%T?f@o>Fs~4I+p^k z0{v}Wy;1$JPch*2)e3;986;wM03&QuNvO=@kK3=kX?UhFW+yN#VT&l>3Ff)C{c8dR zzDN;>$Dz6w7;e9}0$PDY_le&))S@PD-~e6Z_D7=*=TEc<*n-c zC?yH_^&oyAy&KYlfGJMJ?>`@}x%$ST-vMK7RSQZm4h~=`ml;<|6VTRe4CMRjT;~B# zDppKyKeoTM7O-qpe}pUI_S{Wg*YVp|Om4n&#dEne-qdbAAec1ZBOv5Z%0)xc$GBW( zuoy|TqE<`up|c~umlJIMwN3wNm2r#vYgYv z2TomJL*tbw6~I7SHS6udah1tD5vXoFVqecdU_?~U4pHIpI5-dk4)r<>msU3kN{It} zo2XQF_kA$Wy$5&`I26<9w68LXo=5;+EHPI1nt-CW+Aak+hq8E?cf{HA{8Jv&=#(!r zd{Y6x6C62OUUzr6YZe5;jfDs|*tzSJ34qIf4bzr^lsUi>2Y69dZQ&27 zd{*F#r@m|zm7oN|4Wkj+0i<;~%s+La6=j@V`MQvB<KQhdus?+^?>0a?I7vC^hx*3G@g-u$UhndglzC+}##$-vhFcZSM5yL#0P{p%ad zsMw=1AYN#Os%hVFJa^TnKryg5-?!zGPIuk~T;t&DfGW`5w_`CfX=rTBy3w)6o&;+C zA#rBI@!VCP0ILP&Cj?xlJkP8xtV7K!zyZtB(ok8B_PQGe!VTjP`4ZTAq~DJ-_qf)) z1x&Wh2gORCmRUPzyw$(0^2E&*^AqyCD5rh-4;p2jDybsGj7v@>DHJaRy(7QvwjBqm z8!Lc^1jg58EI5erk&^_F58P$vxyx=qOLE$m?~vrt?v(GrObF&>w|Co)QA!YgU6$wG z3vf$~_kIV7p+Lm`&)DF_Iql`W0gnMiPVl6qIOuinS4)@2*Y%UbE&Wc9e83SCsZQ{# zqBBZFT>}*s0-rm!I%>~`vlM0nGmM(e|7tAnm=Pi)1zCA!#J;(wuJ||}6BbZ>;Wx8i zuJ+&6;uzIOBWwo-0ID#vIM4llpNG&rY%1->nh z0NJ2bj-J0(kdzK0dPb#l^jlc(8vAUjod=NrB~ktc|2-VUh%R%J00000NkvXXu0mjf D^0>9~ literal 0 HcmV?d00001 diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100755 index 0000000000000000000000000000000000000000..b8ff5f84d1da75f58cdcfd3dcce417eef1dfdc71 GIT binary patch literal 3523 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 + +## Define Tests + +There are currently 3 types of tests: + +- `snapshot` -> snapshot testing, only needs `actual` and compares that to the snapshot +- `unit` -> equality checking, needs `expected` and `actual` or `actualDrv` +- `script` -> shell script test, needs `script` + +Examples: + +```nix +[ + { + name = "unit-test"; # required + type = "unit"; # default is unit + expected = 1; + actual = 1; + } + { + name = "snapshot-test"; + type = "snapshot"; + # snapshot tests use snapshot files (stored by default in ./snapshots/) + # and compare the "actual" value below with these files + actual = 1; + } + { + name = "snapshot-derivation-test"; + type = "snapshot"; + # instead of passing a nix expression, we can also use a derivation to do + # more complex stuff. Will only be built when running the test (+ included + # in the test time). + actualDrv = pkgs.runCommand "test-snapshot" {} '' + echo '"snapshot drv"' > $out + ''; + } + { + name = "script-test"; + type = "script"; + script = + # there are two modes, "default"/"impure" and "pure" + # in impure mode all env variables etc. from your current session are kept + # and are available to the test + # to make it more reproducible and cleaner, use --pure to switch to pure + # mode which will unset all env variables before running the test. That + # requires you to set PATH yourself then: + '' + export PATH="${lib.makeBinPath [pkgs.gnugrep]}" + grep -q "test" ${builtins.toFile "test" "test"} + ''; + } + { + name = "pretty-test"; + # by default it uses json to serialize and compare the values. Derivations + # and functions don't really work that way though, so you can also use + # "pretty" to use lib.generators.pretty + format = "pretty"; + # you can also set the pos here + pos = __curPos; + expected = pkgs.hello; + actual = pkgs.hello; + } +] +``` diff --git a/flake.lock b/flake.lock index f6538f2..e4cecf7 100644 --- a/flake.lock +++ b/flake.lock @@ -169,6 +169,21 @@ "type": "github" } }, + "mkdocs-material-umami": { + "locked": { + "lastModified": 1745840856, + "narHash": "sha256-1Ad1JTMQMP6YsoIKAA+SBCE15qWrYkGue9/lXOLnu9I=", + "owner": "technofab", + "repo": "mkdocs-material-umami", + "rev": "3ac9b194450f6b779c37b8d16fec640198e5cd0a", + "type": "gitlab" + }, + "original": { + "owner": "technofab", + "repo": "mkdocs-material-umami", + "type": "gitlab" + } + }, "nix": { "inputs": { "flake-compat": [ @@ -205,21 +220,38 @@ "nix-gitlab-ci": { "locked": { "dir": "lib", - "lastModified": 1746300997, - "narHash": "sha256-PuI1WaDFgvRh5d0yBAJzkbbonZaTxqWqm1hu3WP+9iU=", - "owner": "TECHNOFAB", + "lastModified": 1746973171, + "narHash": "sha256-q/LhPZlhJB2gXZ5BfgU1Wep/1x1y9Sct3/JU8A2fzjg=", + "owner": "technofab", "repo": "nix-gitlab-ci", - "rev": "9ee4ad02b8f950d48fb30ab11b8475a3f52d327c", + "rev": "dca2d724c155799e537a898cb9f948f8afae4921", "type": "gitlab" }, "original": { "dir": "lib", - "owner": "TECHNOFAB", - "ref": "2.0.0", + "owner": "technofab", + "ref": "2.0.1", "repo": "nix-gitlab-ci", "type": "gitlab" } }, + "nix-mkdocs": { + "locked": { + "dir": "lib", + "lastModified": 1745841841, + "narHash": "sha256-297zPQbUlc7ZAYDoaD6mCmQxCC3Tr4YOKekRF1ArZ7g=", + "owner": "technofab", + "repo": "nixmkdocs", + "rev": "c7e3c3b13ded25818e9789938387bba6f2cde690", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "technofab", + "repo": "nixmkdocs", + "type": "gitlab" + } + }, "nixpkgs": { "locked": { "lastModified": 1733212471, @@ -319,7 +351,9 @@ "inputs": { "devenv": "devenv", "flake-parts": "flake-parts_2", + "mkdocs-material-umami": "mkdocs-material-umami", "nix-gitlab-ci": "nix-gitlab-ci", + "nix-mkdocs": "nix-mkdocs", "nixpkgs": "nixpkgs_4", "systems": "systems", "treefmt-nix": "treefmt-nix" diff --git a/flake.nix b/flake.nix index 940057a..8f90425 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,7 @@ inputs.devenv.flakeModule inputs.treefmt-nix.flakeModule inputs.nix-gitlab-ci.flakeModule + inputs.nix-mkdocs.flakeModule ./lib/flakeModule.nix ]; systems = import systems; @@ -26,6 +27,12 @@ mdformat.enable = true; gofmt.enable = true; }; + settings.formatter.mdformat.command = let + pkg = pkgs.python3.withPackages (p: [ + p.mdformat + p.mdformat-mkdocs + ]); + in "${pkg}/bin/mdformat"; }; devenv.shells.default = { containers = pkgs.lib.mkForce {}; @@ -136,8 +143,84 @@ }; }; + doc = { + path = ./docs; + deps = pp: [ + pp.mkdocs-material + (pp.callPackage inputs.mkdocs-material-umami {}) + ]; + config = { + site_name = "Nixtest"; + repo_name = "TECHNOFAB/nixtest"; + repo_url = "https://gitlab.com/TECHNOFAB/nixtest"; + edit_uri = "edit/main/docs/"; + theme = { + name = "material"; + features = ["content.code.copy" "content.action.edit"]; + icon.repo = "simple/gitlab"; + logo = "images/logo.png"; + favicon = "images/favicon.png"; + palette = [ + { + scheme = "default"; + media = "(prefers-color-scheme: light)"; + primary = "green"; + accent = "light green"; + toggle = { + icon = "material/brightness-7"; + name = "Switch to dark mode"; + }; + } + { + scheme = "slate"; + media = "(prefers-color-scheme: dark)"; + primary = "green"; + accent = "light green"; + toggle = { + icon = "material/brightness-4"; + name = "Switch to light mode"; + }; + } + ]; + }; + plugins = ["search" "material-umami"]; + nav = [ + {"Introduction" = "index.md";} + {"Usage" = "usage.md";} + {"CLI" = "cli.md";} + {"Example Configs" = "examples.md";} + ]; + markdown_extensions = [ + "pymdownx.superfences" + ]; + extra.analytics = { + provider = "umami"; + site_id = "716d1869-9342-4b62-a770-e15d2d5c807d"; + src = "https://analytics.tf/umami"; + domains = "nixtest.projects.tf"; + feedback = { + title = "Was this page helpful?"; + ratings = [ + { + icon = "material/thumb-up-outline"; + name = "This page is helpful"; + data = "good"; + note = "Thanks for your feedback!"; + } + { + icon = "material/thumb-down-outline"; + name = "This page could be improved"; + data = "bad"; + note = "Thanks for your feedback! Please leave feedback by creating an issue :)"; + } + ]; + }; + }; + }; + }; + ci = { - stages = ["test"]; + stages = ["test" "build" "deploy"]; jobs = { "test" = { stage = "test"; @@ -150,6 +233,30 @@ reports.junit = "junit.xml"; }; }; + "docs" = { + stage = "build"; + script = [ + # sh + '' + nix build .#docs:default + mkdir -p public + cp -r result/. public/ + '' + ]; + artifacts.paths = ["public"]; + }; + "pages" = { + nix.enable = false; + image = "alpine:latest"; + stage = "deploy"; + script = ["true"]; + artifacts.paths = ["public"]; + rules = [ + { + "if" = "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"; + } + ]; + }; }; }; @@ -165,7 +272,9 @@ systems.url = "github:nix-systems/default-linux"; devenv.url = "github:cachix/devenv"; treefmt-nix.url = "github:numtide/treefmt-nix"; - nix-gitlab-ci.url = "gitlab:TECHNOFAB/nix-gitlab-ci/2.0.0?dir=lib"; + nix-gitlab-ci.url = "gitlab:technofab/nix-gitlab-ci/2.0.1?dir=lib"; + nix-mkdocs.url = "gitlab:technofab/nixmkdocs?dir=lib"; + mkdocs-material-umami.url = "gitlab:technofab/mkdocs-material-umami"; }; nixConfig = {