sayso-js-test-driver-rails 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .idea
2
+ .rvmrc
3
+ .bundle
4
+ jsTestDriver.conf
5
+ pkg/*
6
+ tags
7
+ .js_test_driver
data/.gitmodules ADDED
@@ -0,0 +1,6 @@
1
+ [submodule "vendor/jasmine"]
2
+ path = vendor/jasmine
3
+ url = git://github.com/pivotal/jasmine.git
4
+ [submodule "vendor/jasmine-jstd-adapter"]
5
+ path = vendor/jasmine-jstd-adapter
6
+ url = git://github.com/ibolmo/jasmine-jstd-adapter.git
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in js-test-driver-rails.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ js-test-driver-rails (0.4.2)
5
+ json
6
+ rake
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ json (1.4.6)
12
+ mocha (0.9.9)
13
+ rake
14
+ rake (0.8.7)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ js-test-driver-rails!
21
+ mocha
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 by Adam Pohorecki
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,118 @@
1
+ JS Test Driver Rails
2
+ ====================
3
+
4
+ js-test-driver-rails is a thin wrapper for the JsTestDriver library: http://code.google.com/p/js-test-driver/
5
+
6
+ Configuration
7
+ ------------
8
+
9
+ To take advantage of js-test-driver-rails, you should create a js_test_driver.rb file in your RAILS_ROOT/config/ directory.
10
+
11
+ The file may contain following directives:
12
+
13
+ # the paths are relative to the current directory, but you can use absolute paths too
14
+ # this is different from the JsTestDriver which does not allow you to use absolute paths in the config file
15
+
16
+ # files to be included
17
+ # you can use Ruby globbing syntax (spec/js/**/*_spec.js), which will be automatically expanded
18
+ includes 'foo', 'bar', 'public/javascripts/*.js'
19
+
20
+ # files to be excluded, useful with globbing
21
+ excludes 'public/javascripts/fail.js'
22
+
23
+ # the host to which the test runner will connect, by default 'localhost'
24
+ host 'my-laptop'
25
+
26
+ # the port to which test runner will connect, and on which the test server will start, by default 4224
27
+ port 6666
28
+
29
+ # you can specify the default browsers which will be captured
30
+ browser 'firefox'
31
+
32
+ Note, that this is a ruby file, so the file/browser list can be generated dynamically - it's completely up to you.
33
+
34
+ For example in our project we examine a list of known browsers to determine the ones installed on the developer's system, and define only those that were found.
35
+
36
+ Similarly we get the list of .js files to include from our asset packaging solution.
37
+
38
+ HTML Fixtures
39
+ -------------
40
+
41
+ js-test-driver-rails also allows you to define HTML fixtures easily.
42
+
43
+ Imagine you have a directory structure like this:
44
+
45
+ RAILS_ROOT:
46
+ test/
47
+ js/
48
+ fixtures/
49
+ foo/
50
+ a.html
51
+ a.html
52
+
53
+ Then by defining the fixtures directory in your config file:
54
+
55
+ fixtures "test/js/fixtures"
56
+
57
+ At runtime, your tests will have access to the contents of the fixture files:
58
+
59
+ htmlFixtures.all["a"] // contents of the test/js/fixtures/a.html
60
+ htmlFixtures.all["foo/a"] // contents of the test/js/fixtures/foo/a.html
61
+
62
+ You can customize the namespace and fixture container name:
63
+
64
+ # the fixtures will be accessible through myApp.html["<fixture name goes here>"]
65
+ fixtures "test/js/fixtures", :name => "html", :namespace => "myApp"
66
+
67
+ Using Jasmine
68
+ -------------
69
+
70
+ By default JsTestDriver comes with a pretty simple Test::Unit like testing framework.
71
+ However it supports a couple of other frameworks, including Jasmine (http://pivotal.github.com/jasmine/), which is an RSpec-like BDD framework.
72
+
73
+ If you want to user Jasmine, simply add:
74
+
75
+ enable_jasmine
76
+
77
+ in your config file, somewhere before including your test files and you are golden:)
78
+
79
+ Measuring code coverage
80
+ -----------------------
81
+
82
+ JsTestDriver has a pretty cool feature of being able to measure code coverage. To enable this in your config, you just need to add:
83
+
84
+ measure_coverage
85
+
86
+ in your config file.
87
+
88
+ You need to have lcov installed for the HTML report to be generated:
89
+
90
+ sudo apt-get install lcov
91
+
92
+ The HTML coverage report will be saved in the .js_test_driver/tests/coverage directory.
93
+
94
+ Rake tasks
95
+ ----------
96
+
97
+ This gem comes with some rake tasks, which you should require in your Rake file:
98
+
99
+ require "js_test_driver/tasks"
100
+
101
+ To start the js test driver server:
102
+
103
+ rake js_test_driver:start_server
104
+
105
+ To capture the default (or specified) browsers
106
+
107
+ rake js_test_driver:capture_browsers [BROWSERS=foo,bar,baz]
108
+
109
+ To run the tests (all or the specified ones)
110
+
111
+ rake js_test_driver:run_tests [TESTS=TestCase[.testMethod]]
112
+
113
+ To run the server, capture the browsers and run tests all in one command
114
+
115
+ rake js_test_driver:run [TESTS=TestCase[.testMethod]] [BROWSERS=foo,bar,baz] [OUTPUT_XML=1 | OUTPUT_PATH=/some/dir] [CAPTURE_CONSOLE=1]
116
+
117
+ This last task is mostly useful on CI, because it's much faster to run the server and capture the browsers once and then run the tests again and again in development mode.
118
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new("test") do |test|
4
+ test.libs << 'test'
5
+ test.pattern = 'test/**/*_test.rb'
6
+ test.verbose = true
7
+ end
8
+
9
+ task :default => :test
10
+
11
+ require 'bundler'
12
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "js_test_driver/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sayso-js-test-driver-rails"
7
+ s.version = JsTestDriver::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["SaySo"]
10
+ s.email = ["sayso@truvolabs.com"]
11
+ s.homepage = "http://github.com/sayso/js-test-driver-rails"
12
+ s.summary = "A wrapper for JsTestDriver for use with ruby/rails projects"
13
+ s.description = "Use ruby to configure JsTestDriver, capture browsers and run tests."
14
+
15
+ s.rubyforge_project = "js-test-driver-rails"
16
+
17
+ s.add_dependency 'json'
18
+ s.add_dependency 'rake'
19
+ s.add_development_dependency 'mocha'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,6 @@
1
+ require 'json'
2
+ require 'fileutils'
3
+
4
+ require File.expand_path(File.join(File.dirname(__FILE__), 'js_test_driver', 'config'))
5
+ require File.expand_path(File.join(File.dirname(__FILE__), 'js_test_driver', 'runner'))
6
+ require File.expand_path(File.join(File.dirname(__FILE__), 'js_test_driver', 'html_fixture'))
@@ -0,0 +1,209 @@
1
+ module JsTestDriver
2
+ # The Config class represents the YAML config file that is passed to JsTestDriver
3
+ #
4
+ # includes corresponds to load
5
+ # excludes corresponds to exclude
6
+ # server can be configures either using server, or host and port
7
+ #
8
+ # The configuration is very basic, however the fact that it is done in Ruby, gives the
9
+ # user a significant amount of freedom in terms of what is and is not loaded, and so on
10
+ class Config
11
+
12
+ def initialize(attributes = {})
13
+ self.attributes = attributes
14
+ end
15
+
16
+ # Adds a file to be loaded, the path *must* be relative to the root_dir (which is the current dir by default)
17
+ #
18
+ # JsTestDriver supports globbing
19
+ def includes(*paths)
20
+ self.included_files.concat(expand_globs(paths))
21
+ end
22
+
23
+ # Files specified here will not be loaded, it's useful when combined with globbing in includes
24
+ #
25
+ # paths should be relative to root_dir
26
+ def excludes(*paths)
27
+ self.excluded_files.concat(expand_globs(paths))
28
+ end
29
+
30
+ # Defines a browser to be captured by default
31
+ #
32
+ # This should be a string with no spaces (if you need to pass parameters to the browser you will
33
+ # need to create a shell script ans put it's name here)
34
+ def browser(*browsers)
35
+ browsers.each do |browser|
36
+ self.browsers << browser
37
+ end
38
+ end
39
+
40
+ # Defines a HTML fixture directory
41
+ #
42
+ # the first argument is the directory to scan for html fixtures
43
+ # you can pass also :name and :namespace arguments to define the name and the namespace of the fixture
44
+ #
45
+ # the fixtures will be accessible through:
46
+ # namespace.name["file_name_without the html extension"]
47
+ #
48
+ # by default the namespace is called htmlFixtures
49
+ # and the fixture name is called all
50
+ def fixtures(directory, opts = {})
51
+ fixture = JsTestDriver::HtmlFixture.new(directory, opts[:name], opts[:namespace])
52
+ if html_fixtures.detect{|f| f.name == fixture.name && f.namespace == fixture.namespace}
53
+ raise ArgumentError.new("Fixture #{fixture.namespace}.#{fixture.name} already defined!")
54
+ end
55
+ html_fixtures << fixture
56
+ end
57
+
58
+ # Includes the bundled with the gem jasmine js file and an adapter for jasmine
59
+ #
60
+ # There's no hacks or modifications here, so this method is just for the users convenience
61
+ def enable_jasmine
62
+ includes File.join(vendor_directory, "jasmine.js")
63
+ includes File.join(vendor_directory, "JasmineAdapter.js")
64
+ end
65
+
66
+ # Adds a JsTestDriver plugin for measuring coverage to the configuration
67
+ def measure_coverage
68
+ @measure_coverage = true
69
+ self.plugins << {
70
+ 'name' => 'coverage',
71
+ 'jar' => File.join(vendor_directory, 'coverage.jar'),
72
+ 'module' => 'com.google.jstestdriver.coverage.CoverageModule'
73
+ }
74
+ end
75
+
76
+ def measure_coverage?
77
+ !!@measure_coverage
78
+ end
79
+
80
+ # Plugins to include in the config
81
+ def plugins
82
+ @plugins ||= []
83
+ end
84
+
85
+ # config variable which has a regular setter,
86
+ # but also can be set by calling the "getter" with an argument
87
+ # and if called without an argument the getter will return the passed block
88
+ #
89
+ # Ex.
90
+ # A.define_config_variable(:foo) { @foo || "hello" }
91
+ # a = A.new
92
+ # a.foo # returns "hello"
93
+ # a.foo "foo"
94
+ # a.foo # returns "foo"
95
+ # a.foo = "bar"
96
+ # a.foo # returns "bar"
97
+ def self.define_config_variable(name, &block)
98
+ attr_writer name
99
+
100
+ define_method(name) do |*values|
101
+ unless values.empty?
102
+ self.send("#{name}=", values.first)
103
+ else
104
+ instance_eval(&block)
105
+ end
106
+ end
107
+ end
108
+
109
+ # the port the server will use, by default 4224
110
+ define_config_variable(:port) { @port ||= 4224 }
111
+
112
+ # the host of the server, by default localhost
113
+ define_config_variable(:host) { @host ||= 'localhost' }
114
+
115
+ # the whole server string - unless overwritten will be constructed from host and port,
116
+ # if you specify server, host and port will be ignored
117
+ # but you still need to specify port for starting the server
118
+ define_config_variable(:server) { @server || "http://#{host}:#{port}" }
119
+
120
+ # the base path to which all of the paths in the config file are relative
121
+ define_config_variable(:base_path) { @base_path ||= '/' }
122
+
123
+ def included_files
124
+ @includes ||= []
125
+ end
126
+
127
+ def excluded_files
128
+ @excludes ||= []
129
+ end
130
+
131
+ def html_fixtures
132
+ @html_fixtures ||= []
133
+ end
134
+
135
+ attr_writer :browsers
136
+
137
+ def browsers
138
+ @browsers ||= []
139
+ end
140
+
141
+ def to_s
142
+ hash = {'server' => server, 'basepath' => base_path}
143
+ hash['load'] = loaded_files unless loaded_files.empty?
144
+ hash['exclude'] = map_paths(excluded_files) unless excluded_files.empty?
145
+ hash['plugin'] = plugins unless plugins.empty?
146
+ return hash.to_yaml
147
+ end
148
+
149
+ def self.parse(string)
150
+ config = new
151
+ config.instance_eval(string)
152
+ return config
153
+ end
154
+
155
+ attr_writer :config_dir
156
+
157
+ # this is where the config files are saved (ex. RAILS_ROOT/.js_test_driver)
158
+ def config_dir
159
+ @config_dir ||= File.expand_path(".")
160
+ end
161
+
162
+ def save_fixtures
163
+ html_fixtures.each do |fixture|
164
+ path = fixture_file_name(fixture)
165
+ FileUtils.mkdir_p(File.dirname(path))
166
+ File.open(path, "w+") do |f|
167
+ f.puts fixture.to_s
168
+ end
169
+ end
170
+ end
171
+
172
+ private
173
+
174
+ def vendor_directory
175
+ this_directory = File.dirname(__FILE__)
176
+ return File.expand_path(File.join('..', '..', 'vendor'), this_directory)
177
+ end
178
+
179
+ def expand_globs(paths)
180
+ with_expanded_paths = paths.map{|path| File.expand_path(path)}
181
+ return with_expanded_paths.map{|path| path.include?('*') ? Dir[path].sort : path}.flatten
182
+ end
183
+
184
+ def fixture_file_name(fixture)
185
+ File.expand_path(File.join(config_dir, "fixtures", fixture.namespace, "#{fixture.name}.js"))
186
+ end
187
+
188
+ def loaded_files
189
+ files = included_files + html_fixtures.collect { |fixture| fixture_file_name(fixture) }
190
+
191
+ map_paths(files)
192
+ end
193
+
194
+ def path_relative_to_base_path(path)
195
+ path.gsub(/^#{Regexp.escape(base_path)}/, '')
196
+ end
197
+
198
+ def map_paths(files)
199
+ files.map{|file| path_relative_to_base_path(file)}
200
+ end
201
+
202
+ def attributes=(values)
203
+ values.each do |attr, value|
204
+ self.send("#{attr}=", value)
205
+ end
206
+ end
207
+
208
+ end
209
+ end
@@ -0,0 +1,40 @@
1
+ module JsTestDriver
2
+ # This is a class that given a directory name, puts all its *.html children
3
+ # into a javascript file, so that they can later be used in the tests
4
+ class HtmlFixture
5
+
6
+ attr_reader :name, :namespace
7
+
8
+ def initialize(directory_name, name = nil, namespace = nil)
9
+ @name = name || "all"
10
+ @namespace = namespace || "htmlFixtures"
11
+ @data = {}
12
+
13
+ load_data(directory_name)
14
+ end
15
+
16
+ def to_h
17
+ @data
18
+ end
19
+
20
+ def to_s
21
+ <<JS
22
+ if (typeof(#{namespace}) === 'undefined') { #{namespace} = {}; }
23
+ #{namespace}.#{name} = #{self.to_h.to_json};
24
+ JS
25
+ end
26
+
27
+ private
28
+
29
+ def load_data(directory_name)
30
+ full_path = File.expand_path(directory_name)
31
+ files = Dir["#{full_path}/**/*.html"]
32
+
33
+ files.each do |file|
34
+ name = file.gsub(/^#{full_path}\//, '').gsub(/\.html$/, '')
35
+ @data[name] = File.read(file)
36
+ end
37
+ end
38
+
39
+ end
40
+ end