opal-minitest 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/example/Gemfile +4 -0
- data/example/Rakefile +17 -0
- data/example/opal/bacterium.rb +5 -0
- data/example/test/bacterium_test.rb +11 -0
- data/lib/opal/minitest/rake_task.rb +45 -0
- data/lib/opal/minitest/version.rb +5 -0
- data/lib/opal/minitest.rb +4 -0
- data/opal/minitest/assertions.rb +666 -0
- data/opal/minitest/core_classes.rb +571 -0
- data/opal/minitest/test.rb +290 -0
- data/opal/minitest.rb +251 -0
- data/opal/opal/minitest/loader.rb.erb +8 -0
- data/opal-minitest.gemspec +23 -0
- data/test/example_test.rb +23 -0
- data/vendor/runner.js +23 -0
- metadata +104 -0
@@ -0,0 +1,290 @@
|
|
1
|
+
# OMT: removed
|
2
|
+
#require "minitest" unless defined? Minitest::Runnable
|
3
|
+
|
4
|
+
module Minitest
|
5
|
+
##
|
6
|
+
# Subclass Test to create your own tests. Typically you'll want a
|
7
|
+
# Test subclass per implementation class.
|
8
|
+
#
|
9
|
+
# See Minitest::Assertions
|
10
|
+
|
11
|
+
class Test < Runnable
|
12
|
+
require "minitest/assertions"
|
13
|
+
include Minitest::Assertions
|
14
|
+
|
15
|
+
# OMT: modified
|
16
|
+
#PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, # :nodoc:
|
17
|
+
# Interrupt, SystemExit]
|
18
|
+
PASSTHROUGH_EXCEPTIONS = [SystemExit] # :nodoc:
|
19
|
+
|
20
|
+
# OMT: unsupported
|
21
|
+
#class << self; attr_accessor :io_lock; end
|
22
|
+
#self.io_lock = Mutex.new
|
23
|
+
|
24
|
+
##
|
25
|
+
# Call this at the top of your tests when you absolutely
|
26
|
+
# positively need to have ordered tests. In doing so, you're
|
27
|
+
# admitting that you suck and your tests are weak.
|
28
|
+
|
29
|
+
def self.i_suck_and_my_tests_are_order_dependent!
|
30
|
+
class << self
|
31
|
+
undef_method :test_order if method_defined? :test_order
|
32
|
+
define_method :test_order do :alpha end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Make diffs for this Test use #pretty_inspect so that diff
|
38
|
+
# in assert_equal can have more details. NOTE: this is much slower
|
39
|
+
# than the regular inspect but much more usable for complex
|
40
|
+
# objects.
|
41
|
+
|
42
|
+
def self.make_my_diffs_pretty!
|
43
|
+
require "pp"
|
44
|
+
|
45
|
+
define_method :mu_pp do |o|
|
46
|
+
o.pretty_inspect
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Call this at the top of your tests when you want to run your
|
52
|
+
# tests in parallel. In doing so, you're admitting that you rule
|
53
|
+
# and your tests are awesome.
|
54
|
+
# OMT: unsupported
|
55
|
+
|
56
|
+
#def self.parallelize_me!
|
57
|
+
# include Minitest::Parallel::Test
|
58
|
+
# extend Minitest::Parallel::Test::ClassMethods
|
59
|
+
#end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Returns all instance methods starting with "test_". Based on
|
63
|
+
# #test_order, the methods are either sorted, randomized
|
64
|
+
# (default), or run in parallel.
|
65
|
+
|
66
|
+
def self.runnable_methods
|
67
|
+
methods = methods_matching(/^test_/)
|
68
|
+
# OMT: added
|
69
|
+
methods.delete('test_order')
|
70
|
+
|
71
|
+
case self.test_order
|
72
|
+
when :random, :parallel then
|
73
|
+
max = methods.size
|
74
|
+
methods.sort.sort_by { rand max }
|
75
|
+
when :alpha, :sorted then
|
76
|
+
methods.sort
|
77
|
+
else
|
78
|
+
raise "Unknown test_order: #{self.test_order.inspect}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Defines the order to run tests (:random by default). Override
|
84
|
+
# this or use a convenience method to change it for your tests.
|
85
|
+
|
86
|
+
def self.test_order
|
87
|
+
:random
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# The time it took to run this test.
|
92
|
+
|
93
|
+
attr_accessor :time
|
94
|
+
|
95
|
+
def marshal_dump # :nodoc:
|
96
|
+
super << self.time
|
97
|
+
end
|
98
|
+
|
99
|
+
def marshal_load ary # :nodoc:
|
100
|
+
self.time = ary.pop
|
101
|
+
super
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Runs a single test with setup/teardown hooks.
|
106
|
+
|
107
|
+
def run
|
108
|
+
with_info_handler do
|
109
|
+
time_it do
|
110
|
+
capture_exceptions do
|
111
|
+
before_setup; setup; after_setup
|
112
|
+
|
113
|
+
self.send self.name
|
114
|
+
end
|
115
|
+
|
116
|
+
%w{ before_teardown teardown after_teardown }.each do |hook|
|
117
|
+
capture_exceptions do
|
118
|
+
self.send hook
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
self # per contract
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Provides before/after hooks for setup and teardown. These are
|
129
|
+
# meant for library writers, NOT for regular test authors. See
|
130
|
+
# #before_setup for an example.
|
131
|
+
|
132
|
+
module LifecycleHooks
|
133
|
+
|
134
|
+
##
|
135
|
+
# Runs before every test, before setup. This hook is meant for
|
136
|
+
# libraries to extend minitest. It is not meant to be used by
|
137
|
+
# test developers.
|
138
|
+
#
|
139
|
+
# As a simplistic example:
|
140
|
+
#
|
141
|
+
# module MyMinitestPlugin
|
142
|
+
# def before_setup
|
143
|
+
# super
|
144
|
+
# # ... stuff to do before setup is run
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# def after_setup
|
148
|
+
# # ... stuff to do after setup is run
|
149
|
+
# super
|
150
|
+
# end
|
151
|
+
#
|
152
|
+
# def before_teardown
|
153
|
+
# super
|
154
|
+
# # ... stuff to do before teardown is run
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# def after_teardown
|
158
|
+
# # ... stuff to do after teardown is run
|
159
|
+
# super
|
160
|
+
# end
|
161
|
+
# end
|
162
|
+
#
|
163
|
+
# class MiniTest::Test
|
164
|
+
# include MyMinitestPlugin
|
165
|
+
# end
|
166
|
+
|
167
|
+
def before_setup; end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Runs before every test. Use this to set up before each test
|
171
|
+
# run.
|
172
|
+
|
173
|
+
def setup; end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Runs before every test, after setup. This hook is meant for
|
177
|
+
# libraries to extend minitest. It is not meant to be used by
|
178
|
+
# test developers.
|
179
|
+
#
|
180
|
+
# See #before_setup for an example.
|
181
|
+
|
182
|
+
def after_setup; end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Runs after every test, before teardown. This hook is meant for
|
186
|
+
# libraries to extend minitest. It is not meant to be used by
|
187
|
+
# test developers.
|
188
|
+
#
|
189
|
+
# See #before_setup for an example.
|
190
|
+
|
191
|
+
def before_teardown; end
|
192
|
+
|
193
|
+
##
|
194
|
+
# Runs after every test. Use this to clean up after each test
|
195
|
+
# run.
|
196
|
+
|
197
|
+
def teardown; end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Runs after every test, after teardown. This hook is meant for
|
201
|
+
# libraries to extend minitest. It is not meant to be used by
|
202
|
+
# test developers.
|
203
|
+
#
|
204
|
+
# See #before_setup for an example.
|
205
|
+
|
206
|
+
def after_teardown; end
|
207
|
+
end # LifecycleHooks
|
208
|
+
|
209
|
+
def capture_exceptions # :nodoc:
|
210
|
+
begin
|
211
|
+
yield
|
212
|
+
rescue *PASSTHROUGH_EXCEPTIONS
|
213
|
+
raise
|
214
|
+
rescue Assertion => e
|
215
|
+
self.failures << e
|
216
|
+
rescue Exception => e
|
217
|
+
self.failures << UnexpectedError.new(e)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
##
|
222
|
+
# Did this run error?
|
223
|
+
|
224
|
+
def error?
|
225
|
+
self.failures.any? { |f| UnexpectedError === f }
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# The location identifier of this test.
|
230
|
+
|
231
|
+
def location
|
232
|
+
loc = " [#{self.failure.location}]" unless passed? or error?
|
233
|
+
"#{self.class}##{self.name}#{loc}"
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Did this run pass?
|
238
|
+
#
|
239
|
+
# Note: skipped runs are not considered passing, but they don't
|
240
|
+
# cause the process to exit non-zero.
|
241
|
+
|
242
|
+
def passed?
|
243
|
+
not self.failure
|
244
|
+
end
|
245
|
+
|
246
|
+
##
|
247
|
+
# Returns ".", "F", or "E" based on the result of the run.
|
248
|
+
|
249
|
+
def result_code
|
250
|
+
self.failure and self.failure.result_code or "."
|
251
|
+
end
|
252
|
+
|
253
|
+
##
|
254
|
+
# Was this run skipped?
|
255
|
+
|
256
|
+
def skipped?
|
257
|
+
self.failure and Skip === self.failure
|
258
|
+
end
|
259
|
+
|
260
|
+
def time_it # :nodoc:
|
261
|
+
t0 = Time.now
|
262
|
+
|
263
|
+
yield
|
264
|
+
ensure
|
265
|
+
self.time = Time.now - t0
|
266
|
+
end
|
267
|
+
|
268
|
+
def to_s # :nodoc:
|
269
|
+
return location if passed? and not skipped?
|
270
|
+
|
271
|
+
failures.map { |failure|
|
272
|
+
"#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
|
273
|
+
}.join "\n"
|
274
|
+
end
|
275
|
+
|
276
|
+
def with_info_handler &block # :nodoc:
|
277
|
+
t0 = Time.now
|
278
|
+
|
279
|
+
handler = lambda do
|
280
|
+
warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Time.now - t0]
|
281
|
+
end
|
282
|
+
|
283
|
+
self.class.on_signal "INFO", handler, &block
|
284
|
+
end
|
285
|
+
|
286
|
+
include LifecycleHooks
|
287
|
+
include Guard
|
288
|
+
extend Guard
|
289
|
+
end # Test
|
290
|
+
end
|
data/opal/minitest.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
# OMT: unsupported
|
2
|
+
#require "optparse"
|
3
|
+
#require "thread"
|
4
|
+
#require "mutex_m"
|
5
|
+
#require "minitest/parallel"
|
6
|
+
|
7
|
+
##
|
8
|
+
# :include: README.txt
|
9
|
+
module Minitest
|
10
|
+
VERSION = "5.3.4.opal" # :nodoc:
|
11
|
+
|
12
|
+
@@installed_at_exit ||= false
|
13
|
+
@@after_run = []
|
14
|
+
@extensions = []
|
15
|
+
|
16
|
+
mc = (class << self; self; end)
|
17
|
+
|
18
|
+
##
|
19
|
+
# Parallel test executor
|
20
|
+
# OMT: unsupported
|
21
|
+
|
22
|
+
#mc.send :attr_accessor, :parallel_executor
|
23
|
+
#self.parallel_executor = Parallel::Executor.new((ENV['N'] || 2).to_i)
|
24
|
+
|
25
|
+
##
|
26
|
+
# Filter object for backtraces.
|
27
|
+
|
28
|
+
mc.send :attr_accessor, :backtrace_filter
|
29
|
+
|
30
|
+
##
|
31
|
+
# Reporter object to be used for all runs.
|
32
|
+
#
|
33
|
+
# NOTE: This accessor is only available during setup, not during runs.
|
34
|
+
|
35
|
+
mc.send :attr_accessor, :reporter
|
36
|
+
|
37
|
+
##
|
38
|
+
# Names of known extension plugins.
|
39
|
+
# OMT: unsupported
|
40
|
+
|
41
|
+
#mc.send :attr_accessor, :extensions
|
42
|
+
|
43
|
+
##
|
44
|
+
# Registers Minitest to run at process exit
|
45
|
+
# OMT: unsupported
|
46
|
+
|
47
|
+
# def self.autorun
|
48
|
+
# at_exit {
|
49
|
+
# next if $! and not ($!.kind_of? SystemExit and $!.success?)
|
50
|
+
#
|
51
|
+
# exit_code = nil
|
52
|
+
#
|
53
|
+
# at_exit {
|
54
|
+
# @@after_run.reverse_each(&:call)
|
55
|
+
# exit exit_code || false
|
56
|
+
# }
|
57
|
+
#
|
58
|
+
# exit_code = Minitest.run ARGV
|
59
|
+
# } unless @@installed_at_exit
|
60
|
+
# @@installed_at_exit = true
|
61
|
+
# end
|
62
|
+
|
63
|
+
##
|
64
|
+
# A simple hook allowing you to run a block of code after everything
|
65
|
+
# is done running. Eg:
|
66
|
+
#
|
67
|
+
# Minitest.after_run { p $debugging_info }
|
68
|
+
|
69
|
+
def self.after_run &block
|
70
|
+
@@after_run << block
|
71
|
+
end
|
72
|
+
|
73
|
+
# OMT: unsupported
|
74
|
+
#def self.init_plugins options # :nodoc:
|
75
|
+
# self.extensions.each do |name|
|
76
|
+
# msg = "plugin_#{name}_init"
|
77
|
+
# send msg, options if self.respond_to? msg
|
78
|
+
# end
|
79
|
+
#end
|
80
|
+
|
81
|
+
# OMT: unsupported
|
82
|
+
#def self.load_plugins # :nodoc:
|
83
|
+
# return unless self.extensions.empty?
|
84
|
+
|
85
|
+
# seen = {}
|
86
|
+
|
87
|
+
# require "rubygems" unless defined? Gem
|
88
|
+
|
89
|
+
# Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
|
90
|
+
# name = File.basename plugin_path, "_plugin.rb"
|
91
|
+
|
92
|
+
# next if seen[name]
|
93
|
+
# seen[name] = true
|
94
|
+
|
95
|
+
# require plugin_path
|
96
|
+
# self.extensions << name
|
97
|
+
# end
|
98
|
+
#end
|
99
|
+
|
100
|
+
##
|
101
|
+
# This is the top-level run method. Everything starts from here. It
|
102
|
+
# tells each Runnable sub-class to run, and each of those are
|
103
|
+
# responsible for doing whatever they do.
|
104
|
+
#
|
105
|
+
# The overall structure of a run looks like this:
|
106
|
+
#
|
107
|
+
# Minitest.autorun
|
108
|
+
# Minitest.run(args)
|
109
|
+
# Minitest.__run(reporter, options)
|
110
|
+
# Runnable.runnables.each
|
111
|
+
# runnable.run(reporter, options)
|
112
|
+
# self.runnable_methods.each
|
113
|
+
# self.run_one_method(self, runnable_method, reporter)
|
114
|
+
# Minitest.run_one_method(klass, runnable_method, reporter)
|
115
|
+
# klass.new(runnable_method).run
|
116
|
+
|
117
|
+
def self.run args = []
|
118
|
+
# OMT: removed
|
119
|
+
#self.load_plugins
|
120
|
+
|
121
|
+
options = process_args args
|
122
|
+
|
123
|
+
reporter = CompositeReporter.new
|
124
|
+
reporter << SummaryReporter.new(options[:io], options)
|
125
|
+
reporter << ProgressReporter.new(options[:io], options)
|
126
|
+
|
127
|
+
self.reporter = reporter # this makes it available to plugins
|
128
|
+
# OMT: removed
|
129
|
+
#self.init_plugins options
|
130
|
+
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
131
|
+
|
132
|
+
reporter.start
|
133
|
+
__run reporter, options
|
134
|
+
# OMT: removed
|
135
|
+
#self.parallel_executor.shutdown
|
136
|
+
reporter.report
|
137
|
+
|
138
|
+
# OMT: modified
|
139
|
+
#reporter.passed?
|
140
|
+
`window.OPAL_TEST_EXIT_STATUS = #{reporter.passed?}`
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Internal run method. Responsible for telling all Runnable
|
145
|
+
# sub-classes to run.
|
146
|
+
#
|
147
|
+
# NOTE: this method is redefined in parallel_each.rb, which is
|
148
|
+
# loaded if a Runnable calls parallelize_me!.
|
149
|
+
|
150
|
+
def self.__run reporter, options
|
151
|
+
suites = Runnable.runnables.shuffle
|
152
|
+
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
153
|
+
|
154
|
+
# If we run the parallel tests before the serial tests, the parallel tests
|
155
|
+
# could run in parallel with the serial tests. This would be bad because
|
156
|
+
# the serial tests won't lock around Reporter#record. Run the serial tests
|
157
|
+
# first, so that after they complete, the parallel tests will lock when
|
158
|
+
# recording results.
|
159
|
+
serial.map { |suite| suite.run reporter, options } +
|
160
|
+
parallel.map { |suite| suite.run reporter, options }
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.process_args args = [] # :nodoc:
|
164
|
+
options = {
|
165
|
+
:io => $stdout,
|
166
|
+
}
|
167
|
+
orig_args = args.dup
|
168
|
+
|
169
|
+
# OMT: unsupported
|
170
|
+
# OptionParser.new do |opts|
|
171
|
+
# opts.banner = "minitest options:"
|
172
|
+
# opts.version = Minitest::VERSION
|
173
|
+
#
|
174
|
+
# opts.on "-h", "--help", "Display this help." do
|
175
|
+
# puts opts
|
176
|
+
# exit
|
177
|
+
# end
|
178
|
+
#
|
179
|
+
# opts.on "-s", "--seed SEED", Integer, "Sets random seed" do |m|
|
180
|
+
# options[:seed] = m.to_i
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
|
184
|
+
# options[:verbose] = true
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# opts.on "-n", "--name PATTERN","Filter run on /pattern/ or string." do |a|
|
188
|
+
# options[:filter] = a
|
189
|
+
# end
|
190
|
+
#
|
191
|
+
# unless extensions.empty?
|
192
|
+
# opts.separator ""
|
193
|
+
# opts.separator "Known extensions: #{extensions.join(', ')}"
|
194
|
+
#
|
195
|
+
# extensions.each do |meth|
|
196
|
+
# msg = "plugin_#{meth}_options"
|
197
|
+
# send msg, opts, options if self.respond_to?(msg)
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# begin
|
202
|
+
# opts.parse! args
|
203
|
+
# rescue OptionParser::InvalidOption => e
|
204
|
+
# puts
|
205
|
+
# puts e
|
206
|
+
# puts
|
207
|
+
# puts opts
|
208
|
+
# exit 1
|
209
|
+
# end
|
210
|
+
#
|
211
|
+
# orig_args -= args
|
212
|
+
# end
|
213
|
+
|
214
|
+
unless options[:seed] then
|
215
|
+
srand
|
216
|
+
options[:seed] = srand % 0xFFFF
|
217
|
+
orig_args << "--seed" << options[:seed].to_s
|
218
|
+
end
|
219
|
+
|
220
|
+
srand options[:seed]
|
221
|
+
|
222
|
+
options[:args] = orig_args.map { |s|
|
223
|
+
s =~ /[\s|&<>$()]/ ? s.inspect : s
|
224
|
+
}.join " "
|
225
|
+
|
226
|
+
options
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.filter_backtrace bt # :nodoc:
|
230
|
+
backtrace_filter.filter bt
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# OMT: section moved to core_classes.rb
|
235
|
+
##
|
236
|
+
|
237
|
+
self.backtrace_filter = BacktraceFilter.new
|
238
|
+
|
239
|
+
def self.run_one_method klass, method_name # :nodoc:
|
240
|
+
result = klass.new(method_name).run
|
241
|
+
raise "#{klass}#run _must_ return self" unless klass === result
|
242
|
+
result
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# OMT: added
|
247
|
+
require "minitest/core_classes"
|
248
|
+
|
249
|
+
require "minitest/test"
|
250
|
+
# OMT: unsupported
|
251
|
+
#require "minitest/unit" unless defined?(MiniTest) # compatibility layer only
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'opal/minitest/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'opal-minitest'
|
9
|
+
s.version = Opal::Minitest::VERSION
|
10
|
+
s.author = 'Artur Ostrega'
|
11
|
+
s.email = 'artur.mariusz.ostrega@gmail.com'
|
12
|
+
s.summary = 'MiniTest for Opal'
|
13
|
+
s.description = 'MiniTest test runner for Opal'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.add_dependency 'opal', '~> 0.6.2'
|
20
|
+
s.add_dependency 'rake', '~> 10.3.2'
|
21
|
+
s.add_development_dependency 'minitest', '5.3.2'
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ExampleTest < Minitest::Test
|
2
|
+
def test_passing_assert
|
3
|
+
assert true
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_failing_assert
|
7
|
+
assert false, "intentional failure"
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_skip
|
11
|
+
skip "intentional skip"
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_capture_io
|
15
|
+
out, err = capture_io do
|
16
|
+
puts 'woo'
|
17
|
+
warn 'boo'
|
18
|
+
end
|
19
|
+
|
20
|
+
assert_match out, 'woo'
|
21
|
+
assert_match err, 'boo'
|
22
|
+
end
|
23
|
+
end
|
data/vendor/runner.js
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
// Headlessly open test loader and wait until tests finish.
|
2
|
+
|
3
|
+
var url = phantom.args[0],
|
4
|
+
page = require('webpage').create();
|
5
|
+
|
6
|
+
page.onConsoleMessage = function(msg) { console.log(msg) };
|
7
|
+
|
8
|
+
page.open(url, function(loadStatus) {
|
9
|
+
if (loadStatus !== 'success') {
|
10
|
+
console.error("Cannot load: " + url);
|
11
|
+
phantom.exit(1);
|
12
|
+
}
|
13
|
+
var loop = setInterval(function() {
|
14
|
+
var exitStatus = page.evaluate(function() {
|
15
|
+
return window.OPAL_TEST_EXIT_STATUS;
|
16
|
+
});
|
17
|
+
|
18
|
+
if (exitStatus != null) {
|
19
|
+
clearInterval(loop);
|
20
|
+
phantom.exit(exitStatus);
|
21
|
+
}
|
22
|
+
}, 500);
|
23
|
+
});
|