# This file is copied to ~/spec when you run 'ruby script/generate rspec' # from the project root directory. ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'spec' require 'spec/rails' SAMPLES_PATH = File.expand_path(File.dirname(__FILE__) + "/samples") unless defined?(SAMPLES_PATH) def read_sample(path_fragment) File.read(File.join(SAMPLES_PATH, path_fragment)) end Spec::Runner.configure do |config| # If you're not using ActiveRecord you should remove these # lines, delete config/database.yml and disable :active_record # in your config/boot.rb config.use_transactional_fixtures = true config.use_instantiated_fixtures = false config.fixture_path = RAILS_ROOT + '/spec/fixtures/' # == Fixtures # # You can declare fixtures for each example_group like this: # describe "...." do # fixtures :table_a, :table_b # # Alternatively, if you prefer to declare them only once, you can # do so right here. Just uncomment the next line and replace the fixture # names with your fixtures. # # config.global_fixtures = :table_a, :table_b # # If you declare global fixtures, be aware that they will be declared # for all of your examples, even those that don't use them. # # == Mock Framework # # RSpec uses it's own mocking framework by default. If you prefer to # use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr end class BeValidXhtml # require 'action_controller/test_process' # require 'test/unit' require 'net/http' require 'md5' require 'ftools' def initialize(options) @fragment = options[:fragment] end # Assert that markup (html/xhtml) is valid according the W3C validator web service. # By default, it validates the contents of @response.body, which is set after calling # one of the get/post/etc helper methods. You can also pass it a string to be validated. # Validation errors, if any, will be included in the output. The input fragment and # response from the validator service will be cached in the $RAILS_ROOT/tmp directory to # minimize network calls. # # For example, if you have a FooController with an action Bar, put this in foo_controller_test.rb: # # def test_bar_valid_markup # get :bar # assert_valid_markup # end # @@markup_validator_host = ENV['MARKUP_VALIDATOR_HOST'] || 'validator.w3.org' @@markup_validator_path = ENV['MARKUP_VALIDATOR_PATH'] || '/check' @@css_validator_host = ENV['CSS_VALIDATOR_HOST'] || 'jigsaw.w3.org' @@css_validator_path = ENV['CSS_VALIDATOR_PATH'] || '/css-validator/validator' @@display_invalid_content = true cattr_accessor :display_invalid_content @@auto_validate = false cattr_accessor :auto_validate class_inheritable_accessor :auto_validate_excludes class_inheritable_accessor :auto_validate_includes def matches?(response) fn = response.rendered_file fragment = response.body fragment = wrap_with_xhtml_header(fragment) if @fragment return true if validity_checks_disabled? base_filename = cache_resource('markup',fragment,'html',fn) return false unless base_filename results_filename = base_filename + '-results.yml' begin response = File.open(results_filename) do |f| Marshal.load(f) end rescue response = http.start(@@markup_validator_host).post2(@@markup_validator_path, "fragment=#{CGI.escape(fragment)}&output=xml") File.open(results_filename, 'w+') do |f| Marshal.dump(response, f) end end markup_is_valid = response['x-w3c-validator-status'] == 'Valid' @message = '' unless markup_is_valid fragment.split($/).each_with_index{|line, index| @message << "#{'%04i' % (index+1)} : #{line}#{$/}"} if @@display_invalid_content @message << XmlSimple.xml_in(response.body)['messages'][0]['msg'].collect{ |m| "Invalid markup: line #{m['line']}: #{CGI.unescapeHTML(m['content'])}" }.join("\n") end if markup_is_valid return true else return false end end def wrap_with_xhtml_header(fragment) ret = <<-EOS