typesafe_enum 0.1.3 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6dca44bfdc19636b439aea18d0a5bbb195150fcf
4
- data.tar.gz: ae8b31bcd16f05536e1bb2ffd9346fbd395465e7
3
+ metadata.gz: 5b0677a4297fd6de2704786aa65b16b10a3a89de
4
+ data.tar.gz: ae7122293d92ba5417e684ae9746fa798f9d6f47
5
5
  SHA512:
6
- metadata.gz: d8c40232f8fa100c7de8f49d830e20bce082126d951a69a4e53294a89134647c6cf2d0244034efe47bb88348a70352d4b3c061c5ff6c6a0d19f296e4a4de154d
7
- data.tar.gz: 24543c5f5b1b72dbf554662275d47c918ef3807e723648aebe34552b217b52e82a91f9a20f35d9a7569ace4279dcdebefb00df0b136099a2f802fb66ac6c9812
6
+ metadata.gz: 44ec4665cb20ee046932e909d91738273c1591c06f9dd103693a2f38fb9082b160c0ab1e4941e6dc5901a5a3a70bcb4b7205f5a732d9f17d166b47e00e254d48
7
+ data.tar.gz: 069df54602db3f496024d3d99d1a8d400f204ba4bbf4d6f1cc8e1d3e0b717ae6036279208a8e3eeb577b49eb1f9a5b85ee0e6978e8cb5e826fcbcf8576196574
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.1.4
2
+
3
+ - Exact duplicate instances (e.g. due to multiple `requires`) are now ignored with a warning,
4
+ instead of causing a `NameError`. Duplicate keys with different values, and duplicate values
5
+ with different keys, still raise a `NameError`.
6
+ - `NameErrors` due to invalid keys or values no longer cause the enum class to be undefined.
7
+ However, the invalid instances will still not be registered and no constants created for them.
8
+
1
9
  ## 0.1.3
2
10
 
3
11
  - Fixed issue where invalid classes weren't properly removed after duplicate name declarations,
data/README.md CHANGED
@@ -69,6 +69,76 @@ Scale::KILO.value
69
69
  # => 1000
70
70
  ```
71
71
 
72
+ Declaring two instances with the same key will produce an error:
73
+
74
+ ```ruby
75
+ class Suit < TypesafeEnum::Base
76
+ new :CLUBS
77
+ new :DIAMONDS
78
+ new :HEARTS
79
+ new :SPADES
80
+ new :SPADES, '♠'
81
+ end
82
+ ```
83
+
84
+ ```
85
+ typesafe_enum/lib/typesafe_enum/base.rb:88:in `valid_key_and_value': Suit::SPADES already exists (NameError)
86
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:98:in `register'
87
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:138:in `block in initialize'
88
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:137:in `class_exec'
89
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:137:in `initialize'
90
+ from ./scratch.rb:11:in `new'
91
+ from ./scratch.rb:11:in `<class:Suit>'
92
+ from ./scratch.rb:6:in `<main>'
93
+ ```
94
+
95
+ Likewise two instances with the same value but different keys:
96
+
97
+ ```ruby
98
+ class Tarot < TypesafeEnum::Base
99
+ new :CUPS, 'Cups'
100
+ new :COINS, 'Coins'
101
+ new :WANDS, 'Wands'
102
+ new :SWORDS, 'Swords'
103
+ new :STAVES, 'Wands'
104
+ end
105
+ ```
106
+
107
+ ```
108
+ /typesafe_enum/lib/typesafe_enum/base.rb:92:in `valid_key_and_value': A Tarot instance with value 'Wands' already exists (NameError)
109
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:98:in `register'
110
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:138:in `block in initialize'
111
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:137:in `class_exec'
112
+ from /Users/dmoles/Work/Stash/typesafe_enum/lib/typesafe_enum/base.rb:137:in `initialize'
113
+ from ./scratch.rb:11:in `new'
114
+ from ./scratch.rb:11:in `<class:Tarot>'
115
+ from ./scratch.rb:6:in `<main>'
116
+ ```
117
+
118
+ However, declaring an identical key/value pair will be ignored with a warning, to avoid unnecessary errors
119
+ when, e.g., a declaration file is accidentally `required` twice.
120
+
121
+ ```ruby
122
+ class Tarot < TypesafeEnum::Base
123
+ new :CUPS, 'Cups'
124
+ new :COINS, 'Coins'
125
+ new :WANDS, 'Wands'
126
+ new :SWORDS, 'Swords'
127
+ end
128
+
129
+ class Tarot < TypesafeEnum::Base
130
+ new :CUPS, 'Cups'
131
+ new :COINS, 'Coins'
132
+ new :WANDS, 'Wands'
133
+ new :SWORDS, 'Swords'
134
+ end
135
+
136
+ # => ignoring redeclaration of Tarot::CUPS with value: Cups
137
+ # => ignoring redeclaration of Tarot::COINS with value: Coins
138
+ # => ignoring redeclaration of Tarot::WANDS with value: Wands
139
+ # => ignoring redeclaration of Tarot::SWORDS with value: Swords
140
+ ```
141
+
72
142
  ## Ordering
73
143
 
74
144
  Enum instances have an ordinal value corresponding to their declaration
@@ -59,51 +59,40 @@ module TypesafeEnum
59
59
 
60
60
  private
61
61
 
62
- attr_accessor :by_key
63
- attr_accessor :by_value
64
- attr_accessor :as_array
65
-
66
- def parent
67
- parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
68
- parent_name ? Object.const_get(parent_name) : Object
69
- end
70
-
71
- def undefine_class
72
- class_value = name.split('::').last || ''
73
- parent.send(:remove_const, class_value)
62
+ def by_key
63
+ @by_key ||= {}
74
64
  end
75
65
 
76
- def register(instance)
77
- ensure_registries
78
- key, value = valid_key_and_value(instance)
79
-
80
- by_key[key] = instance
81
- by_value[value] = instance
82
- as_array << instance
83
- const_set(key.to_s, instance)
66
+ def by_value
67
+ @by_value ||= {}
84
68
  end
85
69
 
86
- def ensure_registries
87
- self.by_key ||= {}
88
- self.by_value ||= {}
89
- self.as_array ||= []
70
+ def as_array
71
+ @as_array ||= []
90
72
  end
91
73
 
92
74
  def valid_key_and_value(instance)
93
75
  key = instance.key
94
76
  value = instance.value
95
-
96
- begin
97
- fail NameError, "#{name}::#{key} already exists" if find_by_key(key)
77
+ if (found = find_by_key(key))
78
+ fail NameError, "#{name}::#{key} already exists" unless value == found.value
79
+ warn("ignoring redeclaration of #{name}::#{key} with value: #{value}")
80
+ nil
81
+ else
98
82
  fail NameError, "A #{name} instance with value '#{value}' already exists" if find_by_value(value)
99
- rescue NameError => e
100
- undefine_class
101
- raise e
83
+ [key, value]
102
84
  end
103
-
104
- [key, value]
105
85
  end
106
86
 
87
+ def register(instance)
88
+ key, value = valid_key_and_value(instance)
89
+ return unless key && value
90
+
91
+ const_set(key.to_s, instance)
92
+ by_key[key] = instance
93
+ by_value[value] = instance
94
+ as_array << instance
95
+ end
107
96
  end
108
97
 
109
98
  # The symbol key for the enum instance
@@ -3,7 +3,7 @@ module TypesafeEnum
3
3
  NAME = 'typesafe_enum'
4
4
 
5
5
  # The version of this gem
6
- VERSION = '0.1.3'
6
+ VERSION = '0.1.4'
7
7
 
8
8
  # The copyright notice for this gem
9
9
  COPYRIGHT = 'Copyright (c) 2015 The Regents of the University of California'
@@ -1,27 +1,27 @@
1
1
  # coding: UTF-8
2
2
  require 'spec_helper'
3
3
 
4
- class ::Suit < TypesafeEnum::Base
4
+ class Suit < TypesafeEnum::Base
5
5
  new :CLUBS
6
6
  new :DIAMONDS
7
7
  new :HEARTS
8
8
  new :SPADES
9
9
  end
10
10
 
11
- class ::Tarot < TypesafeEnum::Base
11
+ class Tarot < TypesafeEnum::Base
12
12
  new :CUPS, 'Cups'
13
13
  new :COINS, 'Coins'
14
14
  new :WANDS, 'Wands'
15
15
  new :SWORDS, 'Swords'
16
16
  end
17
17
 
18
- class ::RGBColor < TypesafeEnum::Base
18
+ class RGBColor < TypesafeEnum::Base
19
19
  new :RED, :red
20
20
  new :GREEN, :green
21
21
  new :BLUE, :blue
22
22
  end
23
23
 
24
- class ::Scale < TypesafeEnum::Base
24
+ class Scale < TypesafeEnum::Base
25
25
  new :DECA, 10
26
26
  new :HECTO, 100
27
27
  new :KILO, 1_000
@@ -39,40 +39,64 @@ module TypesafeEnum
39
39
 
40
40
  it 'insists symbols be symbols' do
41
41
  expect do
42
- class ::Cheat < Base
42
+ class ::StringKeys < Base
43
43
  new 'spades', 'spades'
44
44
  end
45
45
  end.to raise_error(TypeError)
46
+ expect(::StringKeys.to_a).to be_empty
46
47
  end
47
48
 
48
49
  it 'insists symbols be uppercase' do
49
50
  expect do
50
- class ::Cheat < Base
51
+ class ::LowerCaseKeys < Base
51
52
  new :spades, 'spades'
52
53
  end
53
54
  end.to raise_error(NameError)
55
+ expect(::LowerCaseKeys.to_a).to be_empty
54
56
  end
55
57
 
56
- it 'disallows duplicate symbols' do
58
+ it 'disallows duplicate symbols with different values' do
57
59
  expect do
58
- class ::Cheat < Base
60
+ class ::DuplicateSymbols < Base
59
61
  new :SPADES, 'spades'
60
62
  new :SPADES, 'more spades'
61
63
  end
62
64
  end.to raise_error(NameError)
63
-
64
- expect { ::Cheat.class }.to raise_error(NameError)
65
+ expect(::DuplicateSymbols.to_a).to eq([::DuplicateSymbols::SPADES])
66
+ expect(::DuplicateSymbols::SPADES.value).to eq('spades')
67
+ expect(::DuplicateSymbols.find_by_value('more spades')).to be_nil
65
68
  end
66
69
 
67
- it 'disallows duplicate values' do
70
+ it 'disallows duplicate values with different symbols' do
68
71
  expect do
69
- class ::Cheat < Base
72
+ class ::DuplicateValues < Base
70
73
  new :SPADES, 'spades'
71
74
  new :ALSO_SPADES, 'spades'
72
75
  end
73
76
  end.to raise_error(NameError)
77
+ expect(::DuplicateValues.to_a).to eq([::DuplicateValues::SPADES])
78
+ expect(::DuplicateValues::SPADES.value).to eq('spades')
79
+ expect(::DuplicateValues.find_by_key(:ALSO_SPADES)).to be_nil
80
+ end
74
81
 
75
- expect { ::Cheat.class }.to raise_error(NameError)
82
+ it 'disallows nil keys' do
83
+ expect do
84
+ class ::NilKeys < Base
85
+ new nil, 'nil'
86
+ end
87
+ end.to raise_error(TypeError)
88
+ expect(::NilKeys.to_a).to be_empty
89
+ end
90
+
91
+ it 'allows, but ignores redeclaration of identical instances' do
92
+ class ::IdenticalInstances < Base
93
+ new :SPADES, 'spades'
94
+ end
95
+ expect(::IdenticalInstances).to receive(:warn).with('ignoring redeclaration of IdenticalInstances::SPADES with value: spades')
96
+ class ::IdenticalInstances < Base
97
+ new :SPADES, 'spades'
98
+ end
99
+ expect(::IdenticalInstances.to_a).to eq([::IdenticalInstances::SPADES])
76
100
  end
77
101
 
78
102
  it 'defaults the value to a lower-cased version of the symbol' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typesafe_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Moles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-17 00:00:00.000000000 Z
11
+ date: 2015-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler