necromancer 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|