xommelier 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xommelier.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rb-inotify'
8
+ gem 'libnotify'
9
+ gem 'rspec'
10
+ gem 'guard'
11
+ gem 'guard-rspec'
12
+ gem 'guard-bundler'
13
+ end
14
+
15
+ group :development do
16
+ gem 'ripl'
17
+ gem 'ripl-auto_indent', require: 'ripl/auto_indent'
18
+ gem 'ripl-color_error', require: 'ripl/color_error'
19
+ gem 'ripl-color_result', require: 'ripl/color_result'
20
+ gem 'ripl-multi_line', require: 'ripl/multi_line'
21
+ gem 'ripl-rails', require: 'ripl/rails'
22
+ gem 'ripl-rocket', require: 'ripl/rocket'
23
+ end
@@ -0,0 +1,10 @@
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ watch(/^.+\.gemspec/)
4
+ end
5
+
6
+ guard 'rspec', :version => 2 do
7
+ watch(%r{^spec/.+_spec\.rb$})
8
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
+ watch('spec/spec_helper.rb') { "spec" }
10
+ end
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,27 @@
1
+ require 'xommelier/atom'
2
+ require 'open-uri'
3
+
4
+ # Reading a feed
5
+ feed = Xommelier::Atom::Feed.parse(open('http://example.com/blog.atom'))
6
+ puts feed.id, feed.title, feed.updated
7
+
8
+ feed.each(:entry) do |entry|
9
+ puts feed.id, feed.title, feed.published, feed.updated
10
+ puts feed.content || feed.summary
11
+ end
12
+
13
+ # Building a feed
14
+ feed = Xommelier::Atom::Feed.new
15
+ feed.id = 'http://example.com/blog'
16
+ feed.title = 'Example.com blog'
17
+
18
+ 5.times do |i|
19
+ entry = Xommelier::Atom::Entry.new
20
+ entry.id = "http://example.com/blog/#{i}"
21
+ entry.title = "Example.com blog entry #{i}"
22
+ entry.updated = (5 - i).days.ago
23
+
24
+ feed << entry
25
+ end
26
+
27
+ puts feed.to_xml
@@ -0,0 +1,17 @@
1
+ require 'xommelier'
2
+
3
+ class Author < Xommelier::Xml::Element
4
+ attribute :id
5
+
6
+ element :given_name
7
+ element :family_name
8
+ element :born_on, type: Date
9
+ end
10
+
11
+ class Book < Xommelier::Xml::Element
12
+ attribute :isdn
13
+
14
+ element :author, type: Author
15
+ element :title
16
+ element :published_on, type: Date
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'xommelier/version'
2
+ require 'xommelier/core_ext'
3
+
4
+ module Xommelier
5
+ autoload :Collection, 'xommelier/collection'
6
+
7
+ autoload :Xml, 'xommelier/xml'
8
+ autoload :Atom, 'xommelier/atom'
9
+ end
@@ -0,0 +1,38 @@
1
+ require 'xommelier/xml'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ include Xommelier::Xml
6
+
7
+ xmlns 'http://www.w3.org/2005/Atom', as: :atom
8
+
9
+ autoload :Link, 'xommelier/atom/link'
10
+ autoload :Person, 'xommelier/atom/person'
11
+ autoload :Category, 'xommelier/atom/category'
12
+ autoload :Generator, 'xommelier/atom/generator'
13
+ autoload :Source, 'xommelier/atom/source'
14
+ autoload :Feed, 'xommelier/atom/feed'
15
+ autoload :Entry, 'xommelier/atom/entry'
16
+
17
+ #namespace 'http://purl.org/syndication/thread/1.0', as: :thr do
18
+ #element :in_reply_to, as: 'in-reply-to' do
19
+ #attribute :ref
20
+
21
+ #may do
22
+ #attribute :href, type: Uri
23
+ #attribute :type, type: String
24
+ #attribute :source
25
+ #end
26
+ #end
27
+
28
+ #ns.atom.element :entry do
29
+ #element :in_reply_to, ns: ns.thr
30
+ #element :total, type: Integer, ns: ns.thr
31
+ #end
32
+
33
+ #ns.atom.element :link, values: [:replies] do
34
+ #ns.thr.attribute :count, type: Integer
35
+ #end
36
+ #end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Category < Xml::Element
6
+ attribute :term
7
+
8
+ may do
9
+ attribute :scheme, type: URI
10
+ attribute :label
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Entry < Xml::Element
6
+ root
7
+
8
+ element :id, unique: true
9
+ element :title
10
+ element :updated, type: Time
11
+
12
+ may do
13
+ element :content
14
+ element :published, type: Time
15
+ element :rights
16
+ element :source
17
+ element :summary
18
+ end
19
+
20
+ any do
21
+ element :author, type: Person
22
+ element :category, type: Category
23
+ element :contributor, type: Person
24
+ element :link
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Feed < Xml::Element
6
+ root
7
+
8
+ element :id, unique: true
9
+ element :title
10
+ element :updated, type: Time
11
+
12
+ may do
13
+ element :generator, type: Generator
14
+ element :icon
15
+ element :logo
16
+ element :rights
17
+ element :subtitle, type: String
18
+ end
19
+
20
+ any do
21
+ element :author, type: Person
22
+ element :category, type: Category
23
+ element :contributor, type: Person
24
+ element :entry, type: Entry
25
+ element :link, type: Link
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Generator < Xml::Element
6
+ may do
7
+ attribute :uri, type: URI
8
+ attribute :version
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Link < Xml::Element
6
+ attribute :href, type: URI
7
+
8
+ may do
9
+ attribute :rel#, type: Enum(:alternate, :related, :self, :enclosure, :via)
10
+ attribute :type
11
+ attribute :hreflang
12
+ attribute :title
13
+ attribute :length
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Person < Xml::Element
6
+ element :name
7
+
8
+ may do
9
+ element :email
10
+ element :uri, type: URI
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'xommelier/atom'
2
+
3
+ module Xommelier
4
+ module Atom
5
+ class Source < Xml::Element
6
+ may do
7
+ element :generator, :icon, :id, :logo, :rights, :subtitle, :title, :updated
8
+ end
9
+ any do
10
+ element :author, :category, :contributor, :link
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,46 @@
1
+ require 'xommelier'
2
+
3
+ module Xommelier
4
+ class Collection < Hash
5
+ def initialize(klass)
6
+ @klass = klass
7
+ end
8
+
9
+ def respond_to?(name)
10
+ key?(name) || super(name)
11
+ end
12
+
13
+ def find_and_append(name, options = {}, &block)
14
+ item = self[name]
15
+ item.options = options
16
+ if block_given?
17
+ item.scoped(&block)
18
+ end
19
+ item
20
+ end
21
+
22
+ def method_missing(name, options = {}, &block)
23
+ if key?(name)
24
+ find_and_append(name, options, &block)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def find_or_create(name, options = {}, &block)
31
+ if key?(name)
32
+ find_and_append(name, options, &block)
33
+ else
34
+ @klass.new(name, options, &block)
35
+ end
36
+ end
37
+
38
+ def inspect
39
+ values.map { |value| value.inspect }.inspect
40
+ end
41
+
42
+ def pretty_inspect
43
+ values.map { |value| value.inspect }.pretty_inspect
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ require 'xommelier'
2
+
3
+ require 'xommelier/core_ext/boolean'
4
+ require 'xommelier/core_ext/date'
5
+ require 'xommelier/core_ext/float'
6
+ require 'xommelier/core_ext/integer'
7
+ require 'xommelier/core_ext/string'
8
+ require 'xommelier/core_ext/time'
9
+ require 'xommelier/core_ext/uri'
@@ -0,0 +1,24 @@
1
+ require 'xommelier'
2
+
3
+ class Boolean
4
+ BOOLEAN_MAP = {
5
+ true => true, 'true' => true, 'TRUE' => true, '1' => true, '1.0' => true, 1 => true, 1.0 => true,
6
+ false => false, 'false' => false, 'FALSE' => false, '0' => false, '0.0' => false, 0 => false, 0.0 => false
7
+ }
8
+
9
+ def self.from_xommelier(value)
10
+ BOOLEAN_MAP[value]
11
+ end
12
+ end
13
+
14
+ class TrueClass
15
+ def to_xommelier
16
+ self
17
+ end
18
+ end
19
+
20
+ class FalseClass
21
+ def to_xommelier
22
+ self
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'date'
2
+
3
+ class Date
4
+ def self.from_xommelier(value)
5
+ xmlschema(value)
6
+ end
7
+
8
+ def to_xommelier
9
+ xmlschema
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ class Float
2
+ def self.from_xommelier(value)
3
+ return nil if value.blank?
4
+ begin
5
+ Float(value)
6
+ rescue ArgumentError => e
7
+ value
8
+ end
9
+ end
10
+
11
+ def to_xommelier
12
+ self
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class Integer
2
+ def self.from_xommelier(value)
3
+ return nil if value.blank?
4
+ begin
5
+ value =~ /\./ ? Float(value) : Integer(value)
6
+ rescue ArgumentError => e
7
+ value
8
+ end
9
+ end
10
+
11
+ def to_xommelier
12
+ self
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def self.from_xommelier(value)
3
+ value.to_s
4
+ end
5
+
6
+ def to_xommelier
7
+ self
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require 'time'
2
+
3
+ class Time
4
+ def self.from_xommelier(value)
5
+ Time.xmlschema value
6
+ end
7
+
8
+ def to_xommelier
9
+ xmlschema
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'uri'
2
+
3
+ class URI::Generic
4
+ def self.from_xommelier(value)
5
+ URI.parse value
6
+ end
7
+
8
+ def to_xommelier
9
+ to_s
10
+ end
11
+ end
12
+ Uri = String
@@ -0,0 +1,3 @@
1
+ module Xommelier
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'xommelier'
2
+ require 'xommelier/xml/class_methods'
3
+ require 'active_support/concern'
4
+
5
+ module Xommelier
6
+ module Xml
7
+ extend ActiveSupport::Concern
8
+
9
+ Infinity = 1.0 / 0
10
+
11
+ included do
12
+ instance_variable_set :@_xmlns, nil
13
+ end
14
+
15
+ autoload :Namespace, 'xommelier/xml/namespace'
16
+ autoload :Element, 'xommelier/xml/element'
17
+ autoload :Attribute, 'xommelier/xml/attribute'
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ require 'xommelier/xml'
2
+
3
+ module Xommelier
4
+ module Xml
5
+ class Attribute
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ require 'xommelier/xml'
2
+
3
+ module Xommelier
4
+ module Xml
5
+ module ClassMethods
6
+ def ns
7
+ Xommelier::Xml::Namespace.registry
8
+ end
9
+
10
+ # Defines namespace used in formats
11
+ def xmlns(uri = nil, options = {}, &block)
12
+ if uri
13
+ instance_variable_set :@_xmlns, Xommelier::Xml::Namespace.new(uri, options, &block)
14
+ end
15
+ instance_variable_get :@_xmlns
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,142 @@
1
+ require 'xommelier/xml'
2
+ require 'xommelier/xml/element/dsl'
3
+ require 'nokogiri'
4
+ require 'active_support/core_ext/string/inflections'
5
+ require 'active_support/core_ext/array/extract_options'
6
+ require 'active_support/core_ext/class/attribute'
7
+
8
+ module Xommelier
9
+ module Xml
10
+ DEFAULT_OPTIONS = {
11
+ type: String
12
+ }
13
+ DEFAULT_ELEMENT_OPTIONS = DEFAULT_OPTIONS.merge(
14
+ count: :one
15
+ )
16
+
17
+ class Element
18
+ extend Xommelier::Xml::Element::DSL
19
+
20
+ class_attribute :elements, :attributes
21
+ self.elements = {}
22
+ self.attributes = {}
23
+
24
+ class << self
25
+ def xmlns(value = nil)
26
+ if value
27
+ @xmlns = case ns
28
+ when Module
29
+ ns.xmlns
30
+ else
31
+ ns
32
+ end
33
+ end
34
+ @xmlns ||= find_namespace
35
+ end
36
+ alias xmlns= xmlns
37
+
38
+ def element_name(element_name = nil)
39
+ @element_name = element_name if element_name
40
+ @element_name ||= find_element_name
41
+ end
42
+
43
+ private
44
+
45
+ def containing_module
46
+ @containing_module ||= ("::#{name.gsub(/::[^:]+$/, '')}").constantize
47
+ end
48
+
49
+ def find_namespace
50
+ containing_module.xmlns
51
+ end
52
+
53
+ def find_element_name
54
+ name.demodulize.tableize.dasherize
55
+ end
56
+ end
57
+
58
+ def initialize(contents = {}, options = {})
59
+ @options = DEFAULT_OPTIONS.merge(options)
60
+
61
+ @elements = {}
62
+ @attributes = {}
63
+ @text = nil
64
+
65
+ case contents
66
+ when Hash
67
+ contents.each do |name, value|
68
+ send("#{name}=", value)
69
+ end
70
+ else
71
+ send(:text=, contents)
72
+ end
73
+ end
74
+
75
+ def to_xml(options = {})
76
+ element_name = options.delete(:element_name) { self.element_name }
77
+ if options[:builder] # Non-root element
78
+ builder = options.delete(:builder)
79
+ attribute_values = {}
80
+ else # Root element
81
+ builder = Nokogiri::XML::Builder.new(options)
82
+ attribute_values = {xmlns: xmlns.to_s}
83
+ end
84
+ attributes.each do |name, value|
85
+ serialize_attribute(name, value, attribute_values)
86
+ end
87
+ builder.send(element_name, attribute_values) do |xml|
88
+ if respond_to?(:text)
89
+ xml.text @text
90
+ else
91
+ elements.each do |name, value|
92
+ serialize_element(name, value, xml)
93
+ end
94
+ end
95
+ end
96
+ builder.to_xml
97
+ end
98
+
99
+ protected
100
+
101
+ def element_options(name)
102
+ self.class.elements[name]
103
+ end
104
+
105
+ def attribute_options(name)
106
+ self.class.attributes[name]
107
+ end
108
+
109
+ def element_name
110
+ self.class.element_name
111
+ end
112
+
113
+ def xmlns
114
+ self.class.xmlns
115
+ end
116
+
117
+ def serialize_attribute(name, value, attributes)
118
+ attribute_options = self.attribute_options(name)
119
+ attribute_class = attribute_options[:type]
120
+ value = attribute_class.new(value) unless value.is_a?(attribute_class)
121
+ attributes[name] = value.to_xommelier
122
+ end
123
+
124
+ def serialize_element(name, value, xml, element_options = nil)
125
+ element_options ||= self.element_options(name)
126
+ if element_options[:count] == :many
127
+ single_element = element_options.merge(count: :one)
128
+ value.each { |item| serialize_element(name, item, xml, single_element) }
129
+ else
130
+ element_class = element_options[:type]
131
+ value = element_class.new(value) unless value.is_a?(element_class)
132
+ case value
133
+ when Xommelier::Xml::Element
134
+ value.to_xml(builder: xml, element_name: name)
135
+ else
136
+ xml.send(name) { xml.text value.to_xommelier }
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,51 @@
1
+ require 'xommelier/xml/element'
2
+
3
+ module Xommelier
4
+ module Xml
5
+ class Element
6
+ module DSL
7
+ def element(name, options = {})
8
+ self.elements[name] = DEFAULT_ELEMENT_OPTIONS.merge(options)
9
+ define_element_accessors(name)
10
+ end
11
+
12
+ def attribute(name, options = {})
13
+ self.attributes[name] = DEFAULT_OPTIONS.merge(options)
14
+ define_attribute_accessors(name)
15
+ end
16
+
17
+ def text(options = {})
18
+ define_text_accessors
19
+ end
20
+
21
+ private
22
+
23
+ def define_text_accessors
24
+ define_method(:text) { @text ||= '' }
25
+ define_method(:text=) { |value| @text = value }
26
+ end
27
+
28
+ def define_element_accessors(name)
29
+ case elements[name][:count]
30
+ when :one, :may
31
+ define_method(name) { @elements[name] }
32
+ define_method("#{name}=") { |value| @elements[name] = value }
33
+ when :many
34
+ define_method(name) {
35
+ @elements[name] ||= []
36
+ }
37
+ define_method("#{name}=") do |value|
38
+ @elements[name] ||= []
39
+ @elements[name] += Array(value)
40
+ end
41
+ end
42
+ end
43
+
44
+ def define_attribute_accessors(name)
45
+ define_method(name) { @attributes[name] }
46
+ define_method("#{name}=") { |value| @attributes[name] = value }
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,68 @@
1
+ require 'xommelier/xml'
2
+ require 'active_support/core_ext/array/extract_options'
3
+
4
+ module Xommelier
5
+ module Xml
6
+ class Namespace
7
+ class << self
8
+ def registry
9
+ @registry ||= Xommelier::Collection.new(self)
10
+ end
11
+ end
12
+
13
+ attr_reader :uri, :options, :as, :elements, :attributes
14
+ alias to_s uri
15
+
16
+ def initialize(uri, options = {}, &block)
17
+ @uri = uri
18
+ @options = {}
19
+ @elements = Xommelier::Collection.new(Xommelier::Xml::Element)
20
+ @attributes = Xommelier::Collection.new(Xommelier::Xml::Attribute)
21
+ @as = options.delete(:as)
22
+
23
+ Xommelier::Xml::Namespace.registry[as] = self
24
+
25
+ self.options = options
26
+ scoped(&block) if block_given?
27
+ end
28
+
29
+ def ns
30
+ Xommelier::Xml::Namespace.registry
31
+ end
32
+
33
+ def options=(options)
34
+ options.delete(:elements) { [] }.each do |name|
35
+ element(name)
36
+ end
37
+ options.delete(:attributes) { [] }.each do |name|
38
+ attribute(name)
39
+ end
40
+ @options.merge!(options)
41
+ end
42
+
43
+ def scoped(&block)
44
+ instance_exec(&block)
45
+ end
46
+
47
+ def attribute(*names, &block)
48
+ options = names.extract_options!
49
+ names.map do |name|
50
+ options[:ns] ||= self
51
+ attributes.find_or_create(name, options, &block)
52
+ end
53
+ end
54
+
55
+ def element(*names, &block)
56
+ options = names.extract_options!
57
+ names.map do |name|
58
+ options[:ns] ||= self
59
+ elements.find_or_create(name, options, &block)
60
+ end
61
+ end
62
+
63
+ def inspect
64
+ %(xmlns:#{as}="#{uri}")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ describe Xommelier::Xml::Element do
4
+ describe 'class' do
5
+ subject { NamespacedModule::EmptyRoot }
6
+
7
+ it { should respond_to(:xmlns) }
8
+ it { subject.xmlns.to_s.should == 'http://example.org/' }
9
+
10
+ it { should respond_to(:element_name) }
11
+ it { subject.element_name.should == 'empty-root' }
12
+
13
+ it { should respond_to(:elements) }
14
+ it { should respond_to(:attributes) }
15
+ end
16
+
17
+ describe 'DSL' do
18
+ subject { NamespacedModule::RootWithSimpleSubelement }
19
+
20
+ it { should respond_to(:element) }
21
+ it 'defines subelement' do
22
+ NamespacedModule::RootWithSimpleSubelement.elements.should have_key(:some)
23
+ end
24
+
25
+ it { should respond_to(:attribute) }
26
+ it 'defines attribute' do
27
+ NamespacedModule::RootWithAttribute.attributes.should have_key(:another)
28
+ end
29
+
30
+ it { should respond_to(:text) }
31
+ it 'defines as containing text' do
32
+ NamespacedModule::RootWithText.new.should respond_to(:text)
33
+ end
34
+ end
35
+
36
+ describe 'instance' do
37
+ subject { NamespacedModule::EmptyRoot.new }
38
+
39
+ it { should respond_to(:to_xml) }
40
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<empty-root xmlns="http://example.org/"/>\n) }
41
+
42
+ describe 'with text' do
43
+ subject { NamespacedModule::RootWithText.new('Text') }
44
+
45
+ it { should respond_to(:text) }
46
+ it { subject.text.should == 'Text' }
47
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-text xmlns="http://example.org/">Text</root-with-text>\n) }
48
+ end
49
+
50
+ describe 'with simple subelements' do
51
+ subject { NamespacedModule::RootWithSimpleSubelement.new(some: 'Text') }
52
+
53
+ it { should respond_to(:some) }
54
+ it { subject.some.should == 'Text' }
55
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-simple-subelement xmlns="http://example.org/">\n <some>Text</some>\n</root-with-simple-subelement>\n) }
56
+ end
57
+
58
+ describe 'with many simple subelements' do
59
+ subject do
60
+ NamespacedModule::RootWithManySimpleSubelements.new(foo: ['bar', 'baz'])
61
+ end
62
+
63
+ it { should respond_to(:foo) }
64
+ it { subject.foo.should == ['bar', 'baz'] }
65
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-many-simple-subelements xmlns="http://example.org/">\n <foo>bar</foo>\n <foo>baz</foo>\n</root-with-many-simple-subelements>\n) }
66
+ end
67
+
68
+ describe 'with attribute' do
69
+ subject { NamespacedModule::RootWithAttribute.new(another: 'Difference') }
70
+
71
+ it { should respond_to(:another) }
72
+ it { subject.another.should == 'Difference' }
73
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-attribute xmlns="http://example.org/" another="Difference"/>\n) }
74
+ end
75
+
76
+ describe 'with subelements' do
77
+ subject do
78
+ NamespacedModule::RootWithSubelement.new(
79
+ one: Date.new(2011, 8, 15),
80
+ two: '2',
81
+ some: 'Text',
82
+ another: {some: 'Text'}
83
+ )
84
+ end
85
+
86
+ it { should respond_to(:one) }
87
+ it { subject.another.should == {some: 'Text'} }
88
+ it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-subelement xmlns="http://example.org/" one="2011-08-15" two="2">\n <some>Text</some>\n <another>\n <some>Text</some>\n </another>\n</root-with-subelement>\n) }
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Xommelier::Xml do
4
+ end
5
+
6
+ describe NamespacedModule do
7
+ subject { NamespacedModule }
8
+
9
+ it { should respond_to(:xmlns) }
10
+ it { subject.xmlns.to_s.should == 'http://example.org/' }
11
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Xommelier do
4
+ it { Xommelier::VERSION.should == '0.0.1' }
5
+ end
@@ -0,0 +1,32 @@
1
+ module NamespacedModule
2
+ include Xommelier::Xml
3
+
4
+ xmlns 'http://example.org/'
5
+
6
+ class EmptyRoot < Xommelier::Xml::Element
7
+ end
8
+
9
+ class RootWithText < Xommelier::Xml::Element
10
+ text
11
+ end
12
+
13
+ class RootWithSimpleSubelement < Xommelier::Xml::Element
14
+ element :some
15
+ end
16
+
17
+ class RootWithAttribute < Xommelier::Xml::Element
18
+ attribute :one, type: Date
19
+ attribute :another
20
+ end
21
+
22
+ class RootWithManySimpleSubelements < Xommelier::Xml::Element
23
+ element :foo, count: :many
24
+ end
25
+
26
+ class RootWithSubelement < Xommelier::Xml::Element
27
+ attribute :one, type: Date
28
+ attribute :two
29
+ element :some
30
+ element :another, type: RootWithSimpleSubelement
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ root = File.expand_path('../..', __FILE__)
2
+ $:<< File.join(root, 'lib')
3
+ require 'rspec'
4
+ require 'xommelier'
5
+ require 'namespaced_module'
6
+
7
+ Dir[File.join(root, 'spec/support/**/*.rb')].each {|f| require f}
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "xommelier/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "xommelier"
7
+ s.version = Xommelier::VERSION
8
+ s.authors = ["Alexander Semyonov"]
9
+ s.email = ["al@semyonov.us"]
10
+ s.homepage = "http://github.com/alsemyonov/xommelier"
11
+ s.summary = %q{XML-Object Mapper}
12
+ s.description = %q{XML-Object Mapper with many built-in XML formats supported}
13
+
14
+ s.rubyforge_project = "xommelier"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'nokogiri', '~> 1.5.0'
22
+ s.add_dependency 'activesupport', '~> 3.0.0'
23
+ s.add_dependency 'activemodel', '~> 3.0.0'
24
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xommelier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alexander Semyonov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-15 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.5.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: activemodel
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 3.0.0
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ description: XML-Object Mapper with many built-in XML formats supported
49
+ email:
50
+ - al@semyonov.us
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - .rspec
60
+ - Gemfile
61
+ - Guardfile
62
+ - Rakefile
63
+ - examples/atom.rb
64
+ - examples/xml.rb
65
+ - lib/xommelier.rb
66
+ - lib/xommelier/atom.rb
67
+ - lib/xommelier/atom/category.rb
68
+ - lib/xommelier/atom/entry.rb
69
+ - lib/xommelier/atom/feed.rb
70
+ - lib/xommelier/atom/generator.rb
71
+ - lib/xommelier/atom/link.rb
72
+ - lib/xommelier/atom/person.rb
73
+ - lib/xommelier/atom/source.rb
74
+ - lib/xommelier/collection.rb
75
+ - lib/xommelier/core_ext.rb
76
+ - lib/xommelier/core_ext/boolean.rb
77
+ - lib/xommelier/core_ext/date.rb
78
+ - lib/xommelier/core_ext/float.rb
79
+ - lib/xommelier/core_ext/integer.rb
80
+ - lib/xommelier/core_ext/string.rb
81
+ - lib/xommelier/core_ext/time.rb
82
+ - lib/xommelier/core_ext/uri.rb
83
+ - lib/xommelier/version.rb
84
+ - lib/xommelier/xml.rb
85
+ - lib/xommelier/xml/attribute.rb
86
+ - lib/xommelier/xml/class_methods.rb
87
+ - lib/xommelier/xml/element.rb
88
+ - lib/xommelier/xml/element/dsl.rb
89
+ - lib/xommelier/xml/namespace.rb
90
+ - spec/lib/xommelier/xml/element_spec.rb
91
+ - spec/lib/xommelier/xml_spec.rb
92
+ - spec/lib/xommelier_spec.rb
93
+ - spec/namespaced_module.rb
94
+ - spec/spec_helper.rb
95
+ - xommelier.gemspec
96
+ homepage: http://github.com/alsemyonov/xommelier
97
+ licenses: []
98
+
99
+ post_install_message:
100
+ rdoc_options: []
101
+
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project: xommelier
119
+ rubygems_version: 1.8.5
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: XML-Object Mapper
123
+ test_files: []
124
+