semantic-mapper 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/semantic/mapper/markup.rb +34 -4
- data/lib/semantic/mapper/version.rb +1 -1
- data/spec/fixtures/reservation.html +8 -8
- data/spec/lib/semantic/mapper/markup_spec.rb +42 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7d2ffcffd11d706a95f945f1e40e8271487059f
|
4
|
+
data.tar.gz: 71c2c16b8544022aa75ecaeb2a093db6230c1b90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44f7c907d3b1e7e7a70d3c981750b4d68cac224b9baa88e73d5789af628712f2407c6998b8cec0f6bfca27f449d102c3b16feccbb7751df5e088955f4d3b0691
|
7
|
+
data.tar.gz: a4ae4599a427ae1bf726933b2f2f02963069586b38455345116c2f6073bebb26e29d1a333916a107c0a2521099ffd1d63f581864b23e93853e747de34951aec3
|
@@ -2,19 +2,49 @@ module Semantic
|
|
2
2
|
module Mapper
|
3
3
|
class Markup
|
4
4
|
SELECTOR = '[data-mapping]'
|
5
|
+
attr_reader :mapped_hash
|
5
6
|
|
6
7
|
def initialize(html)
|
7
8
|
@html = html
|
9
|
+
@mapped_hash = HashWithIndifferentAccess.new
|
8
10
|
end
|
9
11
|
|
10
12
|
def map
|
11
|
-
document.css(SELECTOR).
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
document.css(SELECTOR).each do |element|
|
14
|
+
fields(element).each do |key|
|
15
|
+
final_attribute_value = attribute_value(element, 'name')
|
16
|
+
keys = build_keys(key)
|
17
|
+
map_hash(final_attribute_value, keys)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@mapped_hash
|
15
21
|
end
|
16
22
|
|
17
23
|
private
|
24
|
+
|
25
|
+
def map_hash(value, keys)
|
26
|
+
merge_or_set(keys[0], value) and return if keys.length == 1
|
27
|
+
current_key = keys.pop
|
28
|
+
value = HashWithIndifferentAccess.new(current_key => value)
|
29
|
+
map_hash(value, keys)
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_keys(key)
|
33
|
+
key.scan(/([\w-]+)|\[([\w-]+?)\]/).flatten.compact
|
34
|
+
end
|
35
|
+
|
36
|
+
def merge_or_set(key, value)
|
37
|
+
if @mapped_hash.has_key?(key)
|
38
|
+
@mapped_hash[key].deep_merge!(value)
|
39
|
+
else
|
40
|
+
@mapped_hash[key] = value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def fields(element)
|
45
|
+
attribute_value(element, 'data-mapping').split(" ")
|
46
|
+
end
|
47
|
+
|
18
48
|
def document
|
19
49
|
@document ||= Nokogiri::HTML(@html)
|
20
50
|
end
|
@@ -1,27 +1,27 @@
|
|
1
1
|
<div class="p-author h-card">
|
2
2
|
<div class="form-field">
|
3
3
|
<label for="p-first-name" class="required">First Name</label>
|
4
|
-
<input type="text" id="p-first-name" class="p-first-name" name="p-first-name" data-mapping="first_name" required>
|
4
|
+
<input type="text" id="p-first-name" class="p-first-name" name="p-first-name" data-mapping="customer[first_name]" required>
|
5
5
|
</div>
|
6
6
|
|
7
7
|
<div class="form-field">
|
8
8
|
<label for="p-last-name" class="required">Last Name</label>
|
9
|
-
<input type="text" id="p-last-name" class="p-last-name" name="p-last-name" data-mapping="last_name" required>
|
9
|
+
<input type="text" id="p-last-name" class="p-last-name" name="p-last-name" data-mapping="customer[last_name]" required>
|
10
10
|
</div>
|
11
11
|
|
12
12
|
<div class="form-field">
|
13
13
|
<label for="p-address1" class="required">Address</label>
|
14
|
-
<input type="text" id="p-address1" class="p-address1" name="p-address1" data-mapping="address1" required>
|
14
|
+
<input type="text" id="p-address1" class="p-address1" name="p-address1" data-mapping="customer[address1] customer[billing_address]" required>
|
15
15
|
</div>
|
16
16
|
|
17
17
|
<div class="form-field">
|
18
18
|
<label for="p-city" class="required">City</label>
|
19
|
-
<input type="text" id="p-city" class="p-city" name="p-city" data-mapping="city" required>
|
19
|
+
<input type="text" id="p-city" class="p-city" name="p-city" data-mapping="customer[street_address][city]" required>
|
20
20
|
</div>
|
21
21
|
|
22
22
|
<div class="form-field">
|
23
23
|
<label for="p-state" class="required">State</label>
|
24
|
-
<input type="text" id="p-state" class="p-state" name="p-state" data-mapping="region" required>
|
24
|
+
<input type="text" id="p-state" class="p-state" name="p-state" data-mapping="customer[street_address][region]" required>
|
25
25
|
</div>
|
26
26
|
|
27
27
|
<div class="form-field">
|
@@ -31,12 +31,12 @@
|
|
31
31
|
|
32
32
|
<div class="form-field">
|
33
33
|
<label for="p-tel">Phone Number</label>
|
34
|
-
<input type="tel" id="p-tel" class="p-tel" name="p-tel" data-mapping="phone">
|
34
|
+
<input type="tel" id="p-tel" class="p-tel" name="p-tel" data-mapping="customer[phone]">
|
35
35
|
</div>
|
36
36
|
|
37
37
|
<div class="form-field">
|
38
38
|
<label for="u-email" class="required">Email</label>
|
39
|
-
<input type="email" id="u-email" class="u-email" name="u-email" data-mapping="email" required>
|
39
|
+
<input type="email" id="u-email" class="u-email" name="u-email" data-mapping="customer[email]" required>
|
40
40
|
</div>
|
41
41
|
|
42
42
|
<div class="form-field">
|
@@ -62,7 +62,7 @@
|
|
62
62
|
|
63
63
|
<div class="form-field">
|
64
64
|
<label for="p-card-exp-month" class="required">Expiration Date:</label>
|
65
|
-
<select id="p-card-exp-month" class="p-card-exp-month" name="p-card-exp-month" data-mapping="credit_card_exp_month" required>
|
65
|
+
<select id="p-card-exp-month" class="p-card-exp-month" name="p-card-exp-month" data-mapping="credit_card[credit_card_exp_month]" required>
|
66
66
|
<option value="1">1 - January</option>
|
67
67
|
<option value="2">2 - February</option>
|
68
68
|
<option value="3">3 - March</option>
|
@@ -5,16 +5,48 @@ describe Semantic::Mapper::Markup do
|
|
5
5
|
let(:html) { fixture('reservation.html') }
|
6
6
|
|
7
7
|
describe :map do
|
8
|
-
|
8
|
+
context 'nested mapping' do
|
9
|
+
subject { markup.map[:customer] }
|
10
|
+
its([:first_name]) { is_expected.to eq('p-first-name') }
|
11
|
+
its([:last_name]) { is_expected.to eq('p-last-name') }
|
12
|
+
its([:address1]) { is_expected.to eq('p-address1') }
|
13
|
+
its([:billing_address]) { is_expected.to eq('p-address1') }
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
it 'maps 3 levels deeps' do
|
16
|
+
expect(subject[:street_address][:city]).to eq('p-city')
|
17
|
+
expect(subject[:street_address][:region]).to eq('p-state')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'top level attributes' do
|
21
|
+
subject { markup.map }
|
22
|
+
its([:message]) { is_expected.to eq('e-content') }
|
23
|
+
its([:storage_unit_external_id]) { is_expected.to eq('p-storage-unit-external-id') }
|
24
|
+
its([:rental_rate]) { is_expected.to eq('p-rental-rate') }
|
25
|
+
its([:reservation_date]) { is_expected.to eq('p-reservation-date') }
|
26
|
+
its([:time_zone]) { is_expected.to eq('p-time-zone') }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe :map_hash do
|
31
|
+
[{value: 3, keys: %w(whatever foo), expected: {"whatever" => {"foo" => 3}}},
|
32
|
+
{value: 'semantic', keys: %w(customer address street1), expected: {"customer" => {"address" => {"street1" => "semantic"}}}},
|
33
|
+
{value: 'mapper', keys: ['jimmy'], expected: {"jimmy" => "mapper"}}
|
34
|
+
].each do |test_hash|
|
35
|
+
it "should map hash with value #{test_hash[:value]} and keys #{test_hash[:keys]} to #{test_hash[:expected]}" do
|
36
|
+
markup.send(:map_hash, test_hash[:value], test_hash[:keys])
|
37
|
+
expect(markup.mapped_hash).to eq(test_hash[:expected])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe :build_keys do
|
43
|
+
[{data_mapping: 'jimmy[walker]', expected: %w(jimmy walker)},
|
44
|
+
{data_mapping: 'jimmy[walker][foo]', expected: %w(jimmy walker foo)},
|
45
|
+
{data_mapping: 'jimmy', expected: %w(jimmy)}
|
46
|
+
].each do |test_hash|
|
47
|
+
it "should build #{test_hash[:expected]} from #{test_hash[:data_mapping]}" do
|
48
|
+
expect(markup.send(:build_keys, test_hash[:data_mapping])).to eq(test_hash[:expected])
|
49
|
+
end
|
50
|
+
end
|
19
51
|
end
|
20
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semantic-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Perry Hertler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|