From 1b8baa3d03c1ca13bdefe1f24794998c169704d7 Mon Sep 17 00:00:00 2001 From: Alexey Verkhovsky Date: Tue, 2 Aug 2005 08:56:09 +0000 Subject: [PATCH] Some infrastructure for AR and accompanying unit tests --- app/model/page.rb | 4 ++ app/model/revision.rb | 3 + app/model/web.rb | 3 + config/database.yml | 6 +- config/environment.rb | 115 ++++++++++++++++++++---------------- config/environments/test.rb | 2 - db/webs.erbsql | 2 +- lib/active_record_stub.rb | 31 ---------- lib/db_structure.rb | 2 +- script/create_db | 24 ++++++++ script/debug_storage | 97 ------------------------------ test/fixtures/pages.yml | 2 + test/fixtures/revisions.yml | 2 + test/fixtures/webs.yml | 2 + test/test_helper.rb | 26 ++++++++ test/unit/page_test.rb | 7 +++ test/unit/revision_test.rb | 7 +++ test/unit/web_test.rb | 7 +++ 18 files changed, 155 insertions(+), 187 deletions(-) create mode 100644 app/model/page.rb create mode 100644 app/model/revision.rb create mode 100644 app/model/web.rb delete mode 100644 lib/active_record_stub.rb create mode 100644 script/create_db delete mode 100644 script/debug_storage create mode 100644 test/fixtures/pages.yml create mode 100644 test/fixtures/revisions.yml create mode 100644 test/fixtures/webs.yml create mode 100644 test/test_helper.rb create mode 100644 test/unit/page_test.rb create mode 100644 test/unit/revision_test.rb create mode 100644 test/unit/web_test.rb diff --git a/app/model/page.rb b/app/model/page.rb new file mode 100644 index 00000000..5f85c8ab --- /dev/null +++ b/app/model/page.rb @@ -0,0 +1,4 @@ +class Page < ActiveRecord::Base + belongs_to :web + has_many :pages +end \ No newline at end of file diff --git a/app/model/revision.rb b/app/model/revision.rb new file mode 100644 index 00000000..017b3543 --- /dev/null +++ b/app/model/revision.rb @@ -0,0 +1,3 @@ +class Revision < ActiveRecord::Base + belongs_to :page +end \ No newline at end of file diff --git a/app/model/web.rb b/app/model/web.rb new file mode 100644 index 00000000..2c31bf8f --- /dev/null +++ b/app/model/web.rb @@ -0,0 +1,3 @@ +class Web < ActiveRecord::Base + has_many :pages +end \ No newline at end of file diff --git a/config/database.yml b/config/database.yml index c21e3f65..1233b7e3 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,6 +1,6 @@ # SQLite is enabled by default. Remember to change the dbfile path. production: - adapter: sqlite + adapter: sqlite3 dbfile: /tmp/instiki_prod.db # Uncomment this section for MySQL: @@ -21,10 +21,10 @@ production: # The following settings are only used for testing and development. development: - adapter: sqlite + adapter: sqlite3 dbfile: /tmp/instiki_dev.db test: - adapter: sqlite + adapter: sqlite3 dbfile: /tmp/instiki_test.db diff --git a/config/environment.rb b/config/environment.rb index bc3ac725..589025c8 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,10 @@ -if RUBY_VERSION < '1.8.1' - puts 'Instiki requires Ruby 1.8.1+' +# Load the Rails framework and configure your application. +# You can include your own configuration at the end of this file. +# +# Be sure to restart your webserver when you modify this file. + +if RUBY_VERSION < '1.8.2' + puts 'Instiki requires Ruby 1.8.2+' exit end @@ -7,76 +12,82 @@ end $KCODE = 'u' require 'jcode' -RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') unless defined? RAILS_ROOT -RAILS_ENV = ENV['RAILS_ENV'] || 'production' unless defined? RAILS_ENV +# The path to the root directory of your application. +RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') -unless defined? ADDITIONAL_LOAD_PATHS - # Mocks first. - ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"] +# The environment your application is currently running. Don't set +# this here; put it in your webserver's configuration as the RAILS_ENV +# environment variable instead. +# +# See config/environments/*.rb for environment-specific configuration. +RAILS_ENV = ENV['RAILS_ENV'] || 'development' - # Then model subdirectories. - ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"]) - ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/components/[_a-z]*"]) +# Load the Rails framework. Mock classes for testing come first. +ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"] - # Followed by the standard includes. - ADDITIONAL_LOAD_PATHS.concat %w( - app - app/models - app/controllers - app/helpers - app/apis - components - config - lib - vendor - vendor/rails/railties - vendor/rails/railties/lib - vendor/rails/actionpack/lib - vendor/rails/activesupport/lib - vendor/rails/activerecord/lib - vendor/rails/actionmailer/lib - vendor/rails/actionwebservice/lib - vendor/madeleine-0.7.1/lib - vendor/RedCloth-3.0.3/lib - vendor/rubyzip-0.5.8/lib - ).map { |dir| "#{File.expand_path(File.join(RAILS_ROOT, dir))}" - }.delete_if { |dir| not File.exist?(dir) } +# Then model subdirectories. +ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"]) +ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/components/[_a-z]*"]) - # Prepend to $LOAD_PATH - ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } -end +# Followed by the standard includes. +ADDITIONAL_LOAD_PATHS.concat %w( + app + app/models + app/controllers + app/helpers + app/apis + components + config + lib + vendor + vendor/rails/railties + vendor/rails/railties/lib + vendor/rails/actionpack/lib + vendor/rails/activesupport/lib + vendor/rails/activerecord/lib + vendor/rails/actionmailer/lib + vendor/rails/actionwebservice/lib + vendor/RedCloth-3.0.3/lib + vendor/rubyzip-0.5.8/lib +).map { |dir| "#{RAILS_ROOT}/#{dir}" }.select { |dir| File.directory?(dir) } + +# Prepend to $LOAD_PATH +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } # Require Rails libraries. require 'rubygems' unless File.directory?("#{RAILS_ROOT}/vendor/rails") require 'active_support' +require 'active_record' require 'action_controller' -require_dependency 'instiki_errors' -require_dependency 'active_record_stub' - -# Environment specific configuration +# Environment-specific configuration. require_dependency "environments/#{RAILS_ENV}" +ActiveRecord::Base.configurations = File.open("#{RAILS_ROOT}/config/database.yml") { |f| YAML::load(f) } +ActiveRecord::Base.establish_connection # Configure defaults if the included environment did not. -unless defined? RAILS_DEFAULT_LOGGER +begin + RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log") + RAILS_DEFAULT_LOGGER.level = (RAILS_ENV == 'production' ? Logger::INFO : Logger::DEBUG) +rescue StandardError RAILS_DEFAULT_LOGGER = Logger.new(STDERR) - ActionController::Base.logger ||= RAILS_DEFAULT_LOGGER - if $instiki_debug_logging - RAILS_DEFAULT_LOGGER.level = Logger::DEBUG - ActionController::Base.logger.level = Logger::DEBUG - else - RAILS_DEFAULT_LOGGER.level = Logger::INFO - ActionController::Base.logger.level = Logger::INFO - end + RAILS_DEFAULT_LOGGER.level = Logger::WARN + RAILS_DEFAULT_LOGGER.warn( + "Rails Error: Unable to access log file. Please ensure that log/#{RAILS_ENV}.log exists and is chmod 0666. " + + "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." + ) end -ActionController::Base.template_root ||= "#{RAILS_ROOT}/app/views/" +[ActiveRecord, ActionController, ActionMailer].each { |mod| mod::Base.logger ||= RAILS_DEFAULT_LOGGER } +[ActionController, ActionMailer].each { |mod| mod::Base.template_root ||= "#{RAILS_ROOT}/app/views/" } + +# Set up routes. ActionController::Routing::Routes.reload + Controllers = Dependencies::LoadingModule.root( File.join(RAILS_ROOT, 'app', 'controllers'), File.join(RAILS_ROOT, 'components') ) -require 'wiki_service' -Socket.do_not_reverse_lookup = true +require_dependency 'instiki_errors' diff --git a/config/environments/test.rb b/config/environments/test.rb index ece6e9cf..fac509a1 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -12,6 +12,4 @@ unless defined? TEST_LOGGER TEST_LOGGER = ActionController::Base.logger = Logger.new(log_name) $instiki_debug_logging = true - - WikiService.storage_path = RAILS_ROOT + '/storage/test/' end diff --git a/db/webs.erbsql b/db/webs.erbsql index 24ebc04a..bbb9758c 100644 --- a/db/webs.erbsql +++ b/db/webs.erbsql @@ -1,4 +1,4 @@ -CREATE TABLE pages ( +CREATE TABLE webs ( id <%= @pk %>, created_at <%= @datetime %> NOT NULL, updated_at <%= @datetime %> NOT NULL, diff --git a/lib/active_record_stub.rb b/lib/active_record_stub.rb deleted file mode 100644 index 126beb0b..00000000 --- a/lib/active_record_stub.rb +++ /dev/null @@ -1,31 +0,0 @@ -# This project uses Railties, which has an external dependency on ActiveRecord -# Since ActiveRecord may not be present in Instiki runtime environment, this -# file provides a stub replacement for it - -module ActiveRecord - class Base - - # dependency in railties/lib/dispatcher.rb - def self.reset_column_information_and_inheritable_attributes_for_all_subclasses - # noop - end - - # dependency in actionpack/lib/action_controller/benchmarking.rb - def self.connected? - false - end - - # dependency in actionpack/lib/action_controller/benchmarking.rb - def self.connection - return ConnectionStub - end - - end - - module ConnectionStub - def self.reset_runtime - 0 - end - end - -end diff --git a/lib/db_structure.rb b/lib/db_structure.rb index 0a2c4beb..c7b58c33 100644 --- a/lib/db_structure.rb +++ b/lib/db_structure.rb @@ -25,7 +25,7 @@ def db_structure(db) end s = '' - Dir['db/*.erbsql'].each do |filename| + Dir[RAILS_ROOT + '/db/*.erbsql'].each do |filename| s += ERB.new(File.read(filename)).result end s diff --git a/script/create_db b/script/create_db new file mode 100644 index 00000000..b421fb8c --- /dev/null +++ b/script/create_db @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby + +APP_ROOT = File.expand_path(File.dirname(__FILE__)) + '/../' + +require APP_ROOT + 'config/environment' +require 'db_structure' + +config = ActiveRecord::Base.configurations + +['production', 'test', 'development'].each do |target| + begin + ENV['RAILS_ENV'] = target + load APP_ROOT + 'config/environment.rb' + puts "Creating tables for #{target}..." + + db_structure(config[target]['adapter']).split(/\s*;\s*/).each do |sql| + ActiveRecord::Base.connection.execute(sql) + end + + puts "done." + rescue => e + puts "failed: " + e.inspect + end +end diff --git a/script/debug_storage b/script/debug_storage deleted file mode 100644 index 8b0060f0..00000000 --- a/script/debug_storage +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/ruby - -=begin -The purpose of this script is to help people poke around in the Madeleine storage. - -Two caveats: -1. You MUST be a reasonably good Ruby programmer to use it successfully for anything non-trivial. -2. It's very easy to screw up something by poking in the storage internals. If you do, please - undo your changes by deleting the most recent snapshot(s) and don't ask for help. - -Usage example: - -E:\eclipse\workspace\instiki\script>irb -irb(main):001:0> load 'debug_storage' -Enter path to storage [E:/eclipse/workspace/instiki/storage/2500]: -Loading storage from the default storage path (E:/eclipse/workspace/instiki/storage/2500) -Instiki storage from E:/eclipse/workspace/instiki/storage/2500 is loaded. -Access it via global variable $wiki. -Happy poking! -=> true -irb(main):003:0> $wiki.system -=> {"password"=>"foo"} -irb(main):005:0> $wiki.system['password'] = 'bar' -=> "bar" -irb(main):006:0> $wiki.webs.keys -=> ["wiki1", "wiki2"] -irb(main):007:0> $wiki.webs['wiki1'].password = 'the_password' -=> "the_password" -irb(main):008:0> WikiService::snapshot -=> [] - - -Things that are possible: - -# cleaning old revisions -$wiki.webs['wiki'].pages['HomePage'].revisions = $wiki.webs['wiki'].pages['HomePage'].revisions[-1..-1] - -# Changing contents of a revision -$wiki.webs['wiki'].pages['HomePage'].revisions[-1] = 'new content' - -# Checking that all pages can be rendered by the markup engine -$wiki.webs['wiki'].pages.each_pair do |name, page| - page.revisions.each_with_index do |revision, i| - begin - revision.display_content - rescue => - puts "Error when rendering revision ##{i} of page #{name.inspect}:" - puts e.message - puts e.backtrace.join("\n") - end -end -=end - -require 'fileutils' -require 'optparse' -require 'webrick' - -default_storage_path = File.expand_path(File.dirname(__FILE__) + "/../storage/2500") - -print "Enter path to storage [#{default_storage_path}]: " -storage_path = gets.chomp -if storage_path.empty? - storage_path = default_storage_path - puts "Loading storage from the default storage path (#{storage_path})" -else - puts "Loading storage from the path you entered (#{storage_path})" -end - -unless File.directory?(storage_path) and not - (Dir["#{storage_path}/*.snapshot"] + Dir["#{storage_path}/*.command_log"]).empty? - raise "Found no storage at #{storage_path}" -end - -RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') unless defined? RAILS_ROOT - -unless defined? ADDITIONAL_LOAD_PATHS - ADDITIONAL_LOAD_PATHS = %w( - app/models - lib - vendor/madeleine-0.7.1/lib - vendor/RedCloth-3.0.3/lib - vendor/rubyzip-0.5.8/lib - ).map { |dir| "#{File.expand_path(File.join(RAILS_ROOT, dir))}" - }.delete_if { |dir| not File.exist?(dir) } - - # Prepend to $LOAD_PATH - ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } -end - -require 'wiki_service' - -WikiService.storage_path = storage_path -$wiki = WikiService.instance -puts "Instiki storage from #{storage_path} is loaded." -puts 'Access it via global variable $wiki.' -puts 'Happy poking!' -nil diff --git a/test/fixtures/pages.yml b/test/fixtures/pages.yml new file mode 100644 index 00000000..9f856f2a --- /dev/null +++ b/test/fixtures/pages.yml @@ -0,0 +1,2 @@ +home_page: + id: 1 diff --git a/test/fixtures/revisions.yml b/test/fixtures/revisions.yml new file mode 100644 index 00000000..6538429d --- /dev/null +++ b/test/fixtures/revisions.yml @@ -0,0 +1,2 @@ +home_page_first_revision: + id: 1 diff --git a/test/fixtures/webs.yml b/test/fixtures/webs.yml new file mode 100644 index 00000000..8c4a2778 --- /dev/null +++ b/test/fixtures/webs.yml @@ -0,0 +1,2 @@ +test_wiki: + id: 1 diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 00000000..19219ce7 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,26 @@ +ENV["RAILS_ENV"] = "test" + +# Expand the path to environment so that Ruby does not load it multiple times +# File.expand_path can be removed if Ruby 1.9 is in use. +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'application' + +require 'test/unit' +require 'active_record/fixtures' +require 'action_controller/test_process' +require 'action_web_service/test_invoke' +require 'breakpoint' + +Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/" + +class Test::Unit::TestCase + # Turn these on to use transactional fixtures with table_name(:fixture_name) instantiation of fixtures + # self.use_transactional_fixtures = true + # self.use_instantiated_fixtures = false + + def create_fixtures(*table_names) + Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_names) + end + + # Add more helper methods to be used by all tests here... +end \ No newline at end of file diff --git a/test/unit/page_test.rb b/test/unit/page_test.rb new file mode 100644 index 00000000..8af94246 --- /dev/null +++ b/test/unit/page_test.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class PageTest < Test::Unit::TestCase + + fixtures 'webs', 'pages', 'revisions' + +end diff --git a/test/unit/revision_test.rb b/test/unit/revision_test.rb new file mode 100644 index 00000000..0024c6b3 --- /dev/null +++ b/test/unit/revision_test.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class RevisionTest < Test::Unit::TestCase + + fixtures 'webs', 'pages', 'revisions' + +end diff --git a/test/unit/web_test.rb b/test/unit/web_test.rb new file mode 100644 index 00000000..2e504e0c --- /dev/null +++ b/test/unit/web_test.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class WebTest < Test::Unit::TestCase + + fixtures 'webs', 'pages', 'revisions' + +end