mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-27 21:42:53 +00:00
LibWeb: Simplify standalone CSS math functions when used outside calc()
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Math functions like abs(), clamp(), round(), etc, can be used by themselves in property values, without wrapping them in calc(). Before this change, we were neglecting to run calc simplification on the generated calculation node trees. By doing that manually after parsing a standalone math function, we score at least a couple hundred WPT points.
This commit is contained in:
parent
94ae63c436
commit
0553bcb35b
Notes:
github-actions[bot]
2025-04-24 18:38:57 +00:00
Author: https://github.com/awesomekling
Commit: 0553bcb35b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4458
10 changed files with 1298 additions and 2 deletions
|
@ -3515,8 +3515,11 @@ RefPtr<CalculationNode const> Parser::parse_a_calc_function_node(Function const&
|
||||||
if (function.name.equals_ignoring_ascii_case("calc"sv))
|
if (function.name.equals_ignoring_ascii_case("calc"sv))
|
||||||
return parse_a_calculation(function.value, context);
|
return parse_a_calculation(function.value, context);
|
||||||
|
|
||||||
if (auto maybe_function = parse_math_function(function, context))
|
if (auto maybe_function = parse_math_function(function, context)) {
|
||||||
return maybe_function;
|
// NOTE: We have to simplify manually here, since parse_math_function() is a helper for calc() parsing
|
||||||
|
// that doesn't do it directly by itself.
|
||||||
|
return simplify_a_calculation_tree(*maybe_function, context, CalculationResolutionContext {});
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 17 tests
|
||||||
|
|
||||||
|
17 Pass
|
||||||
|
Pass Property letter-spacing value 'clamp(10px, 20px, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px, 5px, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px, 35px, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px, 35px , 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px, 35px /*foo*/, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px /* foo */ , 35px, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(10px , 35px, 30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(30px, 100px, 20px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(-30px, -20px, -10px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(-30px, -100px, -10px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(-30px, 100px, -10px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(-10px, 100px, -30px)'
|
||||||
|
Pass Property letter-spacing value 'clamp(-10px, -100px, -30px)'
|
||||||
|
Pass Property letter-spacing value 'calc(0px + clamp(10px, 20px, 30px))'
|
||||||
|
Pass Property letter-spacing value 'calc(0px - clamp(10px, 20px, 30px))'
|
||||||
|
Pass Property letter-spacing value 'calc(0px + clamp(30px, 100px, 20px))'
|
||||||
|
Pass Property letter-spacing value 'calc(0px - clamp(30px, 100px, 20px))'
|
|
@ -0,0 +1,37 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 32 tests
|
||||||
|
|
||||||
|
32 Pass
|
||||||
|
Pass min(1deg) should be used-value-equivalent to 1deg
|
||||||
|
Pass min(1grad) should be used-value-equivalent to 1grad
|
||||||
|
Pass min(1rad) should be used-value-equivalent to 1rad
|
||||||
|
Pass min(1turn) should be used-value-equivalent to 1turn
|
||||||
|
Pass max(1deg) should be used-value-equivalent to 1deg
|
||||||
|
Pass max(1grad) should be used-value-equivalent to 1grad
|
||||||
|
Pass max(1rad) should be used-value-equivalent to 1rad
|
||||||
|
Pass max(1turn) should be used-value-equivalent to 1turn
|
||||||
|
Pass min(1deg, 2deg) should be used-value-equivalent to 1deg
|
||||||
|
Pass min(1grad, 2grad) should be used-value-equivalent to 1grad
|
||||||
|
Pass min(1rad, 2rad) should be used-value-equivalent to 1rad
|
||||||
|
Pass min(1turn, 2turn) should be used-value-equivalent to 1turn
|
||||||
|
Pass max(1deg, 2deg) should be used-value-equivalent to 2deg
|
||||||
|
Pass max(1grad, 2grad) should be used-value-equivalent to 2grad
|
||||||
|
Pass max(1rad, 2rad) should be used-value-equivalent to 2rad
|
||||||
|
Pass max(1turn, 2turn) should be used-value-equivalent to 2turn
|
||||||
|
Pass min(90deg, 0.26turn) should be used-value-equivalent to 90deg
|
||||||
|
Pass min(1.57rad, 95deg) should be used-value-equivalent to 1.57rad
|
||||||
|
Pass max(91deg, 0.25turn) should be used-value-equivalent to 91deg
|
||||||
|
Pass max(1.58rad, 90deg) should be used-value-equivalent to 1.58rad
|
||||||
|
Pass min(270deg, max(0.25turn, 3.14rad)) should be used-value-equivalent to 3.14rad
|
||||||
|
Pass max(0.25turn, min(270deg, 3.14rad)) should be used-value-equivalent to 3.14rad
|
||||||
|
Pass calc(min(90deg, 1.58rad) + 0.125turn) should be used-value-equivalent to 135deg
|
||||||
|
Pass calc(min(90deg, 1.58rad) - 0.125turn) should be used-value-equivalent to 45deg
|
||||||
|
Pass calc(min(90deg, 1.58rad) * 1.5 should be used-value-equivalent to 135deg
|
||||||
|
Pass calc(min(90deg, 1.58rad) / 2 should be used-value-equivalent to 45deg
|
||||||
|
Pass calc(max(90deg, 1.56rad) + 0.125turn should be used-value-equivalent to 135deg
|
||||||
|
Pass calc(max(90deg, 1.56rad) - 0.125turn) should be used-value-equivalent to 45deg
|
||||||
|
Pass calc(max(90deg, 1.56rad) * 1.5 should be used-value-equivalent to 135deg
|
||||||
|
Pass calc(max(90deg, 1.56rad) / 2 should be used-value-equivalent to 45deg
|
||||||
|
Pass calc(min(90deg, 1.58rad) + max(0.125turn, 49grad)) should be used-value-equivalent to 135deg
|
||||||
|
Pass calc(min(90deg, 1.58rad) - max(0.25turn, 99grad)) should be used-value-equivalent to 0deg
|
|
@ -0,0 +1,235 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 229 tests
|
||||||
|
|
||||||
|
195 Pass
|
||||||
|
34 Fail
|
||||||
|
Pass round(10,10) should be used-value-equivalent to 10
|
||||||
|
Pass mod(1,1) should be used-value-equivalent to 0
|
||||||
|
Pass rem(1,1) should be used-value-equivalent to 0
|
||||||
|
Pass calc(round(100,10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(up, 101,10)) should be used-value-equivalent to 110
|
||||||
|
Pass calc(round(down, 106,10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(to-zero, 105, 10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(to-zero, -105, 10)) should be used-value-equivalent to -100
|
||||||
|
Pass calc(round(-100, 10)) should be used-value-equivalent to -100
|
||||||
|
Pass calc(round(up, -103, 10)) should be used-value-equivalent to -100
|
||||||
|
Pass round(up, 0, 5) should be used-value-equivalent to 0
|
||||||
|
Pass round(down, 0, 5) should be used-value-equivalent to 0
|
||||||
|
Pass round(nearest, 0, 5) should be used-value-equivalent to 0
|
||||||
|
Pass round(to-zero, 0, 5) should be used-value-equivalent to 0
|
||||||
|
Pass round(up, 5, 5) should be used-value-equivalent to 5
|
||||||
|
Pass round(down, 5, 5) should be used-value-equivalent to 5
|
||||||
|
Pass round(nearest, 5, 5) should be used-value-equivalent to 5
|
||||||
|
Pass round(to-zero, 5, 5) should be used-value-equivalent to 5
|
||||||
|
Pass round(up, -5, 5) should be used-value-equivalent to -5
|
||||||
|
Pass round(down, -5, 5) should be used-value-equivalent to -5
|
||||||
|
Pass round(nearest, -5, 5) should be used-value-equivalent to -5
|
||||||
|
Pass round(to-zero, -5, 5) should be used-value-equivalent to -5
|
||||||
|
Pass round(up, 10, 5) should be used-value-equivalent to 10
|
||||||
|
Pass round(down, 10, 5) should be used-value-equivalent to 10
|
||||||
|
Pass round(nearest, 10, 5) should be used-value-equivalent to 10
|
||||||
|
Pass round(to-zero, 10, 5) should be used-value-equivalent to 10
|
||||||
|
Pass round(up, -10, 5) should be used-value-equivalent to -10
|
||||||
|
Pass round(down, -10, 5) should be used-value-equivalent to -10
|
||||||
|
Pass round(nearest, -10, 5) should be used-value-equivalent to -10
|
||||||
|
Pass round(to-zero, -10, 5) should be used-value-equivalent to -10
|
||||||
|
Pass round(up, 20, 5) should be used-value-equivalent to 20
|
||||||
|
Pass round(down, 20, 5) should be used-value-equivalent to 20
|
||||||
|
Pass round(nearest, 20, 5) should be used-value-equivalent to 20
|
||||||
|
Pass round(to-zero, 20, 5) should be used-value-equivalent to 20
|
||||||
|
Pass round(up, -20, 5) should be used-value-equivalent to -20
|
||||||
|
Pass round(down, -20, 5) should be used-value-equivalent to -20
|
||||||
|
Pass round(nearest, -20, 5) should be used-value-equivalent to -20
|
||||||
|
Pass round(to-zero, -20, 5) should be used-value-equivalent to -20
|
||||||
|
Pass mod(18,5) should be used-value-equivalent to 3
|
||||||
|
Pass rem(18,5) should be used-value-equivalent to 3
|
||||||
|
Pass mod(-140,-90) should be used-value-equivalent to -50
|
||||||
|
Pass mod(-18,5) should be used-value-equivalent to 2
|
||||||
|
Pass rem(-18,5) should be used-value-equivalent to -3
|
||||||
|
Pass mod(140,-90) should be used-value-equivalent to -40
|
||||||
|
Pass rem(140,-90) should be used-value-equivalent to 50
|
||||||
|
Pass calc(round(round(100,10), 10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(up, round(100,10) + 1,10)) should be used-value-equivalent to 110
|
||||||
|
Pass calc(round(down, round(100,10) + 2 * 3,10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(to-zero,round(100,10) * 2 - 95, 10)) should be used-value-equivalent to 100
|
||||||
|
Pass calc(round(round(100,10)* -1,10)) should be used-value-equivalent to -100
|
||||||
|
Pass calc(round(up, -103 + -103 / -103 - 1,10)) should be used-value-equivalent to -100
|
||||||
|
Pass calc(mod(18,5) * 2 + mod(17,5)) should be used-value-equivalent to 8
|
||||||
|
Pass calc(rem(mod(18,5),5)) should be used-value-equivalent to 3
|
||||||
|
Pass calc(rem(mod(18,5),mod(17,5))) should be used-value-equivalent to 1
|
||||||
|
Pass calc(mod(-140,-90)) should be used-value-equivalent to -50
|
||||||
|
Pass calc(mod(rem(1,18)* -1,5)) should be used-value-equivalent to 4
|
||||||
|
Pass round(10px,6px) should be used-value-equivalent to 12px
|
||||||
|
Fail round(10cm,6cm) should be used-value-equivalent to 12cm
|
||||||
|
Fail round(10mm,6mm) should be used-value-equivalent to 12mm
|
||||||
|
Pass round(10Q, 6Q) should be used-value-equivalent to 12Q
|
||||||
|
Pass round(10in,6in) should be used-value-equivalent to 12in
|
||||||
|
Pass round(10pc,6pc) should be used-value-equivalent to 12pc
|
||||||
|
Pass round(10pt,6pt) should be used-value-equivalent to 12pt
|
||||||
|
Pass round(10em,6em) should be used-value-equivalent to 12em
|
||||||
|
Pass round(10ex,6ex) should be used-value-equivalent to 12ex
|
||||||
|
Pass round(10ch,6ch) should be used-value-equivalent to 12ch
|
||||||
|
Pass round(10rem,6rem) should be used-value-equivalent to 12rem
|
||||||
|
Pass round(10vh,6vh) should be used-value-equivalent to 12vh
|
||||||
|
Pass round(10vw,6vw) should be used-value-equivalent to 12vw
|
||||||
|
Pass round(10vmin,6vmin) should be used-value-equivalent to 12vmin
|
||||||
|
Pass round(10vmax,6vmax) should be used-value-equivalent to 12vmax
|
||||||
|
Pass round(10s,6s) should be used-value-equivalent to 12s
|
||||||
|
Pass round(10ms,6ms) should be used-value-equivalent to 12ms
|
||||||
|
Pass round(10deg,6deg) should be used-value-equivalent to 12deg
|
||||||
|
Pass round(10grad,6grad) should be used-value-equivalent to 12grad
|
||||||
|
Pass round(10rad,6rad) should be used-value-equivalent to 12rad
|
||||||
|
Pass round(10turn,6turn) should be used-value-equivalent to 12turn
|
||||||
|
Pass mod(10px,6px) should be used-value-equivalent to 4px
|
||||||
|
Pass mod(10cm,6cm) should be used-value-equivalent to 4cm
|
||||||
|
Pass mod(10mm,6mm) should be used-value-equivalent to 4mm
|
||||||
|
Pass mod(10Q, 6Q) should be used-value-equivalent to 4Q
|
||||||
|
Pass mod(10in,6in) should be used-value-equivalent to 4in
|
||||||
|
Pass mod(10pc,6pc) should be used-value-equivalent to 4pc
|
||||||
|
Pass mod(10em,6em) should be used-value-equivalent to 4em
|
||||||
|
Pass mod(10ex,6ex) should be used-value-equivalent to 4ex
|
||||||
|
Pass mod(10ch,6ch) should be used-value-equivalent to 4ch
|
||||||
|
Pass mod(10rem,6rem) should be used-value-equivalent to 4rem
|
||||||
|
Pass mod(10vh,6vh) should be used-value-equivalent to 4vh
|
||||||
|
Pass mod(10vw,6vw) should be used-value-equivalent to 4vw
|
||||||
|
Pass mod(10vmin,6vmin) should be used-value-equivalent to 4vmin
|
||||||
|
Pass mod(10vmax,6vmax) should be used-value-equivalent to 4vmax
|
||||||
|
Pass mod(10s,6s) should be used-value-equivalent to 4s
|
||||||
|
Pass mod(10ms,6ms) should be used-value-equivalent to 4ms
|
||||||
|
Pass mod(10deg,6deg) should be used-value-equivalent to 4deg
|
||||||
|
Pass mod(10grad,6grad) should be used-value-equivalent to 4grad
|
||||||
|
Pass mod(10rad,6rad) should be used-value-equivalent to 4rad
|
||||||
|
Pass mod(10turn,6turn) should be used-value-equivalent to 4turn
|
||||||
|
Pass rem(10px,6px) should be used-value-equivalent to 4px
|
||||||
|
Pass rem(10cm,6cm) should be used-value-equivalent to 4cm
|
||||||
|
Pass rem(10mm,6mm) should be used-value-equivalent to 4mm
|
||||||
|
Pass rem(10Q, 6Q) should be used-value-equivalent to 4Q
|
||||||
|
Pass rem(10in,6in) should be used-value-equivalent to 4in
|
||||||
|
Pass rem(10pc,6pc) should be used-value-equivalent to 4pc
|
||||||
|
Pass rem(10em,6em) should be used-value-equivalent to 4em
|
||||||
|
Pass rem(10ex,6ex) should be used-value-equivalent to 4ex
|
||||||
|
Pass rem(10ch,6ch) should be used-value-equivalent to 4ch
|
||||||
|
Pass rem(10rem,6rem) should be used-value-equivalent to 4rem
|
||||||
|
Pass rem(10vh,6vh) should be used-value-equivalent to 4vh
|
||||||
|
Pass rem(10vw,6vw) should be used-value-equivalent to 4vw
|
||||||
|
Pass rem(10vmin,6vmin) should be used-value-equivalent to 4vmin
|
||||||
|
Pass rem(10vmax,6vmax) should be used-value-equivalent to 4vmax
|
||||||
|
Pass rem(10s,6s) should be used-value-equivalent to 4s
|
||||||
|
Pass rem(10ms,6ms) should be used-value-equivalent to 4ms
|
||||||
|
Pass rem(10deg,6deg) should be used-value-equivalent to 4deg
|
||||||
|
Pass rem(10grad,6grad) should be used-value-equivalent to 4grad
|
||||||
|
Pass rem(10rad,6rad) should be used-value-equivalent to 4rad
|
||||||
|
Pass rem(10turn,6turn) should be used-value-equivalent to 4turn
|
||||||
|
Fail round(10%,1px) should be used-value-equivalent to 8px
|
||||||
|
Fail round(10%,5px) should be used-value-equivalent to 10px
|
||||||
|
Pass round(2rem,5px) should be used-value-equivalent to 30px
|
||||||
|
Pass round(100px,1rem) should be used-value-equivalent to 96px
|
||||||
|
Pass round(10s,6000ms) should be used-value-equivalent to 12s
|
||||||
|
Pass round(10000ms,6s) should be used-value-equivalent to 12s
|
||||||
|
Fail mod(10%,1px) should be used-value-equivalent to 0.5px
|
||||||
|
Fail mod(10%,5px) should be used-value-equivalent to 2.5px
|
||||||
|
Pass mod(2rem,5px) should be used-value-equivalent to 2px
|
||||||
|
Pass mod(100px,1rem) should be used-value-equivalent to 4px
|
||||||
|
Pass mod(10s,6000ms) should be used-value-equivalent to 4s
|
||||||
|
Pass mod(10000ms,6s) should be used-value-equivalent to 4s
|
||||||
|
Fail mod(18px,100% / 15) should be used-value-equivalent to 3px
|
||||||
|
Fail mod(-18px,100% / 10) should be used-value-equivalent to 4.5px
|
||||||
|
Pass mod(18%,5%) should be used-value-equivalent to 3%
|
||||||
|
Pass mod(-19%,5%) should be used-value-equivalent to 1%
|
||||||
|
Pass mod(18vw,5vw) should be used-value-equivalent to 3vw
|
||||||
|
Pass mod(-18vw,5vw) should be used-value-equivalent to 2vw
|
||||||
|
Fail rem(10%,1px) should be used-value-equivalent to 0.5px
|
||||||
|
Fail rem(10%,5px) should be used-value-equivalent to 2.5px
|
||||||
|
Pass rem(2rem,5px) should be used-value-equivalent to 2px
|
||||||
|
Pass rem(100px,1rem) should be used-value-equivalent to 4px
|
||||||
|
Pass rem(10s,6000ms) should be used-value-equivalent to 4s
|
||||||
|
Pass rem(10000ms,6s) should be used-value-equivalent to 4s
|
||||||
|
Fail rem(18px,100% / 15) should be used-value-equivalent to 3px
|
||||||
|
Fail rem(-18px,100% / 15) should be used-value-equivalent to -3px
|
||||||
|
Pass rem(18vw,5vw) should be used-value-equivalent to 3vw
|
||||||
|
Pass rem(-18vw,5vw) should be used-value-equivalent to -3vw
|
||||||
|
Pass calc(round(1px + 0%, 1px + 0%)) should be used-value-equivalent to 1px
|
||||||
|
Pass calc(mod(3px + 0%, 2px + 0%)) should be used-value-equivalent to 1px
|
||||||
|
Pass calc(rem(3px + 0%, 2px + 0%)) should be used-value-equivalent to 1px
|
||||||
|
Pass round(1px + 0%, 1px) should be used-value-equivalent to 1px
|
||||||
|
Fail mod(3px + 0%, 2px) should be used-value-equivalent to 1px
|
||||||
|
Fail rem(3px + 0%, 2px) should be used-value-equivalent to 1px
|
||||||
|
Pass round(0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(-0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(-Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(-4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(-Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(-Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(-0, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(-Infinity, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(-4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(4, 0) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(-Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(Infinity, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass rem(-Infinity, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass round(up, Infinity, 4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(up, -Infinity, 4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(up, Infinity, -4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(up, -Infinity, -4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(down, Infinity, 4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(down, -Infinity, 4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(down, Infinity, -4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(down, -Infinity, -4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(nearest, Infinity, 4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(nearest, -Infinity, 4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(nearest, Infinity, -4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(nearest, -Infinity, -4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(to-zero, Infinity, 4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(to-zero, -Infinity, 4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(to-zero, Infinity, -4) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(to-zero, -Infinity, -4) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass round(nearest, 0, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(nearest, 4, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(nearest, -0, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(nearest, -4, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Pass round(nearest, 0, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(nearest, 4, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(nearest, -0, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(nearest, -4, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Pass round(to-zero, 0, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(to-zero, 4, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(to-zero, -0, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(to-zero, -4, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Pass round(to-zero, 0, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(to-zero, 4, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(to-zero, -0, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(to-zero, -4, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(up, 1, Infinity) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(up, 0, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(up, -1, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(up, 1, -Infinity) should be used-value-equivalent to calc(Infinity)
|
||||||
|
Pass round(up, 0, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(up, -1, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Fail round(down, 1, Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Pass round(down, 0, Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(down, -1, Infinity) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Fail round(down, 1, -Infinity) should be used-value-equivalent to calc(-0)
|
||||||
|
Pass round(down, 0, -Infinity) should be used-value-equivalent to 0
|
||||||
|
Fail round(down, -1, -Infinity) should be used-value-equivalent to calc(-Infinity)
|
||||||
|
Pass mod(-0, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(0, -Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(-4, Infinity) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass mod(4, -Infinity) should be used-value-equivalent to calc(NaN)
|
|
@ -0,0 +1,239 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 233 tests
|
||||||
|
|
||||||
|
120 Pass
|
||||||
|
113 Fail
|
||||||
|
Pass abs(1) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1) should be used-value-equivalent to 1
|
||||||
|
Pass abs(-1) should be used-value-equivalent to 1
|
||||||
|
Pass sign(-1) should be used-value-equivalent to -1
|
||||||
|
Pass abs(sign(1)) should be used-value-equivalent to 1
|
||||||
|
Pass abs(sign(sign(1))) should be used-value-equivalent to 1
|
||||||
|
Pass sign(sign(sign(1) + sign(1))) should be used-value-equivalent to 1
|
||||||
|
Pass calc(abs(0.1 + 0.2) + 0.05) should be used-value-equivalent to 0.35
|
||||||
|
Pass calc(sign(0.1 + 0.2) - 0.05) should be used-value-equivalent to 0.95
|
||||||
|
Pass calc(abs(0.1 + 0.2) * 2) should be used-value-equivalent to 0.6
|
||||||
|
Pass calc(abs(sign(0.1) + 0.2) / 2) should be used-value-equivalent to 0.6
|
||||||
|
Pass calc(abs(0.1 + 0.2) * -2) should be used-value-equivalent to -0.6
|
||||||
|
Pass calc(sign(0.1 - 0.2) - 0.05) should be used-value-equivalent to -1.05
|
||||||
|
Pass calc(sign(1) + sign(1) - 0.05) should be used-value-equivalent to 1.95
|
||||||
|
Pass abs(10px) should be used-value-equivalent to 10px
|
||||||
|
Fail abs(10%) should be used-value-equivalent to 10px
|
||||||
|
Fail abs(10px + 10%) should be used-value-equivalent to 20px
|
||||||
|
Fail calc(10px + abs(10%)) should be used-value-equivalent to 20px
|
||||||
|
Pass abs(-10px) should be used-value-equivalent to 10px
|
||||||
|
Fail abs(-10%) should be used-value-equivalent to 10px
|
||||||
|
Fail calc((1em + 1px) * (sign(1em - 10px - 10%) + 1)) should be used-value-equivalent to 21px
|
||||||
|
Pass calc(calc(sign(-0))) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(calc(sign(-0)))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(calc(sign(0))) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(calc(sign(0)))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass abs(infinity) should be used-value-equivalent to calc(infinity)
|
||||||
|
Pass abs(-infinity) should be used-value-equivalent to calc(infinity)
|
||||||
|
Pass abs(NaN) should be used-value-equivalent to calc(NaN)
|
||||||
|
Pass calc(20 - abs(-10)) should be used-value-equivalent to 10
|
||||||
|
Pass calc(20 - abs(10)) should be used-value-equivalent to 10
|
||||||
|
Pass calc(10 - abs(10 - abs(-30)) should be used-value-equivalent to -10
|
||||||
|
Pass calc(2 - sign(1)) should be used-value-equivalent to 1
|
||||||
|
Pass calc(2 - sign(-1)) should be used-value-equivalent to 3
|
||||||
|
Pass calc(2 - sign(1 - sign(-1))) should be used-value-equivalent to 1
|
||||||
|
Pass calc(10 - abs(20 - sign(2 - abs(-20)))) should be used-value-equivalent to -11
|
||||||
|
Pass sign(1px) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1cm) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1mm) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1Q) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1in) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1pc) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1pt) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1em) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1ex) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1ch) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1rem) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1vh) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1vw) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1vmin) should be used-value-equivalent to 1
|
||||||
|
Fail sign(1vmax) should be used-value-equivalent to 1
|
||||||
|
Pass sign(-1px) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1cm) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1mm) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1Q) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1in) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1pc) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1pt) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1em) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1ex) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1ch) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1rem) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1vh) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1vw) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1vmin) should be used-value-equivalent to -1
|
||||||
|
Fail sign(-1vmax) should be used-value-equivalent to -1
|
||||||
|
Pass sign(1s) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1ms) should be used-value-equivalent to 1
|
||||||
|
Pass sign(-1s) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1ms) should be used-value-equivalent to -1
|
||||||
|
Pass sign(1deg) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1grad) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1rad) should be used-value-equivalent to 1
|
||||||
|
Pass sign(1turn) should be used-value-equivalent to 1
|
||||||
|
Pass sign(-1deg) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1grad) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1rad) should be used-value-equivalent to -1
|
||||||
|
Pass sign(-1turn) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(0px)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0px))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0cm)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0cm))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0mm)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0mm))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0Q)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0Q))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0in)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0in))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0pc)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0pc))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0pt)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0pt))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0em)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0em))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0ex)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0ex))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0ch)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0ch))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0rem)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0rem))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0vh)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0vh))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0vw)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0vw))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0vmin)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0vmin))), 1) should be used-value-equivalent to 1
|
||||||
|
Fail calc(sign(0vmax)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(0vmax))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(-0px)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0px))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0cm)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0cm))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0mm)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0mm))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0Q)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0Q))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0in)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0in))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0pc)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0pc))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0pt)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0pt))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0em)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0em))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0ex)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0ex))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0ch)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0ch))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0rem)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0rem))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0vh)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0vh))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0vw)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0vw))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0vmin)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0vmin))), 1) should be used-value-equivalent to -1
|
||||||
|
Fail calc(sign(-0vmax)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0vmax))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(0s)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0s))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0ms)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0ms))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(-0s)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0s))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0ms)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0ms))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(0deg)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0deg))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0grad)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0grad))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0rad)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0rad))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(0turn)) should be used-value-equivalent to 0
|
||||||
|
Pass clamp(-1, calc( 1 / sign(sign(0turn))), 1) should be used-value-equivalent to 1
|
||||||
|
Pass calc(sign(-0deg)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0deg))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0grad)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0grad))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0rad)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0rad))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass calc(sign(-0turn)) should be used-value-equivalent to 0
|
||||||
|
Fail clamp(-1, calc( 1 / sign(sign(-0turn))), 1) should be used-value-equivalent to -1
|
||||||
|
Pass abs(1px) should be used-value-equivalent to 1px
|
||||||
|
Pass abs(1cm) should be used-value-equivalent to 1cm
|
||||||
|
Pass abs(1mm) should be used-value-equivalent to 1mm
|
||||||
|
Pass abs(1Q) should be used-value-equivalent to 1Q
|
||||||
|
Pass abs(1in) should be used-value-equivalent to 1in
|
||||||
|
Pass abs(1pc) should be used-value-equivalent to 1pc
|
||||||
|
Pass abs(1pt) should be used-value-equivalent to 1pt
|
||||||
|
Fail abs(1em) should be used-value-equivalent to 1em
|
||||||
|
Fail abs(1ex) should be used-value-equivalent to 1ex
|
||||||
|
Fail abs(1ch) should be used-value-equivalent to 1ch
|
||||||
|
Fail abs(1rem) should be used-value-equivalent to 1rem
|
||||||
|
Fail abs(1vh) should be used-value-equivalent to 1vh
|
||||||
|
Fail abs(1vw) should be used-value-equivalent to 1vw
|
||||||
|
Fail abs(1vmin) should be used-value-equivalent to 1vmin
|
||||||
|
Fail abs(1vmax) should be used-value-equivalent to 1vmax
|
||||||
|
Pass abs(-1px) should be used-value-equivalent to 1px
|
||||||
|
Pass abs(-1cm) should be used-value-equivalent to 1cm
|
||||||
|
Pass abs(-1mm) should be used-value-equivalent to 1mm
|
||||||
|
Pass abs(-1Q) should be used-value-equivalent to 1Q
|
||||||
|
Pass abs(-1in) should be used-value-equivalent to 1in
|
||||||
|
Pass abs(-1pc) should be used-value-equivalent to 1pc
|
||||||
|
Pass abs(-1pt) should be used-value-equivalent to 1pt
|
||||||
|
Fail abs(-1em) should be used-value-equivalent to 1em
|
||||||
|
Fail abs(-1ex) should be used-value-equivalent to 1ex
|
||||||
|
Fail abs(-1ch) should be used-value-equivalent to 1ch
|
||||||
|
Fail abs(-1rem) should be used-value-equivalent to 1rem
|
||||||
|
Fail abs(-1vh) should be used-value-equivalent to 1vh
|
||||||
|
Fail abs(-1vw) should be used-value-equivalent to 1vw
|
||||||
|
Fail abs(-1vmin) should be used-value-equivalent to 1vmin
|
||||||
|
Fail abs(-1vmax) should be used-value-equivalent to 1vmax
|
||||||
|
Pass abs(1s) should be used-value-equivalent to 1s
|
||||||
|
Pass abs(1ms) should be used-value-equivalent to 1ms
|
||||||
|
Pass abs(-1s) should be used-value-equivalent to 1s
|
||||||
|
Pass abs(-1ms) should be used-value-equivalent to 1ms
|
||||||
|
Pass abs(1deg) should be used-value-equivalent to 1deg
|
||||||
|
Pass abs(1grad) should be used-value-equivalent to 1grad
|
||||||
|
Pass abs(1rad) should be used-value-equivalent to 1rad
|
||||||
|
Pass abs(1turn) should be used-value-equivalent to 1turn
|
||||||
|
Pass abs(-1deg) should be used-value-equivalent to 1deg
|
||||||
|
Pass abs(-1grad) should be used-value-equivalent to 1grad
|
||||||
|
Pass abs(-1rad) should be used-value-equivalent to 1rad
|
||||||
|
Pass abs(-1turn) should be used-value-equivalent to 1turn
|
||||||
|
Fail sign(10px - 1em) should be used-value-equivalent to 0; fontSize=10px
|
||||||
|
Fail sign(10px - 2em) should be used-value-equivalent to -1; fontSize=10px
|
||||||
|
Fail calc(sign(10%) * 100px) should be used-value-equivalent to 100px
|
||||||
|
Fail calc(2.5 - sign(41px - 2em) / 2) should be used-value-equivalent to 2
|
||||||
|
Fail calc(2.5 - sign(40px - 2em) / 2) should be used-value-equivalent to 2.5
|
||||||
|
Fail calc(2.5 - sign(39px - 2em) / 2) should be used-value-equivalent to 3
|
||||||
|
Fail calc(3 + sign(42px - 2em)) should be used-value-equivalent to 4
|
||||||
|
Fail calc(3 + sign(40px - 2em)) should be used-value-equivalent to 3
|
||||||
|
Fail calc(3 + sign(38px - 2em)) should be used-value-equivalent to 2
|
||||||
|
Fail calc(50px + 100px * sign(42px - 2em)) should be used-value-equivalent to 150px
|
||||||
|
Fail calc(50px + 100px * sign(40px - 2em)) should be used-value-equivalent to 50px
|
||||||
|
Fail calc(50px + 100px * sign(38px - 2em)) should be used-value-equivalent to -50px
|
||||||
|
Fail calc(90deg + 30deg * sign(42px - 2em)) should be used-value-equivalent to 120deg
|
||||||
|
Fail calc(90deg + 30deg * sign(40px - 2em)) should be used-value-equivalent to 90deg
|
||||||
|
Fail calc(90deg + 30deg * sign(38px - 2em)) should be used-value-equivalent to 60deg
|
||||||
|
Fail calc(5s + 15s * sign(42px - 2em)) should be used-value-equivalent to 20s
|
||||||
|
Fail calc(5s + 15s * sign(40px - 2em)) should be used-value-equivalent to 5s
|
||||||
|
Fail calc(5s + 15s * sign(38px - 2em)) should be used-value-equivalent to -10s
|
||||||
|
Fail calc(100dpi + 20dpi * sign(42px - 2em)) should be used-value-equivalent to 120dpi
|
||||||
|
Fail calc(100dpi + 20dpi * sign(40px - 2em)) should be used-value-equivalent to 100dpi
|
||||||
|
Fail calc(100dpi + 20dpi * sign(38px - 2em)) should be used-value-equivalent to 80dpi
|
||||||
|
Fail calc(3fr + 1fr * sign(42px - 2em)) should be used-value-equivalent to 4fr
|
||||||
|
Fail calc(3fr + 1fr * sign(40px - 2em)) should be used-value-equivalent to 3fr
|
||||||
|
Fail calc(3fr + 1fr * sign(38px - 2em)) should be used-value-equivalent to 2fr
|
||||||
|
Fail calc(2.5 - sign(33px - 2rem) / 2) should be used-value-equivalent to 2
|
||||||
|
Fail calc(2.5 - sign(32px - 2rem) / 2) should be used-value-equivalent to 2.5
|
||||||
|
Fail calc(2.5 - sign(31px - 2rem) / 2) should be used-value-equivalent to 3
|
||||||
|
Fail calc(50px + 100px * sign(34px - 2rem)) should be used-value-equivalent to 150px
|
||||||
|
Fail calc(50px + 100px * sign(32px - 2rem)) should be used-value-equivalent to 50px
|
||||||
|
Fail calc(50px + 100px * sign(30px - 2rem)) should be used-value-equivalent to -50px
|
|
@ -0,0 +1,47 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
|
||||||
|
<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../support/computed-testcommon.js"></script>
|
||||||
|
<div id="container" style="font-size: 20px">
|
||||||
|
<div id="target"></div>
|
||||||
|
<div id="reference"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const property = 'letter-spacing';
|
||||||
|
|
||||||
|
function test_length_equals(value, expected) {
|
||||||
|
const reference = document.getElementById('reference');
|
||||||
|
reference.style[property] = '';
|
||||||
|
reference.style[property] = expected;
|
||||||
|
const computed = getComputedStyle(reference)[property];
|
||||||
|
test_computed_value(property, value, computed);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_length_equals('clamp(10px, 20px, 30px)', '20px');
|
||||||
|
test_length_equals('clamp(10px, 5px, 30px)', '10px');
|
||||||
|
test_length_equals('clamp(10px, 35px, 30px)', '30px');
|
||||||
|
test_length_equals('clamp(10px, 35px , 30px)', '30px');
|
||||||
|
test_length_equals('clamp(10px, 35px /*foo*/, 30px)', '30px');
|
||||||
|
test_length_equals('clamp(10px /* foo */ , 35px, 30px)', '30px');
|
||||||
|
test_length_equals('clamp(10px , 35px, 30px)', '30px');
|
||||||
|
|
||||||
|
// clamp(MIN, VAL, MAX) is identical to max(MIN, min(VAL, MAX)),
|
||||||
|
// so MIN wins over MAX if they are in the wrong order.
|
||||||
|
test_length_equals('clamp(30px, 100px, 20px)', '30px');
|
||||||
|
|
||||||
|
// also test with negative values
|
||||||
|
test_length_equals('clamp(-30px, -20px, -10px)', '-20px');
|
||||||
|
test_length_equals('clamp(-30px, -100px, -10px)', '-30px');
|
||||||
|
test_length_equals('clamp(-30px, 100px, -10px)', '-10px');
|
||||||
|
test_length_equals('clamp(-10px, 100px, -30px)', '-10px');
|
||||||
|
test_length_equals('clamp(-10px, -100px, -30px)', '-10px');
|
||||||
|
|
||||||
|
// and negating the result of clamp
|
||||||
|
test_length_equals('calc(0px + clamp(10px, 20px, 30px))', '20px');
|
||||||
|
test_length_equals('calc(0px - clamp(10px, 20px, 30px))', '-20px');
|
||||||
|
test_length_equals('calc(0px + clamp(30px, 100px, 20px))', '30px');
|
||||||
|
test_length_equals('calc(0px - clamp(30px, 100px, 20px))', '-30px');
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
|
||||||
|
<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../support/numeric-testcommon.js"></script>
|
||||||
|
<div id="target"></div>
|
||||||
|
<div id="reference"></div>
|
||||||
|
<script>
|
||||||
|
function test_angle_equals(value, expected) {
|
||||||
|
test_math_used(value, expected, {type: "angle"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identity tests
|
||||||
|
test_angle_equals('min(1deg)', '1deg');
|
||||||
|
test_angle_equals('min(1grad)', '1grad');
|
||||||
|
test_angle_equals('min(1rad)', '1rad');
|
||||||
|
test_angle_equals('min(1turn)', '1turn');
|
||||||
|
test_angle_equals('max(1deg)', '1deg');
|
||||||
|
test_angle_equals('max(1grad)', '1grad');
|
||||||
|
test_angle_equals('max(1rad)', '1rad');
|
||||||
|
test_angle_equals('max(1turn)', '1turn');
|
||||||
|
|
||||||
|
// Comparisons between same units
|
||||||
|
test_angle_equals('min(1deg, 2deg)', '1deg');
|
||||||
|
test_angle_equals('min(1grad, 2grad)', '1grad');
|
||||||
|
test_angle_equals('min(1rad, 2rad)', '1rad');
|
||||||
|
test_angle_equals('min(1turn, 2turn)', '1turn');
|
||||||
|
test_angle_equals('max(1deg, 2deg)', '2deg');
|
||||||
|
test_angle_equals('max(1grad, 2grad)', '2grad');
|
||||||
|
test_angle_equals('max(1rad, 2rad)', '2rad');
|
||||||
|
test_angle_equals('max(1turn, 2turn)', '2turn');
|
||||||
|
|
||||||
|
// Comparisons between different units
|
||||||
|
test_angle_equals('min(90deg, 0.26turn)', '90deg');
|
||||||
|
test_angle_equals('min(1.57rad, 95deg)', '1.57rad');
|
||||||
|
test_angle_equals('max(91deg, 0.25turn)', '91deg');
|
||||||
|
test_angle_equals('max(1.58rad, 90deg)', '1.58rad');
|
||||||
|
|
||||||
|
// Nestings
|
||||||
|
test_angle_equals('min(270deg, max(0.25turn, 3.14rad))', '3.14rad');
|
||||||
|
test_angle_equals('max(0.25turn, min(270deg, 3.14rad))', '3.14rad');
|
||||||
|
|
||||||
|
// General calculations
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) + 0.125turn)', '135deg');
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) - 0.125turn)', '45deg');
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) * 1.5', '135deg');
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) / 2', '45deg');
|
||||||
|
test_angle_equals('calc(max(90deg, 1.56rad) + 0.125turn', '135deg');
|
||||||
|
test_angle_equals('calc(max(90deg, 1.56rad) - 0.125turn)', '45deg');
|
||||||
|
test_angle_equals('calc(max(90deg, 1.56rad) * 1.5', '135deg');
|
||||||
|
test_angle_equals('calc(max(90deg, 1.56rad) / 2', '45deg');
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) + max(0.125turn, 49grad))', '135deg');
|
||||||
|
test_angle_equals('calc(min(90deg, 1.58rad) - max(0.25turn, 99grad))', '0deg');
|
||||||
|
</script>
|
|
@ -0,0 +1,218 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#round-func">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
|
||||||
|
<link rel="author" title="Apple Inc">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../support/numeric-testcommon.js"></script>
|
||||||
|
<div style="width: 75px;">
|
||||||
|
<div id="target"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// Simple tests
|
||||||
|
test_math_used('round(10,10)', '10', {type:'number'});
|
||||||
|
test_math_used('mod(1,1)', '0', {type:'number'});
|
||||||
|
test_math_used('rem(1,1)', '0', {type:'number'});
|
||||||
|
|
||||||
|
// Test basic round
|
||||||
|
test_math_used('calc(round(100,10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(up, 101,10))', '110', {type:'number'});
|
||||||
|
test_math_used('calc(round(down, 106,10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(to-zero, 105, 10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(to-zero, -105, 10))', '-100', {type:'number'});
|
||||||
|
test_math_used('calc(round(-100, 10))', '-100', {type:'number'});
|
||||||
|
test_math_used('calc(round(up, -103, 10))', '-100', {type:'number'});
|
||||||
|
|
||||||
|
// Test round when first number is a multiple of the second number.
|
||||||
|
for (let number of [0, 5, -5, 10, -10, 20, -20]) {
|
||||||
|
test_math_used(`round(up, ${number}, 5)`, `${number}`, {type:'number'});
|
||||||
|
test_math_used(`round(down, ${number}, 5)`, `${number}`, {type:'number'});
|
||||||
|
test_math_used(`round(nearest, ${number}, 5)`, `${number}`, {type:'number'});
|
||||||
|
test_math_used(`round(to-zero, ${number}, 5)`, `${number}`, {type:'number'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test basic mod/rem
|
||||||
|
test_math_used('mod(18,5)', '3', {type:'number'});
|
||||||
|
test_math_used('rem(18,5)', '3', {type:'number'});
|
||||||
|
test_math_used('mod(-140,-90)', '-50', {type:'number'});
|
||||||
|
test_math_used('mod(-18,5)', '2', {type:'number'});
|
||||||
|
test_math_used('rem(-18,5)', '-3', {type:'number'});
|
||||||
|
test_math_used('mod(140,-90)', '-40', {type:'number'});
|
||||||
|
test_math_used('rem(140,-90)', '50', {type:'number'});
|
||||||
|
|
||||||
|
// Test basic calculations
|
||||||
|
test_math_used('calc(round(round(100,10), 10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(up, round(100,10) + 1,10))', '110', {type:'number'});
|
||||||
|
test_math_used('calc(round(down, round(100,10) + 2 * 3,10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(to-zero,round(100,10) * 2 - 95, 10))', '100', {type:'number'});
|
||||||
|
test_math_used('calc(round(round(100,10)* -1,10))', '-100', {type:'number'});
|
||||||
|
test_math_used('calc(round(up, -103 + -103 / -103 - 1,10))', '-100', {type:'number'});
|
||||||
|
test_math_used('calc(mod(18,5) * 2 + mod(17,5))', '8', {type:'number'});
|
||||||
|
test_math_used('calc(rem(mod(18,5),5))', '3', {type:'number'});
|
||||||
|
test_math_used('calc(rem(mod(18,5),mod(17,5)))', '1', {type:'number'});
|
||||||
|
test_math_used('calc(mod(-140,-90))', '-50', {type:'number'});
|
||||||
|
test_math_used('calc(mod(rem(1,18)* -1,5))', '4', {type:'number'});
|
||||||
|
|
||||||
|
// Type check
|
||||||
|
test_math_used('round(10px,6px)', '12px');
|
||||||
|
test_math_used('round(10cm,6cm)', '12cm');
|
||||||
|
test_math_used('round(10mm,6mm)', '12mm');
|
||||||
|
test_math_used('round(10Q, 6Q)', '12Q');
|
||||||
|
test_math_used('round(10in,6in)', '12in');
|
||||||
|
test_math_used('round(10pc,6pc)', '12pc');
|
||||||
|
test_math_used('round(10pt,6pt)', '12pt');
|
||||||
|
test_math_used('round(10em,6em)', '12em');
|
||||||
|
test_math_used('round(10ex,6ex)', '12ex');
|
||||||
|
test_math_used('round(10ch,6ch)', '12ch');
|
||||||
|
test_math_used('round(10rem,6rem)', '12rem');
|
||||||
|
test_math_used('round(10vh,6vh)', '12vh');
|
||||||
|
test_math_used('round(10vw,6vw)', '12vw');
|
||||||
|
test_math_used('round(10vmin,6vmin)', '12vmin');
|
||||||
|
test_math_used('round(10vmax,6vmax)', '12vmax');
|
||||||
|
test_math_used('round(10s,6s)', '12s', {type:'time'});
|
||||||
|
test_math_used('round(10ms,6ms)', '12ms', {type:'time'});
|
||||||
|
test_math_used('round(10deg,6deg)', '12deg', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('round(10grad,6grad)', '12grad', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('round(10rad,6rad)', '12rad',{type:'angle', approx:0.1});
|
||||||
|
test_math_used('round(10turn,6turn)', '12turn',{type:'angle', approx:0.1});
|
||||||
|
|
||||||
|
test_math_used('mod(10px,6px)', '4px');
|
||||||
|
test_math_used('mod(10cm,6cm)', '4cm');
|
||||||
|
test_math_used('mod(10mm,6mm)', '4mm');
|
||||||
|
test_math_used('mod(10Q, 6Q)', '4Q');
|
||||||
|
test_math_used('mod(10in,6in)', '4in');
|
||||||
|
test_math_used('mod(10pc,6pc)', '4pc');
|
||||||
|
test_math_used('mod(10em,6em)', '4em');
|
||||||
|
test_math_used('mod(10ex,6ex)', '4ex');
|
||||||
|
test_math_used('mod(10ch,6ch)', '4ch');
|
||||||
|
test_math_used('mod(10rem,6rem)', '4rem');
|
||||||
|
test_math_used('mod(10vh,6vh)', '4vh', {approx: 0.1});
|
||||||
|
test_math_used('mod(10vw,6vw)', '4vw', {approx: 0.1});
|
||||||
|
test_math_used('mod(10vmin,6vmin)', '4vmin', {approx: 0.1});
|
||||||
|
test_math_used('mod(10vmax,6vmax)', '4vmax', {approx: 0.1});
|
||||||
|
test_math_used('mod(10s,6s)', '4s', {type:'time'});
|
||||||
|
test_math_used('mod(10ms,6ms)', '4ms', {type:'time'});
|
||||||
|
test_math_used('mod(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('mod(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('mod(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
|
||||||
|
test_math_used('mod(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
|
||||||
|
|
||||||
|
test_math_used('rem(10px,6px)', '4px');
|
||||||
|
test_math_used('rem(10cm,6cm)', '4cm');
|
||||||
|
test_math_used('rem(10mm,6mm)', '4mm');
|
||||||
|
test_math_used('rem(10Q, 6Q)', '4Q');
|
||||||
|
test_math_used('rem(10in,6in)', '4in');
|
||||||
|
test_math_used('rem(10pc,6pc)', '4pc');
|
||||||
|
test_math_used('rem(10em,6em)', '4em');
|
||||||
|
test_math_used('rem(10ex,6ex)', '4ex');
|
||||||
|
test_math_used('rem(10ch,6ch)', '4ch');
|
||||||
|
test_math_used('rem(10rem,6rem)', '4rem');
|
||||||
|
test_math_used('rem(10vh,6vh)', '4vh', {approx: 0.1});
|
||||||
|
test_math_used('rem(10vw,6vw)', '4vw', {approx: 0.1});
|
||||||
|
test_math_used('rem(10vmin,6vmin)', '4vmin', {approx: 0.1});
|
||||||
|
test_math_used('rem(10vmax,6vmax)', '4vmax', {approx: 0.1});
|
||||||
|
test_math_used('rem(10s,6s)', '4s', {type:'time'});
|
||||||
|
test_math_used('rem(10ms,6ms)', '4ms', {type:'time'});
|
||||||
|
test_math_used('rem(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('rem(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
|
||||||
|
test_math_used('rem(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
|
||||||
|
test_math_used('rem(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
|
||||||
|
|
||||||
|
//Test percentage and mixed units
|
||||||
|
test_math_used('round(10%,1px)', '8px');
|
||||||
|
test_math_used('round(10%,5px)', '10px');
|
||||||
|
test_math_used('round(2rem,5px)', '30px');
|
||||||
|
test_math_used('round(100px,1rem)', '96px');
|
||||||
|
test_math_used('round(10s,6000ms)', '12s', {type:'time'});
|
||||||
|
test_math_used('round(10000ms,6s)', '12s', {type:'time'});
|
||||||
|
|
||||||
|
test_math_used('mod(10%,1px)', '0.5px');
|
||||||
|
test_math_used('mod(10%,5px)', '2.5px');
|
||||||
|
test_math_used('mod(2rem,5px)', '2px');
|
||||||
|
test_math_used('mod(100px,1rem)', '4px');
|
||||||
|
test_math_used('mod(10s,6000ms)', '4s', {type:'time'});
|
||||||
|
test_math_used('mod(10000ms,6s)', '4s', {type:'time'});
|
||||||
|
test_math_used('mod(18px,100% / 15)', '3px', {approx: 0.1});
|
||||||
|
test_math_used('mod(-18px,100% / 10)', '4.5px');
|
||||||
|
test_math_used('mod(18%,5%)', '3%');
|
||||||
|
test_math_used('mod(-19%,5%)', '1%');
|
||||||
|
test_math_used('mod(18vw,5vw)', '3vw');
|
||||||
|
test_math_used('mod(-18vw,5vw)', '2vw', {approx: 0.1});
|
||||||
|
|
||||||
|
test_math_used('rem(10%,1px)', '0.5px');
|
||||||
|
test_math_used('rem(10%,5px)', '2.5px');
|
||||||
|
test_math_used('rem(2rem,5px)', '2px');
|
||||||
|
test_math_used('rem(100px,1rem)', '4px');
|
||||||
|
test_math_used('rem(10s,6000ms)', '4s', {type:'time'});
|
||||||
|
test_math_used('rem(10000ms,6s)', '4s', {type:'time'});
|
||||||
|
test_math_used('rem(18px,100% / 15)', '3px', {approx: 0.1});
|
||||||
|
test_math_used('rem(-18px,100% / 15)', '-3px', {approx: 0.1});
|
||||||
|
test_math_used('rem(18vw,5vw)', '3vw');
|
||||||
|
test_math_used('rem(-18vw,5vw)', '-3vw');
|
||||||
|
|
||||||
|
test_math_used('calc(round(1px + 0%, 1px + 0%))', '1px');
|
||||||
|
test_math_used('calc(mod(3px + 0%, 2px + 0%))', '1px');
|
||||||
|
test_math_used('calc(rem(3px + 0%, 2px + 0%))', '1px');
|
||||||
|
|
||||||
|
test_math_used('round(1px + 0%, 1px)', '1px');
|
||||||
|
test_math_used('mod(3px + 0%, 2px)', '1px');
|
||||||
|
test_math_used('rem(3px + 0%, 2px)', '1px');
|
||||||
|
|
||||||
|
// In round(A, B), if B is 0, the result is NaN. If A and B are both infinite, the result is NaN.
|
||||||
|
// In mod(A, B) or rem(A, B), if B is 0, the result is NaN. If A is infinite, the result is NaN.
|
||||||
|
for (let operator of ['round', 'mod', 'rem']) {
|
||||||
|
test_math_used(`${operator}(0, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(-0, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(Infinity, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(-Infinity, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(-4, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(4, 0)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(Infinity, Infinity)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(-Infinity, -Infinity)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(Infinity, -Infinity)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used(`${operator}(-Infinity, Infinity)`, 'calc(NaN)', {type: 'number'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// In round(A, B), if A is infinite but B is finite, the result is the same infinity.
|
||||||
|
for (let roundingStrategy of ['up', 'down', 'nearest', 'to-zero']) {
|
||||||
|
test_math_used(`round(${roundingStrategy}, Infinity, 4)`, 'calc(Infinity)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -Infinity, 4)`, 'calc(-Infinity)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, Infinity, -4)`, 'calc(Infinity)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -Infinity, -4)`, 'calc(-Infinity)', {type: 'number'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// If A is finite but B is infinite, the result depends on the <rounding-strategy> and the sign of A:
|
||||||
|
// nearest & to-zero: If A is positive or 0⁺, return 0⁺. Otherwise, return 0⁻.
|
||||||
|
for (let roundingStrategy of ['nearest', 'to-zero']) {
|
||||||
|
test_math_used(`round(${roundingStrategy}, 0, Infinity)`, '0', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, 4, Infinity)`, '0', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -0, Infinity)`, 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -4, Infinity)`, 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, 0, -Infinity)`, '0', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, 4, -Infinity)`, '0', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -0, -Infinity)`, 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used(`round(${roundingStrategy}, -4, -Infinity)`, 'calc(-0)', {type: 'number'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// up: If A is positive (not zero), return +∞. If A is 0⁺, return 0⁺. Otherwise, return 0⁻.
|
||||||
|
test_math_used('round(up, 1, Infinity)', 'calc(Infinity)', {type: 'number'});
|
||||||
|
test_math_used('round(up, 0, Infinity)', '0', {type: 'number'});
|
||||||
|
test_math_used('round(up, -1, Infinity)', 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used('round(up, 1, -Infinity)', 'calc(Infinity)', {type: 'number'});
|
||||||
|
test_math_used('round(up, 0, -Infinity)', '0', {type: 'number'});
|
||||||
|
test_math_used('round(up, -1, -Infinity)', 'calc(-0)', {type: 'number'});
|
||||||
|
// down: If A is negative (not zero), return −∞. If A is 0⁻, return 0⁻. Otherwise, return 0⁺.
|
||||||
|
test_math_used('round(down, 1, Infinity)', 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used('round(down, 0, Infinity)', '0', {type: 'number'});
|
||||||
|
test_math_used('round(down, -1, Infinity)', 'calc(-Infinity)', {type: 'number'});
|
||||||
|
test_math_used('round(down, 1, -Infinity)', 'calc(-0)', {type: 'number'});
|
||||||
|
test_math_used('round(down, 0, -Infinity)', '0', {type: 'number'});
|
||||||
|
test_math_used('round(down, -1, -Infinity)', 'calc(-Infinity)', {type: 'number'});
|
||||||
|
|
||||||
|
// In mod(A, B) only, if B is infinite and A has opposite sign to B (including an oppositely-signed zero), the result is NaN.
|
||||||
|
test_math_used('mod(-0, Infinity)', 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used('mod(0, -Infinity)', 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used('mod(-4, Infinity)', 'calc(NaN)', {type: 'number'});
|
||||||
|
test_math_used('mod(4, -Infinity)', 'calc(NaN)', {type: 'number'});
|
||||||
|
</script>
|
|
@ -0,0 +1,240 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
|
||||||
|
<link rel="author" title="Apple Inc">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../support/numeric-testcommon.js"></script>
|
||||||
|
<div id="container" style="font-size: 20px; width: 100px">
|
||||||
|
<div id="target"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function test_zero(expression, { is_negative }) {
|
||||||
|
test_math_used(`calc(${expression})`, '0', {type:'integer'});
|
||||||
|
// to test zero sign, make it to negative infinity and clamp it between -1 and 1
|
||||||
|
test_math_used(`clamp(-1, calc( 1 / sign(${expression})), 1)`, (is_negative)? '-1' : '1', {type:'integer'});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_length_equals(value, expected, msgExtra) {
|
||||||
|
test_math_used(value, expected, {msgExtra, type: 'integer'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identity tests
|
||||||
|
test_math_used('abs(1)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1)', '1', {type:'integer'});
|
||||||
|
test_math_used('abs(-1)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1)', '-1', {type:'integer'});
|
||||||
|
|
||||||
|
// Nestings
|
||||||
|
test_math_used('abs(sign(1))', '1', {type:'integer'});
|
||||||
|
test_math_used('abs(sign(sign(1)))', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(sign(sign(1) + sign(1)))', '1', {type:'integer'});
|
||||||
|
|
||||||
|
// General calculations
|
||||||
|
test_math_used('calc(abs(0.1 + 0.2) + 0.05)', '0.35', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(sign(0.1 + 0.2) - 0.05)', '0.95', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(abs(0.1 + 0.2) * 2)', '0.6', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(abs(sign(0.1) + 0.2) / 2)', '0.6', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(abs(0.1 + 0.2) * -2)', '-0.6', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(sign(0.1 - 0.2) - 0.05)', '-1.05', {type:'number', approx:0.1});
|
||||||
|
test_math_used('calc(sign(1) + sign(1) - 0.05)', '1.95', {type:'number', approx:0.1});
|
||||||
|
|
||||||
|
// Test with <length-percentage>
|
||||||
|
test_math_used('abs(10px)', '10px', {type:'length'});
|
||||||
|
test_math_used('abs(10%)', '10px', {type:'length'});
|
||||||
|
test_math_used('abs(10px + 10%)', '20px', {type:'length'});
|
||||||
|
test_math_used('calc(10px + abs(10%))', '20px', {type:'length'});
|
||||||
|
test_math_used('abs(-10px)', '10px', {type:'length'});
|
||||||
|
test_math_used('abs(-10%)', '10px', {type:'length'});
|
||||||
|
// (20px + 1px) * (sign(20px - 10px - 10px) + 1)
|
||||||
|
test_math_used('calc((1em + 1px) * (sign(1em - 10px - 10%) + 1))', '21px', {type:'length'});
|
||||||
|
|
||||||
|
// Test sign for zero
|
||||||
|
test_zero('calc(sign(-0))', {is_negative: true});
|
||||||
|
test_zero('calc(sign(0))', {is_negative: false});
|
||||||
|
|
||||||
|
// Test with NaN and inf
|
||||||
|
test_math_used('abs(infinity)', 'calc(infinity)', {type:'number'});
|
||||||
|
test_math_used('abs(-infinity)', 'calc(infinity)', {type:'number'});
|
||||||
|
test_math_used('abs(NaN)', 'calc(NaN)', {type:'number'});
|
||||||
|
|
||||||
|
// Test abs/sign with negate
|
||||||
|
test_math_used('calc(20 - abs(-10))', '10', {type:'number'});
|
||||||
|
test_math_used('calc(20 - abs(10))', '10', {type:'number'});
|
||||||
|
test_math_used('calc(10 - abs(10 - abs(-30))', '-10', {type:'number'});
|
||||||
|
test_math_used('calc(2 - sign(1))', '1', {type:'number'});
|
||||||
|
test_math_used('calc(2 - sign(-1))', '3', {type:'number'});
|
||||||
|
test_math_used('calc(2 - sign(1 - sign(-1)))', '1', {type:'number'});
|
||||||
|
test_math_used('calc(10 - abs(20 - sign(2 - abs(-20))))', '-11', {type:'number'});
|
||||||
|
|
||||||
|
// Type checking sign
|
||||||
|
test_math_used('sign(1px)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1cm)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1mm)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1Q)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1in)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1pc)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1pt)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1em)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1ex)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1ch)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1rem)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1vh)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1vw)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1vmin)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1vmax)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1px)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1cm)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1mm)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1Q)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1in)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1pc)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1pt)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1em)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1ex)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1ch)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1rem)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1vh)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1vw)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1vmin)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1vmax)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(1s)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1ms)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1s)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1ms)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(1deg)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1grad)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1rad)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(1turn)', '1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1deg)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1grad)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1rad)', '-1', {type:'integer'});
|
||||||
|
test_math_used('sign(-1turn)', '-1', {type:'integer'});
|
||||||
|
test_zero('sign(0px)', {is_negative: false});
|
||||||
|
test_zero('sign(0cm)', {is_negative: false});
|
||||||
|
test_zero('sign(0mm)', {is_negative: false});
|
||||||
|
test_zero('sign(0Q)', {is_negative: false});
|
||||||
|
test_zero('sign(0in)', {is_negative: false});
|
||||||
|
test_zero('sign(0pc)', {is_negative: false});
|
||||||
|
test_zero('sign(0pt)', {is_negative: false});
|
||||||
|
test_zero('sign(0em)', {is_negative: false});
|
||||||
|
test_zero('sign(0ex)', {is_negative: false});
|
||||||
|
test_zero('sign(0ch)', {is_negative: false});
|
||||||
|
test_zero('sign(0rem)', {is_negative: false});
|
||||||
|
test_zero('sign(0vh)', {is_negative: false});
|
||||||
|
test_zero('sign(0vw)', {is_negative: false});
|
||||||
|
test_zero('sign(0vmin)', {is_negative: false});
|
||||||
|
test_zero('sign(0vmax)', {is_negative: false});
|
||||||
|
test_zero('sign(-0px)', {is_negative: true});
|
||||||
|
test_zero('sign(-0cm)', {is_negative: true});
|
||||||
|
test_zero('sign(-0mm)', {is_negative: true});
|
||||||
|
test_zero('sign(-0Q)', {is_negative: true});
|
||||||
|
test_zero('sign(-0in)', {is_negative: true});
|
||||||
|
test_zero('sign(-0pc)', {is_negative: true});
|
||||||
|
test_zero('sign(-0pt)', {is_negative: true});
|
||||||
|
test_zero('sign(-0em)', {is_negative: true});
|
||||||
|
test_zero('sign(-0ex)', {is_negative: true});
|
||||||
|
test_zero('sign(-0ch)', {is_negative: true});
|
||||||
|
test_zero('sign(-0rem)', {is_negative: true});
|
||||||
|
test_zero('sign(-0vh)', {is_negative: true});
|
||||||
|
test_zero('sign(-0vw)', {is_negative: true});
|
||||||
|
test_zero('sign(-0vmin)', {is_negative: true});
|
||||||
|
test_zero('sign(-0vmax)', {is_negative: true});
|
||||||
|
test_zero('sign(0s)', {is_negative: false});
|
||||||
|
test_zero('sign(0ms)', {is_negative: false});
|
||||||
|
test_zero('sign(-0s)', {is_negative: true});
|
||||||
|
test_zero('sign(-0ms)', {is_negative: true});
|
||||||
|
test_zero('sign(0deg)', {is_negative: false});
|
||||||
|
test_zero('sign(0grad)', {is_negative: false});
|
||||||
|
test_zero('sign(0rad)', {is_negative: false});
|
||||||
|
test_zero('sign(0turn)', {is_negative: false});
|
||||||
|
test_zero('sign(-0deg)', {is_negative: true});
|
||||||
|
test_zero('sign(-0grad)', {is_negative: true});
|
||||||
|
test_zero('sign(-0rad)', {is_negative: true});
|
||||||
|
test_zero('sign(-0turn)', {is_negative: true});
|
||||||
|
|
||||||
|
// Type checking abs
|
||||||
|
test_math_used('abs(1px)', '1px');
|
||||||
|
test_math_used('abs(1cm)', '1cm');
|
||||||
|
test_math_used('abs(1mm)', '1mm');
|
||||||
|
test_math_used('abs(1Q)', '1Q');
|
||||||
|
test_math_used('abs(1in)', '1in');
|
||||||
|
test_math_used('abs(1pc)', '1pc');
|
||||||
|
test_math_used('abs(1pt)', '1pt');
|
||||||
|
test_math_used('abs(1em)', '1em');
|
||||||
|
test_math_used('abs(1ex)', '1ex');
|
||||||
|
test_math_used('abs(1ch)', '1ch');
|
||||||
|
test_math_used('abs(1rem)', '1rem');
|
||||||
|
test_math_used('abs(1vh)', '1vh');
|
||||||
|
test_math_used('abs(1vw)', '1vw');
|
||||||
|
test_math_used('abs(1vmin)', '1vmin');
|
||||||
|
test_math_used('abs(1vmax)', '1vmax');
|
||||||
|
test_math_used('abs(-1px)', '1px');
|
||||||
|
test_math_used('abs(-1cm)', '1cm');
|
||||||
|
test_math_used('abs(-1mm)', '1mm');
|
||||||
|
test_math_used('abs(-1Q)', '1Q');
|
||||||
|
test_math_used('abs(-1in)', '1in');
|
||||||
|
test_math_used('abs(-1pc)', '1pc');
|
||||||
|
test_math_used('abs(-1pt)', '1pt');
|
||||||
|
test_math_used('abs(-1em)', '1em');
|
||||||
|
test_math_used('abs(-1ex)', '1ex');
|
||||||
|
test_math_used('abs(-1ch)', '1ch');
|
||||||
|
test_math_used('abs(-1rem)', '1rem');
|
||||||
|
test_math_used('abs(-1vh)', '1vh');
|
||||||
|
test_math_used('abs(-1vw)', '1vw');
|
||||||
|
test_math_used('abs(-1vmin)', '1vmin');
|
||||||
|
test_math_used('abs(-1vmax)', '1vmax');
|
||||||
|
test_math_used('abs(1s)', '1s', {type:'time'});
|
||||||
|
test_math_used('abs(1ms)', '1ms', {type:'time'});
|
||||||
|
test_math_used('abs(-1s)', '1s', {type:'time'});
|
||||||
|
test_math_used('abs(-1ms)', '1ms', {type:'time'});
|
||||||
|
test_math_used('abs(1deg)', '1deg', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(1grad)', '1grad', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(1rad)', '1rad', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(1turn)', '1turn', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(-1deg)', '1deg', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(-1grad)', '1grad', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(-1rad)', '1rad', {type:'angle', approx:0.001});
|
||||||
|
test_math_used('abs(-1turn)', '1turn', {type:'angle', approx:0.001});
|
||||||
|
|
||||||
|
// with relative length
|
||||||
|
document.getElementById('container').style.fontSize = '10px';
|
||||||
|
test_length_equals('sign(10px - 1em)', '0', 'fontSize=10px');
|
||||||
|
test_length_equals('sign(10px - 2em)', '-1', 'fontSize=10px');
|
||||||
|
document.getElementById('container').style.fontSize = '20px';
|
||||||
|
|
||||||
|
test_math_used('calc(sign(10%) * 100px)', '100px');
|
||||||
|
|
||||||
|
// Basic tests (just px and em) for sign() interaction with units not
|
||||||
|
// otherwise used by the property.
|
||||||
|
test_math_used('calc(2.5 - sign(41px - 2em) / 2)', '2', {type:'number'});
|
||||||
|
test_math_used('calc(2.5 - sign(40px - 2em) / 2)', '2.5', {type:'number'});
|
||||||
|
test_math_used('calc(2.5 - sign(39px - 2em) / 2)', '3', {type:'number'});
|
||||||
|
test_math_used('calc(3 + sign(42px - 2em))', '4', {type:'integer'});
|
||||||
|
test_math_used('calc(3 + sign(40px - 2em))', '3', {type:'integer'});
|
||||||
|
test_math_used('calc(3 + sign(38px - 2em))', '2', {type:'integer'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(42px - 2em))', '150px', {type:'length'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(40px - 2em))', '50px', {type:'length'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(38px - 2em))', '-50px', {type:'length'});
|
||||||
|
test_math_used('calc(90deg + 30deg * sign(42px - 2em))', '120deg', {type:'angle'});
|
||||||
|
test_math_used('calc(90deg + 30deg * sign(40px - 2em))', '90deg', {type:'angle'});
|
||||||
|
test_math_used('calc(90deg + 30deg * sign(38px - 2em))', '60deg', {type:'angle'});
|
||||||
|
test_math_used('calc(5s + 15s * sign(42px - 2em))', '20s', {type:'time'});
|
||||||
|
test_math_used('calc(5s + 15s * sign(40px - 2em))', '5s', {type:'time'});
|
||||||
|
test_math_used('calc(5s + 15s * sign(38px - 2em))', '-10s', {type:'time'});
|
||||||
|
test_math_used('calc(100dpi + 20dpi * sign(42px - 2em))', '120dpi', {type:'resolution'});
|
||||||
|
test_math_used('calc(100dpi + 20dpi * sign(40px - 2em))', '100dpi', {type:'resolution'});
|
||||||
|
test_math_used('calc(100dpi + 20dpi * sign(38px - 2em))', '80dpi', {type:'resolution'});
|
||||||
|
test_math_used('calc(3fr + 1fr * sign(42px - 2em))', '4fr', {type:'flex'});
|
||||||
|
test_math_used('calc(3fr + 1fr * sign(40px - 2em))', '3fr', {type:'flex'});
|
||||||
|
test_math_used('calc(3fr + 1fr * sign(38px - 2em))', '2fr', {type:'flex'});
|
||||||
|
// repeat a few with px and rem
|
||||||
|
test_math_used('calc(2.5 - sign(33px - 2rem) / 2)', '2', {type:'number'});
|
||||||
|
test_math_used('calc(2.5 - sign(32px - 2rem) / 2)', '2.5', {type:'number'});
|
||||||
|
test_math_used('calc(2.5 - sign(31px - 2rem) / 2)', '3', {type:'number'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(34px - 2rem))', '150px', {type:'length'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(32px - 2rem))', '50px', {type:'length'});
|
||||||
|
test_math_used('calc(50px + 100px * sign(30px - 2rem))', '-50px', {type:'length'});
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,198 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Provides functions to help test that two numeric values are equivalent.
|
||||||
|
These *do not* rely on you predicting what one value will serialize to;
|
||||||
|
instead, they set and serialize *both* values,
|
||||||
|
and just ensure that they serialize to the same thing.
|
||||||
|
|
||||||
|
They rely on a #target element existing in the document,
|
||||||
|
as this might rely on layout to resolve styles,
|
||||||
|
and so it needs to be in the document.
|
||||||
|
|
||||||
|
Three main functions are defined, with the same signatures:
|
||||||
|
test_math_used() (for testing used values),
|
||||||
|
test_math_computed() (for testing computed values),
|
||||||
|
and test_math_specified() (for testing specified values).
|
||||||
|
Signature for all is:
|
||||||
|
|
||||||
|
test_math_X(
|
||||||
|
testString, // A numeric value; required.
|
||||||
|
expectedString, // A hopefully-equivalent numeric value; required.
|
||||||
|
{ // all of these are optional
|
||||||
|
type, // "number", "length", etc. See impl for full list. Defaults to "length".
|
||||||
|
msg, // The message to display for the test; autogenned if not provided.
|
||||||
|
msgExtra, // Extra info to put after the auto-genned message.
|
||||||
|
prop, // If you want to override the automatic choice of tested property.
|
||||||
|
extraStyle, // Styles that need to be set at the same time to properly test the value.
|
||||||
|
approx, // The epsilon in order to compare numeric-ish values.
|
||||||
|
// Note that it'd use parseFloat in order to extract the
|
||||||
|
// values, so they can drop units or what not.
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Additionally, five specialized functions are provided
|
||||||
|
to test that a given value is ±∞, ±0, or NaN:
|
||||||
|
|
||||||
|
* test_plus_infinity(testString)
|
||||||
|
* test_minus_infinity(testString)
|
||||||
|
* test_plus_zero(testString)
|
||||||
|
* test_minus_zero(testString)
|
||||||
|
* test_nan(testString)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function test_math_used(testString, expectedString, {approx, msg, msgExtra, type, prop, extraStyle={}}={}) {
|
||||||
|
if(type === undefined) type = "length";
|
||||||
|
if(!prop) {
|
||||||
|
switch(type) {
|
||||||
|
case "number": prop = "scale"; break;
|
||||||
|
case "integer": prop = "z-index"; extraStyle.position="absolute"; break;
|
||||||
|
case "length": prop = "margin-left"; break;
|
||||||
|
case "angle": prop = "rotate"; break;
|
||||||
|
case "time": prop = "transition-delay"; break;
|
||||||
|
case "resolution": prop = "image-resolution"; break;
|
||||||
|
case "flex": prop = "grid-template-rows"; break;
|
||||||
|
default: throw Exception(`Value type '${type}' isn't capable of math.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
_test_math({stage:'used', testString, expectedString, type, approx, msg, msgExtra, prop, extraStyle});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_math_computed(testString, expectedString, {approx, msg, msgExtra, type, prop, extraStyle={}}={}) {
|
||||||
|
if(type === undefined) type = "length";
|
||||||
|
if(!prop) {
|
||||||
|
switch(type) {
|
||||||
|
case "number": prop = "scale"; break;
|
||||||
|
case "integer": prop = "z-index"; extraStyle.position="absolute"; break;
|
||||||
|
case "length": prop = "flex-basis"; break;
|
||||||
|
case "angle": prop = "rotate"; break;
|
||||||
|
case "time": prop = "transition-delay"; break;
|
||||||
|
case "resolution": prop = "image-resolution"; break;
|
||||||
|
case "flex": prop = "grid-template-rows"; break;
|
||||||
|
default: throw Exception(`Value type '${type}' isn't capable of math.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
_test_math({stage:'computed', testString, expectedString, type, approx, msg, msgExtra, prop, extraStyle});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_math_specified(testString, expectedString, {approx, msg, msgExtra, type, prop, extraStyle={}}={}) {
|
||||||
|
if(type === undefined) type = "length";
|
||||||
|
const stage = "specified";
|
||||||
|
if(!prop) {
|
||||||
|
switch(type) {
|
||||||
|
case "number": prop = "scale"; break;
|
||||||
|
case "integer": prop = "z-index"; extraStyle.position="absolute"; break;
|
||||||
|
case "length": prop = "flex-basis"; break;
|
||||||
|
case "angle": prop = "rotate"; break;
|
||||||
|
case "time": prop = "transition-delay"; break;
|
||||||
|
case "resolution": prop = "image-resolution"; break;
|
||||||
|
case "flex": prop = "grid-template-rows"; break;
|
||||||
|
default: throw Exception(`Value type '${type}' isn't capable of math.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Find the test element
|
||||||
|
const testEl = document.getElementById('target');
|
||||||
|
if(testEl == null) throw "Couldn't find #target element to run tests on.";
|
||||||
|
// Then reset its styles
|
||||||
|
testEl.style = "";
|
||||||
|
for(const p in extraStyle) {
|
||||||
|
testEl.style[p] = extraStyle[p];
|
||||||
|
}
|
||||||
|
if(!msg) {
|
||||||
|
msg = `${testString} should be ${stage}-value-equivalent to ${expectedString}`;
|
||||||
|
if(msgExtra) msg += "; " + msgExtra;
|
||||||
|
}
|
||||||
|
let t = testString;
|
||||||
|
let e = expectedString;
|
||||||
|
test(()=>{
|
||||||
|
testEl.style[prop] = '';
|
||||||
|
testEl.style[prop] = t;
|
||||||
|
const usedValue = testEl.style[prop];
|
||||||
|
assert_not_equals(usedValue, '', `${testString} isn't valid in '${prop}'; got the default value instead.`);
|
||||||
|
testEl.style[prop] = '';
|
||||||
|
testEl.style[prop] = e;
|
||||||
|
const expectedValue = testEl.style[prop];
|
||||||
|
assert_not_equals(expectedValue, '', `${expectedString} isn't valid in '${prop}'; got the default value instead.`)
|
||||||
|
if (approx) {
|
||||||
|
let extractValue = function(value) {
|
||||||
|
if (value.startsWith("calc(")) {
|
||||||
|
value = value.slice("calc(".length, -1);
|
||||||
|
}
|
||||||
|
return parseFloat(value);
|
||||||
|
};
|
||||||
|
let parsedUsed = extractValue(usedValue);
|
||||||
|
let parsedExpected = extractValue(expectedValue);
|
||||||
|
assert_approx_equals(parsedUsed, parsedExpected, approx, `${testString} and ${expectedString} ${approx} serialize to the same thing in ${stage} values.`);
|
||||||
|
} else {
|
||||||
|
assert_equals(usedValue, expectedValue, `${testString} and ${expectedString} serialize to the same thing in ${stage} values.`);
|
||||||
|
}
|
||||||
|
}, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
All of these expect the testString to evaluate to a <number>.
|
||||||
|
*/
|
||||||
|
function test_plus_infinity(testString) {
|
||||||
|
test_math_used(testString, "calc(infinity)", {type:"number"});
|
||||||
|
}
|
||||||
|
function test_minus_infinity(testString) {
|
||||||
|
test_math_used(testString, "calc(-infinity)", {type:"number"});
|
||||||
|
}
|
||||||
|
function test_plus_zero(testString) {
|
||||||
|
test_math_used(`calc(1 / ${testString})`, "calc(infinity)", {type:"number"});
|
||||||
|
}
|
||||||
|
function test_minus_zero(testString) {
|
||||||
|
test_math_used(`calc(1 / ${testString})`, "calc(-infinity)", {type:"number"});
|
||||||
|
}
|
||||||
|
function test_nan(testString) {
|
||||||
|
// Make sure that it's NaN, not an infinity,
|
||||||
|
// by making sure that it's the same value both pos and neg.
|
||||||
|
test_math_used(testString, "calc(NaN)", {type:"number"});
|
||||||
|
test_math_used(`calc(-1 * ${testString})`, "calc(NaN)", {type:"number"});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function _test_math({stage, testEl, testString, expectedString, type, approx, msg, msgExtra, prop, extraStyle}={}) {
|
||||||
|
// Find the test element
|
||||||
|
if(!testEl) testEl = document.getElementById('target');
|
||||||
|
if(testEl == null) throw "Couldn't find #target element to run tests on.";
|
||||||
|
// Then reset its styles
|
||||||
|
testEl.style = "";
|
||||||
|
for(const p in extraStyle) {
|
||||||
|
testEl.style[p] = extraStyle[p];
|
||||||
|
}
|
||||||
|
if(!msg) {
|
||||||
|
msg = `${testString} should be ${stage}-value-equivalent to ${expectedString}`;
|
||||||
|
if(msgExtra) msg += "; " + msgExtra;
|
||||||
|
}
|
||||||
|
let t = testString;
|
||||||
|
let e = expectedString;
|
||||||
|
test(()=>{
|
||||||
|
testEl.style[prop] = '';
|
||||||
|
const defaultValue = getComputedStyle(testEl)[prop];
|
||||||
|
testEl.style[prop] = t;
|
||||||
|
const usedValue = getComputedStyle(testEl)[prop];
|
||||||
|
assert_not_equals(usedValue, defaultValue, `${testString} isn't valid in '${prop}'; got the default value instead.`);
|
||||||
|
testEl.style[prop] = '';
|
||||||
|
testEl.style[prop] = e;
|
||||||
|
const expectedValue = getComputedStyle(testEl)[prop];
|
||||||
|
assert_not_equals(expectedValue, defaultValue, `${expectedString} isn't valid in '${prop}'; got the default value instead.`)
|
||||||
|
if (approx) {
|
||||||
|
let extractValue = function(value) {
|
||||||
|
return parseFloat(value);
|
||||||
|
};
|
||||||
|
let parsedUsed = extractValue(usedValue);
|
||||||
|
let parsedExpected = extractValue(expectedValue);
|
||||||
|
assert_approx_equals(parsedUsed, parsedExpected, approx, `${testString} and ${expectedString} ${approx} serialize to the same thing in ${stage} values.`);
|
||||||
|
} else {
|
||||||
|
assert_equals(usedValue, expectedValue, `${testString} and ${expectedString} serialize to the same thing in ${stage} values.`);
|
||||||
|
}
|
||||||
|
}, msg);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue