File: put_spec.rb

package info (click to toggle)
ruby-immutable-ruby 0.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,852 kB
  • sloc: ruby: 16,556; makefile: 4
file content (111 lines) | stat: -rw-r--r-- 3,294 bytes parent folder | download
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
require 'spec_helper'

describe Immutable::Hash do
  describe '#[]=' do
    let(:hash) { H['A' => 'aye', 'B' => 'bee', 'C' => 'see'] }

    it 'raises error pointing to #put' do
      expect { hash[:A] = 'aye' }
        .to raise_error(NoMethodError, /Immutable::Hash.*`put'/)
    end
  end

  describe '#put' do
    let(:hash) { H['A' => 'aye', 'B' => 'bee', 'C' => 'see'] }

    context 'with a block' do
      it 'passes the value to the block' do
        hash.put('A') { |value| value.should == 'aye' }
      end

      it 'replaces the value with the result of the block' do
        result = hash.put('A') { |value| 'FLIBBLE' }
        result.get('A').should == 'FLIBBLE'
      end

      it 'supports to_proc methods' do
        result = hash.put('A', &:upcase)
        result.get('A').should == 'AYE'
      end

      context 'if there is no existing association' do
        it 'passes nil to the block' do
          hash.put('D') { |value| value.should be_nil }
        end

        it 'stores the result of the block as the new value' do
          result = hash.put('D') { |value| 'FLIBBLE' }
          result.get('D').should == 'FLIBBLE'
        end
      end
    end

    context 'with a unique key' do
      let(:result) { hash.put('D', 'dee') }

      it 'preserves the original' do
        result
        hash.should eql(H['A' => 'aye', 'B' => 'bee', 'C' => 'see'])
      end

      it 'returns a copy with the superset of key/value pairs' do
        result.should eql(H['A' => 'aye', 'B' => 'bee', 'C' => 'see', 'D' => 'dee'])
      end
    end

    context 'with a duplicate key' do
      let(:result) { hash.put('C', 'sea') }

      it 'preserves the original' do
        result
        hash.should eql(H['A' => 'aye', 'B' => 'bee', 'C' => 'see'])
      end

      it 'returns a copy with the superset of key/value pairs' do
        result.should eql(H['A' => 'aye', 'B' => 'bee', 'C' => 'sea'])
      end
    end

    context 'with duplicate key and identical value' do
      let(:hash) { H['X' => 1, 'Y' => 2] }
      let(:result) { hash.put('X', 1) }

      it 'returns the original hash unmodified' do
        result.should be(hash)
      end

      context 'with big hash (force nested tries)' do
        let(:keys) { (0..99).map(&:to_s) }
        let(:values) { (100..199).to_a }
        let(:hash) { H[keys.zip(values)] }

        it 'returns the original hash unmodified for all changes' do
          keys.each_with_index do |key, index|
            result = hash.put(key, values[index])
            result.should be(hash)
          end
        end
      end
    end

    context 'with unequal keys which hash to the same value' do
      let(:hash) { H[DeterministicHash.new('a', 1) => 'aye'] }

      it 'stores and can retrieve both' do
        result = hash.put(DeterministicHash.new('b', 1), 'bee')
        result.get(DeterministicHash.new('a', 1)).should eql('aye')
        result.get(DeterministicHash.new('b', 1)).should eql('bee')
      end
    end

    context 'when a String is inserted as key and then mutated' do
      it 'is not affected' do
        string = 'a string!'
        hash = H.empty.put(string, 'a value!')
        string.upcase!
        hash['a string!'].should == 'a value!'
        hash['A STRING!'].should be_nil
      end
    end
  end
end