lib-opal/opal/rspec/async/example.rb in opal-rspec-0.8.0 vs lib-opal/opal/rspec/async/example.rb in opal-rspec-1.0.0.alpha1
- old
+ new
@@ -1,187 +1,99 @@
-require 'js'
+# await: *await*
-module ::RSpec::Core
- class Example
- # WAS:
- # def run_after_example
- # @example_group_class.hooks.run(:after, :example, self)
- # verify_mocks
- # assign_generated_description if RSpec.configuration.expecting_with_rspec?
- # rescue Exception => e
- # set_exception(e, "in an `after(:example)` hook")
- # ensure
- # @example_group_instance.teardown_mocks_for_rspec
- # end
- # NOW:
- def run_after_example
- @example_group_class.hooks.run(:after, :example, self).then do
- verify_mocks
- assign_generated_description if RSpec.configuration.expecting_with_rspec?
- end.rescue do |e|
- set_exception(e, "in an `after(:example)` hook")
- end.ensure do
- @example_group_instance.teardown_mocks_for_rspec
- end
- end
+module RSpec
+ module Core
+ class Example
+ def run_await(example_group_instance, reporter)
+ # added awaits
+ @example_group_instance = example_group_instance
+ @reporter = reporter
+ RSpec.configuration.configure_example(self, hooks)
+ RSpec.current_example = self
- def run(example_group_instance, reporter)
- @example_group_instance = example_group_instance
- RSpec.current_example = self
+ start(reporter)
+ Pending.mark_pending!(self, pending) if pending?
- start(reporter)
- Pending.mark_pending!(self, pending) if pending?
-
- # WAS:
- # …
- # begin
- # if skipped?
- # Pending.mark_pending! self, skip
- # elsif !RSpec.configuration.dry_run?
- # with_around_example_hooks do
- # begin
- # run_before_example
- # @example_group_instance.instance_exec(self, &@example_block)
- #
- # if pending?
- # Pending.mark_fixed! self
- #
- # raise Pending::PendingExampleFixedError,
- # 'Expected example to fail since it is pending, but it passed.',
- # [location]
- # end
- # rescue Pending::SkipDeclaredInExample
- # # no-op, required metadata has already been set by the `skip`
- # # method.
- # rescue Exception => e
- # set_exception(e)
- # ensure
- # run_after_example
- # end
- # end
- # end
- # rescue Exception => e
- # set_exception(e)
- # ensure
- # @example_group_instance.instance_variables.each do |ivar|
- # @example_group_instance.instance_variable_set(ivar, nil)
- # end
- # @example_group_instance = nil
- # end
- #
- # finish(reporter)
- # ensure
- # RSpec.current_example = nil
- Promise.value(true).then do
- Promise.value(true).then do
+ begin
if skipped?
Pending.mark_pending! self, skip
elsif !RSpec.configuration.dry_run?
- with_around_example_hooks do
- # WAS:
- # with_around_example_hooks do
- # begin
- # run_before_example
- # @example_group_instance.instance_exec(self, &@example_block)
- #
- # if pending?
- # Pending.mark_fixed! self
- #
- # raise Pending::PendingExampleFixedError,
- # 'Expected example to fail since it is pending, but it passed.',
- # [location]
- # end
- # rescue Pending::SkipDeclaredInExample
- # # no-op, required metadata has already been set by the `skip`
- # # method.
- # rescue Exception => e
- # set_exception(e)
- # ensure
- # run_after_example
- # end
- # end
- # NOW:
- Promise.value(true).then do
- run_before_example
- .then do
- # TODO: Use subject! to create a before hook on the fly, might be cleaner than this
- # Might be a better way to do this, but then you end up with promises around the expectation handlers, which could get ugly
- begin
- subj = example_group_instance.subject
- if subj.is_a? Promise
- return subj.then do |resolved_subject|
- # This is a private method, but we're using Opal
- example_group_instance.__memoized[:subject] = resolved_subject
- end
- end
- rescue StandardError, JS::Error
- # Exception occurred while checking the subject, might be that the example
- # group had a described class, was not intending on using it as the subject,
- # and the initializer for that described class failed
- end
- Promise.value(true)
- end
- .then do
- # WAS:
- # @example_group_instance.instance_exec(self, &@example_block)
- # NOW:
- Promise.value(@example_group_instance.instance_exec(self, &@example_block)).then do |result|
- result
- end.rescue do |ex|
- case ex
- when nil then Exception.new 'Async promise failed for unspecified reason'
- when Exception then ex
- else Exception.new(ex)
- end
- end
- end
- .then do
- # ORIGINAL:
- if pending?
- Pending.mark_fixed! self
+ with_around_and_singleton_context_hooks_await do
+ begin
+ run_before_example_await
+ RSpec.current_scope = :example
+ @example_group_instance.instance_exec_await(self, &@example_block)
- raise Pending::PendingExampleFixedError,
- 'Expected example to fail since it is pending, but it passed.',
- [location]
- end
+ if pending?
+ Pending.mark_fixed! self
+
+ raise Pending::PendingExampleFixedError,
+ 'Expected example to fail since it is pending, but it passed.',
+ [location]
end
- end.rescue do |e|
- # WAS:
- # rescue Pending::SkipDeclaredInExample
- # # no-op, required metadata has already been set by the `skip`
- # # method.
- # rescue Exception => e
- # set_exception(e)
- # ensure
- # run_after_example
- # end
- # NOW:
- case e
- when Pending::SkipDeclaredInExample
- # no-op, required metadata has already been set by the `skip`
- # method.
- when Exception
- set_exception(e)
- end
- end.ensure do
- run_after_example
+ rescue Pending::SkipDeclaredInExample => _
+ # The "=> _" is normally useless but on JRuby it is a workaround
+ # for a bug that prevents us from getting backtraces:
+ # https://github.com/jruby/jruby/issues/4467
+ #
+ # no-op, required metadata has already been set by the `skip`
+ # method.
+ rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
+ set_exception(e)
+ ensure
+ RSpec.current_scope = :after_example_hook
+ run_after_example_await
end
end
end
- end.rescue do |e|
+ rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
set_exception(e)
- end.ensure do
- @example_group_instance.instance_variables.each do |ivar|
- @example_group_instance.instance_variable_set(ivar, nil)
- end
- @example_group_instance = nil
+ ensure
+ @example_group_instance = nil # if you love something... let it go
end
- end.then do
+
finish(reporter)
- end.ensure do |result|
+ ensure
+ execution_result.ensure_timing_set(clock)
RSpec.current_example = nil
- # promise always/ensure do not behave exactly like ensure, need to be explicit about value being returned
- result
+ end
+
+ def run_before_example_await
+ # added awaits
+ @example_group_instance.setup_mocks_for_rspec
+ hooks.run_await(:before, :example, self)
+ end
+
+ def run_after_example_await
+ # added awaits
+ assign_generated_description if defined?(::RSpec::Matchers)
+ hooks.run_await(:after, :example, self)
+ verify_mocks
+ ensure
+ @example_group_instance.teardown_mocks_for_rspec
+ end
+
+ def with_around_and_singleton_context_hooks_await
+ singleton_context_hooks_host = example_group_instance.singleton_class
+ singleton_context_hooks_host.run_before_context_hooks_await(example_group_instance)
+ with_around_example_hooks_await { yield.await }
+ ensure
+ singleton_context_hooks_host.run_after_context_hooks_await(example_group_instance)
+ end
+
+ def with_around_example_hooks_await
+ RSpec.current_scope = :before_example_hook
+ hooks.run_await(:around, :example, self) { yield.await }
+ rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
+ set_exception(e)
+ end
+
+ def instance_exec_await(*args, &block)
+ @example_group_instance.instance_exec_await(*args, &block)
+ end
+
+ class Procsy
+ alias run_await run
end
end
end
end