happy-nav 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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/lib/happy-nav/navigation_presenter.rb +137 -0
- data/lib/happy-nav/railtie.rb +10 -0
- data/lib/happy-nav.rb +23 -0
- data/spec/navigation_helper_spec.rb +103 -0
- data/spec/navigation_presenter_spec.rb +261 -0
- data/spec/spec_helper.rb +16 -0
- metadata +76 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Andy Pearson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= happy-nav
|
2
|
+
|
3
|
+
Happy Nav is the easy (and cheerful) way to create structured HTML for you site navigation.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Andy Pearson. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = "happy-nav"
|
9
|
+
gem.summary = %Q{Happy Nav is the easy (and cheerful) way to create structured HTML for your site navigation.}
|
10
|
+
gem.description = %Q{Happy Nav is the easy (and cheerful) way to create structured HTML for your site navigation.}
|
11
|
+
gem.email = "andy@andy-pearson.com"
|
12
|
+
gem.homepage = "http://github.com/andypearson/happy-nav"
|
13
|
+
gem.authors = ["Andy Pearson"]
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Test the happ-nav plugin.'
|
21
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
22
|
+
t.pattern = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'rcov/rcovtask'
|
27
|
+
Rcov::RcovTask.new do |test|
|
28
|
+
test.libs << 'test'
|
29
|
+
test.pattern = 'test/**/test_*.rb'
|
30
|
+
test.verbose = true
|
31
|
+
end
|
32
|
+
rescue LoadError
|
33
|
+
task :rcov do
|
34
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "happy-nav #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,137 @@
|
|
1
|
+
class NavigationPresenter
|
2
|
+
|
3
|
+
include ActionView::Helpers::TagHelper
|
4
|
+
|
5
|
+
attr_accessor :items, :options
|
6
|
+
|
7
|
+
def initialize(items = [], options = {}, current_items = [])
|
8
|
+
@items = items
|
9
|
+
@options = options
|
10
|
+
@current_items = current_items
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_html
|
14
|
+
unless @items.empty?
|
15
|
+
wrap do
|
16
|
+
h.content_tag :ul, :class => @options[:class] do i=0
|
17
|
+
content = ''
|
18
|
+
@items.each do |item| i=i+1
|
19
|
+
content += h.content_tag :li, :class => classes(i) do
|
20
|
+
item_link(item) + nested_navigation(item).to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
content.html_safe
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
27
|
+
''
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def nested_navigation(item)
|
32
|
+
unless @options[:flat]
|
33
|
+
item = format_item(item)
|
34
|
+
if item[:items] && current_item?(item[:permalink])
|
35
|
+
options = {
|
36
|
+
:level => next_level,
|
37
|
+
:class => 'nav-sub-' + next_level.to_s,
|
38
|
+
:base_url => item[:url],
|
39
|
+
:wrap => false
|
40
|
+
}
|
41
|
+
NavigationPresenter.new(item[:items], options, @current_items[1..-1]).to_html
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def item_link(item, options = {})
|
47
|
+
|
48
|
+
item = format_item(item, options)
|
49
|
+
content = item[:text]
|
50
|
+
|
51
|
+
if item[:summary]
|
52
|
+
item[:title] += ': '+item[:summary]
|
53
|
+
content = h.content_tag(:strong, content) + ' ' + content_tag(:em, item[:summary])
|
54
|
+
end
|
55
|
+
|
56
|
+
if item[:id] || @options[:id]
|
57
|
+
item[:id] = item[:permalink] if @options[:id] === true || item[:id] === true
|
58
|
+
item[:id] = "nav_#{item[:id]}"
|
59
|
+
end
|
60
|
+
|
61
|
+
h.link_to content, item[:url], {
|
62
|
+
:id => item[:id],
|
63
|
+
:class => (current_item?(item[:permalink]) ? 'current' : nil),
|
64
|
+
:title => item[:title],
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def item_url(text)
|
69
|
+
if (text == 'Home')
|
70
|
+
admin? ? '/admin' : '/'
|
71
|
+
else
|
72
|
+
base_url + '/' + text.parameterize('-')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def base_url
|
77
|
+
if options[:base_url]
|
78
|
+
options[:base_url]
|
79
|
+
else
|
80
|
+
admin? ? '/admin' : ''
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def current_item(current_item)
|
85
|
+
@current_items << current_item
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def h
|
91
|
+
ActionController::Base.helpers
|
92
|
+
end
|
93
|
+
|
94
|
+
def classes(i)
|
95
|
+
classes = []
|
96
|
+
classes << 'first' if i==1
|
97
|
+
classes << 'last' if i==@items.length
|
98
|
+
!classes.empty? ? classes.join(' ') : nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def current_item?(permalink)
|
102
|
+
!@current_items.empty? && permalink == @current_items.first.parameterize('-')
|
103
|
+
end
|
104
|
+
|
105
|
+
def admin?
|
106
|
+
@options[:admin]
|
107
|
+
end
|
108
|
+
|
109
|
+
def format_item(item, options = {})
|
110
|
+
item = { :text => item } if item.kind_of? String
|
111
|
+
item = item.merge(options)
|
112
|
+
item[:id] = nil if !item[:id]
|
113
|
+
item[:url] = item_url(item[:text]) if !item[:url]
|
114
|
+
item[:title] = item[:text] if !item[:title]
|
115
|
+
item[:permalink] = item[:text].parameterize('-') if !item[:permalink]
|
116
|
+
item
|
117
|
+
end
|
118
|
+
|
119
|
+
def current_level
|
120
|
+
@options[:level] ||= 0
|
121
|
+
end
|
122
|
+
|
123
|
+
def next_level
|
124
|
+
current_level + 1
|
125
|
+
end
|
126
|
+
|
127
|
+
def wrap(&block)
|
128
|
+
if @options[:wrap] === false
|
129
|
+
yield
|
130
|
+
else
|
131
|
+
h.content_tag :div, { :class => 'nav' } do
|
132
|
+
yield
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
data/lib/happy-nav.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[happy-nav navigation_presenter])
|
2
|
+
require File.join(File.dirname(__FILE__), *%w[happy-nav railtie]) if defined?(::Rails::Railtie)
|
3
|
+
|
4
|
+
module HappyNav
|
5
|
+
|
6
|
+
def navigation(items = [], options = {})
|
7
|
+
unless items.empty?
|
8
|
+
@navigation_presenter = NavigationPresenter.new(items, options)
|
9
|
+
if @current_pages
|
10
|
+
@current_pages.each { |page| @navigation_presenter.current_item(page) }
|
11
|
+
end
|
12
|
+
@navigation = @navigation_presenter.to_html
|
13
|
+
end
|
14
|
+
@navigation ||= ''
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_page(page = nil)
|
18
|
+
@current_pages ||= []
|
19
|
+
@current_pages << page if page
|
20
|
+
@current_pages.first
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe 'Happy Nav!' do
|
4
|
+
|
5
|
+
include SpecHelperMethods
|
6
|
+
|
7
|
+
before do
|
8
|
+
@view = ActionView::Base.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'after loading the plugin' do
|
12
|
+
|
13
|
+
it "should be mixed into ActionView::Base" do
|
14
|
+
ActionView::Base.included_modules.include?(HappyNav).should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should respond to happy_title helper' do
|
18
|
+
@view.should respond_to(:navigation)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should respond to title helper' do
|
22
|
+
@view.should respond_to(:current_page)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#navigation' do
|
28
|
+
|
29
|
+
before do
|
30
|
+
@items = ['Home', 'About', 'Our Services', 'Contact']
|
31
|
+
@output = <<-eos
|
32
|
+
<div class="nav">
|
33
|
+
<ul>
|
34
|
+
<li class="first"><a href="/" title="Home">Home</a></li>
|
35
|
+
<li><a href="/about" title="About">About</a></li>
|
36
|
+
<li><a href="/our-services" title="Our Services">Our Services</a></li>
|
37
|
+
<li class="last"><a href="/contact" title="Contact">Contact</a></li>
|
38
|
+
</ul>
|
39
|
+
</div>
|
40
|
+
eos
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should always return a string' do
|
44
|
+
@view.navigation.should be_a(String)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return blank if there are no items' do
|
48
|
+
@view.navigation.should == ''
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should return the formatted navigation if there are items' do
|
52
|
+
@view.navigation(@items).should == clean_string(@output)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return the generated navigation multiple times' do
|
56
|
+
output = ''
|
57
|
+
output += @view.navigation(@items)
|
58
|
+
output += @view.navigation
|
59
|
+
output += @view.navigation
|
60
|
+
|
61
|
+
output.should == clean_string(@output+@output+@output)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should regenerate the navigation if new items are passed' do
|
65
|
+
output = <<-eos
|
66
|
+
<div class="nav">
|
67
|
+
<ul>
|
68
|
+
<li class="first last"><a href="/about" title="About">About</a></li>
|
69
|
+
</ul>
|
70
|
+
</div>
|
71
|
+
eos
|
72
|
+
@view.navigation(@items).should == clean_string(@output)
|
73
|
+
@view.navigation(['About']).should == clean_string(output)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#current_page' do
|
79
|
+
|
80
|
+
it 'should be nil by default' do
|
81
|
+
@view.current_page.should == nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should mark the current page' do
|
85
|
+
@view.current_page('Home')
|
86
|
+
@view.current_page.should == 'Home'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should render a navigation with the current page' do
|
90
|
+
output = <<-eos
|
91
|
+
<div class="nav">
|
92
|
+
<ul>
|
93
|
+
<li class="first last"><a href="/about" class="current" title="About">About</a></li>
|
94
|
+
</ul>
|
95
|
+
</div>
|
96
|
+
eos
|
97
|
+
@view.current_page('About')
|
98
|
+
@view.navigation(['About']).should == clean_string(output)
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe NavigationPresenter do
|
4
|
+
|
5
|
+
include SpecHelperMethods
|
6
|
+
|
7
|
+
before do
|
8
|
+
@items = ['Home', 'About', 'Our Services', 'Contact']
|
9
|
+
@output = <<-eos
|
10
|
+
<div class="nav">
|
11
|
+
<ul>
|
12
|
+
<li class="first"><a href="/" title="Home">Home</a></li>
|
13
|
+
<li><a href="/about" title="About">About</a></li>
|
14
|
+
<li><a href="/our-services" title="Our Services">Our Services</a></li>
|
15
|
+
<li class="last"><a href="/contact" title="Contact">Contact</a></li>
|
16
|
+
</ul>
|
17
|
+
</div>
|
18
|
+
eos
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#to_html' do
|
22
|
+
|
23
|
+
it 'should return an empty string with no items' do
|
24
|
+
NavigationPresenter.new.to_html.should == ''
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should always return a string' do
|
28
|
+
NavigationPresenter.new.to_html.should be_a(String)
|
29
|
+
NavigationPresenter.new(@items).to_html.should be_a(String)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return a formatted navigation if there are items' do
|
33
|
+
NavigationPresenter.new(@items).to_html.should == clean_string(@output)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should correctly format a single item' do
|
37
|
+
output = <<-eos
|
38
|
+
<div class="nav">
|
39
|
+
<ul>
|
40
|
+
<li class="first last"><a href="/about" title="About">About</a></li>
|
41
|
+
</ul>
|
42
|
+
</div>
|
43
|
+
eos
|
44
|
+
|
45
|
+
NavigationPresenter.new(['About']).to_html.should == clean_string(output)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should add an id to all links' do
|
49
|
+
output = <<-eos
|
50
|
+
<div class="nav">
|
51
|
+
<ul>
|
52
|
+
<li class="first"><a href="/" id="nav_home" title="Home">Home</a></li>
|
53
|
+
<li class="last"><a href="/contact" id="nav_contact" title="Contact">Contact</a></li>
|
54
|
+
</ul>
|
55
|
+
</div>
|
56
|
+
eos
|
57
|
+
|
58
|
+
NavigationPresenter.new(['Home', 'Contact'], :id => true).to_html.should == clean_string(output)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should add a class to the unordered list' do
|
62
|
+
output = <<-eos
|
63
|
+
<div class="nav">
|
64
|
+
<ul class="ul-class">
|
65
|
+
<li class="first last"><a href="/about" title="About">About</a></li>
|
66
|
+
</ul>
|
67
|
+
</div>
|
68
|
+
eos
|
69
|
+
|
70
|
+
NavigationPresenter.new(['About'], :class => 'ul-class').to_html.should == clean_string(output)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not wrap the unordered list in a div' do
|
74
|
+
output = <<-eos
|
75
|
+
<ul>
|
76
|
+
<li class="first last"><a href="/about" title="About">About</a></li>
|
77
|
+
</ul>
|
78
|
+
eos
|
79
|
+
|
80
|
+
NavigationPresenter.new(['About'], :wrap => false).to_html.should == clean_string(output)
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'with nested items' do
|
84
|
+
|
85
|
+
before do
|
86
|
+
@items = [
|
87
|
+
'Home',
|
88
|
+
{
|
89
|
+
:text => 'About Us',
|
90
|
+
:items => [
|
91
|
+
{
|
92
|
+
:text => 'Team',
|
93
|
+
:items => [
|
94
|
+
'Guybrush Threepwood',
|
95
|
+
'Ghost Pirate LeChuck'
|
96
|
+
]
|
97
|
+
}
|
98
|
+
]
|
99
|
+
},
|
100
|
+
{
|
101
|
+
:text => 'Our Services',
|
102
|
+
:items => ['Swash buckling']
|
103
|
+
},
|
104
|
+
'Contact'
|
105
|
+
]
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should render nested navigation links' do
|
109
|
+
output = <<-eos
|
110
|
+
<div class="nav">
|
111
|
+
<ul>
|
112
|
+
<li class="first"><a href="/" title="Home">Home</a></li>
|
113
|
+
<li>
|
114
|
+
<a href="/about-us" class="current" title="About Us">About Us</a>
|
115
|
+
<ul class="nav-sub-1">
|
116
|
+
<li class="first last">
|
117
|
+
<a href="/about-us/team" class="current" title="Team">Team</a>
|
118
|
+
<ul class="nav-sub-2">
|
119
|
+
<li class="first"><a href="/about-us/team/guybrush-threepwood" class="current" title="Guybrush Threepwood">Guybrush Threepwood</a></li>
|
120
|
+
<li class="last"><a href="/about-us/team/ghost-pirate-lechuck" title="Ghost Pirate LeChuck">Ghost Pirate LeChuck</a></li>
|
121
|
+
</ul>
|
122
|
+
</li>
|
123
|
+
</ul>
|
124
|
+
</li>
|
125
|
+
<li><a href="/our-services" title="Our Services">Our Services</a></li>
|
126
|
+
<li class="last"><a href="/contact" title="Contact">Contact</a></li>
|
127
|
+
</ul>
|
128
|
+
</div>
|
129
|
+
eos
|
130
|
+
navigation_presenter = NavigationPresenter.new(@items)
|
131
|
+
navigation_presenter.current_item('About Us')
|
132
|
+
navigation_presenter.current_item('Team')
|
133
|
+
navigation_presenter.current_item('Guybrush Threepwood')
|
134
|
+
navigation_presenter.to_html.should == clean_string(output)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should render a flat list if flat is passed as an option' do
|
138
|
+
output = <<-eos
|
139
|
+
<div class="nav">
|
140
|
+
<ul>
|
141
|
+
<li class="first"><a href="/" title="Home">Home</a></li>
|
142
|
+
<li><a href="/about-us" class="current" title="About Us">About Us</a></li>
|
143
|
+
<li><a href="/our-services" title="Our Services">Our Services</a></li>
|
144
|
+
<li class="last"><a href="/contact" title="Contact">Contact</a></li>
|
145
|
+
</ul>
|
146
|
+
</div>
|
147
|
+
eos
|
148
|
+
navigation_presenter = NavigationPresenter.new(@items, :flat => true)
|
149
|
+
navigation_presenter.current_item('About Us')
|
150
|
+
navigation_presenter.current_item('Team')
|
151
|
+
navigation_presenter.current_item('Guybrush Threepwood')
|
152
|
+
navigation_presenter.to_html.should == clean_string(output)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#item_link' do
|
160
|
+
|
161
|
+
before do
|
162
|
+
@navigation = NavigationPresenter.new
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should always return a string' do
|
166
|
+
@navigation.item_link('Home').should be_a(String)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should return a link with a title' do
|
170
|
+
@navigation.item_link('About').should == '<a href="/about" title="About">About</a>'
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should return a link to root if the page is "Home"' do
|
174
|
+
@navigation.item_link('Home').should == '<a href="/" title="Home">Home</a>'
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should allow customisation using a Hash' do
|
178
|
+
@navigation.item_link({
|
179
|
+
:text => 'Custom',
|
180
|
+
:url => '/linky',
|
181
|
+
:title => 'Custom Title'
|
182
|
+
}).should == '<a href="/linky" title="Custom Title">Custom</a>'
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should allow for a summary' do
|
186
|
+
@navigation.item_link({ :text => 'Summary', :summary => 'A quick summary...' }).should == '<a href="/summary" title="Summary: A quick summary..."><strong>Summary</strong> <em>A quick summary...</em></a>'
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should mark "About" as the current page' do
|
190
|
+
@navigation.current_item('About')
|
191
|
+
@navigation.item_link('About').should == '<a href="/about" class="current" title="About">About</a>'
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should allow for an id' do
|
195
|
+
@navigation.item_link({ :text => 'Linky', :id => true }).should == '<a href="/linky" id="nav_linky" title="Linky">Linky</a>'
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should allow for a custom id' do
|
199
|
+
@navigation.item_link({ :text => 'Linky', :id => 'custom' }).should == '<a href="/linky" id="nav_custom" title="Linky">Linky</a>'
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#item_url' do
|
205
|
+
|
206
|
+
before do
|
207
|
+
@navigation = NavigationPresenter.new
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should always return a string' do
|
211
|
+
@navigation.item_url('Home').should be_a(String)
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should return the path to root if the page is "Home"' do
|
215
|
+
@navigation.item_url('Home').should == '/'
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should return a path' do
|
219
|
+
@navigation.item_url('About').should == '/about'
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'should path to the admin homepage' do
|
223
|
+
@navigation.stub!(:admin?).and_return(true)
|
224
|
+
@navigation.item_url('Home').should == '/admin'
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should path to the admin namespace' do
|
228
|
+
@navigation.stub!(:admin?).and_return(true)
|
229
|
+
@navigation.item_url('About').should == '/admin/about'
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'should use the base_url option' do
|
233
|
+
@navigation.stub!(:options).and_return({ :base_url => '/example/base' })
|
234
|
+
@navigation.item_url('About').should == '/example/base/about'
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#admin?' do
|
240
|
+
|
241
|
+
before do
|
242
|
+
@navigation = NavigationPresenter.new
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should return false if the admin option is not set' do
|
246
|
+
@navigation.send(:admin?).should be_false
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should return false if the admin option is false' do
|
250
|
+
@navigation.options[:admin] = false
|
251
|
+
@navigation.send(:admin?).should be_false
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should return true if the admin option is true' do
|
255
|
+
@navigation.options[:admin] = true
|
256
|
+
@navigation.send(:admin?).should be_true
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'action_pack'
|
3
|
+
require 'action_view'
|
4
|
+
require 'action_controller'
|
5
|
+
|
6
|
+
require File.join(File.dirname(__FILE__), "../lib/happy-nav")
|
7
|
+
|
8
|
+
ActionView::Base.class_eval do
|
9
|
+
include HappyNav
|
10
|
+
end
|
11
|
+
|
12
|
+
module SpecHelperMethods
|
13
|
+
def clean_string(s)
|
14
|
+
s.gsub(/^\s+/, "").gsub(/\n/, "")
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: happy-nav
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Andy Pearson
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-26 00:00:00 +00:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Happy Nav is the easy (and cheerful) way to create structured HTML for your site navigation.
|
22
|
+
email: andy@andy-pearson.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- .document
|
32
|
+
- .gitignore
|
33
|
+
- LICENSE
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- lib/happy-nav.rb
|
38
|
+
- lib/happy-nav/navigation_presenter.rb
|
39
|
+
- lib/happy-nav/railtie.rb
|
40
|
+
- spec/navigation_helper_spec.rb
|
41
|
+
- spec/navigation_presenter_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/andypearson/happy-nav
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --charset=UTF-8
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.6
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Happy Nav is the easy (and cheerful) way to create structured HTML for your site navigation.
|
73
|
+
test_files:
|
74
|
+
- spec/navigation_helper_spec.rb
|
75
|
+
- spec/navigation_presenter_spec.rb
|
76
|
+
- spec/spec_helper.rb
|