From 3ceb580768233f6f1791706327aa6ba6b7e6ff1d Mon Sep 17 00:00:00 2001 From: tristan Date: Mon, 1 Jan 2024 13:48:26 +0000 Subject: [PATCH] fix a extensibility and test for errors --- nixite/elems.nix | 22 ++++++++++++++++------ nixite/html.nix | 32 ++++++++++++++++++-------------- nixite/md.nix | 4 ++-- nixite/site.nix | 12 +++++------- nixite/style.nix | 5 ++--- testing/elems.test.nix | 16 ++++++++++++++++ testing/html.test.nix | 27 ++++++++++++++++++++++++--- testing/import.nix | 3 +-- testing/it.nix | 21 ++++++++++++++++----- testing/md.test.nix | 24 +++++++++++++++++------- testing/site.test.nix | 32 +++++++++++++++++++++++++++++++- testing/style.test.nix | 34 ++++++++++++++++++++++++++-------- 12 files changed, 174 insertions(+), 58 deletions(-) diff --git a/nixite/elems.nix b/nixite/elems.nix index 49ef8c2..7f027f0 100644 --- a/nixite/elems.nix +++ b/nixite/elems.nix @@ -41,9 +41,13 @@ in { main = html.tag "main"; div = html.tag "div"; # Text-level semantics - a = params: - html.tag "a" - (if builtins.isString params then { href = params; } else params); + 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"; @@ -124,10 +128,16 @@ in { template = html.tag "template"; slot = html.tag "slot"; canvas = html.tag "canvas"; + # custom - List = params: child: - assert builtins.isList child; - html.tag "ul" { } (map (html.tag "li" { }) child); + 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; diff --git a/nixite/html.nix b/nixite/html.nix index b6e04e2..0f4a025 100644 --- a/nixite/html.nix +++ b/nixite/html.nix @@ -28,27 +28,31 @@ in rec { else keyvalue key value) attrs))); - tag = t: { - tag = t; - attrs = {}; + tag = t: + ({ + tag = t; + attrs = { }; + } // baseTag); + + baseTag = { __toString = self: toString (self ""); __functor = self: child: (if !(isTag child) then (if isSet child then - self // ({attrs = self.attrs // child;}) + incorporateAttrs self child else - throw "tag child must be tag, list, or string, got ${ - builtins.typeOf child - }" - ) - else { - tag = t; - attrs = self.attrs; - inherit child; - __toString = toHTML; - }); + throw "tag child must be tag, list, or string, got ${ + builtins.typeOf child + }") + else + self // { + inherit child; + __toString = toHTML; + }); }; + incorporateAttrs = self: attrs: self // ({ attrs = self.attrs // attrs; }); + isSet = a: builtins.isAttrs a && !a ? __toString; isTag = tag: diff --git a/nixite/md.nix b/nixite/md.nix index 3f1740f..415f215 100644 --- a/nixite/md.nix +++ b/nixite/md.nix @@ -4,9 +4,9 @@ let H = n: let v = if n < 1 then - builtins.trace "attempted to make heading size ${n} (min is 1)" 1 + builtins.trace "attempted to make heading size ${toString n} (min is 1)" 1 else if n > 6 then - builtins.trace "attempted to make heading size ${n} (max is 6)" 6 + builtins.trace "attempted to make heading size ${toString n} (max is 6)" 6 else n; in html.tag "h${toString v}" { }; diff --git a/nixite/site.nix b/nixite/site.nix index 7f7b8ad..efcf8c5 100644 --- a/nixite/site.nix +++ b/nixite/site.nix @@ -49,15 +49,13 @@ 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: @@ -112,7 +110,7 @@ in rec { 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: diff --git a/nixite/style.nix b/nixite/style.nix index 36bfa28..b453b93 100644 --- a/nixite/style.nix +++ b/nixite/style.nix @@ -45,7 +45,7 @@ let 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: @@ -55,6 +55,5 @@ let in { inherit getStyle getStyles stylesToString; - component = tag: class: props: - tag ( mkProps tag class props ); + component = tag: class: props: tag (mkProps tag class props); } diff --git a/testing/elems.test.nix b/testing/elems.test.nix index 7272476..774ff37 100644 --- a/testing/elems.test.nix +++ b/testing/elems.test.nix @@ -1,5 +1,6 @@ let elems = import ../nixite/elems.nix; + style = import ../nixite/style.nix; html = import ../nixite/html.nix; it = import ./it.nix; in with elems; [ @@ -33,11 +34,26 @@ in with elems; [ 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 "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 "makes a stylesheet link" { expected = html.tag "link" { href = "/style"; diff --git a/testing/html.test.nix b/testing/html.test.nix index ffd2425..fe0297b 100644 --- a/testing/html.test.nix +++ b/testing/html.test.nix @@ -9,7 +9,7 @@ in with html; [ expected = "p"; })) - (it "keeps attr info in the tag" (let p = tag "p" { class = ""; }; + (it "keeps attr info in the tag" (let p = tag "p" { class = ""; }; in { actual = p.attrs; expected = { class = ""; }; @@ -27,8 +27,8 @@ in with html; [ tag = "p"; attrs = { }; child = "Hello"; - __toString = toHTML; }; + removeDunders = true; }) (it "makes element" (let para = (tag "p" { }); @@ -96,6 +96,26 @@ in with html; [ actual = toString (para (a "hello")); })) + (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 bool" ({ + actual = toString (tag "p" true); + 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

''; @@ -108,7 +128,8 @@ in with html; [ tag = "html"; attrs = { }; child = [ (tag "head" { } [ "foo" "bar" ]) ]; - __toString = toHTML; }; + removeDunders = true; })) + ] diff --git a/testing/import.nix b/testing/import.nix index 5bef664..eaf4ede 100644 --- a/testing/import.nix +++ b/testing/import.nix @@ -1,6 +1,5 @@ path: -builtins.trace ( "testing " + builtins.baseNameOf path ) -'' +builtins.trace ("testing " + builtins.baseNameOf path) '' echo echo 'TEST: ${builtins.baseNameOf path}' echo diff --git a/testing/it.nix b/testing/it.nix index 9071da6..d33549d 100644 --- a/testing/it.nix +++ b/testing/it.nix @@ -1,6 +1,6 @@ msg: -{ actual, expected, asString ? false, asJSON ? false, removeDunders ? false -, safeToPrint ? true }: +{ actual, expected ? { }, asString ? false, asJSON ? false +, removeDunders ? false, safeToPrint ? true, throws ? false }: let preProcess = v: if removeDunders then @@ -15,11 +15,22 @@ let a = preProcess actual; e = preProcess expected; - undunder = v: if builtins.isAttrs v then builtins.removeAttrs v [ "__toString" "__functor" ] else v; + undunder = v: + if builtins.isAttrs v then + builtins.removeAttrs v [ "__toString" "__functor" ] + else + v; - out = (if safeToPrint then builtins.toJSON (undunder actual) else ''{"msg": "refusing to print"}''); + out = (if safeToPrint then + builtins.toJSON + (undunder (if throws then (builtins.tryEval actual).value else actual)) + else + ''{"msg": "refusing to print"}''); -in if (a == e) then '' + success = + if throws then (builtins.tryEval actual).success == false else (a == e); + +in if success then '' echo 'it ${msg}' '' else builtins.trace "FAILED ${msg}" '' diff --git a/testing/md.test.nix b/testing/md.test.nix index 72a2023..adb072f 100644 --- a/testing/md.test.nix +++ b/testing/md.test.nix @@ -3,14 +3,24 @@ let elems = import ../nixite/elems.nix; it = import ./it.nix; in with md; [ - (assert heading "# heading 1" == [ "#" "heading 1" ]; "echo gets heading 1") - (assert heading "## subheading" == [ "##" "subheading" ]; - "echo gets heading 2") - (assert heading "some paragraph" == null; "echo paragraph is heading 0") - #(assert mdBlock "# heading 1" == elems.h 1 "heading 1"; "echo makes h1 tag") - #(assert mdBlock "## subheading" == elems.h 2 "subheading"; "echo makes h2 tag") - #(assert mdBlock "some paragraph" == elems.p {} "some paragraph"; "echo makes p tag") + (it "gets md heading" { + actual = mdBlock '' + # title of the page''; + expected = elems.h1 "title of the page"; + }) + + (it "gets md heading 2" { + actual = mdBlock '' + ## a subheading''; + expected = elems.h2 "a subheading"; + }) + + (it "limits to 6 #" { + actual = mdBlock '' + ######## super ultra tiny heading''; + expected = elems.h6 "super ultra tiny heading"; + }) (it "processes md block" { actual = readMd '' diff --git a/testing/site.test.nix b/testing/site.test.nix index 3f46afe..50770f8 100644 --- a/testing/site.test.nix +++ b/testing/site.test.nix @@ -85,7 +85,9 @@ in with site; [ }) (it "gets all styles" { - expected = {"p"={};"div"={}; + expected = { + "p" = { }; + "div" = { }; "p.class" = { color = "blue"; }; "div.class2" = { color = "green"; }; }; @@ -235,6 +237,34 @@ in with site; [ ''; })) + (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 bool for a page" ({ + actual = copyTo "." { + page = true; + }; + throws = true; + })) + + (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 { } [ diff --git a/testing/style.test.nix b/testing/style.test.nix index 5deb192..5b0e333 100644 --- a/testing/style.test.nix +++ b/testing/style.test.nix @@ -7,7 +7,10 @@ in [ (it "fetches empty style" (let para = (style.component elems.p "para" { }); in { - expected = { "p" = {}; "p.para" = { }; }; + expected = { + "p" = { }; + "p.para" = { }; + }; actual = style.getStyle (para ""); })) @@ -15,7 +18,10 @@ in [ attrs = { style = { foo = "bar"; }; }; para = (style.component elems.p "para" attrs); in { - expected = {"p" = {}; "p.para" = attrs.style; }; + expected = { + "p" = { }; + "p.para" = attrs.style; + }; actual = style.getStyle (para ""); })) @@ -42,12 +48,17 @@ in [ s = { foo = "bar"; }; para = (style.component elems.p "para" { style = s; }); in { - expected = { "p" = {}; "p.para" = s; }; + expected = { + "p" = { }; + "p.para" = s; + }; actual = style.getStyle (para ""); })) (it "fetches style recursively" (let - s = {"p" = {};"div" = {}; + s = { + "p" = { }; + "div" = { }; "p.para" = { foo = "bar"; }; "div.link" = { this = "that"; }; }; @@ -60,7 +71,9 @@ in [ })) (it "fetches style recursively through lists" (let - s = {"p" = {};"div" = {}; + s = { + "p" = { }; + "div" = { }; "p.para" = { foo = "bar"; }; "div.link" = { this = "that"; }; }; @@ -73,7 +86,9 @@ in [ })) (it "fetches style recursively with repeats" (let - s = {"p" = {};"div" = {}; + s = { + "p" = { }; + "div" = { }; "p.para" = { foo = "bar"; }; "div.link" = { this = "that"; }; }; @@ -86,7 +101,8 @@ in [ })) (it "converts styles to string" (let - s = {"p" = {}; + s = { + "p" = { }; "p.para" = { foo = "bar"; }; "a.link" = { this = "that"; }; }; @@ -116,7 +132,9 @@ in [ })) (it "extends styled tags classes" (let - s = {"p" = {}; "div" = {}; + s = { + "p" = { }; + "div" = { }; "p.para" = { foo = "bar"; }; "p.para.oof" = { oof = "yes"; }; };