test.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. // Initiate ModeTest and set defaults
  2. var MT = ModeTest;
  3. MT.modeName = 'css';
  4. MT.modeOptions = {};
  5. // Requires at least one media query
  6. MT.testMode(
  7. 'atMediaEmpty',
  8. '@media { }',
  9. [
  10. 'def', '@media',
  11. null, ' ',
  12. 'error', '{',
  13. null, ' }'
  14. ]
  15. );
  16. MT.testMode(
  17. 'atMediaMultiple',
  18. '@media not screen and (color), not print and (color) { }',
  19. [
  20. 'def', '@media',
  21. null, ' ',
  22. 'keyword', 'not',
  23. null, ' ',
  24. 'attribute', 'screen',
  25. null, ' ',
  26. 'operator', 'and',
  27. null, ' (',
  28. 'property', 'color',
  29. null, '), ',
  30. 'keyword', 'not',
  31. null, ' ',
  32. 'attribute', 'print',
  33. null, ' ',
  34. 'operator', 'and',
  35. null, ' (',
  36. 'property', 'color',
  37. null, ') { }'
  38. ]
  39. );
  40. MT.testMode(
  41. 'atMediaCheckStack',
  42. '@media screen { } foo { }',
  43. [
  44. 'def', '@media',
  45. null, ' ',
  46. 'attribute', 'screen',
  47. null, ' { } ',
  48. 'tag', 'foo',
  49. null, ' { }'
  50. ]
  51. );
  52. MT.testMode(
  53. 'atMediaCheckStack',
  54. '@media screen (color) { } foo { }',
  55. [
  56. 'def', '@media',
  57. null, ' ',
  58. 'attribute', 'screen',
  59. null, ' (',
  60. 'property', 'color',
  61. null, ') { } ',
  62. 'tag', 'foo',
  63. null, ' { }'
  64. ]
  65. );
  66. MT.testMode(
  67. 'atMediaCheckStackInvalidAttribute',
  68. '@media foobarhello { } foo { }',
  69. [
  70. 'def', '@media',
  71. null, ' ',
  72. 'attribute error', 'foobarhello',
  73. null, ' { } ',
  74. 'tag', 'foo',
  75. null, ' { }'
  76. ]
  77. );
  78. // Error, because "and" is only allowed immediately preceding a media expression
  79. MT.testMode(
  80. 'atMediaInvalidAttribute',
  81. '@media foobarhello { }',
  82. [
  83. 'def', '@media',
  84. null, ' ',
  85. 'attribute error', 'foobarhello',
  86. null, ' { }'
  87. ]
  88. );
  89. // Error, because "and" is only allowed immediately preceding a media expression
  90. MT.testMode(
  91. 'atMediaInvalidAnd',
  92. '@media and screen { }',
  93. [
  94. 'def', '@media',
  95. null, ' ',
  96. 'error', 'and',
  97. null, ' ',
  98. 'attribute', 'screen',
  99. null, ' { }'
  100. ]
  101. );
  102. // Error, because "not" is only allowed as the first item in each media query
  103. MT.testMode(
  104. 'atMediaInvalidNot',
  105. '@media screen not (not) { }',
  106. [
  107. 'def', '@media',
  108. null, ' ',
  109. 'attribute', 'screen',
  110. null, ' ',
  111. 'error', 'not',
  112. null, ' (',
  113. 'error', 'not',
  114. null, ') { }'
  115. ]
  116. );
  117. // Error, because "only" is only allowed as the first item in each media query
  118. MT.testMode(
  119. 'atMediaInvalidOnly',
  120. '@media screen only (only) { }',
  121. [
  122. 'def', '@media',
  123. null, ' ',
  124. 'attribute', 'screen',
  125. null, ' ',
  126. 'error', 'only',
  127. null, ' (',
  128. 'error', 'only',
  129. null, ') { }'
  130. ]
  131. );
  132. // Error, because "foobarhello" is neither a known type or property, but
  133. // property was expected (after "and"), and it should be in parenthese.
  134. MT.testMode(
  135. 'atMediaUnknownType',
  136. '@media screen and foobarhello { }',
  137. [
  138. 'def', '@media',
  139. null, ' ',
  140. 'attribute', 'screen',
  141. null, ' ',
  142. 'operator', 'and',
  143. null, ' ',
  144. 'error', 'foobarhello',
  145. null, ' { }'
  146. ]
  147. );
  148. // Error, because "color" is not a known type, but is a known property, and
  149. // should be in parentheses.
  150. MT.testMode(
  151. 'atMediaInvalidType',
  152. '@media screen and color { }',
  153. [
  154. 'def', '@media',
  155. null, ' ',
  156. 'attribute', 'screen',
  157. null, ' ',
  158. 'operator', 'and',
  159. null, ' ',
  160. 'error', 'color',
  161. null, ' { }'
  162. ]
  163. );
  164. // Error, because "print" is not a known property, but is a known type,
  165. // and should not be in parenthese.
  166. MT.testMode(
  167. 'atMediaInvalidProperty',
  168. '@media screen and (print) { }',
  169. [
  170. 'def', '@media',
  171. null, ' ',
  172. 'attribute', 'screen',
  173. null, ' ',
  174. 'operator', 'and',
  175. null, ' (',
  176. 'error', 'print',
  177. null, ') { }'
  178. ]
  179. );
  180. // Soft error, because "foobarhello" is not a known property or type.
  181. MT.testMode(
  182. 'atMediaUnknownProperty',
  183. '@media screen and (foobarhello) { }',
  184. [
  185. 'def', '@media',
  186. null, ' ',
  187. 'attribute', 'screen',
  188. null, ' ',
  189. 'operator', 'and',
  190. null, ' (',
  191. 'property error', 'foobarhello',
  192. null, ') { }'
  193. ]
  194. );
  195. MT.testMode(
  196. 'tagSelector',
  197. 'foo { }',
  198. [
  199. 'tag', 'foo',
  200. null, ' { }'
  201. ]
  202. );
  203. MT.testMode(
  204. 'classSelector',
  205. '.foo-bar_hello { }',
  206. [
  207. 'qualifier', '.foo-bar_hello',
  208. null, ' { }'
  209. ]
  210. );
  211. MT.testMode(
  212. 'idSelector',
  213. '#foo { #foo }',
  214. [
  215. 'builtin', '#foo',
  216. null, ' { ',
  217. 'error', '#foo',
  218. null, ' }'
  219. ]
  220. );
  221. MT.testMode(
  222. 'tagSelectorUnclosed',
  223. 'foo { margin: 0 } bar { }',
  224. [
  225. 'tag', 'foo',
  226. null, ' { ',
  227. 'property', 'margin',
  228. 'operator', ':',
  229. null, ' ',
  230. 'number', '0',
  231. null, ' } ',
  232. 'tag', 'bar',
  233. null, ' { }'
  234. ]
  235. );
  236. MT.testMode(
  237. 'tagStringNoQuotes',
  238. 'foo { font-family: hello world; }',
  239. [
  240. 'tag', 'foo',
  241. null, ' { ',
  242. 'property', 'font-family',
  243. 'operator', ':',
  244. null, ' ',
  245. 'variable-2', 'hello',
  246. null, ' ',
  247. 'variable-2', 'world',
  248. null, '; }'
  249. ]
  250. );
  251. MT.testMode(
  252. 'tagStringDouble',
  253. 'foo { font-family: "hello world"; }',
  254. [
  255. 'tag', 'foo',
  256. null, ' { ',
  257. 'property', 'font-family',
  258. 'operator', ':',
  259. null, ' ',
  260. 'string', '"hello world"',
  261. null, '; }'
  262. ]
  263. );
  264. MT.testMode(
  265. 'tagStringSingle',
  266. 'foo { font-family: \'hello world\'; }',
  267. [
  268. 'tag', 'foo',
  269. null, ' { ',
  270. 'property', 'font-family',
  271. 'operator', ':',
  272. null, ' ',
  273. 'string', '\'hello world\'',
  274. null, '; }'
  275. ]
  276. );
  277. MT.testMode(
  278. 'tagColorKeyword',
  279. 'foo { color: black; }',
  280. [
  281. 'tag', 'foo',
  282. null, ' { ',
  283. 'property', 'color',
  284. 'operator', ':',
  285. null, ' ',
  286. 'keyword', 'black',
  287. null, '; }'
  288. ]
  289. );
  290. MT.testMode(
  291. 'tagColorHex3',
  292. 'foo { background: #fff; }',
  293. [
  294. 'tag', 'foo',
  295. null, ' { ',
  296. 'property', 'background',
  297. 'operator', ':',
  298. null, ' ',
  299. 'atom', '#fff',
  300. null, '; }'
  301. ]
  302. );
  303. MT.testMode(
  304. 'tagColorHex6',
  305. 'foo { background: #ffffff; }',
  306. [
  307. 'tag', 'foo',
  308. null, ' { ',
  309. 'property', 'background',
  310. 'operator', ':',
  311. null, ' ',
  312. 'atom', '#ffffff',
  313. null, '; }'
  314. ]
  315. );
  316. MT.testMode(
  317. 'tagColorHex4',
  318. 'foo { background: #ffff; }',
  319. [
  320. 'tag', 'foo',
  321. null, ' { ',
  322. 'property', 'background',
  323. 'operator', ':',
  324. null, ' ',
  325. 'atom error', '#ffff',
  326. null, '; }'
  327. ]
  328. );
  329. MT.testMode(
  330. 'tagColorHexInvalid',
  331. 'foo { background: #ffg; }',
  332. [
  333. 'tag', 'foo',
  334. null, ' { ',
  335. 'property', 'background',
  336. 'operator', ':',
  337. null, ' ',
  338. 'atom error', '#ffg',
  339. null, '; }'
  340. ]
  341. );
  342. MT.testMode(
  343. 'tagNegativeNumber',
  344. 'foo { margin: -5px; }',
  345. [
  346. 'tag', 'foo',
  347. null, ' { ',
  348. 'property', 'margin',
  349. 'operator', ':',
  350. null, ' ',
  351. 'number', '-5px',
  352. null, '; }'
  353. ]
  354. );
  355. MT.testMode(
  356. 'tagPositiveNumber',
  357. 'foo { padding: 5px; }',
  358. [
  359. 'tag', 'foo',
  360. null, ' { ',
  361. 'property', 'padding',
  362. 'operator', ':',
  363. null, ' ',
  364. 'number', '5px',
  365. null, '; }'
  366. ]
  367. );
  368. MT.testMode(
  369. 'tagVendor',
  370. 'foo { -foo-box-sizing: -foo-border-box; }',
  371. [
  372. 'tag', 'foo',
  373. null, ' { ',
  374. 'meta', '-foo-',
  375. 'property', 'box-sizing',
  376. 'operator', ':',
  377. null, ' ',
  378. 'meta', '-foo-',
  379. 'string-2', 'border-box',
  380. null, '; }'
  381. ]
  382. );
  383. MT.testMode(
  384. 'tagBogusProperty',
  385. 'foo { barhelloworld: 0; }',
  386. [
  387. 'tag', 'foo',
  388. null, ' { ',
  389. 'property error', 'barhelloworld',
  390. 'operator', ':',
  391. null, ' ',
  392. 'number', '0',
  393. null, '; }'
  394. ]
  395. );
  396. MT.testMode(
  397. 'tagTwoProperties',
  398. 'foo { margin: 0; padding: 0; }',
  399. [
  400. 'tag', 'foo',
  401. null, ' { ',
  402. 'property', 'margin',
  403. 'operator', ':',
  404. null, ' ',
  405. 'number', '0',
  406. null, '; ',
  407. 'property', 'padding',
  408. 'operator', ':',
  409. null, ' ',
  410. 'number', '0',
  411. null, '; }'
  412. ]
  413. );
  414. //
  415. //MT.testMode(
  416. // 'tagClass',
  417. // '@media only screen and (min-width: 500px), print {foo.bar#hello { color: black !important; background: #f00; margin: -5px; padding: 5px; -foo-box-sizing: border-box; } /* world */}',
  418. // [
  419. // 'def', '@media',
  420. // null, ' ',
  421. // 'keyword', 'only',
  422. // null, ' ',
  423. // 'attribute', 'screen',
  424. // null, ' ',
  425. // 'operator', 'and',
  426. // null, ' ',
  427. // 'bracket', '(',
  428. // 'property', 'min-width',
  429. // 'operator', ':',
  430. // null, ' ',
  431. // 'number', '500px',
  432. // 'bracket', ')',
  433. // null, ', ',
  434. // 'attribute', 'print',
  435. // null, ' {',
  436. // 'tag', 'foo',
  437. // 'qualifier', '.bar',
  438. // 'header', '#hello',
  439. // null, ' { ',
  440. // 'property', 'color',
  441. // 'operator', ':',
  442. // null, ' ',
  443. // 'keyword', 'black',
  444. // null, ' ',
  445. // 'keyword', '!important',
  446. // null, '; ',
  447. // 'property', 'background',
  448. // 'operator', ':',
  449. // null, ' ',
  450. // 'atom', '#f00',
  451. // null, '; ',
  452. // 'property', 'padding',
  453. // 'operator', ':',
  454. // null, ' ',
  455. // 'number', '5px',
  456. // null, '; ',
  457. // 'property', 'margin',
  458. // 'operator', ':',
  459. // null, ' ',
  460. // 'number', '-5px',
  461. // null, '; ',
  462. // 'meta', '-foo-',
  463. // 'property', 'box-sizing',
  464. // 'operator', ':',
  465. // null, ' ',
  466. // 'string-2', 'border-box',
  467. // null, '; } ',
  468. // 'comment', '/* world */',
  469. // null, '}'
  470. // ]
  471. //);