nanoc-toolbox 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  require 'nanoc/toolbox/helpers/html_tag'
2
2
 
3
- module Nanoc::Toolbox::Helpers
3
+ module Nanoc::Toolbox::Helpers
4
4
  # NANOC Helper for the Navigation related stuff.
5
5
  #
6
6
  # This module contains functions for generating navigation menus for your
@@ -8,7 +8,7 @@ module Nanoc::Toolbox::Helpers
8
8
  #
9
9
  # @author Anouar ADLANI <anouar@adlani.com>
10
10
  module Navigation
11
- include Nanoc3::Helpers::LinkTo
11
+ include Nanoc::Helpers::LinkTo
12
12
  include Nanoc::Toolbox::Helpers::HtmlTag
13
13
 
14
14
  # Generate a navigation menu for a given item.
@@ -34,39 +34,38 @@ module Nanoc::Toolbox::Helpers
34
34
  render_menu(sections, options)
35
35
  end
36
36
 
37
-
38
37
  # Generate a Table of Content for a given item. The toc will be generated
39
38
  # form the item content. The parsing is done with Nokogiri through XPath.
40
39
  #
41
- # @param [String] item_rep - the representation of desired item
40
+ # @param [Nanoc::ItemRep] item_rep - the representation of desired item
42
41
  # @param [Hash] options - The Optional parameters
43
42
  # @option options (see #render_menu)
44
43
  # @option options [String] :path ('div[@class="section"]') Generic XPath for the sections
45
- #
44
+ #
46
45
  # @return [String] The output ready to be displayed by the caller
47
46
  #
48
47
  # @see http://nokogiri.org/
49
48
  def toc_for(item_rep, options={})
50
49
  require 'nokogiri'
50
+ item_rep = item_rep.rep_named(:default) if item_rep.is_a? Nanoc::Item
51
51
 
52
- # Parse options or set to default values
53
52
  options[:path] ||= 'div[@class="section"]'
54
53
 
55
54
  # Retreive the parsed content and init nokogiri
56
55
  compiled_content = item_rep.instance_eval { @content[:pre] }
57
56
  doc = Nokogiri::HTML(compiled_content)
58
57
  doc_root = doc.xpath('/html/body').first
58
+ return "" if doc_root.nil?
59
59
 
60
60
  # Find all sections, and render them
61
61
  sections = find_toc_sections(doc_root, options[:path])
62
- render_menu(sections, options)
62
+ render_menu(sections, options) || ""
63
63
  end
64
64
 
65
-
66
65
  # Generate a Breadcrumb for a given item. The breadcrumbs, is starting with
67
66
  # the root item and ending with the item itself.
68
67
  #
69
- # Requires the Helper: Nanoc3::Helpers::Breadcrumbs
68
+ # Requires the Helper: Nanoc::Helpers::Breadcrumbs
70
69
  #
71
70
  # @param [String] identifier - the identifier string of element
72
71
  # @param [Hash] options - The Optional parameters
@@ -74,12 +73,11 @@ module Nanoc::Toolbox::Helpers
74
73
  #
75
74
  # @return [String] The output ready to be displayed by the caller
76
75
  #
77
- # @see Nanoc3::Helpers::Breadcrumbs#breadcrumbs_for_identifier
76
+ # @see Nanoc::Helpers::Breadcrumbs#breadcrumbs_for_identifier
78
77
  def breadcrumb_for(identifier, options={})
79
-
80
- # Parse options or set to default values
81
78
  options[:collection_tag] ||= 'ul'
82
-
79
+ options[:collection_class] ||= 'breadcrumb'
80
+
83
81
  # Retreive the breadcrumbs trail and format them
84
82
  sections = find_breadcrumbs_trail(identifier)
85
83
  render_menu(sections, options)
@@ -118,24 +116,22 @@ module Nanoc::Toolbox::Helpers
118
116
  #
119
117
  # @return [String] The output ready to be displayed by the caller
120
118
  def render_menu(items, options={})
121
-
122
- # Parse options or set to default values
123
119
  options[:depth] ||= 3
124
120
  options[:collection_tag] ||= 'ol'
121
+ options[:collection_class] ||= 'menu'
125
122
  options[:item_tag] ||= 'li'
126
123
  options[:title_tag] ||= 'h2'
127
124
  options[:title] ||= nil
128
-
125
+
129
126
  # Parse the title and remove it from the options
130
127
  title = options[:title] ? content_tag(options[:title_tag], options[:title]) : ''
131
- options.delete(:title_tag)
132
- options.delete(:title)
133
-
128
+ options.delete(:title_tag)
129
+ options.delete(:title)
130
+
134
131
  # Decrease the depth level
135
132
  options[:depth] -= 1
136
133
 
137
134
  rendered_menu = items.map do |item|
138
-
139
135
  # Render only if there is depth left
140
136
  if options[:depth].to_i > 0 && item[:subsections]
141
137
  output = render_menu(item[:subsections], options)
@@ -146,60 +142,58 @@ module Nanoc::Toolbox::Helpers
146
142
 
147
143
  end.join()
148
144
 
149
-
150
- title + content_tag(options[:collection_tag], rendered_menu) unless rendered_menu.strip.empty?
145
+ title + content_tag(options[:collection_tag], rendered_menu, :class => options[:collection_class]) unless rendered_menu.strip.empty?
151
146
  end
152
147
 
153
- private
154
-
155
- # Recursive method that extract from an XPath pattern the document structure
156
- # and return the "permalinks" to each sections in an Array of Hash that
157
- # could be used by the rendering method. The structure is deducted by the
158
- # H1-6 header within the html element defined by the XPATH
159
- def find_toc_sections(section, section_xpath, title_level=1)
160
- return {} unless section.xpath(section_xpath)
161
-
162
- # For each section found call the find_toc_sections on it with an
163
- # increased header level (ex: h1 => h2) and then generate the hash res
164
- sections = section.xpath(section_xpath).map do |subsection|
165
- header = subsection.css("h1, h2, h3, h4, h5, h6").first
166
- sub_id = subsection['id']
167
- sub_title = header ? header.inner_html : 'untitled'
168
- subsections = {}
169
-
170
- if subsection.xpath("#{section_xpath}") && title_level <= 6
171
- subsections = find_toc_sections(subsection, "#{section_xpath}", title_level+1)
172
- end
173
- { :title => sub_title, :link => '#' + sub_id, :subsections => subsections }
148
+ private
149
+
150
+ # Recursive method that extract from an XPath pattern the document structure
151
+ # and return the "permalinks" to each sections in an Array of Hash that
152
+ # could be used by the rendering method. The structure is deducted by the
153
+ # H1-6 header within the html element defined by the XPATH
154
+ def find_toc_sections(section, section_xpath, title_level=1)
155
+ return {} unless section.xpath(section_xpath)
156
+
157
+ # For each section found call the find_toc_sections on it with an
158
+ # increased header level (ex: h1 => h2) and then generate the hash res
159
+ sections = section.xpath(section_xpath).map do |subsection|
160
+ header = subsection.css("h1, h2, h3, h4, h5, h6").first
161
+ sub_id = subsection['id']
162
+ sub_title = header ? header.inner_html : 'untitled'
163
+ subsections = {}
164
+
165
+ if subsection.xpath("#{section_xpath}") && title_level <= 6
166
+ subsections = find_toc_sections(subsection, "#{section_xpath}", title_level+1)
174
167
  end
168
+ { :title => sub_title, :link => '#' + sub_id, :subsections => subsections }
175
169
  end
170
+ end
176
171
 
177
- # Recursive method that extract from an XPath pattern the document structure
178
- # and return the "permalinks" in a Array of Hash that could be used by the
179
- # rendering method
180
- def find_item_tree(root, options={})
181
- return nil unless root.children
182
-
183
- # filter the elements to contain only the kind requested
184
- children = options[:kind] ? root.children.select { |item| item[:kind] == options[:kind] } : root.children
185
-
186
- # For each child call the find_item_tree on it and then generate the hash
187
- sections = children.map do |child|
188
- subsections = find_item_tree(child)
189
-
190
- { :title => (child[:title] || child.identifier),
191
- :link => relative_path_to(child),
192
- :subsections => subsections }
193
- end
194
- end
172
+ # Recursive method that extract from an XPath pattern the document structure
173
+ # and return the "permalinks" in a Array of Hash that could be used by the
174
+ # rendering method
175
+ def find_item_tree(root, options={})
176
+ return nil unless root.children
195
177
 
178
+ # filter the elements to contain only the kind requested
179
+ children = options[:kind] ? root.children.select { |item| item[:kind] == options[:kind] } : root.children
196
180
 
197
- def find_breadcrumbs_trail(root)
198
- sections = breadcrumbs_for_identifier(root).map do |child|
199
- { :title => (child[:title] || child.identifier),
200
- :link => relative_path_to(child),
201
- :subsections => nil }
202
- end
181
+ # For each child call the find_item_tree on it and then generate the hash
182
+ sections = children.map do |child|
183
+ subsections = find_item_tree(child)
184
+
185
+ { :title => (child[:title] || child.identifier),
186
+ :link => relative_path_to(child),
187
+ :subsections => subsections }
203
188
  end
189
+ end
190
+
191
+ def find_breadcrumbs_trail(root)
192
+ sections = breadcrumbs_for_identifier(root).map do |child|
193
+ { :title => (child[:short_title] || child[:title] || child.identifier),
194
+ :link => relative_path_to(child),
195
+ :subsections => nil }
196
+ end
197
+ end
204
198
  end
205
199
  end
@@ -0,0 +1,135 @@
1
+ module Nanoc::Toolbox::Helpers
2
+
3
+ # NANOC Helper for added tagging functions
4
+ #
5
+ # This module contains functions for ...
6
+ #
7
+ # @see http://groups.google.com/group/nanoc/browse_thread/thread/caefcab791fd3c4b
8
+ module TaggingExtra
9
+ include Nanoc::Helpers::Blogging
10
+
11
+ # Returns all the tags present in a collection of items. The tags are
12
+ # only present once in the returned value. When called whithout
13
+ # parameters, all the site items are considered.
14
+ #
15
+ # @param [Array<Nanoc::Item>] items
16
+ # @return [Array<String>] An array of tags
17
+ def tag_set(items=nil)
18
+ items ||= @items
19
+ items.map { |i| i[:tags] }.flatten.uniq.delete_if{|t| t.nil?}
20
+ end
21
+
22
+ # Return true if an item has a specified tag
23
+ #
24
+ # @param [Nanoc::Item] item
25
+ # @param [String] tag
26
+ # @return [Boolean] true if the item contains the specified tag
27
+ def has_tag?(item, tag)
28
+ return false if item[:tags].nil?
29
+ item[:tags].include? tag
30
+ end
31
+
32
+ # Finds all the items having a specified tag. By default the method search
33
+ # in all the site items. Alternatively, an item collection can be passed as
34
+ # second (optional) parameter, to restrict the search in the collection.
35
+ #
36
+ # @param [Array<Nanoc::Item>] items
37
+ # @param [String] tag
38
+ # @param [Nanoc::Item] item
39
+ def items_with_tag(tag, items=nil)
40
+ items = sorted_articles if items.nil?
41
+ items.select { |item| has_tag?( item, tag ) }
42
+ end
43
+
44
+ # Count the tags in a given collection of items. By default, the method
45
+ # counts tags in all the site items. The result is an hash such as:
46
+ # { tag => count }.
47
+ #
48
+ # @param [Array<Nanoc::Item>] items
49
+ # @return [Hash] Hash indexed by tag name with the occurences as value
50
+ def count_tags(items=nil)
51
+ items ||= @items
52
+ tags = items.map { |i| i[:tags] }.flatten.delete_if{|t| t.nil?}
53
+ tags.inject(Hash.new(0)) {|h,i| h[i] += 1; h }
54
+ end
55
+
56
+ # Sort the tags of an item collection (defaults to all site items) in 'n'
57
+ # classes of rank. The rank 0 corresponds to the most frequent tags.
58
+ # The rank 'n-1' to the least frequents. The result is a hash such as:
59
+ # { tag => rank }
60
+ #
61
+ # @param [Integer] n number of rank
62
+ # @param [Array<Nanoc::Item>] items
63
+ def rank_tags(n, items=nil)
64
+ raise ArgumentError, 'the number of ranks should be > 1' if n < 2
65
+
66
+ items = @items if items.nil?
67
+ count = count_tags( items )
68
+ min, max = count.values.minmax
69
+
70
+ ranker = lambda { |num| n - 1 - (num - min) / (max - min) }
71
+
72
+ Hash[count.map {|tag,value| [tag, ranker.call(value) ] }]
73
+ end
74
+
75
+ # Returns an Array of links to tags in the item, optionally omits the
76
+ # given tags from the selection
77
+ #
78
+ # @param [Item] item the item from which to extract tags
79
+ # @param [Array<String>] omit_tags tags that should be excluded
80
+ # @param [Item] options the options for the links to be created
81
+ # @option options [String] :tag_pattern ("%%tag%%") The pattern to be replace by the tag name
82
+ # @option options [String] :title ("options[:tag_pattern]") The text that will be in the link
83
+ # @option options [String] :file_extension (".html") The file extension
84
+ # @option options [String] :url_format ("/tags/:tag_pattern:file_extension") The path pattern
85
+ #
86
+ # @return [Array<String>] An array of html links
87
+ #
88
+ # @example
89
+ # omited = ['strange_tag']
90
+ # options = { :tag_pattern => "%%TAGNAME%%",
91
+ # :title => "articles tagged with %%TAGNAME%%",
92
+ # :url_format => "/tags/tag_%%TAGNAME%%.html"}
93
+ # tag_links_for(item, omited, options) # => ['<a href="/tags/tag_a.html">articles tagged with a</a>', '<a href="/tags/tag_b.html">articles tagged with b</a>']
94
+ def tag_links_for(item, omit_tags=[], options={})
95
+ tags = []
96
+ return tags unless item[:tags]
97
+
98
+ options[:tag_pattern] ||= "%%tag%%"
99
+ options[:title] ||= options[:tag_pattern]
100
+ options[:file_extension] ||= ".html"
101
+ options[:url_format] ||= "/tags/#{options[:tag_pattern]}#{options[:file_extension]}"
102
+
103
+ tags = item[:tags] - omit_tags
104
+
105
+ tags.map! do |tag|
106
+ title = options[:title].gsub(options[:tag_pattern], tag.downcase)
107
+ url = options[:url_format].gsub(options[:tag_pattern], tag.downcase)
108
+ content_tag('a', title, {:href => url})
109
+ end
110
+ end
111
+
112
+ # Creates in-memory tag pages from tags of the passed items or form all items
113
+ #
114
+ # @param [Array<Item>] item the item from which to extract tags
115
+ # @param [Item] options the options for the item to be created
116
+ # @option options [String] :tag_pattern ("%%tag%%") The pattern to be replace by the tag name
117
+ # @option options [String] :title ("options[:tag_pattern]") The text that will be in the link
118
+ # @option options [String] :identifier ("/tags/option[:tag_pattern]") The item identifer
119
+ # @option options [String] :template ("tag") The template/layout to use to render the tag
120
+ def create_tag_pages(items=nil, options={})
121
+ options[:tag_pattern] ||= "%%tag%%"
122
+ options[:title] ||= options[:tag_pattern]
123
+ options[:identifier] ||= "/tags/#{options[:tag_pattern]}/"
124
+ options[:template] ||= "tag"
125
+
126
+ tag_set(items).each do |tagname|
127
+ raw_content = "<%= render('#{options[:template]}', :tag => '#{tagname}') %>"
128
+ attributes = { :title => options[:title].gsub(options[:tag_pattern], tagname) }
129
+ identifier = options[:identifier].gsub(options[:tag_pattern], tagname)
130
+
131
+ @items << Nanoc::Item.new(raw_content, attributes, identifier, :binary => false)
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,9 +1,12 @@
1
1
  require 'nanoc/toolbox/helpers/navigation'
2
2
  require 'nanoc/toolbox/helpers/gravatar'
3
3
  require 'nanoc/toolbox/helpers/html_tag'
4
+ require 'nanoc/toolbox/helpers/disqus'
5
+ require 'nanoc/toolbox/helpers/blogging_extra'
6
+ require 'nanoc/toolbox/helpers/tagging_extra'
4
7
  require 'nanoc/toolbox/helpers/google_analytics'
5
8
 
6
9
  # This module will regroup all the helpers for nanoc
7
10
  module Nanoc::Toolbox::Helpers
8
11
 
9
- end
12
+ end
@@ -3,8 +3,8 @@ module Nanoc
3
3
  # Holds information about library version.
4
4
  module Version
5
5
  MAJOR = 0
6
- MINOR = 0
7
- PATCH = 7
6
+ MINOR = 1
7
+ PATCH = 0
8
8
  BUILD = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join(".")
@@ -2,25 +2,26 @@
2
2
  require File.expand_path("../lib/nanoc/toolbox/version", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "nanoc-toolbox"
6
- s.version = Nanoc::Toolbox::VERSION
7
- s.platform = Gem::Platform::RUBY
8
- s.authors = ["Anouar ADLANI"]
9
- s.email = ["anouar@adlani.com"]
10
- s.homepage = "http://aadlani.github.com/nanoc-toolbox/"
11
- s.summary = "A collection of helper and filters for nanoc"
12
- s.description = "The nanoc-toolbox is a collection of filters and helpers for the static site generator tool nanoc"
5
+ s.name = "nanoc-toolbox"
6
+ s.version = Nanoc::Toolbox::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Anouar ADLANI"]
9
+ s.email = ["anouar@adlani.com"]
10
+ s.homepage = "http://aadlani.github.com/nanoc-toolbox/"
11
+ s.summary = "A collection of helper and filters for nanoc"
12
+ s.description = "The nanoc-toolbox is a collection of filters and helpers for the static site generator tool nanoc"
13
13
  s.rdoc_options = ["--main", "README.rdoc"]
14
14
 
15
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
15
16
  s.required_rubygems_version = ">= 1.3.6"
16
17
 
17
- s.add_dependency "nanoc", ">= 3.1.6"
18
- s.add_dependency "nokogiri", ">= 1.4.4"
19
- s.add_dependency "jsmin", ">= 1.0.1"
18
+ s.add_dependency "nanoc", "~> 3.4"
19
+ s.add_dependency "nokogiri", "~> 1.4"
20
+ s.add_dependency "jsmin", "~> 1.0"
20
21
 
21
- s.add_development_dependency "bundler", ">= 1.0.0"
22
- s.add_development_dependency "rspec", ">= 1.0.0"
23
- s.add_development_dependency "rake"
22
+ s.add_development_dependency "bundler", "~> 1.1"
23
+ s.add_development_dependency "rspec", "~> 2.4"
24
+ s.add_development_dependency "rake", "~> 0.9"
24
25
 
25
26
  s.files = `git ls-files`.split("\n")
26
27
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
@@ -1,31 +1,4 @@
1
- # <div>
2
- # <h1>Title</h1>
3
- #
4
- # <h2>Sub title1</h2>
5
- # <p>Lorem Ipsum</p>
6
- #
7
- # <h3>Sub Sub Title1</h3>
8
- # <p>Lorem Ipsum</p>
9
- #
10
- # <h3>Sub Sub Title2</h3>
11
- # <p>Lorem Ipsum</p>
12
- #
13
- # <h3>Sub Sub Title3</h3>
14
- # <p>Lorem Ipsum</p>
15
- #
16
- #
17
- # <h2>Sub title2</h2>
18
- # <p>Lorem Ipsum</p>
19
- #
20
- # <h2>Sub title3</h2>
21
- # <p>Lorem Ipsum</p>
22
- #
23
- # <h2>Sub title4</h2>
24
- # <p>Lorem Ipsum</p>
25
- # </div>
26
-
27
1
  require "spec_helper"
28
- require "nokogiri"
29
2
 
30
3
  describe Nanoc::Toolbox::Filters::AddSections do
31
4
  before(:each) do
@@ -33,6 +6,11 @@ describe Nanoc::Toolbox::Filters::AddSections do
33
6
  end
34
7
 
35
8
  describe ".run" do
36
-
9
+ it "minifies javascript" do
10
+ content = "<h1>A Title<h1/><h2>A Second Title<h2/>"
11
+ result = @filter.run(content)
12
+ result.should_not eq content
13
+ result.should =~ /"section"/
14
+ end
37
15
  end
38
- end
16
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe Nanoc::Toolbox::Filters::JsMinify do
4
+ before(:each) do
5
+ @filter = described_class.new
6
+ end
7
+
8
+ describe ".run" do
9
+ it "minifies javascript" do
10
+ content = "alert('Hello World!'); /*Print Hello world*/\n"
11
+ @filter.run(content).should_not eq content
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,134 @@
1
+ require "spec_helper"
2
+
3
+ class BloggingExtraDummyClass
4
+ include Nanoc::Toolbox::Helpers::BloggingExtra
5
+ def initialize
6
+ @config = {}
7
+ end
8
+ end
9
+
10
+ describe Nanoc::Toolbox::Helpers::BloggingExtra do
11
+
12
+ subject { BloggingExtraDummyClass.new }
13
+
14
+ it { should respond_to(:add_post_attributes) }
15
+ it { should respond_to(:act_as_post) }
16
+ it { should respond_to(:slug_for) }
17
+ it { should respond_to(:recent_posts) }
18
+ it { should respond_to(:posts_by_date) }
19
+
20
+ describe ".slug_for" do
21
+ it "returns the slug set in the item if it's existing" do
22
+ item = { :slug => "abc-def-geh.html" }
23
+ subject.slug_for(item).should == "abc-def-geh.html"
24
+ end
25
+
26
+ it "generate the slug based on the item filename, by striping spaces" do
27
+ item = { :filename => "abc def geh.html" }
28
+ subject.slug_for(item).should == "abc-def-geh"
29
+ end
30
+ end
31
+
32
+ describe ".add_post_attributes" do
33
+ it "defines the items as posts when located in the defined folders" do
34
+ articles = [
35
+ Nanoc::Item.new("", { :extension => ".md", :created_at => "01/12/2012 22:14" }, "test-of-post2"),
36
+ Nanoc::Item.new("", { :filename => "_posts/test-of-post2", :extension => ".md", :created_at => "01/12/2012 22:14" }, "test-of-post2"),
37
+ Nanoc::Item.new("", { :filename => "_articles/test-of-post3", :extension => ".md", :created_at => "01/12/2010 22:13" }, "test-of-post3"),
38
+ Nanoc::Item.new("", { :filename => "test-of-post6", :extension => ".md", :created_at => "01/12/2008 22:10" }, "test-of-post6")]
39
+
40
+ subject.stub(:items).and_return(articles)
41
+ subject.should_receive(:act_as_post).with(an_instance_of(Nanoc::Item)).twice
42
+ subject.add_post_attributes
43
+ end
44
+ end
45
+
46
+ describe ".act_as_post" do
47
+ before do
48
+ @item = { :filename => "2011-02-12-test-of-post", :extension => ".md", :created_at => "01/12/2011 22:15" }
49
+ subject.act_as_post(@item)
50
+ end
51
+
52
+ it "forces the item kind to article" do
53
+ @item[:kind].should == 'article'
54
+ end
55
+
56
+ it "handles the date from the filename" do
57
+ @item[:created_at].should == Time.local(2011, 02, 12)
58
+ @item[:year].should == "2011"
59
+ @item[:month].should == "02"
60
+ @item[:day].should == "12"
61
+ end
62
+
63
+ it "do something when no date set in the filename" do
64
+ @item[:year].to_i.should == @item[:created_at].year
65
+ @item[:month].to_i.should == @item[:created_at].month
66
+ @item[:day].to_i.should == @item[:created_at].day
67
+ end
68
+
69
+ it "generates a slug from the filename" do
70
+ @item[:slug].should == "test-of-post"
71
+ end
72
+
73
+ it "enables by default the comments" do
74
+ @item[:comments].should be_true
75
+ end
76
+ end
77
+
78
+ describe ".recent_posts" do
79
+ before do
80
+ @last_articles = [
81
+ Nanoc::Item.new("", { :filename => "test-of-post1", :extension => ".md", :created_at => "01/12/2008 22:15" }, "test-of-post1"),
82
+ Nanoc::Item.new("", { :filename => "test-of-post2", :extension => ".md", :created_at => "01/12/2012 22:14" }, "test-of-post2"),
83
+ Nanoc::Item.new("", { :filename => "test-of-post3", :extension => ".md", :created_at => "01/12/2010 22:13" }, "test-of-post3"),
84
+ Nanoc::Item.new("", { :filename => "test-of-post4", :extension => ".md", :created_at => "01/12/2010 22:12" }, "test-of-post4"),
85
+ Nanoc::Item.new("", { :filename => "test-of-post5", :extension => ".md", :created_at => "01/11/2010 22:11" }, "test-of-post5"),
86
+ Nanoc::Item.new("", { :filename => "test-of-post6", :extension => ".md", :created_at => "01/12/2013 22:10" }, "test-of-post6")]
87
+
88
+ subject.stub(:sorted_articles).and_return(@last_articles)
89
+ end
90
+
91
+ it "returns the requested recent posts" do
92
+ posts = subject.recent_posts(3)
93
+ posts.length.should eq 3
94
+ posts.should_not include(@last_articles.last)
95
+ posts.should include(@last_articles.first)
96
+ end
97
+
98
+ it "returns the existing posts when requesting more than" do
99
+ posts = subject.recent_posts(13)
100
+ posts.length.should eq @last_articles.length
101
+ posts.should eq(@last_articles)
102
+ end
103
+
104
+ it "excludes the current item when requested" do
105
+ posts = subject.recent_posts(6, @last_articles.last)
106
+ posts.should_not include(@last_articles.last)
107
+ end
108
+ end
109
+
110
+ describe ".posts_by_date" do
111
+ before do
112
+ @last_articles = []
113
+ articles = [
114
+ Nanoc::Item.new("", { :filename => "test-of-post1", :extension => ".md", :created_at => "01/12/2013 22:15" }, "test-of-post1"),
115
+ Nanoc::Item.new("", { :filename => "test-of-post2", :extension => ".md", :created_at => "01/12/2012 22:14" }, "test-of-post2"),
116
+ Nanoc::Item.new("", { :filename => "test-of-post3", :extension => ".md", :created_at => "01/12/2010 22:13" }, "test-of-post3"),
117
+ Nanoc::Item.new("", { :filename => "test-of-post4", :extension => ".md", :created_at => "01/12/2010 22:12" }, "test-of-post4"),
118
+ Nanoc::Item.new("", { :filename => "test-of-post5", :extension => ".md", :created_at => "01/02/2010 22:11" }, "test-of-post5"),
119
+ Nanoc::Item.new("", { :filename => "test-of-post6", :extension => ".md", :created_at => "01/12/2008 22:10" }, "test-of-post6")]
120
+
121
+ articles.each do |article|
122
+ @last_articles << subject.act_as_post(article)
123
+ end
124
+ subject.stub(:sorted_articles).and_return(@last_articles)
125
+ end
126
+
127
+ it "returns the article grouped by years and months" do
128
+ grouped_article = subject.posts_by_date
129
+ grouped_article.keys.should eq @last_articles.map {|i| i[:year]}.uniq
130
+ grouped_article[2010][12].should eq @last_articles[2..3]
131
+ end
132
+ end
133
+ end
134
+
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyDisqusClass
4
+ include Nanoc::Toolbox::Helpers::Disqus
5
+ end
6
+
7
+ describe Nanoc::Toolbox::Helpers::Disqus do
8
+ subject { DummyDisqusClass.new }
9
+
10
+ it { should respond_to :disqus_id_for }
11
+ it { should respond_to :disqus_js_snippet }
12
+ it { should respond_to :disqus_nojs_snippet }
13
+
14
+ describe ".disqus_id_for" do
15
+ it "calls slug_for to generate the id" do
16
+ subject.should_receive(:slug_for).once.and_return('hello-world')
17
+ subject.disqus_id_for({}).should eq 'hello_world'
18
+ end
19
+
20
+ it "prepends the disqus prefix id if passed in the options" do
21
+ subject.should_receive(:slug_for).once.and_return('hello-world')
22
+ subject.disqus_id_for({}, {:disqus_id_prefix => 'my_website_'}).should eq 'my_website_hello_world'
23
+ end
24
+ end
25
+
26
+ describe ".disqus_js_snippet" do
27
+ it "returns the JS snippet" do
28
+ subject.disqus_js_snippet.should =~/<script type="text\/javascript">/
29
+ end
30
+
31
+ it "declares prefixed variables passed in options" do
32
+ menu = subject.disqus_js_snippet({:name => "Anouar", :lastname => 'ADLANI'})
33
+ menu.should =~/var disqus_name = 'Anouar';/
34
+ menu.should =~/var disqus_lastname = 'ADLANI';/
35
+ end
36
+ end
37
+
38
+ describe ".disqus_nojs_snippet" do
39
+ it "returns the default noscript snippet" do
40
+ subject.disqus_nojs_snippet.should eq "<noscript>Please enable JavaScript to view the <a href=\"http://disqus.com/?ref_noscript\">comments powered by Disqus.</a></noscript>"
41
+ end
42
+
43
+ it "render the specified message" do
44
+ subject.disqus_nojs_snippet("No message").should eq "<noscript>No message</noscript>"
45
+ end
46
+ end
47
+ end