constants 0.1.0
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/MIT-LICENSE +21 -0
- data/README +125 -0
- data/Rakefile +171 -0
- data/lib/constants.rb +5 -0
- data/lib/constants/constant.rb +94 -0
- data/lib/constants/constant_library.rb +299 -0
- data/lib/constants/libraries/element.rb +214 -0
- data/lib/constants/libraries/particle.rb +83 -0
- data/lib/constants/libraries/physical.rb +297 -0
- data/lib/constants/library.rb +133 -0
- data/lib/constants/stash.rb +94 -0
- data/lib/constants/uncertainty.rb +8 -0
- data/test/constants/constant_library_test.rb +304 -0
- data/test/constants/constant_test.rb +77 -0
- data/test/constants/libraries/element_test.rb +207 -0
- data/test/constants/libraries/particle_test.rb +43 -0
- data/test/constants/libraries/physical_test.rb +32 -0
- data/test/constants/library_test.rb +125 -0
- data/test/constants/stash_test.rb +99 -0
- data/test/constants_test_helper.rb +51 -0
- data/test/constants_test_suite.rb +3 -0
- data/test/readme_doc_test.rb +58 -0
- metadata +84 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'constants/constant_library'
|
2
|
+
|
3
|
+
module Constants
|
4
|
+
|
5
|
+
# Library adds methods for convenient indexing and access of constants
|
6
|
+
# in a module. Usually Library is included after the constants have
|
7
|
+
# been defined.
|
8
|
+
#
|
9
|
+
# module Color
|
10
|
+
# RED = 'red'
|
11
|
+
# GREEN = 'green'
|
12
|
+
# BLUE = 'blue'
|
13
|
+
# GREY = 'grey'
|
14
|
+
#
|
15
|
+
# include Constants::Library
|
16
|
+
# library.index_by('name') {|c| c }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Now the Color constants can be accessed through the indicies hash
|
20
|
+
# or through [], which searches all indicies for the first match.
|
21
|
+
#
|
22
|
+
# Color.index('name')
|
23
|
+
# # => {
|
24
|
+
# # 'red' => Color::RED,
|
25
|
+
# # 'blue' => Color::BLUE,
|
26
|
+
# # 'green' => Color::GREEN,
|
27
|
+
# # 'grey' => Color::GREY}
|
28
|
+
#
|
29
|
+
# Color['red'] # => Color::RED
|
30
|
+
#
|
31
|
+
# Indexing is simplified for attributes. Notice that multiple
|
32
|
+
# values matching the same key are stashed into one group:
|
33
|
+
#
|
34
|
+
# Color.library.index_by_attribute 'length'
|
35
|
+
# Color.index('length')
|
36
|
+
# # => {
|
37
|
+
# # 3 => Color::RED,
|
38
|
+
# # 4 => [Color::BLUE, Color::GREY],
|
39
|
+
# # 5 => Color::GREEN}
|
40
|
+
#
|
41
|
+
# Color[4] # => [Color::BLUE, Color::GREY]
|
42
|
+
#
|
43
|
+
# Constants may also be assembled into ordered collections, which
|
44
|
+
# may or may not contain all the constants.
|
45
|
+
#
|
46
|
+
# Color.library.collect('gstar') {|c| c =~ /^g/ ? c : nil }
|
47
|
+
# Color.collection('gstar') # => [Color::GREEN, Color::GREY]
|
48
|
+
#
|
49
|
+
# Color.library.collect_attribute 'length'
|
50
|
+
# Color.collection('length') # => [3,5,4,4]
|
51
|
+
#
|
52
|
+
# New constants (even 'constants' that are not declared in the module) may be
|
53
|
+
# added manually, or by resetting the library. All indexes and collections
|
54
|
+
# are updated automatically.
|
55
|
+
#
|
56
|
+
# Color.library.add('yellow')
|
57
|
+
# Color.index('length')
|
58
|
+
# # => {
|
59
|
+
# # 3 => Color::RED,
|
60
|
+
# # 4 => [Color::BLUE, Color::GREY],
|
61
|
+
# # 5 => Color::GREEN,
|
62
|
+
# # 6 => 'yellow'}
|
63
|
+
#
|
64
|
+
# module Color
|
65
|
+
# ORANGE = 'orange'
|
66
|
+
# reset_library
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# Color.index('length')
|
70
|
+
# # => {
|
71
|
+
# # 3 => Color::RED,
|
72
|
+
# # 4 => [Color::BLUE, Color::GREY],
|
73
|
+
# # 5 => Color::GREEN,
|
74
|
+
# # 6 => Color::ORANGE}
|
75
|
+
#
|
76
|
+
# Notice 'yellow' was removed when the library was reset. The yellow example
|
77
|
+
# illustrates the fact that library only tracks the values of constants, not
|
78
|
+
# the constants themselves. If, for some reason, you dynamically reset a constant
|
79
|
+
# value then the change will not be reflected in the library until the library
|
80
|
+
# is reset.
|
81
|
+
#
|
82
|
+
# ==== Ruby 1.8
|
83
|
+
# Ruby doesn't track of the order of constant declaration until Ruby 1.9... this
|
84
|
+
# may cause collected values to be re-ordered in an unpredictable fashion. For
|
85
|
+
# instance in the Color example:
|
86
|
+
#
|
87
|
+
# Color[4] # may equal [Color::BLUE, Color::GREY] or [Color::GREY, Color::BLUE].
|
88
|
+
#
|
89
|
+
# In any case, the constants will be ordered as in Color.constants.
|
90
|
+
#
|
91
|
+
# == Performance Considerations
|
92
|
+
# ConstantsLibrary makes access of constants easier, but at the expense of
|
93
|
+
# performance. Naturally the constant itself is the highest-performing
|
94
|
+
# way of accessing the constant value.
|
95
|
+
#
|
96
|
+
module Library
|
97
|
+
|
98
|
+
# Accesses the module constant library.
|
99
|
+
attr_accessor :library
|
100
|
+
|
101
|
+
def self.included(mod)
|
102
|
+
mod.extend self
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.extended(mod)
|
106
|
+
mod.library = ConstantLibrary.new
|
107
|
+
mod.reset_library
|
108
|
+
end
|
109
|
+
|
110
|
+
# Alias for library[identifier] (see Constants::ConstantLibrary#[])
|
111
|
+
def [](identifier)
|
112
|
+
library[identifier]
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns the index by the specified name.
|
116
|
+
def index(name)
|
117
|
+
library.indicies[name]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the collection by the specified name.
|
121
|
+
def collection(name)
|
122
|
+
library.collections[name]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Resets the library using constants from self. A block
|
126
|
+
# can be provided to filter constants, see
|
127
|
+
# Constants::ConstantLibrary#add_constants_from
|
128
|
+
def reset_library(&block)
|
129
|
+
library.clear
|
130
|
+
library.add_constants_from(self, &block)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Constants
|
2
|
+
|
3
|
+
# Stash provides methods to store values by a non-unique key. The
|
4
|
+
# initial stored value is directly stored by the key, subsequent
|
5
|
+
# values are grouped into a StashArray.
|
6
|
+
#
|
7
|
+
# class StashingHash < Hash
|
8
|
+
# include Constants::Stash
|
9
|
+
#
|
10
|
+
# def initialize(*args)
|
11
|
+
# super(*args)
|
12
|
+
# @nil_value = nil
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# s = StashingHash.new
|
17
|
+
#
|
18
|
+
# s.stash('key', 'one')
|
19
|
+
# s['key'] # => 'one'
|
20
|
+
#
|
21
|
+
# s.stash('key', 'two')
|
22
|
+
# s['key'] # => ['one' , 'two']
|
23
|
+
# s['key'].class # => Constants::Stash::StashArray
|
24
|
+
#
|
25
|
+
# The stash method requires some kind of flag to differentiate when a new
|
26
|
+
# value should be stored and when the existing value and new value
|
27
|
+
# should be converted into a StashArray. If the existing value as
|
28
|
+
# determined by [] is equal to the nil_value, then the new value is
|
29
|
+
# stored through []=.
|
30
|
+
#
|
31
|
+
# s = StashingHash.new
|
32
|
+
# s['key'] # => nil
|
33
|
+
# s.nil_value # => nil
|
34
|
+
#
|
35
|
+
# s.stash('key', 1)
|
36
|
+
# s['key'] # => 1
|
37
|
+
#
|
38
|
+
# s.stash('key', 2)
|
39
|
+
# s['key'] # => [1, 2]
|
40
|
+
#
|
41
|
+
# In the first case, the existing value for 'key' is equals the nil_value,
|
42
|
+
# so the new value is set. In the second case, the existing value for 'key'
|
43
|
+
# does not equal the nil_value; stash takes this as a signal that a
|
44
|
+
# non-unique key was specified and collects the values into a StashArray.
|
45
|
+
# As a consequence, neither the nil_value nor StashArrays may be stashed.
|
46
|
+
#
|
47
|
+
# s.stash('key', nil) # ! ArgumentError
|
48
|
+
#
|
49
|
+
module Stash
|
50
|
+
|
51
|
+
# A subclass of Array with no new functionality, necessary
|
52
|
+
# to differentiate between regular arrays and collections
|
53
|
+
# in a Stash.
|
54
|
+
class StashArray < Array
|
55
|
+
end
|
56
|
+
|
57
|
+
# The value considered to be nil in store (used to
|
58
|
+
# signal when a new value can be stashed for a given
|
59
|
+
# key; if store[key] == nil_value, then a new value
|
60
|
+
# can be stashed).
|
61
|
+
attr_accessor :nil_value
|
62
|
+
|
63
|
+
# Assigns the value to key in store. If the store already has a
|
64
|
+
# non-nil_value at key (as determined by []), then the existing
|
65
|
+
# and new value will be concatenated into a StashArray. All
|
66
|
+
# subsequent values are added to the StashArray. stash uses
|
67
|
+
# the []= method to set values.
|
68
|
+
#
|
69
|
+
# nil_value and StashArray values cannot be stashed; either raises
|
70
|
+
# an error.
|
71
|
+
def stash(key, value)
|
72
|
+
case value
|
73
|
+
when nil_value
|
74
|
+
raise ArgumentError.new("the nil_value for self cannot be stashed")
|
75
|
+
when StashArray
|
76
|
+
raise ArgumentError.new("StashArrays cannot be stashed")
|
77
|
+
end
|
78
|
+
|
79
|
+
current_value = self[key]
|
80
|
+
|
81
|
+
case current_value
|
82
|
+
when nil_value
|
83
|
+
self[key] = value
|
84
|
+
when StashArray
|
85
|
+
current_value << value
|
86
|
+
else
|
87
|
+
self[key] = StashArray.new([current_value, value])
|
88
|
+
end
|
89
|
+
|
90
|
+
self
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../constants_test_helper.rb')
|
2
|
+
require 'constants/constant_library'
|
3
|
+
|
4
|
+
class ConstantLibraryTest < Test::Unit::TestCase
|
5
|
+
include Constants
|
6
|
+
|
7
|
+
attr_accessor :lib
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@lib = ConstantLibrary.new 'one', 'two', :one
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# documentation test
|
15
|
+
#
|
16
|
+
|
17
|
+
def test_documentation
|
18
|
+
lib = ConstantLibrary.new('one', 'two', :three)
|
19
|
+
lib.index_by('upcase') {|value| value.to_s.upcase }
|
20
|
+
assert_equal({'ONE' => 'one', 'TWO' => 'two', 'THREE' => :three}, lib.indicies['upcase'])
|
21
|
+
|
22
|
+
lib.collect("string") {|value| value.to_s }
|
23
|
+
assert_equal(['one', 'two', 'three'], lib.collections['string'])
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# initialize test
|
28
|
+
#
|
29
|
+
|
30
|
+
def test_initialize
|
31
|
+
lib = ConstantLibrary.new
|
32
|
+
|
33
|
+
assert_equal([], lib.values)
|
34
|
+
assert_equal({}, lib.indicies)
|
35
|
+
assert_equal({}, lib.collections)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_initialize_with_values
|
39
|
+
assert_equal(['one', 'two', :one], lib.values)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_initialize_removes_duplicate_values
|
43
|
+
lib = ConstantLibrary.new 'one', 'two', 'one'
|
44
|
+
assert_equal(['one', 'two'], lib.values)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# index_by test
|
49
|
+
#
|
50
|
+
|
51
|
+
def test_index_by_documentation
|
52
|
+
lib = ConstantLibrary.new('one', 'two', :one)
|
53
|
+
lib.index_by("string") {|value| value.to_s }
|
54
|
+
assert_equal({
|
55
|
+
'one' => ['one', :one],
|
56
|
+
'two' => 'two'},
|
57
|
+
lib.indicies['string'])
|
58
|
+
|
59
|
+
lib = ConstantLibrary.new(1,2,nil)
|
60
|
+
assert_raise(ArgumentError) { lib.index_by("error", false, nil) {|value| value } }
|
61
|
+
|
62
|
+
|
63
|
+
obj = Object.new
|
64
|
+
index = lib.index_by("ok", false, obj) {|value| value }
|
65
|
+
assert_equal 1, index[1]
|
66
|
+
assert_equal nil, index[nil]
|
67
|
+
|
68
|
+
assert_equal obj, index['non-existant']
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_index_by_creates_a_new_index_for_the_specified_inputs
|
72
|
+
block = lambda {|v| }
|
73
|
+
lib.index_by("name", "nil", "nil_value", &block)
|
74
|
+
|
75
|
+
assert lib.indicies.has_key?('name')
|
76
|
+
index = lib.indicies['name']
|
77
|
+
|
78
|
+
assert_equal ConstantLibrary::Index, index.class
|
79
|
+
assert_equal "nil", index.exclusion_value
|
80
|
+
assert_equal "nil_value", index.nil_value
|
81
|
+
assert_equal block, index.block
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_index_by_uses_name_as_indicies_key
|
85
|
+
lib.index_by(:sym) {|v| v.to_s }
|
86
|
+
assert lib.indicies.has_key?(:sym)
|
87
|
+
assert !lib.indicies.has_key?('sym')
|
88
|
+
|
89
|
+
lib.index_by('str') {|v| v.to_s }
|
90
|
+
assert !lib.indicies.has_key?(:str)
|
91
|
+
assert lib.indicies.has_key?('str')
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_index_stashes_values_by_block
|
95
|
+
lib.index_by("string") {|v| v.to_s }
|
96
|
+
assert_equal({'one' => ['one', :one], 'two' => 'two'}, lib.indicies["string"])
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_index_stashes_key_value_pairs_if_returned
|
100
|
+
lib.index_by("pairs") {|v| [v, v.to_s.upcase] }
|
101
|
+
assert_equal({'one' => 'ONE', :one => 'ONE', 'two' => 'TWO'}, lib.indicies["pairs"])
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_index_excludes_values_which_return_the_exclusion_value
|
105
|
+
lib.index_by("exclusion", nil) do |v|
|
106
|
+
v.kind_of?(String) ? nil : [v, v.to_s.upcase]
|
107
|
+
end
|
108
|
+
|
109
|
+
assert_equal({:one => 'ONE'}, lib.indicies["exclusion"])
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_index_by_default_exclusion_value_is_nil
|
113
|
+
lib.index_by("name") {|v|}
|
114
|
+
assert_equal nil, lib.indicies['name'].exclusion_value
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_index_by_raises_error_for_no_block_given
|
118
|
+
assert_raise(ArgumentError) { lib.index_by('name') }
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_index_by_returns_index
|
122
|
+
result = lib.index_by("name") {|v|}
|
123
|
+
assert_equal(lib.indicies['name'], result)
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# index_by_attribute test
|
128
|
+
#
|
129
|
+
|
130
|
+
def test_index_by_attribute_stashes_values_by_method_value
|
131
|
+
lib.index_by_attribute("to_s")
|
132
|
+
assert_equal({'one' => ['one', :one], 'two' => 'two'}, lib.indicies["to_s"])
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_index_by_attribute_returns_index
|
136
|
+
result = lib.index_by_attribute("object_id")
|
137
|
+
assert_equal(lib.indicies['object_id'], result)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_index_by_attribute_raises_error_if_objects_dont_respond_to_attribute
|
141
|
+
assert_raise(NoMethodError) { lib.index_by_attribute("non_existant") }
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# collect test
|
146
|
+
#
|
147
|
+
|
148
|
+
def test_collect_documentation
|
149
|
+
lib = ConstantLibrary.new('one', 'two', :three)
|
150
|
+
lib.collect("string") {|value| value.to_s }
|
151
|
+
assert_equal ['one', 'two', 'three'], lib.collections['string']
|
152
|
+
|
153
|
+
lib.collect("length") {|value| [value, value.to_s.length] }
|
154
|
+
assert_equal [nil, nil, nil, ['one', 'two'], nil, :three], lib.collections['length']
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_collect_creates_a_new_collection_for_the_specified_inputs
|
158
|
+
block = lambda {|v| }
|
159
|
+
lib.collect("name", &block)
|
160
|
+
|
161
|
+
assert lib.collections.has_key?('name')
|
162
|
+
collection = lib.collections['name']
|
163
|
+
|
164
|
+
assert_equal ConstantLibrary::Collection, collection.class
|
165
|
+
assert_equal nil, collection.nil_value
|
166
|
+
assert_equal block, collection.block
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_collect_uses_name_as_collections_key
|
170
|
+
lib.collect(:sym) {|v| v.to_s }
|
171
|
+
assert lib.collections.has_key?(:sym)
|
172
|
+
assert !lib.collections.has_key?('sym')
|
173
|
+
|
174
|
+
lib.collect('str') {|v| v.to_s }
|
175
|
+
assert !lib.collections.has_key?(:str)
|
176
|
+
assert lib.collections.has_key?('str')
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_collection_stashes_block_value
|
180
|
+
lib.collect("string") {|v| v.to_s }
|
181
|
+
assert_equal(['one', 'two', 'one'], lib.collections["string"])
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_collection_stashes_values_index_pairs_if_returned
|
185
|
+
map = {'one' => 2, 'two' => 0}
|
186
|
+
|
187
|
+
lib.collect("pairs") {|v| [v, map[v.to_s]] }
|
188
|
+
assert_equal(['two', nil, ['one', :one]], lib.collections["pairs"])
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_collection_excludes_values_which_return_nil
|
192
|
+
lib.collect("exclusion") do |v|
|
193
|
+
v.kind_of?(String) ? nil : v
|
194
|
+
end
|
195
|
+
assert_equal([:one], lib.collections["exclusion"])
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_collect_raises_error_for_no_block_given
|
199
|
+
assert_raise(ArgumentError) { lib.collect('name') }
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_collect_returns_collection
|
203
|
+
result = lib.collect("name") {|v|}
|
204
|
+
assert_equal(lib.collections['name'], result)
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# collect_attribute test
|
209
|
+
#
|
210
|
+
|
211
|
+
def test_collect_attribute_collects_attribute_values
|
212
|
+
lib.collect_attribute("to_s")
|
213
|
+
assert_equal(['one', 'two', 'one'], lib.collections["to_s"])
|
214
|
+
end
|
215
|
+
|
216
|
+
#
|
217
|
+
# [] test
|
218
|
+
#
|
219
|
+
|
220
|
+
def test_get_searches_all_indicies_match
|
221
|
+
lib.index_by("string") {|v| v.to_s }
|
222
|
+
lib.index_by("strlen") {|v| v.to_s.length }
|
223
|
+
|
224
|
+
assert_equal ['one', :one], lib['one']
|
225
|
+
assert_equal ['one', 'two', :one], lib[3]
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_get_returns_nil_if_no_matches_are_found
|
229
|
+
assert_equal nil, lib['three']
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_get_returns_first_match_only
|
233
|
+
lib.index_by("str1") {|v| v.to_s }
|
234
|
+
lib.index_by("str2") {|v| [v.to_s, v.to_s.upcase] }
|
235
|
+
|
236
|
+
assert lib.indicies['str1'].has_key?('one')
|
237
|
+
assert lib.indicies['str2'].has_key?('one')
|
238
|
+
|
239
|
+
assert_not_equal lib.indicies['str1']['one'], lib.indicies['str2']['one']
|
240
|
+
assert_equal lib.indicies['str1']['one'], lib['one']
|
241
|
+
end
|
242
|
+
|
243
|
+
#
|
244
|
+
# clear test
|
245
|
+
#
|
246
|
+
|
247
|
+
def test_clear_clears_all_values_from_lib_indicies_and_collections
|
248
|
+
lib.index_by("str") {|v| v.to_s }
|
249
|
+
lib.collect("str") {|v| v.to_s }
|
250
|
+
|
251
|
+
assert !lib.values.empty?
|
252
|
+
assert !lib.indicies['str'].empty?
|
253
|
+
assert !lib.collections['str'].empty?
|
254
|
+
|
255
|
+
lib.clear
|
256
|
+
|
257
|
+
assert lib.values.empty?
|
258
|
+
assert lib.indicies['str'].empty?
|
259
|
+
assert lib.collections['str'].empty?
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_clear_only_removes_indicies_and_collections_if_specified
|
263
|
+
lib.index_by("str") {|v| v.to_s }
|
264
|
+
lib.collect("str") {|v| v.to_s }
|
265
|
+
|
266
|
+
lib.clear
|
267
|
+
|
268
|
+
assert !lib.indicies.empty?
|
269
|
+
assert !lib.collections.empty?
|
270
|
+
|
271
|
+
lib.clear(true)
|
272
|
+
|
273
|
+
assert lib.indicies.empty?
|
274
|
+
assert lib.collections.empty?
|
275
|
+
end
|
276
|
+
|
277
|
+
#
|
278
|
+
# add test
|
279
|
+
#
|
280
|
+
|
281
|
+
def test_add_adds_new_values
|
282
|
+
lib.add(:two, 'three')
|
283
|
+
assert_equal ['one', 'two', :one, :two, 'three'], lib.values
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_add_does_not_add_duplicate_values
|
287
|
+
lib.add(:one, :two, 'two', 'three')
|
288
|
+
assert_equal ['one', 'two', :one, :two, 'three'], lib.values
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_add_returns_newly_added_values
|
292
|
+
assert_equal [:two, 'three'], lib.add(:one, :two, 'two', 'three')
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_add_incorporates_new_values_into_existing_indicies_and_collections
|
296
|
+
lib.index_by("str") {|v| v.to_s }
|
297
|
+
lib.collect("length") {|v| [v, v.to_s.length] }
|
298
|
+
|
299
|
+
lib.add(:one, :two, 'two', 'three')
|
300
|
+
assert_equal({'one' => ['one', :one], 'two' => ['two', :two], 'three' => 'three'}, lib.indicies['str'])
|
301
|
+
assert_equal([nil,nil,nil,['one', 'two', :one, :two], nil, 'three'], lib.collections['length'])
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|