From 7fb0c1510b1e8bb8f69b2f9140d4b6dde62bef46 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 30 Jun 2026 00:56:01 +0800 Subject: [PATCH] Run tests from `less-test-suite` (#19494) --- package.json | 1 + .../__snapshots__/format.test.js.snap | 17561 ++++++++++++++++ .../less/less-test-suite/format.test.js | 39 + yarn.lock | 8 + 4 files changed, 17609 insertions(+) create mode 100644 tests/format/less/less-test-suite/__snapshots__/format.test.js.snap create mode 100644 tests/format/less/less-test-suite/format.test.js diff --git a/package.json b/package.json index fce87d835..98514259a 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "json-test-suite": "1.0.0", "jsx-test-suite": "0.0.2", "knip": "6.21.0", + "less-test-suite": "0.0.1", "magic-string": "0.30.21", "make-synchronized": "0.8.0", "nano-spawn": "2.1.0", diff --git a/tests/format/less/less-test-suite/__snapshots__/format.test.js.snap b/tests/format/less/less-test-suite/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..86eadb4a4 --- /dev/null +++ b/tests/format/less/less-test-suite/__snapshots__/format.test.js.snap @@ -0,0 +1,17561 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`snippet: plugin/plugin-transitive.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@plugin "plugin-transitive"; + +.other { + trans : test-transitive(); +} +=====================================output===================================== +@plugin "plugin-transitive"; + +.other { + trans: test-transitive(); +} + +================================================================================ +`; + +exports[`snippet: tests-config/3rd-party/bootstrap4.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "bootstrap-less-port/less/bootstrap"; +=====================================output===================================== +@import "bootstrap-less-port/less/bootstrap"; + +================================================================================ +`; + +exports[`snippet: tests-config/at-rules-compressed/at-rules-compressed.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests for atrule.js coverage - compressed output path (lines 243-250) +// Also covers parser + genCSS + outputRuleset + +// Compressed @media with rules +@media screen { + body { margin: 0; } + p { padding: 0; } +} + +// Compressed @layer with multiple rules +@layer base { + body { margin: 0; } + p { padding: 0; } + div { border: 0; } +} + +// Compressed @supports +@supports (display: grid) { + .grid { display: grid; } + .item { grid-column: 1; } +} + +// Compressed @page +@page { + margin: 2cm; + size: A4; +} + +// Compressed @keyframes +@keyframes slide { + from { transform: translateX(0); } + to { transform: translateX(100px); } +} + + +=====================================output===================================== +// Tests for atrule.js coverage - compressed output path (lines 243-250) +// Also covers parser + genCSS + outputRuleset + +// Compressed @media with rules +@media screen { + body { + margin: 0; + } + p { + padding: 0; + } +} + +// Compressed @layer with multiple rules +@layer base { + body { + margin: 0; + } + p { + padding: 0; + } + div { + border: 0; + } +} + +// Compressed @supports +@supports (display: grid) { + .grid { + display: grid; + } + .item { + grid-column: 1; + } +} + +// Compressed @page +@page { + margin: 2cm; + size: A4; +} + +// Compressed @keyframes +@keyframes slide { + from { + transform: translateX(0); + } + to { + transform: translateX(100px); + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/at-rules-compressed-evaluation/at-rules-compressed-evaluation.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Test at-rule evaluation paths (eval, evalRoot, genCSS, accept, etc.) + +// Test keywordList - @media with keyword list +@media screen, print, handheld { + body { + font-size: 12pt; + } +} + +// Test declarationsBlock with mergeable=true (nested ruleset with declarations) +@media screen { + .container { + color: red; + background: blue; + } +} + +// Test simpleBlock optimization with allRulesetDeclarations (single ruleset) +@media screen { + .test { + color: red; + background: blue; + } +} + +// Test eval with value evaluation and keywordList conversion +@breakpoint: screen; +@media @breakpoint, print { + body { + margin: 0; + } +} + +// Test evalRoot with ampersand handling +.container { + @media screen { + & { + color: red; + } + .child { + color: blue; + } + } +} + +// Test evalRoot with mixed ampersands +.wrapper { + .inner { + @media screen { + & { + color: green; + } + } + } +} + +// Test genCSS with value +@charset "UTF-8"; + +// Test genCSS with simpleBlock +@page { + margin: 2cm; + size: A4; +} + +// Test genCSS with rules (non-simpleBlock) +@supports (display: grid) { + .grid { + display: grid; + } + .flex { + display: flex; + } +} + +// Test isCharset +@charset "UTF-8"; + +// Test isRulesetLike (non-charset) +@media screen { + body { + color: black; + } +} + +// Test compressed output (outputRuleset compressed path) +@layer base { + body { + margin: 0; + } + p { + padding: 0; + } +} + +// Test variable/find/rulesets delegation +@media screen { + @var: value; + .test { + color: @var; + } +} + +// Test eval with media bubbling +@media screen { + @media print { + body { + color: black; + } + } +} + + +=====================================output===================================== +// Test at-rule evaluation paths (eval, evalRoot, genCSS, accept, etc.) + +// Test keywordList - @media with keyword list +@media screen, print, handheld { + body { + font-size: 12pt; + } +} + +// Test declarationsBlock with mergeable=true (nested ruleset with declarations) +@media screen { + .container { + color: red; + background: blue; + } +} + +// Test simpleBlock optimization with allRulesetDeclarations (single ruleset) +@media screen { + .test { + color: red; + background: blue; + } +} + +// Test eval with value evaluation and keywordList conversion +@breakpoint: screen; +@media @breakpoint, print { + body { + margin: 0; + } +} + +// Test evalRoot with ampersand handling +.container { + @media screen { + & { + color: red; + } + .child { + color: blue; + } + } +} + +// Test evalRoot with mixed ampersands +.wrapper { + .inner { + @media screen { + & { + color: green; + } + } + } +} + +// Test genCSS with value +@charset "UTF-8"; + +// Test genCSS with simpleBlock +@page { + margin: 2cm; + size: A4; +} + +// Test genCSS with rules (non-simpleBlock) +@supports (display: grid) { + .grid { + display: grid; + } + .flex { + display: flex; + } +} + +// Test isCharset +@charset "UTF-8"; + +// Test isRulesetLike (non-charset) +@media screen { + body { + color: black; + } +} + +// Test compressed output (outputRuleset compressed path) +@layer base { + body { + margin: 0; + } + p { + padding: 0; + } +} + +// Test variable/find/rulesets delegation +@media screen { + @var: value; + .test { + color: @var; + } +} + +// Test eval with media bubbling +@media screen { + @media print { + body { + color: black; + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/compression/compression.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#colours { + color1: #fea; + color2: #ffeeaa; + color3: rgba(255, 238, 170, 0.1); + @color1: #fea; + string: "@{color1}"; + /* comments are stripped */ + // both types! + /*! but not this type + Note preserved whitespace + */ +} +dimensions { + val: 0.1px; + val: 0em; + val: 4cm; + val: 0.2; + val: 5; + angles-must-have-unit: 0deg; + durations-must-have-unit: 0s; + length-doesnt-have-unit: 0px; + width: auto\\9; +} +@page { + marks: none; +@top-left-corner { + vertical-align: top; +} +@top-left { + vertical-align: top; +} +} +.shadow ^ .dom, +body ^^ .shadow { + display: done; +} + +=====================================output===================================== +#colours { + color1: #fea; + color2: #ffeeaa; + color3: rgba(255, 238, 170, 0.1); + @color1: #fea; + string: "@{color1}"; + /* comments are stripped */ + // both types! + /*! but not this type + Note preserved whitespace + */ +} +dimensions { + val: 0.1px; + val: 0em; + val: 4cm; + val: 0.2; + val: 5; + angles-must-have-unit: 0deg; + durations-must-have-unit: 0s; + length-doesnt-have-unit: 0px; + width: auto\\9; +} +@page { + marks: none; + @top-left-corner { + vertical-align: top; + } + @top-left { + vertical-align: top; + } +} +.shadow ^ .dom, +body ^^ .shadow { + display: done; +} + +================================================================================ +`; + +exports[`snippet: tests-config/debug/all/linenumbers-all.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Entry file for -all configuration +@import "../linenumbers.less"; + +=====================================output===================================== +// Entry file for -all configuration +@import "../linenumbers.less"; + +================================================================================ +`; + +exports[`snippet: tests-config/debug/comments/linenumbers-comments.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Entry file for -comments configuration +@import "../linenumbers.less"; + +=====================================output===================================== +// Entry file for -comments configuration +@import "../linenumbers.less"; + +================================================================================ +`; + +exports[`snippet: tests-config/debug/import/test.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "ISO-8859-1"; + +.mixin_import1() { + @media all { + .tst { + color: black; + @media screen { + color: red; + .tst3 { + color: inherit; + } + } + } + } +} + +.mixin_import2() { + .tst2 { + color: inherit; + } +} + +.tst3 { + color: grey; +} +=====================================output===================================== +@charset "ISO-8859-1"; + +.mixin_import1() { + @media all { + .tst { + color: black; + @media screen { + color: red; + .tst3 { + color: inherit; + } + } + } + } +} + +.mixin_import2() { + .tst2 { + color: inherit; + } +} + +.tst3 { + color: grey; +} + +================================================================================ +`; + +exports[`snippet: tests-config/debug/linenumbers.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "UTF-8"; + +@import "import/test.less"; + +.start() { + .test-rule2 { + color: red; + } +} + +.mix() { + color: black; +} + +.test-rule1 { + .mix(); +} + +.start(); + +.mixin_import1(); + +.mixin_import2(); + +@debug: 1; +& when (@debug = 1) { + .test-rule { + color: red; + & when (@debug = 1) { + width: 2; + } + } +} + +.supports-rule { + @supports (display: grid) { + color: green; + .nested-supports { + color: blue; + } + } +} +=====================================output===================================== +@charset "UTF-8"; + +@import "import/test.less"; + +.start() { + .test-rule2 { + color: red; + } +} + +.mix() { + color: black; +} + +.test-rule1 { + .mix(); +} + +.start(); + +.mixin_import1(); + +.mixin_import2(); + +@debug: 1; +& when (@debug = 1) { + .test-rule { + color: red; + & when (@debug = 1) { + width: 2; + } + } +} + +.supports-rule { + @supports (display: grid) { + color: green; + .nested-supports { + color: blue; + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/debug/mediaquery/linenumbers-mediaquery.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Entry file for -mediaquery configuration +@import "../linenumbers.less"; + +=====================================output===================================== +// Entry file for -mediaquery configuration +@import "../linenumbers.less"; + +================================================================================ +`; + +exports[`snippet: tests-config/filemanagerPlugin/filemanager.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "test.test"; +.test-rule { + color: @color; +} + +=====================================output===================================== +@import "test.test"; +.test-rule { + color: @color; +} + +================================================================================ +`; + +exports[`snippet: tests-config/globalVars/extended.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#header { + color: (@base-color * 3); + border-left: @the-border; + border-right: (@the-border * 2); +} +#footer { + color: (@base-color + #003300); + border-color: @red; +} +@red: desaturate(red, 10%); // less file overrides passed in color <- note line comment on last line to check it is okay +=====================================output===================================== +#header { + color: (@base-color * 3); + border-left: @the-border; + border-right: (@the-border * 2); +} +#footer { + color: (@base-color + #003300); + border-color: @red; +} +@red: desaturate( + red, + 10% +); // less file overrides passed in color <- note line comment on last line to check it is okay + +================================================================================ +`; + +exports[`snippet: tests-config/globalVars/simple.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.class { + color: @my-color; +} +=====================================output===================================== +.class { + color: @my-color; +} + +================================================================================ +`; + +exports[`snippet: tests-config/import-redirect/import-redirect.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "https://example.com/redirect.less"; + +h1 { color: red; } + +=====================================output===================================== +@import "https://example.com/redirect.less"; + +h1 { + color: red; +} + +================================================================================ +`; + +exports[`snippet: tests-config/include-path/import-test-e.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +body { width: 100% } + +=====================================output===================================== +body { + width: 100%; +} + +================================================================================ +`; + +exports[`snippet: tests-config/include-path/include-path.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "import-test-e"; + +data-uri { + property: data-uri('image.svg'); +} +image-size { + property: image-size('image.svg'); +} + +=====================================output===================================== +@import "import-test-e"; + +data-uri { + property: data-uri("image.svg"); +} +image-size { + property: image-size("image.svg"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/include-path-string/include-path-string.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +data-uri { + property: data-uri('image.svg'); +} + +=====================================output===================================== +data-uri { + property: data-uri("image.svg"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/js-type-errors/js-type-error.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.scope { + var: \`this.foo.toJS\`; +} + +=====================================output===================================== +.scope { + var: \`this.foo.toJS\`; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-always/mixins-guards.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/less/less.js/issues/2798 +.test-rule-2798 when ((8+4) < 13) { + regression: fixed; +} +.test-rule-2798 when ((8+6) < 13) { + regression: should not be visible; +} +.conditions-parser-1 when (8+4 < 13) { + only-atomic: ok; +} +.conditions-parser-1 when (8+6 < 13) { + only-atomic: should not be visible; +} +.conditions-parser-2 when (8+(5-1) < 13) { + only-atomic-with-nested-parenthesis: ok; +} +.conditions-parser-2 when (8+(15-1) < 13) { + only-atomic-with-nested-parenthesis: should not be visible; +} +.conditions-parser-3 when (8 < (13+1)) { + only-atomic-nested-parenthesis-on-right: ok; +} +.conditions-parser-3 when (8 < (3+1)) { + only-atomic-nested-parenthesis-on-right: should not be visible; +} + +=====================================output===================================== +// https://github.com/less/less.js/issues/2798 +.test-rule-2798 when ((8+4) < 13) { + regression: fixed; +} +.test-rule-2798 when ((8+6) < 13) { + regression: should not be visible; +} +.conditions-parser-1 when (8+4 < 13) { + only-atomic: ok; +} +.conditions-parser-1 when (8+6 < 13) { + only-atomic: should not be visible; +} +.conditions-parser-2 when (8+(5-1) < 13) { + only-atomic-with-nested-parenthesis: ok; +} +.conditions-parser-2 when (8+(15-1) < 13) { + only-atomic-with-nested-parenthesis: should not be visible; +} +.conditions-parser-3 when (8 < (13+1)) { + only-atomic-nested-parenthesis-on-right: ok; +} +.conditions-parser-3 when (8 < (3+1)) { + only-atomic-nested-parenthesis-on-right: should not be visible; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-always/no-sm-operations.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.named-colors-in-expressions { + color-0: 0 -red; + color-1: 1 - red; + color-2: red * 2; + color-3: 2 * red; + @3: -red; + &-bar@{3} {x: y} + @color: red; + &-bar@{color} {a: a}; + background-color: blue-2; + color: green-black; + animation: blue-change 5s infinite; +} +.division { + value: ((16px ./ 2) / 2) / 2; +} +=====================================output===================================== +.named-colors-in-expressions { + color-0: 0 -red; + color-1: 1 - red; + color-2: red * 2; + color-3: 2 * red; + @3: -red; + &-bar@{3} { + x: y; + } + @color: red; + &-bar@{color} { + a: a; + } + background-color: blue-2; + color: green-black; + animation: blue-change 5s infinite; +} +.division { + value: ((16px ./ 2) / 2) / 2; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-parens-division/media-math.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@var: 10 + 6; + +@media (min-width: @var + 1) { + .foo { bar: 1; } +} + +@media (min-width: @var / 9) { + .foo { bar: 1; } +} +=====================================output===================================== +@var: 10 + 6; + +@media (min-width: @var + 1) { + .foo { + bar: 1; + } +} + +@media (min-width: @var / 9) { + .foo { + bar: 1; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-parens-division/mixins-args.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny +(@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden(); +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { margin: @width; } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { .var-inside(); } + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments(); +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-rule-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-rule-calling-one-arg-mixin(@a) { +} + +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-rule-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 {.m3(@x...)} + &2 {.m3(@y...)} + &3 {.wr(a, b, c)} + &4 {.wr(a; b; c, d)} + &5 {.wr(@x...)} + &6 {.m4(0; @x...)} + &7 {.m4(@x..., @a: 0)} + &8 {.m4(@b: 1.5; @x...)} + &9 {.aa(@y, @x..., and again, @y...)} + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a {.m3(@a...)} + &b {.m4(0, @a...)} + &c {.m4(@a..., 4)} + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} +=====================================output===================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny (@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden(); +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { + margin: @width; + } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { + .var-inside(); +} + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments(); +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-rule-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-rule-calling-one-arg-mixin(@a) { +} + +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-rule-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 { + .m3(@x...); + } + &2 { + .m3(@y...); + } + &3 { + .wr(a, b, c); + } + &4 { + .wr(a; b; c, d); + } + &5 { + .wr(@x...); + } + &6 { + .m4(0; @x...); + } + &7 { + .m4(@x..., @a: 0); + } + &8 { + .m4(@b: 1.5; @x...); + } + &9 { + .aa(@y, @x..., and again, @y...); + } + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a { + .m3(@a...); + } + &b { + .m4(0, @a...); + } + &c { + .m4(@a..., 4); + } + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-parens-division/new-division.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.units { + font: 1.2rem/2rem; + font: 8vw/9vw; + font: 10vh/12vh; + font: 12vm/15vm; + font: 12vmin/15vmin; + font: 1.2ch/1.5ch; +} + +.math { + a: 1 + 1; + b: 2px / 2; + c: 2px ./ 2; + d: (10px / 10px); + e: ((16px ./ 2) / 2) / 2; + f: ((16px ./ 2) / 2) ./ 2; +} +=====================================output===================================== +.units { + font: 1.2rem/2rem; + font: 8vw/9vw; + font: 10vh/12vh; + font: 12vm/15vm; + font: 12vmin/15vmin; + font: 1.2ch/1.5ch; +} + +.math { + a: 1 + 1; + b: 2px / 2; + c: 2px ./ 2; + d: (10px / 10px); + e: ((16px ./ 2) / 2) / 2; + f: ((16px ./ 2) / 2) ./ 2; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-parens-division/parens.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.parens-issues-3616 { + bar: if(false, 666, 888 / 444); + bar2: if(false, 666, (666 / 333)); + bar3: if(false, 666, ((444 / 222))); +} + +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-rule-false-negatives { + a: ~"("; +} + +=====================================output===================================== +.parens-issues-3616 { + bar: if(false, 666, 888 / 444); + bar2: if(false, 666, (666 / 333)); + bar3: if(false, 666, ((444 / 222))); +} + +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-rule-false-negatives { + a: ~"("; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-strict/css.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "utf-8"; +div { color: black; } +div { width: 99%; } + +* { + min-width: 45em; +} + +h1, h2 > a > p, h3 { + color: none; +} + +div.class { + color: blue; +} + +div#id { + color: green; +} + +.class#id { + color: purple; +} + +.one.two.three { + color: grey; +} + +@media print { + * { + font-size: 3em; + } +} + +@media screen { + * { + font-size: 10px; + } +} + +@font-face { + font-family: 'Garamond Pro'; +} + +a:hover, a:link { + color: #999; +} + +p, p:first-child { + text-transform: none; +} + +q:lang(no) { + quotes: none; +} + +p + h1 { + font-size: +2.2em; +} + +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + font: 100%/16px Arial; + margin: 1px 0; + padding: 0 auto; +} + +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; + font: 0/0 a; + border-radius: 5px / 10px; +} + +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: .1em; + background-color: #009998; + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; + .nested-multiple { + multiple-semi-colons: yes;;;;;; + }; + filter: alpha(opacity=100); + width: auto\\9; +} + +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} + +.def-font(@name) { + @font-face { + font-family: @name + } +} + +.def-font(font-a); +.def-font(font-b); + +.æøå { + margin: 0; +} + +=====================================output===================================== +@charset "utf-8"; +div { + color: black; +} +div { + width: 99%; +} + +* { + min-width: 45em; +} + +h1, +h2 > a > p, +h3 { + color: none; +} + +div.class { + color: blue; +} + +div#id { + color: green; +} + +.class#id { + color: purple; +} + +.one.two.three { + color: grey; +} + +@media print { + * { + font-size: 3em; + } +} + +@media screen { + * { + font-size: 10px; + } +} + +@font-face { + font-family: "Garamond Pro"; +} + +a:hover, +a:link { + color: #999; +} + +p, +p:first-child { + text-transform: none; +} + +q:lang(no) { + quotes: none; +} + +p + h1 { + font-size: +2.2em; +} + +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + font: 100%/16px Arial; + margin: 1px 0; + padding: 0 auto; +} + +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: + normal small/20px "Trebuchet MS", + Verdana, + sans-serif; + font: 0/0 a; + border-radius: 5px / 10px; +} + +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: 0.1em; + background-color: #009998; + background: -webkit-gradient( + linear, + left top, + left bottom, + from(red), + to(blue) + ); + margin:; + .nested-multiple { + multiple-semi-colons: yes; + } + filter: alpha(opacity=100); + width: auto\\9; +} + +#important { + color: red !important; + width: 100% !important; + height: 20px !important; +} + +.def-font(@name) { + @font-face { + font-family: @name; + } +} + +.def-font(font-a); +.def-font(font-b); + +.æøå { + margin: 0; +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-strict/media-math.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@var: 16; + +@media (min-width: @var + 1) { + .foo { bar: 1; } +} + +@media (min-width: @var / 9) { + .foo { bar: 1; } +} +=====================================output===================================== +@var: 16; + +@media (min-width: @var + 1) { + .foo { + bar: 1; + } +} + +@media (min-width: @var / 9) { + .foo { + bar: 1; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-strict/mixins-args.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny +(@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden(); +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { margin: @width; } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { .var-inside(); } + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments(); +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-rule-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-rule-calling-one-arg-mixin(@a) { +} + +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-rule-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 {.m3(@x...)} + &2 {.m3(@y...)} + &3 {.wr(a, b, c)} + &4 {.wr(a; b; c, d)} + &5 {.wr(@x...)} + &6 {.m4(0; @x...)} + &7 {.m4(@x..., @a: 0)} + &8 {.m4(@b: 1.5; @x...)} + &9 {.aa(@y, @x..., and again, @y...)} + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a {.m3(@a...)} + &b {.m4(0, @a...)} + &c {.m4(@a..., 4)} + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} +=====================================output===================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + depth: @b - 1%; +} + +.mixina (@style, @width, @color: black) { + border: @width @style @color; +} + +.mixiny (@a: 0, @b: 0) { + margin: @a; + padding: @b; +} + +.hidden() { + color: transparent; // asd +} + +#hidden { + .hidden(); +} + +#hidden1 { + .hidden(); +} + +.two-args { + color: blue; + .mixin(2px, 100%); + .mixina(dotted, 2px); +} + +.one-arg { + .mixin(3px); +} + +.no-args { + .mixin(); +} + +.var-args { + @var: 9; + .mixin(@var, (@var * 2) / 2); +} + +.multi-mix { + .mixin(2px, 30%); + .mixiny(4, 5); +} + +.maxa(@arg1: 10, @arg2: #f00) { + padding: (@arg1 * 2px); + color: @arg2; +} + +body { + .maxa(15); +} + +@glob: 5; +.global-mixin(@a:2) { + width: (@glob + @a); +} + +.scope-mix { + .global-mixin(3); +} + +.nested-ruleset (@width: 200px) { + width: @width; + .column { + margin: @width; + } +} +.content { + .nested-ruleset(600px); +} + +// + +.same-var-name2(@radius) { + radius: @radius; +} +.same-var-name(@radius) { + .same-var-name2(@radius); +} +#same-var-name { + .same-var-name(5px); +} + +// + +.var-inside () { + @var: 10px; + width: @var; +} +#var-inside { + .var-inside(); +} + +.mixin-arguments (@width: 0px, ...) { + border: @arguments; + width: @width; +} + +.arguments { + .mixin-arguments(1px, solid, black); +} +.arguments2 { + .mixin-arguments(); +} +.arguments3 { + .mixin-arguments(); +} + +.mixin-arguments2 (@width, @rest...) { + border: @arguments; + rest: @rest; + width: @width; +} +.arguments4 { + .mixin-arguments2(0, 1, 2, 3, 4); +} + +// Edge cases + +.edge-case { + .mixin-arguments("{"); +} + +// Division vs. Literal Slash +.border-radius(@r: 2px/5px) { + border-radius: @r; +} +.slash-vs-math { + .border-radius(); + .border-radius(5px/10px); + .border-radius((3px * 2)); +} +// semi-colon vs comma for delimiting + +.mixin-takes-one(@a) { + one: @a; +} + +.mixin-takes-two(@a; @b) { + one: @a; + two: @b; +} + +.comma-vs-semi-colon { + .mixin-takes-two(@a : a; @b : b, c); + .mixin-takes-two(@a : d, e; @b : f); + .mixin-takes-one(@a: g); + .mixin-takes-one(@a : h;); + .mixin-takes-one(i); + .mixin-takes-one(j;); + .mixin-takes-two(k, l); + .mixin-takes-one(m, n;); + .mixin-takes-two(o, p; q); + .mixin-takes-two(r, s; t;); +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC) { + three: @a, @b, @c; +} + +.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { + four: @a, @b, @c, @d; +} + +#named-conflict { + .mixin-conflict(11, 12, 13, @a:a); + .mixin-conflict(@a:a, 21, 22, 23); +} +@a: 3px; +.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { + defaults: 1px 1px 1px; + defaults: 2px 2px 2px; +} + +.test-rule-mixin-default-arg { + .mixin-default-arg(); + .mixin-default-arg(2px); +} + +.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector { + .mixin-comma-default1(#33acfe; 4); +} +.mixin-comma-default2(@margin: 2, 2, 2, 2;) { + margin: @margin; +} +.selector2 { + .mixin-comma-default2(); +} +.mixin-comma-default3(@margin: 2, 2, 2, 2) { + margin: @margin; +} +.selector3 { + .mixin-comma-default3(4,2,2,2); +} + +.test-rule-calling-one-arg-mixin(@a) { +} + +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { +} + +div { + .test-rule-calling-one-arg-mixin(1); +} + +mixins-args-expand-op- { + @x: 1, 2, 3; + @y: 4 5 6; + + &1 { + .m3(@x...); + } + &2 { + .m3(@y...); + } + &3 { + .wr(a, b, c); + } + &4 { + .wr(a; b; c, d); + } + &5 { + .wr(@x...); + } + &6 { + .m4(0; @x...); + } + &7 { + .m4(@x..., @a: 0); + } + &8 { + .m4(@b: 1.5; @x...); + } + &9 { + .aa(@y, @x..., and again, @y...); + } + + .m3(@a, @b, @c) { + m3: @a, @b, @c; + } + + .m4(@a, @b, @c, @d) { + m4: @a, @b, @c, @d; + } + + .wr(@a...) { + &a { + .m3(@a...); + } + &b { + .m4(0, @a...); + } + &c { + .m4(@a..., 4); + } + } + + .aa(@a...) { + aa: @a; + a4: extract(@a, 5); + a8: extract(@a, 8); + } +} +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} + +================================================================================ +`; + +exports[`snippet: tests-config/math-strict/parens.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.parens-issues-3616 { + bar: if(false, 666, 888 / 444); + bar2: if(false, 666, (666 / 333)); + bar3: if(false, 666, ((444 / 222))); +} + +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-rule-false-negatives { + a: ~"("; +} + +=====================================output===================================== +.parens-issues-3616 { + bar: if(false, 666, 888 / 444); + bar2: if(false, 666, (666 / 333)); + bar3: if(false, 666, ((444 / 222))); +} + +.parens { + @var: 1px; + border: (@var * 2) solid black; + margin: (@var * 1) (@var + 2) (4 * 4) 3; + width: (6 * 6); + padding: 2px (6 * 6px); +} + +.more-parens { + @var: (2 * 2); + padding: (2 * @var) 4 4 (@var * 1px); + width-all: ((@var * @var) * 6); + width-first: ((@var * @var)) * 6; + width-keep: (@var * @var) * 6; + height: calc(100% + (25vh - 20px)); + height-keep: (7 * 7) + (8 * 8); + height-all: ((7 * 7) + (8 * 8)); + height-parts: ((7 * 7)) + ((8 * 8)); + margin-keep: (4 * (5 + 5) / 2) - (@var * 2); + margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); + margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); + border-radius-keep: 4px * (1 + 1) / @var + 3px; + border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); + border-radius-all: (4px * (1 + 1) / @var + 3px); + // margin: (6 * 6)px; +} + +.negative { + @var: 1; + neg-var: -@var; // -1 ? + neg-var-paren: -(@var); // -(1) ? +} + +.nested-parens { + width: 2 * (4 * (2 + (1 + 6))) - 1; + height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; +} + +.mixed-units { + margin: 2px 4em 1 5pc; + padding: (2px + 4px) 1em 2px 2; +} + +.test-rule-false-negatives { + a: ~"("; +} + +================================================================================ +`; + +exports[`snippet: tests-config/modifyVars/extended.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#header { + color: (@base-color * 3); + border-left: @the-border; + border-right: (@the-border * 2); +} +#footer { + color: (@base-color + #003300); + border-color: @red; +} +@red: blue; // var is overridden by the modifyVars +//@base-color: green; +=====================================output===================================== +#header { + color: (@base-color * 3); + border-left: @the-border; + border-right: (@the-border * 2); +} +#footer { + color: (@base-color + #003300); + border-color: @red; +} +@red: blue; // var is overridden by the modifyVars +//@base-color: green; + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/imports/a-better-bootstrap.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#theme() { + .light() {} //... + .dark() { + // ... + .navbar() { + .colors() { + primary: blue; + secondary: lightblue; + } + } + // ... + } +} +=====================================output===================================== +#theme() { + .light() { + } //... + .dark() { + // ... + .navbar() { + .colors() { + primary: blue; + secondary: lightblue; + } + } + // ... + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/imports/library.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +// I am a library +#library { + .sizes() { + @width: 600px; + } + .add-one(@val) { + @return: @val + 1px; + } + .sizes(@test) when (@test = true) { + @width: 400px; + } +} + + +=====================================output===================================== +// I am a library +#library { + .sizes() { + @width: 600px; + } + .add-one(@val) { + @return: @val + 1px; + } + .sizes(@test) when (@test = true) { + @width: 400px; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-1.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@varToGet: default-color; +.foo { + color1: @defaults[@default-color]; + color2: @defaults[@nested][@color]; + color3: @theme[color]; + color4: @theme[@nested][color]; + color5: @defaults[@@varToGet]; + prop: #ns1[foo]; + var: #ns1[@foo]; + sub: #ns1.vars[$sub]; +} + +@defaults: { + @default-color: red; + @nested: { + @color: yellow; + } +}; + +@theme: { + color: red; + @nested: { + color: yellow; + } +}; + +#ns1 { + foo: bar; + @foo: baz; + .vars() { + sub: value; + } +} + +// Test that it matches more than one mixin +#ns1 { + foo: uno; + @foo: dos; + .vars() { + sub: tres; + } +} + +// https://github.com/less/less.js/issues/3346 +#DEF() { + .colors() { primary: grey; } +} + +.button { + color: #DEF.colors[primary]; + border-color: #AAA #CCC; +} +=====================================output===================================== +@varToGet: default-color; +.foo { + color1: @defaults[@default-color]; + color2: @defaults[@nested][@color]; + color3: @theme[color]; + color4: @theme[@nested][color]; + color5: @defaults[@@varToGet]; + prop: #ns1[foo]; + var: #ns1[ @foo]; + sub: #ns1.vars[$sub]; +} + +@defaults: { + @default-color: red; + @nested: { + @color: yellow; + }; +}; + +@theme: { + color: red; + @nested: { + color: yellow; + }; +}; + +#ns1 { + foo: bar; + @foo: baz; + .vars() { + sub: value; + } +} + +// Test that it matches more than one mixin +#ns1 { + foo: uno; + @foo: dos; + .vars() { + sub: tres; + } +} + +// https://github.com/less/less.js/issues/3346 +#DEF() { + .colors() { + primary: grey; + } +} + +.button { + color: #DEF.colors[primary]; + border-color: #aaa #ccc; +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-2.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "imports/library.less"; + +.bar { + width: #library.sizes[@width]; + height: #library.add-one(1px)[@return]; +} + +// I'm gonna override some values +#library { + .sizes() { + @width: 800px; + } +} + +.foo { + width: #library.sizes[@width]; +} + +.foods() { + @dessert: ice cream; +} + +@key-to-lookup: dessert; + +.lunch { + treat: .foods[@@key-to-lookup]; +} +=====================================output===================================== +@import "imports/library.less"; + +.bar { + width: #library.sizes[ @width]; + height: #library.add-one(1px)[@return]; +} + +// I'm gonna override some values +#library { + .sizes() { + @width: 800px; + } +} + +.foo { + width: #library.sizes[ @width]; +} + +.foods() { + @dessert: ice cream; +} + +@key-to-lookup: dessert; + +.lunch { + treat: .foods[ @@key-to-lookup]; +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-3.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@map: { + @width: 400px; + @colors: { + toolbar-background: red; + toolbar-foreground: inherit; + } +}; + +#ns { + .mixin() { + @height: 200px; + } +} + +@breakpoints: { + mobile: 320px; + tablet: 768px; + desktop: 1024px; +}; + +@media (min-width: @breakpoints[mobile]) { + .toolbar { + width: @map[@width]; + height: #ns.mixin[@height]; + background: @map[@colors][toolbar-background]; + color: @map[@colors][toolbar-foreground]; + } +} + +// !important after map usage +// https://github.com/less/less.js/issues/3430 +@margins: { + zero: 0; + ten: 10px; +} +.cell { + margin: @margins[zero] (@margins[ten]/2) !important; +} + +.mixin(@color: black; @margin: 10px; @padding: 20px) { + color: @color; + margin: @margin; + padding: @padding; + width: @margins[zero] !important +} +.class1 { + .mixin(@margin: 20px; @color: #33acfe) !important; +} +.class2 { + .mixin(#efca44; @padding: 40px 10px); +} + +=====================================output===================================== +@map: { + @width: 400px; + @colors: { + toolbar-background: red; + toolbar-foreground: inherit; + }; +}; + +#ns { + .mixin() { + @height: 200px; + } +} + +@breakpoints: { + mobile: 320px; + tablet: 768px; + desktop: 1024px; +}; + +@media (min-width: @breakpoints[mobile]) { + .toolbar { + width: @map[@width]; + height: #ns.mixin[ @height]; + background: @map[@colors][toolbar-background]; + color: @map[@colors][toolbar-foreground]; + } +} + +// !important after map usage +// https://github.com/less/less.js/issues/3430 +@margins: { + zero: 0; + ten: 10px; +}; +.cell { + margin: @margins[zero] (@margins[ten] / 2) !important; +} + +.mixin(@color: black; @margin: 10px; @padding: 20px) { + color: @color; + margin: @margin; + padding: @padding; + width: @margins[zero] !important; +} +.class1 { + .mixin(@margin: 20px; @color: #33acfe) !important; +} +.class2 { + .mixin(#efca44; @padding: 40px 10px); +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-4.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#ns { + .mixin(@a) when (@a = 1) { + @a: 20px; + } +} + +.alias() { + #ns.mixin(1); +} + +#library { + .core() { + .colors() { + primary: blue; + foreground: inherit; + } + } +} + +#library { + .core() { + .colors() { + primary: rebeccapurple; + } + } +} + +.foo { + .colors() { #library.core.colors(); } + width: .alias[@a]; + background: .colors[primary]; + color: .colors[foreground]; +} +=====================================output===================================== +#ns { + .mixin(@a) when (@a = 1) { + @a: 20px; + } +} + +.alias() { + #ns.mixin(1); +} + +#library { + .core() { + .colors() { + primary: blue; + foreground: inherit; + } + } +} + +#library { + .core() { + .colors() { + primary: rebeccapurple; + } + } +} + +.foo { + .colors() { + #library.core.colors(); + } + width: .alias[ @a]; + background: .colors[primary]; + color: .colors[foreground]; +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-5.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "imports/a-better-bootstrap"; + +#theme.dark.navbar { + .colors() { + primary: rebeccapurple; + } + .colors(dark) { + primary: black; + secondary: grey; + } + .test-rule() { + val: output; + } +} + +.my-navbar { + #theme.dark.navbar(); + background: .colors[primary]; + .test-rule(); +} + +.another-navbar { + @colors: #theme.dark.navbar.colors() !important; + background: @colors[primary]; + border: 1px solid @colors[secondary]; +} + +.another { + @colors: #theme.dark.navbar.colors(dark); + background: @colors[primary]; + border: 1px solid @colors[secondary]; +} +=====================================output===================================== +@import "imports/a-better-bootstrap"; + +#theme.dark.navbar { + .colors() { + primary: rebeccapurple; + } + .colors(dark) { + primary: black; + secondary: grey; + } + .test-rule() { + val: output; + } +} + +.my-navbar { + #theme.dark.navbar(); + background: .colors[primary]; + .test-rule(); +} + +.another-navbar { + @colors: #theme.dark.navbar.colors() !important; + background: @colors[primary]; + border: 1px solid @colors[secondary]; +} + +.another { + @colors: #theme.dark.navbar.colors(dark); + background: @colors[primary]; + border: 1px solid @colors[secondary]; +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-6.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.wrapper(@another-mixin) { + @another-mixin(); +} + +.something(foo) { + width: 10px; +} + +.output-height() { + height: 10px; +} + +.rule-1 { + @alias: .something(foo); + @alias(); +} + +.rule-2 { + @alias: .something(foo); + .wrapper(@alias); +} + +.rule-3 { + .wrapper(.something(foo)); + .wrapper(.output-height()); +} +=====================================output===================================== +.wrapper(@another-mixin) { + @another-mixin(); +} + +.something(foo) { + width: 10px; +} + +.output-height() { + height: 10px; +} + +.rule-1 { + @alias: .something(foo); + @alias(); +} + +.rule-2 { + @alias: .something(foo); + .wrapper(@alias); +} + +.rule-3 { + .wrapper(.something(foo)); + .wrapper(.output-height()); +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-7.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#ns { + .options() { + option: true; + } +} + +@ns: { + @options: { + option: true; + }; +}; + +& when (#ns.options[option]) { + .output { + a: b; + } +} + +& when (#ns.options[option] = true) { + .output-2 { + c: d; + } +} + +& when (#ns.options[option] = false) { + .no-reach { + c: d; + } +} + +// DR access +& when (@ns[@options][option]) { + .dr { + a: b; + } +} + +& when (@ns[@options][option] = true) { + .dr-2 { + c: d; + } +} + +& when (@ns[@options][option] = false) { + .dr-no-reach { + c: d; + } +} +=====================================output===================================== +#ns { + .options() { + option: true; + } +} + +@ns: { + @options: { + option: true; + }; +}; + +& when (#ns.options[option]) { + .output { + a: b; + } +} + +& when (#ns.options[option] = true) { + .output-2 { + c: d; + } +} + +& when (#ns.options[option] = false) { + .no-reach { + c: d; + } +} + +// DR access +& when (@ns[@options][option]) { + .dr { + a: b; + } +} + +& when (@ns[@options][option] = true) { + .dr-2 { + c: d; + } +} + +& when (@ns[@options][option] = false) { + .dr-no-reach { + c: d; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-8.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// see: https://github.com/less/less.js/issues/3368 +@vars: { + background-color: black; + color: contrast($background-color, #000, #fff); +} + +:root { + each(@vars, { + --@{key}: @value; + }); +} + +div { + display: inline-block; + padding: 1rem; + background-color: var(--background-color); + color: var(--color); +} + +// see: https://github.com/less/less.js/issues/3339 +// still fails - move to 4.0 +// @components: { +// columns: true; +// ratios: false; +// }; + +// each(@components, { +// & when (@value = true) { +// @import (optional) "components/@{key}.less"; +// } +// }); +=====================================output===================================== +// see: https://github.com/less/less.js/issues/3368 +@vars: { + background-color: black; + color: contrast($background-color, #000, #fff); +}; + +:root { + each(@vars, { + --@{key}: @value; + }); +} + +div { + display: inline-block; + padding: 1rem; + background-color: var(--background-color); + color: var(--color); +} + +// see: https://github.com/less/less.js/issues/3339 +// still fails - move to 4.0 +// @components: { +// columns: true; +// ratios: false; +// }; + +// each(@components, { +// & when (@value = true) { +// @import (optional) "components/@{key}.less"; +// } +// }); + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-functions.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.add(@a, @b) { + @r: @a + @b; +} +.foo { + width: .add(10px, 10px)[]; + bar: @return[]; +} + +@return: { + single: val; +} + +// Issue #3405 +#lookup { + @prop: test; +} + +.mix (@var) { + width: @var; +} + +.bar { + .mix(#lookup[@prop]); +} + +// Issue #3406 +.mix2 (@n) { + value: @n; +} +#lookup2 { + @var: .mix2(lookup); +} +.example { + // #lookup[@var](); -- fails, need the following alias + @dr: #lookup2[@var]; + @dr(); +} +=====================================output===================================== +.add(@a, @b) { + @r: @a + @b; +} +.foo { + width: .add(10px, 10px) []; + bar: @return[]; +} + +@return: { + single: val; +}; + +// Issue #3405 +#lookup { + @prop: test; +} + +.mix (@var) { + width: @var; +} + +.bar { + .mix(#lookup[@prop]); +} + +// Issue #3406 +.mix2 (@n) { + value: @n; +} +#lookup2 { + @var: .mix2(lookup); +} +.example { + // #lookup[@var](); -- fails, need the following alias + @dr: #lookup2[ @var]; + @dr(); +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-media.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#ns { + .sizes() { + @small: 600px; + } + .breakpoint(@size) { + @val: #ns.sizes[@@size]; + @min: (min-width: @val); + @max: not all and @min; + } +} + +#ns { + .sizes() { + @small: 480px; + } +} + +.valToGet() { + keyword: small; +} + +@media #ns.breakpoint(.valToGet[])[@max] { + .selector { + prop: val; + } +} +=====================================output===================================== +#ns { + .sizes() { + @small: 600px; + } + .breakpoint(@size) { + @val: #ns.sizes[ @@size]; + @min: (min-width: @val); + @max: not all and @min; + } +} + +#ns { + .sizes() { + @small: 480px; + } +} + +.valToGet() { + keyword: small; +} + +@media #ns.breakpoint(.valToGet[]) [@max] { + .selector { + prop: val; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/namespacing/namespacing-operations.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#ns { + .options() { + val1: 10px; + } +} + +@ns: { + @options: { + val2: 20px; + } +} + +.foo { + val: #ns.options[val1] + @ns[@options][val2] + 5px; +} +=====================================output===================================== +#ns { + .options() { + val1: 10px; + } +} + +@ns: { + @options: { + val2: 20px; + }; +}; + +.foo { + val: #ns.options[val1] + @ns[@options][val2] + 5px; +} + +================================================================================ +`; + +exports[`snippet: tests-config/no-js-errors/no-js-errors.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.a { + a: \`1 + 1\`; +} +=====================================output===================================== +.a { + a: \`1 + 1\`; +} + +================================================================================ +`; + +exports[`snippet: tests-config/postProcessorPlugin/postProcessor.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@color: inherit; +.test-rule { + color: @color; +} + +=====================================output===================================== +@color: inherit; +.test-rule { + color: @color; +} + +================================================================================ +`; + +exports[`snippet: tests-config/preProcessorPlugin/preProcessor.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.test-rule { + color: @color; +} + +=====================================output===================================== +.test-rule { + color: @color; +} + +================================================================================ +`; + +exports[`snippet: tests-config/process-imports/google.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); + +.a { b: c; } +=====================================output===================================== +@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,700"); + +.a { + b: c; +} + +================================================================================ +`; + +exports[`snippet: tests-config/rewrite-urls-all/folder/file.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rewrite-urls-all/rewrite-urls-all.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "./folder/file.less"; + +#rewrite-urls-all { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +@import "./folder/file.less"; + +#rewrite-urls-all { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rewrite-urls-local/folder/file.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rewrite-urls-local/rewrite-urls-local.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "./folder/file.less"; + +#rewrite-urls-local { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +@import "./folder/file.less"; + +#rewrite-urls-local { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/root-registry/file.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "utf-8"; +=====================================output===================================== +@charset "utf-8"; + +================================================================================ +`; + +exports[`snippet: tests-config/root-registry/root.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/less/less.js/issues/3112 +@file: ext(); +@import '@{file}'; +=====================================output===================================== +// https://github.com/less/less.js/issues/3112 +@file: ext(); +@import "@{file}"; + +================================================================================ +`; + +exports[`snippet: tests-config/rootpath-rewrite-urls-all/folder/file.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rootpath-rewrite-urls-all/rootpath-rewrite-urls-all.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "./folder/file.less"; + +#rootpath-rewrite-urls-all { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +@import "./folder/file.less"; + +#rootpath-rewrite-urls-all { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rootpath-rewrite-urls-local/folder/file.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +#imported-file { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("../../relative/path"); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/rootpath-rewrite-urls-local/rootpath-rewrite-urls-local.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "./folder/file.less"; + +#rootpath-rewrite-urls-local { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +=====================================output===================================== +@import "./folder/file.less"; + +#rootpath-rewrite-urls-local { + background-image: url("./relative/path"); + background-image: url("../relative/path"); + background-image: url("./relative/../path"); + background-image: url("./relative/../path/.."); + background-image: url("module"); + background-image: url("module/path"); + background-image: url("module/path/../relative/path"); +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps/basic.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@var: black; + +.a() { + color: red; +} + +.b { + color: green; + .a(); + color: blue; + background: @var; +} + +.a, .b { + background: green; + .c, .d { + background: gray; + & + & { + color: red; + } + } +} + +.extend:extend(.a all) { + color: pink; +} +@import (inline) "imported.css"; +=====================================output===================================== +@var: black; + +.a() { + color: red; +} + +.b { + color: green; + .a(); + color: blue; + background: @var; +} + +.a, +.b { + background: green; + .c, + .d { + background: gray; + & + & { + color: red; + } + } +} + +.extend:extend(.a all) { + color: pink; +} +@import (inline) "imported.css"; + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps/comprehensive/comprehensive.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Comprehensive sourcemap test covering various Less.js features +// This test exercises sourcemap generation for different code structures + +// Variables +@primary-color: #3498db; +@secondary-color: #2ecc71; +@spacing: 20px; + +// Mixins +.border-radius(@radius: 5px) { + border-radius: @radius; + -webkit-border-radius: @radius; + -moz-border-radius: @radius; +} + +.box-shadow(@x: 0, @y: 0, @blur: 10px, @color: rgba(0,0,0,0.5)) { + box-shadow: @x @y @blur @color; +} + +// Nested rules +.container { + padding: @spacing; + background: @primary-color; + + .header { + color: white; + font-size: 24px; + + .title { + font-weight: bold; + margin-bottom: 10px; + } + } + + .content { + background: @secondary-color; + padding: 15px; + + p { + margin: 0; + line-height: 1.5; + } + } +} + +// Operations +.calculated { + width: calc(100% - @spacing * 2); + height: calc(50vh + 20px); + margin: (@spacing / 2); +} + +// Functions +.functions { + color: darken(@primary-color, 10%); + background: lighten(@secondary-color, 20%); + border: 1px solid fade(@primary-color, 50%); +} + +// Mixins +.card { + .border-radius(10px); + .box-shadow(0, 2px, 15px, rgba(0,0,0,0.1)); + padding: @spacing; + background: white; +} + +// @-rules +@media (max-width: 768px) { + .container { + padding: (@spacing / 2); + + .header { + font-size: 18px; + } + } +} + +@supports (display: grid) { + .grid-layout { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: @spacing; + } +} + +// Extend +.button-base { + padding: 10px 20px; + border: none; + cursor: pointer; +} + +.button-primary { + &:extend(.button-base); + background: @primary-color; + color: white; +} + +// Selectors with & +.navigation { + ul { + list-style: none; + + li { + display: inline-block; + + a { + text-decoration: none; + + &:hover { + color: @primary-color; + } + + &:active { + color: darken(@primary-color, 20%); + } + } + } + } +} + +// Import (if we have imported files) +// @import "imported.less"; + +// Variables in selectors +@selector-name: my-component; +.@{selector-name} { + color: @primary-color; +} + +// Multiple levels of nesting +.level1 { + .level2 { + .level3 { + .level4 { + color: @secondary-color; + } + } + } +} + + +=====================================output===================================== +// Comprehensive sourcemap test covering various Less.js features +// This test exercises sourcemap generation for different code structures + +// Variables +@primary-color: #3498db; +@secondary-color: #2ecc71; +@spacing: 20px; + +// Mixins +.border-radius(@radius: 5px) { + border-radius: @radius; + -webkit-border-radius: @radius; + -moz-border-radius: @radius; +} + +.box-shadow(@x: 0, @y: 0, @blur: 10px, @color: rgba(0,0,0,0.5)) { + box-shadow: @x @y @blur @color; +} + +// Nested rules +.container { + padding: @spacing; + background: @primary-color; + + .header { + color: white; + font-size: 24px; + + .title { + font-weight: bold; + margin-bottom: 10px; + } + } + + .content { + background: @secondary-color; + padding: 15px; + + p { + margin: 0; + line-height: 1.5; + } + } +} + +// Operations +.calculated { + width: calc(100% - @spacing * 2); + height: calc(50vh + 20px); + margin: (@spacing / 2); +} + +// Functions +.functions { + color: darken(@primary-color, 10%); + background: lighten(@secondary-color, 20%); + border: 1px solid fade(@primary-color, 50%); +} + +// Mixins +.card { + .border-radius(10px); + .box-shadow(0, 2px, 15px, rgba(0,0,0,0.1)); + padding: @spacing; + background: white; +} + +// @-rules +@media (max-width: 768px) { + .container { + padding: (@spacing / 2); + + .header { + font-size: 18px; + } + } +} + +@supports (display: grid) { + .grid-layout { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: @spacing; + } +} + +// Extend +.button-base { + padding: 10px 20px; + border: none; + cursor: pointer; +} + +.button-primary { + &:extend(.button-base); + background: @primary-color; + color: white; +} + +// Selectors with & +.navigation { + ul { + list-style: none; + + li { + display: inline-block; + + a { + text-decoration: none; + + &:hover { + color: @primary-color; + } + + &:active { + color: darken(@primary-color, 20%); + } + } + } + } +} + +// Import (if we have imported files) +// @import "imported.less"; + +// Variables in selectors +@selector-name: my-component; +.@{selector-name} { + color: @primary-color; +} + +// Multiple levels of nesting +.level1 { + .level2 { + .level3 { + .level4 { + color: @secondary-color; + } + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps/custom-props.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@color: var(--foo); + +body { + border-left: 1px solid @color; + width: calc(50% - 5px); + border-top: 1px solid @color; +} + + +=====================================output===================================== +@color: var(--foo); + +body { + border-left: 1px solid @color; + width: calc(50% - 5px); + border-top: 1px solid @color; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-basepath/sourcemaps-basepath.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@size: 16px; + +.text { + font-size: @size; + line-height: 1.5; +} + +.title { + font-weight: bold; +} + + +=====================================output===================================== +@size: 16px; + +.text { + font-size: @size; + line-height: 1.5; +} + +.title { + font-weight: bold; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-disable-annotation/basic.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +body { + /*# sourceMappingURL=this-should-be-ok.css.map */ + color: white; +} +=====================================output===================================== +body { + /*# sourceMappingURL=this-should-be-ok.css.map */ + color: white; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-empty/empty.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +=====================================output===================================== + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-empty/var-defs.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@test-var: 'something'; +=====================================output===================================== +@test-var: "something"; + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-include-source/sourcemaps-include-source.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@primary: #007bff; +@secondary: #6c757d; + +.button { + background: @primary; + color: white; + padding: 10px 20px; +} + +.secondary { + background: @secondary; +} + + +=====================================output===================================== +@primary: #007bff; +@secondary: #6c757d; + +.button { + background: @primary; + color: white; + padding: 10px 20px; +} + +.secondary { + background: @secondary; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-rootpath/sourcemaps-rootpath.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@var: green; + +.container { + padding: 20px; + color: @var; +} + +.item { + margin: 5px; +} + + +=====================================output===================================== +@var: green; + +.container { + padding: 20px; + color: @var; +} + +.item { + margin: 5px; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-url/sourcemaps-url.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@color: red; + +.header { + color: @color; + background: blue; +} + +.footer { + margin: 10px; +} + + +=====================================output===================================== +@color: red; + +.header { + color: @color; + background: blue; +} + +.footer { + margin: 10px; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-variable-selector/basic.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import (reference) "./vars.less"; + +.@{hello}-class { + font-size: @font-size; +} + +=====================================output===================================== +@import (reference) "./vars.less"; + +.@{hello}-class { + font-size: @font-size; +} + +================================================================================ +`; + +exports[`snippet: tests-config/sourcemaps-variable-selector/vars.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@foo: bar; +@font-size: 12px; +@hello: world; + +=====================================output===================================== +@foo: bar; +@font-size: 12px; +@hello: world; + +================================================================================ +`; + +exports[`snippet: tests-config/static-urls/urls.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); +} + +#svg-data-uri { + background: transparent url('data:image/svg+xml, '); +} + +.comma-delimited { + background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); +} +.values { + @a: 'Trebuchet'; + url: url(@a); +} + +@import "../../tests-unit/import/import/import-and-relative-paths-test"; + + +=====================================output===================================== +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: + local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); +} + +#svg-data-uri { + background: transparent + url('data:image/svg+xml, '); +} + +.comma-delimited { + background: + url(bg.jpg) no-repeat, + url(bg.png) repeat-x top left, + url(bg); +} +.values { + @a: "Trebuchet"; + url: url(@a); +} + +@import "../../tests-unit/import/import/import-and-relative-paths-test"; + +================================================================================ +`; + +exports[`snippet: tests-config/strict-imports/imported.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.imported { + background: green; +} + +=====================================output===================================== +.imported { + background: green; +} + +================================================================================ +`; + +exports[`snippet: tests-config/strict-imports/strict-imports.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Test that strictImports: true allows @import at root level +@import "imported.less"; + +// Test that strictImports: true allows @import inside @media blocks +@media (max-width: 768px) { + @import "imported.less"; + .mobile { + color: red; + } +} + +// Test that strictImports: true skips @import inside selector blocks (import is not processed) +.container { + @import "imported.less"; + .nested { + color: blue; + } +} + + +=====================================output===================================== +// Test that strictImports: true allows @import at root level +@import "imported.less"; + +// Test that strictImports: true allows @import inside @media blocks +@media (max-width: 768px) { + @import "imported.less"; + .mobile { + color: red; + } +} + +// Test that strictImports: true skips @import inside selector blocks (import is not processed) +.container { + @import "imported.less"; + .nested { + color: blue; + } +} + +================================================================================ +`; + +exports[`snippet: tests-config/units/no-strict/no-strict.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@media (-o-min-device-pixel-ratio: 2) { + .test-rule-math-and-units { + font: ignores 0/0 rules; + test-division: 4 / 2 + 5em; + simple: 1px + 1px; + } +} +#units { + t1: (2em/1em) + 20; + t2: 20 + (2em/1em); + t3: 2em/1em; + t4: (2em/1px) + 20; + t5: 20 + (2em/1px); + t6: 2em/1px; + t7: (2em*1em) + 20; + t8: 20 + (2em*1em); + t9: 2em*1em; + t10: (2em*1px) + 20; + t11: 20 + (2em*1px); + t12: 2em*1px; +} +=====================================output===================================== +@media (-o-min-device-pixel-ratio: 2) { + .test-rule-math-and-units { + font: ignores 0/0 rules; + test-division: 4 / 2 + 5em; + simple: 1px + 1px; + } +} +#units { + t1: (2em/1em) + 20; + t2: 20 + (2em/1em); + t3: 2em/1em; + t4: (2em/1px) + 20; + t5: 20 + (2em/1px); + t6: 2em/1px; + t7: (2em * 1em) + 20; + t8: 20 + (2em * 1em); + t9: 2em * 1em; + t10: (2em * 1px) + 20; + t11: 20 + (2em * 1px); + t12: 2em * 1px; +} + +================================================================================ +`; + +exports[`snippet: tests-config/units/strict/strict-units.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.units { + cancels-to-nothing: (1px / 1px); + cancels: ((((10px / 5em) / 1px) * 3em) * 1px); +} + +=====================================output===================================== +.units { + cancels-to-nothing: (1px / 1px); + cancels: ((((10px / 5em) / 1px) * 3em) * 1px); +} + +================================================================================ +`; + +exports[`snippet: tests-config/url-args/urls.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; + background: url("img.jpg") center / 100px; + background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); + background-image: url("http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700"); +} + +#svg-data-uri { + background: transparent url('data:image/svg+xml, '); +} + +.comma-delimited { + background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); +} +.values { + @a: 'Trebuchet'; + url: url(@a); +} + +@import "../../tests-unit/import/import/imports/font"; + +#data-uri { + uri: data-uri('image/jpeg;base64', '../../data/image.jpg'); +} + +#data-uri-guess { + uri: data-uri('../../data/image.jpg'); +} + +#data-uri-ascii { + uri-1: data-uri('text/html', '../../data/page.html'); + uri-2: data-uri('../../data/page.html'); +} + +#svg-functions { + background-image: svg-gradient(to bottom, black, white); + background-image: svg-gradient(to bottom, black, orange 3%, white); + @green_5: green 5%; + @orange_percentage: 3%; + @orange_color: orange; + background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); +} + +#data-uri-with-spaces { + background-image: url( data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url( ' data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9=='); +} + +=====================================output===================================== +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: + local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; + background: url("img.jpg") center / 100px; + background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box + padding-box; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); + background-image: url('http://fonts.googleapis.com/css?family="Rokkitt":\\(400\\),700'); +} + +#svg-data-uri { + background: transparent + url('data:image/svg+xml, '); +} + +.comma-delimited { + background: + url(bg.jpg) no-repeat, + url(bg.png) repeat-x top left, + url(bg); +} +.values { + @a: "Trebuchet"; + url: url(@a); +} + +@import "../../tests-unit/import/import/imports/font"; + +#data-uri { + uri: data-uri("image/jpeg;base64", "../../data/image.jpg"); +} + +#data-uri-guess { + uri: data-uri("../../data/image.jpg"); +} + +#data-uri-ascii { + uri-1: data-uri("text/html", "../../data/page.html"); + uri-2: data-uri("../../data/page.html"); +} + +#svg-functions { + background-image: svg-gradient(to bottom, black, white); + background-image: svg-gradient(to bottom, black, orange 3%, white); + @green_5: green 5%; + @orange_percentage: 3%; + @orange_color: orange; + background-image: svg-gradient( + to bottom, + (mix(black, white) + #444) 1%, + @orange_color @orange_percentage, + ((@green_5)), + white 95% + ); +} + +#data-uri-with-spaces { + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(" data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9=="); +} + +================================================================================ +`; + +exports[`snippet: tests-config/visitorPlugin/visitor.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.test-rule { + color: red; + -some-aribitrary-property: value; +} + +=====================================output===================================== +.test-rule { + color: red; + -some-aribitrary-property: value; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules/at-rules.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Test various @-rule types and structures + +// @page with simple block +@page { + margin: 2cm; + @top-left { + content: "Page " counter(page); + } +} + +// @page with nested rules +@page :first { + margin: 3cm; + @top-center { + content: "First Page"; + } +} + +// @charset +@charset "UTF-8"; + +// @namespace +@namespace url(http://www.w3.org/1999/xhtml); +@namespace svg url(http://www.w3.org/2000/svg); + +// @viewport +@viewport { + width: device-width; + initial-scale: 1.0; +} + +// @keyframes with simple block +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + to { + margin-left: 0%; + width: 100%; + } +} + +// @keyframes with nested rules (name can be a string) +@keyframes "complex-animation" { + 0% { + opacity: 0; + transform: scale(0.5); + } + 50% { + opacity: 0.5; + transform: scale(1.2); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +// @font-face with simple block +@font-face { + font-family: "MyFont"; + src: url("myfont.woff2") format("woff2"); + font-weight: normal; + font-style: normal; +} + +// @font-face with variables +@font-family-name: "CustomFont"; +@font-face { + font-family: @font-family-name; + src: url("custom.woff") format("woff"); +} + +// @supports with simple block +@supports (display: grid) { + .grid-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + } +} + +// @supports with nested @-rules +@supports (transform-style: preserve-3d) { + @media (min-width: 768px) { + .card { + transform: rotateY(15deg); + } + } +} + +// @media with simple block +@media print { + body { + font-size: 12pt; + color: black; + } +} + +// @media with nested @-rules +@media screen { + @supports (display: flex) { + .container { + display: flex; + } + } +} + +// @-rule with value (not simple block) +@media (max-width: 600px) { + .sidebar { + display: none; + } +} + +// @-rule inside ruleset +.container { + @media (max-width: 768px) { + padding: 10px; + } +} + +// Multiple @-rules +@page :left { + margin-left: 4cm; + margin-right: 3cm; +} + +@page :right { + margin-left: 3cm; + margin-right: 4cm; +} + +// @-rule with mixins +.mixin-with-atrule() { + @media (max-width: 600px) { + .mobile-only { + display: block; + } + } +} + +.wrapper { + .mixin-with-atrule(); +} + +// @-rule with variables in value +@breakpoint: 1024px; +@media (min-width: @breakpoint) { + .desktop { + display: block; + } +} + + +=====================================output===================================== +// Test various @-rule types and structures + +// @page with simple block +@page { + margin: 2cm; + @top-left { + content: "Page " counter(page); + } +} + +// @page with nested rules +@page :first { + margin: 3cm; + @top-center { + content: "First Page"; + } +} + +// @charset +@charset "UTF-8"; + +// @namespace +@namespace url(http://www.w3.org/1999/xhtml); +@namespace svg url(http://www.w3.org/2000/svg); + +// @viewport +@viewport { + width: device-width; + initial-scale: 1; +} + +// @keyframes with simple block +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + to { + margin-left: 0%; + width: 100%; + } +} + +// @keyframes with nested rules (name can be a string) +@keyframes "complex-animation" { + 0% { + opacity: 0; + transform: scale(0.5); + } + 50% { + opacity: 0.5; + transform: scale(1.2); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +// @font-face with simple block +@font-face { + font-family: "MyFont"; + src: url("myfont.woff2") format("woff2"); + font-weight: normal; + font-style: normal; +} + +// @font-face with variables +@font-family-name: "CustomFont"; +@font-face { + font-family: @font-family-name; + src: url("custom.woff") format("woff"); +} + +// @supports with simple block +@supports (display: grid) { + .grid-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + } +} + +// @supports with nested @-rules +@supports (transform-style: preserve-3d) { + @media (min-width: 768px) { + .card { + transform: rotateY(15deg); + } + } +} + +// @media with simple block +@media print { + body { + font-size: 12pt; + color: black; + } +} + +// @media with nested @-rules +@media screen { + @supports (display: flex) { + .container { + display: flex; + } + } +} + +// @-rule with value (not simple block) +@media (max-width: 600px) { + .sidebar { + display: none; + } +} + +// @-rule inside ruleset +.container { + @media (max-width: 768px) { + padding: 10px; + } +} + +// Multiple @-rules +@page :left { + margin-left: 4cm; + margin-right: 3cm; +} + +@page :right { + margin-left: 3cm; + margin-right: 4cm; +} + +// @-rule with mixins +.mixin-with-atrule() { + @media (max-width: 600px) { + .mobile-only { + display: block; + } + } +} + +.wrapper { + .mixin-with-atrule(); +} + +// @-rule with variables in value +@breakpoint: 1024px; +@media (min-width: @breakpoint) { + .desktop { + display: block; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules-declarations/at-rules-declarations.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests for atrule.js line 117 - genCSS with simpleBlock declarations +// Covers parser + genCSS + outputRuleset with declarations path + +// @page with declarations (simpleBlock) +@page { + margin: 2cm; + size: A4; + marks: crop cross; +} + +// @font-face with declarations +@font-face { + font-family: "MyFont"; + src: url("myfont.woff2"); + font-weight: 400; + font-style: normal; +} + +// @counter-style with declarations +@counter-style my-counter { + system: fixed; + symbols: "A" "B" "C"; + suffix: ". "; +} + + +=====================================output===================================== +// Tests for atrule.js line 117 - genCSS with simpleBlock declarations +// Covers parser + genCSS + outputRuleset with declarations path + +// @page with declarations (simpleBlock) +@page { + margin: 2cm; + size: A4; + marks: crop cross; +} + +// @font-face with declarations +@font-face { + font-family: "MyFont"; + src: url("myfont.woff2"); + font-weight: 400; + font-style: normal; +} + +// @counter-style with declarations +@counter-style my-counter { + system: fixed; + symbols: "A" "B" "C"; + suffix: ". "; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules-empty/at-rules-empty.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests for atrule.js line 121 - genCSS with no rules or declarations +// Covers parser + genCSS path + +// @charset without block +@charset "UTF-8"; + +// @import (will be processed separately, but tests the path) +@import url("test.css"); + +// @namespace +@namespace "http://www.w3.org/1999/xhtml"; + +// @namespace with prefix +@namespace svg "http://www.w3.org/2000/svg"; + + +=====================================output===================================== +// Tests for atrule.js line 121 - genCSS with no rules or declarations +// Covers parser + genCSS path + +// @charset without block +@charset "UTF-8"; + +// @import (will be processed separately, but tests the path) +@import url("test.css"); + +// @namespace +@namespace "http://www.w3.org/1999/xhtml"; + +// @namespace with prefix +@namespace svg "http://www.w3.org/2000/svg"; + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules-empty-block/at-rules-empty-block.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests for atrule.js lines 255-256 - empty rules block in non-compressed mode +// Covers parser + genCSS + outputRuleset with empty rules + +// @media with empty block +@media screen { +} + +// @supports with empty block +@supports (display: grid) { +} + +// @layer with empty block +@layer base { +} + +// @page with empty block +@page { +} + + +=====================================output===================================== +// Tests for atrule.js lines 255-256 - empty rules block in non-compressed mode +// Covers parser + genCSS + outputRuleset with empty rules + +// @media with empty block +@media screen { +} + +// @supports with empty block +@supports (display: grid) { +} + +// @layer with empty block +@layer base { +} + +// @page with empty block +@page { +} + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules-keyword-comments/at-rules-keyword-comments.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests for atrule.js keywordList method with Comments (line 84) +// Covers parser + eval + keywordList path +// This tests when a keyword list contains Comments + +@media screen /* comment */, print /* another */, handheld { + body { + font-size: 12pt; + } +} + +// @import with media queries containing comments +@import "test.css" screen /* comment */, print; + + +=====================================output===================================== +// Tests for atrule.js keywordList method with Comments (line 84) +// Covers parser + eval + keywordList path +// This tests when a keyword list contains Comments + +@media screen /* comment */, print /* another */, handheld { + body { + font-size: 12pt; + } +} + +// @import with media queries containing comments +@import "test.css" screen /* comment */, print; + +================================================================================ +`; + +exports[`snippet: tests-unit/at-rules-targeted/at-rules-targeted.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Targeted tests for specific uncovered lines in atrule.js + +// Line 35-36: Single ruleset with declarations (allRulesetDeclarations path) +@media screen { + .test { + color: red; + } +} + +// Line 138-140: Value that evaluates to keyword list (keywordList method) +@media screen, print, handheld { + body { + font-size: 12pt; + } +} + +// Line 146-154: rules[0].rules path with mergeable declarations +@supports (display: grid) { + .grid { + display: grid; + grid-template-columns: 1fr 1fr; + } +} + +// Line 155-158: simpleBlock with rules evaluation +@page { + margin: 2cm; + size: A4; +} + +// Line 172-174: Non-simpleBlock rules evaluation (evalRoot) +@media screen { + @media (max-width: 768px) { + .nested { + display: block; + } + } +} + +// Line 203-215: evalRoot with ampersand counting +.container { + @media screen { + & { + color: red; + } + .child { + color: blue; + } + } +} + +// Line 217-236: variable, find, rulesets methods +// These methods are called when accessing variables/properties from within at-rule scope +@media screen { + @var: value; + .test-var-access { + color: @var; + } +} + +// Line 238-270: outputRuleset (compressed and non-compressed) +@layer base { + body { + margin: 0; + } + p { + padding: 0; + } +} + +// Line 121: At-rule without rules or declarations +@charset "UTF-8"; + +// Line 103-105: isRulesetLike and isCharset +@charset "UTF-8"; +@media screen { + body { + color: black; + } +} + + +=====================================output===================================== +// Targeted tests for specific uncovered lines in atrule.js + +// Line 35-36: Single ruleset with declarations (allRulesetDeclarations path) +@media screen { + .test { + color: red; + } +} + +// Line 138-140: Value that evaluates to keyword list (keywordList method) +@media screen, print, handheld { + body { + font-size: 12pt; + } +} + +// Line 146-154: rules[0].rules path with mergeable declarations +@supports (display: grid) { + .grid { + display: grid; + grid-template-columns: 1fr 1fr; + } +} + +// Line 155-158: simpleBlock with rules evaluation +@page { + margin: 2cm; + size: A4; +} + +// Line 172-174: Non-simpleBlock rules evaluation (evalRoot) +@media screen { + @media (max-width: 768px) { + .nested { + display: block; + } + } +} + +// Line 203-215: evalRoot with ampersand counting +.container { + @media screen { + & { + color: red; + } + .child { + color: blue; + } + } +} + +// Line 217-236: variable, find, rulesets methods +// These methods are called when accessing variables/properties from within at-rule scope +@media screen { + @var: value; + .test-var-access { + color: @var; + } +} + +// Line 238-270: outputRuleset (compressed and non-compressed) +@layer base { + body { + margin: 0; + } + p { + padding: 0; + } +} + +// Line 121: At-rule without rules or declarations +@charset "UTF-8"; + +// Line 103-105: isRulesetLike and isCharset +@charset "UTF-8"; +@media screen { + body { + color: black; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/calc/calc.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@val: 10px; +@var: 50vh/2; + +.calc-basic { + width: calc(100% - 30px); + height: calc(50% + 20px); + margin: calc(10px * 2); + padding: calc(100vh - 50px); +} + +.calc-variables { + @c: 10px + 20px; + @calc: (@val + 30px); + root: calc(100% - @c); + root2: calc(100% - @calc); + width: calc(50% + (@var - 20px)); + height: calc(50% + ((@var - 20px))); +} + +.calc-nested { + min-height: calc(((10vh)) + calc((5vh))); + nested: calc(calc(2.25rem + 2px) - 1px * 2); +} + +.calc-functions { + @a: 10px; + @b: 10px; + @floor: floor(1 + .1); + + one: calc(100% - ((min(@a + @b)))); + two: calc(100% - (((@a + @b)))); + bar: calc(@floor + 20%); +} + +.calc-escape { + three: calc(e('100%') - (3 * 1)); + four: calc(~'100%' - (3 * 1)); +} + +.calc-mixed { + foo: 1 + 2 calc(3 + 4) 5 + 6; + @v: 10px; + height: calc(100% - ((@v * 3) + (@v * 2))); +} + + + +=====================================output===================================== +@val: 10px; +@var: 50vh/2; + +.calc-basic { + width: calc(100% - 30px); + height: calc(50% + 20px); + margin: calc(10px * 2); + padding: calc(100vh - 50px); +} + +.calc-variables { + @c: 10px + 20px; + @calc: (@val + 30px); + root: calc(100% - @c); + root2: calc(100% - @calc); + width: calc(50% + (@var - 20px)); + height: calc(50% + ((@var - 20px))); +} + +.calc-nested { + min-height: calc(((10vh)) + calc((5vh))); + nested: calc(calc(2.25rem + 2px) - 1px * 2); +} + +.calc-functions { + @a: 10px; + @b: 10px; + @floor: floor(1 + 0.1); + + one: calc(100% - ((min(@a + @b)))); + two: calc(100% - (((@a + @b)))); + bar: calc(@floor + 20%); +} + +.calc-escape { + three: calc(e("100%") - (3 * 1)); + four: calc(~"100%" - (3 * 1)); +} + +.calc-mixed { + foo: 1 + 2 calc(3 + 4) 5 + 6; + @v: 10px; + height: calc(100% - ((@v * 3) + (@v * 2))); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/charsets/charsets.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// @charset directive test +@charset "UTF-8"; + +@import "import/import-charset-test"; + +=====================================output===================================== +// @charset directive test +@charset "UTF-8"; + +@import "import/import-charset-test"; + +================================================================================ +`; + +exports[`snippet: tests-unit/charsets/import/import-charset-test.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "ISO-8859-1"; + +=====================================output===================================== +@charset "ISO-8859-1"; + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/alpha.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Alpha function tests - no nesting, just alpha function behavior +#alpha { + @colorvar: rgba(150, 200, 150, 0.7); + #fromvar { + opacity: alpha(@colorvar); + } + #short { + opacity: alpha(#aaa); + } + #long { + opacity: alpha(#bababa); + } + #rgba { + opacity: alpha(rgba(50, 120, 95, 0.2)); + } + #hsl { + opacity: alpha(hsl(120, 100%, 50%)); + } + #transparent-hex4 { + opacity: alpha(#0000); + } + #transparent-hex8 { + opacity: alpha(#00000000); + } +} + +=====================================output===================================== +// Alpha function tests - no nesting, just alpha function behavior +#alpha { + @colorvar: rgba(150, 200, 150, 0.7); + #fromvar { + opacity: alpha(@colorvar); + } + #short { + opacity: alpha(#aaa); + } + #long { + opacity: alpha(#bababa); + } + #rgba { + opacity: alpha(rgba(50, 120, 95, 0.2)); + } + #hsl { + opacity: alpha(hsl(120, 100%, 50%)); + } + #transparent-hex4 { + opacity: alpha(#0000); + } + #transparent-hex8 { + opacity: alpha(#00000000); + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/basic.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Basic color function tests - no nesting, just color functions +.lightenblue { + color: lighten(blue, 10%); +} + +.darkenblue { + color: darken(blue, 10%); +} + +.unknowncolors { + color: blue2; + border: 2px solid superred; +} + +.transparent { + color: transparent; + background-color: rgba(0, 0, 0, 0); +} + +#percentage { + color: red(rgb(100%, 0, 0)); + border-color: rgba(100%, 0, 0, 50%); +} + +=====================================output===================================== +// Basic color function tests - no nesting, just color functions +.lightenblue { + color: lighten(blue, 10%); +} + +.darkenblue { + color: darken(blue, 10%); +} + +.unknowncolors { + color: blue2; + border: 2px solid superred; +} + +.transparent { + color: transparent; + background-color: rgba(0, 0, 0, 0); +} + +#percentage { + color: red(rgb(100%, 0, 0)); + border-color: rgba(100%, 0, 0, 50%); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/comprehensive.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Comprehensive color function tests - all color functions without problematic nesting +.lightenblue { + color: lighten(blue, 10%); +} + +.darkenblue { + color: darken(blue, 10%); +} + +.unknowncolors { + color: blue2; + border: 2px solid superred; +} + +.transparent { + color: transparent; + background-color: rgba(0, 0, 0, 0); +} + +#alpha { + @colorvar: rgba(150, 200, 150, 0.7); + #fromvar { + opacity: alpha(@colorvar); + } + #short { + opacity: alpha(#aaa); + } + #long { + opacity: alpha(#bababa); + } + #rgba { + opacity: alpha(rgba(50, 120, 95, 0.2)); + } + #hsl { + opacity: alpha(hsl(120, 100%, 50%)); + } +} + +#percentage { + color: red(rgb(100%, 0, 0)); + border-color: rgba(100%, 0, 0, 50%); +} + +#grey { + color: rgb(200, 200, 200); +} + +#aa3333 { + color: rgb(66.66%, 20%, 20%); +} + +#bb8080 { + color: hsl(0deg, 30%, 62%); +} + +#ccff00 { + color: hsl(72deg, 100%, 50%); +} + +=====================================output===================================== +// Comprehensive color function tests - all color functions without problematic nesting +.lightenblue { + color: lighten(blue, 10%); +} + +.darkenblue { + color: darken(blue, 10%); +} + +.unknowncolors { + color: blue2; + border: 2px solid superred; +} + +.transparent { + color: transparent; + background-color: rgba(0, 0, 0, 0); +} + +#alpha { + @colorvar: rgba(150, 200, 150, 0.7); + #fromvar { + opacity: alpha(@colorvar); + } + #short { + opacity: alpha(#aaa); + } + #long { + opacity: alpha(#bababa); + } + #rgba { + opacity: alpha(rgba(50, 120, 95, 0.2)); + } + #hsl { + opacity: alpha(hsl(120, 100%, 50%)); + } +} + +#percentage { + color: red(rgb(100%, 0, 0)); + border-color: rgba(100%, 0, 0, 50%); +} + +#grey { + color: rgb(200, 200, 200); +} + +#aa3333 { + color: rgb(66.66%, 20%, 20%); +} + +#bb8080 { + color: hsl(0deg, 30%, 62%); +} + +#ccff00 { + color: hsl(72deg, 100%, 50%); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/formats.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Color format tests - testing different color formats and conversions +#yelow #short { + color: #fea; +} +#yelow #long { + color: #ffeeaa; +} +#yelow #rgba { + color: rgba(255, 238, 170, 0.1); +} +#yelow #argb { + color: argb(rgba(255, 238, 170, 0.1)); +} + +#blue #short { + color: #00f; +} +#blue #long { + color: #0000ff; +} +#blue #rgba { + color: rgba(0, 0, 255, 0.1); +} +#blue #argb { + color: argb(rgba(0, 0, 255, 0.1)); +} + +#alpha #hsla { + color: hsla(11, 20%, 20%, 0.6); +} + +#grey { + color: rgb(200, 200, 200); +} + +#aa3333 { + color: rgb(66.66%, 20%, 20%); +} + +#bb8080 { + color: hsl(0deg, 30%, 62%); +} + +#ccff00 { + color: hsl(72deg, 100%, 50%); +} + +=====================================output===================================== +// Color format tests - testing different color formats and conversions +#yelow #short { + color: #fea; +} +#yelow #long { + color: #ffeeaa; +} +#yelow #rgba { + color: rgba(255, 238, 170, 0.1); +} +#yelow #argb { + color: argb(rgba(255, 238, 170, 0.1)); +} + +#blue #short { + color: #00f; +} +#blue #long { + color: #0000ff; +} +#blue #rgba { + color: rgba(0, 0, 255, 0.1); +} +#blue #argb { + color: argb(rgba(0, 0, 255, 0.1)); +} + +#alpha #hsla { + color: hsla(11, 20%, 20%, 0.6); +} + +#grey { + color: rgb(200, 200, 200); +} + +#aa3333 { + color: rgb(66.66%, 20%, 20%); +} + +#bb8080 { + color: hsl(0deg, 30%, 62%); +} + +#ccff00 { + color: hsl(72deg, 100%, 50%); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/modern.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Modern color space function tests +.color-oklch-sub { + background: oklch(from #0000FF calc(l - 0.1) c h); +} + +.color-oklch-add { + background: oklch(from #0000FF calc(l + 0.1) c h); +} + +.color-oklch-mult { + background: oklch(from #0000FF calc(l * 0.1) c h); +} + +.color-oklch-div { + background: oklch(from #0000FF calc(l / 2) c h); +} + +.color-hsl-sub { + background: hsl(from #0000FF calc(h - 1) s l); +} + +.color-hsl-add { + background: hsl(from #0000FF calc(h + 1) s l); +} + +.color-hsl-mult { + background: hsl(from #0000FF calc(h * 1) s l); +} + +.color-hsl-div { + background: hsl(from #0000FF calc(h / 2) s l); +} + +.color-rgb-sub { + background: rgb(from #0000FF calc(r - 1) g b); +} + +.color-rgb-add { + background: rgb(from #0000FF calc(r + 1) g b); +} + +.color-rgb-mult { + background: rgb(from #0000FF calc(r * 1) g b); +} + +.color-rgb-div { + background: rgb(from #0000FF calc(r / 2) g b); +} + +.color-rgb-sub-right-operand { + background: rgb(from blue calc(100 - r) g b); +} + +.color-rgb-add-left-operand { + background: rgb(from blue calc(r + 100) g b); +} + +=====================================output===================================== +// Modern color space function tests +.color-oklch-sub { + background: oklch(from #0000ff calc(l - 0.1) c h); +} + +.color-oklch-add { + background: oklch(from #0000ff calc(l + 0.1) c h); +} + +.color-oklch-mult { + background: oklch(from #0000ff calc(l * 0.1) c h); +} + +.color-oklch-div { + background: oklch(from #0000ff calc(l / 2) c h); +} + +.color-hsl-sub { + background: hsl(from #0000ff calc(h - 1) s l); +} + +.color-hsl-add { + background: hsl(from #0000ff calc(h + 1) s l); +} + +.color-hsl-mult { + background: hsl(from #0000ff calc(h * 1) s l); +} + +.color-hsl-div { + background: hsl(from #0000ff calc(h / 2) s l); +} + +.color-rgb-sub { + background: rgb(from #0000ff calc(r - 1) g b); +} + +.color-rgb-add { + background: rgb(from #0000ff calc(r + 1) g b); +} + +.color-rgb-mult { + background: rgb(from #0000ff calc(r * 1) g b); +} + +.color-rgb-div { + background: rgb(from #0000ff calc(r / 2) g b); +} + +.color-rgb-sub-right-operand { + background: rgb(from blue calc(100 - r) g b); +} + +.color-rgb-add-left-operand { + background: rgb(from blue calc(r + 100) g b); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/modern-syntax.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Modern CSS color syntax tests - space-separated values and / alpha syntax +foo { + color: rgb(0 128 255); + color: rgb(0 128 255 / 50%); + color: hsl(198deg 28% 50%); + color: hsl(198deg 28% 50% / 50%); +} + +=====================================output===================================== +// Modern CSS color syntax tests - space-separated values and / alpha syntax +foo { + color: rgb(0 128 255); + color: rgb(0 128 255 / 50%); + color: hsl(198deg 28% 50%); + color: hsl(198deg 28% 50% / 50%); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/operations.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Color operations tests - testing color math operations +#overflow { + .a { color: (#111111 - #444444); } // #000000 + .b { color: (#eee + #fff); } // #ffffff + .c { color: (#aaa * 3); } // #ffffff + .d { color: (#00ee00 + #009900); } // #00ff00 + .e { color: rgba(-99.9, 31.4159, 321, 0.42); } +} + +=====================================output===================================== +// Color operations tests - testing color math operations +#overflow { + .a { + color: (#111111 - #444444); + } // #000000 + .b { + color: (#eee + #fff); + } // #ffffff + .c { + color: (#aaa * 3); + } // #ffffff + .d { + color: (#00ee00 + #009900); + } // #00ff00 + .e { + color: rgba(-99.9, 31.4159, 321, 0.42); + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/color-functions/rgba.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// RGBA and RRGGBBAA tests +#rrggbbaa { + test-1: #55FF5599; + test-2: #5F59; + test-3: lighten(#55FF5599, 10%); + test-4: fade(#5F59, 10%); + test-5: rgba(#55FF5599); + test-6: rgba(#5F59); + test-7: rgba(#5F59, 0.5); + test-8: rgba(var(--color-accent), 0.2); + test-9: rgb(var(--color-accent)); + test-9: hsla(var(--color-accent)); + test-10: color('#55FF5599'); + test-11: hsla(#5F59); + test-12: hsla(#5F59, 0.5); + --semi-transparent-dark-background: #001e00ee; + --semi-transparent-dark-background-2: rgba(0, 30, 0, 238); // invalid opacity will be capped +} + +=====================================output===================================== +// RGBA and RRGGBBAA tests +#rrggbbaa { + test-1: #55ff5599; + test-2: #5f59; + test-3: lighten(#55ff5599, 10%); + test-4: fade(#5f59, 10%); + test-5: rgba(#55ff5599); + test-6: rgba(#5f59); + test-7: rgba(#5f59, 0.5); + test-8: rgba(var(--color-accent), 0.2); + test-9: rgb(var(--color-accent)); + test-9: hsla(var(--color-accent)); + test-10: color("#55FF5599"); + test-11: hsla(#5f59); + test-12: hsla(#5f59, 0.5); + --semi-transparent-dark-background: #001e00ee; + --semi-transparent-dark-background-2: rgba( + 0, + 30, + 0, + 238 + ); // invalid opacity will be capped +} + +================================================================================ +`; + +exports[`snippet: tests-unit/comments/comments2.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Inline comments and grid system tests +@media all and/*! */(max-width:1024px) {} +@-webkit-keyframes hover /* Safari and Chrome */{ } +.bg { + background-image: linear-gradient(#333 /*{comment}*/, #111); +} +#planadvisor, +/*comment*//*comment*/ +.first,/*comment*//*comment*/.planning { + margin:10px; + total-width: @total-width; +} +@base : 1; +@column-width : @base * 6em; // Width of column */ +@gutter-width : 2em; // Width of column spacing */ +@columns : 12; // Number of Columns */ +@gridsystem-width : (@column-width * // For calculating the total */ + @columns) + ( // width of the content area. */ + @gutter-width * // We strongly recommend you */ + @columns); // do not change this formula. */ +@total-width : @gridsystem-width; // set to 100% for fluid grid */ + +// ............................................................................. + +.some-inline-comments { + a: yes /* comment */; + b: red /* comment */; + @c: yes /* comment */; + @d: red /* comment */; + c: @c; + d: @d; +} + +=====================================output===================================== +// Inline comments and grid system tests +@media all and/*! */(max-width:1024px) { +} +@-webkit-keyframes hover /* Safari and Chrome */ { +} +.bg { + background-image: linear-gradient(#333 /*{comment}*/, #111); +} +#planadvisor, +/*comment*//*comment*/ +.first,/*comment*//*comment*/.planning +{ + margin: 10px; + total-width: @total-width; +} +@base: 1; +@column-width: @base * 6em; // Width of column */ +@gutter-width: 2em; // Width of column spacing */ +@columns: 12; // Number of Columns */ +@gridsystem-width: ( + @column-width * // For calculating the total */ + @columns + ) + + ( + // width of the content area. */ + @gutter-width * // We strongly recommend you */ + @columns + ); // do not change this formula. */ +@total-width: @gridsystem-width; // set to 100% for fluid grid */ + +// ............................................................................. + +.some-inline-comments { + a: yes /* comment */; + b: red /* comment */; + @c: yes/* comment */ ; + @d: red/* comment */ ; + c: @c; + d: @d; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/container/container.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.widget.discoverresults, .widget.repositoriesresults { + container-type: inline-size; + + @container (max-width: 350px) { + .cite { + .wdr-authors { + display: none; + } + } + } +} + +@container (min-width: 700px) { + .card h2 { + font-size: 2em; + } +} + +@container sidebar (min-width: 700px) { + .card { + font-size: 2em; + } +} + +@container (min-width: 60ch) { + .container:nth-child(odd) > article { + border: 1px solid grey; + } +} + +@container size(min-width: 60ch) { + .article--post header { + grid-template-areas: + "avatar name" + "avatar headline"; + align-items: start; + } + + .article--post { + grid-template-areas: "header header" ". stats" ". content"; + grid-auto-columns: 5rem 1fr; + column-gap: 1rem; + } + + .article--post__title { + font-size: 1.75rem; + } +} + +.card h2 { + container-type: inline-size; + margin: 0; + padding: 10px; + + @container (min-width: 500px) { + .card-content { + grid-template-columns: 1fr 2fr; + grid-template-rows: auto 1fr; + align-items: start; + column-gap: 20px; + } + + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } + } +} + +@container (width >= 500px) and (height >= 500px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width > 760px) not (height > 670px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container not (height <= 1080px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width < 500px) or (height < 500px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width < 500px) or (height < 500px) and (inline-size >= 0px) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container my-page-layout (width < 500px) or (height < 500px) and (block-size > 12em) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container (width < 500px) or (height < 500px) and (aspect-ratio: 3/2) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container (width < 500px) or (height < 500px) and (orientation: portrait) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container card (inline-size > 30em) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } + + @container style(--responsive: true) { + .card-content { + grid-template-columns: 1fr 2fr; + grid-template-rows: auto 1fr; + align-items: start; + column-gap: 20px; + } + + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } + } +} + +@container card (width > 400px), style(--responsive: true), scroll-state(stuck: top) { + h2 { + font-size: 1.5em; + } +} + +@container style(--theme) { + .style-query { + color: red; + } +} + +@container style((--theme: one) or (--theme: two)) { + .style-query-list { + color: blue; + } +} + +@container contactBody (min-width: 1300px) { + .named-container { + width: 25%; + } +} + +@container _body (min-width: 1300px) { + .underscored-container { + width: 25%; + } +} + +@container --body (min-width: 1300px) { + .custom-ident-container { + width: 25%; + } +} + +@container contact\\.body (min-width: 1300px) { + .escaped-container { + width: 25%; + } +} + +@container café (min-width: 1300px) { + .nonascii-container { + width: 25%; + } +} + +@container ( width < 500px ) or (height<500px) and (orientation: portrait) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container my-page-layout ( width< 500px) or ( height<500px) and ( block-size>12em ) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +.wrapper { + container-name: wrapper; + container-type: size; +} + +.my_mixin(@height) { + @container wrapper (height < @height) { + a { + max-height: @height; + } + } +} + +.my_mixin(100); +.my_mixin(200); +.my_mixin(300); + +@media only screen and (min-width: 768px) { + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } + + .media-2 { + font-size: 2rem; + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + + @media (hover: hover) { + .foo { + font-size: 1.75rem; + } + } + } + + .media-2 { + font-size: 2rem; + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + + @media (hover: hover) { + .foo { + font-size: 1.75rem; + + @media not all and (hover: hover) { + color: limegreen; + } + } + + .media-3 { + padding: 0.5rem; + } + } + } + + .media-2 { + font-size: 2rem; + } +} + +@container (min-width: 768px) { + @media only screen and (min-width: 768px) { + .foo { + color: aliceblue; + } + } + + .container-1 { + color: purple; + } +} + +#sticky { + position: sticky; + container-type: scroll-state; +} + +@container scroll-state(stuck: top) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(snapped: x) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(scrollable: top) { + #sticky-child { + font-size: 75%; + } +} + +@container sidebar (min-width: 400px), scroll-state(stuck: top) { + #sticky-child { + font-size: 80%; + } +} + +@varfoo: foo; +@threshold: 400px; +@container @varfoo (min-width: @threshold) { + #sticky-child { + font-size: 75%; + } +} + +// Regression test: mixin with variable container name and variable query condition +// Issue: mixins with parameters using @container @name (condition < @var) failed +// with "variable @bp is undefined" error in older versions +@issue-width: 125px; + +.container-query-mixin(@container-name; @bp) { + @container @container-name (width < @bp) { + display: none; + } +} + +.mixin-container-test { + .container-query-mixin(name, @issue-width); + color: red; +} + +// Verify multiple calls with different params produce correct output +.sidebar-test { + .container-query-mixin(sidebar, 500px); +} +.header-test { + .container-query-mixin(header, 800px); +} + +=====================================output===================================== +.widget.discoverresults, +.widget.repositoriesresults { + container-type: inline-size; + + @container (max-width: 350px) { + .cite { + .wdr-authors { + display: none; + } + } + } +} + +@container (min-width: 700px) { + .card h2 { + font-size: 2em; + } +} + +@container sidebar (min-width: 700px) { + .card { + font-size: 2em; + } +} + +@container (min-width: 60ch) { + .container:nth-child(odd) > article { + border: 1px solid grey; + } +} + +@container size(min-width: 60ch) { + .article--post header { + grid-template-areas: + "avatar name" + "avatar headline"; + align-items: start; + } + + .article--post { + grid-template-areas: "header header" ". stats" ". content"; + grid-auto-columns: 5rem 1fr; + column-gap: 1rem; + } + + .article--post__title { + font-size: 1.75rem; + } +} + +.card h2 { + container-type: inline-size; + margin: 0; + padding: 10px; + + @container (min-width: 500px) { + .card-content { + grid-template-columns: 1fr 2fr; + grid-template-rows: auto 1fr; + align-items: start; + column-gap: 20px; + } + + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } + } +} + +@container (width >= 500px) and (height >= 500px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width > 760px) not (height > 670px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container not (height <= 1080px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width < 500px) or (height < 500px) { + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } +} + +@container (width < 500px) or (height < 500px) and (inline-size >= 0px) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container my-page-layout (width < 500px) or (height < 500px) and (block-size > 12em) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container (width < 500px) or (height < 500px) and (aspect-ratio: 3/2) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container (width < 500px) or (height < 500px) and (orientation: portrait) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container card (inline-size > 30em) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } + + @container style(--responsive: true) { + .card-content { + grid-template-columns: 1fr 2fr; + grid-template-rows: auto 1fr; + align-items: start; + column-gap: 20px; + } + + .card-content h2 { + padding: 0; + margin: 0.5em 0 0 0; + } + } +} + +@container card (width > 400px), style(--responsive: true), scroll-state(stuck: top) { + h2 { + font-size: 1.5em; + } +} + +@container style(--theme) { + .style-query { + color: red; + } +} + +@container style((--theme: one) or (--theme: two)) { + .style-query-list { + color: blue; + } +} + +@container contactBody (min-width: 1300px) { + .named-container { + width: 25%; + } +} + +@container _body (min-width: 1300px) { + .underscored-container { + width: 25%; + } +} + +@container --body (min-width: 1300px) { + .custom-ident-container { + width: 25%; + } +} + +@container contact\\.body (min-width: 1300px) { + .escaped-container { + width: 25%; + } +} + +@container café (min-width: 1300px) { + .nonascii-container { + width: 25%; + } +} + +@container ( width < 500px ) or (height<500px) and (orientation: portrait) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +@container my-page-layout ( width< 500px) or ( height<500px) and ( block-size>12em ) { + .card-content p { + padding: 0; + + h2 { + margin: 0.5em 0 0 0; + } + } +} + +.wrapper { + container-name: wrapper; + container-type: size; +} + +.my_mixin(@height) { + @container wrapper (height < @height) { + a { + max-height: @height; + } + } +} + +.my_mixin(100); +.my_mixin(200); +.my_mixin(300); + +@media only screen and (min-width: 768px) { + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + } + + .media-2 { + font-size: 2rem; + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + + @media (hover: hover) { + .foo { + font-size: 1.75rem; + } + } + } + + .media-2 { + font-size: 2rem; + } +} + +@media only screen and (min-width: 768px) { + .media-1 { + font-size: 1.5rem; + } + + @container (min-width: 500px) { + .primary-content { + font-size: 1rem; + } + + @media (hover: hover) { + .foo { + font-size: 1.75rem; + + @media not all and (hover: hover) { + color: limegreen; + } + } + + .media-3 { + padding: 0.5rem; + } + } + } + + .media-2 { + font-size: 2rem; + } +} + +@container (min-width: 768px) { + @media only screen and (min-width: 768px) { + .foo { + color: aliceblue; + } + } + + .container-1 { + color: purple; + } +} + +#sticky { + position: sticky; + container-type: scroll-state; +} + +@container scroll-state(stuck: top) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(snapped: x) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(scrollable: top) { + #sticky-child { + font-size: 75%; + } +} + +@container sidebar (min-width: 400px), scroll-state(stuck: top) { + #sticky-child { + font-size: 80%; + } +} + +@varfoo: foo; +@threshold: 400px; +@container @varfoo (min-width: @threshold) { + #sticky-child { + font-size: 75%; + } +} + +// Regression test: mixin with variable container name and variable query condition +// Issue: mixins with parameters using @container @name (condition < @var) failed +// with "variable @bp is undefined" error in older versions +@issue-width: 125px; + +.container-query-mixin(@container-name; @bp) { + @container @container-name (width < @bp) { + display: none; + } +} + +.mixin-container-test { + .container-query-mixin(name, @issue-width); + color: red; +} + +// Verify multiple calls with different params produce correct output +.sidebar-test { + .container-query-mixin(sidebar, 500px); +} +.header-test { + .container-query-mixin(header, 800px); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/css-3/css-3.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@namespace foo url(http://www.example.com); +.comma-delimited { + text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; + -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, + 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; + -webkit-transform: rotate(-0.0000000001deg); +} +@font-face { + font-family: Headline; + unicode-range: U+??????, U+0???, U+0-7F, U+A5; +} +.other { + -moz-transform: translate(0, 11em) rotate(-90deg); + transform: rotateX(45deg); +} +.item[data-cra_zy-attr1b-ut3=bold] { + font-weight: bold; +} +p:not([class*="lead"]) { + color: black; +} + +input[type="text"].class#id[attr=i32]:not(.one) { + color: inherit; +} + +div#id.class[a=one][b=two].class:not(.one) { + color: inherit; +} + +ul.comma > li:not(:only-child)::after { + color: inherit; +} + +ol.comma > li:nth-last-child(2)::after { + color: inherit; +} + +li:nth-child(4n+1), +li:nth-child(-5n), +li:nth-child(-n+2) { + color: inherit; +} + +a[href^="http://"] { + color: black; +} + +a[href$="http://"] { + color: black; +} + +form[data-disabled] { + color: black; +} + +p::before { + color: black; +} + +#issue322 { + -webkit-animation: anim2 7s infinite ease-in-out; +} + +@-webkit-keyframes frames { + 0% { border: 1px } + 5.5% { border: 2px } + 100% { border: 3px } +} + +@keyframes fontbulger1 { + to { + font-size: 15px; + } + from,to { + font-size: 12px; + } + 0%,100% { + font-size: 12px; + } +} + +@supports ( box-shadow: 2px 2px 2px black ) or + ( -moz-box-shadow: 2px 2px 2px black ) { + .outline { + box-shadow: 2px 2px 2px black; + -moz-box-shadow: 2px 2px 2px black; + } +} + +@-x-document url-prefix(""github.com"") { + h1 { + color: red; + } +} + +@viewport { + font-size: 10px; +} + +foo|h1 { color: blue; } +foo|* { color: yellow; } +*|h1 { color: green; } +h1 { color: green; } +.upper-test { + UpperCaseProperties: allowed; +} +@host { + div { + display: block; + } +} +:not(input::placeholder) { + color: #b3b3b3; +} +.shadow > .dom, +body > .shadow { + display: done; +} + +:host(.sel.a), +:host-context(.sel.b), +.sel > .b, +::content .sel { + type: shadow-dom; +} +* b { + c: 'd'; + &[e]{ + f: 'g'; + } +} + +#issue2066 { + background: url('/images/icon-team.svg') 0 0 / contain; +} + +@counter-style triangle { + system: cyclic; + symbols: ‣; + suffix: " "; +} + +@-ms-viewport{ + // width: auto !important; +} + +@unknown foo 42 (bar) { + x {y: z} +} + +@unknown foo 43; + + + +=====================================output===================================== +@namespace foo url(http://www.example.com); +.comma-delimited { + text-shadow: + -1px -1px 1px red, + 6px 5px 5px yellow; + -moz-box-shadow: + 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, + 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; + -webkit-transform: rotate(-0.0000000001deg); +} +@font-face { + font-family: Headline; + unicode-range: U+??????, U+0???, U+0-7F, U+A5; +} +.other { + -moz-transform: translate(0, 11em) rotate(-90deg); + transform: rotateX(45deg); +} +.item[data-cra_zy-attr1b-ut3="bold"] { + font-weight: bold; +} +p:not([class*="lead"]) { + color: black; +} + +input[type="text"].class#id[attr="i32"]:not(.one) { + color: inherit; +} + +div#id.class[a="one"][b="two"].class:not(.one) { + color: inherit; +} + +ul.comma > li:not(:only-child)::after { + color: inherit; +} + +ol.comma > li:nth-last-child(2)::after { + color: inherit; +} + +li:nth-child(4n + 1), +li:nth-child(-5n), +li:nth-child(-n + 2) { + color: inherit; +} + +a[href^="http://"] { + color: black; +} + +a[href$="http://"] { + color: black; +} + +form[data-disabled] { + color: black; +} + +p::before { + color: black; +} + +#issue322 { + -webkit-animation: anim2 7s infinite ease-in-out; +} + +@-webkit-keyframes frames { + 0% { + border: 1px; + } + 5.5% { + border: 2px; + } + 100% { + border: 3px; + } +} + +@keyframes fontbulger1 { + to { + font-size: 15px; + } + from, + to { + font-size: 12px; + } + 0%, + 100% { + font-size: 12px; + } +} + +@supports (box-shadow: 2px 2px 2px black) or + (-moz-box-shadow: 2px 2px 2px black) { + .outline { + box-shadow: 2px 2px 2px black; + -moz-box-shadow: 2px 2px 2px black; + } +} + +@-x-document url-prefix(""github.com"") { + h1 { + color: red; + } +} + +@viewport { + font-size: 10px; +} + +foo|h1 { + color: blue; +} +foo|* { + color: yellow; +} +*|h1 { + color: green; +} +h1 { + color: green; +} +.upper-test { + uppercaseproperties: allowed; +} +@host { + div { + display: block; + } +} +:not(input::placeholder) { + color: #b3b3b3; +} +.shadow > .dom, +body > .shadow { + display: done; +} + +:host(.sel.a), +:host-context(.sel.b), +.sel > .b, +::content .sel { + type: shadow-dom; +} +* b { + c: "d"; + &[e] { + f: "g"; + } +} + +#issue2066 { + background: url("/images/icon-team.svg") 0 0 / contain; +} + +@counter-style triangle { + system: cyclic; + symbols: ‣; + suffix: " "; +} + +@-ms-viewport { + // width: auto !important; +} + +@unknown foo 42 (bar) { + x { + y: z; + } +} + +@unknown foo 43; + +================================================================================ +`; + +exports[`snippet: tests-unit/css-grid/css-grid.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.wrapper { + display: grid; + grid-template-columns: [col1-start] 9fr [col1-end] 10px [col2-start] 3fr [col2-end]; + grid-template-rows: auto; +} + +.wrapper { + display: grid; + grid-template-columns: [left-bound] auto [container-left] 1170px [container-right] auto [right-bound]; + grid-template-rows: [row-1-start] 140px [row-2-start] 390px [row-3-start] 200px [row-4-start] 120px [row-5-start] 120px [row-6-start] 120px; +} + +.container-12 { + z-index: 20; + display: grid; + grid-column: container-left / span 1; + grid-row: 2; + grid-template-columns: [wrapcol-1-start] 1fr [wrapcol-1-end] 15px [wrapcol-2-start] 1fr [wrapcol-2-end] 15px [wrapcol-3-start] 1fr [wrapcol-3-end] 15px [wrapcol-4-start] 1fr [wrapcol-4-end] 15px [wrapcol-5-start] 1fr [wrapcol-5-end] 15px [wrapcol-6-start] 1fr [wrapcol-6-end] 15px [wrapcol-7-start] 1fr [wrapcol-7-end] 15px [wrapcol-8-start] 1fr [wrapcol-8-end] 15px [wrapcol-9-start] 1fr [wrapcol-9-end] 15px [wrapcol-10-start] 1fr [wrapcol-10-end] 15px [wrapcol-11-start] 1fr [wrapcol-11-end] 15px [wrapcol-12-start] 1fr [wrapcol-12-end]; + grid-template-rows: repeat(14, [gutter] 10px [row] 60px); +} + +.wrapper { + display: grid; + grid-template-columns: 9fr 1.875em 3fr; + grid-template-rows: auto; + grid-template-areas: + "header header header" + "content . sidebar" + "footer footer footer"; +} + + + +=====================================output===================================== +.wrapper { + display: grid; + grid-template-columns: [col1-start] 9fr [col1-end] 10px [col2-start] 3fr [col2-end]; + grid-template-rows: auto; +} + +.wrapper { + display: grid; + grid-template-columns: [left-bound] auto [container-left] 1170px [container-right] auto [right-bound]; + grid-template-rows: [row-1-start] 140px [row-2-start] 390px [row-3-start] 200px [row-4-start] 120px [row-5-start] 120px [row-6-start] 120px; +} + +.container-12 { + z-index: 20; + display: grid; + grid-column: container-left / span 1; + grid-row: 2; + grid-template-columns: [wrapcol-1-start] 1fr [wrapcol-1-end] 15px [wrapcol-2-start] 1fr [wrapcol-2-end] 15px [wrapcol-3-start] 1fr [wrapcol-3-end] 15px [wrapcol-4-start] 1fr [wrapcol-4-end] 15px [wrapcol-5-start] 1fr [wrapcol-5-end] 15px [wrapcol-6-start] 1fr [wrapcol-6-end] 15px [wrapcol-7-start] 1fr [wrapcol-7-end] 15px [wrapcol-8-start] 1fr [wrapcol-8-end] 15px [wrapcol-9-start] 1fr [wrapcol-9-end] 15px [wrapcol-10-start] 1fr [wrapcol-10-end] 15px [wrapcol-11-start] 1fr [wrapcol-11-end] 15px [wrapcol-12-start] 1fr [wrapcol-12-end]; + grid-template-rows: repeat(14, [gutter] 10px [row] 60px); +} + +.wrapper { + display: grid; + grid-template-columns: 9fr 1.875em 3fr; + grid-template-rows: auto; + grid-template-areas: + "header header header" + "content . sidebar" + "footer footer footer"; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/css-guards/css-guards.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.light when (lightness(@a) > 50%) { + color: green; +} +.dark when (lightness(@a) < 50%) { + color: orange; +} +@a: #ddd; + +.see-the { + @a: #444; // this mirrors what mixins do - they evaluate the guards at the point of definition + .light(); + .dark(); +} + +.hide-the { + .light(); + .dark(); +} + +.multiple-conditions-1 when (@b = 1), (@c = 2), (@d = 3) { + color: red; +} + +.multiple-conditions-2 when (@b = 1), (@c = 2), (@d = 2) { + color: blue; +} + +@b: 2; +@c: 3; +@d: 3; + +.inheritance when (@b = 2) { + .test-rule { + color: black; + } + &:hover { + color: pink; + } + .hideme when (@b = 1) { + color: green; + } + & when (@b = 1) { + hideme: green; + } +} + +.hideme when (@b = 1) { + .test-rule { + color: black; + } + &:hover { + color: pink; + } + .hideme when (@b = 1) { + color: green; + } +} + +& when (@b = 1) { + .hideme { + color: red; + } +} + +.mixin-with-guard-inside(@colWidth) { + // selector with guard (applies also to & when() ...) + .clsWithGuard when (@colWidth <= 0) { + dispaly: none; + } +} + +.mixin-with-guard-inside(0px); + +.dont-split-me-up { + width: 1px; + & when (@c = 3) { + color: red; + } + & when (@c = 3) { + height: 1px; + } + * & when (@c = 3) { + sibling: true; + } +} + +.scope-check when (@c = 3) { + @k: 1px; + & when (@c = 3) { + @k: 2px; + sub-prop: @k; + } + prop: @k; +} +.scope-check-2 { + .scope-check(); + @k:4px; +} +.errors-if-called when (@c = never) { + .mixin-doesnt-exist(); +} +a:hover when (2 = true) {5:-} + + + +=====================================output===================================== +.light when (lightness(@a) > 50%) { + color: green; +} +.dark when (lightness(@a) < 50%) { + color: orange; +} +@a: #ddd; + +.see-the { + @a: #444; // this mirrors what mixins do - they evaluate the guards at the point of definition + .light(); + .dark(); +} + +.hide-the { + .light(); + .dark(); +} + +.multiple-conditions-1 when (@b = 1), (@c = 2), (@d = 3) { + color: red; +} + +.multiple-conditions-2 when (@b = 1), (@c = 2), (@d = 2) { + color: blue; +} + +@b: 2; +@c: 3; +@d: 3; + +.inheritance when (@b = 2) { + .test-rule { + color: black; + } + &:hover { + color: pink; + } + .hideme when (@b = 1) { + color: green; + } + & when (@b = 1) { + hideme: green; + } +} + +.hideme when (@b = 1) { + .test-rule { + color: black; + } + &:hover { + color: pink; + } + .hideme when (@b = 1) { + color: green; + } +} + +& when (@b = 1) { + .hideme { + color: red; + } +} + +.mixin-with-guard-inside(@colWidth) { + // selector with guard (applies also to & when() ...) + .clsWithGuard when (@colWidth <= 0) { + dispaly: none; + } +} + +.mixin-with-guard-inside(0px); + +.dont-split-me-up { + width: 1px; + & when (@c = 3) { + color: red; + } + & when (@c = 3) { + height: 1px; + } + * & when (@c = 3) { + sibling: true; + } +} + +.scope-check when (@c = 3) { + @k: 1px; + & when (@c = 3) { + @k: 2px; + sub-prop: @k; + } + prop: @k; +} +.scope-check-2 { + .scope-check(); + @k: 4px; +} +.errors-if-called when (@c = never) { + .mixin-doesnt-exist(); +} +a:hover when (2 = true) { + 5: -; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/detached-rulesets/detached-rulesets.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@ruleset: { + color: black; + background: white; +} + +@a: 1px; +.wrap-mixin(@ruleset) { + @a: hidden and if you see this in the output its a bug; + @b: visible; + @d: magic-frame; // same behaviour as mixin calls - falls back to this frame + .wrap-selector { + @c: visible; + @ruleset(); + visible-one: @b; + visible-two: @c; + } +} + +.wrap-mixin({ + color: black; + one: @a; + @b: hidden and if you see this in the output its a bug; + @c: hidden and if you see this in the output its a bug; + four: @d; +}); + +.wrap-mixin(@ruleset: { + color: red; +}); + +.wrap-mixin(@ruleset); + +.desktop-and-old-ie(@rules) { + @media screen and (min-width: 1200) { @rules() } + html.lt-ie9 & { @rules() } +} + +header { + background: blue; + + .desktop-and-old-ie({ + background: red; + }); +} + +.wrap-mixin-calls-wrap(@ruleset) { + .wrap-mixin(@ruleset); +}; + +.wrap-mixin({ + test: extra-wrap; + .wrap-mixin-calls-wrap({ + test: wrapped-twice; + }); +}); + +.wrap-mixin({ + test-func: unit(90px); + test-arithmetic: unit((9+9), px); +}); +// without mixins +@ruleset-2: { + b: 1; +}; +.without-mixins { + @ruleset-2(); +} +@my-ruleset: { + .my-selector { + @media (tv) { + background-color: black; + } + } + }; +@media (orientation:portrait) { + @my-ruleset(); + .wrap-media-mixin({ + @media (tv) { + .triple-wrapped-mq { + triple: true; + } + } + }); +} +.wrap-media-mixin(@ruleset) { + @media (widescreen) { + @media (print) { + @ruleset(); + } + @ruleset(); + } + @ruleset(); +} +// unlocking mixins +@my-mixins: { + .mixin() { + test: test; + } +}; +@my-mixins(); +.a { + .mixin(); +} +// as mixin argument default +.mixin-definition(@a: {}; @b: {default: works;};) { + @a(); + @b(); +} +.argument-default { + .mixin-definition(); + .mixin-definition({direct: works;}; @b: {named: works;}); +} + + + +=====================================output===================================== +@ruleset: { + color: black; + background: white; +}; + +@a: 1px; +.wrap-mixin(@ruleset) { + @a: hidden and if you see this in the output its a bug; + @b: visible; + @d: magic-frame; // same behaviour as mixin calls - falls back to this frame + .wrap-selector { + @c: visible; + @ruleset(); + visible-one: @b; + visible-two: @c; + } +} + +.wrap-mixin({ + color: black; + one: @a; + @b: hidden and if you see this in the output its a bug; + @c: hidden and if you see this in the output its a bug; + four: @d; +}); + +.wrap-mixin(@ruleset: { + color: red; +}); + +.wrap-mixin(@ruleset); + +.desktop-and-old-ie(@rules) { + @media screen and (min-width: 1200) { + @rules(); + } + html.lt-ie9 & { + @rules(); + } +} + +header { + background: blue; + + .desktop-and-old-ie({ + background: red; + }); +} + +.wrap-mixin-calls-wrap(@ruleset) { + .wrap-mixin(@ruleset); +} + +.wrap-mixin({ + test: extra-wrap; + .wrap-mixin-calls-wrap({ + test: wrapped-twice; + }); +}); + +.wrap-mixin({ + test-func: unit(90px); + test-arithmetic: unit((9+9), px); +}); +// without mixins +@ruleset-2: { + b: 1; +}; +.without-mixins { + @ruleset-2(); +} +@my-ruleset: { + .my-selector { + @media (tv) { + background-color: black; + } + } +}; +@media (orientation: portrait) { + @my-ruleset(); + .wrap-media-mixin({ + @media (tv) { + .triple-wrapped-mq { + triple: true; + } + } + }); +} +.wrap-media-mixin(@ruleset) { + @media (widescreen) { + @media (print) { + @ruleset(); + } + @ruleset(); + } + @ruleset(); +} +// unlocking mixins +@my-mixins: { + .mixin() { + test: test; + } +}; +@my-mixins(); +.a { + .mixin(); +} +// as mixin argument default +.mixin-definition(@a: {}; @b: {default: works;};) { + @a(); + @b(); +} +.argument-default { + .mixin-definition(); + .mixin-definition({direct: works;}; @b: {named: works;}); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/directives-bubbling/directives-bubbling.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +//simple case: @document +.parent { + color:green; + + @document url-prefix() { + .child { + color:red; + } + } +} + +//selectors joinings test +.top { + @supports (sandwitch: butter) { + .inside & { + property: value; + } + } +} + +@supports (sandwitch: bread) { + .in1 { + .in2 { + property: value; + } + } +} + +.top { + .inside & { + @supports (sandwitch: ham) { + property: value; + } + } +} + +//combined with @font-face which has different kind of body +@supports (font-family: weirdFont) { + @font-face { + font-family: something; + src: made-up-url; + } +} + +@font-face { + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + font-family: something; + src: made-up-url; + } +} + +//bubbling through media +@supports (property: value) { + .outOfMedia & { + @media (max-size: 2px) { + @supports (whatever: something) { + property: value; + } + } + } +} + +.onTop & { + @supports (property: value) { + @media (max-size: 2px) { + @supports (whatever: something) { + property: value; + } + } + } +} + + +//long combination of supports and media +@media print { + html { + in-html: visible; + @supports (upper: test) { + in-supports: first; + div { + in-div: visible; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + in-supports: second; + @media screen { + font-weight: 400; + nested { + property: value; + } + } + } + } + } + } +} + +//another long combination of supports and media +@media print { + @media (max-size: 2px) { + .in1 { + stay: here; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + .in2 & { + @supports (whatever: something) { + property: value; + } + } + } + } + } +} + +//called from mixin +.nestedSupportsMixin() { + font-weight: 300; + -webkit-font-smoothing: subpixel-antialiased; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + font-weight: 400; + nested { + property: value; + } + } +} + +html { + .nestedSupportsMixin(); +} + +// selectors should not propagate into all directive types +.onTop { + @font-face { + font-family: something; + src: made-up-url; + } + + @keyframes "textscale" { + 0% { font-size : 1em; } + 100% { font-size : 2em; } + } + + animation : "textscale"; + font-family : something; +} + + +=====================================output===================================== +//simple case: @document +.parent { + color: green; + + @document url-prefix() { + .child { + color: red; + } + } +} + +//selectors joinings test +.top { + @supports (sandwitch: butter) { + .inside & { + property: value; + } + } +} + +@supports (sandwitch: bread) { + .in1 { + .in2 { + property: value; + } + } +} + +.top { + .inside & { + @supports (sandwitch: ham) { + property: value; + } + } +} + +//combined with @font-face which has different kind of body +@supports (font-family: weirdFont) { + @font-face { + font-family: something; + src: made-up-url; + } +} + +@font-face { + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + font-family: something; + src: made-up-url; + } +} + +//bubbling through media +@supports (property: value) { + .outOfMedia & { + @media (max-size: 2px) { + @supports (whatever: something) { + property: value; + } + } + } +} + +.onTop & { + @supports (property: value) { + @media (max-size: 2px) { + @supports (whatever: something) { + property: value; + } + } + } +} + +//long combination of supports and media +@media print { + html { + in-html: visible; + @supports (upper: test) { + in-supports: first; + div { + in-div: visible; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + in-supports: second; + @media screen { + font-weight: 400; + nested { + property: value; + } + } + } + } + } + } +} + +//another long combination of supports and media +@media print { + @media (max-size: 2px) { + .in1 { + stay: here; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + .in2 & { + @supports (whatever: something) { + property: value; + } + } + } + } + } +} + +//called from mixin +.nestedSupportsMixin() { + font-weight: 300; + -webkit-font-smoothing: subpixel-antialiased; + @supports not (-webkit-font-smoothing: subpixel-antialiased) { + font-weight: 400; + nested { + property: value; + } + } +} + +html { + .nestedSupportsMixin(); +} + +// selectors should not propagate into all directive types +.onTop { + @font-face { + font-family: something; + src: made-up-url; + } + + @keyframes "textscale" { + 0% { + font-size: 1em; + } + 100% { + font-size: 2em; + } + } + + animation: "textscale"; + font-family: something; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/empty/empty.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + + + + +=====================================output===================================== + +================================================================================ +`; + +exports[`snippet: tests-unit/extend/extend.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Extend functionality tests +.error { + border: 1px #f00; + background: #fdd; +} +.error.intrusion { + font-size: 1.3em; + font-weight: bold; +} +.intrusion .error { + display: none; +} +.badError { + &:extend(.error all); + border-width: 3px; +} + +.foo .bar, .foo .baz { + display: none; +} + +.ext1 .ext2 { + &:extend(.foo all); +} + +.ext3, +.ext4 { + &:extend(.foo all); + &:extend(.bar all); +} + +div.ext5, +.ext6 > .ext5 { + width: 100px; +} + +.ext7 { + &:extend(.ext5 all); +} + +.ext8.ext9 { + result: add-foo; +} +.ext8 .ext9, +.ext8 + .ext9, +.ext8 > .ext9 { + result: bar-matched; +} +.ext8.nomatch { + result: none; +} +.ext8 { + .ext9 { + result: match-nested-bar; + } +} +.ext8 { + &.ext9 { + result: match-nested-foo; + } +} + +.fuu:extend( .ext8.ext9 all) {} +.buu:extend(.ext8 .ext9 all) {} +.zap:extend(.ext8 + .ext9 all) {} +.zoo:extend(.ext8 > .ext9 all) {} + +.aa { + color: black; + .dd { + background: red; + } +} +.bb { + background: red; + .bb { + color: black; + } +} +.cc:extend(.aa,.bb) {} +.ee:extend(.dd all,.bb) {} +.ff:extend(.dd,.bb all) {} + +=====================================output===================================== +// Extend functionality tests +.error { + border: 1px #f00; + background: #fdd; +} +.error.intrusion { + font-size: 1.3em; + font-weight: bold; +} +.intrusion .error { + display: none; +} +.badError { + &:extend(.error all); + border-width: 3px; +} + +.foo .bar, +.foo .baz { + display: none; +} + +.ext1 .ext2 { + &:extend(.foo all); +} + +.ext3, +.ext4 { + &:extend(.foo all); + &:extend(.bar all); +} + +div.ext5, +.ext6 > .ext5 { + width: 100px; +} + +.ext7 { + &:extend(.ext5 all); +} + +.ext8.ext9 { + result: add-foo; +} +.ext8 .ext9, +.ext8 + .ext9, +.ext8 > .ext9 { + result: bar-matched; +} +.ext8.nomatch { + result: none; +} +.ext8 { + .ext9 { + result: match-nested-bar; + } +} +.ext8 { + &.ext9 { + result: match-nested-foo; + } +} + +.fuu:extend(.ext8.ext9 all) { +} +.buu:extend(.ext8 .ext9 all) { +} +.zap:extend(.ext8 + .ext9 all) { +} +.zoo:extend(.ext8 > .ext9 all) { +} + +.aa { + color: black; + .dd { + background: red; + } +} +.bb { + background: red; + .bb { + color: black; + } +} +.cc:extend(.aa, .bb) { +} +.ee:extend(.dd all, .bb) { +} +.ff:extend(.dd, .bb all) { +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend/extend-clearfix.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.clearfix { + *zoom: 1; + &:after { + content: ''; + display: block; + clear: both; + height: 0; + } +} + +.foo { + &:extend(.clearfix all); + color: red; +} + +.bar { + &:extend(.clearfix all); + color: blue; +} + +=====================================output===================================== +.clearfix { + *zoom: 1; + &:after { + content: ""; + display: block; + clear: both; + height: 0; + } +} + +.foo { + &:extend(.clearfix all); + color: red; +} + +.bar { + &:extend(.clearfix all); + color: blue; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend-clearfix/extend-clearfix.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.clearfix { + *zoom: 1; + &:after { + content: ''; + display: block; + clear: both; + height: 0; + } +} + +.foo { + &:extend(.clearfix all); + color: red; +} + +.bar { + &:extend(.clearfix all); + color: blue; +} + + +=====================================output===================================== +.clearfix { + *zoom: 1; + &:after { + content: ""; + display: block; + clear: both; + height: 0; + } +} + +.foo { + &:extend(.clearfix all); + color: red; +} + +.bar { + &:extend(.clearfix all); + color: blue; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend-exact/extend-exact.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.replace.replace, +.c.replace + .replace { + .replace, + .c { + prop: copy-paste-replace; + } +} +.rep_ace:extend(.replace.replace .replace) {} + +.a .b .c { + prop: not_effected; +} + +.a { + prop: is_effected; + .b { + prop: not_effected; + } + .b.c { + prop: not_effected; + } +} + +.c, .a { + .b, .a { + .a, .c { + prop: not_effected; + } + } +} + +.effected { + &:extend(.a); + &:extend(.b); + &:extend(.c); +} + +.e { + && { + prop: extend-double; + &:hover { + hover: not-extended; + } + } +} +.dbl:extend(.e.e) {} + + +=====================================output===================================== +.replace.replace, +.c.replace + .replace { + .replace, + .c { + prop: copy-paste-replace; + } +} +.rep_ace:extend(.replace.replace .replace) { +} + +.a .b .c { + prop: not_effected; +} + +.a { + prop: is_effected; + .b { + prop: not_effected; + } + .b.c { + prop: not_effected; + } +} + +.c, +.a { + .b, + .a { + .a, + .c { + prop: not_effected; + } + } +} + +.effected { + &:extend(.a); + &:extend(.b); + &:extend(.c); +} + +.e { + && { + prop: extend-double; + &:hover { + hover: not-extended; + } + } +} +.dbl:extend(.e.e) { +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend-media/extend-media.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.ext1 .ext2 { + background: black; +} + +@media (tv) { + .ext1 .ext3 { + color: inherit; + } + .tv-lowres :extend(.ext1 all) { + background: blue; + } + @media (hires) { + .ext1 .ext4 { + color: green; + } + .tv-hires :extend(.ext1 all) { + background: red; + } + } +} + +.all:extend(.ext1 all) { + +} + + +=====================================output===================================== +.ext1 .ext2 { + background: black; +} + +@media (tv) { + .ext1 .ext3 { + color: inherit; + } + .tv-lowres :extend(.ext1 all) { + background: blue; + } + @media (hires) { + .ext1 .ext4 { + color: green; + } + .tv-hires :extend(.ext1 all) { + background: red; + } + } +} + +.all:extend(.ext1 all) { +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend-nest/extend-nest.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.sidebar { + width: 300px; + background: red; + + .box { + background: #FFF; + border: 1px solid #000; + margin: 10px 0; + } +} + +.sidebar2 { + &:extend(.sidebar all); + background: blue; +} + +.type1 { + .sidebar3 { + &:extend(.sidebar all); + background: green; + } +} + +.type2 { + &.sidebar4 { + &:extend(.sidebar all); + background: red; + } +} + +.button { + color: black; + &:hover { + color: inherit; + } +} +.submit { + &:extend(.button); + &:hover:extend(.button:hover) {} +} + +.nomatch { + &:hover:extend(.button :hover) {} +} + +.button2 { + :hover { + nested: white; + } +} +.button2 :hover { + notnested: black; +} + +.nomatch :extend(.button2:hover) {} + +.amp-test-a, +.amp-test-b { + .amp-test-c &.amp-test-d&.amp-test-e { + .amp-test-f&+&.amp-test-g:extend(.amp-test-h) {} + } +} +.amp-test-h { + test: extended by masses of selectors; +} + + +=====================================output===================================== +.sidebar { + width: 300px; + background: red; + + .box { + background: #fff; + border: 1px solid #000; + margin: 10px 0; + } +} + +.sidebar2 { + &:extend(.sidebar all); + background: blue; +} + +.type1 { + .sidebar3 { + &:extend(.sidebar all); + background: green; + } +} + +.type2 { + &.sidebar4 { + &:extend(.sidebar all); + background: red; + } +} + +.button { + color: black; + &:hover { + color: inherit; + } +} +.submit { + &:extend(.button); + &:hover:extend(.button:hover) { + } +} + +.nomatch { + &:hover:extend(.button :hover) { + } +} + +.button2 { + :hover { + nested: white; + } +} +.button2 :hover { + notnested: black; +} + +.nomatch :extend(.button2:hover) { +} + +.amp-test-a, +.amp-test-b { + .amp-test-c &.amp-test-d&.amp-test-e { + .amp-test-f& + &.amp-test-g:extend(.amp-test-h) { + } + } +} +.amp-test-h { + test: extended by masses of selectors; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/extend-selector/extend-selector.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.error { + border: 1px #f00; + background: #fdd; +} +.error.intrusion { + font-size: 1.3em; + font-weight: bold; +} +.intrusion .error { + display: none; +} +.badError:extend(.error all) { + border-width: 3px; +} + +.foo .bar, .foo .baz { + display: none; +} + +.ext1 .ext2 + :extend(.foo all) { +} + +.ext3:extend(.foo all), +.ext4:extend(.foo all) { +} + +div.ext5, +.ext6 > .ext5 { + width: 100px; +} + +.should-not-exist-in-output, +.ext7:extend(.ext5 all) { +} + +.ext { + test: 1; +} +// same as +// .a .c:extend(.ext all) +// .b .c:extend(.ext all) +// .a .c .d +// .b .c .d +.a, .b { + test: 2; + .c:extend(.ext all) { + test: 3; + .d { + test: 4; + } + } +} + +.replace.replace, +.c.replace + .replace { + .replace, + .c { + prop: copy-paste-replace; + } +} +.rep_ace:extend(.replace all) {} + +.attributes { + [data="test"] { + extend: attributes; + } + .attribute-test { + &:extend([data="test"] all); + } + [data] { + extend: attributes2; + } + .attribute-test2 { + &:extend([data] all); //you could argue it should match [data="test"]... not for now though... + } + @attr-data: "test3"; + [data=@{attr-data}] { + extend: attributes2; + } + .attribute-test { + &:extend([data="test3"] all); + } +} + +.header { + .header-nav { + background: red; + &:before { + background: blue; + } + } +} + +.footer { + .footer-nav { + &:extend( .header .header-nav all ); + } +} + +.issue-2586-bordered { + border: solid 1px black; +} +.issue-2586-somepage { + .content:extend(.issue-2586-bordered) { + &>span { + margin-bottom: 10px; + } + } +} + + +=====================================output===================================== +.error { + border: 1px #f00; + background: #fdd; +} +.error.intrusion { + font-size: 1.3em; + font-weight: bold; +} +.intrusion .error { + display: none; +} +.badError:extend(.error all) { + border-width: 3px; +} + +.foo .bar, +.foo .baz { + display: none; +} + +.ext1 .ext2 :extend(.foo all) { +} + +.ext3:extend(.foo all), +.ext4:extend(.foo all) { +} + +div.ext5, +.ext6 > .ext5 { + width: 100px; +} + +.should-not-exist-in-output, +.ext7:extend(.ext5 all) { +} + +.ext { + test: 1; +} +// same as +// .a .c:extend(.ext all) +// .b .c:extend(.ext all) +// .a .c .d +// .b .c .d +.a, +.b { + test: 2; + .c:extend(.ext all) { + test: 3; + .d { + test: 4; + } + } +} + +.replace.replace, +.c.replace + .replace { + .replace, + .c { + prop: copy-paste-replace; + } +} +.rep_ace:extend(.replace all) { +} + +.attributes { + [data="test"] { + extend: attributes; + } + .attribute-test { + &:extend([data="test"] all); + } + [data] { + extend: attributes2; + } + .attribute-test2 { + &:extend([data] + all); //you could argue it should match [data="test"]... not for now though... + } + @attr-data: "test3"; + [data="@{attr-data}"] { + extend: attributes2; + } + .attribute-test { + &:extend([data="test3"] all); + } +} + +.header { + .header-nav { + background: red; + &:before { + background: blue; + } + } +} + +.footer { + .footer-nav { + &:extend(.header .header-nav all); + } +} + +.issue-2586-bordered { + border: solid 1px black; +} +.issue-2586-somepage { + .content:extend(.issue-2586-bordered) { + & > span { + margin-bottom: 10px; + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/functions-each/functions-each.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@selectors: blue, green, red; +@list: a b c d; + +each(@selectors, { + .sel-@{value} { + a: b; + } +}); + +.each { + each(@list, { + index+: @index; + item@{index}: @value; + }); + + // nested each + each(10px 15px, 20px 25px; { + // demonstrates nesting of each() + each(@value; #(@v, @k, @i) { + nest-@{i}-@{index}: @v @k; + }); + }); + + // nested anonymous mixin + .nest-anon { + each(a b, .(@v;@i) { + each(c d, .(@vv;@ii) { + nest-@{i}-@{ii}: @v @vv; + }); + }); + } + + // vector math + each(1 2 3 4, { + padding+_: (@value * 10px); + }); +} + +@set: { + one: blue; + // skip comments + two: green; + /** and these + */ + three: red; //and this +} +.set { + each(@set, { + @{key}: @value; + }); +} +.set-2() { + one: blue; + two: green; + three: red; +} +.set-2 { + each(.set-2(), .(@v, @k, @i) { + @{k}-@{i}: @v; + }); +} + +.pick(@a) when (@a = 4) { + val3: @a; +} +.single { + each(true, { + val: @value; + }); + @exp: 1 + 1; + each(@exp, { + val2: @value; + }); + each(1 2 3 4, { + .pick(@value); + }); +} + +@columns: range(4); +.column-list { + list: @columns; +} + +each(@columns, .(@val) { + .col-@{val} { + width: (100% / length(@columns)); + } +}); + +each(range(10px, 30px, 10px), .(@val, @index) { + .row-@{index} { + width: @val; + } +}); + +@list: a b c d; +.box { + each(@list, { + -less-log: extract(@list, @index); + }) +} + +// https://github.com/less/less.js/issues/3325 + +@color-schemes: { + @primary: { + @color: blue; + } + @secondary: { + @color: red; + } +} +.test-rule { + each(primary secondary, .(@color-name) { + @scheme: @color-schemes[@@color-name]; // e.g. @color-name = primary + color: @scheme[@color]; + }); +} + +@one: { + @two: { + foo: red; + bar: blue; + }; +}; + +each(@one[@two], { + .@{key} { + content: @value; + } +}); + +// https://github.com/less/less.js/issues/3354 +.log(@msgs) { + each(@msgs; { + content: @value; + }); +} + +@messages: 'foo', 'bar'; + +span { + .log(@messages); +} + +div { + .log('foo'); +} + +// https://github.com/less/less.js/issues/3345 +.mixin-create-width-style() { + @list: e("90 100 110"); + + each(@list, { + .w-@{key} { + width: @value; + } + }) +} + +.a { + .mixin-create-width-style(); +} + + + +=====================================output===================================== +@selectors: blue, green, red; +@list: a b c d; + +each(@selectors, { + .sel-@{value} { + a: b; + } +}); + +.each { + each(@list, { + index+: @index; + item@{index}: @value; + }); + + // nested each + each(10px 15px, 20px 25px; { + // demonstrates nesting of each() + each(@value; #(@v, @k, @i) { + nest-@{i}-@{index}: @v @k; + }); + }); + + // nested anonymous mixin + .nest-anon { + each(a b, .(@v;@i) { + each(c d, .(@vv;@ii) { + nest-@{i}-@{ii}: @v @vv; + }); + }); + } + + // vector math + each(1 2 3 4, { + padding+_: (@value * 10px); + }); +} + +@set: { + one: blue; + // skip comments + two: green; + /** and these + */ + three: red; //and this +}; +.set { + each(@set, { + @{key}: @value; + }); +} +.set-2() { + one: blue; + two: green; + three: red; +} +.set-2 { + each(.set-2(), .(@v, @k, @i) { + @{k}-@{i}: @v; + }); +} + +.pick(@a) when (@a = 4) { + val3: @a; +} +.single { + each(true, { + val: @value; + }); + @exp: 1 + 1; + each(@exp, { + val2: @value; + }); + each(1 2 3 4, { + .pick(@value); + }); +} + +@columns: range(4); +.column-list { + list: @columns; +} + +each(@columns, .(@val) { + .col-@{val} { + width: (100% / length(@columns)); + } +}); + +each(range(10px, 30px, 10px), .(@val, @index) { + .row-@{index} { + width: @val; + } +}); + +@list: a b c d; +.box { + each(@list, { + -less-log: extract(@list, @index); + }); +} + +// https://github.com/less/less.js/issues/3325 + +@color-schemes: { + @primary: { + @color: blue; + }; + @secondary: { + @color: red; + }; +}; +.test-rule { + each(primary secondary, .(@color-name) { + @scheme: @color-schemes[@@color-name]; // e.g. @color-name = primary + color: @scheme[@color]; + }); +} + +@one: { + @two: { + foo: red; + bar: blue; + }; +}; + +each(@one[@two], { + .@{key} { + content: @value; + } +}); + +// https://github.com/less/less.js/issues/3354 +.log(@msgs) { + each(@msgs; { + content: @value; + }); +} + +@messages: "foo", "bar"; + +span { + .log(@messages); +} + +div { + .log("foo"); +} + +// https://github.com/less/less.js/issues/3345 +.mixin-create-width-style() { + @list: e("90 100 110"); + + each(@list, { + .w-@{key} { + width: @value; + } + }); +} + +.a { + .mixin-create-width-style(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/ie-filters/ie-filters.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@fat: 0; +@cloudhead: "#000000"; + +.nav { + filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20); + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat); +} +.evalTest(@arg) { + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg); +} +.evalTest1 { + .evalTest(30); + .evalTest(5); +} + + + +=====================================output===================================== +@fat: 0; +@cloudhead: "#000000"; + +.nav { + filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20); + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat); +} +.evalTest(@arg) { + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg); +} +.evalTest1 { + .evalTest(30); + .evalTest(5); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/impor/impor.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/less/less.js/issues/3660 +// const dir = parserInput.$re(/^@import?\\s+/); +// correct regexp is /^@import\\s+/ +// so follow code will change nothing, parse result is same with raw less code +@impor "impor-typo-dont-parse-as-@import.less"; + +=====================================output===================================== +// https://github.com/less/less.js/issues/3660 +// const dir = parserInput.$re(/^@import?\\s+/); +// correct regexp is /^@import\\s+/ +// so follow code will change nothing, parse result is same with raw less code +@impor "impor-typo-dont-parse-as-@import.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +/** comment at the top**/ +@plugin "../../plugin/plugin-simple"; + +@import url(/absolute/something.css) screen and (color) and (max-width: 600px); + +@import (optional) "file-does-not-exist.does-not-exist"; + +@var: 100px; +@import url("//ha.com/file.css") (min-width:@var); + +#import-test { + .mixin(); + width: 10px; + height: (@a + 10%); + value: pi-anon(); +} +@import "import/import-test-e" screen and (max-width: 600px); + +@import url("import/import-test-a.less"); + +@import (less, multiple) "import/import-test-d.css" screen and (max-width: 601px); + +@import (multiple) "import/import-test-e" screen and (max-width: 602px); + +@import (less, multiple) url("import/import-test-d.css") screen and (max-width: 603px); + +@media print { + @import (multiple) "import/import-test-e"; +} + +@charset "UTF-8"; // climb on top #2126 + + +=====================================output===================================== +/** comment at the top**/ +@plugin "../../plugin/plugin-simple"; + +@import url(/absolute/something.css) screen and (color) and (max-width: 600px); + +@import (optional) "file-does-not-exist.does-not-exist"; + +@var: 100px; +@import url("//ha.com/file.css") (min-width: @var); + +#import-test { + .mixin(); + width: 10px; + height: (@a + 10%); + value: pi-anon(); +} +@import "import/import-test-e" screen and (max-width: 600px); + +@import url("import/import-test-a.less"); + +@import (less, multiple) "import/import-test-d.css" screen and + (max-width: 601px); + +@import (multiple) "import/import-test-e" screen and (max-width: 602px); + +@import (less, multiple) url("import/import-test-d.css") screen and + (max-width: 603px); + +@media print { + @import (multiple) "import/import-test-e"; +} + +@charset "UTF-8"; // climb on top #2126 + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/css-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import url("test.css"); + +=====================================output===================================== +@import url("test.css"); + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/deeper/deeper-2/url-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import url("url-import-2.less"); +=====================================output===================================== +@import url("url-import-2.less"); + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/deeper/deeper-2/url-import-2.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.deep-import-url { + color: red; +} +=====================================output===================================== +.deep-import-url { + color: red; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/deeper/import-once-test-a.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "../import-once-test-c"; +=====================================output===================================== +@import "../import-once-test-c"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/deeper/url-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import url("deeper-2/url-import.less"); +=====================================output===================================== +@import url("deeper-2/url-import.less"); + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-and-relative-paths-test.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "css/background.css"; +@import "import-test-d.css"; + +@import "imports/logo"; +@import "imports/font"; + +.unquoted-relative-path-bg() { + background-image: url(../../data/image.jpg); +} +.quoted-relative-path-border-image() { + border-image: url('../../data/image.jpg'); +} + +#imported-relative-path { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} +=====================================output===================================== +@import "css/background.css"; +@import "import-test-d.css"; + +@import "imports/logo"; +@import "imports/font"; + +.unquoted-relative-path-bg() { + background-image: url(../../data/image.jpg); +} +.quoted-relative-path-border-image() { + border-image: url("../../data/image.jpg"); +} + +#imported-relative-path { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-charset-test.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@charset "ISO-8859-1"; +=====================================output===================================== +@charset "ISO-8859-1"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-inline-invalid-css.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import (inline) "invalid-css.less"; +=====================================output===================================== +@import (inline) "invalid-css.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-interpolation.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import (inline) "imports/logo.less"; +@import "import-@{in}@{terpolation}2.less"; +=====================================output===================================== +@import (inline) "imports/logo.less"; +@import "import-@{in}@{terpolation}2.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-interpolation2.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.a { + var: test; +} + +@in: "redefined-does-nothing"; +=====================================output===================================== +.a { + var: test; +} + +@in: "redefined-does-nothing"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-once-test-c.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +@c: red; + +#import { + color: @c; +} + +=====================================output===================================== +@c: red; + +#import { + color: @c; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-reference.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.z { + color: red; + .c { + color: green; + } +} +.only-with-visible, +.z { + color: green; + &:hover { + color: green; + } + & { + color: green; + } + & + & { + color: green; + .sub { + color: green; + } + } +} + +& { + .hidden { + hidden: true; + } +} + +@media tv { + .hidden { + hidden: true; + } +} + +/* comment is not output */ + +.zz { + .y { + pulled-in: yes /* inline comment survives */; + } + /* comment pulled in */ +} +@max-size: 450px; +.mixin-with-mediaq(@num) { + color: green; + test: @num; + @media (max-size: @max-size) { + color: red; + } +} +//https://github.com/less/less.js/issues/2359 +@supports (something: else) { + .class { + something: else; + } + .nestedToo { + .class { + something: else; + } + } + .invisible { + something: else; + } +} +//https://github.com/less/less.js/issues/1979 +.mixin-with-nested-selectors() { + .test-rule { + color: red; + &:first-child { + color: blue; + } + } +} +.mixin-with-directives(@keyframeName) { + @keyframes @keyframeName { + @rules1(); + } + @supports (animation-name: test) { + @keyframes @keyframeName { + @rules2(); + } + .selector { + color: red; + } + } + @rules1: {property: value;}; + @rules2: {property: value;}; +} + +@import (inline, multiple) "invalid-css.less"; +@import "import-inline-invalid-css.less"; +.print-referenced-import-inline() { + div { + @import (inline, multiple) "invalid-css.less"; + } + @import (inline, multiple) "invalid-css.less"; +} +=====================================output===================================== +.z { + color: red; + .c { + color: green; + } +} +.only-with-visible, +.z { + color: green; + &:hover { + color: green; + } + & { + color: green; + } + & + & { + color: green; + .sub { + color: green; + } + } +} + +& { + .hidden { + hidden: true; + } +} + +@media tv { + .hidden { + hidden: true; + } +} + +/* comment is not output */ + +.zz { + .y { + pulled-in: yes /* inline comment survives */; + } + /* comment pulled in */ +} +@max-size: 450px; +.mixin-with-mediaq(@num) { + color: green; + test: @num; + @media (max-size: @max-size) { + color: red; + } +} +//https://github.com/less/less.js/issues/2359 +@supports (something: else) { + .class { + something: else; + } + .nestedToo { + .class { + something: else; + } + } + .invisible { + something: else; + } +} +//https://github.com/less/less.js/issues/1979 +.mixin-with-nested-selectors() { + .test-rule { + color: red; + &:first-child { + color: blue; + } + } +} +.mixin-with-directives(@keyframeName) { + @keyframes @keyframeName { + @rules1(); + } + @supports (animation-name: test) { + @keyframes @keyframeName { + @rules2(); + } + .selector { + color: red; + } + } + @rules1: { + property: value; + }; + @rules2: { + property: value; + }; +} + +@import (inline, multiple) "invalid-css.less"; +@import "import-inline-invalid-css.less"; +.print-referenced-import-inline() { + div { + @import (inline, multiple) "invalid-css.less"; + } + @import (inline, multiple) "invalid-css.less"; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-test-a.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "import-test-b.less"; +@import url(import-test-f.less); +@import url("deeper/url-import.less"); +@a: 20%; +@import "urls.less"; +=====================================output===================================== +@import "import-test-b.less"; +@import url(import-test-f.less); +@import url("deeper/url-import.less"); +@a: 20%; +@import "urls.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-test-b.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "import-test-c"; + +@b: 100%; + +.mixin { + height: 10px; + color: @c; +} + +=====================================output===================================== +@import "import-test-c"; + +@b: 100%; + +.mixin { + height: 10px; + color: @c; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-test-c.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +@c: red; + +#import { + color: @c; +} + +=====================================output===================================== +@c: red; + +#import { + color: @c; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-test-e.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== + +body { width: 100% } + +=====================================output===================================== +body { + width: 100%; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/import-test-f.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "import-test-e"; + +.test-rule-f { + height: 10px; +} + +=====================================output===================================== +@import "import-test-e"; + +.test-rule-f { + height: 10px; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/imports/font.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@font-face { + font-family: xecret; + src: url('../assets/xecret.ttf'); +} + +#secret { + font-family: xecret, sans-serif; +} + +=====================================output===================================== +@font-face { + font-family: xecret; + src: url("../assets/xecret.ttf"); +} + +#secret { + font-family: xecret, sans-serif; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/imports/logo.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#logo { + width: 100px; + height: 100px; + background: url('./assets/logo.png'); + background: url("#inline-svg"); +} + +=====================================output===================================== +#logo { + width: 100px; + height: 100px; + background: url("./assets/logo.png"); + background: url("#inline-svg"); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/interpolation-vars.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@in: "in"; +@terpolation: "terpolation"; + +// should be ignored because its already imported +// and it uses a variable from the parent scope +@import "import-@{my_theme}-e.less"; + +=====================================output===================================== +@in: "in"; +@terpolation: "terpolation"; + +// should be ignored because its already imported +// and it uses a variable from the parent scope +@import "import-@{my_theme}-e.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/json/index.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "../import-test-a"; +=====================================output===================================== +@import "../import-test-a"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/layer-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.sub-rule { + ul { + color: white; + } +} + +=====================================output===================================== +.sub-rule { + ul { + color: white; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import/urls.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// empty file showing that it loads from the relative path first + +=====================================output===================================== +// empty file showing that it loads from the relative path first + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-inline.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import url("import/import-test-c.less");// import inline should not float above this #1954 +@import (inline) url("import/import-test-d.css") (min-width:600px); +@import (inline, css) url("import/invalid-css.less"); +=====================================output===================================== +@import url("import/import-test-c.less"); // import inline should not float above this #1954 +@import (inline) url("import/import-test-d.css") (min-width: 600px); +@import (inline, css) url("import/invalid-css.less"); + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-interpolation.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@my_theme: "test"; + +@import "import/import-@{my_theme}-e.less"; + +@import "import/import-@{in}@{terpolation}.less"; + +@import "import/interpolation-vars.less"; + + +=====================================output===================================== +@my_theme: "test"; + +@import "import/import-@{my_theme}-e.less"; + +@import "import/import-@{in}@{terpolation}.less"; + +@import "import/interpolation-vars.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-module.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "@less/test-import-module/one/two/three/3.less"; +@import "@less/test-import-module/one/two/2"; +@import "@less/test-import-module/one/1.less"; + +=====================================output===================================== +@import "@less/test-import-module/one/two/three/3.less"; +@import "@less/test-import-module/one/two/2"; +@import "@less/test-import-module/one/1.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-once.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "import/import-once-test-c"; +@import "import/import-once-test-c"; +@import "import/import-once-test-c.less"; +@import "import/deeper/import-once-test-a"; +@import (multiple) "import/import-test-f.less"; +@import (multiple) "import/import-test-f.less"; +=====================================output===================================== +@import "import/import-once-test-c"; +@import "import/import-once-test-c"; +@import "import/import-once-test-c.less"; +@import "import/deeper/import-once-test-a"; +@import (multiple) "import/import-test-f.less"; +@import (multiple) "import/import-test-f.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import (reference) url("import-once.less"); +@import (reference) url("../css-3/css-3.less"); +@import (reference) url("../media/media.less"); +@import (reference) url("import/import-reference.less"); +@import (reference) url("import/css-import.less"); + +.b { + .z(); +} + +.zz(); + +.visible:extend(.z all) { + extend: test; +} + +.test-rule-mediaq-import { + .mixin-with-mediaq(340px); +} + +.class:extend(.class all) { +} +.mixin-with-nested-selectors(); +.mixin-with-directives(some-name); + +.print-referenced-import-inline(); + +=====================================output===================================== +@import (reference) url("import-once.less"); +@import (reference) url("../css-3/css-3.less"); +@import (reference) url("../media/media.less"); +@import (reference) url("import/import-reference.less"); +@import (reference) url("import/css-import.less"); + +.b { + .z(); +} + +.zz(); + +.visible:extend(.z all) { + extend: test; +} + +.test-rule-mediaq-import { + .mixin-with-mediaq(340px); +} + +.class:extend(.class all) { +} +.mixin-with-nested-selectors(); +.mixin-with-directives(some-name); + +.print-referenced-import-inline(); + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Tests following past issues: +// * #1851 - Extend within (reference) imported files +// * #1896 - Namespace imported less code does not get properly referenced, when there's a (reference) keyword. +// * #1878 - extend inside referenced file should not extend outside selectors +// * #2716 - A file imported by reference and then normally - multiple imports should be independent +// * #1968 - When using an @import (reference), mixins that contain an & selector get added to the compiled output improperly +// * #2162 - Cannot put import by reference inside of a mixin (also doubles #1896) +// * #2991 - Empty @media queries generated through line comments when compiling less file with (reference) + +// #1878: extend inside referenced file should not extend outside selectors +@import (reference) "import-reference-issues/global-scope-import.less"; +.theOnlySelector { + shall-have: one selector; +} + +// #2716: A file imported by reference and then normally - multiple imports should be independent +// #1878: - double nested version +#do-not-show-import { + @import (reference, multiple) "import-reference-issues/multiple-import.less"; +} + +show-all-content { + @import (multiple) "import-reference-issues/multiple-import.less"; +} +// #1896: Namespace imported less code does not get properly referenced, when there's a (reference) keyword. +#Namespace { + @import (less, reference) "import-reference-issues/simple-mixin.css"; +} +#used-namespaced-mixin { + #Namespace > .mixin(); + shall-see: another property above; +} + +// #1851: Extend within (reference) imported files +// test-b is in global-scope-import.less file +.test-rule-c { + &:extend(.test-rule-b all); +} + +// #1968: When using an @import (reference), mixins that contain an & selector get added to the compiled output improperly +@import "import-reference-issues/mixin-1968.less"; +@import (reference) "import-reference-issues/appender-reference-1968.less"; + +// #2162 - Cannot put import by reference inside of a mixin (also doubles #1896) +.mixin-with-import-by-reference-inside() { + the-only-property: nothing-below-this; + @import (reference) "import-reference-issues/simple-ruleset-2162.less"; +} +call-mixin-with-import-by-reference-inside { + .mixin-with-import-by-reference-inside(); +} + +@import (reference) "import-reference-issues/comments-2991.less"; +=====================================output===================================== +// Tests following past issues: +// * #1851 - Extend within (reference) imported files +// * #1896 - Namespace imported less code does not get properly referenced, when there's a (reference) keyword. +// * #1878 - extend inside referenced file should not extend outside selectors +// * #2716 - A file imported by reference and then normally - multiple imports should be independent +// * #1968 - When using an @import (reference), mixins that contain an & selector get added to the compiled output improperly +// * #2162 - Cannot put import by reference inside of a mixin (also doubles #1896) +// * #2991 - Empty @media queries generated through line comments when compiling less file with (reference) + +// #1878: extend inside referenced file should not extend outside selectors +@import (reference) "import-reference-issues/global-scope-import.less"; +.theOnlySelector { + shall-have: one selector; +} + +// #2716: A file imported by reference and then normally - multiple imports should be independent +// #1878: - double nested version +#do-not-show-import { + @import (reference, multiple) "import-reference-issues/multiple-import.less"; +} + +show-all-content { + @import (multiple) "import-reference-issues/multiple-import.less"; +} +// #1896: Namespace imported less code does not get properly referenced, when there's a (reference) keyword. +#Namespace { + @import (less, reference) "import-reference-issues/simple-mixin.css"; +} +#used-namespaced-mixin { + #Namespace > .mixin(); + shall-see: another property above; +} + +// #1851: Extend within (reference) imported files +// test-b is in global-scope-import.less file +.test-rule-c { + &:extend(.test-rule-b all); +} + +// #1968: When using an @import (reference), mixins that contain an & selector get added to the compiled output improperly +@import "import-reference-issues/mixin-1968.less"; +@import (reference) "import-reference-issues/appender-reference-1968.less"; + +// #2162 - Cannot put import by reference inside of a mixin (also doubles #1896) +.mixin-with-import-by-reference-inside() { + the-only-property: nothing-below-this; + @import (reference) "import-reference-issues/simple-ruleset-2162.less"; +} +call-mixin-with-import-by-reference-inside { + .mixin-with-import-by-reference-inside(); +} + +@import (reference) "import-reference-issues/comments-2991.less"; + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/appender-reference-1968.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.container-no-parent-selector { + .mixin-no-parent-selector(); +} +.container-with-parent-selector { + .mixin-with-parent-selector() +} + +=====================================output===================================== +.container-no-parent-selector { + .mixin-no-parent-selector(); +} +.container-with-parent-selector { + .mixin-with-parent-selector(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/comments-2991.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.referenced { + // This file should not output anything if referenced. + @media (hover) { + // This file should not output anything if referenced. + } + // This file should not output anything if referenced. + @media (hover) { + // This file should not output anything if referenced. + } + // This file should not output anything if referenced. + @media (hover) { + /* This file should not output anything if referenced. */ + } + // This file should not output anything if referenced. + @media (hover) { + color: #000000; + } +} +// This file should not output anything if referenced. +@media (hover) { + // This file should not output anything if referenced. +} +@media (hover) { + /* This file should not output anything if referenced. */ +} + +=====================================output===================================== +.referenced { + // This file should not output anything if referenced. + @media (hover) { + // This file should not output anything if referenced. + } + // This file should not output anything if referenced. + @media (hover) { + // This file should not output anything if referenced. + } + // This file should not output anything if referenced. + @media (hover) { + /* This file should not output anything if referenced. */ + } + // This file should not output anything if referenced. + @media (hover) { + color: #000000; + } +} +// This file should not output anything if referenced. +@media (hover) { + // This file should not output anything if referenced. +} +@media (hover) { + /* This file should not output anything if referenced. */ +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/global-scope-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.theOnlySelector { + avoid: warning; +} +.unusedAndReference:extend(.theOnlySelector) { + unused-and: reference; +} + +@import (reference) "global-scope-nested.less"; + +.test-rule-b { + background-color: green; + &:extend(.test-rule-a all); +} + +=====================================output===================================== +.theOnlySelector { + avoid: warning; +} +.unusedAndReference:extend(.theOnlySelector) { + unused-and: reference; +} + +@import (reference) "global-scope-nested.less"; + +.test-rule-b { + background-color: green; + &:extend(.test-rule-a all); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/global-scope-nested.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.test-rule-a { + color: red; +} + +=====================================output===================================== +.test-rule-a { + color: red; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/mixin-1968.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin-no-parent-selector() { + background-color: red; +} +.mixin-with-parent-selector() { + &:first-child{ // USING AN & SELECTOR HERE + background-color: blue; + } +} + +=====================================output===================================== +.mixin-no-parent-selector() { + background-color: red; +} +.mixin-with-parent-selector() { + &:first-child { + // USING AN & SELECTOR HERE + background-color: blue; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/multiple-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +/* + tralala +*/ +.fix { + fix: fix; +} +.something { + @import (reference) "multiple-import-nested.less"; + inside: something; +} + +=====================================output===================================== +/* + tralala +*/ +.fix { + fix: fix; +} +.something { + @import (reference) "multiple-import-nested.less"; + inside: something; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/multiple-import-nested.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +/* double nested file */ +should { + be: invisible; +} +/* do not extend outside of this */ +.something { + invisible: suppress warning; +} +.invisible { + &:extend(.something all); +} + + +=====================================output===================================== +/* double nested file */ +should { + be: invisible; +} +/* do not extend outside of this */ +.something { + invisible: suppress warning; +} +.invisible { + &:extend(.something all); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-reference-issues/simple-ruleset-2162.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +ruleset { + shall-be-invisible: less; +} + +=====================================output===================================== +ruleset { + shall-be-invisible: less; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/import/import-remote.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/less/less.js/issues/3541 +@import (reference) url(https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/selectors/selectors.less); +@import (reference) url("https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/media/media.less"); +@import (reference) url("https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/empty/empty.less?arg"); + +.test { + color: @var; +} +=====================================output===================================== +// https://github.com/less/less.js/issues/3541 +@import (reference) + url(https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/selectors/selectors.less); +@import (reference) + url("https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/media/media.less"); +@import (reference) + url("https://cdn.jsdelivr.net/npm/@less/test-data/tests-unit/empty/empty.less?arg"); + +.test { + color: @var; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/javascript/javascript.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// JavaScript evaluation tests +.eval { + js: \`42\`; + js: \`1 + 1\`; + js: \`"hello world"\`; + js: \`[1, 2, 3]\`; + title: \`typeof process.title\`; + ternary: \`(1 + 1 == 2 ? true : false)\`; + multiline: \`(function(){var x = 1 + 1; + return x})()\`; +} +.scope { + --empty: \`+function(){}\`; + @foo: 42; + var: \`parseInt(this.foo.toJS())\`; + escaped: ~\`2 + 5 + 'px'\`; +} +.vars { + @var: \`4 + 4\`; + width: @var; +} +.escape-interpol { + @world: "world"; + width: ~\`"hello" + " " + @{world}\`; +} +.arrays { + @ary: 1, 2, 3; + @ary2: 1 2 3; + ary: \`@{ary}.join(', ')\`; + ary1: \`@{ary2}.join(', ')\`; +} +.transitions(...) { + @arg: ~\`"@{arguments}".replace(/[\\[\\]]*/g, '')\`; + one: @arg; // rounded to integers + two: ~\`"@{arguments}"\`; // rounded to integers + three: @arguments; // OK +} +.test-rule-tran { + .transitions(opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear;); +} + +=====================================output===================================== +// JavaScript evaluation tests +.eval { + js: \`42\`; + js: \`1 + 1\`; + js: \` "hello world" \`; + js: \`[1, 2, 3]\`; + title: \`typeof process.title\`; + ternary: \`(1 + 1 == 2 ? true: false) \`; + multiline: \`(function(){var x = 1 + 1; return x}) () \`; +} +.scope { + --empty: \` + function(){}\`; + @foo: 42; + var: \`parseInt(this.foo.toJS()) \`; + escaped: ~\`2 + 5 + 'px'\`; +} +.vars { + @var: \`4 + 4\`; + width: @var; +} +.escape-interpol { + @world: "world"; + width: ~\`"hello" + " " + @{world}\`; +} +.arrays { + @ary: 1, 2, 3; + @ary2: 1 2 3; + ary: \` @{ary}.join(", ") \`; + ary1: \` @{ary2}.join(", ") \`; +} +.transitions(...) { + @arg: ~\`"@{arguments}".replace(/[\\[\\]]*/g, '')\`; + one: @arg; // rounded to integers + two: ~\`"@{arguments}"\`; // rounded to integers + three: @arguments; // OK +} +.test-rule-tran { + .transitions(opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear;); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/layer/assets/import/layer-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.layer-import { + color: indigo; +} + + +=====================================output===================================== +.layer-import { + color: indigo; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/layer/import/layer-import.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.sub-rule { + ul { + color: white; + } +} + +=====================================output===================================== +.sub-rule { + ul { + color: white; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/layer/layer.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.main { + @layer { + &::before { + color: #f00; + } + } +} + +@layer legacy { + @import "./import/layer-import.less"; +} + +@import url("/import/layer-import-2.css") layer(foo); +@import url("/import/layer-import-3.css") layer(responsive) supports(display: flex) screen and (max-width: 768px); +@import url("/import/layer-import-4.css") layer(print) print; +@import url("/import/layer-import-4.css") layer(print) print, (max-width: 600px); +@import url("/import/layer-import-5.css") layer(features) supports(display: grid); + +@layer-name: primevue; + +@layer @layer-name { + .test { + foo: bar; + } +} + +@layer reset, base, components, utilities; + +@layer reset { + + *, + *::before, + *::after { + box-sizing: border-box; + } +} + +@layer base { + body { + margin: 0; + font-family: system-ui, sans-serif; + + header { + background-color: #f0f0f0; + padding: 1rem; + } + } +} + +@layer components { + .button { + display: inline-block; + padding: 0.5rem 1rem; + background-color: blue; + color: white; + + &:hover { + background-color: darkblue; + } + } +} + +@layer utilities { + .text-center { + text-align: center; + } + + .responsive { + width: 100%; + + @media (min-width: 768px) { + width: 50%; + } + } +} + +.parent { + color: black; + + .child { + color: red; + } + + &:hover { + background: lightgray; + } +} + +@layer foo.baz { + .bar { + font-weight: bold; + } +} + +@layer framework { + @layer layout { + .container { + display: grid; + gap: 2rem; + } + } +} + +@layer framework.layout { + main { + padding: 2rem; + } + p { + margin-block: 1rem; + color: #555; + } +} + + +@layer theme; +@layer layout, utilities; + +body { + color: black; +} + +@layer components { + .btn { + color: red; + &:hover { + color: blue; + } + } +} + +@layer { + p { + margin-block: 1rem; + } +} + +@layer framework.buttons.primary { + .btn-primary { + background: dodgerblue; + color: white; + } +} + +.feature { + color: gray; + + @layer component { + h2 { + font-size: 1.5rem; + } + } +} + +@primary-color: rebeccapurple; + +.button-styles() { + padding: 0.5rem 1rem; + border-radius: 4px; +} + +@layer ui { + .btn { + .button-styles(); + background: @primary-color; + color: white; + } +} + +=====================================output===================================== +.main { + @layer { + &::before { + color: #f00; + } + } +} + +@layer legacy { + @import "./import/layer-import.less"; +} + +@import url("/import/layer-import-2.css") layer(foo); +@import url("/import/layer-import-3.css") layer(responsive) + supports(display: flex) screen and (max-width: 768px); +@import url("/import/layer-import-4.css") layer(print) print; +@import url("/import/layer-import-4.css") layer(print) print, (max-width: 600px); +@import url("/import/layer-import-5.css") layer(features) + supports(display: grid); + +@layer-name: primevue; + +@layer @layer-name { + .test { + foo: bar; + } +} + +@layer reset, base, components, utilities; + +@layer reset { + *, + *::before, + *::after { + box-sizing: border-box; + } +} + +@layer base { + body { + margin: 0; + font-family: system-ui, sans-serif; + + header { + background-color: #f0f0f0; + padding: 1rem; + } + } +} + +@layer components { + .button { + display: inline-block; + padding: 0.5rem 1rem; + background-color: blue; + color: white; + + &:hover { + background-color: darkblue; + } + } +} + +@layer utilities { + .text-center { + text-align: center; + } + + .responsive { + width: 100%; + + @media (min-width: 768px) { + width: 50%; + } + } +} + +.parent { + color: black; + + .child { + color: red; + } + + &:hover { + background: lightgray; + } +} + +@layer foo.baz { + .bar { + font-weight: bold; + } +} + +@layer framework { + @layer layout { + .container { + display: grid; + gap: 2rem; + } + } +} + +@layer framework.layout { + main { + padding: 2rem; + } + p { + margin-block: 1rem; + color: #555; + } +} + +@layer theme; +@layer layout, utilities; + +body { + color: black; +} + +@layer components { + .btn { + color: red; + &:hover { + color: blue; + } + } +} + +@layer { + p { + margin-block: 1rem; + } +} + +@layer framework.buttons.primary { + .btn-primary { + background: dodgerblue; + color: white; + } +} + +.feature { + color: gray; + + @layer component { + h2 { + font-size: 1.5rem; + } + } +} + +@primary-color: rebeccapurple; + +.button-styles() { + padding: 0.5rem 1rem; + border-radius: 4px; +} + +@layer ui { + .btn { + .button-styles(); + background: @primary-color; + color: white; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/lazy-eval/lazy-eval.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Lazy evaluation tests +@var: @a; +@a: 100%; + +.lazy-eval { + width: @var; +} + +=====================================output===================================== +// Lazy evaluation tests +@var: @a; +@a: 100%; + +.lazy-eval { + width: @var; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/media/media.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// For now, variables can't be declared inside @media blocks. + +@var: 42; + +@media print { + .class { + color: blue; + .sub { + width: @var; + } + } + .top, header > h1 { + color: (#222 * 2); + } +} + +@media screen { + @base: 8; + .body { max-width: (@base * 60); } +} + +@ratio_large: 16; +@ratio_small: 9; + +@media all and (device-aspect-ratio: ~'@{ratio_large} / @{ratio_small}') { + .body { max-width: 800px; } +} + +@media all and (orientation:portrait) { + aside { float: none; } +} + +@media handheld and (min-width: @var), screen and (min-width: 20em) { + .body { + max-width: 480px; + } +} + +.body { + @media print { + padding: 20px; + + header { + background-color: red; + } + + @media (orientation:landscape) { + margin-left: 20px; + } + } +} + +@media screen { + .sidebar { + width: 300px; + @media (orientation: landscape) { + width: 500px; + } + } +} + +@media a { + .first { + @media (b) { + .second { + .third { + width: 300px; + @media (c) { + width: 500px; + } + } + .fourth { + width: 3; + } + } + } + } +} + +.body { + @media a, (b) and (c) { + width: 95%; + + @media (x), (y) { + width: 100%; + } + } +} + +.mediaMixin(@fallback: 200px) { + background: black; + + @media handheld { + background: white; + + @media (max-width: @fallback) { + background: red; + } + } +} + +.a { + .mediaMixin(100px); +} + +.b { + .mediaMixin(); +} +@smartphone: ~"only screen and (max-width: 200px)"; +@media @smartphone { + .body { + width: 480px; + } +} + +@media print { + @page :left { + margin: 0.5cm; + } + @page :right { + margin: 0.5cm; + } + @page Test:first { + margin: 1cm; + } + @page :first { + size: 8.5in 11in; + @top-left { + margin: 1cm; + } + @top-left-corner { + margin: 1cm; + } + @top-center { + margin: 1cm; + } + @top-right { + margin: 1cm; + } + @top-right-corner { + margin: 1cm; + } + @bottom-left { + margin: 1cm; + } + @bottom-left-corner { + margin: 1cm; + } + @bottom-center { + margin: 1cm; + } + @bottom-right { + margin: 1cm; + } + @bottom-right-corner { + margin: 1cm; + } + @left-top { + margin: 1cm; + } + @left-middle { + margin: 1cm; + } + @left-bottom { + margin: 1cm; + } + @right-top { + margin: 1cm; + } + @right-middle { + content: "Page " counter(page); + } + @right-bottom { + margin: 1cm; + } + } +} + +@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: ~"2/1"), (min-resolution: 2dppx), (min-resolution: 128dpcm) { + .b { + background: red; + } +} + +.bg() { + background: red; + + @media (max-width: 500px) { + background: green; + } +} + +.body { + .bg(); +} + +@bpMedium: 1000px; +@media (max-width: @bpMedium) { + .body { + .bg(); + background: blue; + } +} + +@media (max-width: 1200px) { + /* a comment */ + + @media (max-width: 900px) { + .body { font-size: 11px; } + } +} + +.nav-justified { + @media (min-width: 480px) { + > li { + display: table-cell; + } + } +} + +.menu +{ + @media (min-width: 768px) { + .nav-justified(); + } +} +@all: ~"all"; +@tv: ~"(tv)"; +@media @all and @tv { + .all-and-tv-variables { + var: all-and-tv; + } +} + +@some-var: 60px; +@media screen and (min-width: (@some-var + 1)) { + .selector { + foo: bar; + } +} + +@media screen and (color), projection and (color) { + .selector { + color: #eee; + } +} + +@media not (width <= -100px) { + body { + background: green; + } +} + +@media (height > -100px) { + body { + background: green; + } +} + +@media not (resolution: -300dpi) { + body { + background: green; + } +} + +@media (min-orientation:portrait) { + body { + background: green; + } +} + +@media print and (min-resolution: 118dpcm) { + body { + background: green; + } +} + +@media (200px <= width <= 500px) { + .test-range-syntax { + padding: 0; + } +} + +.selector { + color: #eee; + + @media (200px <= width <= 500px) { + .test-range-syntax { + padding: 0; + } + } +} + +@media print, (max-width: 992px) { + div { + color: red; + } +} + +.form-process-table { + @media screen and(max-width: 1280px) { + color: red; + } +} + +@media ((color) and (hover)), all { + body { + background: green; + } +} + +=====================================output===================================== +// For now, variables can't be declared inside @media blocks. + +@var: 42; + +@media print { + .class { + color: blue; + .sub { + width: @var; + } + } + .top, + header > h1 { + color: (#222 * 2); + } +} + +@media screen { + @base: 8; + .body { + max-width: (@base * 60); + } +} + +@ratio_large: 16; +@ratio_small: 9; + +@media all and (device-aspect-ratio: ~"@{ratio_large} / @{ratio_small}") { + .body { + max-width: 800px; + } +} + +@media all and (orientation: portrait) { + aside { + float: none; + } +} + +@media handheld and (min-width: @var), screen and (min-width: 20em) { + .body { + max-width: 480px; + } +} + +.body { + @media print { + padding: 20px; + + header { + background-color: red; + } + + @media (orientation: landscape) { + margin-left: 20px; + } + } +} + +@media screen { + .sidebar { + width: 300px; + @media (orientation: landscape) { + width: 500px; + } + } +} + +@media a { + .first { + @media (b) { + .second { + .third { + width: 300px; + @media (c) { + width: 500px; + } + } + .fourth { + width: 3; + } + } + } + } +} + +.body { + @media a, (b) and (c) { + width: 95%; + + @media (x), (y) { + width: 100%; + } + } +} + +.mediaMixin(@fallback: 200px) { + background: black; + + @media handheld { + background: white; + + @media (max-width: @fallback) { + background: red; + } + } +} + +.a { + .mediaMixin(100px); +} + +.b { + .mediaMixin(); +} +@smartphone: ~"only screen and (max-width: 200px)"; +@media @smartphone { + .body { + width: 480px; + } +} + +@media print { + @page :left { + margin: 0.5cm; + } + @page :right { + margin: 0.5cm; + } + @page Test:first { + margin: 1cm; + } + @page :first { + size: 8.5in 11in; + @top-left { + margin: 1cm; + } + @top-left-corner { + margin: 1cm; + } + @top-center { + margin: 1cm; + } + @top-right { + margin: 1cm; + } + @top-right-corner { + margin: 1cm; + } + @bottom-left { + margin: 1cm; + } + @bottom-left-corner { + margin: 1cm; + } + @bottom-center { + margin: 1cm; + } + @bottom-right { + margin: 1cm; + } + @bottom-right-corner { + margin: 1cm; + } + @left-top { + margin: 1cm; + } + @left-middle { + margin: 1cm; + } + @left-bottom { + margin: 1cm; + } + @right-top { + margin: 1cm; + } + @right-middle { + content: "Page " counter(page); + } + @right-bottom { + margin: 1cm; + } + } +} + +@media (-webkit-min-device-pixel-ratio: 2), + (min--moz-device-pixel-ratio: 2), + (-o-min-device-pixel-ratio: ~"2/1"), + (min-resolution: 2dppx), + (min-resolution: 128dpcm) { + .b { + background: red; + } +} + +.bg() { + background: red; + + @media (max-width: 500px) { + background: green; + } +} + +.body { + .bg(); +} + +@bpMedium: 1000px; +@media (max-width: @bpMedium) { + .body { + .bg(); + background: blue; + } +} + +@media (max-width: 1200px) { + /* a comment */ + + @media (max-width: 900px) { + .body { + font-size: 11px; + } + } +} + +.nav-justified { + @media (min-width: 480px) { + > li { + display: table-cell; + } + } +} + +.menu { + @media (min-width: 768px) { + .nav-justified(); + } +} +@all: ~"all"; +@tv: ~"(tv)"; +@media @all and @tv { + .all-and-tv-variables { + var: all-and-tv; + } +} + +@some-var: 60px; +@media screen and (min-width: (@some-var + 1)) { + .selector { + foo: bar; + } +} + +@media screen and (color), projection and (color) { + .selector { + color: #eee; + } +} + +@media not (width <= -100px) { + body { + background: green; + } +} + +@media (height > -100px) { + body { + background: green; + } +} + +@media not (resolution: -300dpi) { + body { + background: green; + } +} + +@media (min-orientation: portrait) { + body { + background: green; + } +} + +@media print and (min-resolution: 118dpcm) { + body { + background: green; + } +} + +@media (200px <= width <= 500px) { + .test-range-syntax { + padding: 0; + } +} + +.selector { + color: #eee; + + @media (200px <= width <= 500px) { + .test-range-syntax { + padding: 0; + } + } +} + +@media print, (max-width: 992px) { + div { + color: red; + } +} + +.form-process-table { + @media screen and(max-width: 1280px) { + color: red; + } +} + +@media ((color) and (hover)), all { + body { + background: green; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/merge/merge.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Merge functionality tests +.first-transform() { + transform+: rotate(90deg), skew(30deg); +} +.second-transform() { + transform+: scale(2,4); +} +.third-transform() { + transform: scaleX(45deg); +} +.fourth-transform() { + transform+: scaleX(45deg); +} +.fifth-transform() { + transform+: scale(2,4) !important; +} +.first-background() { + background+: url(data://img1.png); +} +.second-background() { + background+: url(data://img2.png); +} + +.test-rule1 { + // Can merge values + .first-transform(); + .second-transform(); +} +.test-rule2 { + // Won't merge values without +: merge directive, for backwards compatibility with css + .first-transform(); + .third-transform(); +} +.test-rule3 { + // Won't merge values from two sources with different properties + .fourth-transform(); + .first-background(); +} +.test-rule4 { + .first-transform(); + .fifth-transform(); +} +.test-rule5 { + .first-transform(); + .second-transform() !important; +} +.test-rule6 { + .second-transform(); +} +.test-rule7 { + // inherit !important from merged subrules + .second-transform(); + .second-transform() !important; + .second-transform(); +} + +.test-rule-interleaved { + transform+: t1; + background+: b1; + transform+: t2; + background+: b2, b3; + transform+: t3; +} + +.test-rule-spaced { + transform+_: t1; + background+_: b1; + transform+_: t2; + background+_: b2, b3; + transform+_: t3; +} + +.test-rule-interleaved-with-spaced { + transform+_: t1s; + transform+: t2; + background+: b1; + transform+_: t3s; + transform+: t4 t5s; + background+_: b2s, b3; + transform+_: t6s; + background+: b4; +} + +=====================================output===================================== +// Merge functionality tests +.first-transform() { + transform+: rotate(90deg), skew(30deg); +} +.second-transform() { + transform+: scale(2, 4); +} +.third-transform() { + transform: scaleX(45deg); +} +.fourth-transform() { + transform+: scaleX(45deg); +} +.fifth-transform() { + transform+: scale(2, 4) !important; +} +.first-background() { + background+: url(data://img1.png); +} +.second-background() { + background+: url(data://img2.png); +} + +.test-rule1 { + // Can merge values + .first-transform(); + .second-transform(); +} +.test-rule2 { + // Won't merge values without +: merge directive, for backwards compatibility with css + .first-transform(); + .third-transform(); +} +.test-rule3 { + // Won't merge values from two sources with different properties + .fourth-transform(); + .first-background(); +} +.test-rule4 { + .first-transform(); + .fifth-transform(); +} +.test-rule5 { + .first-transform(); + .second-transform() !important; +} +.test-rule6 { + .second-transform(); +} +.test-rule7 { + // inherit !important from merged subrules + .second-transform(); + .second-transform() !important; + .second-transform(); +} + +.test-rule-interleaved { + transform+: t1; + background+: b1; + transform+: t2; + background+: b2, b3; + transform+: t3; +} + +.test-rule-spaced { + transform+_: t1; + background+_: b1; + transform+_: t2; + background+_: b2, b3; + transform+_: t3; +} + +.test-rule-interleaved-with-spaced { + transform+_: t1s; + transform+: t2; + background+: b1; + transform+_: t3s; + transform+: t4 t5s; + background+_: b2s, b3; + transform+_: t6s; + background+: b4; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixin-noparens/mixin-noparens.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#theme { + > .mixin { + background-color: grey; + } +} +#container { + color: black; + #theme > .mixin; +} + +=====================================output===================================== +#theme { + > .mixin { + background-color: grey; + } +} +#container { + color: black; + #theme > .mixin; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins/maps.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.maps { + @a: 10; + h2 { width: unit(@a, px); } + + .mk-map() { + text: white; + background: black; + } + + @p: .mk-map(); + + h1 { color: @p[text]; } +} + + + +=====================================output===================================== +.maps { + @a: 10; + h2 { + width: unit(@a, px); + } + + .mk-map() { + text: white; + background: black; + } + + @p: .mk-map(); + + h1 { + color: @p[text]; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins/mixins.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin { border: 1px solid black; } +.mixout { border-color: orange; } +.borders { border-style: dashed; } +.mixin > * { border: do not match me; } + +#namespace { + .borders { + border-style: dotted; + } + .biohazard { + content: "death"; + .man { + color: transparent; + } + } +} +#theme { + > .mixin { + background-color: grey; + } +} +#container { + color: black; + .mixin(); + .mixout (); + #theme > .mixin(); +} + +#header { + .milk { + color: inherit; + .mixin(); + #theme > .mixin(); + } + #cookie { + .chips { + #namespace .borders(); + .calories { + #container(); + } + } + .borders(); + } +} +.secure-zone { #namespace .biohazard .man(); } +.direct { + #namespace > .borders(); +} + +.bo, .bar { + width: 100%; +} +.bo { + border: 1px; +} +.ar.bo.ca { + color: black; +} +.jo.ki { + background: none; +} +.amp { + &.support { + color: orange; + .higher { + top: 0px; + } + &.deeper { + height: auto; + } + } +} +.extended { + .bo(); + .jo.ki(); + .amp.support(); + .amp.support.higher(); + .amp.support.deeper(); +} +.do .re .mi .fa { + .sol .la { + .si { + color: cyan; + } + } +} +.mutli-selector-parents { + .do.re.mi.fa.sol.la.si(); +} +.foo .bar { + .bar(); +} +.has_parents() { + & .underParents { + color: red; + } +} +.has_parents(); +.parent { + .has_parents(); +} +.margin_between(@above, @below) { + * + & { margin-top: @above; } + legend + & { margin-top: 0; } + & + * { margin-top: @below; } +} +h1 { .margin_between(25px, 10px); } +h2 { .margin_between(20px, 8px); } +h3 { .margin_between(15px, 5px); } + +.mixin_def(@url, @position){ + background-image: @url; + background-position: @position; +} +.error{ + @s: "/"; + .mixin_def( "@{s}a.png", center center); +} +.recursion() { + color: black; +} +.test-rule-rec { + .recursion { + .recursion(); + } +} +.paddingFloat(@padding) { padding-left: @padding; } + +.button { + .paddingFloat(((10px + 12) * 2)); + + &.large { .paddingFloat(((10em * 2) * 2)); } +} +.clearfix() { + // ... +} +.clearfix { + .clearfix(); +} +.clearfix { + .clearfix(); +} +.foo { + .clearfix(); +} + +=====================================output===================================== +.mixin { + border: 1px solid black; +} +.mixout { + border-color: orange; +} +.borders { + border-style: dashed; +} +.mixin > * { + border: do not match me; +} + +#namespace { + .borders { + border-style: dotted; + } + .biohazard { + content: "death"; + .man { + color: transparent; + } + } +} +#theme { + > .mixin { + background-color: grey; + } +} +#container { + color: black; + .mixin(); + .mixout (); + #theme > .mixin(); +} + +#header { + .milk { + color: inherit; + .mixin(); + #theme > .mixin(); + } + #cookie { + .chips { + #namespace .borders(); + .calories { + #container(); + } + } + .borders(); + } +} +.secure-zone { + #namespace .biohazard .man(); +} +.direct { + #namespace > .borders(); +} + +.bo, +.bar { + width: 100%; +} +.bo { + border: 1px; +} +.ar.bo.ca { + color: black; +} +.jo.ki { + background: none; +} +.amp { + &.support { + color: orange; + .higher { + top: 0px; + } + &.deeper { + height: auto; + } + } +} +.extended { + .bo(); + .jo.ki(); + .amp.support(); + .amp.support.higher(); + .amp.support.deeper(); +} +.do .re .mi .fa { + .sol .la { + .si { + color: cyan; + } + } +} +.mutli-selector-parents { + .do.re.mi.fa.sol.la.si(); +} +.foo .bar { + .bar(); +} +.has_parents() { + & .underParents { + color: red; + } +} +.has_parents(); +.parent { + .has_parents(); +} +.margin_between(@above, @below) { + * + & { + margin-top: @above; + } + legend + & { + margin-top: 0; + } + & + * { + margin-top: @below; + } +} +h1 { + .margin_between(25px, 10px); +} +h2 { + .margin_between(20px, 8px); +} +h3 { + .margin_between(15px, 5px); +} + +.mixin_def(@url, @position) { + background-image: @url; + background-position: @position; +} +.error { + @s: "/"; + .mixin_def( "@{s}a.png", center center); +} +.recursion() { + color: black; +} +.test-rule-rec { + .recursion { + .recursion(); + } +} +.paddingFloat(@padding) { + padding-left: @padding; +} + +.button { + .paddingFloat(((10px + 12) * 2)); + + &.large { + .paddingFloat(((10em * 2) * 2)); + } +} +.clearfix() { + // ... +} +.clearfix { + .clearfix(); +} +.clearfix { + .clearfix(); +} +.foo { + .clearfix(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins/mixins-advanced.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Advanced mixin call tests to cover edge cases + +// Mixin call with expanded arguments +.mixin(@a, @b) { + a: @a; + b: @b; +} +@args: 1px, 2px; +.test-expanded { + .mixin(@args...); +} + +// Mixin call with condition matching and multiple definitions +.mixin-multi-def(@x: 10) when (@x > 10) { + large: @x; +} +.mixin-multi-def(@x: 10) when (@x <= 10) { + small: @x; +} +.test-multi-def { + .mixin-multi-def(); + .mixin-multi-def(15); +} + +// Mixin call with condition matching +.mixin-guarded(@x) when (@x > 10) { + large: @x; +} +.mixin-guarded(@x) when (@x <= 10) { + small: @x; +} +.test-conditions { + .mixin-guarded(15); + .mixin-guarded(5); +} + +// Mixin call with no arguments filter +.mixin-no-args() { + no-args: true; +} +.mixin-no-args(@x) { + with-args: @x; +} +.test-no-args-filter { + .mixin-no-args(); + .mixin-no-args(10); +} + +// Mixin call with recursive mixin +.mixin-recursive(@n) when (@n > 0) { + level: @n; + .mixin-recursive(@n - 1); +} +.mixin-recursive(@n) when (@n <= 0) { + done: true; +} +.test-recursive { + .mixin-recursive(3); +} + +// Mixin call with namespace path +#namespace { + .mixin() { + from-namespace: true; + } +} +.test-namespace-path { + #namespace > .mixin(); +} + +// Mixin call with important flag +.mixin-important() { + important: true; +} +.test-important { + .mixin-important() !important; +} + +// Mixin call with multiple candidates +.mixin-multi(@x: 1) { + value1: @x; +} +.mixin-multi(@x: 2) { + value2: @x; +} +.test-multi { + .mixin-multi(); +} + +// Mixin call with named arguments +.mixin-named(@a: a, @b: b) { + a: @a; + b: @b; +} +.test-named { + .mixin-named(@b: B, @a: A); +} + +// Mixin call with expanded array +.mixin-array(@a, @b, @c) { + a: @a; + b: @b; + c: @c; +} +@array: 1, 2, 3; +.test-array-expand { + .mixin-array(@array...); +} + + +=====================================output===================================== +// Advanced mixin call tests to cover edge cases + +// Mixin call with expanded arguments +.mixin(@a, @b) { + a: @a; + b: @b; +} +@args: 1px, 2px; +.test-expanded { + .mixin(@args...); +} + +// Mixin call with condition matching and multiple definitions +.mixin-multi-def(@x: 10) when (@x > 10) { + large: @x; +} +.mixin-multi-def(@x: 10) when (@x <= 10) { + small: @x; +} +.test-multi-def { + .mixin-multi-def(); + .mixin-multi-def(15); +} + +// Mixin call with condition matching +.mixin-guarded(@x) when (@x > 10) { + large: @x; +} +.mixin-guarded(@x) when (@x <= 10) { + small: @x; +} +.test-conditions { + .mixin-guarded(15); + .mixin-guarded(5); +} + +// Mixin call with no arguments filter +.mixin-no-args() { + no-args: true; +} +.mixin-no-args(@x) { + with-args: @x; +} +.test-no-args-filter { + .mixin-no-args(); + .mixin-no-args(10); +} + +// Mixin call with recursive mixin +.mixin-recursive(@n) when (@n > 0) { + level: @n; + .mixin-recursive(@n - 1); +} +.mixin-recursive(@n) when (@n <= 0) { + done: true; +} +.test-recursive { + .mixin-recursive(3); +} + +// Mixin call with namespace path +#namespace { + .mixin() { + from-namespace: true; + } +} +.test-namespace-path { + #namespace > .mixin(); +} + +// Mixin call with important flag +.mixin-important() { + important: true; +} +.test-important { + .mixin-important() !important; +} + +// Mixin call with multiple candidates +.mixin-multi(@x: 1) { + value1: @x; +} +.mixin-multi(@x: 2) { + value2: @x; +} +.test-multi { + .mixin-multi(); +} + +// Mixin call with named arguments +.mixin-named(@a: a, @b: b) { + a: @a; + b: @b; +} +.test-named { + .mixin-named(@b: B, @a: A); +} + +// Mixin call with expanded array +.mixin-array(@a, @b, @c) { + a: @a; + b: @b; + c: @c; +} +@array: 1, 2, 3; +.test-array-expand { + .mixin-array(@array...); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-closure/mixins-closure.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.scope { + @var: 99px; + .mixin () { + width: @var; + } +} + +.class { + .scope > .mixin(); +} + +.overwrite { + @var: 0px; + .scope > .mixin(); +} + +.nested { + @var: 5px; + .mixin () { + width: @var; + } + .class { + @var: 10px; + .mixin(); + } +} + +=====================================output===================================== +.scope { + @var: 99px; + .mixin () { + width: @var; + } +} + +.class { + .scope > .mixin(); +} + +.overwrite { + @var: 0px; + .scope > .mixin(); +} + +.nested { + @var: 5px; + .mixin () { + width: @var; + } + .class { + @var: 10px; + .mixin(); + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-guards/mixins-guards.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Stacking, functions.. + +.light (@a) when (lightness(@a) > 50%) { + color: inherit; +} +.light (@a) when (lightness(@a) < 50%) { + color: black; +} +.light (@a) { + margin: 1px; +} + +.light1 { .light(#ddd) } +.light2 { .light(#444) } + +// Arguments against each other + +.max (@a, @b) when (@a > @b) { + width: @a; +} +.max (@a, @b) when (@a < @b) { + width: @b; +} + +.max1 { .max(3, 6) } +.max2 { .max(8, 1) } + +// Globals inside guards + +@g: auto; + +.glob (@a) when (@a = @g) { + margin: @a @g; +} +.glob1 { .glob(auto) } + +// Other operators + +.ops (@a) when (@a >= 0) { + height: gt-or-eq; +} +.ops (@a) when (@a =< 0) { + height: lt-or-eq; +} +.ops (@a) when (@a <= 0) { + height: lt-or-eq-alias; +} +.ops (@a) when not(@a = 0) { + height: not-eq; +} +.ops1 { .ops(0) } +.ops2 { .ops(1) } +.ops3 { .ops(-1) } + +// Scope and default values + +@a: auto; + +.default (@a: inherit) when (@a = inherit) { + content: default; +} +.default1 { .default() } + +// true & false keywords +.test-rule (@a) when (@a) { + content: "true."; +} +.test-rule (@a) when not (@a) { + content: "false."; +} + +.test-rule1 { .test-rule(true) } +.test-rule2 { .test-rule(false) } +.test-rule3 { .test-rule(1) } +.test-rule4 { .test-rule(boo) } +.test-rule5 { .test-rule("true") } + +// Boolean expressions + +.bool () when (true) and (false) { content: true and false } // FALSE +.bool () when (true) and (true) { content: true and true } // TRUE +.bool () when (true) { content: true } // TRUE +.bool () when (false) and (false) { content: true } // FALSE +.bool () when (false), (true) { content: false, true } // TRUE +.bool () when (false) and (true) and (true), (true) { content: false and true and true, true } // TRUE +.bool () when (true) and (true) and (false), (false) { content: true and true and false, false } // FALSE +.bool () when (false), (true) and (true) { content: false, true and true } // TRUE +.bool () when (false), (false), (true) { content: false, false, true } // TRUE +.bool () when (false), (false) and (true), (false) { content: false, false and true, false } // FALSE +.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE +.bool () when not (false) { content: not false } +.bool () when not (true) and not (false) { content: not true and not false } +.bool () when not (true) and not (true) { content: not true and not true } +.bool () when not (false) and (false), not (false) { content: not false and false, not false } + +.bool1 { .bool() } + +.equality-unit-test(@num) when (@num = 1%) { + test: fail; +} +.equality-unit-test(@num) when (@num = 2) { + test: pass; +} +.equality-units { + .equality-unit-test(1px); + .equality-unit-test(2px); +} + +.colorguard(@col) when (@col = red) { content: is @col; } +.colorguard(@col) when not (blue = @col) { content: is not blue its @col; } +.colorguard(@col) {} +.colorguardtest { + .colorguard(red); + .colorguard(blue); + .colorguard(purple); +} + +.stringguard(@str) when (@str = "theme1") { content: @str is "theme1"; } +.stringguard(@str) when not ("theme2" = @str) { content: @str is not "theme2"; } +.stringguard(@str) when (@str = 'theme1') { content: @str is 'theme1'; } +.stringguard(@str) when not ('theme2' = @str) { content: @str is not 'theme2'; } +.stringguard(@str) when (~"theme1" = @str) { content: @str is theme1; } +.stringguard(@str) {} +.stringguardtest { + .stringguard("theme1"); + .stringguard("theme2"); + .stringguard('theme1'); + .stringguard('theme2'); + .stringguard(theme1); +} + +.generic(@a, @b) {/**/} +.generic(@a, @b) when (@a = @b) {content: @a is equal to @b} +.generic(@a, @b) when (@b = @a) {content: @b is equal to @a too} +.generic(@a, @b) when (@a < @b) {content: @a is less than @b} +.generic(@a, @b) when (@b < @a) {content: @b is less than @a too} +.generic(@a, @b) when (@a > @b) {content: @a is greater than @b} +.generic(@a, @b) when (@b > @a) {content: @b is greater than @a too} +.generic(@a, @b) when not(@a = @b) {content: @a is not equal to @b} +.generic(@a, @b) when not(@b = @a) {content: @b is not equal to @a too} + +.variouse-types-comparison { + .generic(true, false); + .generic(1, true); + .generic(2, 2px); + .generic(3, ~"3"); + .generic(5, ~"4"); + .generic(abc, ~"abc"); + .generic(abc, "abc"); + .generic('abc', "abd"); + .generic(6, e("6")); + .generic(9, 8); + .generic(a, b); + .generic(1 2, 3); +} + +.list-comparison { + .generic(a b c, a b c); + .generic(a b c, a b d); + .generic(a, b, c; a, b, c); + .generic(a, b, c; a, b, d); + .generic(1 2px 300ms, 1em 2 .3s); + + @space-list: 1 2 3; + @comma-list: 1, 2, 3; + @compound: @space-list @comma-list; + + .generic(@space-list, @comma-list); + .generic(@comma-list, ~"1, 2, 3"); + .generic(@compound, @space-list @comma-list); + .generic(@compound, @comma-list @space-list); + .generic(@compound 4, ~"1 2 3 1, 2, 3 4"); +} + +.mixin(...) { + catch:all; +} +.mixin(@var) when (@var=4) { + declare: 4; +} +.mixin(@var) when (@var=4px) { + declare: 4px; +} +#tryNumberPx { + .mixin(4px); +} + +.lock-mixin(@a) { + .inner-locked-mixin(@x: @a) when (@a = 1) { + a: @a; + x: @x; + } +} +.call-lock-mixin { + .lock-mixin(1); + .call-inner-lock-mixin { + .inner-locked-mixin(); + } +} +.bug-100cm-1m(@a) when (@a = 1) { + .failed { + one-hundred: not-equal-to-1; + } +} +.bug-100cm-1m(100cm); + +#ns { + .mixin-for-root-usage(@a) when (@a > 0) { + .mixin-generated-class { + a: @a; + } + } +} + +#ns > .mixin-for-root-usage(1); + +@namespaceGuard: 1; +#guarded when (@namespaceGuard>0) { + #deeper { + .mixin() { + guarded: namespace; + } + } +} +#guarded() when (@namespaceGuard>0) { + #deeper { + .mixin() { + silent: namespace; + } + } +} +#guarded(@variable) when (@namespaceGuard>0) { + #deeper { + .mixin() { + should: not match because namespace argument; + } + } +} +#guarded(@variable: default) when (@namespaceGuard>0) { + #deeper { + .mixin() { + guarded: with default; + } + } +} +#guarded when (@namespaceGuard<0) { + #deeper { + .mixin() { + should: not match because namespace guard; + } + } +} +#guarded-caller { + #guarded > #deeper > .mixin(); +} +#top { + #deeper when (@namespaceGuard<0) { + .mixin(@a) { + should: not match because namespace guard; + } + } + #deeper() when (@namespaceGuard>0) { + .mixin(@a) { + should: match @a; + } + } +} +#guarded-deeper { + #top > #deeper > .mixin(1); +} + +// namespaced & guarded mixin in root +// outputs nothing but should pass: + +@guarded-mixin-for-root: true; +#ns { + .guarded-mixin-for-root() when (@guarded-mixin-for-root) {} +} +#ns > .guarded-mixin-for-root(); +// various combinations of nested or, and, parenthesis and negation +.parenthesisNot(@value) when ((((@value)))) { + parenthesisNot: just-value; +} +.parenthesisNot(@value) when (((not(@value)))) { + parenthesisNot: negated once inside; +} +.parenthesisNot(@value) when not((((@value)))) { + parenthesisNot: negated once outside; +} +.parenthesisNot(@value) when ((not((@value)))) { + parenthesisNot: negated once middle; +} +.parenthesisNot(@value) when not(((not(@value)))) { + parenthesisNot: negated twice 1; +} +.parenthesisNot(@value) when (not((not(@value)))) { + parenthesisNot: negated twice 2; +} +.parenthesisNot(@value) when ((not(not(@value)))) { + parenthesisNot: negated twice 3; +} +.parenthesisNot (...) when (default()) { + parenthesisNot: none matched; +} + +#parenthesisNot-true { + .parenthesisNot(true); +} +#parenthesisNot-false { + .parenthesisNot(false); +} + +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and (@a2) or (@a3)) { + no-parenthesis: evaluated true 1a; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a3) or (@a1) and (@a2)) { + no-parenthesis: evaluated true 1b; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and ((@a2) or (@a3))) { + no-parenthesis: evaluated true 1c; +} +.orderOfEvaluation(@a1, @a2, @a3) when (@a3), (@a1) and (@a2) { + no-parenthesis: evaluated true 1d; +} +.orderOfEvaluation(@a1, @a2, @a3) when (((@a3) or (@a1)) and (@a2)) { + no-parenthesis: evaluated true 1e; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and (@a2) or not (@a3)) { + no-parenthesis: evaluated true 2a; +} +.orderOfEvaluation(@a1, @a2, @a3) when (not (@a3) or (@a1) and (@a2)) { + no-parenthesis: evaluated true 2b; +} +.orderOfEvaluation(@a1, @a2, @a3) when not (@a3), (@a1) and (@a2) { + no-parenthesis: evaluated true 2c; +} +.orderOfEvaluation(@a1, @a2, @a3) when (not (@a1) and (@a2) or (@a3)) { + no-parenthesis: evaluated true 3; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((((@a1) and (@a2) or (@a3)))) { + no-parenthesis: evaluated true 4; +} +.orderOfEvaluation(@a1, @a2, @a3) when (((@a1) and (@a2)) or (@a3)) { + with-parenthesis: evaluated true; +} +.orderOfEvaluation(...) when (default()) { + orderOfEvaluation: evaluated false; +} +#orderOfEvaluation-false-false-true { + .orderOfEvaluation(false, false, true); +} +#orderOfEvaluation-false-false-false { + .orderOfEvaluation(false, false, false); +} +#orderOfEvaluation-true-true-false { + .orderOfEvaluation(true, true, false); +} + +// not without parentheses should work the same as not with parentheses +.test-not-noparens (@a) when not @a { + content: "not without parens false."; +} +.test-not-noparens (@a) when (@a) { + content: "not without parens true."; +} + +.test-not-noparens1 { .test-not-noparens(true) } +.test-not-noparens2 { .test-not-noparens(false) } + + +=====================================output===================================== +// Stacking, functions.. + +.light (@a) when (lightness(@a) > 50%) { + color: inherit; +} +.light (@a) when (lightness(@a) < 50%) { + color: black; +} +.light (@a) { + margin: 1px; +} + +.light1 { + .light(#ddd); +} +.light2 { + .light(#444); +} + +// Arguments against each other + +.max (@a, @b) when (@a > @b) { + width: @a; +} +.max (@a, @b) when (@a < @b) { + width: @b; +} + +.max1 { + .max(3, 6); +} +.max2 { + .max(8, 1); +} + +// Globals inside guards + +@g: auto; + +.glob (@a) when (@a = @g) { + margin: @a @g; +} +.glob1 { + .glob(auto); +} + +// Other operators + +.ops (@a) when (@a >= 0) { + height: gt-or-eq; +} +.ops (@a) when (@a =< 0) { + height: lt-or-eq; +} +.ops (@a) when (@a <= 0) { + height: lt-or-eq-alias; +} +.ops (@a) when not(@a = 0) { + height: not-eq; +} +.ops1 { + .ops(0); +} +.ops2 { + .ops(1); +} +.ops3 { + .ops(-1); +} + +// Scope and default values + +@a: auto; + +.default (@a: inherit) when (@a = inherit) { + content: default; +} +.default1 { + .default(); +} + +// true & false keywords +.test-rule (@a) when (@a) { + content: "true."; +} +.test-rule (@a) when not (@a) { + content: "false."; +} + +.test-rule1 { + .test-rule(true); +} +.test-rule2 { + .test-rule(false); +} +.test-rule3 { + .test-rule(1); +} +.test-rule4 { + .test-rule(boo); +} +.test-rule5 { + .test-rule("true"); +} + +// Boolean expressions + +.bool () when (true) and (false) { + content: true and false; +} // FALSE +.bool () when (true) and (true) { + content: true and true; +} // TRUE +.bool () when (true) { + content: true; +} // TRUE +.bool () when (false) and (false) { + content: true; +} // FALSE +.bool () when (false), (true) { + content: false, true; +} // TRUE +.bool () when (false) and (true) and (true), (true) { + content: + false and true and true, + true; +} // TRUE +.bool () when (true) and (true) and (false), (false) { + content: + true and true and false, + false; +} // FALSE +.bool () when (false), (true) and (true) { + content: + false, + true and true; +} // TRUE +.bool () when (false), (false), (true) { + content: false, false, true; +} // TRUE +.bool () when (false), (false) and (true), (false) { + content: + false, + false and true, + false; +} // FALSE +.bool () when (false), (true) and (true) and (true), (false) { + content: + false, + true and true and true, + false; +} // TRUE +.bool () when not (false) { + content: not false; +} +.bool () when not (true) and not (false) { + content: not true and not false; +} +.bool () when not (true) and not (true) { + content: not true and not true; +} +.bool () when not (false) and (false), +not (false) { + content: + not false and false, + not false; +} + +.bool1 { + .bool(); +} + +.equality-unit-test(@num) when (@num = 1%) { + test: fail; +} +.equality-unit-test(@num) when (@num = 2) { + test: pass; +} +.equality-units { + .equality-unit-test(1px); + .equality-unit-test(2px); +} + +.colorguard(@col) when (@col = red) { + content: is @col; +} +.colorguard(@col) when not (blue = @col) { + content: is not blue its @col; +} +.colorguard(@col) { +} +.colorguardtest { + .colorguard(red); + .colorguard(blue); + .colorguard(purple); +} + +.stringguard(@str) when (@str = "theme1") { + content: @str is "theme1"; +} +.stringguard(@str) when not ("theme2" = @str) { + content: @str is not "theme2"; +} +.stringguard(@str) when (@str = "theme1") { + content: @str is "theme1"; +} +.stringguard(@str) when not ("theme2" = @str) { + content: @str is not "theme2"; +} +.stringguard(@str) when (~"theme1" = @str) { + content: @str is theme1; +} +.stringguard(@str) { +} +.stringguardtest { + .stringguard("theme1"); + .stringguard("theme2"); + .stringguard("theme1"); + .stringguard("theme2"); + .stringguard(theme1); +} + +.generic(@a, @b) { + /**/ +} +.generic(@a, @b) when (@a = @b) { + content: @a is equal to @b; +} +.generic(@a, @b) when (@b = @a) { + content: @b is equal to @a too; +} +.generic(@a, @b) when (@a < @b) { + content: @a is less than @b; +} +.generic(@a, @b) when (@b < @a) { + content: @b is less than @a too; +} +.generic(@a, @b) when (@a > @b) { + content: @a is greater than @b; +} +.generic(@a, @b) when (@b > @a) { + content: @b is greater than @a too; +} +.generic(@a, @b) when not(@a = @b) { + content: @a is not equal to @b; +} +.generic(@a, @b) when not(@b = @a) { + content: @b is not equal to @a too; +} + +.variouse-types-comparison { + .generic(true, false); + .generic(1, true); + .generic(2, 2px); + .generic(3, ~"3"); + .generic(5, ~"4"); + .generic(abc, ~"abc"); + .generic(abc, "abc"); + .generic("abc", "abd"); + .generic(6, e("6")); + .generic(9, 8); + .generic(a, b); + .generic(1 2, 3); +} + +.list-comparison { + .generic(a b c, a b c); + .generic(a b c, a b d); + .generic(a, b, c; a, b, c); + .generic(a, b, c; a, b, d); + .generic(1 2px 300ms, 1em 2 0.3s); + + @space-list: 1 2 3; + @comma-list: 1, 2, 3; + @compound: @space-list @comma-list; + + .generic(@space-list, @comma-list); + .generic(@comma-list, ~"1, 2, 3"); + .generic(@compound, @space-list @comma-list); + .generic(@compound, @comma-list @space-list); + .generic(@compound 4, ~"1 2 3 1, 2, 3 4"); +} + +.mixin(...) { + catch: all; +} +.mixin(@var) when (@var=4) { + declare: 4; +} +.mixin(@var) when (@var=4px) { + declare: 4px; +} +#tryNumberPx { + .mixin(4px); +} + +.lock-mixin(@a) { + .inner-locked-mixin(@x: @a) when (@a = 1) { + a: @a; + x: @x; + } +} +.call-lock-mixin { + .lock-mixin(1); + .call-inner-lock-mixin { + .inner-locked-mixin(); + } +} +.bug-100cm-1m(@a) when (@a = 1) { + .failed { + one-hundred: not-equal-to-1; + } +} +.bug-100cm-1m(100cm); + +#ns { + .mixin-for-root-usage(@a) when (@a > 0) { + .mixin-generated-class { + a: @a; + } + } +} + +#ns > .mixin-for-root-usage(1); + +@namespaceGuard: 1; +#guarded when (@namespaceGuard>0) { + #deeper { + .mixin() { + guarded: namespace; + } + } +} +#guarded() when (@namespaceGuard>0) { + #deeper { + .mixin() { + silent: namespace; + } + } +} +#guarded(@variable) when (@namespaceGuard>0) { + #deeper { + .mixin() { + should: not match because namespace argument; + } + } +} +#guarded(@variable: default) when (@namespaceGuard>0) { + #deeper { + .mixin() { + guarded: with default; + } + } +} +#guarded when (@namespaceGuard<0) { + #deeper { + .mixin() { + should: not match because namespace guard; + } + } +} +#guarded-caller { + #guarded > #deeper > .mixin(); +} +#top { + #deeper when (@namespaceGuard<0) { + .mixin(@a) { + should: not match because namespace guard; + } + } + #deeper() when (@namespaceGuard>0) { + .mixin(@a) { + should: match @a; + } + } +} +#guarded-deeper { + #top > #deeper > .mixin(1); +} + +// namespaced & guarded mixin in root +// outputs nothing but should pass: + +@guarded-mixin-for-root: true; +#ns { + .guarded-mixin-for-root() when (@guarded-mixin-for-root) { + } +} +#ns > .guarded-mixin-for-root(); +// various combinations of nested or, and, parenthesis and negation +.parenthesisNot(@value) when ((((@value)))) { + parenthesisnot: just-value; +} +.parenthesisNot(@value) when (((not(@value)))) { + parenthesisnot: negated once inside; +} +.parenthesisNot(@value) when not((((@value)))) { + parenthesisnot: negated once outside; +} +.parenthesisNot(@value) when ((not((@value)))) { + parenthesisnot: negated once middle; +} +.parenthesisNot(@value) when not(((not(@value)))) { + parenthesisnot: negated twice 1; +} +.parenthesisNot(@value) when (not((not(@value)))) { + parenthesisnot: negated twice 2; +} +.parenthesisNot(@value) when ((not(not(@value)))) { + parenthesisnot: negated twice 3; +} +.parenthesisNot (...) when (default()) { + parenthesisnot: none matched; +} + +#parenthesisNot-true { + .parenthesisNot(true); +} +#parenthesisNot-false { + .parenthesisNot(false); +} + +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and (@a2) or (@a3)) { + no-parenthesis: evaluated true 1a; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a3) or (@a1) and (@a2)) { + no-parenthesis: evaluated true 1b; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and ((@a2) or (@a3))) { + no-parenthesis: evaluated true 1c; +} +.orderOfEvaluation(@a1, @a2, @a3) when (@a3), (@a1) and (@a2) { + no-parenthesis: evaluated true 1d; +} +.orderOfEvaluation(@a1, @a2, @a3) when (((@a3) or (@a1)) and (@a2)) { + no-parenthesis: evaluated true 1e; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((@a1) and (@a2) or not (@a3)) { + no-parenthesis: evaluated true 2a; +} +.orderOfEvaluation(@a1, @a2, @a3) when (not (@a3) or (@a1) and (@a2)) { + no-parenthesis: evaluated true 2b; +} +.orderOfEvaluation(@a1, @a2, @a3) when not (@a3), (@a1) and (@a2) { + no-parenthesis: evaluated true 2c; +} +.orderOfEvaluation(@a1, @a2, @a3) when (not (@a1) and (@a2) or (@a3)) { + no-parenthesis: evaluated true 3; +} +.orderOfEvaluation(@a1, @a2, @a3) when ((((@a1) and (@a2) or (@a3)))) { + no-parenthesis: evaluated true 4; +} +.orderOfEvaluation(@a1, @a2, @a3) when (((@a1) and (@a2)) or (@a3)) { + with-parenthesis: evaluated true; +} +.orderOfEvaluation(...) when (default()) { + orderofevaluation: evaluated false; +} +#orderOfEvaluation-false-false-true { + .orderOfEvaluation(false, false, true); +} +#orderOfEvaluation-false-false-false { + .orderOfEvaluation(false, false, false); +} +#orderOfEvaluation-true-true-false { + .orderOfEvaluation(true, true, false); +} + +// not without parentheses should work the same as not with parentheses +.test-not-noparens (@a) when not @a { + content: "not without parens false."; +} +.test-not-noparens (@a) when (@a) { + content: "not without parens true."; +} + +.test-not-noparens1 { + .test-not-noparens(true); +} +.test-not-noparens2 { + .test-not-noparens(false); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-guards-default-func/mixins-guards-default-func.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// basics: + +guard-default-basic-1 { + .m(1) {case: 1} + .m(@x) when (default()) {default: @x} + + &-1 {.m(1)} + &-2 {.m(2)} +} + +guard-default-basic-2 { + .m(1) {case: 1} + .m(2) {case: 2} + .m(3) {case: 3} + .m(@x) when (default()) {default: @x} + + &-0 {.m(0)} + &-2 {.m(2)} +} + +guard-default-basic-3 { + .m(@x) when (@x = 1) {case: 1} + .m(2) {case: 2} + .m(@x) when (@x = 3) {case: 3} + .m(@x) when (default()) {default: @x} + + &-0 {.m(0)} + &-2 {.m(2)} + &-3 {.m(3)} +} + +guard-default-definition-order { + .m(@x) when (default()) {default: @x} + .m(@x) when (@x = 1) {case: 1} + .m(2) {case: 2} + .m(@x) when (@x = 3) {case: 3} + + &-0 {.m(0)} + &-2 {.m(2)} + &-2 {.m(3)} +} + +// out of guard: + +guard-default-out-of-guard { + .m(1) {case-1: 1} + .m(@x: default()) when (default()) {default: @x} + + &-0 { + case-0: default(); + .m(1); + .m(2); + case-2: default(); + } + &-1 {.m(default())} + &-2 {.m()} +} + +// expressions: + +guard-default-expr-not { + .m(1) {case: 1} + .m(@x) when not(default()) {default: @x} + + &-1 {.m(1)} + &-2 {.m(2)} +} + +guard-default-expr-eq { + .m(@x) when (@x = true) {case: @x} + .m(@x) when (@x = false) {case: @x} + .m(@x) when (@x = default()) {default: @x} + + &-true {.m(true)} + &-false {.m(false)} +} + +guard-default-expr-or { + .m(1) {case: 1} + .m(2) {case: 2} + .m(@x) when (default()), (@x = 2) {default: @x} + + &-1 {.m(1)} + &-2 {.m(2)} + &-3 {.m(3)} +} + +guard-default-expr-and { + .m(1) {case: 1} + .m(2) {case: 2} + .m(@x) when (default()) and (@x = 3) {default: @x} + + &-1 {.m(1)} + &-2 {.m(2)} + &-3 {.m(3)} + &-4 {.m(4)} +} + +guard-default-expr-always { + .m(1) {case: 1} + .m(@x) when (default()), not(default()) {default: @x} // always match + + &-1 {.m(1)} + &-2 {.m(2)} +} + +guard-default-expr-never { + .m(1) {case: 1} + .m(@x) when (default()) and not(default()) {default: @x} // never match + + &-1 {.m(1)} + &-2 {.m(2)} +} + + +// not conflicting multiple default() uses: + +guard-default-multi-1 { + .m(0) {case: 0} + .m(@x) when (default()) {default-1: @x} + .m(2) when (default()) {default-2: @x} + + &-0 {.m(0)} + &-1 {.m(1)} +} + +guard-default-multi-2 { + .m(1, @x) when (default()) {default-1: @x} + .m(2, @x) when (default()) {default-2: @x} + .m(@x, yes) when (default()) {default-3: @x} + + &-1 {.m(1, no)} + &-2 {.m(2, no)} + &-3 {.m(3, yes)} +} + +guard-default-multi-3 { + .m(red) {case-1: darkred} + .m(blue) {case-2: darkblue} + .m(@x) when (iscolor(@x)) and (default()) {default-color: @x} + .m('foo') {case-1: I am 'foo'} + .m('bar') {case-2: I am 'bar'} + .m(@x) when (isstring(@x)) and (default()) {default-string: I am @x} + + &-blue {.m(blue)} + &-green {.m(green)} + &-foo {.m('foo')} + &-baz {.m('baz')} +} + +guard-default-multi-4 { + .m(@x) when (default()), not(default()) {always: @x} + .m(@x) when (default()) and not(default()) {never: @x} + .m(2) {case: 2} + + .m(1); + .m(2); +} + +guard-default-not-ambiguous-2 { + .m(@x) {case: 1} + .m(@x) when (default()) {default: @x} + .m(@x) when not(default()) {not-default: @x} + + .m(2); +} + +guard-default-not-ambiguous-3 { + .m(@x) {case: 1} + .m(@x) when not(default()) {not-default-1: @x} + .m(@x) when not(default()) {not-default-2: @x} + + .m(2); +} + +// default & scope + +guard-default-scopes { + .s1() {.m(@v) {one: no condition}} + .s2() {.m(@v) when (@v) {two: when true}} + .s3() {.m(@v) when (default()) {three: when default}} + + &-3 { + .s2(); + .s3(); + .m(false); + } + + &-1 { + .s1(); + .s3(); + .m(false); + } +} + + +=====================================output===================================== +// basics: + +guard-default-basic-1 { + .m(1) { + case: 1; + } + .m(@x) when (default()) { + default: @x; + } + + &-1 { + .m(1); + } + &-2 { + .m(2); + } +} + +guard-default-basic-2 { + .m(1) { + case: 1; + } + .m(2) { + case: 2; + } + .m(3) { + case: 3; + } + .m(@x) when (default()) { + default: @x; + } + + &-0 { + .m(0); + } + &-2 { + .m(2); + } +} + +guard-default-basic-3 { + .m(@x) when (@x = 1) { + case: 1; + } + .m(2) { + case: 2; + } + .m(@x) when (@x = 3) { + case: 3; + } + .m(@x) when (default()) { + default: @x; + } + + &-0 { + .m(0); + } + &-2 { + .m(2); + } + &-3 { + .m(3); + } +} + +guard-default-definition-order { + .m(@x) when (default()) { + default: @x; + } + .m(@x) when (@x = 1) { + case: 1; + } + .m(2) { + case: 2; + } + .m(@x) when (@x = 3) { + case: 3; + } + + &-0 { + .m(0); + } + &-2 { + .m(2); + } + &-2 { + .m(3); + } +} + +// out of guard: + +guard-default-out-of-guard { + .m(1) { + case-1: 1; + } + .m(@x: default()) when (default()) { + default: @x; + } + + &-0 { + case-0: default(); + .m(1); + .m(2); + case-2: default(); + } + &-1 { + .m(default()); + } + &-2 { + .m(); + } +} + +// expressions: + +guard-default-expr-not { + .m(1) { + case: 1; + } + .m(@x) when not(default()) { + default: @x; + } + + &-1 { + .m(1); + } + &-2 { + .m(2); + } +} + +guard-default-expr-eq { + .m(@x) when (@x = true) { + case: @x; + } + .m(@x) when (@x = false) { + case: @x; + } + .m(@x) when (@x = default()) { + default: @x; + } + + &-true { + .m(true); + } + &-false { + .m(false); + } +} + +guard-default-expr-or { + .m(1) { + case: 1; + } + .m(2) { + case: 2; + } + .m(@x) when (default()), (@x = 2) { + default: @x; + } + + &-1 { + .m(1); + } + &-2 { + .m(2); + } + &-3 { + .m(3); + } +} + +guard-default-expr-and { + .m(1) { + case: 1; + } + .m(2) { + case: 2; + } + .m(@x) when (default()) and (@x = 3) { + default: @x; + } + + &-1 { + .m(1); + } + &-2 { + .m(2); + } + &-3 { + .m(3); + } + &-4 { + .m(4); + } +} + +guard-default-expr-always { + .m(1) { + case: 1; + } + .m(@x) when (default()), + not(default()) { + default: @x; + } // always match + + &-1 { + .m(1); + } + &-2 { + .m(2); + } +} + +guard-default-expr-never { + .m(1) { + case: 1; + } + .m(@x) when (default()) and not(default()) { + default: @x; + } // never match + + &-1 { + .m(1); + } + &-2 { + .m(2); + } +} + +// not conflicting multiple default() uses: + +guard-default-multi-1 { + .m(0) { + case: 0; + } + .m(@x) when (default()) { + default-1: @x; + } + .m(2) when (default()) { + default-2: @x; + } + + &-0 { + .m(0); + } + &-1 { + .m(1); + } +} + +guard-default-multi-2 { + .m(1, @x) when (default()) { + default-1: @x; + } + .m(2, @x) when (default()) { + default-2: @x; + } + .m(@x, yes) when (default()) { + default-3: @x; + } + + &-1 { + .m(1, no); + } + &-2 { + .m(2, no); + } + &-3 { + .m(3, yes); + } +} + +guard-default-multi-3 { + .m(red) { + case-1: darkred; + } + .m(blue) { + case-2: darkblue; + } + .m(@x) when (iscolor(@x)) and (default()) { + default-color: @x; + } + .m("foo") { + case-1: I am "foo"; + } + .m("bar") { + case-2: I am "bar"; + } + .m(@x) when (isstring(@x)) and (default()) { + default-string: I am @x; + } + + &-blue { + .m(blue); + } + &-green { + .m(green); + } + &-foo { + .m("foo"); + } + &-baz { + .m("baz"); + } +} + +guard-default-multi-4 { + .m(@x) when (default()), + not(default()) { + always: @x; + } + .m(@x) when (default()) and not(default()) { + never: @x; + } + .m(2) { + case: 2; + } + + .m(1); + .m(2); +} + +guard-default-not-ambiguous-2 { + .m(@x) { + case: 1; + } + .m(@x) when (default()) { + default: @x; + } + .m(@x) when not(default()) { + not-default: @x; + } + + .m(2); +} + +guard-default-not-ambiguous-3 { + .m(@x) { + case: 1; + } + .m(@x) when not(default()) { + not-default-1: @x; + } + .m(@x) when not(default()) { + not-default-2: @x; + } + + .m(2); +} + +// default & scope + +guard-default-scopes { + .s1() { + .m(@v) { + one: no condition; + } + } + .s2() { + .m(@v) when (@v) { + two: when true; + } + } + .s3() { + .m(@v) when (default()) { + three: when default; + } + } + + &-3 { + .s2(); + .s3(); + .m(false); + } + + &-1 { + .s1(); + .s3(); + .m(false); + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-important/mixins-important.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.submixin(@a) { + border-width: @a; +} +.mixin (9) { + border: 9 !important; +} +.mixin (@a: 0) { + border: @a; + boxer: @a; + .inner { + test: @a; + } + // comment + .submixin(@a); +} + +.class { + .mixin(1); + .mixin(2) !important; + .mixin(3); + .mixin(4) !important; + .mixin(5); + .mixin() !important; + .mixin(9); +} +.size(@aaa: auto) { + .set-width(@aaa) { + width: @aaa; + } + .set-width(@aaa); +} +.when-calling-nested-issue-2394 { + .size() !important; +} +.when-calling-nested-with-param-issue-2394 { + .size(10px) !important; +} +.test-ruleMixin-2421 () { + .topCheck-2421 () { + .nestedCheck-2421() { + margin: 5px; + } + .nestedCheck-2421(); + } + .topCheck-2421(); +} +.class1-2421 { + .test-ruleMixin-2421() !important; +} +.class2-2421 { + .test-ruleMixin-2421(); +} + +=====================================output===================================== +.submixin(@a) { + border-width: @a; +} +.mixin (9) { + border: 9 !important; +} +.mixin (@a: 0) { + border: @a; + boxer: @a; + .inner { + test: @a; + } + // comment + .submixin(@a); +} + +.class { + .mixin(1); + .mixin(2) !important; + .mixin(3); + .mixin(4) !important; + .mixin(5); + .mixin() !important; + .mixin(9); +} +.size(@aaa: auto) { + .set-width(@aaa) { + width: @aaa; + } + .set-width(@aaa); +} +.when-calling-nested-issue-2394 { + .size() !important; +} +.when-calling-nested-with-param-issue-2394 { + .size(10px) !important; +} +.test-ruleMixin-2421 () { + .topCheck-2421 () { + .nestedCheck-2421() { + margin: 5px; + } + .nestedCheck-2421(); + } + .topCheck-2421(); +} +.class1-2421 { + .test-ruleMixin-2421() !important; +} +.class2-2421 { + .test-ruleMixin-2421(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-named-args/mixins-named-args.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + args: @arguments; +} +.mixin (@a: 1px, @b: 50%) when (@b > 75%){ + text-align: center; +} + +.named-arg { + color: blue; + .mixin(@b: 100%); +} + +.class { + @var: 20%; + .mixin(@b: @var); +} + +.all-args-wrong-args { + .mixin(@b: 10%, @a: 2px); +} + +.mixin2 (@a: 1px, @b: 50%, @c: 50) { + width: (@a * 5); + height: (@b - 1%); + color: (#000000 + @c); +} + +.named-args2 { + .mixin2(3px, @c: 100); +} + +.named-args3 { + .mixin2(@b: 30%, @c: #123456); +} + +=====================================output===================================== +.mixin (@a: 1px, @b: 50%) { + width: (@a * 5); + height: (@b - 1%); + args: @arguments; +} +.mixin (@a: 1px, @b: 50%) when (@b > 75%) { + text-align: center; +} + +.named-arg { + color: blue; + .mixin(@b: 100%); +} + +.class { + @var: 20%; + .mixin(@b: @var); +} + +.all-args-wrong-args { + .mixin(@b: 10%, @a: 2px); +} + +.mixin2 (@a: 1px, @b: 50%, @c: 50) { + width: (@a * 5); + height: (@b - 1%); + color: (#000000 + @c); +} + +.named-args2 { + .mixin2(3px, @c: 100); +} + +.named-args3 { + .mixin2(@b: 30%, @c: #123456); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-nested/mixins-nested.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mix-inner (@var) { + border-width: @var; +} + +.mix (@a: 10) { + .inner { + height: (@a * 10); + + .innest { + width: @a; + .mix-inner((@a * 2)); + } + } +} + +.class { + .mix(30); +} + +.class2 { + .mix(60); +} + +=====================================output===================================== +.mix-inner (@var) { + border-width: @var; +} + +.mix (@a: 10) { + .inner { + height: (@a * 10); + + .innest { + width: @a; + .mix-inner((@a * 2)); + } + } +} + +.class { + .mix(30); +} + +.class2 { + .mix(60); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/mixins-pattern/mixins-pattern.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin (...) { + variadic: true; +} +.mixin (@a...) { + named-variadic: true; +} +.mixin () { + zero: 0; +} +.mixin (@a: 1px) { + one: 1; +} +.mixin (@a) { + one-req: 1; +} +.mixin (@a: 1px, @b: 2px) { + two: 2; +} + +.mixin (@a, @b, @c) { + three-req: 3; +} + +.mixin (@a: 1px, @b: 2px, @c: 3px) { + three: 3; +} + +.zero { + .mixin(); +} + +.one { + .mixin(1); +} + +.two { + .mixin(1, 2); +} + +.three { + .mixin(1, 2, 3); +} + +// + +.mixout ('left') { + left: 1; +} + +.mixout ('right') { + right: 1; +} + +.left { + .mixout('left'); +} +.right { + .mixout('right'); +} + +// + +.border (@side, @width) { + color: black; + .border-side(@side, @width); +} +.border-side (left, @w) { + border-left: @w; +} +.border-side (right, @w) { + border-right: @w; +} + +.border-right { + .border(right, 4px); +} +.border-left { + .border(left, 4px); +} + +// + + +.border-radius (@r) { + both: (@r * 10); +} +.border-radius (@r, left) { + left: @r; +} +.border-radius (@r, right) { + right: @r; +} + +.only-right { + .border-radius(33, right); +} +.only-left { + .border-radius(33, left); +} +.left-right { + .border-radius(33); +} + +=====================================output===================================== +.mixin (...) { + variadic: true; +} +.mixin (@a...) { + named-variadic: true; +} +.mixin () { + zero: 0; +} +.mixin (@a: 1px) { + one: 1; +} +.mixin (@a) { + one-req: 1; +} +.mixin (@a: 1px, @b: 2px) { + two: 2; +} + +.mixin (@a, @b, @c) { + three-req: 3; +} + +.mixin (@a: 1px, @b: 2px, @c: 3px) { + three: 3; +} + +.zero { + .mixin(); +} + +.one { + .mixin(1); +} + +.two { + .mixin(1, 2); +} + +.three { + .mixin(1, 2, 3); +} + +// + +.mixout ("left") { + left: 1; +} + +.mixout ("right") { + right: 1; +} + +.left { + .mixout("left"); +} +.right { + .mixout("right"); +} + +// + +.border (@side, @width) { + color: black; + .border-side(@side, @width); +} +.border-side (left, @w) { + border-left: @w; +} +.border-side (right, @w) { + border-right: @w; +} + +.border-right { + .border(right, 4px); +} +.border-left { + .border(left, 4px); +} + +// + +.border-radius (@r) { + both: (@r * 10); +} +.border-radius (@r, left) { + left: @r; +} +.border-radius (@r, right) { + right: @r; +} + +.only-right { + .border-radius(33, right); +} +.only-left { + .border-radius(33, left); +} +.left-right { + .border-radius(33); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/namespace-targeted/namespace-targeted.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Targeted tests for specific uncovered lines in namespace-value.js + +// Lines 51-52: $@var interpolation (property interpolation with variable) +// This tests: name.substring(0, 2) === '$@' +// The syntax is #namespace[$@var-name] where @var-name contains the property name +@prop-name: my-prop; +#namespace { + my-prop: prop-value; +} +.test-prop-interp { + value: #namespace[$@prop-name]; +} + +// Lines 43-47: Variable not found error path +// Access a variable that doesn't exist in the namespace +#namespace-with-var { + @existing-var: value; +} +.test-var-not-found { + // This will error: variable @nonexistent-var not found + // color: #namespace-with-var[@nonexistent-var]; +} + +// Lines 61-65: Property not found error path +// Access a property that doesn't exist in the namespace +#namespace-with-prop { + existing-prop: value; +} +.test-prop-not-found { + // This will error: property "nonexistent-prop" not found + // value: #namespace-with-prop[$nonexistent-prop]; +} + + +=====================================output===================================== +// Targeted tests for specific uncovered lines in namespace-value.js + +// Lines 51-52: $@var interpolation (property interpolation with variable) +// This tests: name.substring(0, 2) === '$@' +// The syntax is #namespace[$@var-name] where @var-name contains the property name +@prop-name: my-prop; +#namespace { + my-prop: prop-value; +} +.test-prop-interp { + value: #namespace[$ @prop-name]; +} + +// Lines 43-47: Variable not found error path +// Access a variable that doesn't exist in the namespace +#namespace-with-var { + @existing-var: value; +} +.test-var-not-found { + // This will error: variable @nonexistent-var not found + // color: #namespace-with-var[@nonexistent-var]; +} + +// Lines 61-65: Property not found error path +// Access a property that doesn't exist in the namespace +#namespace-with-prop { + existing-prop: value; +} +.test-prop-not-found { + // This will error: property "nonexistent-prop" not found + // value: #namespace-with-prop[$nonexistent-prop]; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/nesting/nesting.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.nesting-parent { + color: red; + + .nesting-child { + color: blue; + + .nesting-grandchild { + color: green; + } + } + + &:hover { + color: orange; + } + + &.modifier { + color: purple; + } +} + +.correctly-exit-calc-mode { + @a: 10; + h2 { width: unit(@a, px); } + + div { width: calc(100px * 2); } + + .mk-map() { + text: white; + background: black; + } + + @p: .mk-map(); + + h1 { color: @p[text]; } +} + + + +=====================================output===================================== +.nesting-parent { + color: red; + + .nesting-child { + color: blue; + + .nesting-grandchild { + color: green; + } + } + + &:hover { + color: orange; + } + + &.modifier { + color: purple; + } +} + +.correctly-exit-calc-mode { + @a: 10; + h2 { + width: unit(@a, px); + } + + div { + width: calc(100px * 2); + } + + .mk-map() { + text: white; + background: black; + } + + @p: .mk-map(); + + h1 { + color: @p[text]; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/no-output/no-output.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin() { +} + +=====================================output===================================== +.mixin() { +} + +================================================================================ +`; + +exports[`snippet: tests-unit/operations/operations.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Mathematical operations tests +#operations { + color: (#110000 + #000011 + #001100); // #111111 + color-2: (yellow - #070707); + height: (10px / 2px + 6px - 1px * 2); // 9px + width: (2 * 4 - 5em); // 3em + .spacing { + height: (10px / 2px+6px-1px*2); + width: (2 * 4-5em); + } + subtraction: (20 - 10 - 5 - 5); // 0 + division: (20 / 5 / 4); // 1 +} + +@x: 4; +@y: 12em; + +.with-variables { + height: (@x + @y); // 16em + width: (12 + @y); // 24em + size: (5cm - @x); // 1cm +} + +.with-functions { + color: (rgb(200, 200, 200) / 2); + color: (2 * hsl(0, 50%, 50%)); + color: (rgb(10, 10, 10) + hsl(0, 50%, 50%)); +} + +@z: -2; + +.negative { + height: (2px + @z); // 0px + width: (2px - @z); // 4px +} + +.shorthands { + padding: -1px 2px 0 -4px; // +} + +.rem-dimensions { + font-size: (20rem / 5 + 1.5rem); // 5.5rem +} + +.colors { + color: #123; // #112233 + border-color: (#234 + #111111); // #334455 + background-color: (#222222 - #fff); // #000000 + .other { + color: (2 * #111); // #222222 + border-color: (#333333 / 3 + #111); // #222222 + } +} + +.negations { + @var: 4px; + variable: (-@var); // 4 + variable1: (-@var + @var); // 0 + variable2: (@var + -@var); // 0 + variable3: (@var - -@var); // 8 + variable4: (-@var - -@var); // 0 + paren: (-(@var)); // -4px + paren2: (-(2 + 2) * -@var); // 16 +} + +=====================================output===================================== +// Mathematical operations tests +#operations { + color: (#110000 + #000011 + #001100); // #111111 + color-2: (yellow - #070707); + height: (10px / 2px + 6px - 1px * 2); // 9px + width: (2 * 4 - 5em); // 3em + .spacing { + height: (10px / 2px+6px-1px * 2); + width: (2 * 4-5em); + } + subtraction: (20 - 10 - 5 - 5); // 0 + division: (20 / 5 / 4); // 1 +} + +@x: 4; +@y: 12em; + +.with-variables { + height: (@x + @y); // 16em + width: (12 + @y); // 24em + size: (5cm - @x); // 1cm +} + +.with-functions { + color: (rgb(200, 200, 200) / 2); + color: (2 * hsl(0, 50%, 50%)); + color: (rgb(10, 10, 10) + hsl(0, 50%, 50%)); +} + +@z: -2; + +.negative { + height: (2px + @z); // 0px + width: (2px - @z); // 4px +} + +.shorthands { + padding: -1px 2px 0 -4px; // +} + +.rem-dimensions { + font-size: (20rem / 5 + 1.5rem); // 5.5rem +} + +.colors { + color: #123; // #112233 + border-color: (#234 + #111111); // #334455 + background-color: (#222222 - #fff); // #000000 + .other { + color: (2 * #111); // #222222 + border-color: (#333333 / 3 + #111); // #222222 + } +} + +.negations { + @var: 4px; + variable: (-@var); // 4 + variable1: (-@var + @var); // 0 + variable2: (@var + -@var); // 0 + variable3: (@var - -@var); // 8 + variable4: (-@var - -@var); // 0 + paren: (-(@var)); // -4px + paren2: (-(2 + 2) * -@var); // 16 +} + +================================================================================ +`; + +exports[`snippet: tests-unit/operations/operations-advanced.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Advanced operation tests to cover edge cases + +// Operations with math off +@math-off: true; +.test-math-off { + @a: 10px; + @b: 5px; + result: @a + @b; +} + +// Operations with Dimension to Color conversion +@dimension: 10px; +@color: #ff0000; +.test-dim-to-color { + // This should convert dimension to color for operation + result: @dimension + @color; +} + +// Operations with Color to Dimension conversion +.test-color-to-dim { + result: @color + @dimension; +} + +// Operations with division and PARENS_DIVISION math mode +@div-op: (10px / 2); +.test-division { + result: @div-op * 2; +} + +// Operations with nested operations +@nested: (10px + 5px) * 2; +.test-nested { + result: @nested; +} + +// Operations with spaced operators +@spaced: 10px + 5px; +.test-spaced { + result: @spaced; +} + +// Operations with non-spaced operators +@non-spaced: 10px+5px; +.test-non-spaced { + result: @non-spaced; +} + +// Operations with division operator +@div-op: 10px / 2; +.test-div { + result: @div-op; +} + +// Operations with invalid types (should error, but test the path) +.test-invalid { + // This will error, but tests the error path + // result: "string" + 10px; +} + +// Operations with Operation operands +@op1: 10px + 5px; +@op2: 20px - 10px; +.test-op-operands { + result: @op1 * @op2; +} + +// Operations with math context +.test-math-context { + @a: 10; + @b: 5; + add: @a + @b; + sub: @a - @b; + mul: @a * @b; + div: @a / @b; +} + + +=====================================output===================================== +// Advanced operation tests to cover edge cases + +// Operations with math off +@math-off: true; +.test-math-off { + @a: 10px; + @b: 5px; + result: @a + @b; +} + +// Operations with Dimension to Color conversion +@dimension: 10px; +@color: #ff0000; +.test-dim-to-color { + // This should convert dimension to color for operation + result: @dimension + @color; +} + +// Operations with Color to Dimension conversion +.test-color-to-dim { + result: @color + @dimension; +} + +// Operations with division and PARENS_DIVISION math mode +@div-op: (10px / 2); +.test-division { + result: @div-op * 2; +} + +// Operations with nested operations +@nested: (10px + 5px) * 2; +.test-nested { + result: @nested; +} + +// Operations with spaced operators +@spaced: 10px + 5px; +.test-spaced { + result: @spaced; +} + +// Operations with non-spaced operators +@non-spaced: 10px+5px; +.test-non-spaced { + result: @non-spaced; +} + +// Operations with division operator +@div-op: 10px / 2; +.test-div { + result: @div-op; +} + +// Operations with invalid types (should error, but test the path) +.test-invalid { + // This will error, but tests the error path + // result: "string" + 10px; +} + +// Operations with Operation operands +@op1: 10px + 5px; +@op2: 20px - 10px; +.test-op-operands { + result: @op1 * @op2; +} + +// Operations with math context +.test-math-context { + @a: 10; + @b: 5; + add: @a + @b; + sub: @a - @b; + mul: @a * @b; + div: @a / @b; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/parse-interpolation/parse-interpolation.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Parse interpolation tests +@inputs: input[type=text], input[type=email], input[type=password], textarea; + +@{inputs} { + &:focus { + foo: bar; + } +} + +@classes: .a, .b, .c; + +@{classes} { + + .z { + color: blue; + } +} + +.bar { + .d@{classes}&:hover, baz { + color: blue; + } +} + +@c: ~'.a, .b'; +@d: ~'.c, .d'; +@e: ~' + .e'; + +@{c}@{d} { + @{e} { + foo: bar; + } +} + +@textClasses: ~'&[class="text"], &.text'; + +input { + @{textClasses} { + background: red; + } +} + +@my-selector: ~'.selector-1, .selector-2'; +.master-page-1 { + @{my-selector} { + background-color: red; + } +} + +@list: apple, satsuma, banana, pear; +@{list} { + .fruit-& { + content: "Just a test."; + } +} + +=====================================output===================================== +// Parse interpolation tests +@inputs: input[type=text], input[type=email], input[type=password], textarea; + +@{inputs} { + &:focus { + foo: bar; + } +} + +@classes: .a, .b, .c; + +@{classes} { + + .z { + color: blue; + } +} + +.bar { + .d@{classes}&:hover, + baz { + color: blue; + } +} + +@c: ~".a, .b"; +@d: ~".c, .d"; +@e: ~" + .e"; + +@{c}@{d} { + @{e} { + foo: bar; + } +} + +@textClasses: ~'&[class="text"], &.text'; + +input { + @{textClasses} { + background: red; + } +} + +@my-selector: ~".selector-1, .selector-2"; +.master-page-1 { + @{my-selector} { + background-color: red; + } +} + +@list: apple, satsuma, banana, pear; +@{list} { + .fruit-& { + content: "Just a test."; + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/parser-slashed-combinator/parser-slashed-combinator.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Test for slashedCombinator parser (lines 1392-1399) +// This tests /deep/ and /shadow/ combinators +// NOTE: These combinators are DEPRECATED in CSS and should not be used in new code +// They were part of the Shadow DOM specification but have been removed + +// /deep/ combinator (deprecated) +.parent /deep/ .child { + color: red; +} + +// /shadow/ combinator (deprecated) +.container /shadow/ .content { + background: blue; +} + +// Test with nested selectors +.wrapper /deep/ .inner /deep/ .deepest { + padding: 10px; +} + + +=====================================output===================================== +// Test for slashedCombinator parser (lines 1392-1399) +// This tests /deep/ and /shadow/ combinators +// NOTE: These combinators are DEPRECATED in CSS and should not be used in new code +// They were part of the Shadow DOM specification but have been removed + +// /deep/ combinator (deprecated) +.parent /deep/ .child { + color: red; +} + +// /shadow/ combinator (deprecated) +.container /shadow/ .content { + background: blue; +} + +// Test with nested selectors +.wrapper /deep/ .inner /deep/ .deepest { + padding: 10px; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/plugi/plugi.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/less/less.js/issues/3660 +// const dir = parserInput.$re(/^@plugin?\\s+/); +// correct regexp is /^@plugin\\s+/ +// so follow code will change nothing, parse result is same with raw less code +@plugi "plugi-typo-dont-parse-as-@plugin"; + +=====================================output===================================== +// https://github.com/less/less.js/issues/3660 +// const dir = parserInput.$re(/^@plugin?\\s+/); +// correct regexp is /^@plugin\\s+/ +// so follow code will change nothing, parse result is same with raw less code +@plugi "plugi-typo-dont-parse-as-@plugin"; + +================================================================================ +`; + +exports[`snippet: tests-unit/plugin-module/plugin-module.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Test NPM import +@plugin "clean-css"; + +a { + background: none; +} + +=====================================output===================================== +// Test NPM import +@plugin "clean-css"; + +a { + background: none; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/plugin-preeval/plugin-preeval.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@plugin "../../plugin/plugin-preeval"; + +.two(@rules: {}) { + :root.two & { + @rules(); + } +} + +.one { + .two({ + --foo: @replace !important; + }); +} + +@stop: end; + +=====================================output===================================== +@plugin "../../plugin/plugin-preeval"; + +.two(@rules: {}) { + :root.two & { + @rules(); + } +} + +.one { + .two({ + --foo: @replace !important; + }); +} + +@stop: end; + +================================================================================ +`; + +exports[`snippet: tests-unit/property-targeted/property-targeted.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Targeted tests for specific uncovered lines in property.js + +// Lines 49-51: Property with important flag handling +// This tests when a property accessor accesses a property that has !important +.test-important { + color: red !important; + background: $color; +} + +// Lines 60-64: Property undefined error (should be in tests-error, but testing the path) +// This will error, but tests the error path +.test-undefined { + // value: @undefined-property; +} + +// Lines 72-73: find method returning null (property not found in any frame) +// This tests the find method when property doesn't exist +.test-not-found { + // value: @nonexistent; +} + + +=====================================output===================================== +// Targeted tests for specific uncovered lines in property.js + +// Lines 49-51: Property with important flag handling +// This tests when a property accessor accesses a property that has !important +.test-important { + color: red !important; + background: $color; +} + +// Lines 60-64: Property undefined error (should be in tests-error, but testing the path) +// This will error, but tests the error path +.test-undefined { + // value: @undefined-property; +} + +// Lines 72-73: find method returning null (property not found in any frame) +// This tests the find method when property doesn't exist +.test-not-found { + // value: @nonexistent; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/rulesets/rulesets.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Ruleset nesting and selector tests +#first > .one { + > #second .two > #deux { + width: 50%; + #third { + &:focus { + color: black; + #fifth { + > #sixth { + .seventh #eighth { + + #ninth { + color: purple; + } + } + } + } + } + height: 100%; + } + #fourth, #five, #six { + color: #110000; + .seven, .eight > #nine { + border: 1px solid black; + } + #ten { + color: red; + } + } + } + font-size: 2em; + hasOwnProperty: blue; +} + +=====================================output===================================== +// Ruleset nesting and selector tests +#first > .one { + > #second .two > #deux { + width: 50%; + #third { + &:focus { + color: black; + #fifth { + > #sixth { + .seventh #eighth { + + #ninth { + color: purple; + } + } + } + } + } + height: 100%; + } + #fourth, + #five, + #six { + color: #110000; + .seven, + .eight > #nine { + border: 1px solid black; + } + #ten { + color: red; + } + } + } + font-size: 2em; + hasownproperty: blue; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/scope/scope.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@x: red; +@x: blue; +@z: transparent; +@mix: none; + +.mixin { + @mix: #989; +} +@mix: blue; +.tiny-scope { + color: @mix; // #989 + .mixin(); +} + +.scope1 { + @y: orange; + @z: black; + color: @x; // blue + border-color: @z; // black + .hidden { + @x: #131313; + } + .scope2 { + @y: red; + color: @x; // blue + .scope3 { + @local: white; + color: @y; // red + border-color: @z; // black + background-color: @local; // white + } + } +} + +#namespace { + .scoped_mixin() { + @local-will-be-made-global: green; + .scope { + scoped-val: @local-will-be-made-global; + } + } +} + +#namespace > .scoped_mixin(); + +.setHeight(@h) { @height: 1024px; } +.useHeightInMixinCall(@h) { .useHeightInMixinCall { mixin-height: @h; } } +@mainHeight: 50%; +.setHeight(@mainHeight); +.heightIsSet { height: @height; } +.useHeightInMixinCall(@height); + +.importRuleset() { + .imported { + exists: true; + } +} +.importRuleset(); +.testImported { + .imported(); +} + +@parameterDefault: 'top level'; +@anotherVariable: 'top level'; +//mixin uses top-level variables +.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') { + default: @parameter; + scope: @anotherVariable; + sub-scope-only: @subScopeOnly; +} + +#allAreUsedHere { + //redefine top-level variables in different scope + @parameterDefault: 'inside'; + @anotherVariable: 'inside'; + @subScopeOnly: 'inside'; + //use the mixin + .mixinNoParam(); +} +#parentSelectorScope { + @col: white; + & { + @col: black; + } + prop: @col; + & { + @col: black; + } +} +.test-empty-mixin() { +} +#parentSelectorScopeMixins { + & { + .test-empty-mixin() { + should: never seee 1; + } + } + .test-empty-mixin(); + & { + .test-empty-mixin() { + should: never seee 2; + } + } +} + +=====================================output===================================== +@x: red; +@x: blue; +@z: transparent; +@mix: none; + +.mixin { + @mix: #989; +} +@mix: blue; +.tiny-scope { + color: @mix; // #989 + .mixin(); +} + +.scope1 { + @y: orange; + @z: black; + color: @x; // blue + border-color: @z; // black + .hidden { + @x: #131313; + } + .scope2 { + @y: red; + color: @x; // blue + .scope3 { + @local: white; + color: @y; // red + border-color: @z; // black + background-color: @local; // white + } + } +} + +#namespace { + .scoped_mixin() { + @local-will-be-made-global: green; + .scope { + scoped-val: @local-will-be-made-global; + } + } +} + +#namespace > .scoped_mixin(); + +.setHeight(@h) { + @height: 1024px; +} +.useHeightInMixinCall(@h) { + .useHeightInMixinCall { + mixin-height: @h; + } +} +@mainHeight: 50%; +.setHeight(@mainHeight); +.heightIsSet { + height: @height; +} +.useHeightInMixinCall(@height); + +.importRuleset() { + .imported { + exists: true; + } +} +.importRuleset(); +.testImported { + .imported(); +} + +@parameterDefault: "top level"; +@anotherVariable: "top level"; +//mixin uses top-level variables +.mixinNoParam(@parameter: @parameterDefault) when (@parameter = "top level") { + default: @parameter; + scope: @anotherVariable; + sub-scope-only: @subScopeOnly; +} + +#allAreUsedHere { + //redefine top-level variables in different scope + @parameterDefault: "inside"; + @anotherVariable: "inside"; + @subScopeOnly: "inside"; + //use the mixin + .mixinNoParam(); +} +#parentSelectorScope { + @col: white; + & { + @col: black; + } + prop: @col; + & { + @col: black; + } +} +.test-empty-mixin() { +} +#parentSelectorScopeMixins { + & { + .test-empty-mixin() { + should: never seee 1; + } + } + .test-empty-mixin(); + & { + .test-empty-mixin() { + should: never seee 2; + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/selectors/selectors.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Selector handling tests +h1, h2, h3 { + a, p { + &:hover { + color: red; + } + } +} + +#all { color: blue; } +#the { color: blue; } +#same { color: blue; } + +ul, li, div, q, blockquote, textarea { + margin: 0; +} + +td { + margin: 0; + padding: 0; +} + +td, input { + line-height: 1em; +} + +a { + color: red; + + &:hover { color: blue; } + + div & { color: green; } + + p & span { color: yellow; } +} + +.foo { + .bar, .baz { + & .qux { + display: block; + } + .qux & { + display: inline; + } + .qux& { + display: inline-block; + } + .qux & .biz { + display: none; + } + } +} + +.b { + &.c { + .a& { + color: red; + } + } +} + +.b { + .c & { + &.a { + color: red; + } + } +} + +.p { + .foo &.bar { + color: red; + } +} + +.p { + .foo&.bar { + color: red; + } +} + +.foo { + .foo + & { + background: amber; + } + & + & { + background: amber; + } +} + +.foo, .bar { + & + & { + background: amber; + } +} + +.foo, .bar { + a, b { + & > & { + background: amber; + } + } +} + +.other ::fnord { color: red } +.other::fnord { color: red } +.other { + ::bnord {color: red } + &::bnord {color: red } +} + +// selector interpolation +@theme: blood; +@selector: ~".@{theme}"; +@{selector} { + color:red; +} +@{selector}red { + color: green; +} +.red { + #@{theme}.@{theme}&.black:@{theme} { + color:black; + } +} +@num: 3; +:nth-child(@{num}) { + selector: interpolated; +} +.test-rule { + &:nth-child(@{num}) { + selector: interpolated; + } + &:nth-child(odd):not(:nth-child(3)) { + color: #ff0000; + } +} +@prop: p; +[prop], +[prop=ten-percent], +[prop|="value@{num}"], +[prop*="val@{num}"], +[|prop~="val@{num}"], +[*|prop$="val@{num}"], +[ns|prop^="val@{num}"], +[@{prop}^="val@{num}"], +[@{prop}] { + attributes: yes; +} + +/** + * https://www.w3.org/TR/selectors-4/#attribute-case + */ +@pattern: less; +a[href*="insensitive" i] { + color: cyan; +} +a[href*="cAsE" s] { + color: pink; +} +a[href*="@{pattern}" I] { + background-color: silver; +} +a[href*="@{pattern}" S] { + background-color: red; +} + +/* +Large comment means chunk will be emitted after } which means chunk will begin with whitespace... +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +*/ +@{selector} { + color: red; +} +.only-nested { + .level2 { + .foo:not(.tst&:hover) { + test: only-nested; + } + } +} +.nestend-and-non-nested { + .foo&:not(.tst&:hover) { + test: nestend-and-non-nested; + } +} +.selector:not(&:hover) { + test: global scope; +} +// https://github.com/less/less.js/issues/2206 +.extend-this { + content: '\\2661'; +} +.first-level { + .second-level { + .active&:extend(.extend-this) { } + &.active2:extend(.extend-this) { } + } +} + +// https://github.com/less/less.js/issues/4358 +.x { + &:is(&.a) { color: red; } + &:not(&.b, &.c) { color: green; } + &:is(&.d, &.e, &.f) { color: blue; } +} + +a:is(.b, :is(.c)) { + color: blue; +} + +a:is(.b, :is(.c), :has(div)) { + color: red; +} + +// https://github.com/less/less.js/issues/4378 +:is(:not(:has(>.foo)), :has(>.foo.bar)) { + overflow: clip; +} + +:matches(:not(:has(>.foo)), :has(>.foo.bar)) { + overflow: clip; +} + +:where(:not(:has(>.foo)), :has(>.foo.bar)) { + overflow: clip; +} + +:is(:has(>.foo + .bar), :has(>.baz ~ .qux), :not(:has(.quux))) { + color: blue; +} + +:where(.a, .b, .c) { + color: red; +} + +:not(.a, .b, .c) { + color: green; +} + +:where(:is(.a, .b), :has(>.c)) { + color: blue; +} + +:is(:where(:has(.foo)), :not(:has(.bar))) { + color: purple; +} + +=====================================output===================================== +// Selector handling tests +h1, +h2, +h3 { + a, + p { + &:hover { + color: red; + } + } +} + +#all { + color: blue; +} +#the { + color: blue; +} +#same { + color: blue; +} + +ul, +li, +div, +q, +blockquote, +textarea { + margin: 0; +} + +td { + margin: 0; + padding: 0; +} + +td, +input { + line-height: 1em; +} + +a { + color: red; + + &:hover { + color: blue; + } + + div & { + color: green; + } + + p & span { + color: yellow; + } +} + +.foo { + .bar, + .baz { + & .qux { + display: block; + } + .qux & { + display: inline; + } + .qux& { + display: inline-block; + } + .qux & .biz { + display: none; + } + } +} + +.b { + &.c { + .a& { + color: red; + } + } +} + +.b { + .c & { + &.a { + color: red; + } + } +} + +.p { + .foo &.bar { + color: red; + } +} + +.p { + .foo&.bar { + color: red; + } +} + +.foo { + .foo + & { + background: amber; + } + & + & { + background: amber; + } +} + +.foo, +.bar { + & + & { + background: amber; + } +} + +.foo, +.bar { + a, + b { + & > & { + background: amber; + } + } +} + +.other ::fnord { + color: red; +} +.other::fnord { + color: red; +} +.other { + ::bnord { + color: red; + } + &::bnord { + color: red; + } +} + +// selector interpolation +@theme: blood; +@selector: ~".@{theme}"; +@{selector} { + color: red; +} +@{selector}red { + color: green; +} +.red { + #@{theme}.@{theme}&.black:@{theme} { + color: black; + } +} +@num: 3; +:nth-child(@{num}) { + selector: interpolated; +} +.test-rule { + &:nth-child(@{num}) { + selector: interpolated; + } + &:nth-child(odd):not(:nth-child(3)) { + color: #ff0000; + } +} +@prop: p; +[prop], +[prop="ten-percent"], +[prop|="value@{num}"], +[prop*="val@{num}"], +[|prop~="val@{num}"], +[*|prop$="val@{num}"], +[ns|prop^="val@{num}"], +[@{prop}^="val@{num}"], +[@{prop}] { + attributes: yes; +} + +/** + * https://www.w3.org/TR/selectors-4/#attribute-case + */ +@pattern: less; +a[href*="insensitive" i] { + color: cyan; +} +a[href*="cAsE" s] { + color: pink; +} +a[href*="@{pattern}" I] { + background-color: silver; +} +a[href*="@{pattern}" S] { + background-color: red; +} + +/* +Large comment means chunk will be emitted after } which means chunk will begin with whitespace... +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank +*/ +@{selector} { + color: red; +} +.only-nested { + .level2 { + .foo:not(.tst&:hover) { + test: only-nested; + } + } +} +.nestend-and-non-nested { + .foo&:not(.tst&:hover) { + test: nestend-and-non-nested; + } +} +.selector:not(&:hover) { + test: global scope; +} +// https://github.com/less/less.js/issues/2206 +.extend-this { + content: "\\2661"; +} +.first-level { + .second-level { + .active&:extend(.extend-this) { + } + &.active2:extend(.extend-this) { + } + } +} + +// https://github.com/less/less.js/issues/4358 +.x { + &:is(&.a) { + color: red; + } + &:not(&.b, &.c) { + color: green; + } + &:is(&.d, &.e, &.f) { + color: blue; + } +} + +a:is(.b, :is(.c)) { + color: blue; +} + +a:is(.b, :is(.c), :has(div)) { + color: red; +} + +// https://github.com/less/less.js/issues/4378 +:is(:not(:has(> .foo)), :has(> .foo.bar)) { + overflow: clip; +} + +:matches(:not(:has(> .foo)), :has(> .foo.bar)) { + overflow: clip; +} + +:where(:not(:has(> .foo)), :has(> .foo.bar)) { + overflow: clip; +} + +:is(:has(> .foo + .bar), :has(> .baz ~ .qux), :not(:has(.quux))) { + color: blue; +} + +:where(.a, .b, .c) { + color: red; +} + +:not(.a, .b, .c) { + color: green; +} + +:where(:is(.a, .b), :has(> .c)) { + color: blue; +} + +:is(:where(:has(.foo)), :not(:has(.bar))) { + color: purple; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/starting-style/starting-style.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#nav { + transition: background-color 3.5s; + background-color: gray; +} + +[popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + opacity: 0; + transform: scaleX(0); + } +} + +#target { + transition: background-color 1.5s; + background-color: green; +} + +@starting-style { + #target { + background-color: transparent; + } +} + +#source { + transition: background-color 2.5s; + background-color: red; +} + +source:first { + opacity: 1; + transform: scaleX(1); + + @starting-style { + opacity: 0; + transform: scaleX(0); + } +} + +#footer { + color: yellow; +} + +@starting-style { + #footer { + background-color: transparent; + } +} + +nav > [popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + padding+_: 10px; + padding+_: 8px; + padding+_: 6px; + padding+_: 4px; + } +} + +aside > [popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + // vector math + each(1 2 3 4, { + padding+_: (@value * 10px); + }); + } +} + + + +=====================================output===================================== +#nav { + transition: background-color 3.5s; + background-color: gray; +} + +[popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + opacity: 0; + transform: scaleX(0); + } +} + +#target { + transition: background-color 1.5s; + background-color: green; +} + +@starting-style { + #target { + background-color: transparent; + } +} + +#source { + transition: background-color 2.5s; + background-color: red; +} + +source:first { + opacity: 1; + transform: scaleX(1); + + @starting-style { + opacity: 0; + transform: scaleX(0); + } +} + +#footer { + color: yellow; +} + +@starting-style { + #footer { + background-color: transparent; + } +} + +nav > [popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + padding+_: 10px; + padding+_: 8px; + padding+_: 6px; + padding+_: 4px; + } +} + +aside > [popover]:popover-open { + opacity: 1; + transform: scaleX(1); + + @starting-style { + // vector math + each(1 2 3 4, { + padding+_: (@value * 10px); + }); + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/strings/strings.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// String handling and interpolation tests +#strings { + background-image: url("http://son-of-a-banana.com"); + quotes: "~" "~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{" "}"; + escapes: "\\"hello\\" \\\\world"; + escapes2: "\\"llo"; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#single-quote { + quotes: "'" "'"; + content: '""#!&""'; + empty: ''; + semi-colon: ';'; +} +#one-line { image: url(http://tooks.com) } +#crazy { image: url(http://), "}", url("http://}") } +#interpolation { + @var: '/dev'; + url: "http://lesscss.org@{var}/image.jpg"; + + @var2: 256; + url2: "http://lesscss.org/image-@{var2}.jpg"; + + @var3: #456; + url3: "http://lesscss.org@{var3}"; + + @var4: hello; + url4: "http://lesscss.org/@{var4}"; + + @var5: 54.4px; + url5: "http://lesscss.org/@{var5}"; +} + +// multiple calls with string interpolation + +.mix-mul (@a: green) { + color: ~"@{a}"; +} +.mix-mul-class { + .mix-mul(blue); + .mix-mul(red); + .mix-mul(black); + .mix-mul(orange); +} + +@test: Arial, Verdana, San-Serif; +.watermark { + @family: ~"Univers, @{test}"; + family: @family; +} +#iterated-interpolation { + @box-small: 10px; + @box-large: 100px; + + .mixin { // both ruleset and mixin + width: ~"@{box-@{suffix}}"; + weird: ~"@{box}-@{suffix}}"; + width-str: "@{box-@{suffix}}"; + weird-str: "@{box}-@{suffix}}"; + @box: ~"@{box"; + @suffix: large; + } + .interpolation-mixin { + .mixin(); //call the above as mixin + } +} + +=====================================output===================================== +// String handling and interpolation tests +#strings { + background-image: url("http://son-of-a-banana.com"); + quotes: "~""~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{" "}"; + escapes: '"hello" \\\\world'; + escapes2: '"llo'; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#single-quote { + quotes: "'" "'"; + content: '""#!&""'; + empty: ""; + semi-colon: ";"; +} +#one-line { + image: url(http://tooks.com); +} +#crazy { + image: url(http://), "}", url("http://}"); +} +#interpolation { + @var: "/dev"; + url: "http://lesscss.org@{var}/image.jpg"; + + @var2: 256; + url2: "http://lesscss.org/image-@{var2}.jpg"; + + @var3: #456; + url3: "http://lesscss.org@{var3}"; + + @var4: hello; + url4: "http://lesscss.org/@{var4}"; + + @var5: 54.4px; + url5: "http://lesscss.org/@{var5}"; +} + +// multiple calls with string interpolation + +.mix-mul (@a: green) { + color: ~"@{a}"; +} +.mix-mul-class { + .mix-mul(blue); + .mix-mul(red); + .mix-mul(black); + .mix-mul(orange); +} + +@test: Arial, Verdana, San-Serif; +.watermark { + @family: ~"Univers, @{test}"; + family: @family; +} +#iterated-interpolation { + @box-small: 10px; + @box-large: 100px; + + .mixin { + // both ruleset and mixin + width: ~"@{box-@{suffix}}"; + weird: ~"@{box}-@{suffix}}"; + width-str: "@{box-@{suffix}}"; + weird-str: "@{box}-@{suffix}}"; + @box: ~"@{box"; + @suffix: large; + } + .interpolation-mixin { + .mixin(); //call the above as mixin + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/tailwind/tailwind.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.box { + @apply h-64 w-64; +} + +=====================================output===================================== +.box { + @apply h-64 w-64; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/assets/nested-gradient-with-svg-gradient/mixin-consumer.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.mixin-consumer { + color: violet; +} + + +=====================================output===================================== +.mixin-consumer { + color: violet; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/assets/nested-gradient-with-svg-gradient/svg-gradient-mixin.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.gradient-mixin(@color) { + background: svg-gradient(to bottom, + fade(@color, 0%) 0%, + fade(@color, 5%) 60%, + fade(@color, 10%) 70%, + fade(@color, 15%) 73%, + fade(@color, 20%) 75%, + fade(@color, 25%) 80%, + fade(@color, 30%) 85%, + fade(@color, 35%) 88%, + fade(@color, 40%) 90%, + fade(@color, 45%) 95%, + fade(@color, 50%) 100% + ); +} + +=====================================output===================================== +.gradient-mixin(@color) { + background: svg-gradient( + to bottom, + fade(@color, 0%) 0%, + fade(@color, 5%) 60%, + fade(@color, 10%) 70%, + fade(@color, 15%) 73%, + fade(@color, 20%) 75%, + fade(@color, 25%) 80%, + fade(@color, 30%) 85%, + fade(@color, 35%) 88%, + fade(@color, 40%) 90%, + fade(@color, 45%) 95%, + fade(@color, 50%) 100% + ); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/import/import-and-relative-paths-test.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "../css/background.css"; +@import "import-test-d.css"; + +@import "imports/logo"; +@import "imports/font"; + +.unquoted-relative-path-bg() { + background-image: url(../../../data/image.jpg); +} +.quoted-relative-path-border-image() { + border-image: url('../../../data/image.jpg'); +} + +#imported-relative-path { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} + +=====================================output===================================== +@import "../css/background.css"; +@import "import-test-d.css"; + +@import "imports/logo"; +@import "imports/font"; + +.unquoted-relative-path-bg() { + background-image: url(../../../data/image.jpg); +} +.quoted-relative-path-border-image() { + border-image: url("../../../data/image.jpg"); +} + +#imported-relative-path { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/import/imports/font.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@font-face { + font-family: xecret; + src: url('../assets/xecret.ttf'); +} + +#secret { + font-family: xecret, sans-serif; +} + +=====================================output===================================== +@font-face { + font-family: xecret; + src: url("../assets/xecret.ttf"); +} + +#secret { + font-family: xecret, sans-serif; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/import/imports/logo.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +#logo { + width: 100px; + height: 100px; + background: url('../assets/logo.png'); + background: url("#inline-svg"); +} + +=====================================output===================================== +#logo { + width: 100px; + height: 100px; + background: url("../assets/logo.png"); + background: url("#inline-svg"); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/nested-gradient-with-svg-gradient/mixin-consumer.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "svg-gradient-mixin.less"; + +.gray-gradient { + .gradient-mixin(#999); +} + +=====================================output===================================== +@import "svg-gradient-mixin.less"; + +.gray-gradient { + .gradient-mixin(#999); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/nested-gradient-with-svg-gradient/svg-gradient-mixin.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +.gradient-mixin(@color) { + background: svg-gradient(to bottom, + fade(@color, 0%) 0%, + fade(@color, 5%) 60%, + fade(@color, 10%) 70%, + fade(@color, 15%) 73%, + fade(@color, 20%) 75%, + fade(@color, 25%) 80%, + fade(@color, 30%) 85%, + fade(@color, 35%) 88%, + fade(@color, 40%) 90%, + fade(@color, 45%) 95%, + fade(@color, 50%) 100% + ); +} + +=====================================output===================================== +.gradient-mixin(@color) { + background: svg-gradient( + to bottom, + fade(@color, 0%) 0%, + fade(@color, 5%) 60%, + fade(@color, 10%) 70%, + fade(@color, 15%) 73%, + fade(@color, 20%) 75%, + fade(@color, 25%) 80%, + fade(@color, 30%) 85%, + fade(@color, 35%) 88%, + fade(@color, 40%) 90%, + fade(@color, 45%) 95%, + fade(@color, 50%) 100% + ); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/urls/urls.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@import "nested-gradient-with-svg-gradient/mixin-consumer.less"; + +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); + not-a-comment: url(//z); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; + background: url("img.jpg") center / 100px; + background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); + background-image: url("http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700"); +} + +#svg-data-uri { + background: transparent url('data:image/svg+xml, '); +} + +.comma-delimited { + background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); +} +.values { + @a: 'Trebuchet'; + url: url(@a); +} + +@import "import/import-and-relative-paths-test"; + +#relative-url-import { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} + +#data-uri { + uri: data-uri('image/jpeg;base64', '../../data/image.jpg'); + @var: replace('../../data/replace.jpg', "replace", "image"); + background-image: data-uri(@var), data-uri(replace('../../data/image.filext', "filext", "jpg")); + + uri-fragment: data-uri('image/jpeg;base64', '../../data/image.jpg#fragment'); +} + +#data-uri-guess { + uri: data-uri('../../data/image.jpg'); +} + +#data-uri-ascii { + uri-1: data-uri('text/html', '../../data/page.html'); + uri-2: data-uri('../../data/page.html'); +} + +#file-functions { + svg-not-base-64: data-uri('../../data/image.svg'); + size: image-size('../../data/data-uri-fail.png'); + width: image-width('../../data/data-uri-fail.png'); + height: image-height('../../data/data-uri-fail.png'); +} +.add_an_import(@file_to_import) { +@import "@{file_to_import}"; +} + +.add_an_import("file.css"); + +#svg-functions { + background-image: svg-gradient(to bottom, black, white); + background-image: svg-gradient(to bottom, black, orange 3%, white); + @green_5: green 5%; + @orange_percentage: 3%; + @orange_color: orange; + background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); +} +//it should work also inside @font-face #2035 +@font-face { + font-family: 'MyWebFont'; + src: url(webfont.eot); + src+: url('webfont.eot?#iefix'); + src+_: format('embedded-opentype'); + src+: url('webfont.woff') format('woff'); + src+: format('truetype'); + src+_: url('webfont.ttf'); + src+: url('webfont.svg#svgFontName') format('svg'); +} + +=====================================output===================================== +@import "nested-gradient-with-svg-gradient/mixin-consumer.less"; + +@font-face { + src: url("/fonts/garamond-pro.ttf"); + src: + local(Futura-Medium), + url(fonts.svg#MyGeometricModern) format("svg"); + not-a-comment: url(//z); +} +#shorthands { + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; + background: url("img.jpg") center / 100px; + background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box + padding-box; +} +#misc { + background-image: url(images/image.jpg); +} +#data-uri { + background: url(data:image/png;charset=utf-8;base64, + kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ + k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U + kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); + background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); + background-image: url(http://fonts.googleapis.com/css?family=\\"Rokkitt\\":\\(400\\),700); + background-image: url('http://fonts.googleapis.com/css?family="Rokkitt":\\(400\\),700'); +} + +#svg-data-uri { + background: transparent + url('data:image/svg+xml, '); +} + +.comma-delimited { + background: + url(bg.jpg) no-repeat, + url(bg.png) repeat-x top left, + url(bg); +} +.values { + @a: "Trebuchet"; + url: url(@a); +} + +@import "import/import-and-relative-paths-test"; + +#relative-url-import { + .unquoted-relative-path-bg(); + .quoted-relative-path-border-image(); +} + +#data-uri { + uri: data-uri("image/jpeg;base64", "../../data/image.jpg"); + @var: replace("../../data/replace.jpg", "replace", "image"); + background-image: + data-uri(@var), + data-uri(replace("../../data/image.filext", "filext", "jpg")); + + uri-fragment: data-uri("image/jpeg;base64", "../../data/image.jpg#fragment"); +} + +#data-uri-guess { + uri: data-uri("../../data/image.jpg"); +} + +#data-uri-ascii { + uri-1: data-uri("text/html", "../../data/page.html"); + uri-2: data-uri("../../data/page.html"); +} + +#file-functions { + svg-not-base-64: data-uri("../../data/image.svg"); + size: image-size("../../data/data-uri-fail.png"); + width: image-width("../../data/data-uri-fail.png"); + height: image-height("../../data/data-uri-fail.png"); +} +.add_an_import(@file_to_import) { + @import "@{file_to_import}"; +} + +.add_an_import("file.css"); + +#svg-functions { + background-image: svg-gradient(to bottom, black, white); + background-image: svg-gradient(to bottom, black, orange 3%, white); + @green_5: green 5%; + @orange_percentage: 3%; + @orange_color: orange; + background-image: svg-gradient( + to bottom, + (mix(black, white) + #444) 1%, + @orange_color @orange_percentage, + ((@green_5)), + white 95% + ); +} +//it should work also inside @font-face #2035 +@font-face { + font-family: "MyWebFont"; + src: url(webfont.eot); + src+: url("webfont.eot?#iefix"); + src+_: format("embedded-opentype"); + src+: url("webfont.woff") format("woff"); + src+: format("truetype"); + src+_: url("webfont.ttf"); + src+: url("webfont.svg#svgFontName") format("svg"); +} + +================================================================================ +`; + +exports[`snippet: tests-unit/variables/variables.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@a: 2; +@x: (@a * @a); +@y: (@x + 1); +@z: (@x * 2 + @y); +@var: -1; +@b: @a * 10; +@c: #888; +@fonts: "Trebuchet MS", Verdana, sans-serif; +@f: @fonts; +@quotes: "~" "~"; +@q: @quotes; +@onePixel: 1px; + +.variables-basic { + width: (@z + 1cm); + height: (@b + @x + 0px); + color: @c; + font-family: @f; + quotes: @q; +} + +.variable-dash { + @jumbotron-padding: 30px; + padding: @jumbotron-padding (@jumbotron-padding/2); +} + +.variable-redefinition { + @var: 0; + zero: @var; +} + +.variable-scope { + @var: 4; + @var: 2; + three: @var; + @var: 3; +} + +.variable-important { + @important-var: @c !important; + @important-var-two: @a !important; + minus-one: @var; + @a: 'Trebuchet'; + @multi: 'A', B, C; + font-family: @a, @a, @a; + color: @c !important; + same-color: @important-var; + same-again: @important-var !important; + multi-important: @important-var @important-var, @important-var-two; + multi: something @multi, @a; +} + +.variable-names-quoted { + @var: 'hello'; + @name: 'var'; + name: @@name; +} + +.variable-names-unquoted { + @var: 'hello'; + @name: var; + name: @@name; +} + +.variable-names-color-keyword { + @red: 'hello'; + @name: red; + name: @@name; +} + +.variable-units { + width: @onePixel; + same-unit-as-previously: (@onePixel / @onePixel); + square-pixel-divided: (@onePixel * @onePixel / @onePixel); + odd-unit: unit((@onePixel * 4em / 2cm)); +} + +.variable-pollution { + @a: 'no-pollution'; + a: @a; +} + +.polluteMixin() { + @a: 'pollution'; +} + + + +// https://github.com/less/less.js/issues/2462 +@type: 5_large; +.icon-@{type} { + background-image: ~"url(/img/icon/@{type}.svg)"; +} + +=====================================output===================================== +@a: 2; +@x: (@a * @a); +@y: (@x + 1); +@z: (@x * 2 + @y); +@var: -1; +@b: @a * 10; +@c: #888; +@fonts: "Trebuchet MS", Verdana, sans-serif; +@f: @fonts; +@quotes: "~""~"; +@q: @quotes; +@onePixel: 1px; + +.variables-basic { + width: (@z + 1cm); + height: (@b + @x + 0px); + color: @c; + font-family: @f; + quotes: @q; +} + +.variable-dash { + @jumbotron-padding: 30px; + padding: @jumbotron-padding (@jumbotron-padding / 2); +} + +.variable-redefinition { + @var: 0; + zero: @var; +} + +.variable-scope { + @var: 4; + @var: 2; + three: @var; + @var: 3; +} + +.variable-important { + @important-var: @c !important; + @important-var-two: @a !important; + minus-one: @var; + @a: "Trebuchet"; + @multi: "A", B, C; + font-family: @a, @a, @a; + color: @c !important; + same-color: @important-var; + same-again: @important-var !important; + multi-important: + @important-var @important-var, + @important-var-two; + multi: + something @multi, + @a; +} + +.variable-names-quoted { + @var: "hello"; + @name: "var"; + name: @@name; +} + +.variable-names-unquoted { + @var: "hello"; + @name: var; + name: @@name; +} + +.variable-names-color-keyword { + @red: "hello"; + @name: red; + name: @@name; +} + +.variable-units { + width: @onePixel; + same-unit-as-previously: (@onePixel / @onePixel); + square-pixel-divided: (@onePixel * @onePixel / @onePixel); + odd-unit: unit((@onePixel * 4em / 2cm)); +} + +.variable-pollution { + @a: "no-pollution"; + a: @a; +} + +.polluteMixin() { + @a: "pollution"; +} + +// https://github.com/less/less.js/issues/2462 +@type: 5_large; +.icon-@{type} { + background-image: ~"url(/img/icon/@{type}.svg)"; +} + +================================================================================ +`; + +exports[`snippet: tests-unit/variables-in-at-rules/variables-in-at-rules.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +@Eight: 8; +@charset "UTF-@{Eight}"; + +@ns: less; +@namespace @ns "http://lesscss.org"; + +@name: enlarger; +@keyframes @name { + from {font-size: 12px;} + to {font-size: 15px;} +} + +.m(reducer); +.m(@name) { + @-webkit-keyframes @name { + from {font-size: 13px;} + to {font-size: 10px;} + } +} + +=====================================output===================================== +@Eight: 8; +@charset "UTF-@{Eight}"; + +@ns: less; +@namespace @ns "http://lesscss.org"; + +@name: enlarger; +@keyframes @name { + from { + font-size: 12px; + } + to { + font-size: 15px; + } +} + +.m(reducer); +.m(@name) { + @-webkit-keyframes @name { + from { + font-size: 13px; + } + to { + font-size: 10px; + } + } +} + +================================================================================ +`; + +exports[`snippet: tests-unit/whitespace/whitespace.less format 1`] = ` +====================================options===================================== +parsers: ["less"] + printWidth: 80 (default) | +=====================================input====================================== +// Whitespace handling tests + + +.whitespace + { color: white; } + +.whitespace +{ + color: white; +} + .whitespace +{ color: white; } + +.whitespace{color:white;} +.whitespace { color : white ; } + +.white, +.space, +.mania +{ color: white; } + +.no-semi-column { color: white } +.no-semi-column { + color: white; + white-space: pre +} +.no-semi-column {border: 2px solid white} +.newlines { + background: the, + great, + wall; + border: 2px + solid + black; +} +.empty { + +} +.sel +.newline_ws .tab_ws { +color: +white; +background-position: 45 +-23; +} + +=====================================output===================================== +// Whitespace handling tests + +.whitespace { + color: white; +} + +.whitespace { + color: white; +} +.whitespace { + color: white; +} + +.whitespace { + color: white; +} +.whitespace { + color: white; +} + +.white, +.space, +.mania { + color: white; +} + +.no-semi-column { + color: white; +} +.no-semi-column { + color: white; + white-space: pre; +} +.no-semi-column { + border: 2px solid white; +} +.newlines { + background: the, great, wall; + border: 2px solid black; +} +.empty { +} +.sel .newline_ws .tab_ws { + color: white; + background-position: 45 -23; +} + +================================================================================ +`; diff --git a/tests/format/less/less-test-suite/format.test.js b/tests/format/less/less-test-suite/format.test.js new file mode 100644 index 000000000..6b4a4652e --- /dev/null +++ b/tests/format/less/less-test-suite/format.test.js @@ -0,0 +1,39 @@ +import lessTestSuite from "less-test-suite"; + +/* spell-checker: disable */ +const SKIP = new Set(["tests-unit/import/import/invalid-css.less"]); +const BUGS = new Set([ + // Can't parse + "tests-unit/variables/variable-advanced.less", + "tests-unit/property-accessors/property-accessors.less", + "tests-unit/plugin/plugin.less", + "tests-unit/permissive-parse/permissive-parse.less", + "tests-unit/parser-property-interp/parser-property-interp.less", + "tests-unit/mixins-interpolated/mixins-interpolated.less", + "tests-unit/import/import/invalid-css.less", + "tests-unit/functions/functions.less", + "tests-unit/extract-and-length/extract-and-length.less", + "tests-unit/css-escapes/css-escapes.less", + "tests-unit/comments/comments.less", + + // Ast changed or unstable + "tests-unit/property-name-interp/property-name-interp.less", + "tests-unit/extend-chaining/extend-chaining.less", +]); +/* spell-checker: enable */ + +const testCases = lessTestSuite.filter( + ({ error, name }) => !error && !SKIP.has(name) && !BUGS.has(name), +); + +runFormatTest( + { + importMeta: import.meta, + snippets: testCases.map(({ name, input }) => ({ + name, + filename: name, + code: input, + })), + }, + ["less"], +); diff --git a/yarn.lock b/yarn.lock index 0936f9c1c..86059f3cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6392,6 +6392,13 @@ __metadata: languageName: node linkType: hard +"less-test-suite@npm:0.0.1": + version: 0.0.1 + resolution: "less-test-suite@npm:0.0.1" + checksum: 10/89b750e91ab3d8309d130f240f6e9583b489265080989dc3398a66f45cf53faa7ebb29240746fb3820aa8caa4d9420601a19af3bb09eff1452a3dcdbba03363a + languageName: node + linkType: hard + "leven@npm:4.1.0, leven@npm:^4.1.0": version: 4.1.0 resolution: "leven@npm:4.1.0" @@ -8018,6 +8025,7 @@ __metadata: json5: "npm:2.2.3" jsx-test-suite: "npm:0.0.2" knip: "npm:6.21.0" + less-test-suite: "npm:0.0.1" leven: "npm:4.1.0" linguist-languages: "npm:9.4.0" magic-string: "npm:0.30.21"