nori 2.3.0 → 2.4.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.
@@ -2,12 +2,8 @@
2
2
  language: "ruby"
3
3
  script: "bundle exec rake"
4
4
  rvm:
5
- - 1.8.7
6
5
  - 1.9.2
7
6
  - 1.9.3
8
7
  - 2.0
9
- - jruby-18mode
10
8
  - jruby-19mode
11
- - rbx-18mode
12
- - rbx-19mode
13
- - ree
9
+ - rbx
@@ -1,3 +1,11 @@
1
+ # 2.4.0 (2014-04-19)
2
+
3
+ * Change: Dropped support for ruby 1.8, rubinius and ree
4
+
5
+ * Feature: Added `:convert_attributes` feature similar to `:convert_tags_to`
6
+
7
+ * Feature: Added `:convert_dashes_to_underscore` option
8
+
1
9
  # 2.3.0 (2013-07-26)
2
10
 
3
11
  * Change: `Nori#find` now ignores namespace prefixes in Hash keys it is searching through.
data/Gemfile CHANGED
@@ -1,2 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ platform :rbx do
5
+ gem 'json'
6
+ gem 'racc'
7
+ gem 'rubysl'
8
+ gem 'rubinius-coverage'
9
+ end
data/README.md CHANGED
@@ -67,3 +67,21 @@ parser = Nori.new(:convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
67
67
  xml = '<userResponse><accountStatus>active</accountStatus></userResponse>'
68
68
  parser.parse(xml) # => { :user_response => { :account_status => "active" }
69
69
  ```
70
+
71
+ Dashes and underscores
72
+ ----------------------
73
+
74
+ Nori will automatically convert dashes in tag names to underscores.
75
+ For example:
76
+
77
+ ```ruby
78
+ parser = Nori.new
79
+ parser.parse('<any-tag>foo bar</any-tag>') # => { "any_tag" => "foo bar" }
80
+ ```
81
+
82
+ You can control this behavior with the `:convert_dashes_to_underscores` option:
83
+
84
+ ```ruby
85
+ parser = Nori.new(:convert_dashes_to_underscores => false)
86
+ parser.parse('<any-tag>foo bar</any-tag>') # => { "any-tag" => "foo bar" }
87
+ ```
@@ -5,7 +5,7 @@ require "nori/xml_utility_node"
5
5
  class Nori
6
6
 
7
7
  def self.hash_key(name, options = {})
8
- name = name.tr("-", "_")
8
+ name = name.tr("-", "_") if options[:convert_dashes_to_underscores]
9
9
  name = name.split(":").last if options[:strip_namespaces]
10
10
  name = options[:convert_tags_to].call(name) if options[:convert_tags_to].respond_to? :call
11
11
  name
@@ -18,7 +18,9 @@ class Nori
18
18
  :strip_namespaces => false,
19
19
  :delete_namespace_attributes => false,
20
20
  :convert_tags_to => nil,
21
+ :convert_attributes_to => nil,
21
22
  :advanced_typecasting => true,
23
+ :convert_dashes_to_underscores => true,
22
24
  :parser => :nokogiri
23
25
  }
24
26
 
@@ -45,12 +47,17 @@ class Nori
45
47
  end
46
48
 
47
49
  private
48
-
49
50
  def load_parser(parser)
50
51
  require "nori/parser/#{parser}"
51
52
  Parser.const_get PARSERS[parser]
52
53
  end
53
54
 
55
+ # Expects a +block+ which receives a tag to convert.
56
+ # Accepts +nil+ for a reset to the default behavior of not converting tags.
57
+ def convert_tags_to(reset = nil, &block)
58
+ @convert_tag = reset || block
59
+ end
60
+
54
61
  def validate_options!(available_options, options)
55
62
  spurious_options = options - available_options
56
63
 
@@ -16,9 +16,7 @@ class Nori
16
16
  # }.to_params
17
17
  # #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
18
18
  def to_params
19
- params = self.map { |k, v| normalize_param(k,v) }.join
20
- params.chop! # trailing &
21
- params
19
+ map { |k, v| normalize_param(k,v) }.flatten.join('&')
22
20
  end
23
21
 
24
22
  # @param key<Object> The key for the param.
@@ -26,30 +24,15 @@ class Nori
26
24
  #
27
25
  # @return <String> This key value pair as a param
28
26
  #
29
- # @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
27
+ # @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones"
30
28
  def normalize_param(key, value)
31
- param = ''
32
- stack = []
33
-
34
29
  if value.is_a?(Array)
35
- param << value.map { |element| normalize_param("#{key}[]", element) }.join
30
+ normalize_array_params(key, value)
36
31
  elsif value.is_a?(Hash)
37
- stack << [key,value]
32
+ normalize_hash_params(key, value)
38
33
  else
39
- param << "#{key}=#{URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}&"
40
- end
41
-
42
- stack.each do |parent, hash|
43
- hash.each do |key, value|
44
- if value.is_a?(Hash)
45
- stack << ["#{parent}[#{key}]", value]
46
- else
47
- param << normalize_param("#{parent}[#{key}]", value)
48
- end
49
- end
34
+ normalize_simple_type_params(key, value)
50
35
  end
51
-
52
- param
53
36
  end
54
37
 
55
38
  # @return <String> The hash as attributes for an XML tag.
@@ -63,6 +46,28 @@ class Nori
63
46
  end.join(' ')
64
47
  end
65
48
 
49
+ private
50
+
51
+ def normalize_simple_type_params(key, value)
52
+ ["#{key}=#{encode_simple_value(value)}"]
53
+ end
54
+
55
+ def normalize_array_params(key, array)
56
+ array.map do |element|
57
+ normalize_param("#{key}[]", element)
58
+ end
59
+ end
60
+
61
+ def normalize_hash_params(key, hash)
62
+ hash.map do |nested_key, element|
63
+ normalize_param("#{key}[#{nested_key}]", element)
64
+ end
65
+ end
66
+
67
+ def encode_simple_value(value)
68
+ URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
69
+ end
70
+
66
71
  end
67
72
  end
68
73
  end
@@ -5,9 +5,9 @@ class Nori
5
5
  # Returns the String in snake_case.
6
6
  def snakecase
7
7
  str = dup
8
- str.gsub! /::/, '/'
9
- str.gsub! /([A-Z]+)([A-Z][a-z])/, '\1_\2'
10
- str.gsub! /([a-z\d])([A-Z])/, '\1_\2'
8
+ str.gsub!(/::/, '/')
9
+ str.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
10
+ str.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
11
11
  str.tr! ".", "_"
12
12
  str.tr! "-", "_"
13
13
  str.downcase!
@@ -1,5 +1,3 @@
1
1
  class Nori
2
-
3
- VERSION = "2.3.0"
4
-
2
+ VERSION = "2.4.0"
5
3
  end
@@ -85,6 +85,11 @@ class Nori
85
85
  @options = options
86
86
  @name = Nori.hash_key(name, options)
87
87
 
88
+ if converter = options[:convert_attributes_to]
89
+ intermediate = attributes.map {|k, v| converter.call(k, v) }.flatten
90
+ attributes = Hash[*intermediate]
91
+ end
92
+
88
93
  # leave the type alone if we don't know what it is
89
94
  @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
90
95
 
@@ -238,16 +243,17 @@ class Nori
238
243
  attributes.merge!(:type => @type ) if @type
239
244
  "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
240
245
  end
241
-
242
246
  alias to_s to_html
243
247
 
244
248
  private
245
-
246
249
  def try_to_convert(value, &block)
247
250
  block.call(value)
248
251
  rescue ArgumentError
249
252
  value
250
253
  end
251
- end
252
254
 
255
+ def strip_namespace(string)
256
+ string.split(":").last
257
+ end
258
+ end
253
259
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.license = "MIT"
16
16
 
17
17
  s.add_development_dependency "rake", "~> 10.0"
18
- s.add_development_dependency "nokogiri", ">= 1.4.0", "< 1.6"
18
+ s.add_development_dependency "nokogiri", ">= 1.4.0"
19
19
  s.add_development_dependency "rspec", "~> 2.12"
20
20
 
21
21
  s.files = `git ls-files`.split("\n")
@@ -162,6 +162,14 @@ describe Nori do
162
162
  end
163
163
  end
164
164
 
165
+ context "#parse with :convert_dashes_to_underscores" do
166
+ it "can be configured to skip dash to underscope conversion" do
167
+ xml = '<any-tag>foo bar</any-tag'
168
+ hash = nori(:convert_dashes_to_underscores => false).parse(xml)
169
+ hash.should == {'any-tag' => 'foo bar'}
170
+ end
171
+ end
172
+
165
173
  def nori(options = {})
166
174
  Nori.new(options)
167
175
  end
@@ -460,6 +460,17 @@ describe Nori do
460
460
  end
461
461
  end
462
462
 
463
+ context "with convert_attributes_to set to a custom formula" do
464
+ it "alters attributes and values" do
465
+ converter = lambda {|key, value| ["#{key}_k", "#{value}_v"] }
466
+ xml = <<-XML
467
+ <user name="value"><age>21</age></user>
468
+ XML
469
+
470
+ parse(xml, :convert_attributes_to => converter).should == {'user' => {'@name_k' => 'value_v', 'age' => '21'}}
471
+ end
472
+ end
473
+
463
474
  it "should handle a single record from_xml with attributes other than type (ActiveSupport Compatible)" do
464
475
  topic_xml = <<-EOT
465
476
  <rsp stat="ok">
@@ -600,15 +611,15 @@ describe Nori do
600
611
  parse(product_xml)["product"].should == expected_product_hash
601
612
  end
602
613
 
603
- it "should handle unescaping from xml (ActiveResource Compatible)" #do
604
- # xml_string = '<person><bare-string>First &amp; Last Name</bare-string><pre-escaped-string>First &amp;amp; Last Name</pre-escaped-string></person>'
605
- # expected_hash = {
606
- # 'bare_string' => 'First & Last Name',
607
- # 'pre_escaped_string' => 'First &amp; Last Name'
608
- # }
609
- #
610
- # parse(xml_string)['person'].should == expected_hash
611
- # end
614
+ it "should handle unescaping from xml (ActiveResource Compatible)" do
615
+ xml_string = '<person><bare-string>First &amp; Last Name</bare-string><pre-escaped-string>First &amp;amp; Last Name</pre-escaped-string></person>'
616
+ expected_hash = {
617
+ 'bare_string' => 'First & Last Name',
618
+ 'pre_escaped_string' => 'First &amp; Last Name'
619
+ }
620
+
621
+ parse(xml_string)['person'].should == expected_hash
622
+ end
612
623
 
613
624
  it "handle an empty xml string" do
614
625
  parse('').should == {}
@@ -623,8 +634,7 @@ describe Nori do
623
634
  end
624
635
 
625
636
  def parse(xml, options = {})
626
- defaults = { :parser => parser }
637
+ defaults = {:parser => parser}
627
638
  Nori.new(defaults.merge(options)).parse(xml)
628
639
  end
629
-
630
640
  end
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nori
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Daniel Harrington
@@ -10,11 +11,12 @@ authors:
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2013-07-26 00:00:00.000000000 Z
14
+ date: 2014-04-19 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: rake
17
18
  requirement: !ruby/object:Gem::Requirement
19
+ none: false
18
20
  requirements:
19
21
  - - ~>
20
22
  - !ruby/object:Gem::Version
@@ -22,6 +24,7 @@ dependencies:
22
24
  type: :development
23
25
  prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
25
28
  requirements:
26
29
  - - ~>
27
30
  - !ruby/object:Gem::Version
@@ -29,26 +32,23 @@ dependencies:
29
32
  - !ruby/object:Gem::Dependency
30
33
  name: nokogiri
31
34
  requirement: !ruby/object:Gem::Requirement
35
+ none: false
32
36
  requirements:
33
- - - '>='
37
+ - - ! '>='
34
38
  - !ruby/object:Gem::Version
35
39
  version: 1.4.0
36
- - - <
37
- - !ruby/object:Gem::Version
38
- version: '1.6'
39
40
  type: :development
40
41
  prerelease: false
41
42
  version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
42
44
  requirements:
43
- - - '>='
45
+ - - ! '>='
44
46
  - !ruby/object:Gem::Version
45
47
  version: 1.4.0
46
- - - <
47
- - !ruby/object:Gem::Version
48
- version: '1.6'
49
48
  - !ruby/object:Gem::Dependency
50
49
  name: rspec
51
50
  requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
52
  requirements:
53
53
  - - ~>
54
54
  - !ruby/object:Gem::Version
@@ -56,6 +56,7 @@ dependencies:
56
56
  type: :development
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
59
60
  requirements:
60
61
  - - ~>
61
62
  - !ruby/object:Gem::Version
@@ -97,26 +98,27 @@ files:
97
98
  homepage: https://github.com/savonrb/nori
98
99
  licenses:
99
100
  - MIT
100
- metadata: {}
101
101
  post_install_message:
102
102
  rdoc_options: []
103
103
  require_paths:
104
104
  - lib
105
105
  required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
106
107
  requirements:
107
- - - '>='
108
+ - - ! '>='
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
111
113
  requirements:
112
- - - '>='
114
+ - - ! '>='
113
115
  - !ruby/object:Gem::Version
114
116
  version: '0'
115
117
  requirements: []
116
118
  rubyforge_project: nori
117
- rubygems_version: 2.0.6
119
+ rubygems_version: 1.8.23
118
120
  signing_key:
119
- specification_version: 4
121
+ specification_version: 3
120
122
  summary: XML to Hash translator
121
123
  test_files:
122
124
  - spec/nori/api_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 7a4585ff58e2073a1108c7961be22c7f3caf5c80
4
- data.tar.gz: b9ab6223657d1839d7a2e4553b7d5a84452bf4c7
5
- SHA512:
6
- metadata.gz: 432b9de3992b4d4b16a6bfa2fa2e222dbaf11f478ebac4e1f73f8c565ff8d30952a03ee65d6bdd224fb409c82972340ed25817110aeb6ec396974ff50cb11709
7
- data.tar.gz: aae0fa14740a20a9f4e5419261a22ad4733da0a2b841e56dbc080bad205f7bfc98a386bb4cf674d8457e20b6e1b7a6c38af9ee4f76b64fb14cd04d4ee1e6d1a5