atto 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,50 @@
1
+ INTRODUCTION
2
+
3
+ Atto is an ultra-tiny self-contained testing framework inspired by
4
+ and partially based on nanotest. It is self-contained in that it needs no
5
+ external libraries. Every file in this project is,and will remain under 100
6
+ lines long, comments included.
7
+
8
+
9
+ USAGE
10
+
11
+ To use it in your tests, for every ruby file lib/foo/bar.rb in your project,
12
+ make a test file lib/foo/test_bar.rb and start it with:
13
+
14
+ require 'atto'
15
+ include Atto::Test
16
+
17
+ # Then you can add tests like this:
18
+ assert "A test that will always suceed" do true end
19
+ # Or like this :
20
+ assert { Foo::Bar }
21
+
22
+ Then run the command atto from your project directory and it will run the tests
23
+ automatically, every time you change either the lib file or the test file. It
24
+ will also detect new files being added.
25
+
26
+ LICENSE
27
+
28
+ The MIT License
29
+
30
+ Copyright (c) 2011 Beoran (beoran@rubyforge.org)
31
+
32
+ Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ of this software and associated documentation files (the "Software"), to deal
34
+ in the Software without restriction, including without limitation the rights
35
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ copies of the Software, and to permit persons to whom the Software is
37
+ furnished to do so, subject to the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be included in
40
+ all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48
+ THE SOFTWARE.
49
+
50
+
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ # Rakefile added by John Mair (banisterfiend)
2
+
3
+ require 'rake/gempackagetask'
4
+ require 'rake/clean'
5
+ CLEAN.include("pkg/*.gem")
6
+
7
+
8
+ ATTO_VERSION = "0.9.0"
9
+
10
+ def apply_spec_defaults(s)
11
+ end
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = "atto"
15
+ s.summary = "An ultra-tiny self-contained testing framework."
16
+ s.description = s.summary + " "
17
+ s.version = ATTO_VERSION
18
+ s.author = "Beoran"
19
+ s.email = 'beoran@rubyforge.org'
20
+ s.date = Time.now.strftime '%Y-%m-%d'
21
+ s.require_path = 'lib'
22
+ s.homepage = "https://github.com/beoran/atto"
23
+ # s.platform = Gem::Platform::CURRENT
24
+ s.files = ["Rakefile" , "README" ] +
25
+ FileList["lib/atto.rb", "lib/atto/*.rb",
26
+ "test/*.rb" , "test/atto/*.rb" ].to_a
27
+ s.bindir = "bin"
28
+ s.executables = "atto"
29
+ end
30
+
31
+ Rake::GemPackageTask.new(spec) do |pkg|
32
+ pkg.need_zip = false
33
+ pkg.need_tar = false
34
+ end
35
+
36
+
37
+ task :test do
38
+ for file in FileList["test/*.rb" , "test/atto/*.rb" ] do
39
+ puts("Running tests for #{file}:")
40
+ res = system("ruby -I lib #{file}")
41
+ puts res ? "OK!" : "Failed!"
42
+ end
43
+ end
44
+
45
+ task :default => :test
46
+
data/bin/atto ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'atto'
4
+
5
+ Atto::Run.main
data/lib/atto/ansi.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Atto
2
+ # ANSI colors
3
+ module Ansi
4
+ extend self
5
+
6
+ ATTRIBUTES = {
7
+ :reset => 0 , :bold => 1 , :dark => 2 , :underline => 4 ,
8
+ :blink => 5 , :negative => 7 , :concealed => 8 , :black => 30,
9
+ :red => 31, :green => 32, :yellow => 33, :blue => 34,
10
+ :magenta => 35, :cyan => 36, :white => 37, :on_black => 40,
11
+ :on_red => 41, :on_green => 42, :on_yellow => 43, :on_blue => 44,
12
+ :on_magenta=> 45, :on_cyan => 46, :on_white => 47, }
13
+
14
+ # Replaces symbols witch refer to ANSI escape codes with those escape codes.
15
+ def color(*args)
16
+ out = []
17
+ for arg in args
18
+ col = ATTRIBUTES[arg]
19
+ if col
20
+ out << "\e[#{col}m"
21
+ else
22
+ out << arg
23
+ end
24
+ end
25
+ out << "\e[0m"
26
+ return out
27
+ end
28
+
29
+ # Replaces ansi codes and returns the joined string
30
+ def color_string(*args)
31
+ return color(*args).map { |e| e.to_s }.join
32
+ end
33
+
34
+ # puts output colored with ANSI escape codes
35
+ def puts(*args)
36
+ Kernel.puts(*self.color(*args))
37
+ end
38
+
39
+ end
40
+ end
data/lib/atto/run.rb ADDED
@@ -0,0 +1,93 @@
1
+ module Atto
2
+ # Test autorunner
3
+ class Run
4
+ # Shortcut to run main
5
+ def self.main
6
+ return self.new.main
7
+ end
8
+
9
+ # Find all Ruby all files under the named dir
10
+ def all_files(name)
11
+ return Dir.new(name).inject([]) do |res, e|
12
+ full = File.join(name, e)
13
+ if Dir.exist?(full) && e !='.' && e != '..'
14
+ res += all_files(full)
15
+ else
16
+ res << full if full =~ /\.rb\Z/
17
+ end
18
+ res
19
+ end
20
+ end
21
+
22
+ # updates the timestamp info for files
23
+ def update_info(files)
24
+ return files.inject({}) do |res, name|
25
+ stat = File.stat(name)
26
+ res[name] = Struct.new(:mtime).new(stat.mtime)
27
+ res
28
+ end
29
+ end
30
+
31
+ # matches libfiles wih testfiles
32
+ def match_files(libfiles, testfiles)
33
+ return libfiles.inject({}) do |res, libname|
34
+ testname = libname.dup
35
+ where = libname.rindex(File::Separator)
36
+ testname[where]= File::Separator + 'test_'
37
+ testname[File.join('','lib','')] = File.join('','test','')
38
+ res[libname] = testname if testfiles.member?(testname)
39
+ res
40
+ end
41
+ end
42
+
43
+ # Runs a list of tests
44
+ def run_tests(list)
45
+ return list.inject({}) do |results, file|
46
+ puts("Running tests for #{file}:")
47
+ res = system("ruby -I #@libdir -I #@testdir #{file}")
48
+ puts res ? "OK!" : "Failed!"
49
+ results[file] = Time.now
50
+ results
51
+ end
52
+ end
53
+
54
+ # Checks if a test file must run
55
+ def must_run(ran_tests, k, v)
56
+ ran_tests[k] ? ran_tests[k] <= v.mtime : true
57
+ end
58
+
59
+ # updates all state info
60
+ def update_all
61
+ @libfiles = all_files(@libdir)
62
+ @testfiles = all_files(@testdir)
63
+ @matchfiles= match_files(@libfiles, @testfiles)
64
+ @libinfo = update_info(@libfiles)
65
+ @testinfo = update_info(@testfiles)
66
+ end
67
+
68
+ # Main, runs the tests when needed
69
+ def main
70
+ @projdir = ARGV[0] || Dir.pwd
71
+ @libdir = File.join(@projdir, ARGV[1] || 'lib')
72
+ @testdir = File.join(@projdir, ARGV[2] || 'test')
73
+ update_all
74
+ @ran_tests = run_tests(@testfiles)
75
+ loop do
76
+ update_all
77
+ torun = @testinfo.select do |k,v|
78
+ must_run(@ran_tests, k, v)
79
+ end
80
+ extra = @libinfo.select do |k,v|
81
+ linked = @matchfiles[k]
82
+ linked ? must_run(@ran_tests, linked, v) : false
83
+ end.map { |k,v| @matchfiles[k] }
84
+ run_tests(torun.keys + extra).each { |k,v| @ran_tests[k] = v }
85
+ sleep(1)
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ if __FILE__ == $0
92
+ Atto::Run.main
93
+ end
data/lib/atto/test.rb ADDED
@@ -0,0 +1,80 @@
1
+ require 'timeout'
2
+
3
+ module Atto
4
+ # Tiny module for test driven development. Use with include Atto::Test.
5
+ module Test
6
+ extend self
7
+ @@failures, @@dots, @@messages = [], [], []
8
+
9
+ # Returns the file and line of the calling context
10
+ def parse_stack(stack=caller)
11
+ return *(stack.first.match(/(.*):(\d+)/)[1..2])
12
+ end
13
+
14
+ # Formats a message that reporst on any test failiures
15
+ def format_failure(message, stack = caller)
16
+ # file, line =
17
+ return "(%s:%0.3d) %s" % [*parse_stack(stack), message]
18
+ end
19
+
20
+ # Formats an exception backtrace to a string.
21
+ def format_exception(raised, msg = "")
22
+ return msg + raised.to_s + "\n" + raised.backtrace.join("\n")
23
+ end
24
+
25
+ # Creates a failiure for the given raised and result state
26
+ # Returns nil if no failure
27
+ def make_failure(res, raised, msg, stack)
28
+ return nil if res
29
+ if raised
30
+ return format_failure(msg || format_exception(raised, "Exception!\n"), stack)
31
+ end
32
+ return format_failure(msg || "Assertion failed!", stack)
33
+ end
34
+
35
+ # Makes a dot for the given raised and result state
36
+ def make_dot(res, raised)
37
+ return res ? '.' : ( raised ? 'E' : 'F')
38
+ end
39
+
40
+ # Calls a block safely with a timeout
41
+ def run_block(delay = 10, &block)
42
+ res, raised = nil, nil
43
+ begin
44
+ Timeout.timeout(delay) do res = block.call ; end
45
+ rescue
46
+ raised = $!
47
+ end
48
+ return res, raised
49
+ end
50
+
51
+ # Test assertion.
52
+ def assert(msg=nil, file=nil, line=nil, delay=10, stack=caller, &block)
53
+ res, raised = run_block(delay, &block)
54
+ @@dots << make_dot(res, raised)
55
+ failure = make_failure(res, raised, msg, stack)
56
+ @@failures << failure if failure
57
+ if msg
58
+ @@messages << ( failure ? msg + " (failed) " : msg)
59
+ end
60
+ res
61
+ end
62
+
63
+ # Results of the tests
64
+ def self.results
65
+ aid = @@dots.join + "\n" + @@failures.join("\n") + "\n"
66
+ col = @@failures.empty? ? :green : :red
67
+ aid << Atto::Ansi.color_string(col, "=" * 78)
68
+ end
69
+
70
+ # Describes the tests
71
+ def self.describe_tests
72
+ @@messages.join(".\n") + ".\n"
73
+ end
74
+
75
+ at_exit {
76
+ puts results unless results.strip.empty?;
77
+ exit @@failures.empty?
78
+ }
79
+ end
80
+ end
data/lib/atto.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Atto is a tiny KISS library full of useful functionality for TDD and BDD.
2
+ module Atto
3
+ # Ansi colors for red/green display after testing.
4
+ autoload :Ansi, 'atto/ansi'
5
+ # Testing
6
+ autoload :Test, 'atto/test'
7
+ # Autorunning tests
8
+ autoload :Run, 'atto/run'
9
+ end
@@ -0,0 +1,27 @@
1
+ require 'atto'
2
+ include Atto::Test
3
+
4
+ assert("Ansi is defined") { Atto::Ansi }
5
+
6
+ assert("Ansi::ATTRIBUTES is defined") { Atto::Ansi::ATTRIBUTES }
7
+
8
+ for attr, value in Atto::Ansi::ATTRIBUTES do
9
+ assert "Attribute #{attr} is colored correctly" do
10
+ Atto::Ansi.color(attr) == ["\e[#{value}m", "\e[0m"]
11
+ end
12
+ end
13
+
14
+ for attr, value in Atto::Ansi::ATTRIBUTES do
15
+ assert "Attribute with text #{attr} is colored correctly" do
16
+ Atto::Ansi.color(attr, "hello") == ["\e[#{value}m", "hello", "\e[0m"]
17
+ end
18
+ end
19
+
20
+ assert "Atto::Ansi#color_string works correctly" do
21
+ Atto::Ansi.color_string(:green, :on_yellow, "This works!") ==
22
+ "\e[32m\e[43mThis works!\e[0m"
23
+ end
24
+
25
+ assert "Atto::Ansi#puts works correctly" do
26
+ (Atto::Ansi.puts :green, :on_yellow, "This works!").nil?
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'atto'
2
+ include Atto::Test
3
+
4
+ assert "Atto is defined" do Atto end
5
+ assert "Atto::Test is defined" do Atto::Test end
6
+ assert "Success can be detected" do true end
7
+ assert "Works with nexted asserts" do
8
+ assert "This is a nested assert" do true end
9
+ end
10
+
11
+ assert "Works with empty description" do assert { true } end
12
+
13
+ assert "Nested asserts keep the return value" do
14
+ assert { 7 } == 7
15
+ end
16
+
17
+ assert "Atto::Test#describe_tests is defined" do Atto::Test.describe_tests end
18
+
19
+
20
+
21
+
22
+
data/test/test_atto.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'atto'
2
+ include Atto::Test
3
+
4
+ assert { Atto }
5
+ assert { Atto::Ansi }
6
+ assert { Atto::Test }
7
+ # assert { Atto::Spec }
8
+
9
+
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atto
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 9
8
+ - 0
9
+ version: 0.9.0
10
+ platform: ruby
11
+ authors:
12
+ - Beoran
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-05-07 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: "An ultra-tiny self-contained testing framework. "
22
+ email: beoran@rubyforge.org
23
+ executables:
24
+ - atto
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - Rakefile
31
+ - README
32
+ - lib/atto.rb
33
+ - lib/atto/ansi.rb
34
+ - lib/atto/run.rb
35
+ - lib/atto/test.rb
36
+ - test/test_atto.rb
37
+ - test/atto/test_ansi.rb
38
+ - test/atto/test_test.rb
39
+ - bin/atto
40
+ has_rdoc: true
41
+ homepage: https://github.com/beoran/atto
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: An ultra-tiny self-contained testing framework.
72
+ test_files: []
73
+