test_parsePseudoClassesAndAttributes.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
  2. /* Any copyright is dedicated to the Public Domain.
  3. http://creativecommons.org/publicdomain/zero/1.0/ */
  4. "use strict";
  5. var Cu = Components.utils;
  6. const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
  7. const {
  8. parsePseudoClassesAndAttributes,
  9. SELECTOR_ATTRIBUTE,
  10. SELECTOR_ELEMENT,
  11. SELECTOR_PSEUDO_CLASS
  12. } = require("devtools/shared/css/parsing-utils");
  13. const TEST_DATA = [
  14. // Test that a null input throws an exception
  15. {
  16. input: null,
  17. throws: true
  18. },
  19. // Test that a undefined input throws an exception
  20. {
  21. input: undefined,
  22. throws: true
  23. },
  24. {
  25. input: ":root",
  26. expected: [
  27. { value: ":root", type: SELECTOR_PSEUDO_CLASS }
  28. ]
  29. },
  30. {
  31. input: ".testclass",
  32. expected: [
  33. { value: ".testclass", type: SELECTOR_ELEMENT }
  34. ]
  35. },
  36. {
  37. input: "div p",
  38. expected: [
  39. { value: "div p", type: SELECTOR_ELEMENT }
  40. ]
  41. },
  42. {
  43. input: "div > p",
  44. expected: [
  45. { value: "div > p", type: SELECTOR_ELEMENT }
  46. ]
  47. },
  48. {
  49. input: "a[hidden]",
  50. expected: [
  51. { value: "a", type: SELECTOR_ELEMENT },
  52. { value: "[hidden]", type: SELECTOR_ATTRIBUTE }
  53. ]
  54. },
  55. {
  56. input: "a[hidden=true]",
  57. expected: [
  58. { value: "a", type: SELECTOR_ELEMENT },
  59. { value: "[hidden=true]", type: SELECTOR_ATTRIBUTE }
  60. ]
  61. },
  62. {
  63. input: "a[hidden=true] p:hover",
  64. expected: [
  65. { value: "a", type: SELECTOR_ELEMENT },
  66. { value: "[hidden=true]", type: SELECTOR_ATTRIBUTE },
  67. { value: " p", type: SELECTOR_ELEMENT },
  68. { value: ":hover", type: SELECTOR_PSEUDO_CLASS }
  69. ]
  70. },
  71. {
  72. input: "a[checked=\"true\"]",
  73. expected: [
  74. { value: "a", type: SELECTOR_ELEMENT },
  75. { value: "[checked=\"true\"]", type: SELECTOR_ATTRIBUTE }
  76. ]
  77. },
  78. {
  79. input: "a[title~=test]",
  80. expected: [
  81. { value: "a", type: SELECTOR_ELEMENT },
  82. { value: "[title~=test]", type: SELECTOR_ATTRIBUTE }
  83. ]
  84. },
  85. {
  86. input: "h1[hidden=\"true\"][title^=\"Important\"]",
  87. expected: [
  88. { value: "h1", type: SELECTOR_ELEMENT },
  89. { value: "[hidden=\"true\"]", type: SELECTOR_ATTRIBUTE },
  90. { value: "[title^=\"Important\"]", type: SELECTOR_ATTRIBUTE}
  91. ]
  92. },
  93. {
  94. input: "p:hover",
  95. expected: [
  96. { value: "p", type: SELECTOR_ELEMENT },
  97. { value: ":hover", type: SELECTOR_PSEUDO_CLASS }
  98. ]
  99. },
  100. {
  101. input: "p + .testclass:hover",
  102. expected: [
  103. { value: "p + .testclass", type: SELECTOR_ELEMENT },
  104. { value: ":hover", type: SELECTOR_PSEUDO_CLASS }
  105. ]
  106. },
  107. {
  108. input: "p::before",
  109. expected: [
  110. { value: "p", type: SELECTOR_ELEMENT },
  111. { value: "::before", type: SELECTOR_PSEUDO_CLASS }
  112. ]
  113. },
  114. {
  115. input: "p:nth-child(2)",
  116. expected: [
  117. { value: "p", type: SELECTOR_ELEMENT },
  118. { value: ":nth-child(2)", type: SELECTOR_PSEUDO_CLASS }
  119. ]
  120. },
  121. {
  122. input: "p:not([title=\"test\"]) .testclass",
  123. expected: [
  124. { value: "p", type: SELECTOR_ELEMENT },
  125. { value: ":not([title=\"test\"])", type: SELECTOR_PSEUDO_CLASS },
  126. { value: " .testclass", type: SELECTOR_ELEMENT }
  127. ]
  128. },
  129. {
  130. input: "a\\:hover",
  131. expected: [
  132. { value: "a\\:hover", type: SELECTOR_ELEMENT }
  133. ]
  134. },
  135. {
  136. input: ":not(:lang(it))",
  137. expected: [
  138. { value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS }
  139. ]
  140. },
  141. {
  142. input: "p:not(:lang(it))",
  143. expected: [
  144. { value: "p", type: SELECTOR_ELEMENT },
  145. { value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS }
  146. ]
  147. },
  148. {
  149. input: "p:not(p:lang(it))",
  150. expected: [
  151. { value: "p", type: SELECTOR_ELEMENT },
  152. { value: ":not(p:lang(it))", type: SELECTOR_PSEUDO_CLASS }
  153. ]
  154. },
  155. {
  156. input: ":not(:lang(it)",
  157. expected: [
  158. { value: ":not(:lang(it)", type: SELECTOR_ELEMENT }
  159. ]
  160. },
  161. {
  162. input: ":not(:lang(it)))",
  163. expected: [
  164. { value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS },
  165. { value: ")", type: SELECTOR_ELEMENT }
  166. ]
  167. }
  168. ];
  169. function run_test() {
  170. for (let test of TEST_DATA) {
  171. dump("Test input string " + test.input + "\n");
  172. let output;
  173. try {
  174. output = parsePseudoClassesAndAttributes(test.input);
  175. } catch (e) {
  176. dump("parsePseudoClassesAndAttributes threw an exception with the " +
  177. "given input string\n");
  178. if (test.throws) {
  179. ok(true, "Exception expected");
  180. } else {
  181. dump();
  182. ok(false, "Exception unexpected\n" + e);
  183. }
  184. }
  185. if (output) {
  186. assertOutput(output, test.expected);
  187. }
  188. }
  189. }
  190. function assertOutput(actual, expected) {
  191. if (actual.length === expected.length) {
  192. for (let i = 0; i < expected.length; i++) {
  193. dump("Check that the output item has the expected value and type\n");
  194. ok(!!actual[i]);
  195. equal(expected[i].value, actual[i].value);
  196. equal(expected[i].type, actual[i].type);
  197. }
  198. } else {
  199. for (let prop of actual) {
  200. dump("Actual output contained: {value: " + prop.value + ", type: " +
  201. prop.type + "}\n");
  202. }
  203. equal(actual.length, expected.length);
  204. }
  205. }