archive_tree 1.0.0.rc3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 3.0.1'
4
+ gem 'actionpack', '~> 3.0.1'
5
+
6
+ group :development, :test do
7
+ gem 'mysql', '~> 2.8.0'
8
+
9
+ if RUBY_VERSION =~ /1\.9\.\d/
10
+ gem('ruby-debug-base19', '=0.11.23') if RUBY_VERSION == '1.9.1'
11
+ gem 'ruby-debug19', '~> 0.11.0'
12
+ else
13
+ gem 'ruby-debug'
14
+ end
15
+
16
+ gem 'rspec', '~> 2.0.0'
17
+ gem 'factory_girl_rails', '~> 1.0.0'
18
+ gem 'database_cleaner', '~> 0.6.0'
19
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,109 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionmailer (3.0.1)
6
+ actionpack (= 3.0.1)
7
+ mail (~> 2.2.5)
8
+ actionpack (3.0.1)
9
+ activemodel (= 3.0.1)
10
+ activesupport (= 3.0.1)
11
+ builder (~> 2.1.2)
12
+ erubis (~> 2.6.6)
13
+ i18n (~> 0.4.1)
14
+ rack (~> 1.2.1)
15
+ rack-mount (~> 0.6.12)
16
+ rack-test (~> 0.5.4)
17
+ tzinfo (~> 0.3.23)
18
+ activemodel (3.0.1)
19
+ activesupport (= 3.0.1)
20
+ builder (~> 2.1.2)
21
+ i18n (~> 0.4.1)
22
+ activerecord (3.0.1)
23
+ activemodel (= 3.0.1)
24
+ activesupport (= 3.0.1)
25
+ arel (~> 1.0.0)
26
+ tzinfo (~> 0.3.23)
27
+ activeresource (3.0.1)
28
+ activemodel (= 3.0.1)
29
+ activesupport (= 3.0.1)
30
+ activesupport (3.0.1)
31
+ archive-tar-minitar (0.5.2)
32
+ arel (1.0.1)
33
+ activesupport (~> 3.0.0)
34
+ builder (2.1.2)
35
+ columnize (0.3.2)
36
+ database_cleaner (0.6.0)
37
+ diff-lcs (1.1.2)
38
+ erubis (2.6.6)
39
+ abstract (>= 1.0.0)
40
+ factory_girl (1.3.2)
41
+ factory_girl_rails (1.0)
42
+ factory_girl (~> 1.3)
43
+ rails (>= 3.0.0.beta4)
44
+ i18n (0.4.2)
45
+ linecache19 (0.5.11)
46
+ ruby_core_source (>= 0.1.4)
47
+ mail (2.2.9)
48
+ activesupport (>= 2.3.6)
49
+ i18n (~> 0.4.1)
50
+ mime-types (~> 1.16)
51
+ treetop (~> 1.4.8)
52
+ mime-types (1.16)
53
+ mysql (2.8.1)
54
+ polyglot (0.3.1)
55
+ rack (1.2.1)
56
+ rack-mount (0.6.13)
57
+ rack (>= 1.0.0)
58
+ rack-test (0.5.6)
59
+ rack (>= 1.0)
60
+ rails (3.0.1)
61
+ actionmailer (= 3.0.1)
62
+ actionpack (= 3.0.1)
63
+ activerecord (= 3.0.1)
64
+ activeresource (= 3.0.1)
65
+ activesupport (= 3.0.1)
66
+ bundler (~> 1.0.0)
67
+ railties (= 3.0.1)
68
+ railties (3.0.1)
69
+ actionpack (= 3.0.1)
70
+ activesupport (= 3.0.1)
71
+ rake (>= 0.8.4)
72
+ thor (~> 0.14.0)
73
+ rake (0.8.7)
74
+ rspec (2.0.1)
75
+ rspec-core (~> 2.0.1)
76
+ rspec-expectations (~> 2.0.1)
77
+ rspec-mocks (~> 2.0.1)
78
+ rspec-core (2.0.1)
79
+ rspec-expectations (2.0.1)
80
+ diff-lcs (>= 1.1.2)
81
+ rspec-mocks (2.0.1)
82
+ rspec-core (~> 2.0.1)
83
+ rspec-expectations (~> 2.0.1)
84
+ ruby-debug-base19 (0.11.24)
85
+ columnize (>= 0.3.1)
86
+ linecache19 (>= 0.5.11)
87
+ ruby_core_source (>= 0.1.4)
88
+ ruby-debug19 (0.11.6)
89
+ columnize (>= 0.3.1)
90
+ linecache19 (>= 0.5.11)
91
+ ruby-debug-base19 (>= 0.11.19)
92
+ ruby_core_source (0.1.4)
93
+ archive-tar-minitar (>= 0.5.2)
94
+ thor (0.14.4)
95
+ treetop (1.4.8)
96
+ polyglot (>= 0.3.1)
97
+ tzinfo (0.3.23)
98
+
99
+ PLATFORMS
100
+ ruby
101
+
102
+ DEPENDENCIES
103
+ actionpack (~> 3.0.1)
104
+ activerecord (~> 3.0.1)
105
+ database_cleaner (~> 0.6.0)
106
+ factory_girl_rails (~> 1.0.0)
107
+ mysql (~> 2.8.0)
108
+ rspec (~> 2.0.0)
109
+ ruby-debug19 (~> 0.11.0)
data/README.md CHANGED
@@ -1,9 +1,15 @@
1
1
  ## Introduction
2
2
 
3
- ArchiveTree is a plugin for your Ruby on Rails application that makes it easy for you to generate structured trees of your records.
3
+ ArchiveTree is a Ruby Gem for your Ruby on Rails application that makes it easy for you to generate structured trees of your records.
4
4
 
5
- Since it makes use of your model's _created_at_ column, ArchiveTree is ultimately compatible with most ActiveRecord Models out there.
5
+ Since it uses a column of your choice, from any ActiveRecord Model, you will have flexibility to use in most of the Ruby on Rails applications
6
6
 
7
+ ## Compatibility
8
+
9
+ The Gem was developed to work with Rails 3.0.x, running on Ruby 1.8.7 or 1.9.2.
10
+ Since it uses SQL specific queries, it works on MySQL and PostgreSQL databases.
11
+
12
+ **Note:** This gem does not work with Ruby v1.9.1.
7
13
 
8
14
  ## Installation
9
15
 
@@ -28,6 +34,14 @@ Now let's say that you wish to allow your users to sweep through your posts in a
28
34
 
29
35
  ### API
30
36
 
37
+ #### Inclusion:
38
+
39
+ In your ActiveRecord Model:
40
+
41
+ <pre>
42
+ acts_as_archive #=> defaults to :created_at
43
+ </pre>
44
+
31
45
  #### Default usage:
32
46
 
33
47
  <pre>
@@ -54,15 +68,15 @@ Post.archive_tree(:months => [1]) #=> { 2010 => { 1 => [Post] },
54
68
  Post.archive_tree(:years_and_months => { 2010 => [1] }) #=> { 2010 => { 1 => [Post] } }
55
69
  </pre>
56
70
 
57
- ### Views
71
+ ### View
58
72
 
59
73
  <pre>
60
- draw_archive_tree(:model_sym => :post, :route => :archive_published_at_path, :toggle => false)
74
+ draw_archive_tree #=> defaults to: :model_sym => :post, :route => :posts_path, :toggle => true, :toggle_text => '[ + ]'
61
75
  </pre>
62
76
 
63
77
  ## Documentation
64
78
 
65
- This gem's documentation documentation is available at http://yardoc.org/docs/GnomesLab-archive_tree
79
+ This gem's documentation documentation is available at http://rubydoc.info/github/GnomesLab/archive_tree/
66
80
 
67
81
 
68
82
  ## License
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+
5
+ desc 'Generate documentation for the archive_tree plugin.'
6
+ Rake::RDocTask.new(:rdoc) do |rdoc|
7
+ rdoc.rdoc_dir = 'rdoc'
8
+ rdoc.title = 'ArchiveTree'
9
+ rdoc.options << '--line-numbers' << '--inline-source'
10
+ rdoc.rdoc_files.include('README.md')
11
+ rdoc.rdoc_files.include('lib/**/*.rb')
12
+ end
13
+
14
+ begin
15
+ require 'rspec/core/rake_task'
16
+
17
+ RSpec::Core::RakeTask.new(:spec) do |t|
18
+ t.ruby_opts = '-w'
19
+ end
20
+
21
+ task :default => :spec
22
+ rescue LoadError
23
+ raise 'RSpec could not be loaded. Run `bundle install` to get all development dependencies.'
24
+ end
25
+
26
+ # Rubygems
27
+ namespace :rubygems do
28
+ gemspec = eval(File.read('archive_tree.gemspec'))
29
+ Rake::GemPackageTask.new(gemspec) do |pkg|
30
+ pkg.gem_spec = gemspec
31
+ end
32
+
33
+ desc "build the gem and release it to rubygems.org"
34
+ task :release => :gem do
35
+ sh "rake spec"
36
+ sh "gem push pkg/archive_tree-#{gemspec.version}.gem"
37
+ end
38
+ end
data/lib/archive_tree.rb CHANGED
@@ -17,8 +17,8 @@
17
17
  # TODO: This module should undergo a query optimization. Furthermore, an ORM abstraction.
18
18
  module ArchiveTree
19
19
 
20
- require 'archive_tree/action_view_extensions'
21
20
  autoload :Core, 'archive_tree/core'
21
+ autoload :ActionViewExtensions, 'archive_tree/action_view_extensions'
22
22
 
23
23
  def acts_as_archive(date_field = :created_at)
24
24
  raise ::ArgumentError, "undefined parameter #{date_field.to_s}" unless column = columns_hash[date_field.to_s]
@@ -33,5 +33,3 @@ module ArchiveTree
33
33
  attr_accessor :date_field
34
34
 
35
35
  end # ArchiveTree
36
-
37
- ActiveRecord::Base.send :extend, ArchiveTree if defined?(ActiveRecord::Base)
@@ -1,8 +1,73 @@
1
1
  module ArchiveTree
2
2
 
3
3
  module ActionViewExtensions
4
- require 'archive_tree/action_view_extensions/draw_archive_tree'
5
- ::ActionView::Base.send :include, DrawArchiveTree
4
+
5
+ # In the presence of records for a given model it draws the archive tree. Otherwise, returns an empty string
6
+ #
7
+ # This method relies on the following private methods:
8
+ # * +draw_years+
9
+ # * +draw_months+
10
+ #
11
+ # Default behavior
12
+ # * It will attempt to create a tree of your Post model
13
+ # * Will use the posts_path route
14
+ # * Will display a toggle link
15
+ # * Will use "[ + ]" as the text for the toggle link
16
+ #
17
+ # Options
18
+ # * model_sym #=> the symbol of the model to request the archive_nodes
19
+ # * route #=> the route that handles the archived posts requests
20
+ # * toggle #=> when true, includes a toggle link before the years
21
+ # * toggle_text #=> the text used in the toggle link
22
+ #
23
+ # Example using the default settings:
24
+ # <%= draw_archive_tree %>
25
+ #
26
+ # Overriding the defaults example:
27
+ # <%= draw_archive_tree :model_sym => :post, :route => :archive_published_at_path, :toggle => false %>
28
+
29
+ def draw_archive_tree(options = {})
30
+ options.reverse_merge!({ :model_sym => :post, :route => :posts_path, :toggle => true, :toggle_text => '[ + ]' })
31
+ model = options[:model_sym].to_s.capitalize.constantize
32
+
33
+ raw model.count > 0 ? draw_years(model, options[:route], options[:toggle], options[:toggle_text]) : ''
34
+ end # draw_archive_tree
35
+
36
+ private
37
+ def draw_years(model_sym, route, toggle, toggle_text) # :nodoc:
38
+ model = model_sym.to_s.capitalize.constantize
39
+ route = :posts_path unless self.respond_to? route
40
+
41
+ content_tag :ul do
42
+ ul_body = ""
43
+
44
+ model.archived_years.each_key do |year, count|
45
+ ul_body << content_tag(:li, :class => year == Time.now.year ? 'active' : 'inactive') do
46
+ (toggle ? link_to(toggle_text, "#", :class => "toggle") : '') + " " +
47
+ link_to(year, self.send(route, year)) +
48
+ draw_months(model_sym, route, year)
49
+ end
50
+ end
51
+
52
+ ul_body
53
+ end
54
+ end # draw_years
55
+
56
+ def draw_months(model_sym, route, year) # :nodoc:
57
+ model = model_sym.to_s.capitalize.constantize
58
+
59
+ content_tag :ul do
60
+ ul_body = ""
61
+
62
+ model.archived_months(:year => year).each_pair do |month, count|
63
+ ul_body << content_tag(:li, link_to("#{Date::MONTHNAMES[month]} (#{count})",
64
+ self.send(route, year, month < 10 ? "0#{month}" : month)))
65
+ end
66
+
67
+ ul_body
68
+ end
69
+ end # draw_months
70
+
6
71
  end # ActionViewExtensions
7
72
 
8
73
  end # ArchiveTree
data/spec/db/models.rb ADDED
@@ -0,0 +1,3 @@
1
+ class Post < ActiveRecord::Base
2
+ acts_as_archive
3
+ end
data/spec/db/schema.rb ADDED
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define(:version => 20100803160738) do
2
+
3
+ create_table "posts", :force => true do |t|
4
+ t.string "title", :null => false
5
+ t.text "body", :null => false
6
+ t.datetime "published_at", :null => true
7
+ t.datetime "created_at"
8
+ t.datetime "updated_at"
9
+ end
10
+
11
+ add_index "posts", ["created_at"], :name => "index_posts_on_created_at"
12
+ add_index "posts", ["published_at"], :name => "index_posts_on_published_at"
13
+
14
+ end
@@ -0,0 +1,6 @@
1
+ Factory.define(:post) do |p|
2
+ p.sequence(:title) { |n| "Post Title #{n}" }
3
+ p.sequence(:body) { |n| "This is the #{n}th post. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer dictum, neque ut imperdiet pellentesque, nulla tellus tempus magna, sed consectetur orci metus a justo. Aliquam ac congue nunc. Mauris a tortor ut massa egestas tempus. Pellentesque tincidunt fermentum diam sagittis ullamcorper. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer dictum." }
4
+ p.sequence(:published_at) { |n| Time.now - n.month }
5
+ p.created_at Time.now
6
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree::ActionViewExtensions do
4
+
5
+ before :each do
6
+ @helper = ActionView::Base.new
7
+
8
+ # Inject routes into ActionView::Base
9
+ @helper.instance_eval do
10
+ def posts_path(*)
11
+ '/blog/2010'
12
+ end
13
+
14
+ def dummy_path(*)
15
+ '/dummy/2010'
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "draw_achive_tree" do
21
+
22
+ it "should be included in ActionView::Base" do
23
+ @helper.should respond_to :draw_archive_tree
24
+ end # included
25
+
26
+ describe "without posts" do
27
+ it "returns an empty string when the archive tree is empty" do
28
+ @helper.draw_archive_tree.should be_empty
29
+ end
30
+ end # without posts
31
+
32
+ describe "with posts" do
33
+ before :each do
34
+ Factory.create :post, :created_at => Date.new(Time.now.year, 1, 1)
35
+ Factory.create :post, :created_at => Date.new(Time.now.year, 2, 1)
36
+ end
37
+
38
+ it "should return the archive tree for all records" do
39
+ @helper.draw_archive_tree.should == %Q{<ul><li class=\"active\"><a href=\"#\" class=\"toggle\">[ + ]</a> <a href=\"/blog/2010\">2010</a><ul><li><a href=\"/blog/2010\">January (1)</a></li><li><a href=\"/blog/2010\">February (1)</a></li></ul></li></ul>}
40
+ end
41
+ end # with posts
42
+
43
+ describe "overridable" do
44
+ before :each do
45
+ Factory.create :post, :created_at => Date.new(Time.now.year, 1, 1)
46
+ Factory.create :post, :created_at => Date.new(Time.now.year, 2, 1)
47
+ end
48
+
49
+ it "allows the model name to be overriden" do
50
+ lambda { @helper.draw_archive_tree(:model_sym => :hello) }.should raise_error NameError
51
+ end
52
+
53
+ it "allows the route to be overriden" do
54
+ @helper.draw_archive_tree(:route => :dummy_path).should == %Q{<ul><li class=\"active\"><a href=\"#\" class=\"toggle\">[ + ]</a> <a href=\"/dummy/2010\">2010</a><ul><li><a href=\"/dummy/2010\">January (1)</a></li><li><a href=\"/dummy/2010\">February (1)</a></li></ul></li></ul>}
55
+ end
56
+
57
+ it "defaults to the hardcoded route whenever the provided route is unknown" do
58
+ 1.upto(10) { |i| Factory.create :post }
59
+ @helper.draw_archive_tree(:route => :xpto_path).should match(/ul/)
60
+ end
61
+
62
+ it "allows the toggle to be overriden" do
63
+ html = @helper.draw_archive_tree(:toggle => false)
64
+ html.should_not include '<a href="#" class="toggle">[ + ]</a>'
65
+ end
66
+
67
+ it "allows the toggle text to be overriden" do
68
+ html = @helper.draw_archive_tree(:toggle_text => '+toggle+')
69
+ html.should include '<a href="#" class="toggle">+toggle+</a>'
70
+ end
71
+
72
+ end # overridable
73
+
74
+ end # draw_achive_tree
75
+
76
+ end # ArchiveTree::ActionViewExtensions
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree do
4
+ describe "archive_node" do
5
+
6
+ before :each do
7
+ 1.upto(2) { |i| Factory.create(:post, :created_at => "#{Time.now.year}-0#{i}-01 00:00:00") }
8
+ 1.upto(2) { |i| Factory.create(:post, :created_at => "#{Time.now.year + 1}-0#{i}-01 00:00:00") }
9
+ end
10
+
11
+ describe "defaults" do
12
+ it "uses the current year" do
13
+ Post.archive_node.each { |p| p.created_at.year.should == Time.now.year }
14
+ end
15
+
16
+ it "ignores the month" do
17
+ Post.archive_node.should have(2).record
18
+ end
19
+
20
+ end # defaults
21
+
22
+ describe "overridable" do
23
+ it "allows to override the year" do
24
+ year = Time.now.year + 1
25
+ Post.archive_node(:year => year).each { |p| p.created_at.year.should == year }
26
+ end
27
+
28
+ it "allows to select a month" do
29
+ Post.archive_node(:year => Time.now.year, :month => 1).each { |p| p.created_at.month.should == 1 }
30
+ end
31
+
32
+ it "allows to override the year and select a month" do
33
+ Post.archive_node(:year => Time.now.year, :month => 1).should have(1).record
34
+ end
35
+ end # overridables
36
+
37
+ end # archive_node
38
+ end # ArchiveTree
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree do
4
+
5
+ describe "self included" do
6
+
7
+ it "should extend klass with its ArchiveTree::Core" do
8
+ [:archived_years, :archived_months, :archive_tree, :archive_node].each do |method|
9
+ Post.should respond_to method
10
+ end
11
+ end
12
+ end # self.included
13
+
14
+ end # ArchiveTree
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree do
4
+
5
+ describe "acts_as_archive" do
6
+
7
+ it "should be a class method of ActiveRecord::Base" do
8
+ ActiveRecord::Base.should respond_to :acts_as_archive
9
+ end
10
+
11
+ it "should raise exception for undefined fields" do
12
+ lambda do
13
+ class Post < ActiveRecord::Base
14
+ acts_as_archive :dummy
15
+ end
16
+ end.should raise_error(ArgumentError)
17
+ end
18
+
19
+ it "should raise exception for invalid fields" do
20
+ lambda do
21
+ class Post < ActiveRecord::Base
22
+ acts_as_archive :body
23
+ end
24
+ end.should raise_error(ArgumentError)
25
+ end
26
+
27
+ end # acts_as_archive
28
+
29
+ describe "archive tree" do
30
+
31
+ before :each do
32
+ [2007, 2008, 2009, 2010].each do |year|
33
+ 5.times { |i| Factory.create(:post, :created_at => "#{year}-#{01 + i}-01 00:00:00") }
34
+ end
35
+ end
36
+
37
+ describe "default behavior" do
38
+
39
+ it "should return an empty hash when there are no records" do
40
+ Post.destroy_all
41
+
42
+ Post.archive_tree.should == {}
43
+ end
44
+
45
+ it "should return the archive tree for all posts" do
46
+ tree = {}
47
+ [2007, 2008, 2009, 2010].each_with_index do |year, year_index|
48
+ tree[year] = {}
49
+ 0.upto(4).each { |i| tree[year][i+1] = [Post.find(Post.first.id + year_index*5 + i)] }
50
+ end
51
+
52
+ Post.archive_tree.should == tree
53
+ end
54
+
55
+ end # default behavior
56
+
57
+ describe "years to sweep" do
58
+
59
+ it "accepts a years key in the options hash and complies to it" do
60
+ tree = {}
61
+ [2009, 2010].each_with_index do |year, year_index|
62
+ tree[year] = {}
63
+ 0.upto(4).each { |i| tree[year][i+1] = [Post.find(10 + Post.first.id + year_index*5 + i)] }
64
+ end
65
+
66
+ Post.archive_tree(:years => [2009, 2010]).should == tree
67
+ end
68
+
69
+ end # years to sweep
70
+
71
+ describe "months to sweep" do
72
+
73
+ it "should only sweep January" do
74
+ tree = {}
75
+ [2007, 2008, 2009, 2010].each_with_index do |year, year_index|
76
+ tree[year] = {}
77
+ tree[year][1] = [Post.find(Post.first.id + year_index*5)]
78
+ end
79
+
80
+ Post.archive_tree(:months => [1]).should == tree
81
+ end
82
+
83
+ end # months to sweep
84
+
85
+ describe "years and months" do
86
+
87
+ it "should comply with the requested years and months filter" do
88
+ tree = { 2007 => { 1 => [Post.find(Post.first.id)] },
89
+ 2008 => { 2 => [Post.find(Post.first.id + 6)], 3 => [Post.find(Post.first.id + 7)] } }
90
+
91
+ Post.archive_tree(:years_and_months => { 2007 => [1], 2008 => [2, 3] }).should == tree
92
+ end
93
+
94
+ end # years and months
95
+
96
+ end # archive_tree
97
+
98
+ end # ArchiveTree
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree do
4
+
5
+ describe "archived months" do
6
+
7
+ before :each do
8
+ 2.times do |i|
9
+ Factory.create(:post, :created_at => "#{Time.now.year + i}-01-01 00:00:00")
10
+ Factory.create(:post, :created_at => "#{Time.now.year + i}-02-01 00:00:00")
11
+ end
12
+ end
13
+
14
+ it "returns an empty hash if no records exist for a given year" do
15
+ Post.archived_months(:year => 3000).should == {}
16
+ end
17
+
18
+ it "returns an integer months counter hash" do
19
+ Post.archived_months.should == { 1 => 1, 2 => 1 }
20
+ end
21
+
22
+ it "defaults it's sweep year to the current year" do
23
+ Factory.create :post, :created_at => "#{Time.now.year}-#{12}-01 00:00:00"
24
+ Post.archived_months == { 1 => 1, 2 => 1, 12 => 1 }
25
+ end
26
+
27
+ it "allows the invoker to specify the year being sweeped" do
28
+ Post.archived_months(:year => (Time.now.year + 1)).should == { 1 => 1, 2 => 1 }
29
+ end
30
+
31
+ it "allows the type of month name to be specified as short" do
32
+ Post.archived_months(:month_names => :short).should == { "Jan" => 1, "Feb" => 1 }
33
+ end
34
+
35
+ it "allows the type of month name to be specified as long" do
36
+ Post.archived_months(:month_names => :long).should == { "January" => 1, "February" => 1 }
37
+ end
38
+
39
+ it "defaults to :month_names => :int whenever an unknown value is passed" do
40
+ Post.archived_months(:month_names => :invalid_value).should == { 1 => 1, 2 => 1 }
41
+ end
42
+
43
+ it "discards dates that are null" do
44
+ Post.first.update_attributes(:created_at => nil)
45
+ Post.archived_months.should == { 2 => 1 }
46
+ end
47
+ end # archived_months
48
+
49
+ end # ArchiveTree
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchiveTree do
4
+
5
+ describe "archived years" do
6
+
7
+ it "returns an empty hash if no years are archived" do
8
+ Post.archived_years.should == {}
9
+ end
10
+
11
+ it "returns a years counter hash" do
12
+ 2.times { |i| Factory.create(:post, :created_at => "#{Time.now.year + i}-#{01 + i}-01 00:00:00") }
13
+
14
+ Post.archived_years.should == { Time.now.year => 1, (Time.now.year + 1) => 1 }
15
+ end
16
+
17
+ it "discards dates that are null" do
18
+ 2.times { |i| Factory.create(:post, :created_at => "#{Time.now.year + i}-#{01 + i}-01 00:00:00") }
19
+
20
+ Post.last.update_attributes(:created_at => nil)
21
+
22
+ Post.archived_years.should == { Time.now.year => 1 }
23
+ end
24
+
25
+ end # archived_years
26
+
27
+ end # ArchiveTree
@@ -0,0 +1,69 @@
1
+ $:.unshift File.dirname(__FILE__) unless $:.include? File.dirname(__FILE__)
2
+ $:.unshift File.join(File.dirname(__FILE__), '..') unless $:.include? File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'init'
6
+ require 'erb'
7
+ require 'logger'
8
+ require 'rspec'
9
+ require 'active_record'
10
+ require 'database_cleaner'
11
+ require 'factory_girl'
12
+
13
+ RSpec.configure do |config|
14
+ config.debug = true
15
+ # == Mock Framework
16
+ config.mock_with :rspec
17
+
18
+ # database_cleaner
19
+ config.before(:suite) do
20
+ DatabaseCleaner.strategy = :transaction
21
+ DatabaseCleaner.clean_with(:truncation)
22
+ end
23
+
24
+ config.before(:each) do
25
+ DatabaseCleaner.start
26
+ end
27
+
28
+ config.after(:each) do
29
+ DatabaseCleaner.clean
30
+ end
31
+ end
32
+ rescue LoadError => load_error
33
+ puts "Please run bundle install"
34
+ rescue StandardError => e
35
+ puts "Something went wrong while loading the environment."
36
+ throw e
37
+ end
38
+
39
+ # Requires supporting files with custom matchers and macros, etc, in ./support/ and its subdirectories.
40
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
41
+
42
+ # Requires all supporting factories
43
+ Dir.glob(File.join(File.dirname(__FILE__), 'factories', '*_factory.rb')).each { |f| require f }
44
+
45
+ # ActiveRecord Test database configurations
46
+ database_yml_file = File.expand_path('../config/database.yml', __FILE__)
47
+
48
+ begin
49
+ if File.exists?(database_yml_file)
50
+ active_record_configuration = YAML.load_file(database_yml_file)['test']
51
+ ActiveRecord::Base.establish_connection(active_record_configuration)
52
+ ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), 'log', 'test.log'))
53
+
54
+ ActiveRecord::Base.silence do
55
+ ActiveRecord::Migration.verbose = false
56
+
57
+ load File.join(File.dirname(__FILE__), 'db', 'schema.rb')
58
+ load File.join(File.dirname(__FILE__), 'db' , 'models.rb')
59
+ end
60
+
61
+ # The config/database.yml is in the spec folder
62
+ DatabaseCleaner.app_root = File.expand_path('spec')
63
+ else
64
+ raise "Please create #{database_yml} first. Take a look at the database.sample.yml in the config folder."
65
+ end
66
+ rescue StandardError => e
67
+ puts "Something went wrong while attempting to load your database file, or while configuring ActiveRecord."
68
+ throw e
69
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: archive_tree
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
4
+ prerelease: false
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
8
  - 0
9
- - rc3
10
- version: 1.0.0.rc3
9
+ version: 1.0.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Diogo Almeida
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-11-03 00:00:00 +00:00
18
+ date: 2010-11-09 00:00:00 +00:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -30,36 +29,100 @@ dependencies:
30
29
  segments:
31
30
  - 3
32
31
  - 0
33
- - 0
34
- version: 3.0.0
32
+ - 1
33
+ version: 3.0.1
35
34
  type: :runtime
36
35
  version_requirements: *id001
37
36
  - !ruby/object:Gem::Dependency
38
- name: rspec
37
+ name: actionpack
39
38
  prerelease: false
40
39
  requirement: &id002 !ruby/object:Gem::Requirement
41
40
  none: false
42
41
  requirements:
43
- - - ">="
42
+ - - ~>
44
43
  - !ruby/object:Gem::Version
45
44
  segments:
45
+ - 3
46
46
  - 0
47
- version: "0"
48
- type: :development
47
+ - 1
48
+ version: 3.0.1
49
+ type: :runtime
49
50
  version_requirements: *id002
50
51
  - !ruby/object:Gem::Dependency
51
- name: database_cleaner
52
+ name: mysql
52
53
  prerelease: false
53
54
  requirement: &id003 !ruby/object:Gem::Requirement
54
55
  none: false
55
56
  requirements:
56
- - - ">="
57
+ - - ~>
57
58
  - !ruby/object:Gem::Version
58
59
  segments:
60
+ - 2
61
+ - 8
59
62
  - 0
60
- version: "0"
63
+ version: 2.8.0
61
64
  type: :development
62
65
  version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: ruby-debug19
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ - 11
77
+ - 0
78
+ version: 0.11.0
79
+ type: :development
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 2
91
+ - 0
92
+ - 0
93
+ version: 2.0.0
94
+ type: :development
95
+ version_requirements: *id005
96
+ - !ruby/object:Gem::Dependency
97
+ name: factory_girl_rails
98
+ prerelease: false
99
+ requirement: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ segments:
105
+ - 1
106
+ - 0
107
+ - 0
108
+ version: 1.0.0
109
+ type: :development
110
+ version_requirements: *id006
111
+ - !ruby/object:Gem::Dependency
112
+ name: database_cleaner
113
+ prerelease: false
114
+ requirement: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
121
+ - 6
122
+ - 0
123
+ version: 0.6.0
124
+ type: :development
125
+ version_requirements: *id007
63
126
  description: ArchiveTree is a Ruby Gem that makes it easy for you to create beautiful chronological archive trees of your models. For instance, you can create a tree for your blog posts.
64
127
  email:
65
128
  - mail@gnomeslab.com
@@ -70,12 +133,24 @@ extensions: []
70
133
  extra_rdoc_files: []
71
134
 
72
135
  files:
73
- - lib/archive_tree/action_view_extensions/draw_archive_tree.rb
74
136
  - lib/archive_tree/action_view_extensions.rb
75
137
  - lib/archive_tree/core.rb
76
138
  - lib/archive_tree.rb
139
+ - Gemfile
140
+ - Gemfile.lock
77
141
  - MIT-LICENSE
142
+ - Rakefile
78
143
  - README.md
144
+ - spec/db/models.rb
145
+ - spec/db/schema.rb
146
+ - spec/factories/posts_factory.rb
147
+ - spec/lib/action_view_extensions/action_view_extensions_spec.rb
148
+ - spec/lib/archive_node_spec.rb
149
+ - spec/lib/archive_tree_core_spec.rb
150
+ - spec/lib/archive_tree_spec.rb
151
+ - spec/lib/archived_months_spec.rb
152
+ - spec/lib/archived_years_spec.rb
153
+ - spec/spec_helper.rb
79
154
  has_rdoc: true
80
155
  homepage: http://github.com/GnomesLab/archive_tree/
81
156
  licenses: []
@@ -85,6 +160,7 @@ rdoc_options: []
85
160
 
86
161
  require_paths:
87
162
  - lib
163
+ - lib
88
164
  required_ruby_version: !ruby/object:Gem::Requirement
89
165
  none: false
90
166
  requirements:
@@ -109,6 +185,6 @@ rubyforge_project:
109
185
  rubygems_version: 1.3.7
110
186
  signing_key:
111
187
  specification_version: 3
112
- summary: Creates chronological trees of your models based on their created_at column value.
188
+ summary: Creates chronological trees of your models based on column of your choice.
113
189
  test_files: []
114
190
 
@@ -1,76 +0,0 @@
1
- module ArchiveTree
2
- module ActionViewExtensions
3
-
4
- # Defines the helper methods that will be included in the ActionView::Base in
5
- # order to return the html representation of the archive tree
6
- module DrawArchiveTree
7
-
8
- # In the presence of records for a given model it draws the archive tree. Otherwise, returns an empty string
9
- #
10
- # This method relies on the following private methods:
11
- # * +draw_years+
12
- # * +draw_months+
13
- #
14
- # Default behavior
15
- # * It will attempt to create a tree of your Post model
16
- # * Will use the posts_path route
17
- # * Will display a toggle link
18
- # * Will use "[ + ]" as the text for the toggle link
19
- #
20
- # Options
21
- # * model_sym #=> the symbol of the model to request the archive_nodes
22
- # * route #=> the route that handles the archived posts requests
23
- # * toggle #=> when true, includes a toggle link before the years
24
- # * toggle_text #=> the text used in the toggle link
25
- #
26
- # Example using the default settings:
27
- # <%= draw_archive_tree %>
28
- #
29
- # Overriding the defaults example:
30
- # <%= draw_archive_tree :model_sym => :post, :route => :archive_published_at_path, :toggle => false %>
31
-
32
- def draw_archive_tree(options = {})
33
- options.reverse_merge!({ :model_sym => :post, :route => :posts_path, :toggle => true, :toggle_text => '[ + ]' })
34
- model = options[:model_sym].to_s.capitalize.constantize
35
-
36
- raw model.count > 0 ? draw_years(model, options[:route], options[:toggle], options[:toggle_text]) : ''
37
- end # draw_archive_tree
38
-
39
- private
40
- def draw_years(model_sym, route, toggle, toggle_text) # :nodoc:
41
- model = model_sym.to_s.capitalize.constantize
42
- route = :posts_path unless self.respond_to? route
43
-
44
- content_tag :ul do
45
- ul_body = ""
46
-
47
- model.archived_years.each_key do |year, count|
48
- ul_body << content_tag(:li, :class => year == Time.now.year ? 'active' : 'inactive') do
49
- (toggle ? link_to(toggle_text, "#", :class => "toggle") : '') + " " +
50
- link_to(year, self.send(route, year)) +
51
- draw_months(model_sym, route, year)
52
- end
53
- end
54
-
55
- ul_body
56
- end
57
- end
58
-
59
- def draw_months(model_sym, route, year) # :nodoc:
60
- model = model_sym.to_s.capitalize.constantize
61
-
62
- content_tag :ul do
63
- ul_body = ""
64
-
65
- model.archived_months(:year => year).each_pair do |month, count|
66
- ul_body << content_tag(:li, link_to("#{Date::MONTHNAMES[month]} (#{count})",
67
- self.send(route, year, month < 10 ? "0#{month}" : month)))
68
- end
69
-
70
- ul_body
71
- end
72
- end
73
- end # DrawArchiveTree
74
-
75
- end # ActionViewExtensions
76
- end # ArchiveTree