diff options
Diffstat (limited to 'tests')
56 files changed, 507 insertions, 562 deletions
diff --git a/tests/ref/code/array.png b/tests/ref/code/array.png Binary files differindex b1e20348..c90898c1 100644 --- a/tests/ref/code/array.png +++ b/tests/ref/code/array.png diff --git a/tests/ref/code/block-invalid.png b/tests/ref/code/block-invalid.png Binary files differdeleted file mode 100644 index d1e85402..00000000 --- a/tests/ref/code/block-invalid.png +++ /dev/null diff --git a/tests/ref/code/block.png b/tests/ref/code/block.png Binary files differindex 3e64d82c..afdd176b 100644 --- a/tests/ref/code/block.png +++ b/tests/ref/code/block.png diff --git a/tests/ref/code/call-invalid.png b/tests/ref/code/call-invalid.png Binary files differdeleted file mode 100644 index b2f62ac2..00000000 --- a/tests/ref/code/call-invalid.png +++ /dev/null diff --git a/tests/ref/code/call-wide.png b/tests/ref/code/call-wide.png Binary files differdeleted file mode 100644 index 2d5b4ffe..00000000 --- a/tests/ref/code/call-wide.png +++ /dev/null diff --git a/tests/ref/code/call.png b/tests/ref/code/call.png Binary files differindex fd2abbd8..1839c5d8 100644 --- a/tests/ref/code/call.png +++ b/tests/ref/code/call.png diff --git a/tests/ref/code/closure.png b/tests/ref/code/closure.png Binary files differnew file mode 100644 index 00000000..043d4a11 --- /dev/null +++ b/tests/ref/code/closure.png diff --git a/tests/ref/code/comment.png b/tests/ref/code/comment.png Binary files differindex bb8bf69a..e349b384 100644 --- a/tests/ref/code/comment.png +++ b/tests/ref/code/comment.png diff --git a/tests/ref/code/dict.png b/tests/ref/code/dict.png Binary files differindex 730ff6d8..7b7f4d8c 100644 --- a/tests/ref/code/dict.png +++ b/tests/ref/code/dict.png diff --git a/tests/ref/code/for.png b/tests/ref/code/for.png Binary files differindex de1f3cab..7178b594 100644 --- a/tests/ref/code/for.png +++ b/tests/ref/code/for.png diff --git a/tests/ref/code/if.png b/tests/ref/code/if.png Binary files differindex 48152e23..7b54203a 100644 --- a/tests/ref/code/if.png +++ b/tests/ref/code/if.png diff --git a/tests/ref/code/import.png b/tests/ref/code/import.png Binary files differindex 75d4adce..00595f8a 100644 --- a/tests/ref/code/import.png +++ b/tests/ref/code/import.png diff --git a/tests/ref/code/let.png b/tests/ref/code/let.png Binary files differindex e9c00064..9805b8ee 100644 --- a/tests/ref/code/let.png +++ b/tests/ref/code/let.png diff --git a/tests/ref/code/while.png b/tests/ref/code/while.png Binary files differindex a772fd59..0956fe45 100644 --- a/tests/ref/code/while.png +++ b/tests/ref/code/while.png diff --git a/tests/ref/insert/circle.png b/tests/ref/insert/circle.png Binary files differindex 8364d42b..7e44907b 100644 --- a/tests/ref/insert/circle.png +++ b/tests/ref/insert/circle.png diff --git a/tests/ref/insert/square.png b/tests/ref/insert/square.png Binary files differindex def2e664..c84e6f0e 100644 --- a/tests/ref/insert/square.png +++ b/tests/ref/insert/square.png diff --git a/tests/ref/layout/spacing.png b/tests/ref/layout/spacing.png Binary files differindex 2205809a..b2b8707d 100644 --- a/tests/ref/layout/spacing.png +++ b/tests/ref/layout/spacing.png diff --git a/tests/ref/markup/escape.png b/tests/ref/markup/escape.png Binary files differindex 686471c6..227b1eeb 100644 --- a/tests/ref/markup/escape.png +++ b/tests/ref/markup/escape.png diff --git a/tests/ref/markup/raw.png b/tests/ref/markup/raw.png Binary files differindex 05aeea13..f7bb2ab0 100644 --- a/tests/ref/markup/raw.png +++ b/tests/ref/markup/raw.png diff --git a/tests/ref/text/decorations.png b/tests/ref/text/decorations.png Binary files differindex e3ca1be5..5ae569f3 100644 --- a/tests/ref/text/decorations.png +++ b/tests/ref/text/decorations.png diff --git a/tests/ref/text/whitespace.png b/tests/ref/text/whitespace.png Binary files differindex 27a67586..764c7413 100644 --- a/tests/ref/text/whitespace.png +++ b/tests/ref/text/whitespace.png diff --git a/tests/typ/code/array.typ b/tests/typ/code/array.typ index 9e14bf16..fc8795c2 100644 --- a/tests/typ/code/array.typ +++ b/tests/typ/code/array.typ @@ -18,6 +18,7 @@ , rgb("002") ,)} +--- // Error: 3 expected closing paren {(} diff --git a/tests/typ/code/block-invalid.typ b/tests/typ/code/block-invalid.typ deleted file mode 100644 index 01df81d5..00000000 --- a/tests/typ/code/block-invalid.typ +++ /dev/null @@ -1,38 +0,0 @@ -// Test invalid code block syntax. - ---- -// Multiple unseparated expressions in one line. - -// Error: 2-4 expected expression, found invalid token -{1u} - -// Should output `1`. -// Error: 3 expected semicolon or line break -// Error: 4-5 cannot join integer with integer -{1 2} - -// Should output `2`. -// Error: 12 expected semicolon or line break -// Error: 22 expected semicolon or line break -{let x = -1 let y = 3 x + y} - -// Should output `3`. -{ - // Error: 9-12 expected identifier, found string - for "v" - - // Error: 10 expected keyword `in` - for v let z = 1 + 2 - - z -} - ---- -// Ref: false -// Error: 2:1 expected closing brace -{ - ---- -// Ref: false -// Error: 1-2 unexpected closing brace -} diff --git a/tests/typ/code/block-scoping.typ b/tests/typ/code/block-scoping.typ deleted file mode 100644 index 7970ee1b..00000000 --- a/tests/typ/code/block-scoping.typ +++ /dev/null @@ -1,45 +0,0 @@ -// Test scoping with blocks. -// Ref: false - ---- -// Block in template does not create a scope. -{ let x = 1 } -#test(x, 1) - ---- -// Block in expression does create a scope. -#let a = { - let b = 1 - b -} - -#test(a, 1) - -// Error: 2-3 unknown variable -{b} - ---- -// Double block creates a scope. -{{ - import b from "target.typ" - test(b, 1) -}} - -// Error: 2-3 unknown variable -{b} - ---- -// Multiple nested scopes. -{ - let a = "a1" - { - let a = "a2" - { - test(a, "a2") - let a = "a3" - test(a, "a3") - } - test(a, "a2") - } - test(a, "a1") -} diff --git a/tests/typ/code/block.typ b/tests/typ/code/block.typ index 8c30fa64..ac289abf 100644 --- a/tests/typ/code/block.typ +++ b/tests/typ/code/block.typ @@ -1,58 +1,135 @@ // Test code blocks. +// Ref: false --- -All none - -// Nothing evaluates to none. -{} +// Ref: true -// Let evaluates to none. -{ let v = 0 } +// Evaluates to join of none, [My ] and the two loop bodies. +{ + let parts = ("my fri", "end.") + [Hello, ] + for s in parts [{s}] +} -// Type is joined with trailing none, evaluates to string. +// Evaluates to join of the templates and strings. { - type("") - none + [How] + if true { + " are" + } + [ ] + if false [Nope] + [you] + "?" } --- +// Nothing evaluates to none. +#test({}, none) + +// Let evaluates to none. +#test({ let v = 0 }, none) + // Evaluates to single expression. -{ "Hello" } +#test({ "hello" }, "hello") // Evaluates to string. -{ let x = "Hel"; x + "lo" } +#test({ let x = "m"; x + "y" }, "my") + +// Evaluated to int. +#test({ + let x = 1 + let y = 2 + x + y +}, 3) + +// String is joined with trailing none, evaluates to string. +#test({ + type("") + none +}, "string") -// Evaluates to join of none, [He] and the two loop bodies. +--- +// Some things can't be joined. { - let parts = ("l", "lo") - [He] - for s in parts [{s}] + [A] + // Error: 5-6 cannot join template with integer + 1 + [B] } --- -// Evaluates to join of the templates and strings. +// Block in template does not create a scope. +{ let x = 1 } +#test(x, 1) + +--- +// Block in expression does create a scope. +#let a = { + let b = 1 + b +} + +#test(a, 1) + +// Error: 2-3 unknown variable +{b} + +--- +// Double block creates a scope. +{{ + import b from "target.typ" + test(b, 1) +}} + +// Error: 2-3 unknown variable +{b} + +--- +// Multiple nested scopes. { - [Hey, ] - if true { - "there!" + let a = "a1" + { + let a = "a2" + { + test(a, "a2") + let a = "a3" + test(a, "a3") + } + test(a, "a2") } - [ ] - if false [Nope] - [How are ] + "you?" + test(a, "a1") } +--- +// Multiple unseparated expressions in one line. + +// Error: 2-4 expected expression, found invalid token +{1u} + +// Should output `1`. +// Error: 3 expected semicolon or line break +{1 2} + +// Should output `2`. +// Error: 12 expected semicolon or line break +// Error: 22 expected semicolon or line break +{let x = -1 let y = 3 x + y} + +// Should output `3`. { - [A] - // Error: 5-6 cannot join template with integer - 1 - [B] + // Error: 9-12 expected identifier, found string + for "v" + + // Error: 10 expected keyword `in` + for v let z = 1 + 2 + + z } --- -// Works the same way in code environment. -// Ref: false -#test(3, { - let x = 1 - let y = 2 - x + y -}) +// Error: 2:1 expected closing brace +{ + +--- +// Error: 1-2 unexpected closing brace +} diff --git a/tests/typ/code/call-invalid.typ b/tests/typ/code/call-invalid.typ deleted file mode 100644 index dd5897b8..00000000 --- a/tests/typ/code/call-invalid.typ +++ /dev/null @@ -1,39 +0,0 @@ -// Test invalid function calls. - ---- -// Error: 7-8 expected expression, found colon -#args(:) - -// Error: 10-12 expected expression, found end of block comment -#args(a:1*/) - -// Error: 8 expected comma -#args(1 2) - -// Error: 7-8 expected identifier -// Error: 9 expected expression -#args(1:) - -// Error: 7-8 expected identifier -#args(1:2) - -// Error: 7-10 expected identifier -{args((x):1)} - ---- -#let x = "string" - -// Error: 1-3 expected function, found string -#x() - -// Error: 2:1 expected closing bracket -#args[`a]` - ---- -// Error: 7 expected closing paren -{args(} - ---- -// Error: 2:1 expected quote -// Error: 2:1 expected closing paren -#args("] diff --git a/tests/typ/code/call-wide.typ b/tests/typ/code/call-wide.typ deleted file mode 100644 index 1ad4995d..00000000 --- a/tests/typ/code/call-wide.typ +++ /dev/null @@ -1,40 +0,0 @@ -// Test wide calls. - ---- -// Test multiple wide calls in separate expressions. -#font!(fill: eastern) - First -#font!(fill: forest) - Second - ---- -// Test in heading. -= A #align!(right) B -C - ---- -// Test evaluation semantics. - -#let x = 1 -#let f(x, body) = (x, body) -#f!(x) -{ x = 2 } - ---- -// Test multiple wide calls in one expression. -// Ref: false - -#let f() = [] -#let g(x, y) = [] - -// Error: 2-4 wide calls are only allowed directly in templates -{f!()} - -// Test nested wide calls. -// Error: 5-7 wide calls are only allowed directly in templates -#g!(f!()) - ---- -// Test missing parentheses. -// Ref: false - -// Error: 4 expected argument list -#f! diff --git a/tests/typ/code/call.typ b/tests/typ/code/call.typ index eb5c6732..28ce860c 100644 --- a/tests/typ/code/call.typ +++ b/tests/typ/code/call.typ @@ -1,34 +1,64 @@ // Test function calls. +// Ref: false --- -// One argument. -#args(bold) +// Ref: true -// One argument and trailing comma. -#args(1,) +// Ommitted space. +#font(weight:bold)[Bold] -// One named argument. -#args(a:2) +// Call return value of function with body. +#let f(x, body) = (y) => [#x] + body + [#y] +#f(1)[2](3) -// Mixed arguments. -{args(1, b: "2", 3)} +// Don't parse this as a function. +// Should output `<function test> (it)`. +#test (it) -// Should output `() + 2`. -#args() + 2 +#let f(body) = body +#f[A] +#f()[A] +#f([A]) --- -// Ref: false +// Ref: true + +// Test multiple wide calls in separate expressions inside a template. +[ + #font!(fill: eastern) - First + #font!(fill: forest) - Second +] + +// Test wide call in heading. += A #align!(right) B +C + +--- +// Test wide call in expression. + +// Error: 2-4 wide calls are only allowed directly in templates +{f!()} + +// Error: 5-7 wide calls are only allowed directly in templates +#g!(f!()) + +--- +// Test wide call evaluation semantics. +#let x = 1 +#let f(x, body) = test(x, 1) +#f!(x) +{ x = 2 } + +--- +// Trailing comma. +#test(1 + 1, 2,) // Call function assigned to variable. #let alias = type #test(alias(alias), "function") ---- // Callee expressions. { - // Error: 5-9 expected function, found boolean - true() - // Wrapped in parens. test((type)("hi"), "string") @@ -37,30 +67,60 @@ test(adder(2)(5), 7) } -#let f(x, body) = (y) => { - [{x}] + body + [{y}] -} - -// Call return value of function with body. -#f(1)[2](3) +--- +// Error: 2-6 expected function, found boolean +{true()} -// Don't allow this to be a closure. -// Should output `x => "hi"`. +--- #let x = "x" -#x => "hi" + +// Error: 1-3 expected function, found string +#x() + +--- +#let f(x) = x + +// Error: 1-6 expected function, found integer +#f(1)(2) + +--- +#let f(x) = x + +// Error: 1-6 expected function, found template +#f[1](2) --- -// Different forms of template arguments. +// Error: 7 expected argument list +#func! + +// Error: 7-8 expected expression, found colon +#func(:) + +// Error: 10-12 expected expression, found end of block comment +#func(a:1*/) -#let a = "a" +// Error: 8 expected comma +#func(1 2) -#args(a) \ -#args[a] \ -#args(a, [b]) +// Error: 7-8 expected identifier +// Error: 9 expected expression +#func(1:) -// Template can be argument or body depending on whitespace. -#if "template" == type[b] [Sure ] -#if "template" == type [Nope.] #else [thing.] +// Error: 7-8 expected identifier +#func(1:2) -// Should output `<function args> (Okay.)`. -#args (Okay.) +// Error: 7-10 expected identifier +{func((x):1)} + +--- +// Error: 2:1 expected closing bracket +#func[`a]` + +--- +// Error: 7 expected closing paren +{func(} + +--- +// Error: 2:1 expected quote +// Error: 2:1 expected closing paren +#func("] diff --git a/tests/typ/code/closure.typ b/tests/typ/code/closure.typ index 20a5f18d..75241f32 100644 --- a/tests/typ/code/closure.typ +++ b/tests/typ/code/closure.typ @@ -2,13 +2,22 @@ // Ref: false --- +// Don't parse closure directly in template. +// Ref: true +#let x = "\"hi\"" + +// Should output `"hi" => "bye"`. +#x => "bye" + +--- // Basic closure without captures. { let adder = (x, y) => x + y test(adder(2, 3), 5) } +--- // Pass closure as argument and return closure. // Also uses shorthand syntax for a single argument. { @@ -19,6 +28,7 @@ test(h(2), 5) } +--- // Capture environment. { let mark = "?" @@ -35,15 +45,7 @@ test(greet("Typst"), "Hi, Typst!") } -// Don't leak environment. -{ - // Error: 18-19 unknown variable - let func() = x - let x = "hi" - - test(func(), error) -} - +--- // Redefined variable. { let x = 1 @@ -55,6 +57,15 @@ } --- +// Don't leak environment. +{ + // Error: 18-19 unknown variable + let func() = x + let x = "hi" + func() +} + +--- // Too few arguments. { let types(x, y) = "[" + type(x) + ", " + type(y) + "]" @@ -64,11 +75,11 @@ test(types("nope"), "[string, none]") } +--- // Too many arguments. { let f(x) = x + 1 // Error: 10-15 unexpected argument - // Error: 17-24 unexpected argument f(1, "two", () => x) } diff --git a/tests/typ/code/for-pattern.typ b/tests/typ/code/for-pattern.typ deleted file mode 100644 index a6a7c16a..00000000 --- a/tests/typ/code/for-pattern.typ +++ /dev/null @@ -1,35 +0,0 @@ -// Test for loop patterns. -// Ref: false - ---- -#let out = () - -// Values of array. -#for v in (1, 2, 3) { - out += (v,) -} - -// Indices and values of array. -#for i, v in ("1", "2", "3") { - test(repr(i + 1), v) -} - -// Values of dictionary. -#for v in (a: 4, b: 5) { - out += (v,) -} - -// Keys and values of dictionary. -#for k, v in (a: 6, b: 7) { - out += (k,) - out += (v,) -} - -#test(out, (1, 2, 3, 4, 5, "a", 6, "b", 7)) - ---- -// Keys and values of strings. -// Error: 6-10 mismatched pattern -#for k, v in "hi" { - dont-care -} diff --git a/tests/typ/code/for.typ b/tests/typ/code/for.typ index e6bcf269..62cb0bb5 100644 --- a/tests/typ/code/for.typ +++ b/tests/typ/code/for.typ @@ -1,42 +1,23 @@ // Test for loops. +// Ref: false --- +// Ref: true + // Empty array. #for x in () [Nope] -// Array. -#let sum = 0 -#for x in (1, 2, 3, 4, 5) { - sum += x -} - -#test(sum, 15) - // Dictionary is not traversed in insertion order. -// Should output `age: 1, name: Typst,`. +// Should output `Age: 2. Name: Typst.`. #for k, v in (Name: "Typst", Age: 2) [ {k}: {v}. ] -// String. -{ - let first = true - let out = for c in "abc" { - if not first { - ", " - } - c - first = false - } - test(out, "a, b, c") -} - ---- // Block body. -// Should output `[1st, 2nd, 3rd, 4th, 5th, 6th]`. +// Should output `[1st, 2nd, 3rd, 4th, 5th]`. { "[" - for v in (1, 2, 3, 4, 5, 6) { + for v in (1, 2, 3, 4, 5) { if v > 1 [, ] [#v] if v == 1 [st] @@ -48,30 +29,60 @@ } // Template body. -// Should output `234`. +// Should output `2345`. #for v in (1, 2, 3, 4, 5, 6, 7) [#if v >= 2 and v <= 5 { repr(v) }] --- -// Value of for loops. -// Ref: false +#let out = () + +// Values of array. +#for v in (1, 2, 3) { + out += (v,) +} + +// Indices and values of array. +#for i, v in ("1", "2", "3") { + test(repr(i + 1), v) +} + +// Values of dictionary. +#for v in (a: 4, b: 5) { + out += (v,) +} + +// Keys and values of dictionary. +#for k, v in (a: 6, b: 7) { + out += (k,) + out += (v,) +} + +#test(out, (1, 2, 3, 4, 5, "a", 6, "b", 7)) + +// Chars of string. +#let first = true +#let joined = for c in "abc" { + if not first { ", " } + first = false + c +} + +#test(joined, "a, b, c") + +// Return value. #test(for v in "" [], none) #test(type(for v in "1" []), "template") --- -// Ref: false - // Uniterable expression. // Error: 11-15 cannot loop over boolean #for v in true {} -// Make sure that we don't complain twice. -// Error: 11-18 cannot add integer and string -#for v in 1 + "2" {} - -// Errors taint everything. -#test(error, for v in (1, 2, 3) { - if v < 2 [Ok] else {error} -}) +--- +// Keys and values of strings. +// Error: 6-10 mismatched pattern +#for k, v in "hi" { + dont-care +} --- // Error: 5 expected identifier @@ -89,19 +100,15 @@ // Error: 15 expected body #for v in iter -// Should output `v in iter`. // Error: 5 expected identifier #for v in iter {} -// Should output `A thing`. // Error: 7-10 expected identifier, found string A#for "v" thing -// Should output `in iter`. // Error: 6-9 expected identifier, found string #for "v" in iter {} -// Should output `+ b in iter`. // Error: 7 expected keyword `in` #for a + b in iter {} diff --git a/tests/typ/code/if.typ b/tests/typ/code/if.typ index dd5d23a0..db8b059e 100644 --- a/tests/typ/code/if.typ +++ b/tests/typ/code/if.typ @@ -39,9 +39,16 @@ "Four" + point } +// Template can be argument or body depending on whitespace. +{ + if "template" == type[b] [Fi] else [Nope] + if "template" == type [Nope] else [ve.] +} + --- // Value of if expressions. // Ref: false + { let x = 1 let y = 2 @@ -61,13 +68,12 @@ } --- -// Ref: false - // Condition must be boolean. // If it isn't, neither branch is evaluated. // Error: 5-14 expected boolean, found string #if "a" + "b" { nope } #else { nope } +--- // Make sure that we don't complain twice. // Error: 5-12 cannot add integer and string #if 1 + "2" {} diff --git a/tests/typ/code/import.typ b/tests/typ/code/import.typ index e1af8ceb..93d4d168 100644 --- a/tests/typ/code/import.typ +++ b/tests/typ/code/import.typ @@ -11,8 +11,7 @@ #let value = [foo] // Import multiple things. -// Error: 9-10 expected expression, found comma -#import ,fn, value from "target.typ" +#import fn, value from "target.typ" #fn[Like and Subscribe!] #value @@ -24,10 +23,6 @@ #test(b, 1) -// This should not exist yet -// Error: 1-3 unknown variable -#d - // A wildcard import. #import * from "target.typ" @@ -45,30 +40,35 @@ #import a, c, from "target.typ" --- -// Test bad imports. -// Ref: false - // Error: 19-21 file not found #import name from "" +--- // Error: 16-27 file not found #import * from "lib/0.2.1" +--- // Some non-text stuff. // Error: 16-37 file is not valid utf-8 #import * from "../../res/rhino.png" +--- // Unresolved import. // Error: 9-21 unresolved import #import non_existing from "target.typ" -// Cyclic import. -// Error: 16-41 cyclic import -#import * from "./importable/cycle1.typ" +--- +// Cyclic import of this very file. +// Error: 16-30 cyclic import +#import * from "./import.typ" --- -// Test bad syntax. +// Cyclic import in other file. +#import * from "./importable/cycle1.typ" +This is never reached. + +--- // Error: 8 expected import items // Error: 8 expected keyword `from` #import @@ -100,7 +100,6 @@ #from "target.typ" // Should output `target`. -// Error: 1:16-2:2 file not found // Error: 2:2 expected semicolon or line break #import * from "target.typ "target diff --git a/tests/typ/code/importable/cycle1.typ b/tests/typ/code/importable/cycle1.typ index ae755fa0..a9c00f5e 100644 --- a/tests/typ/code/importable/cycle1.typ +++ b/tests/typ/code/importable/cycle1.typ @@ -1,6 +1,5 @@ // Ref: false -// Error: 16-28 cyclic import #import * from "cycle2.typ" #let inaccessible = "wow" diff --git a/tests/typ/code/importable/cycle2.typ b/tests/typ/code/importable/cycle2.typ index d4f94564..204da519 100644 --- a/tests/typ/code/importable/cycle2.typ +++ b/tests/typ/code/importable/cycle2.typ @@ -1,6 +1,5 @@ // Ref: false -// Error: 16-28 cyclic import #import * from "cycle1.typ" #let val = "much cycle" diff --git a/tests/typ/code/include.typ b/tests/typ/code/include.typ index 166c3945..0d1abc08 100644 --- a/tests/typ/code/include.typ +++ b/tests/typ/code/include.typ @@ -6,18 +6,21 @@ // Include a file #include "importable/chap1.typ" -// The variables of the file should not appear in this scope. -// Error: 1-6 unknown variable -#name - // Expression as a file name. #let chap2 = include "import" + "able/chap" + "2.typ" -- _Intermission_ -- #chap2 +--- { - // Expressions, code mode. // Error: 21-43 file not found let x = include "importable/chap3.typ" } + +--- +#include "importable/chap1.typ" + +// The variables of the file should not appear in this scope. +// Error: 1-6 unknown variable +#name diff --git a/tests/typ/code/let.typ b/tests/typ/code/let.typ index 9079b541..3f3f9d35 100644 --- a/tests/typ/code/let.typ +++ b/tests/typ/code/let.typ @@ -1,38 +1,19 @@ // Test let bindings. --- -// Ref: false - // Automatically initialized with none. #let x #test(x, none) -// Error: 9 expected expression -#let y = -#test(y, none) - // Manually initialized with one. #let z = 1 #test(z, 1) ---- // Syntax sugar for function definitions. #let fill = conifer #let rect(body) = rect(width: 2cm, fill: fill, pad(5pt, body)) #rect[Hi!] -// Error: 13 expected body -#let func(x) - -// Error: 2-6 unknown variable -{func} - -// Error: 15 expected expression -#let func(x) = - -// Error: 2-6 unknown variable -{func} - --- // Termination. @@ -47,20 +28,9 @@ One #let v3 = 3; Three -// Terminated because expression ends. -// Error: 12 expected semicolon or line break -#let v4 = 4 Four - -// Terminated by semicolon even though we are in a paren group. -// Error: 19 expected expression -// Error: 19 expected closing paren -#let v5 = (1, 2 + ; Five - #test(v1, 1) #test(v2, 2) #test(v3, 3) -#test(v4, 4) -#test(v5, (1, 2)) --- // Error: 5 expected identifier @@ -72,13 +42,27 @@ Three // Error: 6-9 expected identifier, found string #let "v" -// Should output `1`. // Error: 7 expected semicolon or line break #let v 1 // Error: 9 expected expression #let v = -// Should output a heading `1`. // Error: 6-9 expected identifier, found string #let "v" = 1 + +// Terminated because expression ends. +// Error: 12 expected semicolon or line break +#let v4 = 4 Four + +// Terminated by semicolon even though we are in a paren group. +// Error: 19 expected expression +// Error: 19 expected closing paren +#let v5 = (1, 2 + ; Five + +--- +// Error: 13 expected body +#let func(x) + +// Error: 15 expected expression +#let func(x) = diff --git a/tests/typ/code/ops-invalid.typ b/tests/typ/code/ops-invalid.typ index 149a60dd..5e56ff98 100644 --- a/tests/typ/code/ops-invalid.typ +++ b/tests/typ/code/ops-invalid.typ @@ -1,67 +1,84 @@ -// Test invalid expressions. +// Test invalid operations. // Ref: false --- -// Missing expressions. - // Error: 3 expected expression {-} +--- // Error: 10 expected expression #test({1+}, 1) +--- // Error: 10 expected expression #test({2*}, 2) --- -// Mismatched types. - // Error: 2-12 cannot apply '+' to template {+([] + [])} +--- // Error: 2-5 cannot apply '-' to string {-""} +--- // Error: 2-8 cannot apply 'not' to array {not ()} +--- // Error: 2-12 cannot apply '<=' to relative and relative {30% <= 40%} +--- // Special messages for +, -, * and /. // Error: 03-10 cannot add integer and string +{(1 + "2", 40% - 1)} + +--- // Error: 12-19 cannot subtract integer from relative -// Error: 21-29 cannot multiply integer with boolean -// Error: 31-39 cannot divide integer by length -{(1 + "2", 40% - 1, 2 * true, 3 / 12pt)} +{(1234567, 40% - 1)} + +--- +// Error: 2-10 cannot multiply integer with boolean +{2 * true} -// Error: 14-22 cannot apply '+=' to integer and string +--- +// Error: 2-10 cannot divide integer by length +{3 / 12pt} + +--- +// Error: 14-22 cannot add integer and string { let x = 1; x += "2" } +--- // Error: 13-14 expected argument list, found integer { test with 2 } +--- // Error: 3-4 expected function, found integer { 1 with () } +--- // Error: 3-10 cannot apply '..' to integer and string { 1 .. "" } --- -// Bad left-hand sides of assignment. - // Error: 3-6 cannot assign to this expression { (x) = "" } +--- // Error: 3-8 cannot assign to this expression { 1 + 2 += 3 } +--- // Error: 3-4 unknown variable { z = 1 } +--- // Error: 3-7 cannot assign to a constant { rect = "hi" } +--- // Works if we define rect beforehand // (since then it doesn't resolve to the standard library version anymore). #let rect = "" diff --git a/tests/typ/code/repr.typ b/tests/typ/code/repr.typ index 3da86bf8..35a47e49 100644 --- a/tests/typ/code/repr.typ +++ b/tests/typ/code/repr.typ @@ -10,9 +10,6 @@ {ke-bab} \ {α} -// Error: 2-3 unknown variable -{_} - --- // Literal values. {none} (empty) \ diff --git a/tests/typ/code/while.typ b/tests/typ/code/while.typ index 306c1e45..2f0984d2 100644 --- a/tests/typ/code/while.typ +++ b/tests/typ/code/while.typ @@ -29,23 +29,16 @@ #test(type(while i < 1 [{ i += 1 }]), "template") --- -// Ref: false - // Condition must be boolean. // Error: 8-14 expected boolean, found template #while [nope] [nope] -// Make sure that we don't complain twice. -// Error: 8-15 unknown variable -#while nothing {} - -// Errors taint everything. -#let i = 0 -#test(error, while i < 10 { - i += 1 - if i < 5 [nope] else { error } -}) -#test(i, 10) +--- +// Make sure that we terminate and don't complain multiple times. +#while true { + // Error: 5-9 unknown variable + nope +} --- // Error: 7 expected expression @@ -57,11 +50,9 @@ // Error: 9 expected body #while x -// Should output `x`. // Error: 7 expected expression #while x {} -// Should output `something`. // Error: 9 expected body #while x something diff --git a/tests/typ/insert/circle.typ b/tests/typ/insert/circle.typ index 38fce645..8d76f4ef 100644 --- a/tests/typ/insert/circle.typ +++ b/tests/typ/insert/circle.typ @@ -39,9 +39,9 @@ Expanded by height. --- // Radius wins over width and height. // Error: 23-34 unexpected argument -// Error: 36-49 unexpected argument #circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern) +--- // Width wins over height. -// Error: 22-34 unexpected argument -#circle(width: 20pt, height: 50pt, fill: eastern) +// Error: 9-21 unexpected argument +#circle(height: 50pt, width: 20pt, fill: eastern) diff --git a/tests/typ/insert/image.typ b/tests/typ/insert/image.typ index 35087c2e..84069949 100644 --- a/tests/typ/insert/image.typ +++ b/tests/typ/insert/image.typ @@ -10,12 +10,6 @@ // Load an RGB JPEG image. #image("../../res/tiger.jpg") -// Error: 8-29 file not found -#image("path/does/not/exist") - -// Error: 8-21 failed to load image -#image("./image.typ") - --- // Test configuring the size and fitting behaviour of images. @@ -36,3 +30,11 @@ // Make sure the bounding-box of the image is correct. #align(bottom, right, image("../../res/tiger.jpg", width: 60pt)) + +--- +// Error: 8-29 file not found +#image("path/does/not/exist") + +--- +// Error: 8-21 failed to load image +#image("./image.typ") diff --git a/tests/typ/insert/square.typ b/tests/typ/insert/square.typ index d546773f..7d65b529 100644 --- a/tests/typ/insert/square.typ +++ b/tests/typ/insert/square.typ @@ -10,12 +10,6 @@ Auto-sized square. \ ] --- -// Length wins over width and height. -// Error: 09-20 unexpected argument -// Error: 22-34 unexpected argument -#square(width: 10cm, height: 20cm, length: 1cm, fill: rgb("eb5278")) - ---- // Test height overflow. #page!(width: 75pt, height: 100pt) #square(fill: conifer)[ @@ -28,3 +22,8 @@ Auto-sized square. \ #square(fill: conifer)[ But, soft! what light through yonder window breaks? ] + +--- +// Length wins over width and height. +// Error: 09-20 unexpected argument +#square(width: 10cm, height: 20cm, length: 1cm, fill: rgb("eb5278")) diff --git a/tests/typ/layout/grid-3.typ b/tests/typ/layout/grid-3.typ index 38572520..450ce60c 100644 --- a/tests/typ/layout/grid-3.typ +++ b/tests/typ/layout/grid-3.typ @@ -25,9 +25,9 @@ gutter-columns: (0pt, 10%), image("../../res/rhino.png"), align(right, rect(width: 100%, fill: eastern)[LoL]), - "rofl", - "\nA" * 3, - "Ha!\n" * 3, + [rofl], + [\ A] * 3, + [Ha!\ ] * 3, ) --- @@ -38,9 +38,9 @@ gutter-rows: (8pt,), gutter-columns: (0pt, 10%), [A], [B], [C], - "Ha!\n" * 6, - "rofl", - "\nA" * 3, + [Ha!\ ] * 6, + [rofl], + [\ A] * 3, [hello], [darkness], [my old] @@ -54,10 +54,10 @@ gutter-rows: (10pt,), gutter-columns: (0pt, 10%), [A], [B], [C], [D], - grid(columns: 2, [A], [B], "C\n"*3, [D]), + grid(columns: 2, [A], [B], [C\ ]*3, [D]), align(right, rect(width: 100%, fill: eastern)[LoL]), - "rofl", - "E\n"*4, + [rofl], + [E\ ]*4, ) --- diff --git a/tests/typ/layout/pad.typ b/tests/typ/layout/pad.typ index d43cafc5..eba68af2 100644 --- a/tests/typ/layout/pad.typ +++ b/tests/typ/layout/pad.typ @@ -10,8 +10,7 @@ #rect(width: 20pt, height: 20pt, fill: rgb("eb5278")) ] -// Error: 13-23 missing argument: body -Hi #box(pad(left: 10pt)) there +Hi #box(pad(left: 10pt)[]) there --- #let pad(body) = pad(left: 10pt, right: 10pt, body) diff --git a/tests/typ/layout/page.typ b/tests/typ/layout/page.typ index d154d5f4..ba87ad51 100644 --- a/tests/typ/layout/page.typ +++ b/tests/typ/layout/page.typ @@ -22,9 +22,6 @@ // Ensure that specific margins override general margins. #page(margins: 0pt, left: 20pt)[Overriden] -// Error: 8-19 unknown variable -#page!(nonexistant) - // Flipped predefined paper. #page("a11", flip: true)[Flipped A11] diff --git a/tests/typ/layout/pagebreak.typ b/tests/typ/layout/pagebreak.typ index b13a1bfd..ff15d156 100644 --- a/tests/typ/layout/pagebreak.typ +++ b/tests/typ/layout/pagebreak.typ @@ -10,10 +10,7 @@ First of two A #box[ B - // Error: 16 cannot modify page from here #pagebreak() - - // Error: 11-15 cannot modify page from here #page("a4")[] ] C diff --git a/tests/typ/layout/spacing.typ b/tests/typ/layout/spacing.typ index bd38631e..ec520063 100644 --- a/tests/typ/layout/spacing.typ +++ b/tests/typ/layout/spacing.typ @@ -13,6 +13,7 @@ Add #h(10pt) #h(10pt) up // Relative to font size. Relative #h(100%) spacing +--- // Missing spacing. // Error: 12 missing argument: spacing Totally #h() ignored diff --git a/tests/typ/markup/escape.typ b/tests/typ/markup/escape.typ index b0a809f9..c039e0b7 100644 --- a/tests/typ/markup/escape.typ +++ b/tests/typ/markup/escape.typ @@ -21,14 +21,15 @@ // Escaped escape sequence. \u{41} vs. \\u\{41\} +// Some code stuff in text. +let f() , ; : | + - /= == 12 "string" + +--- // Unicode codepoint does not exist. // Error: 1-11 invalid unicode escape sequence \u{FFFFFF} +--- // Unterminated. // Error: 6 expected closing brace \u{41*Bold* - ---- -// Some code stuff in text. -let f() , ; : | + - /= == 12 "string" diff --git a/tests/typ/text/decorations.typ b/tests/typ/text/decorations.typ index 3741dc19..83b04650 100644 --- a/tests/typ/text/decorations.typ +++ b/tests/typ/text/decorations.typ @@ -1,19 +1,34 @@ // Test text decorations. --- -#strike[Statements dreamt up by the utterly deranged.] - -Sometimes, we work #strike(10pt, extent: 5%)[in secret]. -There might be #strike(stroke: rgb("abcdef88"), thickness: 10pt, extent: 5%)[redacted] -things. +// Basic strikethrough. +#strike[ + Statements dreamt up by the utterly deranged. +] +// Move underline down. #underline(offset: 5pt)[Further below.] ---- +// Different color. #underline(rgb("fc0030"))[Critical information is conveyed here.] -#underline[Still important, but not #underline(0pt)[mission ]critical.] +// Inherits font color. #font(fill: rgb("fc0030"), underline[Change with the wind.]) ---- +// Both over- and underline. #overline(underline[Running amongst the wolves.]) + +// Disable underline by setting it back to 0pt. +#underline[Still important, but not #underline(0pt)[mission ]critical.] + +--- +#let redact = strike with (10pt, extent: 5%) +#let highlight = strike with ( + stroke: rgb("abcdef88"), + thickness: 10pt, + extent: 5%, +) + +// Abuse thickness and transparency for redacting and highlighting stuff. +Sometimes, we work #redact[in secret]. +There might be #highlight[redacted] things. diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ index 0f64e244..cc906fbc 100644 --- a/tests/typ/text/font.typ +++ b/tests/typ/text/font.typ @@ -54,21 +54,25 @@ Emoji: 🐪, 🌋, 🏞 #font(monospace, monospace: ("Nope", "Latin Modern Math"))[Math.] --- -// Ref: false - // Error: 7-12 unexpected argument #font(false)[] +--- // Error: 14-18 expected font style, found font weight -// Error: 28-34 expected font weight, found string -// Error: 43-44 expected string or array of strings, found integer -#font(style: bold, weight: "thin", serif: 0)[] +#font(style: bold, weight: "thin")[] -// Error: 7-27 unexpected argument -#font(something: "invalid")[] +--- +// Error: 14-15 expected string or array of strings, found integer +#font(serif: 0)[] -// Error: 13-23 unexpected argument -#font(12pt, size: 10pt)[] +--- +// Error: 19-23 unexpected argument +#font(size: 10pt, 12pt)[] -// Error: 16-35 unexpected argument -#font("Arial", family: "Helvetica")[] +--- +// Error: 28-35 unexpected argument +#font(family: "Helvetica", "Arial")[] + +--- +// Error: 7-27 unexpected argument +#font(something: "invalid")[] diff --git a/tests/typ/text/whitespace.typ b/tests/typ/text/whitespace.typ index 418c3a12..c81513fa 100644 --- a/tests/typ/text/whitespace.typ +++ b/tests/typ/text/whitespace.typ @@ -2,16 +2,12 @@ --- // Spacing around let. - -// Error: 6 expected identifier -A#let;B \ A#let x = 1;B #test(x, 1) \ A #let x = 2;B #test(x, 2) \ A#let x = 3; B #test(x, 3) --- // Spacing around if-else. - A#if true [B]C \ A#if true [B] C \ A #if true{"B"}C \ @@ -21,7 +17,6 @@ A#if true [B] #else [] C --- // Spacing around while loop. - #let c = true; A#while c [{c = false}B]C \ #let c = true; A#while c [{c = false}B] C \ #let c = true; A #while c { c = false; "B" }C \ @@ -29,7 +24,6 @@ A#if true [B] #else [] C --- // Spacing around for loop. - A#for _ in (none,) [B]C \ A#for _ in (none,) [B] C \ A #for _ in (none,) {"B"}C diff --git a/tests/typ/utility/basics.typ b/tests/typ/utility/basics.typ index 75e06413..25cac039 100644 --- a/tests/typ/utility/basics.typ +++ b/tests/typ/utility/basics.typ @@ -3,14 +3,15 @@ --- // Test the `len` function. - #test(len(()), 0) #test(len(("A", "B", "C")), 3) #test(len("Hello World!"), 12) #test(len((a: 1, b: 2)), 2) +--- // Error: 6 missing argument: collection #len() +--- // Error: 6-10 expected string, array or dictionary #len(12pt) diff --git a/tests/typ/utility/color.typ b/tests/typ/utility/color.typ index 8f4c0522..5b10477f 100644 --- a/tests/typ/utility/color.typ +++ b/tests/typ/utility/color.typ @@ -11,13 +11,14 @@ // Clamped. #test(rgb(-30, 15.5, 0.5), rgb("00ff80")) -// Error: 11-15 missing argument: blue component -#test(rgb(0, 1), rgb("00ff00")) +--- +// Error: 6-11 invalid color +#rgb("lol") -// Error: 11-16 invalid color -#test(rgb("lol"), error) +--- +// Error: 6 missing argument: red component +#rgb() -// Error: 11 missing argument: red component -// Error: 11 missing argument: green component -// Error: 11 missing argument: blue component -#test(rgb(), black) +--- +// Error: 6-10 missing argument: blue component +#rgb(0, 1) diff --git a/tests/typ/utility/math.typ b/tests/typ/utility/math.typ index db234d9c..933f882f 100644 --- a/tests/typ/utility/math.typ +++ b/tests/typ/utility/math.typ @@ -8,8 +8,10 @@ #test(max(-3, 11), 11) #test(min("hi"), "hi") +--- // Error: 6 missing argument: value #min() +--- // Error: 11-18 cannot compare integer with string #test(min(1, "hi"), error) diff --git a/tests/typeset.rs b/tests/typeset.rs index 78577098..39ff9643 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -1,4 +1,3 @@ -use std::cell::RefCell; use std::env; use std::ffi::OsStr; use std::fs; @@ -11,20 +10,17 @@ use ttf_parser::{GlyphId, OutlineBuilder}; use walkdir::WalkDir; use typst::color::Color; -use typst::diag::{Diag, DiagSet, Level}; -use typst::eval::{eval, Scope, Value}; +use typst::diag::{Error, TypResult}; +use typst::eval::{eval, Value}; use typst::exec::{exec, State}; use typst::geom::{self, Length, PathElement, Point, Sides, Size}; use typst::image::ImageId; -use typst::layout::{layout, Element, Frame, Geometry, Paint, Text}; +use typst::layout::{layout, Element, Frame, Geometry, LayoutTree, Paint, Text}; use typst::loading::{FileId, FsLoader}; use typst::parse::{parse, LineMap, Scanner}; use typst::syntax::{Location, Pos}; use typst::Context; -#[cfg(feature = "layout-cache")] -use typst::layout::LayoutTree; - const TYP_DIR: &str = "./typ"; const REF_DIR: &str = "./ref"; const PNG_DIR: &str = "./png"; @@ -67,10 +63,22 @@ fn main() { page.size = Size::new(Length::pt(120.0), Length::inf()); page.margins = Sides::splat(Some(Length::pt(10.0).into())); - // We hook up some extra test helpers into the global scope. + // Hook up an assert function into the global scope. let mut std = typst::library::new(); - let panics = Rc::new(RefCell::new(vec![])); - register_helpers(&mut std, Rc::clone(&panics)); + std.def_func("test", move |_, args| { + let lhs = args.expect::<Value>("left-hand side")?; + let rhs = args.expect::<Value>("right-hand side")?; + if lhs != rhs { + typst::bail!( + args.file, + args.span, + "Assertion failed: {:?} != {:?}", + lhs, + rhs + ); + } + Ok(Value::None) + }); // Create loader and context. let loader = FsLoader::new().with_path(FONT_DIR).wrap(); @@ -88,7 +96,6 @@ fn main() { ok &= test( &mut ctx, loader.as_ref(), - &panics, &src_path, &png_path, &ref_path, @@ -134,35 +141,9 @@ impl Args { } } -type Panics = Rc<RefCell<Vec<Panic>>>; - -struct Panic { - pos: Pos, - lhs: Option<Value>, - rhs: Option<Value>, -} - -fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<Panic>>>) { - scope.def_const("error", Value::Error); - scope.def_func("args", |_, args| { - let repr = typst::pretty::pretty(args); - args.items.clear(); - Value::template(move |ctx| ctx.push_monospace_text(&repr)) - }); - scope.def_func("test", move |ctx, args| { - let lhs = args.expect::<Value>(ctx, "left-hand side"); - let rhs = args.expect::<Value>(ctx, "right-hand side"); - if lhs != rhs { - panics.borrow_mut().push(Panic { pos: args.span.start, lhs, rhs }); - } - Value::None - }); -} - fn test( ctx: &mut Context, loader: &FsLoader, - panics: &Panics, src_path: &Path, png_path: &Path, ref_path: &Path, @@ -171,8 +152,8 @@ fn test( let name = src_path.strip_prefix(TYP_DIR).unwrap_or(src_path); println!("Testing {}", name.display()); + let file = loader.resolve(src_path).unwrap(); let src = fs::read_to_string(src_path).unwrap(); - let src_id = loader.resolve(src_path).unwrap(); let mut ok = true; let mut frames = vec![]; @@ -196,7 +177,7 @@ fn test( } } else { let (part_ok, compare_here, part_frames) = - test_part(ctx, panics, src_id, part, i, compare_ref, lines); + test_part(ctx, file, part, i, compare_ref, lines); ok &= part_ok; compare_ever |= compare_here; frames.extend(part_frames); @@ -221,7 +202,7 @@ fn test( println!(" Does not match reference image. ❌"); ok = false; } - } else { + } else if !frames.is_empty() { println!(" Failed to open reference image. ❌"); ok = false; } @@ -236,71 +217,58 @@ fn test( fn test_part( ctx: &mut Context, - panics: &Panics, - src_id: FileId, + file: FileId, src: &str, i: usize, compare_ref: bool, lines: u32, ) -> (bool, bool, Vec<Rc<Frame>>) { let map = LineMap::new(src); - let (local_compare_ref, ref_diags) = parse_metadata(src, &map); + let (local_compare_ref, mut ref_errors) = parse_metadata(file, src, &map); let compare_ref = local_compare_ref.unwrap_or(compare_ref); - // Clear the module cache between tests. - ctx.modules.clear(); - - let ast = parse(src); - let module = eval(ctx, src_id, Rc::new(ast.output)); - let tree = exec(ctx, &module.output.template); - let mut frames = layout(ctx, &tree.output); + let mut ok = true; - let mut diags = ast.diags; - diags.extend(module.diags); - diags.extend(tree.diags); + let result = typeset(ctx, file, src); + let (frames, mut errors) = match result { + #[allow(unused_variables)] + Ok((tree, mut frames)) => { + #[cfg(feature = "layout-cache")] + (ok &= test_incremental(ctx, i, &tree, &frames)); - let mut ok = true; + if !compare_ref { + frames.clear(); + } - for panic in panics.borrow().iter() { - let line = map.location(panic.pos).unwrap().line; - println!(" Assertion failed in line {} ❌", lines + line); - if let (Some(lhs), Some(rhs)) = (&panic.lhs, &panic.rhs) { - println!(" Left: {:?}", lhs); - println!(" Right: {:?}", rhs); - } else { - println!(" Missing argument."); + (frames, vec![]) } - ok = false; - } + Err(errors) => (vec![], *errors), + }; - panics.borrow_mut().clear(); + // TODO: Also handle errors from other files. + errors.retain(|error| error.file == file); + ref_errors.sort(); + errors.sort(); - if diags != ref_diags { - println!(" Subtest {} does not match expected diagnostics. ❌", i); + if errors != ref_errors { + println!(" Subtest {} does not match expected errors. ❌", i); ok = false; - for diag in &diags { - if !ref_diags.contains(diag) { + for error in errors.iter() { + if error.file == file && !ref_errors.contains(error) { print!(" Not annotated | "); - print_diag(diag, &map, lines); + print_error(error, &map, lines); } } - for diag in &ref_diags { - if !diags.contains(diag) { + for error in ref_errors.iter() { + if !errors.contains(error) { print!(" Not emitted | "); - print_diag(diag, &map, lines); + print_error(error, &map, lines); } } } - #[cfg(feature = "layout-cache")] - (ok &= test_incremental(ctx, i, &tree.output, &frames)); - - if !compare_ref { - frames.clear(); - } - (ok, compare_ref, frames) } @@ -350,9 +318,9 @@ fn test_incremental( ok } -fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) { - let mut diags = DiagSet::new(); +fn parse_metadata(file: FileId, src: &str, map: &LineMap) -> (Option<bool>, Vec<Error>) { let mut compare_ref = None; + let mut errors = vec![]; let lines: Vec<_> = src.lines().map(str::trim).collect(); for (i, line) in lines.iter().enumerate() { @@ -364,10 +332,8 @@ fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) { compare_ref = Some(true); } - let (level, rest) = if let Some(rest) = line.strip_prefix("// Warning: ") { - (Level::Warning, rest) - } else if let Some(rest) = line.strip_prefix("// Error: ") { - (Level::Error, rest) + let rest = if let Some(rest) = line.strip_prefix("// Error: ") { + rest } else { continue; }; @@ -391,18 +357,30 @@ fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) { let start = pos(&mut s); let end = if s.eat_if('-') { pos(&mut s) } else { start }; - diags.insert(Diag::new(start .. end, level, s.rest().trim())); + errors.push(Error::new(file, start .. end, s.rest().trim())); } - (compare_ref, diags) + (compare_ref, errors) +} + +fn typeset( + ctx: &mut Context, + file: FileId, + src: &str, +) -> TypResult<(LayoutTree, Vec<Rc<Frame>>)> { + let ast = parse(file, src)?; + let module = eval(ctx, file, Rc::new(ast))?; + let tree = exec(ctx, &module.template); + let frames = layout(ctx, &tree); + Ok((tree, frames)) } -fn print_diag(diag: &Diag, map: &LineMap, lines: u32) { - let mut start = map.location(diag.span.start).unwrap(); - let mut end = map.location(diag.span.end).unwrap(); +fn print_error(error: &Error, map: &LineMap, lines: u32) { + let mut start = map.location(error.span.start).unwrap(); + let mut end = map.location(error.span.end).unwrap(); start.line += lines; end.line += lines; - println!("{}: {}-{}: {}", diag.level, start, end, diag.message); + println!("Error: {}-{}: {}", start, end, error.message); } fn draw(ctx: &Context, frames: &[Rc<Frame>], dpi: f32) -> sk::Pixmap { |
