etest 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/Manifest ADDED
@@ -0,0 +1,13 @@
1
+ Manifest
2
+ Rakefile
3
+ etest.gemspec
4
+ init.rb
5
+ lib/dlog_ext.rb
6
+ lib/etest.rb
7
+ lib/etest/assertions.rb
8
+ lib/etest/grep.rb
9
+ lib/module_ext.rb
10
+ lib/string_ext.rb
11
+ script/console
12
+ script/rebuild
13
+ test/test.rb
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ task :default => :test
2
+
3
+ task :test do
4
+ sh "ruby test/test.rb"
5
+ end
6
+
7
+ task :rcov do
8
+ sh "cd test; rcov -o ../coverage -x ruby/.*/gems -x ^test.rb test.rb"
9
+ end
10
+
11
+ task :rdoc do
12
+ sh "rdoc -o doc/rdoc"
13
+ end
14
+
15
+ require 'rubygems'
16
+ require 'rake'
17
+ require 'echoe'
18
+
19
+ Echoe.new('etest', '0.1') do |p|
20
+ p.description = "Embedded tests"
21
+ p.url = "http://github.com/pboy/etest"
22
+ p.author = "pboy"
23
+ p.email = "eno-pboy@open-lab.org"
24
+ p.ignore_pattern = ["tmp/*"]
25
+ # p.runtime_dependencies = %w(nokogiri htmlentities rdiscount)
26
+ end
27
+
28
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
29
+
data/etest.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{etest}
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["pboy"]
9
+ s.date = %q{2010-02-28}
10
+ s.description = %q{Embedded tests}
11
+ s.email = %q{eno-pboy@open-lab.org}
12
+ s.extra_rdoc_files = ["lib/dlog_ext.rb", "lib/etest.rb", "lib/etest/assertions.rb", "lib/etest/grep.rb", "lib/module_ext.rb", "lib/string_ext.rb"]
13
+ s.files = ["Manifest", "Rakefile", "etest.gemspec", "init.rb", "lib/dlog_ext.rb", "lib/etest.rb", "lib/etest/assertions.rb", "lib/etest/grep.rb", "lib/module_ext.rb", "lib/string_ext.rb", "script/console", "script/rebuild", "test/test.rb"]
14
+ s.homepage = %q{http://github.com/pboy/etest}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Etest"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{etest}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Embedded tests}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ $: << "#{File.dirname(__FILE__)}/lib"
2
+
3
+ require "etest"
data/lib/dlog_ext.rb ADDED
@@ -0,0 +1,46 @@
1
+ module Dlog
2
+ def dlog(*args)
3
+ end
4
+ end
5
+
6
+ if !ENV["NO_DLOG"]
7
+
8
+ module Dlog
9
+ ROOT = if defined?(RAILS_ROOT)
10
+ RAILS_ROOT
11
+ else
12
+ File.expand_path(Dir.getwd)
13
+ end
14
+
15
+ HOME = ENV["HOME"] + "/"
16
+
17
+ def dlog(*args)
18
+ msg = ""
19
+ was_string = true
20
+ args.map do |s|
21
+ msg += was_string ? " " : ", " unless msg.empty?
22
+ msg += ((was_string = s.is_a?(String)) ? s : s.inspect)
23
+ end
24
+ STDERR.puts "#{dlog_caller}: #{msg}"
25
+ end
26
+
27
+ def dlog_caller
28
+ if caller[1] =~ /^(.*):(\d+)/
29
+ file, line = $1, $2
30
+ file = File.expand_path(file)
31
+
32
+ file.gsub!(ROOT, ".") or
33
+ file.gsub!(HOME, "~/")
34
+
35
+ "#{file}(#{line})"
36
+ else
37
+ "<dlog>"
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ class Object
45
+ include Dlog
46
+ end
data/lib/etest.rb ADDED
@@ -0,0 +1,66 @@
1
+ require "rubygems"
2
+ require "minitest/unit"
3
+ require File.dirname(__FILE__) + "/string_ext"
4
+ require File.dirname(__FILE__) + "/module_ext"
5
+ require File.dirname(__FILE__) + "/dlog_ext"
6
+
7
+ #
8
+ # Embedded test cases:
9
+ #
10
+ # The Etest module contains methods to run etests.
11
+ #
12
+ module Etest
13
+ end
14
+
15
+ require File.dirname(__FILE__) + "/etest/assertions"
16
+
17
+ class MiniTest::Unit::TestCase
18
+ def self.run_etests(*test_cases)
19
+ MiniTest::Unit::TestCase.reset
20
+
21
+ test_cases.each do |test_case|
22
+ MiniTest::Unit::TestCase.inherited test_case
23
+ end
24
+
25
+ MiniTest::Unit.new.run([])
26
+ MiniTest::Unit::TestCase.reset
27
+ end
28
+ end
29
+
30
+ module Etest
31
+ def self.auto_run
32
+ #
33
+ # find all modules that are not named /::Etest$/, and try to load
34
+ # the respective Etest module.
35
+ etests = Module.instances.map { |mod|
36
+ #next if mod.name =~ /\bEtest$/
37
+ next if mod.name == "Object"
38
+
39
+ Module.by_name "#{mod.name}::Etest"
40
+ }.compact.uniq.sort_by(&:name)
41
+
42
+ run *etests
43
+ end
44
+
45
+ def self.run(*etests)
46
+ dlog "Running", etests
47
+ #
48
+ # convert all Etest modules into a test case
49
+ test_cases = etests.map { |etest|
50
+ to_test_case etest
51
+ }
52
+
53
+ MiniTest::Unit::TestCase.run_etests *test_cases
54
+ end
55
+
56
+ #
57
+ # convert an Etest moodule into a MiniTest testcase
58
+ def self.to_test_case(mod)
59
+ klass = Class.new MiniTest::Unit::TestCase
60
+ klass.send :include, mod
61
+ klass.send :include, Assertions
62
+
63
+ mod.const_set("TestCase", klass)
64
+ klass
65
+ end
66
+ end
@@ -0,0 +1,118 @@
1
+ #
2
+ #
3
+ # Some assertions
4
+ module Etest::Assertions
5
+ def assert_respond_to(obj, *args)
6
+ raise ArgumentError, "Missing argument(s)" if args.length < 1
7
+
8
+ args.reject! { |sym| obj.respond_to?(sym) }
9
+
10
+ assert args.empty?, "#{obj.inspect} should respond to #{args.map(&:inspect).join(", ")}, but doesn't."
11
+ end
12
+
13
+ # returns a list of invalid attributes in a model, as symbols.
14
+ def invalid_attributes(model) #:nodoc:
15
+ model.valid? ? [] : model.errors.instance_variable_get("@errors").keys.map(&:to_sym)
16
+ end
17
+
18
+ #
19
+ # Verifies that a model is valid. Pass in some attributes to only
20
+ # validate those attributes.
21
+ def assert_valid(model, *attributes)
22
+ if attributes.empty?
23
+ assert(model.valid?, "#{model.inspect} should be valid, but isn't: #{model.errors.full_messages.join(", ")}.")
24
+ else
25
+ invalid_attributes = invalid_attributes(model) & attributes
26
+ assert invalid_attributes.empty?,
27
+ "Attribute(s) #{invalid_attributes.join(", ")} should be valid"
28
+ end
29
+ end
30
+
31
+ #
32
+ # Verifies that a model is invalid. Pass in some attributes to only
33
+ # validate those attributes.
34
+ def assert_invalid(model, *attributes)
35
+ assert(!model.valid?, "#{model.inspect} should be invalid, but isn't.")
36
+
37
+ return if attributes.empty?
38
+
39
+ missing_invalids = attributes - invalid_attributes(model)
40
+
41
+ assert missing_invalids.empty?,
42
+ "Attribute(s) #{missing_invalids.join(", ")} should be invalid, but are not"
43
+ end
44
+
45
+ #
46
+ #
47
+ def assert_valid_xml(*args)
48
+ args.push @response.body if args.empty?
49
+
50
+ args.each do |xml|
51
+ assert xml_valid?(xml), "XML is not valid: #{xml}"
52
+ end
53
+ end
54
+
55
+ def xml_valid?(xml)
56
+ require "libxml"
57
+ LibXML::XML::Error.reset_handler
58
+
59
+ LibXML::XML::Document.io StringIO.new(xml)
60
+ true
61
+ rescue LibXML::XML::Error
62
+ false
63
+ end
64
+
65
+ def assert_invalid_xml(*args)
66
+ args.push @response.body if args.empty?
67
+
68
+ args.each do |xml|
69
+ assert !xml_valid?(xml), "XML should not be valid: #{xml}"
70
+ end
71
+ end
72
+
73
+ def assert_route(uri_path, params)
74
+ assert_recognizes params, uri_path
75
+ end
76
+
77
+ def assert_raises_kind_of(klass, &block)
78
+ begin
79
+ yield
80
+ assert false, "Should raise a #{klass} exception, but didn't raise at all"
81
+ rescue klass
82
+ assert $!.is_a?(klass), "Should raise a #{klass} exception, but raised a #{$!.class.name} exception"
83
+ end
84
+ end
85
+ end
86
+
87
+
88
+ module Etest::Assertions::Etest
89
+ #
90
+ # this actually tests the existance of an assertion and one successful
91
+ # assertion, nothing less, and nothing more...
92
+ def test_asserts
93
+ assert_respond_to "nsn", :upcase
94
+ assert respond_to?(:assert_invalid)
95
+ assert respond_to?(:assert_valid)
96
+ end
97
+
98
+ class TestError < RuntimeError; end
99
+
100
+ def test_assert_raises_kind_of
101
+ assert_raises_kind_of RuntimeError do
102
+ raise TestError
103
+ end
104
+ end
105
+
106
+ def test_xml
107
+ assert_valid_xml <<-XML
108
+ <root>
109
+ <p> lkhj </p>
110
+ </root>
111
+ XML
112
+
113
+ assert_invalid_xml <<-XML
114
+ <root>
115
+ <p> lkhj </p>
116
+ XML
117
+ end
118
+ end
data/lib/etest/grep.rb ADDED
@@ -0,0 +1,39 @@
1
+ __END__
2
+
3
+ module Etest::Grep
4
+ def self.load_from_directories(*dirs)
5
+ raise ArgumentError, "Missing directories" if dirs.empty?
6
+ # -- collect tests
7
+
8
+ STDERR.puts "\nLoad etests"
9
+
10
+ etests = []
11
+ rex = /^\s*module\s+(\S*\bEtest\b)/
12
+
13
+ dirs.each do |dir|
14
+ File.grep(rex, Dir.glob("#{dir}/**/*.rb")) do |_, _, matches|
15
+ etests << matches[1]
16
+ end
17
+ end
18
+
19
+ etests = etests.uniq.sort
20
+
21
+ # -- load tests
22
+
23
+ etests = etests.uniq.sort.each do |etest|
24
+ mod = etest.constantize rescue nil
25
+ next STDERR.puts(" #{etest}: cannot load test") unless mod
26
+
27
+ tests = mod.instance_methods.select { |m| m =~ /^test_/ }
28
+
29
+ next STDERR.puts(" #{etest}: Does not define any tests") if tests.empty?
30
+
31
+ STDERR.puts(" #{etest}: w/#{tests.length} tests")
32
+
33
+ klass = Class.new(Mpx::TestCase)
34
+ klass.send :include, mod
35
+
36
+ mod.const_set("TestCase", klass)
37
+ end.compact
38
+ end
39
+ end
data/lib/module_ext.rb ADDED
@@ -0,0 +1,58 @@
1
+ #
2
+ # TDD helpers for modules.
3
+ class Module
4
+ #
5
+ # reloads the module, and runs the module's etests.
6
+ def etest
7
+ reload if respond_to?(:reload)
8
+ ::Etest.run self.const_get("Etest")
9
+ end
10
+
11
+ #
12
+ # returns all instances of a module
13
+ def instances #:nodoc:
14
+ r = []
15
+ ObjectSpace.each_object(self) { |mod| r << mod }
16
+ r
17
+ end
18
+
19
+ #
20
+ # load a module by name.
21
+ def self.by_name(name) #:nodoc:
22
+ old_verbose, $VERBOSE = $VERBOSE, nil
23
+
24
+ r = eval(name, nil, __FILE__, __LINE__)
25
+ r if r.is_a?(Module) && r.name == name
26
+ rescue NameError, LoadError
27
+ nil
28
+ ensure
29
+ $VERBOSE = old_verbose
30
+ end
31
+
32
+ #
33
+ # tries to reload the source file for this module. THIS IS A DEVELOPMENT
34
+ # helper, don't try to use it in production mode!
35
+ #
36
+ # Limitations:
37
+ #
38
+ # To reload a module with a name of "X::Y" we try to load (in that order)
39
+ # "x/y.rb", "x.rb"
40
+ #
41
+ def reload
42
+ Module::Reloader.reload_file("#{to_s.underscore}.rb") || begin
43
+ dlog("Cannot reload module #{self}")
44
+ false
45
+ end
46
+ end
47
+
48
+ module Reloader #:nodoc:
49
+ def self.reload_file(file)
50
+ begin
51
+ load(file) && file
52
+ rescue LoadError
53
+ nfile = file.gsub(/\/[^\/]+\.rb/, ".rb")
54
+ nfile != file && reload_file(nfile)
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/string_ext.rb ADDED
@@ -0,0 +1,27 @@
1
+ class String
2
+ # taken from active-support
3
+ def underscore
4
+ gsub(/::/, '/').
5
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
6
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
7
+ tr("-", "_").
8
+ downcase
9
+ end
10
+
11
+ def camelize
12
+ gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
13
+ end
14
+ end
15
+
16
+ module String::Etest
17
+ def test_camelize
18
+ assert_equal "x", "X".underscore
19
+ assert_equal "xa_la_nder", "XaLaNder".underscore
20
+ end
21
+
22
+ def test_underscore
23
+ assert_equal "X", "x".camelize
24
+ assert_equal "XaLaNder", "xa_la_nder".camelize
25
+ end
26
+ end
27
+
data/script/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require "irb"
3
+ require "rubygems"
4
+ $: << "#{File.dirname(__FILE__)}/../lib"
5
+
6
+ require "etest"
7
+
8
+ IRB.start
data/script/rebuild ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+ rake default build_gemspec package || exit 1
3
+ echo "============================================="
4
+ echo "I built the gem for you. To upload, run "
5
+ echo
6
+ echo "gem push $(ls -d pkg/*.gem | tail -n 1)"
7
+
data/test/test.rb ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ DIRNAME = File.expand_path File.dirname(__FILE__)
3
+ Dir.chdir(DIRNAME)
4
+
5
+ #
6
+ # initialize the gem
7
+ require '../init'
8
+
9
+ require 'logger'
10
+ require 'rubygems'
11
+ require 'ruby-debug'
12
+
13
+ LOGFILE = "log/test.log"
14
+ SQLITE_FILE = ":memory:"
15
+
16
+ #
17
+ # -- set up fake rails ------------------------------------------------
18
+
19
+ RAILS_ENV="test"
20
+ RAILS_ROOT="#{DIRNAME}"
21
+
22
+ if !defined?(RAILS_DEFAULT_LOGGER)
23
+ FileUtils.mkdir_p File.dirname(LOGFILE)
24
+ RAILS_DEFAULT_LOGGER = Logger.new(LOGFILE)
25
+ RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
26
+ end
27
+
28
+ #
29
+ # -- set up active record for tests -----------------------------------
30
+
31
+ if defined?(ActiveRecord::Base) && !ActiveRecord::Base.connection
32
+ ActiveRecord::Base.logger = RAILS_DEFAULT_LOGGER
33
+ FileUtils.mkdir_p File.dirname(SQLITE_FILE) unless SQLITE_FILE == ":memory:"
34
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3",
35
+ :database => SQLITE_FILE
36
+ end
37
+
38
+ # ---------------------------------------------------------------------
39
+
40
+ module Fixnum::Etest
41
+ def test_success
42
+ $etests_did_run = true
43
+ assert true
44
+ end
45
+ end
46
+
47
+ $etests_did_run = false
48
+ Etest.reload
49
+ Etest.auto_run
50
+
51
+ unless $etests_did_run
52
+ STDERR.puts "Something's wrong with etests :("
53
+ exit 1
54
+ end
55
+
56
+ STDERR.puts "===== Reloading and rerunning one test"
57
+
58
+ $etests_did_run = false
59
+
60
+ Fixnum.etest
61
+
62
+ unless $etests_did_run
63
+ STDERR.puts "Something's wrong with etests :("
64
+ exit 1
65
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: etest
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - pboy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-28 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Embedded tests
17
+ email: eno-pboy@open-lab.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/dlog_ext.rb
24
+ - lib/etest.rb
25
+ - lib/etest/assertions.rb
26
+ - lib/etest/grep.rb
27
+ - lib/module_ext.rb
28
+ - lib/string_ext.rb
29
+ files:
30
+ - Manifest
31
+ - Rakefile
32
+ - etest.gemspec
33
+ - init.rb
34
+ - lib/dlog_ext.rb
35
+ - lib/etest.rb
36
+ - lib/etest/assertions.rb
37
+ - lib/etest/grep.rb
38
+ - lib/module_ext.rb
39
+ - lib/string_ext.rb
40
+ - script/console
41
+ - script/rebuild
42
+ - test/test.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/pboy/etest
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --line-numbers
50
+ - --inline-source
51
+ - --title
52
+ - Etest
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "1.2"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: etest
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Embedded tests
74
+ test_files: []
75
+