pump 0.2.0 → 0.3.0

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