ROXML 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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