From dc33fdf093d112997989b5aea9c1421b1ae465ac Mon Sep 17 00:00:00 2001 From: tristan Date: Tue, 2 Jan 2024 10:53:45 +0000 Subject: [PATCH] alejandra --- flake.lock | 8 +- flake.nix | 70 +++--- nixite/default.nix | 9 +- nixite/elems.nix | 52 ++-- nixite/html.nix | 94 +++---- nixite/make-site.nix | 28 +-- nixite/md.nix | 200 +++++++-------- nixite/site.nix | 152 +++++++----- nixite/style.nix | 64 ++--- testing/elems.test.nix | 155 ++++++------ testing/html.test.nix | 253 +++++++++---------- testing/md.test.nix | 270 ++++++++++---------- testing/site.test.nix | 544 ++++++++++++++++++++--------------------- testing/style.test.nix | 106 ++++---- 14 files changed, 1029 insertions(+), 976 deletions(-) diff --git a/flake.lock b/flake.lock index 80017ca..025c5ab 100644 --- a/flake.lock +++ b/flake.lock @@ -37,11 +37,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1704187012, - "narHash": "sha256-td0PQa1cTvjurjBmLpCynAgDV425Mh8sRObRtbTGxiQ=", + "lastModified": 1704192724, + "narHash": "sha256-Cx9os5FQU4UTjxt/uE1trPHxegXyhvV/wSiIiBWTDt0=", "ref": "refs/heads/master", - "rev": "249bd9cda4fe9b02f3c85b22179109794eb57256", - "revCount": 2, + "rev": "b800bb46955d69cf7693d7c788a4d624eff2717f", + "revCount": 3, "type": "git", "url": "https://git.tristans.cloud/tristan/tix" }, diff --git a/flake.nix b/flake.nix index 3542429..d297a6f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,14 +1,19 @@ { description = "A site in nix?"; - inputs = { tix.url = "git+https://git.tristans.cloud/tristan/tix"; }; + inputs = {tix.url = "git+https://git.tristans.cloud/tristan/tix";}; - outputs = { self, nixpkgs, tix }: - let - system = "x86_64-linux"; - pkgs = import nixpkgs { inherit system; }; - nixite = import ./nixite/. { inherit pkgs; }; - in nixite // { + outputs = { + self, + nixpkgs, + tix, + }: let + system = "x86_64-linux"; + pkgs = import nixpkgs {inherit system;}; + nixite = import ./nixite/. {inherit pkgs;}; + in + nixite + // { packages.${system} = { raw = nixite.mkSite (let readme = { @@ -16,33 +21,34 @@ content = nixite.md.mdToPage ./README.md; }; markup = { - "index.html" = with nixite.elems; - let - blue = nixite.style.component span "blue" { - style = { color = "blue"; }; - }; - underblue = nixite.style.component blue "under" { - style = { text-decoration = "underline"; }; - }; - in (Doc { } [ - [ (title "Nixite") ] - (main [ - (a { href = nixite.site.link readme; } "Readme") - (a "/blog" "blog") - (List { } [ "item 1" "item 2" "item 3" ]) - (p [ - "check out my" - (blue "blue span") - "isn't it" - (underblue { onclick = "alert(1)"; } "great!") - ]) + "index.html" = with nixite.elems; let + blue = nixite.style.component span "blue" { + style = {color = "blue";}; + }; + underblue = nixite.style.component blue "under" { + style = {text-decoration = "underline";}; + }; + in (Doc {} [ + [(title "Nixite")] + (main [ + (a {href = nixite.site.link readme;} "Readme") + (a "/blog" "blog") + (List {} ["item 1" "item 2" "item 3"]) + (p [ + "check out my" + (blue "blue span") + "isn't it" + (underblue {onclick = "alert(1)";} "great!") ]) - ]); + ]) + ]); blog = nixite.md.readDir ./testing/blog; }; - site = (nixite.site.prepare { favicon = ./testing/src/favicon.png; } - markup); - in site); + site = + nixite.site.prepare {favicon = ./testing/src/favicon.png;} + markup; + in + site); default = nixite.serve self.packages.${system}.raw; @@ -54,7 +60,7 @@ ./testing/style.test.nix ]; - watch = tix.watch "nix run .#test --show-trace" "fx"; + watch = tix.watch "nix run .#test | ${pkgs.fx}/bin/fx" "fx"; dev = tix.watch "nix run .# --show-trace" "caddy"; }; diff --git a/nixite/default.nix b/nixite/default.nix index 8e75a57..3d83062 100644 --- a/nixite/default.nix +++ b/nixite/default.nix @@ -1,9 +1,8 @@ -{ pkgs, ... }: { +{pkgs, ...}: { mkSite = import ./make-site.nix pkgs; - serve = site: - (pkgs.writeShellScriptBin "serve" '' - ${pkgs.caddy}/bin/caddy file-server --root ${site} - ''); + serve = site: (pkgs.writeShellScriptBin "serve" '' + ${pkgs.caddy}/bin/caddy file-server --root ${site} + ''); md = import ./md.nix; html = import ./html.nix; elems = import ./elems.nix; diff --git a/nixite/elems.nix b/nixite/elems.nix index 7f027f0..d91994e 100644 --- a/nixite/elems.nix +++ b/nixite/elems.nix @@ -1,4 +1,5 @@ -let html = import ./html.nix; +let + html = import ./html.nix; in { html = html.tag "html"; # Document metadata @@ -41,13 +42,15 @@ in { main = html.tag "main"; div = html.tag "div"; # Text-level semantics - a = html.tag "a" // { - __functor = self: href: - (if builtins.isString href then - (self // html.baseTag) { inherit href; } - else - (self // html.baseTag) href); - }; + a = + html.tag "a" + // { + __functor = self: href: ( + if builtins.isString href + then (self // html.baseTag) {inherit href;} + else (self // html.baseTag) href + ); + }; em = html.tag "em"; strong = html.tag "strong"; small = html.tag "small"; @@ -130,24 +133,31 @@ in { canvas = html.tag "canvas"; # custom - List = html.tag "ul" // { - __functor = self: children: - (if builtins.isList children then - (self // html.baseTag) (map (html.tag "li") children) - else - html.incorporateAttrs self children); - }; + List = + html.tag "ul" + // { + __functor = self: children: ( + if builtins.isList children + then (self // html.baseTag) (map (html.tag "li") children) + else html.incorporateAttrs self children + ); + }; Doc = params: child: assert builtins.isList child; assert builtins.length child == 2; assert builtins.isList (builtins.elemAt child 0); - html.tag "html" ({ lang = "en"; } // params) [ - (html.tag "head" { } (builtins.elemAt child 0)) - (html.tag "body" { } (builtins.elemAt child 1)) - ]; + html.tag "html" ({lang = "en";} // params) [ + (html.tag "head" {} (builtins.elemAt child 0)) + (html.tag "body" {} (builtins.elemAt child 1)) + ]; Stylesheet = params: html.tag "link" ({ - rel = "stylesheet"; - } // (if builtins.isString params then { href = params; } else params)) ""; + rel = "stylesheet"; + } + // ( + if builtins.isString params + then {href = params;} + else params + )) ""; } diff --git a/nixite/html.nix b/nixite/html.nix index e940612..521a188 100644 --- a/nixite/html.nix +++ b/nixite/html.nix @@ -1,70 +1,78 @@ let keyvalue = key: value: assert builtins.isString key; - if builtins.isAttrs value then - builtins.trace "Skipping ${key} as it is a set" "" - else if value == "" || value == [ ] || value == false then - "" - else if value == true then - key - else - ''${key}="${toString value}"''; + if builtins.isAttrs value + then builtins.trace "Skipping ${key} as it is a set" "" + else if value == "" || value == [] || value == false + then "" + else if value == true + then key + else ''${key}="${toString value}"''; in rec { toHTML = elem: - if builtins.isString elem then - elem - else if builtins.isList elem then - builtins.toString (map toHTML elem) - else - "<${elem.tag} ${writeAttrs elem.attrs or { }}>${ - toHTML elem.child or "" - }"; + if builtins.isString elem + then elem + else if builtins.isList elem + then builtins.toString (map toHTML elem) + else "<${elem.tag} ${writeAttrs elem.attrs or {}}>${ + toHTML elem.child or "" + }"; writeAttrs = attrs: toString (builtins.filter (value: value != "") (builtins.attrValues (builtins.mapAttrs (key: value: - if (builtins.isPath value) then - keyvalue key (baseNameOf value) - else if (builtins.substring 0 2 key) == "__" then - "" - else - keyvalue key value) attrs))); + if (builtins.isPath value) + then keyvalue key (baseNameOf value) + else if (builtins.substring 0 2 key) == "__" + then "" + else keyvalue key value) + attrs))); - tag = t: - ({ + tag = t: ({ tag = t; - attrs = { }; - } // baseTag); + attrs = {}; + } + // baseTag); baseTag = { __toString = self: toString (self ""); - __functor = self: child: - (if !(isTag child) then - (if isSet child then - incorporateAttrs self child - else - throw "tag child must be tag, list, or string, got ${ - builtins.typeOf child - }") + __functor = self: child: ( + if !(isTag child) + then + ( + if isSet child + then incorporateAttrs self child + else + throw "tag child must be tag, list, or string, got ${ + builtins.typeOf child + }" + ) else - self // { + self + // { inherit child; __toString = toHTML; - }); + } + ); }; - incorporateAttrs = self: attrs: self // ({ attrs = self.attrs // attrs; }); + incorporateAttrs = self: attrs: self // {attrs = self.attrs // attrs;}; isSet = a: builtins.isAttrs a && !a ? __toString; - isTag = tag: - (builtins.isString tag || builtins.isList tag - || (tag ? __toString && builtins.isFunction tag.__toString)); + isTag = tag: (builtins.isString tag + || builtins.isList tag + || (tag ? __toString && builtins.isFunction tag.__toString)); addToHead = page: heads: - page // { - child = map - (e: if e.tag == "head" then e // { child = e.child ++ heads; } else e) + page + // { + child = + map + (e: + if e.tag == "head" + then e // {child = e.child ++ heads;} + else e) page.child; }; } diff --git a/nixite/make-site.nix b/nixite/make-site.nix index a202e54..9f5177d 100644 --- a/nixite/make-site.nix +++ b/nixite/make-site.nix @@ -1,16 +1,16 @@ -{ stdenv, ... }: -raw: -let site = import ./site.nix; -in stdenv.mkDerivation { - name = "site"; - src = ./.; - buildPhase = '' - mkdir dist +{stdenv, ...}: raw: let + site = import ./site.nix; +in + stdenv.mkDerivation { + name = "site"; + src = ./.; + buildPhase = '' + mkdir dist - ${site.copyTo "dist" raw} + ${site.copyTo "dist" raw} - ''; - installPhase = '' - cp -r dist $out - ''; -} + ''; + installPhase = '' + cp -r dist $out + ''; + } diff --git a/nixite/md.nix b/nixite/md.nix index 01d3380..567a467 100644 --- a/nixite/md.nix +++ b/nixite/md.nix @@ -1,57 +1,55 @@ -let elems = import ./elems.nix; +let + elems = import ./elems.nix; in rec { readMd = md: - if builtins.isPath md then - processMd (builtins.readFile md) - else - processMd md; + if builtins.isPath md + then processMd (builtins.readFile md) + else processMd md; processMd = processStr; recReadMd = root: assert builtins.isPath root; - builtins.mapAttrs (path: type: - if type == "directory" then - recReadMd (root + (/. + path)) - else if type == "regular" then - mdToPage (root + (/. + path)) - else - throw "Cannot read ${path}, file type ${type}") (builtins.readDir root); + builtins.mapAttrs (path: type: + if type == "directory" + then recReadMd (root + (/. + path)) + else if type == "regular" + then mdToPage (root + (/. + path)) + else throw "Cannot read ${path}, file type ${type}") (builtins.readDir root); recFixAppendix = site: builtins.listToAttrs (builtins.attrValues (builtins.mapAttrs (name: value: { - name = fixAppendix name; - value = if builtins.isAttrs value then recFixAppendix value else value; - }) site)); + name = fixAppendix name; + value = + if builtins.isAttrs value + then recFixAppendix value + else value; + }) + site)); - fixAppendix = builtins.replaceStrings [ ".md" ] [ ".html" ]; + fixAppendix = builtins.replaceStrings [".md"] [".html"]; readDir = root: recFixAppendix (recReadMd root); mdToPage = md: - elems.Doc { } [ [ (elems.title { } "markdown file") ] (readMd md) ]; - - code = block: - matchThen "(```)(.*)(```)" block (m: elems.code (builtins.elemAt m 1)); + elems.Doc {} [[(elems.title {} "markdown file")] (readMd md)]; list = block: - matchThen ('' - (- .+ - )*(- .+ - ?)'') block (m: elems.List (splitList block)); + matchThen "(- .+\n)*(- .+\n?)" + block (m: elems.List (splitList block)); splitList = block: - map (listItem) (builtins.filter (s: builtins.isString s && s != "") + map listItem (builtins.filter (s: builtins.isString s && s != "") (builtins.split "\n" block)); - listItem = str: - let - li = builtins.match "- (.*)" str; - checkbox = builtins.match "- \\[(.)] (.*)" str; - checked = builtins.elemAt checkbox 0; - content = builtins.elemAt checkbox 1; - in if checkbox == null then - li + listItem = str: let + li = builtins.match "- (.*)" str; + checkbox = builtins.match "- \\[(.)] (.*)" str; + checked = builtins.elemAt checkbox 0; + content = builtins.elemAt checkbox 1; + in + if checkbox == null + then li else [ (elems.input { type = "checkbox"; @@ -61,28 +59,41 @@ in rec { content ]; - replace = regex: apply: block: - (let - m = builtins.match regex block; - before = let v = builtins.elemAt m 0; in if v == null then "" else v; - after = toString (builtins.elemAt m (matchCount - 1)); - matchCount = builtins.length m; - in if m == null then - block - else - (replace regex apply before) + (apply m) + after); + replace = regex: apply: block: (let + m = builtins.match regex block; + before = let + v = builtins.elemAt m 0; + in + if v == null + then "" + else v; + after = toString (builtins.elemAt m (matchCount - 1)); + matchCount = builtins.length m; + in + if m == null + then block + else (replace regex apply before) + (apply m) + after); rule = matcher: apply: blocks: - map (b: if builtins.isString b then replace matcher apply b else b) blocks; + map (b: + if builtins.isString b + then replace matcher apply b + else b) + blocks; - applyRules = i: rules: input: - let - group = if builtins.isString input then [ input ] else input; - len = builtins.length rules; - rule = builtins.elemAt rules i; - next = i + 1; - in assert i < len; - if next < len then rule (applyRules next rules group) else rule group; + applyRules = i: rules: input: let + group = + if builtins.isString input + then [input] + else input; + len = builtins.length rules; + rule = builtins.elemAt rules i; + next = i + 1; + in + assert i < len; + if next < len + then rule (applyRules next rules group) + else rule group; basicRule = matcher: elem: rule matcher (m: elem (builtins.elemAt m 1)); @@ -96,60 +107,27 @@ in rec { (basicRule (wrap "~~") elems.del) (basicRule (wrap "\\*\\*") elems.strong) (basicRule (wrapBreak "__") elems.strong) - (rule (contains "\\[(.*)]\\((.*)\\)") (m: - let - href = builtins.elemAt m 2; - text = builtins.elemAt m 1; - in (elems.a href text))) - (rule ('' - (.* - )([^-][^ - ]+ - )((- [^ - ]+ - )+)(.*)'') ( - - l: - (elems.ul (basicRule ('' - (.* - )?- ([^ - ]+) - (.*)'') (m: - elems.li (basicRule ("()\\[(.)](.*)") (check: - elems.input { - type = "checkbox"; - checked = check != " "; - disabled = true; - }) [ m ])) [ (builtins.elemAt l 2) ])) - - )) - (basicRule ('' - (.* - - )?(.+) - (.*)?'') elems.p) - (basicRule ('' - (.* - - )?```(.*)```(.*)?'') (elems.textarea { readonly = true; })) - (basicRule (containsBreak '' - ###### ([^ - ]+)'') (elems.h6)) - (basicRule (containsBreak '' - ##### ([^ - ]+)'') (elems.h5)) - (basicRule (containsBreak '' - #### ([^ - ]+)'') (elems.h4)) - (basicRule (containsBreak '' - ### ([^ - ]+)'') (elems.h3)) - (basicRule (containsBreak '' - ## ([^ - ]+)'') (elems.h2)) - (basicRule (containsBreak '' - # ([^ - ]+)'') (elems.h1)) + (rule (contains "\\[(.*)]\\((.*)\\)") (m: let + href = builtins.elemAt m 2; + text = builtins.elemAt m 1; + in (elems.a href text))) + (rule "(.*\n)([^-][^\n]+\n)((- [^\n]+\n)+)(.*)" ( + l: (elems.ul (basicRule "(.*\n)?- ([^\n]+)\n(.*)" (m: + elems.li (basicRule "()\\[(.)](.*)" (check: + elems.input { + type = "checkbox"; + checked = check != " "; + disabled = true; + }) [m])) [(builtins.elemAt l 2)])) + )) + (basicRule "(.*\n\n)?(.+)\n(.*)?" elems.p) + (basicRule "(.*\n\n)?```(.*)```(.*)?" (elems.textarea {readonly = true;})) + (basicRule (containsBreak "###### ([^\n]+)") (elems.h6)) + (basicRule (containsBreak "##### ([^\n]+)") (elems.h5)) + (basicRule (containsBreak "#### ([^\n]+)") (elems.h4)) + (basicRule (containsBreak "### ([^\n]+)") (elems.h3)) + (basicRule (containsBreak "## ([^\n]+)") (elems.h2)) + (basicRule (containsBreak "# ([^\n]+)") (elems.h1)) (basicRule (containsBreak "<(${linkmatcher})>") (m: elems.a m m)) ]; @@ -160,10 +138,11 @@ in rec { containsBreak = matcher: "(.*[[:space:]])?${matcher}(.*)"; wrapBreak = matcher: containsBreak "${matcher}([^${matcher}]+)${matcher}"; - matchThen = matcher: block: func: - let m = builtins.match matcher block; - in if m == null then - dontMatch block + matchThen = matcher: block: func: let + m = builtins.match matcher block; + in + if m == null + then dontMatch block else { matched = true; block = func m; @@ -173,5 +152,4 @@ in rec { matched = false; inherit block; }; - } diff --git a/nixite/site.nix b/nixite/site.nix index efcf8c5..5145f51 100644 --- a/nixite/site.nix +++ b/nixite/site.nix @@ -3,13 +3,17 @@ let elems = import ./elems.nix; style = import ./style.nix; in rec { - prepare = { favicon ? null, styles ? { }, }: - site: - let - nullFn = p: p; - allStyles = styles // getStyles site; - doFavicon = if favicon != null then (applyFavicon favicon) else nullFn; - in (extractPaths (extractLinks (applyStyle allStyles (doFavicon site)))); + prepare = { + favicon ? null, + styles ? {}, + }: site: let + nullFn = p: p; + allStyles = styles // getStyles site; + doFavicon = + if favicon != null + then (applyFavicon favicon) + else nullFn; + in (extractPaths (extractLinks (applyStyle allStyles (doFavicon site)))); getStyles = site: builtins.zipAttrsWith (name: value: builtins.elemAt value 0) @@ -17,27 +21,25 @@ in rec { flatten = site: map (page: - if builtins.isAttrs page && page ? "__toString" then - page - else if builtins.isAttrs page then - flatten page - else - page) (builtins.attrValues site); + if builtins.isAttrs page && page ? "__toString" + then page + else if builtins.isAttrs page + then flatten page + else page) (builtins.attrValues site); - applyStyle = style: site: ((linkStyle site) // { "style.css" = style; }); + applyStyle = style: site: ((linkStyle site) // {"style.css" = style;}); linkStyle = site: eachPage site - (content: html.addToHead content [ (elems.Stylesheet "/style.css") ]); + (content: html.addToHead content [(elems.Stylesheet "/style.css")]); - eachPage = site: callback: - (builtins.mapAttrs (name: content: - if builtins.isAttrs content && content ? "__toString" then - callback content - else if builtins.isAttrs content then - eachPage content callback - else - content) site); + eachPage = site: callback: (builtins.mapAttrs (name: content: + if builtins.isAttrs content && content ? "__toString" + then callback content + else if builtins.isAttrs content + then eachPage content callback + else content) + site); applyFavicon = icon: site: eachPage site (content: @@ -49,19 +51,21 @@ in rec { ]); extractPaths = content: - switchPaths content // { - static = (content.static or { }) // getPaths content; + switchPaths content + // { + static = (content.static or {}) // getPaths content; }; extractLinks = content: - switchLinks content // { - static = (content.static or { }) // getLinks content; + switchLinks content + // { + static = (content.static or {}) // getLinks content; }; isLink = value: builtins.isAttrs value && value ? type && value.type == "link"; - switchLinks = runDeep (isLink) (value: "/static/" + value.name); + switchLinks = runDeep isLink (value: "/static/" + value.name); getLinks = content: (builtins.listToAttrs (getLinksKV content)); @@ -72,19 +76,30 @@ in rec { }; runLink = f: - if !builtins.isFunction f then - null + if !builtins.isFunction f + then null else - (let res = f { }; in (if !builtins.isAttrs res then null else res)); + (let + res = f {}; + in ( + if !builtins.isAttrs res + then null + else res + )); - runDeep = when: do: set: - (if builtins.isAttrs set then + runDeep = when: do: set: ( + if builtins.isAttrs set + then builtins.mapAttrs - (key: value: if when value then do value else runDeep when do value) set - else if builtins.isList set then - (map (runDeep when do) set) - else - set); + (key: value: + if when value + then do value + else runDeep when do value) + set + else if builtins.isList set + then (map (runDeep when do) set) + else set + ); switchPaths = runDeep builtins.isPath (value: "/static/" + baseNameOf value); @@ -96,35 +111,60 @@ in rec { value = v: v; }; - getAllKV = { when, key, value }@params: - path: - (if when path then [{ - name = key path; - value = value path; - }] else if builtins.isAttrs path then + getAllKV = { + when, + key, + value, + } @ params: path: ( + if when path + then [ + { + name = key path; + value = value path; + } + ] + else if builtins.isAttrs path + then builtins.concatMap (getAllKV params) (builtins.attrValues (builtins.mapAttrs - (n: v: if (builtins.substring 0 2 n == "__") then null else v) path)) - else if builtins.isList path then - builtins.concatMap (getAllKV params) path - else - [ ]); + (n: v: + if (builtins.substring 0 2 n == "__") + then null + else v) + path)) + else if builtins.isList path + then builtins.concatMap (getAllKV params) path + else [] + ); - link = { name, content }@page: page // { type = "link"; }; + link = { + name, + content, + } @ page: + page // {type = "link";}; copyTo = prefix: site: builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content: - if builtins.isString content then '' + if builtins.isString content + then '' cp ${builtins.toFile name content} ${prefix}/${name} - '' else if builtins.isPath content then '' + '' + else if builtins.isPath content + then '' cp -r ${content} ${prefix}/${name} - '' else if builtins.isAttrs content && content ? "__toString" then '' + '' + else if builtins.isAttrs content && content ? "__toString" + then '' cp ${builtins.toFile name (toString content)} ${prefix}/${name} - '' else if builtins.isAttrs content then '' + '' + else if builtins.isAttrs content + then '' mkdir -p ${prefix}/${name} ${copyTo "${prefix}/${name}" content} - '' else + '' + else throw "Site page must be string, path or attrset, but got ${ builtins.typeOf content - }: [${toString content}]") site)); + }: [${toString content}]") + site)); } diff --git a/nixite/style.nix b/nixite/style.nix index b453b93..c488230 100644 --- a/nixite/style.nix +++ b/nixite/style.nix @@ -1,57 +1,63 @@ let - styleToString = identifier: styles: - if !builtins.isAttrs styles then - "" - else if styles == { } then - "" + if !builtins.isAttrs styles + then "" + else if styles == {} + then "" else assert builtins.isString identifier; '' ${identifier} { ${ - toString (builtins.attrValues - (builtins.mapAttrs (key: value: "${key}: ${value};") styles)) - } + toString (builtins.attrValues + (builtins.mapAttrs (key: value: "${key}: ${value};") styles)) + } } ''; getStyle = element: - if builtins.isAttrs element && element.attrs ? __id then + if builtins.isAttrs element && element.attrs ? __id + then ({ - ${element.attrs.__id} = element.attrs.style or { }; - } // (if element.attrs ? __extends then { - ${element.attrs.__extends.attrs.__id or element.attrs.__extends.tag} = - element.attrs.__extends.attrs.style or { }; - } else - { })) - else - { }; + ${element.attrs.__id} = element.attrs.style or {}; + } + // ( + if element.attrs ? __extends + then { + ${element.attrs.__extends.attrs.__id or element.attrs.__extends.tag} = + element.attrs.__extends.attrs.style or {}; + } + else {} + )) + else {}; getStyles = element: - (getStyle element) // (if builtins.isList element then - getStylesFromList element - else if element ? child then - getStyles element.child - else - { }) // { - __toString = stylesToString; - }; + (getStyle element) + // ( + if builtins.isList element + then getStylesFromList element + else if element ? child + then getStyles element.child + else {} + ) + // { + __toString = stylesToString; + }; getStylesFromList = elements: builtins.zipAttrsWith (name: value: builtins.elemAt value 0) (map getStyles elements); mkProps = tag: class: props: - props // { + props + // { __id = "${tag.tag}.${class}"; __extends = tag; - class = (tag.attrs.class or [ ]) ++ [ class ] ++ (props.class or [ ]); + class = (tag.attrs.class or []) ++ [class] ++ (props.class or []); }; stylesToString = styles: builtins.concatStringsSep "" - (builtins.attrValues (builtins.mapAttrs (styleToString) styles)); - + (builtins.attrValues (builtins.mapAttrs styleToString styles)); in { inherit getStyle getStyles stylesToString; diff --git a/testing/elems.test.nix b/testing/elems.test.nix index 897bc53..c93d872 100644 --- a/testing/elems.test.nix +++ b/testing/elems.test.nix @@ -1,83 +1,86 @@ -{ it, ... }: -let +{it, ...}: let elems = import ../nixite/elems.nix; style = import ../nixite/style.nix; html = import ../nixite/html.nix; -in with elems; [ - (it "makes a p tag" { - expected = html.tag "p" { } "foobar"; - actual = p { } "foobar"; - asString = true; - }) - (it "makes a div tag" { - expected = html.tag "div" { } "foobar"; - actual = div { } "foobar"; - asString = true; - }) - (it "makes a section tag" { - expected = html.tag "section" { } "foobar"; - actual = section { } "foobar"; - asString = true; - }) - (it "makes a span tag" { - expected = html.tag "span" { } "foobar"; - actual = span { } "foobar"; - asString = true; - }) - (it "makes a main tag" { - expected = html.tag "main" { } [ "yeet" ]; - actual = main { } [ "yeet" ]; - asString = true; - }) - (it "makes a title tag" { - expected = html.tag "title" { } "foobar"; - actual = title { } "foobar"; - asString = true; - }) +in + with elems; [ + (it "makes a p tag" { + expected = html.tag "p" {} "foobar"; + actual = p {} "foobar"; + asString = true; + }) + (it "makes a div tag" { + expected = html.tag "div" {} "foobar"; + actual = div {} "foobar"; + asString = true; + }) + (it "makes a section tag" { + expected = html.tag "section" {} "foobar"; + actual = section {} "foobar"; + asString = true; + }) + (it "makes a span tag" { + expected = html.tag "span" {} "foobar"; + actual = span {} "foobar"; + asString = true; + }) + (it "makes a main tag" { + expected = html.tag "main" {} ["yeet"]; + actual = main {} ["yeet"]; + asString = true; + }) + (it "makes a title tag" { + expected = html.tag "title" {} "foobar"; + actual = title {} "foobar"; + asString = true; + }) - (it "makes an a tag" { - expected = html.tag "a" { href = "https://example.com"; } "example"; - actual = a { href = "https://example.com"; } "example"; - asString = true; - }) + (it "makes an a tag" { + expected = html.tag "a" {href = "https://example.com";} "example"; + actual = a {href = "https://example.com";} "example"; + asString = true; + }) - (it "lets the a tag drop the props" { - expected = html.tag "a" { href = "https://example.com"; } "example"; - actual = a "https://example.com" "example"; - asString = true; - }) + (it "lets the a tag drop the props" { + expected = html.tag "a" {href = "https://example.com";} "example"; + actual = a "https://example.com" "example"; + asString = true; + }) - (it "lets you extend the a tag" { - expected = [ "linky" ]; - actual = ((style.component a "linky" { }) "https://example.com" - "example").attrs.class; - asString = true; - }) + (it "lets you extend the a tag" { + expected = ["linky"]; + actual = + ((style.component a "linky" {}) "https://example.com" + "example") + .attrs + .class; + asString = true; + }) - (it "makes a stylesheet link" { - expected = html.tag "link" { - href = "/style"; - rel = "stylesheet"; - } ""; - actual = Stylesheet { href = "/style"; }; - asString = true; - }) - (it "makes a list" { - expected = html.tag "ul" { __ = ""; } [ - (html.tag "li" { } "foo") - (html.tag "li" { } "bar") - (html.tag "li" { } "baz") - ]; - actual = List { } [ "foo" "bar" "baz" ]; - asString = true; - }) - (it "makes an html doc" { - expected = html.tag "html" { - __child = ""; - class = [ ]; - lang = "en"; - } [ (html.tag "head" { } [ "foo" ]) (html.tag "body" { } "bar") ]; - actual = Doc { } [ [ "foo" ] "bar" ]; - asString = true; - }) -] + (it "makes a stylesheet link" { + expected = html.tag "link" { + href = "/style"; + rel = "stylesheet"; + } ""; + actual = Stylesheet {href = "/style";}; + asString = true; + }) + (it "makes a list" { + expected = html.tag "ul" {__ = "";} [ + (html.tag "li" {} "foo") + (html.tag "li" {} "bar") + (html.tag "li" {} "baz") + ]; + actual = List {} ["foo" "bar" "baz"]; + asString = true; + }) + (it "makes an html doc" { + expected = html.tag "html" { + __child = ""; + class = []; + lang = "en"; + } [(html.tag "head" {} ["foo"]) (html.tag "body" {} "bar")]; + actual = Doc {} [["foo"] "bar"]; + asString = true; + }) + ] diff --git a/testing/html.test.nix b/testing/html.test.nix index 96c3871..5531a95 100644 --- a/testing/html.test.nix +++ b/testing/html.test.nix @@ -1,142 +1,149 @@ -{ it, ... }: -let html = import ../nixite/html.nix; -in with html; [ +{it, ...}: let + html = import ../nixite/html.nix; +in + with html; [ + (it "keeps info in the tag" (let + p = tag "p"; + in { + actual = p.tag; + expected = "p"; + })) - (it "keeps info in the tag" (let p = tag "p"; - in { - actual = p.tag; - expected = "p"; - })) + (it "keeps attr info in the tag" (let + p = tag "p" {class = "";}; + in { + actual = p.attrs; + expected = {class = "";}; + })) - (it "keeps attr info in the tag" (let p = tag "p" { class = ""; }; - in { - actual = p.attrs; - expected = { class = ""; }; - })) + (it "keeps tag after setting attrs" (let + p = tag "p" {class = "";}; + in { + actual = p.tag; + expected = "p"; + })) - (it "keeps tag after setting attrs" (let p = tag "p" { class = ""; }; - in { - actual = p.tag; - expected = "p"; - })) + (it "makes a p tag" { + actual = tag "p" {} "Hello"; + expected = { + tag = "p"; + attrs = {}; + child = "Hello"; + }; + removeDunders = true; + }) - (it "makes a p tag" { - actual = tag "p" { } "Hello"; - expected = { - tag = "p"; - attrs = { }; - child = "Hello"; - }; - removeDunders = true; - }) + (it "makes element" (let + para = tag "p" {}; + in { + expected = "p"; + actual = para.tag; + })) - (it "makes element" (let para = (tag "p" { }); - in { - expected = "p"; - actual = para.tag; - })) + (it "keeps attrs on element" (let + attrs = {style = {foo = "bar";};}; + para = tag "p" attrs; + in { + expected = attrs; + actual = para.attrs; + })) - (it "keeps attrs on element" (let - attrs = { style = { foo = "bar"; }; }; - para = (tag "p" attrs); - in { - expected = attrs; - actual = para.attrs; - })) + (it "makes renderable element" (let + attrs = {style = {foo = "bar";};}; + para = tag "p" attrs; + in { + expected = "

"; + actual = toString (para ""); + })) - (it "makes renderable element" (let - attrs = { style = { foo = "bar"; }; }; - para = (tag "p" attrs); - in { - expected = "

"; - actual = toString (para ""); - })) + (it "keeps tag" (let + attrs = {style = {foo = "bar";};}; + para = tag "p" attrs; + in { + expected = "p"; + actual = (para "").tag; + })) - (it "keeps tag" (let - attrs = { style = { foo = "bar"; }; }; - para = (tag "p" attrs); - in { - expected = "p"; - actual = (para "").tag; - })) + (it "keeps style" (let + attrs = {style = {foo = "bar";};}; + para = tag "p" attrs; + in { + expected = {foo = "bar";}; + actual = (para "").attrs.style; + })) - (it "keeps style" (let - attrs = { style = { foo = "bar"; }; }; - para = (tag "p" attrs); - in { - expected = { foo = "bar"; }; - actual = (para "").attrs.style; - })) + (it "needs no args to make string" (let + p = tag "p"; + in { + actual = toString p; + expected = "

"; + })) - (it "needs no args to make string" (let p = tag "p"; - in { - actual = toString p; - expected = "

"; - })) + (it "needs no content to make string" (let + p = tag "p"; + in { + actual = toString (p {class = "foobar";}); + expected = ''

''; + })) - (it "needs no content to make string" (let p = tag "p"; - in { - actual = toString (p { class = "foobar"; }); - expected = ''

''; - })) + (it "can take many sets of props" (let + p = tag "p"; + in { + actual = toString (p {class = "foobar";} {style = "a style";}); + expected = ''

''; + })) - (it "can take many sets of props" (let p = tag "p"; - in { - actual = toString (p { class = "foobar"; } { style = "a style"; }); - expected = ''

''; - })) + (it "works recursively" (let + attrs = {style = {foo = "bar";};}; + para = tag "p" attrs; + a = tag "a" {}; + in { + expected = "

hello

"; + actual = toString (para (a "hello")); + })) - (it "works recursively" (let - attrs = { style = { foo = "bar"; }; }; - para = (tag "p" attrs); - a = (tag "a" { }); - in { - expected = "

hello

"; - actual = toString (para (a "hello")); - })) + (it "throws with function child" { + actual = toString (tag "p" (i: "")); + throws = true; + }) - (it "throws with function child" ({ - actual = toString (tag "p" (i: "")); - throws = true; - })) + (it "throws with a number" { + actual = toString (tag "p" 5); + throws = true; + }) - (it "throws with a number" ({ - actual = toString (tag "p" 5); - throws = true; - })) + (it "throws with a bool" { + actual = toString (tag "p" true); + throws = true; + }) - (it "throws with a bool" ({ - actual = toString (tag "p" true); - throws = true; - })) + (it "throws with a null" { + actual = toString (tag "p" null); + throws = true; + }) - (it "throws with a null" ({ - actual = toString (tag "p" null); - throws = true; - })) + (it "concatinates classes" { + actual = toString (tag "p" {class = ["class1" "class2"];} "Hello"); + expected = ''

Hello

''; + }) - (it "concatinates classes" { - actual = toString (tag "p" { class = [ "class1" "class2" ]; } "Hello"); - expected = ''

Hello

''; - }) + (it "applies style" (let + page = tag "html" {} [(tag "head" {} ["foo"])]; + in { + actual = addToHead page ["bar"]; + expected = { + tag = "html"; + attrs = {}; + child = [(tag "head" {} ["foo" "bar"])]; + }; + removeDunders = true; + })) - (it "applies style" (let page = tag "html" { } [ (tag "head" { } [ "foo" ]) ]; - in { - actual = addToHead page [ "bar" ]; - expected = { - tag = "html"; - attrs = { }; - child = [ (tag "head" { } [ "foo" "bar" ]) ]; - }; - removeDunders = true; - })) - - (it "renders on / off attrs" ({ - actual = toString (tag "p" { - on = true; - off = false; - }); - expected = "

"; - })) - -] + (it "renders on / off attrs" { + actual = toString (tag "p" { + on = true; + off = false; + }); + expected = "

"; + }) + ] diff --git a/testing/md.test.nix b/testing/md.test.nix index 4a8d216..3e9c624 100644 --- a/testing/md.test.nix +++ b/testing/md.test.nix @@ -1,148 +1,148 @@ -{ it, ... }: -let +{it, ...}: let md = import ../nixite/md.nix; elems = import ../nixite/elems.nix; -in with md; [ +in + with md; [ + (it "matches a list of one element" { + actual = list '' + - something + ''; + expected = { + matched = true; + block = elems.List ["something"]; + }; + asJSON = true; + }) - (it "matches a list of one element" ({ - actual = list '' - - something - ''; - expected = { - matched = true; - block = elems.List [ "something" ]; - }; - asJSON = true; - })) + (it "makes a list of many elements" { + actual = list '' + - something + - something else + ''; + expected = { + matched = true; + block = elems.List ["something" "something else"]; + }; + asJSON = true; + }) - (it "makes a list of many elements" ({ - actual = list '' - - something - - something else - ''; - expected = { - matched = true; - block = elems.List [ "something" "something else" ]; - }; - asJSON = true; - })) + (it "makes a list of many checkboxes" { + actual = list '' + - [ ] something + - [X] something else + ''; + expected = { + matched = true; + block = elems.List [ + [ + (elems.input { + type = "checkbox"; + disabled = true; + checked = false; + } "") + "something" + ] + [ + (elems.input { + type = "checkbox"; + disabled = true; + checked = true; + } "") + "something else" + ] + ]; + }; + asJSON = true; + }) - (it "makes a list of many checkboxes" ({ - actual = list '' - - [ ] something - - [X] something else - ''; - expected = { - matched = true; - block = elems.List [ - [ - (elems.input { - type = "checkbox"; - disabled = true; - checked = false; - } "") - "something" - ] - [ - (elems.input { - type = "checkbox"; - disabled = true; - checked = true; - } "") - "something else" - ] + (it "matches a list with no whitespace around" { + actual = list '' + - something + - something else''; + expected = { + matched = true; + block = elems.List ["something" "something else"]; + }; + asJSON = true; + }) + + (it "doesnt match not a list" (let + str = "blah blah"; + in { + actual = list str; + expected = { + matched = false; + block = str; + }; + })) + + (it "processes whole string with all rules" { + actual = processStr '' + this text **may** *or may not* contain **bold** words *inside* it. + ''; + expected = elems.p [ + "this text" + (elems.strong "may") + (elems.em "or may not") + "contain" + (elems.strong "bold") + "words" + (elems.em "inside") + "it." ]; - }; - asJSON = true; - })) + asString = true; + }) - (it "matches a list with no whitespace around" ({ - actual = list '' - - something - - something else''; - expected = { - matched = true; - block = elems.List [ "something" "something else" ]; - }; - asJSON = true; - })) + (it "makes paragraphs" { + actual = readMd '' + lorem ipsum + dolor sit - (it "doesnt match not a list" (let str = "blah blah"; - in { - actual = list str; - expected = { - matched = false; - block = str; - }; - })) + foo bar + ''; + expected = '' +

lorem ipsum + dolor sit +

foo bar

''; + asString = true; + }) - (it "processes whole string with all rules" ({ - actual = processStr '' - this text **may** *or may not* contain **bold** words *inside* it. - ''; - expected = (elems.p [ - "this text" - (elems.strong "may") - (elems.em "or may not") - "contain" - (elems.strong "bold") - "words" - (elems.em "inside") - "it." - ]); - asString = true; - })) + (it "can fix file appendixes" { + actual = fixAppendix "index.md"; + expected = "index.html"; + }) - (it "makes paragraphs" { - actual = readMd '' - lorem ipsum - dolor sit + (it "converts markdown to a page" { + actual = toString (mdToPage ./blog/index.md) + "\n"; + expected = builtins.readFile ./out/index.html; + asString = true; + }) - foo bar - ''; - expected = '' -

lorem ipsum - dolor sit -

foo bar

''; - asString = true; - }) + (it "recursively reads dir" { + actual = recReadMd ./blog; + expected = { + "index.md" = mdToPage ./blog/index.md; + "dir" = {"index.md" = mdToPage ./blog/dir/index.md;}; + }; + asJSON = true; + }) - (it "can fix file appendixes" { - actual = fixAppendix "index.md"; - expected = "index.html"; - }) + (it "recursively fixes filename" { + actual = recFixAppendix { + "index.md" = "something"; + dir = {"index.md" = "something else";}; + }; + expected = { + "index.html" = "something"; + dir = {"index.html" = "something else";}; + }; + }) - (it "converts markdown to a page" { - actual = toString (mdToPage ./blog/index.md) + "\n"; - expected = builtins.readFile ./out/index.html; - asString = true; - }) - - (it "recursively reads dir" { - actual = recReadMd ./blog; - expected = { - "index.md" = mdToPage ./blog/index.md; - "dir" = { "index.md" = mdToPage ./blog/dir/index.md; }; - }; - asJSON = true; - }) - - (it "recursively fixes filename" { - actual = recFixAppendix { - "index.md" = "something"; - dir = { "index.md" = "something else"; }; - }; - expected = { - "index.html" = "something"; - dir = { "index.html" = "something else"; }; - }; - }) - - (it "recursively translates md to html" { - actual = builtins.toJSON (readDir ./blog); - expected = builtins.toJSON { - "index.html" = mdToPage ./blog/index.md; - "dir" = { "index.html" = mdToPage ./blog/dir/index.md; }; - }; - }) -] + (it "recursively translates md to html" { + actual = builtins.toJSON (readDir ./blog); + expected = builtins.toJSON { + "index.html" = mdToPage ./blog/index.md; + "dir" = {"index.html" = mdToPage ./blog/dir/index.md;}; + }; + }) + ] diff --git a/testing/site.test.nix b/testing/site.test.nix index 8e1e893..a3ce367 100644 --- a/testing/site.test.nix +++ b/testing/site.test.nix @@ -1,315 +1,313 @@ -{ it, ... }: -let +{it, ...}: let html = import ../nixite/html.nix; elems = import ../nixite/elems.nix; site = import ../nixite/site.nix; style = import ../nixite/style.nix; -in with site; [ - (it "applies a style" { - expected = { - "index.html" = html.tag "html" { } [ - (html.tag "head" { } [ - (elems.title { } "foobar") - (elems.Stylesheet "/style.css") - ]) - (elems.main { } "something") - ]; - blog = { - "index.html" = html.tag "html" { } [ - (html.tag "head" { } [ - (elems.title { } "foobar") +in + with site; [ + (it "applies a style" { + expected = { + "index.html" = html.tag "html" {} [ + (html.tag "head" {} [ + (elems.title {} "foobar") (elems.Stylesheet "/style.css") ]) - (elems.main { } "blogy blog") + (elems.main {} "something") ]; + blog = { + "index.html" = html.tag "html" {} [ + (html.tag "head" {} [ + (elems.title {} "foobar") + (elems.Stylesheet "/style.css") + ]) + (elems.main {} "blogy blog") + ]; + }; + "style.css" = '' + this is a stylesheet + ''; }; - "style.css" = '' - this is a stylesheet - ''; - }; - actual = applyStyle '' - this is a stylesheet - '' { - "index.html" = html.tag "html" { } [ - (html.tag "head" { } [ (elems.title { } "foobar") ]) - (elems.main { } "something") - ]; - blog = { - "index.html" = html.tag "html" { } [ - (html.tag "head" { } [ (elems.title { } "foobar") ]) - (elems.main { } "blogy blog") - ]; - }; - }; - asJSON = true; - }) + actual = + applyStyle '' + this is a stylesheet + '' { + "index.html" = html.tag "html" {} [ + (html.tag "head" {} [(elems.title {} "foobar")]) + (elems.main {} "something") + ]; + blog = { + "index.html" = html.tag "html" {} [ + (html.tag "head" {} [(elems.title {} "foobar")]) + (elems.main {} "blogy blog") + ]; + }; + }; + asJSON = true; + }) - (it "applies a favicon" { - expected = { - "index.html" = elems.html { } [ - (elems.head { } [ - (elems.title { } "foobar") - (elems.link { - rel = "shortcut icon"; - href = ./src/favicon.png; - }) - ]) - (elems.main { } "something") - ]; - blog = { - "index.html" = elems.html { } [ - (elems.head { } [ - (elems.title { } "foobar") + (it "applies a favicon" { + expected = { + "index.html" = elems.html {} [ + (elems.head {} [ + (elems.title {} "foobar") (elems.link { rel = "shortcut icon"; href = ./src/favicon.png; }) ]) - (elems.main { } "something") + (elems.main {} "something") ]; + blog = { + "index.html" = elems.html {} [ + (elems.head {} [ + (elems.title {} "foobar") + (elems.link { + rel = "shortcut icon"; + href = ./src/favicon.png; + }) + ]) + (elems.main {} "something") + ]; + }; }; - }; - actual = applyFavicon ./src/favicon.png { - "index.html" = elems.html { } [ - (elems.head { } [ (elems.title { } "foobar") ]) - (elems.main { } "something") - ]; - blog = { - "index.html" = elems.html { } [ - (elems.head { } [ (elems.title { } "foobar") ]) - (elems.main { } "something") + actual = applyFavicon ./src/favicon.png { + "index.html" = elems.html {} [ + (elems.head {} [(elems.title {} "foobar")]) + (elems.main {} "something") ]; + blog = { + "index.html" = elems.html {} [ + (elems.head {} [(elems.title {} "foobar")]) + (elems.main {} "something") + ]; + }; }; - }; - asJSON = true; - }) + asJSON = true; + }) - (it "gets all styles" { - expected = { - "p" = { }; - "div" = { }; - "p.class" = { color = "blue"; }; - "div.class2" = { color = "green"; }; - }; - actual = getStyles (let - p = style.component elems.p "class" { style = { color = "blue"; }; }; - g = style.component elems.div "class2" { style = { color = "green"; }; }; + (it "gets all styles" { + expected = { + "p" = {}; + "div" = {}; + "p.class" = {color = "blue";}; + "div.class2" = {color = "green";}; + }; + actual = getStyles (let + p = style.component elems.p "class" {style = {color = "blue";};}; + g = style.component elems.div "class2" {style = {color = "green";};}; + in { + "index.html" = p ""; + blog = {"index.html" = g "";}; + }); + removeDunders = true; + }) + + (it "gets top level paths" { + actual = getPaths { + something = ""; + src = ./src/index.md; + }; + expected = {"index.md" = ./src/index.md;}; + }) + (it "gets lower level paths" { + actual = getPaths { + something = "yes"; + a-list = [ + {thingy = ./src/index.md;} + [(html.tag "img" {src = ./src/favicon.png;} "")] + ]; + }; + expected = { + "index.md" = ./src/index.md; + "favicon.png" = ./src/favicon.png; + }; + }) + + (it "switches paths" { + actual = switchPaths { + something = ""; + a-thing = {src = ./src/index.md;}; + a-list = [{thingy = ./src/index.md;}]; + }; + expected = { + something = ""; + a-thing = {src = "/static/index.md";}; + a-list = [{thingy = "/static/index.md";}]; + }; + }) + + (it "extracts paths" { + actual = extractPaths { + something = ""; + a-thing = {src = ./src/index.md;}; + a-list = [{thingy = ./src/index.md;}]; + }; + expected = { + something = ""; + a-thing = {src = "/static/index.md";}; + a-list = [{thingy = "/static/index.md";}]; + static = {"index.md" = ./src/index.md;}; + }; + }) + + (it "switches links" (let + coolPage = { + type = "link"; + name = "cool-page"; + content = ""; + }; in { - "index.html" = p ""; - blog = { "index.html" = g ""; }; - }); - removeDunders = true; - }) + actual = switchLinks { + something = ""; + a-thing = {src = coolPage;}; + a-list = [{thingy = coolPage;}]; + }; + expected = { + something = ""; + a-thing = {src = "/static/cool-page";}; + a-list = [{thingy = "/static/cool-page";}]; + }; + })) - (it "gets top level paths" { - actual = getPaths { - something = ""; - src = ./src/index.md; - }; - expected = { "index.md" = ./src/index.md; }; - }) - (it "gets lower level paths" { - actual = getPaths { - something = "yes"; - a-list = [ - { thingy = ./src/index.md; } - [ (html.tag "img" { src = ./src/favicon.png; } "") ] - ]; - }; - expected = { - "index.md" = ./src/index.md; - "favicon.png" = ./src/favicon.png; - }; - }) - - (it "switches paths" { - actual = switchPaths { - something = ""; - a-thing = { src = ./src/index.md; }; - a-list = [{ thingy = ./src/index.md; }]; - }; - expected = { - something = ""; - a-thing = { src = "/static/index.md"; }; - a-list = [{ thingy = "/static/index.md"; }]; - }; - }) - - (it "extracts paths" { - actual = extractPaths { - something = ""; - a-thing = { src = ./src/index.md; }; - a-list = [{ thingy = ./src/index.md; }]; - }; - expected = { - something = ""; - a-thing = { src = "/static/index.md"; }; - a-list = [{ thingy = "/static/index.md"; }]; - static = { "index.md" = ./src/index.md; }; - }; - }) - - (it "switches links" (let - coolPage = { - type = "link"; - name = "cool-page"; - content = ""; - }; - in { - actual = switchLinks { - something = ""; - a-thing = { src = coolPage; }; - a-list = [{ thingy = coolPage; }]; - }; - expected = { - something = ""; - a-thing = { src = "/static/cool-page"; }; - a-list = [{ thingy = "/static/cool-page"; }]; - }; - })) - - (it "gets links" (let - coolPage = { - type = "link"; - name = "cool-page"; - content = "cool content"; - }; - otherPage = { - type = "link"; - name = "page2"; - content = "stuff"; - }; - in { - actual = getLinks { - something = "yes"; - a-list = - [ { thingy = coolPage; } [ (elems.img { src = otherPage; } "") ] ]; - }; - expected = { - "cool-page" = "cool content"; - "page2" = "stuff"; - }; - })) - - (it "extracts links" (let - coolPage = { - type = "link"; - name = "cool-page"; - content = "cool content"; - }; - otherPage = { - type = "link"; - name = "page2"; - content = "stuff"; - }; - - in { - actual = extractLinks { - something = ""; - a-thing = { src = coolPage; }; - a-list = [{ thingy = otherPage; }]; - }; - expected = { - something = ""; - a-thing = { src = "/static/cool-page"; }; - a-list = [{ thingy = "/static/page2"; }]; - static = { + (it "gets links" (let + coolPage = { + type = "link"; + name = "cool-page"; + content = "cool content"; + }; + otherPage = { + type = "link"; + name = "page2"; + content = "stuff"; + }; + in { + actual = getLinks { + something = "yes"; + a-list = [{thingy = coolPage;} [(elems.img {src = otherPage;} "")]]; + }; + expected = { "cool-page" = "cool content"; "page2" = "stuff"; }; - }; - })) + })) - (it "copies all the files" ({ - actual = copyTo "." { - page = "this is a page"; - subdir = { - page = "this page is in a subdir"; - link = ./src; + (it "extracts links" (let + coolPage = { + type = "link"; + name = "cool-page"; + content = "cool content"; }; - }; - expected = '' - cp /nix/store/crirfz0n6f8dgl1si3x7pwyw7fqm0r8l-page ./page - mkdir -p ./subdir - cp -r /nix/store/q95cn7ccixzi9w22aic4bl0ykk40ka7v-src ./subdir/link - cp /nix/store/ic6fyy8wg8r4338a3m5kinmg11igxsyj-page ./subdir/page + otherPage = { + type = "link"; + name = "page2"; + content = "stuff"; + }; + in { + actual = extractLinks { + something = ""; + a-thing = {src = coolPage;}; + a-list = [{thingy = otherPage;}]; + }; + expected = { + something = ""; + a-thing = {src = "/static/cool-page";}; + a-list = [{thingy = "/static/page2";}]; + static = { + "cool-page" = "cool content"; + "page2" = "stuff"; + }; + }; + })) - ''; - })) + (it "copies all the files" { + actual = copyTo "." { + page = "this is a page"; + subdir = { + page = "this page is in a subdir"; + link = ./src; + }; + }; + expected = '' + cp /nix/store/crirfz0n6f8dgl1si3x7pwyw7fqm0r8l-page ./page + mkdir -p ./subdir + cp -r /nix/store/q95cn7ccixzi9w22aic4bl0ykk40ka7v-src ./subdir/link + cp /nix/store/ic6fyy8wg8r4338a3m5kinmg11igxsyj-page ./subdir/page - (it "throws with a list for a page" ({ - actual = copyTo "." { page = [ ]; }; - throws = true; - })) + ''; + }) - (it "throws with null for a page" ({ - actual = copyTo "." { page = null; }; - throws = true; - })) + (it "throws with a list for a page" { + actual = copyTo "." {page = [];}; + throws = true; + }) - (it "throws with a bool for a page" ({ - actual = copyTo "." { page = true; }; - throws = true; - })) + (it "throws with null for a page" { + actual = copyTo "." {page = null;}; + throws = true; + }) - (it "throws with a number for a page" ({ - actual = copyTo "." { page = 5; }; - throws = true; - })) + (it "throws with a bool for a page" { + actual = copyTo "." {page = true;}; + throws = true; + }) - (it "prepares the site" ({ - actual = prepare { favicon = ./src/favicon.png; } { - "index.html" = elems.html { } [ - (elems.head { } [ (elems.title { } "foobar") ]) - (elems.main { } [ - (elems.a { - href = { - type = "link"; - name = "a-page"; - content = "this is another page"; - }; - } "A Page") - ]) - ]; - blog = { - "index.html" = elems.html { } [ - (elems.head { } [ (elems.title { } "foobar") ]) - (elems.main { } "something") + (it "throws with a number for a page" { + actual = copyTo "." {page = 5;}; + throws = true; + }) + + (it "prepares the site" { + actual = prepare {favicon = ./src/favicon.png;} { + "index.html" = elems.html {} [ + (elems.head {} [(elems.title {} "foobar")]) + (elems.main {} [ + (elems.a { + href = { + type = "link"; + name = "a-page"; + content = "this is another page"; + }; + } "A Page") + ]) ]; + blog = { + "index.html" = elems.html {} [ + (elems.head {} [(elems.title {} "foobar")]) + (elems.main {} "something") + ]; + }; }; - }; - expected = { - "index.html" = elems.html { } [ - (elems.head { } [ - (elems.title { } "foobar") - (elems.link { - rel = "shortcut icon"; - href = "/static/favicon.png"; - }) - (elems.Stylesheet "/style.css") - ]) - (elems.main { } [ (elems.a { href = "/static/a-page"; } "A Page") ]) - ]; - blog = { - "index.html" = elems.html { } [ - (elems.head { } [ - (elems.title { } "foobar") + expected = { + "index.html" = elems.html {} [ + (elems.head {} [ + (elems.title {} "foobar") (elems.link { rel = "shortcut icon"; href = "/static/favicon.png"; }) (elems.Stylesheet "/style.css") ]) - (elems.main { } "something") + (elems.main {} [(elems.a {href = "/static/a-page";} "A Page")]) ]; + blog = { + "index.html" = elems.html {} [ + (elems.head {} [ + (elems.title {} "foobar") + (elems.link { + rel = "shortcut icon"; + href = "/static/favicon.png"; + }) + (elems.Stylesheet "/style.css") + ]) + (elems.main {} "something") + ]; + }; + static = { + "favicon.png" = ./src/favicon.png; + "a-page" = "this is another page"; + }; + "style.css" = ""; }; - static = { - "favicon.png" = ./src/favicon.png; - "a-page" = "this is another page"; - }; - "style.css" = ""; - }; - asJSON = true; - })) - -] + asJSON = true; + }) + ] diff --git a/testing/style.test.nix b/testing/style.test.nix index fb81f90..c53bd7e 100644 --- a/testing/style.test.nix +++ b/testing/style.test.nix @@ -1,54 +1,53 @@ -{ it, ... }: -let +{it, ...}: let style = import ../nixite/style.nix; elems = import ../nixite/elems.nix; in [ - - (it "fetches empty style" (let para = (style.component elems.p "para" { }); + (it "fetches empty style" (let + para = style.component elems.p "para" {}; in { expected = { - "p" = { }; - "p.para" = { }; + "p" = {}; + "p.para" = {}; }; actual = style.getStyle (para ""); })) (it "fetches style" (let - attrs = { style = { foo = "bar"; }; }; - para = (style.component elems.p "para" attrs); + attrs = {style = {foo = "bar";};}; + para = style.component elems.p "para" attrs; in { expected = { - "p" = { }; + "p" = {}; "p.para" = attrs.style; }; actual = style.getStyle (para ""); })) (it "appliess class" (let - attrs = { style = { foo = "bar"; }; }; - para = (style.component elems.p "para" attrs); + attrs = {style = {foo = "bar";};}; + para = style.component elems.p "para" attrs; in { - expected = [ "para" ]; + expected = ["para"]; actual = (para "").attrs.class; })) (it "applies classes from props" (let attrs = { - style = { foo = "bar"; }; - class = [ "other" "class" ]; + style = {foo = "bar";}; + class = ["other" "class"]; }; - para = (style.component elems.p "para" attrs); + para = style.component elems.p "para" attrs; in { - expected = [ "para" "other" "class" ]; + expected = ["para" "other" "class"]; actual = (para "").attrs.class; })) (it "fetches style for class" (let - s = { foo = "bar"; }; - para = (style.component elems.p "para" { style = s; }); + s = {foo = "bar";}; + para = style.component elems.p "para" {style = s;}; in { expected = { - "p" = { }; + "p" = {}; "p.para" = s; }; actual = style.getStyle (para ""); @@ -56,13 +55,13 @@ in [ (it "fetches style recursively" (let s = { - "p" = { }; - "div" = { }; - "p.para" = { foo = "bar"; }; - "div.link" = { this = "that"; }; + "p" = {}; + "div" = {}; + "p.para" = {foo = "bar";}; + "div.link" = {this = "that";}; }; - para = (style.component elems.p "para" { style = s."p.para"; }); - div = (style.component elems.div "link" { style = s."div.link"; }); + para = style.component elems.p "para" {style = s."p.para";}; + div = style.component elems.div "link" {style = s."div.link";}; in { expected = s; actual = style.getStyles (para (div "hello")); @@ -71,39 +70,39 @@ in [ (it "fetches style recursively through lists" (let s = { - "p" = { }; - "div" = { }; - "p.para" = { foo = "bar"; }; - "div.link" = { this = "that"; }; + "p" = {}; + "div" = {}; + "p.para" = {foo = "bar";}; + "div.link" = {this = "that";}; }; - para = (style.component elems.p "para" { style = s."p.para"; }); - a = (style.component elems.div "link" { style = s."div.link"; }); + para = style.component elems.p "para" {style = s."p.para";}; + a = style.component elems.div "link" {style = s."div.link";}; in { expected = s; - actual = style.getStyles (para [ (a "hello") ]); + actual = style.getStyles (para [(a "hello")]); removeDunders = true; })) (it "fetches style recursively with repeats" (let s = { - "p" = { }; - "div" = { }; - "p.para" = { foo = "bar"; }; - "div.link" = { this = "that"; }; + "p" = {}; + "div" = {}; + "p.para" = {foo = "bar";}; + "div.link" = {this = "that";}; }; - para = (style.component elems.p "para" { style = s."p.para"; }); - a = (style.component elems.div "link" { style = s."div.link"; }); + para = style.component elems.p "para" {style = s."p.para";}; + a = style.component elems.div "link" {style = s."div.link";}; in { expected = s; - actual = style.getStyles (para [ (a "hello") (a "hello") ]); + actual = style.getStyles (para [(a "hello") (a "hello")]); removeDunders = true; })) (it "converts styles to string" (let s = { - "p" = { }; - "p.para" = { foo = "bar"; }; - "a.link" = { this = "that"; }; + "p" = {}; + "p.para" = {foo = "bar";}; + "a.link" = {this = "that";}; }; in { expected = '' @@ -119,11 +118,11 @@ in [ (it "extends styled tags" (let s = { - "p.para" = { foo = "bar"; }; - "p.oof" = { oof = "yes"; }; + "p.para" = {foo = "bar";}; + "p.oof" = {oof = "yes";}; }; - para = (style.component elems.p "para" { style = s."p.para"; }); - para2 = (style.component para "oof" { style = s."p.oof"; }); + para = style.component elems.p "para" {style = s."p.para";}; + para2 = style.component para "oof" {style = s."p.oof";}; in { expected = s; actual = style.getStyles (para2 ""); @@ -132,16 +131,15 @@ in [ (it "extends styled tags classes" (let s = { - "p" = { }; - "div" = { }; - "p.para" = { foo = "bar"; }; - "p.para.oof" = { oof = "yes"; }; + "p" = {}; + "div" = {}; + "p.para" = {foo = "bar";}; + "p.para.oof" = {oof = "yes";}; }; - para = (style.component elems.p "para" { style = s."p.para"; }); - para2 = (style.component para "oof" { style = s."p.para.oof"; }); + para = style.component elems.p "para" {style = s."p.para";}; + para2 = style.component para "oof" {style = s."p.para.oof";}; in { - expected = [ "para" "oof" ]; + expected = ["para" "oof"]; actual = (para2 "").attrs.class; })) - ]