jordi-xml_struct 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -121,11 +121,25 @@ all methods it doesn't contain to the collection below, so you get:
121
121
 
122
122
  student.courses.collect { |c| c.downcase.to_sym } => [:math, :biology]
123
123
 
124
- ### Auto "type-casting"
124
+ ### Attribute auto "type-casting"
125
125
 
126
- Strings that look like integers are promoted via `to_i`, and similarly
127
- floats via `to_f`. Strings that look like booleans are also promoted, but
128
- only if called by their question mark names (such as `enabled?`.)
126
+ Attribute strings that look like integers are promoted via `to_i`, and
127
+ similarly floats via `to_f`. Strings that look like booleans are also
128
+ promoted, but only if called by their question mark names (such as
129
+ `enabled?`.)
130
+
131
+ At first, elements appear to do the same, but they don't, really. (I'd like
132
+ to, but one can't define methods on, say `5`, or `-1.2`.) So in the case of
133
+ the following XML:
134
+
135
+ <thing><name>Foo</name></thing>
136
+
137
+ While `thing.name == 'Foo'` is `true`, `thing.name => <XMLStruct ...>`. The
138
+ consequence is that you can call `String` methods on `thing.name` (such as
139
+ `upcase`, or `==`), but if you assign it to a new variable, you will not get
140
+ a `String` object. To do that, call `thing.name.to_obj`, which will return
141
+ you the auto type-casted (see above) version of `thing.name`, in this case
142
+ `"Foo"`.
129
143
 
130
144
  ### Slow
131
145
 
data/TODO CHANGED
@@ -1,3 +1,4 @@
1
1
  * Make use of libxml if it's available, then fallback to REXML
2
2
  * Refactor so as to not do things recursively
3
3
  * Detect more types, such as dates and timestamps
4
+ * Remove ActiveSupport dependency
data/WHATSNEW CHANGED
@@ -1,3 +1,11 @@
1
+ * 0.1.3 (2008-10-10):
2
+ - Switched tests to use test/spec
3
+ - Added XMLStruct#to_obj to return the corresponding Ruby object value
4
+ - Added XMLStruct#to_raw_xml to return the REXML object
5
+ - Added documentation on auto-typecasting behaviour caveat
6
+
7
+ * 0.1.2 (2008-10-10):
8
+ - Documentation
9
+
1
10
  * 0.1.1 (2008-10-10):
2
11
  - First "release" ;)
3
-
data/lib/xml_struct.rb CHANGED
@@ -21,17 +21,27 @@ class XMLStruct
21
21
  @raw.attributes.each { |n, v| __set_attribute n, v }
22
22
  end
23
23
 
24
+ # Returns the raw REXML::Element object used to build this XMLStruct
25
+ def to_raw_xml
26
+ @raw
27
+ end
28
+
29
+ # Returns the Ruby value to which we pass missing methods
30
+ def to_obj
31
+ @value
32
+ end
33
+
24
34
  # An XMLStruct is blank when it has a blank value, no child elements,
25
35
  # and no attributes. For example:
26
36
  #
27
37
  # <blank_element></blank_element>
28
38
  def blank?
29
- @value.blank? && @children.blank? && @attributes.blank?
39
+ to_obj.blank? && @children.blank? && @attributes.blank?
30
40
  end
31
41
 
32
42
  # XMLStruct objects are compared according to their values
33
43
  def <=>(other)
34
- @value <=> other
44
+ to_obj <=> other
35
45
  end
36
46
 
37
47
  # Array-notation access to elements and attributes. It comes handy when
@@ -80,17 +90,17 @@ class XMLStruct
80
90
 
81
91
  %w[ true yes t y ].include? boolish.downcase
82
92
 
83
- elsif @value.blank? && (@children.size == 1) &&
93
+ elsif to_obj.blank? && (@children.size == 1) &&
84
94
  (single_child = @children.values.first).respond_to?(method)
85
95
 
86
96
  single_child.send method, *args, &block
87
97
  else
88
- @value.send method, *args, &block
98
+ to_obj.send method, *args, &block
89
99
  end
90
100
  end
91
101
 
92
102
  def inspect # :nodoc:
93
- %{ #<#{self.class.to_s} value=#{@value.inspect} (#{@value.class.to_s})
103
+ %{ #<#{self.class.to_s} value=#{to_obj.inspect} (#{to_obj.class.to_s})
94
104
  attributes=[#{@attributes.keys.map(&:to_s).join(', ') }]
95
105
  children=[#{@children.keys.map(&:to_s).join(', ') }]> }.squish
96
106
  end
data/test/test_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'test/unit'
2
2
  require 'rubygems'
3
+ require File.join(File.dirname(__FILE__),
4
+ 'vendor', 'test-spec', 'lib', 'test', 'spec')
3
5
 
4
6
  begin
5
7
  require 'redgreen'
@@ -7,6 +9,12 @@ rescue LoadError
7
9
  puts "Install the 'redgreen' gem to get color output"
8
10
  end
9
11
 
12
+ begin
13
+ require 'ruby-prof'
14
+ rescue LoadError
15
+ puts "Install the 'ruby-prof' gem (>= 0.6.1) to get profiling information"
16
+ end
17
+
10
18
  require File.join(File.dirname(__FILE__), '..', 'lib', 'xml_struct')
11
19
 
12
20
  def xml_file(name_symbol)
@@ -23,14 +31,6 @@ require 'digest/md5'
23
31
  end
24
32
 
25
33
  class Test::Unit::TestCase
26
- def self.should(do_stuff_that_is_true, &block)
27
-
28
- object = to_s.split('Test').first
29
- method = "test that #{object} should #{do_stuff_that_is_true}"
30
-
31
- define_method(method.intern) { assert block.bind(self).call }
32
- end
33
-
34
34
  def debug
35
35
  require 'ruby-debug'; debugger
36
36
  end
@@ -0,0 +1,378 @@
1
+ = test/spec, a BDD interface for Test::Unit
2
+
3
+ Copyright (C) 2006, 2007, 2008 Christian Neukirchen <mailto:chneukirchen@gmail.com>
4
+
5
+
6
+ == What is test/spec?
7
+
8
+ test/spec layers an RSpec-inspired interface on top of Test::Unit, so
9
+ you can mix TDD and BDD (Behavior-Driven Development).
10
+
11
+ test/spec is a clean-room implementation that maps most kinds of
12
+ Test::Unit assertions to a `should'-like syntax.
13
+
14
+ Consider this Test::Unit test case:
15
+
16
+ class TestFoo < Test::Unit::TestCase
17
+ def test_should_bar
18
+ assert_equal 5, 2 + 3
19
+ end
20
+ end
21
+
22
+ In test/spec, it looks like this:
23
+
24
+ require 'test/spec'
25
+
26
+ context "Foo" do
27
+ specify "should bar" do
28
+ (2 + 3).should.equal 5
29
+ end
30
+ end
31
+
32
+ Since test/spec 0.4, you can also use the new RSpec 1.0 style:
33
+
34
+ require 'test/spec'
35
+
36
+ describe "Foo" do
37
+ it "should bar" do
38
+ (2 + 3).should.equal 5
39
+ end
40
+ end
41
+
42
+ test/spec does not include a mocking/stubbing-framework; use whichever
43
+ you like to. test/spec has been tested successfully with FlexMock and
44
+ Mocha.
45
+
46
+ test/spec has no dependencies outside Ruby 1.8.
47
+
48
+
49
+ == Mixing test/spec and test/unit
50
+
51
+ test/spec and Test::Unit contexts/test cases can be intermixed freely,
52
+ run in the same test and live in the same files. You can just add them
53
+ to your Rake::TestTask, too. test/spec allows you to leverage your
54
+ full existing Test::Unit infrastructure.
55
+
56
+ test/spec does not change Test::Unit with the exception of
57
+ monkey-patching Test::Unit::TestSuite to order the test cases before
58
+ running them. (This should not do any harm, but if you know a way
59
+ around it, please tell me.)
60
+
61
+ test/spec adds seven global methods, Object#should, Kernel.context,
62
+ Kernel.xcontext, Kernel.shared_context, Kernel.describe,
63
+ Kernel.xdescribe, and Kernel.describe_shared. The Kernel methods are
64
+ private.
65
+
66
+ You can use <tt>assert_*</tt> freely in specify-blocks; Object#should
67
+ works in plain Test::Unit test cases, too, but they will not be counted.
68
+
69
+
70
+ == Wrapped assertions
71
+
72
+ +assert_equal+:: <tt>should.equal</tt>, <tt>should ==</tt>
73
+ +assert_not_equal+:: <tt>should.not.equal</tt>, <tt>should.not ==</tt>
74
+ +assert_same+:: <tt>should.be</tt>
75
+ +assert_not_same+:: <tt>should.not.be</tt>
76
+ +assert_nil+:: <tt>should.be.nil</tt>
77
+ +assert_not_nil+:: <tt>should.not.be.nil</tt>
78
+ +assert_in_delta+:: <tt>should.be.close</tt>
79
+ +assert_match+:: <tt>should.match</tt>, <tt>should =~</tt>
80
+ +assert_no_match+:: <tt>should.not.match</tt>, <tt>should.not =~</tt>
81
+
82
+ +assert_instance_of+:: <tt>should.be.an.instance_of</tt>
83
+ +assert_kind_of+:: <tt>should.be.a.kind_of</tt>
84
+ +assert_respond_to+:: <tt>should.respond_to</tt>
85
+ +assert_raise+:: <tt>should.raise</tt>
86
+ +assert_nothing_raised+:: <tt>should.not.raise</tt>
87
+ +assert_throws+:: <tt>should.throw</tt>
88
+ +assert_nothing_thrown+:: <tt>should.not.throw</tt>
89
+
90
+ +assert_block+:: <tt>should.satisfy</tt>
91
+
92
+ (+a+, +an+ and +be+ without arguments are optional and no-ops.)
93
+
94
+
95
+ == Additional assertions
96
+
97
+ These assertions are not included in Test::Unit, but have been added
98
+ to test/spec for convenience:
99
+
100
+ * <tt>should.not.satisfy</tt>
101
+ * <tt>should.include</tt>
102
+ * <tt>a.should.</tt>_predicate_ (works like <tt>assert
103
+ a.</tt>_predicate_<tt>?</tt>)
104
+ * <tt>a.should.be </tt>_operator_ (where _operator_ is one of <tt>></tt>, <tt>>=</tt>, <tt><</tt>, <tt><=</tt> or <tt>===</tt>)
105
+ * <tt>should.output</tt> (require test/spec/should-output)
106
+
107
+ If you write an useful general-purpose assertion, I'd like to hear of
108
+ it and may add it to the test/spec distribution.
109
+
110
+
111
+ == Messaging/Blaming
112
+
113
+ With more complex assertions, it may be helpful to provide a message
114
+ to show if the assertion has failed. This can be done with the
115
+ Should#blaming or Should#messaging methods:
116
+
117
+ RUBY_VERSION.should.messaging("Ruby too old.").be > "1.8.4"
118
+
119
+ (1 + 1).should.blaming("weird math").not.equal 11
120
+
121
+
122
+ == Custom shoulds ("Matchers")
123
+
124
+ To capture recurring patterns in parts of your specifications, you can
125
+ define custom "shoulds" (RSpec calls them "matchers") in your
126
+ contexts, or include modules of them:
127
+
128
+ context "Numbers"
129
+ class EqualString < Test::Spec::CustomShould
130
+ def matches?(other)
131
+ object == other.to_s
132
+ end
133
+ end
134
+
135
+ def equal_string(str)
136
+ EqualString.new(str)
137
+ end
138
+
139
+ specify "should have to_s"
140
+ 42.should equal_string("42")
141
+ end
142
+ end
143
+
144
+ Alternatively, your implementation can define
145
+ CustomShould#assumptions, where you can use test/spec assertions
146
+ instead of Boolean predicates:
147
+
148
+ class EqualString < Test::Spec::CustomShould
149
+ def assumptions(other)
150
+ object.should.equal other.to_s
151
+ end
152
+ end
153
+
154
+ A CustomShould by default takes one argument, which is placed in
155
+ self.object for your convenience.
156
+
157
+ You can CustomShould#failure_message to provide a better error
158
+ message.
159
+
160
+
161
+ == SpecDox and RDox
162
+
163
+ test/spec adds two additional test runners to Test::Unit, based on the
164
+ console runner but with a different output format.
165
+
166
+ SpecDox, run with <tt>--runner=specdox</tt> (or <tt>-rs</tt>) looks
167
+ like RSpec's output:
168
+
169
+ should.output
170
+ - works for print
171
+ - works for puts
172
+ - works with readline
173
+
174
+ RDox, run with <tt>--runner=rdox</tt> (or <tt>-rr</tt>) can be
175
+ included for RDoc documentation (e.g. see SPECS):
176
+
177
+ == should.output
178
+ * works for print
179
+ * works for puts
180
+ * works with readline
181
+
182
+ SpecDox and RDox work for Test::Unit too:
183
+
184
+ $ ruby -r test/spec test/testunit/test_testresult.rb -rs
185
+
186
+ Test::Unit::TC_TestResult
187
+ - fault notification
188
+ - passed?
189
+ - result changed notification
190
+
191
+ Finished in 0.106647 seconds.
192
+
193
+ 3 specifications (30 requirements), 0 failures
194
+
195
+ Since version 0.4, SpecDox and RDox also notice and count empty
196
+ specifications.
197
+
198
+
199
+ == Disabled specifications
200
+
201
+ Akin to the usual Test::Unit practice, tests quickly can be disabled
202
+ by replacing +specify+ with +xspecify+ (or +it+ with +xit+).
203
+ test/spec will count the disabled tests when you run it with SpecDox
204
+ or RDox.
205
+
206
+ When you use xspecify/xit, you also can drop the block. This is
207
+ useful for writing specifications that you haven't yet started
208
+ implementing.
209
+
210
+ Complete contexts can be disabled by using +xcontext+/+xdescribe+.
211
+
212
+
213
+ == Setup/Teardown
214
+
215
+ Setup/Teardown methods are run in this order:
216
+
217
+ * before(:all) in order of definition
218
+ * before(:each)/setup in order of definition
219
+ * specify
220
+ * after(:each)/setup in order of definition
221
+ * before(:each)/setup in order of definition
222
+ * specify
223
+ * after(:each)/setup in order of definition
224
+ * ...
225
+ * after(:all) in order of definition
226
+
227
+ Please note that before(:all) and after(:all) are run in their own
228
+ instance, so all instance variables they set are lost(!) and not
229
+ visible to other specifications. They are e.g. useful for setting up
230
+ database connections or starting servers.
231
+
232
+
233
+ == Shared contexts
234
+
235
+ Since version 0.9, you can define shared contexts in test/spec using
236
+ shared_context/describe_shared. These contexts are not executed on
237
+ their own, but can be included with it_should_behave_like/behaves_like
238
+ in other contexts. You can use shared contexts to structure suites
239
+ with many recurring specifications.
240
+
241
+
242
+ == specrb
243
+
244
+ Since version 0.2, test/spec features a standalone test runner called
245
+ specrb. specrb is like an extended version of testrb, Test::Unit's
246
+ test runner, but has additional options. It can be used for
247
+ plain Test::Unit suites, too.
248
+
249
+ $ specrb -a -s -n should.output
250
+
251
+ should.output
252
+ - works for print
253
+ - works for puts
254
+ - works with readline
255
+
256
+ Finished in 0.162571 seconds.
257
+
258
+ 3 specifications (6 requirements), 0 failures
259
+
260
+ Run <tt>specrb --help</tt> for the usage.
261
+
262
+
263
+ == test/spec on Rails
264
+
265
+ If you want to specify your Rails applications, you can use the third-party
266
+ plugin "test/spec on Rails", which can be found at:
267
+
268
+ http://svn.techno-weenie.net/projects/plugins/test_spec_on_rails/
269
+
270
+ It features testing of model validation, redirection, output, HTTP
271
+ status, template rendering and URL generation.
272
+
273
+
274
+ == Installing with RubyGems
275
+
276
+ Since version 0.3, a Gem of test/spec is available. You can install with:
277
+
278
+ gem install test-spec
279
+
280
+ I also provide a local mirror of the gems (and development snapshots)
281
+ at my site:
282
+
283
+ gem install test-spec --source http://chneukirchen.org/releases/gems
284
+
285
+
286
+ == History
287
+
288
+ * September 29th, 2006: First public release 0.1.
289
+
290
+ * October 18th, 2006: Second public release 0.2.
291
+ * Better, module-based implementation
292
+ * Official support for FlexMock and Mocha
293
+ * More robust Should#output
294
+ * Should#_operator_
295
+ * Nested contexts
296
+ * Standalone test/spec runner, specrb
297
+
298
+ * January 24th, 2007: Third public release 0.3.
299
+ * should.be_close, should.be_an_instance_of, should.be_a_kind_of,
300
+ and should.be_nil have been deprecated. Use the dot-variants of
301
+ them. These assertions will be removed in 1.0.
302
+ * specrb -a now includes -Ilib by default for easier out-of-the-box
303
+ testing.
304
+ * Added custom shoulds.
305
+ * Added messaging/blaming.
306
+ * Added disabling of specifications.
307
+ * Small bug fixes.
308
+ * Gem available.
309
+
310
+ * June 29th, 2007: Fourth public release 0.4.
311
+ * Support for Ruby 1.8.6.
312
+ * Support describe/it/before/after RSpec 1.0 syntax.
313
+ * Allow should.raise { code_that_raises }
314
+ * Add xcontext to disable complete contexts.
315
+ * Backtraces are cleaner now.
316
+ * Mention test/spec on Rails.
317
+ * Fix small Gem bugs.
318
+ * Fix bug related to counting negated assertions.
319
+ * Fix bug in specrb.
320
+ * Allow empty xspecifys.
321
+ * Make SpecDox and RDox count empty specifications.
322
+ * Allow Kernel#context to take a superclass.
323
+
324
+ * July 2nd, 2008: Fifth public release 0.9.
325
+ * Allow should.<predicate>? as well as should.<predicate>.
326
+ * Add shared contexts.
327
+ * Nested contexts now run the
328
+ setups/teardowns/before(:all)/after(:all) of their parents.
329
+
330
+
331
+ == Contact
332
+
333
+ Please mail bugs, suggestions and patches to
334
+ <mailto:chneukirchen@gmail.com>.
335
+
336
+ Darcs repository ("darcs send" is welcome for patches):
337
+ http://chneukirchen.org/repos/testspec
338
+
339
+
340
+ == Thanks to
341
+
342
+ * Eero Saynatkari for writing <tt>should.output</tt>.
343
+ * Tuxie for writing test/spec on Rails.
344
+ * Brian Donovan for allowing alternative superclasses.
345
+ * Xavier Shay for implementing nested setups/teardowns.
346
+ * Chris Wanstrath for <tt>should.raise</tt> with a block and <tt>xcontext</tt>.
347
+ * Jean-Michel Garnier for packaging the first gem.
348
+ * Mikko Lehtonen, Jan Wikholm, Matt Mower and Michael Fellinger for
349
+ testing the gem.
350
+ * Chris McGrath for reporting a bug.
351
+ * Thomas Fuchs for script.aculo.us BDD testing which convinced me.
352
+ * Dave Astels for BDD.
353
+ * The RSpec team for API inspiration.
354
+ * Nathaniel Talbott for Test::Unit.
355
+
356
+
357
+ == Copying
358
+
359
+ Copyright (C) 2006, 2007, 2008 Christian Neukirchen <http://purl.org/net/chneukirchen>
360
+
361
+ test/spec is licensed under the same terms as Ruby itself.
362
+
363
+ Please mail bugs, feature requests or patches to the mail addresses
364
+ found above or use IRC[irc://freenode.net/#ruby-lang] to contact the
365
+ developer.
366
+
367
+
368
+ == Links
369
+
370
+ Behavior-Driven Development:: <http://behaviour-driven.org/>
371
+ RSpec:: <http://rspec.rubyforge.org/>
372
+ script.aculo.us testing:: <http://mir.aculo.us/articles/2006/08/29/bdd-style-javascript-testing>
373
+
374
+ FlexMock:: <http://onestepback.org/software/flexmock/>
375
+ Mocha:: <http://mocha.rubyforge.org/>
376
+
377
+ Christian Neukirchen:: <http://chneukirchen.org/>
378
+