oxmlk 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +8 -6
- data/VERSION +1 -1
- data/examples/example.rb +32 -0
- data/examples/posts.rb +9 -0
- data/examples/xml/example.xml +14 -0
- data/examples/xml/posts.xml +23 -0
- data/lib/oxmlk/description.rb +121 -0
- data/lib/oxmlk/xml.rb +31 -0
- data/lib/oxmlk.rb +36 -11
- data/oxmlk.gemspec +22 -5
- data/spec/description_spec.rb +221 -0
- data/spec/oxmlk_spec.rb +85 -28
- data/spec/spec_helper.rb +12 -0
- data/spec/xml_spec.rb +40 -0
- metadata +33 -2
data/Rakefile
CHANGED
@@ -4,18 +4,20 @@ require 'rake'
|
|
4
4
|
begin
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name =
|
7
|
+
gem.name = 'oxmlk'
|
8
8
|
gem.summary = %Q{Object 2 XML kit for ruby}
|
9
9
|
gem.description = %Q{OxMlk gives you a simple way to map you ruby objects to XML and then convert one to the other.}
|
10
|
-
gem.email =
|
11
|
-
gem.homepage =
|
12
|
-
gem.authors = [
|
13
|
-
gem.add_development_dependency
|
10
|
+
gem.email = 'hexorx@gmail.com'
|
11
|
+
gem.homepage = 'http://github.com/hexorx/oxmlk'
|
12
|
+
gem.authors = ['Josh Robinson']
|
13
|
+
gem.add_development_dependency 'rspec'
|
14
|
+
gem.add_dependency 'libxml-ruby'
|
15
|
+
gem.add_dependency 'activesupport', '>= 2.1.0'
|
14
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
17
|
end
|
16
18
|
Jeweler::GemcutterTasks.new
|
17
19
|
rescue LoadError
|
18
|
-
puts
|
20
|
+
puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
|
19
21
|
end
|
20
22
|
|
21
23
|
require 'spec/rake/spectask'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/examples/example.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class Number
|
2
|
+
include OxMlk
|
3
|
+
|
4
|
+
ox_tag :number
|
5
|
+
|
6
|
+
ox_attr(:value, :from => :content)
|
7
|
+
end
|
8
|
+
|
9
|
+
class Email
|
10
|
+
include OxMlk
|
11
|
+
|
12
|
+
ox_tag :email
|
13
|
+
|
14
|
+
ox_attr(:value, :from => :content)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Person
|
18
|
+
include OxMlk
|
19
|
+
|
20
|
+
ox_tag :person
|
21
|
+
|
22
|
+
ox_attr(:category, :from => :attr)
|
23
|
+
ox_attr(:two_attr, :from => '@attr2')
|
24
|
+
|
25
|
+
ox_attr(:name)
|
26
|
+
ox_attr(:numbers, :as => [Number], :freeze => false)
|
27
|
+
ox_attr(:contacts, :as => [Number,Email], :freeze => true)
|
28
|
+
|
29
|
+
def say_hello(xml)
|
30
|
+
'hello'
|
31
|
+
end
|
32
|
+
end
|
data/examples/posts.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<person category="meat_popsicle">
|
2
|
+
<name>Joe</name>
|
3
|
+
<number group="main">3035551212</number>
|
4
|
+
<number group="cell">3035551234</number>
|
5
|
+
<email group="home">test@example.com</email>
|
6
|
+
<friends>
|
7
|
+
<person>
|
8
|
+
<name>Bob</name>
|
9
|
+
</person>
|
10
|
+
<person>
|
11
|
+
<name>John</name>
|
12
|
+
</person>
|
13
|
+
</friends>
|
14
|
+
</person>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<posts user="jnunemaker" tag="ruby">
|
2
|
+
<post href="http://roxml.rubyforge.org/" hash="19bba2ab667be03a19f67fb67dc56917" description="ROXML - Ruby Object to XML Mapping Library" tag="ruby xml gems mapping" time="2008-08-09T05:24:20Z" others="56" extended="ROXML is a Ruby library designed to make it easier for Ruby developers to work with XML. Using simple annotations, it enables Ruby classes to be custom-mapped to XML. ROXML takes care of the marshalling and unmarshalling of mapped attributes so that developers can focus on building first-class Ruby classes."/>
|
3
|
+
<post href="http://code.google.com/p/sparrow/" hash="1df8a7cb9e8960992556518c0ea0d146" description="sparrow - Google Code" tag="ruby sparrow memcache queue" time="2008-08-06T15:07:24Z" others="115" extended="Sparrow is a really fast lightweight queue written in Ruby that speaks memcache. That means you can use Sparrow with any memcached client library (Ruby or otherwise)."/>
|
4
|
+
<post href="http://code.google.com/p/query-reviewer/" hash="963187e8bf350ae42e21eee13a2bef07" description="query-reviewer - Google Code" tag="rails ruby railstips plugins database optimization" time="2008-08-04T21:50:14Z" others="180" extended="This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of query warnings that it analyzed."/>
|
5
|
+
<post href="http://dev.zeraweb.com/introducing-functor" hash="2cdd545934bd37ae6f4829c51b3041c5" description="dev.zeraweb.com: Introducing Functor" tag="ruby methods gems railstips" time="2008-08-04T21:46:47Z" others="61" extended="Really cool ruby lib for overloading method definitions. I can think of a few places this would be handy."/>
|
6
|
+
<post href="http://prawn.majesticseacreature.com/" hash="92764e019de7553b4cd38017e42e4aaa" description="prawn.majesticseacreature.com" tag="pdf ruby railstips" time="2008-08-04T21:26:20Z" others="237" extended="pure ruby pdf generation library."/>
|
7
|
+
<post href="http://meme-rocket.com/2006/09/28/ruby-moduleinclude-at-odds-with-duck-typing/" hash="4ce96c7c237161819e9625737c22b462" description="Bill Burcham’s memeRocket :: Ruby Module#include at Odds with Duck Typing." tag="ruby railstips enumerable comparable" time="2008-08-03T16:09:24Z" others="3" extended="How to build your own enumerable and comparable objects in ruby. This article is old but just came across it and found it handy."/>
|
8
|
+
<post href="http://bl.ogtastic.com/archives/2008/7" hash="6bebd138c037d7d7c88a7046ca03f671" description="The right way to do something you should never do" tag="juggernaut observers rails flash ruby" time="2008-08-03T03:50:58Z" others="0" extended="Example of how to use juggernaut with an observer."/>
|
9
|
+
<post href="http://ncavig.com/blog/?page_id=8" hash="55450d103d6e2dd609b203ad133d751f" description="Nic’s Notions » Juggernaut Tutorials" tag="juggernaut rails ruby flash plugins server chat" time="2008-08-03T02:26:39Z" others="30" extended="Several juggernaut tutorials."/>
|
10
|
+
<post href="http://blog.labnotes.org/2008/05/05/distributed-twitter-client-in-20-lines-of-code/" hash="7c2a36292db109b144036a02eb3f46b7" description="Labnotes » Distributed Twitter Client in 20 lines of code" tag="xmpp ruby jabber xmpp4r" time="2008-08-01T18:16:23Z" others="18" extended="Cool little snippet of xmpp goodness to check your buddies status messages."/>
|
11
|
+
<post href="http://labs.reevoo.com/plugins/beanstalk-messaging" hash="d100c10208acbf5e954320a5577838d9" description="reevoolabs - Beanstalk Messaging" tag="railstips messaging queue rails ruby" time="2008-07-28T02:57:00Z" others="33" extended="Good write up on beanstalk"/>
|
12
|
+
<post href="http://www.slideshare.net/guest807bb2/rubyfringe?src=embed" hash="c3dc3b940dbe25e39737240b4e1ab071" description="Rockstar Memcached" tag="memcached performance caching ruby rails railstips" time="2008-07-28T02:30:50Z" others="11" extended="Killer presentation on memcached by Tobi of Shopify."/>
|
13
|
+
<post href="http://www.igvita.com/2008/07/22/unix-signals-for-live-debugging/" hash="288054a38d870b15bdf060ed5c6b2a2e" description="Unix Signals for Live Debugging - igvita.com" tag="ruby signals unix debugging signal railstips" time="2008-07-27T04:53:00Z" others="86" extended="I've known how to kill processes and such but never quite understood kill. Ilya Grigorik explains not only how to send those signals but how to use them in your scripts to change the way they behave on the fly. Very cool."/>
|
14
|
+
<post href="http://www.rubyinside.com/redcloth-4-released-962.html" hash="b3db9b84940ce550e26a560b83eb2f66" description="RedCloth 4.0 Released: 40x Faster Textile Rendering" tag="textile ruby gems railstips" time="2008-07-27T04:42:29Z" others="20" extended="Redcloth gets some serious love. It's now much faster. Sweet!"/>
|
15
|
+
<post href="http://code.google.com/p/rubycas-server/" hash="b532ea5933e4eba76c44823e17fecd31" description="rubycas-server - Google Code" tag="sso authentication cas ruby" time="2008-07-22T17:04:09Z" others="132" extended="RubyCAS-Server provides a single sign-on solution for web applications, implementing the server-end of JA-SIG's CAS protocol."/>
|
16
|
+
<post href="http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx.html" hash="033d72ac54d8c722618383e0e2aa18ff" description="ReinH — A Thinking Man's Sphinx" tag="rails railstips sphinx search ruby" time="2008-07-17T19:34:59Z" others="142" extended="A guide to the two sphynx plugins: ultrasphynx and thinksphynx and why you should choose one or the other."/>
|
17
|
+
<post href="http://www.rubyinside.com/ruby-xml-crisis-over-libxml-0-8-0-released-955.html" hash="70490d9786f09db5ba5f7904f88d304c" description="libxml-ruby 0.8.0 Released: Ruby Gets Fast, Reliable XML Processing At Last" tag="libxml xml ruby gems" time="2008-07-17T18:22:23Z" others="55" extended="lib xml gets an update and now it's really fast."/>
|
18
|
+
<post href="http://github.com/RISCfuture/autumn/tree/master" hash="9b47db4bf59da2009642f4084e3113a2" description="autumn at master — GitHub" tag="irc ruby gems" time="2008-07-17T18:20:19Z" others="18" extended="Easy, fresh, feature-rich IRC bots in Ruby"/>
|
19
|
+
<post href="http://groups.google.com/group/datamapper/browse_thread/thread/d33fbb20e41fad04" hash="4403898c92b37788f002ad6d79a66b68" description="New Finder Syntax (before 1.0) -" tag="railstips ruby datamapper" time="2008-07-05T20:42:27Z" others="1" extended="really cool idea for conditions in datamapper. even if you don't use datamapper, read this as it's sweet."/>
|
20
|
+
<post href="http://codeclimber.blogspot.com/2008/06/using-ruby-for-imap-with-gmail.html" hash="33bbf2492beac5fbf1fc167014060067" description="CodeClimber: using Ruby for IMAP with Gmail" tag="email gems gmail google imap rails railstips ruby" time="2008-07-05T20:06:47Z" others="118" extended="how to check gmail using ruby's IMAP libraries. the key is to use the login method instead of the authenticate one."/>
|
21
|
+
<post href="http://xullicious.blogspot.com/2008/07/updated-curb-multi-interface-patch.html" hash="f95dcc012bdc13bc26bace3ceed10656" description="Xul for thought: Updated curb multi interface patch" tag="curl ruby http" time="2008-07-03T21:52:45Z" others="1" extended="Really cool multi curl stuff to rapidly hit urls."/>
|
22
|
+
</posts>
|
23
|
+
<!-- fe04.api.del.ac4.yahoo.net uncompressed/chunked Sat Aug 9 00:20:11 PDT 2008 -->
|
data/lib/oxmlk/description.rb
CHANGED
@@ -1,5 +1,126 @@
|
|
1
1
|
module OxMlk
|
2
|
+
|
2
3
|
class Description
|
4
|
+
PROCESSORS = {
|
5
|
+
:elem => {
|
6
|
+
:value => proc {|x| x.content rescue nil},
|
7
|
+
Integer => proc {|x| x.content.to_i rescue nil},
|
8
|
+
Float => proc {|x| x.content.to_f rescue nil}
|
9
|
+
},
|
10
|
+
:attribute => {
|
11
|
+
:value => proc {|x| x.value rescue nil}
|
12
|
+
}
|
13
|
+
}
|
3
14
|
|
15
|
+
attr_reader :xpath
|
16
|
+
|
17
|
+
def initialize(name,o={},&block)
|
18
|
+
@froze = o.delete(:freeze)
|
19
|
+
@from = o.delete(:from)
|
20
|
+
@as = o.delete(:as)
|
21
|
+
@wrapper = o.delete(:wrapper)
|
22
|
+
@name = name.to_s
|
23
|
+
|
24
|
+
@is_attribute = computed_is_attribute
|
25
|
+
@processors = [coputed_processor, block].compact
|
26
|
+
@xpath = computed_xpath
|
27
|
+
end
|
28
|
+
|
29
|
+
def accessor
|
30
|
+
@accessor ||= @name.intern
|
31
|
+
end
|
32
|
+
|
33
|
+
def setter
|
34
|
+
:"#{accessor}="
|
35
|
+
end
|
36
|
+
|
37
|
+
def instance_variable
|
38
|
+
:"@#{accessor}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def froze?
|
42
|
+
@froze ||= false
|
43
|
+
end
|
44
|
+
|
45
|
+
def writable?
|
46
|
+
!froze?
|
47
|
+
end
|
48
|
+
|
49
|
+
def attribute?
|
50
|
+
@is_attribute ||= false
|
51
|
+
end
|
52
|
+
|
53
|
+
def elem?
|
54
|
+
!attribute?
|
55
|
+
end
|
56
|
+
|
57
|
+
def ox_type
|
58
|
+
elem? ? :elem : :attribute
|
59
|
+
end
|
60
|
+
|
61
|
+
def collection?
|
62
|
+
@as.is_a?(Array)
|
63
|
+
end
|
64
|
+
|
65
|
+
def ox_object?
|
66
|
+
return false if [*@as].empty?
|
67
|
+
[*@as].all? {|x| x.respond_to?(:from_xml)}
|
68
|
+
end
|
69
|
+
|
70
|
+
def process(node,instance)
|
71
|
+
@processors.inject(node) do |memo,processor|
|
72
|
+
case processor
|
73
|
+
when Proc
|
74
|
+
processor.call(memo)
|
75
|
+
when Symbol
|
76
|
+
instance.send(processor,memo)
|
77
|
+
else
|
78
|
+
processor.from_xml(memo)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def from_xml(data,instance)
|
84
|
+
xml = XML::Node.from(data)
|
85
|
+
nodes = xml.find(@xpath)
|
86
|
+
return nil if nodes.first.nil?
|
87
|
+
return process(nodes.first,instance) unless collection?
|
88
|
+
(nodes).map {|n| process(n,instance)}
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def computed_xpath
|
94
|
+
wrap case @from
|
95
|
+
when nil
|
96
|
+
if ox_object?
|
97
|
+
[*@as].map(&:ox_tag).join('|')
|
98
|
+
elsif collection?
|
99
|
+
@name.to_s.singularize
|
100
|
+
else
|
101
|
+
@name.to_s
|
102
|
+
end
|
103
|
+
when String
|
104
|
+
@from
|
105
|
+
when :attr
|
106
|
+
"@#{accessor}"
|
107
|
+
when :content
|
108
|
+
'.'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def computed_is_attribute
|
113
|
+
@from.to_s[0,1] == '@' || @from == :attr
|
114
|
+
end
|
115
|
+
|
116
|
+
def coputed_processor
|
117
|
+
return proc {|x| Hash[*@as.map{|o| [o.ox_tag,o]}.flatten][x.name].from_xml(x) } if collection? && ox_object?
|
118
|
+
processor = [*@as].first || :value
|
119
|
+
PROCESSORS[ox_type][processor] || processor
|
120
|
+
end
|
121
|
+
|
122
|
+
def wrap(xpath=nil)
|
123
|
+
[@wrapper,xpath].compact.join('/')
|
124
|
+
end
|
4
125
|
end
|
5
126
|
end
|
data/lib/oxmlk/xml.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'libxml'
|
2
|
+
require 'pathname'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module OxMlk
|
6
|
+
module XML
|
7
|
+
Document = LibXML::XML::Document
|
8
|
+
Node = LibXML::XML::Node
|
9
|
+
Parser = LibXML::XML::Parser
|
10
|
+
Error = LibXML::XML::Error
|
11
|
+
|
12
|
+
class Node
|
13
|
+
def self.from(data)
|
14
|
+
case data
|
15
|
+
when XML::Document
|
16
|
+
data.root
|
17
|
+
when XML::Node
|
18
|
+
data
|
19
|
+
when File
|
20
|
+
XML::Parser.io(data).parse.root
|
21
|
+
when Pathname, URI
|
22
|
+
XML::Parser.file(data.to_s).parse.root
|
23
|
+
when String
|
24
|
+
XML::Parser.string(data).parse.root
|
25
|
+
else
|
26
|
+
raise 'Invalid XML data'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/oxmlk.rb
CHANGED
@@ -1,30 +1,55 @@
|
|
1
1
|
dir = File.dirname(__FILE__)
|
2
|
+
require File.join(dir, 'oxmlk/xml')
|
2
3
|
require File.join(dir, 'oxmlk/description')
|
4
|
+
require 'activesupport'
|
3
5
|
|
4
6
|
module OxMlk
|
5
7
|
|
6
8
|
def self.included(base)
|
7
|
-
base.
|
8
|
-
include InstanceMethods
|
9
|
-
extend ClassMethods
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module InstanceMethods
|
9
|
+
base.extend ClassMethods
|
14
10
|
end
|
15
11
|
|
16
12
|
module ClassMethods
|
13
|
+
|
17
14
|
def ox_attrs
|
18
15
|
@ox_attrs ||= []
|
19
16
|
end
|
20
17
|
|
21
|
-
def ox_attr(name)
|
22
|
-
|
18
|
+
def ox_attr(name,o={})
|
19
|
+
new_attr = Description.new(name, o)
|
20
|
+
ox_attrs << new_attr
|
21
|
+
attr new_attr.accessor, new_attr.writable?
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_xml(data)
|
25
|
+
xml = XML::Node.from(data)
|
26
|
+
p [xml.name, ox_tag]
|
27
|
+
raise 'invalid XML' unless xml.name == ox_tag
|
28
|
+
|
29
|
+
ox = new
|
30
|
+
ox_attrs.each do |a|
|
31
|
+
value = a.from_xml(xml,ox)
|
32
|
+
if ox.respond_to?(a.setter)
|
33
|
+
ox.send(a.setter,value)
|
34
|
+
else
|
35
|
+
ox.instance_variable_set(a.instance_variable,value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
ox
|
23
39
|
end
|
24
40
|
|
25
|
-
def
|
26
|
-
|
41
|
+
def ox_attributes
|
42
|
+
ox_attrs.select {|x| x.attribute?}
|
27
43
|
end
|
44
|
+
|
45
|
+
def ox_elems
|
46
|
+
ox_attrs.select {|x| x.elem?}
|
47
|
+
end
|
48
|
+
|
49
|
+
def ox_tag(tag=false)
|
50
|
+
@ox_tag ||= (tag || self).to_s
|
51
|
+
end
|
52
|
+
|
28
53
|
end
|
29
54
|
|
30
55
|
end
|
data/oxmlk.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{oxmlk}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Josh Robinson"]
|
12
|
-
s.date = %q{2009-08-
|
12
|
+
s.date = %q{2009-08-24}
|
13
13
|
s.description = %q{OxMlk gives you a simple way to map you ruby objects to XML and then convert one to the other.}
|
14
14
|
s.email = %q{hexorx@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,12 +23,19 @@ Gem::Specification.new do |s|
|
|
23
23
|
"README.rdoc",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
|
+
"examples/example.rb",
|
27
|
+
"examples/posts.rb",
|
28
|
+
"examples/xml/example.xml",
|
29
|
+
"examples/xml/posts.xml",
|
26
30
|
"lib/oxmlk.rb",
|
27
31
|
"lib/oxmlk/description.rb",
|
32
|
+
"lib/oxmlk/xml.rb",
|
28
33
|
"oxmlk.gemspec",
|
34
|
+
"spec/description_spec.rb",
|
29
35
|
"spec/oxmlk_spec.rb",
|
30
36
|
"spec/spec.opts",
|
31
|
-
"spec/spec_helper.rb"
|
37
|
+
"spec/spec_helper.rb",
|
38
|
+
"spec/xml_spec.rb"
|
32
39
|
]
|
33
40
|
s.homepage = %q{http://github.com/hexorx/oxmlk}
|
34
41
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -36,8 +43,12 @@ Gem::Specification.new do |s|
|
|
36
43
|
s.rubygems_version = %q{1.3.3}
|
37
44
|
s.summary = %q{Object 2 XML kit for ruby}
|
38
45
|
s.test_files = [
|
39
|
-
"spec/
|
40
|
-
"spec/
|
46
|
+
"spec/description_spec.rb",
|
47
|
+
"spec/oxmlk_spec.rb",
|
48
|
+
"spec/spec_helper.rb",
|
49
|
+
"spec/xml_spec.rb",
|
50
|
+
"examples/example.rb",
|
51
|
+
"examples/posts.rb"
|
41
52
|
]
|
42
53
|
|
43
54
|
if s.respond_to? :specification_version then
|
@@ -46,10 +57,16 @@ Gem::Specification.new do |s|
|
|
46
57
|
|
47
58
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
59
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
60
|
+
s.add_runtime_dependency(%q<libxml-ruby>, [">= 0"])
|
61
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.1.0"])
|
49
62
|
else
|
50
63
|
s.add_dependency(%q<rspec>, [">= 0"])
|
64
|
+
s.add_dependency(%q<libxml-ruby>, [">= 0"])
|
65
|
+
s.add_dependency(%q<activesupport>, [">= 2.1.0"])
|
51
66
|
end
|
52
67
|
else
|
53
68
|
s.add_dependency(%q<rspec>, [">= 0"])
|
69
|
+
s.add_dependency(%q<libxml-ruby>, [">= 0"])
|
70
|
+
s.add_dependency(%q<activesupport>, [">= 2.1.0"])
|
54
71
|
end
|
55
72
|
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe OxMlk::Description do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
require example(:example)
|
7
|
+
|
8
|
+
@xml = OxMlk::XML::Node.from(xml_for(:example))
|
9
|
+
@klass = Person
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'xpath' do
|
13
|
+
it 'should be name by default' do
|
14
|
+
@desc = OxMlk::Description.new(:name)
|
15
|
+
@desc.xpath.should == 'name'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should be the string if :from is a string' do
|
19
|
+
@desc = OxMlk::Description.new(:name, :from => 'String')
|
20
|
+
@desc.xpath.should == 'String'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be @+accessor if :from is :attr' do
|
24
|
+
@desc = OxMlk::Description.new(:name, :from => :attr)
|
25
|
+
@desc.xpath.should == '@name'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should be . if :from is :content' do
|
29
|
+
@desc = OxMlk::Description.new(:name, :from => :content)
|
30
|
+
@desc.xpath.should == '.'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be singular if plural name and is a collection' do
|
34
|
+
@desc = OxMlk::Description.new(:numbers, :as => [])
|
35
|
+
@desc.xpath.should == 'number'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should be ox_tag if :as is a ox_object' do
|
39
|
+
@desc = OxMlk::Description.new(:digits, :as => Number)
|
40
|
+
@desc.xpath.should == 'number'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should be list of ox_tag if :as is an array of ox_objects' do
|
44
|
+
@desc = OxMlk::Description.new(:digits, :as => [Number,Person])
|
45
|
+
@desc.xpath.should == 'number|person'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should add wrapper + / to xpath if wrapper is passed' do
|
49
|
+
@desc = OxMlk::Description.new(:person, :wrapper => :friends)
|
50
|
+
@desc.xpath.should == 'friends/person'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'accessor' do
|
55
|
+
it 'should be attr name as Symbol' do
|
56
|
+
@desc = OxMlk::Description.new(:name)
|
57
|
+
@desc.accessor.should == :name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'setter' do
|
62
|
+
it 'should be accessor with = on the end' do
|
63
|
+
@desc = OxMlk::Description.new(:name)
|
64
|
+
@desc.setter.should == :'name='
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'instance_variable' do
|
69
|
+
it 'should be accessor with @ on the front' do
|
70
|
+
@desc = OxMlk::Description.new(:name)
|
71
|
+
@desc.instance_variable.should == :'@name'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'writable?' do
|
76
|
+
it 'should be true by default' do
|
77
|
+
@desc = OxMlk::Description.new(:name)
|
78
|
+
@desc.writable?.should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should be true if :freeze is false' do
|
82
|
+
@desc = OxMlk::Description.new(:name, :freeze => false)
|
83
|
+
@desc.writable?.should be_true
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should be false if :freeze is true' do
|
87
|
+
@desc = OxMlk::Description.new(:name, :freeze => true)
|
88
|
+
@desc.writable?.should be_false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'attribute?' do
|
93
|
+
it 'should be true if :from starts with @' do
|
94
|
+
@desc = OxMlk::Description.new(:name, :from => '@name')
|
95
|
+
@desc.attribute?.should be_true
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should be true if :from is :attribute' do
|
99
|
+
@desc = OxMlk::Description.new(:name, :from => :attr)
|
100
|
+
@desc.attribute?.should be_true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'elem?' do
|
105
|
+
it 'should be true if attribute? is false' do
|
106
|
+
@desc = OxMlk::Description.new(:name)
|
107
|
+
@desc.elem?.should be_true
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should be false if attribute? is true' do
|
111
|
+
@desc = OxMlk::Description.new(:name, :from => :attr)
|
112
|
+
@desc.elem?.should be_false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'ox_type' do
|
117
|
+
it 'should be :elem if elem? is true' do
|
118
|
+
@desc = OxMlk::Description.new(:name)
|
119
|
+
@desc.ox_type.should == :elem
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should be :attribute if attribute? is true' do
|
123
|
+
@desc = OxMlk::Description.new(:name, :from => :attr)
|
124
|
+
@desc.ox_type.should == :attribute
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'collection?' do
|
129
|
+
it 'should be true if :as is an Array' do
|
130
|
+
@desc = OxMlk::Description.new(:name, :as => [])
|
131
|
+
@desc.collection?.should be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should be false if :as is not Array' do
|
135
|
+
@desc = OxMlk::Description.new(:name)
|
136
|
+
@desc.collection?.should be_false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'ox_object?' do
|
141
|
+
it 'should be true if :as responds to from_xml' do
|
142
|
+
@desc = OxMlk::Description.new(:number, :as => Person)
|
143
|
+
@desc.ox_object?.should be_true
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should be true if :as is an array of objects that respond to from_xml' do
|
147
|
+
@desc = OxMlk::Description.new(:number, :as => [Person,Number])
|
148
|
+
@desc.ox_object?.should be_true
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should be false if :as does not responds to from_xml' do
|
152
|
+
@desc = OxMlk::Description.new(:number, :as => 1)
|
153
|
+
@desc.ox_object?.should be_false
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should be false if any of the items in :as array do not respond to from_xml' do
|
157
|
+
@desc = OxMlk::Description.new(:number, :as => [Person,Number,1])
|
158
|
+
@desc.ox_object?.should be_false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'from_xml' do
|
163
|
+
|
164
|
+
it 'should accept xml argument' do
|
165
|
+
@desc = OxMlk::Description.new(:name)
|
166
|
+
@desc.from_xml(@xml, @klass.new).should be_a(String)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should return an array if :as is an array' do
|
170
|
+
@desc = OxMlk::Description.new(:name, :as => [])
|
171
|
+
@desc.from_xml(@xml, @klass.new).should be_an(Array)
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should return a String if :as is :value' do
|
175
|
+
@desc = OxMlk::Description.new(:name, :as => :value)
|
176
|
+
@desc.from_xml(@xml, @klass.new).should be_an(String)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should return a String if :as is nil' do
|
180
|
+
@desc = OxMlk::Description.new(:name)
|
181
|
+
@desc.from_xml(@xml, @klass.new).should be_an(String)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should return an Integer if :as is Integer' do
|
185
|
+
@desc = OxMlk::Description.new(:name, :as => Integer)
|
186
|
+
@desc.from_xml(@xml, @klass.new).should be_an(Integer)
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should return an Float if :as is Float' do
|
190
|
+
@desc = OxMlk::Description.new(:name, :as => Float)
|
191
|
+
@desc.from_xml(@xml, @klass.new).should be_an(Float)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should return an Array of Integers if :as is [Integer]' do
|
195
|
+
@desc = OxMlk::Description.new(:name, :as => [Integer])
|
196
|
+
@desc.from_xml(@xml, @klass.new).each do |x|
|
197
|
+
x.should be_an(Integer)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should run procs passed to :as' do
|
202
|
+
@desc = OxMlk::Description.new(:name, :as => proc {|x| 'hi'})
|
203
|
+
@desc.from_xml(@xml, @klass.new).should == 'hi'
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should run method when symbol is passed to :as' do
|
207
|
+
@desc = OxMlk::Description.new(:name, :as => :say_hello)
|
208
|
+
@desc.from_xml(@xml, @klass.new).should == 'hello'
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should return an OxMlk object if one is passed to :as' do
|
212
|
+
@desc = OxMlk::Description.new(:number, :as => Number)
|
213
|
+
@desc.from_xml(@xml, @klass.new).should be_a(Number)
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should match class to ox_tag if array of ox_objects is passed to :as' do
|
217
|
+
@desc = OxMlk::Description.new(:contact, :as => [Number,Email])
|
218
|
+
@desc.from_xml(@xml, @klass.new).first.should be_a(Number)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
data/spec/oxmlk_spec.rb
CHANGED
@@ -2,46 +2,103 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe OxMlk do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
before(:all) do
|
6
|
+
require example(:example)
|
7
|
+
@klass = Person
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'being included into another class' do
|
11
|
+
it 'should set ox_attrs to an array' do
|
12
|
+
@klass.ox_attrs.should be_a(Array)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should add an ox_attr method' do
|
16
|
+
@klass.should respond_to(:ox_attr)
|
14
17
|
end
|
15
18
|
|
16
|
-
it
|
17
|
-
@klass.
|
19
|
+
it 'should add a from_xml method' do
|
20
|
+
@klass.should respond_to(:from_xml)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should add an ox_attributes method' do
|
24
|
+
@klass.should respond_to(:ox_attributes)
|
18
25
|
end
|
19
26
|
|
20
|
-
it
|
21
|
-
@klass.
|
22
|
-
@klass.ox_attrs.size.should == 1
|
27
|
+
it 'should add an ox_elems method' do
|
28
|
+
@klass.should respond_to(:ox_elems)
|
23
29
|
end
|
24
30
|
|
25
|
-
it
|
26
|
-
@klass.
|
31
|
+
it 'should add a tag_name method' do
|
32
|
+
@klass.should respond_to(:ox_tag)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#ox_attr' do
|
37
|
+
it 'should add an OxMlk::Description to the class' do
|
38
|
+
@klass.ox_attrs.first.should be_a(OxMlk::Description)
|
27
39
|
end
|
40
|
+
|
41
|
+
it 'should add a reader method' do
|
42
|
+
@klass.new.should respond_to(:name)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should add a writter method by default' do
|
46
|
+
@klass.new.should respond_to(:name=)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should add a writter method when :freeze => false' do
|
50
|
+
@klass.new.should respond_to(:numbers=)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should not add a writter method when :freeze => true' do
|
54
|
+
@klass.new.should_not respond_to(:contacts=)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#from_xml' do
|
28
59
|
|
29
|
-
it
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
60
|
+
it 'should return an instance of class' do
|
61
|
+
@klass.from_xml('<person/>').should be_a(@klass)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should error on mismatched tag' do
|
65
|
+
proc { @klass.from_xml('<Person/>') }.should raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'example' do
|
69
|
+
before(:all) do
|
70
|
+
@xml = xml_for(:example)
|
71
|
+
@example = Person.from_xml(@xml)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should fetch name' do
|
75
|
+
@example.name.should == 'Joe'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should fetch category' do
|
79
|
+
@example.category.should == 'meat_popsicle'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should fetch numbers' do
|
83
|
+
@example.numbers.map(&:value).should == ['3035551212','3035551234']
|
34
84
|
end
|
35
85
|
|
36
|
-
|
86
|
+
it 'should fetch contacts' do
|
87
|
+
@example.contacts.map(&:value).should == ['3035551212','3035551234','test@example.com']
|
88
|
+
end
|
37
89
|
end
|
38
|
-
|
39
90
|
end
|
40
91
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
92
|
+
describe '#ox_attributes' do
|
93
|
+
it 'should return a list of attributes' do
|
94
|
+
@klass.ox_attributes.size.should == 2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#ox_elems' do
|
99
|
+
it 'should return a list of elements' do
|
100
|
+
@klass.ox_elems.size.should == 3
|
101
|
+
end
|
46
102
|
end
|
47
103
|
end
|
104
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
3
4
|
require 'oxmlk'
|
4
5
|
require 'spec'
|
5
6
|
require 'spec/autorun'
|
7
|
+
require 'pathname'
|
6
8
|
|
7
9
|
Spec::Runner.configure do |config|
|
8
10
|
|
9
11
|
end
|
12
|
+
|
13
|
+
DIR = Pathname.new(__FILE__ + '../..').expand_path.dirname
|
14
|
+
|
15
|
+
def example(name)
|
16
|
+
DIR.join("examples/#{name}.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
def xml_for(name)
|
20
|
+
DIR.join("examples/xml/#{name}.xml")
|
21
|
+
end
|
data/spec/xml_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe OxMlk::XML::Node, '#from' do
|
4
|
+
before(:all) do
|
5
|
+
@xml = xml_for(:posts)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should parse an XML::Document' do
|
9
|
+
data = OxMlk::XML::Document.new
|
10
|
+
node = OxMlk::XML::Node.new(:name)
|
11
|
+
data.root = node
|
12
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should parse an XML::Node' do
|
16
|
+
data = OxMlk::XML::Node.new(:name)
|
17
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should parse a File' do
|
21
|
+
data = File.new(@xml)
|
22
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should parse a Path' do
|
26
|
+
data = Pathname.new(@xml)
|
27
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should parse a URI' do
|
31
|
+
data = URI.parse("file:////#{File.expand_path(File.expand_path(@xml))}")
|
32
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should parse a String' do
|
36
|
+
data = File.open(@xml).read
|
37
|
+
OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oxmlk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Robinson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-24 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,26 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: libxml-ruby
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: activesupport
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.1.0
|
44
|
+
version:
|
25
45
|
description: OxMlk gives you a simple way to map you ruby objects to XML and then convert one to the other.
|
26
46
|
email: hexorx@gmail.com
|
27
47
|
executables: []
|
@@ -38,12 +58,19 @@ files:
|
|
38
58
|
- README.rdoc
|
39
59
|
- Rakefile
|
40
60
|
- VERSION
|
61
|
+
- examples/example.rb
|
62
|
+
- examples/posts.rb
|
63
|
+
- examples/xml/example.xml
|
64
|
+
- examples/xml/posts.xml
|
41
65
|
- lib/oxmlk.rb
|
42
66
|
- lib/oxmlk/description.rb
|
67
|
+
- lib/oxmlk/xml.rb
|
43
68
|
- oxmlk.gemspec
|
69
|
+
- spec/description_spec.rb
|
44
70
|
- spec/oxmlk_spec.rb
|
45
71
|
- spec/spec.opts
|
46
72
|
- spec/spec_helper.rb
|
73
|
+
- spec/xml_spec.rb
|
47
74
|
has_rdoc: true
|
48
75
|
homepage: http://github.com/hexorx/oxmlk
|
49
76
|
licenses: []
|
@@ -73,5 +100,9 @@ signing_key:
|
|
73
100
|
specification_version: 3
|
74
101
|
summary: Object 2 XML kit for ruby
|
75
102
|
test_files:
|
103
|
+
- spec/description_spec.rb
|
76
104
|
- spec/oxmlk_spec.rb
|
77
105
|
- spec/spec_helper.rb
|
106
|
+
- spec/xml_spec.rb
|
107
|
+
- examples/example.rb
|
108
|
+
- examples/posts.rb
|