From abbd6ffd71973a7ce7bdea24218a9fb01974a9d2 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Mon, 23 Jan 2023 11:55:52 -0700 Subject: [PATCH 01/10] Fix splat argument expansion in method redefinition The constructed previous_def call was malformed for stub methods. Resolves the original issue in https://github.com/icy-arctic-fox/spectator/issues/49 --- spec/issues/github_issue_49_spec.cr | 6 ++++++ src/spectator/mocks/stubbable.cr | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 spec/issues/github_issue_49_spec.cr diff --git a/spec/issues/github_issue_49_spec.cr b/spec/issues/github_issue_49_spec.cr new file mode 100644 index 0000000..d6a3417 --- /dev/null +++ b/spec/issues/github_issue_49_spec.cr @@ -0,0 +1,6 @@ +require "../spec_helper" + +# https://github.com/icy-arctic-fox/spectator/issues/49 +Spectator.describe "GitHub Issue #49" do + mock File +end diff --git a/src/spectator/mocks/stubbable.cr b/src/spectator/mocks/stubbable.cr index 119111d..3a14887 100644 --- a/src/spectator/mocks/stubbable.cr +++ b/src/spectator/mocks/stubbable.cr @@ -133,13 +133,12 @@ module Spectator if method.splat_index method.args.each_with_index do |arg, i| if i == method.splat_index - original += '*' if arg.internal_name && arg.internal_name.size > 0 - original += "#{arg.internal_name}, " + original += "*#{arg.internal_name}, " end original += "**#{method.double_splat}, " if method.double_splat elsif i > method.splat_index - original += "#{arg.name}: #{arg.internal_name}" + original += "#{arg.name}: #{arg.internal_name}, " else original += "#{arg.internal_name}, " end @@ -283,9 +282,8 @@ module Spectator if method.splat_index method.args.each_with_index do |arg, i| if i == method.splat_index - original += '*' if arg.internal_name && arg.internal_name.size > 0 - original += "#{arg.internal_name}, " + original += "*#{arg.internal_name}, " end original += "**#{method.double_splat}, " if method.double_splat elsif i > method.splat_index From a5e8f11e1188f2ec8acfbd7d1fba5a83833828ec Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Mon, 23 Jan 2023 16:02:30 -0700 Subject: [PATCH 02/10] Store type to reduce a bit of bloat --- src/spectator/mocks/stubbable.cr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/spectator/mocks/stubbable.cr b/src/spectator/mocks/stubbable.cr index 3a14887..3385ad4 100644 --- a/src/spectator/mocks/stubbable.cr +++ b/src/spectator/mocks/stubbable.cr @@ -537,6 +537,7 @@ module Spectator # Get the value as-is from the stub. # This will be compiled as a union of all known stubbed value types. %value = {{stub}}.call({{call}}) + %type = {{type}} # Attempt to cast the value to the method's return type. # If successful, which it will be in most cases, return it. @@ -547,12 +548,12 @@ module Spectator %cast {% elsif fail_cast == :raise %} # Check if nil was returned by the stub and if its okay to return it. - if %value.nil? && {{type}}.nilable? + if %value.nil? && %type.nilable? # Value was nil and nil is allowed to be returned. - %cast.as({{type}}) + %type.cast(%cast) elsif %cast.nil? # The stubbed value was something else entirely and cannot be cast to the return type. - raise TypeCastError.new("#{_spectator_stubbed_name} received message #{ {{call}} } and is attempting to return a `#{%value.class}`, but returned type must be `#{ {{type}} }`.") + raise TypeCastError.new("#{_spectator_stubbed_name} received message #{ {{call}} } and is attempting to return a `#{%value.class}`, but returned type must be `#{%type}`.") else # Types match and value can be returned as cast type. %cast From cb89589155cedc89dd9faeeca864e97266284edd Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Wed, 25 Jan 2023 16:09:16 -0700 Subject: [PATCH 03/10] Compiler bug when using unsafe_as --- src/spectator/mocks/stubbable.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spectator/mocks/stubbable.cr b/src/spectator/mocks/stubbable.cr index 3385ad4..6c5f7ad 100644 --- a/src/spectator/mocks/stubbable.cr +++ b/src/spectator/mocks/stubbable.cr @@ -550,7 +550,7 @@ module Spectator # Check if nil was returned by the stub and if its okay to return it. if %value.nil? && %type.nilable? # Value was nil and nil is allowed to be returned. - %type.cast(%cast) + %cast.unsafe_as({{type}}) elsif %cast.nil? # The stubbed value was something else entirely and cannot be cast to the return type. raise TypeCastError.new("#{_spectator_stubbed_name} received message #{ {{call}} } and is attempting to return a `#{%value.class}`, but returned type must be `#{%type}`.") From 7149ef7df572eddd3037e0e2a0ee922a66332ec5 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:12:54 -0700 Subject: [PATCH 04/10] Revert "Compiler bug when using unsafe_as" This reverts commit cb89589155cedc89dd9faeeca864e97266284edd. --- src/spectator/mocks/stubbable.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spectator/mocks/stubbable.cr b/src/spectator/mocks/stubbable.cr index 6c5f7ad..3385ad4 100644 --- a/src/spectator/mocks/stubbable.cr +++ b/src/spectator/mocks/stubbable.cr @@ -550,7 +550,7 @@ module Spectator # Check if nil was returned by the stub and if its okay to return it. if %value.nil? && %type.nilable? # Value was nil and nil is allowed to be returned. - %cast.unsafe_as({{type}}) + %type.cast(%cast) elsif %cast.nil? # The stubbed value was something else entirely and cannot be cast to the return type. raise TypeCastError.new("#{_spectator_stubbed_name} received message #{ {{call}} } and is attempting to return a `#{%value.class}`, but returned type must be `#{%type}`.") From 528ad7257da3f01c164df619f210a8336a556ad7 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:17:29 -0700 Subject: [PATCH 05/10] Disable GitHub issue 49 spec for now --- spec/issues/github_issue_49_spec.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/issues/github_issue_49_spec.cr b/spec/issues/github_issue_49_spec.cr index d6a3417..6161a57 100644 --- a/spec/issues/github_issue_49_spec.cr +++ b/spec/issues/github_issue_49_spec.cr @@ -2,5 +2,5 @@ require "../spec_helper" # https://github.com/icy-arctic-fox/spectator/issues/49 Spectator.describe "GitHub Issue #49" do - mock File + # mock File end From 24a860ea1161eff12d81cc7d5cf0c24044ac4bfe Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:18:26 -0700 Subject: [PATCH 06/10] Add reference to new issue https://github.com/icy-arctic-fox/spectator/issues/51 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7b645..fe4331d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for string interpolation in context names/labels. ### Fixed -- Fix invalid syntax (unterminated call) when recording calls to stubs with an un-named splat. +- Fix invalid syntax (unterminated call) when recording calls to stubs with an un-named splat. [#51](https://github.com/icy-arctic-fox/spectator/issues/51) ### Changed - Expectations using 'should' syntax report file and line where the 'should' keyword is instead of the test start. From 9ea5c261b15f4bb526aa5e1e3d1f93125f2e3168 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:19:55 -0700 Subject: [PATCH 07/10] Add entry for GitHub issue 49 https://github.com/icy-arctic-fox/spectator/issues/49 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4331d..8d93c8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fix invalid syntax (unterminated call) when recording calls to stubs with an un-named splat. [#51](https://github.com/icy-arctic-fox/spectator/issues/51) +- Fix malformed method signature when using named splat with keyword arguments in mocked type. [#49](https://github.com/icy-arctic-fox/spectator/issues/49) ### Changed - Expectations using 'should' syntax report file and line where the 'should' keyword is instead of the test start. From 735122a94ba9a86a7957df9e0a1b7b8cf697b32b Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:21:33 -0700 Subject: [PATCH 08/10] Bump v0.11.6 --- CHANGELOG.md | 5 ++++- shard.yml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d93c8c..ffd70d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [0.11.6] - 2023-01-26 ### Added - Added ability to cast types using the return value from expect/should statements with a type matcher. - Added support for string interpolation in context names/labels. @@ -445,7 +447,8 @@ This has been changed so that it compiles and raises an error at runtime with a First version ready for public use. -[Unreleased]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.5...master +[Unreleased]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.6...master +[0.11.6]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.5...v0.11.6 [0.11.5]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.4...v0.11.5 [0.11.4]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.3...v0.11.4 [0.11.3]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.11.2...v0.11.3 diff --git a/shard.yml b/shard.yml index a41bc90..06ba936 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: spectator -version: 0.11.5 +version: 0.11.6 description: | Feature-rich testing framework for Crystal inspired by RSpec. From 5c08427ca0440193fc304c3405f8f56c079a0773 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 16:43:19 -0700 Subject: [PATCH 09/10] Add utility script to run nightly spec --- util/nightly.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 util/nightly.sh diff --git a/util/nightly.sh b/util/nightly.sh new file mode 100755 index 0000000..460a839 --- /dev/null +++ b/util/nightly.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -e + +readonly image=crystallang/crystal:nightly +readonly code=/project + +docker run -it -v "$PWD:${code}" -w "${code}" "${image}" crystal spec "$@" From 726a2e1515f437027c20a61e90e423223a6961ae Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 26 Jan 2023 17:19:31 -0700 Subject: [PATCH 10/10] Add non-captured block argument Preparing for Crystal 1.8.0 https://github.com/crystal-lang/crystal/issues/8764 --- CHANGELOG.md | 1 + spec/spectator/dsl/mocks/double_spec.cr | 2 +- spec/spectator/dsl/mocks/mock_spec.cr | 44 ++++++++++---------- spec/spectator/dsl/mocks/null_double_spec.cr | 2 +- spec/spectator/mocks/double_spec.cr | 2 +- spec/spectator/mocks/mock_spec.cr | 4 +- spec/spectator/mocks/null_double_spec.cr | 2 +- src/spectator/context.cr | 2 +- src/spectator/dsl/expectations.cr | 2 +- src/spectator/error_result.cr | 2 +- src/spectator/example.cr | 6 +-- src/spectator/example_group.cr | 2 +- src/spectator/fail_result.cr | 2 +- src/spectator/formatting/components/block.cr | 4 +- src/spectator/harness.cr | 12 +++--- src/spectator/matchers/exception_matcher.cr | 2 +- src/spectator/pass_result.cr | 2 +- src/spectator/pending_result.cr | 2 +- 18 files changed, 48 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffd70d3..17b7220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Expectations using 'should' syntax report file and line where the 'should' keyword is instead of the test start. +- Add non-captured block argument in preparation for Crystal 1.8.0. ## [0.11.5] - 2022-12-18 ### Added diff --git a/spec/spectator/dsl/mocks/double_spec.cr b/spec/spectator/dsl/mocks/double_spec.cr index 89f652c..5547ae0 100644 --- a/spec/spectator/dsl/mocks/double_spec.cr +++ b/spec/spectator/dsl/mocks/double_spec.cr @@ -168,7 +168,7 @@ Spectator.describe "Double DSL", :smoke do context "methods accepting blocks" do double(:test7) do - stub def foo + stub def foo(&) yield end diff --git a/spec/spectator/dsl/mocks/mock_spec.cr b/spec/spectator/dsl/mocks/mock_spec.cr index 05ef4c9..cd57cdc 100644 --- a/spec/spectator/dsl/mocks/mock_spec.cr +++ b/spec/spectator/dsl/mocks/mock_spec.cr @@ -40,17 +40,17 @@ Spectator.describe "Mock DSL", :smoke do arg end - def method4 : Symbol + def method4(&) : Symbol @_spectator_invocations << :method4 yield end - def method5 + def method5(&) @_spectator_invocations << :method5 yield.to_i end - def method6 + def method6(&) @_spectator_invocations << :method6 yield end @@ -60,7 +60,7 @@ Spectator.describe "Mock DSL", :smoke do {arg, args, kwarg, kwargs} end - def method8(arg, *args, kwarg, **kwargs) + def method8(arg, *args, kwarg, **kwargs, &) @_spectator_invocations << :method8 yield {arg, args, kwarg, kwargs} @@ -80,7 +80,7 @@ Spectator.describe "Mock DSL", :smoke do "stubbed" end - stub def method4 : Symbol + stub def method4(&) : Symbol yield :block end @@ -258,12 +258,12 @@ Spectator.describe "Mock DSL", :smoke do # NOTE: Abstract methods that yield must have yield functionality defined in the method. # This requires that yielding methods have a default implementation. # Just providing `&` in the arguments gets dropped by the compiler unless `yield` is in the method definition. - stub def method5 + stub def method5(&) yield end # NOTE: Another quirk where a default implementation must be provided because `&` is dropped. - stub def method6 : Symbol + stub def method6(&) : Symbol yield end @@ -381,12 +381,12 @@ Spectator.describe "Mock DSL", :smoke do # NOTE: Abstract methods that yield must have yield functionality defined in the method. # This requires that yielding methods have a default implementation. # Just providing `&` in the arguments gets dropped by the compiler unless `yield` is in the method definition. - stub def method5 + stub def method5(&) yield end # NOTE: Another quirk where a default implementation must be provided because `&` is dropped. - stub def method6 : Symbol + stub def method6(&) : Symbol yield end end @@ -454,12 +454,12 @@ Spectator.describe "Mock DSL", :smoke do # NOTE: Abstract methods that yield must have yield functionality defined in the method. # This requires that yielding methods have a default implementation. # Just providing `&` in the arguments gets dropped by the compiler unless `yield` is in the method definition. - stub def method5 + stub def method5(&) yield end # NOTE: Another quirk where a default implementation must be provided because `&` is dropped. - stub def method6 : Symbol + stub def method6(&) : Symbol yield end @@ -577,12 +577,12 @@ Spectator.describe "Mock DSL", :smoke do # NOTE: Abstract methods that yield must have yield functionality defined in the method. # This requires that yielding methods have a default implementation. # Just providing `&` in the arguments gets dropped by the compiler unless `yield` is in the method definition. - stub def method5 + stub def method5(&) yield end # NOTE: Another quirk where a default implementation must be provided because `&` is dropped. - stub def method6 : Symbol + stub def method6(&) : Symbol yield end end @@ -620,11 +620,11 @@ Spectator.describe "Mock DSL", :smoke do :original end - def method3 + def method3(&) yield end - def method4 : Int32 + def method4(&) : Int32 yield.to_i end @@ -749,11 +749,11 @@ Spectator.describe "Mock DSL", :smoke do :original end - def method3 + def method3(&) yield end - def method4 : Int32 + def method4(&) : Int32 yield.to_i end @@ -1108,17 +1108,17 @@ Spectator.describe "Mock DSL", :smoke do arg end - def method4 : Symbol + def method4(&) : Symbol @_spectator_invocations << :method4 yield end - def method5 + def method5(&) @_spectator_invocations << :method5 yield.to_i end - def method6 + def method6(&) @_spectator_invocations << :method6 yield end @@ -1128,7 +1128,7 @@ Spectator.describe "Mock DSL", :smoke do {arg, args, kwarg, kwargs} end - def method8(arg, *args, kwarg, **kwargs) + def method8(arg, *args, kwarg, **kwargs, &) @_spectator_invocations << :method8 yield {arg, args, kwarg, kwargs} @@ -1148,7 +1148,7 @@ Spectator.describe "Mock DSL", :smoke do "stubbed" end - stub def method4 : Symbol + stub def method4(&) : Symbol yield :block end diff --git a/spec/spectator/dsl/mocks/null_double_spec.cr b/spec/spectator/dsl/mocks/null_double_spec.cr index 1219f50..06d35ee 100644 --- a/spec/spectator/dsl/mocks/null_double_spec.cr +++ b/spec/spectator/dsl/mocks/null_double_spec.cr @@ -156,7 +156,7 @@ Spectator.describe "Null double DSL" do context "methods accepting blocks" do double(:test7) do - stub def foo + stub def foo(&) yield end diff --git a/spec/spectator/mocks/double_spec.cr b/spec/spectator/mocks/double_spec.cr index 41bfad2..e55c549 100644 --- a/spec/spectator/mocks/double_spec.cr +++ b/spec/spectator/mocks/double_spec.cr @@ -297,7 +297,7 @@ Spectator.describe Spectator::Double do arg end - stub def self.baz(arg) + stub def self.baz(arg, &) yield end end diff --git a/spec/spectator/mocks/mock_spec.cr b/spec/spectator/mocks/mock_spec.cr index 7d04fed..3ddd0fe 100644 --- a/spec/spectator/mocks/mock_spec.cr +++ b/spec/spectator/mocks/mock_spec.cr @@ -364,7 +364,7 @@ Spectator.describe Spectator::Mock do arg end - def self.baz(arg) + def self.baz(arg, &) yield end @@ -929,7 +929,7 @@ Spectator.describe Spectator::Mock do arg end - def self.baz(arg) + def self.baz(arg, &) yield end end diff --git a/spec/spectator/mocks/null_double_spec.cr b/spec/spectator/mocks/null_double_spec.cr index ad87ea9..a6fc7d2 100644 --- a/spec/spectator/mocks/null_double_spec.cr +++ b/spec/spectator/mocks/null_double_spec.cr @@ -259,7 +259,7 @@ Spectator.describe Spectator::NullDouble do arg end - stub def self.baz(arg) + stub def self.baz(arg, &) yield end end diff --git a/src/spectator/context.cr b/src/spectator/context.cr index b9f532a..15b9335 100644 --- a/src/spectator/context.cr +++ b/src/spectator/context.cr @@ -5,7 +5,7 @@ # The reason for this is to prevent name collision when using the DSL to define a spec. abstract class SpectatorContext # Evaluates the contents of a block within the scope of the context. - def eval + def eval(&) with self yield end diff --git a/src/spectator/dsl/expectations.cr b/src/spectator/dsl/expectations.cr index a35a15c..dba2e9b 100644 --- a/src/spectator/dsl/expectations.cr +++ b/src/spectator/dsl/expectations.cr @@ -182,7 +182,7 @@ module Spectator::DSL # expect(false).to be_true # end # ``` - def aggregate_failures(label = nil) + def aggregate_failures(label = nil, &) ::Spectator::Harness.current.aggregate_failures(label) do yield end diff --git a/src/spectator/error_result.cr b/src/spectator/error_result.cr index a4531fb..f58da20 100644 --- a/src/spectator/error_result.cr +++ b/src/spectator/error_result.cr @@ -11,7 +11,7 @@ module Spectator end # Calls the `error` method on *visitor*. - def accept(visitor) + def accept(visitor, &) visitor.error(yield self) end diff --git a/src/spectator/example.cr b/src/spectator/example.cr index 04d69c9..e18676c 100644 --- a/src/spectator/example.cr +++ b/src/spectator/example.cr @@ -164,7 +164,7 @@ module Spectator # The context casted to an instance of *klass* is provided as a block argument. # # TODO: Benchmark compiler performance using this method versus client-side casting in a proc. - protected def with_context(klass) + protected def with_context(klass, &) context = klass.cast(@context) with context yield end @@ -184,7 +184,7 @@ module Spectator end # Yields this example and all parent groups. - def ascend + def ascend(&) node = self while node yield node @@ -279,7 +279,7 @@ module Spectator # The block given to this method will be executed within the test context. # # TODO: Benchmark compiler performance using this method versus client-side casting in a proc. - protected def with_context(klass) + protected def with_context(klass, &) context = @example.cast_context(klass) with context yield end diff --git a/src/spectator/example_group.cr b/src/spectator/example_group.cr index 277be3c..55a3233 100644 --- a/src/spectator/example_group.cr +++ b/src/spectator/example_group.cr @@ -87,7 +87,7 @@ module Spectator delegate size, unsafe_fetch, to: @nodes # Yields this group and all parent groups. - def ascend + def ascend(&) group = self while group yield group diff --git a/src/spectator/fail_result.cr b/src/spectator/fail_result.cr index c283a80..082a0d2 100644 --- a/src/spectator/fail_result.cr +++ b/src/spectator/fail_result.cr @@ -24,7 +24,7 @@ module Spectator end # Calls the `failure` method on *visitor*. - def accept(visitor) + def accept(visitor, &) visitor.fail(yield self) end diff --git a/src/spectator/formatting/components/block.cr b/src/spectator/formatting/components/block.cr index 40cd5a8..22411a7 100644 --- a/src/spectator/formatting/components/block.cr +++ b/src/spectator/formatting/components/block.cr @@ -13,7 +13,7 @@ module Spectator::Formatting::Components end # Increases the indent by the a specific *amount* for the duration of the block. - private def indent(amount = INDENT) + private def indent(amount = INDENT, &) @indent += amount yield @indent -= amount @@ -23,7 +23,7 @@ module Spectator::Formatting::Components # The contents of the line should be generated by a block provided to this method. # Ensure that _only_ one line is produced by the block, # otherwise the indent will be lost. - private def line(io) + private def line(io, &) @indent.times { io << ' ' } yield io.puts diff --git a/src/spectator/harness.cr b/src/spectator/harness.cr index 6be48b9..1f9fa09 100644 --- a/src/spectator/harness.cr +++ b/src/spectator/harness.cr @@ -43,7 +43,7 @@ module Spectator # The value of `.current` is set to the harness for the duration of the test. # It will be reset after the test regardless of the outcome. # The result of running the test code will be returned. - def self.run : Result + def self.run(&) : Result with_harness do |harness| harness.run { yield } end @@ -53,7 +53,7 @@ module Spectator # The `.current` harness is set to the new harness for the duration of the block. # `.current` is reset to the previous value (probably nil) afterwards, even if the block raises. # The result of the block is returned. - private def self.with_harness + private def self.with_harness(&) previous = @@current begin @@current = harness = new @@ -70,7 +70,7 @@ module Spectator # Runs test code and produces a result based on the outcome. # The test code should be called from within the block given to this method. - def run : Result + def run(&) : Result elapsed, error = capture { yield } elapsed2, error2 = capture { run_deferred } run_cleanup @@ -106,7 +106,7 @@ module Spectator @cleanup << block end - def aggregate_failures(label = nil) + def aggregate_failures(label = nil, &) previous = @aggregate @aggregate = aggregate = [] of Expectation begin @@ -135,7 +135,7 @@ module Spectator # Yields to run the test code and returns information about the outcome. # Returns a tuple with the elapsed time and an error if one occurred (otherwise nil). - private def capture : Tuple(Time::Span, Exception?) + private def capture(&) : Tuple(Time::Span, Exception?) error = nil elapsed = Time.measure do error = catch { yield } @@ -146,7 +146,7 @@ module Spectator # Yields to run a block of code and captures exceptions. # If the block of code raises an error, the error is caught and returned. # If the block doesn't raise an error, then nil is returned. - private def catch : Exception? + private def catch(&) : Exception? yield rescue e e diff --git a/src/spectator/matchers/exception_matcher.cr b/src/spectator/matchers/exception_matcher.cr index adec663..b26d390 100644 --- a/src/spectator/matchers/exception_matcher.cr +++ b/src/spectator/matchers/exception_matcher.cr @@ -97,7 +97,7 @@ module Spectator::Matchers # Runs a block of code and returns the exception it threw. # If no exception was thrown, *nil* is returned. - private def capture_exception + private def capture_exception(&) exception = nil begin yield diff --git a/src/spectator/pass_result.cr b/src/spectator/pass_result.cr index 20e3b04..21ed6c5 100644 --- a/src/spectator/pass_result.cr +++ b/src/spectator/pass_result.cr @@ -9,7 +9,7 @@ module Spectator end # Calls the `pass` method on *visitor*. - def accept(visitor) + def accept(visitor, &) visitor.pass(yield self) end diff --git a/src/spectator/pending_result.cr b/src/spectator/pending_result.cr index cff38c5..57f7fd7 100644 --- a/src/spectator/pending_result.cr +++ b/src/spectator/pending_result.cr @@ -28,7 +28,7 @@ module Spectator end # Calls the `pending` method on the *visitor*. - def accept(visitor) + def accept(visitor, &) visitor.pending(yield self) end