diff --git a/CHANGELOG.md b/CHANGELOG.md index bccdc60..d2331d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -274,7 +274,9 @@ 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.9.34...HEAD +[Unreleased]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.36...HEAD +[0.9.35]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.35...v0.9.36 +[0.9.35]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.34...v0.9.35 [0.9.34]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.33...v0.9.34 [0.9.33]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.32...v0.9.33 [0.9.32]: https://gitlab.com/arctic-fox/spectator/-/compare/v0.9.31...v0.9.32 diff --git a/spec/matchers/type_matcher_spec.cr b/spec/matchers/type_matcher_spec.cr new file mode 100644 index 0000000..22d218e --- /dev/null +++ b/spec/matchers/type_matcher_spec.cr @@ -0,0 +1,26 @@ +require "../spec_helper" + +Spectator.describe Spectator::Matchers::TypeMatcher do + context String do # Sets `described_class` to String + def other_type + Int32 + end + + describe "#|" do + it "works on sets" do + super_set = (described_class | other_type) + + expect(42).to be_kind_of(super_set) + expect("foo").to be_a(super_set) + end + end + + it "works on described_class" do + expect("foo").to be_a_kind_of(described_class) + end + + it "works on plain types" do + expect(42).to be_a(Int32) + end + end +end diff --git a/src/spectator.cr b/src/spectator.cr index 3dff022..88238a8 100644 --- a/src/spectator.cr +++ b/src/spectator.cr @@ -50,7 +50,7 @@ module Spectator # A `ConfigBuilder` is yielded to allow changing the configuration. # NOTE: The configuration set here can be overriden # with a `.spectator` file and command-line arguments. - def configure : Nil + def configure(& : ConfigBuilder -> _) : Nil yield @@config_builder end diff --git a/src/spectator/context.cr b/src/spectator/context.cr index 2860ae3..475f49c 100644 --- a/src/spectator/context.cr +++ b/src/spectator/context.cr @@ -4,10 +4,17 @@ # This type is intentionally outside the `Spectator` module. # The reason for this is to prevent name collision when using the DSL to define a spec. abstract class SpectatorContext + # Produces a dummy string to represent the context as a string. + # This prevents the default behavior, which normally stringifies instance variables. + # Due to the sheer amount of types Spectator can create + # and that the Crystal compiler instantiates a `#to_s` and/or `#inspect` for each of those types, + # an explosion in method instances can be created. + # The compile time is drastically reduced by using a dummy string instead. def to_s(io) io << "Context" end + # :ditto: def inspect(io) io << "Context<" io << self.class diff --git a/src/spectator/dsl/matchers.cr b/src/spectator/dsl/matchers.cr index a8fabb1..34adf26 100644 --- a/src/spectator/dsl/matchers.cr +++ b/src/spectator/dsl/matchers.cr @@ -77,7 +77,7 @@ module Spectator::DSL # expect(x).to be_a(Int32 | String) # ``` macro be_a(expected) - ::Spectator::Matchers::TypeMatcher({{expected}}).new + ::Spectator::Matchers::TypeMatcher.create({{expected}}) end # Indicates that some value should be of a specified type. diff --git a/src/spectator/formatting/document_formatter.cr b/src/spectator/formatting/document_formatter.cr index 16efdf8..331fb13 100644 --- a/src/spectator/formatting/document_formatter.cr +++ b/src/spectator/formatting/document_formatter.cr @@ -29,7 +29,7 @@ module Spectator::Formatting # Produces a single character output based on a result. def end_example(result) @previous_hierarchy.size.times { @io.print INDENT } - @io.puts result.accept(Color) { result.example.name } + @io.puts result.accept(Color) { result.example } end # Produces a list of groups making up the hierarchy for an example. diff --git a/src/spectator/matchers/type_matcher.cr b/src/spectator/matchers/type_matcher.cr index dc88a24..10d11f4 100644 --- a/src/spectator/matchers/type_matcher.cr +++ b/src/spectator/matchers/type_matcher.cr @@ -4,6 +4,11 @@ module Spectator::Matchers # Matcher that tests a value is of a specified type. # The values are compared with the `Object#is_a?` method. struct TypeMatcher(Expected) < StandardMatcher + # Alternate constructor that works with constant types and types from variables. + def self.create(type : T.class) forall T + TypeMatcher(T).new + end + # Short text about the matcher's purpose. # This explains what condition satisfies the matcher. # The description is used when the one-liner syntax is used. diff --git a/src/spectator/spec/builder.cr b/src/spectator/spec/builder.cr index 3d340a7..dd76a7b 100644 --- a/src/spectator/spec/builder.cr +++ b/src/spectator/spec/builder.cr @@ -175,7 +175,7 @@ module Spectator # Builds the configuration to use for the spec. # A `ConfigBuilder` is yielded to the block provided to this method. # That builder will be used to create the configuration. - def config + def configure(& : ConfigBuilder -> _) : Nil builder = ConfigBuilder.new yield builder @config = builder.build