tabnav 1.0.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 ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ LICENSE
2
+
3
+ The MIT License
4
+
5
+ Copyright (c) 2010 Alex Tomlins and Unboxed Consulting
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ "Software"), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,136 @@
1
+ = Tabnav
2
+
3
+ Tabnav is a helper for generating navigation bars. It allows you to simply specify highlighting rules for each tab.
4
+
5
+ * Homepage: http://github.com/unboxed/tabnav
6
+ * Issues: http://github.com/unboxed/tabnav/issues
7
+
8
+ == Some Examples
9
+
10
+ === Simple Example
11
+
12
+ In your view:
13
+
14
+ <%
15
+ render_tabnav do |n|
16
+ n.add_tab do |t|
17
+ t.named "Home"
18
+ t.links_to root_path
19
+ t.highlights_on :controller => :home, :action => :index
20
+ end
21
+ n.add_tab do |t|
22
+ t.named "Froobles"
23
+ t.links_to froobles_path
24
+ t.highlights_on :controller => :froobles
25
+ end
26
+ end
27
+ %>
28
+
29
+ On home/index will output:
30
+
31
+ <ul>
32
+ <li class="active"><a href="/">Home</a></li>
33
+ <li><a href="/froobles">Froobles</a></li>
34
+ </ul>
35
+
36
+ On any action in FrooblesController will output:
37
+
38
+ <ul>
39
+ <li><a href="/">Home</a></li>
40
+ <li class="active"><a href="/froobles">Froobles</a></li>
41
+ </ul>
42
+
43
+ See the highlights_on method of Tabnav::Tab for full details of the highlighting logic.
44
+
45
+ === Options for controlling markup
46
+
47
+ View:
48
+
49
+ <%
50
+ render_tabnav :id => "main_navigation", :class => "clearfix" do |n|
51
+ n.add_tab :class => "home_tab" do |t|
52
+ t.named "Home"
53
+ t.links_to root_path
54
+ t.highlights_on :controller => :home, :action => :index
55
+ end
56
+ n.add_tab :class => "heading" do |t|
57
+ t.named "Froobles Heading"
58
+ t.highlights_on :controller => :froobles
59
+ end
60
+ n.add_tab do |t|
61
+ t.named "Froobles"
62
+ t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
63
+ t.highlights_on :controller => :froobles, :action => :index
64
+ end
65
+ end
66
+ %>
67
+
68
+ On froobles/index will output:
69
+
70
+ <ul id="main_navigation" class="clearfix">
71
+ <li class="home_tab"><a href="/">Home</a></li>
72
+ <li class="heading active"><span>Froobles Heading</span></li>
73
+ <li class="active"><a href="/froobles" target="_blank" rel="http://foo.bar/">Froobles</a></li>
74
+ </ul>
75
+
76
+ === Custom tab partial
77
+
78
+ It is also possible to specify a partial to be used to generate the tab contents. e.g.:
79
+
80
+ View:
81
+
82
+ <%
83
+ render_tabnav :html => {:id => "main_navigation", :class => "clearfix"} do |n|
84
+ n.tab_partial "/shared/my_custom_tab"
85
+ n.add_tab :html => {:class => "home_tab"} do |t|
86
+ t.named "Home"
87
+ t.links_to root_path
88
+ t.highlights_on :controller => :home, :action => :index
89
+ end
90
+ n.add_tab :html => {:class => "heading"} do |t|
91
+ t.named "Froobles Heading"
92
+ t.highlights_on :controller => :froobles
93
+ end
94
+ n.add_tab do |t|
95
+ t.named "Froobles"
96
+ t.links_to froobles_path, :target => "_blank", :rel => "http://foo.bar/"
97
+ t.highlights_on :controller => :froobles, :action => :index
98
+ end
99
+ end
100
+ %>
101
+
102
+ In the partial, +tab+ will be the Tab instance to be rendered.
103
+
104
+ in /app/views/shared/_my_custom_tab.html.erb:
105
+
106
+ <div class="my_custom_class">
107
+ <%- if tab.has_link? -%>
108
+ <%= link_to tab.name, tab.url %>
109
+ <%- else -%>
110
+ <span><%= tab.name %></span>
111
+ <%- end -%>
112
+ </div>
113
+
114
+ On froobles/index the output will be:
115
+
116
+ <ul id="main_navigation" class="clearfix">
117
+ <li class="home_tab"><div class="my_custom_class"><a href="/">Home</a></div></li>
118
+ <li class="heading active"><div class="my_custom_class"><span>Froobles Heading</span></div></li>
119
+ <li class="active"><div class="my_custom_class"><a href="/froobles">Froobles</a></div></li>
120
+ </ul>
121
+
122
+ -----
123
+
124
+ == Note on Patches/Pull Requests
125
+
126
+ * Fork the project.
127
+ * Make your feature addition or bug fix.
128
+ * Add tests for it. This is important so I don't break it in a
129
+ future version unintentionally.
130
+ * Commit, do not mess with Rakefile, gemspec, version, or history.
131
+ (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)
132
+ * Send me a pull request. Bonus points for topic branches.
133
+
134
+ == Copyright
135
+
136
+ Copyright (c) 2010 Unboxed. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "tabnav"
8
+ gem.summary = %Q{Rails helper for generating navbars}
9
+ gem.description = %Q{Rails helper for generating navbars in a declarative manner}
10
+ gem.email = "github@unboxedconsulting.com"
11
+ gem.homepage = "http://github.com/unboxed/tabnav"
12
+ gem.authors = ["Unboxed"]
13
+ gem.add_dependency "actionpack", ">= 2.3.2"
14
+ gem.add_development_dependency "rspec", ">= 1.2.9"
15
+ gem.add_development_dependency "rspec-rails", ">= 1.2.9"
16
+ gem.files.exclude "*.gemspec", '.gitignore', 'doc/*'
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
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 = "tabnav #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,17 @@
1
+ module Tabnav
2
+ module Helper
3
+
4
+ # This is the main method to be used in your views.
5
+ # It creates and yields a new instance of Navbar.
6
+ #
7
+ # +options+ is an optional hash of options that are passed to the navbar, and
8
+ # and used to create the +ul+.
9
+ #
10
+ # Finally, this renders the navbar, and concats the result into the view.
11
+ def render_tabnav(options = {})
12
+ n = Navbar.new(self, params, options)
13
+ yield(n)
14
+ concat( n.render )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ module Tabnav
2
+ class Navbar
3
+ def initialize(template, params, options = {}) # :nodoc:
4
+ @template = template
5
+ @params = params
6
+ @html_options = options
7
+ @tabs = []
8
+ end
9
+
10
+ # Optionally specifies a partial to be used to render the tab content.
11
+ attr_writer :tab_content_partial
12
+
13
+ # Creates a Tab and adds it to the navbar.
14
+ #
15
+ # +options+ is an optional hash of options which will be used to create the +li+ for the tab.
16
+ #
17
+ # yields the created Tab
18
+ def add_tab(options = {})
19
+ options[:tab_content_partial] = @tab_content_partial if @tab_content_partial
20
+ t = Tab.new(@template, @params, options)
21
+ yield t
22
+ @tabs << t
23
+ end
24
+
25
+ def render # :nodoc:
26
+ return '' if @tabs.empty?
27
+ @template.content_tag :ul, @html_options do
28
+ contents = ''
29
+ @tabs.each do |tab|
30
+ contents += tab.render
31
+ end
32
+ contents
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/tabnav/tab.rb ADDED
@@ -0,0 +1,69 @@
1
+ module Tabnav
2
+ class Tab
3
+
4
+ def initialize(template, params, html_options = {}) # :nodoc:
5
+ @html_options = html_options
6
+ @params = params
7
+ @template = template
8
+ @name = ''
9
+ @active = false
10
+ end
11
+
12
+ # The name of this tab
13
+ attr_accessor :name
14
+
15
+ # The link destination
16
+ attr_accessor :link_url
17
+
18
+ # The link options (if any)
19
+ attr_accessor :link_options
20
+
21
+ # Sets the name of this tab. This will be used as the contents of the link or span
22
+ def named(text)
23
+ @name = text
24
+ end
25
+
26
+ # Sets the link destination.
27
+ #
28
+ # +link_options+ is an option hash of options that will be
29
+ # passed through to the link_to call.
30
+ def links_to(url, link_options = {})
31
+ @link_url = url
32
+ @link_options = link_options
33
+ end
34
+
35
+ # Adds a highlight condition to this tab. +rule+ can be one of the following:
36
+ #
37
+ # * A Hash: The tab will be highlighted if all the values in the given hash match the
38
+ # params hash (strings and symbols are treated as equivelent).
39
+ # * A Proc: The proc will be called, and the tab will be highlighted if it returns true.
40
+ #
41
+ # If multiple highlight conditions are given, the tab will be highlighted if any of them match.
42
+ def highlights_on(rule)
43
+ if rule.is_a?(Hash)
44
+ @active |= rule.with_indifferent_access.all? {|k, v| @params[k] == v.to_s}
45
+ elsif rule.is_a?(Proc)
46
+ @active |= rule.call
47
+ end
48
+ end
49
+
50
+ # Returns +true+ of this tab is highlighted.
51
+ def active?
52
+ @active
53
+ end
54
+
55
+ def render # :nodoc:
56
+ @html_options[:class] = "#{@html_options[:class]} active".strip if self.active?
57
+ partial = @html_options.delete(:tab_content_partial)
58
+ @template.content_tag(:li, @html_options) do
59
+ if partial
60
+ @template.render :partial => partial, :locals => {:tab => self}
61
+ elsif @link_url
62
+ @template.link_to @name, @link_url, @link_options
63
+ else
64
+ @template.content_tag :span, @name
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
data/lib/tabnav.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ module Tabnav
3
+ end
4
+
5
+ require 'tabnav/tab'
6
+ require 'tabnav/navbar'
7
+ require 'tabnav/helper'
8
+ ActionController::Base.helper Tabnav::Helper
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'action_controller'
5
+ require 'tabnav'
6
+
7
+ require 'spec'
8
+ require 'spec/autorun'
9
+
10
+ # The parts of rspec-rails necessary to use helper example groups
11
+ class ApplicationController < ActionController::Base
12
+ end
13
+ require 'active_support/test_case'
14
+ require 'spec/test/unit'
15
+ require 'spec/rails/example'
16
+ require 'spec/rails/interop/testcase'
17
+
18
+ Spec::Runner.configure do |config|
19
+
20
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tabnav::Helper, :type => :helper do
4
+
5
+ describe "render_tabnav" do
6
+ before :each do
7
+ # helper is an instance of a subclass of ActionView::Base
8
+ @template = helper
9
+ @navbar = Tabnav::Navbar.new(@template, {})
10
+ Tabnav::Navbar.stub!(:new).and_return(@navbar)
11
+ helper.output_buffer = ''
12
+ end
13
+ it "should create a new navbar with the template and params and yield it to the block" do
14
+ params[:foo] = "bar"
15
+ Tabnav::Navbar.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(@navbar)
16
+ helper.render_tabnav do |n|
17
+ n.should == @navbar
18
+ end
19
+ end
20
+
21
+ it "should create a new navbar with any passed options" do
22
+ Tabnav::Navbar.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(@navbar)
23
+ helper.render_tabnav :class => "my_class", :id => "my_id" do |n|
24
+ n.should == @navbar
25
+ end
26
+ end
27
+
28
+ it "should concat the results of calling render on the navbar" do
29
+ @navbar.should_receive(:render).and_return("Some Navbar Markup")
30
+ helper.render_tabnav {|n| }
31
+ helper.output_buffer.should == "Some Navbar Markup"
32
+ end
33
+ end
34
+
35
+ it "should be included in ActionController::Base's helpers" do
36
+ ActionController::Base.helpers.should be_a(Tabnav::Helper)
37
+ end
38
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tabnav::Helper, :type => :helper do
4
+ before :each do
5
+ helper.output_buffer = ''
6
+ end
7
+
8
+ describe "basic flat navbar" do
9
+ it "should output a basic 2 tab navbar" do
10
+ helper.render_tabnav do |n|
11
+ n.add_tab do |t|
12
+ t.named "Home"
13
+ t.links_to "/"
14
+ end
15
+ n.add_tab do |t|
16
+ t.named "Froobles"
17
+ t.links_to "/froobles"
18
+ end
19
+ end
20
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li><a href="/froobles">Froobles</a></li></ul>'
21
+ end
22
+
23
+ it "should output a basic 2 tab navbar with extra markup options" do
24
+ helper.render_tabnav :id => "main_navigation", :class => "clearfix" do |n|
25
+ n.add_tab :class => "home_tab" do |t|
26
+ t.named "Home"
27
+ t.links_to "/"
28
+ end
29
+ n.add_tab :class => "heading" do |t|
30
+ t.named "Froobles Heading"
31
+ end
32
+ n.add_tab do |t|
33
+ t.named "Froobles"
34
+ t.links_to "/froobles", :target => "_blank", :rel => "http://foo.bar/"
35
+ end
36
+ end
37
+ helper.output_buffer.should == '<ul class="clearfix" id="main_navigation"><li class="home_tab"><a href="/">Home</a></li>' +
38
+ '<li class="heading"><span>Froobles Heading</span></li>' +
39
+ '<li><a href="/froobles" rel="http://foo.bar/" target="_blank">Froobles</a></li></ul>'
40
+ end
41
+ end
42
+
43
+ describe "highlighting logic" do
44
+ context "params based rules" do
45
+ it "should highlight the tab if the rules match the params hash" do
46
+ params[:controller] = 'home'
47
+ params[:action] = 'index'
48
+ params[:foo] = 'bar'
49
+ helper.render_tabnav :id => "main_navigation", :class => "clearfix" do |n|
50
+ n.add_tab :class => "home_tab" do |t|
51
+ t.named "Home"
52
+ t.links_to '/'
53
+ t.highlights_on :controller => :home, :action => :index
54
+ end
55
+ n.add_tab :class => "heading" do |t|
56
+ t.named "Froobles Heading"
57
+ t.highlights_on :controller => :froobles
58
+ end
59
+ n.add_tab do |t|
60
+ t.named "Froobles"
61
+ t.links_to '/froobles', :target => "_blank", :rel => "http://foo.bar/"
62
+ t.highlights_on :controller => :froobles, :action => :index
63
+ end
64
+ end
65
+ helper.output_buffer.should == '<ul class="clearfix" id="main_navigation"><li class="home_tab active"><a href="/">Home</a></li>' +
66
+ '<li class="heading"><span>Froobles Heading</span></li>' +
67
+ '<li><a href="/froobles" rel="http://foo.bar/" target="_blank">Froobles</a></li></ul>'
68
+ end
69
+
70
+ it "should allow multiple tabs to be active at once" do
71
+ params[:controller] = 'froobles'
72
+ params[:action] = 'index'
73
+ params[:foo] = 'bar'
74
+ helper.render_tabnav do |n|
75
+ n.add_tab :class => "home_tab" do |t|
76
+ t.named "Home"
77
+ t.links_to '/'
78
+ t.highlights_on :controller => :home, :action => :index
79
+ end
80
+ n.add_tab :class => "heading" do |t|
81
+ t.named "Froobles Heading"
82
+ t.highlights_on :controller => :froobles
83
+ end
84
+ n.add_tab do |t|
85
+ t.named "Froobles"
86
+ t.links_to '/froobles', :target => "_blank", :rel => "http://foo.bar/"
87
+ t.highlights_on :controller => :froobles, :action => :index
88
+ end
89
+ end
90
+ helper.output_buffer.should == '<ul><li class="home_tab"><a href="/">Home</a></li>' +
91
+ '<li class="heading active"><span>Froobles Heading</span></li>' +
92
+ '<li class="active"><a href="/froobles" rel="http://foo.bar/" target="_blank">Froobles</a></li></ul>'
93
+ end
94
+
95
+ it "should highlight tabs where any of the highlighting rules match" do
96
+ params[:controller] = 'home'
97
+ params[:action] = 'froobles'
98
+ params[:foo] = 'bar'
99
+ helper.render_tabnav do |n|
100
+ n.add_tab do |t|
101
+ t.named "Home"
102
+ t.links_to "/"
103
+ t.highlights_on :controller => :home, :action => :index
104
+ end
105
+ n.add_tab do |t|
106
+ t.named "Froobles"
107
+ t.links_to "/froobles"
108
+ t.highlights_on :controller => :home, :action => :froobles
109
+ t.highlights_on :controller => :froobles
110
+ end
111
+ end
112
+ helper.output_buffer.should == '<ul><li><a href="/">Home</a></li><li class="active"><a href="/froobles">Froobles</a></li></ul>'
113
+ end
114
+ end
115
+
116
+ context "proc based rules" do
117
+ it "should highlight the tab if the give proc evaluates to true" do
118
+ helper.render_tabnav do |n|
119
+ n.add_tab do |t|
120
+ t.named "Home"
121
+ t.links_to "/"
122
+ t.highlights_on Proc.new { true }
123
+ end
124
+ n.add_tab do |t|
125
+ t.named "Froobles"
126
+ t.links_to "/froobles"
127
+ t.highlights_on Proc.new { false }
128
+ end
129
+ end
130
+ helper.output_buffer.should == '<ul><li class="active"><a href="/">Home</a></li><li><a href="/froobles">Froobles</a></li></ul>'
131
+ end
132
+ end
133
+
134
+ it "should allow a mixture of rule types" do
135
+ params[:controller] = 'home'
136
+ params[:action] = 'index'
137
+ params[:foo] = 'bar'
138
+ helper.render_tabnav do |n|
139
+ n.add_tab :class => "home_tab" do |t|
140
+ t.named "Home"
141
+ t.links_to '/'
142
+ t.highlights_on :controller => :home, :action => :index
143
+ end
144
+ n.add_tab :class => "heading" do |t|
145
+ t.named "Froobles Heading"
146
+ t.highlights_on :controller => :froobles
147
+ t.highlights_on Proc.new { true }
148
+ end
149
+ n.add_tab do |t|
150
+ t.named "Froobles"
151
+ t.links_to '/froobles', :target => "_blank", :rel => "http://foo.bar/"
152
+ t.highlights_on :controller => :froobles, :action => :index
153
+ end
154
+ end
155
+ helper.output_buffer.should == '<ul><li class="home_tab active"><a href="/">Home</a></li>' +
156
+ '<li class="heading active"><span>Froobles Heading</span></li>' +
157
+ '<li><a href="/froobles" rel="http://foo.bar/" target="_blank">Froobles</a></li></ul>'
158
+ end
159
+ end
160
+
161
+ describe "custom tab partials" do
162
+ it "should allow sppecifying a custom partial for rendering the tabs" do
163
+ helper.should_receive(:render).twice do |args|
164
+ args[:partial].should == '/tab_content'
165
+ args[:locals][:tab].should be_a(Tabnav::Tab)
166
+ "Custom markup for #{args[:locals][:tab].name}"
167
+ end
168
+ helper.render_tabnav do |n|
169
+ n.tab_content_partial = '/tab_content'
170
+ n.add_tab do |t|
171
+ t.named "Home"
172
+ t.links_to "/"
173
+ end
174
+ n.add_tab do |t|
175
+ t.named "Froobles"
176
+ t.links_to "/froobles"
177
+ end
178
+ end
179
+ helper.output_buffer.should ==
180
+ '<ul><li>Custom markup for Home</li>' +
181
+ '<li>Custom markup for Froobles</li></ul>'
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tabnav::Navbar do
4
+
5
+ describe "add_tab" do
6
+ before :each do
7
+ @template = ActionView::Base.new()
8
+ end
9
+
10
+ it "should create a new tab with the passed template and params and yield it to the block" do
11
+ n = Tabnav::Navbar.new(@template, {"foo" => "bar"})
12
+ t = Tabnav::Tab.new(@template, {})
13
+ Tabnav::Tab.should_receive(:new).with(@template, {"foo" => "bar"}, {}).and_return(t)
14
+ n.add_tab do |t|
15
+ t.should == t
16
+ end
17
+ end
18
+
19
+ it "should create the tab with any passed options" do
20
+ n = Tabnav::Navbar.new(@template, {})
21
+ t = Tabnav::Tab.new(@template, {})
22
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:class => "my_class", :id => "my_id"}).and_return(t)
23
+ n.add_tab :class => "my_class", :id => "my_id" do |t|
24
+ t.should == t
25
+ end
26
+ end
27
+
28
+ it "should add the custom partial to the options if set" do
29
+ n = Tabnav::Navbar.new(@template, {})
30
+ n.tab_content_partial = 'my_partial'
31
+ t = Tabnav::Tab.new(@template, {})
32
+ Tabnav::Tab.should_receive(:new).with(@template, {}, {:id => "my_id", :tab_content_partial => 'my_partial'}).and_return(t)
33
+ n.add_tab :id => "my_id" do |t|
34
+ t.should == t
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "render" do
40
+ before :each do
41
+ @template = ActionView::Base.new()
42
+ end
43
+
44
+ it "should output nothing if no tabs have been added" do
45
+ n = Tabnav::Navbar.new(@template, {})
46
+ n.render.should == ''
47
+ end
48
+
49
+ it "should output a ul containing the results of rendering each of it's tabs" do
50
+ n = Tabnav::Navbar.new(@template, {})
51
+ t1 = t2 = nil
52
+ n.add_tab do |t|
53
+ t1 = t
54
+ end
55
+ n.add_tab do |t|
56
+ t2 = t
57
+ end
58
+ t1.should_receive(:render).and_return("Tab 1 markup")
59
+ t2.should_receive(:render).and_return("Tab 2 markup")
60
+ n.render.should == '<ul>Tab 1 markupTab 2 markup</ul>'
61
+ end
62
+
63
+ it "should pass the options given on creation to the ul" do
64
+ n = Tabnav::Navbar.new(@template, {}, :id => "my_id", :class => "my_class")
65
+ t1 = nil
66
+ n.add_tab do |t|
67
+ t1 = t
68
+ end
69
+ @template.should_receive(:content_tag).with(:ul, {:id => "my_id", :class => "my_class"}).and_return(:some_markup)
70
+ n.render.should == :some_markup
71
+ end
72
+
73
+ # it "should output a li containing a span with the name if no link given" do
74
+ # t = Tabnav::Tab.new(@template)
75
+ # t.named "A Tab"
76
+ # html = t.render
77
+ # html.should == "<li><span>A Tab</span></li>"
78
+ # end
79
+ #
80
+ # it "should output a li containing a link with the name" do
81
+ # t = Tabnav::Tab.new(@template)
82
+ # t.named "A Tab"
83
+ # t.links_to "/wibble"
84
+ # html = t.render
85
+ # html.should == "<li><a href=\"/wibble\">A Tab</a></li>"
86
+ # end
87
+ #
88
+ # context "with no name given" do
89
+ # it "should output a blank tab if no link given" do
90
+ # t = Tabnav::Tab.new(@template)
91
+ # html = t.render
92
+ # html.should == "<li><span></span></li>"
93
+ # end
94
+ #
95
+ # it "should output an empty link" do
96
+ # t = Tabnav::Tab.new(@template)
97
+ # t.links_to "/wibble"
98
+ # html = t.render
99
+ # html.should == "<li><a href=\"/wibble\"></a></li>"
100
+ # end
101
+ # end
102
+ #
103
+ # it "should pass the options given on creation to the li" do
104
+ # @template.should_receive(:content_tag).with(:li, {:id => "my_id", :class => "my_class"}).and_return(:some_markup)
105
+ # t = Tabnav::Tab.new(@template, :id => "my_id", :class => "my_class")
106
+ # t.named "A Tab"
107
+ # t.render.should == :some_markup
108
+ # end
109
+ #
110
+ # it "should pass the options given to the link to link_to" do
111
+ # @template.should_receive(:link_to).with("A Tab", "/wibble", {:class => "link_class", :target => "_blank"}).and_return("A Link")
112
+ # t = Tabnav::Tab.new(@template)
113
+ # t.named "A Tab"
114
+ # t.links_to "/wibble", :class => "link_class", :target => "_blank"
115
+ # html = t.render
116
+ # html.should == "<li>A Link</li>"
117
+ # end
118
+ end
119
+ end
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tabnav::Tab do
4
+
5
+ describe "accessors" do
6
+ before :each do
7
+ @tab = Tabnav::Tab.new(nil, {})
8
+ @tab.named "A Tab"
9
+ @tab.links_to "/somewhere", :target => "_blank"
10
+ end
11
+
12
+ it "should have a name accessor" do
13
+ @tab.name.should == "A Tab"
14
+ end
15
+
16
+ it "should have a link_url accessor" do
17
+ @tab.link_url.should == "/somewhere"
18
+ end
19
+
20
+ it "should have a link_options accessor" do
21
+ @tab.link_options.should == {:target => "_blank"}
22
+ end
23
+ end
24
+
25
+ describe "render" do
26
+ before :each do
27
+ @template = ActionView::Base.new()
28
+ end
29
+ it "should output a li containing a span with the name if no link given" do
30
+ t = Tabnav::Tab.new(@template, {})
31
+ t.named "A Tab"
32
+ html = t.render
33
+ html.should == "<li><span>A Tab</span></li>"
34
+ end
35
+
36
+ it "should output a li containing a link with the name" do
37
+ t = Tabnav::Tab.new(@template, {})
38
+ t.named "A Tab"
39
+ t.links_to "/wibble"
40
+ html = t.render
41
+ html.should == "<li><a href=\"/wibble\">A Tab</a></li>"
42
+ end
43
+
44
+ context "with no name given" do
45
+ it "should output a blank tab if no link given" do
46
+ t = Tabnav::Tab.new(@template, {})
47
+ html = t.render
48
+ html.should == "<li><span></span></li>"
49
+ end
50
+
51
+ it "should output an empty link" do
52
+ t = Tabnav::Tab.new(@template, {})
53
+ t.links_to "/wibble"
54
+ html = t.render
55
+ html.should == "<li><a href=\"/wibble\"></a></li>"
56
+ end
57
+ end
58
+
59
+ it "should pass the options given on creation to the li" do
60
+ @template.should_receive(:content_tag).with(:li, {:id => "my_id", :class => "my_class"}).and_return(:some_markup)
61
+ t = Tabnav::Tab.new(@template, {}, :id => "my_id", :class => "my_class")
62
+ t.named "A Tab"
63
+ t.render.should == :some_markup
64
+ end
65
+
66
+ it "should pass the options given to the link to link_to" do
67
+ @template.should_receive(:link_to).with("A Tab", "/wibble", {:class => "link_class", :target => "_blank"}).and_return("A Link")
68
+ t = Tabnav::Tab.new(@template, {})
69
+ t.named "A Tab"
70
+ t.links_to "/wibble", :class => "link_class", :target => "_blank"
71
+ html = t.render
72
+ html.should == "<li>A Link</li>"
73
+ end
74
+
75
+ context "with a custom partial" do
76
+ it "should render the partial, assigning the tab" do
77
+ t = Tabnav::Tab.new(@template, {}, :tab_content_partial => 'my_partial')
78
+ t.named "A Tab"
79
+ @template.should_receive(:render).with(:partial => 'my_partial', :locals => {:tab => t}).and_return("Custom tab markup")
80
+ t.render.should == "<li>Custom tab markup</li>"
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "highlighting rules" do
86
+ describe "active logic" do
87
+ describe "params based rules" do
88
+ it "should be active if all the optons in the rule match the params" do
89
+ params = {"key1" => "a_value", "key2" => "another_value", "key3" => "something else"}
90
+ t = Tabnav::Tab.new(@template, params)
91
+ t.highlights_on "key1" => "a_value", "key2" => "another_value"
92
+ t.should be_active
93
+ end
94
+
95
+ it "should not be active if only some of the values match" do
96
+ params = {"key1" => "a_value", "key2" => "another_value", "key3" => "something else"}
97
+ t = Tabnav::Tab.new(@template, params)
98
+ t.highlights_on "key1" => "a_value", "key2" => "a different value"
99
+ t.should_not be_active
100
+ end
101
+
102
+ it "should not be active if some of the values are missing" do
103
+ params = {"key1" => "a_value", "key3" => "something else"}
104
+ t = Tabnav::Tab.new(@template, params)
105
+ t.highlights_on "key1" => "a_value", "key2" => "another_value"
106
+ t.should_not be_active
107
+ end
108
+
109
+ it "should be active if any of the rules match" do
110
+ params = {"key1" => "a_value", "key2" => "another_value", "key3" => "something else"}
111
+ t = Tabnav::Tab.new(@template, params)
112
+ t.highlights_on "key1" => "a_value", "key2" => "a different value"
113
+ t.highlights_on "key1" => "a_value"
114
+ t.highlights_on "key2" => "wibble"
115
+ t.should be_active
116
+ end
117
+
118
+ it "should treat strings ans symobls at matching" do
119
+ params = {"key1" => "a_value", "key2" => "another_value", "key3" => "something else"}
120
+ t = Tabnav::Tab.new(@template, params)
121
+ t.highlights_on :key1 => "a_value", :key2 => :another_value
122
+ t.should be_active
123
+ end
124
+ end
125
+
126
+ describe "proc based rules" do
127
+ it "should be active if the proc returns true" do
128
+ t = Tabnav::Tab.new(@template, {})
129
+ t.highlights_on Proc.new { true }
130
+ t.should be_active
131
+ end
132
+
133
+ it "should not be active if the proc returns false" do
134
+ t = Tabnav::Tab.new(@template, {})
135
+ t.highlights_on Proc.new { false }
136
+ t.should_not be_active
137
+ end
138
+
139
+ it "should co-erce the result of the proc to a boolean" do
140
+ t = Tabnav::Tab.new(@template, {})
141
+ t.highlights_on Proc.new { "wibble" }
142
+ t.active?.should == true
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "output" do
148
+ before :each do
149
+ @template = ActionView::Base.new()
150
+ end
151
+ it "should set the class of the li to active if the tab is highlighted" do
152
+ t = Tabnav::Tab.new(@template, {})
153
+ t.named "A Tab"
154
+ t.stub!(:active?).and_return(true)
155
+ t.render.should == '<li class="active"><span>A Tab</span></li>'
156
+ end
157
+
158
+ it "should merge active with the other classes if highlighted" do
159
+ t = Tabnav::Tab.new(@template, {}, {:class => "my_class"})
160
+ t.named "A Tab"
161
+ t.stub!(:active?).and_return(true)
162
+ t.render.should == '<li class="my_class active"><span>A Tab</span></li>'
163
+ end
164
+ end
165
+ end
166
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tabnav
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Unboxed
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-28 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: actionpack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 2
34
+ version: 2.3.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 13
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 9
50
+ version: 1.2.9
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec-rails
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 13
62
+ segments:
63
+ - 1
64
+ - 2
65
+ - 9
66
+ version: 1.2.9
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: Rails helper for generating navbars in a declarative manner
70
+ email: github@unboxedconsulting.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ files:
79
+ - .document
80
+ - LICENSE
81
+ - README.rdoc
82
+ - Rakefile
83
+ - VERSION
84
+ - lib/tabnav.rb
85
+ - lib/tabnav/helper.rb
86
+ - lib/tabnav/navbar.rb
87
+ - lib/tabnav/tab.rb
88
+ - spec/spec.opts
89
+ - spec/spec_helper.rb
90
+ - spec/tabnav/helper_spec.rb
91
+ - spec/tabnav/integration_spec.rb
92
+ - spec/tabnav/navbar_spec.rb
93
+ - spec/tabnav/tab_spec.rb
94
+ has_rdoc: true
95
+ homepage: http://github.com/unboxed/tabnav
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options:
100
+ - --charset=UTF-8
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project:
124
+ rubygems_version: 1.3.7
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Rails helper for generating navbars
128
+ test_files:
129
+ - spec/spec_helper.rb
130
+ - spec/tabnav/helper_spec.rb
131
+ - spec/tabnav/integration_spec.rb
132
+ - spec/tabnav/navbar_spec.rb
133
+ - spec/tabnav/tab_spec.rb