diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bf29bde..4245abe 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -47,4 +47,4 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Test - run: "bundle exec rspec && bundle exec cucumber || $ALLOW_FAILURES" + run: "bundle exec rspec && bundle exec rake cucumber || $ALLOW_FAILURES" diff --git a/Gemfile b/Gemfile index e346981..639b63f 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ group :test do if RUBY_VERSION >= "3.4" # Cucumber is broken on Ruby 3.4, requires the fix in # https://github.com/cucumber/cucumber-ruby/pull/1757 - gem "cucumber", ">= 9.2", git: "https://github.com/cucumber/cucumber-ruby" + gem "cucumber", ">= 9.2", git: "https://github.com/cucumber/cucumber-ruby", ref: "a468bc682eec68ef5b5660a17c4c0e7e52cfc67b" else gem "cucumber", "~> 9.2" end diff --git a/Rakefile b/Rakefile index fd4014c..5723879 100644 --- a/Rakefile +++ b/Rakefile @@ -2,6 +2,14 @@ task :default => [:spec] +task :cucumber do + if RUBY_VERSION >= "3.4" + sh "cucumber --tags 'not @before_ruby_3_3'" + else + sh "cucumber --tags 'not @after_ruby_3_4'" + end +end + task :add_tag do `git tag -a v#{Contracts::VERSION} -m 'v#{Contracts::VERSION}'` end diff --git a/features/basics/pretty-print.feature b/features/basics/pretty-print_@before_ruby_3_3.feature similarity index 98% rename from features/basics/pretty-print.feature rename to features/basics/pretty-print_@before_ruby_3_3.feature index af88f49..76d3915 100644 --- a/features/basics/pretty-print.feature +++ b/features/basics/pretty-print_@before_ruby_3_3.feature @@ -1,4 +1,5 @@ -Feature: Pretty printing Contract violations +@before_ruby_3_3 +Feature: Pretty printing Contract violations (Ruby 3.3-) Scenario: Big array argument being passed to big array method parameter Given a file named "example.rb" with: diff --git a/features/basics/pretty-print_after_ruby_3_4.feature b/features/basics/pretty-print_after_ruby_3_4.feature new file mode 100644 index 0000000..4280af8 --- /dev/null +++ b/features/basics/pretty-print_after_ruby_3_4.feature @@ -0,0 +1,242 @@ +@after_ruby_3_4 +Feature: Pretty printing Contract violations (Ruby 3.4+) + + Scenario: Big array argument being passed to big array method parameter + Given a file named "example.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + class << self + Contract [ + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol] + ] => nil + def run(data) + nil + end + end + end + + puts Example.run([ + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"] + ]) + """ + When I run `ruby example.rb` + Then the output should contain: + """ + : Contract violation for argument 1 of 1: (ParamContractError) + Expected: [(String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol)], + Actual: [["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"]] + Value guarded in: Example::run + With Contract: Array => NilClass + At: example.rb:17 + """ + + Scenario: Big array value being returned from method expecting different big array type + Given a file named "example.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + class << self + Contract C::None => [ + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol], + C::Or[String, Symbol] + ] + def run + [ + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"] + ] + end + end + end + + puts Example.run + """ + When I run `ruby example.rb` + Then the output should contain: + """ + : Contract violation for return value: (ReturnContractError) + Expected: [(String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol), + (String or Symbol)], + Actual: [["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"], + ["foo", "foo"]] + Value guarded in: Example::run + With Contract: None => Array + At: example.rb:17 + """ + + Scenario: Big hash argument being passed to big hash method parameter + Given a file named "example.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + class << self + Contract ({ + a: C::Or[String, Symbol], + b: C::Or[String, Symbol], + c: C::Or[String, Symbol], + d: C::Or[String, Symbol], + e: C::Or[String, Symbol], + f: C::Or[String, Symbol], + g: C::Or[String, Symbol] + }) => nil + def run(data) + nil + end + end + end + + puts Example.run({ + a: ["foo", "foo"], + b: ["foo", "foo"], + c: ["foo", "foo"], + d: ["foo", "foo"], + e: ["foo", "foo"], + f: ["foo", "foo"], + g: ["foo", "foo"] + }) + """ + When I run `ruby example.rb` + Then the output should contain: + """ + : Contract violation for argument 1 of 1: (ParamContractError) + Expected: {a: (String or Symbol), + b: (String or Symbol), + c: (String or Symbol), + d: (String or Symbol), + e: (String or Symbol), + f: (String or Symbol), + g: (String or Symbol)}, + Actual: {a: ["foo", "foo"], + b: ["foo", "foo"], + c: ["foo", "foo"], + d: ["foo", "foo"], + e: ["foo", "foo"], + f: ["foo", "foo"], + g: ["foo", "foo"]} + Value guarded in: Example::run + With Contract: Hash => NilClass + At: example.rb:17 + """ + + Scenario: Big hash value being returned from method expecting different big hash type + Given a file named "example.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + class << self + Contract C::None => ({ + a: C::Or[String, Symbol], + b: C::Or[String, Symbol], + c: C::Or[String, Symbol], + d: C::Or[String, Symbol], + e: C::Or[String, Symbol], + f: C::Or[String, Symbol], + g: C::Or[String, Symbol] + }) + def run + { + a: ["foo", "foo"], + b: ["foo", "foo"], + c: ["foo", "foo"], + d: ["foo", "foo"], + e: ["foo", "foo"], + f: ["foo", "foo"], + g: ["foo", "foo"] + } + end + end + end + + puts Example.run + """ + When I run `ruby example.rb` + Then the output should contain: + """ + : Contract violation for return value: (ReturnContractError) + Expected: {a: (String or Symbol), + b: (String or Symbol), + c: (String or Symbol), + d: (String or Symbol), + e: (String or Symbol), + f: (String or Symbol), + g: (String or Symbol)}, + Actual: {a: ["foo", "foo"], + b: ["foo", "foo"], + c: ["foo", "foo"], + d: ["foo", "foo"], + e: ["foo", "foo"], + f: ["foo", "foo"], + g: ["foo", "foo"]} + Value guarded in: Example::run + With Contract: None => Hash + At: example.rb:17 + """