diff --git a/.gitignore b/.gitignore index 4212579..b8eec6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ doc .garlic +coverage/* diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..5863933 --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source "http://rubygems.org" +gem "nokogiri" +gem "rack", "~>1.1" +gem "rspec", :require => "spec" +gem 'htmlentities' diff --git a/Rakefile b/Rakefile index 769fa1c..08e3ad3 100644 --- a/Rakefile +++ b/Rakefile @@ -2,33 +2,22 @@ rspec_base = File.expand_path(File.dirname(__FILE__) + '/../rspec/lib') $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) and !$LOAD_PATH.include?(rspec_base) -require 'spec/rake/spectask' -require 'spec/rake/verify_rcov' +require 'rcov' +require 'rspec/core/rake_task' PluginName = "truncate_html" task :default => :spec desc "Run the specs for #{PluginName}" -Spec::Rake::SpecTask.new(:spec) do |t| - t.spec_files = FileList['spec/**/*_spec.rb'] - t.spec_opts = ["--colour"] -end +RSpec::Core::RakeTask.new(:spec) desc "Generate RCov report for #{PluginName}" -Spec::Rake::SpecTask.new(:rcov) do |t| - t.spec_files = FileList['spec/**/*_spec.rb'] +RSpec::Core::RakeTask.new(:rcov) do |t| + # t.spec_files = FileList['spec/**/*_spec.rb'] t.rcov = true - t.rcov_dir = 'doc/coverage' - t.rcov_opts = ['--text-report', '--exclude', "/Library/Ruby,spec/,rcov.rb,#{File.expand_path(File.join(File.dirname(__FILE__),'../../..'))}"] -end - -namespace :rcov do - desc "Verify RCov threshold for #{PluginName}" - RCov::VerifyTask.new(:verify => "rcov") do |t| - t.threshold = 100.0 - t.index_html = File.join(File.dirname(__FILE__), 'doc/coverage/index.html') - end + # t.rcov_dir = 'doc/coverage' + t.rcov_opts = ['--text-report', '--exclude', "/Library/Ruby,spec/,rcov.rb,#{File.expand_path(File.join(File.dirname(__FILE__),'../../..'))}"] end # the following tasks are for CI and doc building @@ -36,9 +25,9 @@ begin require 'hanna/rdoctask' require 'garlic/tasks' require 'grancher/task' - + task :cruise => ['garlic:all', 'doc:publish'] - + Rake::RDocTask.new(:doc) do |d| d.options << '--all' d.rdoc_dir = 'doc' @@ -51,7 +40,7 @@ begin task :publish => :doc do Rake::Task['doc:push'].invoke unless uptodate?('.git/refs/heads/gh-pages', 'doc') end - + Grancher::Task.new(:push) do |g| g.keep_all g.directory 'doc', 'doc' diff --git a/autotest/discover.rb b/autotest/discover.rb new file mode 100644 index 0000000..cd6892c --- /dev/null +++ b/autotest/discover.rb @@ -0,0 +1 @@ +Autotest.add_discovery { "rspec2" } diff --git a/lib/truncate_html_helper.rb b/lib/truncate_html_helper.rb index 53ee88b..302132e 100644 --- a/lib/truncate_html_helper.rb +++ b/lib/truncate_html_helper.rb @@ -3,16 +3,16 @@ module TruncateHtmlHelper # raised when tags could not be fixed up by nokogiri class InvalidHtml < RuntimeError; end - + # you may set this to either 'html4', or 'xhtml1' mattr_accessor :flavor class << self alias_method :flavour=, :flavor= alias_method :flavour, :flavor end - + self.flavor = 'html4' - + # Truncates html respecting tags and html entities. # # The API is the same as ActionView::Helpers::TextHelper#truncate. It uses Rexml for the parsing, and HtmlEntities for entity awareness. If Rexml raises a ParseException, then Hpricot is used to fixup the tags, and we try again @@ -25,12 +25,12 @@ def truncate_html(input, *args) options = args.extract_options! length = options[:length] || args[0] || 30 omission = options[:omission] || args[1] || '…' - + begin parser = REXML::Parsers::PullParser.new(input) encoder = HTMLEntities.new(TruncateHtmlHelper.flavor) tags, output, chars_remaining = [], '', length - + while parser.has_next? && chars_remaining > 0 element = parser.pull case element.event_type @@ -41,15 +41,15 @@ def truncate_html(input, *args) output << "" when :text text = encoder.decode(element[0]) - output << encoder.encode(text.first(chars_remaining)) + output << encoder.encode(text[0,chars_remaining]) chars_remaining -= text.length output << omission if chars_remaining < 0 end end - + tags.reverse.each {|tag| output << "" } output - + rescue REXML::ParseException => e fixed_up = Nokogiri::HTML.fragment(input).to_html raise ::TruncateHtmlHelper::InvalidHtml, "Could not fixup invalid html. #{e.message}" if fixed_up == input @@ -57,9 +57,9 @@ def truncate_html(input, *args) retry end end - + private def rexml_element_to_tag(element) "<#{element[0]}#{element[1].inject(""){|m,(k,v)| m << %{ #{k}="#{v}"}} unless element[1].empty?}>" end -end \ No newline at end of file +end diff --git a/spec/helpers/truncate_html_helper_spec.rb b/spec/helpers/truncate_html_helper_spec.rb index a918836..50dd399 100644 --- a/spec/helpers/truncate_html_helper_spec.rb +++ b/spec/helpers/truncate_html_helper_spec.rb @@ -2,7 +2,7 @@ describe TruncateHtmlHelper do include TruncateHtmlHelper - + describe "examples from Rails doc" do it "'Once upon a time in a world far far away'" do truncate_html("Once upon a time in a world far far away").should == "Once upon a time in a world fa…" @@ -16,22 +16,22 @@ truncate_html("And they found that many people were sleeping better.", :length => 25, :omission => "(clipped)").should == "And they found that many (clipped)" end end - + describe "use cases" do def self.with_length_should_equal(n, str) it "#{n}, should equal #{str}" do truncate_html(@html, :length => n).should == str end end - + describe "html:

Hello World

, length: " do before { @html = '

Hello World

' } - + with_length_should_equal 3, '

Hel…

' with_length_should_equal 7, '

Hello W…

' with_length_should_equal 11, '

Hello World

' end - + describe 'html:

Hello & Goodbye
Hi

, length: ' do before { @html = '

Hello & Goodbye
Hi

' } @@ -42,31 +42,35 @@ def self.with_length_should_equal(n, str) describe '(incorrect) html:

Hello World

And Hi, length: ' do before { @html = '

Hello World

And Hi' } - + with_length_should_equal 10, '

Hello Worl…

' with_length_should_equal 30, '

Hello World

And Hi
' end end - + it "should not convert ' to ' (html4 compat)" do truncate_html("30's").should == "30's" end - + + it "should support chinese comma" do + truncate_html("年,,年,,年,,年,,年,,",6).should == "年,…" + end + describe "when TruncateHtmlHelper.flavour = 'xhtml1'" do before do TruncateHtmlHelper.flavour = 'xhtml1' end - + after do TruncateHtmlHelper.flavour = 'html4' end - + it "should convert ' to '" do truncate_html("30's").should == "30's" end - + it "should translate across the atlantic" do TruncateHtmlHelper.flavor.should == 'xhtml1' end end -end \ No newline at end of file +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 55bb762..04e71b1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,18 +3,11 @@ require 'rubygems' -# if we're in a rails env, use that, otherwise use rubygems to create a spec env -begin - require "#{__DIR__}/../../../../config/environment" -rescue LoadError - require 'activesupport' - require 'actionpack' - require 'action_view' - $LOAD_PATH << "#{__DIR__}/../lib" - require "#{__DIR__}/../init" -end +require 'rails/all' +$LOAD_PATH << "#{__DIR__}/../lib" +require "#{__DIR__}/../init" -require 'spec' +require 'rspec' # dependencies of truncate_html require 'htmlentities'