ROXML 3.0.0

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.
Files changed (101) hide show
  1. data/.gitignore +6 -0
  2. data/.gitmodules +3 -0
  3. data/History.txt +299 -0
  4. data/MIT-LICENSE +18 -0
  5. data/README.rdoc +161 -0
  6. data/Rakefile +95 -0
  7. data/TODO +39 -0
  8. data/VERSION +1 -0
  9. data/config/website.yml +2 -0
  10. data/examples/amazon.rb +35 -0
  11. data/examples/current_weather.rb +27 -0
  12. data/examples/dashed_elements.rb +20 -0
  13. data/examples/library.rb +40 -0
  14. data/examples/posts.rb +27 -0
  15. data/examples/rails.rb +70 -0
  16. data/examples/twitter.rb +37 -0
  17. data/examples/xml/active_record.xml +70 -0
  18. data/examples/xml/amazon.xml +133 -0
  19. data/examples/xml/current_weather.xml +89 -0
  20. data/examples/xml/dashed_elements.xml +52 -0
  21. data/examples/xml/posts.xml +23 -0
  22. data/examples/xml/twitter.xml +422 -0
  23. data/lib/roxml.rb +547 -0
  24. data/lib/roxml/definition.rb +236 -0
  25. data/lib/roxml/hash_definition.rb +25 -0
  26. data/lib/roxml/xml.rb +43 -0
  27. data/lib/roxml/xml/parsers/libxml.rb +91 -0
  28. data/lib/roxml/xml/parsers/nokogiri.rb +77 -0
  29. data/lib/roxml/xml/references.rb +297 -0
  30. data/roxml.gemspec +201 -0
  31. data/spec/definition_spec.rb +486 -0
  32. data/spec/examples/active_record_spec.rb +40 -0
  33. data/spec/examples/amazon_spec.rb +54 -0
  34. data/spec/examples/current_weather_spec.rb +37 -0
  35. data/spec/examples/dashed_elements_spec.rb +20 -0
  36. data/spec/examples/library_spec.rb +46 -0
  37. data/spec/examples/post_spec.rb +24 -0
  38. data/spec/examples/twitter_spec.rb +32 -0
  39. data/spec/roxml_spec.rb +372 -0
  40. data/spec/shared_specs.rb +15 -0
  41. data/spec/spec.opts +1 -0
  42. data/spec/spec_helper.rb +14 -0
  43. data/spec/support/libxml.rb +3 -0
  44. data/spec/support/nokogiri.rb +3 -0
  45. data/spec/xml/attributes_spec.rb +36 -0
  46. data/spec/xml/namespace_spec.rb +240 -0
  47. data/spec/xml/namespaces_spec.rb +32 -0
  48. data/spec/xml/parser_spec.rb +26 -0
  49. data/tasks/rdoc.rake +13 -0
  50. data/tasks/rspec.rake +25 -0
  51. data/tasks/test.rake +35 -0
  52. data/test/fixtures/book_malformed.xml +5 -0
  53. data/test/fixtures/book_pair.xml +8 -0
  54. data/test/fixtures/book_text_with_attribute.xml +5 -0
  55. data/test/fixtures/book_valid.xml +5 -0
  56. data/test/fixtures/book_with_authors.xml +7 -0
  57. data/test/fixtures/book_with_contributions.xml +9 -0
  58. data/test/fixtures/book_with_contributors.xml +7 -0
  59. data/test/fixtures/book_with_contributors_attrs.xml +7 -0
  60. data/test/fixtures/book_with_default_namespace.xml +9 -0
  61. data/test/fixtures/book_with_depth.xml +6 -0
  62. data/test/fixtures/book_with_octal_pages.xml +4 -0
  63. data/test/fixtures/book_with_publisher.xml +7 -0
  64. data/test/fixtures/book_with_wrapped_attr.xml +3 -0
  65. data/test/fixtures/dictionary_of_attr_name_clashes.xml +8 -0
  66. data/test/fixtures/dictionary_of_attrs.xml +6 -0
  67. data/test/fixtures/dictionary_of_guarded_names.xml +6 -0
  68. data/test/fixtures/dictionary_of_mixeds.xml +4 -0
  69. data/test/fixtures/dictionary_of_name_clashes.xml +10 -0
  70. data/test/fixtures/dictionary_of_names.xml +4 -0
  71. data/test/fixtures/dictionary_of_texts.xml +10 -0
  72. data/test/fixtures/library.xml +30 -0
  73. data/test/fixtures/library_uppercase.xml +30 -0
  74. data/test/fixtures/muffins.xml +3 -0
  75. data/test/fixtures/nameless_ageless_youth.xml +2 -0
  76. data/test/fixtures/node_with_attr_name_conflicts.xml +1 -0
  77. data/test/fixtures/node_with_name_conflicts.xml +4 -0
  78. data/test/fixtures/numerology.xml +4 -0
  79. data/test/fixtures/person.xml +1 -0
  80. data/test/fixtures/person_with_guarded_mothers.xml +13 -0
  81. data/test/fixtures/person_with_mothers.xml +10 -0
  82. data/test/mocks/dictionaries.rb +57 -0
  83. data/test/mocks/mocks.rb +279 -0
  84. data/test/support/fixtures.rb +11 -0
  85. data/test/test_helper.rb +34 -0
  86. data/test/unit/definition_test.rb +235 -0
  87. data/test/unit/deprecations_test.rb +24 -0
  88. data/test/unit/to_xml_test.rb +81 -0
  89. data/test/unit/xml_attribute_test.rb +39 -0
  90. data/test/unit/xml_block_test.rb +81 -0
  91. data/test/unit/xml_bool_test.rb +122 -0
  92. data/test/unit/xml_convention_test.rb +150 -0
  93. data/test/unit/xml_hash_test.rb +115 -0
  94. data/test/unit/xml_initialize_test.rb +49 -0
  95. data/test/unit/xml_name_test.rb +141 -0
  96. data/test/unit/xml_namespace_test.rb +31 -0
  97. data/test/unit/xml_object_test.rb +207 -0
  98. data/test/unit/xml_required_test.rb +94 -0
  99. data/test/unit/xml_text_test.rb +71 -0
  100. data/website/index.html +98 -0
  101. metadata +254 -0
@@ -0,0 +1,297 @@
1
+ module ROXML
2
+ class RequiredElementMissing < Exception # :nodoc:
3
+ end
4
+
5
+ #
6
+ # Internal base class that represents an XML - Class binding.
7
+ #
8
+ class XMLRef # :nodoc:
9
+ delegate :required?, :array?, :blocks, :accessor, :default, :wrapper, :to => :opts
10
+
11
+ def initialize(opts, instance)
12
+ @opts = opts
13
+ @instance = instance
14
+ end
15
+
16
+ def to_xml(instance)
17
+ val = instance.__send__(accessor)
18
+ opts.to_xml.respond_to?(:call) ? opts.to_xml.call(val) : val
19
+ end
20
+
21
+ def update_xml(xml, value)
22
+ returning wrap(xml) do |xml|
23
+ write_xml(xml, value)
24
+ end
25
+ end
26
+
27
+ def name
28
+ opts.name_explicit? ? opts.name : conventionize(opts.name)
29
+ end
30
+
31
+ def xpath_name
32
+ namespacify(name)
33
+ end
34
+
35
+ def value_in(xml)
36
+ xml = XML::Node.from(xml)
37
+ value = fetch_value(xml)
38
+ value = default if value.nil?
39
+
40
+ freeze(apply_blocks(value))
41
+ end
42
+
43
+ private
44
+ attr_reader :opts
45
+
46
+ def conventionize(what)
47
+ convention ||= @instance.class.respond_to?(:roxml_naming_convention) && @instance.class.roxml_naming_convention
48
+ if !what.blank? && convention.respond_to?(:call)
49
+ URI.unescape(convention.call(URI.escape(what, /\/|::/)))
50
+ else
51
+ what
52
+ end
53
+ end
54
+
55
+ def namespacify(what)
56
+ return "#{opts.namespace}:#{what}" if opts.namespace
57
+
58
+ namespace = @instance.class.roxml_namespace || @default_namespace
59
+ if namespace && what.present? && !what.include?(':') && (opts.namespace != false)
60
+ "#{namespace}:#{what}"
61
+ else
62
+ what
63
+ end
64
+ end
65
+
66
+ def apply_blocks(val)
67
+ begin
68
+ blocks.inject(val) {|val, block| block.call(val) }
69
+ rescue Exception => ex
70
+ raise ex, "#{accessor}: #{ex.message}"
71
+ end
72
+ end
73
+
74
+ def freeze(val)
75
+ if opts.frozen?
76
+ val.each(&:freeze) if val.is_a?(Enumerable)
77
+ val.freeze
78
+ else
79
+ val
80
+ end
81
+ end
82
+
83
+ def xpath
84
+ opts.wrapper ? "#{namespacify(opts.wrapper)}/#{xpath_name}" : xpath_name.to_s
85
+ end
86
+
87
+ def auto_xpath
88
+ "#{namespacify(conventionize(opts.name.pluralize))}/#{xpath_name}" if array?
89
+ end
90
+
91
+ def several?
92
+ array?
93
+ end
94
+
95
+ def wrap(xml)
96
+ return xml if !wrapper || xml.name == wrapper
97
+ if child = xml.children.find {|c| c.name == wrapper }
98
+ return child
99
+ end
100
+ xml.add_child(XML::Node.create(wrapper.to_s))
101
+ end
102
+
103
+ def nodes_in(xml)
104
+ @default_namespace = xml.default_namespace
105
+ vals = xml.search(xpath, @instance.class.roxml_namespaces)
106
+
107
+ if several? && vals.empty? && !wrapper && auto_xpath
108
+ vals = xml.search(auto_xpath, @instance.class.roxml_namespaces)
109
+ @auto_vals = !vals.empty?
110
+ end
111
+
112
+ if vals.empty?
113
+ raise RequiredElementMissing, "#{name} from #{xml} for #{accessor}" if required?
114
+ default
115
+ elsif several?
116
+ vals.map do |val|
117
+ yield val
118
+ end
119
+ else
120
+ yield(vals.first)
121
+ end
122
+ end
123
+ end
124
+
125
+ # Interal class representing an XML attribute binding
126
+ #
127
+ # In context:
128
+ # <element attribute="XMLAttributeRef">
129
+ # XMLTextRef
130
+ # </element>
131
+ class XMLAttributeRef < XMLRef # :nodoc:
132
+ private
133
+ # Updates the attribute in the given XML block to
134
+ # the value provided.
135
+ def write_xml(xml, value)
136
+ xml.attributes[name] = value.to_s
137
+ end
138
+
139
+ def fetch_value(xml)
140
+ nodes_in(xml) do |node|
141
+ node.value
142
+ end
143
+ end
144
+
145
+ def xpath_name
146
+ "@#{name}"
147
+ end
148
+ end
149
+
150
+ # Interal class representing XML content text binding
151
+ #
152
+ # In context:
153
+ # <element attribute="XMLAttributeRef">
154
+ # XMLTextRef
155
+ # </element>
156
+ class XMLTextRef < XMLRef # :nodoc:
157
+ delegate :cdata?, :content?, :name?, :to => :opts
158
+
159
+ private
160
+ # Updates the text in the given _xml_ block to
161
+ # the _value_ provided.
162
+ def write_xml(xml, value)
163
+ if content?
164
+ add(xml, value)
165
+ elsif name?
166
+ xml.name = value
167
+ elsif array?
168
+ value.each do |v|
169
+ add(xml.add_child(XML::Node.create(name)), v)
170
+ end
171
+ else
172
+ add(xml.add_child(XML::Node.create(name)), value)
173
+ end
174
+ end
175
+
176
+ def fetch_value(xml)
177
+ if content? || name?
178
+ value =
179
+ if content?
180
+ xml.content.to_s.strip
181
+ elsif name?
182
+ xml.name
183
+ end
184
+
185
+ if value.empty?
186
+ raise RequiredElementMissing, "#{name} from #{xml} for #{accessor}" if required?
187
+ default
188
+ else
189
+ value
190
+ end
191
+ else
192
+ nodes_in(xml) do |node|
193
+ node.content.strip
194
+ end
195
+ end
196
+ end
197
+
198
+ def add(dest, value)
199
+ if cdata?
200
+ dest.add_child(XML::Node.new_cdata(value.to_s))
201
+ else
202
+ dest.content = value.to_s
203
+ end
204
+ end
205
+ end
206
+
207
+ class XMLHashRef < XMLTextRef # :nodoc:
208
+ delegate :hash, :to => :opts
209
+
210
+ def initialize(opts, inst)
211
+ super(opts, inst)
212
+ @key = opts.hash.key.to_ref(inst)
213
+ @value = opts.hash.value.to_ref(inst)
214
+ end
215
+
216
+ def several?
217
+ true
218
+ end
219
+
220
+ private
221
+ # Updates the composed XML object in the given XML block to
222
+ # the value provided.
223
+ def write_xml(xml, value)
224
+ value.each_pair do |k, v|
225
+ node = xml.add_child(XML::Node.create(hash.wrapper))
226
+ @key.update_xml(node, k)
227
+ @value.update_xml(node, v)
228
+ end
229
+ end
230
+
231
+ def fetch_value(xml)
232
+ nodes_in(xml) do |node|
233
+ [@key.value_in(node), @value.value_in(node)]
234
+ end
235
+ end
236
+
237
+ def apply_blocks(vals)
238
+ unless blocks.empty?
239
+ vals.collect! do |kvp|
240
+ super(kvp)
241
+ end
242
+ end
243
+ to_hash(vals) if vals
244
+ end
245
+
246
+ def freeze(vals)
247
+ if opts.frozen?
248
+ vals.each_pair{|k, v| k.freeze; v.freeze }
249
+ vals.freeze
250
+ else
251
+ vals
252
+ end
253
+ end
254
+
255
+ def to_hash(array)
256
+ hash = array.inject({}) do |result, (k, v)|
257
+ result[k] ||= []
258
+ result[k] << v
259
+ result
260
+ end
261
+ hash.each_pair do |k, v|
262
+ hash[k] = v.first if v.size == 1
263
+ end
264
+ end
265
+ end
266
+
267
+ class XMLObjectRef < XMLTextRef # :nodoc:
268
+ delegate :type, :to => :opts
269
+
270
+ private
271
+ # Updates the composed XML object in the given XML block to
272
+ # the value provided.
273
+ def write_xml(xml, value)
274
+ if array?
275
+ value.each do |v|
276
+ xml.add_child(v.to_xml(name))
277
+ end
278
+ elsif value.is_a?(ROXML)
279
+ xml.add_child(value.to_xml(name))
280
+ else
281
+ node = XML::Node.create(name)
282
+ node.content = value.to_xml
283
+ xml.add_child(node)
284
+ end
285
+ end
286
+
287
+ def fetch_value(xml)
288
+ nodes_in(xml) do |node|
289
+ if type.respond_to? :from_xml
290
+ type.from_xml(node)
291
+ else
292
+ type.new(node)
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,201 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{roxml}
8
+ s.version = "3.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ben Woosley", "Zak Mandhro", "Anders Engstrom", "Russ Olsen"]
12
+ s.date = %q{2009-10-16}
13
+ s.description = %q{ROXML is a Ruby library designed to make it easier for Ruby developers to work with XML.
14
+ Using simple annotations, it enables Ruby classes to be mapped to XML. ROXML takes care
15
+ of the marshalling and unmarshalling of mapped attributes so that developers can focus on
16
+ building first-class Ruby classes. As a result, ROXML simplifies the development of
17
+ RESTful applications, Web Services, and XML-RPC.
18
+ }
19
+ s.email = %q{ben.woosley@gmail.com}
20
+ s.extra_rdoc_files = [
21
+ "History.txt",
22
+ "README.rdoc"
23
+ ]
24
+ s.files = [
25
+ ".gitignore",
26
+ ".gitmodules",
27
+ "History.txt",
28
+ "MIT-LICENSE",
29
+ "README.rdoc",
30
+ "Rakefile",
31
+ "TODO",
32
+ "VERSION",
33
+ "config/website.yml",
34
+ "examples/amazon.rb",
35
+ "examples/current_weather.rb",
36
+ "examples/dashed_elements.rb",
37
+ "examples/library.rb",
38
+ "examples/posts.rb",
39
+ "examples/rails.rb",
40
+ "examples/twitter.rb",
41
+ "examples/xml/active_record.xml",
42
+ "examples/xml/amazon.xml",
43
+ "examples/xml/current_weather.xml",
44
+ "examples/xml/dashed_elements.xml",
45
+ "examples/xml/posts.xml",
46
+ "examples/xml/twitter.xml",
47
+ "lib/roxml.rb",
48
+ "lib/roxml/definition.rb",
49
+ "lib/roxml/hash_definition.rb",
50
+ "lib/roxml/xml.rb",
51
+ "lib/roxml/xml/parsers/libxml.rb",
52
+ "lib/roxml/xml/parsers/nokogiri.rb",
53
+ "lib/roxml/xml/references.rb",
54
+ "roxml.gemspec",
55
+ "spec/definition_spec.rb",
56
+ "spec/examples/active_record_spec.rb",
57
+ "spec/examples/amazon_spec.rb",
58
+ "spec/examples/current_weather_spec.rb",
59
+ "spec/examples/dashed_elements_spec.rb",
60
+ "spec/examples/library_spec.rb",
61
+ "spec/examples/post_spec.rb",
62
+ "spec/examples/twitter_spec.rb",
63
+ "spec/roxml_spec.rb",
64
+ "spec/shared_specs.rb",
65
+ "spec/spec.opts",
66
+ "spec/spec_helper.rb",
67
+ "spec/support/libxml.rb",
68
+ "spec/support/nokogiri.rb",
69
+ "spec/xml/attributes_spec.rb",
70
+ "spec/xml/namespace_spec.rb",
71
+ "spec/xml/namespaces_spec.rb",
72
+ "spec/xml/parser_spec.rb",
73
+ "tasks/rdoc.rake",
74
+ "tasks/rspec.rake",
75
+ "tasks/test.rake",
76
+ "test/fixtures/book_malformed.xml",
77
+ "test/fixtures/book_pair.xml",
78
+ "test/fixtures/book_text_with_attribute.xml",
79
+ "test/fixtures/book_valid.xml",
80
+ "test/fixtures/book_with_authors.xml",
81
+ "test/fixtures/book_with_contributions.xml",
82
+ "test/fixtures/book_with_contributors.xml",
83
+ "test/fixtures/book_with_contributors_attrs.xml",
84
+ "test/fixtures/book_with_default_namespace.xml",
85
+ "test/fixtures/book_with_depth.xml",
86
+ "test/fixtures/book_with_octal_pages.xml",
87
+ "test/fixtures/book_with_publisher.xml",
88
+ "test/fixtures/book_with_wrapped_attr.xml",
89
+ "test/fixtures/dictionary_of_attr_name_clashes.xml",
90
+ "test/fixtures/dictionary_of_attrs.xml",
91
+ "test/fixtures/dictionary_of_guarded_names.xml",
92
+ "test/fixtures/dictionary_of_mixeds.xml",
93
+ "test/fixtures/dictionary_of_name_clashes.xml",
94
+ "test/fixtures/dictionary_of_names.xml",
95
+ "test/fixtures/dictionary_of_texts.xml",
96
+ "test/fixtures/library.xml",
97
+ "test/fixtures/library_uppercase.xml",
98
+ "test/fixtures/muffins.xml",
99
+ "test/fixtures/nameless_ageless_youth.xml",
100
+ "test/fixtures/node_with_attr_name_conflicts.xml",
101
+ "test/fixtures/node_with_name_conflicts.xml",
102
+ "test/fixtures/numerology.xml",
103
+ "test/fixtures/person.xml",
104
+ "test/fixtures/person_with_guarded_mothers.xml",
105
+ "test/fixtures/person_with_mothers.xml",
106
+ "test/mocks/dictionaries.rb",
107
+ "test/mocks/mocks.rb",
108
+ "test/support/fixtures.rb",
109
+ "test/test_helper.rb",
110
+ "test/unit/definition_test.rb",
111
+ "test/unit/deprecations_test.rb",
112
+ "test/unit/to_xml_test.rb",
113
+ "test/unit/xml_attribute_test.rb",
114
+ "test/unit/xml_block_test.rb",
115
+ "test/unit/xml_bool_test.rb",
116
+ "test/unit/xml_convention_test.rb",
117
+ "test/unit/xml_hash_test.rb",
118
+ "test/unit/xml_initialize_test.rb",
119
+ "test/unit/xml_name_test.rb",
120
+ "test/unit/xml_namespace_test.rb",
121
+ "test/unit/xml_object_test.rb",
122
+ "test/unit/xml_required_test.rb",
123
+ "test/unit/xml_text_test.rb",
124
+ "website/index.html"
125
+ ]
126
+ s.homepage = %q{http://roxml.rubyforge.org}
127
+ s.rdoc_options = ["--charset=UTF-8"]
128
+ s.require_paths = ["lib"]
129
+ s.rubyforge_project = %q{ROXML}
130
+ s.rubygems_version = %q{1.3.5}
131
+ s.summary = %q{Ruby Object to XML mapping library}
132
+ s.test_files = [
133
+ "spec/definition_spec.rb",
134
+ "spec/examples/active_record_spec.rb",
135
+ "spec/examples/amazon_spec.rb",
136
+ "spec/examples/current_weather_spec.rb",
137
+ "spec/examples/dashed_elements_spec.rb",
138
+ "spec/examples/library_spec.rb",
139
+ "spec/examples/post_spec.rb",
140
+ "spec/examples/twitter_spec.rb",
141
+ "spec/roxml_spec.rb",
142
+ "spec/shared_specs.rb",
143
+ "spec/spec_helper.rb",
144
+ "spec/support/libxml.rb",
145
+ "spec/support/nokogiri.rb",
146
+ "spec/xml/attributes_spec.rb",
147
+ "spec/xml/namespace_spec.rb",
148
+ "spec/xml/namespaces_spec.rb",
149
+ "spec/xml/parser_spec.rb",
150
+ "test/mocks/dictionaries.rb",
151
+ "test/mocks/mocks.rb",
152
+ "test/support/fixtures.rb",
153
+ "test/test_helper.rb",
154
+ "test/unit/definition_test.rb",
155
+ "test/unit/deprecations_test.rb",
156
+ "test/unit/to_xml_test.rb",
157
+ "test/unit/xml_attribute_test.rb",
158
+ "test/unit/xml_block_test.rb",
159
+ "test/unit/xml_bool_test.rb",
160
+ "test/unit/xml_convention_test.rb",
161
+ "test/unit/xml_hash_test.rb",
162
+ "test/unit/xml_initialize_test.rb",
163
+ "test/unit/xml_name_test.rb",
164
+ "test/unit/xml_namespace_test.rb",
165
+ "test/unit/xml_object_test.rb",
166
+ "test/unit/xml_required_test.rb",
167
+ "test/unit/xml_text_test.rb",
168
+ "examples/amazon.rb",
169
+ "examples/current_weather.rb",
170
+ "examples/dashed_elements.rb",
171
+ "examples/library.rb",
172
+ "examples/posts.rb",
173
+ "examples/rails.rb",
174
+ "examples/twitter.rb"
175
+ ]
176
+
177
+ if s.respond_to? :specification_version then
178
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
179
+ s.specification_version = 3
180
+
181
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
182
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.1.0"])
183
+ s.add_runtime_dependency(%q<nokogiri>, [">= 1.3.3"])
184
+ s.add_development_dependency(%q<rspec>, [">= 0"])
185
+ s.add_development_dependency(%q<sqlite3-ruby>, [">= 1.2.4"])
186
+ s.add_development_dependency(%q<activerecord>, [">= 2.2.2"])
187
+ else
188
+ s.add_dependency(%q<activesupport>, [">= 2.1.0"])
189
+ s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
190
+ s.add_dependency(%q<rspec>, [">= 0"])
191
+ s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.4"])
192
+ s.add_dependency(%q<activerecord>, [">= 2.2.2"])
193
+ end
194
+ else
195
+ s.add_dependency(%q<activesupport>, [">= 2.1.0"])
196
+ s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
197
+ s.add_dependency(%q<rspec>, [">= 0"])
198
+ s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.4"])
199
+ s.add_dependency(%q<activerecord>, [">= 2.2.2"])
200
+ end
201
+ end