qualitysmith_extensions 0.0.29 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes.
|
6
|
+
# Developer notes::
|
7
|
+
# * Names considered:
|
8
|
+
# * intersection (since there's already a Regexp#union), but unlike Regexp#union, it really doesn't seem like this method lends itself to a name from set theory. Mostly because unlike when dealing with sets (or unioned Regexps), *order matters* here.
|
9
|
+
# * merge, concat, sum, add, combines
|
10
|
+
# * join -- Settled on this because it's a lot like File.join: it combines the given pieces, *in order*, to make a whole.
|
11
|
+
#++
|
12
|
+
|
13
|
+
|
14
|
+
class Regexp
|
15
|
+
# Returns a Regexp that results from interpolating each of the given +elements+ into an empty regular expression.
|
16
|
+
# /ab/ == Regexp.join(/a/, /b/) # except spelled differently
|
17
|
+
# Accepts both strings and Regexp's as +elements+ to join together. Strings that are passed in will be escaped (so characters like '*' will lose all of the Regexp powers that they would otherwise have and are treated as literals).
|
18
|
+
#
|
19
|
+
# Serving suggestion: Use it to check if the +actual+ string in an <tt>assert_match</tt> contains certain literal strings, which may be separated by any number of characters or lines that we don't care about. In other words, use it to see if a string contains the necessary "keywords" or "key phrases"...
|
20
|
+
# assert_match Regexp.join(
|
21
|
+
# 'keyword1',
|
22
|
+
# /.*/m,
|
23
|
+
# 'keyword2'
|
24
|
+
# ), some_method()
|
25
|
+
# # where some_method() returns "keyword1 blah blah blah keyword2"
|
26
|
+
#
|
27
|
+
def self.join(*elements)
|
28
|
+
elements.inject(//) do |accumulator, element|
|
29
|
+
accumulator + element
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Pads the +elements+ (which may be strings or Regexp's) with /.*/ (match any number of characters) patterns.
|
34
|
+
# Pass :multi_line => true if you want /.*/m as the padding pattern instead.
|
35
|
+
def self.loose_join(*elements)
|
36
|
+
options = (if elements.last.is_a?(Hash) then elements.pop else {} end)
|
37
|
+
multi_line = options[:multi_line] || options[:m]
|
38
|
+
padding = (multi_line ? /.*/m : /.*/)
|
39
|
+
elements.inject(//) do |accumulator, element|
|
40
|
+
accumulator + padding + element
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# /a/ + /b/ == /ab/
|
45
|
+
# Actually, the way it's currently implemented, it is
|
46
|
+
# /a/ + /b/ == /(?-mix:a)(?-mix:b)/
|
47
|
+
# But they seem to be functionally equivalent despite the different spellings.
|
48
|
+
def +(other)
|
49
|
+
other = Regexp.escape(other) if other.is_a?(String)
|
50
|
+
/#{self}#{other}/
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
# _____ _
|
58
|
+
# |_ _|__ ___| |_
|
59
|
+
# | |/ _ \/ __| __|
|
60
|
+
# | | __/\__ \ |_
|
61
|
+
# |_|\___||___/\__|
|
62
|
+
#
|
63
|
+
=begin test
|
64
|
+
require 'test/unit'
|
65
|
+
|
66
|
+
class TheTest < Test::Unit::TestCase
|
67
|
+
def test_1_simple_letters
|
68
|
+
assert_equal /(?-mix:)(?-mix:b)/, // + /b/
|
69
|
+
assert_equal /(?-mix:)b/, // + 'b'
|
70
|
+
assert_equal /(?-mix:a)(?-mix:b)/, /a/ + /b/
|
71
|
+
assert_equal /(?-mix:a)b/, /a/ + 'b'
|
72
|
+
assert_equal /(?-mix:(?-mix:(?-mix:)a)b)c/, Regexp.join('a', 'b', 'c')
|
73
|
+
#assert_equal /(?-mix:(?-mix:(?-mix:)a)b)c/, Regexp.join(/a/, /b/, /c/)
|
74
|
+
assert_equal 2, '__abc__' =~ Regexp.join('a', 'b', 'c')
|
75
|
+
assert_equal 2, '__abc__' =~ Regexp.join(/a/, /b/, /c/)
|
76
|
+
assert_equal nil, '__a.c__' =~ Regexp.join('a', 'b', 'c')
|
77
|
+
assert_equal nil, '__a.c__' =~ Regexp.join(/a/, /b/, /c/)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_2_escaping
|
81
|
+
assert_equal /(?-mix:)\./, // + '.' # Escaped
|
82
|
+
assert_equal /(?-mix:)(?-mix:.)/, // + /./ # Not escaped
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_3
|
86
|
+
assert_match Regexp.join(
|
87
|
+
'keyword1',
|
88
|
+
/.*/m,
|
89
|
+
'keyword2'
|
90
|
+
),
|
91
|
+
'keyword1
|
92
|
+
asuethausnthauesth
|
93
|
+
blah blah blah
|
94
|
+
keyword2'
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_loose_join
|
98
|
+
regexp = Regexp.loose_join('keyword1', 'keyword2')
|
99
|
+
assert_match regexp, 'keyword1 blah blah blah keyword2'
|
100
|
+
assert_equal nil, "keyword1 blah\nblah\nblah keyword2" =~ regexp
|
101
|
+
end
|
102
|
+
def test_loose_join_multiline
|
103
|
+
regexp = Regexp.loose_join('keyword1', 'keyword2', :m => true)
|
104
|
+
assert_match regexp, 'keyword1 blah blah blah keyword2'
|
105
|
+
assert_match regexp, "keyword1 blah\nblah\nblah keyword2"
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
=end
|
110
|
+
|
111
|
+
|
@@ -5,7 +5,8 @@
|
|
5
5
|
# Submit to Facets?::
|
6
6
|
# Developer notes::
|
7
7
|
#++
|
8
|
-
|
8
|
+
# This file adds a bit of color to your failed string comparisons (assert_equal).
|
9
|
+
# Differences will be highlighted for you in color so that you can instantly find them.
|
9
10
|
|
10
11
|
require 'rubygems'
|
11
12
|
gem 'colored'
|
@@ -19,6 +20,8 @@ require 'qualitysmith_extensions/module/bool_attr_accessor'
|
|
19
20
|
require 'qualitysmith_extensions/module/guard_method'
|
20
21
|
require 'qualitysmith_extensions/colored/toggleability'
|
21
22
|
|
23
|
+
require 'test/unit'
|
24
|
+
|
22
25
|
class String
|
23
26
|
# For all of the next 3 methods, we will underline spaces so that they are actually visible on the screen.
|
24
27
|
# Newlines will be replaced with '\n'"\n".
|
@@ -27,32 +30,32 @@ class String
|
|
27
30
|
def highlight_commonality
|
28
31
|
self.
|
29
32
|
make_control_characters_visible.
|
30
|
-
|
31
|
-
green.
|
32
|
-
send_unless(self == ' ', :bold) # spaces are not bold
|
33
|
+
make_spaces_visible(:green).
|
34
|
+
green.bold
|
35
|
+
#send_unless(self == ' ', :bold) # spaces are not bold; '_'s (and everything else) are
|
33
36
|
end
|
34
37
|
# This is a (sub)string that is different between expected and actual
|
35
38
|
def highlight_difference
|
36
39
|
self.
|
37
40
|
make_control_characters_visible.
|
38
|
-
|
39
|
-
red.
|
40
|
-
send_unless(self == ' ', :bold) # spaces are not bold
|
41
|
+
make_spaces_visible(:red).
|
42
|
+
red.bold
|
43
|
+
#send_unless(self == ' ', :bold) # spaces are not bold; '_'s (and everything else) are
|
41
44
|
end
|
42
45
|
# This is a (sub)string that exists only in *self*, not in the other string
|
43
46
|
def highlight_unique
|
44
47
|
self.
|
45
48
|
make_control_characters_visible.
|
46
|
-
|
47
|
-
|
49
|
+
make_spaces_visible(:magenta).
|
50
|
+
magenta
|
48
51
|
end
|
49
|
-
# This is a (sub)string that doesn't exist in self, only in the *other* string
|
52
|
+
# This is a (sub)string that doesn't exist in self, only in the *other* string. It's just a placeholder character (a space) that represents a *missing* character.
|
50
53
|
def highlight_absence
|
51
|
-
self.white.
|
54
|
+
self.white.on_cyan.bold
|
52
55
|
end
|
53
|
-
def
|
56
|
+
def make_spaces_visible(color)
|
54
57
|
#:todo: Make this optional? Might be useful if you are comparing things with lots of spaces and underscores and you want to be able to tell the difference between them...?
|
55
|
-
self.gsub(' ', ' '.
|
58
|
+
self.gsub(' ', ' '.send(:"on_#{color}"))
|
56
59
|
end
|
57
60
|
def make_control_characters_visible
|
58
61
|
self.gsub(/\n/, '\n'+"\n"). # Show '\n' in addition to actually doing the line break
|
@@ -61,9 +64,11 @@ class String
|
|
61
64
|
#:todo: Add other control characters?
|
62
65
|
end
|
63
66
|
end
|
67
|
+
|
64
68
|
module Test
|
65
69
|
module Unit
|
66
70
|
module Assertions
|
71
|
+
|
67
72
|
class AssertionMessage
|
68
73
|
@@inspect_strings = false
|
69
74
|
mguard_method :inspect_strings!, :@@inspect_strings
|
@@ -87,7 +92,8 @@ module Test
|
|
87
92
|
end
|
88
93
|
end
|
89
94
|
alias_method_chain :convert, :option_to_not_use_inspect_for_strings
|
90
|
-
end
|
95
|
+
end # class AssertionMessage
|
96
|
+
|
91
97
|
end
|
92
98
|
end
|
93
99
|
end
|
@@ -98,26 +104,38 @@ module Test
|
|
98
104
|
@@use_assert_equal_with_highlight = nil
|
99
105
|
mguard_method :use_assert_equal_with_highlight!, :@@use_assert_equal_with_highlight
|
100
106
|
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
107
|
+
# The built-in behavior for <tt>assert_equal</tt> method is great for comparing small strings, but not so great for long strings.
|
108
|
+
# If both the strings you are dealing with are both 20 paragraphs long, for example, and they differ by only one character,
|
109
|
+
# the task of locating and identifying the one character that is off is akin to finding a (literal) needle in a
|
110
|
+
# (literal) haystack (not fun!).
|
111
|
+
#
|
112
|
+
# link:include/assert_equal_with_difference_highlighting-wheres_waldo.png
|
113
|
+
#
|
114
|
+
# This replacement/wrapper for <tt>assert_equal</tt> aims to solve all of your string comparison woes (and eventually someday
|
115
|
+
# perhaps arrays and hashes as well), helping you to spot differences very quickly and to have fun doing it.
|
104
116
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
# other are displayed in yellow (a blank yellow background as placeholders for the string in which those characters
|
109
|
-
# are missing).
|
110
|
-
# Arrays:
|
111
|
-
# [:todo:]
|
112
|
-
# Hashes:
|
113
|
-
# [:todo:]
|
117
|
+
# Rather than simply showing you the raw (<tt>inspect</tt>ed) +expected+ and +actual+ and expecting you, the poor user, to
|
118
|
+
# painstakingly compare the two and figure out exactly which characters are different by yourself this method will *highlight*
|
119
|
+
# the differences for you, allowing you to spot them an instant or less!!
|
114
120
|
#
|
115
|
-
#
|
116
|
-
# * last argument is a hash (+options+) rather than message=nil, since I don't see the use in passing in a message if
|
117
|
-
# the default message can be made useful enough.
|
118
|
-
# * If you really want to pass in a message, use <tt>:message => 'my message'</tt>
|
121
|
+
# link:include/assert_equal_with_difference_highlighting-there_he_is.png
|
119
122
|
#
|
120
|
-
#
|
123
|
+
# *Strings*:
|
124
|
+
# * Does a characterwise comparison between the two strings. That is, for each index, it will look at the character at that
|
125
|
+
# index and decide if it is the same or different than the character at the same location in the other string. There are
|
126
|
+
# 3 1/2 cases:
|
127
|
+
# * *Common* characters are displayed in _green_,
|
128
|
+
# * *Different* characters in _red_,
|
129
|
+
# * Characters that exist <b>in only one string</b> but not the other are displayed in _yellow_
|
130
|
+
# * A _cyan_ <tt>~</tt> will appear that location in the _other_ string, as a placeholder for the <b>missing character</b>.
|
131
|
+
# *Arrays*:
|
132
|
+
# * [:todo:]
|
133
|
+
# *Hashes*:
|
134
|
+
# * [:todo:]
|
135
|
+
#
|
136
|
+
# <b>Disabling/enabling highlighting</b>:
|
137
|
+
#
|
138
|
+
# By default, highlighting is only used when one or both of the strings being compared is long or spans multiple lines. You can override the default with the <tt>:higlight</tt> option:
|
121
139
|
# assert_equal 'really long string', 'another really long string', :highlight => true
|
122
140
|
# You can turn it on for all assert_equal assertions by calling
|
123
141
|
# Test::Unit::Assertions::use_assert_equal_with_highlight!
|
@@ -126,14 +144,26 @@ module Test
|
|
126
144
|
# assert_equal 'really long string', 'another really long string'
|
127
145
|
# end
|
128
146
|
#
|
129
|
-
# *
|
130
|
-
# *
|
147
|
+
# *Notes*:
|
148
|
+
# * Spaces are displayed as with a bright colored background so that they are actually visible on the screen (so you can distinguish an empty line from a line with spaces on it, for example).
|
149
|
+
# * Newlines are displayed as the text <tt>\n</tt> followed by the actual newline. Other control characters (<tt>\t</tt>, <tt>\r</tt>) are escaped as well so that you can tell what character it is.
|
131
150
|
#
|
132
|
-
#
|
133
|
-
# *
|
151
|
+
# <b>Difference in method signature</b> from <tt>assert_equal_without_difference_highlighting</tt> (the standard behavior):
|
152
|
+
# * The last argument (+options+) is expected to be a hash rather than message=nil, since I don't see the use in passing in a message if
|
153
|
+
# the _default_ message can be made useful enough.
|
154
|
+
# * However, for compatibility with existing assert_equal calls, it will check if the 3rd argument is a string and if it is will use it as the failure message.
|
155
|
+
# * If you to pass in a message in combination with other options, use <tt>:message => 'my message'</tt>
|
156
|
+
#
|
157
|
+
# *Advanced*:
|
158
|
+
# * If you want everything to be escaped (so you can see the color _codes_ instead of the color itself, for example), use <tt>:inspect_strings => true</tt>
|
134
159
|
#
|
135
160
|
def assert_equal_with_highlighting(expected, actual, options = {})
|
136
|
-
|
161
|
+
if options.is_a?(String)
|
162
|
+
message = options
|
163
|
+
options = {}
|
164
|
+
else
|
165
|
+
message = options.delete(:message) || nil
|
166
|
+
end
|
137
167
|
highlight = options.delete(:highlight)
|
138
168
|
|
139
169
|
Assertions.send_unless(highlight.nil?, :use_assert_equal_with_highlight!, highlight) do
|
@@ -151,11 +181,10 @@ module Test
|
|
151
181
|
act = actual[i] ? actual[i].chr : nil
|
152
182
|
if act.nil?
|
153
183
|
expected_with_highlighting << exp.highlight_unique
|
154
|
-
actual_with_highlighting << '
|
184
|
+
actual_with_highlighting << '~'.highlight_absence
|
155
185
|
elsif exp.nil?
|
156
|
-
expected_with_highlighting << '
|
186
|
+
expected_with_highlighting << '~'.highlight_absence
|
157
187
|
actual_with_highlighting << act.highlight_unique
|
158
|
-
|
159
188
|
elsif exp != act
|
160
189
|
expected_with_highlighting << exp.highlight_difference
|
161
190
|
actual_with_highlighting << act.highlight_difference
|
@@ -166,9 +195,9 @@ module Test
|
|
166
195
|
|
167
196
|
end
|
168
197
|
full_message = build_message(message, <<End, expected_with_highlighting, actual_with_highlighting)
|
169
|
-
#{(' '*50 + ' Expected: ' + ' '*50).blue.on_white }
|
198
|
+
#{(' '*50 + ' Expected: ' + ' '*50).blue.underline.on_white }
|
170
199
|
?
|
171
|
-
#{(' '*50 + ' But was: ' + ' '*50).yellow.on_red }
|
200
|
+
#{(' '*50 + ' But was: ' + ' '*50).yellow.underline.on_red }
|
172
201
|
?
|
173
202
|
End
|
174
203
|
end
|
@@ -182,7 +211,6 @@ End
|
|
182
211
|
end # use_assert_equal_with_highlight!
|
183
212
|
|
184
213
|
end # def assert_equal_with_highlighting
|
185
|
-
alias_method :assert_equal_with_difference_highlighting, :assert_equal_with_highlighting
|
186
214
|
alias_method_chain :assert_equal, :highlighting
|
187
215
|
|
188
216
|
end
|
@@ -210,11 +238,11 @@ require 'test/unit'
|
|
210
238
|
# nice to capture the output of the failure and make an assertion against that. But I'm not sure how to do that...
|
211
239
|
|
212
240
|
class TheTest < Test::Unit::TestCase
|
213
|
-
def
|
241
|
+
def test01_single_character_differences
|
214
242
|
assert_equal <<End, <<End
|
215
243
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sagittis, augue non eleifend sodales, arcu urna congue sapien, aliquet molestie pede urna sit amet dolor. Etiam diam. Vestibulum ornare, felis et porta faucibus, magna sapien vulputate arcu, vel facilisis lectus ipsum et ipsum.
|
216
244
|
|
217
|
-
Vivamus massa odio, lacinia eu, euismod vitae, lobortis eu, erat. Duis tincidunt, neque
|
245
|
+
Vivamus massa odio, lacinia eu, euismod vitae, lobortis eu, erat. Duis tincidunt, neque ac_tincidunt convallis, nibh tellus sodales eros, ut tristique nunc purus in urna. Nullam semper. Fusce quis augue ut metus interdum congue. Duis id dolor eu mi pellentesque sagittis. Quisque imperdiet orci a odio.
|
218
246
|
End
|
219
247
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat mi. In sagittis, augue non eleifend sodales, arcu urna congue sapien, aliquet molestie pede urna sit amet dolor. Etiam diam. Vestibulum ornare, felis et porta faucibus, magna sapien vulputate arcu, vel facilisis lectus ipsum et ipsum.
|
220
248
|
|
@@ -259,10 +287,8 @@ End
|
|
259
287
|
|
260
288
|
def test07_underscores_versus_underlines
|
261
289
|
assert_equal <<End, <<End
|
262
|
-
If you look really closely, you'll see that underscores are a brighter color (bold), while spaces appear somewhaat faded, less visible:
|
263
290
|
___[Underscores]___[Underscores] [Spaces] _ _ _ _ _ [Mix]
|
264
291
|
End
|
265
|
-
If you look really closely, you'll see that underscores are a brighter color (bold), while spaces appear somewhaat faded, less visible:
|
266
292
|
[Spaces] ___[Underscores] [Spaces] _ _ __ _ _[Mix]
|
267
293
|
End
|
268
294
|
end
|
@@ -283,6 +309,13 @@ End
|
|
283
309
|
assert_equal 'really long string', 'another really long string'
|
284
310
|
end
|
285
311
|
end
|
312
|
+
def test12_compatibility__using_arg3_as_message
|
313
|
+
assert_equal 'really long string', 'another really long string', 'This is my message! Can you see it?'
|
314
|
+
end
|
315
|
+
def test13_that_assert_nil_still_works
|
316
|
+
# Exposed a bug that existed previously, where it tried to do "".delete(:message)
|
317
|
+
assert_nil nil
|
318
|
+
end
|
286
319
|
|
287
320
|
end
|
288
321
|
=end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: qualitysmith_extensions
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.0.33
|
7
|
+
date: 2007-05-01 00:00:00 -07:00
|
8
8
|
summary: A collection of reusable Ruby methods developed by QualitySmith.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/qualitysmith_extensions/date/month_ranges.rb
|
69
69
|
- lib/qualitysmith_extensions/time/deprecated.rb
|
70
70
|
- lib/qualitysmith_extensions/time/all.rb
|
71
|
+
- lib/qualitysmith_extensions/regexp/join.rb
|
71
72
|
- lib/qualitysmith_extensions/mutex/if_available.rb
|
72
73
|
- lib/qualitysmith_extensions/console/command.rb
|
73
74
|
- lib/qualitysmith_extensions/console/command.facets.1.8.54.rb
|