use std/assert def 'http get' [--raw, --max-time: duration, url: string] { 'attempt' | save --append ($env.PUK_TEST_ROOT | path join downloads) if ($env.PUK_TEST_HTTP_FAIL? | default false | into bool) { error make { msg: 'Injected HTTP failure' } } open --raw ($env.PUK_TEST_ROOT | path join fixture.tar.gz) } alias system-which = which def which [command: string] { if $command == 'zig' and ($env.PUK_TEST_NO_ZIG? | default false | into bool) { [] } else { system-which $command } } def tree-sitter [...args: string] { if ($args | first) == 'build' { assert equal $env.CC 'zig cc' assert equal $env.CRATE_CC_NO_DEFAULTS '1' let flags = if $nu.os-info.name == 'windows' { $"-target ($nu.os-info.arch)-windows-gnu -O2" } else { '-O2' } assert equal $env.CFLAGS $flags } if ($env.PUK_TEST_BUILD_FAIL? | default false | into bool) { run-external $nu.current-exe '--no-config-file' '--commands' 'exit 9' } else { if ($args | first) == 'build' { 'new-parser' | save --force ($args | get 2) } else { assert ($args | get 1 | path exists) assert equal ($args | get 2) '--output' assert equal ($args | get 3 | path basename) src } run-external $nu.current-exe '--no-config-file' '--commands' 'exit 0' } } def ps [] { [{ name: puk-test, pid: 0 }] } def nvim [--headless, --clean, --user(-u): string, --cmd: string, --command(-c): string, ...args: string] { if $clean { run-external $nu.current-exe '--no-config-file' '--commands' '{ data: ([$env.PUK_TEST_ROOT data] | path join), cache: ([$env.PUK_TEST_ROOT cache] | path join) } | to json --raw | print' } else if ($env.PUK_TEST_REAL_NVIM? | default false | into bool) { ^nvim -u NONE -i NONE --headless -c $command ...$args } else { if $command != null and ($env.PUK_TEST_DEPENDENCY? | default null) != null { assert ($env.PUK_TEST_DEPENDENCY | path exists) } run-external $nu.current-exe '--no-config-file' '--commands' $"exit ($env.PUK_TEST_NVIM_EXIT? | default 0)" } } source ../puk.nu alias run-puk = main alias update-puk = main update hide main hide 'main update' def run-tests [] { let root = mktemp --directory --tmpdir 'puk-tests-XXXXXX' try { with-env { PUK_TEST_ROOT: $root, TMPDIR: $root, TEMP: $root, TMP: $root } { let source = [$root source package] | path join let cache = [$root cache] | path join let plugins = [$root site pack puk opt] | path join let site = [$root site] | path join mkdir ($source | path join lua) ($source | path join src) ($source | path join queries) $cache $plugins 'return true' | save ($source | path join lua fixture.lua) 'parser-source' | save ($source | path join src parser.c) 'grammar-source' | save ($source | path join grammar.js) '(node) @type' | save ($source | path join queries highlights.scm) let archive = [$root fixture.tar.gz] | path join tar --create --gzip --file $archive --directory ($source | path dirname) package let spec = { name: fixture, source: github, repo: test/fixture, commit: abc, build: null, post_install: null } let archive_path = make-archive-path $spec $cache assert equal (download-plugin $spec $cache) $archive_path assert equal (open --raw ($root | path join downloads)) 'attempt' download-plugin $spec $cache | ignore assert equal (open --raw ($root | path join downloads)) 'attempt' 'corrupt' | save --force $archive_path download-plugin $spec $cache | ignore assert equal (open --raw ($root | path join downloads)) 'attemptattempt' rm $archive_path with-env { PUK_TEST_HTTP_FAIL: true } { assert (try { download-plugin $spec $cache; false } catch { true }) } assert (not ($archive_path | path exists)) assert (glob $"($cache | str replace --all '\' '/')/puk-download.*" | is-empty) download-plugin $spec $cache | ignore assert (install-spec $spec $plugins $site $cache | is-empty) assert (plugin-is-installed $spec $plugins) assert equal (open --raw ($plugins | path join fixture lua fixture.lua)) 'return true' let hook_spec = ($spec | update name hook | update post_install ['lua print(1)']) cp $archive_path (make-archive-path $hook_spec $cache) assert (install-spec $hook_spec $plugins $site $cache | is-empty) assert (not (plugin-is-installed $hook_spec $plugins)) with-env { PUK_TEST_NVIM_EXIT: 4 } { assert equal (finish-plugin $hook_spec $plugins | length) 1 } assert (not (plugin-is-installed $hook_spec $plugins)) with-env { PUK_TEST_REAL_NVIM: true } { assert equal (finish-plugin ($hook_spec | update post_install ['lua error("injected failure")']) $plugins | length) 1 assert (not (plugin-is-installed $hook_spec $plugins)) assert (finish-plugin ($hook_spec | update post_install ['lua assert(1 + 1 == 2)']) $plugins | is-empty) } assert (plugin-is-installed $hook_spec $plugins) let build_spec = ($spec | update build 'use std/assert; assert equal ([1 2 3] | math sum) 6') let unpacked = unpack-plugin-archive $build_spec $archive_path rm --recursive $unpacked assert (try { unpack-plugin-archive ($spec | update build 'exit 3') $archive_path; false } catch { true }) let bad_archive = [$root invalid.tar.gz] | path join 'invalid' | save $bad_archive assert (try { unpack-plugin-archive $spec $bad_archive; false } catch { true }) let parser = { name: parser_fixture, source: github, repo: test/parser, commit: abc, generate: false, queries: queries, location: null } cp $archive_path (make-archive-path $parser $cache) let compiler_env_before = { cc: $env.CC?, defaults: $env.CRATE_CC_NO_DEFAULTS?, flags: $env.CFLAGS? } assert (install-spec-parser $parser $site $cache | is-empty) assert equal { cc: $env.CC?, defaults: $env.CRATE_CC_NO_DEFAULTS?, flags: $env.CFLAGS? } $compiler_env_before let parser_path = [$site parser parser_fixture.so] | path join let query_path = [$site queries parser_fixture highlights.scm] | path join let pin_path = [$site parser .parser_fixture.commit.puk] | path join assert equal (open --raw $parser_path) 'new-parser' rm $parser_path assert (install-spec-parser $parser $site $cache | is-empty) assert ($parser_path | path exists) rm $query_path assert (install-spec-parser $parser $site $cache | is-empty) assert ($query_path | path exists) 'old-parser' | save --force $parser_path 'old-query' | save --force $query_path 'old' | save --force $pin_path with-env { PUK_TEST_BUILD_FAIL: true } { assert equal (install-spec-parser $parser $site $cache | length) 1 } assert equal (open --raw $parser_path) 'old-parser' assert equal (open --raw $query_path) 'old-query' assert equal (open --raw $pin_path) 'old' assert equal (install-spec-parser ($parser | update queries missing) $site $cache | length) 1 assert equal (open --raw $parser_path) 'old-parser' assert equal (open --raw $query_path) 'old-query' assert equal (open --raw $pin_path) 'old' rm $pin_path mkdir $pin_path assert equal (install-spec-parser $parser $site $cache | length) 1 assert equal (open --raw $parser_path) 'old-parser' assert equal (open --raw $query_path) 'old-query' rm --recursive $pin_path assert (install-spec-parser $parser $site $cache | is-empty) assert equal (open --raw $parser_path) 'new-parser' assert equal (open --raw $query_path) '(node) @type' assert equal (open --raw $pin_path) 'abc' let generated = ($parser | update commit generated | update generate true) cp $archive_path (make-archive-path $generated $cache) assert (install-spec-parser $generated $site $cache | is-empty) assert equal (open --raw $pin_path) generated let project = [$root project] | path join mkdir $project let dependency = ($spec | update name dependency) let main_hook = ($hook_spec | update name main_hook) [$main_hook $dependency] | to nuon | save ($project | path join puk.plugins.nuon) [] | to nuon | save ($project | path join puk.parsers.nuon) with-env { PUK_TEST_NO_ZIG: true } { let failure = try { run-puk; null } catch { |e| $e } assert equal $failure.msg 'puk requires Zig in PATH.' let update_failure = try { update-puk; null } catch { |e| $e } assert equal $update_failure.msg 'puk requires Zig in PATH.' assert (not ($root | path join data | path exists)) } let expected = [$root data site pack puk opt dependency .commit.puk] | path join with-env { PUK_TEST_DEPENDENCY: $expected } { cd $project run-puk } assert (plugin-is-installed $main_hook ($root | path join data site pack puk opt)) assert (glob $"($root | str replace --all '\' '/')/tmp*" | is-empty) print 'puk lifecycle tests passed' } } finally { rm --recursive $root } } run-tests