matcha 0.9.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 (50) hide show
  1. data/.gitignore +19 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +90 -0
  4. data/README.md +194 -0
  5. data/Rakefile +8 -0
  6. data/app/controllers/matcha/specs_controller.rb +22 -0
  7. data/app/models/matcha/spec.rb +25 -0
  8. data/app/views/layouts/matcha/specs.html.erb +31 -0
  9. data/app/views/matcha/specs/index.html.erb +1 -0
  10. data/app/views/matcha/specs/show.html.erb +1 -0
  11. data/config/routes.rb +4 -0
  12. data/lib/matcha.rb +41 -0
  13. data/lib/matcha/engine.rb +31 -0
  14. data/lib/matcha/runner.rb +151 -0
  15. data/lib/matcha/server.rb +7 -0
  16. data/lib/tasks/matcha.rake +11 -0
  17. data/matcha.gemspec +30 -0
  18. data/spec/controllers/specs_controller_spec.rb +46 -0
  19. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  20. data/spec/dummy/app/assets/javascripts/array_sum.js.coffee +4 -0
  21. data/spec/dummy/config.ru +4 -0
  22. data/spec/dummy/config/application.rb +17 -0
  23. data/spec/dummy/config/boot.rb +6 -0
  24. data/spec/dummy/config/environment.rb +5 -0
  25. data/spec/dummy/config/environments/test.rb +29 -0
  26. data/spec/dummy/config/initializers/matcha.rb +3 -0
  27. data/spec/dummy/spec/javascripts/array_sum_cs_spec.js.coffee +8 -0
  28. data/spec/dummy/spec/javascripts/array_sum_js_spec.js +11 -0
  29. data/spec/dummy/spec/javascripts/assert_spec.js.coffee +9 -0
  30. data/spec/dummy/spec/javascripts/failing_spec.js +5 -0
  31. data/spec/dummy/spec/javascripts/spec_helper.js +3 -0
  32. data/spec/dummy/spec/javascripts/spec_helper_spec.js +7 -0
  33. data/spec/dummy/spec/javascripts/subdirectory/subdirectory_spec.js +5 -0
  34. data/spec/dummy/spec/javascripts/templates/hello.jst.ejs +1 -0
  35. data/spec/dummy/spec/javascripts/templating_spec.js +8 -0
  36. data/spec/dummy/spec/javascripts/transactions_spec.js.coffee +7 -0
  37. data/spec/matcha_spec.rb +40 -0
  38. data/spec/models/spec_spec.rb +45 -0
  39. data/spec/runner_spec.rb +36 -0
  40. data/spec/server_spec.rb +41 -0
  41. data/spec/spec_helper.rb +18 -0
  42. data/spec/views/specs/index.html.erb_spec.rb +12 -0
  43. data/spec/views/specs/show.html.erb_spec.rb +10 -0
  44. data/spec/views/specs/specs.html.erb_spec.rb +15 -0
  45. data/vendor/assets/javascripts/chai.js +2007 -0
  46. data/vendor/assets/javascripts/matcha/runner.js +70 -0
  47. data/vendor/assets/javascripts/matcha/server.js +0 -0
  48. data/vendor/assets/javascripts/mocha.js +3290 -0
  49. data/vendor/assets/stylesheets/mocha.css +133 -0
  50. metadata +202 -0
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ node_modules
19
+ spec/dummy/log
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ # This is a runtime dependency in the gemspec, so it shouldn't be necessary to
5
+ # specify it again, but bundler is buggy:
6
+ # https://github.com/carlhuda/bundler/issues/1041
7
+ gem "jquery-rails"
data/LICENSE ADDED
@@ -0,0 +1,90 @@
1
+ Copyright (c) 2012 John Firebaugh
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ Portions derived from Evergreen (https://github.com/jnicklas/evergreen):
25
+
26
+ Copyright (c) 2009 Jonas Nicklas
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining
29
+ a copy of this software and associated documentation files (the
30
+ 'Software'), to deal in the Software without restriction, including
31
+ without limitation the rights to use, copy, modify, merge, publish,
32
+ distribute, sublicense, and/or sell copies of the Software, and to
33
+ permit persons to whom the Software is furnished to do so, subject to
34
+ the following conditions:
35
+
36
+ The above copyright notice and this permission notice shall be
37
+ included in all copies or substantial portions of the Software.
38
+
39
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
40
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
43
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
+
47
+ Portions derived from Mocha (https://github.com/visionmedia/mocha)
48
+
49
+ Copyright (c) 20011-2012 TJ Holowaychuk <tj@vision-media.ca>
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining
52
+ a copy of this software and associated documentation files (the
53
+ 'Software'), to deal in the Software without restriction, including
54
+ without limitation the rights to use, copy, modify, merge, publish,
55
+ distribute, sublicense, and/or sell copies of the Software, and to
56
+ permit persons to whom the Software is furnished to do so, subject to
57
+ the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be
60
+ included in all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
63
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
65
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
66
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
67
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
68
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69
+
70
+ Portions derived from Chai (https://github.com/logicalparadox/chai)
71
+
72
+ Copyright (c) 2011 Jake Luer <jake@alogicalparadox.com>
73
+
74
+ Permission is hereby granted, free of charge, to any person obtaining a copy
75
+ of this software and associated documentation files (the "Software"), to deal
76
+ in the Software without restriction, including without limitation the rights
77
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
78
+ copies of the Software, and to permit persons to whom the Software is
79
+ furnished to do so, subject to the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be included in
82
+ all copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
87
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
88
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
89
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
90
+ THE SOFTWARE.
@@ -0,0 +1,194 @@
1
+ # Matcha
2
+
3
+ Matcha is a Rails engine that allows you to test your JavaScript with the
4
+ [mocha](http://visionmedia.github.com/mocha/) test framework and [chai](http://chaijs.com/)
5
+ assertion library.
6
+
7
+ It is similar to [Jasmine](https://github.com/pivotal/jasmine-gem) and
8
+ [Evergreen](https://github.com/jnicklas/evergreen), but does not attempt to be framework
9
+ agnostic. By sticking with Rails, Matcha can take full advantage of features such as
10
+ the asset pipeline and engines.
11
+
12
+ ## Installation
13
+
14
+ Add matcha to the `:test` and `:development` groups in the Gemfile:
15
+
16
+ group :test, :development do
17
+ gem "matcha"
18
+ end
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install matcha
27
+
28
+ ## Usage
29
+
30
+ Create a `spec/javascripts` directory and name the files in it with a `_spec` suffix.
31
+ You can write the specs in either JavaScript or CoffeeScript, using a `.js` or
32
+ `.js.coffee` extension respectively, like you would any other script asset.
33
+
34
+ Require the assets under test and any other dependencies using Sprockets directives.
35
+ For example, suppose you wanted to test your cool JavaScript `Array#sum` method, which
36
+ you placed in `app/assets/javascripts/array_sum.js`. Write the specs in JavaScript in
37
+ the file `spec/javascripts/array_sum_spec.js`:
38
+
39
+ //= require array_sum
40
+
41
+ describe("Array#sum", function(){
42
+ it("returns 0 when the Array is empty", function(){
43
+ [].sum().should.equal(0);
44
+ });
45
+
46
+ it("returns the sum of numeric elements", function(){
47
+ [1,2,3].sum().should.equal(6);
48
+ });
49
+ });
50
+
51
+ Or, if you prefer CoffeeScript, in `spec/javascripts/array_sum_spec.js.coffee`:
52
+
53
+ #= require array_sum
54
+
55
+ describe "Array#sum", ->
56
+ it "returns 0 when the Array is empty", ->
57
+ [].sum().should.equal(0)
58
+
59
+ it "returns the sum of numeric elements", ->
60
+ [1,2,3].sum().should.equal(6)
61
+
62
+ The `matcha:server` rake task starts a server for your tests. You can go to the root
63
+ page to run all specs (e.g. `http://localhost:8888/`), or a sub page to run an individual
64
+ spec file (e.g. `http://localhost:8888/array_sum_spec`).
65
+
66
+ Alternatively, you can run the specs headlessly with the `matcha:ci` task.
67
+
68
+ ## Spec Helper
69
+
70
+ Since Matcha integrates with the asset pipeline, using setup helpers in your specs is
71
+ easy. Just create a `spec_helper.js` or `spec_helper.js.coffee` file in `specs/javascripts`
72
+ and require it in your tests:
73
+
74
+ //= require spec_helper
75
+ //= require array_sum
76
+
77
+ describe("Array#sum", function(){
78
+ ...
79
+ });
80
+
81
+ ## Directives and Asset Bundling
82
+
83
+ We suggest that you explicitly require just the assets necessary for each spec. In CI
84
+ mode, Matcha will run each spec in isolation, and requiring things explicitly will help
85
+ ensure your scripts don't accumulate hidden dependencies and tight coupling.
86
+
87
+ However, you are free to ignore this advice and require the entire application.js asset
88
+ bundle in your specs or spec helper, or a bundled subset of assets. Requiring bundled
89
+ assets works like it does in Rails development mode -- Matcha will detect the complete
90
+ set of dependencies and generate a separate script tag for each one. You won't have to
91
+ search through a many thousand line application.js bundle to debug a spec failure.
92
+
93
+ ## Configuration
94
+
95
+ Matcha can be configured in an initializer, e.g. `config/initializers/matcha.rb`:
96
+
97
+ Matcha.configure do |config|
98
+ config.spec_dir = "spec/javascripts"
99
+ config.interface = :bdd
100
+ config.driver = :selenium
101
+ end if defined?(Matcha)
102
+
103
+ The `defined?` check is necessary to avoid a dependency on Matcha in the production
104
+ environment.
105
+
106
+ The `spec_dir` option tells Matcha where to find JavaScript specs. The `interface`
107
+ option specifies the test interface used by Mocha (see below). `driver` names a
108
+ Capybara driver used for the CI task (try `:webkit`, after installing
109
+ [capybara-webkit](https://github.com/thoughtbot/capybara-webkit)).
110
+
111
+ The values above are the defaults.
112
+
113
+ ## Test Interface and Assertions
114
+
115
+ Matcha includes a vendored copy of mocha.js and the [chai](http://chaijs.com/)
116
+ assertion libraries.
117
+
118
+ By default, it will assume that you want to use Mocha's "BDD" test interface, which
119
+ provides `describe()`, `it()`, `before()`, `after()`, `beforeEach()`, and `afterEach()`.
120
+ If you want to use the TDD, Exports, or QUnit interfaces instead, set the `interface`
121
+ configuration option in an initializer:
122
+
123
+ Matcha.configure do |config|
124
+ config.interface = :tdd # Or :exports or :qunit
125
+ end if defined?(Matcha)
126
+
127
+ Matcha will make all three of chai's assertion styles available to you: `expect`,
128
+ `should`, and `assert`. See the chai documentation for the details.
129
+
130
+ If you use jQuery, you may want to check out [chai-jquery](https://github.com/jfirebaugh/chai-jquery)
131
+ for some jQuery-specific assertions.
132
+
133
+ ## Transactions
134
+
135
+ One problem often faced when writing unit tests for client side code is that changes
136
+ to the page are not reverted for the next example, so that successive examples become
137
+ dependent on each other. Matcha adds a special div to your page with an id of `test`.
138
+ This div is automatically emptied before each example. You should avoid appending markup
139
+ to the page body and instead append it to this test div:
140
+
141
+ describe "transactions", ->
142
+ it "should add stuff in one test...", ->
143
+ $('#test').append('<h1 id="added">New Stuff</h1>')
144
+ $('#test h1#added').length.should.equal(1)
145
+
146
+ it "... should have been removed before the next starts", ->
147
+ $('#test h1#added').length.should.equal(0)
148
+
149
+ Note: this functionality is available only for the "BDD" (default) and "TDD" mocha interfaces,
150
+ and not for the "exports" or "QUnit" interfaces.
151
+
152
+ ## Templates / Fixtures
153
+
154
+ Matcha has no template (a.k.a. HTML fixture) support of its own. Instead, we suggest you use
155
+ Sprocket's built in support for JavaScript template (`.jst`) files. Add a `spec/javascripts/templates`
156
+ directory, place template files there (using any JS template language supported by Sprockets),
157
+ require them in your spec or spec_helper, and render them into the `#test` div.
158
+
159
+ For example, in `spec/javascripts/templates/hello.jst.ejs`:
160
+
161
+ <h1>Hello Matcha!</h1>
162
+
163
+ In `spec_helper.js`:
164
+
165
+ //= require_tree ./templates
166
+
167
+ And your spec:
168
+
169
+ //= require spec_helper
170
+
171
+ describe("templating", function(){
172
+ it("is built in to Sprockets", function(){
173
+ $('#test').html(JST['templates/hello']());
174
+ $('#test h1').text().should.equal('Hello Matcha!');
175
+ });
176
+ });
177
+
178
+ ## Contributing
179
+
180
+ 1. Fork it
181
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
182
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
183
+ 4. Push to the branch (`git push origin my-new-feature`)
184
+ 5. Create new Pull Request
185
+
186
+ ## License
187
+
188
+ Copyright (c) 2012 John Firebaugh
189
+
190
+ MIT License (see the LICENSE file)
191
+
192
+ Portions: Copyright (c) 2009 Jonas Nicklas, Copyright (c) 20011-2012 TJ Holowaychuk
193
+ <tj@vision-media.ca>, Copyright (c) 2011 Jake Luer <jake@alogicalparadox.com>. See
194
+ LICENSE file for details.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new :spec
7
+
8
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ module Matcha
2
+ class SpecsController < ActionController::Base
3
+ before_filter :set_interface, :set_mode
4
+
5
+ def set_interface
6
+ @interface = Matcha.interface
7
+ end
8
+
9
+ def set_mode
10
+ @mode = Matcha.mode
11
+ end
12
+
13
+ def index
14
+ @specs = Matcha::Spec.all
15
+ end
16
+
17
+ def show
18
+ @spec = Matcha::Spec.find(params[:spec])
19
+ @spec or render :text => "Not Found", :status => 404
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Matcha
2
+ class Spec
3
+ def self.all
4
+ Matcha.spec_paths.map { |path| new(path) }
5
+ end
6
+
7
+ def self.find(basename)
8
+ all.find { |spec| spec.basename == basename }
9
+ end
10
+
11
+ attr_accessor :path
12
+
13
+ def initialize(path)
14
+ @path = path
15
+ end
16
+
17
+ def url
18
+ "/#{basename}"
19
+ end
20
+
21
+ def basename
22
+ path[/.*(?=\.js.*$)/]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8" />
5
+ <title>Mocha Tests</title>
6
+ <%= stylesheet_link_tag "mocha" %>
7
+ <%= javascript_include_tag "jquery", "mocha", "chai", "matcha/#{@mode}" %>
8
+ <script>
9
+ mocha.setup(<%= raw @interface.to_json %>);
10
+ var expect = chai.expect,
11
+ should = chai.should(),
12
+ assert = chai.assert;
13
+ window.onload = mocha.run;
14
+
15
+ <% if @interface == :bdd %>
16
+ beforeEach(function() {
17
+ document.getElementById('test').innerHTML = "";
18
+ });
19
+ <% elsif @interface == :tdd %>
20
+ setup(function() {
21
+ document.getElementById('test').innerHTML = "";
22
+ });
23
+ <% end %>
24
+ </script>
25
+ <%= yield %>
26
+ </head>
27
+ <body>
28
+ <div id="mocha"></div>
29
+ <div id="test"></div>
30
+ </body>
31
+ </html>
@@ -0,0 +1 @@
1
+ <%= javascript_include_tag *@specs.map(&:basename) %>
@@ -0,0 +1 @@
1
+ <%= javascript_include_tag @spec.basename %>
@@ -0,0 +1,4 @@
1
+ Matcha::Engine.routes.draw do
2
+ match "/" => "matcha/specs#index"
3
+ match "/*spec" => "matcha/specs#show"
4
+ end
@@ -0,0 +1,41 @@
1
+ require "matcha/engine"
2
+ require "matcha/runner"
3
+ require "matcha/server"
4
+
5
+ module Matcha
6
+ class << self
7
+ attr_accessor :mode
8
+
9
+ def serve
10
+ puts "your tests are here:"
11
+ puts " http://localhost:#{port}/"
12
+ self.mode = :server
13
+ Matcha::Server.start
14
+ end
15
+
16
+ def run
17
+ self.mode = :runner
18
+ Matcha::Runner.start
19
+ end
20
+
21
+ def config
22
+ Matcha::Engine.config.matcha
23
+ end
24
+
25
+ def configure
26
+ yield config
27
+ end
28
+
29
+ delegate :port, :spec_dir, :interface, :application, :driver, :to => :config
30
+
31
+ def spec_root
32
+ File.join(Rails.root, config.spec_dir)
33
+ end
34
+
35
+ def spec_paths
36
+ Dir[File.join(spec_root, "**/*_spec.*")].map do |path|
37
+ path.gsub(File.join(spec_root, ''), '')
38
+ end
39
+ end
40
+ end
41
+ end