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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1c2f7a7dfa509891b8a6e9b54b0dc1c06220bd6
4
- data.tar.gz: 0e4645b6d70af9782ded19b153937cb35ae29ca1
3
+ metadata.gz: 0ab93f1c0f77de5f9d0643fee2136e1a18448509
4
+ data.tar.gz: 44e07300b65361d813dfa3e4d36381ef44cb0d8b
5
5
  SHA512:
6
- metadata.gz: b3e8624ae93d5dea444a1948fecee7be8dfdcdc24b04e4caca39dd93d22214b2035f124de5fdd360ee1af62bfce87dbadd20aa0a13496b7003b104cc3c879de6
7
- data.tar.gz: c61f41045c0709a96f7e1d81dce673260f4410ffd91f6d69febf8de0f334d3c8634bb74b20efa6fd8ad88172ad3748bcb5e9e5c6d988c684344759f7159a7a89
6
+ metadata.gz: 9049c66ec36a5f139de3ffd32d14232eaf95118437c9323fec32cd34054722ea0106c7e1b59d7d284fb53ab52d14a1c3dc723cad07431f541f591200a84f167e
7
+ data.tar.gz: 9471c9273853b50e269e9aa96efe7f3ae87d99236a7b222d8eb95fd03371a15485d7070fe903eba95949e524b68fec516d0746e05a9b1094c588d6029b52d9c2
@@ -1,3 +1,8 @@
1
+ 0.3.0 (December 14, 2014)
2
+
3
+ * Add array converters for :hash, :set and :object conversions
4
+ * Add ability to configure global conversion settings per instance
5
+
1
6
  0.2.0 (December 7, 2014)
2
7
 
3
8
  * Add #fail_conversion_type to Converter and use in converters
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 **Necormancer** call `can?` with the `source` and `target` of the desired conversion.
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 string into an array object:
206
+ The **Necromancer** allows you to transform arbitrary object into array:
181
207
 
182
208
  ```ruby
183
- converter.call('a, b, c') # => ['a', 'b', 'c']
209
+ converter.convert(nil).to(:array) # => []
210
+ converter.convert({x: 1}).to(:array) # => [[:x, 1]]
184
211
  ```
185
212
 
186
- If the string is a list of separated numbers, they will be converted to their respective numeric types:
213
+ In addition, **Necromancer** excels at converting `,` or `-` delimited string into an array object:
187
214
 
188
215
  ```ruby
189
- converter.call('1 - 2 - 3') # => [1, 2, 3]
216
+ converter.convert('a, b, c').to(:array) # => ['a', 'b', 'c']
190
217
  ```
191
218
 
192
- You can also convert array containing string objects to array containing numeric values:
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(['1', '2.3', '3.0']).from(:array).to(:numeric)
222
+ converter.convert('1 - 2 - 3').to(:array) # => [1, 2, 3]
196
223
  ```
197
224
 
198
- or simply:
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
@@ -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
@@ -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
- @conversions = Conversions.new
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] || fail(NoTypeConversionAvailableError)
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, false)
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
- if strict
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 Array to a numeric
30
+ # An object that converts an array to an array with numeric values
35
31
  class ArrayToNumericConverter < Converter
36
- # Convert an array to a numeric value
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 [Object] value
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, false)
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, false)
51
+ strict = options.fetch(:strict, config.strict)
52
52
  begin
53
53
  !value.zero?
54
54
  rescue
55
- strict ? fail_conversion_type(value) : value
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, false)
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, false)
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, false)
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, false)
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, false)
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, false)
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)
@@ -23,7 +23,7 @@ module Necromancer
23
23
  #
24
24
  # @api public
25
25
  def call(value, options = {})
26
- strict = options.fetch(:strict, false)
26
+ strict = options.fetch(:strict, config.strict)
27
27
  case value
28
28
  when SINGLE_DIGIT_MATCHER
29
29
  ::Range.new($1.to_i, $1.to_i)
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Necromancer
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end # Necromancer
@@ -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
@@ -3,7 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Necromancer::Conversions, '.register' do
6
-
7
6
  it "allows to register converter" do
8
7
  context = described_class.new
9
8
  converter = double(:converter, {source: :string, target: :numeric})
@@ -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.2.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-07 00:00:00.000000000 Z
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