shell_test 0.1.0 → 0.2.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.
data/History.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.2.0 2011/08/03
2
+
3
+ * Split out a StringMethods module [issue #7]
4
+ * Renamed assert_output_equal to assert_str_equal and assert_alike to
5
+ assert_str_match.
6
+ * Added FileMethods#_prepare and made prepare outdent content [issue #9]
7
+ * Added content, mode, and glob to FileMethods [issue #10]
8
+ * Added FileMethods#prepare_dir
9
+
1
10
  == 0.1.0 2011/07/07
2
11
 
3
12
  Initial release.
data/README.rdoc CHANGED
@@ -130,7 +130,7 @@ ShellTest is available as a gem[http://rubygems.org/gems/shell_test].
130
130
 
131
131
  To get started, checkout the code from GitHub[http://github.com/thinkerbot/shell_test] and run:
132
132
 
133
- git clone https://thinkerbot@github.com/thinkerbot/shell_test.git
133
+ git clone git://github.com/thinkerbot/shell_test.git
134
134
  cd shell_test
135
135
  rake test
136
136
 
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'shell_test/string_methods'
2
3
 
3
4
  module ShellTest
4
5
  module FileMethods
@@ -124,17 +125,25 @@ module ShellTest
124
125
  end
125
126
  end
126
127
 
128
+ include StringMethods
127
129
  extend ModuleMethods
128
130
 
131
+ # Calls cleanup to remove any files left over from previous test runs (for
132
+ # instance by running with a flag to keep outputs).
129
133
  def setup
130
134
  super
131
135
  cleanup
132
136
  end
133
137
 
138
+ # Generic cleanup method. Returns users to the user_dir then calls
139
+ # cleanup unless keep_outputs? returns true. If cleanup is called, any
140
+ # empty directories under method_dir are also removed.
141
+ #
142
+ # Be sure to call super if teardown is overridden in a test case.
134
143
  def teardown
135
144
  Dir.chdir(user_dir)
136
145
 
137
- unless ENV["KEEP_OUTPUTS"] == "true"
146
+ unless keep_outputs?
138
147
  cleanup
139
148
 
140
149
  dir = method_dir
@@ -147,50 +156,74 @@ module ShellTest
147
156
  super
148
157
  end
149
158
 
159
+ # Returns true if KEEP_OUTPUTS is set to 'true' in ENV.
160
+ def keep_outputs?
161
+ ENV["KEEP_OUTPUTS"] == "true"
162
+ end
163
+
164
+ # Returns the absolute path to the current working directory.
150
165
  def user_dir
151
166
  @user_dir ||= File.expand_path('.')
152
167
  end
153
168
 
169
+ # Returns the absolute path to a directory specific to the current test
170
+ # class, specifically the class.class_dir expanded relative to the
171
+ # user_dir.
154
172
  def class_dir
155
173
  @class_dir ||= File.expand_path(self.class.class_dir, user_dir)
156
174
  end
157
175
 
176
+ # Returns the absolute path to a directory specific to the current test
177
+ # method, specifically method_name expanded relative to class_dir.
158
178
  def method_dir
159
179
  @method_dir ||= File.expand_path(method_name.to_s, class_dir)
160
180
  end
161
181
 
182
+ # Returns the method name of the current test.
183
+ #
184
+ # Really this method is an alias for __name__ which is present in
185
+ # MiniTest::Unit and reproduces the method_name in Test::Unit.
186
+ # ShellTest::Unit ensures this method is set up correctly in those
187
+ # frameworks. If this module is used in other frameworks, then
188
+ # method_name must be implemented separately.
162
189
  def method_name
163
190
  __name__
164
191
  end
165
192
 
166
- def cleanup_methods
167
- self.class.cleanup_methods
168
- end
169
-
170
- def cleanup
171
- if cleanup_paths = cleanup_methods[method_name.to_sym]
172
- cleanup_paths.each {|relative_path| remove(relative_path) }
173
- end
174
- end
175
-
193
+ # Expands relative_path relative to method_dir and returns the resulting
194
+ # absolute path. Raises an error if the resulting path is not relative to
195
+ # method_dir.
176
196
  def path(relative_path)
177
- path = File.expand_path(relative_path, method_dir)
197
+ full_path = File.expand_path(relative_path, method_dir)
178
198
 
179
- unless path.index(method_dir) == 0
199
+ unless full_path.index(method_dir) == 0
180
200
  raise "does not make a path relative to method_dir: #{relative_path.inspect}"
181
201
  end
182
202
 
183
- path
203
+ full_path
184
204
  end
185
205
 
186
- def prepare(relative_path, content=nil, &block)
206
+ # Globs the pattern under method_dir.
207
+ def glob(pattern)
208
+ Dir.glob path(pattern)
209
+ end
210
+
211
+ # Creates a directory under method_dir.
212
+ def prepare_dir(relative_path)
213
+ target_dir = path(relative_path)
214
+ FileUtils.mkdir_p(target_dir)
215
+ target_dir
216
+ end
217
+
218
+ # Same as prepare but does not outdent content.
219
+ def _prepare(relative_path, content=nil, &block)
187
220
  target = path(relative_path)
188
221
 
189
222
  if File.exists?(target)
190
223
  FileUtils.rm(target)
191
224
  else
192
225
  target_dir = File.dirname(target)
193
- FileUtils.mkdir_p(target_dir) unless File.exists?(target_dir)
226
+ FileUtils.mkdir_p(target_dir)
194
227
  end
195
228
 
196
229
  FileUtils.touch(target)
@@ -200,9 +233,54 @@ module ShellTest
200
233
  target
201
234
  end
202
235
 
236
+ # Creates a file under method_dir with the specified content, which may be
237
+ # provided as a string or with a block (the block recieves an open File).
238
+ # If no content is given, then an empty file is created.
239
+ #
240
+ # Content provided as a string is outdented (see StringMethods#outdent),
241
+ # so this syntax is possible:
242
+ #
243
+ # path = prepare 'file', %{
244
+ # line one
245
+ # line two
246
+ # }
247
+ # File.read(path) # => "line one\nline two\n"
248
+ #
249
+ # Returns the absolute path to the new file.
250
+ def prepare(relative_path, content=nil, &block)
251
+ content = outdent(content) if content
252
+ _prepare(relative_path, content, &block)
253
+ end
254
+
255
+ # Returns the content of the file under method_dir, if it exists.
256
+ def content(relative_path, length=nil, offset=nil)
257
+ full_path = path(relative_path)
258
+ File.exists?(full_path) ? File.read(full_path, length, offset) : nil
259
+ end
260
+
261
+ # Returns the formatted string mode (ex '100640') of the file under
262
+ # method_dir, if it exists.
263
+ def mode(relative_path)
264
+ full_path = path(relative_path)
265
+ File.exists?(full_path) ? sprintf("%o", File.stat(full_path).mode) : nil
266
+ end
267
+
268
+ # Removes a file or directory under method_dir, if it exists.
203
269
  def remove(relative_path)
204
270
  full_path = path(relative_path)
205
271
  FileUtils.rm_r(full_path) if File.exists?(full_path)
206
272
  end
273
+
274
+ # Shortcut to access the class.cleanup_methods.
275
+ def cleanup_methods
276
+ self.class.cleanup_methods
277
+ end
278
+
279
+ # Recursively removes paths specified for cleanup in cleanup_methods.
280
+ def cleanup
281
+ if cleanup_paths = cleanup_methods[method_name.to_sym]
282
+ cleanup_paths.each {|relative_path| remove(relative_path) }
283
+ end
284
+ end
207
285
  end
208
286
  end
@@ -1,8 +1,11 @@
1
1
  require 'shell_test/regexp_escape'
2
2
  require 'shell_test/command_parser'
3
+ require 'shell_test/string_methods'
3
4
 
4
5
  module ShellTest
5
6
  module ShellMethods
7
+ include StringMethods
8
+
6
9
  def setup
7
10
  super
8
11
  @notify_method_name = true
@@ -86,7 +89,7 @@ module ShellTest
86
89
  parse_script(script, options).each do |cmd, output, status|
87
90
  result = sh(cmd)
88
91
 
89
- _assert_output_equal(output, result, cmd) if output
92
+ _assert_str_equal(output, result, cmd) if output
90
93
  assert_equal(status, $?.exitstatus, cmd) if status
91
94
  end
92
95
  end
@@ -99,78 +102,9 @@ module ShellTest
99
102
  parse_script(script, options).each do |cmd, output, status|
100
103
  result = sh(cmd)
101
104
 
102
- _assert_alike(output, result, cmd) if output
105
+ _assert_str_match(output, result, cmd) if output
103
106
  assert_equal(status, $?.exitstatus, cmd) if status
104
107
  end
105
108
  end
106
-
107
- # Asserts whether or not the a and b strings are equal, with a more
108
- # readable output than assert_equal for large strings (especially large
109
- # strings with significant whitespace).
110
- def assert_output_equal(a, b, msg=nil)
111
- _assert_output_equal outdent(a), b, msg
112
- end
113
-
114
- def _assert_output_equal(a, b, msg=nil)
115
- if a == b
116
- assert true
117
- else
118
- flunk %Q{
119
- #{msg}
120
- ==================== expected output ====================
121
- #{whitespace_escape(a)}
122
- ======================== but was ========================
123
- #{whitespace_escape(b)}
124
- =========================================================
125
- }
126
- end
127
- end
128
-
129
- # Asserts whether or not b is like a (which should be a Regexp), and
130
- # provides a more readable output in the case of a failure as compared
131
- # with assert_match.
132
- #
133
- # If a is a string it is turned into a RegexpEscape.
134
- def assert_alike(a, b, msg=nil)
135
- a = outdent(a) if a.kind_of?(String)
136
- _assert_alike a, b, msg
137
- end
138
-
139
- def _assert_alike(a, b, msg=nil)
140
- if a.kind_of?(String)
141
- a = RegexpEscape.new(a)
142
- end
143
-
144
- if b =~ a
145
- assert true
146
- else
147
- flunk %Q{
148
- #{msg}
149
- ================= expected output like ==================
150
- #{whitespace_escape(a)}
151
- ======================== but was ========================
152
- #{whitespace_escape(b)}
153
- =========================================================
154
- }
155
- end
156
- end
157
-
158
- # helper for stripping indentation off a string
159
- def outdent(str)
160
- str =~ /\A(?:\s*?\n)( *)(.*)\z/m ? $2.gsub!(/^ {0,#{$1.length}}/, '') : str
161
- end
162
-
163
- # helper for formatting escaping whitespace into readable text
164
- def whitespace_escape(str)
165
- str.to_s.gsub(/\s/) do |match|
166
- case match
167
- when "\n" then "\\n\n"
168
- when "\t" then "\\t"
169
- when "\r" then "\\r"
170
- when "\f" then "\\f"
171
- else match
172
- end
173
- end
174
- end
175
109
  end
176
110
  end
@@ -0,0 +1,72 @@
1
+ module ShellTest
2
+ module StringMethods
3
+ # Asserts whether or not the a and b strings are equal, with a more
4
+ # readable output than assert_equal for large strings (especially large
5
+ # strings with significant whitespace).
6
+ def assert_str_equal(a, b, msg=nil)
7
+ _assert_str_equal outdent(a), b, msg
8
+ end
9
+
10
+ def _assert_str_equal(a, b, msg=nil)
11
+ if a == b
12
+ assert true
13
+ else
14
+ flunk %Q{
15
+ #{msg}
16
+ ==================== expected output ====================
17
+ #{whitespace_escape(a)}
18
+ ======================== but was ========================
19
+ #{whitespace_escape(b)}
20
+ =========================================================
21
+ }
22
+ end
23
+ end
24
+
25
+ # Asserts whether or not b is like a (which should be a Regexp), and
26
+ # provides a more readable output in the case of a failure as compared
27
+ # with assert_match.
28
+ #
29
+ # If a is a string it is turned into a RegexpEscape.
30
+ def assert_str_match(a, b, msg=nil)
31
+ a = outdent(a) if a.kind_of?(String)
32
+ _assert_str_match a, b, msg
33
+ end
34
+
35
+ def _assert_str_match(a, b, msg=nil)
36
+ if a.kind_of?(String)
37
+ a = RegexpEscape.new(a)
38
+ end
39
+
40
+ if b =~ a
41
+ assert true
42
+ else
43
+ flunk %Q{
44
+ #{msg}
45
+ ================= expected output like ==================
46
+ #{whitespace_escape(a)}
47
+ ======================== but was ========================
48
+ #{whitespace_escape(b)}
49
+ =========================================================
50
+ }
51
+ end
52
+ end
53
+
54
+ # helper for stripping indentation off a string
55
+ def outdent(str)
56
+ str =~ /\A(?:\s*?\n)( *)(.*)\z/m ? $2.gsub!(/^ {0,#{$1.length}}/, '') : str
57
+ end
58
+
59
+ # helper for formatting escaping whitespace into readable text
60
+ def whitespace_escape(str)
61
+ str.to_s.gsub(/\s/) do |match|
62
+ case match
63
+ when "\n" then "\\n\n"
64
+ when "\t" then "\\t"
65
+ when "\r" then "\\r"
66
+ when "\f" then "\\f"
67
+ else match
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -34,6 +34,8 @@ class Test::Unit::TestResult
34
34
  @skips ||= []
35
35
  end
36
36
 
37
+ alias shell_test_original_add_error add_error
38
+
37
39
  # Partition errors from a SkipException from other errors and records as
38
40
  # them as skips (the error is extended to display as a skip).
39
41
  def add_error(error)
@@ -1,3 +1,3 @@
1
1
  module ShellTest
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shell_test
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
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
  - Simon Chiang
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-07 00:00:00 -06:00
18
+ date: 2011-08-03 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -36,6 +36,7 @@ files:
36
36
  - lib/shell_test/file_methods.rb
37
37
  - lib/shell_test/regexp_escape.rb
38
38
  - lib/shell_test/shell_methods.rb
39
+ - lib/shell_test/string_methods.rb
39
40
  - lib/shell_test/unit.rb
40
41
  - lib/shell_test/unit/shim.rb
41
42
  - lib/shell_test/version.rb