realize 1.1.0 → 1.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
  SHA256:
3
- metadata.gz: 0f1004b6b97c8ebd485bac4fb9859ffd28511240f4a9943c73875664be35722c
4
- data.tar.gz: 979d68bb86ecc8ba32251c2346a0183158686bf04fb9949f04646e7e16a6a03b
3
+ metadata.gz: 0d7bccc32a2837daee77ec8bcdda00975744c90e0ac08f62f5dbfcaf338dfd91
4
+ data.tar.gz: aa23c2077287abe225dc2c4b7aa3a2bec7a405bdfd4011ce375d7aed64ac5f56
5
5
  SHA512:
6
- metadata.gz: f2398a44d581a5e8685ef9c29acbb140fbc2488cb7ffc6411317254325154e30b72b3828b96df5aa7e17f299a79c802f4ece1a50486c0ec62d20bdcb9bd5f073
7
- data.tar.gz: 9b87926382b38afda00be7ab8055ab26eea572228489f0d0efd341dd0b709d11d1becafa3e925d79baa5c30bccd0fab30130c8792e646891c902fc6cb7a23aa9
6
+ metadata.gz: e1201c0671253238b656904b713482db1b53b1f720c36821b87618fd6d0ace49314eda6773080ccb3ed27fca50d8cb68f822547d9d631ff8529f437e7babdba5
7
+ data.tar.gz: aadc039cccfdcae68d14b7902e854e14078ea2a674d7c4e84cc2f16c2f1e54f6f1cc1568a408676b726b581a5f80004861d44f751a350eb340d1bd995f02d3fe
@@ -17,6 +17,7 @@ Metrics/MethodLength:
17
17
 
18
18
  AllCops:
19
19
  TargetRubyVersion: 2.5
20
+ NewCops: enable
20
21
 
21
22
  Metrics/AbcSize:
22
23
  Max: 16
@@ -1,3 +1,25 @@
1
+ # 1.3.0 (November 4th, 2020)
2
+
3
+ New Transformers:
4
+
5
+ * r/format/string_template
6
+ * r/format/substring
7
+
8
+ # 1.2.0 (October 6th, 2020)
9
+
10
+ New Transformers:
11
+
12
+ * r/type/boolean
13
+ * r/type/string
14
+ * r/value/now
15
+ * r/value/uuid
16
+
17
+ # 1.1.1 (September 9th, 2020)
18
+
19
+ Fixes:
20
+
21
+ * Do not leverage #to_datetime even if it is available for date parsing. This removes un-intentional coupling of other libraries into Realize and keeps it based on Ruby standard and core libraries.
22
+
1
23
  # 1.1.0 (June 24th, 2020)
2
24
 
3
25
  Addition of r/collection/at_index, r/collection/first, and r/collection/last
data/README.md CHANGED
@@ -13,7 +13,7 @@ It is currently used in production at Blue Marble to power the transformation pi
13
13
  To install through Rubygems:
14
14
 
15
15
  ````
16
- gem install install realize
16
+ gem install realize
17
17
  ````
18
18
 
19
19
  You can also add this to your Gemfile:
@@ -79,18 +79,27 @@ Here is a list of each built-in transformer, their options, and what their funct
79
79
  * **r/format/date** [input_format, output_format]: Parses the incoming value into a Time object using the configured input_format and outputs it as formatted by the configured output_format.
80
80
  * **r/format/remove_whitespace** []: Removes all whitespace from the incoming value.
81
81
  * **r/format/string_replace** [original, replacement]: Replaces all occurrences of the configured original value with the replacement value.
82
+ * **r/format/string_template** [expression, separator, use_record]: String interpolate an expression using either the record or passed in value. Nested objects can be handled (i.e. key paths like dot-notation) by passing in a separator.
83
+ * **r/format/substring** [start_index, end_index, exclusive]: Cut a string in a given range. All options are optional. If a start_index is not provided, the beginning of the string is used. If no end_index is specified then the end of the string is used. If exclusive is set to true then the last index position will not be included. For example: "hellofriend" with a start_index of 0, an end_index of 5, and exclusive as true would yield: "hello". If exclusive was false then it would yield "hellof"
82
84
 
83
85
  #### Logical Transformers
84
86
 
85
87
  * **r/logical/switch** [cases, default_transformers, key]: Provides a value-based logic branching. If a value matches a specific case, the specific cases transformers will be executed. If it does not match any case then the default_transformers will be executed.
86
88
 
89
+ #### Type Transformers
90
+
91
+ * **r/type/boolean** [nullable]: Returns `true` if the input is 'truthy', `false` if not. By default nullable is false, which means a nil input will return false. Changing this to true will return nil if nil is passed in. A 'truthy' value is defined as matching: true, t, yes, y, or 1 (case-insensitive).
92
+ * **r/type/string** []: Calls `#to_s` on the value so the returned value is guaranteed to be a string type.
93
+
87
94
  #### Value-oriented Transformers
88
95
 
89
96
  * **r/value/blank** []: Always return a blank string.
90
97
  * **r/value/map** [values]: Do a lookup on the value using the `values` hash. If a value is found, then its corresponding value is returned. If it isn't then the input is returned.
98
+ * **r/value/now** [utc_offset]: Returns a Time object, defaulting to UTC offset. You can optionally pass in a different offset in the FORM: "+/-HH:MM"
91
99
  * **r/value/null** []: Always returns null.
92
100
  * **r/value/resolve** [key]: Dynamically resolves a value based on the record's key. It uses the [Objectable](https://github.com/bluemarblepayroll/objectable) library by default, which provides some goodies like dot-notation for nested objects and type-insensitivity (works for Ruby objects, hashes, structs, etc.)
93
101
  * **r/value/static** [value]: Always returns a hard-coded value.
102
+ * **r/value/uuid** []: Returns a new 36 character UUID (i.e. 6967fec6-bbde-4497-82d9-55ccc7b87cd0)
94
103
  * **r/value/verbatim** []: Default transformer, simply echos back the input.
95
104
 
96
105
  ### Plugging in Transformers
@@ -9,6 +9,8 @@
9
9
 
10
10
  require 'acts_as_hashable'
11
11
  require 'objectable'
12
+ require 'securerandom'
13
+ require 'stringento'
12
14
  require 'time'
13
15
 
14
16
  require_relative 'realize/arrays'
@@ -30,12 +30,10 @@ module Realize
30
30
  return nil if value.to_s.empty?
31
31
 
32
32
  date_time =
33
- if value.respond_to?(:to_datetime)
34
- value.to_datetime
35
- elsif input_format?
33
+ if input_format?
36
34
  DateTime.strptime(value, input_format)
37
35
  else
38
- DateTime.parse(value)
36
+ DateTime.parse(value.to_s)
39
37
  end
40
38
 
41
39
  date_time.strftime(output_format)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Format
5
+ # Use an expression as a template and string interpolate it using the Stringento library.
6
+ # Stringento also uses Objectable to provide (optional) key-path notation for handling
7
+ # nested objects.
8
+ # For more information see underlying libraries:
9
+ # * Stringento: https://github.com/bluemarblepayroll/stringento
10
+ # * Objectable: https://github.com/bluemarblepayroll/objectable
11
+ class StringTemplate
12
+ acts_as_hashable
13
+
14
+ DEFAULT_SEPARATOR = '.'
15
+
16
+ attr_reader :expression, :resolver, :use_record
17
+
18
+ def initialize(expression: '', separator: DEFAULT_SEPARATOR, use_record: false)
19
+ @expression = expression.to_s
20
+ @resolver = Objectable.resolver(separator: separator)
21
+ @use_record = use_record || false
22
+
23
+ freeze
24
+ end
25
+
26
+ def transform(_resolver, value, _time, record)
27
+ input = use_record ? record : value
28
+
29
+ Stringento.evaluate(expression, input, resolver: self)
30
+ end
31
+
32
+ # For Stringento consumption
33
+ def resolve(value, input)
34
+ resolver.get(input, value)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Format
5
+ # Cut a string using a range (start and end index). You can also choose whether you wish the
6
+ # range selection to be inclusive (default) or exclusive.
7
+ #
8
+ # Examples using the string: '012-345-6789'
9
+ #
10
+ # Exclusive vs. Inclusive
11
+ #
12
+ # [start_index: 4, end_index: 6, exclusive: false] => '345'
13
+ # [start_index: 4, end_index: 6, exclusive: true] => '34'
14
+ #
15
+ # Default Values / Omitted Options
16
+ #
17
+ # [end_index: 6] => '012-345'
18
+ # [start_index: 4] => '345-6789'
19
+ class Substring
20
+ acts_as_hashable
21
+
22
+ DEFAULT_END_INDEX = -1
23
+ DEFAULT_START_INDEX = 0
24
+
25
+ attr_reader :end_index, :exclusive, :start_index
26
+
27
+ def initialize(
28
+ end_index: DEFAULT_END_INDEX,
29
+ exclusive: false,
30
+ start_index: DEFAULT_START_INDEX
31
+ )
32
+ @end_index = end_index.to_i
33
+ @exclusive = exclusive || false
34
+ @start_index = start_index.to_i
35
+
36
+ freeze
37
+ end
38
+
39
+ def transform(_resolver, value, _time, _record)
40
+ exclusive ? value.to_s[start_index...end_index] : value.to_s[start_index..end_index]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -14,7 +14,7 @@ module Realize
14
14
 
15
15
  attr_reader :cases, :default_transformers, :key
16
16
 
17
- def initialize(cases: [], default_transformers: [], key:)
17
+ def initialize(key:, cases: [], default_transformers: [])
18
18
  raise ArgumentError, 'key is required' if key.to_s.empty?
19
19
 
20
20
  @cases = Case.array(cases)
@@ -4,19 +4,30 @@ require_relative 'collection/at_index'
4
4
  require_relative 'collection/first'
5
5
  require_relative 'collection/last'
6
6
  require_relative 'collection/sort'
7
+
7
8
  require_relative 'filter/by_key_record_value'
8
9
  require_relative 'filter/by_key_value'
9
10
  require_relative 'filter/by_key_value_presence'
10
11
  require_relative 'filter/inactive'
12
+
11
13
  require_relative 'format/date'
12
14
  require_relative 'format/remove_whitespace'
13
15
  require_relative 'format/string_replace'
16
+ require_relative 'format/string_template'
17
+ require_relative 'format/substring'
18
+
14
19
  require_relative 'logical/switch'
20
+
21
+ require_relative 'type/boolean'
22
+ require_relative 'type/string'
23
+
15
24
  require_relative 'value/blank'
16
25
  require_relative 'value/map'
26
+ require_relative 'value/now'
17
27
  require_relative 'value/null'
18
28
  require_relative 'value/resolve'
19
29
  require_relative 'value/static'
30
+ require_relative 'value/uuid'
20
31
  require_relative 'value/verbatim'
21
32
 
22
33
  module Realize
@@ -27,24 +38,34 @@ module Realize
27
38
  class Transformers
28
39
  acts_as_hashable_factory
29
40
 
30
- register '', Value::Verbatim
31
41
  register 'r/collection/at_index', Collection::AtIndex
32
42
  register 'r/collection/first', Collection::First
33
43
  register 'r/collection/last', Collection::Last
34
44
  register 'r/collection/sort', Collection::Sort
45
+
35
46
  register 'r/filter/by_key_record_value', Filter::ByKeyRecordValue
36
47
  register 'r/filter/by_key_value', Filter::ByKeyValue
37
48
  register 'r/filter/by_key_value_presence', Filter::ByKeyValuePresence
38
49
  register 'r/filter/inactive', Filter::Inactive
50
+
39
51
  register 'r/format/date', Format::Date
40
52
  register 'r/format/remove_whitespace', Format::RemoveWhitespace
41
53
  register 'r/format/string_replace', Format::StringReplace
54
+ register 'r/format/string_template', Format::StringTemplate
55
+ register 'r/format/substring', Format::Substring
56
+
42
57
  register 'r/logical/switch', Logical::Switch
58
+
59
+ register 'r/type/boolean', Type::Boolean
60
+ register 'r/type/string', Type::String
61
+
43
62
  register 'r/value/blank', Value::Blank
44
63
  register 'r/value/map', Value::Map
64
+ register 'r/value/now', Value::Now
45
65
  register 'r/value/null', Value::Null
46
66
  register 'r/value/resolve', Value::Resolve
47
67
  register 'r/value/static', Value::Static
48
- register 'r/value/verbatim', Value::Verbatim
68
+ register 'r/value/uuid', Value::Uuid
69
+ register 'r/value/verbatim', '', Value::Verbatim
49
70
  end
50
71
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Type
5
+ # Convert input into either true, false, or nil.
6
+ # By default nils will return false unless nullable: true is passed in.
7
+ # This transformer is very liberal in its parsing and will return true for:
8
+ # true, 'true', 't', 'TRUE', 'True', 1, '1', 'Y', 'yes', 'Yes', 'YES'
9
+ # All other non-truthy values will evaluate to false, such as:
10
+ # false, 'false', 'f', 'FALSE', 'False', 0, '0', 'N', 'no', 'No', 'NO', {}, [], '',
11
+ # 'abc', 123, :abc, etc...
12
+ class Boolean
13
+ acts_as_hashable
14
+
15
+ attr_reader :nullable
16
+
17
+ def initialize(nullable: false)
18
+ @nullable = nullable || false
19
+ end
20
+
21
+ def transform(_resolver, value, _time, _record)
22
+ if nullable && value.nil?
23
+ nil
24
+ elsif truthy?(value)
25
+ true
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def truthy?(value)
34
+ value.to_s.match?(/(true|t|yes|y|1)$/i)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Type
5
+ # Call #to_s on the value and return result.
6
+ class String
7
+ acts_as_hashable
8
+
9
+ attr_reader :nullable
10
+
11
+ def initialize(nullable: false)
12
+ @nullable = nullable || false
13
+ end
14
+
15
+ def transform(_resolver, value, _time, _record)
16
+ return nil if nullable && value.nil?
17
+
18
+ value.to_s
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Value
5
+ # Return a current Time object.
6
+ class Now
7
+ acts_as_hashable
8
+
9
+ DEFAULT_UTC_OFFSET = '+00:00'
10
+
11
+ attr_reader :utc_offset
12
+
13
+ def initialize(utc_offset: DEFAULT_UTC_OFFSET)
14
+ @utc_offset = utc_offset || DEFAULT_UTC_OFFSET
15
+
16
+ freeze
17
+ end
18
+
19
+ def transform(_resolver, _value, _time, _record)
20
+ Time.now.utc.localtime(utc_offset)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Realize
4
+ class Value
5
+ # Return a current Time object.
6
+ class Uuid
7
+ acts_as_hashable
8
+
9
+ def transform(_resolver, _value, _time, _record)
10
+ SecureRandom.uuid
11
+ end
12
+ end
13
+ end
14
+ end
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module Realize
11
- VERSION = '1.1.0'
11
+ VERSION = '1.3.0'
12
12
  end
@@ -30,12 +30,13 @@ Gem::Specification.new do |s|
30
30
 
31
31
  s.add_dependency('acts_as_hashable', '~>1', '>=1.2.0')
32
32
  s.add_dependency('objectable', '~>1')
33
+ s.add_dependency('stringento', '~>2.1')
33
34
 
34
35
  s.add_development_dependency('guard-rspec', '~>4.7')
35
36
  s.add_development_dependency('pry', '~>0')
36
37
  s.add_development_dependency('rake', '~> 13')
37
38
  s.add_development_dependency('rspec')
38
- s.add_development_dependency('rubocop', '~>0.79.0')
39
+ s.add_development_dependency('rubocop', '~>1.1')
39
40
  s.add_development_dependency('simplecov', '~>0.17.0')
40
41
  s.add_development_dependency('simplecov-console', '~>0.6.0')
41
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: realize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-06-24 00:00:00.000000000 Z
12
+ date: 2020-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: acts_as_hashable
@@ -45,6 +45,20 @@ dependencies:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1'
48
+ - !ruby/object:Gem::Dependency
49
+ name: stringento
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.1'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
48
62
  - !ruby/object:Gem::Dependency
49
63
  name: guard-rspec
50
64
  requirement: !ruby/object:Gem::Requirement
@@ -107,14 +121,14 @@ dependencies:
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 0.79.0
124
+ version: '1.1'
111
125
  type: :development
112
126
  prerelease: false
113
127
  version_requirements: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: 0.79.0
131
+ version: '1.1'
118
132
  - !ruby/object:Gem::Dependency
119
133
  name: simplecov
120
134
  requirement: !ruby/object:Gem::Requirement
@@ -179,15 +193,21 @@ files:
179
193
  - lib/realize/format/date.rb
180
194
  - lib/realize/format/remove_whitespace.rb
181
195
  - lib/realize/format/string_replace.rb
196
+ - lib/realize/format/string_template.rb
197
+ - lib/realize/format/substring.rb
182
198
  - lib/realize/logical/switch.rb
183
199
  - lib/realize/logical/switch/case.rb
184
200
  - lib/realize/pipeline.rb
185
201
  - lib/realize/transformers.rb
202
+ - lib/realize/type/boolean.rb
203
+ - lib/realize/type/string.rb
186
204
  - lib/realize/value/blank.rb
187
205
  - lib/realize/value/map.rb
206
+ - lib/realize/value/now.rb
188
207
  - lib/realize/value/null.rb
189
208
  - lib/realize/value/resolve.rb
190
209
  - lib/realize/value/static.rb
210
+ - lib/realize/value/uuid.rb
191
211
  - lib/realize/value/verbatim.rb
192
212
  - lib/realize/version.rb
193
213
  - realize.gemspec