remi 0.2.6 → 0.2.7

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: 2c802335b8494b30ff89e4c31b1ce4df34b2fc8a
4
- data.tar.gz: b405fbefb668bf07db5bcbb4a0cf6d8550658f13
3
+ metadata.gz: 0bb16e0f2dccad23e3473e60a9a83445f6eb0128
4
+ data.tar.gz: f362f1d884d7c904cefadccf8d56899bfd334e1d
5
5
  SHA512:
6
- metadata.gz: e2380bbb4cc87d67cfdb554763f8614cfcc791ceb3b70f711ed2fb975dcaf142438f2937453734479a43d3735ea61c8bcb4e093e3f380b5ae107e2dba5fe9522
7
- data.tar.gz: 56f42c6b3608157959713478fbeee5cea4898238a6af176ab0b632cc0bb75ec5c60c66fe0ad60b45f6483aee09bb2943ddfabe586a88ef223ceaf9349eeded07
6
+ metadata.gz: 4f57654405b399951ddf657c20779bab7801d3d59bef03c4452f0e3a74acfe5eb22b0a5aea699b2f00761529126df903fda07640c6a73e6dff93720d9d0db7ff
7
+ data.tar.gz: 10f4f6675c25fa25898c0637eea43eb67323d5215a5eb95cf43a4adcdb6a01f3cd953c2f2f1712600ec4a21fc94655637346ece3d7823639f1d2f3a64f6db7b4
@@ -27,7 +27,7 @@ module Remi::BusinessRules
27
27
  end
28
28
 
29
29
  def base_regex
30
- @base_regex ||= /\A\*(.*)\*\Z/
30
+ @base_regex ||= /\*(.*)\*/
31
31
  end
32
32
 
33
33
  def formulas
@@ -44,9 +44,14 @@ module Remi::BusinessRules
44
44
  form_opt = formulas[form, :match]
45
45
  raise "Unknown formula #{form}" unless form_opt
46
46
 
47
- if form_opt[:value][0] == :date_reference
47
+ to_replace = form.match(base_regex)[0]
48
+ replace_with = if form_opt[:value][0] == :date_reference
48
49
  date_reference(form_opt[:value][1], form_opt[:match])
50
+ else
51
+ to_replace
49
52
  end
53
+
54
+ form.gsub(to_replace, replace_with)
50
55
  end
51
56
 
52
57
 
@@ -245,6 +250,34 @@ module Remi::BusinessRules
245
250
  end
246
251
 
247
252
 
253
+ # Would like to have this return a new DataSubject and not a dataframe.
254
+ # Need more robust duping to make that feasible.
255
+ # Don't use results for anything more than size.
256
+ def where(field_name, operation)
257
+ @data_obj.df.where(@data_obj.df[field_name.symbolize(@data_obj.field_symbolizer)].recode { |v| operation.call(v) })
258
+ end
259
+
260
+ def where_is(field_name, value)
261
+ where(field_name, ->(v) { v == value })
262
+ end
263
+
264
+ def where_lt(field_name, value)
265
+ where(field_name, ->(v) { v.to_f < value.to_f })
266
+ end
267
+
268
+ def where_gt(field_name, value)
269
+ where(field_name, ->(v) { v.to_f > value.to_f })
270
+ end
271
+
272
+ def where_between(field_name, low_value, high_value)
273
+ where(field_name, ->(v) { v.to_f.between?(low_value.to_f, high_value.to_f) })
274
+ end
275
+
276
+ def where_in(field_name, list)
277
+ list_array = list.split(',').map { |v| v.strip }
278
+ where(field_name, ->(v) { list_array.include?(v) })
279
+ end
280
+
248
281
 
249
282
  def stub_data
250
283
  @data_obj.stub_df if @data_obj.respond_to? :stub_df
@@ -59,5 +59,9 @@ module Remi
59
59
  class Salesforce
60
60
  include DataStub
61
61
  end
62
+
63
+ class DataFrame
64
+ include DataStub
65
+ end
62
66
  end
63
67
  end
@@ -3,8 +3,14 @@ module Remi
3
3
  class DataFrame
4
4
  include DataSubject
5
5
 
6
- def initialize(**args)
6
+ def initialize(fields: {}, **args)
7
+ @fields = fields
7
8
  end
9
+
10
+ def df
11
+ @dataframe ||= Daru::DataFrame.new([], order: @fields.keys)
12
+ end
13
+
8
14
  end
9
15
  end
10
16
  end
@@ -22,3 +22,28 @@ Feature: This tests the creation of example records.
22
22
  | *Yesterday* | *3 days from now* |
23
23
  Then the target field 'Yesterday' is the date 1 day ago
24
24
  And the target field 'ThreeDaysFromNow' is the date 3 days from now
25
+
26
+ Scenario: Counting the number of records.
27
+ Given the following example record for 'Source Data':
28
+ | Id | Name |
29
+ | 1 | Alpha |
30
+ | 2 | Beta |
31
+ | 3 | Gamma |
32
+ Then the target has 3 records
33
+ Then the target 'Target Data' has 3 records
34
+
35
+ Scenario: Counting the number of recors that satisfy some condition.
36
+ Given the following example record for 'Source Data':
37
+ | Id | Name | Category | Quantity |
38
+ | 1 | Alpha | Small | 0.5 |
39
+ | 2 | Beta | Small | 0.7 |
40
+ | 3 | Gamma | Big | 30 |
41
+ | 4 | Delta | Big | 38 |
42
+ | 5 | Epsilon | Normal | 1 |
43
+ Then the target has 2 records where 'Category' is "Small"
44
+ And the target has 3 records where 'Category' is in "Small, Normal"
45
+ And the target has 1 record where 'Quantity' is 0.7
46
+ And the target has 2 records where 'Quantity' is less than 1
47
+ And the target has 3 records where 'Quantity' is greater than 0.9
48
+ And the target has 3 records where 'Quantity' is between 0 and 1
49
+ And the target has 2 records where 'Quantity' is between 0.6 and 2
@@ -1,4 +1,5 @@
1
1
  Feature: This tests the creation of example records.
2
+ The job that runs does nothing but copy source data to target.
2
3
 
3
4
  Background:
4
5
  Given the job is 'Copy Source'
@@ -55,14 +56,20 @@ Feature: This tests the creation of example records.
55
56
  And the target field 'SevenWeeksAgo' is the date 7 weeks ago
56
57
  And the target field 'ThreeWeeksFromNow' is the date 3 weeks from now
57
58
 
58
- Scenario: Handling date formulas when set explicitly in the source.
59
+ Scenario: Handling date formulas when set outside of a data example.
59
60
 
60
- Given the following example record for 'Source Data':
61
- | SomeDate |
62
- | 2015-10-22 |
63
- And the source field 'SomeDate' is set to the value "*Yesterday*"
64
- Then the target field 'SomeDate' is the date 1 day ago
61
+ Given the source field 'Some Date' is set to the value "*Yesterday*"
62
+ Then the target field 'Some Date' is the date 1 day ago
63
+
64
+ When the source field 'Some Date' is set to the value "*2 months from now*"
65
+ Then the target field 'Some Date' is the date 2 months from now
66
+ Then the target field 'Some Date' is populated with "*2 months from now*"
65
67
 
66
- When the source field 'SomeDate' is set to the value "*2 months from now*"
67
- Then the target field 'SomeDate' is the date 2 months from now
68
- Then the target field 'SomeDate' is populated with "*2 months from now*"
68
+ Scenario: Handling a date formula that is embedded in a larger string.
69
+ Given the following example record for 'Source Data':
70
+ | Some Date | Some String | Combination |
71
+ | *Today* | Something | *Today*-Something |
72
+ And the source field 'Some Date'
73
+ And the source field 'Some String'
74
+ And the target field 'Combination'
75
+ Then the target field is a concatenation of 'Some Date' and 'Some String', delimited by "-"
@@ -15,7 +15,7 @@ Given /^the job target '([[:alnum:]\s\-_]+)'$/ do |arg|
15
15
  @brt.add_job_target arg
16
16
  end
17
17
 
18
- Given /^the following example record called '([[:alnum:]\s\-_]+)':$/ do |arg, example_table|
18
+ Given /^the following example(?: record| records|) called '([[:alnum:]\s\-_]+)':$/ do |arg, example_table|
19
19
  @brt.add_example arg, example_table
20
20
  end
21
21
 
@@ -25,7 +25,7 @@ end
25
25
 
26
26
  ### Setting up example data
27
27
 
28
- Given /^the following example record for '([[:alnum:]\s\-_]+)':$/ do |source_name, example_table|
28
+ Given /^the following example(?: record| records|) for '([[:alnum:]\s\-_]+)':$/ do |source_name, example_table|
29
29
  example_name = source_name
30
30
  @brt.add_example example_name, example_table
31
31
  @brt.job_sources[source_name].stub_data_with(@brt.examples[example_name])
@@ -197,6 +197,15 @@ Then /^the target field '(.+)' is (?:set to the value|populated with) "([^"]*)"$
197
197
  expect(@brt.targets.fields[target_field].values.uniq).to eq [Remi::BusinessRules::ParseFormula.parse(value)]
198
198
  end
199
199
 
200
+ Then /^the target field '(.+)' is in the list "([^"]*)"$/ do |target_field, list|
201
+ step "the target field '#{target_field}'"
202
+
203
+ list_array = list.split(',').map(&:strip)
204
+ @brt.run_transforms
205
+ expect(@brt.targets.fields[target_field].values.uniq & list_array).to include(*@brt.targets.fields[target_field].values.uniq)
206
+ end
207
+
208
+
200
209
  Then /^the target field '(.+)' is the date (.+)$/ do |target_field, date_reference|
201
210
  step "the target field '#{target_field}' is set to the value \"*#{date_reference}*\""
202
211
  end
@@ -229,6 +238,12 @@ Then /^the target field is a concatenation of the source fields, delimited by "(
229
238
  expect(@brt.targets.fields.values.uniq).to eq concatenated_source
230
239
  end
231
240
 
241
+ Then /^the target field is a concatenation of '(.+)' and '(.+)', delimited by "([^"]*)"$/ do |source_field_1, source_field_2, delimiter|
242
+ expected_value = [@brt.sources.fields[source_field_1].value, @brt.sources.fields[source_field_2].value].join(delimiter)
243
+ @brt.run_transforms
244
+ expect(@brt.targets.fields.values.uniq).to eq [[expected_value]]
245
+ end
246
+
232
247
  Then /^the target field is a concatenation of "([^"]*)" and '(.+)', delimited by "([^"]*)"$/ do |constant, source_field, delimiter|
233
248
  expected_value = [constant, @brt.sources.fields[source_field].value].join(delimiter)
234
249
  @brt.run_transforms
@@ -295,8 +310,8 @@ end
295
310
 
296
311
  ### Record-level expectations
297
312
 
298
- Then /^the record should be (?i)(Retained|Rejected)(?-i)(?: without error|)$/ do |action|
299
- source_size = @brt.source.size
313
+ Then /^the record from source '(.+)' should be (?i)(Retained|Rejected)(?-i)(?: without error|)$/ do |source_name, action|
314
+ source_size = @brt.sources[source_name].size
300
315
  @brt.run_transforms
301
316
  targets_size = @brt.targets.total_size
302
317
 
@@ -310,7 +325,12 @@ Then /^the record should be (?i)(Retained|Rejected)(?-i)(?: without error|)$/ do
310
325
  end
311
326
  end
312
327
 
313
- Then /^the record should (not be|be) present on the target$/ do |action|
328
+ Then /^the record(?:s|) should be (?i)(Retained|Rejected)(?-i)(?: without error|)$/ do |action|
329
+ source_name = @brt.sources.keys.first
330
+ step "the record from source '#{source_name}' should be #{action}"
331
+ end
332
+
333
+ Then /^the record(?:s|) should (not be|be) present on the target$/ do |action|
314
334
  map_action = { 'not be' => 'rejected', 'be' => 'retained' }
315
335
  step "the record should be #{map_action[action]}"
316
336
  end
@@ -324,3 +344,68 @@ Then /^a target record is not created$/ do
324
344
  @brt.run_transforms
325
345
  expect(@brt.targets.total_size).to be 0
326
346
  end
347
+
348
+
349
+ ### Record counting
350
+
351
+ Then /^the target has (\d+) record(?:s|)$/ do |nrecords|
352
+ target_name = @brt.targets.keys.first
353
+ step "the target '#{target_name}' has #{nrecords} records"
354
+ end
355
+
356
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|)$/ do |target_name, nrecords|
357
+ @brt.run_transforms
358
+ expect(@brt.targets[target_name].size).to be nrecords.to_i
359
+ end
360
+
361
+ Then /^the target has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is "([^"]*)"$/ do |nrecords, field_name, value|
362
+ target_name = @brt.targets.keys.first
363
+ step "the target '#{target_name}' has #{nrecords} records where '#{field_name}' is \"#{value}\""
364
+ end
365
+
366
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is "([^"]*)"$/ do |target_name, nrecords, field_name, value|
367
+ @brt.run_transforms
368
+ expect(@brt.targets[target_name].where_is(field_name, value).size).to eq nrecords.to_i
369
+ end
370
+
371
+ Then /^the target has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is in "([^"]*)"$/ do |nrecords, field_name, value|
372
+ target_name = @brt.targets.keys.first
373
+ step "the target '#{target_name}' has #{nrecords} records where '#{field_name}' is in \"#{value}\""
374
+ end
375
+
376
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is in "([^"]*)"$/ do |target_name, nrecords, field_name, value|
377
+ @brt.run_transforms
378
+ expect(@brt.targets[target_name].where_in(field_name, value).size).to eq nrecords.to_i
379
+ end
380
+
381
+ Then /^the target has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is (\d*\.?\d+)$/ do |nrecords, field_name, value|
382
+ target_name = @brt.targets.keys.first
383
+ step "the target '#{target_name}' has #{nrecords} records where '#{field_name}' is #{value}"
384
+ end
385
+
386
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is (\d*\.?\d+)$/ do |target_name, nrecords, field_name, value|
387
+ @brt.run_transforms
388
+ expect(@brt.targets[target_name].where_is(field_name, value).size).to eq nrecords.to_i
389
+ end
390
+
391
+ Then /^the target has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is (less|greater) than (\d*\.?\d+)$/ do |nrecords, field_name, direction, value|
392
+ target_name = @brt.targets.keys.first
393
+ step "the target '#{target_name}' has #{nrecords} records where '#{field_name}' is #{direction} than #{value}"
394
+ end
395
+
396
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is (less|greater) than (\d*\.?\d+)$/ do |target_name, nrecords, field_name, direction, value|
397
+ @brt.run_transforms
398
+ query_method = { 'less' => :where_lt, 'greater' => :where_gt }[direction]
399
+
400
+ expect(@brt.targets[target_name].send(query_method, field_name, value).size).to eq nrecords.to_i
401
+ end
402
+
403
+ Then /^the target has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is between (\d*\.?\d+) and (\d*\.?\d+)$/ do |nrecords, field_name, low_value, high_value|
404
+ target_name = @brt.targets.keys.first
405
+ step "the target '#{target_name}' has #{nrecords} records where '#{field_name}' is between #{low_value} and #{high_value}"
406
+ end
407
+
408
+ Then /^the target '([[:alnum:]\s\-_]+)' has (\d+) record(?:s|) where '([[:alnum:]\s\-_]+)' is between (\d*\.?\d+) and (\d*\.?\d+)$/ do |target_name, nrecords, field_name, low_value, high_value|
409
+ @brt.run_transforms
410
+ expect(@brt.targets[target_name].where_between(field_name, low_value, high_value).size).to eq nrecords.to_i
411
+ end
@@ -7,9 +7,6 @@ Feature: Tests the date_diff transform
7
7
 
8
8
  And the source 'Source Data'
9
9
  And the target 'Target Data'
10
- And the following example record for 'Source Data':
11
- | Date1 | Date2 |
12
- | 2015-12-31 | 2016-01-02 |
13
10
 
14
11
  Scenario Outline: Calculating date difference in days2.
15
12
  Given the job parameter 'measure' is "days"
@@ -7,9 +7,6 @@ Feature: Tests the parse_date transform
7
7
 
8
8
  And the source 'Source Data'
9
9
  And the target 'Target Data'
10
- And the following example record for 'Source Data':
11
- | Date String |
12
- | 2015-12-31 |
13
10
 
14
11
  Scenario Outline: Parsing date strings.
15
12
  Given the source field 'Date String' has the value "<Date String>"
@@ -5,11 +5,8 @@ Feature: Test the prefix transformer.
5
5
  And the job source 'Source Data'
6
6
  And the job target 'Target Data'
7
7
 
8
-
9
8
  Scenario: Prefixing a field.
10
9
  Given the source 'Source Data'
11
10
  And the target 'Target Data'
12
- Given the following example record for 'Source Data':
13
- | Field |
14
- | something |
15
- Then the target field 'Field' is set to the value "prefixsomething"
11
+ And the source field 'My Field' is set to the value "something"
12
+ Then the target field 'Prefixed Field' is set to the value "prefixsomething"
@@ -4,7 +4,11 @@ class CopySourceJob
4
4
  include AllJobsShared
5
5
  using Remi::Refinements::Daru
6
6
 
7
- define_source :source_data, Remi::DataSource::DataFrame
7
+ define_source :source_data, Remi::DataSource::DataFrame,
8
+ fields: {
9
+ :some_field => {},
10
+ :some_date => { type: :date, format: '%Y-%m-%d' }
11
+ }
8
12
  define_source :target_data, Remi::DataSource::DataFrame
9
13
 
10
14
  define_transform :main, sources: :source_data, targets: :target_data do
@@ -4,7 +4,11 @@ class DateDiffJob
4
4
  include AllJobsShared
5
5
 
6
6
  define_param :measure, :days
7
- define_source :source_data, Remi::DataSource::DataFrame
7
+ define_source :source_data, Remi::DataSource::DataFrame,
8
+ fields: {
9
+ :date1 => { type: :date, format: '%Y-%m-%d' },
10
+ :date2 => { type: :date, format: '%Y-%m-%d' }
11
+ }
8
12
  define_target :target_data, Remi::DataTarget::DataFrame
9
13
 
10
14
  define_transform :main, sources: :source_data, targets: :target_data do
@@ -5,7 +5,10 @@ class ParseDateJob
5
5
 
6
6
  define_param :format, '%Y-%m-%d'
7
7
  define_param :if_blank, nil
8
- define_source :source_data, Remi::DataSource::DataFrame
8
+ define_source :source_data, Remi::DataSource::DataFrame,
9
+ fields: {
10
+ :date_string => {}
11
+ }
9
12
  define_target :target_data, Remi::DataTarget::DataFrame
10
13
 
11
14
  define_transform :main, sources: :source_data, targets: :target_data do
@@ -4,12 +4,15 @@ class PrefixJob
4
4
  include AllJobsShared
5
5
 
6
6
  define_param :prefix, 'prefix'
7
- define_source :source_data, Remi::DataSource::DataFrame
7
+ define_source :source_data, Remi::DataSource::DataFrame,
8
+ fields: {
9
+ :my_field => {}
10
+ }
8
11
  define_target :target_data, Remi::DataTarget::DataFrame
9
12
 
10
13
  define_transform :main, sources: :source_data, targets: :target_data do
11
14
  Remi::SourceToTargetMap.apply(source_data.df, target_data.df) do
12
- map source(:field) .target(:field)
15
+ map source(:my_field) .target(:prefixed_field)
13
16
  .transform(Remi::Transform[:prefix].(params[:prefix]))
14
17
  end
15
18
  end
@@ -1,3 +1,3 @@
1
1
  module Remi
2
- VERSION = '0.2.6'
2
+ VERSION = '0.2.7'
3
3
  end
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.6
4
+ version: 0.2.7
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-01-25 00:00:00.000000000 Z
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daru