hash_engine 0.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.
@@ -0,0 +1,146 @@
1
+ # encoding: utf-8
2
+ require 'hash_engine'
3
+
4
+ describe HashEngine do
5
+ describe 'valid_action?' do
6
+ it 'returns true when key exists' do
7
+ HashEngine.valid_action?('first_value').should be_true
8
+ end
9
+
10
+ it 'returns false when key does not exist' do
11
+ HashEngine.valid_action?('foo').should be_false
12
+ end
13
+ end
14
+
15
+ describe 'action' do
16
+ describe 'of type: proc' do
17
+ describe 'with data as an array' do
18
+ it 'returns nil when there is a nil in the data' do
19
+ HashEngine.action('proc', 'proc {|x, y| x[1..3]}', [nil, :key1]).should == nil
20
+ end
21
+
22
+ it 'returns the result of the proc' do
23
+ my_proc = Proc.new {|x| x[0..2]}
24
+ HashEngine.action('proc', my_proc, ['foobar']).should == 'foo'
25
+ end
26
+
27
+ it 'returns the result of the string evaluated to be a proc' do
28
+ HashEngine.action('proc', 'proc {|x| x[0..2]}', ['foobar']).should == 'foo'
29
+ end
30
+ end
31
+
32
+ describe 'with data as a single value' do
33
+ it 'returns nil when there is a nil in the data' do
34
+ HashEngine.action('proc', 'proc {|x, y| x[1..3]}', nil).should == nil
35
+ end
36
+
37
+ it 'returns the result of the proc' do
38
+ my_proc = Proc.new {|x| x[0..2]}
39
+ HashEngine.action('proc', my_proc, 'foobar').should == 'foo'
40
+ end
41
+
42
+ it 'returns the result of the string evaluated to be a proc' do
43
+ HashEngine.action('proc', 'proc {|x| x[0..2]}', 'foobar').should == 'foo'
44
+ end
45
+ end
46
+ end
47
+
48
+ describe 'of type: unprotected_proc' do
49
+ describe 'with data as an array' do
50
+ it 'returns the result of the proc' do
51
+ my_proc = Proc.new {|x| x.nil? ? "nil" : x}
52
+ HashEngine.action('unprotected_proc', my_proc, [nil]).should == 'nil'
53
+ my_proc = Proc.new {|x, y| x.nil? ? "nil" : x}
54
+ HashEngine.action('unprotected_proc', my_proc, [nil, :key1]).should == 'nil'
55
+ end
56
+
57
+ it 'returns the result of the string evaluated to be a proc' do
58
+ HashEngine.action('unprotected_proc', 'proc {|x, y| x.nil? ? "nil" : x}', [nil, :key1]).should == 'nil'
59
+ HashEngine.action('proc', 'proc {|x| x[1..3]}', ['1234567']).should == '234'
60
+ end
61
+ end
62
+ end
63
+
64
+ describe 'of type: lookup_map' do
65
+ it 'returns the lookup value' do
66
+ action_data = {:key1 => :value1,
67
+ :key2 => :value2}
68
+ HashEngine.action('lookup_map', action_data, :key1).should == :value1
69
+ end
70
+
71
+ it 'returns nil on a miss' do
72
+ action_data = {:key1 => :value1,
73
+ :key2 => :value2}
74
+ HashEngine.action('lookup_map', action_data, :key3).should == nil
75
+ end
76
+
77
+ it 'returns the literal default on a miss' do
78
+ action_data = {:key1 => :value1,
79
+ :key2 => :value2,
80
+ 'default' => :default}
81
+ HashEngine.action('lookup_map', action_data, :key3).should == :default
82
+ end
83
+
84
+ it 'returns the key on a miss' do
85
+ action_data = {:key1 => :value1,
86
+ :key2 => :value2,
87
+ 'default_to_key' => true}
88
+ HashEngine.action('lookup_map', action_data, :key3).should == :key3
89
+ end
90
+ end
91
+
92
+ describe 'of type: first_value' do
93
+ it 'returns data if data is not an array' do
94
+ HashEngine.action('first_value', nil, '0123456789').should == '0123456789'
95
+ end
96
+
97
+ it 'returns the first non-nil value' do
98
+ HashEngine.action('first_value', nil, [nil, '0123456789']).should == '0123456789'
99
+ end
100
+ end
101
+
102
+ describe 'of type: join' do
103
+ it 'returns data elements joined' do
104
+ HashEngine.action('join', nil, ['foo', 'bar']).should == 'foobar'
105
+ end
106
+
107
+ it 'returns data elements as strings joined' do
108
+ HashEngine.action('join', nil, [:foo, :bar]).should == 'foobar'
109
+ end
110
+
111
+ it 'returns data elements joined by specified seperator' do
112
+ HashEngine.action('join', ', ', ['foo', 'bar']).should == 'foo, bar'
113
+ end
114
+
115
+ it 'returns data elements with an included nil joined by specified seperator' do
116
+ HashEngine.action('join', ', ', [nil, 'bar']).should == ', bar'
117
+ end
118
+
119
+ it 'returns data if data is not an array' do
120
+ HashEngine.action('join', ', ', 'foo').should == 'foo'
121
+ end
122
+ end
123
+
124
+ describe 'of type: max_length' do
125
+ it 'returns an unaltered string when less than length' do
126
+ HashEngine.action('max_length', 50, '0123456789').should == '0123456789'
127
+ end
128
+
129
+ it 'returns a number as a string when less than length' do
130
+ HashEngine.action('max_length', 50, 123456789).should == '123456789'
131
+ end
132
+
133
+ it 'trims the string when longer than length' do
134
+ HashEngine.action('max_length', 5, '0123456789').should == '01234'
135
+ end
136
+
137
+ it 'trims a number when longer than length' do
138
+ HashEngine.action('max_length', 5, 123456789).should == '12345'
139
+ end
140
+
141
+ it 'trims unicode string when longer than length' do
142
+ HashEngine.action('max_length', 3, 'ÑAlaman').should == 'ÑAl'
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,28 @@
1
+ require 'hash_engine'
2
+
3
+ describe HashEngine do
4
+ describe 'conditional operations' do
5
+ # left_op right_op operation expected
6
+ [[1, 2, 'ne', true],
7
+ [1, 1, 'ne', false],
8
+ [1, 1, 'eq', true],
9
+ [1, 2, 'eq', false],
10
+ [1, 2, 'lt', true],
11
+ [1, 1, 'lt', false],
12
+ [2, 1, 'gt', true],
13
+ [1, 1, 'gt', false],
14
+ [1, 2, 'lteq', true],
15
+ [1, 1, 'lteq', true],
16
+ [2, 1, 'lteq', false],
17
+ [2, 1, 'gteq', true],
18
+ [2, 2, 'gteq', true],
19
+ [1, 2, 'gteq', false],
20
+ [1, '', 'exist', true],
21
+ [nil, '', 'exist', false],
22
+ ].each {|left_operand, right_operand, operation, expected|
23
+ it "#{left_operand.inspect} #{operation} #{right_operand.inspect} should be #{expected}" do
24
+ HashEngine.conditional(operation, left_operand, right_operand).should == expected
25
+ end
26
+ }
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ require 'hash_engine'
2
+
3
+ describe HashEngine::CSVParse do
4
+ describe 'parse_line' do
5
+ context 'returns correct hash for' do
6
+ it 'simple case' do
7
+ expected = {'field1' => 'foo', 'field2' => 'bar', 'field3' => 'baz', :error => []}
8
+ string = 'foo,bar,baz'
9
+ headers = %w( field1 field2 field3 )
10
+ HashEngine.parse_line(string, headers).should == expected
11
+ end
12
+
13
+ it 'field with quote' do
14
+ expected = {'field1' => 'foo', 'field2' => '15"', 'field3' => 'baz', :error => []}
15
+ string = 'foo,15"",baz'
16
+ headers = %w( field1 field2 field3 )
17
+ HashEngine.parse_line(string, headers).should == expected
18
+ end
19
+
20
+ it 'quoted field case' do
21
+ expected = {'field1' => 'fubar, real bad', 'field2' => 'bar', 'field3' => 'baz', :error => []}
22
+ string = '"fubar, real bad",bar,baz'
23
+ headers = %w( field1 field2 field3 )
24
+ HashEngine.parse_line(string, headers).should == expected
25
+ end
26
+
27
+ it 'nil case' do
28
+ expected = {'field1' => 'foo', 'field2' => nil, 'field3' => 'baz', :error => []}
29
+ string = 'foo,,baz'
30
+ headers = %w( field1 field2 field3 )
31
+ HashEngine.parse_line(string, headers).should == expected
32
+ end
33
+
34
+ it 'alternate delimiter case' do
35
+ expected = {'field1' => 'foo', 'field2' => 'bar', 'field3' => 'baz', :error => []}
36
+ string = 'foo|bar|baz'
37
+ headers = %w( field1 field2 field3 )
38
+ HashEngine.parse_line(string, headers, '|').should == expected
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,90 @@
1
+ require 'hash_engine'
2
+
3
+ describe HashEngine do
4
+ describe 'csv transform' do
5
+ # Given String:
6
+ # ok|http://www.domain.com|1234567890
7
+ # Given Instructions:
8
+ # delimiter: '|'
9
+ # hash_keys:
10
+ # - status:
11
+ # lookup_map:
12
+ # ok: accepted
13
+ # decline: reject
14
+ # default: error
15
+ # - payload:
16
+ # - uuid:
17
+ # Return:
18
+ # status: accepted
19
+ # payload: http://www.domain.com
20
+ # uuid: 1234567890
21
+
22
+ it 'nil case' do
23
+ string = 'ok||1234567890'
24
+ instructions = {'delimiter' => '|',
25
+ 'allow_nil' => true,
26
+ 'suppress_nil' => false,
27
+ 'header' => ['status',
28
+ 'payload',
29
+ 'uuid'],
30
+ 'fields' => {'status' => {'input' => 'status'},
31
+ 'payload' => {'input' => 'payload'},
32
+ 'uuid' => {'input' => 'uuid'}} }
33
+ expected = {:error => [],
34
+ 'status' => 'ok',
35
+ 'payload' => nil,
36
+ 'uuid' => '1234567890'}
37
+ HashEngine.csv_transform(string, instructions).should == expected
38
+ end
39
+
40
+ it 'trivial case' do
41
+ string = 'ok|http://www.domain.com|1234567890'
42
+ instructions = {'delimiter' => '|',
43
+ 'header' => ['status',
44
+ 'payload',
45
+ 'uuid'],
46
+ 'fields' => {'status' => 'status',
47
+ 'payload' => 'payload',
48
+ 'uuid' => 'uuid'} }
49
+ expected = {:error => [],
50
+ 'status' => 'ok',
51
+ 'payload' => 'http://www.domain.com',
52
+ 'uuid' => '1234567890'}
53
+ HashEngine.csv_transform(string, instructions).should == expected
54
+ end
55
+
56
+ it 'simple formatting' do
57
+ string = 'ok|http://www.domain.com|ABCD1234'
58
+ instructions = {'delimiter' => '|',
59
+ 'header' => ['status',
60
+ 'payload',
61
+ 'uuid'],
62
+ 'fields' => {'status' => {'input' => 'status'},
63
+ 'payload' => {'input' => 'payload'},
64
+ 'uuid' => {'input' => 'uuid', 'format' => 'numeric'}}}
65
+ expected = {:error => [],
66
+ 'status' => 'ok',
67
+ 'payload' => 'http://www.domain.com',
68
+ 'uuid' => '1234'}
69
+ HashEngine.csv_transform(string, instructions).should == expected
70
+ end
71
+ it 'processiong case' do
72
+ string = 'ok|http://www.domain.com|1234567890'
73
+ instructions = {'delimiter' => '|',
74
+ 'header' => ['status',
75
+ 'payload',
76
+ 'uuid'],
77
+ 'fields' => {'status' => {'input' => 'status',
78
+ 'lookup_map' =>{'ok' => 'accepted',
79
+ 'decline' => 'reject',
80
+ 'default' => 'error'}},
81
+ 'payload' => {'input' => 'payload'},
82
+ 'uuid' => {'input' => 'uuid'}} }
83
+ expected = {:error => [],
84
+ 'status' => 'accepted',
85
+ 'payload' => 'http://www.domain.com',
86
+ 'uuid' => '1234567890'}
87
+ HashEngine.csv_transform(string, instructions).should == expected
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,178 @@
1
+ require 'hash_engine'
2
+ require 'yaml'
3
+
4
+ describe HashEngine do
5
+ let(:data) { {'first'=>'Firstname', 'last'=>'Lastname', 'set_number' => 12} }
6
+ let(:alt_data) { {'first'=>'Firstname', 'set_number' => 12} }
7
+
8
+ it 'joins first+seperator+last' do
9
+ instructions = {'fields'=>
10
+ {'name_field'=>
11
+ [{'data' => ['first',
12
+ 'last']},
13
+ {'join'=> '\#' }]}}
14
+ results = HashEngine.transform(data, instructions)
15
+ results['name_field'].should == 'Firstname\#Lastname'
16
+ end
17
+
18
+ it 'joins first+seperator+first+seperator+first+seperator+last' do
19
+ instructions = {'fields'=>
20
+ {'name_field'=>
21
+ [{'data' => ['first',
22
+ 'first',
23
+ 'first',
24
+ 'last']},
25
+ {'join'=> '\#' }]}}
26
+ results = HashEngine.transform(data, instructions)
27
+ results['name_field'].should == 'Firstname\#Firstname\#Firstname\#Lastname'
28
+ end
29
+
30
+ it 'joins last+seperator+first' do
31
+ instructions = {'fields'=>
32
+ {'name_field'=>
33
+ [{'data' => ['last',
34
+ 'first']},
35
+ {'join'=> '\#' }]}}
36
+ results = HashEngine.transform(data, instructions)
37
+ results['name_field'].should == 'Lastname\#Firstname'
38
+ end
39
+
40
+ it 'joins last+seperator+last+seperator+first' do
41
+ instructions = {'fields'=>
42
+ {'name_field'=>
43
+ [{'data' => ['last',
44
+ 'last',
45
+ 'first']},
46
+ {'join'=> '\#' }]}}
47
+ results = HashEngine.transform(data, instructions)
48
+ results['name_field'].should == 'Lastname\#Lastname\#Firstname'
49
+ end
50
+
51
+ it '"#{first_name}#{separator}#{last_name}<Wrapper=#{wrapper_set}>"' do
52
+ yaml =<<EOYAML
53
+ fields:
54
+ name_field:
55
+ - subgroup:
56
+ data:
57
+ - first
58
+ - last
59
+ join: '\\#'
60
+ - literal: '<Wrapper='
61
+ - input: set_number
62
+ - literal: '>'
63
+ - join:
64
+ EOYAML
65
+ instructions = YAML.load yaml
66
+ results = HashEngine.transform(data, instructions)
67
+ results['name_field'].should == 'Firstname\#Lastname<Wrapper=12>'
68
+ end
69
+
70
+ it '"#{first_name}#{separator}#{last_name}#{separator}#{first_name}#{separator}#{last_name}#{separator}#{first_name}#{separator}#{last_name}#{separator}#{first_name}#{separator}#{last_name}#{separator}#{first_name}#{separator}#{last_name}"' do
71
+ instructions = {'fields'=>
72
+ {'name_field'=>
73
+ [{'data' => [ 'first','last','first','last','first','last','first','last','first','last' ]},
74
+ {'join'=> '\#' }]}}
75
+ results = HashEngine.transform(data, instructions)
76
+ results['name_field'].should == 'Firstname\#Lastname\#Firstname\#Lastname\#Firstname\#Lastname\#Firstname\#Lastname\#Firstname\#Lastname'
77
+ end
78
+
79
+ context 'last_name.present? ? "#{first_name}#{separator}#{last_name}" : "#{first_name}#{separator}#{first_name}"' do
80
+ let(:instructions) do
81
+ {'fields'=>
82
+ {'name_field'=>
83
+ [{'input' => 'first'},
84
+ {'data' => ['last',
85
+ 'first']},
86
+ {'first_value'=>nil},
87
+ {'join'=> '\#' }]}}
88
+ yaml =<<EOYAML
89
+ fields:
90
+ name_field:
91
+ - input: first
92
+ - subgroup:
93
+ data:
94
+ - last
95
+ - first
96
+ first_value:
97
+ - join: '\\#'
98
+ EOYAML
99
+ instructions = YAML.load yaml
100
+ end
101
+
102
+ it 'last name present' do
103
+ results = HashEngine.transform(data, instructions)
104
+ results['name_field'].should == 'Firstname\#Lastname'
105
+ end
106
+
107
+ it 'last name blank' do
108
+ results = HashEngine.transform(alt_data, instructions)
109
+ results['name_field'].should == 'Firstname\#Firstname'
110
+ end
111
+ end
112
+
113
+ context 'last_name.present? ? "#{last_name}" : "#{first_name}"' do
114
+ let(:instructions) do
115
+ {'fields'=>
116
+ {'name_field'=>
117
+ [{'data' => ['last',
118
+ 'first']},
119
+ {'first_value'=>nil}]}}
120
+ end
121
+
122
+ it 'last name present' do
123
+ results = HashEngine.transform(data, instructions)
124
+ results['name_field'].should == 'Lastname'
125
+ end
126
+
127
+ it 'last name blank' do
128
+ results = HashEngine.transform(alt_data, instructions)
129
+ results['name_field'].should == 'Firstname'
130
+ end
131
+ end
132
+
133
+ context 'last_name.present? ? "#{first_name}#{separator}#{last_name}" : "#{separator}#{first_name}"' do
134
+ let(:instructions) do
135
+ yaml =<<EOYAML
136
+ fields:
137
+ name_field:
138
+ - conditional_input:
139
+ input: last
140
+ test: ne
141
+ test_value:
142
+ true:
143
+ input: first
144
+ false:
145
+ literal: ''
146
+ - subgroup_input:
147
+ data:
148
+ - last
149
+ - first
150
+ first_value:
151
+ - join: '\\#'
152
+ EOYAML
153
+ YAML.load yaml
154
+ end
155
+
156
+ it 'last name present' do
157
+ pending
158
+ results = HashEngine.transform(data, instructions)
159
+ results['name_field'].should == 'Firstname\#Lastname'
160
+ end
161
+
162
+ it 'last name blank' do
163
+ pending
164
+ results = HashEngine.transform(alt_data, instructions)
165
+ results['name_field'].should == '\#Firstname'
166
+ end
167
+ end
168
+
169
+ it '"#{first_name} #{last_name}"' do
170
+ instructions = {'fields'=>
171
+ {'name_field'=>
172
+ [{'data' => ['first',
173
+ 'last']},
174
+ {'join'=> ' ' }]}}
175
+ results = HashEngine.transform(data, instructions)
176
+ results['name_field'].should == 'Firstname Lastname'
177
+ end
178
+ end