File: coercion_spec.rb

package info (click to toggle)
ruby-hashie 2.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 272 kB
  • ctags: 179
  • sloc: ruby: 1,898; makefile: 4
file content (151 lines) | stat: -rw-r--r-- 4,118 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
require 'spec_helper'

describe Hashie::Extensions::Coercion do
  class Initializable
    def initialize(obj, coerced = false)
      @coerced = coerced
      @value = obj.class.to_s
    end
    def coerced?; @coerced end
    attr_reader :value
  end

  class Coercable < Initializable
    def self.coerce(obj)
      new(obj, true)
    end
  end

  before(:each) do
    class ExampleCoercableHash < Hash
      include Hashie::Extensions::Coercion
      include Hashie::Extensions::MergeInitializer
    end
  end
  subject { ExampleCoercableHash }
  let(:instance){ subject.new }

  describe '.coerce_key' do
    it { subject.should be_respond_to(:coerce_key) }

    it 'should run through coerce on a specified key' do
      subject.coerce_key :foo, Coercable

      instance[:foo] = "bar"
      instance[:foo].should be_coerced
    end

    it "should support an array of keys" do
      subject.coerce_keys :foo, :bar, Coercable

      instance[:foo] = "bar"
      instance[:bar] = "bax"
      instance[:foo].should be_coerced
      instance[:bar].should be_coerced
    end

    it 'should just call #new if no coerce method is available' do
      subject.coerce_key :foo, Initializable

      instance[:foo] = "bar"
      instance[:foo].value.should == "String"
      instance[:foo].should_not be_coerced
    end

    it "should coerce when the merge initializer is used" do
      subject.coerce_key :foo, Coercable
      instance = subject.new(:foo => "bar")

      instance[:foo].should be_coerced
    end

    context 'when #replace is used' do
      before { subject.coerce_key :foo, :bar, Coercable }

      let(:instance) do
        subject.new(:foo => "bar").
          replace(:foo => "foz", :bar => "baz", :hi => "bye")
      end

      it "should coerce relevant keys" do
        instance[:foo].should be_coerced
        instance[:bar].should be_coerced
        instance[:hi].should_not respond_to(:coerced?)
      end

      it "should set correct values" do
        instance[:hi].should == "bye"
      end
    end

    context "when used with a Mash" do
      class UserMash < Hashie::Mash
      end
      class TweetMash < Hashie::Mash
        include Hashie::Extensions::Coercion
        coerce_key :user, UserMash
      end

      it "should coerce with instance initialization" do
        tweet = TweetMash.new(:user => {:email => 'foo@bar.com'})
        tweet[:user].should be_a(UserMash)
      end

      it "should coerce when setting with attribute style" do
        tweet = TweetMash.new
        tweet.user = {:email => 'foo@bar.com'}
        tweet[:user].should be_a(UserMash)
      end

      it "should coerce when setting with string index" do
        tweet = TweetMash.new
        tweet['user'] = {:email => 'foo@bar.com'}
        tweet[:user].should be_a(UserMash)
      end

      it "should coerce when setting with symbol index" do
        tweet = TweetMash.new
        tweet[:user] = {:email => 'foo@bar.com'}
        tweet[:user].should be_a(UserMash)
      end
    end
  end

  describe '.coerce_value' do
    context 'with :strict => true' do
      it 'should coerce any value of the exact right class' do
        subject.coerce_value String, Coercable

        instance[:foo] = "bar"
        instance[:bar] = "bax"
        instance[:hi]  = :bye
        instance[:foo].should be_coerced
        instance[:bar].should be_coerced
        instance[:hi].should_not respond_to(:coerced?)
      end

      it 'should coerce values from a #replace call' do
        subject.coerce_value String, Coercable

        instance[:foo] = :bar
        instance.replace(:foo => "bar", :bar => "bax")
        instance[:foo].should be_coerced
        instance[:bar].should be_coerced
      end

      it 'should not coerce superclasses' do
        klass = Class.new(String)
        subject.coerce_value klass, Coercable

        instance[:foo] = "bar"
        instance[:foo].should_not be_kind_of(Coercable)
        instance[:foo] = klass.new
        instance[:foo].should be_kind_of(Coercable)
      end
    end
  end

  after(:each) do
    Object.send(:remove_const, :ExampleCoercableHash)
  end
end