nanoc-toolbox 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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