diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac60f01..8f0a4a2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,3 +19,5 @@ jobs: access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - name: Run tests run: nix-instantiate --eval --strict test/test.nix + - name: Test parameter parsing + run: nix-instantiate --eval --strict test/testParams.nix diff --git a/nix/parseParamsString.nix b/nix/parseParamsString.nix index 1807d55..c0277ca 100644 --- a/nix/parseParamsString.nix +++ b/nix/parseParamsString.nix @@ -1,11 +1,36 @@ with builtins; let + takeWhile = p: xs: + if length xs == 0 + then [ ] + else if p (head xs) + then [ (head xs) ] ++ takeWhile p (tail xs) + else [ ]; + + dropWhile = p: xs: + if length xs == 0 + then [ ] + else if p (head xs) + then dropWhile p (tail xs) + else xs; + + isKeyword = s: stringLength s > 0 && substring 0 1 s == ":"; + + notKeyword = s: !(isKeyword s); + + toValue = xs: + if length xs == 0 + then true + else if length xs == 1 + then head xs + else xs; + listToAttrs = xs: if length xs == 0 then { } - else if length xs == 1 - then throw "parseParamsString: Found an odd number of items: ${head xs}" - else { ${head xs} = elemAt xs 1; } // listToAttrs (tail (tail xs)); + else { + ${head xs} = toValue (takeWhile notKeyword (tail xs)); + } // listToAttrs (dropWhile notKeyword (tail xs)); stripPat = "[[:space:]]+(.*)"; @@ -20,6 +45,10 @@ let go = m: [ (elemAt m 0) ] ++ parse (elemAt m 1); + # TODO: Handle expressions + # + # This will be hard, as it requires an elisp parser. + # It is probably better to unsupport it. parse' = string: if string == "" then [ ] diff --git a/test/testParams.nix b/test/testParams.nix new file mode 100644 index 0000000..6a4e68f --- /dev/null +++ b/test/testParams.nix @@ -0,0 +1,42 @@ +# nix-instantiate --eval --strict test/testParams.nix +let + pkgs = import {}; + parse = import ../nix/parseParamsString.nix; +in +pkgs.lib.runTests { + testSimple = { + expr = parse ":tangle no"; + expected = { + ":tangle" = "no"; + }; + }; + + testOdd = { + expr = parse ":async"; + expected = { + ":async" = true; + }; + }; + + testNonAlpha = { + expr = parse ":session kernel-16577-ssh.json"; + expected = { + ":session" = "kernel-16577-ssh.json"; + }; + }; + + # This case is unsupported right now. + # + # testExpression = { + # expr = parse ":value '(this is so annoying)"; + # expected = { }; + # }; + + testDoubleQuotes = { + expr = parse ":caption \"Hello, I am Katja\""; + expected = { + ":caption" = "Hello, I am Katja"; + }; + }; + +}