Module: Amount::RSpecMatchers

Defined in:
lib/amount/rspec_matchers.rb

Overview

Internal matcher helpers for the opt-in RSpec integration.

Class Method Summary collapse

Class Method Details

.define_amount_column_matcherObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/amount/rspec_matchers.rb', line 68

def define_amount_column_matcher
  RSpec::Matchers.define :have_amount_column do |name, *expected_arguments|
    match do |record|
      @name = name
      @expected = Amount::RSpecSupport.coerce_amount_arguments(expected_arguments)
      @definition = record.class.amount_attribute_definitions.fetch(name.to_sym)

      @definition.read(record) == @expected &&
        record.public_send(@definition.atomic_column).to_i == @expected.atomic &&
        (@definition.fixed_symbol? ||
          record.public_send(@definition.symbol_column) == @expected.symbol.to_s)
    end

    failure_message do |record|
      "expected #{record.inspect} to have #{@name} column matching #{@expected.inspect}"
    end
  end
end

.define_amount_equality_matcher(name, &expected_builder) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/amount/rspec_matchers.rb', line 8

def define_amount_equality_matcher(name, &expected_builder)
  RSpec::Matchers.define name do |*arguments|
    match do |actual|
      @expected = instance_exec(*arguments, &expected_builder)
      actual.is_a?(Amount) && actual == @expected
    end

    failure_message do |actual|
      return "expected #{actual.inspect} to be an Amount equal to #{@expected.inspect}" unless actual.is_a?(Amount)

      "expected #{actual.inspect} to equal amount #{@expected.inspect}"
    end
  end
end

.define_amount_predicate_matcher(name, description, &predicate) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/amount/rspec_matchers.rb', line 23

def define_amount_predicate_matcher(name, description, &predicate)
  RSpec::Matchers.define name do
    match do |actual|
      actual.is_a?(Amount) && instance_exec(actual, &predicate)
    end

    failure_message do |actual|
      "expected #{actual.inspect} to be #{description}"
    end
  end
end

.define_amount_sum_matcherObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/amount/rspec_matchers.rb', line 87

def define_amount_sum_matcher
  RSpec::Matchers.define :match_amounts do |expected_hash|
    match do |actual_hash|
      @expected = expected_hash.to_h do |symbol, value|
        amount = Amount.new(value, symbol)
        [amount.symbol, amount]
      end
      @actual = Amount::RSpecSupport.normalize_amount_sums(actual_hash)

      @actual == @expected
    end

    failure_message do |_actual_hash|
      "expected grouped amounts #{@actual.inspect} to match #{@expected.inspect}"
    end
  end
end

.define_amount_type_matcherObject



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/amount/rspec_matchers.rb', line 35

def define_amount_type_matcher
  RSpec::Matchers.define :be_amount_of do |expected_symbol|
    match do |actual|
      @expected_symbol = expected_symbol.to_sym
      actual.is_a?(Amount) && actual.symbol == @expected_symbol
    end

    failure_message do |actual|
      "expected #{actual.inspect} to be an Amount of #{@expected_symbol}"
    end
  end
end

.define_approximate_amount_matcherObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/amount/rspec_matchers.rb', line 48

def define_approximate_amount_matcher
  RSpec::Matchers.define :be_approximately_amount do |*expected_arguments, within:|
    match do |actual|
      @expected = Amount::RSpecSupport.coerce_amount_arguments(expected_arguments)
      @within = Amount::RSpecSupport.coerce_delta(@expected, within)

      actual.is_a?(Amount) &&
        actual.same_type?(@expected) &&
        @within.same_type?(@expected) &&
        (actual - @expected).abs.atomic <= @within.atomic
    end

    failure_message do |actual|
      return "expected #{actual.inspect} to be an Amount within #{@within.inspect} of #{@expected.inspect}" unless actual.is_a?(Amount)

      "expected #{actual.inspect} to be within #{@within.inspect} of #{@expected.inspect}"
    end
  end
end