btakita-screw_unit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +2 -0
- data/README +147 -0
- data/Rakefile +70 -0
- data/bin/screw_unit +6 -0
- data/bin/screw_unit_server +10 -0
- data/core/README.markdown +107 -0
- data/core/TODO +2 -0
- data/core/lib/jquery-1.2.3.js +3408 -0
- data/core/lib/jquery.fn.js +29 -0
- data/core/lib/jquery.print.js +24 -0
- data/core/lib/screw.assets.js +36 -0
- data/core/lib/screw.behaviors.js +91 -0
- data/core/lib/screw.builder.js +81 -0
- data/core/lib/screw.css +93 -0
- data/core/lib/screw.events.js +39 -0
- data/core/lib/screw.matchers.js +65 -0
- data/core/lib/screw.server.js +21 -0
- data/core/spec/behaviors_spec.js +178 -0
- data/core/spec/matchers_spec.js +93 -0
- data/core/spec/suite.html +17 -0
- data/init.rb +0 -0
- data/lib/screw_unit/resources/spec.rb +37 -0
- data/lib/screw_unit/resources.rb +2 -0
- data/lib/screw_unit.rb +26 -0
- data/spec/functional/functional_spec.rb +14 -0
- data/spec/functional/functional_spec_helper.rb +55 -0
- data/spec/functional_suite.rb +10 -0
- data/spec/spec_suite.rb +3 -0
- data/spec/unit/js_test_core/specs/spec_dir_spec.rb +43 -0
- data/spec/unit/js_test_core/specs/spec_file_spec.rb +43 -0
- data/spec/unit/unit_spec_helper.rb +120 -0
- data/spec/unit_suite.rb +10 -0
- data/vendor/js_test_core/CHANGES +9 -0
- data/vendor/js_test_core/README +12 -0
- data/vendor/js_test_core/Rakefile +72 -0
- data/vendor/js_test_core/lib/js_test_core/client.rb +50 -0
- data/vendor/js_test_core/lib/js_test_core/rack/commonlogger.rb +5 -0
- data/vendor/js_test_core/lib/js_test_core/rack.rb +2 -0
- data/vendor/js_test_core/lib/js_test_core/rails_server.rb +22 -0
- data/vendor/js_test_core/lib/js_test_core/resources/dir.rb +52 -0
- data/vendor/js_test_core/lib/js_test_core/resources/file.rb +32 -0
- data/vendor/js_test_core/lib/js_test_core/resources/runners/firefox_runner.rb +73 -0
- data/vendor/js_test_core/lib/js_test_core/resources/runners.rb +15 -0
- data/vendor/js_test_core/lib/js_test_core/resources/specs/spec_dir.rb +50 -0
- data/vendor/js_test_core/lib/js_test_core/resources/specs/spec_file.rb +17 -0
- data/vendor/js_test_core/lib/js_test_core/resources/suite.rb +24 -0
- data/vendor/js_test_core/lib/js_test_core/resources/suite_finish.rb +19 -0
- data/vendor/js_test_core/lib/js_test_core/resources/web_root.rb +54 -0
- data/vendor/js_test_core/lib/js_test_core/resources.rb +10 -0
- data/vendor/js_test_core/lib/js_test_core/selenium/selenium_driver.rb +5 -0
- data/vendor/js_test_core/lib/js_test_core/selenium.rb +2 -0
- data/vendor/js_test_core/lib/js_test_core/server.rb +111 -0
- data/vendor/js_test_core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
- data/vendor/js_test_core/lib/js_test_core/thin/js_test_core_connection.rb +42 -0
- data/vendor/js_test_core/lib/js_test_core/thin.rb +3 -0
- data/vendor/js_test_core/lib/js_test_core.rb +30 -0
- data/vendor/js_test_core/spec/example_core/JsTestCore.css +0 -0
- data/vendor/js_test_core/spec/example_core/JsTestCore.js +0 -0
- data/vendor/js_test_core/spec/example_public/favicon.ico +0 -0
- data/vendor/js_test_core/spec/example_public/javascripts/foo.js +3 -0
- data/vendor/js_test_core/spec/example_public/robots.txt +0 -0
- data/vendor/js_test_core/spec/example_public/stylesheets/example.css +3 -0
- data/vendor/js_test_core/spec/example_specs/failing_spec.js +5 -0
- data/vendor/js_test_core/spec/example_specs/foo/failing_spec.js +6 -0
- data/vendor/js_test_core/spec/example_specs/foo/passing_spec.js +6 -0
- data/vendor/js_test_core/spec/spec_suite.rb +2 -0
- data/vendor/js_test_core/spec/specs/failing_spec.js +0 -0
- data/vendor/js_test_core/spec/unit/js_spec/client_spec.rb +137 -0
- data/vendor/js_test_core/spec/unit/js_spec/rails_server_spec.rb +45 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/dir_spec.rb +42 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/file_spec.rb +88 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/runner_spec.rb +24 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/runners/firefox_runner_spec.rb +161 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/specs/spec_dir_spec.rb +79 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/specs/spec_file_spec.rb +42 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/suite_finish_spec.rb +94 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/suite_spec.rb +44 -0
- data/vendor/js_test_core/spec/unit/js_spec/resources/web_root_spec.rb +67 -0
- data/vendor/js_test_core/spec/unit/js_spec/server_spec.rb +131 -0
- data/vendor/js_test_core/spec/unit/thin/js_spec_connection_spec.rb +64 -0
- data/vendor/js_test_core/spec/unit/thin/js_test_core_connection_spec.rb +92 -0
- data/vendor/js_test_core/spec/unit/unit_spec_helper.rb +125 -0
- data/vendor/js_test_core/spec/unit_suite.rb +10 -0
- metadata +169 -0
data/CHANGES
ADDED
data/README
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Screw Unit
|
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 screw_unit
|
8
|
+
|
9
|
+
To install the plugin, run:
|
10
|
+
script/plugin install git://github.com/btakita/screw-unit-server.git
|
11
|
+
script/generate screw_unit
|
12
|
+
|
13
|
+
The Rails plugin gives you generators when using Screw Unit in a Rails environment.
|
14
|
+
|
15
|
+
# Running Screw Unit Server
|
16
|
+
First you need to start your Screw Unit server.
|
17
|
+
|
18
|
+
If you are using screw_unit_server as a Rails plugin, you can simply run:
|
19
|
+
script/screw_unit_server
|
20
|
+
|
21
|
+
If you are using the screw_unit gem, you can run:
|
22
|
+
screw_unit_server /path/to/your/javascript/spec/files /path/to/your/javascript/implementation/files
|
23
|
+
|
24
|
+
Once the server is started, there are two possibly ways to run your js spec:
|
25
|
+
* Open your browser to http://localhost:8080/specs
|
26
|
+
* Start the Selenium server by running `selenium` from the command line, then running `screw_unit` from the command line
|
27
|
+
|
28
|
+
# Screw Unit on CI
|
29
|
+
JS spec uses the Selenium gem to automatically control browsers on different machines.
|
30
|
+
|
31
|
+
To use Screw Unit in a CI environment,
|
32
|
+
* Install and run the selenium RC server on the machine that you want to run the browsers by using the command:
|
33
|
+
selenium
|
34
|
+
* Run the screw_unit_server on the machine that has the files.
|
35
|
+
script/screw_unit_server
|
36
|
+
* Run the screw_unit client. The screw_unit client has --selenium_host, --selenium_port, and --spec_url arguments to specify
|
37
|
+
where the Selenium server is relative to the screw_unit server, and where the screw_unit server is relative to the browser.
|
38
|
+
|
39
|
+
# Screw Unit Library
|
40
|
+
|
41
|
+
Screw.Unit is a Behavior-Driven Testing Framework for Javascript written by Nathan Sobo and Nick Kallen. It features nested describes. Its goals are to provide:
|
42
|
+
|
43
|
+
* a DSL for elegant, readable, organized specs;
|
44
|
+
* an interactive runner which can execute focused specs and describes;
|
45
|
+
* and brief, extensible source-code.
|
46
|
+
|
47
|
+
# What it is
|
48
|
+
|
49
|
+
![Test Runner](http://s3.amazonaws.com/assets.pivotallabs.com/87/original/runner.png)
|
50
|
+
|
51
|
+
The testing language is inspired by JSpec (and Rspec, obviously). Consider,
|
52
|
+
|
53
|
+
describe("Matchers", function() {
|
54
|
+
it("invokes the provided matcher on a call to expect", function() {
|
55
|
+
expect(true).to(equal, true);
|
56
|
+
expect(true).to_not(equal, false);
|
57
|
+
});
|
58
|
+
});
|
59
|
+
|
60
|
+
A key feature of Screw.Unit are nested `describes` and the cascading `before` behavior that entails:
|
61
|
+
|
62
|
+
describe("a nested describe", function() {
|
63
|
+
var invocations = [];
|
64
|
+
|
65
|
+
before(function() {
|
66
|
+
invocations.push("before");
|
67
|
+
});
|
68
|
+
|
69
|
+
describe("a doubly nested describe", function() {
|
70
|
+
before(function() {
|
71
|
+
invocations.push('inner before');
|
72
|
+
});
|
73
|
+
|
74
|
+
it("runs befores in all ancestors prior to an it", function() {
|
75
|
+
expect(invocations).to(equal, ["before", "inner before"]);
|
76
|
+
});
|
77
|
+
});
|
78
|
+
});
|
79
|
+
|
80
|
+
The Screw.Unit runner is pretty fancy, supporting focused `describes` and focused `its`:
|
81
|
+
|
82
|
+
![Focused Runner](http://s3.amazonaws.com/assets.pivotallabs.com/86/original/focused.png)
|
83
|
+
|
84
|
+
You can [download the source](http://github.com/nkallen/screw-unit/tree/master) from Github. Please see the included spec (`screwunit_spec.js`) to get up and running.
|
85
|
+
|
86
|
+
# Implementation Details
|
87
|
+
|
88
|
+
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:
|
89
|
+
|
90
|
+
var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
|
91
|
+
var fn = new Function("matchers", "specifications",
|
92
|
+
"with (specifications) { with (matchers) { " + contents + " } }"
|
93
|
+
);
|
94
|
+
|
95
|
+
fn.call(this, Screw.Matchers, Screw.Specifications);
|
96
|
+
|
97
|
+
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,
|
98
|
+
|
99
|
+
$('.describe').fn({
|
100
|
+
parent: function() {
|
101
|
+
return $(this).parent('.describes').parent('.describe');
|
102
|
+
},
|
103
|
+
run: function() {
|
104
|
+
$(this).children('.its').children('.it').fn('run');
|
105
|
+
$(this).children('.describes').children('.describe').fn('run');
|
106
|
+
},
|
107
|
+
});
|
108
|
+
|
109
|
+
Here two methods (`#parent` and `#run`) are attached directly to DOM elements that have class `describe`. To invoke one of these methods, simply:
|
110
|
+
|
111
|
+
$('.describe').fn('run');
|
112
|
+
|
113
|
+
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:
|
114
|
+
|
115
|
+
$('.describe, .it').fn({...}); // applies to both describe and its
|
116
|
+
$('.describe .describe').fn({...}); // applies to nested describes only
|
117
|
+
|
118
|
+
A typical Concrete Javascript Application is divided into 4 aspects:
|
119
|
+
|
120
|
+
* a DOM data model,
|
121
|
+
* CSS bound to DOM elements,
|
122
|
+
* asynchronous events bound to DOM elements (`click`, `mouseover`), etc.,
|
123
|
+
* synchronous behaviors bound to DOM elements (`run` and `parent` in the above example).
|
124
|
+
|
125
|
+
The Concrete style is particularly well-suited to Screw.Unit; to add the ability to run a focused spec, we simply bind a click event to an `it` or a `describe`, which runs itself:
|
126
|
+
|
127
|
+
$('.describe, .it')
|
128
|
+
.click(function() {
|
129
|
+
$(this).fn('run');
|
130
|
+
})
|
131
|
+
|
132
|
+
Anyway, more details about Effen / Concrete Javascript in a later post.
|
133
|
+
|
134
|
+
# Extensibility
|
135
|
+
|
136
|
+
Screw.Unit is designed from the ground-up to be extensible. For example, to add custom logging, simply subscribe to certain events:
|
137
|
+
|
138
|
+
$('.it')
|
139
|
+
.bind('enqueued', function() {...})
|
140
|
+
.bind('running', function() {...})
|
141
|
+
.bind('passed', function() {...})
|
142
|
+
.bind('failed', function(e, reason) {...})
|
143
|
+
|
144
|
+
# Thanks to
|
145
|
+
|
146
|
+
* Nathan Sobo
|
147
|
+
* Yehuda Katz
|
data/Rakefile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require "rake"
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/contrib/rubyforgepublisher'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rake/testtask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
|
8
|
+
desc "Runs the Rspec suite"
|
9
|
+
task(:default) do
|
10
|
+
run_suite
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Runs the Rspec suite"
|
14
|
+
task(:spec) do
|
15
|
+
run_suite
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Copies the trunk to a tag with the name of the current release"
|
19
|
+
task(:tag_release) do
|
20
|
+
tag_release
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_suite
|
24
|
+
dir = File.dirname(__FILE__)
|
25
|
+
system("ruby #{dir}/spec/spec_suite.rb") || raise("Example Suite failed")
|
26
|
+
end
|
27
|
+
|
28
|
+
PKG_NAME = "screw_unit"
|
29
|
+
PKG_VERSION = "0.1.0"
|
30
|
+
PKG_FILES = FileList[
|
31
|
+
'[A-Z]*',
|
32
|
+
'*.rb',
|
33
|
+
'lib/**/*.rb',
|
34
|
+
'core/**',
|
35
|
+
'bin/**',
|
36
|
+
'spec/**/*.rb'
|
37
|
+
]
|
38
|
+
|
39
|
+
spec = Gem::Specification.new do |s|
|
40
|
+
s.name = PKG_NAME
|
41
|
+
s.version = PKG_VERSION
|
42
|
+
s.summary = "The ScrewUnit client library (http://github.com/nkallen/screw-unit) plus a convenient ruby server."
|
43
|
+
s.test_files = "spec/spec_suite.rb"
|
44
|
+
s.description = s.summary
|
45
|
+
|
46
|
+
s.files = PKG_FILES.to_a
|
47
|
+
s.require_path = 'lib'
|
48
|
+
|
49
|
+
s.has_rdoc = true
|
50
|
+
s.extra_rdoc_files = [ "README", "CHANGES" ]
|
51
|
+
s.rdoc_options = ["--main", "README", "--inline-source", "--line-numbers"]
|
52
|
+
|
53
|
+
s.test_files = Dir.glob('spec/*_spec.rb')
|
54
|
+
s.require_path = 'lib'
|
55
|
+
s.author = "Brian Takita"
|
56
|
+
s.email = "brian@pivotallabs.com"
|
57
|
+
s.homepage = "http://pivotallabs.com"
|
58
|
+
s.rubyforge_project = "pivotalrb"
|
59
|
+
s.add_dependency('Selenium')
|
60
|
+
s.add_dependency('thin', '>=0.8.0')
|
61
|
+
end
|
62
|
+
|
63
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
64
|
+
pkg.need_zip = true
|
65
|
+
pkg.need_tar = true
|
66
|
+
end
|
67
|
+
|
68
|
+
def tag_release
|
69
|
+
system("git tag #{dashed_version} -m 'Version #{PKG_VERSION}'")
|
70
|
+
end
|
data/bin/screw_unit
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
$LOAD_PATH.unshift("#{dir}/../lib")
|
5
|
+
require "screw_unit"
|
6
|
+
|
7
|
+
spec_root_path = ARGV[0] || raise("You need to pass in a spec root")
|
8
|
+
implementation_root_path = ARGV[1] || raise("You need to pass in an implementation root")
|
9
|
+
public_path = ARGV[2] || raise("You need to pass in a public path")
|
10
|
+
ScrewUnit::Server.run(spec_root_path, implementation_root_path, public_path)
|
@@ -0,0 +1,107 @@
|
|
1
|
+
Screw.Unit is a Behavior-Driven Testing Framework for Javascript written by Nathan Sobo and Nick Kallen. It features nested describes. Its goals are to provide:
|
2
|
+
|
3
|
+
* a DSL for elegant, readable, organized specs;
|
4
|
+
* an interactive runner which can execute focused specs and describes;
|
5
|
+
* and brief, extensible source-code.
|
6
|
+
|
7
|
+
# What it is
|
8
|
+
|
9
|
+
![Test Runner](http://s3.amazonaws.com/assets.pivotallabs.com/87/original/runner.png)
|
10
|
+
|
11
|
+
The testing language is inspired by JSpec (and Rspec, obviously). Consider,
|
12
|
+
|
13
|
+
describe("Matchers", function() {
|
14
|
+
it("invokes the provided matcher on a call to expect", function() {
|
15
|
+
expect(true).to(equal, true);
|
16
|
+
expect(true).to_not(equal, false);
|
17
|
+
});
|
18
|
+
});
|
19
|
+
|
20
|
+
A key feature of Screw.Unit are nested `describes` and the cascading `before` behavior that entails:
|
21
|
+
|
22
|
+
describe("a nested describe", function() {
|
23
|
+
var invocations = [];
|
24
|
+
|
25
|
+
before(function() {
|
26
|
+
invocations.push("before");
|
27
|
+
});
|
28
|
+
|
29
|
+
describe("a doubly nested describe", function() {
|
30
|
+
before(function() {
|
31
|
+
invocations.push('inner before');
|
32
|
+
});
|
33
|
+
|
34
|
+
it("runs befores in all ancestors prior to an it", function() {
|
35
|
+
expect(invocations).to(equal, ["before", "inner before"]);
|
36
|
+
});
|
37
|
+
});
|
38
|
+
});
|
39
|
+
|
40
|
+
The Screw.Unit runner is pretty fancy, supporting focused `describes` and focused `its`:
|
41
|
+
|
42
|
+
![Focused Runner](http://s3.amazonaws.com/assets.pivotallabs.com/86/original/focused.png)
|
43
|
+
|
44
|
+
You can [download the source](http://github.com/nkallen/screw-unit/tree/master) from Github. Please see the included spec (`screwunit_spec.js`) to get up and running.
|
45
|
+
|
46
|
+
# Implementation Details
|
47
|
+
|
48
|
+
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:
|
49
|
+
|
50
|
+
var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
|
51
|
+
var fn = new Function("matchers", "specifications",
|
52
|
+
"with (specifications) { with (matchers) { " + contents + " } }"
|
53
|
+
);
|
54
|
+
|
55
|
+
fn.call(this, Screw.Matchers, Screw.Specifications);
|
56
|
+
|
57
|
+
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,
|
58
|
+
|
59
|
+
$('.describe').fn({
|
60
|
+
parent: function() {
|
61
|
+
return $(this).parent('.describes').parent('.describe');
|
62
|
+
},
|
63
|
+
run: function() {
|
64
|
+
$(this).children('.its').children('.it').fn('run');
|
65
|
+
$(this).children('.describes').children('.describe').fn('run');
|
66
|
+
},
|
67
|
+
});
|
68
|
+
|
69
|
+
Here two methods (`#parent` and `#run`) are attached directly to DOM elements that have class `describe`. To invoke one of these methods, simply:
|
70
|
+
|
71
|
+
$('.describe').fn('run');
|
72
|
+
|
73
|
+
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:
|
74
|
+
|
75
|
+
$('.describe, .it').fn({...}); // applies to both describe and its
|
76
|
+
$('.describe .describe').fn({...}); // applies to nested describes only
|
77
|
+
|
78
|
+
A typical Concrete Javascript Application is divided into 4 aspects:
|
79
|
+
|
80
|
+
* a DOM data model,
|
81
|
+
* CSS bound to DOM elements,
|
82
|
+
* asynchronous events bound to DOM elements (`click`, `mouseover`), etc.,
|
83
|
+
* synchronous behaviors bound to DOM elements (`run` and `parent` in the above example).
|
84
|
+
|
85
|
+
The Concrete style is particularly well-suited to Screw.Unit; to add the ability to run a focused spec, we simply bind a click event to an `it` or a `describe`, which runs itself:
|
86
|
+
|
87
|
+
$('.describe, .it')
|
88
|
+
.click(function() {
|
89
|
+
$(this).fn('run');
|
90
|
+
})
|
91
|
+
|
92
|
+
Anyway, more details about Effen / Concrete Javascript in a later post.
|
93
|
+
|
94
|
+
# Extensibility
|
95
|
+
|
96
|
+
Screw.Unit is designed from the ground-up to be extensible. For example, to add custom logging, simply subscribe to certain events:
|
97
|
+
|
98
|
+
$('.it')
|
99
|
+
.bind('enqueued', function() {...})
|
100
|
+
.bind('running', function() {...})
|
101
|
+
.bind('passed', function() {...})
|
102
|
+
.bind('failed', function(e, reason) {...})
|
103
|
+
|
104
|
+
# Thanks to
|
105
|
+
|
106
|
+
* Nathan Sobo
|
107
|
+
* Yehuda Katz
|
data/core/TODO
ADDED