mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 06:42:41 +01:00
Add a LESS linter.
Summary: This class provides an adapter for [[https://github.com/less/less.js/ | lessc]]. Test Plan: Wrote and executed unit tests. Reviewers: chad, #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D8992
This commit is contained in:
parent
9a13c87ac4
commit
88ff113f92
96 changed files with 3860 additions and 0 deletions
|
@ -87,6 +87,8 @@ phutil_register_library_map(array(
|
|||
'ArcanistJSONLintLinter' => 'lint/linter/ArcanistJSONLintLinter.php',
|
||||
'ArcanistJSONLintLinterTestCase' => 'lint/linter/__tests__/ArcanistJSONLintLinterTestCase.php',
|
||||
'ArcanistLandWorkflow' => 'workflow/ArcanistLandWorkflow.php',
|
||||
'ArcanistLesscLinter' => 'lint/linter/ArcanistLesscLinter.php',
|
||||
'ArcanistLesscLinterTestCase' => 'lint/linter/__tests__/ArcanistLesscLinterTestCase.php',
|
||||
'ArcanistLiberateWorkflow' => 'workflow/ArcanistLiberateWorkflow.php',
|
||||
'ArcanistLintConsoleRenderer' => 'lint/renderer/ArcanistLintConsoleRenderer.php',
|
||||
'ArcanistLintEngine' => 'lint/engine/ArcanistLintEngine.php',
|
||||
|
@ -254,6 +256,8 @@ phutil_register_library_map(array(
|
|||
'ArcanistJSONLintLinter' => 'ArcanistExternalLinter',
|
||||
'ArcanistJSONLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||
'ArcanistLandWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistLesscLinter' => 'ArcanistExternalLinter',
|
||||
'ArcanistLesscLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||
'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistLintConsoleRenderer' => 'ArcanistLintRenderer',
|
||||
'ArcanistLintJSONRenderer' => 'ArcanistLintRenderer',
|
||||
|
|
160
src/lint/linter/ArcanistLesscLinter.php
Normal file
160
src/lint/linter/ArcanistLesscLinter.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A linter for LESSCSS files.
|
||||
*
|
||||
* This linter uses [[https://github.com/less/less.js | lessc]] to detect
|
||||
* errors and potential problems in [[http://lesscss.org/ | LESS]] code.
|
||||
*/
|
||||
final class ArcanistLesscLinter extends ArcanistExternalLinter {
|
||||
|
||||
const LINT_RUNTIME_ERROR = 1;
|
||||
const LINT_ARGUMENT_ERROR = 2;
|
||||
const LINT_FILE_ERROR = 3;
|
||||
const LINT_NAME_ERROR = 4;
|
||||
const LINT_OPERATION_ERROR = 5;
|
||||
const LINT_PARSE_ERROR = 6;
|
||||
const LINT_SYNTAX_ERROR = 7;
|
||||
|
||||
public function getLinterName() {
|
||||
return 'LESSC';
|
||||
}
|
||||
|
||||
public function getLinterConfigurationName() {
|
||||
return 'lessc';
|
||||
}
|
||||
|
||||
public function getLinterConfigurationOptions() {
|
||||
return parent::getLinterConfigurationOptions() + array(
|
||||
'lessc.strict-math' => 'optional bool',
|
||||
'lessc.strict-units' => 'optional bool',
|
||||
);
|
||||
}
|
||||
|
||||
public function getLintNameMap() {
|
||||
return array(
|
||||
self::LINT_RUNTIME_ERROR => pht('Runtime Error'),
|
||||
self::LINT_ARGUMENT_ERROR => pht('Argument Error'),
|
||||
self::LINT_FILE_ERROR => pht('File Error'),
|
||||
self::LINT_NAME_ERROR => pht('Name Error'),
|
||||
self::LINT_OPERATION_ERROR => pht('Operation Error'),
|
||||
self::LINT_PARSE_ERROR => pht('Parse Error'),
|
||||
self::LINT_SYNTAX_ERROR => pht('Syntax Error'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getDefaultBinary() {
|
||||
return 'lessc';
|
||||
}
|
||||
|
||||
public function getCacheVersion() {
|
||||
list($stdout) = execx('%C --version', $this->getExecutableCommand());
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('/^lessc (?P<version>\d+\.\d+\.\d+)$/', $stdout, $matches)) {
|
||||
$version = $matches['version'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getInstallInstructions() {
|
||||
return pht('Install lessc using `npm install -g lessc`.');
|
||||
}
|
||||
|
||||
public function shouldExpectCommandErrors() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function supportsReadDataFromStdin() {
|
||||
// Technically `lessc` can read data from standard input however, when doing
|
||||
// so, relative imports cannot be resolved. Therefore, this functionality is
|
||||
// disabled.
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getReadDataFromStdinFilename() {
|
||||
return '-';
|
||||
}
|
||||
|
||||
protected function getMandatoryFlags() {
|
||||
return array(
|
||||
'--lint',
|
||||
'--no-color',
|
||||
'--strict-math='.
|
||||
($this->getConfig('lessc.strict-math') ? 'on' : 'off'),
|
||||
'--strict-units='.
|
||||
($this->getConfig('lessc.strict-units') ? 'on' : 'off'));
|
||||
}
|
||||
|
||||
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
|
||||
$lines = phutil_split_lines($stderr, false);
|
||||
|
||||
$messages = array();
|
||||
foreach ($lines as $line) {
|
||||
$matches = null;
|
||||
$match = preg_match(
|
||||
'/^(?P<name>\w+): (?P<description>.+) ' .
|
||||
'in (?P<path>.+|-) ' .
|
||||
'on line (?P<line>\d+), column (?P<column>\d+):$/',
|
||||
$line,
|
||||
$matches);
|
||||
|
||||
if ($match) {
|
||||
switch ($matches['name']) {
|
||||
case 'RuntimeError':
|
||||
$code = self::LINT_RUNTIME_ERROR;
|
||||
break;
|
||||
|
||||
case 'ArgumentError':
|
||||
$code = self::LINT_ARGUMENT_ERROR;
|
||||
break;
|
||||
|
||||
case 'FileError':
|
||||
$code = self::LINT_FILE_ERROR;
|
||||
break;
|
||||
|
||||
case 'NameError':
|
||||
$code = self::LINT_NAME_ERROR;
|
||||
break;
|
||||
|
||||
case 'OperationError':
|
||||
$code = self::LINT_OPERATION_ERROR;
|
||||
break;
|
||||
|
||||
case 'ParseError':
|
||||
$code = self::LINT_PARSE_ERROR;
|
||||
break;
|
||||
|
||||
case 'SyntaxError':
|
||||
$code = self::LINT_SYNTAX_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException(pht(
|
||||
'Unrecognized lint message code "%s".',
|
||||
$code));
|
||||
}
|
||||
|
||||
$code = $this->getLintCodeFromLinterConfigurationKey($matches['name']);
|
||||
|
||||
$message = new ArcanistLintMessage();
|
||||
$message->setPath($path);
|
||||
$message->setLine($matches['line']);
|
||||
$message->setChar($matches['column']);
|
||||
$message->setCode($this->getLintMessageFullCode($code));
|
||||
$message->setSeverity($this->getLintMessageSeverity($code));
|
||||
$message->setName($this->getLintMessageName($code));
|
||||
$message->setDescription(ucfirst($matches['description']));
|
||||
|
||||
$messages[] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
if ($err && !$messages) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
}
|
12
src/lint/linter/__tests__/ArcanistLesscLinterTestCase.php
Normal file
12
src/lint/linter/__tests__/ArcanistLesscLinterTestCase.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistLesscLinterTestCase
|
||||
extends ArcanistArcanistLinterTestCase {
|
||||
|
||||
public function testLesscLinter() {
|
||||
$this->executeTestsInDirectory(
|
||||
dirname(__FILE__).'/lessc/',
|
||||
new ArcanistLesscLinter());
|
||||
}
|
||||
|
||||
}
|
99
src/lint/linter/__tests__/lessc/colors.lint-test
Normal file
99
src/lint/linter/__tests__/lessc/colors.lint-test
Normal file
|
@ -0,0 +1,99 @@
|
|||
#yelow {
|
||||
#short {
|
||||
color: #fea;
|
||||
}
|
||||
#long {
|
||||
color: #ffeeaa;
|
||||
}
|
||||
#rgba {
|
||||
color: rgba(255, 238, 170, 0.1);
|
||||
}
|
||||
#argb {
|
||||
color: argb(rgba(255, 238, 170, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
#blue {
|
||||
#short {
|
||||
color: #00f;
|
||||
}
|
||||
#long {
|
||||
color: #0000ff;
|
||||
}
|
||||
#rgba {
|
||||
color: rgba(0, 0, 255, 0.1);
|
||||
}
|
||||
#argb {
|
||||
color: argb(rgba(0, 0, 255, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
#alpha #hsla {
|
||||
color: hsla(11, 20%, 20%, 0.6);
|
||||
}
|
||||
|
||||
#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); }
|
||||
}
|
||||
|
||||
#grey {
|
||||
color: rgb(200, 200, 200);
|
||||
}
|
||||
|
||||
#333333 {
|
||||
color: rgb(20%, 20%, 20%);
|
||||
}
|
||||
|
||||
#808080 {
|
||||
color: hsl(50, 0%, 50%);
|
||||
}
|
||||
|
||||
#00ff00 {
|
||||
color: hsl(120, 100%, 50%);
|
||||
}
|
||||
|
||||
.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%);
|
||||
}
|
||||
~~~~~~~~~~
|
84
src/lint/linter/__tests__/lessc/comments.lint-test
Normal file
84
src/lint/linter/__tests__/lessc/comments.lint-test
Normal file
|
@ -0,0 +1,84 @@
|
|||
/******************\
|
||||
* *
|
||||
* Comment Header *
|
||||
* *
|
||||
\******************/
|
||||
|
||||
/*
|
||||
|
||||
Comment
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Comment Test
|
||||
*
|
||||
* - cloudhead (http://cloudhead.net)
|
||||
*
|
||||
*/
|
||||
|
||||
////////////////
|
||||
@var: "content";
|
||||
////////////////
|
||||
|
||||
/* Colors
|
||||
* ------
|
||||
* #EDF8FC (background blue)
|
||||
* #166C89 (darkest blue)
|
||||
*
|
||||
* Text:
|
||||
* #333 (standard text) // A comment within a comment!
|
||||
* #1F9EC9 (standard link)
|
||||
*
|
||||
*/
|
||||
|
||||
/* @group Variables
|
||||
------------------- */
|
||||
#comments /* boo *//* boo again*/,
|
||||
//.commented_out1
|
||||
//.commented_out2
|
||||
//.commented_out3
|
||||
.comments //end of comments1
|
||||
//end of comments2
|
||||
{
|
||||
/**/ // An empty comment
|
||||
color: red; /* A C-style comment */ /* A C-style comment */
|
||||
background-color: orange; // A little comment
|
||||
font-size: 12px;
|
||||
|
||||
/* lost comment */ content: @var;
|
||||
|
||||
border: 1px solid black;
|
||||
|
||||
// padding & margin //
|
||||
padding: 0; // }{ '"
|
||||
margin: 2em;
|
||||
} //
|
||||
|
||||
/* commented out
|
||||
#more-comments {
|
||||
color: grey;
|
||||
}
|
||||
*/
|
||||
|
||||
.selector /* .with */, .lots, /* of */ .comments {
|
||||
color: grey, /* blue */ orange;
|
||||
-webkit-border-radius: 2px /* webkit only */;
|
||||
-moz-border-radius: (2px * 4) /* moz only with operation */;
|
||||
}
|
||||
|
||||
.mixin_def_with_colors(@a: white, // in
|
||||
@b: 1px //put in @b - causes problems! --->
|
||||
) // the
|
||||
when (@a = white) {
|
||||
.test {
|
||||
color: @b;
|
||||
}
|
||||
}
|
||||
.mixin_def_with_colors();
|
||||
|
||||
#last { color: blue }
|
||||
//
|
||||
|
||||
/* *//* { *//* *//* *//* */#div { color:#A33; }/* } */
|
||||
~~~~~~~~~~
|
130
src/lint/linter/__tests__/lessc/css-3.lint-test
Normal file
130
src/lint/linter/__tests__/lessc/css-3.lint-test
Normal file
|
@ -0,0 +1,130 @@
|
|||
.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=32]:not(1) {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div#id.class[a=1][b=2].class:not(1) {
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul.comma > li:not(:only-child)::after {
|
||||
color: white;
|
||||
}
|
||||
|
||||
ol.comma > li:nth-last-child(2)::after {
|
||||
color: white;
|
||||
}
|
||||
|
||||
li:nth-child(4n+1),
|
||||
li:nth-child(-5n),
|
||||
li:nth-child(-n+2) {
|
||||
color: white;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
.units {
|
||||
font: 1.2rem/2rem;
|
||||
font: 8vw/9vw;
|
||||
font: 10vh/12vh;
|
||||
font: 12vm/15vm;
|
||||
font: 12vmin/15vmin;
|
||||
font: 1.2ch/1.5ch;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
@namespace foo url(http://www.example.com);
|
||||
|
||||
foo|h1 { color: blue; }
|
||||
foo|* { color: yellow; }
|
||||
|h1 { color: red; }
|
||||
*|h1 { color: green; }
|
||||
h1 { color: green; }
|
||||
.upper-test {
|
||||
UpperCaseProperties: allowed;
|
||||
}
|
||||
@host {
|
||||
div {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
::distributed(input::placeholder) {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
.shadow ^ .dom,
|
||||
body ^^ .shadow {
|
||||
display: done;
|
||||
}
|
||||
~~~~~~~~~~
|
34
src/lint/linter/__tests__/lessc/css-escapes.lint-test
Normal file
34
src/lint/linter/__tests__/lessc/css-escapes.lint-test
Normal file
|
@ -0,0 +1,34 @@
|
|||
@ugly: fuchsia;
|
||||
|
||||
.escape\|random\|char {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.mixin\!tUp {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// class="404"
|
||||
.\34 04 {
|
||||
background: red;
|
||||
|
||||
strong {
|
||||
color: @ugly;
|
||||
.mixin\!tUp;
|
||||
}
|
||||
}
|
||||
|
||||
.trailingTest\+ {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */
|
||||
\62\6c\6f \63 \6B \0071 \000075o\74 e {
|
||||
color: silver;
|
||||
}
|
||||
|
||||
[ng\:cloak],
|
||||
ng\:form {
|
||||
display: none;
|
||||
}
|
||||
~~~~~~~~~~
|
65
src/lint/linter/__tests__/lessc/css-guards.lint-test
Normal file
65
src/lint/linter/__tests__/lessc/css-guards.lint-test
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
.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 guards at the point of execution
|
||||
.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 {
|
||||
color: black;
|
||||
}
|
||||
&:hover {
|
||||
color: pink;
|
||||
}
|
||||
.hideme when (@b = 1) {
|
||||
color: green;
|
||||
}
|
||||
& when (@b = 1) {
|
||||
hideme: green;
|
||||
}
|
||||
}
|
||||
|
||||
.hideme when (@b = 1) {
|
||||
.test {
|
||||
color: black;
|
||||
}
|
||||
&:hover {
|
||||
color: pink;
|
||||
}
|
||||
.hideme when (@b = 1) {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
& when (@b = 1) {
|
||||
.hideme {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
109
src/lint/linter/__tests__/lessc/css.lint-test
Normal file
109
src/lint/linter/__tests__/lessc/css.lint-test
Normal file
|
@ -0,0 +1,109 @@
|
|||
@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;
|
||||
}
|
||||
~~~~~~~~~~
|
104
src/lint/linter/__tests__/lessc/detached-rulesets.lint-test
Normal file
104
src/lint/linter/__tests__/lessc/detached-rulesets.lint-test
Normal file
|
@ -0,0 +1,104 @@
|
|||
@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();
|
||||
}
|
||||
~~~~~~~~~~
|
1
src/lint/linter/__tests__/lessc/empty.lint-test
Normal file
1
src/lint/linter/__tests__/lessc/empty.lint-test
Normal file
|
@ -0,0 +1 @@
|
|||
~~~~~~~~~~
|
|
@ -0,0 +1,8 @@
|
|||
.a {
|
||||
error: (1px + 3em);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
||||
~~~~~~~~~~
|
||||
~~~~~~~~~~
|
||||
{"config":{"lessc.strict-units":true}}
|
|
@ -0,0 +1,8 @@
|
|||
.a {
|
||||
error: ((1px * 2px) + (3em * 3px));
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
||||
~~~~~~~~~~
|
||||
~~~~~~~~~~
|
||||
{"config":{"lessc.strict-units":true}}
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
@keyframes @name {
|
||||
50% {width: 20px;}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:12
|
|
@ -0,0 +1,3 @@
|
|||
@@demo: "hi";
|
||||
~~~~~~~~~~
|
||||
error:1:1
|
|
@ -0,0 +1,5 @@
|
|||
.test {
|
||||
color: color("NOT A COLOR");
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:10
|
|
@ -0,0 +1,3 @@
|
|||
#gaga /* Comment */ span { color: red }
|
||||
~~~~~~~~~~
|
||||
error:1:21
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
selector when (default()) {
|
||||
color: red;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:16
|
|
@ -0,0 +1,8 @@
|
|||
@a: {
|
||||
b: 1;
|
||||
};
|
||||
.a {
|
||||
a: @a;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:5:3
|
|
@ -0,0 +1,8 @@
|
|||
@a: {
|
||||
b: 1;
|
||||
};
|
||||
.a {
|
||||
a: @a();
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:5:3
|
|
@ -0,0 +1,6 @@
|
|||
@a: {
|
||||
b: 1;
|
||||
};
|
||||
@a();
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
|
@ -0,0 +1,7 @@
|
|||
.mixin-definition(@a: {
|
||||
b: 1;
|
||||
}) {
|
||||
@a();
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:18
|
|
@ -0,0 +1,6 @@
|
|||
.mixin-definition(@b) {
|
||||
@a();
|
||||
}
|
||||
.mixin-definition({color: red;});
|
||||
~~~~~~~~~~
|
||||
error:4:1
|
|
@ -0,0 +1,7 @@
|
|||
.a {
|
||||
b: {
|
||||
color: red;
|
||||
};
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
|
@ -0,0 +1,8 @@
|
|||
.a {
|
||||
error: (1px / 3em);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
||||
~~~~~~~~~~
|
||||
~~~~~~~~~~
|
||||
{"config":{"lessc.strict-units":true}}
|
|
@ -0,0 +1,5 @@
|
|||
:extend(.a all) {
|
||||
property: red;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:17
|
|
@ -0,0 +1,5 @@
|
|||
.a:extend(.b all).c {
|
||||
property: red;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:21
|
|
@ -0,0 +1,8 @@
|
|||
.a {
|
||||
color: green;
|
||||
// tests line number for import reference is correct
|
||||
}
|
||||
|
||||
@import "file-does-not-exist.less";
|
||||
~~~~~~~~~~
|
||||
error:6:1
|
|
@ -0,0 +1,3 @@
|
|||
@import "this-statement-is-invalid.less"
|
||||
~~~~~~~~~~
|
||||
error:1:1
|
|
@ -0,0 +1,5 @@
|
|||
.scope {
|
||||
var: `this.foo.toJS()`;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:27
|
|
@ -0,0 +1,5 @@
|
|||
.scope {
|
||||
@a: `@{b}`;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:15
|
|
@ -0,0 +1,8 @@
|
|||
.mixin(@a : 4, @b : 3, @c: 2) {
|
||||
will: fail;
|
||||
}
|
||||
.mixin-test {
|
||||
.mixin(@a: 5; @b: 6, @c: 7);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:5:30
|
|
@ -0,0 +1,8 @@
|
|||
.mixin(@a : 4, @b : 3, @c: 2) {
|
||||
will: fail;
|
||||
}
|
||||
.mixin-test {
|
||||
.mixin(@a: 5, @b: 6; @c: 7);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:5:26
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
.error-is-further-on() {
|
||||
}
|
||||
|
||||
.pad-here-to-reproduce-error-in() {
|
||||
}
|
||||
|
||||
.the-import-subfolder-test() {
|
||||
}
|
||||
|
||||
.mixin-not-defined();
|
||||
~~~~~~~~~~
|
||||
error:11:1
|
|
@ -0,0 +1,8 @@
|
|||
@saxofon:trumpete;
|
||||
|
||||
.mixin(saxofon) {
|
||||
}
|
||||
|
||||
.mixin(@saxofon);
|
||||
~~~~~~~~~~
|
||||
error:6:1
|
|
@ -0,0 +1,8 @@
|
|||
@saxofon:trumpete;
|
||||
|
||||
.mixin(@a, @b) {
|
||||
}
|
||||
|
||||
.mixin(@a: @saxofon);
|
||||
~~~~~~~~~~
|
||||
error:6:1
|
|
@ -0,0 +1,11 @@
|
|||
.something {
|
||||
& {
|
||||
.a {value: a}
|
||||
}
|
||||
|
||||
& {
|
||||
.b {.a} // was Err. before 1.6.2
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:7:13
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
guard-default-func-conflict {
|
||||
.m(@x, 1) {}
|
||||
.m(@x, 2) when (default()) {}
|
||||
.m(@x, 2) when (default()) {}
|
||||
|
||||
.m(1, 1);
|
||||
.m(1, 2);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:8:5
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
guard-default-func-conflict {
|
||||
.m(1) {}
|
||||
.m(@x) when not(default()) {}
|
||||
.m(@x) when (@x = 3) and (default()) {}
|
||||
|
||||
.m(2);
|
||||
.m(3);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:8:5
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
guard-default-func-conflict {
|
||||
.m(1) {}
|
||||
.m(@x) when not(default()) {}
|
||||
.m(@x) when not(default()) {}
|
||||
|
||||
.m(1);
|
||||
.m(2);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:8:5
|
|
@ -0,0 +1,6 @@
|
|||
@ie8: true;
|
||||
.a when (@ie8 = true),
|
||||
.b {
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:3:1
|
|
@ -0,0 +1,6 @@
|
|||
@ie8: true;
|
||||
.a,
|
||||
.b when (@ie8 = true) {
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:3:23
|
|
@ -0,0 +1,12 @@
|
|||
/* Test */
|
||||
#blah {
|
||||
// blah
|
||||
}
|
||||
.a {
|
||||
error: (1px * 1em);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:6:3
|
||||
~~~~~~~~~~
|
||||
~~~~~~~~~~
|
||||
{"config":{"lessc.strict-units":true}}
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
something: (12 (13 + 5 -23) + 5);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:18
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
something: (12 * (13 + 5 -23));
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:28
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
something: (12 + (13 + 10 -23));
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:29
|
|
@ -0,0 +1,6 @@
|
|||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:4:1
|
|
@ -0,0 +1,7 @@
|
|||
@media (extra: bracket)) {
|
||||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:24
|
|
@ -0,0 +1,4 @@
|
|||
body {
|
||||
background-color: #fff;
|
||||
~~~~~~~~~~
|
||||
error:1:6
|
|
@ -0,0 +1,7 @@
|
|||
@media (missing: bracket {
|
||||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:8
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
error: calc(1 %);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
|
@ -0,0 +1,5 @@
|
|||
a {
|
||||
* : 1;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:5
|
|
@ -0,0 +1,5 @@
|
|||
.test {
|
||||
display/*/: block; /*sorry for IE5*/
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
|
@ -0,0 +1,6 @@
|
|||
.a() {
|
||||
prop:1;
|
||||
}
|
||||
.a();
|
||||
~~~~~~~~~~
|
||||
error:2:3
|
|
@ -0,0 +1,6 @@
|
|||
prop:1;
|
||||
.a {
|
||||
prop:1;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:1:1
|
|
@ -0,0 +1,3 @@
|
|||
a {outline-@{color}: green}
|
||||
~~~~~~~~~~
|
||||
error:1:12
|
|
@ -0,0 +1,3 @@
|
|||
@bodyColor: darken(@bodyColor, 30%);
|
||||
~~~~~~~~~~
|
||||
error:1:20
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
a: svg-gradient(horizontal, black, white);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:6
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
a: svg-gradient(to bottom, black, orange, 45%, white);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:6
|
|
@ -0,0 +1,5 @@
|
|||
.a {
|
||||
a: svg-gradient(black, orange);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:6
|
|
@ -0,0 +1,8 @@
|
|||
.a {
|
||||
font-size: unit(80/16,rem);
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:2:14
|
||||
~~~~~~~~~~
|
||||
~~~~~~~~~~
|
||||
{"config":{"lessc.strict-math":true}}
|
92
src/lint/linter/__tests__/lessc/extend-chaining.lint-test
Normal file
92
src/lint/linter/__tests__/lessc/extend-chaining.lint-test
Normal file
|
@ -0,0 +1,92 @@
|
|||
//very simple chaining
|
||||
.a {
|
||||
color: black;
|
||||
}
|
||||
.b:extend(.a) {}
|
||||
.c:extend(.b) {}
|
||||
|
||||
//very simple chaining, ordering not important
|
||||
|
||||
.d:extend(.e) {}
|
||||
.e:extend(.f) {}
|
||||
.f {
|
||||
color: black;
|
||||
}
|
||||
|
||||
//extend with all
|
||||
|
||||
.g.h {
|
||||
color: black;
|
||||
}
|
||||
.i.j:extend(.g all) {
|
||||
color: white;
|
||||
}
|
||||
.k:extend(.i all) {}
|
||||
|
||||
//extend multi-chaining
|
||||
|
||||
.l {
|
||||
color: black;
|
||||
}
|
||||
.m:extend(.l){}
|
||||
.n:extend(.m){}
|
||||
.o:extend(.n){}
|
||||
.p:extend(.o){}
|
||||
.q:extend(.p){}
|
||||
.r:extend(.q){}
|
||||
.s:extend(.r){}
|
||||
.t:extend(.s){}
|
||||
|
||||
// self referencing is ignored
|
||||
|
||||
.u {color: black;}
|
||||
.v.u.v:extend(.u all){}
|
||||
|
||||
// circular reference because the new extend product will match the existing extend
|
||||
|
||||
.w:extend(.w) {color: black;}
|
||||
.v.w.v:extend(.w all){}
|
||||
|
||||
// classic circular references
|
||||
|
||||
.x:extend(.z) {
|
||||
color: x;
|
||||
}
|
||||
.y:extend(.x) {
|
||||
color: y;
|
||||
}
|
||||
.z:extend(.y) {
|
||||
color: z;
|
||||
}
|
||||
|
||||
//very simple chaining, but with the extend inside the ruleset
|
||||
.va {
|
||||
color: black;
|
||||
}
|
||||
.vb {
|
||||
&:extend(.va);
|
||||
color: white;
|
||||
}
|
||||
.vc {
|
||||
&:extend(.vb);
|
||||
}
|
||||
|
||||
// media queries - dont extend outside, do extend inside
|
||||
|
||||
@media tv {
|
||||
.ma:extend(.a,.b,.c,.d,.e,.f,.g,.h,.i,.j,.k,.l,.m,.n,.o,.p,.q,.r,.s,.t,.u,.v,.w,.x,.y,.z,.md) {
|
||||
color: black;
|
||||
}
|
||||
.md {
|
||||
color: white;
|
||||
}
|
||||
@media plasma {
|
||||
.me, .mf {
|
||||
&:extend(.mb,.md);
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mb:extend(.ma) {};
|
||||
.mc:extend(.mb) {};
|
||||
~~~~~~~~~~
|
20
src/lint/linter/__tests__/lessc/extend-clearfix.lint-test
Normal file
20
src/lint/linter/__tests__/lessc/extend-clearfix.lint-test
Normal file
|
@ -0,0 +1,20 @@
|
|||
.clearfix {
|
||||
*zoom: 1;
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.foo {
|
||||
&:extend(.clearfix all);
|
||||
color: red;
|
||||
}
|
||||
|
||||
.bar {
|
||||
&:extend(.clearfix all);
|
||||
color: blue;
|
||||
}
|
||||
~~~~~~~~~~
|
47
src/lint/linter/__tests__/lessc/extend-exact.lint-test
Normal file
47
src/lint/linter/__tests__/lessc/extend-exact.lint-test
Normal file
|
@ -0,0 +1,47 @@
|
|||
.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) {}
|
||||
~~~~~~~~~~
|
25
src/lint/linter/__tests__/lessc/extend-media.lint-test
Normal file
25
src/lint/linter/__tests__/lessc/extend-media.lint-test
Normal file
|
@ -0,0 +1,25 @@
|
|||
.ext1 .ext2 {
|
||||
background: black;
|
||||
}
|
||||
|
||||
@media tv {
|
||||
.ext1 .ext3 {
|
||||
color: white;
|
||||
}
|
||||
.tv-lowres :extend(.ext1 all) {
|
||||
background: blue;
|
||||
}
|
||||
@media hires {
|
||||
.ext1 .ext4 {
|
||||
color: green;
|
||||
}
|
||||
.tv-hires :extend(.ext1 all) {
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.all:extend(.ext1 all) {
|
||||
|
||||
}
|
||||
~~~~~~~~~~
|
66
src/lint/linter/__tests__/lessc/extend-nest.lint-test
Normal file
66
src/lint/linter/__tests__/lessc/extend-nest.lint-test
Normal file
|
@ -0,0 +1,66 @@
|
|||
.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: white;
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
~~~~~~~~~~
|
100
src/lint/linter/__tests__/lessc/extend-selector.lint-test
Normal file
100
src/lint/linter/__tests__/lessc/extend-selector.lint-test
Normal file
|
@ -0,0 +1,100 @@
|
|||
.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 );
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
82
src/lint/linter/__tests__/lessc/extend.lint-test
Normal file
82
src/lint/linter/__tests__/lessc/extend.lint-test
Normal file
|
@ -0,0 +1,82 @@
|
|||
.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) {}
|
||||
~~~~~~~~~~
|
134
src/lint/linter/__tests__/lessc/extract-and-length.lint-test
Normal file
134
src/lint/linter/__tests__/lessc/extract-and-length.lint-test
Normal file
|
@ -0,0 +1,134 @@
|
|||
|
||||
// simple array/list:
|
||||
|
||||
.multiunit {
|
||||
@v: abc "abc" 1 1px 1% #123;
|
||||
length: length(@v);
|
||||
extract: extract(@v, 1) extract(@v, 2) extract(@v, 3) extract(@v, 4) extract(@v, 5) extract(@v, 6);
|
||||
}
|
||||
|
||||
.incorrect-index {
|
||||
@v1: a b c;
|
||||
@v2: a, b, c;
|
||||
v1: extract(@v1, 5);
|
||||
v2: extract(@v2, -2);
|
||||
}
|
||||
|
||||
.scalar {
|
||||
@var: variable;
|
||||
var-value: extract(@var, 1);
|
||||
var-length: length(@var);
|
||||
ill-index: extract(@var, 2);
|
||||
|
||||
name-value: extract(name, 1);
|
||||
string-value: extract("string", 1);
|
||||
number-value: extract(12345678, 1);
|
||||
color-value: extract(blue, 1);
|
||||
rgba-value: extract(rgba(80, 160, 240, 0.67), 1);
|
||||
empty-value: extract(~'', 1);
|
||||
|
||||
name-length: length(name);
|
||||
string-length: length("string");
|
||||
number-length: length(12345678);
|
||||
color-length: length(blue);
|
||||
rgba-length: length(rgba(80, 160, 240, 0.67));
|
||||
empty-length: length(~'');
|
||||
}
|
||||
|
||||
.mixin-arguments {
|
||||
.mixin-args(a b c d);
|
||||
.mixin-args(a, b, c, d);
|
||||
.mixin-args(1; 2; 3; 4);
|
||||
}
|
||||
|
||||
.mixin-args(@value) {
|
||||
&-1 {
|
||||
length: length(@value);
|
||||
extract: extract(@value, 3) ~"|" extract(@value, 2) ~"|" extract(@value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.mixin-args(...) {
|
||||
&-2 {
|
||||
length: length(@arguments);
|
||||
extract: extract(@arguments, 3) ~"|" extract(@arguments, 2) ~"|" extract(@arguments, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.mixin-args(@values...) {
|
||||
&-3 {
|
||||
length: length(@values);
|
||||
extract: extract(@values, 3) ~"|" extract(@values, 2) ~"|" extract(@values, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.mixin-args(@head, @tail...) {
|
||||
&-4 {
|
||||
length: length(@tail);
|
||||
extract: extract(@tail, 2) ~"|" extract(@tail, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// "multidimensional" array/list
|
||||
|
||||
.md-space-comma {
|
||||
@v: a b c, 1 2 3, "x" "y" "z";
|
||||
length-1: length(@v);
|
||||
extract-1: extract(@v, 2);
|
||||
length-2: length(extract(@v, 2));
|
||||
extract-2: extract(extract(@v, 2), 2);
|
||||
|
||||
&-as-args {.mixin-args(a b c, 1 2 3, "x" "y" "z")}
|
||||
}
|
||||
|
||||
.md-cat-space-comma {
|
||||
@a: a b c;
|
||||
@b: 1 2 3;
|
||||
@c: "x" "y" "z";
|
||||
@v: @a, @b, @c;
|
||||
length-1: length(@v);
|
||||
extract-1: extract(@v, 2);
|
||||
length-2: length(extract(@v, 2));
|
||||
extract-2: extract(extract(@v, 2), 2);
|
||||
|
||||
&-as-args {.mixin-args(@a, @b, @c)}
|
||||
}
|
||||
|
||||
.md-cat-comma-space {
|
||||
@a: a, b, c;
|
||||
@b: 1, 2, 3;
|
||||
@c: "x", "y", "z";
|
||||
@v: @a @b @c;
|
||||
length-1: length(@v);
|
||||
extract-1: extract(@v, 2);
|
||||
length-2: length(extract(@v, 2));
|
||||
extract-2: extract(extract(@v, 2), 2);
|
||||
|
||||
&-as-args {.mixin-args(@a @b @c)}
|
||||
}
|
||||
|
||||
.md-3D {
|
||||
@a: a b c d, 1 2 3 4;
|
||||
@b: 5 6 7 8, e f g h;
|
||||
.3D(@a, @b);
|
||||
|
||||
.3D(...) {
|
||||
|
||||
@v1: @arguments;
|
||||
length-1: length(@v1);
|
||||
extract-1: extract(@v1, 1);
|
||||
|
||||
@v2: extract(@v1, 2);
|
||||
length-2: length(@v2);
|
||||
extract-2: extract(@v2, 1);
|
||||
|
||||
@v3: extract(@v2, 1);
|
||||
length-3: length(@v3);
|
||||
extract-3: extract(@v3, 3);
|
||||
|
||||
@v4: extract(@v3, 4);
|
||||
length-4: length(@v4);
|
||||
extract-4: extract(@v4, 1);
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
169
src/lint/linter/__tests__/lessc/functions.lint-test
Normal file
169
src/lint/linter/__tests__/lessc/functions.lint-test
Normal file
|
@ -0,0 +1,169 @@
|
|||
#functions {
|
||||
@var: 10;
|
||||
@colors: #000, #fff;
|
||||
color: _color("evil red"); // #660000
|
||||
width: increment(15);
|
||||
height: undefined("self");
|
||||
border-width: add(2, 3);
|
||||
variable: increment(@var);
|
||||
background: linear-gradient(@colors);
|
||||
}
|
||||
|
||||
#built-in {
|
||||
@r: 32;
|
||||
escaped: e("-Some::weird(#thing, y)");
|
||||
lighten: lighten(#ff0000, 40%);
|
||||
darken: darken(#ff0000, 40%);
|
||||
saturate: saturate(#29332f, 20%);
|
||||
desaturate: desaturate(#203c31, 20%);
|
||||
greyscale: greyscale(#203c31);
|
||||
hsl-clamp: hsl(380, 150%, 150%);
|
||||
spin-p: spin(hsl(340, 50%, 50%), 40);
|
||||
spin-n: spin(hsl(30, 50%, 50%), -40);
|
||||
luma-white: luma(#fff);
|
||||
luma-black: luma(#000);
|
||||
luma-black-alpha: luma(rgba(0,0,0,0.5));
|
||||
luma-red: luma(#ff0000);
|
||||
luma-green: luma(#00ff00);
|
||||
luma-blue: luma(#0000ff);
|
||||
luma-yellow: luma(#ffff00);
|
||||
luma-cyan: luma(#00ffff);
|
||||
luma-white-alpha: luma(rgba(255,255,255,0.5));
|
||||
contrast-filter: contrast(30%);
|
||||
saturate-filter: saturate(5%);
|
||||
contrast-white: contrast(#fff);
|
||||
contrast-black: contrast(#000);
|
||||
contrast-red: contrast(#ff0000);
|
||||
contrast-green: contrast(#00ff00);
|
||||
contrast-blue: contrast(#0000ff);
|
||||
contrast-yellow: contrast(#ffff00);
|
||||
contrast-cyan: contrast(#00ffff);
|
||||
contrast-light: contrast(#fff, #111111, #eeeeee);
|
||||
contrast-dark: contrast(#000, #111111, #eeeeee);
|
||||
contrast-wrongorder: contrast(#fff, #eeeeee, #111111, 0.5);
|
||||
contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5);
|
||||
contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5);
|
||||
contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6);
|
||||
contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1);
|
||||
contrast-light-thresh-per: contrast(#fff, #111111, #eeeeee, 50%);
|
||||
contrast-dark-thresh-per: contrast(#000, #111111, #eeeeee, 50%);
|
||||
contrast-high-thresh-per: contrast(#555, #111111, #eeeeee, 60%);
|
||||
contrast-low-thresh-per: contrast(#555, #111111, #eeeeee, 10%);
|
||||
replace: replace("Hello, Mars.", "Mars\.", "World!");
|
||||
replace-captured: replace("This is a string.", "(string)\.$", "new $1.");
|
||||
replace-with-flags: replace("One + one = 4", "one", "2", "gi");
|
||||
replace-single-quoted: replace('foo-1', "1", "2");
|
||||
replace-escaped-string: replace(~"bar-1", "1", "2");
|
||||
replace-keyword: replace(baz-1, "1", "2");
|
||||
format: %("rgb(%d, %d, %d)", @r, 128, 64);
|
||||
format-string: %("hello %s", "world");
|
||||
format-multiple: %("hello %s %d", "earth", 2);
|
||||
format-url-encode: %("red is %A", #ff0000);
|
||||
format-single-quoted: %('hello %s', "single world");
|
||||
format-escaped-string: %(~"hello %s", "escaped world");
|
||||
eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
|
||||
|
||||
unitless: unit(12px);
|
||||
unit: unit((13px + 1px), em);
|
||||
unitpercentage: unit(100, %);
|
||||
|
||||
get-unit: get-unit(10px);
|
||||
get-unit-empty: get-unit(10);
|
||||
|
||||
hue: hue(hsl(98, 12%, 95%));
|
||||
saturation: saturation(hsl(98, 12%, 95%));
|
||||
lightness: lightness(hsl(98, 12%, 95%));
|
||||
hsvhue: hsvhue(hsv(98, 12%, 95%));
|
||||
hsvsaturation: hsvsaturation(hsv(98, 12%, 95%));
|
||||
hsvvalue: hsvvalue(hsv(98, 12%, 95%));
|
||||
red: red(#f00);
|
||||
green: green(#0f0);
|
||||
blue: blue(#00f);
|
||||
rounded: round((@r/3));
|
||||
rounded-two: round((@r/3), 2);
|
||||
roundedpx: round((10px / 3));
|
||||
roundedpx-three: round((10px / 3), 3);
|
||||
rounded-percentage: round(10.2%);
|
||||
ceil: ceil(10.1px);
|
||||
floor: floor(12.9px);
|
||||
sqrt: sqrt(25px);
|
||||
pi: pi();
|
||||
mod: mod(13m, 11cm); // could take into account units, doesn't at the moment
|
||||
abs: abs(-4%);
|
||||
tan: tan(42deg);
|
||||
sin: sin(10deg);
|
||||
cos: cos(12);
|
||||
atan: atan(tan(0.1rad));
|
||||
atan: convert(acos(cos(34deg)), deg);
|
||||
atan: convert(acos(cos(50grad)), deg);
|
||||
pow: pow(8px, 2);
|
||||
pow: pow(4, 3);
|
||||
pow: pow(3, 3em);
|
||||
min: min(0);
|
||||
min: min(6, 5);
|
||||
min: min(1pt, 3pt);
|
||||
min: min(1cm, 3mm);
|
||||
max: max(1, 3);
|
||||
max: max(3em, 1em, 2em, 5em);
|
||||
percentage: percentage((10px / 50));
|
||||
color: color("#ff0011");
|
||||
tint: tint(#777777, 13);
|
||||
tint-full: tint(#777777, 100);
|
||||
tint-percent: tint(#777777, 13%);
|
||||
tint-negative: tint(#777777, -13%);
|
||||
shade: shade(#777777, 13);
|
||||
shade-full: shade(#777777, 100);
|
||||
shade-percent: shade(#777777, 13%);
|
||||
shade-negative: shade(#777777, -13%);
|
||||
|
||||
fade-out: fadeOut(red, 5%); // support fadeOut and fadeout
|
||||
fade-in: fadein(fadeout(red, 10%), 5%);
|
||||
|
||||
hsv: hsv(5, 50%, 30%);
|
||||
hsva: hsva(3, 50%, 30%, 0.2);
|
||||
|
||||
mix: mix(#ff0000, #ffff00, 80);
|
||||
mix-0: mix(#ff0000, #ffff00, 0);
|
||||
mix-100: mix(#ff0000, #ffff00, 100);
|
||||
mix-weightless: mix(#ff0000, #ffff00);
|
||||
mixt: mix(#ff0000, transparent);
|
||||
|
||||
.is-a {
|
||||
color: iscolor(#ddd);
|
||||
color1: iscolor(red);
|
||||
color2: iscolor(rgb(0, 0, 0));
|
||||
color3: iscolor(transparent);
|
||||
keyword: iskeyword(hello);
|
||||
number: isnumber(32);
|
||||
string: isstring("hello");
|
||||
pixel: ispixel(32px);
|
||||
percent: ispercentage(32%);
|
||||
em: isem(32em);
|
||||
cat: isunit(32cat, cat);
|
||||
}
|
||||
}
|
||||
|
||||
#alpha {
|
||||
alpha: darken(hsla(25, 50%, 50%, 0.6), 10%);
|
||||
alpha2: alpha(rgba(3, 4, 5, 0.5));
|
||||
alpha3: alpha(transparent);
|
||||
}
|
||||
|
||||
#blendmodes {
|
||||
multiply: multiply(#f60000, #f60000);
|
||||
screen: screen(#f60000, #0000f6);
|
||||
overlay: overlay(#f60000, #0000f6);
|
||||
softlight: softlight(#f60000, #ffffff);
|
||||
hardlight: hardlight(#f60000, #0000f6);
|
||||
difference: difference(#f60000, #0000f6);
|
||||
exclusion: exclusion(#f60000, #0000f6);
|
||||
average: average(#f60000, #0000f6);
|
||||
negation: negation(#f60000, #313131);
|
||||
}
|
||||
|
||||
#extract-and-length {
|
||||
@anon: A B C 1 2 3;
|
||||
extract: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1);
|
||||
length: length(@anon);
|
||||
}
|
||||
~~~~~~~~~~
|
16
src/lint/linter/__tests__/lessc/ie-filters.lint-test
Normal file
16
src/lint/linter/__tests__/lessc/ie-filters.lint-test
Normal file
|
@ -0,0 +1,16 @@
|
|||
@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);
|
||||
}
|
||||
~~~~~~~~~~
|
30
src/lint/linter/__tests__/lessc/javascript.lint-test
Normal file
30
src/lint/linter/__tests__/lessc/javascript.lint-test
Normal file
|
@ -0,0 +1,30 @@
|
|||
.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 {
|
||||
@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(', ')`;
|
||||
}
|
||||
~~~~~~~~~~
|
7
src/lint/linter/__tests__/lessc/lazy-eval.lint-test
Normal file
7
src/lint/linter/__tests__/lessc/lazy-eval.lint-test
Normal file
|
@ -0,0 +1,7 @@
|
|||
@var: @a;
|
||||
@a: 100%;
|
||||
|
||||
.lazy-eval {
|
||||
width: @var;
|
||||
}
|
||||
~~~~~~~~~~
|
235
src/lint/linter/__tests__/lessc/media.lint-test
Normal file
235
src/lint/linter/__tests__/lessc/media.lint-test
Normal file
|
@ -0,0 +1,235 @@
|
|||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
60
src/lint/linter/__tests__/lessc/merge.lint-test
Normal file
60
src/lint/linter/__tests__/lessc/merge.lint-test
Normal file
|
@ -0,0 +1,60 @@
|
|||
.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);
|
||||
}
|
||||
|
||||
.test1 {
|
||||
// Can merge values
|
||||
.first-transform();
|
||||
.second-transform();
|
||||
}
|
||||
.test2 {
|
||||
// Wont merge values without +: merge directive, for backwards compatibility with css
|
||||
.first-transform();
|
||||
.third-transform();
|
||||
}
|
||||
.test3 {
|
||||
// Wont merge values from two sources with different properties
|
||||
.fourth-transform();
|
||||
.first-background();
|
||||
}
|
||||
.test4 {
|
||||
// Wont merge values from sources that merked as !important, for backwards compatibility with css
|
||||
.first-transform();
|
||||
.fifth-transform();
|
||||
}
|
||||
.test5 {
|
||||
// Wont merge values from mixins that merked as !important, for backwards compatibility with css
|
||||
.first-transform();
|
||||
.second-transform() !important;
|
||||
}
|
||||
.test6 {
|
||||
// Ignores !merge if no peers found
|
||||
.second-transform();
|
||||
}
|
||||
|
||||
.test-interleaved {
|
||||
transform+: t1;
|
||||
background+: b1;
|
||||
transform+: t2;
|
||||
background+: b2, b3;
|
||||
transform+: t3;
|
||||
}
|
||||
~~~~~~~~~~
|
216
src/lint/linter/__tests__/lessc/mixins-args.lint-test
Normal file
216
src/lint/linter/__tests__/lessc/mixins-args.lint-test
Normal file
|
@ -0,0 +1,216 @@
|
|||
.mixin (@a: 1px, @b: 50%) {
|
||||
width: (@a * 5);
|
||||
height: (@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-parens {
|
||||
.mixin;
|
||||
}
|
||||
|
||||
.no-args {
|
||||
.mixin();
|
||||
}
|
||||
|
||||
.var-args {
|
||||
@var: 9;
|
||||
.mixin(@var, (@var * 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-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-calling-one-arg-mixin(@a) {
|
||||
}
|
||||
|
||||
.test-calling-one-arg-mixin(@a, @b, @rest...) {
|
||||
}
|
||||
|
||||
div {
|
||||
.test-calling-one-arg-mixin(1);
|
||||
}
|
||||
~~~~~~~~~~
|
27
src/lint/linter/__tests__/lessc/mixins-closure.lint-test
Normal file
27
src/lint/linter/__tests__/lessc/mixins-closure.lint-test
Normal file
|
@ -0,0 +1,27 @@
|
|||
.scope {
|
||||
@var: 99px;
|
||||
.mixin () {
|
||||
width: @var;
|
||||
}
|
||||
}
|
||||
|
||||
.class {
|
||||
.scope > .mixin;
|
||||
}
|
||||
|
||||
.overwrite {
|
||||
@var: 0px;
|
||||
.scope > .mixin;
|
||||
}
|
||||
|
||||
.nested {
|
||||
@var: 5px;
|
||||
.mixin () {
|
||||
width: @var;
|
||||
}
|
||||
.class {
|
||||
@var: 10px;
|
||||
.mixin;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
|
@ -0,0 +1,196 @@
|
|||
|
||||
// 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-ambiguos-2 {
|
||||
.m(@x) {case: 1}
|
||||
.m(@x) when (default()) {default: @x}
|
||||
.m(@x) when not(default()) {not-default: @x}
|
||||
|
||||
.m(2);
|
||||
}
|
||||
|
||||
guard-default-not-ambiguos-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) {1: no condition}}
|
||||
.s2() {.m(@v) when (@v) {2: when true}}
|
||||
.s3() {.m(@v) when (default()) {3: when default}}
|
||||
|
||||
&-3 {
|
||||
.s2();
|
||||
.s3();
|
||||
.m(false);
|
||||
}
|
||||
|
||||
&-1 {
|
||||
.s1();
|
||||
.s3();
|
||||
.m(false);
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
154
src/lint/linter/__tests__/lessc/mixins-guards.lint-test
Normal file
154
src/lint/linter/__tests__/lessc/mixins-guards.lint-test
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
// Stacking, functions..
|
||||
|
||||
.light (@a) when (lightness(@a) > 50%) {
|
||||
color: white;
|
||||
}
|
||||
.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 (@a) when (@a) {
|
||||
content: "true.";
|
||||
}
|
||||
.test (@a) when not (@a) {
|
||||
content: "false.";
|
||||
}
|
||||
|
||||
.test1 { .test(true) }
|
||||
.test2 { .test(false) }
|
||||
.test3 { .test(1) }
|
||||
.test4 { .test(boo) }
|
||||
.test5 { .test("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: is theme1; }
|
||||
.stringguard(@str) when not ("theme2" = @str) { content: is not theme2; }
|
||||
.stringguard(@str) when (~"theme1" = @str) { content: is theme1 no quotes; }
|
||||
.stringguard(@str) {}
|
||||
.stringguardtest {
|
||||
.stringguard("theme1");
|
||||
.stringguard("theme2");
|
||||
.stringguard(theme1);
|
||||
}
|
||||
|
||||
.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();
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
26
src/lint/linter/__tests__/lessc/mixins-important.lint-test
Normal file
26
src/lint/linter/__tests__/lessc/mixins-important.lint-test
Normal file
|
@ -0,0 +1,26 @@
|
|||
.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);
|
||||
}
|
||||
~~~~~~~~~~
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
@a1: foo;
|
||||
@a2: ~".foo";
|
||||
@a4: ~"#foo";
|
||||
|
||||
.@{a1} {
|
||||
a: 1;
|
||||
}
|
||||
|
||||
@{a2} {
|
||||
a: 2;
|
||||
}
|
||||
|
||||
#@{a1} {
|
||||
a: 3;
|
||||
}
|
||||
|
||||
@{a4} {
|
||||
a: 4;
|
||||
}
|
||||
|
||||
mi-test-a {
|
||||
.foo;
|
||||
#foo;
|
||||
}
|
||||
|
||||
.b .bb {
|
||||
&.@{a1}-xxx .yyy-@{a1}@{a4} {
|
||||
& @{a2}.bbb {
|
||||
b: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi-test-b {
|
||||
.b.bb.foo-xxx.yyy-foo#foo.foo.bbb;
|
||||
}
|
||||
|
||||
@c1: @a1;
|
||||
@c2: bar;
|
||||
@c3: baz;
|
||||
|
||||
#@{c1}-foo {
|
||||
> .@{c2} {
|
||||
.@{c3} {
|
||||
c: c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi-test-c {
|
||||
&-1 {#foo-foo;}
|
||||
&-2 {#foo-foo > .bar;}
|
||||
&-3 {#foo-foo > .bar.baz;}
|
||||
}
|
||||
|
||||
.Person(@name, @gender_) {
|
||||
.@{name} {
|
||||
@gender: @gender_;
|
||||
.sayGender() {
|
||||
gender: @gender;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi-test-d {
|
||||
.Person(person, "Male");
|
||||
.person.sayGender();
|
||||
}
|
||||
~~~~~~~~~~
|
37
src/lint/linter/__tests__/lessc/mixins-named-args.lint-test
Normal file
37
src/lint/linter/__tests__/lessc/mixins-named-args.lint-test
Normal file
|
@ -0,0 +1,37 @@
|
|||
.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);
|
||||
}
|
||||
~~~~~~~~~~
|
23
src/lint/linter/__tests__/lessc/mixins-nested.lint-test
Normal file
23
src/lint/linter/__tests__/lessc/mixins-nested.lint-test
Normal file
|
@ -0,0 +1,23 @@
|
|||
.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);
|
||||
}
|
||||
~~~~~~~~~~
|
103
src/lint/linter/__tests__/lessc/mixins-pattern.lint-test
Normal file
103
src/lint/linter/__tests__/lessc/mixins-pattern.lint-test
Normal file
|
@ -0,0 +1,103 @@
|
|||
.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);
|
||||
}
|
||||
~~~~~~~~~~
|
142
src/lint/linter/__tests__/lessc/mixins.lint-test
Normal file
142
src/lint/linter/__tests__/lessc/mixins.lint-test
Normal file
|
@ -0,0 +1,142 @@
|
|||
.mixin { border: 1px solid black; }
|
||||
.mixout { border-color: orange; }
|
||||
.borders { border-style: dashed; }
|
||||
|
||||
#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: white;
|
||||
.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-rec {
|
||||
.recursion {
|
||||
.recursion();
|
||||
}
|
||||
}
|
||||
.paddingFloat(@padding) { padding-left: @padding; }
|
||||
|
||||
.button {
|
||||
.paddingFloat(((10px + 12) * 2));
|
||||
|
||||
&.large { .paddingFloat(((10em * 2) * 2)); }
|
||||
}
|
||||
.clearfix() {
|
||||
// ...
|
||||
}
|
||||
.clearfix {
|
||||
.clearfix();
|
||||
}
|
||||
.foo {
|
||||
.clearfix();
|
||||
}
|
||||
~~~~~~~~~~
|
3
src/lint/linter/__tests__/lessc/no-output.lint-test
Normal file
3
src/lint/linter/__tests__/lessc/no-output.lint-test
Normal file
|
@ -0,0 +1,3 @@
|
|||
.mixin() {
|
||||
}
|
||||
~~~~~~~~~~
|
63
src/lint/linter/__tests__/lessc/operations.lint-test
Normal file
63
src/lint/linter/__tests__/lessc/operations.lint-test
Normal file
|
@ -0,0 +1,63 @@
|
|||
#operations {
|
||||
color: (#110000 + #000011 + #001100); // #111111
|
||||
height: (10px / 2px + 6px - 1px * 2); // 9px
|
||||
width: (2 * 4 - 5em); // 3em
|
||||
.spacing {
|
||||
height: (10px / 2px+6px-1px*2);
|
||||
width: (2 * 4-5em);
|
||||
}
|
||||
substraction: (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
|
||||
}
|
||||
~~~~~~~~~~
|
46
src/lint/linter/__tests__/lessc/parens.lint-test
Normal file
46
src/lint/linter/__tests__/lessc/parens.lint-test
Normal file
|
@ -0,0 +1,46 @@
|
|||
.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-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-false-negatives {
|
||||
a: ~"(";
|
||||
}
|
||||
~~~~~~~~~~
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
test {
|
||||
@prefix: ufo-;
|
||||
@a: border;
|
||||
@bb: top;
|
||||
@c_c: left;
|
||||
@d-d4: radius;
|
||||
@-: -;
|
||||
|
||||
@{a}: 0;
|
||||
@{prefix}width: 50%;
|
||||
*-z-@{a} :1px dashed blue;
|
||||
-www-@{a}-@{bb}: 2px;
|
||||
@{d-d4}-is-not-a-@{a}:true;
|
||||
@{a}-@{bb}-@{c_c}-@{d-d4} : 2em;
|
||||
@{a}@{-}@{bb}@{-}red@{-}@{d-d4}-: 3pt;
|
||||
|
||||
.mixin(mixer);
|
||||
.merge(ish, base);
|
||||
}
|
||||
|
||||
@global: global;
|
||||
|
||||
.mixin(@arg) {
|
||||
@local: local;
|
||||
@{global}-@{local}-@{arg}-property: strong;
|
||||
}
|
||||
|
||||
.merge(@p, @v) {
|
||||
&-merge {
|
||||
@prefix: pre;
|
||||
@suffix: ish;
|
||||
@{prefix}-property-ish+ :high;
|
||||
pre-property-@{suffix} +: middle;
|
||||
@{prefix}-property-@{suffix}+: low;
|
||||
@{prefix}-property-@{p} + : @v;
|
||||
|
||||
@subterfuge: ~'+';
|
||||
pre-property-ish@{subterfuge}: nice try dude;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
31
src/lint/linter/__tests__/lessc/rulesets.lint-test
Normal file
31
src/lint/linter/__tests__/lessc/rulesets.lint-test
Normal file
|
@ -0,0 +1,31 @@
|
|||
#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;
|
||||
}
|
||||
~~~~~~~~~~
|
105
src/lint/linter/__tests__/lessc/scope.lint-test
Normal file
105
src/lint/linter/__tests__/lessc/scope.lint-test
Normal file
|
@ -0,0 +1,105 @@
|
|||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
157
src/lint/linter/__tests__/lessc/selectors.lint-test
Normal file
157
src/lint/linter/__tests__/lessc/selectors.lint-test
Normal file
|
@ -0,0 +1,157 @@
|
|||
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 {
|
||||
color:black;
|
||||
}
|
||||
}
|
||||
@num: 3;
|
||||
:nth-child(@{num}) {
|
||||
selector: interpolated;
|
||||
}
|
||||
.test {
|
||||
&:nth-child(odd):not(:nth-child(3)) {
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
[prop],
|
||||
[prop=10%],
|
||||
[prop="value@{num}"],
|
||||
[prop*="val@{num}"],
|
||||
[|prop~="val@{num}"],
|
||||
[*|prop$="val@{num}"],
|
||||
[ns|prop^="val@{num}"],
|
||||
[@{num}^="val@{num}"],
|
||||
[@{num}=@{num}],
|
||||
[@{num}] {
|
||||
attributes: yes;
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
~~~~~~~~~~
|
58
src/lint/linter/__tests__/lessc/strings.lint-test
Normal file
58
src/lint/linter/__tests__/lessc/strings.lint-test
Normal file
|
@ -0,0 +1,58 @@
|
|||
#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: ';';
|
||||
}
|
||||
#escaped {
|
||||
filter: ~"DX.Transform.MS.BS.filter(opacity=50)";
|
||||
}
|
||||
#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;
|
||||
}
|
||||
~~~~~~~~~~
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
@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;}
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
84
src/lint/linter/__tests__/lessc/variables.lint-test
Normal file
84
src/lint/linter/__tests__/lessc/variables.lint-test
Normal file
|
@ -0,0 +1,84 @@
|
|||
@a: 2;
|
||||
@x: (@a * @a);
|
||||
@y: (@x + 1);
|
||||
@z: (@x * 2 + @y);
|
||||
@var: -1;
|
||||
|
||||
.variables {
|
||||
width: (@z + 1cm); // 14cm
|
||||
}
|
||||
|
||||
@b: @a * 10;
|
||||
@c: #888;
|
||||
|
||||
@fonts: "Trebuchet MS", Verdana, sans-serif;
|
||||
@f: @fonts;
|
||||
|
||||
@quotes: "~" "~";
|
||||
@q: @quotes;
|
||||
@onePixel: 1px;
|
||||
|
||||
.variables {
|
||||
height: (@b + @x + 0px); // 24px
|
||||
color: @c;
|
||||
font-family: @f;
|
||||
quotes: @q;
|
||||
}
|
||||
|
||||
.redef {
|
||||
@var: 0;
|
||||
.inition {
|
||||
@var: 4;
|
||||
@var: 2;
|
||||
three: @var;
|
||||
@var: 3;
|
||||
}
|
||||
zero: @var;
|
||||
}
|
||||
|
||||
.values {
|
||||
minus-one: @var;
|
||||
@a: 'Trebuchet';
|
||||
@multi: 'A', B, C;
|
||||
font-family: @a, @a, @a;
|
||||
color: @c !important;
|
||||
multi: something @multi, @a;
|
||||
}
|
||||
|
||||
.variable-names {
|
||||
@var: 'hello';
|
||||
@name: 'var';
|
||||
name: @@name;
|
||||
}
|
||||
|
||||
.alpha {
|
||||
@var: 42;
|
||||
filter: alpha(opacity=@var);
|
||||
}
|
||||
|
||||
.polluteMixin() {
|
||||
@a: 'pollution';
|
||||
}
|
||||
.testPollution {
|
||||
@a: 'no-pollution';
|
||||
a: @a;
|
||||
.polluteMixin();
|
||||
a: @a;
|
||||
}
|
||||
|
||||
.units {
|
||||
width: @onePixel;
|
||||
same-unit-as-previously: (@onePixel / @onePixel);
|
||||
square-pixel-divided: (@onePixel * @onePixel / @onePixel);
|
||||
odd-unit: unit((@onePixel * 4em / 2cm));
|
||||
percentage: (10 * 50%);
|
||||
pixels: (50px * 10);
|
||||
conversion-metric-a: (20mm + 1cm);
|
||||
conversion-metric-b: (1cm + 20mm);
|
||||
conversion-imperial: (1in + 72pt + 6pc);
|
||||
custom-unit: (42octocats * 10);
|
||||
custom-unit-cancelling: (8cats * 9dogs / 4cats);
|
||||
mix-units: (1px + 1em);
|
||||
invalid-units: (1px * 1px);
|
||||
}
|
||||
~~~~~~~~~~
|
43
src/lint/linter/__tests__/lessc/whitespace.lint-test
Normal file
43
src/lint/linter/__tests__/lessc/whitespace.lint-test
Normal file
|
@ -0,0 +1,43 @@
|
|||
.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;
|
||||
}
|
||||
~~~~~~~~~~
|
Loading…
Reference in a new issue