File: enum_spec.rb

package info (click to toggle)
ruby-sequel 5.97.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,188 kB
  • sloc: ruby: 123,115; makefile: 3
file content (187 lines) | stat: -rw-r--r-- 6,120 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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
require_relative "spec_helper"

describe "Sequel enum plugin" do
  before do
    @Album = Class.new(Sequel::Model(Sequel.mock[:albums]))
    @Album.columns :id, :status_id
    @Album.plugin :enum
    @Album.enum :status_id, :good=>3, :bad=>5
    @album = @Album.load(:status_id=>3)
  end

  it "should give temporary name to name model-specific module" do
    c = Sequel::Model(:items)
    c.plugin :enum
    c.enum :status_id, :good=>3, :bad=>5
    c.ancestors[1].name.must_equal "Sequel::_Model(:items)::@enum_methods"
  end if RUBY_VERSION >= '3.3'

  it "should add enum_value! and enum_value? methods for setting/checking the enum values" do
    @album.good?.must_equal true
    @album.bad?.must_equal false

    @album.bad!.must_be_nil
    @album.good?.must_equal false
    @album.bad?.must_equal true

    @album.good!.must_be_nil
    @album.good?.must_equal true
    @album.bad?.must_equal false
  end

  it "should have column method convert to enum value if possible" do
    @album.status_id.must_equal :good
    @album.bad!
    @album.status_id.must_equal :bad
    @album[:status_id] = 3
    @album.status_id.must_equal :good
  end

  it "should have the column method pass non-enum values through" do
    @album[:status_id] = 4
    @album.status_id.must_equal 4
  end

  it "should have column= handle enum values" do
    @album.status_id = :bad
    @album[:status_id].must_equal 5
    @album.good?.must_equal false
    @album.bad?.must_equal true

    @album.status_id = :good
    @album[:status_id].must_equal 3
    @album.good?.must_equal true
    @album.bad?.must_equal false
  end

  it "should have column= handle non-enum values" do
    @album.status_id = 5
    @album[:status_id].must_equal 5
    @album.good?.must_equal false
    @album.bad?.must_equal true
  end

  it "should setup dataset methods for each value" do
    ds = @Album.where(:id=>1)
    ds.good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 3))"
    ds.not_good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 3))"
    ds.bad.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 5))"
    ds.not_bad.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 5))"
  end
end

describe "Sequel enum plugin" do
  before do
    @Album = Class.new(Sequel::Model(Sequel.mock[:albums]))
    @Album.columns :id, :status_id
    @Album.plugin :enum
    @album = @Album.load(:status_id=>3)
  end

  it "should allow overriding methods in class and calling super" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :override_accessors=>false
    bad = nil
    @Album.class_eval do
      define_method(:bad?) do
        bad.nil? ? super() : bad
      end
    end

    @album.bad?.must_equal false
    bad = true
    @album.bad?.must_equal true
    bad = false
    @album.bad?.must_equal false
    bad = nil
    @album.bad!
    @album.bad?.must_equal true
  end

  it "should not override accessor methods for each value if :override_accessors option is false" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :override_accessors=>false
    @album.status_id.must_equal 3
    @album.status_id = :bad
    @album.status_id.must_equal :bad
    @album.bad!
    @album.status_id.must_equal 5
  end

  it "should not setup dataset methods for each value if :dataset_methods option is false" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :dataset_methods=>false
    ds = @Album.where(:id=>1)
    ds.wont_respond_to(:good)
    ds.wont_respond_to(:not_good)
    ds.wont_respond_to(:bad)
    ds.wont_respond_to(:not_bad)
  end

  it "should handle :prefix=>true option" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :prefix=>true

    @album.status_id_good?.must_equal true
    @album.status_id_bad!
    @album.status_id_bad?.must_equal true

    ds = @Album.where(:id=>1)
    ds.status_id_good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 3))"
    ds.status_id_not_good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 3))"
  end

  it "should handle :prefix=>string option" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :prefix=>'status'

    @album.status_good?.must_equal true
    @album.status_bad!
    @album.status_bad?.must_equal true

    ds = @Album.where(:id=>1)
    ds.status_good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 3))"
    ds.status_not_good.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 3))"
  end

  it "should handle :suffix=>true option" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :suffix=>true

    @album.good_status_id?.must_equal true
    @album.bad_status_id!
    @album.bad_status_id?.must_equal true

    ds = @Album.where(:id=>1)
    ds.good_status_id.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 3))"
    ds.not_good_status_id.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 3))"
  end

  it "should handle :suffix=>true option" do
    @Album.enum :status_id, {:good=>3, :bad=>5}, :suffix=>'status'

    @album.good_status?.must_equal true
    @album.bad_status!
    @album.bad_status?.must_equal true

    ds = @Album.where(:id=>1)
    ds.good_status.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id = 3))"
    ds.not_good_status.sql.must_equal "SELECT * FROM albums WHERE ((id = 1) AND (status_id != 3))"
  end

  it "should support multiple emums per class" do 
    @Album.enum :id, {:odd=>1, :even=>2}
    @Album.enum :status_id, {:good=>3, :bad=>5}
    @album = @Album.load(:id=>1, :status_id=>3)
    @album.odd?.must_equal true
    @album.even?.must_equal false
    @album.good?.must_equal true
    @album.bad?.must_equal false
  end

  it "raises Error for column that isn't a symbol" do
    proc{@Album.enum 'status_id', :good=>3, :bad=>5}.must_raise Sequel::Error
  end

  it "raises Error for non-hash values" do
    proc{@Album.enum :status_id, [:good, :bad]}.must_raise Sequel::Error
  end

  it "raises Error for values hash with non-symbol keys" do
    proc{@Album.enum :status_id, 'good'=>3, :bad=>5}.must_raise Sequel::Error
  end
end