nori 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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