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 CHANGED
@@ -4,18 +4,20 @@ require 'rake'
4
4
  begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
- gem.name = "oxmlk"
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 = "hexorx@gmail.com"
11
- gem.homepage = "http://github.com/hexorx/oxmlk"
12
- gem.authors = ["Josh Robinson"]
13
- gem.add_development_dependency "rspec"
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 "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
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.0.0
1
+ 0.1.0
@@ -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,9 @@
1
+ class Response
2
+ include OxMlk
3
+
4
+ ox_attr :user, :from => '@user'
5
+ end
6
+
7
+ class Post
8
+ include OxMlk
9
+ end
@@ -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 &quot;EXPLAIN&quot; 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 -->
@@ -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.class_eval do
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
- ox_attrs << name
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 tag_name
26
- @tag_name ||= to_s.split('::')[-1].downcase
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.0.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-20}
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/oxmlk_spec.rb",
40
- "spec/spec_helper.rb"
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
- describe "being included into another class" do
6
- before do
7
- @klass = Class.new do
8
- include OxMlk
9
-
10
- def self.to_s
11
- 'fubar'
12
- end
13
- end
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 "should set ox_attrs to an array" do
17
- @klass.ox_attrs.should == []
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 "should allow adding an ox_attr" do
21
- @klass.ox_attr(:name)
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 "should default tag name to lowercase class" do
26
- @klass.tag_name.should == 'fubar'
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 "should default tag name of class in modules to the last constant lowercase" do
30
- module Fu
31
- class Bar
32
- include OxMlk
33
- end
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
- Fu::Bar.tag_name.should == 'bar'
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
- end
42
-
43
- describe OxMlk::Description do
44
- describe 'being initiated' do
45
- it 'should do something'
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.0.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-20 00:00:00 -06:00
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