honkster-screw-unit-server 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/CHANGES +48 -0
  2. data/README.markdown +359 -0
  3. data/Rakefile +43 -0
  4. data/VERSION.yml +5 -0
  5. data/bin/screw_unit +6 -0
  6. data/bin/screw_unit_server +14 -0
  7. data/core/CHANGES +10 -0
  8. data/core/EXAMPLE.html +68 -0
  9. data/core/LICENSE +22 -0
  10. data/core/README.markdown +307 -0
  11. data/core/example/models/cat.js +5 -0
  12. data/core/example/models/man.js +17 -0
  13. data/core/example/spec/matchers/have.js +8 -0
  14. data/core/example/spec/models/cat_spec.js +31 -0
  15. data/core/example/spec/models/man_spec.js +34 -0
  16. data/core/example/spec/spec_helper.js +5 -0
  17. data/core/example/spec/suite.html +25 -0
  18. data/core/lib/jquery-1.3.2.js +4376 -0
  19. data/core/lib/jquery.fn.js +30 -0
  20. data/core/lib/jquery.print.js +109 -0
  21. data/core/lib/screw.behaviors.js +93 -0
  22. data/core/lib/screw.builder.js +95 -0
  23. data/core/lib/screw.css +90 -0
  24. data/core/lib/screw.events.js +45 -0
  25. data/core/lib/screw.matchers.js +244 -0
  26. data/core/spec/behaviors_spec.js +166 -0
  27. data/core/spec/matchers_spec.js +372 -0
  28. data/core/spec/print_spec.js +158 -0
  29. data/core/spec/spec_helper.js +0 -0
  30. data/core/spec/suite.html +19 -0
  31. data/core/spec/with_screw_context_spec.js +9 -0
  32. data/init.rb +0 -0
  33. data/lib/screw_unit.rb +21 -0
  34. data/spec/functional/functional_spec.rb +25 -0
  35. data/spec/functional/functional_spec_helper.rb +42 -0
  36. data/spec/functional/functional_spec_server_starter.rb +68 -0
  37. data/spec/functional_suite.rb +10 -0
  38. data/spec/spec_suite.rb +2 -0
  39. data/standalone.ru +3 -0
  40. data/vendor/js-test-core/CHANGES +31 -0
  41. data/vendor/js-test-core/README +6 -0
  42. data/vendor/js-test-core/Rakefile +73 -0
  43. data/vendor/js-test-core/bin/js-test-client +0 -0
  44. data/vendor/js-test-core/bin/js-test-server +6 -0
  45. data/vendor/js-test-core/lib/js_test_core.rb +38 -0
  46. data/vendor/js-test-core/lib/js_test_core/app.rb +11 -0
  47. data/vendor/js-test-core/lib/js_test_core/client.rb +139 -0
  48. data/vendor/js-test-core/lib/js_test_core/configuration.rb +65 -0
  49. data/vendor/js-test-core/lib/js_test_core/representations.rb +13 -0
  50. data/vendor/js-test-core/lib/js_test_core/representations/dir.html.rb +25 -0
  51. data/vendor/js-test-core/lib/js_test_core/representations/frameworks.rb +3 -0
  52. data/vendor/js-test-core/lib/js_test_core/representations/not_found.html.rb +16 -0
  53. data/vendor/js-test-core/lib/js_test_core/representations/page.html.rb +41 -0
  54. data/vendor/js-test-core/lib/js_test_core/representations/suite.html.rb +57 -0
  55. data/vendor/js-test-core/lib/js_test_core/representations/suites.rb +3 -0
  56. data/vendor/js-test-core/lib/js_test_core/representations/suites/screw_unit.html.rb +81 -0
  57. data/vendor/js-test-core/lib/js_test_core/resources.rb +15 -0
  58. data/vendor/js-test-core/lib/js_test_core/resources/core_file.rb +19 -0
  59. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +62 -0
  60. data/vendor/js-test-core/lib/js_test_core/resources/implementations_deprecation.rb +12 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources/not_found.rb +28 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/resource.rb +16 -0
  63. data/vendor/js-test-core/lib/js_test_core/resources/spec_file.rb +51 -0
  64. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +15 -0
  65. data/vendor/js-test-core/lib/js_test_core/server.rb +84 -0
  66. data/vendor/js-test-core/public/js_test_server.js +541 -0
  67. data/vendor/js-test-core/spec/example_framework/JsTestCore.css +0 -0
  68. data/vendor/js-test-core/spec/example_framework/JsTestCore.js +0 -0
  69. data/vendor/js-test-core/spec/example_framework/subdir/SubDirFile.js +0 -0
  70. data/vendor/js-test-core/spec/example_root/favicon.ico +0 -0
  71. data/vendor/js-test-core/spec/example_root/javascripts/foo.js +3 -0
  72. data/vendor/js-test-core/spec/example_root/javascripts/large_file.js +59 -0
  73. data/vendor/js-test-core/spec/example_root/javascripts/subdir/bar.js +1 -0
  74. data/vendor/js-test-core/spec/example_root/robots.txt +0 -0
  75. data/vendor/js-test-core/spec/example_root/stylesheets/example.css +3 -0
  76. data/vendor/js-test-core/spec/example_spec/custom_dir_and_suite/passing_spec.js +8 -0
  77. data/vendor/js-test-core/spec/example_spec/custom_suite.html +8 -0
  78. data/vendor/js-test-core/spec/example_spec/failing_spec.js +7 -0
  79. data/vendor/js-test-core/spec/example_spec/foo/failing_spec.js +8 -0
  80. data/vendor/js-test-core/spec/example_spec/foo/passing_spec.js +8 -0
  81. data/vendor/js-test-core/spec/example_spec/passing_spec.js +8 -0
  82. data/vendor/js-test-core/spec/functional/functional_spec.rb +25 -0
  83. data/vendor/js-test-core/spec/functional/functional_spec_helper.rb +42 -0
  84. data/vendor/js-test-core/spec/functional/functional_spec_server_starter.rb +77 -0
  85. data/vendor/js-test-core/spec/functional_suite.rb +10 -0
  86. data/vendor/js-test-core/spec/spec_helpers/be_http.rb +32 -0
  87. data/vendor/js-test-core/spec/spec_helpers/example_group.rb +36 -0
  88. data/vendor/js-test-core/spec/spec_helpers/fake_selenium_driver.rb +16 -0
  89. data/vendor/js-test-core/spec/spec_helpers/show_test_exceptions.rb +22 -0
  90. data/vendor/js-test-core/spec/spec_suite.rb +3 -0
  91. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +196 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/configuration_spec.rb +50 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/resources/core_file_spec.rb +60 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +81 -0
  96. data/vendor/js-test-core/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +18 -0
  97. data/vendor/js-test-core/spec/unit/js_test_core/resources/not_found_spec.rb +51 -0
  98. data/vendor/js-test-core/spec/unit/js_test_core/resources/spec_file_spec.rb +149 -0
  99. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +28 -0
  100. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +66 -0
  101. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +30 -0
  102. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  103. data/vendor/js-test-core/standalone.ru +1 -0
  104. data/vendor/js-test-core/vendor/lucky-luciano/README.markdown +77 -0
  105. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano.rb +5 -0
  106. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +142 -0
  107. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource/path.rb +24 -0
  108. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
  109. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
  110. data/vendor/js-test-core/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +276 -0
  111. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
  112. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
  113. data/vendor/js-test-core/vendor/lucky-luciano/syntax_ideas.txt +34 -0
  114. metadata +201 -0
data/CHANGES ADDED
@@ -0,0 +1,48 @@
1
+ 0.5.12
2
+ - Explicitly pass the :session_id in the post params to /sessions/finish after the suite is finished
3
+
4
+ 0.5.11
5
+ - Added ScrewUnit::Representations::Spec.project_js_files, .project_css_files, and .jquery_js_file.
6
+
7
+ 0.5.10
8
+ - Updated to erector 0.6.7, which fixes a bug related to including modules into Representations.
9
+
10
+ 0.5.9
11
+ - Allow test suite to clear all cookies
12
+
13
+ 0.5.7
14
+ - Fixed Server runner
15
+
16
+ 0.5.5
17
+ - Renamed ScrewUnit::ThinRunner to ScrewUnit::Server
18
+
19
+ 0.5.4
20
+ - Added ScrewUnit::ThinRunner.start
21
+
22
+ 0.5.0
23
+ - Replaced thin-rest with Sinatra and Lucky Luciano as the server base.
24
+ - The Screw Unit Server is now Rake middleware.
25
+ - Sensible directory defaults for the screw_unit_server executable.
26
+ - Replaced /implementations with /javascripts, assuming you have a /javascripts directory in the application root.
27
+
28
+ 0.4.0
29
+ - Added ScrewUnit::Representations::Spec#project_js_files and #project_css_files, which can be overridden, so the javascript include mechanism is not needed.
30
+ - Better error message when running using Selenium.
31
+
32
+ 0.3.3
33
+ - Fixed for latest version of Selenium, Rack, and Thin
34
+
35
+ 0.3.2
36
+ - Upgrading to ScrewUnit 0.3.2
37
+
38
+ 0.3.1
39
+ - Client accepts selenium_server_start_command parameter, which allows the user to parameterize the selenium_server_start_command
40
+ - Added support for running specs in Internet Explorer via POST /runners/iexplore
41
+ - Resource file download performance improvements via caching and chunked sending
42
+ - Fixed false positive bug when Client connection times out
43
+
44
+ 0.3.0
45
+ - Uses ScrewUnit 0.3.0
46
+
47
+ 0.1.0
48
+ - Initial Release
@@ -0,0 +1,359 @@
1
+ # Screw Unit Server
2
+ The Screw Unit ruby library is a server runner for the Screw Unit javascript library.
3
+
4
+ # Installing Screw Unit
5
+ You can use Screw Unit as a gem or as a Rails plugin.
6
+ To install the gem, run:
7
+ sudo gem install pivotal-screw-unit-server
8
+
9
+ To install the plugin with Rails 2.1.0:
10
+ script/plugin install git://github.com/pivotal/screw-unit-server.git
11
+
12
+ To install the plugin with Rails <2.1.0:
13
+ cd vendor/plugins
14
+ git clone git://github.com/pivotal/screw-unit-server.git
15
+
16
+ After installing screw unit server, run:
17
+ script/generate screw_unit
18
+
19
+ The Rails plugin gives you generators when using Screw Unit in a Rails environment.
20
+
21
+ # Running Screw Unit Server
22
+ You can run the Screw Unit Server from the command line or via a Rails script.
23
+ You can pass in the spec_file_path and public_path to the runner scripts,
24
+ or by setting the SCREW_UNIT_SPEC_ROOT and SCREW_UNIT_PUBLIC environment variables.
25
+
26
+ To run from the command line:
27
+ screw_unit_server [spec_file_path] [public_path]
28
+
29
+ If you are using screw_unit_server as a Rails plugin, you can simply run:
30
+ script/screw_unit_server
31
+
32
+ If you are using the screw_unit gem, you can run:
33
+ screw_unit_server /path/to/your/javascript/spec/files /path/to/your/javascript/implementation/files
34
+
35
+ Once the server is started, there are two possibly ways to run your js spec:
36
+ * Open your browser to http://localhost:8080/specs
37
+ * Start the Selenium server by running `selenium` from the command line, then running `screw_unit` from the command line
38
+
39
+ # Screw Unit on CI
40
+ JS spec uses the Selenium gem to automatically control browsers on different machines.
41
+
42
+ To use Screw Unit in a CI environment,
43
+ * Install and run the selenium RC server on the machine that you want to run the browsers by using the command:
44
+ selenium
45
+ * Run the screw_unit_server on the machine that has the files.
46
+ script/screw_unit_server
47
+ * Run the screw_unit client. The screw_unit client has --selenium_browser_start_command, --selenium_host, --selenium_port, and --spec_url arguments to specify
48
+ where the Selenium server is relative to the screw_unit server, and where the screw_unit server is relative to the browser.
49
+ * Running `script/screw_unit_server` is equivalent to running `script/screw_unit_server --selenium_browser_start_command *firefox --selenium_host localhost --selenium_port 4444 --spec_url http://localhost:8080/specs`
50
+
51
+ # Screw Unit Library
52
+
53
+ Screw.Unit is a Behavior-Driven Testing Framework for Javascript. It features nested describes. Its goals are to provide:
54
+
55
+ * a DSL for elegant, readable, organized specs;
56
+ * an interactive runner that can execute focused specs and describes;
57
+ * and brief, extensible source-code.
58
+
59
+ # What it is
60
+
61
+ ![Test Runner](http://s3.amazonaws.com/assets.pivotallabs.com/87/original/runner.png)
62
+
63
+ The testing language is closure-based. Consider,
64
+
65
+ describe("Matchers", function() {
66
+ it("invokes the provided matcher on a call to expect", function() {
67
+ expect(true).to(equal, true);
68
+ expect(true).to_not(equal, false);
69
+ });
70
+ });
71
+
72
+ A key feature of Screw.Unit are nested `describes` and the cascading `before` (and `after`) behavior that entails:
73
+
74
+ describe("a nested describe", function() {
75
+ var invocations = [];
76
+
77
+ before(function() {
78
+ invocations.push("before");
79
+ });
80
+
81
+ describe("a doubly nested describe", function() {
82
+ before(function() {
83
+ invocations.push('inner before');
84
+ });
85
+
86
+ it("runs befores in all ancestors prior to an it", function() {
87
+ expect(invocations).to(equal, ["before", "inner before"]);
88
+ });
89
+ });
90
+ });
91
+
92
+ # The Runner
93
+
94
+ The Screw.Unit runner is pretty fancy, supporting focused `describes` and focused `its`:
95
+
96
+ ![Focused Runner](http://s3.amazonaws.com/assets.pivotallabs.com/86/original/focused.png)
97
+
98
+ Click on a `describe` or `it` to run just those tests.
99
+
100
+ # Global Befores and Afters
101
+
102
+ A global `before` is a `before` block run before all tests in a test suite, regardless of their nesting. This is often useful to reset global variables, or blank-out DOM nodes before each test is run. Put this at the top of the your suite file or in your spec helper.
103
+
104
+ Screw.Unit(function() {
105
+ before(function() { ... });
106
+ });
107
+
108
+ Note that you can have any number of `Screw.Unit(...)` blocks in one file. Thus, you can have multiple global `befores` and `afters`.
109
+
110
+ # Custom Matchers
111
+
112
+ A custom matcher is a custom assertion specifically tailored to your application. These are helpful in increasing the readability and declarativity of your tests. To create a custom matcher, fill in the blanks for this code:
113
+
114
+ Screw.Matchers["be_even"] = {
115
+ match: function(expected, actual) {
116
+ return actual % 2 == 0;
117
+ },
118
+ failure_message: function(expected, actual, not) {
119
+ return 'expected ' + $.print(actual) + (not ? ' not' : '') + ' to be even';
120
+ }
121
+ }
122
+
123
+ You can invoke this matcher as follows: `expect(2).to(be_even)`.
124
+
125
+ # The Anatomy of Test Infrastructure
126
+
127
+ Typical test infrastructure spans multiple files:
128
+
129
+ * A `suite.html` file that has the necessary html, script tags, and link tags, to include your source code as well as the test infrastructure.
130
+ * A `spec_helper.js` file with global `before` and `after` blocks.
131
+ * A set of custom matchers.
132
+ * Your individual tests.
133
+
134
+ The file structure will typically look like:
135
+
136
+ spec/
137
+ suite.html
138
+ spec_helper.js
139
+ matchers/
140
+ a_matcher.js
141
+ another_matcher.js
142
+ models/
143
+ a_spec.js
144
+ another_spec.js
145
+ views/
146
+ yet_another_spec.js
147
+
148
+ The `models` and `views` directories are here only for comparison. As a general rule, mirror the file structure of your source code in your spec directory. For example, if you have an MVC application and you organize your source code into `models`, `views`, and `controllers` directories, have parallel directories in your spec/ directory, with tests for your models, views, and controllers in their respective directories.
149
+
150
+ # Writing Good Tests
151
+
152
+ A great test maximizes these features:
153
+
154
+ * it provides **documentation**, explaining the intended functioning of the system as well as how the source code works;
155
+ * it supports **ongoing development**, as you bit-by-bit write a failing test and make it pass;
156
+ * it supports **refactoring** and **prevents regression**;
157
+ * and it **requires little modification** as the implementation of the system changes, especially changes to unrelated code.
158
+
159
+ This section focuses principally on tests as documentation. **To provide documentation, as well as support future modification, a test should be readable and well organized.** Here are some recommendations on how to do it.
160
+
161
+ ## Use Nested Describes to Express Context
162
+
163
+ Often, when you test a system (a function, an object), it behaves differently in different contexts. Use **nested** describes liberally to express the context under which you make an assertion.
164
+
165
+ describe("Caller#prioritize", function() {
166
+ describe("when there are two callers in the queue", function() {
167
+ describe("and one caller has been waiting longer than another", function() {
168
+ ...
169
+ });
170
+ });
171
+ });
172
+
173
+ In addition to using nested describes to express context, use them to organize tests by the structural properties of your source code and programming language. In Javascript this is typically prototype and function. A parent describe for a prototype contains nested describes for each of its methods. If you have cross-cutting concerns (e.g., related behavior that spans across methods or prototypes), use a describe to group them conceptually.
174
+
175
+ describe("Car", function() {
176
+ describe("#start", function() {
177
+ });
178
+
179
+ describe("#stop", function() {
180
+ });
181
+
182
+ describe("callbacks", function() {
183
+ describe("after_purchase", function() {
184
+ });
185
+ });
186
+
187
+ describe("logging", function() {
188
+ });
189
+ });
190
+
191
+ In this example, one parent `describe` is used for all `Car` behavior. There is a describe for each method. Finally, cross-cutting concerns like callbacks and logging are grouped because of their conceptual affinity.
192
+
193
+ # Test Size
194
+
195
+ Individual tests should be short and sweet. It is sometimes recommended to make only one assertion per test:
196
+
197
+ it("chooses the caller who has been waiting the longest", function() {
198
+ expect(Caller.prioritize()).to(equal, caller_waiting_the_longest);
199
+ });
200
+
201
+ According to some, the ideal test is one line of code. In practice, it may be excessive to divide your tests to be this small. At ten lines of code (or more), a test is difficult to read quickly. Be pragmatic, bearing in mind the aims of testing.
202
+
203
+ Although one assertion per test is a good rule of thumb, feel free to violate the rule if equal clarity and better terseness is achievable:
204
+
205
+ it("returns the string representation of the boolean", function() {
206
+ expect($.print(true)).to(equal, 'true');
207
+ expect($.print(false)).to(equal, 'false');
208
+ });
209
+
210
+ Two tests would be overkill in this example.
211
+
212
+ ## Variable Naming
213
+
214
+ Name variables descriptively, especially ones that will become expected values in assertions. `caller_waiting_the_longest` is better than `c1`.
215
+
216
+ ## Dividing code between tests and `befores`
217
+
218
+ If there is only one line of setup and it is used in only one test, it may be better to include the setup in the test itself:
219
+
220
+ it("decrements the man's luck by 5", function() {
221
+ var man = new Man({luck: 5});
222
+
223
+ cat.cross_path(man);
224
+ expect(man.luck()).to(equal, 0);
225
+ });
226
+
227
+ But in general, it's nice to keep setup code in `before` blocks, especially if the setup can be shared across tests.
228
+
229
+ describe('Man', function() {
230
+ var man;
231
+ before(function() {
232
+ man = new Man({luck: 5});
233
+ });
234
+
235
+ describe('#decrement_luck', function() {
236
+ it("decrements the luck field by the given amount", function() {
237
+ man.decrement_luck(3);
238
+ expect(man.luck()).to(equal, 2)
239
+ });
240
+ });
241
+ ...
242
+ });
243
+
244
+ ## Preconditions
245
+
246
+ It is ideal, if there is any chance that your preconditions are non-obvious, to make precondition asserts in your test. The last example, were it more complicated, might be better written:
247
+
248
+ it("decrements the luck field by the given amount", function() {
249
+ expect(man.luck()).to(equal, 5);
250
+
251
+ man.decrement_luck(3);
252
+ expect(man.luck()).to(equal, 2)
253
+ });
254
+
255
+ Whitespace, as seen here, can be helpful in distinguishing setup and preconditions from the system under test (SUT) and its assertions. It is nice to be consistent in your use of whitespace (e.g., "always follow a group of preconditions by a newline"). But it is better to use whitespace as makes the most sense given the context. As with everything in life, do it consciously and deliberately, but change your mind frequently.
256
+
257
+ ## Behavioral Testing
258
+
259
+ Behavioral testing, that is, asserting that certain functions are called rather than certain values returned, is best done with closures. The dynamic nature of JavaScript makes mocking frameworks mostly unnecessary.
260
+
261
+ it("invokes #decrement_luck", function() {
262
+ var decrement_luck_was_called = false;
263
+ man.decrement_luck = function(amount) {
264
+ decrement_luck_was_called = true;
265
+ });
266
+
267
+ cat.cross_path(man);
268
+ expect(decrement_luck_was_called).to(equal, true);
269
+ });
270
+
271
+ # How to Test the DOM
272
+
273
+ The simplest way to test the DOM is to have a special DOM node in your `suite.html` file. Have all tests insert nodes into this node; have a global `before` reset the node between tests.
274
+
275
+ In `suite.html`:
276
+
277
+ <div id="dom_test"></div>
278
+
279
+ In `spec_helper.js`:
280
+
281
+ Screw.Unit(function() {
282
+ before(function() {
283
+ document.getElementById('dom_test').innerHTML = ''; // but use your favorite JS library here.
284
+ });
285
+ });
286
+
287
+ In `some_spec.js`:
288
+
289
+ describe("something that manipulates the DOM", function() {
290
+ it("is effortless to test!", function() {
291
+ var dom_test = document.getElementById('dom_test');
292
+ dom_test.innerHTML = 'awesome';
293
+ expect(dom_test.innerHTML).to(equal, 'awesome');
294
+ });
295
+ });
296
+
297
+ A Javascript library like jQuery, Prototype, or YUI is a essential for testing events.
298
+
299
+ # Implementation Details
300
+
301
+ Screw.Unit is implemented using some fancy metaprogramming learned from the formidable Yehuda Katz. This allows the `describe` and `it` functions to not pollute the global namespace. Essentially, we take the source code of your test and wrap it in a with block which provides a new scope:
302
+
303
+ var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
304
+ var fn = new Function("matchers", "specifications",
305
+ "with (specifications) { with (matchers) { " + contents + " } }"
306
+ );
307
+
308
+ fn.call(this, Screw.Matchers, Screw.Specifications);
309
+
310
+ Furthermore, Screw.Unit is implemented using the **Concrete Javascript** style, which is made possible by the [Effen plugin](http://github.com/nkallen/effen/tree/master) and jQuery. Concrete Javascript is an alternative to MVC. In Concrete Javascript, DOM objects serve as the model and view simultaneously. The DOM is constructed using semantic (and visual) markup, and behaviors are attached directly to DOM elements. For example,
311
+
312
+ $('.describe').fn({
313
+ parent: function() {
314
+ return $(this).parent('.describes').parent('.describe');
315
+ },
316
+ run: function() {
317
+ $(this).children('.its').children('.it').fn('run');
318
+ $(this).children('.describes').children('.describe').fn('run');
319
+ },
320
+ });
321
+
322
+ Here two methods (`#parent` and `#run`) are attached directly to DOM elements that have class `describe`. To invoke one of these methods, simply:
323
+
324
+ $('.describe').fn('run');
325
+
326
+ Bind behaviors by passing a hash (see the previous example). Using CSS3 selectors and cascading to attach behaviors provides interesting kind of multiple inheritance and polymorphism:
327
+
328
+ $('.describe, .it').fn({...}); // applies to both describe and its
329
+ $('.describe .describe').fn({...}); // applies to nested describes only
330
+
331
+ # Extensibility
332
+
333
+ Screw.Unit is designed from the ground-up to be extensible. For example, to add custom logging, simply subscribe to certain events:
334
+
335
+ $('.it')
336
+ .bind('enqueued', function() {...})
337
+ .bind('running', function() {...})
338
+ .bind('passed', function() {...})
339
+ .bind('failed', function(e, reason) {...})
340
+
341
+ There are also events for the `loading` and `loaded` test code code, as well as just `before` and just `after` all tests are run:
342
+
343
+ $(Screw)
344
+ .bind('loading', function() {...})
345
+ .bind('loaded', function() {...})
346
+ .bind('before', function() {...})
347
+ .bind('after', function() {...})
348
+
349
+ # Download
350
+
351
+ You can [download the source](http://github.com/nkallen/screw-unit/tree/master) from Github. There is are plenty of examples in the distribution.
352
+
353
+ # Thanks to
354
+
355
+ * Nathan Sobo
356
+ * Yehuda Katz
357
+ * Brian Takita
358
+ * Aman Gupta
359
+ * Tim Connor
@@ -0,0 +1,43 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "honkster-screw-unit-server"
5
+ s.executables = ["screw_unit", "screw_unit_server"]
6
+ s.summary = "Server and helpers for your Screw Unit tests."
7
+ s.email = "pivotallabsopensource@googlegroups.com"
8
+ s.homepage = "http://github.com/pivotal/screw-unit-server"
9
+ s.description = "The Screw Unit server conveniently serves your Screw Unit specs and javascript files and css stylesheets."
10
+ s.authors = ["Pivotal Labs", "Brian Takita"]
11
+ s.files = Dir["[A-Z]*"] +
12
+ Dir["*.rb"] +
13
+ Dir["*.ru"] +
14
+ Dir["lib/**/*.rb"] +
15
+ Dir["core/**/**"] +
16
+ Dir["bin/**"] +
17
+ Dir["vendor/**/**"] +
18
+ Dir["spec/**"]
19
+ s.test_files = Dir['spec/**/*.rb']
20
+ s.rdoc_options = ["--main", "README.markdown"]
21
+ s.extra_rdoc_files = ["README.markdown", "CHANGES"]
22
+ s.add_dependency("thin", ">=1.2.1")
23
+ s.add_dependency("erector", ">=0.6.7")
24
+ s.add_dependency("selenium-client")
25
+ end
26
+ rescue LoadError
27
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
28
+ end
29
+
30
+ desc "Runs the Rspec suite"
31
+ task(:default) do
32
+ run_suite
33
+ end
34
+
35
+ desc "Runs the Rspec suite"
36
+ task(:spec) do
37
+ run_suite
38
+ end
39
+
40
+ def run_suite
41
+ dir = File.dirname(__FILE__)
42
+ system("ruby #{dir}/spec/spec_suite.rb") || raise("Example Suite failed")
43
+ end