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
- underline_spaces.
31
- green.
32
- send_unless(self == ' ', :bold) # spaces are not bold, '_'s (and everything else) are
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
- underline_spaces.
39
- red.
40
- send_unless(self == ' ', :bold) # spaces are not bold, '_'s (and everything else) are
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
- underline_spaces.
47
- yellow
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.on_yellow.bold
54
+ self.white.on_cyan.bold
52
55
  end
53
- def underline_spaces
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(' ', ' '.underline)
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
- # Rather than showing the expected and the actual and asking the user to painstakingly compare the two and figure out the
102
- # commonalities and differences himself, this method will highlight the differences for the user (in color), so that they
103
- # can be spotted in less than an instant!
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
- # Strings:
106
- # Does a characterwise comparison between the two strings.
107
- # Common characters are displayed in green, different characters in red, and characters that exist in one but not the
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
- # Difference in method signature from assert_equal_without_difference_highlighting:
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
- # By default, highlighting is only used when one or both of the strings being compared is long/multiline. You can override the default with the <tt>:higlight</tt> option:
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
- # * Spaces are displayed with an underline so that they are actually visible on the screen.
130
- # * Newlines are displayed as the text '\n' followed by an actual newline.
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
- # Advanced:
133
- # * If you want everything to be escaped (so you can see the color *codes* instead of the color itself, for example), use :inspect_strings => true
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
- message = options.delete(:message) || nil
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 << ' '.highlight_absence
184
+ actual_with_highlighting << '~'.highlight_absence
155
185
  elsif exp.nil?
156
- expected_with_highlighting << ' '.highlight_absence
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 test01_single_character_difference
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 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.
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.29
7
- date: 2007-04-30 00:00:00 -07:00
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