Fingertips-headless-squirrel 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. data/README.rdoc +53 -0
  2. data/Rakefile +49 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/jstest +10 -0
  5. data/lib/headless_squirrel/runner.rb +70 -0
  6. data/lib/headless_squirrel/test.rb +17 -0
  7. data/lib/headless_squirrel/test_case.rb +121 -0
  8. data/lib/headless_squirrel.rb +2 -0
  9. data/test/fixtures/a_unit_test.html +27 -0
  10. data/test/fixtures/a_unit_test.js +22 -0
  11. data/test/regression/prototype/unit/ajax_test.html +29 -0
  12. data/test/regression/prototype/unit/array_test.html +28 -0
  13. data/test/regression/prototype/unit/assets/prototype.js +4900 -0
  14. data/test/regression/prototype/unit/assets/unittest.css +50 -0
  15. data/test/regression/prototype/unit/assets/unittest.js +615 -0
  16. data/test/regression/prototype/unit/assets/unittest_transport.js +1 -0
  17. data/test/regression/prototype/unit/base_test.html +27 -0
  18. data/test/regression/prototype/unit/class_test.html +27 -0
  19. data/test/regression/prototype/unit/date_test.html +27 -0
  20. data/test/regression/prototype/unit/dom_test.html +304 -0
  21. data/test/regression/prototype/unit/element_mixins_test.html +30 -0
  22. data/test/regression/prototype/unit/enumerable_test.html +35 -0
  23. data/test/regression/prototype/unit/event_test.html +31 -0
  24. data/test/regression/prototype/unit/fixtures/ajax.html +2 -0
  25. data/test/regression/prototype/unit/fixtures/ajax.js +42 -0
  26. data/test/regression/prototype/unit/fixtures/array.html +1 -0
  27. data/test/regression/prototype/unit/fixtures/class.js +83 -0
  28. data/test/regression/prototype/unit/fixtures/content.html +1 -0
  29. data/test/regression/prototype/unit/fixtures/data.json +1 -0
  30. data/test/regression/prototype/unit/fixtures/dom.css +84 -0
  31. data/test/regression/prototype/unit/fixtures/dom.html +278 -0
  32. data/test/regression/prototype/unit/fixtures/dom.js +17 -0
  33. data/test/regression/prototype/unit/fixtures/element_mixins.html +4 -0
  34. data/test/regression/prototype/unit/fixtures/element_mixins.js +2 -0
  35. data/test/regression/prototype/unit/fixtures/empty.html +0 -0
  36. data/test/regression/prototype/unit/fixtures/empty.js +1 -0
  37. data/test/regression/prototype/unit/fixtures/enumerable.html +8 -0
  38. data/test/regression/prototype/unit/fixtures/enumerable.js +23 -0
  39. data/test/regression/prototype/unit/fixtures/event.html +4 -0
  40. data/test/regression/prototype/unit/fixtures/form.html +108 -0
  41. data/test/regression/prototype/unit/fixtures/function.js +13 -0
  42. data/test/regression/prototype/unit/fixtures/hash.js +25 -0
  43. data/test/regression/prototype/unit/fixtures/hello.js +1 -0
  44. data/test/regression/prototype/unit/fixtures/logo.gif +0 -0
  45. data/test/regression/prototype/unit/fixtures/object.html +6 -0
  46. data/test/regression/prototype/unit/fixtures/object.js +7 -0
  47. data/test/regression/prototype/unit/fixtures/position.html +9 -0
  48. data/test/regression/prototype/unit/fixtures/selector.html +71 -0
  49. data/test/regression/prototype/unit/fixtures/string.js +8 -0
  50. data/test/regression/prototype/unit/fixtures/unittest.html +18 -0
  51. data/test/regression/prototype/unit/form_test.html +135 -0
  52. data/test/regression/prototype/unit/function_test.html +27 -0
  53. data/test/regression/prototype/unit/hash_test.html +27 -0
  54. data/test/regression/prototype/unit/number_test.html +27 -0
  55. data/test/regression/prototype/unit/object_test.html +32 -0
  56. data/test/regression/prototype/unit/periodical_executer_test.html +27 -0
  57. data/test/regression/prototype/unit/position_test.html +36 -0
  58. data/test/regression/prototype/unit/prototype_test.html +27 -0
  59. data/test/regression/prototype/unit/range_test.html +27 -0
  60. data/test/regression/prototype/unit/regexp_test.html +27 -0
  61. data/test/regression/prototype/unit/selector_test.html +98 -0
  62. data/test/regression/prototype/unit/string_test.html +27 -0
  63. data/test/regression/prototype/unit/tests/ajax_test.js +379 -0
  64. data/test/regression/prototype/unit/tests/array_test.js +186 -0
  65. data/test/regression/prototype/unit/tests/base_test.js +43 -0
  66. data/test/regression/prototype/unit/tests/class_test.js +136 -0
  67. data/test/regression/prototype/unit/tests/date_test.js +5 -0
  68. data/test/regression/prototype/unit/tests/dom_test.js +1493 -0
  69. data/test/regression/prototype/unit/tests/element_mixins_test.js +32 -0
  70. data/test/regression/prototype/unit/tests/enumerable_test.js +271 -0
  71. data/test/regression/prototype/unit/tests/event_test.js +235 -0
  72. data/test/regression/prototype/unit/tests/form_test.js +382 -0
  73. data/test/regression/prototype/unit/tests/function_test.js +133 -0
  74. data/test/regression/prototype/unit/tests/hash_test.js +178 -0
  75. data/test/regression/prototype/unit/tests/number_test.js +44 -0
  76. data/test/regression/prototype/unit/tests/object_test.js +180 -0
  77. data/test/regression/prototype/unit/tests/periodical_executer_test.js +15 -0
  78. data/test/regression/prototype/unit/tests/position_test.js +44 -0
  79. data/test/regression/prototype/unit/tests/prototype_test.js +43 -0
  80. data/test/regression/prototype/unit/tests/range_test.js +58 -0
  81. data/test/regression/prototype/unit/tests/regexp_test.js +42 -0
  82. data/test/regression/prototype/unit/tests/selector_test.js +408 -0
  83. data/test/regression/prototype/unit/tests/string_test.js +548 -0
  84. data/test/regression/prototype/unit/tests/unittest_test.js +148 -0
  85. data/test/regression/prototype/unit/unittest_test.html +45 -0
  86. data/test/regression/prototype/upstream +1 -0
  87. data/test/regression/scriptaculous/src/builder.js +134 -0
  88. data/test/regression/scriptaculous/src/controls.js +963 -0
  89. data/test/regression/scriptaculous/src/dragdrop.js +973 -0
  90. data/test/regression/scriptaculous/src/effects.js +1122 -0
  91. data/test/regression/scriptaculous/src/javascripttest.rb +203 -0
  92. data/test/regression/scriptaculous/src/scriptaculous.js +66 -0
  93. data/test/regression/scriptaculous/src/slider.js +273 -0
  94. data/test/regression/scriptaculous/src/sound.js +57 -0
  95. data/test/regression/scriptaculous/src/unittest.js +566 -0
  96. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_alt_text.html +1 -0
  97. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_collection.js +1 -0
  98. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result.html +1 -0
  99. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result2.html +1 -0
  100. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_tagged.html +1 -0
  101. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_text.html +1 -0
  102. data/test/regression/scriptaculous/unit/_ajax_updater_result.html +20 -0
  103. data/test/regression/scriptaculous/unit/_autocomplete_result.html +11 -0
  104. data/test/regression/scriptaculous/unit/_autocomplete_result_nobr.html +1 -0
  105. data/test/regression/scriptaculous/unit/ajax_autocompleter_test.html +243 -0
  106. data/test/regression/scriptaculous/unit/ajax_inplaceeditor_test.html +895 -0
  107. data/test/regression/scriptaculous/unit/builder_test.html +262 -0
  108. data/test/regression/scriptaculous/unit/dragdrop_test.html +131 -0
  109. data/test/regression/scriptaculous/unit/effects_test.html +547 -0
  110. data/test/regression/scriptaculous/unit/element_test.html +116 -0
  111. data/test/regression/scriptaculous/unit/icon.png +0 -0
  112. data/test/regression/scriptaculous/unit/index.html +70 -0
  113. data/test/regression/scriptaculous/unit/loading_test.html +41 -0
  114. data/test/regression/scriptaculous/unit/position_clone_test.html +312 -0
  115. data/test/regression/scriptaculous/unit/slider_test.html +437 -0
  116. data/test/regression/scriptaculous/unit/sortable_test.html +205 -0
  117. data/test/regression/scriptaculous/unit/string_test.html +71 -0
  118. data/test/regression/scriptaculous/unit/unittest_test.html +154 -0
  119. data/test/regression/scriptaculous/upstream +1 -0
  120. data/test/test_helper.rb +20 -0
  121. data/test/unit/runner_test.rb +165 -0
  122. data/test/unit/test_case_test.rb +168 -0
  123. data/test/unit/test_test.rb +24 -0
  124. metadata +179 -0
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <title>script.aculo.us Unit test file</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
7
+ <script src="../../prototype/unit/assets/prototype.js" type="text/javascript"></script>
8
+ <script src="../src/scriptaculous.js" type="text/javascript"></script>
9
+ <script src="../../prototype/unit/assets/unittest.js" type="text/javascript"></script>
10
+ <link rel="stylesheet" href="../../prototype/unit/assets/unittest.css" type="text/css" />
11
+ </head>
12
+ <body>
13
+ <h1>script.aculo.us Unit test file</h1>
14
+ <p>
15
+ Tests for String.prototype extensions in effects.js
16
+ </p>
17
+
18
+ <!-- Log output -->
19
+ <div id="testlog"> </div>
20
+
21
+ <!-- Tests follow -->
22
+ <script type="text/javascript" language="javascript" charset="utf-8">
23
+ // <![CDATA[
24
+
25
+ new Test.Unit.Runner({
26
+
27
+ testStringParseColor: function() { with(this) {
28
+ assertEqual('#000000', "#000000".parseColor());
29
+ assertEqual('#000000', "rgb(0,0,0)".parseColor());
30
+ assertEqual('#000000', "rgb(0, 0, 0)".parseColor());
31
+ assertEqual('#000000', "#000".parseColor());
32
+
33
+ assertEqual('#1', "#1".parseColor());
34
+ assertEqual('#12', "#12".parseColor());
35
+ assertEqual('#112233', "#123".parseColor());
36
+ assertEqual('#1234', "#1234".parseColor());
37
+ assertEqual('#12345', "#12345".parseColor());
38
+ assertEqual('#123456', "#123456".parseColor());
39
+
40
+ assertEqual('#abcdef', "#aBcDeF".parseColor());
41
+ assertEqual('#aabbcc', "#aBc".parseColor());
42
+
43
+ assertEqual('white', "white".parseColor());
44
+ assertEqual('#123456', "#123456".parseColor('#000000')); // default to #000000 if not parseable
45
+ assertEqual('#000000', "white".parseColor('#000000')); // default to #000000 if not parseable
46
+
47
+ assertEqual('#ffffff', "rgb(255,255,255)".parseColor());
48
+ assertEqual('#ff0000', "rgb(255,0,0)".parseColor());
49
+ assertEqual('#00ff00', "rgb(0,255,0)".parseColor());
50
+ assertEqual('#0000ff', "rgb(0,0,255)".parseColor());
51
+ }},
52
+
53
+ testStringParseStyle: function() { with(this) {
54
+ var expected = "#<Hash:{'fontSize': '11px'}>";
55
+ var expectedMultiple = "#<Hash:{'fontSize': '11px', 'width': '780px'}>";
56
+
57
+ assertInspect(expected, "font-size:11px".parseStyle());
58
+ assertInspect(expected, "font-SIZE: 11px".parseStyle());
59
+ assertInspect(expected, "font-size:11px ".parseStyle());
60
+ assertInspect(expected, " Font-size: 11px ".parseStyle());
61
+
62
+ assertInspect(expectedMultiple, " font-size: 11px;width:780px".parseStyle());
63
+
64
+ }}
65
+
66
+ });
67
+
68
+ // ]]>
69
+ </script>
70
+ </body>
71
+ </html>
@@ -0,0 +1,154 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <title>script.aculo.us Unit test file</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
7
+ <script src="../../prototype/unit/assets/prototype.js" type="text/javascript"></script>
8
+ <script src="../src/scriptaculous.js" type="text/javascript"></script>
9
+ <script src="../../prototype/unit/assets/unittest.js" type="text/javascript"></script>
10
+ <link rel="stylesheet" href="../../prototype/unit/assets/unittest.css" type="text/css" />
11
+ <style type="text/css" media="screen">
12
+ /* <![CDATA[ */
13
+ #testcss1 { font-size:11px; color: #f00; }
14
+ #testcss2 { font-size:12px; color: #0f0; display: none; }
15
+ /* ]]> */
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <h1>script.aculo.us Unit test file</h1>
20
+ <p>
21
+ This is a preliminary version mostly for testing the unittest library.
22
+ </p>
23
+
24
+ <!-- Log output -->
25
+ <div id="testlog"> </div>
26
+
27
+ <!-- Test elements follow -->
28
+ <div id="test_1" class="a bbbbbbbbbbbb cccccccccc dddd"> </div>
29
+
30
+ <div id="test_2"> <span> </span>
31
+
32
+
33
+
34
+ <div><div></div> </div><span> </span>
35
+ </div>
36
+
37
+ <ul id="tlist"><li id="tlist_1">x1</li><li id="tlist_2">x2</li></ul>
38
+ <ul id="tlist2"><li class="a" id="tlist2_1">x1</li><li id="tlist2_2">x2</li></ul>
39
+
40
+ <div id="testmoveby" style="background-color:#333;width:100px;">XXXX</div>
41
+
42
+ <div id="testcss1">testcss1<span id="testcss1_span" style="display:none;">blah</span></div><div id="testcss2">testcss1</div>
43
+
44
+ <!-- Tests follow -->
45
+ <script type="text/javascript" language="javascript" charset="utf-8">
46
+ // <![CDATA[
47
+
48
+ var testObj = {
49
+ isNice: function(){
50
+ return true;
51
+ },
52
+ isBroken: function(){
53
+ return false;
54
+ }
55
+ }
56
+
57
+ new Test.Unit.Runner({
58
+
59
+ testAssertEqual: function() { with(this) {
60
+ assertEqual(0, 0);
61
+ assertEqual(0, 0, "test");
62
+
63
+ assertEqual(0,'0');
64
+ assertEqual(65.0, 65);
65
+
66
+ assertEqual("a", "a");
67
+ assertEqual("a", "a", "test");
68
+
69
+ assertNotEqual(0, 1);
70
+ assertNotEqual("a","b");
71
+ assertNotEqual({},{});
72
+ assertNotEqual([],[]);
73
+ assertNotEqual([],{});
74
+ }},
75
+
76
+ testAssertRespondsTo: function() { with(this) {
77
+ assertRespondsTo('isNice', testObj);
78
+ assertRespondsTo('isBroken', testObj);
79
+ }},
80
+
81
+ testAssertIndentical: function() { with(this) {
82
+ assertIdentical(0, 0);
83
+ assertIdentical(0, 0, "test");
84
+ assertIdentical(1, 1);
85
+ assertIdentical('a', 'a');
86
+ assertIdentical('a', 'a', "test");
87
+ assertIdentical('', '');
88
+ assertIdentical(undefined, undefined);
89
+ assertIdentical(null, null);
90
+ assertIdentical(true, true);
91
+ assertIdentical(false, false);
92
+
93
+ var obj = {a:'b'};
94
+ assertIdentical(obj, obj);
95
+
96
+ assertNotIdentical({1:2,3:4},{1:2,3:4});
97
+
98
+ assertIdentical(1, 1.0); // both are typeof == 'number'
99
+
100
+ assertNotIdentical(1, '1');
101
+ assertNotIdentical(1, '1.0');
102
+ }},
103
+
104
+ testAssertMatch: function() { with(this) {
105
+ assertMatch(/knowmad.jpg$/, 'http://script.aculo.us/images/knowmad.jpg');
106
+ assertMatch(/Fuc/, 'Thomas Fuchs');
107
+ assertMatch(/^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/, '$19.95');
108
+ assertMatch(/(\d{3}\) ?)|(\d{3}[- \.])?\d{3}[- \.]\d{4}(\s(x\d+)?){0,1}$/, '704-343-9330');
109
+ assertMatch(/^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$/, '2001-06-16');
110
+ assertMatch(/^((0?[123456789])|(1[012]))\s*:\s*([012345]\d)(\s*:\s*([012345]\d))?\s*[ap]m\s*-\s*((0?[123456789])|(1[012]))\s*:\s*([012345]\d)(\s*:\s*([012345]\d))?\s*[ap]m$/i, '2:00PM-2:15PM');
111
+
112
+ }},
113
+
114
+ testAssertInstanceOf: function() { with(this) {
115
+ assertInstanceOf(Effect.Opacity, new Effect.Opacity('testcss1',{sync:true}));
116
+ assertNotInstanceOf(String, new Effect.Opacity('testcss1',{sync:true}));
117
+
118
+ // note: fails with firefox 1.0.X (bug, fixed in Deer Park)
119
+ assertNotInstanceOf(Effect.Parallel, new Effect.Opacity('testcss1',{sync:true}), "(note: fails with firefox 1.0.X, fixed in Deer Park)");
120
+ }},
121
+
122
+ testAssertReturns: function() { with(this) {
123
+
124
+ assertReturnsTrue('isNice',testObj);
125
+ assertReturnsFalse('isBroken',testObj);
126
+
127
+ assertReturnsTrue('nice',testObj);
128
+ assertReturnsFalse('broken',testObj);
129
+
130
+ }},
131
+
132
+ testAssertVisible: function() { with(this) {
133
+ assertVisible('testcss1');
134
+ assertNotVisible('testcss1_span');
135
+ assertNotVisible('testcss2', "Due to a Safari bug, this test fails in Safari.");
136
+
137
+ Element.hide('testcss1');
138
+ assertNotVisible('testcss1');
139
+ assertNotVisible('testcss1_span');
140
+ Element.show('testcss1');
141
+ assertVisible('testcss1');
142
+ assertNotVisible('testcss1_span');
143
+
144
+ Element.show('testcss1_span');
145
+ assertVisible('testcss1_span');
146
+ Element.hide('testcss1');
147
+ assertNotVisible('testcss1_span'); // hidden by parent
148
+ }}
149
+
150
+ }, "testlog");
151
+ // ]]>
152
+ </script>
153
+ </body>
154
+ </html>
@@ -0,0 +1 @@
1
+ 4b49fd8884920d4ee760b0194431f4f433f878df
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'test/spec'
3
+ require 'mocha'
4
+
5
+ $:.unshift File.expand_path('../../lib', __FILE__)
6
+ require 'headless_squirrel'
7
+
8
+ FIXTURES = File.expand_path('../fixtures', __FILE__)
9
+
10
+ module TestHelper
11
+ def fixture(name)
12
+ File.join(FIXTURES, name)
13
+ end
14
+ end
15
+
16
+ Test::Unit::TestCase.send(:include, TestHelper)
17
+
18
+ Thread.new do
19
+ OSX::NSApplication.sharedApplication.run
20
+ end
@@ -0,0 +1,165 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module RunnerTestHelper
4
+ def setup
5
+ files = [fixture('a_unit_test.html'), fixture('a_unit_test.html')]
6
+ @runner = HeadlessSquirrel::Runner.alloc.initWithHTMLFiles(files)
7
+
8
+ @runner.stubs(:puts)
9
+ @runner.stubs(:print)
10
+ @runner.test_cases.first.stubs(:run)
11
+ @runner.test_cases.last.stubs(:run)
12
+
13
+ OSX::NSApplication.sharedApplication.stubs(:run)
14
+ OSX::NSApplication.sharedApplication.stubs(:terminate)
15
+ end
16
+
17
+ private
18
+
19
+ def test_stub(name)
20
+ test_case = HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate(fixture('a_unit_test.html'), stub_everything)
21
+ test_case.stubs(:title).returns("A test case with #{name}")
22
+ HeadlessSquirrel::TestCase::Test.new(test_case, name.to_s, name.to_sym, name.to_s)
23
+ end
24
+ end
25
+
26
+ describe "HeadlessSquirrel::Runner" do
27
+ include RunnerTestHelper
28
+
29
+ it "should have instantiated a HeadlessSquirrel::TestCase for each html file" do
30
+ @runner.test_cases.length.should == 2
31
+ @runner.test_cases.each do |test_case|
32
+ test_case.html_file.should == fixture('a_unit_test.html')
33
+ test_case.delegate.should == @runner
34
+ end
35
+ end
36
+
37
+ it "should not have finished yet" do
38
+ @runner.should.not.be.finished
39
+ end
40
+
41
+ it "should return the total amount of tests" do
42
+ @runner.test_cases.each { |tc| tc.stubs(:tests).returns(3) }
43
+ @runner.tests.should == 6
44
+ end
45
+
46
+ it "should return the total amount of assertions" do
47
+ @runner.test_cases.each { |tc| tc.stubs(:assertions).returns(2) }
48
+ @runner.assertions.should == 4
49
+ end
50
+
51
+ it "should return the total amount of failures" do
52
+ @runner.test_cases.each { |tc| tc.stubs(:failures).returns(1) }
53
+ @runner.failures.should == 2
54
+ end
55
+
56
+ it "should return the total amount of errors" do
57
+ @runner.test_cases.each { |tc| tc.stubs(:errors).returns(1) }
58
+ @runner.errors.should == 2
59
+ end
60
+
61
+ it "should run the tests cases and start a runloop" do
62
+ @runner.test_cases.first.expects(:run)
63
+ @runner.run
64
+ end
65
+
66
+ it "should start a runloop when running the tests" do
67
+ OSX::NSApplication.sharedApplication.expects(:run)
68
+ @runner.run
69
+ end
70
+
71
+ it "should store the start time" do
72
+ time = Time.now
73
+ Time.stubs(:now).returns(time)
74
+
75
+ @runner.run
76
+ @runner.instance_variable_get(:@start_time).should == time
77
+ end
78
+
79
+ it "should keep a `queued' stack which contains all test cases that are running" do
80
+ @runner.run
81
+ @runner.queued.should == @runner.test_cases
82
+ end
83
+
84
+ it "should remove a finished test case from the `queued' stack" do
85
+ @runner.run
86
+ @runner.test_case_finished(@runner.test_cases.first)
87
+ @runner.queued.should == [@runner.test_cases.last]
88
+ end
89
+
90
+ it "should have finished once the `queued' stack is empty" do
91
+ @runner.run
92
+ @runner.test_case_finished(@runner.test_cases.first)
93
+ @runner.test_case_finished(@runner.test_cases.last)
94
+ @runner.should.be.finished
95
+ end
96
+
97
+ it "should return tests that have ran but didn't pass" do
98
+ test_case = stub(:title => 'A test case')
99
+
100
+ @runner.test_ran(test_stub(:passed))
101
+ @runner.test_ran(test_stub(:failed))
102
+ @runner.test_ran(test_stub(:error))
103
+
104
+ @runner.did_not_pass.first.name.should == 'failed'
105
+ @runner.did_not_pass.last.name.should == 'error'
106
+ end
107
+
108
+ it "should print a dot when a test ran and passed" do
109
+ @runner.expects(:print).with('.')
110
+ @runner.test_ran(test_stub(:passed))
111
+ end
112
+
113
+ it "should print a F when a test ran and failed" do
114
+ @runner.expects(:print).with('F')
115
+ @runner.test_ran(test_stub(:failed))
116
+ end
117
+
118
+ it "should print an E when a test ran and an error occured" do
119
+ @runner.expects(:print).with('E')
120
+ @runner.test_ran(test_stub(:error))
121
+ end
122
+ end
123
+
124
+ describe "HeadlessSquirrel::Runner, when finalizing" do
125
+ include RunnerTestHelper
126
+
127
+ def setup
128
+ super
129
+ time = Time.now
130
+ @runner.instance_variable_set(:@start_time, time)
131
+ Time.stubs(:now).returns(time + 2.3)
132
+ end
133
+
134
+ it "should print the tests that did not pass" do
135
+ test1, test2 = test_stub(:failed), test_stub(:error)
136
+ @runner.test_ran(test1)
137
+ @runner.test_ran(test2)
138
+
139
+ @runner.expects(:puts).with("\n 1) #{test1}")
140
+ @runner.expects(:puts).with("\n 2) #{test2}")
141
+ @runner.send(:finalize)
142
+ end
143
+
144
+ it "should print the time it took to run the tests" do
145
+ @runner.expects(:puts).with("\nFinished in 2.3 seconds.")
146
+ @runner.send(:finalize)
147
+ end
148
+
149
+ it "should print the total amount of tests, assertions, failures, and errors that have been ran" do
150
+ @runner.test_cases.each do |tc|
151
+ tc.stubs(:tests).returns(3)
152
+ tc.stubs(:assertions).returns(2)
153
+ tc.stubs(:failures).returns(1)
154
+ tc.stubs(:errors).returns(1)
155
+ end
156
+
157
+ @runner.expects(:puts).with("\n6 tests, 4 assertions, 2 failures, 2 errors")
158
+ @runner.send(:finalize)
159
+ end
160
+
161
+ it "should terminate the application" do
162
+ OSX::NSApplication.sharedApplication.expects(:terminate).with(@runner)
163
+ @runner.send(:finalize)
164
+ end
165
+ end
@@ -0,0 +1,168 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ describe "HeadlessSquirrel::TestCase, class methods" do
4
+ it "should return a shared WebView instance" do
5
+ HeadlessSquirrel::TestCase.sharedWebView.should.be.instance_of OSX::WebView
6
+ end
7
+ end
8
+
9
+ describe "HeadlessSquirrel::TestCase" do
10
+ before do
11
+ @delegate = stub_everything('delegate')
12
+ @test_case = HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate(fixture('a_unit_test.html'), @delegate)
13
+ end
14
+
15
+ it "should initialize with a html file and delegate" do
16
+ @test_case.html_file.should == fixture('a_unit_test.html')
17
+ @test_case.delegate.should == @delegate
18
+ end
19
+
20
+ it "should raise a FileDoesNotExistError if the given html file does not exist" do
21
+ lambda {
22
+ HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate('/does/not/exist/test.html', @delegate)
23
+ }.should.raise HeadlessSquirrel::TestCase::FileDoesNotExistError
24
+ end
25
+
26
+ it "should instantiate a WebView with the html file and set itself as the frameLoadDelegate" do
27
+ @test_case.webView.should == HeadlessSquirrel::TestCase.sharedWebView
28
+ @test_case.webView.mainFrameURL.should == "file://#{fixture('a_unit_test.html')}"
29
+ @test_case.webView.frameLoadDelegate.should == @test_case
30
+ end
31
+
32
+ it "should not have finished yet" do
33
+ @test_case.should.not.be.finished
34
+ end
35
+
36
+ it "should have set tests, assertions, failures, and errors to zero" do
37
+ @test_case.tests.should == 0
38
+ @test_case.assertions.should == 0
39
+ @test_case.failures.should == 0
40
+ @test_case.errors.should == 0
41
+ end
42
+
43
+ it "should run the tests" do
44
+ @test_case.expects(:webView)
45
+ @test_case.run
46
+ end
47
+ end
48
+
49
+ describe "HeadlessSquirrel::TestCase, when running" do
50
+ before do
51
+ @delegate = stub_everything('delegate')
52
+ @test_case = HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate(fixture('a_unit_test.html'), @delegate)
53
+ run_test_case!
54
+ end
55
+
56
+ it "should return the DOM document" do
57
+ @test_case.document.should.be.instance_of OSX::DOMHTMLDocument
58
+ end
59
+
60
+ it "should have stored the document title" do
61
+ @test_case.title.should == 'A HeadlessSquirrel Unit Test HTML File'
62
+ @test_case.instance_variable_get(:@title).should == 'A HeadlessSquirrel Unit Test HTML File'
63
+ end
64
+
65
+ it "should return the `log' element" do
66
+ @test_case.log.should.be.instance_of OSX::DOMHTMLDivElement
67
+ @test_case.log.className.should == 'logsummary'
68
+ end
69
+
70
+ it "should return the `loglines' element" do
71
+ @test_case.loglines.should.be.instance_of OSX::DOMHTMLTableSectionElement
72
+ @test_case.loglines.className.should == 'loglines'
73
+ end
74
+
75
+ it "should register itself as an event handler for DOMSubtreeModified events on the `log' and `loglines' element" do
76
+ @test_case.log.expects(:addEventListener___).with('DOMSubtreeModified', @test_case, true)
77
+ @test_case.loglines.expects(:addEventListener___).with('DOMSubtreeModified', @test_case, true)
78
+ @test_case.webView_didFinishLoadForFrame(nil, nil)
79
+ end
80
+
81
+ it "should not have finished yet if the inner html of the `log' element is `running...'" do
82
+ @test_case.instance_variable_set(:@finished, nil)
83
+ @test_case.log.stubs(:innerText).returns('running...')
84
+ @test_case.handleEvent(stubbed_log_event)
85
+ @test_case.should.not.be.finished
86
+ end
87
+
88
+ it "should have finished once the inner html of the `log' element is not longer `running...'" do
89
+ @test_case.instance_variable_set(:@finished, nil)
90
+ @test_case.handleEvent(stubbed_log_event)
91
+ @test_case.should.be.finished
92
+ end
93
+
94
+ it "should return the number of tests, assertions, failures, and errors" do
95
+ @test_case.tests.should == 3
96
+ @test_case.assertions.should == 2
97
+ @test_case.failures.should == 1
98
+ @test_case.errors.should == 1
99
+ end
100
+
101
+ it "should let its delegate know its finished running" do
102
+ @delegate.expects(:test_case_finished).with(@test_case)
103
+ @test_case.handleEvent(stubbed_log_event)
104
+ end
105
+
106
+ it "should not let its delegate know a test ran if the targets class is not one of passed, failed, or error" do
107
+ @delegate.expects(:test_ran).never
108
+ event = stubbed_loglines_event('passed')
109
+
110
+ event.target.parentNode.stubs(:className).returns('')
111
+ @test_case.handleEvent(event)
112
+
113
+ event.target.parentNode.stubs(:className).returns('foo')
114
+ @test_case.handleEvent(event)
115
+ end
116
+
117
+ it "should not let its delegate know a test ran if the output is still empty" do
118
+ @delegate.expects(:test_ran).never
119
+ String.any_instance.stubs(:sub).returns('')
120
+ @test_case.handleEvent(stubbed_loglines_event('failed'))
121
+ end
122
+
123
+ # Eloy: Fails on my Mac Pro at the office, maybe because I've installed the Safari 4 beta?
124
+ it "should let its delegate know a test ran if the targets class is one of passed, failed, or error" do
125
+ @test_case = HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate(fixture('a_unit_test.html'), @delegate)
126
+
127
+ @delegate.expects(:test_ran).times(3).with do |test|
128
+ test.name.should == case test.state
129
+ when :passed
130
+ 'testHelloWorldSuccess'
131
+ when :failed
132
+ 'testHelloWorldFailure'
133
+ when :error
134
+ 'testHelloWorldError'
135
+ end
136
+
137
+ test.output.should == case test.state
138
+ when :passed
139
+ ""
140
+ when :failed
141
+ "Failure: assertEqual\nexpected: <'Hello world!'>, actual: <''>"
142
+ when :error
143
+ "TypeError: Value undefined (result of expression this.content.foo) is not object., error=(TypeError: Value undefined (result of expression this.content.foo) is not object.)"
144
+ end
145
+
146
+ true # for mocha
147
+ end
148
+
149
+ run_test_case!
150
+ end
151
+
152
+ private
153
+
154
+ def run_test_case!
155
+ @test_case.run
156
+ sleep 0.25 while not @test_case.finished?
157
+ end
158
+
159
+ def stubbed_log_event
160
+ stub('Event', :target => @test_case.log.firstChild)
161
+ end
162
+
163
+ def stubbed_loglines_event(klass)
164
+ element = @test_case.loglines.getElementsByClassName(klass).item(0).children.item(3)
165
+ element.stubs(:parentNode).returns(@test_case.loglines.getElementsByClassName(klass).item(0))
166
+ stub('Event', :target => element)
167
+ end
168
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ describe "HeadlessSquirrel::TestCase::Test" do
4
+ before do
5
+ @delegate = stub_everything('delegate')
6
+ @test_case = HeadlessSquirrel::TestCase.alloc.initWithHTMLFile_delegate(fixture('a_unit_test.html'), @delegate)
7
+ @test_case.instance_variable_set(:@title, 'A test case')
8
+
9
+ @test = HeadlessSquirrel::TestCase::Test.new(@test_case, 'testHelloWorld', :failed, 'did not meet expectation')
10
+ end
11
+
12
+ it "should initialize with a TestCase, name, state and output" do
13
+ @test.test_case.should == @test_case
14
+ @test.name.should == 'testHelloWorld'
15
+ @test.state.should == :failed
16
+ @test.output.should == 'did not meet expectation'
17
+ end
18
+
19
+ it "should return a formatted string" do
20
+ @test.to_s.should == %{Failed:
21
+ testHelloWorld (A test case) [#{fixture('a_unit_test.html')}]:
22
+ did not meet expectation}
23
+ end
24
+ end