headless-squirrel 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/README.rdoc +55 -0
  2. data/Rakefile +27 -0
  3. data/bin/jstest +10 -0
  4. data/lib/headless_squirrel.rb +2 -0
  5. data/lib/headless_squirrel/console.rb +24 -0
  6. data/lib/headless_squirrel/runner.rb +70 -0
  7. data/lib/headless_squirrel/test.rb +17 -0
  8. data/lib/headless_squirrel/test_case.rb +158 -0
  9. data/test/fixtures/a_unit_test.html +27 -0
  10. data/test/fixtures/a_unit_test.js +22 -0
  11. data/test/fixtures/syntax_error.html +27 -0
  12. data/test/fixtures/syntax_error.js +5 -0
  13. data/test/fixtures/type_error.html +27 -0
  14. data/test/fixtures/type_error.js +1 -0
  15. data/test/regression/prototype/unit/ajax_test.html +29 -0
  16. data/test/regression/prototype/unit/array_test.html +28 -0
  17. data/test/regression/prototype/unit/assets/prototype.js +4900 -0
  18. data/test/regression/prototype/unit/assets/unittest.css +50 -0
  19. data/test/regression/prototype/unit/assets/unittest.js +615 -0
  20. data/test/regression/prototype/unit/assets/unittest_transport.js +1 -0
  21. data/test/regression/prototype/unit/base_test.html +27 -0
  22. data/test/regression/prototype/unit/class_test.html +27 -0
  23. data/test/regression/prototype/unit/date_test.html +27 -0
  24. data/test/regression/prototype/unit/dom_test.html +304 -0
  25. data/test/regression/prototype/unit/element_mixins_test.html +30 -0
  26. data/test/regression/prototype/unit/enumerable_test.html +35 -0
  27. data/test/regression/prototype/unit/event_test.html +31 -0
  28. data/test/regression/prototype/unit/fixtures/ajax.html +2 -0
  29. data/test/regression/prototype/unit/fixtures/ajax.js +42 -0
  30. data/test/regression/prototype/unit/fixtures/array.html +1 -0
  31. data/test/regression/prototype/unit/fixtures/class.js +83 -0
  32. data/test/regression/prototype/unit/fixtures/content.html +1 -0
  33. data/test/regression/prototype/unit/fixtures/data.json +1 -0
  34. data/test/regression/prototype/unit/fixtures/dom.css +84 -0
  35. data/test/regression/prototype/unit/fixtures/dom.html +278 -0
  36. data/test/regression/prototype/unit/fixtures/dom.js +17 -0
  37. data/test/regression/prototype/unit/fixtures/element_mixins.html +4 -0
  38. data/test/regression/prototype/unit/fixtures/element_mixins.js +2 -0
  39. data/test/regression/prototype/unit/fixtures/empty.html +0 -0
  40. data/test/regression/prototype/unit/fixtures/empty.js +1 -0
  41. data/test/regression/prototype/unit/fixtures/enumerable.html +8 -0
  42. data/test/regression/prototype/unit/fixtures/enumerable.js +23 -0
  43. data/test/regression/prototype/unit/fixtures/event.html +4 -0
  44. data/test/regression/prototype/unit/fixtures/form.html +108 -0
  45. data/test/regression/prototype/unit/fixtures/function.js +13 -0
  46. data/test/regression/prototype/unit/fixtures/hash.js +25 -0
  47. data/test/regression/prototype/unit/fixtures/hello.js +1 -0
  48. data/test/regression/prototype/unit/fixtures/logo.gif +0 -0
  49. data/test/regression/prototype/unit/fixtures/object.html +6 -0
  50. data/test/regression/prototype/unit/fixtures/object.js +7 -0
  51. data/test/regression/prototype/unit/fixtures/position.html +9 -0
  52. data/test/regression/prototype/unit/fixtures/selector.html +71 -0
  53. data/test/regression/prototype/unit/fixtures/string.js +8 -0
  54. data/test/regression/prototype/unit/fixtures/unittest.html +18 -0
  55. data/test/regression/prototype/unit/form_test.html +135 -0
  56. data/test/regression/prototype/unit/function_test.html +27 -0
  57. data/test/regression/prototype/unit/hash_test.html +27 -0
  58. data/test/regression/prototype/unit/number_test.html +27 -0
  59. data/test/regression/prototype/unit/object_test.html +32 -0
  60. data/test/regression/prototype/unit/periodical_executer_test.html +27 -0
  61. data/test/regression/prototype/unit/position_test.html +36 -0
  62. data/test/regression/prototype/unit/prototype_test.html +27 -0
  63. data/test/regression/prototype/unit/range_test.html +27 -0
  64. data/test/regression/prototype/unit/regexp_test.html +27 -0
  65. data/test/regression/prototype/unit/selector_test.html +98 -0
  66. data/test/regression/prototype/unit/string_test.html +27 -0
  67. data/test/regression/prototype/unit/tests/ajax_test.js +379 -0
  68. data/test/regression/prototype/unit/tests/array_test.js +186 -0
  69. data/test/regression/prototype/unit/tests/base_test.js +43 -0
  70. data/test/regression/prototype/unit/tests/class_test.js +136 -0
  71. data/test/regression/prototype/unit/tests/date_test.js +5 -0
  72. data/test/regression/prototype/unit/tests/dom_test.js +1493 -0
  73. data/test/regression/prototype/unit/tests/element_mixins_test.js +32 -0
  74. data/test/regression/prototype/unit/tests/enumerable_test.js +271 -0
  75. data/test/regression/prototype/unit/tests/event_test.js +235 -0
  76. data/test/regression/prototype/unit/tests/form_test.js +382 -0
  77. data/test/regression/prototype/unit/tests/function_test.js +133 -0
  78. data/test/regression/prototype/unit/tests/hash_test.js +178 -0
  79. data/test/regression/prototype/unit/tests/number_test.js +44 -0
  80. data/test/regression/prototype/unit/tests/object_test.js +180 -0
  81. data/test/regression/prototype/unit/tests/periodical_executer_test.js +15 -0
  82. data/test/regression/prototype/unit/tests/position_test.js +44 -0
  83. data/test/regression/prototype/unit/tests/prototype_test.js +43 -0
  84. data/test/regression/prototype/unit/tests/range_test.js +58 -0
  85. data/test/regression/prototype/unit/tests/regexp_test.js +42 -0
  86. data/test/regression/prototype/unit/tests/selector_test.js +408 -0
  87. data/test/regression/prototype/unit/tests/string_test.js +548 -0
  88. data/test/regression/prototype/unit/tests/unittest_test.js +148 -0
  89. data/test/regression/prototype/unit/unittest_test.html +45 -0
  90. data/test/regression/prototype/upstream +1 -0
  91. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_alt_text.html +1 -0
  92. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_collection.js +1 -0
  93. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result.html +1 -0
  94. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result2.html +1 -0
  95. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_tagged.html +1 -0
  96. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_text.html +1 -0
  97. data/test/regression/scriptaculous/unit/_ajax_updater_result.html +20 -0
  98. data/test/regression/scriptaculous/unit/_autocomplete_result.html +11 -0
  99. data/test/regression/scriptaculous/unit/_autocomplete_result_nobr.html +1 -0
  100. data/test/regression/scriptaculous/unit/ajax_autocompleter_test.html +243 -0
  101. data/test/regression/scriptaculous/unit/ajax_inplaceeditor_test.html +895 -0
  102. data/test/regression/scriptaculous/unit/assets/builder.js +134 -0
  103. data/test/regression/scriptaculous/unit/assets/controls.js +963 -0
  104. data/test/regression/scriptaculous/unit/assets/dragdrop.js +973 -0
  105. data/test/regression/scriptaculous/unit/assets/effects.js +1122 -0
  106. data/test/regression/scriptaculous/unit/assets/javascripttest.rb +203 -0
  107. data/test/regression/scriptaculous/unit/assets/prototype.js +4320 -0
  108. data/test/regression/scriptaculous/unit/assets/scriptaculous.js +66 -0
  109. data/test/regression/scriptaculous/unit/assets/slider.js +273 -0
  110. data/test/regression/scriptaculous/unit/assets/sound.js +57 -0
  111. data/test/regression/scriptaculous/unit/assets/unittest.js +566 -0
  112. data/test/regression/scriptaculous/unit/bdd_test.html +150 -0
  113. data/test/regression/scriptaculous/unit/builder_test.html +262 -0
  114. data/test/regression/scriptaculous/unit/dragdrop_test.html +131 -0
  115. data/test/regression/scriptaculous/unit/effects_test.html +547 -0
  116. data/test/regression/scriptaculous/unit/element_test.html +116 -0
  117. data/test/regression/scriptaculous/unit/icon.png +0 -0
  118. data/test/regression/scriptaculous/unit/index.html +70 -0
  119. data/test/regression/scriptaculous/unit/loading_test.html +41 -0
  120. data/test/regression/scriptaculous/unit/position_clone_test.html +312 -0
  121. data/test/regression/scriptaculous/unit/slider_test.html +437 -0
  122. data/test/regression/scriptaculous/unit/sortable_test.html +205 -0
  123. data/test/regression/scriptaculous/unit/string_test.html +71 -0
  124. data/test/regression/scriptaculous/unit/unittest_test.html +154 -0
  125. data/test/regression/scriptaculous/upstream +1 -0
  126. data/test/test_helper.rb +20 -0
  127. data/test/unit/runner_test.rb +165 -0
  128. data/test/unit/test_case_test.rb +207 -0
  129. data/test/unit/test_test.rb +24 -0
  130. metadata +209 -0
@@ -0,0 +1,43 @@
1
+ new Test.Unit.Runner({
2
+ testBrowserDetection: function() {
3
+ var results = $H(Prototype.Browser).map(function(engine){
4
+ return engine;
5
+ }).partition(function(engine){
6
+ return engine[1] === true
7
+ });
8
+ var trues = results[0], falses = results[1];
9
+
10
+ this.info('User agent string is: ' + navigator.userAgent);
11
+
12
+ this.assert(trues.size() == 0 || trues.size() == 1,
13
+ 'There should be only one or no browser detected.');
14
+
15
+ // we should have definite trues or falses here
16
+ trues.each(function(result) {
17
+ this.assert(result[1] === true);
18
+ }, this);
19
+ falses.each(function(result) {
20
+ this.assert(result[1] === false);
21
+ }, this);
22
+
23
+ if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
24
+ this.info('Running on WebKit');
25
+ this.assert(Prototype.Browser.WebKit);
26
+ }
27
+
28
+ if(!!window.opera) {
29
+ this.info('Running on Opera');
30
+ this.assert(Prototype.Browser.Opera);
31
+ }
32
+
33
+ if(!!(window.attachEvent && !window.opera)) {
34
+ this.info('Running on IE');
35
+ this.assert(Prototype.Browser.IE);
36
+ }
37
+
38
+ if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) {
39
+ this.info('Running on Gecko');
40
+ this.assert(Prototype.Browser.Gecko);
41
+ }
42
+ }
43
+ });
@@ -0,0 +1,58 @@
1
+ new Test.Unit.Runner({
2
+
3
+ testInclude: function() {
4
+ this.assert(!$R(0, 0, true).include(0));
5
+ this.assert($R(0, 0, false).include(0));
6
+
7
+ this.assert($R(0, 5, true).include(0));
8
+ this.assert($R(0, 5, true).include(4));
9
+ this.assert(!$R(0, 5, true).include(5));
10
+
11
+ this.assert($R(0, 5, false).include(0));
12
+ this.assert($R(0, 5, false).include(5));
13
+ this.assert(!$R(0, 5, false).include(6));
14
+ },
15
+
16
+ testEach: function() {
17
+ var results = [];
18
+ $R(0, 0, true).each(function(value) {
19
+ results.push(value);
20
+ });
21
+
22
+ this.assertEnumEqual([], results);
23
+
24
+ results = [];
25
+ $R(0, 3, false).each(function(value) {
26
+ results.push(value);
27
+ });
28
+
29
+ this.assertEnumEqual([0, 1, 2, 3], results);
30
+ },
31
+
32
+ testAny: function() {
33
+ this.assert(!$R(1, 1, true).any());
34
+ this.assert($R(0, 3, false).any(function(value) {
35
+ return value == 3;
36
+ }));
37
+ },
38
+
39
+ testAll: function() {
40
+ this.assert($R(1, 1, true).all());
41
+ this.assert($R(0, 3, false).all(function(value) {
42
+ return value <= 3;
43
+ }));
44
+ },
45
+
46
+ testToArray: function() {
47
+ this.assertEnumEqual([], $R(0, 0, true).toArray());
48
+ this.assertEnumEqual([0], $R(0, 0, false).toArray());
49
+ this.assertEnumEqual([0], $R(0, 1, true).toArray());
50
+ this.assertEnumEqual([0, 1], $R(0, 1, false).toArray());
51
+ this.assertEnumEqual([-3, -2, -1, 0, 1, 2], $R(-3, 3, true).toArray());
52
+ this.assertEnumEqual([-3, -2, -1, 0, 1, 2, 3], $R(-3, 3, false).toArray());
53
+ },
54
+
55
+ testDefaultsToNotExclusive: function() {
56
+ this.assertEnumEqual($R(-3,3), $R(-3,3,false));
57
+ }
58
+ });
@@ -0,0 +1,42 @@
1
+ new Test.Unit.Runner({
2
+ testRegExpEscape: function() {
3
+ this.assertEqual('word', RegExp.escape('word'));
4
+ this.assertEqual('\\/slashes\\/', RegExp.escape('/slashes/'));
5
+ this.assertEqual('\\\\backslashes\\\\', RegExp.escape('\\backslashes\\'));
6
+ this.assertEqual('\\\\border of word', RegExp.escape('\\border of word'));
7
+
8
+ this.assertEqual('\\(\\?\\:non-capturing\\)', RegExp.escape('(?:non-capturing)'));
9
+ this.assertEqual('non-capturing', new RegExp(RegExp.escape('(?:') + '([^)]+)').exec('(?:non-capturing)')[1]);
10
+
11
+ this.assertEqual('\\(\\?\\=positive-lookahead\\)', RegExp.escape('(?=positive-lookahead)'));
12
+ this.assertEqual('positive-lookahead', new RegExp(RegExp.escape('(?=') + '([^)]+)').exec('(?=positive-lookahead)')[1]);
13
+
14
+ this.assertEqual('\\(\\?<\\=positive-lookbehind\\)', RegExp.escape('(?<=positive-lookbehind)'));
15
+ this.assertEqual('positive-lookbehind', new RegExp(RegExp.escape('(?<=') + '([^)]+)').exec('(?<=positive-lookbehind)')[1]);
16
+
17
+ this.assertEqual('\\(\\?\\!negative-lookahead\\)', RegExp.escape('(?!negative-lookahead)'));
18
+ this.assertEqual('negative-lookahead', new RegExp(RegExp.escape('(?!') + '([^)]+)').exec('(?!negative-lookahead)')[1]);
19
+
20
+ this.assertEqual('\\(\\?<\\!negative-lookbehind\\)', RegExp.escape('(?<!negative-lookbehind)'));
21
+ this.assertEqual('negative-lookbehind', new RegExp(RegExp.escape('(?<!') + '([^)]+)').exec('(?<!negative-lookbehind)')[1]);
22
+
23
+ this.assertEqual('\\[\\\\w\\]\\+', RegExp.escape('[\\w]+'));
24
+ this.assertEqual('character class', new RegExp(RegExp.escape('[') + '([^\\]]+)').exec('[character class]')[1]);
25
+
26
+ this.assertEqual('<div>', new RegExp(RegExp.escape('<div>')).exec('<td><div></td>')[0]);
27
+
28
+ this.assertEqual('false', RegExp.escape(false));
29
+ this.assertEqual('undefined', RegExp.escape());
30
+ this.assertEqual('null', RegExp.escape(null));
31
+ this.assertEqual('42', RegExp.escape(42));
32
+
33
+ this.assertEqual('\\\\n\\\\r\\\\t', RegExp.escape('\\n\\r\\t'));
34
+ this.assertEqual('\n\r\t', RegExp.escape('\n\r\t'));
35
+ this.assertEqual('\\{5,2\\}', RegExp.escape('{5,2}'));
36
+
37
+ this.assertEqual(
38
+ '\\/\\(\\[\\.\\*\\+\\?\\^\\=\\!\\:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\\/\\\\\\\\\\]\\)\\/g',
39
+ RegExp.escape('/([.*+?^=!:${}()|[\\]\\/\\\\])/g')
40
+ );
41
+ }
42
+ });
@@ -0,0 +1,408 @@
1
+ var $RunBenchmarks = false;
2
+
3
+ function reduce(arr) {
4
+ return arr.length > 1 ? arr : arr[0];
5
+ }
6
+
7
+ new Test.Unit.Runner({
8
+
9
+ testSelectorWithTagName: function() {
10
+ this.assertEnumEqual($A(document.getElementsByTagName('li')), $$('li'));
11
+ this.assertEnumEqual([$('strong')], $$('strong'));
12
+ this.assertEnumEqual([], $$('nonexistent'));
13
+
14
+ var allNodes = $A(document.getElementsByTagName('*')).select( function(node) {
15
+ return node.tagName !== '!';
16
+ });
17
+ this.assertEnumEqual(allNodes, $$('*'));
18
+ },
19
+
20
+ testSelectorWithId: function() {
21
+ this.assertEnumEqual([$('fixtures')], $$('#fixtures'));
22
+ this.assertEnumEqual([], $$('#nonexistent'));
23
+ this.assertEnumEqual([$('troubleForm')], $$('#troubleForm'));
24
+ },
25
+
26
+ testSelectorWithClassName: function() {
27
+ this.assertEnumEqual($('p', 'link_1', 'item_1'), $$('.first'));
28
+ this.assertEnumEqual([], $$('.second'));
29
+ },
30
+
31
+ testSelectorWithTagNameAndId: function() {
32
+ this.assertEnumEqual([$('strong')], $$('strong#strong'));
33
+ this.assertEnumEqual([], $$('p#strong'));
34
+ },
35
+
36
+ testSelectorWithTagNameAndClassName: function() {
37
+ this.assertEnumEqual($('link_1', 'link_2'), $$('a.internal'));
38
+ this.assertEnumEqual([$('link_2')], $$('a.internal.highlight'));
39
+ this.assertEnumEqual([$('link_2')], $$('a.highlight.internal'));
40
+ this.assertEnumEqual([], $$('a.highlight.internal.nonexistent'));
41
+ },
42
+
43
+ testSelectorWithIdAndClassName: function() {
44
+ this.assertEnumEqual([$('link_2')], $$('#link_2.internal'));
45
+ this.assertEnumEqual([$('link_2')], $$('.internal#link_2'));
46
+ this.assertEnumEqual([$('link_2')], $$('#link_2.internal.highlight'));
47
+ this.assertEnumEqual([], $$('#link_2.internal.nonexistent'));
48
+ },
49
+
50
+ testSelectorWithTagNameAndIdAndClassName: function() {
51
+ this.assertEnumEqual([$('link_2')], $$('a#link_2.internal'));
52
+ this.assertEnumEqual([$('link_2')], $$('a.internal#link_2'));
53
+ this.assertEnumEqual([$('item_1')], $$('li#item_1.first'));
54
+ this.assertEnumEqual([], $$('li#item_1.nonexistent'));
55
+ this.assertEnumEqual([], $$('li#item_1.first.nonexistent'));
56
+ },
57
+
58
+ test$$MatchesAncestryWithTokensSeparatedByWhitespace: function() {
59
+ this.assertEnumEqual($('em2', 'em', 'span'), $$('#fixtures a *'));
60
+ this.assertEnumEqual([$('p')], $$('div#fixtures p'));
61
+ },
62
+
63
+ test$$CombinesResultsWhenMultipleExpressionsArePassed: function() {
64
+ this.assertEnumEqual($('link_1', 'link_2', 'item_1', 'item_2', 'item_3'), $$('#p a', ' ul#list li '));
65
+ },
66
+
67
+ testSelectorWithTagNameAndAttributeExistence: function() {
68
+ this.assertEnumEqual($$('#fixtures h1'), $$('h1[class]'), 'h1[class]');
69
+ this.assertEnumEqual($$('#fixtures h1'), $$('h1[CLASS]'), 'h1[CLASS]');
70
+ this.assertEnumEqual([$('item_3')], $$('li#item_3[class]'), 'li#item_3[class]');
71
+ },
72
+
73
+ testSelectorWithTagNameAndSpecificAttributeValue: function() {
74
+ this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href="#"]'));
75
+ this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href=#]'));
76
+ },
77
+
78
+ testSelectorWithTagNameAndWhitespaceTokenizedAttributeValue: function() {
79
+ this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~="internal"]'), "a[class~=\"internal\"]");
80
+ this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~=internal]'), "a[class~=internal]");
81
+ },
82
+
83
+ testSelectorWithAttributeAndNoTagName: function() {
84
+ this.assertEnumEqual($(document.body).select('a[href]'), $(document.body).select('[href]'));
85
+ this.assertEnumEqual($$('a[class~="internal"]'), $$('[class~=internal]'));
86
+ this.assertEnumEqual($$('*[id]'), $$('[id]'));
87
+ this.assertEnumEqual($('checked_radio', 'unchecked_radio'), $$('[type=radio]'));
88
+ this.assertEnumEqual($$('*[type=checkbox]'), $$('[type=checkbox]'));
89
+ this.assertEnumEqual($('with_title', 'commaParent'), $$('[title]'));
90
+ this.assertEnumEqual($$('#troubleForm *[type=radio]'), $$('#troubleForm [type=radio]'));
91
+ this.assertEnumEqual($$('#troubleForm *[type]'), $$('#troubleForm [type]'));
92
+ },
93
+
94
+ testSelectorWithAttributeContainingDash: function() {
95
+ this.assertEnumEqual([$('attr_with_dash')], $$('[foo-bar]'), "attribute with hyphen");
96
+ },
97
+
98
+ testSelectorWithUniversalAndHyphenTokenizedAttributeValue: function() {
99
+ this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="es"]'));
100
+ this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="ES"]'));
101
+ },
102
+
103
+ testSelectorWithTagNameAndNegatedAttributeValue: function() {
104
+ this.assertEnumEqual([], $$('a[href!="#"]'));
105
+ },
106
+
107
+ testSelectorWithBracketAttributeValue: function() {
108
+ this.assertEnumEqual($('chk_1', 'chk_2'), $$('#troubleForm2 input[name="brackets[5][]"]'));
109
+ this.assertEnumEqual([$('chk_1')], $$('#troubleForm2 input[name="brackets[5][]"]:checked'));
110
+ this.assertEnumEqual([$('chk_2')], $$('#troubleForm2 input[name="brackets[5][]"][value=2]'));
111
+ this.assertEnumEqual([], $$('#troubleForm2 input[name=brackets[5][]]'));
112
+ },
113
+
114
+ test$$WithNestedAttributeSelectors: function() {
115
+ this.assertEnumEqual([$('strong')], $$('div[style] p[id] strong'), 'div[style] p[id] strong');
116
+ },
117
+
118
+ testSelectorWithMultipleConditions: function() {
119
+ this.assertEnumEqual([$('link_3')], $$('a[class~=external][href="#"]'),
120
+ 'a[class~=external][href="#"]');
121
+ this.assertEnumEqual([], $$('a[class~=external][href!="#"]'),
122
+ 'a[class~=external][href!="#"]');
123
+ },
124
+
125
+ testSelectorMatchElements: function() {
126
+ this.assertElementsMatch(Selector.matchElements($('list').descendants(), 'li'), '#item_1', '#item_2', '#item_3');
127
+ this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), 'a.internal'), '#link_1', '#link_2');
128
+ this.assertEnumEqual([], Selector.matchElements($('fixtures').descendants(), 'p.last'));
129
+ this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), '.inexistant, a.internal'), '#link_1', '#link_2');
130
+ },
131
+
132
+ testSelectorFindElement: function() {
133
+ this.assertElementMatches(Selector.findElement($('list').descendants(), 'li'), 'li#item_1.first');
134
+ this.assertElementMatches(Selector.findElement($('list').descendants(), 'li', 1), 'li#item_2');
135
+ this.assertElementMatches(Selector.findElement($('list').descendants(), 'li#item_3'), 'li');
136
+ this.assertEqual(undefined, Selector.findElement($('list').descendants(), 'em'));
137
+ },
138
+
139
+ testElementMatch: function() {
140
+ var span = $('dupL1');
141
+
142
+ // tests that should pass
143
+ this.assert(span.match('span'));
144
+ this.assert(span.match('span#dupL1'));
145
+ this.assert(span.match('div > span'), 'child combinator');
146
+ this.assert(span.match('#dupContainer span'), 'descendant combinator');
147
+ this.assert(span.match('#dupL1'), 'ID only');
148
+ this.assert(span.match('span.span_foo'), 'class name 1');
149
+ this.assert(span.match('span.span_bar'), 'class name 2');
150
+ this.assert(span.match('span:first-child'), 'first-child pseudoclass');
151
+
152
+ this.assert(!span.match('span.span_wtf'), 'bogus class name');
153
+ this.assert(!span.match('#dupL2'), 'different ID');
154
+ this.assert(!span.match('div'), 'different tag name');
155
+ this.assert(!span.match('span span'), 'different ancestry');
156
+ this.assert(!span.match('span > span'), 'different parent');
157
+ this.assert(!span.match('span:nth-child(5)'), 'different pseudoclass');
158
+
159
+ this.assert(!$('link_2').match('a[rel^=external]'));
160
+ this.assert($('link_1').match('a[rel^=external]'));
161
+ this.assert($('link_1').match('a[rel^="external"]'));
162
+ this.assert($('link_1').match("a[rel^='external']"));
163
+
164
+ this.assert(span.match({ match: function(element) { return true }}), 'custom selector');
165
+ this.assert(!span.match({ match: function(element) { return false }}), 'custom selector');
166
+ },
167
+
168
+ testSelectorWithSpaceInAttributeValue: function() {
169
+ this.assertEnumEqual([$('with_title')], $$('cite[title="hello world!"]'));
170
+ },
171
+
172
+ // AND NOW COME THOSE NEW TESTS AFTER ANDREW'S REWRITE!
173
+
174
+ testSelectorWithNamespacedAttributes: function() {
175
+ if (Prototype.BrowserFeatures.XPath) {
176
+ this.assertUndefined(new Selector('html[xml:lang]').xpath);
177
+ this.assertUndefined(new Selector('body p[xml:lang]').xpath);
178
+ } else
179
+ this.info("Could not test XPath bypass: no XPath to begin with!");
180
+
181
+ this.assertElementsMatch($$('[xml:lang]'), 'html', '#item_3');
182
+ this.assertElementsMatch($$('*[xml:lang]'), 'html', '#item_3');
183
+ },
184
+
185
+ testSelectorWithChild: function() {
186
+ this.assertEnumEqual($('link_1', 'link_2'), $$('p.first > a'));
187
+ this.assertEnumEqual($('father', 'uncle'), $$('div#grandfather > div'));
188
+ this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1>span'));
189
+ this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1 > span'));
190
+ this.assertEnumEqual($('level3_1', 'level3_2'), $$('#level2_1 > *'));
191
+ this.assertEnumEqual([], $$('div > #nonexistent'));
192
+ $RunBenchmarks && this.wait(500, function() {
193
+ this.benchmark(function() { $$('#level1 > span') }, 1000);
194
+ });
195
+ },
196
+
197
+ testSelectorWithAdjacence: function() {
198
+ this.assertEnumEqual([$('uncle')], $$('div.brothers + div.brothers'));
199
+ this.assertEnumEqual([$('uncle')], $$('div.brothers + div'));
200
+ this.assertEqual($('level2_2'), reduce($$('#level2_1+span')));
201
+ this.assertEqual($('level2_2'), reduce($$('#level2_1 + span')));
202
+ this.assertEqual($('level2_2'), reduce($$('#level2_1 + *')));
203
+ this.assertEnumEqual([], $$('#level2_2 + span'));
204
+ this.assertEqual($('level3_2'), reduce($$('#level3_1 + span')));
205
+ this.assertEqual($('level3_2'), reduce($$('#level3_1 + *')));
206
+ this.assertEnumEqual([], $$('#level3_2 + *'));
207
+ this.assertEnumEqual([], $$('#level3_1 + em'));
208
+ $RunBenchmarks && this.wait(500, function() {
209
+ this.benchmark(function() { $$('#level3_1 + span') }, 1000);
210
+ });
211
+ },
212
+
213
+ testSelectorWithLaterSibling: function() {
214
+ this.assertEnumEqual([$('list')], $$('h1 ~ ul'));
215
+ this.assertEqual($('level2_2'), reduce($$('#level2_1 ~ span')));
216
+ this.assertEnumEqual($('level2_2', 'level2_3'), reduce($$('#level2_1 ~ *')));
217
+ this.assertEnumEqual([], $$('#level2_2 ~ span'));
218
+ this.assertEnumEqual([], $$('#level3_2 ~ *'));
219
+ this.assertEnumEqual([], $$('#level3_1 ~ em'));
220
+ this.assertEnumEqual([$('level3_2')], $$('#level3_1 ~ #level3_2'));
221
+ this.assertEnumEqual([$('level3_2')], $$('span ~ #level3_2'));
222
+ this.assertEnumEqual([], $$('div ~ #level3_2'));
223
+ this.assertEnumEqual([], $$('div ~ #level2_3'));
224
+ $RunBenchmarks && this.wait(500, function() {
225
+ this.benchmark(function() { $$('#level2_1 ~ span') }, 1000);
226
+ });
227
+ },
228
+
229
+ testSelectorWithNewAttributeOperators: function() {
230
+ this.assertEnumEqual($('father', 'uncle'), $$('div[class^=bro]'), 'matching beginning of string');
231
+ this.assertEnumEqual($('father', 'uncle'), $$('div[class$=men]'), 'matching end of string');
232
+ this.assertEnumEqual($('father', 'uncle'), $$('div[class*="ers m"]'), 'matching substring')
233
+ this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^="level2_"]'));
234
+ this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^=level2_]'));
235
+ this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$="_1"]'));
236
+ this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$=_1]'));
237
+ this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*="2"]'));
238
+ this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*=2]'));
239
+ $RunBenchmarks && this.wait(500, function() {
240
+ this.benchmark(function() { $$('#level1 *[id^=level2_]') }, 1000, '[^=]');
241
+ this.benchmark(function() { $$('#level1 *[id$=_1]') }, 1000, '[$=]');
242
+ this.benchmark(function() { $$('#level1 *[id*=_2]') }, 1000, '[*=]');
243
+ });
244
+ },
245
+
246
+ testSelectorWithDuplicates: function() {
247
+ this.assertEnumEqual($$('div div'), $$('div div').uniq());
248
+ this.assertEnumEqual($('dupL2', 'dupL3', 'dupL4', 'dupL5'), $$('#dupContainer span span'));
249
+ $RunBenchmarks && this.wait(500, function() {
250
+ this.benchmark(function() { $$('#dupContainer span span') }, 1000);
251
+ });
252
+ },
253
+
254
+ testSelectorWithFirstLastOnlyNthNthLastChild: function() {
255
+ this.assertEnumEqual([$('level2_1')], $$('#level1>*:first-child'));
256
+ this.assertEnumEqual($('level2_1', 'level3_1', 'level_only_child'), $$('#level1 *:first-child'));
257
+ this.assertEnumEqual([$('level2_3')], $$('#level1>*:last-child'));
258
+ this.assertEnumEqual($('level3_2', 'level_only_child', 'level2_3'), $$('#level1 *:last-child'));
259
+ this.assertEnumEqual([$('level2_3')], $$('#level1>div:last-child'));
260
+ this.assertEnumEqual([$('level2_3')], $$('#level1 div:last-child'));
261
+ this.assertEnumEqual([], $$('#level1>div:first-child'));
262
+ this.assertEnumEqual([], $$('#level1>span:last-child'));
263
+ this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 span:first-child'));
264
+ this.assertEnumEqual([], $$('#level1:first-child'));
265
+ this.assertEnumEqual([], $$('#level1>*:only-child'));
266
+ this.assertEnumEqual([$('level_only_child')], $$('#level1 *:only-child'));
267
+ this.assertEnumEqual([], $$('#level1:only-child'));
268
+ this.assertEnumEqual([$('link_2')], $$('#p *:nth-last-child(2)'), 'nth-last-child');
269
+ this.assertEnumEqual([$('link_2')], $$('#p *:nth-child(3)'), 'nth-child');
270
+ this.assertEnumEqual([$('link_2')], $$('#p a:nth-child(3)'), 'nth-child');
271
+ this.assertEnumEqual($('item_2', 'item_3'), $$('#list > li:nth-child(n+2)'));
272
+ this.assertEnumEqual($('item_1', 'item_2'), $$('#list > li:nth-child(-n+2)'));
273
+ $RunBenchmarks && this.wait(500, function() {
274
+ this.benchmark(function() { $$('#level1 *:first-child') }, 1000, ':first-child');
275
+ this.benchmark(function() { $$('#level1 *:last-child') }, 1000, ':last-child');
276
+ this.benchmark(function() { $$('#level1 *:only-child') }, 1000, ':only-child');
277
+ });
278
+ },
279
+
280
+ testSelectorWithFirstLastNthNthLastOfType: function() {
281
+ this.assertEnumEqual([$('link_2')], $$('#p a:nth-of-type(2)'), 'nth-of-type');
282
+ this.assertEnumEqual([$('link_1')], $$('#p a:nth-of-type(1)'), 'nth-of-type');
283
+ this.assertEnumEqual([$('link_2')], $$('#p a:nth-last-of-type(1)'), 'nth-last-of-type');
284
+ this.assertEnumEqual([$('link_1')], $$('#p a:first-of-type'), 'first-of-type');
285
+ this.assertEnumEqual([$('link_2')], $$('#p a:last-of-type'), 'last-of-type');
286
+ },
287
+
288
+ testSelectorWithNot: function() {
289
+ this.assertEnumEqual([$('link_2')], $$('#p a:not(a:first-of-type)'), 'first-of-type');
290
+ this.assertEnumEqual([$('link_1')], $$('#p a:not(a:last-of-type)'), 'last-of-type');
291
+ this.assertEnumEqual([$('link_2')], $$('#p a:not(a:nth-of-type(1))'), 'nth-of-type');
292
+ this.assertEnumEqual([$('link_1')], $$('#p a:not(a:nth-last-of-type(1))'), 'nth-last-of-type');
293
+ this.assertEnumEqual([$('link_2')], $$('#p a:not([rel~=nofollow])'), 'attribute 1');
294
+ this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel^=external])'), 'attribute 2');
295
+ this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel$=nofollow])'), 'attribute 3');
296
+ this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) > em'), 'attribute 4')
297
+ this.assertEnumEqual([$('item_2')], $$('#list li:not(#item_1):not(#item_3)'), 'adjacent :not clauses');
298
+ this.assertEnumEqual([$('son')], $$('#grandfather > div:not(#uncle) #son'));
299
+ this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) em'), 'attribute 4 + all descendants');
300
+ this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"])>em'), 'attribute 4 (without whitespace)');
301
+ },
302
+
303
+ testSelectorWithEnabledDisabledChecked: function() {
304
+ this.assertEnumEqual([$('disabled_text_field')], $$('#troubleForm > *:disabled'));
305
+ this.assertEnumEqual($('troubleForm').getInputs().without($('disabled_text_field'), $('hidden')), $$('#troubleForm > *:enabled'));
306
+ this.assertEnumEqual($('checked_box', 'checked_radio'), $$('#troubleForm *:checked'));
307
+ },
308
+
309
+ testSelectorWithEmpty: function() {
310
+ $('level3_1').innerHTML = "";
311
+ this.assertEnumEqual($('level3_1', 'level3_2', 'level2_3'),
312
+ $$('#level1 *:empty'), '#level1 *:empty');
313
+ this.assertEnumEqual([], $$('#level_only_child:empty'), 'newlines count as content!');
314
+ },
315
+
316
+ testIdenticalResultsFromEquivalentSelectors: function() {
317
+ this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers]'));
318
+ this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers].brothers'));
319
+ this.assertEnumEqual($$('div:not(.brothers)'), $$('div:not([class~=brothers])'));
320
+ this.assertEnumEqual($$('li ~ li'), $$('li:not(:first-child)'));
321
+ this.assertEnumEqual($$('ul > li'), $$('ul > li:nth-child(n)'));
322
+ this.assertEnumEqual($$('ul > li:nth-child(even)'), $$('ul > li:nth-child(2n)'));
323
+ this.assertEnumEqual($$('ul > li:nth-child(odd)'), $$('ul > li:nth-child(2n+1)'));
324
+ this.assertEnumEqual($$('ul > li:first-child'), $$('ul > li:nth-child(1)'));
325
+ this.assertEnumEqual($$('ul > li:last-child'), $$('ul > li:nth-last-child(1)'));
326
+ this.assertEnumEqual($$('ul > li:nth-child(n-999)'), $$('ul > li'));
327
+ this.assertEnumEqual($$('ul>li'), $$('ul > li'));
328
+ this.assertEnumEqual($$('#p a:not(a[rel$="nofollow"])>em'), $$('#p a:not(a[rel$="nofollow"]) > em'))
329
+ },
330
+
331
+ testSelectorsThatShouldReturnNothing: function() {
332
+ this.assertEnumEqual([], $$('span:empty > *'));
333
+ this.assertEnumEqual([], $$('div.brothers:not(.brothers)'));
334
+ this.assertEnumEqual([], $$('#level2_2 :only-child:not(:last-child)'));
335
+ this.assertEnumEqual([], $$('#level2_2 :only-child:not(:first-child)'));
336
+ },
337
+
338
+ testCommasFor$$: function() {
339
+ this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,*[xml:lang="es-us"] , #troubleForm'));
340
+ this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,', '*[xml:lang="es-us"] , #troubleForm'));
341
+ this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"], input[value="#commaOne,#commaTwo"]'));
342
+ this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"]', 'input[value="#commaOne,#commaTwo"]'));
343
+ },
344
+
345
+ testSelectorExtendsAllNodes: function(){
346
+ var element = document.createElement('div');
347
+ (3).times(function(){
348
+ element.appendChild(document.createElement('div'));
349
+ });
350
+ element.setAttribute('id','scratch_element');
351
+ $$('body')[0].appendChild(element);
352
+
353
+ var results = $$('#scratch_element div');
354
+ this.assert(typeof results[0].show == 'function');
355
+ this.assert(typeof results[1].show == 'function');
356
+ this.assert(typeof results[2].show == 'function');
357
+ },
358
+
359
+ testCountedIsNotAnAttribute: function() {
360
+ var el = $('list');
361
+ Selector.handlers.mark([el]);
362
+ this.assert(!el.innerHTML.include("_counted"));
363
+ Selector.handlers.unmark([el]);
364
+ this.assert(!el.innerHTML.include("_counted"));
365
+ },
366
+
367
+ testCopiedNodesGetIncluded: function() {
368
+ this.assertElementsMatch(
369
+ Selector.matchElements($('counted_container').descendants(), 'div'),
370
+ 'div.is_counted'
371
+ );
372
+ $('counted_container').innerHTML += $('counted_container').innerHTML;
373
+ this.assertElementsMatch(
374
+ Selector.matchElements($('counted_container').descendants(), 'div'), 'div.is_counted',
375
+ 'div.is_counted'
376
+ );
377
+ },
378
+
379
+ testSelectorNotInsertedNodes: function() {
380
+ window.debug = true;
381
+ var wrapper = new Element("div");
382
+ wrapper.update("<table><tr><td id='myTD'></td></tr></table>");
383
+ this.assertNotNullOrUndefined(wrapper.select('[id=myTD]')[0],
384
+ 'selecting: [id=myTD]');
385
+ this.assertNotNullOrUndefined(wrapper.select('#myTD')[0],
386
+ 'selecting: #myTD');
387
+ this.assertNotNullOrUndefined(wrapper.select('td')[0],
388
+ 'selecting: td');
389
+ this.assert($$('#myTD').length == 0,
390
+ 'should not turn up in document-rooted search');
391
+ window.debug = false;
392
+ },
393
+
394
+ testElementDown: function() {
395
+ var a = $('dupL4');
396
+ var b = $('dupContainer').down('#dupL4');
397
+
398
+ this.assertEqual(a, b);
399
+ },
400
+
401
+ testDescendantSelectorBuggy: function() {
402
+ var el = document.createElement('div');
403
+ el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
404
+ document.body.appendChild(el);
405
+ this.assertEqual(2, $(el).select('ul li').length);
406
+ document.body.removeChild(el);
407
+ }
408
+ });