minitest_lucid 0.1.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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +28 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +574 -0
  8. data/Rakefile +36 -0
  9. data/lib/lorem.rb +37 -0
  10. data/lib/minitest_lucid.rb +245 -0
  11. data/lib/minitest_lucid/version.rb +3 -0
  12. data/markdown/readme/README.md +102 -0
  13. data/markdown/readme/array/assert_equal/better.txt +31 -0
  14. data/markdown/readme/array/assert_equal/data.rb +48 -0
  15. data/markdown/readme/array/assert_equal/default.txt +5 -0
  16. data/markdown/readme/array/assert_equal/example.rb +35 -0
  17. data/markdown/readme/array/assert_equal/lucid.txt +31 -0
  18. data/markdown/readme/array/assert_equal/template.md +17 -0
  19. data/markdown/readme/array/template.md +3 -0
  20. data/markdown/readme/hash/assert_equal/better.txt +31 -0
  21. data/markdown/readme/hash/assert_equal/data.rb +46 -0
  22. data/markdown/readme/hash/assert_equal/default.txt +5 -0
  23. data/markdown/readme/hash/assert_equal/example.rb +35 -0
  24. data/markdown/readme/hash/assert_equal/lucid.txt +57 -0
  25. data/markdown/readme/hash/assert_equal/template.md +17 -0
  26. data/markdown/readme/hash/template.md +3 -0
  27. data/markdown/readme/set/assert_equal/better.txt +34 -0
  28. data/markdown/readme/set/assert_equal/data.rb +44 -0
  29. data/markdown/readme/set/assert_equal/default.txt +5 -0
  30. data/markdown/readme/set/assert_equal/example.rb +36 -0
  31. data/markdown/readme/set/assert_equal/lucid.txt +43 -0
  32. data/markdown/readme/set/assert_equal/template.md +17 -0
  33. data/markdown/readme/set/template.md +3 -0
  34. data/markdown/readme/struct/assert_equal/better.txt +42 -0
  35. data/markdown/readme/struct/assert_equal/data.rb +85 -0
  36. data/markdown/readme/struct/assert_equal/default.txt +5 -0
  37. data/markdown/readme/struct/assert_equal/example.rb +35 -0
  38. data/markdown/readme/struct/assert_equal/lucid.txt +81 -0
  39. data/markdown/readme/struct/assert_equal/template.md +17 -0
  40. data/markdown/readme/struct/template.md +3 -0
  41. data/markdown/readme/template.md +19 -0
  42. data/minitest_lucid.gemspec +39 -0
  43. metadata +169 -0
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ namespace :build do
11
+
12
+ desc 'Build README pages'
13
+ task :readme do
14
+ project_dir_path = File.dirname(__FILE__ )
15
+ readme_dir_path = File.join(
16
+ project_dir_path,
17
+ 'markdown',
18
+ 'readme',
19
+ )
20
+ Dir.chdir(readme_dir_path) do
21
+ ruby_file_paths = Dir.glob('./**/*.rb')
22
+ ruby_file_paths.each do |ruby_file_path|
23
+ Dir.chdir(File.dirname(ruby_file_path)) do
24
+ ruby_file_name = File.basename(ruby_file_path)
25
+ command = "ruby #{ruby_file_name}"
26
+ system(command)
27
+ end
28
+ end
29
+ command = "markdown_helper include --pristine template.md ../../README.md"
30
+ system(command)
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ task :default => :test
data/lib/lorem.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'lorem-ipsum'
2
+
3
+ include LoremIpsum
4
+
5
+ spec = Gem::Specification.find_by_name('lorem-ipsum')
6
+ gem_root = spec.gem_dir
7
+ lorem_file_path = File.join(gem_root, 'data', 'lorem.txt')
8
+ lorem = Generator.new
9
+ lorem.analyze(lorem_file_path)
10
+
11
+ # puts '['
12
+ # (0...24).each do
13
+ # value = lorem.next_sentence(4).strip
14
+ # puts "'#{value}',"
15
+ # end
16
+ # puts ']'
17
+
18
+ # puts '{'
19
+ # (0..24).each do
20
+ # key = lorem.next_sentence(1).strip.gsub('.', '').downcase
21
+ # value = lorem.next_sentence(4).strip
22
+ # puts ":#{key} => '#{value}',"
23
+ # end
24
+ # puts '}'
25
+
26
+ hash = {}
27
+ (0..24).each do
28
+ key = lorem.next_sentence(1).strip.gsub('.', '').downcase
29
+ value = lorem.next_sentence(4).strip
30
+ hash.store(key, value)
31
+ end
32
+ hash.keys.each do |key|
33
+ puts ":#{key},"
34
+ end
35
+ hash.values.each do |value|
36
+ puts "'#{value}',"
37
+ end
@@ -0,0 +1,245 @@
1
+ require 'minitest'
2
+ require 'diff/lcs'
3
+ require 'set'
4
+
5
+ module Minitest
6
+
7
+ module Assertions
8
+
9
+ alias :old_assert_equal :assert_equal
10
+
11
+ def assert_equal(expected, actual, msg=nil)
12
+ begin
13
+ old_assert_equal(expected, actual, msg)
14
+ rescue Minitest::Assertion => x
15
+ elucidate(x, expected, actual, msg)
16
+ end
17
+ end
18
+
19
+ METHOD_FOR_CLASS = {
20
+ Hash => :elucidate_hash,
21
+ Set => :elucidate_set,
22
+ Struct => :elucidate_struct,
23
+ # Array => :elucidate_array,
24
+ }
25
+ ELUCIDATABLE_CLASSES = METHOD_FOR_CLASS.keys
26
+
27
+ # Lookup objects in hash.
28
+ def lookup(one_object, other_object)
29
+ if ELUCIDATABLE_CLASSES.include?(one_object.class)
30
+ if other_object.kind_of?(one_object.class)
31
+ return METHOD_FOR_CLASS.fetch(one_object.class)
32
+ end
33
+ end
34
+ nil
35
+ end
36
+
37
+ # Poll with kind_of?.
38
+ def poll(expected, actual)
39
+ METHOD_FOR_CLASS.each_pair do |klass, method|
40
+ next unless expected.kind_of?(klass)
41
+ next unless actual.kind_of?(klass)
42
+ return method
43
+ end
44
+ nil
45
+ end
46
+
47
+ def elucidate(exception, expected, actual, msg)
48
+ elucidation_method =
49
+ lookup(expected, actual) ||
50
+ lookup(actual, expected) ||
51
+ poll(expected, actual)
52
+ if elucidation_method
53
+ lines = ['']
54
+ lines.push('{')
55
+ lines.push(" :message => '#{msg}',") if msg
56
+ send(elucidation_method, exception, expected, actual, lines)
57
+ lines.push('}')
58
+ lines.push('')
59
+ message = lines.join("\n")
60
+ new_exception = exception.exception(message)
61
+ new_exception.set_backtrace(exception.backtrace)
62
+ raise new_exception
63
+ else
64
+ raise
65
+ end
66
+ end
67
+
68
+ def elucidate_array(exception, expected, actual, lines)
69
+ sdiff = Diff::LCS.sdiff(expected, actual)
70
+ changes = {}
71
+ statuses = {
72
+ '!' => 'changed',
73
+ '+' => 'unexpected',
74
+ '-' => 'missing',
75
+ '=' => 'unchanged'
76
+ }
77
+ sdiff.each_with_index do |change, i|
78
+ status = statuses.fetch(change.action)
79
+ key = "change_#{i}"
80
+ change_data = {
81
+ :status => status,
82
+ :"old_index_#{change.old_position}" => change.old_element.inspect,
83
+ :"new_index_#{change.new_position}" => change.new_element.inspect,
84
+ }
85
+ changes.store(key, change_data)
86
+ end
87
+ lines.push('elucidation = [')
88
+ changes.each_pair do |category, change_data|
89
+ status = change_data.delete(:status)
90
+ if status == 'unexpected'
91
+ change_data.delete_if {|key, value| key.match(/old/) }
92
+ end
93
+ if status == 'missing'
94
+ change_data.delete_if {|key, value| key.match(/new/) }
95
+ end
96
+ lines.push(' {')
97
+ lines.push(" :status => :#{status},")
98
+ change_data.each_pair do |k, v|
99
+ lines.push(" :#{k} => #{v},")
100
+ end
101
+ lines.push(' },')
102
+ end
103
+ lines.push(']')
104
+ end
105
+
106
+ def elucidate_hash(exception, expected, actual, lines)
107
+ expected_keys = expected.keys
108
+ actual_keys = actual.keys
109
+ keys = Set.new(expected_keys + actual_keys)
110
+ h = {
111
+ :missing_pairs => {},
112
+ :unexpected_pairs => {},
113
+ :changed_values => {},
114
+ :ok_pairs => {},
115
+ }
116
+ keys.each do |key|
117
+ expected_value = expected[key]
118
+ actual_value = actual[key]
119
+ case
120
+ when expected_value && actual_value
121
+ if expected_value == actual_value
122
+ h[:ok_pairs].store(key, expected_value)
123
+ else
124
+ h[:changed_values].store(key, [expected_value, actual_value])
125
+ end
126
+ when expected_value
127
+ h[:missing_pairs].store(key, expected_value)
128
+ when actual_value
129
+ h[:unexpected_pairs].store(key, actual_value)
130
+ else
131
+ fail [expected_value, actual_value].inspect
132
+ end
133
+ end
134
+ lines.push(' :expected => {')
135
+ lines.push(" :class => #{expected.class},")
136
+ lines.push(" :size => #{expected.size},")
137
+ lines.push(' },')
138
+ lines.push(' :actual => {')
139
+ lines.push(" :class => #{actual.class},")
140
+ lines.push(" :size => #{actual.size},")
141
+ lines.push(' },')
142
+ lines.push(' :elucidation => {')
143
+ h.each_pair do |category, items|
144
+ lines.push(" #{pretty(category)} => {")
145
+ items.each_pair do |key, value|
146
+ if value.instance_of?(Array)
147
+ expected, actual = *value
148
+ lines.push(" #{pretty(key)} => {")
149
+ lines.push(" :expected => #{pretty(expected)},")
150
+ lines.push(" :got => #{pretty(actual)},")
151
+ lines.push(' },')
152
+ else
153
+ lines.push(" #{pretty(key)} => #{pretty(value)},")
154
+ end
155
+ end
156
+ lines.push(' },')
157
+ end
158
+ lines.push(' }')
159
+ end
160
+
161
+ def elucidate_set(exception, expected, actual, lines)
162
+ result = {
163
+ :missing => expected.difference(actual),
164
+ :unexpected => actual.difference(expected),
165
+ :ok => expected.intersection(actual),
166
+ }
167
+ lines.push(' :expected => {')
168
+ lines.push(" :class => #{expected.class},")
169
+ lines.push(" :size => #{expected.size},")
170
+ lines.push(' },')
171
+ lines.push(' :actual => {')
172
+ lines.push(" :class => #{actual.class},")
173
+ lines.push(" :size => #{actual.size},")
174
+ lines.push(' },')
175
+ lines.push(' :elucidation => {')
176
+ result.each_pair do |category, items|
177
+ lines.push(" #{pretty(category)} => {")
178
+ items.each do |member|
179
+ lines.push(" #{pretty(member)},")
180
+ end
181
+ lines.push(' },')
182
+ end
183
+ lines.push(' }')
184
+ end
185
+
186
+ def elucidate_struct(exception, expected, actual, lines)
187
+ expected_members = expected.members
188
+ actual_members = actual.members
189
+ members = Set.new(expected_members + actual_members)
190
+ h = {
191
+ :changed_values => {},
192
+ :ok_values => {},
193
+ }
194
+ members.each do |member|
195
+ expected_value = expected[member]
196
+ actual_value = actual[member]
197
+ if expected_value == actual_value
198
+ h[:ok_values].store(member, expected_value)
199
+ else
200
+ h[:changed_values].store(member, [expected_value, actual_value])
201
+ end
202
+ end
203
+ lines.push(' :expected => {')
204
+ lines.push(" :class => #{expected.class},")
205
+ lines.push(" :size => #{expected.size},")
206
+ lines.push(' },')
207
+ lines.push(' :actual => {')
208
+ lines.push(" :class => #{actual.class},")
209
+ lines.push(" :size => #{actual.size},")
210
+ lines.push(' },')
211
+ lines.push(' :elucidation => {')
212
+ h.each_pair do |category, items|
213
+ lines.push(" #{pretty(category)} => {")
214
+ items.each_pair do |member, value|
215
+ if value.instance_of?(Array)
216
+ expected, actual = *value
217
+ lines.push(" #{pretty(member)} => {")
218
+ lines.push(" :expected => #{pretty(expected)},")
219
+ lines.push(" :got => #{pretty(actual)},")
220
+ lines.push(' },')
221
+ else
222
+ lines.push(" #{pretty(member)} => #{pretty(value)},")
223
+ end
224
+ end
225
+ lines.push(' },')
226
+ end
227
+ lines.push(' }')
228
+ end
229
+
230
+ def pretty(arg)
231
+ case
232
+ when arg.kind_of?(Symbol)
233
+ ":#{arg}"
234
+ when arg.kind_of?(String)
235
+ "'#{arg}'"
236
+ when arg.kind_of?(Numeric)
237
+ arg
238
+ else
239
+ arg.inspect
240
+ end
241
+ end
242
+
243
+ end
244
+
245
+ end
@@ -0,0 +1,3 @@
1
+ module MinitestLucid
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,102 @@
1
+ # Minitest Lucid
2
+
3
+ Use ```minitest_lucid``` to improve error messages from ```minitest```.
4
+
5
+
6
+ ## Supported Classes
7
+
8
+ - [Hash](#hash)
9
+
10
+ ### Hash
11
+
12
+ #### assert_equal
13
+
14
+ Here are the hashes, expected and actual, that we'll use for comparison:
15
+
16
+ ```data.rb```:
17
+ ```ruby
18
+ def expected
19
+ {
20
+ :tauro => 'Cia ina do ip ocat doat.',
21
+ :loquens => 'Dua sarat rad noad maat caea.',
22
+ :lor => 'Eser in dolo eaata labor ut.',
23
+ :dolo => 'Ipaat paal doat iruat ala magabor.',
24
+ :offab => 'Ut dolore ua consal vaba caea.',
25
+ :moam => 'Sunt sed te coma teu alaaame.',
26
+ }
27
+ end
28
+ def actual
29
+ {
30
+ :laboru => 'Laboab vaga dat maaua in venima.',
31
+ :dolo => 'Ipaat paal doat iruat ala magabor.',
32
+ :loquens => 'dua sarat rad noad maat caea.',
33
+ :lor => 'Eser in dolo eaata labor ut.',
34
+ :tauro => 'cia ina do ip ocat doat.',
35
+ :amcae => 'Utatu cilaa cit siat commag seqa.',
36
+ }
37
+ end
38
+ ```
39
+
40
+ The default message:
41
+
42
+ ```default.txt```:
43
+ ```
44
+ --- expected
45
+ +++ actual
46
+ @@ -1 +1 @@
47
+ -{:tauro=>"Cia ina do ip ocat doat.", :loquens=>"Dua sarat rad noad maat caea.", :lor=>"Eser in dolo eaata labor ut.", :dolo=>"Ipaat paal doat iruat ala magabor.", :offab=>"Ut dolore ua consal vaba caea.", :moam=>"Sunt sed te coma teu alaaame."}
48
+ +{:laboru=>"Laboab vaga dat maaua in venima.", :dolo=>"Ipaat paal doat iruat ala magabor.", :loquens=>"dua sarat rad noad maat caea.", :lor=>"Eser in dolo eaata labor ut.", :tauro=>"cia ina do ip ocat doat.", :amcae=>"Utatu cilaa cit siat commag seqa."}
49
+ ```
50
+
51
+ Message using ```make_my_diffs_pretty!```:
52
+
53
+ ```better.txt```:
54
+ ```
55
+ --- expected
56
+ +++ actual
57
+ @@ -1,6 +1,6 @@
58
+ -{:tauro=>"Cia ina do ip ocat doat.",
59
+ - :loquens=>"Dua sarat rad noad maat caea.",
60
+ - :lor=>"Eser in dolo eaata labor ut.",
61
+ +{:laboru=>"Laboab vaga dat maaua in venima.",
62
+ :dolo=>"Ipaat paal doat iruat ala magabor.",
63
+ - :offab=>"Ut dolore ua consal vaba caea.",
64
+ - :moam=>"Sunt sed te coma teu alaaame."}
65
+ + :loquens=>"dua sarat rad noad maat caea.",
66
+ + :lor=>"Eser in dolo eaata labor ut.",
67
+ + :tauro=>"cia ina do ip ocat doat.",
68
+ + :amcae=>"Utatu cilaa cit siat commag seqa."}
69
+ ```
70
+
71
+ Message using ```minitest_lucid```
72
+
73
+ ```lucid.txt```:
74
+ ```
75
+
76
+ elucidation = {
77
+ :missing_pairs => {
78
+ :offab => 'Ut dolore ua consal vaba caea.',
79
+ :moam => 'Sunt sed te coma teu alaaame.',
80
+ },
81
+ :unexpected_pairs => {
82
+ :laboru => 'Laboab vaga dat maaua in venima.',
83
+ :amcae => 'Utatu cilaa cit siat commag seqa.',
84
+ },
85
+ :changed_values => {
86
+ :tauro => {
87
+ :expected => 'Cia ina do ip ocat doat.',
88
+ :got => 'cia ina do ip ocat doat.',
89
+ },
90
+ :loquens => {
91
+ :expected => 'Dua sarat rad noad maat caea.',
92
+ :got => 'dua sarat rad noad maat caea.',
93
+ },
94
+ },
95
+ :ok_pairs => {
96
+ :lor => 'Eser in dolo eaata labor ut.',
97
+ :dolo => 'Ipaat paal doat iruat ala magabor.',
98
+ },
99
+ }
100
+ ```
101
+
102
+
@@ -0,0 +1,31 @@
1
+ --- expected
2
+ +++ actual
3
+ @@ -1,19 +1,19 @@
4
+ -["Si alit vagna nonse.",
5
+ - "Serci nosa deaaboat iama.",
6
+ - "Pa ipsab occata seqa.",
7
+ - "Oaba dunt sicid eur.",
8
+ - "Esam est tat sumaan.",
9
+ +["Esam est tat sumaan.",
10
+ "Ad do ea labat.",
11
+ "Cupis doluaan adat duat.",
12
+ "Dolla aua am maab.",
13
+ - "In na idat nonsa.",
14
+ - "Eniat noaeaa in venia.",
15
+ - "Non utat rad et.",
16
+ - "Volu siamc moloab cupi.",
17
+ + "Si alit vagna nonse.",
18
+ + "Serci nosa deaaboat iama.",
19
+ + "Fugame cupis do iramaa.",
20
+ + "Eiusmagat do labore utatur.",
21
+ "Lababor rat vent essa.",
22
+ "Modola cula ocaadia amea.",
23
+ "Ania est exeaat sicid.",
24
+ "Adipsu miate eiuat naam.",
25
+ + "In na idat nonsa.",
26
+ + "Eniat noaeaa in venia.",
27
+ + "Non utat rad et.",
28
+ + "Volu siamc moloab cupi.",
29
+ "Dolor eaae doat volu.",
30
+ "Adiatur anaaa qui eius.",
31
+ "Ad laam utet seri.",