remi 0.2.42 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +7 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -26
- data/README.md +1 -1
- data/features/step_definitions/remi_step.rb +33 -13
- data/features/sub_job_example.feature +24 -0
- data/features/sub_transform_example.feature +35 -0
- data/features/sub_transform_many_to_many.feature +49 -0
- data/features/support/env_app.rb +1 -1
- data/jobs/all_jobs_shared.rb +19 -16
- data/jobs/copy_source_job.rb +11 -9
- data/jobs/csv_file_target_job.rb +10 -9
- data/jobs/json_job.rb +18 -14
- data/jobs/metadata_job.rb +33 -28
- data/jobs/parameters_job.rb +14 -11
- data/jobs/sample_job.rb +106 -77
- data/jobs/sftp_file_target_job.rb +14 -13
- data/jobs/sub_job_example_job.rb +86 -0
- data/jobs/sub_transform_example_job.rb +43 -0
- data/jobs/sub_transform_many_to_many_job.rb +46 -0
- data/jobs/transforms/concatenate_job.rb +16 -12
- data/jobs/transforms/data_frame_sieve_job.rb +24 -19
- data/jobs/transforms/date_diff_job.rb +15 -11
- data/jobs/transforms/nvl_job.rb +16 -12
- data/jobs/transforms/parse_date_job.rb +17 -14
- data/jobs/transforms/partitioner_job.rb +27 -19
- data/jobs/transforms/prefix_job.rb +13 -10
- data/jobs/transforms/truncate_job.rb +14 -10
- data/jobs/transforms/truthy_job.rb +11 -8
- data/lib/remi.rb +25 -11
- data/lib/remi/data_frame.rb +4 -4
- data/lib/remi/data_frame/daru.rb +1 -37
- data/lib/remi/data_subject.rb +234 -48
- data/lib/remi/data_subjects/csv_file.rb +171 -0
- data/lib/remi/data_subjects/data_frame.rb +106 -0
- data/lib/remi/data_subjects/file_system.rb +115 -0
- data/lib/remi/data_subjects/local_file.rb +109 -0
- data/lib/remi/data_subjects/none.rb +31 -0
- data/lib/remi/data_subjects/postgres.rb +186 -0
- data/lib/remi/data_subjects/s3_file.rb +84 -0
- data/lib/remi/data_subjects/salesforce.rb +211 -0
- data/lib/remi/data_subjects/sftp_file.rb +196 -0
- data/lib/remi/data_subjects/sub_job.rb +50 -0
- data/lib/remi/dsl.rb +74 -0
- data/lib/remi/encoder.rb +45 -0
- data/lib/remi/extractor.rb +21 -0
- data/lib/remi/field_symbolizers.rb +1 -0
- data/lib/remi/job.rb +279 -113
- data/lib/remi/job/parameters.rb +90 -0
- data/lib/remi/job/sub_job.rb +35 -0
- data/lib/remi/job/transform.rb +165 -0
- data/lib/remi/loader.rb +22 -0
- data/lib/remi/monkeys/daru.rb +4 -0
- data/lib/remi/parser.rb +44 -0
- data/lib/remi/testing/business_rules.rb +17 -23
- data/lib/remi/testing/data_stub.rb +2 -2
- data/lib/remi/version.rb +1 -1
- data/remi.gemspec +3 -0
- data/spec/data_subject_spec.rb +475 -11
- data/spec/data_subjects/csv_file_spec.rb +69 -0
- data/spec/data_subjects/data_frame_spec.rb +52 -0
- data/spec/{extractor → data_subjects}/file_system_spec.rb +0 -0
- data/spec/{extractor → data_subjects}/local_file_spec.rb +0 -0
- data/spec/data_subjects/none_spec.rb +41 -0
- data/spec/data_subjects/postgres_spec.rb +80 -0
- data/spec/{extractor → data_subjects}/s3_file_spec.rb +0 -0
- data/spec/data_subjects/salesforce_spec.rb +117 -0
- data/spec/{extractor → data_subjects}/sftp_file_spec.rb +16 -0
- data/spec/data_subjects/sub_job_spec.rb +33 -0
- data/spec/encoder_spec.rb +38 -0
- data/spec/extractor_spec.rb +11 -0
- data/spec/fixtures/sf_bulk_helper_stubs.rb +443 -0
- data/spec/job/transform_spec.rb +257 -0
- data/spec/job_spec.rb +507 -0
- data/spec/loader_spec.rb +11 -0
- data/spec/parser_spec.rb +38 -0
- data/spec/sf_bulk_helper_spec.rb +117 -0
- data/spec/testing/data_stub_spec.rb +5 -3
- metadata +109 -27
- data/features/aggregate.feature +0 -42
- data/jobs/aggregate_job.rb +0 -31
- data/jobs/transforms/transform_jobs.rb +0 -4
- data/lib/remi/data_subject/csv_file.rb +0 -162
- data/lib/remi/data_subject/data_frame.rb +0 -52
- data/lib/remi/data_subject/postgres.rb +0 -134
- data/lib/remi/data_subject/salesforce.rb +0 -136
- data/lib/remi/data_subject/sftp_file.rb +0 -65
- data/lib/remi/extractor/file_system.rb +0 -92
- data/lib/remi/extractor/local_file.rb +0 -43
- data/lib/remi/extractor/s3_file.rb +0 -57
- data/lib/remi/extractor/sftp_file.rb +0 -83
- data/spec/data_subject/csv_file_spec.rb +0 -79
- data/spec/data_subject/data_frame.rb +0 -27
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
|
3
|
+
describe Parser::CsvFile do
|
4
|
+
|
5
|
+
let(:basic_file) { 'spec/fixtures/basic.csv' }
|
6
|
+
let(:basic_dataframe) do
|
7
|
+
Remi::DataFrame::Daru.new(
|
8
|
+
{
|
9
|
+
column_a: ['value 1A', 'value 2A'],
|
10
|
+
column_b: ['value 1B', 'value 2B']
|
11
|
+
}
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'converts a CSV into a dataframe' do
|
16
|
+
csv = Parser::CsvFile.new
|
17
|
+
expect(csv.parse(basic_file).to_a).to eq basic_dataframe.to_a
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'adds filename when requested' do
|
21
|
+
csv = Parser::CsvFile.new(
|
22
|
+
filename_field: :from_file
|
23
|
+
)
|
24
|
+
|
25
|
+
expected_files = [Pathname.new(basic_file).to_s] * 2
|
26
|
+
expect(csv.parse(basic_file)[:from_file].to_a).to eq expected_files
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'preprocesses records when required' do
|
30
|
+
csv = Parser::CsvFile.new(
|
31
|
+
preprocessor: ->(line) { line.gsub(/\\"/,'""') }
|
32
|
+
)
|
33
|
+
|
34
|
+
bad_escape_file = 'spec/fixtures/unsupported_escape.csv'
|
35
|
+
|
36
|
+
expected_df = Remi::DataFrame::Daru.new(
|
37
|
+
{
|
38
|
+
column_a: ['value 1A', 'value 2A'],
|
39
|
+
column_b: ['value "1B"', 'value "2B"']
|
40
|
+
}
|
41
|
+
)
|
42
|
+
expect(csv.parse(bad_escape_file).to_a).to eq expected_df.to_a
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'accepts standard Ruby CSV options' do
|
46
|
+
csv = Parser::CsvFile.new(
|
47
|
+
preprocessor: ->(line) { line.gsub(/,/,'|') },
|
48
|
+
csv_options: { col_sep: '|' }
|
49
|
+
)
|
50
|
+
|
51
|
+
expect(csv.parse(basic_file).to_a).to eq basic_dataframe.to_a
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'combines multiple csv files into a single dataframe' do
|
55
|
+
csv = Parser::CsvFile.new
|
56
|
+
two_files = ['spec/fixtures/basic.csv', 'spec/fixtures/basic2.csv']
|
57
|
+
|
58
|
+
expected_df = Remi::DataFrame::Daru.new(
|
59
|
+
{
|
60
|
+
column_a: ['value 1A', 'value 2A', 'value 1A', 'value 2A'],
|
61
|
+
column_b: ['value 1B', 'value 2B', nil, nil],
|
62
|
+
column_c: [nil, nil, 'value 1C', 'value 2C']
|
63
|
+
}
|
64
|
+
)
|
65
|
+
|
66
|
+
expect(csv.parse(two_files).to_a).to eq expected_df.to_a
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
|
3
|
+
describe Extractor::DataFrame do
|
4
|
+
let(:extractor) { Extractor::DataFrame.new(data: data) }
|
5
|
+
let(:data) { 'some_data' }
|
6
|
+
|
7
|
+
context '#data' do
|
8
|
+
it 'returns the raw data' do
|
9
|
+
expect(extractor.extract.data).to eq data
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Parser::DataFrame do
|
15
|
+
let(:fields) do
|
16
|
+
{
|
17
|
+
brewer: { type: 'text' },
|
18
|
+
style: { type: 'text' }
|
19
|
+
}
|
20
|
+
end
|
21
|
+
let(:parser) { Parser::DataFrame.new(fields: fields) }
|
22
|
+
let(:df_extract) { double('df_extract') }
|
23
|
+
let(:data) {
|
24
|
+
[
|
25
|
+
[ 'Baerlic', 'IPA' ],
|
26
|
+
[ 'Ex Novo', 'Red' ]
|
27
|
+
]
|
28
|
+
}
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(df_extract).to receive(:data) { data }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'converts the data array into a dataframe' do
|
35
|
+
expect(parser.parse df_extract).to be_a Remi::DataFrame::Daru
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'converts the data array into the dataframe' do
|
39
|
+
expected_df = Daru::DataFrame.new(
|
40
|
+
:brewer => ['Baerlic', 'Ex Novo'],
|
41
|
+
:style => ['IPA', 'Red']
|
42
|
+
)
|
43
|
+
expect(parser.parse(df_extract).to_a).to eq expected_df.to_a
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe Encoder::DataFrame, skip: 'todo' do
|
49
|
+
end
|
50
|
+
|
51
|
+
describe Loader::DataFrame, skip: 'todo' do
|
52
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
|
3
|
+
describe Extractor::None do
|
4
|
+
let(:extractor) { Extractor::None.new }
|
5
|
+
|
6
|
+
context '#extract' do
|
7
|
+
it 'does nothing' do
|
8
|
+
expect(extractor.extract).to be nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Parser::None do
|
14
|
+
let(:parser) { Parser::None.new }
|
15
|
+
|
16
|
+
context '#parse' do
|
17
|
+
it 'returns what it is given' do
|
18
|
+
expect(parser.parse('some data')).to eq 'some data'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Encoder::None do
|
24
|
+
let(:encoder) { Encoder::None.new }
|
25
|
+
|
26
|
+
context '#encode' do
|
27
|
+
it 'returns what it is given' do
|
28
|
+
expect(encoder.encode('some data')).to eq 'some data'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Loader::None do
|
34
|
+
let(:loader) { Loader::None.new }
|
35
|
+
|
36
|
+
context '#loader' do
|
37
|
+
it 'does nothing' do
|
38
|
+
expect(loader.load('some data')).to be true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
|
3
|
+
describe Extractor::Postgres do
|
4
|
+
let(:extractor) { Extractor::Postgres.new(credentials: {}, query: 'some_query') }
|
5
|
+
let(:pg_conn) { double('pg_conn') }
|
6
|
+
let(:data) { 'some postgres data' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(pg_conn).to receive(:exec) { data }
|
10
|
+
allow(extractor).to receive(:connection) { pg_conn }
|
11
|
+
end
|
12
|
+
|
13
|
+
context '#data' do
|
14
|
+
it 'returns extracted data' do
|
15
|
+
expect(extractor.extract.data).to eq data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe Parser::Postgres do
|
22
|
+
let(:parser) { Parser::Postgres.new }
|
23
|
+
let(:pg_extract) { double('pg_extract') }
|
24
|
+
let(:data) do
|
25
|
+
[
|
26
|
+
{ 'brewer' => 'Baerlic', 'style' => 'IPA', 'quantity' => 5 },
|
27
|
+
{ 'brewer' => 'Ex Novo', 'style' => 'Red', 'quantity' => 3 }
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
allow(pg_extract).to receive(:data) { data }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'converts postgres response data into a dataframe' do
|
36
|
+
expect(parser.parse pg_extract).to be_a Remi::DataFrame::Daru
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'converted data into the correct dataframe' do
|
40
|
+
expected_df = Daru::DataFrame.new(
|
41
|
+
:brewer => ['Baerlic', 'Ex Novo'],
|
42
|
+
:style => ['IPA', 'Red'],
|
43
|
+
:quantity => [5, 3]
|
44
|
+
)
|
45
|
+
expect(parser.parse(pg_extract).to_a).to eq expected_df.to_a
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
describe Encoder::Postgres do
|
51
|
+
let(:fields) do
|
52
|
+
{
|
53
|
+
brewer: { type: 'text' },
|
54
|
+
style: { type: 'text' },
|
55
|
+
quantity: { type: 'integer' }
|
56
|
+
}
|
57
|
+
end
|
58
|
+
let(:encoder) { Encoder::Postgres.new(fields: fields) }
|
59
|
+
let(:dataframe) do
|
60
|
+
expected_df = Daru::DataFrame.new(
|
61
|
+
:brewer => ['Baerlic', 'Ex Novo'],
|
62
|
+
:style => ['IPA', 'Red'],
|
63
|
+
:quantity => [5, 3]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'converts the dataframe into an array of strings to be used by the loader' do
|
68
|
+
expect(encoder.encode(dataframe).values).to eq [
|
69
|
+
"Baerlic\tIPA\t5",
|
70
|
+
"Ex Novo\tRed\t3"
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'builds the field ddl' do
|
75
|
+
expect(encoder.encode(dataframe).ddl_fields).to eq 'brewer text, style text, quantity integer'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe Loader::Postgres, skip: 'todo' do
|
80
|
+
end
|
File without changes
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
require 'remi/data_subjects/salesforce.rb'
|
3
|
+
|
4
|
+
describe Extractor::Salesforce do
|
5
|
+
let(:extractor) { Extractor::Salesforce.new(object: :Contact, credentials: {}, query: '') }
|
6
|
+
let(:sf_bulk) { double('sf_bulk') }
|
7
|
+
let(:data) do
|
8
|
+
{
|
9
|
+
'batches' => [
|
10
|
+
{
|
11
|
+
'id' => ['751160000065e2BAAQ'],
|
12
|
+
'state' => [ 'Completed' ]
|
13
|
+
}
|
14
|
+
]
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow(extractor).to receive(:sf_bulk) { sf_bulk }
|
20
|
+
allow(sf_bulk).to receive(:query) { data }
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#data' do
|
24
|
+
it 'returns extracted data' do
|
25
|
+
expect(extractor.extract.data).to eq data
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
it 'raises an error if the batch fails' do
|
31
|
+
data['batches'].first['state'] = ['Error']
|
32
|
+
expect { extractor.extract }.to raise_error Extractor::Salesforce::ExtractError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
describe Parser::Salesforce do
|
38
|
+
let(:parser) { Parser::Salesforce.new }
|
39
|
+
let(:sf_extract) { double('sf_extract') }
|
40
|
+
let(:data) do
|
41
|
+
{
|
42
|
+
'batches' => [
|
43
|
+
{
|
44
|
+
'id' => ['751160000065e2BAAQ'],
|
45
|
+
'state' => [ 'Completed' ],
|
46
|
+
'response' => [
|
47
|
+
{
|
48
|
+
"xsi:type" => "sObject",
|
49
|
+
"type" => [
|
50
|
+
"Contact"
|
51
|
+
],
|
52
|
+
"Id" => [
|
53
|
+
"003G000001cKYaUIA4",
|
54
|
+
"003G000001cKYaUIA4"
|
55
|
+
],
|
56
|
+
"Student_ID__c" => [
|
57
|
+
"FJD385628"
|
58
|
+
]
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"xsi:type" => "sObject",
|
62
|
+
"type" => [
|
63
|
+
"Contact"
|
64
|
+
],
|
65
|
+
"Id" => [
|
66
|
+
"003G000001cKYbXIA4",
|
67
|
+
"003G000001cKYbXIA4"
|
68
|
+
],
|
69
|
+
"Student_ID__c" => [
|
70
|
+
{ 'xsi:nil' => 'true' }
|
71
|
+
]
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
]
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
before do
|
80
|
+
allow(sf_extract).to receive(:data) { data }
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'converts SalesforceBulkApi response data into a dataframe' do
|
84
|
+
expect(parser.parse sf_extract).to be_a Remi::DataFrame::Daru
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'converted data into the correct dataframe' do
|
88
|
+
expected_df = Daru::DataFrame.new(
|
89
|
+
:Id => ['003G000001cKYaUIA4', '003G000001cKYbXIA4'],
|
90
|
+
:Student_ID__c => ['FJD385628', nil]
|
91
|
+
)
|
92
|
+
expect(parser.parse(sf_extract).to_a).to eq expected_df.to_a
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
describe Encoder::Salesforce do
|
98
|
+
let(:encoder) { Encoder::Salesforce.new }
|
99
|
+
let(:dataframe) do
|
100
|
+
Daru::DataFrame.new(
|
101
|
+
:Id => ['003G000001cKYaUIA4', '003G000001cKYbXIA4'],
|
102
|
+
:Student_ID__c => ['FJD385628', nil]
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'converts the dataframe into an array of hashes' do
|
107
|
+
expected_result = [
|
108
|
+
{ :Id => '003G000001cKYaUIA4', :Student_ID__c => 'FJD385628' },
|
109
|
+
{ :Id => '003G000001cKYbXIA4', :Student_ID__c => nil },
|
110
|
+
]
|
111
|
+
expect(encoder.encode dataframe).to eq expected_result
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
describe Loader::Salesforce, skip: 'todo' do
|
117
|
+
end
|
@@ -82,3 +82,19 @@ describe Extractor::SftpFile do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
|
87
|
+
describe Loader::SftpFile do
|
88
|
+
let(:loader) { Loader::SftpFile.new(credentials: {}, remote_path: 'some_path') }
|
89
|
+
let(:data) { double('some_data') }
|
90
|
+
let(:sftp_session) { instance_double('Net:SFTP::Session') }
|
91
|
+
|
92
|
+
before do
|
93
|
+
allow(Net::SFTP).to receive(:start).and_yield sftp_session
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'loads a csv to a target sftp filesystem' do
|
97
|
+
expect(sftp_session).to receive(:upload!).with(data, 'some_path')
|
98
|
+
loader.load data
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../remi_spec'
|
2
|
+
|
3
|
+
describe 'sub jobs' do
|
4
|
+
before :each do
|
5
|
+
Object.send(:remove_const, :MySubJob) if Object.constants.include?(:MySubJob)
|
6
|
+
class MySubJob < Job
|
7
|
+
source(:sub_source) {}
|
8
|
+
target(:sub_target) {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:sub_job) { Job::SubJob.new { MySubJob.new } }
|
13
|
+
|
14
|
+
|
15
|
+
describe Extractor::SubJob do
|
16
|
+
let(:extractor) { Extractor::SubJob.new(sub_job: sub_job, data_subject: :sub_target) }
|
17
|
+
|
18
|
+
it 'returns the data from the sub-job' do
|
19
|
+
allow(sub_job.job.sub_target).to receive(:df) { 'sub target df' }
|
20
|
+
expect(extractor.extract).to eq 'sub target df'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Loader::SubJob do
|
25
|
+
let(:loader) { Loader::SubJob.new(sub_job: sub_job, data_subject: :sub_source) }
|
26
|
+
|
27
|
+
it 'populates the sub-job data frame' do
|
28
|
+
some_data_frame = Daru::DataFrame.new({ a: [1,2,3] })
|
29
|
+
loader.load(some_data_frame)
|
30
|
+
expect(sub_job.job.sub_source.df).to eq some_data_frame
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'remi_spec'
|
2
|
+
|
3
|
+
describe Remi::Encoder do
|
4
|
+
let(:field_symbolizer) { double('field_symbolizer') }
|
5
|
+
let(:context) { double('context') }
|
6
|
+
let(:fields) { double('fields') }
|
7
|
+
let(:encoder) { Encoder.new(context: context, fields: fields, field_symbolizer: field_symbolizer) }
|
8
|
+
|
9
|
+
context '#encode' do
|
10
|
+
it 'has an encode method' do
|
11
|
+
expect(encoder).respond_to? :encode
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context '#field_symbolizer' do
|
16
|
+
it 'can be set in the constructor' do
|
17
|
+
expect(encoder.field_symbolizer).to eq field_symbolizer
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'the field_symbolizer defined in the context takes priority' do
|
21
|
+
symbolizer_from_context = double('symbolizer_from_context')
|
22
|
+
allow(context).to receive(:field_symbolizer) { symbolizer_from_context }
|
23
|
+
expect(encoder.field_symbolizer).to eq symbolizer_from_context
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context '#fields' do
|
28
|
+
it 'can be set in the constructor' do
|
29
|
+
expect(encoder.fields).to eq fields
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'the field_symbolizer defined in the context takes priority' do
|
33
|
+
fields_from_context = double('fields_from_context')
|
34
|
+
allow(context).to receive(:fields) { fields_from_context }
|
35
|
+
expect(encoder.fields).to eq fields_from_context
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|