wrong 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README.markdown +114 -25
  2. data/lib/predicated/Gemfile +15 -0
  3. data/lib/predicated/LICENSE +20 -0
  4. data/lib/predicated/README.markdown +191 -0
  5. data/lib/predicated/Rakefile +51 -0
  6. data/lib/predicated/lib/predicated.rb +4 -0
  7. data/lib/predicated/lib/predicated/autogen_call.rb +37 -0
  8. data/lib/predicated/lib/predicated/constrain.rb +66 -0
  9. data/lib/predicated/lib/predicated/evaluate.rb +94 -0
  10. data/lib/predicated/lib/predicated/from/callable_object.rb +108 -0
  11. data/lib/predicated/lib/predicated/from/json.rb +59 -0
  12. data/lib/predicated/lib/predicated/from/ruby_code_string.rb +73 -0
  13. data/lib/predicated/lib/predicated/from/url_part.rb +104 -0
  14. data/lib/predicated/lib/predicated/from/xml.rb +61 -0
  15. data/lib/predicated/lib/predicated/gem_check.rb +34 -0
  16. data/lib/predicated/lib/predicated/predicate.rb +111 -0
  17. data/lib/predicated/lib/predicated/print.rb +62 -0
  18. data/lib/predicated/lib/predicated/selectable.rb +102 -0
  19. data/lib/predicated/lib/predicated/simple_templated_predicate.rb +79 -0
  20. data/lib/predicated/lib/predicated/string_utils.rb +20 -0
  21. data/lib/predicated/lib/predicated/to/arel.rb +41 -0
  22. data/lib/predicated/lib/predicated/to/json.rb +48 -0
  23. data/lib/predicated/lib/predicated/to/sentence.rb +94 -0
  24. data/lib/predicated/lib/predicated/to/solr.rb +15 -0
  25. data/lib/predicated/lib/predicated/to/xml.rb +67 -0
  26. data/lib/predicated/lib/predicated/version.rb +3 -0
  27. data/lib/predicated/predicated.gemspec +22 -0
  28. data/lib/predicated/test/autogen_call_test.rb +40 -0
  29. data/lib/predicated/test/canonical_transform_cases.rb +63 -0
  30. data/lib/predicated/test/constrain_test.rb +86 -0
  31. data/lib/predicated/test/enumerable_test.rb +32 -0
  32. data/lib/predicated/test/equality_test.rb +32 -0
  33. data/lib/predicated/test/evaluate_test.rb +149 -0
  34. data/lib/predicated/test/from/callable_object_canonical_test.rb +43 -0
  35. data/lib/predicated/test/from/callable_object_test.rb +78 -0
  36. data/lib/predicated/test/from/json_test.rb +83 -0
  37. data/lib/predicated/test/from/ruby_code_string_canonical_test.rb +37 -0
  38. data/lib/predicated/test/from/ruby_code_string_test.rb +103 -0
  39. data/lib/predicated/test/from/url_part_parser_test.rb +123 -0
  40. data/lib/predicated/test/from/url_part_test.rb +48 -0
  41. data/lib/predicated/test/from/xml_test.rb +57 -0
  42. data/lib/predicated/test/json_conversion_test.rb +33 -0
  43. data/lib/predicated/test/print_test.rb +66 -0
  44. data/lib/predicated/test/selectable_test.rb +123 -0
  45. data/lib/predicated/test/simple_templated_predicate_test.rb +39 -0
  46. data/lib/predicated/test/suite.rb +2 -0
  47. data/lib/predicated/test/test_helper.rb +64 -0
  48. data/lib/predicated/test/test_helper_with_wrong.rb +6 -0
  49. data/lib/predicated/test/to/arel_test.rb +85 -0
  50. data/lib/predicated/test/to/json_test.rb +74 -0
  51. data/lib/predicated/test/to/sentence_test.rb +90 -0
  52. data/lib/predicated/test/to/solr_test.rb +39 -0
  53. data/lib/predicated/test/to/xml_test.rb +72 -0
  54. data/lib/predicated/test/xml_conversion_test.rb +34 -0
  55. data/lib/predicated/test_integration/arel_integration_test.rb +52 -0
  56. data/lib/predicated/test_integration/canonical_integration_cases.rb +66 -0
  57. data/lib/predicated/test_integration/schema.xml +83 -0
  58. data/lib/predicated/test_integration/solr_integration_test.rb +71 -0
  59. data/lib/predicated/test_integration/sqlite_db +0 -0
  60. data/lib/predicated/test_integration/suite.rb +2 -0
  61. data/lib/predicated/test_integration/usage_test.rb +252 -0
  62. data/lib/wrong.rb +3 -1
  63. data/lib/wrong/adapters/test_unit.rb +1 -3
  64. data/lib/wrong/assert.rb +81 -24
  65. data/lib/wrong/chunk.rb +145 -0
  66. data/lib/wrong/message/string_diff.rb +2 -4
  67. data/lib/wrong/message/test_context.rb +2 -2
  68. data/lib/wrong/version.rb +2 -2
  69. data/test/adapters/minitest_test.rb +16 -9
  70. data/test/adapters/test_unit_test.rb +1 -1
  71. data/test/assert_test.rb +90 -0
  72. data/test/catch_raise_test.rb +2 -2
  73. data/test/chunk_test.rb +236 -0
  74. data/test/failures_test.rb +109 -74
  75. data/test/message/array_diff_test.rb +35 -19
  76. data/test/message/string_diff_test.rb +39 -15
  77. data/test/message/test_context_text.rb +2 -2
  78. data/test/test_helper.rb +25 -7
  79. metadata +86 -33
  80. data/test/basic_assert_test.rb +0 -38
@@ -1,37 +1,53 @@
1
- require "test/test_helper"
1
+ require "./test/test_helper"
2
2
  require "wrong/assert"
3
3
  require "wrong/message/array_diff"
4
4
  require "wrong/adapters/minitest"
5
5
 
6
- apropos "when you're comparing strings and they don't match, show me the diff message" do
7
-
8
- def assert_string_diff_message(block, str)
9
- assert{catch_raise{assert(&block)}.message.include?(str)}
6
+ regarding "when you're comparing strings and they don't match, show me the diff message" do
7
+
8
+ def assert_string_diff_message(first_array, second_array, expected_error_message)
9
+ assert {
10
+ catch_raise {
11
+ assert { first_array == second_array }
12
+ }.message.include?(expected_error_message)
13
+ }
10
14
  end
11
-
15
+
12
16
  test "don't attempt to do this if the assertion is not of the form a_array==b_array" do
13
- deny{catch_raise{assert{[1]==2}}.message.include?("diff")}
14
- deny{catch_raise{assert{nil==[1]}}.message.include?("diff")}
17
+ deny {
18
+ catch_raise {
19
+ assert { [1]==2 }
20
+ }.message.include?("diff")
21
+ }
22
+ deny {
23
+ catch_raise {
24
+ assert { nil==[1] }
25
+ }.message.include?("diff")
26
+ }
15
27
  end
16
28
 
17
29
  test "simple" do
18
- assert{catch_raise{assert{["a"]==["b"]}}.message.include?("diff")}
19
-
20
- assert_string_diff_message(proc{["a", "b"]==["a", "c", "c"]}, %{
30
+ assert {
31
+ catch_raise {
32
+ assert { ["a"]==["b"] }
33
+ }.message.include?("diff")
34
+ }
35
+
36
+ assert_string_diff_message(["a", "b"], ["a", "c", "c"], %{
21
37
  ["a", "b"]
22
38
  ["a", "c", "c"]
23
39
  ^ ^
24
40
  })
25
41
  end
26
-
42
+
27
43
  test "elements align properly" do
28
- assert_string_diff_message(proc{["a", "b", "c"]==["a", "cccc", "c"]}, %{
44
+ assert_string_diff_message(["a", "b", "c"], ["a", "cccc", "c"], %{
29
45
  ["a", "b" , "c"]
30
46
  ["a", "cccc", "c"]
31
47
  ^
32
48
  })
33
49
 
34
- assert_string_diff_message(proc{["a", "b", "c", "d"]==["a", "cccc", "xxx", "d"]}, %{
50
+ assert_string_diff_message(["a", "b", "c", "d"], ["a", "cccc", "xxx", "d"], %{
35
51
  ["a", "b" , "c" , "d"]
36
52
  ["a", "cccc", "xxx", "d"]
37
53
  ^ ^
@@ -39,7 +55,7 @@ apropos "when you're comparing strings and they don't match, show me the diff me
39
55
  end
40
56
 
41
57
  test "different primitive types" do
42
- assert_string_diff_message(proc{[1, true]==[2, true, nil]}, %{
58
+ assert_string_diff_message([1, true], [2, true, nil], %{
43
59
  [1, true]
44
60
  [2, true, nil]
45
61
  ^ ^
@@ -47,13 +63,13 @@ apropos "when you're comparing strings and they don't match, show me the diff me
47
63
  end
48
64
 
49
65
  test "2d array - just inspects the inner array like it would any other element" do
50
- assert{[1, [2, 3]]==[1, [2, 3]]}
51
- assert_string_diff_message(proc{[1, [2]]==[1, [2, 3]]}, %{
66
+ assert { [1, [2, 3]] == [1, [2, 3]] }
67
+ assert_string_diff_message([1, [2]], [1, [2, 3]], %{
52
68
  [1, [2] ]
53
69
  [1, [2, 3]]
54
70
  ^
55
71
  })
56
72
 
57
73
  end
58
-
59
- end
74
+
75
+ end
@@ -1,25 +1,49 @@
1
- require "test/test_helper"
1
+ require "./test/test_helper"
2
2
  require "wrong/assert"
3
3
  require "wrong/message/string_diff"
4
4
  require "wrong/adapters/minitest"
5
5
 
6
- apropos "when you're comparing strings and they don't match, show me the diff message" do
6
+ regarding "when you're comparing strings and they don't match, show me the diff message" do
7
7
 
8
- def assert_string_diff_message(block, str)
9
- assert{catch_raise{assert(&block)}.message.include?(str)}
8
+ def assert_string_diff_message(first_string, second_string, str)
9
+ assert{
10
+ catch_raise{
11
+ assert{first_string == second_string}
12
+ }.message.include?(str)
13
+ }
10
14
  end
11
15
 
12
16
  test "don't attempt to do this if the assertion is not of the form a_string==b_string" do
13
- deny{catch_raise{assert{1==2}}.message.include?("diff")}
14
- deny{catch_raise{assert{"a"==2}}.message.include?("diff")}
15
- deny{catch_raise{assert{1=="a"}}.message.include?("diff")}
16
- deny{catch_raise{assert{nil=="a"}}.message.include?("diff")}
17
+ deny{
18
+ catch_raise{
19
+ assert{1==2}
20
+ }.message.include?("diff")
21
+ }
22
+ deny{
23
+ catch_raise{
24
+ assert{"a"==2}
25
+ }.message.include?("diff")
26
+ }
27
+ deny{
28
+ catch_raise{
29
+ assert{1=="a"}
30
+ }.message.include?("diff")
31
+ }
32
+ deny{
33
+ catch_raise{
34
+ assert{nil=="a"}
35
+ }.message.include?("diff")
36
+ }
17
37
  end
18
38
 
19
39
  test "simple" do
20
- assert{catch_raise{assert{"a"=="b"}}.message.include?("diff")}
40
+ assert{
41
+ catch_raise{
42
+ assert{"a"=="b"}
43
+ }.message.include?("diff")
44
+ }
21
45
 
22
- assert_string_diff_message(proc{"ab"=="acc"}, %{
46
+ assert_string_diff_message("ab", "acc", %{
23
47
  ab
24
48
  ^
25
49
  acc
@@ -28,20 +52,20 @@ acc
28
52
  end
29
53
 
30
54
  test "whitespace" do
31
- assert_string_diff_message(proc{"a\nb"=="a\ncc"}, %{
55
+ assert_string_diff_message("a\nb", "a\ncc", %{
32
56
  a\\nb
33
57
  ^
34
58
  a\\ncc
35
59
  ^^
36
60
  })
37
61
 
38
- assert_string_diff_message(proc{"a\tb"=="a\tcc"}, %{
62
+ assert_string_diff_message("a\tb", "a\tcc", %{
39
63
  a\\tb
40
64
  ^
41
65
  a\\tcc
42
66
  ^^
43
67
  })
44
- assert_string_diff_message(proc{"a\rb"=="a\rcc"}, %{
68
+ assert_string_diff_message("a\rb", "a\rcc", %{
45
69
  a\\rb
46
70
  ^
47
71
  a\\rcc
@@ -54,7 +78,7 @@ a\\rcc
54
78
  left = "x"*100 + "ab" + "y"*100 + "AB" + "z"*100
55
79
  right = "x"*100 + "acc" + "y"*100 + "ACC" + "z"*100
56
80
 
57
- assert_string_diff_message(proc{"ab"=="acc"}, %{
81
+ assert_string_diff_message("ab", "acc", %{
58
82
  ...xxabyyy....yyABzzz....
59
83
  ^ ^
60
84
  ...xxaccyyy...yyACCzzz...
@@ -62,4 +86,4 @@ a\\rcc
62
86
  })
63
87
  end
64
88
 
65
- end
89
+ end
@@ -1,8 +1,8 @@
1
- require "test/test_helper"
1
+ require "./test/test_helper"
2
2
  require "wrong/assert"
3
3
  require "wrong/message/test_context"
4
4
 
5
- apropos "test failures" do
5
+ regarding "showing the lines just above where the failure occurs, so you have some context" do
6
6
 
7
7
  include Wrong::Assert
8
8
 
@@ -1,6 +1,6 @@
1
1
  dir = File.dirname(__FILE__)
2
2
  $LOAD_PATH.unshift "#{dir}/../lib"
3
- $LOAD_PATH.unshift "../predicated/lib"
3
+ $LOAD_PATH.unshift "../predicated/lib" if File.exist?("../predicated/lib")
4
4
  require "rubygems"
5
5
  require "minitest/spec"
6
6
  require "minitest/unit"
@@ -13,18 +13,21 @@ def get_error
13
13
  rescue Exception, RuntimeError => e
14
14
  error = e
15
15
  end
16
- e
16
+
17
+ # puts ""
18
+ # puts error
19
+ #
20
+ error
17
21
  end
18
22
 
19
23
  class MiniTest::Unit::TestCase
20
-
21
24
  end
22
25
 
23
26
  module Kernel
24
- alias_method :apropos, :describe
27
+ alias_method :regarding, :describe
25
28
 
26
- def xapropos(str)
27
- puts "x'd out 'apropos \"#{str}\"'"
29
+ def xregarding(str)
30
+ puts "x'd out 'regarding \"#{str}\"'"
28
31
  end
29
32
  end
30
33
 
@@ -41,4 +44,19 @@ class MiniTest::Spec
41
44
  end
42
45
  end
43
46
 
44
- MiniTest::Unit.autorun
47
+ class Color
48
+ attr_reader :name
49
+ def initialize(name)
50
+ @name = name
51
+ end
52
+
53
+ def ==(other)
54
+ other.is_a?(Color) && @name == other.name
55
+ end
56
+
57
+ def inspect
58
+ "Color:#{@name}"
59
+ end
60
+ end
61
+
62
+ MiniTest::Unit.autorun
metadata CHANGED
@@ -1,43 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrong
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Steve Conover
14
+ - Alex Chaffee
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-07-06 00:00:00 -07:00
19
+ date: 2010-08-22 00:00:00 -07:00
19
20
  default_executable:
20
21
  dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: predicated
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 27
30
- segments:
31
- - 0
32
- - 1
33
- - 0
34
- version: 0.1.0
35
- type: :runtime
36
- version_requirements: *id001
37
22
  - !ruby/object:Gem::Dependency
38
23
  name: ParseTree
39
24
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ requirement: &id001 !ruby/object:Gem::Requirement
41
26
  none: false
42
27
  requirements:
43
28
  - - ">="
@@ -49,11 +34,11 @@ dependencies:
49
34
  - 5
50
35
  version: 3.0.5
51
36
  type: :runtime
52
- version_requirements: *id002
37
+ version_requirements: *id001
53
38
  - !ruby/object:Gem::Dependency
54
39
  name: ruby_parser
55
40
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
41
+ requirement: &id002 !ruby/object:Gem::Requirement
57
42
  none: false
58
43
  requirements:
59
44
  - - ">="
@@ -65,11 +50,11 @@ dependencies:
65
50
  - 4
66
51
  version: 2.0.4
67
52
  type: :runtime
68
- version_requirements: *id003
53
+ version_requirements: *id002
69
54
  - !ruby/object:Gem::Dependency
70
55
  name: ruby2ruby
71
56
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
57
+ requirement: &id003 !ruby/object:Gem::Requirement
73
58
  none: false
74
59
  requirements:
75
60
  - - ">="
@@ -81,11 +66,11 @@ dependencies:
81
66
  - 4
82
67
  version: 1.2.4
83
68
  type: :runtime
84
- version_requirements: *id004
69
+ version_requirements: *id003
85
70
  - !ruby/object:Gem::Dependency
86
71
  name: diff
87
72
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
73
+ requirement: &id004 !ruby/object:Gem::Requirement
89
74
  none: false
90
75
  requirements:
91
76
  - - ">="
@@ -97,11 +82,11 @@ dependencies:
97
82
  - 6
98
83
  version: 0.3.6
99
84
  type: :runtime
100
- version_requirements: *id005
85
+ version_requirements: *id004
101
86
  - !ruby/object:Gem::Dependency
102
87
  name: diff-lcs
103
88
  prerelease: false
104
- requirement: &id006 !ruby/object:Gem::Requirement
89
+ requirement: &id005 !ruby/object:Gem::Requirement
105
90
  none: false
106
91
  requirements:
107
92
  - - ">="
@@ -113,8 +98,13 @@ dependencies:
113
98
  - 2
114
99
  version: 1.1.2
115
100
  type: :runtime
116
- version_requirements: *id006
117
- description: Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail.
101
+ version_requirements: *id005
102
+ description: |-
103
+ Wrong provides a general assert method that takes a predicate block. Assertion failure
104
+ messages are rich in detail. The Wrong idea is to replace all those countless assert_this,
105
+ assert_that library methods which only exist to give a more useful failure message than
106
+ "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it
107
+ in Ruby, Wrong can make a sensible failure message out of it.
118
108
  email: sconover@gmail.com
119
109
  executables: []
120
110
 
@@ -123,9 +113,70 @@ extensions: []
123
113
  extra_rdoc_files:
124
114
  - README.markdown
125
115
  files:
116
+ - lib/predicated/Gemfile
117
+ - lib/predicated/lib/predicated/autogen_call.rb
118
+ - lib/predicated/lib/predicated/constrain.rb
119
+ - lib/predicated/lib/predicated/evaluate.rb
120
+ - lib/predicated/lib/predicated/from/callable_object.rb
121
+ - lib/predicated/lib/predicated/from/json.rb
122
+ - lib/predicated/lib/predicated/from/ruby_code_string.rb
123
+ - lib/predicated/lib/predicated/from/url_part.rb
124
+ - lib/predicated/lib/predicated/from/xml.rb
125
+ - lib/predicated/lib/predicated/gem_check.rb
126
+ - lib/predicated/lib/predicated/predicate.rb
127
+ - lib/predicated/lib/predicated/print.rb
128
+ - lib/predicated/lib/predicated/selectable.rb
129
+ - lib/predicated/lib/predicated/simple_templated_predicate.rb
130
+ - lib/predicated/lib/predicated/string_utils.rb
131
+ - lib/predicated/lib/predicated/to/arel.rb
132
+ - lib/predicated/lib/predicated/to/json.rb
133
+ - lib/predicated/lib/predicated/to/sentence.rb
134
+ - lib/predicated/lib/predicated/to/solr.rb
135
+ - lib/predicated/lib/predicated/to/xml.rb
136
+ - lib/predicated/lib/predicated/version.rb
137
+ - lib/predicated/lib/predicated.rb
138
+ - lib/predicated/LICENSE
139
+ - lib/predicated/predicated.gemspec
140
+ - lib/predicated/Rakefile
141
+ - lib/predicated/README.markdown
142
+ - lib/predicated/test/autogen_call_test.rb
143
+ - lib/predicated/test/canonical_transform_cases.rb
144
+ - lib/predicated/test/constrain_test.rb
145
+ - lib/predicated/test/enumerable_test.rb
146
+ - lib/predicated/test/equality_test.rb
147
+ - lib/predicated/test/evaluate_test.rb
148
+ - lib/predicated/test/from/callable_object_canonical_test.rb
149
+ - lib/predicated/test/from/callable_object_test.rb
150
+ - lib/predicated/test/from/json_test.rb
151
+ - lib/predicated/test/from/ruby_code_string_canonical_test.rb
152
+ - lib/predicated/test/from/ruby_code_string_test.rb
153
+ - lib/predicated/test/from/url_part_parser_test.rb
154
+ - lib/predicated/test/from/url_part_test.rb
155
+ - lib/predicated/test/from/xml_test.rb
156
+ - lib/predicated/test/json_conversion_test.rb
157
+ - lib/predicated/test/print_test.rb
158
+ - lib/predicated/test/selectable_test.rb
159
+ - lib/predicated/test/simple_templated_predicate_test.rb
160
+ - lib/predicated/test/suite.rb
161
+ - lib/predicated/test/test_helper.rb
162
+ - lib/predicated/test/test_helper_with_wrong.rb
163
+ - lib/predicated/test/to/arel_test.rb
164
+ - lib/predicated/test/to/json_test.rb
165
+ - lib/predicated/test/to/sentence_test.rb
166
+ - lib/predicated/test/to/solr_test.rb
167
+ - lib/predicated/test/to/xml_test.rb
168
+ - lib/predicated/test/xml_conversion_test.rb
169
+ - lib/predicated/test_integration/arel_integration_test.rb
170
+ - lib/predicated/test_integration/canonical_integration_cases.rb
171
+ - lib/predicated/test_integration/schema.xml
172
+ - lib/predicated/test_integration/solr_integration_test.rb
173
+ - lib/predicated/test_integration/sqlite_db
174
+ - lib/predicated/test_integration/suite.rb
175
+ - lib/predicated/test_integration/usage_test.rb
126
176
  - lib/wrong/adapters/minitest.rb
127
177
  - lib/wrong/adapters/test_unit.rb
128
178
  - lib/wrong/assert.rb
179
+ - lib/wrong/chunk.rb
129
180
  - lib/wrong/message/array_diff.rb
130
181
  - lib/wrong/message/string_diff.rb
131
182
  - lib/wrong/message/test_context.rb
@@ -134,8 +185,9 @@ files:
134
185
  - README.markdown
135
186
  - test/adapters/minitest_test.rb
136
187
  - test/adapters/test_unit_test.rb
137
- - test/basic_assert_test.rb
188
+ - test/assert_test.rb
138
189
  - test/catch_raise_test.rb
190
+ - test/chunk_test.rb
139
191
  - test/failures_test.rb
140
192
  - test/message/array_diff_test.rb
141
193
  - test/message/string_diff_test.rb
@@ -179,8 +231,9 @@ summary: Wrong provides a general assert method that takes a predicate block. A
179
231
  test_files:
180
232
  - test/adapters/minitest_test.rb
181
233
  - test/adapters/test_unit_test.rb
182
- - test/basic_assert_test.rb
234
+ - test/assert_test.rb
183
235
  - test/catch_raise_test.rb
236
+ - test/chunk_test.rb
184
237
  - test/failures_test.rb
185
238
  - test/message/array_diff_test.rb
186
239
  - test/message/string_diff_test.rb