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.
@@ -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,8 @@
1
+ <% require_asset 'opal' %>
2
+ <% require_asset 'minitest' %>
3
+
4
+ <% Dir['test/{test_helper,**/*_test}.{rb,opal}'].each { |file|
5
+ require_asset file.sub(/^test\//, '').sub(/\.{rb,opal}$/, '')
6
+ } %>
7
+
8
+ Minitest.run
@@ -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
+ });