renum 1.2.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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 technicalpickles-jeweler -s http://gems.github.com"
21
+ puts "Jeweler or a dependency not available. To install: sudo gem install jeweler"
22
22
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.1
@@ -1,4 +1,3 @@
1
- $:.unshift File.dirname(__FILE__)
2
1
  require 'renum/enumerated_value_type_factory'
3
2
 
4
3
  # Requiring 'renum' mixes the Renum module into both the main Object and
@@ -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 also delegates []
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
- attr_reader :name
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
@@ -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.2.0"
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{2009-09-01}
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.rubyforge_project = %q{renum}
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 = 2
41
+ s.specification_version = 3
41
42
 
42
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
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
+
@@ -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
@@ -8,7 +8,5 @@ end
8
8
 
9
9
  if ENV['USE_GEM']
10
10
  require 'rubygems'
11
- require 'renum'
12
- else
13
- require File.expand_path(File.dirname(__FILE__) + '/../lib/renum')
14
11
  end
12
+ require 'renum'
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renum
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
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: 2009-09-01 00:00:00 -04:00
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: renum
56
- rubygems_version: 1.3.1
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.7
57
71
  signing_key:
58
- specification_version: 2
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