remi 0.2.11 → 0.2.12

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