remi 0.2.11 → 0.2.12

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: 521283fb3e00330bcbd4bc47ecc65dec7dcfe32d
4
- data.tar.gz: ff6cb6d01002b10b0e68cd50906de59c7b2af16d
3
+ metadata.gz: 2ee4f5ef99f18b36083cf0fa0a31e3c5e9dbab17
4
+ data.tar.gz: f78cdac5e10cc84cde78e7b54ef1955a591eb115
5
5
  SHA512:
6
- metadata.gz: 43b033f8d7f85874e1aab2e726c850580c557ce1a45eafe6481039a3d54fd5e3bb29c04d14d8adb5e007ce5bfdc4e905f2f46c16a5be578f1911daaa281b8318
7
- data.tar.gz: 9513915698ed36bb92949c69fca2bc87ed787fb177435059523342626d7bb9c26624d20c3dbe2710844bd3b2e5c3dd19df2e0d2ef5f62ebf9911e102c14af487
6
+ metadata.gz: 35b23fcdf2de08e344a12b8326159bb6ddb92dd322f732c0f5e3f5693ef0ffdf1731b1293b652581a2353aeb6b2daa732b93684813b8096cdeb0d4eddc9abbbf
7
+ data.tar.gz: f1953467dbc6f9b91cd804014bfb9b427308b974508272891d399f09c3142408f9426ba2af5283c05751b8270a347a6a25570e19d337f575611dcf322cf855ed
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- remi (0.2.10)
4
+ remi (0.2.12)
5
5
  activesupport (~> 4.2)
6
6
  bond (~> 0.5)
7
7
  cucumber (~> 2.1)
@@ -9,6 +9,7 @@ PATH
9
9
  docile (~> 1.1)
10
10
  net-sftp (~> 2.1)
11
11
  pg (~> 0.18)
12
+ regex_sieve (~> 0.1)
12
13
  regexp-examples (~> 1.1)
13
14
  restforce (~> 2.1)
14
15
  rspec (~> 3.3)
@@ -17,7 +18,7 @@ PATH
17
18
  GEM
18
19
  remote: https://rubygems.org/
19
20
  specs:
20
- activesupport (4.2.5)
21
+ activesupport (4.2.5.1)
21
22
  i18n (~> 0.7)
22
23
  json (~> 1.7, >= 1.7.7)
23
24
  minitest (~> 5.1)
@@ -26,12 +27,11 @@ GEM
26
27
  bond (0.5.1)
27
28
  builder (3.2.2)
28
29
  clbustos-rtf (0.4.2)
29
- cucumber (2.3.0)
30
+ cucumber (2.3.2)
30
31
  builder (>= 2.1.2)
31
32
  cucumber-core (~> 1.4.0)
32
33
  cucumber-wire (~> 0.0.1)
33
34
  diff-lcs (>= 1.1.3)
34
- event-bus (~> 0.1.0)
35
35
  gherkin (~> 3.2.0)
36
36
  multi_json (>= 1.7.5, < 2.0)
37
37
  multi_test (>= 0.1.2)
@@ -43,7 +43,6 @@ GEM
43
43
  spreadsheet (~> 1.0.3)
44
44
  diff-lcs (1.2.5)
45
45
  docile (1.1.5)
46
- event-bus (0.1.0)
47
46
  faraday (0.9.2)
48
47
  multipart-post (>= 1.2, < 3)
49
48
  faraday_middleware (0.10.0)
@@ -58,7 +57,7 @@ GEM
58
57
  rbczmq (~> 1.7)
59
58
  json (1.8.3)
60
59
  mimemagic (0.3.1)
61
- minitest (5.8.3)
60
+ minitest (5.8.4)
62
61
  multi_json (1.11.2)
63
62
  multi_test (0.1.2)
64
63
  multipart-post (2.0.0)
@@ -76,7 +75,8 @@ GEM
76
75
  prawn-svg (0.9.1.11)
77
76
  prawn (>= 0.8.4)
78
77
  rbczmq (1.7.9)
79
- regexp-examples (1.1.4)
78
+ regex_sieve (0.1.0)
79
+ regexp-examples (1.2.0)
80
80
  reportbuilder (1.4.2)
81
81
  clbustos-rtf (~> 0.4.0)
82
82
  prawn (~> 0.8.4)
@@ -91,7 +91,7 @@ GEM
91
91
  rspec-core (~> 3.4.0)
92
92
  rspec-expectations (~> 3.4.0)
93
93
  rspec-mocks (~> 3.4.0)
94
- rspec-core (3.4.1)
94
+ rspec-core (3.4.2)
95
95
  rspec-support (~> 3.4.0)
96
96
  rspec-expectations (3.4.0)
97
97
  diff-lcs (>= 1.2.0, < 2.0)
@@ -283,6 +283,27 @@ Then /^the target field '(.+)' is populated with "([^"]*)" using the format "([^
283
283
  expect(@brt.target.field.value).to eq target_reformatted
284
284
  end
285
285
 
286
+ Then /^the target field '(.+)' is the first non-blank value from source fields '(.+)'$/ do |target_field_name, source_field_list|
287
+ source_field_names = "'#{source_field_list}'".split(',').map do |field_with_quotes|
288
+ field_with_quotes.match(/'(.+)'/)[1]
289
+ end
290
+
291
+ source_field_names.each do |name|
292
+ step "the source field '#{name}'"
293
+ end
294
+ step "the target field '#{target_field_name}'"
295
+
296
+ source_field_names.each do |source_field_name|
297
+ @brt.run_transforms
298
+
299
+ source_values = source_field_names.map { |name| @brt.source.fields[name].value }
300
+ source_values_nvl = source_values.find { |arg| !arg.blank? }
301
+
302
+ expect_cucumber { expect(@brt.target.fields[target_field_name].value).to eq source_values_nvl }
303
+ @brt.source.fields[source_field_name].value = ''
304
+ end
305
+
306
+ end
286
307
 
287
308
  When /^in the source field, periods have been used in place of commas$/ do
288
309
  @brt.source.field.value = @brt.source.field.value.gsub(/\./, ',')
@@ -8,3 +8,19 @@ require 'remi/cucumber'
8
8
  require_relative 'env_app.rb'
9
9
 
10
10
  Remi::Settings.log_level = Logger::ERROR
11
+
12
+ Before '~@fails' do
13
+ def expect_cucumber(&block)
14
+ block.call
15
+ end
16
+ end
17
+
18
+ Before '@fails' do
19
+ def expect_cucumber(&block)
20
+ begin
21
+ block.call
22
+ rescue RSpec::Expectations::ExpectationNotMetError => err
23
+ puts "Expected error: #{err}"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ Feature: Test the NVL (Next Value Lookup) transformer.
2
+
3
+ Background:
4
+ Given the job is 'Nvl'
5
+ And the job source 'Source Data'
6
+ And the job target 'Target Data'
7
+
8
+ Scenario Outline: Performing an NVL
9
+ Given the source 'Source Data'
10
+ And the target 'Target Data'
11
+
12
+ And the source field 'Field1' is set to the value "<Field1>"
13
+ And the source field 'Field2' is set to the value "<Field2>"
14
+ And the source field 'Field3' is set to the value "<Field3>"
15
+ And the job parameter 'default' is "<Default>"
16
+ Then the target field 'Result Field' is set to the value "<Expected>"
17
+
18
+ Examples:
19
+ | Field1 | Field2 | Field3 | Default | Expected |
20
+ | A | B | C | | A |
21
+ | | B | C | | B |
22
+ | | | C | | C |
23
+ | | | | | |
24
+ | | | | UNK | UNK |
25
+
26
+
27
+ Scenario: Testing an NVL with the short form version
28
+ Given the source 'Source Data'
29
+ And the target 'Target Data'
30
+
31
+ Then the target field 'Result Field' is the first non-blank value from source fields 'Field1', 'Field2', 'Field3'
32
+
33
+ @fails
34
+ Scenario: Testing that the NVL with the short form version fails appropriately
35
+ Given the source 'Source Data'
36
+ And the target 'Target Data'
37
+
38
+ Then the target field 'Field2 Copy' is the first non-blank value from source fields 'Field1', 'Field2', 'Field3'
@@ -66,14 +66,14 @@ class SampleJob
66
66
  operation: :create,
67
67
  api: :bulk
68
68
 
69
- define_lookup :program_name_lookup, Remi::Lookup::RegexSieve, {
69
+ define_param :program_name_lookup, RegexSieve.new({
70
70
  /^BIO$/ => "Biology",
71
71
  /^Fake Biology$/ => nil,
72
72
  /(?:B|Microb)iology/ => "Biology",
73
73
  /^CHEM$/ => "Chemistry",
74
74
  /Chemistry/ => "Chemistry",
75
75
  /Physics/ => "Physics"
76
- }
76
+ })
77
77
 
78
78
  define_transform :map_common_fields, sources: [:sample_file, :existing_contacts], targets: :all_contacts do
79
79
 
@@ -81,7 +81,7 @@ class SampleJob
81
81
  all_contacts.df = sample_file.df.dup
82
82
  Remi::SourceToTargetMap.apply(all_contacts.df) do
83
83
  map source(:program) .target(:Major__c)
84
- .transform(Remi::Transform[:lookup][program_name_lookup])
84
+ .transform(Remi::Transform[:lookup][params[:program_name_lookup]])
85
85
  end
86
86
  all_contacts.df = all_contacts.df.where(all_contacts.df[:Major__c].not_eq(nil))
87
87
 
@@ -0,0 +1,23 @@
1
+ require_relative '../all_jobs_shared'
2
+
3
+ class NvlJob
4
+ include AllJobsShared
5
+
6
+ define_param :default, ''
7
+ define_source :source_data, Remi::DataSource::DataFrame,
8
+ fields: {
9
+ :field1 => {},
10
+ :field2 => {},
11
+ :field3 => {}
12
+ }
13
+ define_target :target_data, Remi::DataTarget::DataFrame
14
+
15
+ define_transform :main, sources: :source_data, targets: :target_data do
16
+ Remi::SourceToTargetMap.apply(source_data.df, target_data.df) do
17
+ map source(:field1, :field2, :field3) .target(:result_field)
18
+ .transform(Remi::Transform[:nvl].(params[:default]))
19
+
20
+ map source(:field2) .target(:field2_copy)
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,4 @@
1
1
  require_relative 'prefix_job'
2
2
  require_relative 'parse_date_job'
3
3
  require_relative 'date_diff_job'
4
+ require_relative 'nvl_job'
@@ -10,6 +10,7 @@ require 'daru'
10
10
  require 'docile'
11
11
  require 'net/sftp'
12
12
  require 'pg'
13
+ require 'regex_sieve'
13
14
 
14
15
  # ActiveSupport extensions
15
16
  require 'active_support'
@@ -56,5 +57,4 @@ require 'remi/data_target/data_frame'
56
57
  require 'remi/data_target/salesforce'
57
58
  require 'remi/data_target/csv_file'
58
59
 
59
- require 'remi/lookup/regex_sieve'
60
60
  require 'remi/transform'
@@ -15,6 +15,7 @@ module Remi::BusinessRules
15
15
  'windows' => "\r\n",
16
16
  'unix' => "\n",
17
17
  'windows or unix' => :auto,
18
+ 'null character' => 0.chr,
18
19
  }
19
20
  end
20
21
 
@@ -31,7 +32,7 @@ module Remi::BusinessRules
31
32
  end
32
33
 
33
34
  def formulas
34
- @formulas ||= Remi::Lookup::RegexSieve.new({
35
+ @formulas ||= RegexSieve.new({
35
36
  /(today|yesterday|tomorrow)/i => [:date_reference, :match_single_day],
36
37
  /(this|last|previous|next) (day|month|year|week)/i => [:date_reference, :match_single_unit],
37
38
  /(\d+)\s(day|days|month|months|year|years|week|weeks) (ago|from now)/i => [:date_reference, :match_multiple]
@@ -2,7 +2,6 @@ module Remi
2
2
  module Job
3
3
  module JobClassMethods
4
4
  attr_accessor :params
5
- attr_accessor :lookups
6
5
  attr_accessor :sources
7
6
  attr_accessor :targets
8
7
  attr_accessor :transforms
@@ -12,23 +11,6 @@ module Remi
12
11
  @params[key] = value
13
12
  end
14
13
 
15
- def define_lookup(name, type_class, options)
16
- @lookups ||= []
17
- @lookups << name
18
-
19
- define_method(name) do
20
- iv_name = instance_variable_get("@#{name}")
21
- return iv_name if iv_name
22
-
23
- if type_class == Hash
24
- lookup = options
25
- else
26
- lookup = type_class.new(options)
27
- end
28
- instance_variable_set("@#{name}", lookup)
29
- end
30
- end
31
-
32
14
  def define_source(name, type_class, **options)
33
15
  @sources ||= []
34
16
  @sources << name
@@ -69,10 +51,6 @@ module Remi
69
51
  @params || {}
70
52
  end
71
53
 
72
- def lookups
73
- @lookups || []
74
- end
75
-
76
54
  def sources
77
55
  @sources || []
78
56
  end
@@ -96,7 +74,6 @@ module Remi
96
74
  def included(receiver)
97
75
  receiver.extend(JobClassMethods)
98
76
  receiver.params = self.params.merge(receiver.params)
99
- receiver.lookups = self.lookups + receiver.lookups
100
77
  receiver.sources = self.sources + receiver.sources
101
78
  receiver.targets = self.targets + receiver.targets
102
79
  receiver.transforms = self.transforms.merge(receiver.transforms)
@@ -112,10 +89,6 @@ module Remi
112
89
  self.class.params
113
90
  end
114
91
 
115
- def lookups
116
- self.class.lookups
117
- end
118
-
119
92
  def sources
120
93
  self.class.sources
121
94
  end
@@ -50,9 +50,9 @@ module Remi
50
50
  end
51
51
  end
52
52
 
53
- def nvl
54
- memoize_as_lambda(__method__) do |*largs|
55
- Array(largs).find('') { |arg| !arg.blank? }
53
+ def nvl(default='')
54
+ memoize_as_lambda(__method__, default) do |(mdefault), *largs|
55
+ Array(largs).find(->() { mdefault }) { |arg| !arg.blank? }
56
56
  end
57
57
  end
58
58
 
@@ -1,3 +1,3 @@
1
1
  module Remi
2
- VERSION = '0.2.11'
2
+ VERSION = '0.2.12'
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.add_runtime_dependency 'docile', ['~> 1.1']
20
20
  s.add_runtime_dependency 'net-sftp', ['~> 2.1']
21
21
  s.add_runtime_dependency 'pg', ['~> 0.18']
22
+ s.add_runtime_dependency 'regex_sieve', ['~> 0.1']
22
23
 
23
24
  s.add_runtime_dependency "cucumber", ["~> 2.1"]
24
25
  s.add_runtime_dependency "rspec", ["~> 3.3"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.11
4
+ version: 0.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sterling Paramore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-10 00:00:00.000000000 Z
11
+ date: 2016-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daru
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.18'
83
+ - !ruby/object:Gem::Dependency
84
+ name: regex_sieve
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: cucumber
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -204,6 +218,7 @@ files:
204
218
  - features/support/env.rb
205
219
  - features/support/env_app.rb
206
220
  - features/transforms/date_diff.feature
221
+ - features/transforms/nvl.feature
207
222
  - features/transforms/parse_date.feature
208
223
  - features/transforms/prefix.feature
209
224
  - jobs/aggregate_job.rb
@@ -211,6 +226,7 @@ files:
211
226
  - jobs/copy_source_job.rb
212
227
  - jobs/sample_job.rb
213
228
  - jobs/transforms/date_diff_job.rb
229
+ - jobs/transforms/nvl_job.rb
214
230
  - jobs/transforms/parse_date_job.rb
215
231
  - jobs/transforms/prefix_job.rb
216
232
  - jobs/transforms/transform_jobs.rb
@@ -232,7 +248,6 @@ files:
232
248
  - lib/remi/extractor/sftp_file.rb
233
249
  - lib/remi/field_symbolizers.rb
234
250
  - lib/remi/job.rb
235
- - lib/remi/lookup/regex_sieve.rb
236
251
  - lib/remi/refinements/daru.rb
237
252
  - lib/remi/refinements/symbolizer.rb
238
253
  - lib/remi/settings.rb
@@ -276,5 +291,6 @@ test_files:
276
291
  - features/support/env.rb
277
292
  - features/support/env_app.rb
278
293
  - features/transforms/date_diff.feature
294
+ - features/transforms/nvl.feature
279
295
  - features/transforms/parse_date.feature
280
296
  - features/transforms/prefix.feature
@@ -1,55 +0,0 @@
1
- module Remi
2
- module Lookup
3
-
4
- # Public: RegexSieve class. The RegexSieve functions in a manner similar
5
- # a hash. The regex sieve is initialized with a hash where the keys are
6
- # regular expressions and the values can be any valid Ruby object. The order
7
- # of the keys matters. When the regex sieve is accessed using the array
8
- # accessor [], it returns the first matching record. By default, only
9
- # the values are returned, but the key and all matching capture groups
10
- # can optionally be returned.
11
- #
12
- # Examples:
13
- #
14
- # r = RegexSieve.new({
15
- # /something/ => 'Something',
16
- # /something else/ => 'This will never get matched because the one above will match first',
17
- # /cool$/ => 'Cool',
18
- # /cool beans/ => 'Really Cool'
19
- # })
20
- #
21
- # r['something else'] # => 'Something'
22
- # r['cool beans'] # => 'Really Cool'
23
- class RegexSieve
24
- def initialize(sieve)
25
- @sieve = sieve
26
- end
27
-
28
- # Public: Array accessor for Regex Sieve.
29
- #
30
- # key - The string that will be matched to the keys in the sieve.
31
- # opt - By default, only the values in the hash used to initialize the sieve
32
- # will be returned. However, if you want to return the keys or the
33
- # capture groups then use :regex, :match, or both, respectively.
34
- #
35
- # Example:
36
- # r['something'] # => 'Something
37
- # r['something', :regex] # => { value: 'Something', regex: /something/ }
38
- # r['sometinng', :match, :regex] # => { value: 'Something', regex: /something/, match: #<MatchData "something"> }
39
- def [](key, *opt)
40
- opt = opt | [:value]
41
-
42
- regex_match = nil
43
- found = @sieve.find do |regex, v|
44
- regex_match = regex.match(key)
45
- end
46
-
47
- return nil if found.nil?
48
- full_result = { value: found[1], regex: found[0], match: regex_match }
49
-
50
- full_result.select! { |k, v| opt.include?(k) }
51
- full_result.size > 1 ? full_result : full_result.values.first
52
- end
53
- end
54
- end
55
- end