File: concord_spec.rb

package info (click to toggle)
ruby-unparser 0.6.13-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 936 kB
  • sloc: ruby: 7,691; sh: 6; makefile: 4
file content (143 lines) | stat: -rw-r--r-- 4,029 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
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
RSpec.describe Unparser::Concord do
  let(:class_under_test) do
    Class.new do
      include Unparser::Concord.new(:foo, :bar)
    end
  end

  let(:instance_a) { class_under_test.new(foo, bar) }
  let(:instance_b) { class_under_test.new(foo, bar) }
  let(:instance_c) { class_under_test.new(foo, double('Baz')) }

  let(:foo) { double('Foo') }
  let(:bar) { double('Bar') }

  context 'initializer' do
    it 'creates a private #initialize method' do
      mod = Module.new
      expect { mod.send(:include, Unparser::Concord.new) }
        .to change { mod.private_method_defined?(:initialize) }
        .from(false).to(true)
    end

    it 'does not cause warnings' do
      begin
        original = $stderr
        $stderr = StringIO.new
        Class.new do
          include Unparser::Concord.new
        end
        expect($stderr.tap(&:rewind).read).to eql('')
      ensure
        $stderr = original
      end
    end

    it 'creates an initializer that asserts the number of arguments' do
      expect { class_under_test.new(1) }
        .to raise_error(ArgumentError, 'wrong number of arguments (1 for 2)')
    end

    it 'creates an initializer that allows 2 arguments' do
      expect { class_under_test.new(1, 2) }.to_not raise_error
    end

    it 'creates an initializer that is callable via super' do
      class_under_test.class_eval do
        attr_reader :baz
        public :foo
        public :bar

        def initialize(foo, bar)
          @baz = foo + bar
          super(foo, bar)
        end
      end

      instance = class_under_test.new(1, 2)
      expect(instance.foo).to eql(1)
      expect(instance.bar).to eql(2)
      expect(instance.baz).to eql(3)
    end

    it 'creates an initializer that is callable via zsuper' do
      class_under_test.class_eval do
        attr_reader :baz
        public :foo
        public :bar

        def initialize(foo, bar)
          @baz = foo + bar
          super
        end
      end

      instance = class_under_test.new(1, 2)
      expect(instance.foo).to eql(1)
      expect(instance.bar).to eql(2)
      expect(instance.baz).to eql(3)
    end

    it 'creates an initializer that sets the instance variables' do
      instance = class_under_test.new(1, 2)
      expect(instance.instance_variable_get(:@foo)).to be(1)
      expect(instance.instance_variable_get(:@bar)).to be(2)
    end
  end

  context 'with no objects to compose' do
    it 'assigns no ivars' do
      instance = Class.new { include Unparser::Concord.new }.new
      expect(instance.instance_variables).to be_empty
    end
  end

  context 'visibility' do
    it 'should set attribute readers to protected' do
      protected_methods = class_under_test.protected_instance_methods
      expect(protected_methods).to match_array([:foo, :bar])
    end
  end

  context 'attribute behavior' do
    subject { instance_a }

    specify { expect(subject.send(:foo)).to be(foo) }
    specify { expect(subject.send(:bar)).to be(bar) }
  end

  context 'equalization behavior' do
    specify 'composed objects are equalized on attributes' do
      expect(instance_a).to eql(instance_b)
      expect(instance_a.hash).to eql(instance_b.hash)
      expect(instance_a).to eql(instance_b)
      expect(instance_a).to_not be(instance_c)
      expect(instance_a).to_not eql(instance_c)
    end
  end

  context 'when composing too many objects' do
    specify 'it raises an error' do
      expect do
        Unparser::Concord.new(:a, :b, :c, :d)
      end.to raise_error(RuntimeError, 'Composition of more than 3 objects is not allowed')
      expect do
        Unparser::Concord.new(:a, :b, :c)
      end.to_not raise_error
    end
  end

  context Unparser::Concord::Public do
    let(:class_under_test) do
      Class.new do
        include Unparser::Concord::Public.new(:foo, :bar)
      end
    end

    it 'should create public attr readers' do
      object = class_under_test.new(:foo, :bar)
      expect(object.foo).to eql(:foo)
      expect(object.bar).to eql(:bar)
    end
  end
end