xommelier 0.0.1

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.
@@ -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
+