evergreen 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,13 +2,19 @@
2
2
 
3
3
  "Because green is the new Blue(Ridge)"
4
4
 
5
- Evergreen is a tool to run javascript unit tests for client side JavaScript. It combines a server which allows you to serve up and run your specs in a browser, as well as a runner which uses Capybara and any of its drivers to run your specs. Evergreen uses the Jasmine unit testing framework for JavaScript.
5
+ Evergreen is a tool to run javascript unit tests for client side JavaScript. It
6
+ combines a server which allows you to serve up and run your specs in a browser,
7
+ as well as a runner which uses Capybara and any of its drivers to run your
8
+ specs. Evergreen uses the Jasmine unit testing framework for JavaScript.
6
9
 
7
10
  http://github.com/jnicklas/evergreen
8
11
 
9
12
  == Philosophy
10
13
 
11
- Evergreen is a unit testing tool. Its purpose is to test JavaScript in isolation from your application. If you need a tool that tests how your JavaScript integrates with your application you should use an integration testing framework, such as {Capybara}[http://github.com/jnicklas/capybara].
14
+ Evergreen is a unit testing tool. Its purpose is to test JavaScript in
15
+ isolation from your application. If you need a tool that tests how your
16
+ JavaScript integrates with your application you should use an integration
17
+ testing framework, such as {Capybara}[http://github.com/jnicklas/capybara].
12
18
 
13
19
  == Installation
14
20
 
@@ -18,7 +24,9 @@ Install as a Ruby gem:
18
24
 
19
25
  == Usage
20
26
 
21
- Evergreen assumes a file and directory structure, place all your javascript code inside ./public and all spec files inside ./spec/javascripts. All spec files should end in _spec.js. For example:
27
+ Evergreen assumes a file and directory structure, place all your javascript
28
+ code inside ./public and all spec files inside ./spec/javascripts. All spec
29
+ files should end in _spec.js. For example:
22
30
 
23
31
  public/widget.js
24
32
  spec/javascripts/widget_spec.js
@@ -31,7 +39,8 @@ You can require files from the public directory inside your spec file:
31
39
  ...
32
40
  });
33
41
 
34
- You can now look at your spec files inside a browser by starting up the Evergreen server:
42
+ You can now look at your spec files inside a browser by starting up the
43
+ Evergreen server:
35
44
 
36
45
  evergreen serve
37
46
 
@@ -45,7 +54,8 @@ Add Evergreen to your Gemfile:
45
54
 
46
55
  gem 'evergreen', :require => 'evergreen/rails'
47
56
 
48
- Start your rails application and navigate to /evergreen. You should now see a list of all spec files, click on one to run it.
57
+ Start your rails application and navigate to /evergreen. You should now see a
58
+ list of all spec files, click on one to run it.
49
59
 
50
60
  There's a rake task provided for you that you can use to run your specs:
51
61
 
@@ -57,11 +67,15 @@ Add the following line to your Rakefile:
57
67
 
58
68
  require 'evergreen/tasks'
59
69
 
60
- This will give you the `spec:javascripts` rake task. Note that mounting is not possible under Rails 2 and that `require 'evergreen/rails'` will fail.
70
+ This will give you the `spec:javascripts` rake task. Note that mounting is not
71
+ possible under Rails 2 and that `require 'evergreen/rails'` will fail.
61
72
 
62
73
  == Configuration
63
74
 
64
- By default, Evergreen uses Selenium to run your specs and assumes a certain directory structure. If this standard is fine for you, then you don't need to do anything else. If you need to configure Evergreen to suit your needs, Evergreen will automatically look for and load the following files:
75
+ By default, Evergreen uses Selenium to run your specs and assumes a certain
76
+ directory structure. If this standard is fine for you, then you don't need to
77
+ do anything else. If you need to configure Evergreen to suit your needs,
78
+ Evergreen will automatically look for and load the following files:
65
79
 
66
80
  config/evergreen.rb
67
81
  .evergreen
@@ -80,7 +94,12 @@ The content of these files could look like this:
80
94
 
81
95
  == Transactions
82
96
 
83
- One problem often faced when writing unit tests for client side code is that changes to the page are not reverted for the next example, so that successive examples become dependent on each other. Evergreen adds a special div to your page with an id of test. This div is automatically emptied before each example. You should avoid appending markup to the page body and instead append it to this test div:
97
+ One problem often faced when writing unit tests for client side code is that
98
+ changes to the page are not reverted for the next example, so that successive
99
+ examples become dependent on each other. Evergreen adds a special div to your
100
+ page with an id of test. This div is automatically emptied before each example.
101
+ You should avoid appending markup to the page body and instead append it to
102
+ this test div:
84
103
 
85
104
  describe('transactions', function() {
86
105
  it("should add stuff in one test...", function() {
@@ -95,12 +114,14 @@ One problem often faced when writing unit tests for client side code is that cha
95
114
 
96
115
  == Templates
97
116
 
98
- Even more powerful than that, Evergreen allows you to create HTML templates to go along with your specs. Put the templates in their own folder like this:
117
+ Even more powerful than that, Evergreen allows you to create HTML templates to
118
+ go along with your specs. Put the templates in their own folder like this:
99
119
 
100
120
  spec/javascripts/templates/one_template.html
101
121
  spec/javascripts/templates/another_template.html
102
122
 
103
- You can then load the template into the test div, by calling the template function in your specs:
123
+ You can then load the template into the test div, by calling the template
124
+ function in your specs:
104
125
 
105
126
  describe('transactions', function() {
106
127
  template('one_template.html')
@@ -116,19 +137,36 @@ If you add a spec_helper file like so:
116
137
 
117
138
  spec/javascripts/spec_helper.js
118
139
 
119
- It will automatically be loaded. This is a great place for adding custom matchers and the like.
140
+ It will automatically be loaded. This is a great place for adding custom
141
+ matchers and the like.
120
142
 
121
143
  == CoffeeScript
122
144
 
123
- Evergreen supports specs written in {CoffeeScript}[http://github.com/jashkenas/coffee-script]. Just name your spec file _spec.coffee and it will automatically be translated for you.
145
+ Evergreen supports specs written in
146
+ {CoffeeScript}[http://github.com/jashkenas/coffee-script]. Just name your spec
147
+ file _spec.coffee and it will automatically be translated for you.
124
148
 
125
- You can also add a CoffeeScript spec helper, but remember that CoffeeScript encloses individual files in a closure, if you need something you define in the spec helper to be available in your spec files, attach it to the window object:
149
+ You can also add a CoffeeScript spec helper, but remember that CoffeeScript
150
+ encloses individual files in a closure, if you need something you define in the
151
+ spec helper to be available in your spec files, attach it to the window object:
126
152
 
127
153
  # spec/javascripts/spec_helper.coffee
128
154
 
129
155
  MyThing: "foo" # local to spec helper
130
156
  window.MyThing: "foo" # global
131
157
 
158
+ == Development
159
+
160
+ If you plan to work on Evergreen, you need to checkout the Jasmine gem, which
161
+ is added as a git submodule. Run the following command:
162
+
163
+ git submodule update --init
164
+
165
+ If you're using a version of Evergreen from git with bundler, you need to tell
166
+ bundler to use submodules, this can be achieved with the following command:
167
+
168
+ gem 'evergreen', :submodules => true, :git => 'git://github.com/jnicklas/evergreen.git'
169
+
132
170
  == License:
133
171
 
134
172
  (The MIT License)
@@ -21,6 +21,11 @@ module Evergreen
21
21
  yield self
22
22
  end
23
23
 
24
+ def extensions(&block)
25
+ @extensions = block if block
26
+ @extensions
27
+ end
28
+
24
29
  def use_defaults!
25
30
  configure do |config|
26
31
  config.driver = :selenium
@@ -1,6 +1,8 @@
1
1
  module Evergreen
2
2
  def self.application(suite)
3
3
  Rack::Builder.new do
4
+ instance_eval(&Evergreen.extensions) if Evergreen.extensions
5
+
4
6
  map "/jasmine" do
5
7
  use Rack::Static, :urls => ["/"], :root => File.expand_path('../jasmine/lib', File.dirname(__FILE__))
6
8
  run lambda { |env| [404, {}, "No such file"]}
@@ -2,8 +2,6 @@ require 'open3'
2
2
 
3
3
  module Evergreen
4
4
  class Spec
5
- class CoffeeScriptError < StandardError; end
6
-
7
5
  attr_reader :name, :suite
8
6
 
9
7
  def initialize(suite, name)
@@ -21,9 +19,8 @@ module Evergreen
21
19
 
22
20
  def read
23
21
  if full_path =~ /\.coffee$/
24
- stdout, stderr = Open3.popen3("coffee -p #{full_path}")[1,2].map { |b| b.read }
25
- raise CoffeeScriptError, stderr unless stderr.empty?
26
- stdout
22
+ require 'coffee-script'
23
+ CoffeeScript.compile(File.read(full_path))
27
24
  else
28
25
  File.read(full_path)
29
26
  end
@@ -30,8 +30,8 @@ module Evergreen
30
30
  end
31
31
 
32
32
  def specs
33
- Dir.glob(File.join(root, Evergreen.spec_dir, '*_spec.{js,coffee}')).map do |path|
34
- Spec.new(self, File.basename(path))
33
+ Dir.glob(File.join(root, Evergreen.spec_dir, '**/*_spec.{js,coffee}')).map do |path|
34
+ Spec.new(self, path.gsub(File.join(root, Evergreen.spec_dir, ''), ''))
35
35
  end
36
36
  end
37
37
 
@@ -20,6 +20,10 @@ module Evergreen
20
20
  end
21
21
  alias_method :contents, :read
22
22
 
23
+ def escaped_contents
24
+ contents.to_json.gsub("<script>", %{<scr" + "ipt>}).gsub("</script>", %{</scr" + "ipt>})
25
+ end
26
+
23
27
  def exist?
24
28
  File.exist?(full_path)
25
29
  end
@@ -1,3 +1,3 @@
1
1
  module Evergreen
2
- VERSION = '0.4.0'
2
+ VERSION = '0.4.1'
3
3
  end
@@ -25,14 +25,16 @@
25
25
  <div id="test"></div>
26
26
 
27
27
  <script type="text/javascript">
28
- (function() {
29
- Evergreen.driver = <%= Evergreen.driver.to_json %>;
30
- <% @suite.templates.each do |template| %>
31
- Evergreen.templates[<%= template.name.to_json %>] = <%= template.read.to_json %>;
32
- <% end %>
33
- var jasmineEnv = jasmine.getEnv();
34
- jasmineEnv.addReporter(new jasmine.TrivialReporter());
35
- jasmineEnv.addReporter(new Evergreen.ReflectiveReporter());
36
- jasmineEnv.execute();
37
- })();
28
+ // <![CDATA[
29
+ (function() {
30
+ Evergreen.driver = <%= Evergreen.driver.to_json %>;
31
+ <% @suite.templates.each do |template| %>
32
+ Evergreen.templates[<%= template.name.to_json %>] = <%= template.escaped_contents %>;
33
+ <% end %>
34
+ var jasmineEnv = jasmine.getEnv();
35
+ jasmineEnv.addReporter(new jasmine.TrivialReporter());
36
+ jasmineEnv.addReporter(new Evergreen.ReflectiveReporter());
37
+ jasmineEnv.execute();
38
+ })();
39
+ // ]]>
38
40
  </script>
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Evergreen, ".application" do
4
- include Capybara
4
+ include Capybara::DSL
5
5
 
6
6
  it "should show a successful test run" do
7
7
  visit("/")
@@ -21,4 +21,9 @@ describe Evergreen, ".application" do
21
21
  page.should have_content("2 specs, 1 failure")
22
22
  page.should have_content("Expected 'bar' to equal 'noooooo'.")
23
23
  end
24
+
25
+ it "should add extensions to Evergreen" do
26
+ visit('/awesome')
27
+ page.should have_content('Totally awesome')
28
+ end
24
29
  end
@@ -14,7 +14,7 @@ describe Evergreen::Runner do
14
14
 
15
15
  it { should include('.F..') }
16
16
  it { should include("Expected 'bar' to equal 'noooooo'") }
17
- it { should include("17 examples, 3 failures") }
17
+ it { should include("18 examples, 3 failures") }
18
18
  end
19
19
  end
20
20
 
@@ -5,9 +5,15 @@ require 'evergreen'
5
5
  require 'rspec'
6
6
 
7
7
  require 'capybara/dsl'
8
- require 'capybara/envjs'
8
+ require 'capybara-webkit'
9
9
 
10
- TEST_DRIVER = :envjs
10
+ TEST_DRIVER = :webkit
11
+
12
+ Evergreen.extensions do
13
+ map "/awesome" do
14
+ run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<html><body>Totally awesome</body></html>"]}
15
+ end
16
+ end
11
17
 
12
18
  Capybara.app = Evergreen::Suite.new(File.expand_path('suite1', File.dirname(__FILE__))).application
13
19
  Capybara.default_driver = TEST_DRIVER
@@ -0,0 +1 @@
1
+ <script>var foo = 0;</script>
@@ -0,0 +1,3 @@
1
+ <h1 id="script-tags"></h1>
2
+
3
+ <script></script>
@@ -33,6 +33,14 @@ describe('templates', function() {
33
33
  });
34
34
  });
35
35
 
36
+ describe('with template with script tags', function() {
37
+ template('script_tags.html')
38
+
39
+ it("should append the template to the test div", function() {
40
+ expect($('#test h1#script-tags').length).toEqual(1);
41
+ });
42
+ });
43
+
36
44
  });
37
45
 
38
46
  describe('stylesheet', function() {
@@ -13,8 +13,8 @@ describe Evergreen::Suite do
13
13
  end
14
14
 
15
15
  describe '#specs' do
16
- it "should find all specs in the given root directory" do
17
- subject.specs.map(&:name).should include('testing_spec.js', 'foo_spec.js', 'bar_spec.js', 'coffeescript_spec.coffee')
16
+ it "should find all specs recursively in the given root directory" do
17
+ subject.specs.map(&:name).should include('testing_spec.js', 'foo_spec.js', 'bar_spec.js', 'libs/lucid_spec.js', 'models/game_spec.js')
18
18
  end
19
19
  end
20
20
 
@@ -20,3 +20,13 @@ describe Evergreen::Template do
20
20
  end
21
21
 
22
22
  end
23
+
24
+ describe Evergreen::Template, "escaping" do
25
+ let(:root) { File.expand_path('suite1', File.dirname(__FILE__)) }
26
+ let(:suite) { Evergreen::Suite.new(root) }
27
+ subject { Evergreen::Template.new(suite, 'escape.html') }
28
+
29
+ it "escapes contents" do
30
+ subject.escaped_contents.strip.should == %{"<scr" + "ipt>var foo = 0;</scr" + "ipt>\\n"}
31
+ end
32
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evergreen
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 0
10
- version: 0.4.0
9
+ - 1
10
+ version: 0.4.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonas Nicklas
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-05 00:00:00 +01:00
18
+ date: 2011-06-22 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -28,10 +28,9 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  hash: 15
30
30
  segments:
31
+ - 1
31
32
  - 0
32
- - 4
33
- - 0
34
- version: 0.4.0
33
+ version: "1.0"
35
34
  type: :runtime
36
35
  version_requirements: *id001
37
36
  - !ruby/object:Gem::Dependency
@@ -42,12 +41,10 @@ dependencies:
42
41
  requirements:
43
42
  - - ">="
44
43
  - !ruby/object:Gem::Version
45
- hash: 25
44
+ hash: 3
46
45
  segments:
47
46
  - 0
48
- - 3
49
- - 5
50
- version: 0.3.5
47
+ version: "0"
51
48
  type: :runtime
52
49
  version_requirements: *id002
53
50
  - !ruby/object:Gem::Dependency
@@ -56,7 +53,7 @@ dependencies:
56
53
  requirement: &id003 !ruby/object:Gem::Requirement
57
54
  none: false
58
55
  requirements:
59
- - - ">="
56
+ - - ~>
60
57
  - !ruby/object:Gem::Version
61
58
  hash: 13
62
59
  segments:
@@ -73,18 +70,30 @@ dependencies:
73
70
  requirements:
74
71
  - - ">="
75
72
  - !ruby/object:Gem::Version
76
- hash: 23
73
+ hash: 3
77
74
  segments:
78
- - 1
79
75
  - 0
80
- - 0
81
- version: 1.0.0
76
+ version: "0"
82
77
  type: :runtime
83
78
  version_requirements: *id004
84
79
  - !ruby/object:Gem::Dependency
85
- name: rspec
80
+ name: coffee-script
86
81
  prerelease: false
87
82
  requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :runtime
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: rspec
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
88
97
  none: false
89
98
  requirements:
90
99
  - - ~>
@@ -95,23 +104,39 @@ dependencies:
95
104
  - 0
96
105
  version: "2.0"
97
106
  type: :development
98
- version_requirements: *id005
107
+ version_requirements: *id006
99
108
  - !ruby/object:Gem::Dependency
100
- name: capybara-envjs
109
+ name: capybara-webkit
101
110
  prerelease: false
102
- requirement: &id006 !ruby/object:Gem::Requirement
111
+ requirement: &id007 !ruby/object:Gem::Requirement
103
112
  none: false
104
113
  requirements:
105
- - - ~>
114
+ - - ">="
106
115
  - !ruby/object:Gem::Version
107
- hash: 15
116
+ hash: -1848230056
108
117
  segments:
118
+ - 1
109
119
  - 0
110
- - 4
111
120
  - 0
112
- version: 0.4.0
121
+ - beta4
122
+ version: 1.0.0.beta4
113
123
  type: :development
114
- version_requirements: *id006
124
+ version_requirements: *id007
125
+ - !ruby/object:Gem::Dependency
126
+ name: therubyracer
127
+ prerelease: false
128
+ requirement: &id008 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ hash: 25
134
+ segments:
135
+ - 0
136
+ - 9
137
+ version: "0.9"
138
+ type: :development
139
+ version_requirements: *id008
115
140
  description: Run Jasmine JavaScript unit tests, integrate them into Ruby applications.
116
141
  email:
117
142
  - jonas.nicklas@gmail.com
@@ -225,11 +250,15 @@ files:
225
250
  - spec/suite1/spec/javascripts/failing_spec.js
226
251
  - spec/suite1/spec/javascripts/foo_spec.js
227
252
  - spec/suite1/spec/javascripts/invalid_coffee_spec.coffee
253
+ - spec/suite1/spec/javascripts/libs/lucid_spec.js
254
+ - spec/suite1/spec/javascripts/models/game_spec.js
228
255
  - spec/suite1/spec/javascripts/slow_spec.coffee
229
256
  - spec/suite1/spec/javascripts/spec_helper.coffee
230
257
  - spec/suite1/spec/javascripts/spec_helper.js
231
258
  - spec/suite1/spec/javascripts/templates/another_template.html
259
+ - spec/suite1/spec/javascripts/templates/escape.html
232
260
  - spec/suite1/spec/javascripts/templates/one_template.html
261
+ - spec/suite1/spec/javascripts/templates/script_tags.html
233
262
  - spec/suite1/spec/javascripts/templates_spec.js
234
263
  - spec/suite1/spec/javascripts/testing_spec.js
235
264
  - spec/suite1/spec/javascripts/transactions_spec.js