activegroonga 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/AUTHORS +1 -0
  2. data/NEWS.ja.rdoc +5 -0
  3. data/NEWS.rdoc +5 -0
  4. data/README.ja.rdoc +49 -0
  5. data/README.rdoc +49 -0
  6. data/Rakefile +175 -0
  7. data/lib/active_groonga.rb +75 -0
  8. data/lib/active_groonga/aggregations.rb +30 -0
  9. data/lib/active_groonga/associations.rb +93 -0
  10. data/lib/active_groonga/associations/belongs_to_association.rb +25 -0
  11. data/lib/active_groonga/attribute_methods.rb +36 -0
  12. data/lib/active_groonga/base.rb +1579 -0
  13. data/lib/active_groonga/column.rb +107 -0
  14. data/lib/active_groonga/dirty.rb +30 -0
  15. data/lib/active_groonga/fixtures.rb +92 -0
  16. data/lib/active_groonga/migration.rb +150 -0
  17. data/lib/active_groonga/rails_support.rb +31 -0
  18. data/lib/active_groonga/reflection.rb +30 -0
  19. data/lib/active_groonga/schema.rb +314 -0
  20. data/lib/active_groonga/schema_dumper.rb +147 -0
  21. data/lib/active_groonga/tasks.rb +16 -0
  22. data/lib/active_groonga/tasks/groonga.rake +162 -0
  23. data/lib/active_groonga/test_case.rb +21 -0
  24. data/lib/active_groonga/test_help.rb +21 -0
  25. data/lib/active_groonga/timestamp.rb +30 -0
  26. data/lib/active_groonga/validations.rb +26 -0
  27. data/lib/active_groonga/version.rb +24 -0
  28. data/license/LGPL +504 -0
  29. data/rails/README +28 -0
  30. data/rails/init.rb +70 -0
  31. data/rails_generators/model_groonga/USAGE +28 -0
  32. data/rails_generators/model_groonga/model_groonga_generator.rb +45 -0
  33. data/rails_generators/model_groonga/templates/fixtures.yml +17 -0
  34. data/rails_generators/model_groonga/templates/migration.rb +16 -0
  35. data/rails_generators/model_groonga/templates/model.rb +2 -0
  36. data/rails_generators/model_groonga/templates/unit_test.rb +8 -0
  37. data/test-unit/Rakefile +35 -0
  38. data/test-unit/TODO +5 -0
  39. data/test-unit/bin/testrb +5 -0
  40. data/test-unit/html/classic.html +15 -0
  41. data/test-unit/html/index.html +25 -0
  42. data/test-unit/html/index.html.ja +27 -0
  43. data/test-unit/lib/test/unit.rb +342 -0
  44. data/test-unit/lib/test/unit/assertionfailederror.rb +14 -0
  45. data/test-unit/lib/test/unit/assertions.rb +1149 -0
  46. data/test-unit/lib/test/unit/attribute.rb +125 -0
  47. data/test-unit/lib/test/unit/autorunner.rb +306 -0
  48. data/test-unit/lib/test/unit/collector.rb +43 -0
  49. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  50. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  51. data/test-unit/lib/test/unit/collector/load.rb +135 -0
  52. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  53. data/test-unit/lib/test/unit/color-scheme.rb +86 -0
  54. data/test-unit/lib/test/unit/color.rb +96 -0
  55. data/test-unit/lib/test/unit/diff.rb +538 -0
  56. data/test-unit/lib/test/unit/error.rb +124 -0
  57. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  58. data/test-unit/lib/test/unit/failure.rb +110 -0
  59. data/test-unit/lib/test/unit/fixture.rb +176 -0
  60. data/test-unit/lib/test/unit/notification.rb +125 -0
  61. data/test-unit/lib/test/unit/omission.rb +143 -0
  62. data/test-unit/lib/test/unit/pending.rb +146 -0
  63. data/test-unit/lib/test/unit/priority.rb +161 -0
  64. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  65. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  66. data/test-unit/lib/test/unit/testcase.rb +360 -0
  67. data/test-unit/lib/test/unit/testresult.rb +89 -0
  68. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  69. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  70. data/test-unit/lib/test/unit/ui/console/testrunner.rb +220 -0
  71. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  72. data/test-unit/lib/test/unit/ui/testrunner.rb +20 -0
  73. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  74. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  75. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  76. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  77. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  78. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  79. data/test-unit/lib/test/unit/version.rb +7 -0
  80. data/test-unit/sample/adder.rb +13 -0
  81. data/test-unit/sample/subtracter.rb +12 -0
  82. data/test-unit/sample/tc_adder.rb +18 -0
  83. data/test-unit/sample/tc_subtracter.rb +18 -0
  84. data/test-unit/sample/test_user.rb +22 -0
  85. data/test-unit/sample/ts_examples.rb +7 -0
  86. data/test-unit/test/collector/test-descendant.rb +135 -0
  87. data/test-unit/test/collector/test-load.rb +333 -0
  88. data/test-unit/test/collector/test_dir.rb +406 -0
  89. data/test-unit/test/collector/test_objectspace.rb +98 -0
  90. data/test-unit/test/run-test.rb +13 -0
  91. data/test-unit/test/test-attribute.rb +86 -0
  92. data/test-unit/test/test-color-scheme.rb +56 -0
  93. data/test-unit/test/test-color.rb +47 -0
  94. data/test-unit/test/test-diff.rb +477 -0
  95. data/test-unit/test/test-emacs-runner.rb +60 -0
  96. data/test-unit/test/test-fixture.rb +287 -0
  97. data/test-unit/test/test-notification.rb +33 -0
  98. data/test-unit/test/test-omission.rb +81 -0
  99. data/test-unit/test/test-pending.rb +70 -0
  100. data/test-unit/test/test-priority.rb +119 -0
  101. data/test-unit/test/test_assertions.rb +1082 -0
  102. data/test-unit/test/test_error.rb +26 -0
  103. data/test-unit/test/test_failure.rb +33 -0
  104. data/test-unit/test/test_testcase.rb +478 -0
  105. data/test-unit/test/test_testresult.rb +113 -0
  106. data/test-unit/test/test_testsuite.rb +129 -0
  107. data/test-unit/test/testunit-test-util.rb +14 -0
  108. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  109. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  110. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  111. data/test-unit/test/util/test_observable.rb +102 -0
  112. data/test-unit/test/util/test_procwrapper.rb +36 -0
  113. data/test/active-groonga-test-utils.rb +234 -0
  114. data/test/fixtures/bookmark.rb +2 -0
  115. data/test/fixtures/task.rb +2 -0
  116. data/test/fixtures/user.rb +2 -0
  117. data/test/run-test.rb +51 -0
  118. data/test/test-associations.rb +24 -0
  119. data/test/test-base.rb +194 -0
  120. data/test/test-schema.rb +49 -0
  121. metadata +192 -0
data/rails/README ADDED
@@ -0,0 +1,28 @@
1
+ = ActiveGroonga plugin for Ruby on Rails
2
+
3
+ == Setup
4
+
5
+ You need to write RAILS_ROOT/config/groonga.yml like the following:
6
+
7
+ development:
8
+ database: db/development.groonga
9
+
10
+ test:
11
+ database: db/test.groonga
12
+
13
+ production:
14
+ database: db/production.groonga
15
+
16
+ == Model
17
+
18
+ Here is some examples.
19
+
20
+ app/model/post.rb:
21
+ class Post < ActiveGroonga::Base
22
+ belongs_to :users
23
+ end
24
+
25
+ app/model/user.rb:
26
+ class User < ActiveGroonga::Base
27
+ has_many :posts
28
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,70 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ActiveGroonga::Base.logger ||= Rails.logger
4
+
5
+ case Rails.logger.level
6
+ when ActiveSupport::BufferedLogger::DEBUG
7
+ log_level = :debug
8
+ when ActiveSupport::BufferedLogger::INFO
9
+ log_level = :info
10
+ when ActiveSupport::BufferedLogger::WARN
11
+ log_level = :warning
12
+ when ActiveSupport::BufferedLogger::ERROR
13
+ log_level = :error
14
+ when ActiveSupport::BufferedLogger::FATAL
15
+ log_level = :critical
16
+ when ActiveSupport::BufferedLogger::UNKNOWN
17
+ log_level = :none
18
+ else
19
+ log_level = :info
20
+ end
21
+ options = {:level => log_level}
22
+ Groonga::Logger.register(options) do |level, time, title, message, location|
23
+ logger = ActiveGroonga::Base.logger
24
+ method_name = :info
25
+ case level
26
+ when :debug
27
+ method_name = :debug
28
+ when :info
29
+ method_name = :info
30
+ when :warning
31
+ method_name = :warn
32
+ when :error
33
+ method_name = :error
34
+ when :critical
35
+ method_name = :fatal
36
+ when :none
37
+ method_name = :unknown
38
+ end
39
+ message = "[#{title}] #{message}" unless title.blank?
40
+ logger.send(method_name, message)
41
+ end
42
+
43
+ configuration_file = config.groonga_configuration_file
44
+ unless File.exist?(configuration_file)
45
+ File.open(configuration_file, "w") do |file|
46
+ file.puts <<-EOC
47
+ development:
48
+ database: db/development.groonga
49
+
50
+ test:
51
+ database: db/test.groonga
52
+
53
+ production:
54
+ database: db/production.groonga
55
+ EOC
56
+ end
57
+ end
58
+ ActiveGroonga::Base.configurations = config.groonga_configuration
59
+ ActiveGroonga::Base.setup_database
60
+
61
+ # class ::ActionView::Base
62
+ # include ActiveGroonga::Helper
63
+ # end
64
+
65
+ # require 'active_groonga/action_controller/groonga_benchmarking'
66
+ # module ::ActionController
67
+ # class Base
68
+ # include ActiveGroonga::ActionController::GroongaBenchmarking
69
+ # end
70
+ # end
@@ -0,0 +1,28 @@
1
+ Description:
2
+ Stubs out a new model. Pass the model name, either CamelCased or
3
+ under_scored, and an optional list of attribute pairs as arguments.
4
+
5
+ Attribute pairs are column_name:groonga_type arguments specifying the
6
+ model's attributes. Timestamps are added by default, so you don't have to
7
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
8
+
9
+ You don't have to think up every attribute up front, but it helps to
10
+ sketch out a few so you can start working with the model immediately.
11
+
12
+ This generates a model class in app/models, a unit test in test/unit,
13
+ a test fixture in test/fixtures/singular_name.yml, and a migration in
14
+ db/migrate.
15
+
16
+ Examples:
17
+ `./script/generate model_groonga account`
18
+
19
+ creates an Account model, test, fixture, and migration:
20
+ Model: app/models/account.rb
21
+ Test: test/unit/account_test.rb
22
+ Fixtures: test/fixtures/accounts.yml
23
+ Migration: db/migrate/XXX_add_accounts.rb
24
+
25
+ `./script/generate model_groonga Post title:string content:text user:references`
26
+
27
+ creates a Post model with a string title, text content, and user who posts.
28
+
@@ -0,0 +1,45 @@
1
+ class ModelGroongaGenerator < Rails::Generator::NamedBase
2
+ default_options :skip_timestamps => false, :skip_migration => false, :skip_fixture => false
3
+
4
+ def manifest
5
+ record do |m|
6
+ # Check for class naming collisions.
7
+ m.class_collisions class_name, "#{class_name}Test"
8
+
9
+ # Model, test, and fixture directories.
10
+ m.directory File.join('app/models', class_path)
11
+ m.directory File.join('test/unit', class_path)
12
+ m.directory File.join('test/fixtures', class_path)
13
+
14
+ # Model class, unit test, and fixtures.
15
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
16
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
17
+
18
+ unless options[:skip_fixture]
19
+ m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
20
+ end
21
+
22
+ unless options[:skip_migration]
23
+ m.migration_template 'migration.rb', 'db/groonga/migrate', :assigns => {
24
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
25
+ }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+ def banner
32
+ "Usage: #{$0} #{spec.name} ModelName [field:type, field:type]"
33
+ end
34
+
35
+ def add_options!(opt)
36
+ opt.separator ''
37
+ opt.separator 'Options:'
38
+ opt.on("--skip-timestamps",
39
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
40
+ opt.on("--skip-migration",
41
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
42
+ opt.on("--skip-fixture",
43
+ "Don't generation a fixture file for this model") { |v| options[:skip_fixture] = v}
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ <% unless attributes.empty? -%>
2
+ one:
3
+ <% for attribute in attributes -%>
4
+ <%= attribute.name %>: <%= attribute.default %>
5
+ <% end -%>
6
+
7
+ two:
8
+ <% for attribute in attributes -%>
9
+ <%= attribute.name %>: <%= attribute.default %>
10
+ <% end -%>
11
+ <% else -%>
12
+ # one:
13
+ # column: value
14
+ #
15
+ # two:
16
+ # column: value
17
+ <% end -%>
@@ -0,0 +1,16 @@
1
+ class <%= migration_name %> < ActiveGroonga::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% for attribute in attributes -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% unless options[:skip_timestamps] %>
8
+ t.timestamps
9
+ <% end -%>
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= table_name %>
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ class <%= class_name %> < ActiveGroonga::Base
2
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/test/unit/version.rb'
6
+
7
+ version = Test::Unit::VERSION
8
+ ENV["VERSION"] = version
9
+ Hoe.new('test-unit', version) do |p|
10
+ p.developer('Kouhei Sutou', 'kou@cozmixng.org')
11
+ p.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
12
+
13
+ # Ex-Parrot:
14
+ # p.developer('Nathaniel Talbott', 'nathaniel@talbott.ws')
15
+ end
16
+
17
+ task :check_manifest => :clean_test_result
18
+ task :check_manifest => :clean_coverage
19
+
20
+ task :clean_test_result do
21
+ test_results = Dir.glob("**/.test-result")
22
+ sh("rm", "-rf", *test_results) unless test_results.empty?
23
+ end
24
+
25
+ task :clean_coverage do
26
+ sh("rm", "-rf", "coverage")
27
+ end
28
+
29
+ task :tag do
30
+ message = "Released Test::Unit #{version}!"
31
+ base = "svn+ssh://#{ENV['USER']}@rubyforge.org/var/svn/test-unit/"
32
+ sh 'svn', 'copy', '-m', message, "#{base}trunk", "#{base}tags/#{version}"
33
+ end
34
+
35
+ # vim: syntax=Ruby
data/test-unit/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * mock.
2
+ * data-driven test.
3
+ * port ruby trunk's assert_equal's intelligent inspection
4
+ when inspected expected and actual are same content
5
+ string.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ (r = Test::Unit::AutoRunner.new(true)).process_args(ARGV) or
4
+ abort r.options.banner + " tests..."
5
+ exit r.run
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
+ <html>
3
+ <head>
4
+ <title>Test::Unit (Classic)</title>
5
+ </head>
6
+ <body bgcolor="red">
7
+ <p style="text-align: center">
8
+ <img height="161" width="308" src="test-unit-classic.png">
9
+ <br>
10
+ <br>
11
+ <br>
12
+ Read the <a href="classic/test-unit/">rdoc</a>
13
+ </p>
14
+ </body>
15
+ </html>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
6
+ <head>
7
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
8
+ <title>Test::Unit - a Unit Testing Framework for Ruby</title>
9
+ </head>
10
+ <body>
11
+ <h1>Test::Unit - a Unit Testing Framework for Ruby</h1>
12
+ <p>[<a href="index.html.ja">Japanese</a>]</p>
13
+ <ul>
14
+ <li><a href="http://rubyforge.org/projects/test-unit/">Project Page</a></li>
15
+ <li>
16
+ <a href="test-unit/">RDoc</a>
17
+ <!--(<a href="ja/test-unit/">ja</a>)-->
18
+ </li>
19
+ <li>
20
+ <a href="classic.html">Classic</a>
21
+ <!--(<a href="ja/classic.html">ja</a>)-->
22
+ </li>
23
+ </ul>
24
+ </body>
25
+ </html>
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
6
+ <head>
7
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
8
+ <title>Test::Unit - Ruby用単体テストフレームワーク</title>
9
+ </head>
10
+ <body>
11
+ <h1>Test::Unit - Ruby用単体テストフレームワーク</h1>
12
+ <p>[<a href="./">English</a>]</p>
13
+ <ul>
14
+ <li>
15
+ <a href="http://rubyforge.org/projects/test-unit/">プロジェクトページ</a>
16
+ </li>
17
+ <li>
18
+ <!--<a href="ja/test-unit/">RDoc</a>-->
19
+ RDoc(<a href="test-unit/">en</a>)
20
+ </li>
21
+ <li>
22
+ <!--<a href="classic.html.html">Classic</a>-->
23
+ Classic(<a href="classic.html">en</a>)
24
+ </li>
25
+ </ul>
26
+ </body>
27
+ </html>
@@ -0,0 +1,342 @@
1
+ require 'test/unit/testcase'
2
+ require 'test/unit/autorunner'
3
+
4
+ module Test # :nodoc:
5
+ #
6
+ # = Test::Unit - Ruby Unit Testing Framework
7
+ #
8
+ # == Introduction
9
+ #
10
+ # Unit testing is making waves all over the place, largely due to the
11
+ # fact that it is a core practice of XP. While XP is great, unit testing
12
+ # has been around for a long time and has always been a good idea. One
13
+ # of the keys to good unit testing, though, is not just writing tests,
14
+ # but having tests. What's the difference? Well, if you just _write_ a
15
+ # test and throw it away, you have no guarantee that something won't
16
+ # change later which breaks your code. If, on the other hand, you _have_
17
+ # tests (obviously you have to write them first), and run them as often
18
+ # as possible, you slowly build up a wall of things that cannot break
19
+ # without you immediately knowing about it. This is when unit testing
20
+ # hits its peak usefulness.
21
+ #
22
+ # Enter Test::Unit, a framework for unit testing in Ruby, helping you to
23
+ # design, debug and evaluate your code by making it easy to write and
24
+ # have tests for it.
25
+ #
26
+ #
27
+ # == Notes
28
+ #
29
+ # Test::Unit has grown out of and superceded Lapidary.
30
+ #
31
+ #
32
+ # == Feedback
33
+ #
34
+ # I like (and do my best to practice) XP, so I value early releases,
35
+ # user feedback, and clean, simple, expressive code. There is always
36
+ # room for improvement in everything I do, and Test::Unit is no
37
+ # exception. Please, let me know what you think of Test::Unit as it
38
+ # stands, and what you'd like to see expanded/changed/improved/etc. If
39
+ # you find a bug, let me know ASAP; one good way to let me know what the
40
+ # bug is is to submit a new test that catches it :-) Also, I'd love to
41
+ # hear about any successes you have with Test::Unit, and any
42
+ # documentation you might add will be greatly appreciated. My contact
43
+ # info is below.
44
+ #
45
+ #
46
+ # == Contact Information
47
+ #
48
+ # A lot of discussion happens about Ruby in general on the ruby-talk
49
+ # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask
50
+ # any questions you might have there. I monitor the list, as do many
51
+ # other helpful Rubyists, and you're sure to get a quick answer. Of
52
+ # course, you're also welcome to email me (Nathaniel Talbott) directly
53
+ # at mailto:testunit@talbott.ws, and I'll do my best to help you out.
54
+ #
55
+ #
56
+ # == Credits
57
+ #
58
+ # I'd like to thank...
59
+ #
60
+ # Matz, for a great language!
61
+ #
62
+ # Masaki Suketa, for his work on RubyUnit, which filled a vital need in
63
+ # the Ruby world for a very long time. I'm also grateful for his help in
64
+ # polishing Test::Unit and getting the RubyUnit compatibility layer
65
+ # right. His graciousness in allowing Test::Unit to supercede RubyUnit
66
+ # continues to be a challenge to me to be more willing to defer my own
67
+ # rights.
68
+ #
69
+ # Ken McKinlay, for his interest and work on unit testing, and for his
70
+ # willingness to dialog about it. He was also a great help in pointing
71
+ # out some of the holes in the RubyUnit compatibility layer.
72
+ #
73
+ # Dave Thomas, for the original idea that led to the extremely simple
74
+ # "require 'test/unit'", plus his code to improve it even more by
75
+ # allowing the selection of tests from the command-line. Also, without
76
+ # RDoc, the documentation for Test::Unit would stink a lot more than it
77
+ # does now.
78
+ #
79
+ # Everyone who's helped out with bug reports, feature ideas,
80
+ # encouragement to continue, etc. It's a real privilege to be a part of
81
+ # the Ruby community.
82
+ #
83
+ # The guys at RoleModel Software, for putting up with me repeating, "But
84
+ # this would be so much easier in Ruby!" whenever we're coding in Java.
85
+ #
86
+ # My Creator, for giving me life, and giving it more abundantly.
87
+ #
88
+ #
89
+ # == License
90
+ #
91
+ # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free
92
+ # software, and is distributed under the Ruby license. See the COPYING
93
+ # file in the standard Ruby distribution for details.
94
+ #
95
+ #
96
+ # == Warranty
97
+ #
98
+ # This software is provided "as is" and without any express or
99
+ # implied warranties, including, without limitation, the implied
100
+ # warranties of merchantibility and fitness for a particular
101
+ # purpose.
102
+ #
103
+ #
104
+ # == Author
105
+ #
106
+ # Nathaniel Talbott.
107
+ # Copyright (c) 2000-2003, Nathaniel Talbott
108
+ #
109
+ # ----
110
+ #
111
+ # = Usage
112
+ #
113
+ # The general idea behind unit testing is that you write a _test_
114
+ # _method_ that makes certain _assertions_ about your code, working
115
+ # against a _test_ _fixture_. A bunch of these _test_ _methods_ are
116
+ # bundled up into a _test_ _suite_ and can be run any time the
117
+ # developer wants. The results of a run are gathered in a _test_
118
+ # _result_ and displayed to the user through some UI. So, lets break
119
+ # this down and see how Test::Unit provides each of these necessary
120
+ # pieces.
121
+ #
122
+ #
123
+ # == Assertions
124
+ #
125
+ # These are the heart of the framework. Think of an assertion as a
126
+ # statement of expected outcome, i.e. "I assert that x should be equal
127
+ # to y". If, when the assertion is executed, it turns out to be
128
+ # correct, nothing happens, and life is good. If, on the other hand,
129
+ # your assertion turns out to be false, an error is propagated with
130
+ # pertinent information so that you can go back and make your
131
+ # assertion succeed, and, once again, life is good. For an explanation
132
+ # of the current assertions, see Test::Unit::Assertions.
133
+ #
134
+ #
135
+ # == Test Method & Test Fixture
136
+ #
137
+ # Obviously, these assertions have to be called within a context that
138
+ # knows about them and can do something meaningful with their
139
+ # pass/fail value. Also, it's handy to collect a bunch of related
140
+ # tests, each test represented by a method, into a common test class
141
+ # that knows how to run them. The tests will be in a separate class
142
+ # from the code they're testing for a couple of reasons. First of all,
143
+ # it allows your code to stay uncluttered with test code, making it
144
+ # easier to maintain. Second, it allows the tests to be stripped out
145
+ # for deployment, since they're really there for you, the developer,
146
+ # and your users don't need them. Third, and most importantly, it
147
+ # allows you to set up a common test fixture for your tests to run
148
+ # against.
149
+ #
150
+ # What's a test fixture? Well, tests do not live in a vacuum; rather,
151
+ # they're run against the code they are testing. Often, a collection
152
+ # of tests will run against a common set of data, also called a
153
+ # fixture. If they're all bundled into the same test class, they can
154
+ # all share the setting up and tearing down of that data, eliminating
155
+ # unnecessary duplication and making it much easier to add related
156
+ # tests.
157
+ #
158
+ # Test::Unit::TestCase wraps up a collection of test methods together
159
+ # and allows you to easily set up and tear down the same test fixture
160
+ # for each test. This is done by overriding #setup and/or #teardown,
161
+ # which will be called before and after each test method that is
162
+ # run. The TestCase also knows how to collect the results of your
163
+ # assertions into a Test::Unit::TestResult, which can then be reported
164
+ # back to you... but I'm getting ahead of myself. To write a test,
165
+ # follow these steps:
166
+ #
167
+ # * Make sure Test::Unit is in your library path.
168
+ # * require 'test/unit' in your test script.
169
+ # * Create a class that subclasses Test::Unit::TestCase.
170
+ # * Add a method that begins with "test" to your class.
171
+ # * Make assertions in your test method.
172
+ # * Optionally define #setup and/or #teardown to set up and/or tear
173
+ # down your common test fixture.
174
+ # * You can now run your test as you would any other Ruby
175
+ # script... try it and see!
176
+ #
177
+ # A really simple test might look like this (#setup and #teardown are
178
+ # commented out to indicate that they are completely optional):
179
+ #
180
+ # require 'test/unit'
181
+ #
182
+ # class TC_MyTest < Test::Unit::TestCase
183
+ # # def setup
184
+ # # end
185
+ #
186
+ # # def teardown
187
+ # # end
188
+ #
189
+ # def test_fail
190
+ # assert(false, 'Assertion was false.')
191
+ # end
192
+ # end
193
+ #
194
+ #
195
+ # == Test Runners
196
+ #
197
+ # So, now you have this great test class, but you still need a way to
198
+ # run it and view any failures that occur during the run. This is
199
+ # where Test::Unit::UI::Console::TestRunner (and others, such as
200
+ # Test::Unit::UI::GTK::TestRunner) comes into play. The console test
201
+ # runner is automatically invoked for you if you require 'test/unit'
202
+ # and simply run the file. To use another runner, or to manually
203
+ # invoke a runner, simply call its run class method and pass in an
204
+ # object that responds to the suite message with a
205
+ # Test::Unit::TestSuite. This can be as simple as passing in your
206
+ # TestCase class (which has a class suite method). It might look
207
+ # something like this:
208
+ #
209
+ # require 'test/unit/ui/console/testrunner'
210
+ # Test::Unit::UI::Console::TestRunner.run(TC_MyTest)
211
+ #
212
+ #
213
+ # == Test Suite
214
+ #
215
+ # As more and more unit tests accumulate for a given project, it
216
+ # becomes a real drag running them one at a time, and it also
217
+ # introduces the potential to overlook a failing test because you
218
+ # forget to run it. Suddenly it becomes very handy that the
219
+ # TestRunners can take any object that returns a Test::Unit::TestSuite
220
+ # in response to a suite method. The TestSuite can, in turn, contain
221
+ # other TestSuites or individual tests (typically created by a
222
+ # TestCase). In other words, you can easily wrap up a group of
223
+ # TestCases and TestSuites like this:
224
+ #
225
+ # require 'test/unit/testsuite'
226
+ # require 'tc_myfirsttests'
227
+ # require 'tc_moretestsbyme'
228
+ # require 'ts_anothersetoftests'
229
+ #
230
+ # class TS_MyTests
231
+ # def self.suite
232
+ # suite = Test::Unit::TestSuite.new
233
+ # suite << TC_MyFirstTests.suite
234
+ # suite << TC_MoreTestsByMe.suite
235
+ # suite << TS_AnotherSetOfTests.suite
236
+ # return suite
237
+ # end
238
+ # end
239
+ # Test::Unit::UI::Console::TestRunner.run(TS_MyTests)
240
+ #
241
+ # Now, this is a bit cumbersome, so Test::Unit does a little bit more
242
+ # for you, by wrapping these up automatically when you require
243
+ # 'test/unit'. What does this mean? It means you could write the above
244
+ # test case like this instead:
245
+ #
246
+ # require 'test/unit'
247
+ # require 'tc_myfirsttests'
248
+ # require 'tc_moretestsbyme'
249
+ # require 'ts_anothersetoftests'
250
+ #
251
+ # Test::Unit is smart enough to find all the test cases existing in
252
+ # the ObjectSpace and wrap them up into a suite for you. It then runs
253
+ # the dynamic suite using the console TestRunner.
254
+ #
255
+ #
256
+ # == Configuration file
257
+ #
258
+ # Test::Unit reads 'test-unit.yml' in the current working
259
+ # directory as Test::Unit's configuration file. It can
260
+ # contain the following configurations:
261
+ #
262
+ # * color scheme definitions
263
+ # * test runner to be used
264
+ # * test runner options
265
+ # * test collector to be used
266
+ #
267
+ # Except color scheme definitions, all of them are
268
+ # specified by command line option.
269
+ #
270
+ # Here are sample color scheme definitions:
271
+ #
272
+ # color_schemes:
273
+ # inverted:
274
+ # success:
275
+ # name: red
276
+ # bold: true
277
+ # failure:
278
+ # name: green
279
+ # bold: true
280
+ # other_scheme:
281
+ # ...
282
+ #
283
+ # Here are the syntax of color scheme definitions:
284
+ #
285
+ # color_schemes:
286
+ # SCHEME_NAME:
287
+ # EVENT_NAME:
288
+ # name: COLOR_NAME
289
+ # intensity: BOOLEAN
290
+ # bold: BOOLEAN
291
+ # italic: BOOLEAN
292
+ # underline: BOOLEAN
293
+ # ...
294
+ # ...
295
+ #
296
+ # SCHEME_NAME:: the name of the color scheme
297
+ # EVENT_NAME:: one of [success, failure, pending,
298
+ # omission, notification, error]
299
+ # COLOR_NAME:: one of [black, red, green, yellow, blue,
300
+ # magenta, cyan, white]
301
+ # BOOLEAN:: true or false
302
+ #
303
+ # You can use the above 'inverted' color scheme with the
304
+ # following configuration:
305
+ #
306
+ # runner: console
307
+ # console_options:
308
+ # color_scheme: inverted
309
+ # color_schemes:
310
+ # inverted:
311
+ # success:
312
+ # name: red
313
+ # bold: true
314
+ # failure:
315
+ # name: green
316
+ # bold: true
317
+ #
318
+ # == Questions?
319
+ #
320
+ # I'd really like to get feedback from all levels of Ruby
321
+ # practitioners about typos, grammatical errors, unclear statements,
322
+ # missing points, etc., in this document (or any other).
323
+ #
324
+
325
+ module Unit
326
+ # If set to false Test::Unit will not automatically run at exit.
327
+ def self.run=(flag)
328
+ @run = flag
329
+ end
330
+
331
+ # Automatically run tests at exit?
332
+ def self.run?
333
+ @run ||= false
334
+ end
335
+ end
336
+ end
337
+
338
+ at_exit do
339
+ unless $! || Test::Unit.run?
340
+ exit Test::Unit::AutoRunner.run
341
+ end
342
+ end