dm-serializer 0.9.8 → 0.9.9
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/History.txt +14 -0
- data/Manifest.txt +11 -1
- data/README.textile +61 -0
- data/Rakefile +1 -1
- data/benchmarks/to_xml.rb +89 -0
- data/lib/dm-serializer/common.rb +24 -0
- data/lib/dm-serializer/to_csv.rb +35 -0
- data/lib/dm-serializer/to_json.rb +73 -0
- data/lib/dm-serializer/to_xml.rb +61 -0
- data/lib/dm-serializer/to_yaml.rb +48 -0
- data/lib/dm-serializer/version.rb +1 -1
- data/lib/dm-serializer/xml_serializers/libxml.rb +29 -0
- data/lib/dm-serializer/xml_serializers/nokogiri.rb +28 -0
- data/lib/dm-serializer/xml_serializers/rexml.rb +23 -0
- data/lib/dm-serializer/xml_serializers.rb +17 -0
- data/lib/dm-serializer.rb +4 -230
- data/spec/fixtures/cow.rb +0 -4
- data/spec/lib/serialization_method_shared_spec.rb +41 -0
- data/spec/public/to_json_spec.rb +1 -39
- data/spec/public/to_xml_spec.rb +76 -63
- data/spec/public/to_yaml_spec.rb +11 -6
- data/spec/spec_helper.rb +3 -2
- metadata +15 -5
- data/README.txt +0 -3
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 0.9.9 / 2009-01-04
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Uses LibXML or Nokogiri if available for a ~6x improvement in
|
6
|
+
serialization performance.
|
7
|
+
|
8
|
+
* 4 minor enhancements:
|
9
|
+
|
10
|
+
* Added :element_name and :collection_element_name options to #to_xml
|
11
|
+
* Removed #xml_element_name override in #to_xml
|
12
|
+
* Removed :read_only_attributes option from #to_json
|
13
|
+
* Removed #serialized_properties override in #to_json
|
14
|
+
|
1
15
|
=== 0.9.8 / 2008-12-07
|
2
16
|
|
3
17
|
* 2 minor enhancements:
|
data/Manifest.txt
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
History.txt
|
2
2
|
LICENSE
|
3
3
|
Manifest.txt
|
4
|
-
README.
|
4
|
+
README.textile
|
5
5
|
Rakefile
|
6
6
|
TODO
|
7
7
|
autotest/discover.rb
|
8
8
|
autotest/dmserializer_rspec.rb
|
9
|
+
benchmarks/to_xml.rb
|
9
10
|
lib/dm-serializer.rb
|
11
|
+
lib/dm-serializer/common.rb
|
12
|
+
lib/dm-serializer/to_csv.rb
|
13
|
+
lib/dm-serializer/to_json.rb
|
14
|
+
lib/dm-serializer/to_xml.rb
|
15
|
+
lib/dm-serializer/to_yaml.rb
|
10
16
|
lib/dm-serializer/version.rb
|
17
|
+
lib/dm-serializer/xml_serializers.rb
|
18
|
+
lib/dm-serializer/xml_serializers/libxml.rb
|
19
|
+
lib/dm-serializer/xml_serializers/nokogiri.rb
|
20
|
+
lib/dm-serializer/xml_serializers/rexml.rb
|
11
21
|
spec/fixtures/cow.rb
|
12
22
|
spec/fixtures/planet.rb
|
13
23
|
spec/fixtures/quan_tum_cat.rb
|
data/README.textile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
h1. dm-serializer
|
2
|
+
|
3
|
+
h2. Overview
|
4
|
+
|
5
|
+
dm-serializer allows DataMapper models and collections to be serialized to a variety of formats (currently JSON, XML, YAML and CSV).
|
6
|
+
|
7
|
+
h2. How it works
|
8
|
+
|
9
|
+
One method is added to each model/collection for each serialization type - @to_json@, @to_xml@, @to_yaml@, and @to_csv@. With the exception of @to_csv@, all of these methods share the same interface. @to_json@ will be used for examples. Any method specific behaviour is documented in its own section below.
|
10
|
+
|
11
|
+
<pre><code>require 'dm-serializer'
|
12
|
+
|
13
|
+
class Cow
|
14
|
+
include DataMapper::Resource
|
15
|
+
|
16
|
+
property :id, Integer, :key => true
|
17
|
+
property :name, String
|
18
|
+
|
19
|
+
def description
|
20
|
+
"A Cow"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
cow = Cow.create(
|
25
|
+
:id => 1,
|
26
|
+
:name => "Berta"
|
27
|
+
)
|
28
|
+
|
29
|
+
cow.to_json # => { "id": 1, "name": "Berta" }
|
30
|
+
cow.to_json(:only => [:name]) # => { "name": "Berta" }
|
31
|
+
cow.to_json(:exclude => [:id]) # => { "name": "Berta" }
|
32
|
+
cow.to_json(:methods => [:desc]) # => { "id": 1, "name": "Berta", "desc": "A Cow" }</code></pre>
|
33
|
+
|
34
|
+
You can include associations by passing the association accessor the @:methods@ option.
|
35
|
+
|
36
|
+
If you want to only load a particular serialization method, that's cool, you can do that:
|
37
|
+
|
38
|
+
<pre><code>require 'dm-serializer/to_json'</code></pre>
|
39
|
+
|
40
|
+
h2. to_xml
|
41
|
+
|
42
|
+
@to_xml@ supports some extra options to allow you to override the element names
|
43
|
+
|
44
|
+
<pre><code>cow.to_xml( :element_name => 'bovine') # => <bovine><id>1</id><name>Berta</name></bovine>
|
45
|
+
cows.to_xml(:collection_element_name => 'kine') # => <kine><bovine><id>1</id><name>Berta</name></bovine></kine></code></pre>
|
46
|
+
|
47
|
+
If you would like a nice speed boost (~5x), require @libxml@ or @nokogiri@ before @dm-serializer@, and that library will be used rather than REXML.
|
48
|
+
|
49
|
+
h2. to_csv
|
50
|
+
|
51
|
+
@to_csv@ currently doesn't support any options yet. It will in the future. It will not support serializing child associations.
|
52
|
+
|
53
|
+
h2. Arrays, Hashes, and other core classes
|
54
|
+
|
55
|
+
@dm-serializer@ only adds serialization methods to DataMapper objects and collections, however some libraries used (json, yaml) add methods to core classes, such as @Array@. Note that passing @dm-serializer@ options (such as @:only@) to these methods is *not supported*.
|
56
|
+
|
57
|
+
<pre><code>Cow.all.to_a.to_yaml(:only => 'name') # WILL NOT WORK</code></pre>
|
58
|
+
|
59
|
+
h2. Beware
|
60
|
+
|
61
|
+
If you go spelunking through the code you will find other undocumented options. Use at your own risk, I plan on removing or changing these in the near future.
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ GEM_NAME = 'dm-serializer'
|
|
14
14
|
GEM_VERSION = DataMapper::Serializer::VERSION
|
15
15
|
GEM_DEPENDENCIES = [['dm-core', "~>#{GEM_VERSION}"]]
|
16
16
|
GEM_CLEAN = %w[ log pkg coverage ]
|
17
|
-
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.
|
17
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.textile LICENSE TODO History.txt ] }
|
18
18
|
|
19
19
|
PROJECT_NAME = 'datamapper'
|
20
20
|
PROJECT_URL = "http://github.com/sam/dm-more/tree/master/#{GEM_NAME}"
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
gem 'dm-core', '~>0.9.9'
|
5
|
+
require 'dm-core'
|
6
|
+
|
7
|
+
spec_dir_path = Pathname(__FILE__).dirname.expand_path
|
8
|
+
$LOAD_PATH.unshift(spec_dir_path.parent + 'lib/')
|
9
|
+
require 'dm-serializer'
|
10
|
+
|
11
|
+
def load_driver(name, default_uri)
|
12
|
+
begin
|
13
|
+
DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
|
14
|
+
DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
|
15
|
+
DataMapper::Repository.adapters[:alternate] = DataMapper::Repository.adapters[name]
|
16
|
+
true
|
17
|
+
rescue LoadError => e
|
18
|
+
warn "Could not load do_#{name}: #{e}"
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
|
24
|
+
|
25
|
+
class Cow
|
26
|
+
include DataMapper::Resource
|
27
|
+
|
28
|
+
property :id, Integer, :key => true
|
29
|
+
property :composite, Integer, :key => true
|
30
|
+
property :name, String
|
31
|
+
property :breed, String
|
32
|
+
|
33
|
+
has n, :baby_cows, :class_name => 'Cow'
|
34
|
+
belongs_to :mother_cow, :class_name => 'Cow'
|
35
|
+
end
|
36
|
+
|
37
|
+
require "benchwarmer"
|
38
|
+
|
39
|
+
TIMES = 2000
|
40
|
+
DataMapper.auto_migrate!
|
41
|
+
cow = Cow.create(
|
42
|
+
:id => 89,
|
43
|
+
:composite => 34,
|
44
|
+
:name => 'Berta',
|
45
|
+
:breed => 'Guernsey'
|
46
|
+
)
|
47
|
+
all_cows = Cow.all
|
48
|
+
|
49
|
+
puts "REXML"
|
50
|
+
Benchmark.warmer(TIMES) do
|
51
|
+
group("Serialization:") do
|
52
|
+
report "Single Resource" do
|
53
|
+
cow.to_xml
|
54
|
+
end
|
55
|
+
report "Collection" do
|
56
|
+
all_cows.to_xml
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
require 'nokogiri'
|
62
|
+
load 'dm-serializer/xml_serializers.rb'
|
63
|
+
|
64
|
+
puts "Nokogiri"
|
65
|
+
Benchmark.warmer(TIMES) do
|
66
|
+
group("Serialization:") do
|
67
|
+
report "Single Resource" do
|
68
|
+
cow.to_xml
|
69
|
+
end
|
70
|
+
report "Collection" do
|
71
|
+
all_cows.to_xml
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
require 'libxml'
|
77
|
+
load 'dm-serializer/xml_serializers.rb'
|
78
|
+
|
79
|
+
puts "LibXML"
|
80
|
+
Benchmark.warmer(TIMES) do
|
81
|
+
group("Serialization:") do
|
82
|
+
report "Single Resource" do
|
83
|
+
cow.to_xml
|
84
|
+
end
|
85
|
+
report "Collection" do
|
86
|
+
all_cows.to_xml
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
# Returns propreties to serialize based on :only or :exclude arrays, if provided
|
4
|
+
# :only takes precendence over :exclude
|
5
|
+
#
|
6
|
+
# @return <Array> properties that need to be serialized
|
7
|
+
def properties_to_serialize(options)
|
8
|
+
only_properties = Array(options[:only])
|
9
|
+
excluded_properties = Array(options[:exclude])
|
10
|
+
|
11
|
+
self.class.properties(repository.name).reject do |p|
|
12
|
+
if only_properties.include? p.name
|
13
|
+
false
|
14
|
+
else
|
15
|
+
excluded_properties.include?(p.name) || !(only_properties.empty? || only_properties.include?(p.name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Resource
|
22
|
+
include Serialize
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem('fastercsv')
|
5
|
+
require 'faster_csv'
|
6
|
+
rescue LoadError
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
module DataMapper
|
11
|
+
module Serialize
|
12
|
+
# Serialize a Resource to comma-separated values (CSV).
|
13
|
+
#
|
14
|
+
# @return <String> a CSV representation of the Resource
|
15
|
+
def to_csv(writer = '')
|
16
|
+
FasterCSV.generate(writer) do |csv|
|
17
|
+
row = []
|
18
|
+
self.class.properties(repository.name).each do |property|
|
19
|
+
row << send(property.name).to_s
|
20
|
+
end
|
21
|
+
csv << row
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Collection
|
27
|
+
def to_csv
|
28
|
+
result = ""
|
29
|
+
each do |item|
|
30
|
+
result << item.to_csv + "\n"
|
31
|
+
end
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem('json')
|
5
|
+
require 'json/ext'
|
6
|
+
rescue LoadError
|
7
|
+
gem('json_pure')
|
8
|
+
require 'json/pure'
|
9
|
+
end
|
10
|
+
|
11
|
+
module DataMapper
|
12
|
+
module Serialize
|
13
|
+
# Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
|
14
|
+
#
|
15
|
+
# @return <String> a JSON representation of the Resource
|
16
|
+
def to_json(*args)
|
17
|
+
options = args.first || {}
|
18
|
+
result = '{ '
|
19
|
+
fields = []
|
20
|
+
|
21
|
+
propset = properties_to_serialize(options)
|
22
|
+
|
23
|
+
fields += propset.map do |property|
|
24
|
+
"#{property.name.to_json}: #{send(property.getter).to_json}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# add methods
|
28
|
+
(options[:methods] || []).each do |meth|
|
29
|
+
if self.respond_to?(meth)
|
30
|
+
fields << "#{meth.to_json}: #{send(meth).to_json}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Note: if you want to include a whole other model via relation, use :methods
|
35
|
+
# comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
|
36
|
+
# add relationships
|
37
|
+
# TODO: This needs tests and also needs to be ported to #to_xml and #to_yaml
|
38
|
+
(options[:relationships] || {}).each do |rel,opts|
|
39
|
+
if self.respond_to?(rel)
|
40
|
+
fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
result << fields.join(', ')
|
45
|
+
result << ' }'
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module Associations
|
51
|
+
# the json gem adds Object#to_json, which breaks the DM proxies, since it
|
52
|
+
# happens *after* the proxy has been blank slated. This code removes the added
|
53
|
+
# method, so it is delegated correctly to the Collection
|
54
|
+
proxies = []
|
55
|
+
|
56
|
+
proxies << ManyToMany::Proxy if defined?(ManyToMany::Proxy)
|
57
|
+
proxies << OneToMany::Proxy if defined?(OneToMany::Proxy)
|
58
|
+
proxies << ManyToOne::Proxy if defined?(ManyToOne::Proxy)
|
59
|
+
|
60
|
+
proxies.each do |proxy|
|
61
|
+
if proxy.public_instance_methods.any? { |m| m.to_sym == :to_json }
|
62
|
+
proxy.send(:undef_method, :to_json)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Collection
|
68
|
+
def to_json(*args)
|
69
|
+
opts = args.first || {}
|
70
|
+
"[" << map {|e| e.to_json(opts)}.join(",") << "]"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
require 'dm-serializer/xml_serializers'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
module Serialize
|
7
|
+
# Serialize a Resource to XML
|
8
|
+
#
|
9
|
+
# @return <REXML::Document> an XML representation of this Resource
|
10
|
+
def to_xml(opts = {})
|
11
|
+
to_xml_document(opts).to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
# This method requires certain methods to be implemented in the individual
|
16
|
+
# serializer library subclasses:
|
17
|
+
# new_document
|
18
|
+
# root_node
|
19
|
+
# add_property_node
|
20
|
+
# add_node
|
21
|
+
def to_xml_document(opts={}, doc = nil)
|
22
|
+
xml = XMLSerializers::SERIALIZER
|
23
|
+
doc ||= xml.new_document
|
24
|
+
default_xml_element_name = lambda { Extlib::Inflection.underscore(self.class.name).tr("/", "-") }
|
25
|
+
root = xml.root_node(doc, opts[:element_name] || default_xml_element_name[])
|
26
|
+
properties_to_serialize(opts).each do |property|
|
27
|
+
value = send(property.name)
|
28
|
+
attrs = (property.type == String) ? {} : {'type' => property.type.to_s.downcase}
|
29
|
+
xml.add_node(root, property.name.to_s, value, attrs)
|
30
|
+
end
|
31
|
+
|
32
|
+
(opts[:methods] || []).each do |meth|
|
33
|
+
if self.respond_to?(meth)
|
34
|
+
xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
|
35
|
+
value = send(meth)
|
36
|
+
xml.add_node(root, xml_name, value.to_s) unless value.nil?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
doc
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Collection
|
44
|
+
def to_xml(opts = {})
|
45
|
+
to_xml_document(opts).to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def to_xml_document(opts = {})
|
51
|
+
xml = DataMapper::Serialize::XMLSerializers::SERIALIZER
|
52
|
+
doc = xml.new_document
|
53
|
+
default_collection_element_name = lambda {Extlib::Inflection.pluralize(Extlib::Inflection.underscore(self.model.to_s)).tr("/", "-")}
|
54
|
+
root = xml.root_node(doc, opts[:collection_element_name] || default_collection_element_name[], {'type' => 'array'})
|
55
|
+
self.each do |item|
|
56
|
+
item.send(:to_xml_document, opts, doc)
|
57
|
+
end
|
58
|
+
doc
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Serialize
|
5
|
+
# Serialize a Resource to YAML
|
6
|
+
#
|
7
|
+
# @return <YAML> a YAML representation of this Resource
|
8
|
+
def to_yaml(opts_or_emitter = {})
|
9
|
+
if opts_or_emitter.is_a?(YAML::Syck::Emitter)
|
10
|
+
emitter = opts_or_emitter
|
11
|
+
opts = {}
|
12
|
+
else
|
13
|
+
emitter = {}
|
14
|
+
opts = opts_or_emitter
|
15
|
+
end
|
16
|
+
|
17
|
+
YAML::quick_emit(object_id,emitter) do |out|
|
18
|
+
out.map(nil,to_yaml_style) do |map|
|
19
|
+
propset = properties_to_serialize(opts)
|
20
|
+
propset.each do |property|
|
21
|
+
value = send(property.name.to_sym)
|
22
|
+
map.add(property.name, value.is_a?(Class) ? value.to_s : value)
|
23
|
+
end
|
24
|
+
# add methods
|
25
|
+
(opts[:methods] || []).each do |meth|
|
26
|
+
if self.respond_to?(meth)
|
27
|
+
map.add(meth.to_sym, send(meth))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
(instance_variable_get("@yaml_addes") || []).each do |k,v|
|
31
|
+
map.add(k.to_s,v)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Collection
|
39
|
+
def to_yaml(opts_or_emitter = {})
|
40
|
+
if opts_or_emitter.is_a?(YAML::Syck::Emitter)
|
41
|
+
to_a.to_yaml(opts_or_emitter)
|
42
|
+
else
|
43
|
+
# FIXME: Don't double handle the YAML (remove the YAML.load)
|
44
|
+
to_a.collect {|x| YAML.load(x.to_yaml(opts_or_emitter)) }.to_yaml
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module LibXML
|
5
|
+
def self.new_document
|
6
|
+
::LibXML::XML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(doc, name, attrs = {})
|
10
|
+
root = ::LibXML::XML::Node.new(name)
|
11
|
+
attrs.each do |attr_name, attr_val|
|
12
|
+
root[attr_name] = attr_val
|
13
|
+
end
|
14
|
+
doc.root.nil? ? doc.root = root : doc.root << root
|
15
|
+
root
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_node(parent, name, value, attrs = {})
|
19
|
+
value_str = value.to_s unless value.nil?
|
20
|
+
node = ::LibXML::XML::Node.new(name, value_str)
|
21
|
+
attrs.each do |attr_name, attr_val|
|
22
|
+
node[attr_name] = attr_val
|
23
|
+
end
|
24
|
+
parent << node
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module Nokogiri
|
5
|
+
def self.new_document
|
6
|
+
::Nokogiri::XML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(doc, name, attrs = {})
|
10
|
+
root = ::Nokogiri::XML::Node.new(name, doc)
|
11
|
+
attrs.each do |attr_name, attr_val|
|
12
|
+
root[attr_name] = attr_val
|
13
|
+
end
|
14
|
+
doc.root.nil? ? doc.root = root : doc.root << root
|
15
|
+
root
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_node(parent, name, value, attrs = {})
|
19
|
+
node = ::Nokogiri::XML::Node.new(name, parent.document)
|
20
|
+
node << ::Nokogiri::XML::Text.new(value.to_s, parent.document) unless value.nil?
|
21
|
+
attrs.each {|attr_name, attr_val| node[attr_name] = attr_val }
|
22
|
+
parent << node
|
23
|
+
node
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module REXML
|
5
|
+
def self.new_document
|
6
|
+
::REXML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(document, name, attrs = {})
|
10
|
+
add_node(document.root || document, name, nil, attrs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.add_node(parent, name, value, attrs = {})
|
14
|
+
node = parent.add_element(name)
|
15
|
+
attrs.each {|attr_name, attr_val| node.attributes[attr_name] = attr_val}
|
16
|
+
node << ::REXML::Text.new(value.to_s) unless value.nil?
|
17
|
+
node
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'dm-serializer/xml_serializers/rexml'
|
2
|
+
require 'dm-serializer/xml_serializers/nokogiri'
|
3
|
+
require 'dm-serializer/xml_serializers/libxml'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
module Serialize
|
7
|
+
module XMLSerializers
|
8
|
+
SERIALIZER = if defined?(::LibXML)
|
9
|
+
LibXML
|
10
|
+
elsif defined?(::Nokogiri)
|
11
|
+
Nokogiri
|
12
|
+
else
|
13
|
+
REXML
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/dm-serializer.rb
CHANGED
@@ -1,230 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require 'faster_csv'
|
6
|
-
rescue LoadError
|
7
|
-
nil
|
8
|
-
end
|
9
|
-
|
10
|
-
begin
|
11
|
-
gem('json')
|
12
|
-
require 'json/ext'
|
13
|
-
rescue LoadError
|
14
|
-
gem('json_pure')
|
15
|
-
require 'json/pure'
|
16
|
-
end
|
17
|
-
|
18
|
-
module DataMapper
|
19
|
-
module Serialize
|
20
|
-
# Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
|
21
|
-
#
|
22
|
-
# @return <String> a JSON representation of the Resource
|
23
|
-
def to_json(*args)
|
24
|
-
options = args.first || {}
|
25
|
-
result = '{ '
|
26
|
-
fields = []
|
27
|
-
|
28
|
-
propset = properties_to_serialize(options)
|
29
|
-
|
30
|
-
fields += propset.map do |property|
|
31
|
-
"#{property.name.to_json}: #{send(property.getter).to_json}"
|
32
|
-
end
|
33
|
-
|
34
|
-
if self.respond_to?(:serialize_properties)
|
35
|
-
self.serialize_properties.each do |k,v|
|
36
|
-
fields << "#{k.to_json}: #{v.to_json}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
if self.class.respond_to?(:read_only_attributes) && exclude_read_only
|
41
|
-
self.class.read_only_attributes.each do |property|
|
42
|
-
fields << "#{property.to_json}: #{send(property).to_json}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# add methods
|
47
|
-
(options[:methods] || []).each do |meth|
|
48
|
-
if self.respond_to?(meth)
|
49
|
-
fields << "#{meth.to_json}: #{send(meth).to_json}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Note: if you want to include a whole other model via relation, use :methods
|
54
|
-
# comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
|
55
|
-
# add relationships
|
56
|
-
(options[:relationships] || {}).each do |rel,opts|
|
57
|
-
if self.respond_to?(rel)
|
58
|
-
fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
result << fields.join(', ')
|
63
|
-
result << ' }'
|
64
|
-
result
|
65
|
-
end
|
66
|
-
|
67
|
-
# Serialize a Resource to comma-separated values (CSV).
|
68
|
-
#
|
69
|
-
# @return <String> a CSV representation of the Resource
|
70
|
-
def to_csv(writer = '')
|
71
|
-
FasterCSV.generate(writer) do |csv|
|
72
|
-
row = []
|
73
|
-
self.class.properties(repository.name).each do |property|
|
74
|
-
row << send(property.name).to_s
|
75
|
-
end
|
76
|
-
csv << row
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Serialize a Resource to XML
|
81
|
-
#
|
82
|
-
# @return <REXML::Document> an XML representation of this Resource
|
83
|
-
def to_xml(opts = {})
|
84
|
-
|
85
|
-
to_xml_document(opts).to_s
|
86
|
-
end
|
87
|
-
|
88
|
-
# Serialize a Resource to YAML
|
89
|
-
#
|
90
|
-
# @return <YAML> a YAML representation of this Resource
|
91
|
-
def to_yaml(opts = {})
|
92
|
-
YAML::quick_emit(object_id,opts) do |out|
|
93
|
-
out.map(nil,to_yaml_style) do |map|
|
94
|
-
propset = properties_to_serialize(opts)
|
95
|
-
propset.each do |property|
|
96
|
-
value = send(property.name.to_sym)
|
97
|
-
map.add(property.name, value.is_a?(Class) ? value.to_s : value)
|
98
|
-
end
|
99
|
-
# add methods
|
100
|
-
(opts[:methods] || []).each do |meth|
|
101
|
-
if self.respond_to?(meth)
|
102
|
-
map.add(meth.to_sym, send(meth))
|
103
|
-
end
|
104
|
-
end
|
105
|
-
(instance_variable_get("@yaml_addes") || []).each do |k,v|
|
106
|
-
map.add(k.to_s,v)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
protected
|
113
|
-
|
114
|
-
# Returns propreties to serialize based on :only or :exclude arrays, if provided
|
115
|
-
# :only takes precendence over :exclude
|
116
|
-
#
|
117
|
-
# @return <Array> properties that need to be serialized
|
118
|
-
def properties_to_serialize(options)
|
119
|
-
only_properties = Array(options[:only])
|
120
|
-
excluded_properties = Array(options[:exclude])
|
121
|
-
exclude_read_only = options[:without_read_only_attributes] || false
|
122
|
-
|
123
|
-
self.class.properties(repository.name).reject do |p|
|
124
|
-
if only_properties.include? p.name
|
125
|
-
false
|
126
|
-
else
|
127
|
-
excluded_properties.include?(p.name) || !(only_properties.empty? || only_properties.include?(p.name))
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
# Return the name of this Resource - to be used as the root element name.
|
134
|
-
# This can be overloaded.
|
135
|
-
#
|
136
|
-
# @return <String> name of this Resource
|
137
|
-
def xml_element_name
|
138
|
-
Extlib::Inflection.underscore(self.class.name).tr("/", "-")
|
139
|
-
end
|
140
|
-
|
141
|
-
# Return a REXML::Document representing this Resource
|
142
|
-
#
|
143
|
-
# @return <REXML::Document> an XML representation of this Resource
|
144
|
-
def to_xml_document(opts={}, doc=nil)
|
145
|
-
doc ||= REXML::Document.new
|
146
|
-
root = doc.add_element(xml_element_name)
|
147
|
-
|
148
|
-
#TODO old code base was converting single quote to double quote on attribs
|
149
|
-
|
150
|
-
propset = properties_to_serialize(opts)
|
151
|
-
propset.each do |property|
|
152
|
-
value = send(property.name)
|
153
|
-
node = root.add_element(property.name.to_s)
|
154
|
-
unless property.type == String
|
155
|
-
node.attributes["type"] = property.type.to_s.downcase
|
156
|
-
end
|
157
|
-
node << REXML::Text.new(value.to_s) unless value.nil?
|
158
|
-
end
|
159
|
-
|
160
|
-
# add methods
|
161
|
-
(opts[:methods] || []).each do |meth|
|
162
|
-
if self.respond_to?(meth)
|
163
|
-
xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
|
164
|
-
node = root.add_element(xml_name)
|
165
|
-
value = send(meth)
|
166
|
-
node << REXML::Text.new(value.to_s, :raw => true) unless value.nil?
|
167
|
-
end
|
168
|
-
end
|
169
|
-
doc
|
170
|
-
end
|
171
|
-
|
172
|
-
end # module Serialize
|
173
|
-
|
174
|
-
module Resource
|
175
|
-
include Serialize
|
176
|
-
end # module Resource
|
177
|
-
|
178
|
-
# the json gem adds Object#to_json, which breaks the DM proxies, since it
|
179
|
-
# happens *after* the proxy has been blank slated. This code removes the added
|
180
|
-
# method, so it is delegated correctly to the Collection
|
181
|
-
[
|
182
|
-
Associations::OneToMany::Proxy,
|
183
|
-
(Associations::ManyToOne::Proxy if defined?(Associations::ManyToOne::Proxy)),
|
184
|
-
Associations::ManyToMany::Proxy
|
185
|
-
].each do |proxy|
|
186
|
-
[:to_json].each do |method|
|
187
|
-
proxy.send(:undef_method, :to_json) rescue nil
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
class Collection
|
192
|
-
def to_yaml(opts = {})
|
193
|
-
# FIXME: Don't double handle the YAML (remove the YAML.load)
|
194
|
-
to_a.collect {|x| YAML.load(x.to_yaml(opts)) }.to_yaml
|
195
|
-
end
|
196
|
-
|
197
|
-
def to_json(*args)
|
198
|
-
opts = args.first || {}
|
199
|
-
"[" << map {|e| e.to_json(opts)}.join(",") << "]"
|
200
|
-
end
|
201
|
-
|
202
|
-
def to_xml(opts = {})
|
203
|
-
to_xml_document(opts).to_s
|
204
|
-
end
|
205
|
-
|
206
|
-
def to_csv
|
207
|
-
result = ""
|
208
|
-
each do |item|
|
209
|
-
result << item.to_csv + "\n"
|
210
|
-
end
|
211
|
-
result
|
212
|
-
end
|
213
|
-
|
214
|
-
protected
|
215
|
-
def xml_element_name
|
216
|
-
Extlib::Inflection.pluralize(Extlib::Inflection.underscore(self.model.to_s)).tr("/", "-")
|
217
|
-
end
|
218
|
-
|
219
|
-
def to_xml_document(opts={})
|
220
|
-
doc = REXML::Document.new
|
221
|
-
root = doc.add_element(xml_element_name)
|
222
|
-
root.attributes["type"] = 'array'
|
223
|
-
each do |item|
|
224
|
-
item.send(:to_xml_document, opts, root)
|
225
|
-
end
|
226
|
-
doc
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
end # module DataMapper
|
1
|
+
require 'dm-serializer/to_json'
|
2
|
+
require 'dm-serializer/to_xml'
|
3
|
+
require 'dm-serializer/to_yaml'
|
4
|
+
require 'dm-serializer/to_csv'
|
data/spec/fixtures/cow.rb
CHANGED
@@ -1,6 +1,47 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
3
|
|
4
|
+
share_examples_for 'A serialization method that also serializes core classes' do
|
5
|
+
# This spec ensures that we don't break any serialization methods attached
|
6
|
+
# to core classes, such as Array
|
7
|
+
before(:all) do
|
8
|
+
%w[ @harness ].each do |ivar|
|
9
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
|
10
|
+
end
|
11
|
+
|
12
|
+
DataMapper.auto_migrate!
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
Cow.all.destroy!
|
17
|
+
Planet.all.destroy!
|
18
|
+
FriendedPlanet.all.destroy!
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'serializes an array of extended objects' do
|
22
|
+
Cow.create(
|
23
|
+
:id => 89,
|
24
|
+
:composite => 34,
|
25
|
+
:name => 'Berta',
|
26
|
+
:breed => 'Guernsey'
|
27
|
+
)
|
28
|
+
result = @harness.test(Cow.all.to_a)
|
29
|
+
result[0].values_at("id", "composite", "name", "breed").should ==
|
30
|
+
[89, 34, "Berta", "Guernsey"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'serializes an array of collections' do
|
34
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
35
|
+
collection = DataMapper::Collection.new(query) do |c|
|
36
|
+
c.load([1, 2, 'Betsy', 'Jersey'])
|
37
|
+
c.load([89, 34, 'Berta', 'Guernsey'])
|
38
|
+
end
|
39
|
+
result = @harness.test([collection])
|
40
|
+
result[0][1].values_at("id", "composite", "name", "breed").should ==
|
41
|
+
[89, 34, "Berta", "Guernsey"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
4
45
|
share_examples_for 'A serialization method' do
|
5
46
|
before(:all) do
|
6
47
|
%w[ @harness ].each do |ivar|
|
data/spec/public/to_json_spec.rb
CHANGED
@@ -29,45 +29,7 @@ describe DataMapper::Serialize, '#to_json' do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it_should_behave_like "A serialization method"
|
32
|
-
|
33
|
-
it "should serialize an array of collections" do
|
34
|
-
deserialized_collection = JSON.parse([@collection].to_json).first
|
35
|
-
betsy = deserialized_collection.first
|
36
|
-
berta = deserialized_collection.last
|
37
|
-
|
38
|
-
betsy["id"].should == 1
|
39
|
-
betsy["composite"].should == 2
|
40
|
-
betsy["name"].should == "Betsy"
|
41
|
-
betsy["breed"].should == "Jersey"
|
42
|
-
|
43
|
-
berta["id"].should == 10
|
44
|
-
berta["composite"].should == 20
|
45
|
-
berta["name"].should == "Berta"
|
46
|
-
berta["breed"].should == "Guernsey"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should serialize an array of extended objects" do
|
50
|
-
deserialized_collection = JSON.parse(@collection.to_a.to_json)
|
51
|
-
betsy = deserialized_collection.first
|
52
|
-
berta = deserialized_collection.last
|
53
|
-
|
54
|
-
betsy["id"].should == 1
|
55
|
-
betsy["composite"].should == 2
|
56
|
-
betsy["name"].should == "Betsy"
|
57
|
-
betsy["breed"].should == "Jersey"
|
58
|
-
|
59
|
-
berta["id"].should == 10
|
60
|
-
berta["composite"].should == 20
|
61
|
-
berta["name"].should == "Berta"
|
62
|
-
berta["breed"].should == "Guernsey"
|
63
|
-
end
|
64
|
-
|
65
|
-
it "handles extra properties" do
|
66
|
-
deserialized_hash = JSON.parse(Cow.new(:id => 1, :name => "Harry", :breed => "Angus").to_json)
|
67
|
-
|
68
|
-
deserialized_hash["extra"].should == "Extra"
|
69
|
-
deserialized_hash["another"].should == 42
|
70
|
-
end
|
32
|
+
it_should_behave_like 'A serialization method that also serializes core classes'
|
71
33
|
|
72
34
|
it "handles options given to a collection properly" do
|
73
35
|
deserialized_collection = JSON.parse(@collection.to_json(:only => [:composite]))
|
data/spec/public/to_xml_spec.rb
CHANGED
@@ -1,89 +1,102 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
{
|
5
|
+
'REXML' => nil,
|
6
|
+
'LibXML' => 'libxml',
|
7
|
+
'Nokogiri' => 'nokogiri'
|
8
|
+
}.each do |lib, file_to_require|
|
9
|
+
begin
|
10
|
+
require file_to_require if file_to_require
|
11
|
+
rescue LoadError
|
12
|
+
warn "[WARNING] Cannot require '#{file_to_require}', not running #to_xml specs for #{lib}"
|
13
|
+
next
|
14
|
+
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
16
|
+
describe DataMapper::Serialize, "#to_xml using #{lib}" do
|
17
|
+
#
|
18
|
+
# ==== enterprisey XML
|
19
|
+
#
|
20
|
+
|
21
|
+
before(:all) do
|
22
|
+
@harness = Class.new(SerializerTestHarness) do
|
23
|
+
def method_name
|
24
|
+
:to_xml
|
25
|
+
end
|
14
26
|
|
15
|
-
|
27
|
+
protected
|
16
28
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
29
|
+
def deserialize(result)
|
30
|
+
doc = REXML::Document.new(result)
|
31
|
+
root = doc.elements[1]
|
32
|
+
if root.attributes["type"] == "array"
|
33
|
+
root.elements.collect do |element|
|
34
|
+
a = {}
|
35
|
+
element.elements.each do |v|
|
36
|
+
a.update(v.name => cast(v.text, v.attributes["type"]))
|
37
|
+
end
|
38
|
+
a
|
39
|
+
end
|
40
|
+
else
|
22
41
|
a = {}
|
23
|
-
|
42
|
+
root.elements.each do |v|
|
24
43
|
a.update(v.name => cast(v.text, v.attributes["type"]))
|
25
44
|
end
|
26
45
|
a
|
27
46
|
end
|
28
|
-
else
|
29
|
-
a = {}
|
30
|
-
root.elements.each do |v|
|
31
|
-
a.update(v.name => cast(v.text, v.attributes["type"]))
|
32
|
-
end
|
33
|
-
a
|
34
47
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def cast(value, type)
|
38
|
-
boolean_conversions = {"true" => true, "false" => false}
|
39
|
-
value = boolean_conversions[value] if boolean_conversions.has_key?(value)
|
40
|
-
value = value.to_i if value && type == "integer"
|
41
|
-
value
|
42
|
-
end
|
43
|
-
end.new
|
44
|
-
end
|
45
|
-
|
46
|
-
it_should_behave_like "A serialization method"
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def cast(value, type)
|
50
|
+
boolean_conversions = {"true" => true, "false" => false}
|
51
|
+
value = boolean_conversions[value] if boolean_conversions.has_key?(value)
|
52
|
+
value = value.to_i if value && type == "integer"
|
53
|
+
value
|
54
|
+
end
|
55
|
+
end.new
|
56
|
+
DataMapper::Serialize::XMLSerializers.instance_eval { remove_const('SERIALIZER') }
|
57
|
+
DataMapper::Serialize::XMLSerializers::SERIALIZER = DataMapper::Serialize::XMLSerializers::const_get(lib)
|
51
58
|
end
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
60
|
+
it_should_behave_like "A serialization method"
|
61
|
+
|
62
|
+
describe ':element_name option for Resource' do
|
63
|
+
it 'should be used as the root node name by #to_xml' do
|
64
|
+
planet = Planet.new
|
65
|
+
xml = planet.to_xml(:element_name => "aplanet")
|
66
|
+
REXML::Document.new(xml).elements[1].name.should == "aplanet"
|
59
67
|
end
|
60
68
|
|
61
|
-
|
62
|
-
|
69
|
+
it 'when not specified the class name underscored and with slashes replaced with dashes should be used as the root node name' do
|
70
|
+
cat = QuanTum::Cat.new
|
71
|
+
xml = cat.to_xml
|
72
|
+
REXML::Document.new(xml).elements[1].name.should == "quan_tum-cat"
|
73
|
+
end
|
63
74
|
end
|
64
|
-
end
|
65
75
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
76
|
+
describe ':collection_element_name for Collection' do
|
77
|
+
before(:each) do
|
78
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), QuanTum::Cat)
|
79
|
+
@collection = DataMapper::Collection.new(query) {}
|
80
|
+
end
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
it 'when not specified the class name tableized and with slashes replaced with dashes should be used as the root node name' do
|
83
|
+
xml = @collection.to_xml
|
84
|
+
REXML::Document.new(xml).elements[1].name.should == "quan_tum-cats"
|
85
|
+
end
|
75
86
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
"somanycats"
|
82
|
-
end
|
87
|
+
it 'should be used as the root node name by #to_xml' do
|
88
|
+
@collection.load([1])
|
89
|
+
|
90
|
+
xml = @collection.to_xml(:collection_element_name => "somanycats")
|
91
|
+
REXML::Document.new(xml).elements[1].name.should == "somanycats"
|
83
92
|
end
|
84
93
|
|
85
|
-
|
86
|
-
|
94
|
+
it 'should respect :element_name for collection elements' do
|
95
|
+
@collection.load([1])
|
96
|
+
|
97
|
+
xml = @collection.to_xml(:collection_element_name => "somanycats", :element_name => 'cat')
|
98
|
+
REXML::Document.new(xml).elements[1].elements[1].name.should == "cat"
|
99
|
+
end
|
87
100
|
end
|
88
101
|
end
|
89
102
|
end
|
data/spec/public/to_yaml_spec.rb
CHANGED
@@ -18,15 +18,20 @@ describe DataMapper::Serialize, '#to_yaml' do
|
|
18
18
|
def deserialize(result)
|
19
19
|
stringify_keys = lambda {|hash| hash.inject({}) {|a, (key, value)| a.update(key.to_s => value) }}
|
20
20
|
result = YAML.load(result)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
(process = lambda {|object|
|
22
|
+
if object.is_a?(Array)
|
23
|
+
object.collect(&process)
|
24
|
+
elsif object.is_a?(Hash)
|
25
|
+
stringify_keys[object]
|
26
|
+
else
|
27
|
+
object
|
28
|
+
end
|
29
|
+
})[result]
|
26
30
|
end
|
27
31
|
end.new
|
28
32
|
end
|
29
33
|
|
30
|
-
it_should_behave_like
|
34
|
+
it_should_behave_like 'A serialization method'
|
35
|
+
it_should_behave_like 'A serialization method that also serializes core classes'
|
31
36
|
|
32
37
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
|
-
gem 'dm-core', '~>0.9.
|
4
|
+
gem 'dm-core', '~>0.9.9'
|
5
5
|
require 'dm-core'
|
6
6
|
|
7
7
|
spec_dir_path = Pathname(__FILE__).dirname.expand_path
|
8
|
-
|
8
|
+
$LOAD_PATH.unshift(spec_dir_path.parent + 'lib/')
|
9
|
+
require 'dm-serializer'
|
9
10
|
|
10
11
|
def load_driver(name, default_uri)
|
11
12
|
return false if ENV['ADAPTER'] != name.to_s
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guy van den Berg
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-01-04 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.
|
23
|
+
version: 0.9.9
|
24
24
|
version:
|
25
25
|
description: DataMapper plugin for serializing DataMapper objects
|
26
26
|
email:
|
@@ -30,7 +30,7 @@ executables: []
|
|
30
30
|
extensions: []
|
31
31
|
|
32
32
|
extra_rdoc_files:
|
33
|
-
- README.
|
33
|
+
- README.textile
|
34
34
|
- LICENSE
|
35
35
|
- TODO
|
36
36
|
- History.txt
|
@@ -38,13 +38,23 @@ files:
|
|
38
38
|
- History.txt
|
39
39
|
- LICENSE
|
40
40
|
- Manifest.txt
|
41
|
-
- README.
|
41
|
+
- README.textile
|
42
42
|
- Rakefile
|
43
43
|
- TODO
|
44
44
|
- autotest/discover.rb
|
45
45
|
- autotest/dmserializer_rspec.rb
|
46
|
+
- benchmarks/to_xml.rb
|
46
47
|
- lib/dm-serializer.rb
|
48
|
+
- lib/dm-serializer/common.rb
|
49
|
+
- lib/dm-serializer/to_csv.rb
|
50
|
+
- lib/dm-serializer/to_json.rb
|
51
|
+
- lib/dm-serializer/to_xml.rb
|
52
|
+
- lib/dm-serializer/to_yaml.rb
|
47
53
|
- lib/dm-serializer/version.rb
|
54
|
+
- lib/dm-serializer/xml_serializers.rb
|
55
|
+
- lib/dm-serializer/xml_serializers/libxml.rb
|
56
|
+
- lib/dm-serializer/xml_serializers/nokogiri.rb
|
57
|
+
- lib/dm-serializer/xml_serializers/rexml.rb
|
48
58
|
- spec/fixtures/cow.rb
|
49
59
|
- spec/fixtures/planet.rb
|
50
60
|
- spec/fixtures/quan_tum_cat.rb
|
data/README.txt
DELETED