duck_testing 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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.rspec +3 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +7 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +7 -0
- data/Guardfile +19 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/Rakefile +8 -0
- data/duck_testing.gemspec +28 -0
- data/lib/duck_testing.rb +19 -0
- data/lib/duck_testing/errors.rb +4 -0
- data/lib/duck_testing/method_call_data.rb +19 -0
- data/lib/duck_testing/reporter/base.rb +17 -0
- data/lib/duck_testing/reporter/raise_error.rb +30 -0
- data/lib/duck_testing/tester.rb +50 -0
- data/lib/duck_testing/type/base.rb +13 -0
- data/lib/duck_testing/type/class_instance.rb +24 -0
- data/lib/duck_testing/type/constant.rb +26 -0
- data/lib/duck_testing/type/duck_type.rb +24 -0
- data/lib/duck_testing/type/hash.rb +60 -0
- data/lib/duck_testing/type/order_dependent_array.rb +27 -0
- data/lib/duck_testing/type/order_independent_array.rb +27 -0
- data/lib/duck_testing/version.rb +3 -0
- data/lib/duck_testing/violation.rb +41 -0
- data/lib/duck_testing/yard.rb +51 -0
- data/lib/duck_testing/yard/builder.rb +70 -0
- data/lib/duck_testing/yard/class_object.rb +20 -0
- data/lib/duck_testing/yard/code_object.rb +22 -0
- data/lib/duck_testing/yard/method_object.rb +87 -0
- data/lib/duck_testing/yard/method_parameter.rb +49 -0
- data/lib/duck_testing/yard/parser.rb +30 -0
- data/sample/.gitignore +35 -0
- data/sample/.rspec +3 -0
- data/sample/Gemfile +5 -0
- data/sample/lib/concern.rb +9 -0
- data/sample/lib/sample.rb +14 -0
- data/sample/spec/sample_spec.rb +33 -0
- data/sample/spec/spec_helper.rb +4 -0
- data/spec/.rubocop.yml +8 -0
- data/spec/class_type_integration_spec.rb +98 -0
- data/spec/constant_type_integration_spec.rb +90 -0
- data/spec/duck_testing/method_call_data_spec.rb +24 -0
- data/spec/duck_testing/reporter/raise_error_spec.rb +35 -0
- data/spec/duck_testing/tester_spec.rb +73 -0
- data/spec/duck_testing/violation_spec.rb +58 -0
- data/spec/duck_testing/yard/builder_spec.rb +179 -0
- data/spec/duck_testing/yard/parser_spec.rb +38 -0
- data/spec/duck_type_integration_spec.rb +89 -0
- data/spec/hash_type_integration_spec.rb +112 -0
- data/spec/order_dependent_array_type_integration_spec.rb +121 -0
- data/spec/order_independent_array_type_integration_spec.rb +104 -0
- data/spec/spec_helper.rb +78 -0
- metadata +212 -0
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            module DuckTesting
         | 
| 2 | 
            +
              module YARD
         | 
| 3 | 
            +
                class MethodParameter
         | 
| 4 | 
            +
                  attr_reader :method_object, :name, :default, :parameter_tag
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  # @param method_object [DuckTesting::YARD::MethodObject]
         | 
| 7 | 
            +
                  # @param name [String]
         | 
| 8 | 
            +
                  # @param default [String]
         | 
| 9 | 
            +
                  # @param parameter_tag [YARD::Tags::Tag]
         | 
| 10 | 
            +
                  def initialize(method_object, name, default, parameter_tag)
         | 
| 11 | 
            +
                    @method_object = method_object
         | 
| 12 | 
            +
                    @name = name
         | 
| 13 | 
            +
                    @default = default
         | 
| 14 | 
            +
                    @parameter_tag = parameter_tag
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # @return [String]
         | 
| 18 | 
            +
                  def to_s
         | 
| 19 | 
            +
                    if default.nil?
         | 
| 20 | 
            +
                      name
         | 
| 21 | 
            +
                    elsif name.end_with?(":")
         | 
| 22 | 
            +
                      "#{name} #{default}"
         | 
| 23 | 
            +
                    else
         | 
| 24 | 
            +
                      "#{name} = #{default}"
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # @return [Boolean]
         | 
| 29 | 
            +
                  def documented?
         | 
| 30 | 
            +
                    !parameter_tag.nil?
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  # @return [Boolean]
         | 
| 34 | 
            +
                  def keyword?
         | 
| 35 | 
            +
                    name.end_with?(":")
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # @return [Symbol, nil]
         | 
| 39 | 
            +
                  def key_name
         | 
| 40 | 
            +
                    keyword? ? name[0...-1].to_sym : nil
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  # @return [Array<DuckTesting::Type::Base>]
         | 
| 44 | 
            +
                  def expected_types
         | 
| 45 | 
            +
                    parameter_tag ? DuckTesting::YARD.expected_types(parameter_tag.types) : []
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require "yard"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DuckTesting
         | 
| 4 | 
            +
              module YARD
         | 
| 5 | 
            +
                class Parser
         | 
| 6 | 
            +
                  class << self
         | 
| 7 | 
            +
                    # Parses a path or set of paths.
         | 
| 8 | 
            +
                    #
         | 
| 9 | 
            +
                    # @param paths [String, Array<String>] a path, glob or list of paths to parse
         | 
| 10 | 
            +
                    # @param excluded [Array<String, Regexp>] a list of excluded path matchers
         | 
| 11 | 
            +
                    # @return [Array<DuckTesting::YARD::ClassObject>]
         | 
| 12 | 
            +
                    def parse(paths, excluded)
         | 
| 13 | 
            +
                      ::YARD::Registry.clear
         | 
| 14 | 
            +
                      ::YARD::Parser::SourceParser.parse(paths, excluded)
         | 
| 15 | 
            +
                      ::YARD::Registry.all(:class).map { |class_object| ClassObject.new(class_object) }
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    # Parses a string `content`.
         | 
| 19 | 
            +
                    #
         | 
| 20 | 
            +
                    # @param content [String] the block of code to parse.
         | 
| 21 | 
            +
                    # @return [Array<DuckTesting::YARD::ClassObject>]
         | 
| 22 | 
            +
                    def parse_string(content)
         | 
| 23 | 
            +
                      ::YARD::Registry.clear
         | 
| 24 | 
            +
                      ::YARD::Parser::SourceParser.parse_string(content)
         | 
| 25 | 
            +
                      ::YARD::Registry.all(:class).map { |class_object| ClassObject.new(class_object) }
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
    
        data/sample/.gitignore
    ADDED
    
    | @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            *.gem
         | 
| 2 | 
            +
            *.rbc
         | 
| 3 | 
            +
            /.config
         | 
| 4 | 
            +
            /coverage/
         | 
| 5 | 
            +
            /InstalledFiles
         | 
| 6 | 
            +
            /pkg/
         | 
| 7 | 
            +
            /spec/reports/
         | 
| 8 | 
            +
            /test/tmp/
         | 
| 9 | 
            +
            /test/version_tmp/
         | 
| 10 | 
            +
            /tmp/
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ## Specific to RubyMotion:
         | 
| 13 | 
            +
            .dat*
         | 
| 14 | 
            +
            .repl_history
         | 
| 15 | 
            +
            build/
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## Documentation cache and generated files:
         | 
| 18 | 
            +
            /.yardoc/
         | 
| 19 | 
            +
            /_yardoc/
         | 
| 20 | 
            +
            /doc/
         | 
| 21 | 
            +
            /rdoc/
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## Environment normalisation:
         | 
| 24 | 
            +
            /.bundle/
         | 
| 25 | 
            +
            /lib/bundler/man/
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            # for a library or gem, you might want to ignore these files since the code is
         | 
| 28 | 
            +
            # intended to run in multiple environments; otherwise, check them in:
         | 
| 29 | 
            +
            Gemfile.lock
         | 
| 30 | 
            +
            .ruby-version
         | 
| 31 | 
            +
            .ruby-gemset
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
         | 
| 34 | 
            +
            .rvmrc
         | 
| 35 | 
            +
            spec/examples.txt
         | 
    
        data/sample/.rspec
    ADDED
    
    
    
        data/sample/Gemfile
    ADDED
    
    
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require "concern"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Sample
         | 
| 4 | 
            +
              include Concern
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              # Duplicate some text an arbitrary number of times.
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # @param text [String] the string to be duplicated.
         | 
| 9 | 
            +
              # @param count [Integer] the integer number of times to duplicate the `text`.
         | 
| 10 | 
            +
              # @return [String] the duplicated string.
         | 
| 11 | 
            +
              def multiplex(text, count)
         | 
| 12 | 
            +
                text * count
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            describe Sample do
         | 
| 2 | 
            +
              let(:sample) { described_class.new }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              describe "#multiplex" do
         | 
| 5 | 
            +
                subject { sample.multiplex(text, count) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                context "when valid parameters are given" do
         | 
| 8 | 
            +
                  let(:text) { "sample" }
         | 
| 9 | 
            +
                  let(:count) { 3 }
         | 
| 10 | 
            +
                  it { should eq "samplesamplesample" }
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                context "when invalid parameters are given" do
         | 
| 14 | 
            +
                  let(:text) { 3 }
         | 
| 15 | 
            +
                  let(:count) { 3 }
         | 
| 16 | 
            +
                  it { expect { subject }.to raise_error(DuckTesting::ContractViolationError) }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              describe "#double" do
         | 
| 21 | 
            +
                subject { sample.double(number) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                context "when valid parameters are given" do
         | 
| 24 | 
            +
                  let(:number) { 3 }
         | 
| 25 | 
            +
                  it { should eq 6 }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                context "when invalid parameters are given" do
         | 
| 29 | 
            +
                  let(:number) { "sample" }
         | 
| 30 | 
            +
                  it { expect { subject }.to raise_error(DuckTesting::ContractViolationError) }
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
    
        data/spec/.rubocop.yml
    ADDED
    
    
| @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            describe "Integration spec" do
         | 
| 2 | 
            +
              subject do
         | 
| 3 | 
            +
                instance.double(param)
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                klass.send(:prepend, duck_testing_module)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              let(:instance) { klass.new }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              let(:klass) do
         | 
| 13 | 
            +
                Class.new do
         | 
| 14 | 
            +
                  # @param number [Fixnum, Float]
         | 
| 15 | 
            +
                  # @return [Fixnum, Float]
         | 
| 16 | 
            +
                  def double(number)
         | 
| 17 | 
            +
                    number * 2
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              context "when expected parameter and return are given" do
         | 
| 23 | 
            +
                let(:param) { 1 }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                let(:duck_testing_module) do
         | 
| 26 | 
            +
                  Module.new do
         | 
| 27 | 
            +
                    def double(number)
         | 
| 28 | 
            +
                      tester = DuckTesting::Tester.new(self, "double")
         | 
| 29 | 
            +
                      tester.test_param(number, [
         | 
| 30 | 
            +
                        DuckTesting::Type::ClassInstance.new(Fixnum),
         | 
| 31 | 
            +
                        DuckTesting::Type::ClassInstance.new(Float)
         | 
| 32 | 
            +
                      ])
         | 
| 33 | 
            +
                      tester.test_return(super, [
         | 
| 34 | 
            +
                        DuckTesting::Type::ClassInstance.new(Fixnum),
         | 
| 35 | 
            +
                        DuckTesting::Type::ClassInstance.new(Float)
         | 
| 36 | 
            +
                      ])
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                it "does not raise error" do
         | 
| 42 | 
            +
                  expect { subject }.not_to raise_error
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it "returns original result" do
         | 
| 46 | 
            +
                  should eq 2
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              context "when unexpected parameter is given" do
         | 
| 51 | 
            +
                let(:param) { "string" }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                let(:duck_testing_module) do
         | 
| 54 | 
            +
                  Module.new do
         | 
| 55 | 
            +
                    def double(number)
         | 
| 56 | 
            +
                      tester = DuckTesting::Tester.new(self, "double")
         | 
| 57 | 
            +
                      tester.test_param(number, [
         | 
| 58 | 
            +
                        DuckTesting::Type::ClassInstance.new(Fixnum),
         | 
| 59 | 
            +
                        DuckTesting::Type::ClassInstance.new(Float)
         | 
| 60 | 
            +
                      ])
         | 
| 61 | 
            +
                      tester.test_return(super, [
         | 
| 62 | 
            +
                        DuckTesting::Type::ClassInstance.new(Fixnum),
         | 
| 63 | 
            +
                        DuckTesting::Type::ClassInstance.new(Float)
         | 
| 64 | 
            +
                      ])
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                it "raises ContractViolationError" do
         | 
| 70 | 
            +
                  expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 71 | 
            +
                  expect { subject }.to raise_error(/Contract violation for argument/)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              context "when unexpected result is given" do
         | 
| 76 | 
            +
                let(:param) { 1 }
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                let(:duck_testing_module) do
         | 
| 79 | 
            +
                  Module.new do
         | 
| 80 | 
            +
                    def double(number)
         | 
| 81 | 
            +
                      tester = DuckTesting::Tester.new(self, "double")
         | 
| 82 | 
            +
                      tester.test_param(number, [
         | 
| 83 | 
            +
                        DuckTesting::Type::ClassInstance.new(Fixnum),
         | 
| 84 | 
            +
                        DuckTesting::Type::ClassInstance.new(Float)
         | 
| 85 | 
            +
                      ])
         | 
| 86 | 
            +
                      tester.test_return(super, [
         | 
| 87 | 
            +
                        DuckTesting::Type::ClassInstance.new(String)
         | 
| 88 | 
            +
                      ])
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                it "raises ContractViolationError" do
         | 
| 94 | 
            +
                  expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 95 | 
            +
                  expect { subject }.to raise_error(/Contract violation for return value/)
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
| @@ -0,0 +1,90 @@ | |
| 1 | 
            +
            describe "Constant type integration spec" do
         | 
| 2 | 
            +
              subject do
         | 
| 3 | 
            +
                instance.not(param)
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                klass.send(:prepend, duck_testing_module)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              let(:instance) { klass.new }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              let(:klass) do
         | 
| 13 | 
            +
                Class.new do
         | 
| 14 | 
            +
                  # @param a [Boolean]
         | 
| 15 | 
            +
                  # @return [Boolean]
         | 
| 16 | 
            +
                  def not(a)
         | 
| 17 | 
            +
                    !a
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              context "when expected parameter and return are given" do
         | 
| 23 | 
            +
                let(:param) { true }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                let(:duck_testing_module) do
         | 
| 26 | 
            +
                  Module.new do
         | 
| 27 | 
            +
                    def not(a)
         | 
| 28 | 
            +
                      tester = DuckTesting::Tester.new(self, "not")
         | 
| 29 | 
            +
                      tester.test_param(a, [
         | 
| 30 | 
            +
                        DuckTesting::Type::Constant.new(true),
         | 
| 31 | 
            +
                        DuckTesting::Type::Constant.new(false)
         | 
| 32 | 
            +
                      ])
         | 
| 33 | 
            +
                      tester.test_return(super, [
         | 
| 34 | 
            +
                        DuckTesting::Type::Constant.new(true),
         | 
| 35 | 
            +
                        DuckTesting::Type::Constant.new(false)
         | 
| 36 | 
            +
                      ])
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                it "does not raise error" do
         | 
| 42 | 
            +
                  expect { subject }.not_to raise_error
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it "returns original result" do
         | 
| 46 | 
            +
                  should eq false
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              context "when unexpected parameter is given" do
         | 
| 51 | 
            +
                let(:param) { "string" }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                let(:duck_testing_module) do
         | 
| 54 | 
            +
                  Module.new do
         | 
| 55 | 
            +
                    def not(a)
         | 
| 56 | 
            +
                      tester = DuckTesting::Tester.new(self, "not")
         | 
| 57 | 
            +
                      tester.test_param(a, [
         | 
| 58 | 
            +
                        DuckTesting::Type::Constant.new(true),
         | 
| 59 | 
            +
                        DuckTesting::Type::Constant.new(false)
         | 
| 60 | 
            +
                      ])
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                it "raises ContractViolationError" do
         | 
| 66 | 
            +
                  expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 67 | 
            +
                  expect { subject }.to raise_error(/Contract violation for argument/)
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              context "when unexpected result is given" do
         | 
| 72 | 
            +
                let(:param) { true }
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                let(:duck_testing_module) do
         | 
| 75 | 
            +
                  Module.new do
         | 
| 76 | 
            +
                    def not(a)
         | 
| 77 | 
            +
                      tester = DuckTesting::Tester.new(self, "not")
         | 
| 78 | 
            +
                      tester.test_return(super, [
         | 
| 79 | 
            +
                        DuckTesting::Type::Constant.new(true)
         | 
| 80 | 
            +
                      ])
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                it "raises ContractViolationError" do
         | 
| 86 | 
            +
                  expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 87 | 
            +
                  expect { subject }.to raise_error(/Contract violation for return value/)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            describe DuckTesting::MethodCallData do
         | 
| 2 | 
            +
              let(:call_data) { described_class.new(*params) }
         | 
| 3 | 
            +
              let(:params) { [receiver, method_name] }
         | 
| 4 | 
            +
              let(:receiver) { nil }
         | 
| 5 | 
            +
              let(:method_name) { nil }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              describe "#method_expr" do
         | 
| 8 | 
            +
                subject { call_data.method_expr }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                let(:klass) do
         | 
| 11 | 
            +
                  Class.new do
         | 
| 12 | 
            +
                    def self.name
         | 
| 13 | 
            +
                      "Foo::Bar"
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                let(:receiver) { klass.new }
         | 
| 18 | 
            +
                let(:method_name) { "method_name" }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                it 'returns "Class#method" style method name' do
         | 
| 21 | 
            +
                  should eq "#{klass.name}##{method_name}"
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            describe DuckTesting::Reporter::RaiseError do
         | 
| 2 | 
            +
              let(:reporter) { described_class.new(violation) }
         | 
| 3 | 
            +
              let(:violation) { DuckTesting::Violation.new(violation_param) }
         | 
| 4 | 
            +
              let(:violation_param) do
         | 
| 5 | 
            +
                { call_data: call_data,
         | 
| 6 | 
            +
                  expected_types: [] }
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
              let(:call_data) { DuckTesting::MethodCallData.new("receiver", "mehtod_name") }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              describe "#report" do
         | 
| 11 | 
            +
                subject { reporter.report }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                context "when violation#param? is true" do
         | 
| 14 | 
            +
                  before do
         | 
| 15 | 
            +
                    allow(violation).to receive(:param?).and_return(true)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  it "raise ContractViolationError" do
         | 
| 19 | 
            +
                    expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 20 | 
            +
                    expect { subject }.to raise_error(/Contract violation for argument/)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                context "when violation#return? is true" do
         | 
| 25 | 
            +
                  before do
         | 
| 26 | 
            +
                    allow(violation).to receive(:return?).and_return(true)
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  it "raise ContractViolationError" do
         | 
| 30 | 
            +
                    expect { subject }.to raise_error(DuckTesting::ContractViolationError)
         | 
| 31 | 
            +
                    expect { subject }.to raise_error(/Contract violation for return value/)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         |