assert 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ module Assert::RakeTasks
2
+ class Irb
3
+
4
+ def self.file_name
5
+ "irb.rb"
6
+ end
7
+
8
+ def self.task_name
9
+ :irb
10
+ end
11
+
12
+ def initialize(test_root)
13
+ @test_root = test_root
14
+ end
15
+
16
+ def file_path
17
+ File.join(@test_root.to_s, self.class.file_name)
18
+ end
19
+
20
+ def helper_exists?
21
+ File.exists?(self.file_path)
22
+ end
23
+
24
+ def description
25
+ "Open irb preloaded with #{self.file_path}"
26
+ end
27
+
28
+ def cmd
29
+ "irb -rubygems -r ./#{self.file_path}"
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,73 @@
1
+ require 'rake/tasklib'
2
+ require 'assert/rake_tasks/test_task'
3
+
4
+ module Assert::RakeTasks
5
+ class Scope
6
+
7
+ def self.test_file_suffix
8
+ "_test.rb"
9
+ end
10
+
11
+ def initialize(path)
12
+ @path = path
13
+ end
14
+
15
+ def namespace
16
+ File.basename(@path).to_sym
17
+ end
18
+
19
+ # nested test files under the path
20
+ def nested_files
21
+ nested_files = Rake::FileList["#{@path}/**/*#{self.class.test_file_suffix}"]
22
+ end
23
+
24
+ # a list with the path test file "#{path}_test.rb" (if it exists)
25
+ def path_file_list
26
+ path_file_name = @path+self.class.test_file_suffix
27
+ (File.exists?(path_file_name) ? Rake::FileList[path_file_name] : [])
28
+ end
29
+
30
+ # return a test task covering the scopes nested files plus path file
31
+ # but only if there are nested files
32
+ def to_test_task
33
+ if !self.nested_files.empty?
34
+ TestTask.new(@path) do |tt|
35
+ tt.files = self.path_file_list + self.nested_files
36
+ end
37
+ end
38
+ end
39
+
40
+ # a collection of test tasks for every standalone child test file
41
+ def test_tasks
42
+ # get immediate child test files
43
+ Dir.glob("#{@path}/*#{self.class.test_file_suffix}").collect do |f|
44
+ # get just the path name for each file
45
+ File.join(File.dirname(f), File.basename(f, self.class.test_file_suffix))
46
+ end.reject do |p|
47
+ # reject any that have deeply nested test files
48
+ !Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
49
+ end.collect do |p|
50
+ # build a test task for the standalone test file of the path
51
+ TestTask.new(p) do |tt|
52
+ tt.files = Rake::FileList[p+self.class.test_file_suffix]
53
+ end
54
+ end
55
+ end
56
+
57
+ # a collection of scopes for every child test dir or test dir/file combo
58
+ def scopes
59
+ # get immediate child paths
60
+ Dir.glob("#{@path}/*").collect do |p|
61
+ # get just the path name for each dir/file and uniq it
62
+ File.join(File.dirname(p), File.basename(p, self.class.test_file_suffix))
63
+ end.uniq.select do |p|
64
+ # select any that have deeply nested test files
65
+ !Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
66
+ end.collect do |p|
67
+ # build a scope for each path
68
+ self.class.new(p)
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,63 @@
1
+ require 'assert/rake_tasks/scope'
2
+
3
+ module Assert::RakeTasks
4
+
5
+ class TestTask
6
+
7
+ attr_accessor :name, :path, :files
8
+
9
+ # Create a testing task
10
+ def initialize(path)
11
+ @path = path
12
+ @files = []
13
+ yield self if block_given?
14
+ end
15
+
16
+ def relative_path
17
+ File.join(@path.to_s.split(File::SEPARATOR)[1..-1])
18
+ end
19
+
20
+ def scope_description
21
+ relative_path.empty? ? "" : " for #{relative_path}"
22
+ end
23
+
24
+ def description
25
+ "Run all tests#{scope_description}"
26
+ end
27
+
28
+ def name
29
+ File.basename(@path, Scope.test_file_suffix).to_sym
30
+ end
31
+
32
+ def file_list # :nodoc:
33
+ self.files.collect{|f| "\"#{f}\""}.join(' ')
34
+ end
35
+
36
+ def ruby_args
37
+ [ "-rrubygems",
38
+ "\"#{self.rake_loader}\"",
39
+ self.file_list
40
+ ].compact.join(" ")
41
+ end
42
+
43
+ def show_loaded_files?
44
+ ENV["show_loaded_files"] == 'true'
45
+ end
46
+
47
+ protected
48
+
49
+ def rake_loader
50
+ find_file('rake/rake_test_loader')
51
+ end
52
+
53
+ def find_file(fn) # :nodoc:
54
+ $LOAD_PATH.each do |path|
55
+ file_path = File.join(path, "#{fn}.rb")
56
+ return file_path if File.exist? file_path
57
+ end
58
+ nil
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -3,11 +3,10 @@ module Assert::Result
3
3
 
4
4
  class Base; end
5
5
  class Pass < Base; end
6
- class Fail < Base; end
7
6
  class Ignore < Base; end
8
- class FromException < Base; end
9
- class Error < FromException; end
10
- class Skip < FromException; end
7
+ class Fail < Base; end
8
+ class Error < Base; end
9
+ class Skip < Base; end
11
10
 
12
11
  class << self
13
12
  def types
@@ -39,7 +38,6 @@ module Assert::Result
39
38
 
40
39
  # './lib' in project dir, or '/usr/local/blahblah' if installed
41
40
  ASSERT_DIR = File.dirname(File.dirname(file))
42
- MACROS_DIR = File.join(File.dirname(file), 'macros')
43
41
 
44
42
  def initialize(value=nil)
45
43
  super(value || ["No backtrace"])
@@ -66,7 +64,7 @@ module Assert::Result
66
64
  protected
67
65
 
68
66
  def filter_out?(line)
69
- line.rindex(ASSERT_DIR, 0) && !line.rindex(MACROS_DIR, 0)
67
+ line.rindex(ASSERT_DIR, 0)
70
68
  end
71
69
 
72
70
  end
@@ -76,11 +74,11 @@ module Assert::Result
76
74
 
77
75
  class Base
78
76
 
79
- attr_reader :test_name, :message, :backtrace
77
+ attr_reader :test, :message, :backtrace
80
78
 
81
- def initialize(test_name, message, backtrace=nil)
79
+ def initialize(test, message, backtrace=nil)
80
+ @test = test
82
81
  @backtrace = Backtrace.new(backtrace)
83
- @test_name = test_name
84
82
  @message = message && !message.empty? ? message : nil
85
83
  end
86
84
 
@@ -88,10 +86,21 @@ module Assert::Result
88
86
  define_method("#{meth}?") { false }
89
87
  end
90
88
 
89
+ def test_name
90
+ @test.name
91
+ end
92
+
91
93
  def to_sym; nil; end
92
94
 
93
95
  def to_s
94
- [self.test_name, self.message, self.trace].compact.join("\n")
96
+ [ "#{self.name.upcase}: #{self.test_name}",
97
+ self.message,
98
+ self.trace
99
+ ].compact.join("\n")
100
+ end
101
+
102
+ def name
103
+ ""
95
104
  end
96
105
 
97
106
  def trace
@@ -109,58 +118,97 @@ module Assert::Result
109
118
  end
110
119
 
111
120
  class Pass < Base
121
+
112
122
  def pass?; true; end
113
- def to_sym; :passed; end
123
+ def to_sym; :pass; end
114
124
 
115
- def to_s
116
- "PASS: #{super}"
125
+ def name
126
+ "Pass"
117
127
  end
118
- end
119
-
120
- class Fail < Base
121
- def fail?; true; end
122
- def to_sym; :failed; end
123
128
 
124
- def to_s
125
- "FAIL: #{super}"
126
- end
127
129
  end
128
130
 
129
131
  class Ignore < Base
132
+
130
133
  def ignore?; true; end
131
- def to_sym; :ignored; end
134
+ def to_sym; :ignore; end
132
135
 
133
- def to_s
134
- "IGNORE: #{super}"
136
+ def name
137
+ "Ignore"
135
138
  end
139
+
136
140
  end
137
141
 
138
- # Error and Skip results are built from exceptions being raised
139
- class FromException < Base
140
- def initialize(test_name, exception)
141
- super(test_name, exception.message, exception.backtrace || [])
142
+ # raised by the 'fail' context helper to break test execution
143
+ # (if Test.halt_on_fail?)
144
+ class TestFailure < RuntimeError; end
145
+
146
+ class Fail < Base
147
+
148
+ # fail results can be generated manually or by raising Assert::Result::TestFailure
149
+ def initialize(test, message_or_exception, backtrace=nil)
150
+ if message_or_exception.kind_of?(TestFailure)
151
+ super(test, message_or_exception.message, message_or_exception.backtrace || [])
152
+ elsif message_or_exception.kind_of?(Exception)
153
+ raise ArgumentError, "generate fail results by raising Assert::Result::TestFailure"
154
+ else
155
+ super(test, message_or_exception, backtrace)
156
+ end
157
+ end
158
+
159
+ def fail?; true; end
160
+ def to_sym; :fail; end
161
+
162
+ def name
163
+ "Fail"
142
164
  end
165
+
166
+ # override of the base, show the test's context info called_from
167
+ def trace
168
+ self.test.context_info.called_from
169
+ end
170
+
143
171
  end
144
172
 
145
173
  # raised by the 'skip' context helper to break test execution
146
174
  class TestSkipped < RuntimeError; end
147
175
 
148
- class Skip < FromException
176
+ class Skip < Base
177
+
178
+ # skip results are generated by raising Assert::Result::TestSkipped
179
+ def initialize(test, exception)
180
+ if exception.kind_of?(TestSkipped)
181
+ super(test, exception.message, exception.backtrace || [])
182
+ else
183
+ raise ArgumentError, "generate skip results by raising Assert::Result::TestSkipped"
184
+ end
185
+ end
186
+
149
187
  def skip?; true; end
150
- def to_sym; :skipped; end
188
+ def to_sym; :skip; end
151
189
 
152
- def to_s
153
- "SKIP: #{super}"
190
+ def name
191
+ "Skip"
154
192
  end
193
+
155
194
  end
156
195
 
157
- class Error < FromException
196
+ class Error < Base
197
+
198
+ # error results are generated by raising exceptions in tests
199
+ def initialize(test, exception)
200
+ if exception.kind_of?(Exception)
201
+ super(test, "#{exception.message} (#{exception.class.name})", exception.backtrace || [])
202
+ else
203
+ raise ArgumentError, "generate error results by raising an exception"
204
+ end
205
+ end
158
206
 
159
207
  def error?; true; end
160
- def to_sym; :errored; end
208
+ def to_sym; :error; end
161
209
 
162
- def to_s
163
- "ERROR: #{super}"
210
+ def name
211
+ "Error"
164
212
  end
165
213
 
166
214
  # override of the base, always show the full unfiltered backtrace for errors
@@ -11,7 +11,7 @@ module Assert
11
11
  class << self
12
12
 
13
13
  USER_TEST_HELPER = "~/.assert/options"
14
-
14
+
15
15
  # assume the test dir path is ./test and look for helpers in ./test/helper.rb
16
16
  def package_test_dir
17
17
  "test"
@@ -34,7 +34,9 @@ module Assert
34
34
 
35
35
  def require_user_test_helper
36
36
  begin
37
- require File.expand_path(USER_TEST_HELPER)
37
+ if ENV['HOME']
38
+ require File.expand_path(USER_TEST_HELPER)
39
+ end
38
40
  rescue LoadError => err
39
41
  # do nothing
40
42
  end
@@ -45,7 +47,7 @@ module Assert
45
47
  begin
46
48
  require package_helper_file(root_path)
47
49
  rescue LoadError => err
48
- warn err.message
50
+ # do nothing
49
51
  end
50
52
  end
51
53
 
@@ -57,7 +59,8 @@ module Assert
57
59
  # this expects the caller's root path to be the parent dir of the first
58
60
  # parent dir of caller named TEST_DIR
59
61
  def caller_root_path(caller_info)
60
- caller_dirname = File.expand_path(File.dirname(caller_info[0]))
62
+ non_custom_require_caller_info = caller_info.reject{|i| i =~ /rubygems\/custom_require.rb/}
63
+ caller_dirname = File.expand_path(File.dirname(non_custom_require_caller_info[0]))
61
64
  test_dir_pos = caller_dirname.index(package_test_helper_regex)
62
65
  if test_dir_pos && (test_dir_pos > 0)
63
66
  caller_dirname[0..(test_dir_pos-1)]
@@ -1,15 +1,38 @@
1
1
  require 'assert/test'
2
2
 
3
3
  module Assert
4
- class Suite < ::Hash
4
+ class Suite
5
+
6
+ class ContextInfo
7
+
8
+ attr_reader :klass, :called_from, :file
9
+
10
+ def initialize(klass, called_from=nil)
11
+ @klass = klass
12
+ @called_from = called_from
13
+ @file = if called_from
14
+ called_from.gsub(/\:[0-9]+.*$/, '')
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ TEST_METHOD_REGEX = /^test./
5
21
 
6
22
  # A suite is a set of tests to run. When a test class subclasses
7
23
  # the Context class, that test class is pushed to the suite.
8
24
 
9
- attr_accessor :start_time, :end_time
25
+ attr_accessor :tests, :test_methods, :start_time, :end_time
26
+
27
+ def initialize
28
+ @tests = []
29
+ @test_methods = []
30
+ @start_time = 0
31
+ @end_time = 0
32
+ end
10
33
 
11
34
  def run_time
12
- (@end_time || 0) - (@start_time || 0)
35
+ @end_time - @start_time
13
36
  end
14
37
 
15
38
  def runner_seed
@@ -19,42 +42,12 @@ module Assert
19
42
  end).to_i
20
43
  end
21
44
 
22
- def <<(context_klass)
23
- # gsub off any trailing 'Test'
24
- self[context_klass] ||= []
25
- end
26
-
27
- def contexts
28
- self.keys.sort{|a,b| a.to_s <=> b.to_s}
29
- end
30
-
31
- def tests
32
- prep
33
- self.values.flatten
34
- end
35
-
36
- def ordered_tests(klass=nil)
37
- prep
38
- (klass.nil? ? self.contexts : [klass]).inject([]) do |tests, klass|
39
- tests += (self[klass] || [])
40
- end
41
- end
42
-
43
- def ordered_results(klass=nil)
44
- ordered_tests(klass).inject([]) do |results, test|
45
- results += test.results
46
- end
47
- end
45
+ alias_method :ordered_tests, :tests
48
46
 
49
- def test_count(klass=nil)
50
- prep
51
- count_tests(klass.nil? ? self.values : [self[klass]])
52
- end
53
-
54
- def result_count(type=nil)
55
- prep
56
- count_results(self.values, type)
47
+ def results
48
+ tests.inject([]) {|results, test| results += test.results}
57
49
  end
50
+ alias_method :ordered_results, :results
58
51
 
59
52
  def count(thing)
60
53
  case thing
@@ -77,6 +70,20 @@ module Assert
77
70
  end
78
71
  end
79
72
 
73
+ def test_count
74
+ self.tests.size
75
+ end
76
+
77
+ def result_count(type=nil)
78
+ if type
79
+ self.tests.inject(0) do |count, test|
80
+ count += test.result_count(type)
81
+ end
82
+ else
83
+ self.results.size
84
+ end
85
+ end
86
+
80
87
  def setup(&block)
81
88
  if block_given?
82
89
  self.setups << block
@@ -119,30 +126,7 @@ module Assert
119
126
  methods += local_methods
120
127
 
121
128
  # uniq and remove any that don't start with 'test'
122
- methods.uniq.delete_if {|method_name| method_name !~ /^test./ }
123
- end
124
-
125
- private
126
-
127
- def count_tests(test_sets)
128
- test_sets.inject(0) {|count, tests| count += tests.size}
129
- end
130
-
131
- def count_results(test_sets, type)
132
- self.values.flatten.inject(0){|count, test| count += test.result_count(type) }
133
- end
134
-
135
- def prep
136
- if @prepared != true
137
- # look for local public methods starting with 'test_'and add
138
- self.each do |context_class, tests|
139
- local_public_test_methods(context_class).each do |meth|
140
- tests << Test.new(meth.to_s, context_class, meth)
141
- end
142
- tests.uniq
143
- end
144
- end
145
- @prepared = true
129
+ methods.uniq.delete_if {|method_name| method_name !~ TEST_METHOD_REGEX }
146
130
  end
147
131
 
148
132
  end