jbarnette-johnson 1.0.0.200806240111
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/MANIFEST +385 -0
- data/MINGW32.mk +124 -0
- data/README.rdoc +51 -0
- data/Rakefile +166 -0
- data/bin/johnson +107 -0
- data/cross-compile.txt +38 -0
- data/ext/spidermonkey/context.c +122 -0
- data/ext/spidermonkey/context.h +19 -0
- data/ext/spidermonkey/conversions.c +286 -0
- data/ext/spidermonkey/conversions.h +18 -0
- data/ext/spidermonkey/debugger.c +208 -0
- data/ext/spidermonkey/debugger.h +9 -0
- data/ext/spidermonkey/extconf.rb +25 -0
- data/ext/spidermonkey/extensions.c +37 -0
- data/ext/spidermonkey/extensions.h +12 -0
- data/ext/spidermonkey/global.c +40 -0
- data/ext/spidermonkey/global.h +11 -0
- data/ext/spidermonkey/idhash.c +16 -0
- data/ext/spidermonkey/idhash.h +8 -0
- data/ext/spidermonkey/immutable_node.c.erb +522 -0
- data/ext/spidermonkey/immutable_node.h +22 -0
- data/ext/spidermonkey/jroot.h +187 -0
- data/ext/spidermonkey/js_land_proxy.c +609 -0
- data/ext/spidermonkey/js_land_proxy.h +20 -0
- data/ext/spidermonkey/ruby_land_proxy.c +537 -0
- data/ext/spidermonkey/ruby_land_proxy.h +17 -0
- data/ext/spidermonkey/runtime.c +304 -0
- data/ext/spidermonkey/runtime.h +25 -0
- data/ext/spidermonkey/spidermonkey.c +20 -0
- data/ext/spidermonkey/spidermonkey.h +29 -0
- data/js/johnson/browser.js +9 -0
- data/js/johnson/browser/env.js +687 -0
- data/js/johnson/browser/jquery.js +3444 -0
- data/js/johnson/browser/xmlsax.js +1564 -0
- data/js/johnson/browser/xmlw3cdom.js +4189 -0
- data/js/johnson/cli.js +30 -0
- data/js/johnson/prelude.js +80 -0
- data/js/johnson/template.js +29 -0
- data/lib/hoe.rb +748 -0
- data/lib/johnson.rb +46 -0
- data/lib/johnson/cli.rb +7 -0
- data/lib/johnson/cli/options.rb +56 -0
- data/lib/johnson/error.rb +4 -0
- data/lib/johnson/nodes.rb +7 -0
- data/lib/johnson/nodes/binary_node.rb +64 -0
- data/lib/johnson/nodes/for.rb +14 -0
- data/lib/johnson/nodes/for_in.rb +12 -0
- data/lib/johnson/nodes/function.rb +13 -0
- data/lib/johnson/nodes/list.rb +27 -0
- data/lib/johnson/nodes/node.rb +68 -0
- data/lib/johnson/nodes/ternary_node.rb +20 -0
- data/lib/johnson/parser.rb +21 -0
- data/lib/johnson/parser/syntax_error.rb +13 -0
- data/lib/johnson/runtime.rb +55 -0
- data/lib/johnson/spidermonkey/context.rb +10 -0
- data/lib/johnson/spidermonkey/debugger.rb +67 -0
- data/lib/johnson/spidermonkey/immutable_node.rb +280 -0
- data/lib/johnson/spidermonkey/js_land_proxy.rb +62 -0
- data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +233 -0
- data/lib/johnson/spidermonkey/ruby_land_proxy.rb +52 -0
- data/lib/johnson/spidermonkey/runtime.rb +94 -0
- data/lib/johnson/version.rb +4 -0
- data/lib/johnson/visitable.rb +16 -0
- data/lib/johnson/visitors.rb +4 -0
- data/lib/johnson/visitors/dot_visitor.rb +167 -0
- data/lib/johnson/visitors/ecma_visitor.rb +315 -0
- data/lib/johnson/visitors/enumerating_visitor.rb +115 -0
- data/lib/johnson/visitors/sexp_visitor.rb +172 -0
- data/lib/rails/init.rb +37 -0
- data/test/assets/index.html +38 -0
- data/test/assets/jquery_test.html +186 -0
- data/test/helper.rb +58 -0
- data/test/johnson/browser_test.rb +38 -0
- data/test/johnson/conversions/array_test.rb +32 -0
- data/test/johnson/conversions/boolean_test.rb +17 -0
- data/test/johnson/conversions/callable_test.rb +34 -0
- data/test/johnson/conversions/file_test.rb +15 -0
- data/test/johnson/conversions/nil_test.rb +20 -0
- data/test/johnson/conversions/number_test.rb +34 -0
- data/test/johnson/conversions/regexp_test.rb +24 -0
- data/test/johnson/conversions/string_test.rb +26 -0
- data/test/johnson/conversions/struct_test.rb +15 -0
- data/test/johnson/conversions/symbol_test.rb +19 -0
- data/test/johnson/conversions/thread_test.rb +24 -0
- data/test/johnson/error_test.rb +9 -0
- data/test/johnson/extensions_test.rb +56 -0
- data/test/johnson/nodes/array_literal_test.rb +57 -0
- data/test/johnson/nodes/array_node_test.rb +26 -0
- data/test/johnson/nodes/binary_node_test.rb +61 -0
- data/test/johnson/nodes/bracket_access_test.rb +16 -0
- data/test/johnson/nodes/delete_test.rb +11 -0
- data/test/johnson/nodes/do_while_test.rb +12 -0
- data/test/johnson/nodes/dot_accessor_test.rb +15 -0
- data/test/johnson/nodes/export_test.rb +9 -0
- data/test/johnson/nodes/for_test.rb +54 -0
- data/test/johnson/nodes/function_test.rb +71 -0
- data/test/johnson/nodes/if_test.rb +41 -0
- data/test/johnson/nodes/import_test.rb +13 -0
- data/test/johnson/nodes/label_test.rb +19 -0
- data/test/johnson/nodes/object_literal_test.rb +110 -0
- data/test/johnson/nodes/return_test.rb +16 -0
- data/test/johnson/nodes/semi_test.rb +8 -0
- data/test/johnson/nodes/switch_test.rb +55 -0
- data/test/johnson/nodes/ternary_test.rb +25 -0
- data/test/johnson/nodes/throw_test.rb +9 -0
- data/test/johnson/nodes/try_node_test.rb +59 -0
- data/test/johnson/nodes/typeof_test.rb +11 -0
- data/test/johnson/nodes/unary_node_test.rb +23 -0
- data/test/johnson/nodes/void_test.rb +11 -0
- data/test/johnson/nodes/while_test.rb +26 -0
- data/test/johnson/nodes/with_test.rb +10 -0
- data/test/johnson/prelude_test.rb +56 -0
- data/test/johnson/runtime_test.rb +46 -0
- data/test/johnson/spidermonkey/context_test.rb +21 -0
- data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
- data/test/johnson/spidermonkey/js_land_proxy_test.rb +236 -0
- data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +225 -0
- data/test/johnson/spidermonkey/runtime_test.rb +17 -0
- data/test/johnson/version_test.rb +13 -0
- data/test/johnson/visitors/dot_visitor_test.rb +39 -0
- data/test/johnson/visitors/enumerating_visitor_test.rb +12 -0
- data/test/johnson_test.rb +16 -0
- data/test/jquery_units/test.js +27 -0
- data/test/jquery_units/test_helper.js +197 -0
- data/test/jquery_units/units/ajax.js +795 -0
- data/test/jquery_units/units/core.js +1563 -0
- data/test/jquery_units/units/event.js +299 -0
- data/test/jquery_units/units/fx.js +427 -0
- data/test/jquery_units/units/offset.js +112 -0
- data/test/jquery_units/units/selector.js +224 -0
- data/test/jspec/helper.js +7 -0
- data/test/jspec/jspec.js +192 -0
- data/test/jspec/simple_spec.js +68 -0
- data/test/parser_test.rb +276 -0
- data/todo/.keep +0 -0
- metadata +501 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module("offset");
|
2
|
+
|
3
|
+
// opens a new window to run the tests against
|
4
|
+
var testwin = function(name, fn) {
|
5
|
+
testwin[name] = load_offset_fixture(name);
|
6
|
+
var interval = setInterval(function() {
|
7
|
+
if (testwin[name] && testwin[name].$ && testwin[name].$.isReady) {
|
8
|
+
clearInterval(interval);
|
9
|
+
test(name, fn);
|
10
|
+
}
|
11
|
+
}, 0);
|
12
|
+
|
13
|
+
function load_offset_fixture(name) {
|
14
|
+
var win = window.open( "./data/offset/" + name + ".html?num"+parseInt(Math.random()*1000), name, 'left=0,top=0,width=500,height=500,toolbar=1,resizable=0' );
|
15
|
+
if ( !win ) {
|
16
|
+
alert("Please disable your popup blocker for the offset test suite");
|
17
|
+
throw "Please disable your popup blocker for the offset test suite";
|
18
|
+
}
|
19
|
+
return win;
|
20
|
+
}
|
21
|
+
};
|
22
|
+
|
23
|
+
testwin("absolute", function() {
|
24
|
+
var $w = testwin["absolute"].$;
|
25
|
+
|
26
|
+
equals( $w('#absolute-1').offset().top, 1, "$('#absolute-1').offset().top" );
|
27
|
+
equals( $w('#absolute-1').offset().left, 1, "$('#absolute-1').offset().left" );
|
28
|
+
|
29
|
+
equals( $w('#absolute-1-1').offset().top, 5, "$('#absolute-1-1').offset().top" );
|
30
|
+
equals( $w('#absolute-1-1').offset().left, 5, "$('#absolute-1-1').offset().left" );
|
31
|
+
|
32
|
+
equals( $w('#absolute-1-1-1').offset().top, 9, "$('#absolute-1-1-1').offset().top" );
|
33
|
+
equals( $w('#absolute-1-1-1').offset().left, 9, "$('#absolute-1-1-1').offset().left" );
|
34
|
+
|
35
|
+
equals( $w('#absolute-2').offset().top, 20, "$('#absolute-2').offset().top" );
|
36
|
+
equals( $w('#absolute-2').offset().left, 20, "$('#absolute-2').offset().left" );
|
37
|
+
|
38
|
+
testwin["absolute"].close();
|
39
|
+
});
|
40
|
+
|
41
|
+
testwin("relative", function() {
|
42
|
+
var $w = testwin["relative"].$;
|
43
|
+
|
44
|
+
equals( $w('#relative-1').offset().top, $.browser.msie ? 6 : 7, "$('#relative-1').offset().top" );
|
45
|
+
equals( $w('#relative-1').offset().left, 7, "$('#relative-1').offset().left" );
|
46
|
+
|
47
|
+
equals( $w('#relative-1-1').offset().top, $.browser.msie ? 13 : 15, "$('#relative-1-1').offset().top" );
|
48
|
+
equals( $w('#relative-1-1').offset().left, 15, "$('#relative-1-1').offset().left" );
|
49
|
+
|
50
|
+
equals( $w('#relative-2').offset().top, $.browser.msie ? 141 : 142, "$('#relative-2').offset().top" );
|
51
|
+
equals( $w('#relative-2').offset().left, 27, "$('#relative-2').offset().left" );
|
52
|
+
|
53
|
+
testwin["relative"].close();
|
54
|
+
});
|
55
|
+
|
56
|
+
testwin("static", function() {
|
57
|
+
var $w = testwin["static"].$;
|
58
|
+
|
59
|
+
equals( $w('#static-1').offset().top, $.browser.msie ? 6 : 7, "$('#static-1').offset().top" );
|
60
|
+
equals( $w('#static-1').offset().left, 7, "$('#static-1').offset().left" );
|
61
|
+
|
62
|
+
equals( $w('#static-1-1').offset().top, $.browser.msie ? 13 : 15, "$('#static-1-1').offset().top" );
|
63
|
+
equals( $w('#static-1-1').offset().left, 15, "$('#static-1-1').offset().left" );
|
64
|
+
|
65
|
+
equals( $w('#static-1-1-1').offset().top, $.browser.msie ? 20 : 23, "$('#static-1-1-1').offset().top" );
|
66
|
+
equals( $w('#static-1-1-1').offset().left, 23, "$('#static-1-1-1').offset().left" );
|
67
|
+
|
68
|
+
equals( $w('#static-2').offset().top, $.browser.msie ? 121 : 122, "$('#static-2').offset().top" );
|
69
|
+
equals( $w('#static-2').offset().left, 7, "$('#static-2').offset().left" );
|
70
|
+
|
71
|
+
testwin["static"].close();
|
72
|
+
});
|
73
|
+
|
74
|
+
if ( !$.browser.msie || ($.browser.msie && parseInt($.browser.version) > 6) )
|
75
|
+
testwin("fixed", function() {
|
76
|
+
var $w = testwin["fixed"].$;
|
77
|
+
|
78
|
+
equals( $w('#fixed-1').offset().top, 1001, "$('#fixed-1').offset().top" );
|
79
|
+
equals( $w('#fixed-1').offset().left, $.browser.msie ? 994 : 1001, "$('#fixed-1').offset().left" );
|
80
|
+
|
81
|
+
equals( $w('#fixed-2').offset().top, 1021, "$('#fixed-2').offset().top" );
|
82
|
+
equals( $w('#fixed-2').offset().left, $.browser.msie ? 1014 : 1021, "$('#fixed-2').offset().left" );
|
83
|
+
|
84
|
+
testwin["fixed"].close();
|
85
|
+
});
|
86
|
+
|
87
|
+
testwin("table", function() {
|
88
|
+
var $w = testwin["table"].$;
|
89
|
+
|
90
|
+
equals( $w('#table-1').offset().top, 6, "$('#table-1').offset().top" );
|
91
|
+
equals( $w('#table-1').offset().left, 6, "$('#table-1').offset().left" );
|
92
|
+
|
93
|
+
equals( $w('#th-1').offset().top, 10, "$('#table-1').offset().top" );
|
94
|
+
equals( $w('#th-1').offset().left, 10, "$('#table-1').offset().left" );
|
95
|
+
|
96
|
+
equals( $w('#th-2').offset().top, 10, "$('#table-1').offset().top" );
|
97
|
+
equals( $w('#th-2').offset().left, 116, "$('#table-1').offset().left" );
|
98
|
+
|
99
|
+
testwin["table"].close();
|
100
|
+
});
|
101
|
+
|
102
|
+
testwin("scroll", function() {
|
103
|
+
var $w = testwin["scroll"].$;
|
104
|
+
|
105
|
+
equals( $w('#scroll-1').offset().top, $.browser.msie ? 6 : 7, "$('#scroll-1').offset().top" );
|
106
|
+
equals( $w('#scroll-1').offset().left, 7, "$('#scroll-1').offset().left" );
|
107
|
+
|
108
|
+
equals( $w('#scroll-1-1').offset().top, $.browser.msie ? 9 : 11, "$('#scroll-1-1').offset().top" );
|
109
|
+
equals( $w('#scroll-1-1').offset().left, 11, "$('#scroll-1-1').offset().left" );
|
110
|
+
|
111
|
+
testwin["scroll"].close();
|
112
|
+
});
|
@@ -0,0 +1,224 @@
|
|
1
|
+
module("selector");
|
2
|
+
|
3
|
+
test("element", function() {
|
4
|
+
expect(9);
|
5
|
+
ok( $("*").size() >= 30, "Select all" );
|
6
|
+
var all = $("*"), good = true;
|
7
|
+
for ( var i = 0; i < all.length; i++ )
|
8
|
+
if ( all[i].nodeType == 8 )
|
9
|
+
good = false;
|
10
|
+
ok( good, "Select all elements, no comment nodes" );
|
11
|
+
t( "Element Selector", "p", ["firstp","ap","sndp","en","sap","first"] );
|
12
|
+
t( "Element Selector", "body", ["body"] );
|
13
|
+
t( "Element Selector", "html", ["html"] );
|
14
|
+
t( "Parent Element", "div p", ["firstp","ap","sndp","en","sap","first"] );
|
15
|
+
ok( $("param", "#object1").length == 2, "Object/param as context" );
|
16
|
+
|
17
|
+
ok( $("#length").length, '<input name="length"> cannot be found under IE, see #945' );
|
18
|
+
ok( $("#lengthtest input").length, '<input name="length"> cannot be found under IE, see #945' );
|
19
|
+
});
|
20
|
+
|
21
|
+
if ( location.protocol != "file:" ) {
|
22
|
+
test("Element Selector with underscore", function() {
|
23
|
+
expect(1);
|
24
|
+
stop();
|
25
|
+
$.get("data/with_fries.xml", function(xml) {
|
26
|
+
ok( $("foo_bar", xml).length == 1, "Element Selector with underscore" );
|
27
|
+
start();
|
28
|
+
});
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
test("broken", function() {
|
33
|
+
expect(7);
|
34
|
+
t( "Broken Selector", "[", [] );
|
35
|
+
t( "Broken Selector", "(", [] );
|
36
|
+
t( "Broken Selector", "{", [] );
|
37
|
+
t( "Broken Selector", "<", [] );
|
38
|
+
t( "Broken Selector", "()", [] );
|
39
|
+
t( "Broken Selector", "<>", [] );
|
40
|
+
t( "Broken Selector", "{}", [] );
|
41
|
+
});
|
42
|
+
|
43
|
+
test("id", function() {
|
44
|
+
expect(25);
|
45
|
+
t( "ID Selector", "#body", ["body"] );
|
46
|
+
t( "ID Selector w/ Element", "body#body", ["body"] );
|
47
|
+
t( "ID Selector w/ Element", "ul#first", [] );
|
48
|
+
t( "ID selector with existing ID descendant", "#firstp #simon1", ["simon1"] );
|
49
|
+
t( "ID selector with non-existant descendant", "#firstp #foobar", [] );
|
50
|
+
t( "ID selector using UTF8", "#台北Táiběi", ["台北Táiběi"] );
|
51
|
+
t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] );
|
52
|
+
t( "Descendant ID selector using UTF8", "div #台北", ["台北"] );
|
53
|
+
t( "Child ID selector using UTF8", "form > #台北", ["台北"] );
|
54
|
+
|
55
|
+
t( "Escaped ID", "#foo\\:bar", ["foo:bar"] );
|
56
|
+
t( "Escaped ID", "#test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
57
|
+
t( "Descendant escaped ID", "div #foo\\:bar", ["foo:bar"] );
|
58
|
+
t( "Descendant escaped ID", "div #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
59
|
+
t( "Child escaped ID", "form > #foo\\:bar", ["foo:bar"] );
|
60
|
+
t( "Child escaped ID", "form > #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
61
|
+
|
62
|
+
t( "ID Selector, child ID present", "#form > #radio1", ["radio1"] ); // bug #267
|
63
|
+
t( "ID Selector, not an ancestor ID", "#form #first", [] );
|
64
|
+
t( "ID Selector, not a child ID", "#form > #option1a", [] );
|
65
|
+
|
66
|
+
t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] );
|
67
|
+
t( "All Children of ID with no children", "#firstUL/*", [] );
|
68
|
+
|
69
|
+
$('<a name="tName1">tName1 A</a><a name="tName2">tName2 A</a><div id="tName1">tName1 Div</div>').appendTo('#main');
|
70
|
+
ok( $("#tName1")[0].id == 'tName1', "ID selector with same value for a name attribute" );
|
71
|
+
ok( $("#tName2").length == 0, "ID selector non-existing but name attribute on an A tag" );
|
72
|
+
t( "ID Selector on Form with an input that has a name of 'id'", "#lengthtest", ["lengthtest"] );
|
73
|
+
|
74
|
+
t( "ID selector with non-existant ancestor", "#asdfasdf #foobar", [] ); // bug #986
|
75
|
+
|
76
|
+
isSet( $("body").find("div#form"), [], "ID selector within the context of another element" );
|
77
|
+
});
|
78
|
+
|
79
|
+
test("class", function() {
|
80
|
+
expect(16);
|
81
|
+
t( "Class Selector", ".blog", ["mark","simon"] );
|
82
|
+
t( "Class Selector", ".blog.link", ["simon"] );
|
83
|
+
t( "Class Selector w/ Element", "a.blog", ["mark","simon"] );
|
84
|
+
t( "Parent Class Selector", "p .blog", ["mark","simon"] );
|
85
|
+
|
86
|
+
t( "Class selector using UTF8", ".台北Táiběi", ["utf8class1"] );
|
87
|
+
t( "Class selector using UTF8", ".台北", ["utf8class1","utf8class2"] );
|
88
|
+
t( "Class selector using UTF8", ".台北Táiběi.台北", ["utf8class1"] );
|
89
|
+
t( "Class selector using UTF8", ".台北Táiběi, .台北", ["utf8class1","utf8class2"] );
|
90
|
+
t( "Descendant class selector using UTF8", "div .台北Táiběi", ["utf8class1"] );
|
91
|
+
t( "Child class selector using UTF8", "form > .台北Táiběi", ["utf8class1"] );
|
92
|
+
|
93
|
+
t( "Escaped Class", ".foo\\:bar", ["foo:bar"] );
|
94
|
+
t( "Escaped Class", ".test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
95
|
+
t( "Descendant scaped Class", "div .foo\\:bar", ["foo:bar"] );
|
96
|
+
t( "Descendant scaped Class", "div .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
97
|
+
t( "Child escaped Class", "form > .foo\\:bar", ["foo:bar"] );
|
98
|
+
t( "Child escaped Class", "form > .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
|
99
|
+
});
|
100
|
+
|
101
|
+
test("multiple", function() {
|
102
|
+
expect(4);
|
103
|
+
t( "Comma Support", "a.blog, p", ["mark","simon","firstp","ap","sndp","en","sap","first"] );
|
104
|
+
t( "Comma Support", "a.blog , p", ["mark","simon","firstp","ap","sndp","en","sap","first"] );
|
105
|
+
t( "Comma Support", "a.blog ,p", ["mark","simon","firstp","ap","sndp","en","sap","first"] );
|
106
|
+
t( "Comma Support", "a.blog,p", ["mark","simon","firstp","ap","sndp","en","sap","first"] );
|
107
|
+
});
|
108
|
+
|
109
|
+
test("child and adjacent", function() {
|
110
|
+
expect(37);
|
111
|
+
t( "Child", "p > a", ["simon1","google","groups","mark","yahoo","simon"] );
|
112
|
+
t( "Child", "p> a", ["simon1","google","groups","mark","yahoo","simon"] );
|
113
|
+
t( "Child", "p >a", ["simon1","google","groups","mark","yahoo","simon"] );
|
114
|
+
t( "Child", "p>a", ["simon1","google","groups","mark","yahoo","simon"] );
|
115
|
+
t( "Child w/ Class", "p > a.blog", ["mark","simon"] );
|
116
|
+
t( "All Children", "code > *", ["anchor1","anchor2"] );
|
117
|
+
t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] );
|
118
|
+
t( "Adjacent", "a + a", ["groups"] );
|
119
|
+
t( "Adjacent", "a +a", ["groups"] );
|
120
|
+
t( "Adjacent", "a+ a", ["groups"] );
|
121
|
+
t( "Adjacent", "a+a", ["groups"] );
|
122
|
+
t( "Adjacent", "p + p", ["ap","en","sap"] );
|
123
|
+
t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] );
|
124
|
+
|
125
|
+
t( "First Child", "p:first-child", ["firstp","sndp"] );
|
126
|
+
t( "Nth Child", "p:nth-child(1)", ["firstp","sndp"] );
|
127
|
+
|
128
|
+
t( "Last Child", "p:last-child", ["sap"] );
|
129
|
+
t( "Last Child", "a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon"] );
|
130
|
+
|
131
|
+
t( "Nth-child", "#main form#form > *:nth-child(2)", ["text2"] );
|
132
|
+
t( "Nth-child", "#main form#form > :nth-child(2)", ["text2"] );
|
133
|
+
|
134
|
+
t( "Nth-child", "#form select:first option:nth-child(3)", ["option1c"] );
|
135
|
+
t( "Nth-child", "#form select:first option:nth-child(0n+3)", ["option1c"] );
|
136
|
+
t( "Nth-child", "#form select:first option:nth-child(1n+0)", ["option1a", "option1b", "option1c", "option1d"] );
|
137
|
+
t( "Nth-child", "#form select:first option:nth-child(1n)", ["option1a", "option1b", "option1c", "option1d"] );
|
138
|
+
t( "Nth-child", "#form select:first option:nth-child(n)", ["option1a", "option1b", "option1c", "option1d"] );
|
139
|
+
t( "Nth-child", "#form select:first option:nth-child(even)", ["option1b", "option1d"] );
|
140
|
+
t( "Nth-child", "#form select:first option:nth-child(odd)", ["option1a", "option1c"] );
|
141
|
+
t( "Nth-child", "#form select:first option:nth-child(2n)", ["option1b", "option1d"] );
|
142
|
+
t( "Nth-child", "#form select:first option:nth-child(2n+1)", ["option1a", "option1c"] );
|
143
|
+
t( "Nth-child", "#form select:first option:nth-child(3n)", ["option1c"] );
|
144
|
+
t( "Nth-child", "#form select:first option:nth-child(3n+1)", ["option1a", "option1d"] );
|
145
|
+
t( "Nth-child", "#form select:first option:nth-child(3n+2)", ["option1b"] );
|
146
|
+
t( "Nth-child", "#form select:first option:nth-child(3n+3)", ["option1c"] );
|
147
|
+
t( "Nth-child", "#form select:first option:nth-child(3n-1)", ["option1b"] );
|
148
|
+
t( "Nth-child", "#form select:first option:nth-child(3n-2)", ["option1a", "option1d"] );
|
149
|
+
t( "Nth-child", "#form select:first option:nth-child(3n-3)", ["option1c"] );
|
150
|
+
t( "Nth-child", "#form select:first option:nth-child(3n+0)", ["option1c"] );
|
151
|
+
t( "Nth-child", "#form select:first option:nth-child(-n+3)", ["option1a", "option1b", "option1c"] );
|
152
|
+
});
|
153
|
+
|
154
|
+
test("attributes", function() {
|
155
|
+
expect(20);
|
156
|
+
t( "Attribute Exists", "a[title]", ["google"] );
|
157
|
+
t( "Attribute Exists", "*[title]", ["google"] );
|
158
|
+
t( "Attribute Exists", "[title]", ["google"] );
|
159
|
+
|
160
|
+
t( "Attribute Equals", "a[rel='bookmark']", ["simon1"] );
|
161
|
+
t( "Attribute Equals", 'a[rel="bookmark"]', ["simon1"] );
|
162
|
+
t( "Attribute Equals", "a[rel=bookmark]", ["simon1"] );
|
163
|
+
t( "Multiple Attribute Equals", "#form input[type='hidden'],#form input[type='radio']", ["hidden1","radio1","radio2"] );
|
164
|
+
t( "Multiple Attribute Equals", "#form input[type=\"hidden\"],#form input[type='radio']", ["hidden1","radio1","radio2"] );
|
165
|
+
t( "Multiple Attribute Equals", "#form input[type=hidden],#form input[type=radio]", ["hidden1","radio1","radio2"] );
|
166
|
+
|
167
|
+
t( "Attribute selector using UTF8", "span[lang=中文]", ["台北"] );
|
168
|
+
|
169
|
+
t( "Attribute Begins With", "a[href ^= 'http://www']", ["google","yahoo"] );
|
170
|
+
t( "Attribute Ends With", "a[href $= 'org/']", ["mark"] );
|
171
|
+
t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] );
|
172
|
+
|
173
|
+
t("Select options via [selected]", "#select1 option[selected]", ["option1a"] );
|
174
|
+
t("Select options via [selected]", "#select2 option[selected]", ["option2d"] );
|
175
|
+
t("Select options via [selected]", "#select3 option[selected]", ["option3b", "option3c"] );
|
176
|
+
|
177
|
+
t( "Grouped Form Elements", "input[name='foo[bar]']", ["hidden2"] );
|
178
|
+
|
179
|
+
t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2"]);
|
180
|
+
t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3"]);
|
181
|
+
t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3"]);
|
182
|
+
});
|
183
|
+
|
184
|
+
test("pseudo (:) selectors", function() {
|
185
|
+
expect(35);
|
186
|
+
t( "First Child", "p:first-child", ["firstp","sndp"] );
|
187
|
+
t( "Last Child", "p:last-child", ["sap"] );
|
188
|
+
t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] );
|
189
|
+
t( "Empty", "ul:empty", ["firstUL"] );
|
190
|
+
t( "Enabled UI Element", "#form input:enabled", ["text1","radio1","radio2","check1","check2","hidden1","hidden2","name"] );
|
191
|
+
t( "Disabled UI Element", "#form input:disabled", ["text2"] );
|
192
|
+
t( "Checked UI Element", "#form input:checked", ["radio2","check1"] );
|
193
|
+
t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c"] );
|
194
|
+
t( "Text Contains", "a:contains('Google')", ["google","groups"] );
|
195
|
+
t( "Text Contains", "a:contains('Google Groups')", ["groups"] );
|
196
|
+
t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests"] );
|
197
|
+
t( "Not", "a.blog:not(.link)", ["mark"] );
|
198
|
+
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d"] );
|
199
|
+
t( "Not - complex", "#form option:not([id^='opt']:gt(0):nth-child(-n+3))", [ "option1a", "option1d", "option2d", "option3d"] );
|
200
|
+
t( "Not - recursive", "#form option:not(:not(:selected))[id^='option3']", [ "option3b", "option3c"] );
|
201
|
+
|
202
|
+
t( "nth Element", "p:nth(1)", ["ap"] );
|
203
|
+
t( "First Element", "p:first", ["firstp"] );
|
204
|
+
t( "Last Element", "p:last", ["first"] );
|
205
|
+
t( "Even Elements", "p:even", ["firstp","sndp","sap"] );
|
206
|
+
t( "Odd Elements", "p:odd", ["ap","en","first"] );
|
207
|
+
t( "Position Equals", "p:eq(1)", ["ap"] );
|
208
|
+
t( "Position Greater Than", "p:gt(0)", ["ap","sndp","en","sap","first"] );
|
209
|
+
t( "Position Less Than", "p:lt(3)", ["firstp","ap","sndp"] );
|
210
|
+
t( "Is A Parent", "p:parent", ["firstp","ap","sndp","en","sap","first"] );
|
211
|
+
t( "Is Visible", "#form input:visible", ["text1","text2","radio1","radio2","check1","check2","name"] );
|
212
|
+
t( "Is Hidden", "#form input:hidden", ["hidden1","hidden2"] );
|
213
|
+
|
214
|
+
t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "button", "area1", "select1", "select2", "select3"] );
|
215
|
+
t( "Form element :radio", "#form :radio", ["radio1", "radio2"] );
|
216
|
+
t( "Form element :checkbox", "#form :checkbox", ["check1", "check2"] );
|
217
|
+
t( "Form element :text", "#form :text", ["text1", "text2", "hidden2", "name"] );
|
218
|
+
t( "Form element :radio:checked", "#form :radio:checked", ["radio2"] );
|
219
|
+
t( "Form element :checkbox:checked", "#form :checkbox:checked", ["check1"] );
|
220
|
+
t( "Form element :checkbox:checked, :radio:checked", "#form :checkbox:checked, #form :radio:checked", ["check1", "radio2"] );
|
221
|
+
|
222
|
+
t( "Headers", ":header", ["header", "banner", "userAgent"] );
|
223
|
+
t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );
|
224
|
+
});
|
data/test/jspec/jspec.js
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
console = {
|
2
|
+
indentation: 0,
|
3
|
+
indent: function() {
|
4
|
+
for(i=0;i<this.indentation - 1;i++) Ruby.print(" ");
|
5
|
+
if(this.indentation > 0) Ruby.print("- ");
|
6
|
+
},
|
7
|
+
group: function(msg) {
|
8
|
+
this.info(msg);
|
9
|
+
this.indentation += 1;
|
10
|
+
},
|
11
|
+
info: function(msg) {
|
12
|
+
this.indent();
|
13
|
+
Ruby.puts(msg);
|
14
|
+
},
|
15
|
+
error: function(msg) {
|
16
|
+
this.info("F " + msg);
|
17
|
+
},
|
18
|
+
warn: function(msg) {
|
19
|
+
this.info("W " + msg);
|
20
|
+
},
|
21
|
+
groupEnd: function() {
|
22
|
+
this.indentation -= 1;
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
jspec = {
|
27
|
+
fn_contents: function(fn) {
|
28
|
+
return fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
|
29
|
+
},
|
30
|
+
TOP_LEVEL: 0, DESCRIBE: 1, IT_SHOULD_PASS: 2, IT_SHOULD_FAIL: 3,
|
31
|
+
FAILURE: 4, DONE_EXAMPLE: 5, DONE_GROUP: 6, PENDING: 7,
|
32
|
+
logger: function(state, message) {
|
33
|
+
switch(state) {
|
34
|
+
case jspec.TOP_LEVEL:
|
35
|
+
console.group(message);
|
36
|
+
break;
|
37
|
+
case jspec.DESCRIBE:
|
38
|
+
console.group(message);
|
39
|
+
break;
|
40
|
+
case jspec.IT_SHOULD_PASS:
|
41
|
+
console.info(message);
|
42
|
+
break;
|
43
|
+
case jspec.IT_SHOULD_FAIL:
|
44
|
+
console.group(message);
|
45
|
+
break;
|
46
|
+
case jspec.FAILURE:
|
47
|
+
console.error(message);
|
48
|
+
console.groupEnd();
|
49
|
+
break;
|
50
|
+
case jspec.DONE_EXAMPLE:
|
51
|
+
console.groupEnd();
|
52
|
+
break;
|
53
|
+
case jspec.DONE_GROUP:
|
54
|
+
console.groupEnd();
|
55
|
+
break;
|
56
|
+
case jspec.PENDING:
|
57
|
+
console.warn("Pending: " + message);
|
58
|
+
break;
|
59
|
+
}
|
60
|
+
|
61
|
+
},
|
62
|
+
describe: function(str, desc) {
|
63
|
+
jspec.logger(jspec.TOP_LEVEL, str);
|
64
|
+
var it = function(str, fn) {
|
65
|
+
if(fn) {
|
66
|
+
jspec.logger(jspec.DESCRIBE, str);
|
67
|
+
fn();
|
68
|
+
jspec.logger(jspec.DONE_EXAMPLE);
|
69
|
+
} else {
|
70
|
+
jspec.logger(jspec.PENDING, str);
|
71
|
+
};
|
72
|
+
};
|
73
|
+
var Expectation = function(p) { this.expectation = p; };
|
74
|
+
Expectation.prototype.to = function(fn_str, to_compare, not) {
|
75
|
+
try {
|
76
|
+
var pass = jspec.matchers[fn_str].matches(this.expectation, to_compare);
|
77
|
+
if(not) var pass = !pass;
|
78
|
+
} catch(e) {
|
79
|
+
var pass = null;
|
80
|
+
}
|
81
|
+
var should_string = (jspec.matchers[fn_str].describe &&
|
82
|
+
jspec.matchers[fn_str].describe(this.expectation, to_compare, not)) ||
|
83
|
+
this.toString() + " should " + (not ? "not " : "") + fn_str + " " + to_compare;
|
84
|
+
if(pass) {
|
85
|
+
jspec.logger(jspec.IT_SHOULD_PASS, should_string + " (PASS)");
|
86
|
+
} else {
|
87
|
+
jspec.logger(jspec.IT_SHOULD_FAIL, should_string + (pass == false ? " (FAIL)" : " (ERROR)"));
|
88
|
+
jspec.logger(jspec.FAILURE, jspec.matchers[fn_str].failure_message(this.expectation, to_compare, not))
|
89
|
+
}
|
90
|
+
}
|
91
|
+
Expectation.prototype.not_to = function(fn_str, to_compare) { this.to(fn_str, to_compare, true) }
|
92
|
+
var expect = function(p) { return new Expectation(p) };
|
93
|
+
x = desc.toString()
|
94
|
+
var fn_body = this.fn_contents(desc);
|
95
|
+
var fn = new Function("it", "expect", fn_body);
|
96
|
+
fn.call(this, it, expect);
|
97
|
+
jspec.logger(jspec.DONE_GROUP);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
// Helper for
|
102
|
+
|
103
|
+
jspec.print_object = function(obj) {
|
104
|
+
if(obj instanceof Function) {
|
105
|
+
return obj.toString().match(/^([^\{]*) {/)[1];
|
106
|
+
} else if(obj instanceof Array) {
|
107
|
+
return "[" + obj.toString() + "]";
|
108
|
+
} else if(typeof HTMLElement != "undefined" && obj instanceof HTMLElement) {
|
109
|
+
return "<" + obj.tagName + (obj.className != "" ? " class='" + obj.className + "'" : "") +
|
110
|
+
(obj.id != "" ? " id='" + obj.id + "'" : "") + ">";
|
111
|
+
} else if(typeof DOMDocument != "undefined" && obj instanceof DOMDocument) {
|
112
|
+
return "The document element";
|
113
|
+
} else {
|
114
|
+
return obj.toString().replace(/\n\s*/g, "");
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
// Matchers begin here
|
119
|
+
|
120
|
+
jspec.matchers = {};
|
121
|
+
|
122
|
+
jspec.matchers["=="] = {
|
123
|
+
describe: function(self, target, not) {
|
124
|
+
return jspec.print_object(self) + " should " + (not ? "not " : "") + "equal " + jspec.print_object(target)
|
125
|
+
},
|
126
|
+
matches: function(self, target) {
|
127
|
+
return self == target;
|
128
|
+
},
|
129
|
+
failure_message: function(self, target, not) {
|
130
|
+
if (not)
|
131
|
+
return "Expected " + jspec.print_object(self) + " not to equal " + jspec.print_object(target);
|
132
|
+
else
|
133
|
+
return "Expected " + jspec.print_object(self) + ". Got " + jspec.print_object(target);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
jspec.matchers["include"] = {
|
138
|
+
matches: function(self, target) {
|
139
|
+
if(Array.prototype.indexOf) return Array.prototype.indexOf.call(self, target) != -1;
|
140
|
+
else {
|
141
|
+
for(i=0,j=self.length;i<j;i++) {
|
142
|
+
if(target == self[i]) return true;
|
143
|
+
}
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
},
|
147
|
+
failure_message: function(self, target, not) {
|
148
|
+
return "Expected [" + jspec.print_object(self) + "] " + (not ? "not " : "") + "to include " + target;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
jspec.matchers["exist"] = {
|
153
|
+
describe: function(self, target, not) {
|
154
|
+
return jspec.print_object(self) + " should " + (not ? "not " : "") + "exist."
|
155
|
+
},
|
156
|
+
matches: function(self, target) {
|
157
|
+
return !!this;
|
158
|
+
},
|
159
|
+
failure_message: function(self, target, not) {
|
160
|
+
return "Expected " + (not ? "not " : "") + "to exist, but was " + jspec.print_object(self);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
jspec.matchers["be_instanceof"] = {
|
165
|
+
describe: function(self, target, not) {
|
166
|
+
return jspec.print_object(self) + " should " + (not ? "not " : "") +
|
167
|
+
"be an instance of " + jspec.print_object(target);
|
168
|
+
},
|
169
|
+
matches: function(self, target) {
|
170
|
+
return self instanceof target;
|
171
|
+
},
|
172
|
+
failure_message: function(self, target, not) {
|
173
|
+
return "Expected " + jspec.print_object(self) + (not ? "not " : "") +
|
174
|
+
"to be an instance of " + jspec.print_object(target) + ", but was " +
|
175
|
+
jspec.print_object(target.constructor);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
jspec.matchers["have_constructor"] = {
|
180
|
+
describe: function(self, target, not) {
|
181
|
+
return jspec.print_object(self) + " should " + (not ? "not " : "") +
|
182
|
+
"have " + jspec.print_object(target) + " as its constructor";
|
183
|
+
},
|
184
|
+
matches: function(self, target) {
|
185
|
+
return self instanceof target;
|
186
|
+
},
|
187
|
+
failure_message: function(self, target, not) {
|
188
|
+
return "Expected " + jspec.print_object(self) + (not ? "not " : "") +
|
189
|
+
"to have " + jspec.print_object(target) + ", as its constructor but was " +
|
190
|
+
jspec.print_object(target.constructor);
|
191
|
+
}
|
192
|
+
}
|