activeldap 1.2.0 → 1.2.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.
Files changed (68) hide show
  1. data/CHANGES +11 -0
  2. data/README +6 -3
  3. data/Rakefile +6 -6
  4. data/examples/al-admin/config/environment.rb +3 -3
  5. data/examples/groupadd +1 -1
  6. data/examples/groupdel +1 -1
  7. data/examples/groupls +1 -1
  8. data/examples/groupmod +1 -1
  9. data/examples/lpasswd +1 -1
  10. data/examples/ouadd +1 -1
  11. data/examples/useradd +1 -1
  12. data/examples/useradd-binary +1 -1
  13. data/examples/userdel +1 -1
  14. data/examples/userls +1 -1
  15. data/examples/usermod +1 -1
  16. data/examples/usermod-binary-add +1 -1
  17. data/examples/usermod-binary-add-time +1 -1
  18. data/examples/usermod-binary-del +1 -1
  19. data/examples/usermod-lang-add +1 -1
  20. data/lib/active_ldap.rb +6 -6
  21. data/lib/active_ldap/adapter/base.rb +14 -1
  22. data/lib/active_ldap/adapter/jndi.rb +5 -1
  23. data/lib/active_ldap/adapter/net_ldap.rb +7 -1
  24. data/lib/active_ldap/association/belongs_to_many.rb +4 -0
  25. data/lib/active_ldap/association/has_many.rb +5 -5
  26. data/lib/active_ldap/association/has_many_utils.rb +5 -6
  27. data/lib/active_ldap/association/has_many_wrap.rb +13 -9
  28. data/lib/active_ldap/association/proxy.rb +5 -1
  29. data/lib/active_ldap/associations.rb +1 -1
  30. data/lib/active_ldap/attributes.rb +7 -3
  31. data/lib/active_ldap/base.rb +16 -2
  32. data/lib/active_ldap/distinguished_name.rb +3 -6
  33. data/lib/active_ldap/operations.rb +11 -8
  34. data/lib/active_ldap/timeout_stub.rb +1 -1
  35. data/lib/active_ldap/xml.rb +5 -2
  36. data/test-unit/History.txt +54 -0
  37. data/test-unit/Manifest.txt +3 -3
  38. data/test-unit/README.txt +4 -1
  39. data/test-unit/images/color-diff.png +0 -0
  40. data/test-unit/lib/test/unit.rb +23 -42
  41. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  42. data/test-unit/lib/test/unit/assertions.rb +77 -8
  43. data/test-unit/lib/test/unit/autorunner.rb +13 -2
  44. data/test-unit/lib/test/unit/collector/load.rb +2 -3
  45. data/test-unit/lib/test/unit/color-scheme.rb +13 -1
  46. data/test-unit/lib/test/unit/diff.rb +223 -37
  47. data/test-unit/lib/test/unit/failure.rb +27 -5
  48. data/test-unit/lib/test/unit/omission.rb +47 -3
  49. data/test-unit/lib/test/unit/testcase.rb +42 -0
  50. data/test-unit/lib/test/unit/ui/console/testrunner.rb +189 -3
  51. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  52. data/test-unit/lib/test/unit/ui/testrunner.rb +8 -0
  53. data/test-unit/lib/test/unit/version.rb +1 -1
  54. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  55. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  56. data/test-unit/sample/test_user.rb +1 -0
  57. data/test-unit/test/run-test.rb +2 -0
  58. data/test-unit/test/test-color-scheme.rb +7 -0
  59. data/test-unit/test/test-diff.rb +48 -7
  60. data/test-unit/test/test-omission.rb +1 -1
  61. data/test-unit/test/test-testcase.rb +27 -0
  62. data/test-unit/test/test_assertions.rb +43 -10
  63. data/test/al-test-utils.rb +15 -0
  64. data/test/test_associations.rb +46 -1
  65. data/test/test_attributes.rb +43 -20
  66. data/test/test_base.rb +60 -3
  67. metadata +12 -12
  68. data/test-unit/sample/ts_examples.rb +0 -7
@@ -18,6 +18,15 @@ module Test
18
18
  RUNNERS[id.to_s]
19
19
  end
20
20
 
21
+ @@default_runner = nil
22
+ def default_runner
23
+ runner(@@default_runner)
24
+ end
25
+
26
+ def default_runner=(id)
27
+ @@default_runner = id
28
+ end
29
+
21
30
  def register_collector(id, collector_builder=Proc.new)
22
31
  COLLECTORS[id] = collector_builder
23
32
  COLLECTORS[id.to_s] = collector_builder
@@ -325,11 +334,13 @@ module Test
325
334
 
326
335
  private
327
336
  def default_runner
337
+ runner = self.class.default_runner
328
338
  if ENV["EMACS"] == "t"
329
- self.class.runner(:emacs)
339
+ runner ||= self.class.runner(:emacs)
330
340
  else
331
- self.class.runner(:console)
341
+ runner ||= self.class.runner(:console)
332
342
  end
343
+ runner
333
344
  end
334
345
 
335
346
  def default_collector
@@ -29,7 +29,7 @@ module Test
29
29
  add_load_path(@base) do
30
30
  froms = ["."] if froms.empty?
31
31
  test_suites = froms.collect do |from|
32
- test_suite = collect_recursive(from, find_test_cases)
32
+ test_suite = collect_recursive(resolve_path(from), find_test_cases)
33
33
  test_suite = nil if test_suite.tests.empty?
34
34
  test_suite
35
35
  end.compact
@@ -56,10 +56,9 @@ module Test
56
56
  end
57
57
 
58
58
  private
59
- def collect_recursive(name, already_gathered)
59
+ def collect_recursive(path, already_gathered)
60
60
  sub_test_suites = []
61
61
 
62
- path = resolve_path(name)
63
62
  if path.directory?
64
63
  directories, files = path.children.partition do |child|
65
64
  child.directory?
@@ -18,7 +18,19 @@ module Test
18
18
  "case" => Color.new("white", :bold => true) +
19
19
  Color.new("blue", :foreground => false),
20
20
  "suite" => Color.new("white", :bold => true) +
21
- Color.new("green", :foreground => false))
21
+ Color.new("green", :foreground => false),
22
+ "diff-inserted-tag" =>
23
+ Color.new("red", :bold => true),
24
+ "diff-deleted-tag" =>
25
+ Color.new("green", :bold => true),
26
+ "diff-difference-tag" =>
27
+ Color.new("cyan", :bold => true),
28
+ "diff-inserted" =>
29
+ Color.new("red", :foreground => false) +
30
+ Color.new("white", :bold => true),
31
+ "diff-deleted" =>
32
+ Color.new("green", :foreground => false) +
33
+ Color.new("white", :bold => true))
22
34
  end
23
35
 
24
36
  @@schemes = {}
@@ -35,7 +35,7 @@ module Test
35
35
 
36
36
  def grouped_operations(context_size=nil)
37
37
  context_size ||= 3
38
- _operations = operations
38
+ _operations = operations.dup
39
39
  _operations = [[:equal, 0, 0, 0, 0]] if _operations.empty?
40
40
  expand_edge_equal_operations!(_operations, context_size)
41
41
 
@@ -266,29 +266,187 @@ module Test
266
266
  end
267
267
  end
268
268
 
269
+ class UTF8Line
270
+ class << self
271
+ # from http://unicode.org/reports/tr11/
272
+ WIDE_CHARACTERS =
273
+ [0x1100..0x1159, 0x115F..0x115F, 0x2329..0x232A,
274
+ 0x2E80..0x2E99, 0x2E9B..0x2EF3, 0x2F00..0x2FD5,
275
+ 0x2FF0..0x2FFB, 0x3000..0x303E, 0x3041..0x3096,
276
+ 0x3099..0x30FF, 0x3105..0x312D, 0x3131..0x318E,
277
+ 0x3190..0x31B7, 0x31C0..0x31E3, 0x31F0..0x321E,
278
+ 0x3220..0x3243, 0x3250..0x32FE, 0x3300..0x4DB5,
279
+ 0x4E00..0x9FC3, 0xA000..0xA48C, 0xA490..0xA4C6,
280
+ 0xAC00..0xD7A3, 0xF900..0xFA2D, 0xFA30..0xFA6A,
281
+ 0xFA70..0xFAD9, 0xFE10..0xFE19, 0xFE30..0xFE52,
282
+ 0xFE54..0xFE66, 0xFE68..0xFE6B, 0xFF01..0xFF60,
283
+ 0xFFE0..0xFFE6, 0x20000..0x2FFFD, 0x30000..0x3FFFD,
284
+ ]
285
+
286
+ AMBIGUOUS =
287
+ [0x00A1..0x00A1, 0x00A4..0x00A4, 0x00A7..0x00A8,
288
+ 0x00AA..0x00AA, 0x00AD..0x00AE, 0x00B0..0x00B4,
289
+ 0x00B6..0x00BA, 0x00BC..0x00BF, 0x00C6..0x00C6,
290
+ 0x00D0..0x00D0, 0x00D7..0x00D8, 0x00DE..0x00E1,
291
+ 0x00E6..0x00E6, 0x00E8..0x00EA, 0x00EC..0x00ED,
292
+ 0x00F0..0x00F0, 0x00F2..0x00F3, 0x00F7..0x00FA,
293
+ 0x00FC..0x00FC, 0x00FE..0x00FE, 0x0101..0x0101,
294
+ 0x0111..0x0111, 0x0113..0x0113, 0x011B..0x011B,
295
+ 0x0126..0x0127, 0x012B..0x012B, 0x0131..0x0133,
296
+ 0x0138..0x0138, 0x013F..0x0142, 0x0144..0x0144,
297
+ 0x0148..0x014B, 0x014D..0x014D, 0x0152..0x0153,
298
+ 0x0166..0x0167, 0x016B..0x016B, 0x01CE..0x01CE,
299
+ 0x01D0..0x01D0, 0x01D2..0x01D2, 0x01D4..0x01D4,
300
+ 0x01D6..0x01D6, 0x01D8..0x01D8, 0x01DA..0x01DA,
301
+ 0x01DC..0x01DC, 0x0251..0x0251, 0x0261..0x0261,
302
+ 0x02C4..0x02C4, 0x02C7..0x02C7, 0x02C9..0x02CB,
303
+ 0x02CD..0x02CD, 0x02D0..0x02D0, 0x02D8..0x02DB,
304
+ 0x02DD..0x02DD, 0x02DF..0x02DF, 0x0300..0x036F,
305
+ 0x0391..0x03A1, 0x03A3..0x03A9, 0x03B1..0x03C1,
306
+ 0x03C3..0x03C9, 0x0401..0x0401, 0x0410..0x044F,
307
+ 0x0451..0x0451, 0x2010..0x2010, 0x2013..0x2016,
308
+ 0x2018..0x2019, 0x201C..0x201D, 0x2020..0x2022,
309
+ 0x2024..0x2027, 0x2030..0x2030, 0x2032..0x2033,
310
+ 0x2035..0x2035, 0x203B..0x203B, 0x203E..0x203E,
311
+ 0x2074..0x2074, 0x207F..0x207F, 0x2081..0x2084,
312
+ 0x20AC..0x20AC, 0x2103..0x2103, 0x2105..0x2105,
313
+ 0x2109..0x2109, 0x2113..0x2113, 0x2116..0x2116,
314
+ 0x2121..0x2122, 0x2126..0x2126, 0x212B..0x212B,
315
+ 0x2153..0x2154, 0x215B..0x215E, 0x2160..0x216B,
316
+ 0x2170..0x2179, 0x2190..0x2199, 0x21B8..0x21B9,
317
+ 0x21D2..0x21D2, 0x21D4..0x21D4, 0x21E7..0x21E7,
318
+ 0x2200..0x2200, 0x2202..0x2203, 0x2207..0x2208,
319
+ 0x220B..0x220B, 0x220F..0x220F, 0x2211..0x2211,
320
+ 0x2215..0x2215, 0x221A..0x221A, 0x221D..0x2220,
321
+ 0x2223..0x2223, 0x2225..0x2225, 0x2227..0x222C,
322
+ 0x222E..0x222E, 0x2234..0x2237, 0x223C..0x223D,
323
+ 0x2248..0x2248, 0x224C..0x224C, 0x2252..0x2252,
324
+ 0x2260..0x2261, 0x2264..0x2267, 0x226A..0x226B,
325
+ 0x226E..0x226F, 0x2282..0x2283, 0x2286..0x2287,
326
+ 0x2295..0x2295, 0x2299..0x2299, 0x22A5..0x22A5,
327
+ 0x22BF..0x22BF, 0x2312..0x2312, 0x2460..0x24E9,
328
+ 0x24EB..0x254B, 0x2550..0x2573, 0x2580..0x258F,
329
+ 0x2592..0x2595, 0x25A0..0x25A1, 0x25A3..0x25A9,
330
+ 0x25B2..0x25B3, 0x25B6..0x25B7, 0x25BC..0x25BD,
331
+ 0x25C0..0x25C1, 0x25C6..0x25C8, 0x25CB..0x25CB,
332
+ 0x25CE..0x25D1, 0x25E2..0x25E5, 0x25EF..0x25EF,
333
+ 0x2605..0x2606, 0x2609..0x2609, 0x260E..0x260F,
334
+ 0x2614..0x2615, 0x261C..0x261C, 0x261E..0x261E,
335
+ 0x2640..0x2640, 0x2642..0x2642, 0x2660..0x2661,
336
+ 0x2663..0x2665, 0x2667..0x266A, 0x266C..0x266D,
337
+ 0x266F..0x266F, 0x273D..0x273D, 0x2776..0x277F,
338
+ 0xE000..0xF8FF, 0xFE00..0xFE0F, 0xFFFD..0xFFFD,
339
+ 0xE0100..0xE01EF, 0xF0000..0xFFFFD, 0x100000..0x10FFFD,
340
+ ]
341
+
342
+ def wide_character?(character)
343
+ binary_search_ranges(character, WIDE_CHARACTERS) or
344
+ binary_search_ranges(character, AMBIGUOUS)
345
+ end
346
+
347
+ private
348
+ def binary_search_ranges(character, ranges)
349
+ if ranges.size.zero?
350
+ false
351
+ elsif ranges.size == 1
352
+ ranges[0].include?(character)
353
+ else
354
+ half = ranges.size / 2
355
+ range = ranges[half]
356
+ if range.include?(character)
357
+ true
358
+ elsif character < range.begin
359
+ binary_search_ranges(character, ranges[0...half])
360
+ else
361
+ binary_search_ranges(character, ranges[(half + 1)..-1])
362
+ end
363
+ end
364
+ end
365
+ end
366
+
367
+ def initialize(line)
368
+ @line = line
369
+ @characters = @line.unpack("U*")
370
+ end
371
+
372
+ def [](*args)
373
+ result = @characters[*args]
374
+ if result.respond_to?(:pack)
375
+ result.pack("U*")
376
+ else
377
+ result
378
+ end
379
+ end
380
+
381
+ def each(&block)
382
+ @characters.each(&block)
383
+ end
384
+
385
+ def size
386
+ @characters.size
387
+ end
388
+
389
+ def to_s
390
+ @line
391
+ end
392
+
393
+ def compute_width(start, _end)
394
+ width = 0
395
+ start.upto(_end - 1) do |i|
396
+ if self.class.wide_character?(@characters[i])
397
+ width += 2
398
+ else
399
+ width += 1
400
+ end
401
+ end
402
+ width
403
+ end
404
+ end
405
+
269
406
  class ReadableDiffer < Differ
270
407
  def diff(options={})
271
- result = []
272
- matcher = SequenceMatcher.new(@from, @to)
273
- matcher.operations.each do |args|
274
- tag, from_start, from_end, to_start, to_end = args
408
+ @result = []
409
+ operations.each do |tag, from_start, from_end, to_start, to_end|
275
410
  case tag
276
411
  when :replace
277
- result.concat(diff_lines(from_start, from_end, to_start, to_end))
412
+ diff_lines(from_start, from_end, to_start, to_end)
278
413
  when :delete
279
- result.concat(tag_deleted(@from[from_start...from_end]))
414
+ tag_deleted(@from[from_start...from_end])
280
415
  when :insert
281
- result.concat(tag_inserted(@to[to_start...to_end]))
416
+ tag_inserted(@to[to_start...to_end])
282
417
  when :equal
283
- result.concat(tag_equal(@from[from_start...from_end]))
418
+ tag_equal(@from[from_start...from_end])
284
419
  else
285
420
  raise "unknown tag: #{tag}"
286
421
  end
287
422
  end
288
- result
423
+ @result
289
424
  end
290
425
 
291
426
  private
427
+ def operations
428
+ @operations ||= nil
429
+ if @operations.nil?
430
+ matcher = SequenceMatcher.new(@from, @to)
431
+ @operations = matcher.operations
432
+ end
433
+ @operations
434
+ end
435
+
436
+ def default_ratio
437
+ 0.74
438
+ end
439
+
440
+ def cut_off_ratio
441
+ 0.75
442
+ end
443
+
444
+ def tag(mark, contents)
445
+ contents.each do |content|
446
+ @result << "#{mark}#{content}"
447
+ end
448
+ end
449
+
292
450
  def tag_deleted(contents)
293
451
  tag("- ", contents)
294
452
  end
@@ -306,7 +464,7 @@ module Test
306
464
  end
307
465
 
308
466
  def find_diff_line_info(from_start, from_end, to_start, to_end)
309
- best_ratio = 0.74
467
+ best_ratio = default_ratio
310
468
  from_equal_index = to_equal_index = nil
311
469
  from_best_index = to_best_index = nil
312
470
 
@@ -334,30 +492,31 @@ module Test
334
492
  end
335
493
 
336
494
  def diff_lines(from_start, from_end, to_start, to_end)
337
- cut_off = 0.75
338
-
339
495
  info = find_diff_line_info(from_start, from_end, to_start, to_end)
340
496
  best_ratio, from_equal_index, to_equal_index, *info = info
341
497
  from_best_index, to_best_index = info
498
+ from_best_index ||= from_start
499
+ to_best_index ||= to_start
342
500
 
343
- if best_ratio < cut_off
501
+ if best_ratio < cut_off_ratio
344
502
  if from_equal_index.nil?
345
- tagged_from = tag_deleted(@from[from_start...from_end])
346
- tagged_to = tag_inserted(@to[to_start...to_end])
347
503
  if to_end - to_start < from_end - from_start
348
- return tagged_to + tagged_from
504
+ tag_inserted(@to[to_start...to_end])
505
+ tag_deleted(@from[from_start...from_end])
349
506
  else
350
- return tagged_from + tagged_to
507
+ tag_deleted(@from[from_start...from_end])
508
+ tag_inserted(@to[to_start...to_end])
351
509
  end
510
+ return
352
511
  end
353
512
  from_best_index = from_equal_index
354
513
  to_best_index = to_equal_index
355
514
  best_ratio = 1.0
356
515
  end
357
516
 
358
- _diff_lines(from_start, from_best_index, to_start, to_best_index) +
359
- diff_line(@from[from_best_index], @to[to_best_index]) +
360
- _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end)
517
+ _diff_lines(from_start, from_best_index, to_start, to_best_index)
518
+ diff_line(@from[from_best_index], @to[to_best_index])
519
+ _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end)
361
520
  end
362
521
 
363
522
  def _diff_lines(from_start, from_end, to_start, to_end)
@@ -372,26 +531,54 @@ module Test
372
531
  end
373
532
  end
374
533
 
534
+ def line_operations(from_line, to_line)
535
+ if !from_line.respond_to?(:force_encoding) and $KCODE == "UTF8"
536
+ from_line = UTF8Line.new(from_line)
537
+ to_line = UTF8Line.new(to_line)
538
+ end
539
+ matcher = SequenceMatcher.new(from_line, to_line,
540
+ &method(:space_character?))
541
+ [from_line, to_line, matcher.operations]
542
+ end
543
+
544
+ def compute_width(line, start, _end)
545
+ if line.respond_to?(:encoding) and
546
+ Encoding.compatible?(Encoding::UTF_8, line.encoding)
547
+ utf8_line = line[start..._end].encode(Encoding::UTF_8)
548
+ width = 0
549
+ utf8_line.each_codepoint do |unicode_codepoint|
550
+ if UTF8Line.wide_character?(unicode_codepoint)
551
+ width += 2
552
+ else
553
+ width += 1
554
+ end
555
+ end
556
+ width
557
+ elsif line.is_a?(UTF8Line)
558
+ line.compute_width(start, _end)
559
+ else
560
+ _end - start
561
+ end
562
+ end
563
+
375
564
  def diff_line(from_line, to_line)
376
565
  from_tags = ""
377
566
  to_tags = ""
378
- matcher = SequenceMatcher.new(from_line, to_line,
379
- &method(:space_character?))
380
- operations = matcher.operations
381
- operations.each do |tag, from_start, from_end, to_start, to_end|
382
- from_length = from_end - from_start
383
- to_length = to_end - to_start
567
+ from_line, to_line, _operations = line_operations(from_line, to_line)
568
+ _operations.each do |tag, from_start, from_end, to_start, to_end|
569
+ from_width = compute_width(from_line, from_start, from_end)
570
+ to_width = compute_width(to_line, to_start, to_end)
384
571
  case tag
385
572
  when :replace
386
- from_tags << "^" * from_length
387
- to_tags << "^" * to_length
573
+ from_tags << "^" * from_width
574
+ to_tags << "^" * to_width
388
575
  when :delete
389
- from_tags << "-" * from_length
576
+ from_tags << "-" * from_width
390
577
  when :insert
391
- to_tags << "+" * to_length
578
+ to_tags << "+" * to_width
392
579
  when :equal
393
- from_tags << " " * from_length
394
- to_tags << " " * to_length
580
+ from_tags << " " * from_width
581
+ to_tags << " " * to_width
395
582
  else
396
583
  raise "unknown tag: #{tag}"
397
584
  end
@@ -409,13 +596,12 @@ module Test
409
596
 
410
597
  result = tag_deleted([from_line])
411
598
  unless from_tags.empty?
412
- result.concat(tag_difference(["#{"\t" * common}#{from_tags}"]))
599
+ tag_difference(["#{"\t" * common}#{from_tags}"])
413
600
  end
414
- result.concat(tag_inserted([to_line]))
601
+ tag_inserted([to_line])
415
602
  unless to_tags.empty?
416
- result.concat(tag_difference(["#{"\t" * common}#{to_tags}"]))
603
+ tag_difference(["#{"\t" * common}#{to_tags}"])
417
604
  end
418
- result
419
605
  end
420
606
 
421
607
  def n_leading_characters(string, character)
@@ -11,16 +11,23 @@ module Test
11
11
  # when an assertion fails.
12
12
  class Failure
13
13
  attr_reader :test_name, :location, :message
14
-
14
+ attr_reader :expected, :actual, :user_message
15
+ attr_reader :inspected_expected, :inspected_actual
16
+
15
17
  SINGLE_CHARACTER = 'F'
16
18
  LABEL = "Failure"
17
19
 
18
20
  # Creates a new Failure with the given location and
19
21
  # message.
20
- def initialize(test_name, location, message)
22
+ def initialize(test_name, location, message, options={})
21
23
  @test_name = test_name
22
24
  @location = location
23
25
  @message = message
26
+ @expected = options[:expected]
27
+ @actual = options[:actual]
28
+ @inspected_expected = options[:inspected_expected]
29
+ @inspected_actual = options[:inspected_actual]
30
+ @user_message = options[:user_message]
24
31
  end
25
32
 
26
33
  # Returns a single character representation of a failure.
@@ -51,6 +58,15 @@ module Test
51
58
  def to_s
52
59
  long_display
53
60
  end
61
+
62
+ def diff
63
+ @diff ||= compute_diff
64
+ end
65
+
66
+ private
67
+ def compute_diff
68
+ Assertions::AssertionMessage.delayed_diff(@expected, @actual).inspect
69
+ end
54
70
  end
55
71
 
56
72
  module FailureHandler
@@ -64,12 +80,18 @@ module Test
64
80
  def handle_assertion_failed_error(exception)
65
81
  return false unless exception.is_a?(AssertionFailedError)
66
82
  problem_occurred
67
- add_failure(exception.message, exception.backtrace)
83
+ add_failure(exception.message, exception.backtrace,
84
+ :expected => exception.expected,
85
+ :actual => exception.actual,
86
+ :inspected_expected => exception.inspected_expected,
87
+ :inspected_actual => exception.inspected_actual,
88
+ :user_message => exception.user_message)
68
89
  true
69
90
  end
70
91
 
71
- def add_failure(message, backtrace)
72
- failure = Failure.new(name, filter_backtrace(backtrace), message)
92
+ def add_failure(message, backtrace, options={})
93
+ failure = Failure.new(name, filter_backtrace(backtrace), message,
94
+ options)
73
95
  current_result.add_failure(failure)
74
96
  end
75
97
  end