renum 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/renum.rb +0 -1
- data/lib/renum/enumerated_value.rb +26 -16
- data/lib/renum/enumerated_value_type_factory.rb +6 -5
- data/renum.gemspec +9 -7
- data/spec/renum_spec.rb +38 -18
- data/spec/spec_helper.rb +1 -3
- metadata +21 -7
data/Rakefile
CHANGED
@@ -15,8 +15,8 @@ begin
|
|
15
15
|
s.homepage = "http://github.com/duelinmarkers/renum"
|
16
16
|
s.description = "provides a readable but terse enum facility for Ruby"
|
17
17
|
s.authors = ["John Hume"]
|
18
|
-
s.rubyforge_project = "renum"
|
19
18
|
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
20
|
rescue LoadError
|
21
|
-
puts "Jeweler or a dependency not available. To install: sudo gem install
|
21
|
+
puts "Jeweler or a dependency not available. To install: sudo gem install jeweler"
|
22
22
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3.1
|
data/lib/renum.rb
CHANGED
@@ -3,45 +3,55 @@ require 'forwardable'
|
|
3
3
|
module Renum
|
4
4
|
|
5
5
|
# This is the superclass of all enumeration classes.
|
6
|
-
# An enumeration class is Enumerable over its values and
|
7
|
-
# to the values array.
|
6
|
+
# An enumeration class is Enumerable over its values and exposes them by numeric index via [].
|
8
7
|
# Values are also comparable, sorting into the order in which they're declared.
|
9
8
|
class EnumeratedValue
|
10
|
-
|
9
|
+
|
11
10
|
class << self
|
12
11
|
include Enumerable
|
13
12
|
extend Forwardable
|
14
|
-
|
13
|
+
|
15
14
|
def_delegators :values, :each, :[]
|
16
|
-
|
15
|
+
|
17
16
|
# Returns an array of values in the order they're declared.
|
18
17
|
def values
|
19
18
|
@values ||= []
|
20
19
|
end
|
21
|
-
|
20
|
+
|
21
|
+
def with_name name
|
22
|
+
values_by_name[name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def values_by_name
|
26
|
+
@values_by_name ||= values.inject({}) do |memo, value|
|
27
|
+
memo[value.name] = value
|
28
|
+
memo
|
29
|
+
end.freeze
|
30
|
+
end
|
31
|
+
|
22
32
|
end
|
23
|
-
|
33
|
+
|
24
34
|
include Comparable
|
25
|
-
|
26
|
-
attr_reader :index
|
27
|
-
|
35
|
+
|
36
|
+
attr_reader :name, :index
|
37
|
+
|
28
38
|
def initialize name
|
29
|
-
@name = name.to_s
|
39
|
+
@name = name.to_s.freeze
|
30
40
|
@index = self.class.values.size
|
31
41
|
self.class.values << self
|
32
42
|
end
|
33
|
-
|
34
|
-
# Returns the fully qualified constant referring to this value.
|
43
|
+
|
44
|
+
# Returns the fully qualified name of the constant referring to this value.
|
35
45
|
# Don't override this if you're using Renum with the constantize_attribute
|
36
46
|
# plugin, which relies on this behavior.
|
37
47
|
def to_s
|
38
48
|
"#{self.class}::#{name}"
|
39
49
|
end
|
40
|
-
|
50
|
+
|
41
51
|
# Sorts enumerated values into the order in which they're declared.
|
42
52
|
def <=> other
|
43
53
|
index <=> other.index
|
44
54
|
end
|
45
|
-
|
55
|
+
|
46
56
|
end
|
47
|
-
end
|
57
|
+
end
|
@@ -7,13 +7,13 @@ module Renum
|
|
7
7
|
klass = create_class nest, type_name
|
8
8
|
create_values klass, values, &block
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def create_class nest, type_name
|
12
12
|
klass = Class.new EnumeratedValue
|
13
13
|
nest.const_set(type_name, klass)
|
14
14
|
klass
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def create_values klass, values, &block
|
18
18
|
setup_for_definition_in_block(klass) if values == :defined_in_block
|
19
19
|
klass.class_eval &block if block_given?
|
@@ -30,8 +30,9 @@ module Renum
|
|
30
30
|
klass.const_set(name, klass.new(name))
|
31
31
|
end
|
32
32
|
end
|
33
|
+
klass.values.freeze
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
def setup_for_definition_in_block klass
|
36
37
|
klass.class_eval do
|
37
38
|
def self.block_defined_values
|
@@ -43,7 +44,7 @@ module Renum
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
46
|
-
|
47
|
+
|
47
48
|
def teardown_from_definition_in_block klass
|
48
49
|
class << klass
|
49
50
|
remove_method :block_defined_values
|
@@ -52,4 +53,4 @@ module Renum
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
55
|
-
end
|
56
|
+
end
|
data/renum.gemspec
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{renum}
|
5
|
-
s.version = "1.
|
8
|
+
s.version = "1.3.1"
|
6
9
|
|
7
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["John Hume"]
|
9
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-08-17}
|
10
13
|
s.description = %q{provides a readable but terse enum facility for Ruby}
|
11
14
|
s.email = %q{duelin.markers@gmail.com}
|
12
15
|
s.extra_rdoc_files = [
|
@@ -23,12 +26,10 @@ Gem::Specification.new do |s|
|
|
23
26
|
"spec/renum_spec.rb",
|
24
27
|
"spec/spec_helper.rb"
|
25
28
|
]
|
26
|
-
s.has_rdoc = true
|
27
29
|
s.homepage = %q{http://github.com/duelinmarkers/renum}
|
28
30
|
s.rdoc_options = ["--charset=UTF-8"]
|
29
31
|
s.require_paths = ["lib"]
|
30
|
-
s.
|
31
|
-
s.rubygems_version = %q{1.3.1}
|
32
|
+
s.rubygems_version = %q{1.3.7}
|
32
33
|
s.summary = %q{provides a readable but terse enum facility for Ruby}
|
33
34
|
s.test_files = [
|
34
35
|
"spec/renum_spec.rb",
|
@@ -37,11 +38,12 @@ Gem::Specification.new do |s|
|
|
37
38
|
|
38
39
|
if s.respond_to? :specification_version then
|
39
40
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
40
|
-
s.specification_version =
|
41
|
+
s.specification_version = 3
|
41
42
|
|
42
|
-
if Gem::Version.new(Gem::
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
44
|
else
|
44
45
|
end
|
45
46
|
else
|
46
47
|
end
|
47
48
|
end
|
49
|
+
|
data/spec/renum_spec.rb
CHANGED
@@ -3,37 +3,43 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
enum :Status, [ :NOT_STARTED, :IN_PROGRESS, :COMPLETE ]
|
4
4
|
|
5
5
|
describe "basic enum" do
|
6
|
-
|
6
|
+
|
7
7
|
it "creates a class for the value type" do
|
8
8
|
Status.should be_an_instance_of(Class)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it "makes each value an instance of the value type" do
|
12
12
|
Status::NOT_STARTED.should be_an_instance_of(Status)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it "exposes array of values" do
|
16
16
|
Status.values.should == [Status::NOT_STARTED, Status::IN_PROGRESS, Status::COMPLETE]
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "enumerates over values" do
|
20
20
|
Status.map {|s| s.name}.should == %w[NOT_STARTED IN_PROGRESS COMPLETE]
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "indexes values" do
|
24
24
|
Status[2].should == Status::COMPLETE
|
25
25
|
Color[0].should == Color::RED
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "provides index lookup on values" do
|
29
29
|
Status::IN_PROGRESS.index.should == 1
|
30
30
|
Color::GREEN.index.should == 1
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
|
+
it "provides name lookup on values" do
|
34
|
+
Status.with_name('IN_PROGRESS').should == Status::IN_PROGRESS
|
35
|
+
Color.with_name('GREEN').should == Color::GREEN
|
36
|
+
Color.with_name('IN_PROGRESS').should be_nil
|
37
|
+
end
|
38
|
+
|
33
39
|
it "provides a reasonable to_s for values" do
|
34
40
|
Status::NOT_STARTED.to_s.should == "Status::NOT_STARTED"
|
35
41
|
end
|
36
|
-
|
42
|
+
|
37
43
|
it "makes values comparable" do
|
38
44
|
Color::RED.should < Color::GREEN
|
39
45
|
end
|
@@ -84,19 +90,19 @@ describe "enum with no values array and values declared in the block" do
|
|
84
90
|
it "provides another way to declare values where an init method can take extra params" do
|
85
91
|
Size::Small.description.should == "Really really tiny"
|
86
92
|
end
|
87
|
-
|
93
|
+
|
88
94
|
it "works the same as the basic form with respect to ordering" do
|
89
95
|
Size.values.should == [Size::Small, Size::Medium, Size::Large, Size::Unknown]
|
90
96
|
end
|
91
|
-
|
97
|
+
|
92
98
|
it "responds as expected to arbitrary method calls, in spite of using method_missing for value definition" do
|
93
99
|
lambda { Size.ExtraLarge() }.should raise_error(NoMethodError)
|
94
100
|
end
|
95
|
-
|
101
|
+
|
96
102
|
it "supports there being no extra data and no init() method defined, if you don't need them" do
|
97
103
|
HairColor::BLONDE.name.should == "BLONDE"
|
98
104
|
end
|
99
|
-
|
105
|
+
|
100
106
|
it "calls the init method even if no arguments are provided" do
|
101
107
|
Size::Unknown.description.should == "NO DESCRIPTION GIVEN"
|
102
108
|
end
|
@@ -104,23 +110,23 @@ end
|
|
104
110
|
|
105
111
|
enum :Rating do
|
106
112
|
NotRated()
|
107
|
-
|
113
|
+
|
108
114
|
ThumbsDown do
|
109
115
|
def description
|
110
116
|
"real real bad"
|
111
117
|
end
|
112
118
|
end
|
113
|
-
|
119
|
+
|
114
120
|
ThumbsUp do
|
115
121
|
def description
|
116
122
|
"so so good"
|
117
123
|
end
|
118
|
-
|
124
|
+
|
119
125
|
def thumbs_up_only_method
|
120
126
|
"this method is only defined on ThumbsUp"
|
121
127
|
end
|
122
128
|
end
|
123
|
-
|
129
|
+
|
124
130
|
def description
|
125
131
|
raise NotImplementedError
|
126
132
|
end
|
@@ -131,11 +137,11 @@ describe "an enum with instance-specific method definitions" do
|
|
131
137
|
Rating::ThumbsDown.description.should == "real real bad"
|
132
138
|
Rating::ThumbsUp.description.should == "so so good"
|
133
139
|
end
|
134
|
-
|
140
|
+
|
135
141
|
it "uses the implementation given at the top level if no alternate definition is given for an instance" do
|
136
142
|
lambda { Rating::NotRated.description }.should raise_error(NotImplementedError)
|
137
143
|
end
|
138
|
-
|
144
|
+
|
139
145
|
it "allows definition of a method on just one instance" do
|
140
146
|
Rating::ThumbsUp.thumbs_up_only_method.should == "this method is only defined on ThumbsUp"
|
141
147
|
lambda { Rating::NotRated.thumbs_up_only_method }.should raise_error(NoMethodError)
|
@@ -149,3 +155,17 @@ describe "<=> comparison issue that at one time was causing segfaults on MRI" do
|
|
149
155
|
Color::RED.should < Color::BLUE
|
150
156
|
end
|
151
157
|
end
|
158
|
+
|
159
|
+
describe "prevention of subtle and annoying bugs" do
|
160
|
+
it "prevents you modifying the values array" do
|
161
|
+
lambda { Color.values << 'some crazy value' }.should raise_error(TypeError, /can't modify frozen/)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "prevents you modifying the name hash" do
|
165
|
+
lambda { Color.values_by_name['MAGENTA'] = 'some crazy value' }.should raise_error(TypeError, /can't modify frozen/)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "prevents you modifying the name of a value" do
|
169
|
+
lambda { Color::RED.name << 'dish-Brown' }.should raise_error(TypeError, /can't modify frozen/)
|
170
|
+
end
|
171
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: renum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 3
|
9
|
+
- 1
|
10
|
+
version: 1.3.1
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- John Hume
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-08-17 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -33,29 +39,37 @@ files:
|
|
33
39
|
- spec/spec_helper.rb
|
34
40
|
has_rdoc: true
|
35
41
|
homepage: http://github.com/duelinmarkers/renum
|
42
|
+
licenses: []
|
43
|
+
|
36
44
|
post_install_message:
|
37
45
|
rdoc_options:
|
38
46
|
- --charset=UTF-8
|
39
47
|
require_paths:
|
40
48
|
- lib
|
41
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
42
51
|
requirements:
|
43
52
|
- - ">="
|
44
53
|
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
45
57
|
version: "0"
|
46
|
-
version:
|
47
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
48
60
|
requirements:
|
49
61
|
- - ">="
|
50
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
51
66
|
version: "0"
|
52
|
-
version:
|
53
67
|
requirements: []
|
54
68
|
|
55
|
-
rubyforge_project:
|
56
|
-
rubygems_version: 1.3.
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.7
|
57
71
|
signing_key:
|
58
|
-
specification_version:
|
72
|
+
specification_version: 3
|
59
73
|
summary: provides a readable but terse enum facility for Ruby
|
60
74
|
test_files:
|
61
75
|
- spec/renum_spec.rb
|