assert 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Gemfile.lock +3 -1
  2. data/README.rdoc +6 -6
  3. data/Rakefile +2 -3
  4. data/assert.gemspec +1 -0
  5. data/lib/assert/assertions.rb +30 -30
  6. data/lib/assert/context.rb +71 -66
  7. data/lib/assert/macro.rb +14 -0
  8. data/lib/assert/macros/methods.rb +52 -0
  9. data/lib/assert/rake_tasks.rb +31 -13
  10. data/lib/assert/result.rb +12 -4
  11. data/lib/assert/result_set.rb +2 -2
  12. data/lib/assert/runner.rb +2 -6
  13. data/lib/assert/setup/autorun.rb +0 -1
  14. data/lib/assert/suite.rb +19 -15
  15. data/lib/assert/test.rb +6 -17
  16. data/lib/assert/version.rb +1 -1
  17. data/lib/assert/view/base.rb +1 -1
  18. data/lib/assert/view/terminal.rb +8 -30
  19. data/test/assertions/assert_block_test.rb +1 -1
  20. data/test/assertions/assert_empty_test.rb +43 -0
  21. data/test/assertions/assert_equal_test.rb +43 -0
  22. data/test/assertions/assert_includes_test.rb +44 -0
  23. data/test/assertions/assert_instance_of_test.rb +4 -4
  24. data/test/assertions/assert_kind_of_test.rb +3 -3
  25. data/test/assertions/assert_match_test.rb +43 -0
  26. data/test/assertions/assert_nil_test.rb +43 -0
  27. data/test/assertions/assert_not_block_test.rb +1 -1
  28. data/test/assertions/assert_not_empty_test.rb +43 -0
  29. data/test/assertions/assert_not_equal_test.rb +43 -0
  30. data/test/assertions/assert_not_included_test.rb +44 -0
  31. data/test/assertions/assert_not_instance_of_test.rb +4 -4
  32. data/test/assertions/assert_not_kind_of_test.rb +2 -2
  33. data/test/assertions/assert_not_match_test.rb +43 -0
  34. data/test/assertions/assert_not_nil_test.rb +43 -0
  35. data/test/assertions/assert_not_respond_to_test.rb +6 -6
  36. data/test/assertions/assert_not_same_test.rb +45 -0
  37. data/test/assertions/assert_respond_to_test.rb +6 -6
  38. data/test/assertions/assert_same_test.rb +45 -0
  39. data/test/assertions_test.rb +21 -298
  40. data/test/context/class_methods_test.rb +81 -112
  41. data/test/context_test.rb +35 -40
  42. data/test/helper.rb +5 -2
  43. data/test/irb.rb +2 -5
  44. data/test/macro_test.rb +99 -0
  45. data/test/options_test.rb +2 -2
  46. data/test/result_set_test.rb +47 -54
  47. data/test/result_test.rb +4 -17
  48. data/test/runner_test.rb +2 -10
  49. data/test/suite_test.rb +85 -13
  50. data/test/test/running_test.rb +19 -28
  51. data/test/test_test.rb +130 -128
  52. data/test/view_test.rb +3 -17
  53. metadata +50 -7
@@ -6,6 +6,26 @@ module Assert::RakeTasks
6
6
 
7
7
  FILE_SUFFIX = "_test.rb"
8
8
 
9
+ # Setup the rake tasks for testing
10
+ # * add 'include Assert::RakeTasks' to your Rakefile
11
+ def self.included(receiver)
12
+ # get rid of rake warnings
13
+ if defined?(::Rake::DSL)
14
+ receiver.send :include, ::Rake::DSL
15
+ end
16
+
17
+ # auto-build rake tasks for the ./test files (if defined in ./test)
18
+ self.for(:test) if File.exists?(File.expand_path('./test', Dir.pwd))
19
+ end
20
+
21
+ def self.for(test_namespace = :test)
22
+ self.irb_task(test_namespace.to_s)
23
+ self.to_tasks(test_namespace.to_s)
24
+ end
25
+
26
+
27
+
28
+
9
29
  class TestTask < Rake::TaskLib
10
30
  attr_accessor :name, :description, :test_files
11
31
 
@@ -46,11 +66,6 @@ module Assert::RakeTasks
46
66
  end
47
67
 
48
68
  class << self
49
- def for(test_namespace = :test)
50
- self.irb_task(test_namespace.to_s)
51
- self.to_tasks(test_namespace.to_s)
52
- end
53
-
54
69
  def irb_task(path)
55
70
  irb_file = File.join(path, "irb.rb")
56
71
  if File.exist?(irb_file)
@@ -64,28 +79,31 @@ module Assert::RakeTasks
64
79
  def to_tasks(path)
65
80
  suite_name = File.basename(path)
66
81
 
67
- # define a rake test task for all top-level test files at this path
82
+ # define a rake test task for all test files that have addional sub-folder tests
68
83
  if !Dir.glob(File.join(path, "**/*#{FILE_SUFFIX}")).empty?
69
84
  TestTask.new(suite_name.to_sym) do |t|
70
85
  file_location = suite_name == path ? '' : " for #{File.join(path.split(File::SEPARATOR)[1..-1])}"
71
86
  t.description = "Run all tests#{file_location}"
72
- t.test_files = FileList["#{path}/**/*#{FILE_SUFFIX}"]
87
+ t.test_files = (File.exists?(p = (path+FILE_SUFFIX)) ? FileList[p] : []) + FileList["#{path}/**/*#{FILE_SUFFIX}"]
73
88
  end.to_task
74
89
  end
75
90
 
76
91
  namespace suite_name.to_s do
77
- # define rake test tasks for each top-level test file individually
78
92
  Dir.glob(File.join(path, "*#{FILE_SUFFIX}")).each do |test_file|
79
93
  test_name = File.basename(test_file, FILE_SUFFIX)
80
- TestTask.new(test_name.to_sym) do |t|
81
- t.description = "Run tests for #{[path.split(File::SEPARATOR), test_name].flatten[1..-1].join(':')}"
82
- t.test_files = FileList[test_file]
83
- end.to_task
94
+
95
+ # define rake test task for all test files without sub-folder tests
96
+ if Dir.glob(File.join(path, test_name, "*#{FILE_SUFFIX}")).empty?
97
+ TestTask.new(test_name.to_sym) do |t|
98
+ t.description = "Run tests for #{[path.split(File::SEPARATOR), test_name].flatten[1..-1].join(':')}"
99
+ t.test_files = FileList[test_file]
100
+ end.to_task
101
+ end
84
102
  end
85
103
 
86
104
  # recursively define rake test tasks for each file
87
105
  # in each top-level directory
88
- Dir.glob(File.join(path, "*/")).each do |test_dir|
106
+ Dir.glob(File.join(path, "*")).each do |test_dir|
89
107
  self.to_tasks(test_dir)
90
108
  end
91
109
  end
data/lib/assert/result.rb CHANGED
@@ -39,6 +39,7 @@ module Assert::Result
39
39
 
40
40
  # './lib' in project dir, or '/usr/local/blahblah' if installed
41
41
  ASSERT_DIR = File.dirname(File.dirname(file))
42
+ MACROS_DIR = File.join(File.dirname(file), 'macros')
42
43
 
43
44
  def initialize(value=nil)
44
45
  super(value || ["No backtrace"])
@@ -52,15 +53,22 @@ module Assert::Result
52
53
  new_bt = []
53
54
 
54
55
  self.each do |line|
55
- break if line.rindex ASSERT_DIR, 0
56
+ break if filter_out?(line)
56
57
  new_bt << line
57
58
  end
58
59
 
59
- new_bt = self.reject { |line| line.rindex ASSERT_DIR, 0 } if new_bt.empty?
60
+ new_bt = self.reject { |line| filter_out?(line) } if new_bt.empty?
60
61
  new_bt = self.dup if new_bt.empty?
61
62
 
62
63
  self.class.new(new_bt)
63
64
  end
65
+
66
+ protected
67
+
68
+ def filter_out?(line)
69
+ line.rindex(ASSERT_DIR, 0) && !line.rindex(MACROS_DIR, 0)
70
+ end
71
+
64
72
  end
65
73
 
66
74
 
@@ -89,11 +97,11 @@ module Assert::Result
89
97
  def trace
90
98
  self.backtrace.filtered.first.to_s
91
99
  end
92
-
100
+
93
101
  def ==(other)
94
102
  self.class == other.class && self.message == other.message
95
103
  end
96
-
104
+
97
105
  def inspect
98
106
  "#<#{self.class} @message=#{self.message.inspect}>"
99
107
  end
@@ -5,8 +5,8 @@ module Assert
5
5
 
6
6
  def <<(result)
7
7
  super
8
- if @view && @view.respond_to?(:print_runtime_result)
9
- @view.print_runtime_result(result)
8
+ if @view && @view.respond_to?(:handle_runtime_result)
9
+ @view.handle_runtime_result(result)
10
10
  end
11
11
  end
12
12
 
data/lib/assert/runner.rb CHANGED
@@ -12,15 +12,11 @@ module Assert
12
12
  end
13
13
 
14
14
  def run(*args)
15
- @suite.setup_blocks.each do |setup| # TODO: tests!
16
- setup.call
17
- end
15
+ @suite.setup
18
16
  @view.render do
19
17
  benchmark { run_suite }
20
18
  end
21
- @suite.teardown_blocks.each do |teardown| # TODO: tests!
22
- teardown.call
23
- end
19
+ @suite.teardown
24
20
  count(:failed) + count(:errored)
25
21
  end
26
22
 
@@ -22,7 +22,6 @@ module Assert
22
22
 
23
23
  exit_code = nil
24
24
  at_exit { exit(false) if exit_code && exit_code != 0 }
25
- # TODO: read options from a config for extentions??
26
25
  Runner.new(self.suite, self.view).run
27
26
  end unless @@at_exit_installed
28
27
  @@at_exit_installed = true
data/lib/assert/suite.rb CHANGED
@@ -6,7 +6,7 @@ module Assert
6
6
  # A suite is a set of tests to run. When a test class subclasses
7
7
  # the Context class, that test class is pushed to the suite.
8
8
 
9
- attr_accessor :start_time, :end_time, :setup_blocks, :teardown_blocks
9
+ attr_accessor :start_time, :end_time
10
10
 
11
11
  def run_time
12
12
  (@end_time || 0) - (@start_time || 0)
@@ -70,28 +70,32 @@ module Assert
70
70
  end
71
71
  end
72
72
 
73
- def setup_blocks
74
- @setup_blocks ||= []
75
- end
76
-
77
- def teardown_blocks
78
- @teardown_blocks ||= []
79
- end
80
-
81
- # TODO: tests!
82
73
  def setup(&block)
83
- raise ArgumentError, "please provide a setup block" unless block_given?
84
- self.setup_blocks << block
74
+ if block_given?
75
+ self.setups << block
76
+ else
77
+ self.setups.each{|setup| setup.call}
78
+ end
85
79
  end
86
80
 
87
- # TODO: tests!
88
81
  def teardown(&block)
89
- raise ArgumentError, "please provide a teardown block" unless block_given?
90
- self.teardown_blocks << block
82
+ if block_given?
83
+ self.teardowns << block
84
+ else
85
+ self.teardowns.reverse.each{|teardown| teardown.call}
86
+ end
91
87
  end
92
88
 
93
89
  protected
94
90
 
91
+ def setups
92
+ @setups ||= []
93
+ end
94
+
95
+ def teardowns
96
+ @teardowns ||= []
97
+ end
98
+
95
99
  def local_public_test_methods(klass)
96
100
  methods = klass.public_instance_methods
97
101
  while (klass.superclass)
data/lib/assert/test.rb CHANGED
@@ -19,9 +19,9 @@ module Assert
19
19
 
20
20
  def run(view=nil)
21
21
  @results.view = view
22
+ run_scope = @context_class.new(self)
22
23
  begin
23
- run_scope = @context_class.new(self)
24
- run_setup(run_scope)
24
+ @context_class.setup(run_scope)
25
25
  if @code.kind_of?(::Proc)
26
26
  run_scope.instance_eval(&@code)
27
27
  elsif run_scope.respond_to?(@code.to_s)
@@ -33,7 +33,7 @@ module Assert
33
33
  @results << Result::Error.new(self.name, err)
34
34
  ensure
35
35
  begin
36
- run_teardown(run_scope) if run_scope
36
+ @context_class.teardown(run_scope)
37
37
  rescue Exception => teardown_err
38
38
  @results << Result::Error.new(self.name, teardown_err)
39
39
  end
@@ -42,18 +42,6 @@ module Assert
42
42
  @results
43
43
  end
44
44
 
45
- def run_setup(scope)
46
- @context_class.all_setup_blocks.each do |setup|
47
- scope.instance_eval(&setup)
48
- end
49
- end
50
-
51
- def run_teardown(scope)
52
- @context_class.all_teardown_blocks.each do |teardown|
53
- scope.instance_eval(&teardown)
54
- end
55
- end
56
-
57
45
  Assert::Result.types.each do |name, klass|
58
46
  define_method "#{name}_results" do
59
47
  @results.select{|r| r.kind_of?(klass) }
@@ -82,8 +70,9 @@ module Assert
82
70
  protected
83
71
 
84
72
  def name_from_context(name)
85
- name = name.gsub(/^test:\s+should/, "should")
86
- [ @context_class.full_description, name ].compact.join(" ")
73
+ [ @context_class.description,
74
+ name.gsub(/^test:\s+should/, "should")
75
+ ].compact.reject{|p| p.empty?}.join(" ")
87
76
  end
88
77
 
89
78
  end
@@ -1,3 +1,3 @@
1
1
  module Assert
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -16,7 +16,7 @@ module Assert::View
16
16
  def render(*args, &runner)
17
17
  end
18
18
 
19
- def print_runtime_result(result)
19
+ def handle_runtime_result(result)
20
20
  sym = result.to_sym
21
21
  if self.respond_to?(:options)
22
22
  io_print(self.options.send("#{sym}_abbrev"))
@@ -1,32 +1,12 @@
1
1
  require 'assert/view/base'
2
2
  require 'assert/result'
3
3
 
4
+ require 'ansi/code'
5
+
4
6
  module Assert::View
5
7
 
6
8
  class Terminal < Base
7
9
 
8
- TERM_STYLES = {
9
- :reset => 0,
10
- :bold => 1,
11
- :underline => 4,
12
- :black => 30,
13
- :red => 31,
14
- :green => 32,
15
- :yellow => 33,
16
- :blue => 34,
17
- :magenta => 35,
18
- :cyan => 36,
19
- :white => 37,
20
- :bgblack => 40,
21
- :bgred => 41,
22
- :bggreen => 42,
23
- :bgyellow => 43,
24
- :bgblue => 44,
25
- :bgmagenta => 45,
26
- :bgcyan => 46,
27
- :bgwhite => 47
28
- }
29
-
30
10
  options do
31
11
  default_styled false
32
12
  default_passed_abbrev '.'
@@ -42,7 +22,7 @@ module Assert::View
42
22
  end
43
23
 
44
24
  def render(*args, &block)
45
- self.io_print(:load_stmt)
25
+ self.io_puts(:load_stmt)
46
26
 
47
27
  if count(:tests) > 0
48
28
  block.call if block
@@ -52,7 +32,7 @@ module Assert::View
52
32
  self.io_puts(:results_stmt)
53
33
  end
54
34
 
55
- def print_runtime_result(result)
35
+ def handle_runtime_result(result)
56
36
  sym = result.to_sym
57
37
  self.io_print(result_io_msg(self.options.send("#{sym}_abbrev"), sym))
58
38
  end
@@ -61,7 +41,7 @@ module Assert::View
61
41
 
62
42
  def load_stmt
63
43
  tplur = (tcount = count(:tests)) == 1 ? "test": "tests"
64
- "\nLoaded suite (#{tcount} #{tplur}) "
44
+ "\nLoaded suite (#{tcount} #{tplur})"
65
45
  end
66
46
 
67
47
  def detailed_results
@@ -116,16 +96,14 @@ module Assert::View
116
96
  def io_msg(msg, opts={})
117
97
  val = super
118
98
  if !(style = term_style(*opts[:term_styles])).empty?
119
- val = style + val + term_style(:reset)
99
+ val = style + val + ANSI.send(:reset)
120
100
  else
121
101
  val
122
102
  end
123
103
  end
124
104
 
125
- def term_style(*styles)
126
- styles.collect do |style|
127
- TERM_STYLES.include?(style) ? "\e[#{TERM_STYLES[style]}m" : nil
128
- end.join('')
105
+ def term_style(*ansi_codes)
106
+ ansi_codes.collect{|code| ANSI.send(code) rescue nil}.compact.join('')
129
107
  end
130
108
 
131
109
  def show_result_details?(result)
@@ -25,7 +25,7 @@ class Assert::Assertions::AssertBlockTest < Assert::Context
25
25
  class FailMessageTest < AssertBlockTest
26
26
  desc "with a failed result"
27
27
  setup do
28
- @expected = [ "Expected block to return true value.", @fail_desc ].join("\n")
28
+ @expected = [@fail_desc, "Expected block to return true value."].join("\n")
29
29
  @fail_message = @test.fail_results.first.message
30
30
  end
31
31
  subject{ @fail_message }
@@ -0,0 +1,43 @@
1
+ require 'assert'
2
+
3
+ class Assert::Assertions::AssertEmptyTest < Assert::Context
4
+ desc "the assert_empty helper run in a test"
5
+ setup do
6
+ fail_desc = @fail_desc = "assert empty fail desc"
7
+ fail_args = @fail_args = [ [ 1 ], fail_desc ]
8
+ @test = Factory.test do
9
+ assert_empty([]) # pass
10
+ assert_empty(*fail_args) # fail
11
+ end
12
+ @test.run
13
+ end
14
+ subject{ @test }
15
+
16
+ should "have 2 total results" do
17
+ assert_equal 2, subject.result_count
18
+ end
19
+ should "have 1 pass result" do
20
+ assert_equal 1, subject.result_count(:pass)
21
+ end
22
+ should "have 1 fail result" do
23
+ assert_equal 1, subject.result_count(:fail)
24
+ end
25
+
26
+ class FailMessageTest < AssertEmptyTest
27
+ desc "with a failed result"
28
+ setup do
29
+ @expected = [
30
+ @fail_args[1],
31
+ "Expected #{@fail_args[0].inspect} to be empty."
32
+ ].join("\n")
33
+ @fail_message = @test.fail_results.first.message
34
+ end
35
+ subject{ @fail_message }
36
+
37
+ should "have a fail message with an explanation of what failed and my fail description" do
38
+ assert_equal @expected, subject
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,43 @@
1
+ require 'assert'
2
+
3
+ class Assert::Assertions::AssertEqualTest < Assert::Context
4
+ desc "the assert_equal helper run in a test"
5
+ setup do
6
+ fail_desc = @fail_desc = "assert equal fail desc"
7
+ fail_args = @fail_args = [ 1, 2, fail_desc ]
8
+ @test = Factory.test do
9
+ assert_equal(1, 1) # pass
10
+ assert_equal(*fail_args) # fail
11
+ end
12
+ @test.run
13
+ end
14
+ subject{ @test }
15
+
16
+ should "have 2 total results" do
17
+ assert_equal 2, subject.result_count
18
+ end
19
+ should "have 1 pass result" do
20
+ assert_equal 1, subject.result_count(:pass)
21
+ end
22
+ should "have 1 fail result" do
23
+ assert_equal 1, subject.result_count(:fail)
24
+ end
25
+
26
+ class FailMessageTest < AssertEqualTest
27
+ desc "with a failed result"
28
+ setup do
29
+ @expected = [
30
+ @fail_args[2],
31
+ "Expected #{@fail_args[0]}, not #{@fail_args[1]}."
32
+ ].join("\n")
33
+ @fail_message = @test.fail_results.first.message
34
+ end
35
+ subject{ @fail_message }
36
+
37
+ should "have a fail message with an explanation of what failed and my fail description" do
38
+ assert_equal @expected, subject
39
+ end
40
+
41
+ end
42
+
43
+ end