pump 0.2.0 → 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.
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --markup markdown
2
+ -
3
+ README.md
4
+ CHANGES.md
5
+ MIT-LICENSE
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Sebastian
1
+ Copyright (c) 2013 Sebastian Munz
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -6,8 +6,8 @@ Fast but inflexible XML encoding for ruby objects.
6
6
 
7
7
  Serializing an array of 100 random entries 1.000 times.
8
8
 
9
- user system total real
10
- Pump::Xml#encode 1.560000 0.020000 1.580000 ( 1.581375)
11
- Pump::Xml#encode (optimized) 1.060000 0.010000 1.070000 ( 1.067321)
12
- Ox 1.470000 0.000000 1.470000 ( 1.467247)
13
- ActiveModel#serialize 22.840000 0.040000 22.880000 ( 22.871247)
9
+ user system total real
10
+ Pump::Xml#encode 1.450000 0.010000 1.460000 ( 1.466962)
11
+ Pump::Xml#encode (optimized) 1.100000 0.010000 1.110000 ( 1.110234)
12
+ Ox 1.490000 0.000000 1.490000 ( 1.483275)
13
+ ActiveModel#serialize 23.280000 0.060000 23.340000 ( 23.333999)
data/Rakefile CHANGED
@@ -3,3 +3,29 @@ require "bundler/gem_tasks"
3
3
  require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
  task :default => :spec
6
+
7
+ begin
8
+ require "yard"
9
+ require "yard/rake/yardoc_task"
10
+
11
+ namespace :doc do
12
+ desc "Generate Yardoc documentation"
13
+ YARD::Rake::YardocTask.new do |yardoc|
14
+ yardoc.name = "yard"
15
+ yardoc.options = ["--verbose", "--markup", "markdown"]
16
+ yardoc.files = FileList[
17
+ "lib/**/*.rb",
18
+ "-", "README.md", "CHANGES.md", "MIT-LICENSE"
19
+ ]
20
+ end
21
+ end
22
+
23
+ task "clobber" => ["doc:clobber_yard"]
24
+
25
+ desc "Alias to doc:yard"
26
+ task "doc" => "doc:yard"
27
+ rescue LoadError
28
+ # If yard isn't available, it's not the end of the world
29
+ desc "Alias to doc:rdoc"
30
+ task "doc" => "doc:rdoc"
31
+ end
data/lib/pump/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pump
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,51 @@
1
+ module Pump
2
+ class Xml
3
+ class Dsl
4
+ def initialize(&blk)
5
+ raise ArgumentError unless block_given?
6
+ instance_eval(&blk)
7
+ end
8
+
9
+ def config
10
+ @config ||= []
11
+ end
12
+
13
+ private
14
+
15
+ def tag(name, options={}, &blk)
16
+ method = if block_given?
17
+ self.class.new(&blk).config
18
+ else
19
+ options.delete(:from) || (name.to_s =~ /-/ ? name.to_s.gsub('-', '_').to_sym : name)
20
+ end
21
+ config << ({ name => method }).merge(options)
22
+ end
23
+ alias_method :string, :tag
24
+
25
+ def integer(name, options={})
26
+ with_type('integer', name, options)
27
+ end
28
+
29
+ def date(name, options={})
30
+ with_type('date', name, options)
31
+ end
32
+
33
+ def datetime(name, options={})
34
+ options[:typecast] = :xmlschema unless options.has_key?(:typecast)
35
+ with_type('datetime', name, options)
36
+ end
37
+ alias_method :time, :datetime
38
+
39
+ def with_type(type, name, options)
40
+ (options[:attributes] ||= {}).merge!({:type => type})
41
+ options[:xmlsafe] = true unless options.has_key?(:xmlsafe)
42
+ tag(name, options)
43
+ end
44
+
45
+ def array(name, options={}, &blk)
46
+ options[:array] = self.class.new(&blk).config
47
+ tag(name, options)
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/pump/xml.rb CHANGED
@@ -1,19 +1,60 @@
1
1
  require "pump/xml/tag"
2
2
  require "pump/xml/value"
3
3
  require "pump/xml/tag_array"
4
+ require "pump/xml/dsl"
5
+ require 'active_support/core_ext/string/inflections'
4
6
 
5
7
  module Pump
6
8
  class Xml
9
+
7
10
  attr_reader :root_tag_name, :tag_config, :options
8
11
 
9
- def initialize(root_tag_name, tag_config, options={})
12
+ # Creates a new XML-encoder with a root tag named after +root_tag_name+.
13
+ #
14
+ # @example Create a simple encoder for a person with a name attribute:
15
+ # Pump::Xml.new :person do
16
+ # tag :name
17
+ # end
18
+ #
19
+ # @example Create the same without usage of the DSL:
20
+ # Pump::Xml.new :person, [{:name => :name}]
21
+ #
22
+ # @example Create the same but without the xml instruct
23
+ # Pump::Xml.new :person, :instruct => false do
24
+ # tag :name
25
+ # end
26
+ #
27
+ # @example The same again without DSL:
28
+ #
29
+ # Pump::Xml.new :person, [{:name => :name}], :instruct => false
30
+ #
31
+ # @param [String, Symbol] root_tag_name the name of the used root tag
32
+ # @param [Array<Hash>] tag_config optional config for all tags
33
+ # @param [Hash] options optional options for the whole encoder
34
+ # @yield an optional block to create the encoder with the Pump::Xml::Dsl
35
+ #
36
+ # @return [self]
37
+ def initialize(root_tag_name, tag_config=nil, options={}, &blk)
38
+ unless Array === tag_config
39
+ raise ArgumentError unless block_given?
40
+ @options = tag_config || {}
41
+ @tag_config = Dsl.new(&blk).config
42
+ else
43
+ @tag_config = tag_config
44
+ @options = options
45
+ end
10
46
  @root_tag_name = root_tag_name
11
- @tag_config = tag_config
12
- @options = options
13
47
 
14
48
  compile
15
49
  end
16
50
 
51
+ # Encode a object or an array of objects to an XML-string.
52
+ #
53
+ # @param [Object, Array<Object>] object object or an array of objects to
54
+ # encode to XML. The only requirement: The given objects must respond
55
+ # to all methods configured during initalization of the Pump::Xml instance.
56
+ #
57
+ # @return [String]
17
58
  def encode(object)
18
59
  Array === object ? encode_array(object) : encode_single(object)
19
60
  end
@@ -44,12 +85,14 @@ module Pump
44
85
 
45
86
  def build_tag(config)
46
87
  tag_name, method_name = config.keys.first, config.values.first
88
+ attrs = config[:attributes]
47
89
  if method_name.is_a?(Array)
48
- Tag.new(tag_name, config[:attributes], method_name.map{|conf| build_tag(conf) }, config)
49
- elsif config[:array].is_a?(Array)
50
- TagArray.new(tag_name, config[:attributes], config[:array].map{|conf| build_tag(conf) }, config.merge({:array_method => method_name}))
90
+ Tag.new(tag_name, attrs, method_name.map{|conf| build_tag(conf) }, config)
91
+ elsif config[:array]
92
+ config.merge!(:array_method => method_name, :array_root => tag_name)
93
+ TagArray.new(config[:child_root] || tag_name.to_s.singularize, attrs, config[:array].map{|conf| build_tag(conf) }, config)
51
94
  else
52
- Tag.new(tag_name, config[:attributes], Value.new(method_name), config)
95
+ Tag.new(tag_name, attrs, Value.new(method_name), config)
53
96
  end
54
97
  end
55
98
 
data/lib/pump.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "pump/version"
2
2
  require "pump/xml"
3
3
 
4
+ # Fast but inflexible XML encoding for ruby objects.
4
5
  module Pump
5
6
  end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pump::Xml::Dsl do
4
+ subject { Pump::Xml::Dsl.new {} }
5
+
6
+ describe ".new" do
7
+ it "requires one block" do
8
+ lambda{ Pump::Xml::Dsl.new }.should raise_error(ArgumentError)
9
+ lambda{ subject }.should_not raise_error
10
+ end
11
+ end
12
+
13
+ describe "#config" do
14
+ its(:config) { should eql([]) }
15
+
16
+ context "with tag" do
17
+ subject { Pump::Xml::Dsl.new { tag :name } }
18
+ its(:config) { should eql([{:name => :name}]) }
19
+
20
+ context "with attributes and options" do
21
+ subject { Pump::Xml::Dsl.new { tag :name, :attributes => {:a => 'b'}, :options => false } }
22
+ its(:config) { should eql([{:name => :name, :attributes => {:a => 'b'}, :options => false}]) }
23
+ end
24
+
25
+ context "with :from option" do
26
+ subject { Pump::Xml::Dsl.new { tag :name, :from => :method_name } }
27
+ its(:config) { should eql([{:name => :method_name}]) }
28
+ end
29
+
30
+ context "with dashs in tag name" do
31
+ subject { Pump::Xml::Dsl.new { tag :"first-name" } }
32
+ its(:config) { should eql([{:"first-name" => :first_name}]) }
33
+ end
34
+ end
35
+
36
+ context "with string" do
37
+ subject { Pump::Xml::Dsl.new { string :name } }
38
+ its(:config) { should eql([{:name => :name}]) }
39
+
40
+ context "with attributes and options" do
41
+ subject { Pump::Xml::Dsl.new { string :name, :attributes => {:a => 'b'}, :options => false } }
42
+ its(:config) { should eql([{:name => :name, :attributes => {:a => 'b'}, :options => false}]) }
43
+ end
44
+ end
45
+
46
+ context "with integer" do
47
+ subject { Pump::Xml::Dsl.new { integer :name } }
48
+ its(:config) { should eql([{:name => :name, :attributes => {:type => 'integer'}, :xmlsafe => true}]) }
49
+
50
+ context "with attributes and options" do
51
+ subject { Pump::Xml::Dsl.new { integer :name, :attributes => {:a => 'b'}, :options => false } }
52
+ its(:config) { should eql([{:name => :name, :attributes => {:type => 'integer', :a => 'b'}, :options => false, :xmlsafe => true}]) }
53
+ end
54
+ end
55
+
56
+ context "with date" do
57
+ subject { Pump::Xml::Dsl.new { date :at } }
58
+ its(:config) { should eql([{:at => :at, :attributes => {:type => 'date'}, :xmlsafe => true}]) }
59
+
60
+ context "with attributes and options" do
61
+ subject { Pump::Xml::Dsl.new { date :at, :attributes => {:a => 'b'}, :options => false } }
62
+ its(:config) { should eql([{:at => :at, :attributes => {:type => 'date', :a => 'b'}, :options => false, :xmlsafe => true}]) }
63
+ end
64
+ end
65
+
66
+ context "with (date)time" do
67
+ subject { Pump::Xml::Dsl.new { time :at } }
68
+ its(:config) { should eql([{:at => :at, :typecast => :xmlschema, :attributes => {:type => 'datetime'}, :xmlsafe => true}]) }
69
+
70
+ context "with attributes and options" do
71
+ subject { Pump::Xml::Dsl.new { time :at, :attributes => {:a => 'b'}, :options => false } }
72
+ its(:config) { should eql([{:at => :at, :attributes => {:a => 'b', :type => 'datetime'}, :options => false, :typecast => :xmlschema, :xmlsafe => true}]) }
73
+ end
74
+ end
75
+
76
+ context "with nested tags" do
77
+ subject do
78
+ Pump::Xml::Dsl.new do
79
+ tag :person, :option => 'x' do
80
+ string :name
81
+ integer :age
82
+ end
83
+ string :parent_name
84
+ end
85
+ end
86
+ its(:config) { should eql([
87
+ {:person => [
88
+ {:name => :name},
89
+ {:age => :age, :attributes => {:type => 'integer'}, :xmlsafe => true}
90
+ ], :option => 'x'},
91
+ {:parent_name => :parent_name}
92
+ ]) }
93
+ end
94
+ end
95
+
96
+ context "with array tag" do
97
+ subject do
98
+ Pump::Xml::Dsl.new do
99
+ array(:children) do
100
+ tag :name
101
+ end
102
+ end
103
+ end
104
+
105
+ its(:config) { should eql(
106
+ [{:children => :children, :array => [{:name => :name}]}]
107
+ )}
108
+
109
+ context "with options" do
110
+ subject do
111
+ Pump::Xml::Dsl.new do
112
+ array(:children, :from => :kids, :child_root => :ugly_kid_joe) do
113
+ tag :name
114
+ end
115
+ end
116
+ end
117
+
118
+ its(:config) { should eql(
119
+ [{:children => :kids, :array => [{:name => :name}], :child_root => :ugly_kid_joe}]
120
+ )}
121
+ end
122
+ end
123
+ end
@@ -2,10 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe Pump::Xml do
4
4
  describe ".new" do
5
- it "requires two parameters" do
5
+ it "requires two parameters or one and a block" do
6
6
  lambda{ Pump::Xml.new }.should raise_error(ArgumentError)
7
7
  lambda{ Pump::Xml.new('record') }.should raise_error(ArgumentError)
8
8
  lambda{ Pump::Xml.new('record', []) }.should_not raise_error
9
+ lambda{ Pump::Xml.new('record') {} }.should_not raise_error
10
+ end
11
+
12
+ describe "with block given" do
13
+ subject do
14
+ Pump::Xml.new('human', :instruct => false) do
15
+ tag :name
16
+ end.encode(Struct.new(:name).new('Artur'))
17
+ end
18
+
19
+ its(:encode) { should eql("<human>\n <name>Artur</name>\n</human>\n")}
9
20
  end
10
21
  end
11
22
 
@@ -201,15 +212,27 @@ describe Pump::Xml do
201
212
  end
202
213
 
203
214
  context "deep array-like nesting" do
204
- let(:person) { Struct.new(:name, :children).new('Gustav', [Struct.new(:name).new('Lilly'), Struct.new(:name).new('Lena')]) }
205
- let(:xml) { Pump::Xml.new('person', [{:name => :name}, {:child => :children, :array => [{:name => :name}]}], :instruct => false) }
215
+ let(:person) {
216
+ Struct.new(:name, :children).new('Gustav', [
217
+ Struct.new(:name).new('Lilly'),
218
+ Struct.new(:name).new('Lena')
219
+ ]) }
220
+
221
+ let(:xml) { Pump::Xml.new('person', [{:name => :name}, {:children => :children,
222
+ :array => [{:name => :name}]}], :instruct => false) }
206
223
 
207
224
  it "returns xml string" do
208
225
  xml.encode(person).should eql("<person>\n <name>Gustav</name>\n <children type=\"array\">\n <child>\n <name>Lilly</name>\n </child>\n <child>\n <name>Lena</name>\n </child>\n </children>\n</person>\n")
209
226
  end
210
- end
211
-
212
227
 
228
+ context "overwriting child name" do
229
+ let(:xml) { Pump::Xml.new('person', [{:name => :name}, {:children => :children,
230
+ :array => [{:name => :name}], :child_root => 'kid'}], :instruct => false) }
213
231
 
232
+ it "returns xml string" do
233
+ xml.encode(person).should eql("<person>\n <name>Gustav</name>\n <children type=\"array\">\n <kid>\n <name>Lilly</name>\n </kid>\n <kid>\n <name>Lena</name>\n </kid>\n </children>\n</person>\n")
234
+ end
235
+ end
236
+ end
214
237
  end
215
238
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pump
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-11 00:00:00.000000000 Z
12
+ date: 2013-02-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -70,21 +70,24 @@ files:
70
70
  - .rbenv-gemsets
71
71
  - .rbenv-version
72
72
  - .rspec
73
+ - .yardopts
73
74
  - CHANGES.md
74
75
  - Gemfile
75
76
  - Guardfile
76
- - LICENSE.txt
77
+ - MIT-LICENSE
77
78
  - README.md
78
79
  - Rakefile
79
80
  - benchmarks/encode.rb
80
81
  - lib/pump.rb
81
82
  - lib/pump/version.rb
82
83
  - lib/pump/xml.rb
84
+ - lib/pump/xml/dsl.rb
83
85
  - lib/pump/xml/node.rb
84
86
  - lib/pump/xml/tag.rb
85
87
  - lib/pump/xml/tag_array.rb
86
88
  - lib/pump/xml/value.rb
87
89
  - pump.gemspec
90
+ - spec/pump/xml/dsl_spec.rb
88
91
  - spec/pump/xml/tag_array_spec.rb
89
92
  - spec/pump/xml/tag_spec.rb
90
93
  - spec/pump/xml/value_spec.rb
@@ -116,8 +119,10 @@ signing_key:
116
119
  specification_version: 3
117
120
  summary: Fast but inflexible XML encoding for ruby objects.
118
121
  test_files:
122
+ - spec/pump/xml/dsl_spec.rb
119
123
  - spec/pump/xml/tag_array_spec.rb
120
124
  - spec/pump/xml/tag_spec.rb
121
125
  - spec/pump/xml/value_spec.rb
122
126
  - spec/pump/xml_spec.rb
123
127
  - spec/spec_helper.rb
128
+ has_rdoc: