summaryrefslogtreecommitdiff
path: root/spec/ruby/core/module/attr_spec.rb
blob: 7128c610fe19f93d0972419ecd87d88fba9a505f (plain)
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
152
153
154
155
156
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Module#attr" do
  before :each do
    $VERBOSE, @verbose = false, $VERBOSE
  end

  after :each do
    $VERBOSE = @verbose
  end

  it "creates a getter for the given attribute name" do
    c = Class.new do
      attr :attr
      attr "attr3"

      def initialize
        @attr, @attr2, @attr3 = "test", "test2", "test3"
      end
    end

    o = c.new

    %w{attr attr3}.each do |a|
      o.respond_to?(a).should == true
      o.respond_to?("#{a}=").should == false
    end

    o.attr.should == "test"
    o.attr3.should == "test3"
    o.send(:attr).should == "test"
    o.send(:attr3).should == "test3"
  end

  it "creates a setter for the given attribute name if writable is true" do
    c = Class.new do
      attr :attr, true
      attr "attr3", true

      def initialize
        @attr, @attr2, @attr3 = "test", "test2", "test3"
      end
    end

    o = c.new

    %w{attr attr3}.each do |a|
      o.respond_to?(a).should == true
      o.respond_to?("#{a}=").should == true
    end

    o.attr = "test updated"
    o.attr3 = "test3 updated"
  end

  it "creates a getter and setter for the given attribute name if called with and without writeable is true" do
    c = Class.new do
      attr :attr, true
      attr :attr

      attr "attr3", true
      attr "attr3"

      def initialize
        @attr, @attr2, @attr3 = "test", "test2", "test3"
      end
    end

    o = c.new

    %w{attr attr3}.each do |a|
      o.respond_to?(a).should == true
      o.respond_to?("#{a}=").should == true
    end

    o.attr.should == "test"
    o.attr = "test updated"
    o.attr.should == "test updated"

    o.attr3.should == "test3"
    o.attr3 = "test3 updated"
    o.attr3.should == "test3 updated"
  end

  it "applies current visibility to methods created" do
    c = Class.new do
      protected
      attr :foo, true
    end

    lambda { c.new.foo }.should raise_error(NoMethodError)
    lambda { c.new.foo=1 }.should raise_error(NoMethodError)
  end

  it "creates a getter but no setter for all given attribute names" do
    c = Class.new do
      attr :attr, "attr2", "attr3"

      def initialize
        @attr, @attr2, @attr3 = "test", "test2", "test3"
      end
    end

    o = c.new

    %w{attr attr2 attr3}.each do |a|
      o.respond_to?(a).should == true
      o.respond_to?("#{a}=").should == false
    end

    o.attr.should == "test"
    o.attr2.should == "test2"
    o.attr3.should == "test3"
  end

  it "applies current visibility to methods created" do
    c = Class.new do
      protected
      attr :foo, :bar
    end

    lambda { c.new.foo }.should raise_error(NoMethodError)
    lambda { c.new.bar }.should raise_error(NoMethodError)
  end

  it "converts non string/symbol/fixnum names to strings using to_str" do
    (o = mock('test')).should_receive(:to_str).any_number_of_times.and_return("test")
    Class.new { attr o }.new.respond_to?("test").should == true
  end

  it "raises a TypeError when the given names can't be converted to strings using to_str" do
    o = mock('o')
    lambda { Class.new { attr o } }.should raise_error(TypeError)
    (o = mock('123')).should_receive(:to_str).and_return(123)
    lambda { Class.new { attr o } }.should raise_error(TypeError)
  end

  it "with a boolean argument emits a warning when $VERBOSE is true" do
    lambda {
      $VERBOSE = true
      Class.new { attr :foo, true }
    }.should complain(/boolean argument is obsoleted/)
  end

  ruby_version_is ''...'2.5' do
    it "is a private method" do
      Module.should have_private_instance_method(:attr, false)
    end
  end
  ruby_version_is '2.5' do
    it "is a public method" do
      Module.should have_public_instance_method(:attr, false)
    end
  end
end