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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46b303dae82c792ec2862601fe90808952ad1edc
4
- data.tar.gz: 6db10dedf96e9452019b78ab59d536f439fd9716
3
+ metadata.gz: d7d2ffcffd11d706a95f945f1e40e8271487059f
4
+ data.tar.gz: 71c2c16b8544022aa75ecaeb2a093db6230c1b90
5
5
  SHA512:
6
- metadata.gz: e446c85df5964880d649a99ec244f025c2475c525964264f633cf287608710cdedfea7cb8b21650edbbafa42b387f5e12ad100c8c483cf9b3a384df43482d599
7
- data.tar.gz: 79cc02ecb606559ff3c4e9f637e1bf4b5f5bb0840c8c00457f8d1d84db1f91cd0f1c9ee1dc83284cf01c2cc7ef8bf3c42cf3c5a070d536cf75f8c86433d28d34
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).inject({}) do |hash, element|
12
- hash[attribute_value(element, 'data-mapping')] = attribute_value(element, 'name')
13
- hash
14
- end.with_indifferent_access
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,5 +1,5 @@
1
1
  module Semantic
2
2
  module Mapper
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  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
- subject { markup.map }
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
- its([:first_name]) { is_expected.to eq('p-first-name') }
11
- its([:last_name]) { is_expected.to eq('p-last-name') }
12
- its([:credit_card_type]) { is_expected.to eq('p-card-type') }
13
- its([:credit_card_exp_month]) { is_expected.to eq('p-card-exp-month') }
14
- its([:message]) { is_expected.to eq('e-content') }
15
- its([:storage_unit_external_id]) { is_expected.to eq('p-storage-unit-external-id') }
16
- its([:rental_rate]) { is_expected.to eq('p-rental-rate') }
17
- its([:reservation_date]) { is_expected.to eq('p-reservation-date') }
18
- its([:time_zone]) { is_expected.to eq('p-time-zone') }
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.1
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-04 00:00:00.000000000 Z
11
+ date: 2014-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler