overseer 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in overseer.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,3 @@
1
+ # Overseer
2
+
3
+ Overseer is a testing framework in Ruby for educational purposes.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib'
6
+ t.test_files = FileList['test/test*.rb']
7
+ t.verbose = false
8
+ end
@@ -0,0 +1,89 @@
1
+ require_relative '../lib/overseer'
2
+
3
+ class BasicTest
4
+ include Overseer
5
+
6
+ test "#hello" do
7
+ "nothing happens"
8
+ end
9
+
10
+ test "raising an error" do
11
+ this_is_going_to_be_an_error
12
+ end
13
+
14
+ test "need some more time" do
15
+ (1..200000).map {|nr| nr += nr}
16
+ end
17
+
18
+ test "assertion_equal fail" do
19
+ say = "bye"
20
+
21
+ assert_equal "hello", say
22
+ end
23
+
24
+ test "assertion_equal passed" do
25
+ number = 12
26
+
27
+ assert_equal 12, number
28
+ end
29
+
30
+ test "assert_nil failed" do
31
+ the_end = "is coming!"
32
+
33
+ assert_nil the_end
34
+ end
35
+
36
+ test "assert_nil passed" do
37
+ box = nil
38
+
39
+ assert_nil box
40
+ end
41
+
42
+ test "assert_kind_of failed" do
43
+ string = 23
44
+
45
+ assert_kind_of String, string
46
+ end
47
+
48
+ test "assert_kind_of passed" do
49
+ fixnum = 11
50
+
51
+ assert_kind_of Fixnum, fixnum
52
+ end
53
+
54
+ test "assert_instance_of failed" do
55
+ float = 120e2
56
+
57
+ assert_instance_of Fixnum, float
58
+ end
59
+
60
+ test "assert_instance_of passed" do
61
+ bignum = 99999999999999999999999
62
+
63
+ assert_instance_of Bignum, bignum
64
+ end
65
+
66
+ test "assert_respond_to failed" do
67
+ class Responder
68
+ def hello; end
69
+ end
70
+
71
+ assert_respond_to Responder.new, :bye
72
+ end
73
+
74
+ test "assert_respond_to passed" do
75
+ class Responder
76
+ def hello; end
77
+ end
78
+
79
+ assert_respond_to Responder.new, :hello
80
+ end
81
+
82
+ before do
83
+ @james = "brown"
84
+ end
85
+
86
+ test "if the godfather of soul around" do
87
+ assert_equal "brown", @james
88
+ end
89
+ end
data/lib/overseer.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "overseer/reporter"
2
+ require "overseer/color"
3
+ require "overseer/duties"
4
+ require "overseer/dsl"
5
+ require "overseer/assertions"
6
+ require "overseer/suite"
7
+ require "overseer/test"
8
+ require "overseer/runner"
9
+ require "overseer/version"
10
+
11
+ module Overseer
12
+ extend self
13
+ extend Duties
14
+
15
+ OVERSEER_DIR = File.dirname(File.dirname(File.expand_path(__FILE__)))
16
+
17
+ def included(suite) #:nodoc:
18
+ suite.send(:extend, Dsl)
19
+ suite.send(:extend, Assertions)
20
+ build_suite(suite)
21
+ end
22
+
23
+ at_exit { Runner.run }
24
+ end
@@ -0,0 +1,115 @@
1
+ module Overseer
2
+
3
+ # Generic Assertion exception class
4
+ #
5
+ class Assertion < Exception
6
+ end
7
+
8
+ # A set of assertion methods
9
+ #
10
+ module Assertions
11
+
12
+ # Raises an +Assertion+ exception if the given object isn't
13
+ # +true+. It adds the exception to the failure collection of
14
+ # the current test, in which the assertion was executed
15
+ #
16
+ # ==== Parameters
17
+ # result:: the assertion result
18
+ # message<String>:: the identifying message for the +Assertion+ excpetion
19
+ #
20
+ def assert(result, message=nil)
21
+ Overseer.current_test.assertions += 1
22
+ raise Assertion, message unless result
23
+ rescue Assertion => e
24
+ Overseer.current_test.failures << e
25
+ end
26
+
27
+ # Compare two given objects if they are equal
28
+ # Fails if +actual+ isn't equal to +expected+
29
+ #
30
+ # === Parameters
31
+ # expected:: the object which is expected
32
+ # actual:: the actual given object
33
+ # message<String>:: the identifying message for the +Assertion+ exception
34
+ #
35
+ def assert_equal(expected, actual, message=nil)
36
+ message ||= "Expected: \"#{expected}\"\n Got: \"#{actual}\""
37
+ assert(expected == actual, message)
38
+ end
39
+
40
+ # Verify if an object is +nil+
41
+ # Fails if +obj+ isn't +nil+
42
+ #
43
+ # === Parameters
44
+ # obj:: the object which will be verified
45
+ # message<String>:: the identifying message for the +Assertion+ exception
46
+ #
47
+ def assert_nil(obj, message=nil)
48
+ message ||= "Expected #{obj} to be nil"
49
+ assert(obj.nil?, message)
50
+ end
51
+
52
+ # Verify if an object is +true+
53
+ # Fails if +obj+ isn't +true+
54
+ #
55
+ # === Parameters
56
+ # obj:: the object which will be verified
57
+ # message<String>:: the identifying message for the +Assertion+ exception
58
+ #
59
+ def assert_true(obj, message=nil)
60
+ message ||= "Expected #{obj} to be true"
61
+ assert(!!obj, message)
62
+ end
63
+
64
+ # Verify if an object is +false+
65
+ # Fails if +obj+ isn't +false+
66
+ #
67
+ # === Parameters
68
+ # obj:: the object which will be verified
69
+ # message<String>:: the identifying message for the +Assertion+ exception
70
+ #
71
+ def assert_false(obj, message=nil)
72
+ message ||= "Expected #{obj} to be false"
73
+ assert(!obj, message)
74
+ end
75
+
76
+ # Verify if an object is a kind of a specified class
77
+ # Fails if +obj+ isn't a kind of +clazz+
78
+ #
79
+ # === Parameters
80
+ # clazz:: the expected class which should +obj+ be a kind of
81
+ # obj:: the object which will be verified
82
+ # message<String>:: the identifying message for the +Assertion+ exception
83
+ #
84
+ def assert_kind_of(clazz, obj, message=nil)
85
+ message ||= "Expected \"#{obj.inspect}\" to be a kind of \"#{clazz}\", not \"#{obj.class}\""
86
+ assert(obj.kind_of?(clazz), message)
87
+ end
88
+
89
+ # Verify if an object is a instance of a specified class
90
+ # Fails if +obj+ isn't an instance of +clazz+
91
+ #
92
+ # === Parameters
93
+ # clazz:: the expected class which should +obj+ be an instance of
94
+ # obj:: the object which will be verified
95
+ # message<String>:: the identifying message for the +Assertion+ exception
96
+ #
97
+ def assert_instance_of(clazz, obj, message=nil)
98
+ message ||= "Expected \"#{obj.inspect}\" to be an instance of \"#{clazz}\", not \"#{obj.class}\""
99
+ assert(obj.instance_of?(clazz), message)
100
+ end
101
+
102
+ # Verify if an object responds to a method.
103
+ # Fails if +obj+ doesn't respond to +method+
104
+ #
105
+ # === Parameters
106
+ # obj:: the object which will be verified
107
+ # method:: the name of the method which +obj+ should respond to
108
+ # message<String>:: the identifying message for the +Assertion+ exception
109
+ #
110
+ def assert_respond_to(obj, method, message=nil)
111
+ message ||= "Expected \"#{obj.inspect}\" to respond to \"##{method}\""
112
+ assert(obj.respond_to?(method), message)
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,19 @@
1
+ module Overseer
2
+ module Color
3
+ extend self
4
+
5
+ COLORS = {
6
+ :red => "\e[31m",
7
+ :green => "\e[32m",
8
+ :bright_black => "\e[90m",
9
+ :bright_red => "\e[91m",
10
+ :bright_green => "\e[92m",
11
+ }
12
+
13
+ COLORS.each do |color, ansi_code|
14
+ define_method color do |string|
15
+ "#{ansi_code}#{string}\e[0m"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Overseer
2
+ module Dsl
3
+ def test(desc, &block)
4
+ Overseer.build_test(desc, &block)
5
+ end
6
+
7
+ def before(&block)
8
+ Overseer.build_before(&block)
9
+ end
10
+
11
+ def after(&block)
12
+ Overseer.build_after(&block)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,55 @@
1
+ module Overseer
2
+ module Duties
3
+ attr_reader :current_suite
4
+ attr_accessor :current_test
5
+
6
+ def build_test(name, &block)
7
+ @current_suite.tests << Test.new(name, &block)
8
+ end
9
+
10
+ def build_suite(suite)
11
+ @current_suite = Suite.new(suite)
12
+ suites << @current_suite
13
+ end
14
+
15
+ def build_before(&block)
16
+ @current_suite.before = block
17
+ end
18
+
19
+ def build_after(&block)
20
+ @current_suite.after = block
21
+ end
22
+
23
+ def suites
24
+ @suites ||= []
25
+ end
26
+
27
+ def failures_exists?
28
+ total_failures > 0
29
+ end
30
+
31
+ def errors_exists?
32
+ total_errors > 0
33
+ end
34
+
35
+ def total_assertions
36
+ suites.inject(0) { |total, suite| total + suite.total_test_assertions }
37
+ end
38
+
39
+ def total_failures
40
+ suites.inject(0) { |total, suite| total + suite.total_test_failures }
41
+ end
42
+
43
+ def total_errors
44
+ suites.inject(0) { |total, suite| total + suite.total_test_errors }
45
+ end
46
+
47
+ def total_tests
48
+ suites.inject(0) { |total, suite| total + suite.tests.size }
49
+ end
50
+
51
+ def total_time
52
+ suites.inject(0) { |total, suite| total + suite.total_test_time }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,66 @@
1
+ module Overseer
2
+ module Reporter
3
+ extend self
4
+
5
+ def report
6
+ print_header
7
+ yield
8
+ print_test_report
9
+ end
10
+
11
+ def print_header
12
+ puts "Overseer is running..."
13
+ puts
14
+ end
15
+
16
+ def print_test_report
17
+ puts
18
+ print_open_issues
19
+ puts
20
+ puts "Finished in %.3f seconds" % Overseer.total_time
21
+ puts Color.green("#{Overseer.total_tests} tests, #{Overseer.total_assertions} assertions, #{Overseer.total_failures} failures, #{Overseer.total_errors} errors")
22
+ end
23
+
24
+ def print_single_test_result(test)
25
+ print(test.passed? ? Color.green(".") : (test.errors? ? Color.red("E") : Color.red("F")))
26
+ end
27
+
28
+ def print_open_issues
29
+ if Overseer.failures_exists? || Overseer.errors_exists?
30
+ print "\nOpen issues:\n"
31
+ counter = 1
32
+ Overseer.suites.each do |suite|
33
+ suite.tests.each do |test|
34
+ unless test.passed?
35
+ print_test_issues(test, counter)
36
+ counter += 1
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def print_test_issues(test, counter)
44
+ puts
45
+ puts " #{counter}) #{(test.errors?) ? Color.red("Error:") : Color.red("Failure:")}"
46
+ puts " Test: #{test.name} (in #{test.suite.name} Suite)"
47
+ exception = if test.errors?
48
+ test.errors.first
49
+ else
50
+ test.failures.first
51
+ end
52
+ puts Color.red(" #{exception.message}")
53
+ puts Color.bright_black("#{format_backtrace_output(filter_backtrace(exception.backtrace))}")
54
+ end
55
+
56
+ def filter_backtrace(backtrace)
57
+ backtrace.reject do |line|
58
+ line.rindex(OVERSEER_DIR, 0)
59
+ end
60
+ end
61
+
62
+ def format_backtrace_output(backtrace)
63
+ backtrace.map { |line| " # #{line}"}.join("\n")
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,9 @@
1
+ module Overseer
2
+ module Runner
3
+ def self.run
4
+ Reporter.report do
5
+ Overseer.suites.each(&:run)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ module Overseer
2
+ class Suite
3
+ attr_accessor :tests, :before, :after
4
+ attr_reader :name
5
+
6
+ def initialize(suite)
7
+ @name = suite.name
8
+ end
9
+
10
+ # Run all tests and print a report for each run
11
+ # about the success status
12
+ #
13
+ def run
14
+ tests.each do |test|
15
+ test.run
16
+ Reporter.print_single_test_result(test)
17
+ end
18
+ end
19
+
20
+ # The total amount of errors
21
+ #
22
+ def total_test_errors
23
+ tests.inject(0) { |total, test | total + test.errors.size }
24
+ end
25
+
26
+ # The total amount of failures
27
+ #
28
+ def total_test_failures
29
+ tests.inject(0) { |total, test | total + test.failures.size }
30
+ end
31
+
32
+ # The total test running time
33
+ #
34
+ def total_test_time
35
+ tests.inject(0) { |total, test| total + test.time }
36
+ end
37
+
38
+ # The total amount of assertions
39
+ #
40
+ def total_test_assertions
41
+ tests.inject(0) { |total, test | total + test.assertions }
42
+ end
43
+
44
+ # All tests for the suite
45
+ #
46
+ def tests
47
+ @tests ||= []
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,56 @@
1
+ module Overseer
2
+ class Test
3
+ attr_reader :time, :name, :code, :suite
4
+ attr_accessor :errors, :failures, :assertions
5
+
6
+ def initialize(name, &block)
7
+ @name = name
8
+ @code = block
9
+ @suite = Overseer.current_suite
10
+ @errors = []
11
+ @failures = []
12
+ @assertions = 0
13
+ end
14
+
15
+ # Returns +true+ or +false+ depending if the test
16
+ # is passed or not
17
+ #
18
+ def passed?
19
+ !errors? && !failures?
20
+ end
21
+
22
+ # Returns +true+ or +false depending if the test
23
+ # have outstanding errors or not
24
+ #
25
+ def errors?
26
+ errors.any?
27
+ end
28
+
29
+ # Returns +true+ or +false depending if the test
30
+ # have outstanding failures or not
31
+ def failures?
32
+ failures.any?
33
+ end
34
+
35
+ # Run the test, record the run time and store
36
+ # possible exceptions
37
+ #
38
+ def run
39
+ Overseer.current_test = self
40
+ start_time = Time.now
41
+ suite.before.call if suite.before
42
+ begin
43
+ @code.call
44
+ rescue Exception => e
45
+ errors << e
46
+ ensure
47
+ begin
48
+ suite.after.call if suite.after
49
+ rescue Exception => e
50
+ errors << e if passed?
51
+ end
52
+ @time = Time.now - start_time
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ module Overseer
2
+ VERSION = "0.0.1"
3
+ end
data/overseer.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "overseer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "overseer"
7
+ s.version = Overseer::VERSION
8
+ s.authors = ["Samuel Tonini"]
9
+ s.email = ["tonini.samuel@gmail.com"]
10
+ s.homepage = ""
11
+ s.description = %q{A testing framework in Ruby for educational purpose}
12
+ s.summary = s.description
13
+
14
+ s.rubyforge_project = "overseer"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative '../lib/overseer'
@@ -0,0 +1,57 @@
1
+ require_relative 'helper'
2
+
3
+ class TestWorld
4
+ end
5
+
6
+ class TestSuite
7
+ include Overseer
8
+
9
+ before do
10
+ @suite = Suite.new(TestWorld)
11
+ end
12
+
13
+ after do
14
+ @suite.tests.clear
15
+ end
16
+
17
+ test "#name" do
18
+ assert_equal "TestWorld", @suite.name
19
+ end
20
+
21
+ test "#total_test_errors" do
22
+ test = Test.new("the first one!")
23
+ @suite.tests << test
24
+
25
+ assert_equal 0, @suite.total_test_errors
26
+
27
+ test.errors << "ERROR"
28
+ assert_equal 1, @suite.total_test_errors
29
+ end
30
+
31
+ test "#total_test_failures" do
32
+ test = Test.new("doing it!")
33
+ @suite.tests << test
34
+
35
+ assert_equal 0, @suite.total_test_failures
36
+
37
+ test.failures << "FAILURE"
38
+ assert_equal 1, @suite.total_test_failures
39
+ end
40
+
41
+ test "#total_test_assertions" do
42
+ test = Test.new("give it!")
43
+ @suite.tests << test
44
+
45
+ assert_equal 0, @suite.total_test_assertions
46
+
47
+ test.assertions += 1
48
+ assert_equal 1, @suite.total_test_assertions
49
+ end
50
+
51
+ test "#tests" do
52
+ @suite.tests << Test.new("time to rest!")
53
+
54
+ assert_equal 1, @suite.tests.size
55
+ assert_kind_of Array, @suite.tests
56
+ end
57
+ end
data/test/test_test.rb ADDED
@@ -0,0 +1,31 @@
1
+ require_relative 'helper'
2
+
3
+ class TestTest
4
+ include Overseer
5
+
6
+ test "#passed?" do
7
+ test = Test.new("if the world is running")
8
+
9
+ test.failures << "big fail"
10
+ assert_false test.passed?
11
+
12
+ test.failures.clear
13
+
14
+ test.errors << "Got an error!"
15
+ assert_false test.passed?
16
+ end
17
+
18
+ test "#errors?" do
19
+ test = Test.new("error mate!")
20
+
21
+ test.errors << "outch!"
22
+ assert_true test.errors?
23
+ end
24
+
25
+ test "#failures?" do
26
+ test = Test.new("failure hurray!")
27
+
28
+ test.failures << "gotcha!"
29
+ assert_true test.failures?
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: overseer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Samuel Tonini
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-24 00:00:00.000000000 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: A testing framework in Ruby for educational purpose
16
+ email:
17
+ - tonini.samuel@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - README.markdown
25
+ - Rakefile
26
+ - examples/basic_test.rb
27
+ - lib/overseer.rb
28
+ - lib/overseer/assertions.rb
29
+ - lib/overseer/color.rb
30
+ - lib/overseer/dsl.rb
31
+ - lib/overseer/duties.rb
32
+ - lib/overseer/reporter.rb
33
+ - lib/overseer/runner.rb
34
+ - lib/overseer/suite.rb
35
+ - lib/overseer/test.rb
36
+ - lib/overseer/version.rb
37
+ - overseer.gemspec
38
+ - test/helper.rb
39
+ - test/test_suite.rb
40
+ - test/test_test.rb
41
+ has_rdoc: true
42
+ homepage: ''
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project: overseer
62
+ rubygems_version: 1.6.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: A testing framework in Ruby for educational purpose
66
+ test_files:
67
+ - test/helper.rb
68
+ - test/test_suite.rb
69
+ - test/test_test.rb