fix a extensibility and test for errors

This commit is contained in:
tristan 2024-01-01 13:48:26 +00:00
parent e76305f71a
commit 3ceb580768
12 changed files with 174 additions and 58 deletions

View file

@ -41,9 +41,13 @@ in {
main = html.tag "main"; main = html.tag "main";
div = html.tag "div"; div = html.tag "div";
# Text-level semantics # Text-level semantics
a = params: a = html.tag "a" // {
html.tag "a" __functor = self: href:
(if builtins.isString params then { href = params; } else params); (if builtins.isString href then
(self // html.baseTag) { inherit href; }
else
(self // html.baseTag) href);
};
em = html.tag "em"; em = html.tag "em";
strong = html.tag "strong"; strong = html.tag "strong";
small = html.tag "small"; small = html.tag "small";
@ -124,10 +128,16 @@ in {
template = html.tag "template"; template = html.tag "template";
slot = html.tag "slot"; slot = html.tag "slot";
canvas = html.tag "canvas"; canvas = html.tag "canvas";
# custom # custom
List = params: child: List = html.tag "ul" // {
assert builtins.isList child; __functor = self: children:
html.tag "ul" { } (map (html.tag "li" { }) child); (if builtins.isList children then
(self // html.baseTag) (map (html.tag "li") children)
else
html.incorporateAttrs self children);
};
Doc = params: child: Doc = params: child:
assert builtins.isList child; assert builtins.isList child;
assert builtins.length child == 2; assert builtins.length child == 2;

View file

@ -28,27 +28,31 @@ in rec {
else else
keyvalue key value) attrs))); keyvalue key value) attrs)));
tag = t: { tag = t:
tag = t; ({
attrs = {}; tag = t;
attrs = { };
} // baseTag);
baseTag = {
__toString = self: toString (self ""); __toString = self: toString (self "");
__functor = self: child: __functor = self: child:
(if !(isTag child) then (if !(isTag child) then
(if isSet child then (if isSet child then
self // ({attrs = self.attrs // child;}) incorporateAttrs self child
else else
throw "tag child must be tag, list, or string, got ${ throw "tag child must be tag, list, or string, got ${
builtins.typeOf child builtins.typeOf child
}" }")
) else
else { self // {
tag = t; inherit child;
attrs = self.attrs; __toString = toHTML;
inherit child; });
__toString = toHTML;
});
}; };
incorporateAttrs = self: attrs: self // ({ attrs = self.attrs // attrs; });
isSet = a: builtins.isAttrs a && !a ? __toString; isSet = a: builtins.isAttrs a && !a ? __toString;
isTag = tag: isTag = tag:

View file

@ -4,9 +4,9 @@ let
H = n: H = n:
let let
v = if n < 1 then 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 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 else
n; n;
in html.tag "h${toString v}" { }; in html.tag "h${toString v}" { };

View file

@ -49,15 +49,13 @@ in rec {
]); ]);
extractPaths = content: extractPaths = content:
switchPaths content // switchPaths content // {
{ static = (content.static or { }) // getPaths content;
static = ( content.static or { } ) // getPaths content;
}; };
extractLinks = content: extractLinks = content:
switchLinks content // switchLinks content // {
{ static = (content.static or { }) // getLinks content;
static = ( content.static or { } ) // getLinks content;
}; };
isLink = value: isLink = value:
@ -112,7 +110,7 @@ in rec {
else else
[ ]); [ ]);
link = {name, content}@page: page // {type = "link";}; link = { name, content }@page: page // { type = "link"; };
copyTo = prefix: site: copyTo = prefix: site:
builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content: builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content:

View file

@ -45,7 +45,7 @@ let
props // { props // {
__id = "${tag.tag}.${class}"; __id = "${tag.tag}.${class}";
__extends = tag; __extends = tag;
class = ( tag.attrs.class or [] ) ++ [ class ] ++ (props.class or [ ]); class = (tag.attrs.class or [ ]) ++ [ class ] ++ (props.class or [ ]);
}; };
stylesToString = styles: stylesToString = styles:
@ -55,6 +55,5 @@ let
in { in {
inherit getStyle getStyles stylesToString; inherit getStyle getStyles stylesToString;
component = tag: class: props: component = tag: class: props: tag (mkProps tag class props);
tag ( mkProps tag class props );
} }

View file

@ -1,5 +1,6 @@
let let
elems = import ../nixite/elems.nix; elems = import ../nixite/elems.nix;
style = import ../nixite/style.nix;
html = import ../nixite/html.nix; html = import ../nixite/html.nix;
it = import ./it.nix; it = import ./it.nix;
in with elems; [ in with elems; [
@ -33,11 +34,26 @@ in with elems; [
actual = title { } "foobar"; actual = title { } "foobar";
asString = true; asString = true;
}) })
(it "makes an a tag" { (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"; expected = html.tag "a" { href = "https://example.com"; } "example";
actual = a "https://example.com" "example"; actual = a "https://example.com" "example";
asString = true; 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" { (it "makes a stylesheet link" {
expected = html.tag "link" { expected = html.tag "link" {
href = "/style"; href = "/style";

View file

@ -9,7 +9,7 @@ in with html; [
expected = "p"; 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 { in {
actual = p.attrs; actual = p.attrs;
expected = { class = ""; }; expected = { class = ""; };
@ -27,8 +27,8 @@ in with html; [
tag = "p"; tag = "p";
attrs = { }; attrs = { };
child = "Hello"; child = "Hello";
__toString = toHTML;
}; };
removeDunders = true;
}) })
(it "makes element" (let para = (tag "p" { }); (it "makes element" (let para = (tag "p" { });
@ -96,6 +96,26 @@ in with html; [
actual = toString (para (a "hello")); 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" { (it "concatinates classes" {
actual = toString (tag "p" { class = [ "class1" "class2" ]; } "Hello"); actual = toString (tag "p" { class = [ "class1" "class2" ]; } "Hello");
expected = ''<p class="class1 class2">Hello</p>''; expected = ''<p class="class1 class2">Hello</p>'';
@ -108,7 +128,8 @@ in with html; [
tag = "html"; tag = "html";
attrs = { }; attrs = { };
child = [ (tag "head" { } [ "foo" "bar" ]) ]; child = [ (tag "head" { } [ "foo" "bar" ]) ];
__toString = toHTML;
}; };
removeDunders = true;
})) }))
] ]

View file

@ -1,6 +1,5 @@
path: path:
builtins.trace ( "testing " + builtins.baseNameOf path ) builtins.trace ("testing " + builtins.baseNameOf path) ''
''
echo echo
echo 'TEST: ${builtins.baseNameOf path}' echo 'TEST: ${builtins.baseNameOf path}'
echo echo

View file

@ -1,6 +1,6 @@
msg: msg:
{ actual, expected, asString ? false, asJSON ? false, removeDunders ? false { actual, expected ? { }, asString ? false, asJSON ? false
, safeToPrint ? true }: , removeDunders ? false, safeToPrint ? true, throws ? false }:
let let
preProcess = v: preProcess = v:
if removeDunders then if removeDunders then
@ -15,11 +15,22 @@ let
a = preProcess actual; a = preProcess actual;
e = preProcess expected; 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}' echo 'it ${msg}'
'' else '' else
builtins.trace "FAILED ${msg}" '' builtins.trace "FAILED ${msg}" ''

View file

@ -3,14 +3,24 @@ let
elems = import ../nixite/elems.nix; elems = import ../nixite/elems.nix;
it = import ./it.nix; it = import ./it.nix;
in with md; [ 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") (it "gets md heading" {
#(assert mdBlock "## subheading" == elems.h 2 "subheading"; "echo makes h2 tag") actual = mdBlock ''
#(assert mdBlock "some paragraph" == elems.p {} "some paragraph"; "echo makes p tag") # 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" { (it "processes md block" {
actual = readMd '' actual = readMd ''

View file

@ -85,7 +85,9 @@ in with site; [
}) })
(it "gets all styles" { (it "gets all styles" {
expected = {"p"={};"div"={}; expected = {
"p" = { };
"div" = { };
"p.class" = { color = "blue"; }; "p.class" = { color = "blue"; };
"div.class2" = { color = "green"; }; "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" ({ (it "prepares the site" ({
actual = prepare { favicon = ./src/favicon.png; } { actual = prepare { favicon = ./src/favicon.png; } {
"index.html" = elems.html { } [ "index.html" = elems.html { } [

View file

@ -7,7 +7,10 @@ in [
(it "fetches empty style" (let para = (style.component elems.p "para" { }); (it "fetches empty style" (let para = (style.component elems.p "para" { });
in { in {
expected = { "p" = {}; "p.para" = { }; }; expected = {
"p" = { };
"p.para" = { };
};
actual = style.getStyle (para ""); actual = style.getStyle (para "");
})) }))
@ -15,7 +18,10 @@ in [
attrs = { style = { foo = "bar"; }; }; attrs = { style = { foo = "bar"; }; };
para = (style.component elems.p "para" attrs); para = (style.component elems.p "para" attrs);
in { in {
expected = {"p" = {}; "p.para" = attrs.style; }; expected = {
"p" = { };
"p.para" = attrs.style;
};
actual = style.getStyle (para ""); actual = style.getStyle (para "");
})) }))
@ -42,12 +48,17 @@ in [
s = { foo = "bar"; }; s = { foo = "bar"; };
para = (style.component elems.p "para" { style = s; }); para = (style.component elems.p "para" { style = s; });
in { in {
expected = { "p" = {}; "p.para" = s; }; expected = {
"p" = { };
"p.para" = s;
};
actual = style.getStyle (para ""); actual = style.getStyle (para "");
})) }))
(it "fetches style recursively" (let (it "fetches style recursively" (let
s = {"p" = {};"div" = {}; s = {
"p" = { };
"div" = { };
"p.para" = { foo = "bar"; }; "p.para" = { foo = "bar"; };
"div.link" = { this = "that"; }; "div.link" = { this = "that"; };
}; };
@ -60,7 +71,9 @@ in [
})) }))
(it "fetches style recursively through lists" (let (it "fetches style recursively through lists" (let
s = {"p" = {};"div" = {}; s = {
"p" = { };
"div" = { };
"p.para" = { foo = "bar"; }; "p.para" = { foo = "bar"; };
"div.link" = { this = "that"; }; "div.link" = { this = "that"; };
}; };
@ -73,7 +86,9 @@ in [
})) }))
(it "fetches style recursively with repeats" (let (it "fetches style recursively with repeats" (let
s = {"p" = {};"div" = {}; s = {
"p" = { };
"div" = { };
"p.para" = { foo = "bar"; }; "p.para" = { foo = "bar"; };
"div.link" = { this = "that"; }; "div.link" = { this = "that"; };
}; };
@ -86,7 +101,8 @@ in [
})) }))
(it "converts styles to string" (let (it "converts styles to string" (let
s = {"p" = {}; s = {
"p" = { };
"p.para" = { foo = "bar"; }; "p.para" = { foo = "bar"; };
"a.link" = { this = "that"; }; "a.link" = { this = "that"; };
}; };
@ -116,7 +132,9 @@ in [
})) }))
(it "extends styled tags classes" (let (it "extends styled tags classes" (let
s = {"p" = {}; "div" = {}; s = {
"p" = { };
"div" = { };
"p.para" = { foo = "bar"; }; "p.para" = { foo = "bar"; };
"p.para.oof" = { oof = "yes"; }; "p.para.oof" = { oof = "yes"; };
}; };