necromancer 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +40 -9
- data/lib/necromancer.rb +4 -2
- data/lib/necromancer/configuration.rb +46 -0
- data/lib/necromancer/context.rb +32 -3
- data/lib/necromancer/conversions.rb +38 -8
- data/lib/necromancer/converter.rb +14 -0
- data/lib/necromancer/converters/array.rb +65 -9
- data/lib/necromancer/converters/boolean.rb +4 -4
- data/lib/necromancer/converters/date_time.rb +2 -2
- data/lib/necromancer/converters/numeric.rb +3 -3
- data/lib/necromancer/converters/range.rb +1 -1
- data/lib/necromancer/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/config_spec.rb +32 -0
- data/spec/unit/configuration/new_spec.rb +30 -0
- data/spec/unit/conversions/register_spec.rb +0 -1
- data/spec/unit/convert_spec.rb +24 -16
- data/spec/unit/converters/array/array_to_boolean_spec.rb +22 -0
- data/spec/unit/converters/array/array_to_numeric_spec.rb +1 -1
- data/spec/unit/converters/array/array_to_set_spec.rb +18 -0
- data/spec/unit/converters/array/object_to_array_spec.rb +21 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ab93f1c0f77de5f9d0643fee2136e1a18448509
|
4
|
+
data.tar.gz: 44e07300b65361d813dfa3e4d36381ef44cb0d8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9049c66ec36a5f139de3ffd32d14232eaf95118437c9323fec32cd34054722ea0106c7e1b59d7d284fb53ab52d14a1c3dc723cad07431f541f591200a84f167e
|
7
|
+
data.tar.gz: 9471c9273853b50e269e9aa96efe7f3ae87d99236a7b222d8eb95fd03371a15485d7070fe903eba95949e524b68fec516d0746e05a9b1094c588d6029b52d9c2
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -23,6 +23,7 @@ Conversion between Ruby core types frequently comes up in projects but is solved
|
|
23
23
|
* Ability to specify own converters
|
24
24
|
* Ability to compose conversions out of simpler ones
|
25
25
|
* Support conversion of custom defined types
|
26
|
+
* Ability to specify strict conversion mode
|
26
27
|
|
27
28
|
## Installation
|
28
29
|
|
@@ -48,6 +49,7 @@ Or install it yourself as:
|
|
48
49
|
* [2.2 from](#22-from)
|
49
50
|
* [2.3 to](#23-to)
|
50
51
|
* [2.4 can?](#24-can)
|
52
|
+
* [2.5 configure](#25-configure)
|
51
53
|
* [3. Converters](#3-converters)
|
52
54
|
* [3.1 Array](#31-array)
|
53
55
|
* [3.2 Boolean](#32-boolean)
|
@@ -163,7 +165,7 @@ The target parameters are:
|
|
163
165
|
|
164
166
|
### 2.4 can?
|
165
167
|
|
166
|
-
To verify that a given conversion can be handled by **
|
168
|
+
To verify that a given conversion can be handled by **Necromancer** call `can?` with the `source` and `target` of the desired conversion.
|
167
169
|
|
168
170
|
```ruby
|
169
171
|
converter = Necromancer.new
|
@@ -171,31 +173,56 @@ converter.can?(:string, :integer) # => true
|
|
171
173
|
converter.can?(:unknown, :integer) # => false
|
172
174
|
```
|
173
175
|
|
176
|
+
### 2.5 configure
|
177
|
+
|
178
|
+
You may set global configuration options on **Necromancer** instance by passing a block like so:
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
Necromancer.new do |config|
|
182
|
+
config.strict true
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
or calling `configure` method:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
converter = Necromancer.new
|
190
|
+
converter.configure do |config|
|
191
|
+
config.copy false
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
Available configuration options are:
|
196
|
+
|
197
|
+
* strict - ensures correct types for conversion, by default `false`
|
198
|
+
* copy - ensures only copy is modified, by default `true`
|
199
|
+
|
174
200
|
## 3. Converters
|
175
201
|
|
176
202
|
**Necromancer** flexibility means you can register your own converters or use the already defined converters for such types as 'Array', 'Boolean', 'Hash', 'Numeric', 'Range'.
|
177
203
|
|
178
204
|
### 3.1 Array
|
179
205
|
|
180
|
-
The **Necromancer** allows you to transform
|
206
|
+
The **Necromancer** allows you to transform arbitrary object into array:
|
181
207
|
|
182
208
|
```ruby
|
183
|
-
converter.
|
209
|
+
converter.convert(nil).to(:array) # => []
|
210
|
+
converter.convert({x: 1}).to(:array) # => [[:x, 1]]
|
184
211
|
```
|
185
212
|
|
186
|
-
|
213
|
+
In addition, **Necromancer** excels at converting `,` or `-` delimited string into an array object:
|
187
214
|
|
188
215
|
```ruby
|
189
|
-
converter.
|
216
|
+
converter.convert('a, b, c').to(:array) # => ['a', 'b', 'c']
|
190
217
|
```
|
191
218
|
|
192
|
-
|
219
|
+
If the string is a list of `-` or `,` separated numbers, they will be converted to their respective numeric types:
|
193
220
|
|
194
221
|
```ruby
|
195
|
-
converter.convert(
|
222
|
+
converter.convert('1 - 2 - 3').to(:array) # => [1, 2, 3]
|
196
223
|
```
|
197
224
|
|
198
|
-
|
225
|
+
You can also convert array containing string objects to array containing numeric values:
|
199
226
|
|
200
227
|
```ruby
|
201
228
|
converter.convert(['1', '2.3', '3.0']).to(:numeric)
|
@@ -287,18 +314,22 @@ converter.convert('a-z').to(:range) # => 'a'..'z'
|
|
287
314
|
|
288
315
|
### 3.6 Custom
|
289
316
|
|
317
|
+
In case where provided conversions do not match your needs you can create your own and `register` with **Necromancer** by using an `Object` or a `Proc`.
|
318
|
+
|
290
319
|
#### 3.6.1 Using an Object
|
291
320
|
|
292
321
|
Firstly, you need to create a converter that at minimum requires to specify `call` method that will be invoked during conversion:
|
293
322
|
|
294
323
|
```ruby
|
295
324
|
UpcaseConverter = Struct.new(:source, :target) do
|
296
|
-
def call(value, options)
|
325
|
+
def call(value, options = {})
|
297
326
|
value.upcase
|
298
327
|
end
|
299
328
|
end
|
300
329
|
```
|
301
330
|
|
331
|
+
Inside the `UpcaseConverter` you have access to global configuration options by directly calling `config` method.
|
332
|
+
|
302
333
|
Then you need to specify what type conversions this converter will support. For example, `UpcaseConverter` will allow a string object to be converted to a new string object with content upper cased. This can be done:
|
303
334
|
|
304
335
|
```ruby
|
data/lib/necromancer.rb
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'date'
|
5
|
+
require 'set'
|
5
6
|
|
6
7
|
require 'necromancer/conversions'
|
8
|
+
require 'necromancer/configuration'
|
7
9
|
require 'necromancer/context'
|
8
10
|
require 'necromancer/converter'
|
9
11
|
require 'necromancer/null_converter'
|
@@ -30,8 +32,8 @@ module Necromancer
|
|
30
32
|
# @return [Context]
|
31
33
|
#
|
32
34
|
# @api private
|
33
|
-
def new
|
34
|
-
Context.new
|
35
|
+
def new(&block)
|
36
|
+
Context.new(&block)
|
35
37
|
end
|
36
38
|
|
37
39
|
module_function :new
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Necromancer
|
4
|
+
# A global configuration for converters.
|
5
|
+
#
|
6
|
+
# Used internally by {Necromancer::Context}.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Configuration
|
10
|
+
# Configure global strict mode
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
attr_writer :strict
|
14
|
+
|
15
|
+
# Configure global copy mode
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
attr_writer :copy
|
19
|
+
|
20
|
+
# Create a configuration
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
def initialize
|
24
|
+
@strict = false
|
25
|
+
@copy = true
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set or get strict mode
|
29
|
+
#
|
30
|
+
# @return [Boolean]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def strict(value = (not_set = true))
|
34
|
+
not_set ? @strict : (self.strict = value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set or get copy mode
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def copy(value = (not_set = true))
|
43
|
+
not_set ? @copy : (self.copy = value)
|
44
|
+
end
|
45
|
+
end # Configuration
|
46
|
+
end # Necromancer
|
data/lib/necromancer/context.rb
CHANGED
@@ -9,14 +9,43 @@ module Necromancer
|
|
9
9
|
|
10
10
|
def_delegators :"@conversions", :register
|
11
11
|
|
12
|
-
# Create a context
|
12
|
+
# Create a context.
|
13
13
|
#
|
14
14
|
# @api private
|
15
|
-
def initialize
|
16
|
-
|
15
|
+
def initialize(&block)
|
16
|
+
block.call(configuration) if block_given?
|
17
|
+
@conversions = Conversions.new(configuration)
|
17
18
|
@conversions.load
|
18
19
|
end
|
19
20
|
|
21
|
+
# The configuration object.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# converter = Necromancer.new
|
25
|
+
# converter.configuration.strict = true
|
26
|
+
#
|
27
|
+
# @return [Necromancer::Configuration]
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
def configuration
|
31
|
+
@configuration ||= Configuration.new
|
32
|
+
end
|
33
|
+
|
34
|
+
# Yields global configuration to a block.
|
35
|
+
#
|
36
|
+
# @yield [Necromancer::Configuration]
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# converter = Necromancer.new
|
40
|
+
# converter.configure do |config|
|
41
|
+
# config.strict true
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
def configure
|
46
|
+
yield configuration if block_given?
|
47
|
+
end
|
48
|
+
|
20
49
|
# Converts the object
|
21
50
|
# @param [Object] value
|
22
51
|
# any object to be converted
|
@@ -8,19 +8,14 @@ module Necromancer
|
|
8
8
|
class Conversions
|
9
9
|
DELIMITER = '->'.freeze
|
10
10
|
|
11
|
-
# TODO: allow to register converters as just simple proc objects
|
12
|
-
#
|
13
|
-
# register "integer->string", { |value| value.to_s }
|
14
|
-
# if block present then take it as converter class
|
15
|
-
#
|
16
|
-
|
17
11
|
# Creates a new conversions map
|
18
12
|
#
|
19
13
|
# @example
|
20
14
|
# conversion = Necromancer::Conversions.new
|
21
15
|
#
|
22
16
|
# @api public
|
23
|
-
def initialize
|
17
|
+
def initialize(configuration = Configuration.new)
|
18
|
+
@configuration = configuration
|
24
19
|
@converter_map = {}
|
25
20
|
end
|
26
21
|
|
@@ -35,9 +30,30 @@ module Necromancer
|
|
35
30
|
RangeConverters.load(self)
|
36
31
|
end
|
37
32
|
|
33
|
+
# Retrieve converter for source and target
|
34
|
+
#
|
35
|
+
# @param [Object] source
|
36
|
+
# the source of conversion
|
37
|
+
#
|
38
|
+
# @param [Object] target
|
39
|
+
# the target of conversion
|
40
|
+
#
|
41
|
+
# @return [Converter]
|
42
|
+
# the converter for the source and target
|
43
|
+
#
|
44
|
+
# @api public
|
38
45
|
def [](source, target)
|
39
46
|
key = "#{source}#{DELIMITER}#{target}"
|
40
|
-
converter_map[key] ||
|
47
|
+
converter_map[key] ||
|
48
|
+
converter_map["object->#{target}"] ||
|
49
|
+
fail_no_type_conversion_available(key)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Fail with conversion error
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def fail_no_type_conversion_available(key)
|
56
|
+
fail NoTypeConversionAvailableError, "Conversion '#{key}' unavailable."
|
41
57
|
end
|
42
58
|
|
43
59
|
# @example with simple object
|
@@ -50,6 +66,7 @@ module Necromancer
|
|
50
66
|
def register(converter = nil, &block)
|
51
67
|
converter ||= Converter.create(&block)
|
52
68
|
key = generate_key(converter)
|
69
|
+
converter = add_config(converter, @configuration)
|
53
70
|
return false if converter_map.key?(key)
|
54
71
|
converter_map[key] = converter
|
55
72
|
true
|
@@ -61,6 +78,7 @@ module Necromancer
|
|
61
78
|
|
62
79
|
protected
|
63
80
|
|
81
|
+
# @api private
|
64
82
|
def generate_key(converter)
|
65
83
|
parts = []
|
66
84
|
parts << (converter.source ? converter.source.to_s : 'none')
|
@@ -68,8 +86,20 @@ module Necromancer
|
|
68
86
|
parts.join(DELIMITER)
|
69
87
|
end
|
70
88
|
|
89
|
+
# Inject config into converter
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
def add_config(converter, config)
|
93
|
+
converter.instance_exec(:"@config") do |var|
|
94
|
+
instance_variable_set(var, config)
|
95
|
+
end
|
96
|
+
converter
|
97
|
+
end
|
98
|
+
|
71
99
|
# Map of type and conversion
|
72
100
|
#
|
101
|
+
# @return [Hash]
|
102
|
+
#
|
73
103
|
# @api private
|
74
104
|
attr_reader :converter_map
|
75
105
|
end # Conversions
|
@@ -5,9 +5,19 @@ module Necromancer
|
|
5
5
|
#
|
6
6
|
# @api private
|
7
7
|
class Converter
|
8
|
+
# Create an abstract converter
|
9
|
+
#
|
10
|
+
# @param [Object] source
|
11
|
+
# the source object type
|
12
|
+
#
|
13
|
+
# @param [Object] target
|
14
|
+
# the target object type
|
15
|
+
#
|
16
|
+
# @api public
|
8
17
|
def initialize(source = nil, target = nil)
|
9
18
|
@source = source if source
|
10
19
|
@target = target if target
|
20
|
+
@config ||= Configuration.new
|
11
21
|
end
|
12
22
|
|
13
23
|
# Run converter
|
@@ -44,5 +54,9 @@ module Necromancer
|
|
44
54
|
attr_accessor :target
|
45
55
|
|
46
56
|
attr_accessor :convert
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
attr_reader :config
|
47
61
|
end # Converter
|
48
62
|
end # Necromancer
|
@@ -15,30 +15,26 @@ module Necromancer
|
|
15
15
|
#
|
16
16
|
# @api public
|
17
17
|
def call(value, options = {})
|
18
|
-
strict = options.fetch(:strict,
|
18
|
+
strict = options.fetch(:strict, config.strict)
|
19
19
|
case value.to_s
|
20
20
|
when /^\s*?((\d+)(\s*(,|-)\s*)?)+\s*?$/
|
21
21
|
value.to_s.split($4).map(&:to_i)
|
22
22
|
when /^((\w)(\s*(,|-)\s*)?)+$/
|
23
23
|
value.to_s.split($4)
|
24
24
|
else
|
25
|
-
|
26
|
-
fail_conversion_type(value)
|
27
|
-
else
|
28
|
-
Array(value)
|
29
|
-
end
|
25
|
+
strict ? fail_conversion_type(value) : Array(value)
|
30
26
|
end
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
|
-
# An object that converts an
|
30
|
+
# An object that converts an array to an array with numeric values
|
35
31
|
class ArrayToNumericConverter < Converter
|
36
|
-
# Convert an array to
|
32
|
+
# Convert an array to an array of numeric values
|
37
33
|
#
|
38
34
|
# @example
|
39
35
|
# converter.call(['1', '2.3', '3.0]) # => [1, 2.3, 3.0]
|
40
36
|
#
|
41
|
-
# @param [
|
37
|
+
# @param [Array] value
|
42
38
|
# the value to convert
|
43
39
|
#
|
44
40
|
# @api public
|
@@ -50,9 +46,69 @@ module Necromancer
|
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
49
|
+
# An object that converts an array to an array with boolean values
|
50
|
+
class ArrayToBooleanConverter < Converter
|
51
|
+
# @example
|
52
|
+
# converter.call(['t', 'f', 'yes', 'no']) # => [true, false, true, false]
|
53
|
+
#
|
54
|
+
# @param [Array] value
|
55
|
+
# the array value to boolean
|
56
|
+
#
|
57
|
+
# @api public
|
58
|
+
def call(value, options = {})
|
59
|
+
boolean_converter = BooleanConverters::StringToBooleanConverter.new(:string, :boolean)
|
60
|
+
value.reduce([]) do |acc, el|
|
61
|
+
acc << boolean_converter.call(el, options)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# An object that converts an object to an array
|
67
|
+
class ObjectToArrayConverter < Converter
|
68
|
+
# Convert an object to an array
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# converter.call({x: 1}) # => [[:x, 1]]
|
72
|
+
#
|
73
|
+
# @api public
|
74
|
+
def call(value, options = {})
|
75
|
+
strict = options.fetch(:strict, config.strict)
|
76
|
+
begin
|
77
|
+
Array(value)
|
78
|
+
rescue
|
79
|
+
strict ? fail_conversion_type(value) : value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# An object that converts an array to a set
|
85
|
+
class ArrayToSetConverter < Converter
|
86
|
+
# Convert an array to a set
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
# converter.call([:x, :y, :x, 1, 2, 1]) # => <Set: {:x, :y, 1, 2}>
|
90
|
+
#
|
91
|
+
# @param [Array] value
|
92
|
+
# the array to convert
|
93
|
+
#
|
94
|
+
# @api public
|
95
|
+
def call(value, options = {})
|
96
|
+
strict = options.fetch(:strict, config.strict)
|
97
|
+
begin
|
98
|
+
value.to_set
|
99
|
+
rescue
|
100
|
+
strict ? fail_conversion_type(value) : value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
53
105
|
def self.load(conversions)
|
106
|
+
conversions.register NullConverter.new(:array, :array)
|
54
107
|
conversions.register StringToArrayConverter.new(:string, :array)
|
55
108
|
conversions.register ArrayToNumericConverter.new(:array, :numeric)
|
109
|
+
conversions.register ArrayToBooleanConverter.new(:array, :boolean)
|
110
|
+
conversions.register ObjectToArrayConverter.new(:object, :array)
|
111
|
+
conversions.register ObjectToArrayConverter.new(:hash, :array)
|
56
112
|
end
|
57
113
|
end # ArrayConverters
|
58
114
|
end # Necromancer
|
@@ -27,7 +27,7 @@ module Necromancer
|
|
27
27
|
#
|
28
28
|
# @api public
|
29
29
|
def call(value, options = {})
|
30
|
-
strict = options.fetch(:strict,
|
30
|
+
strict = options.fetch(:strict, config.strict)
|
31
31
|
case value.to_s
|
32
32
|
when TRUE_MATCHER then true
|
33
33
|
when FALSE_MATCHER then false
|
@@ -48,11 +48,11 @@ module Necromancer
|
|
48
48
|
#
|
49
49
|
# @api public
|
50
50
|
def call(value, options = {})
|
51
|
-
strict = options.fetch(:strict,
|
51
|
+
strict = options.fetch(:strict, config.strict)
|
52
52
|
begin
|
53
53
|
!value.zero?
|
54
54
|
rescue
|
55
|
-
strict ?
|
55
|
+
strict ? fail_conversion_type(value) : value
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -69,7 +69,7 @@ module Necromancer
|
|
69
69
|
#
|
70
70
|
# @api public
|
71
71
|
def call(value, options = {})
|
72
|
-
strict = options.fetch(:strict,
|
72
|
+
strict = options.fetch(:strict, config.strict)
|
73
73
|
if ['TrueClass', 'FalseClass'].include?(value.class.name)
|
74
74
|
value ? 1 : 0
|
75
75
|
else
|
@@ -6,7 +6,7 @@ module Necromancer
|
|
6
6
|
# An object that converts a String to a Date
|
7
7
|
class StringToDateConverter < Converter
|
8
8
|
def call(value, options = {})
|
9
|
-
strict = options.fetch(:strict,
|
9
|
+
strict = options.fetch(:strict, config.strict)
|
10
10
|
Date.parse(value)
|
11
11
|
rescue
|
12
12
|
strict ? fail_conversion_type(value) : value
|
@@ -16,7 +16,7 @@ module Necromancer
|
|
16
16
|
# An object that converts a String to a DateTime
|
17
17
|
class StringToDateTimeConverter < Converter
|
18
18
|
def call(value, options = {})
|
19
|
-
strict = options.fetch(:strict,
|
19
|
+
strict = options.fetch(:strict, config.strict)
|
20
20
|
DateTime.parse(value)
|
21
21
|
rescue
|
22
22
|
strict ? fail_conversion_type(value) : value
|
@@ -16,7 +16,7 @@ module Necromancer
|
|
16
16
|
#
|
17
17
|
# @api public
|
18
18
|
def call(value, options = {})
|
19
|
-
strict = options.fetch(:strict,
|
19
|
+
strict = options.fetch(:strict, config.strict)
|
20
20
|
Integer(value)
|
21
21
|
rescue
|
22
22
|
strict ? fail_conversion_type(value) : value.to_i
|
@@ -45,7 +45,7 @@ module Necromancer
|
|
45
45
|
#
|
46
46
|
# @api public
|
47
47
|
def call(value, options = {})
|
48
|
-
strict = options.fetch(:strict,
|
48
|
+
strict = options.fetch(:strict, config.strict)
|
49
49
|
Float(value)
|
50
50
|
rescue
|
51
51
|
strict ? fail_conversion_type(value) : value.to_f
|
@@ -64,7 +64,7 @@ module Necromancer
|
|
64
64
|
#
|
65
65
|
# @api public
|
66
66
|
def call(value, options = {})
|
67
|
-
strict = options.fetch(:strict,
|
67
|
+
strict = options.fetch(:strict, config.strict)
|
68
68
|
case value
|
69
69
|
when INTEGER_MATCHER
|
70
70
|
StringToIntegerConverter.new(:string, :integer).call(value, options)
|
data/lib/necromancer/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -44,7 +44,7 @@ RSpec.configure do |config|
|
|
44
44
|
Kernel.srand config.seed
|
45
45
|
|
46
46
|
config.before :each do
|
47
|
-
[:UpcaseConverter].each do |class_name|
|
47
|
+
[:UpcaseConverter, :Custom].each do |class_name|
|
48
48
|
if Object.const_defined?(class_name)
|
49
49
|
Object.send(:remove_const, class_name)
|
50
50
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Necromancer, 'config' do
|
6
|
+
it "configures global settings per instance" do
|
7
|
+
converter = described_class.new
|
8
|
+
|
9
|
+
converter.configure do |config|
|
10
|
+
config.strict false
|
11
|
+
end
|
12
|
+
expect(converter.convert("1.2.3").to(:array)).to eq(["1.2.3"])
|
13
|
+
|
14
|
+
converter.configure do |config|
|
15
|
+
config.strict true
|
16
|
+
end
|
17
|
+
expect {
|
18
|
+
converter.convert("1.2.3").to(:array)
|
19
|
+
}.to raise_error(Necromancer::ConversionTypeError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "configures global settings through instance block" do
|
23
|
+
converter = described_class.new do |config|
|
24
|
+
config.strict true
|
25
|
+
end
|
26
|
+
expect(converter.configuration.strict).to eq(true)
|
27
|
+
|
28
|
+
expect {
|
29
|
+
converter.convert("1.2.3").to(:array)
|
30
|
+
}.to raise_error(Necromancer::ConversionTypeError)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Necromancer::Configuration, '.new' do
|
6
|
+
|
7
|
+
subject(:config) { described_class.new }
|
8
|
+
|
9
|
+
it { is_expected.to respond_to(:strict=) }
|
10
|
+
|
11
|
+
it { is_expected.to respond_to(:copy=) }
|
12
|
+
|
13
|
+
it "is in non-strict mode by default" do
|
14
|
+
expect(config.strict).to eq(false)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is in copy mode by default" do
|
18
|
+
expect(config.copy).to eq(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "allows to set strict through method" do
|
22
|
+
config.strict true
|
23
|
+
expect(config.strict).to eq(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows to set copy mode through method" do
|
27
|
+
config.copy false
|
28
|
+
expect(config.strict).to eq(false)
|
29
|
+
end
|
30
|
+
end
|
data/spec/unit/convert_spec.rb
CHANGED
@@ -6,6 +6,30 @@ RSpec.describe Necromancer, '.convert' do
|
|
6
6
|
|
7
7
|
subject(:converter) { described_class.new }
|
8
8
|
|
9
|
+
context 'when array' do
|
10
|
+
it "converts string to array" do
|
11
|
+
expect(converter.convert("1,2,3").to(:array)).to eq([1,2,3])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "converts array to numeric " do
|
15
|
+
expect(converter.convert(['1','2.3','3.0']).to(:numeric)).to eq([1,2.3,3.0])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "converts array to boolean" do
|
19
|
+
expect(converter.convert(['t', 'no']).to(:boolean)).to eq([true, false])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "converts object to array" do
|
23
|
+
expect(converter.convert({x: 1}).to(:array)).to eq([[:x, 1]])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "fails to convert in strict mode" do
|
27
|
+
expect {
|
28
|
+
converter.convert(['1', '2.3', false]).to(:numeric, strict: true)
|
29
|
+
}.to raise_error(Necromancer::ConversionTypeError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
9
33
|
context 'when numeric' do
|
10
34
|
it "converts string to integer" do
|
11
35
|
expect(converter.convert('1').to(:integer)).to eq(1)
|
@@ -66,22 +90,6 @@ RSpec.describe Necromancer, '.convert' do
|
|
66
90
|
end
|
67
91
|
end
|
68
92
|
|
69
|
-
context 'when array' do
|
70
|
-
it "converts string to array" do
|
71
|
-
expect(converter.convert("1,2,3").to(:array)).to eq([1,2,3])
|
72
|
-
end
|
73
|
-
|
74
|
-
it "converts array to numeric " do
|
75
|
-
expect(converter.convert(['1','2.3','3.0']).to(:numeric)).to eq([1,2.3,3.0])
|
76
|
-
end
|
77
|
-
|
78
|
-
it "fails to convert in strict mode" do
|
79
|
-
expect {
|
80
|
-
converter.convert(['1', '2.3', false]).to(:numeric, strict: true)
|
81
|
-
}.to raise_error(Necromancer::ConversionTypeError)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
93
|
context 'when datetime' do
|
86
94
|
it "converts string to date" do
|
87
95
|
expect(converter.convert('2014-12-07').to(:date)).
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Necromancer::ArrayConverters::ArrayToBooleanConverter, '.call' do
|
6
|
+
|
7
|
+
subject(:converter) { described_class.new(:array, :boolean) }
|
8
|
+
|
9
|
+
it "converts `['t', 'f', 'yes', 'no']` to boolean array" do
|
10
|
+
expect(converter.call(['t', 'f', 'yes', 'no'])).to eq([true, false, true, false])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "fails to convert `['t', 'no', 5]` to boolean array in strict mode" do
|
14
|
+
expect {
|
15
|
+
converter.call(['t', 'no', 5], strict: true)
|
16
|
+
}.to raise_error(Necromancer::ConversionTypeError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "converts `['t', 'no', 5]` to boolean array in non-strict mode" do
|
20
|
+
expect(converter.call(['t', 'no', 5], strict: false)).to eql([true, false, 5])
|
21
|
+
end
|
22
|
+
end
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
RSpec.describe Necromancer::ArrayConverters::ArrayToNumericConverter, '.call' do
|
6
6
|
|
7
|
-
subject(:converter) { described_class.new }
|
7
|
+
subject(:converter) { described_class.new(:array, :numeric) }
|
8
8
|
|
9
9
|
it "converts `['1','2.3','3.0']` to numeric array" do
|
10
10
|
expect(converter.call(['1', '2.3', '3.0'])).to eq([1, 2.3, 3.0])
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Necromancer::ArrayConverters::ArrayToSetConverter, '.call' do
|
6
|
+
|
7
|
+
subject(:converter) { described_class.new(:array, :set) }
|
8
|
+
|
9
|
+
it "converts `[:x,:y,:x,1,2,1]` to set" do
|
10
|
+
expect(converter.call([:x,:y,:x,1,2,1])).to eql(Set[:x,:y,1,2])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "fails to convert `1` to set" do
|
14
|
+
expect {
|
15
|
+
converter.call(1, strict: true)
|
16
|
+
}.to raise_error(Necromancer::ConversionTypeError)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Necromancer::ArrayConverters::ObjectToArrayConverter, '.call' do
|
6
|
+
subject(:converter) { described_class.new(:object, :array) }
|
7
|
+
|
8
|
+
it "converts nil to array" do
|
9
|
+
expect(converter.call(nil)).to eq([])
|
10
|
+
end
|
11
|
+
|
12
|
+
it "converts custom object to array" do
|
13
|
+
Custom = Class.new do
|
14
|
+
def to_ary
|
15
|
+
[:x, :y]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
custom = Custom.new
|
19
|
+
expect(converter.call(custom)).to eq([:x, :y])
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: necromancer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- README.md
|
42
42
|
- Rakefile
|
43
43
|
- lib/necromancer.rb
|
44
|
+
- lib/necromancer/configuration.rb
|
44
45
|
- lib/necromancer/context.rb
|
45
46
|
- lib/necromancer/conversion_target.rb
|
46
47
|
- lib/necromancer/conversions.rb
|
@@ -55,9 +56,14 @@ files:
|
|
55
56
|
- necromancer.gemspec
|
56
57
|
- spec/spec_helper.rb
|
57
58
|
- spec/unit/can_spec.rb
|
59
|
+
- spec/unit/config_spec.rb
|
60
|
+
- spec/unit/configuration/new_spec.rb
|
58
61
|
- spec/unit/conversions/register_spec.rb
|
59
62
|
- spec/unit/convert_spec.rb
|
63
|
+
- spec/unit/converters/array/array_to_boolean_spec.rb
|
60
64
|
- spec/unit/converters/array/array_to_numeric_spec.rb
|
65
|
+
- spec/unit/converters/array/array_to_set_spec.rb
|
66
|
+
- spec/unit/converters/array/object_to_array_spec.rb
|
61
67
|
- spec/unit/converters/array/string_to_array_spec.rb
|
62
68
|
- spec/unit/converters/boolean/boolean_to_integer_spec.rb
|
63
69
|
- spec/unit/converters/boolean/integer_to_boolean_spec.rb
|
@@ -100,9 +106,14 @@ summary: Conversion from one object type to another with a bit of black magic.
|
|
100
106
|
test_files:
|
101
107
|
- spec/spec_helper.rb
|
102
108
|
- spec/unit/can_spec.rb
|
109
|
+
- spec/unit/config_spec.rb
|
110
|
+
- spec/unit/configuration/new_spec.rb
|
103
111
|
- spec/unit/conversions/register_spec.rb
|
104
112
|
- spec/unit/convert_spec.rb
|
113
|
+
- spec/unit/converters/array/array_to_boolean_spec.rb
|
105
114
|
- spec/unit/converters/array/array_to_numeric_spec.rb
|
115
|
+
- spec/unit/converters/array/array_to_set_spec.rb
|
116
|
+
- spec/unit/converters/array/object_to_array_spec.rb
|
106
117
|
- spec/unit/converters/array/string_to_array_spec.rb
|
107
118
|
- spec/unit/converters/boolean/boolean_to_integer_spec.rb
|
108
119
|
- spec/unit/converters/boolean/integer_to_boolean_spec.rb
|