breadcrumby 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE +21 -0
- data/README.md +221 -0
- data/lib/breadcrumby.rb +11 -0
- data/lib/breadcrumby/engine.rb +15 -0
- data/lib/breadcrumby/helpers/view_helper.rb +9 -0
- data/lib/breadcrumby/models/extension.rb +74 -0
- data/lib/breadcrumby/models/home.rb +23 -0
- data/lib/breadcrumby/models/viewer.rb +154 -0
- data/lib/breadcrumby/version.rb +5 -0
- data/spec/factories/course.rb +9 -0
- data/spec/factories/grade.rb +10 -0
- data/spec/factories/level.rb +9 -0
- data/spec/factories/school.rb +7 -0
- data/spec/factories/unit.rb +9 -0
- data/spec/lib/breadcrumby/helpers/breadcrumby_spec.rb +22 -0
- data/spec/lib/breadcrumby/models/extension/breadcrumby_options_spec.rb +89 -0
- data/spec/lib/breadcrumby/models/extension/breadcrumby_spec.rb +126 -0
- data/spec/lib/breadcrumby/models/home/name_spec.rb +25 -0
- data/spec/lib/breadcrumby/models/home/show_path_spec.rb +25 -0
- data/spec/lib/breadcrumby/models/viewer/breadcrumb_spec.rb +55 -0
- data/spec/lib/breadcrumby/models/viewer/breadcrumbs_spec.rb +25 -0
- data/spec/lib/breadcrumby/models/viewer/current_object_spec.rb +68 -0
- data/spec/lib/breadcrumby/models/viewer/i18n_action_name_spec.rb +28 -0
- data/spec/lib/breadcrumby/models/viewer/i18n_name_spec.rb +53 -0
- data/spec/lib/breadcrumby/models/viewer/item_options_spec.rb +17 -0
- data/spec/lib/breadcrumby/models/viewer/item_spec.rb +30 -0
- data/spec/lib/breadcrumby/models/viewer/link_action_spec.rb +23 -0
- data/spec/lib/breadcrumby/models/viewer/link_options_spec.rb +49 -0
- data/spec/lib/breadcrumby/models/viewer/link_spec.rb +40 -0
- data/spec/lib/breadcrumby/models/viewer/link_tag_name_options_spec.rb +13 -0
- data/spec/lib/breadcrumby/models/viewer/link_tag_name_spec.rb +35 -0
- data/spec/lib/breadcrumby/models/viewer/list_options_spec.rb +17 -0
- data/spec/lib/breadcrumby/models/viewer/meta_spec.rb +14 -0
- data/spec/lib/breadcrumby/models/viewer/object_extra_spec.rb +80 -0
- data/spec/lib/breadcrumby/models/viewer/scope_spec.rb +35 -0
- data/spec/rails_helper.rb +11 -0
- data/spec/support/common.rb +22 -0
- data/spec/support/database_cleaner.rb +21 -0
- data/spec/support/db/migrate/course.rb +11 -0
- data/spec/support/db/migrate/grade.rb +12 -0
- data/spec/support/db/migrate/level.rb +11 -0
- data/spec/support/db/migrate/school.rb +9 -0
- data/spec/support/db/migrate/unit.rb +11 -0
- data/spec/support/factory_girl.rb +9 -0
- data/spec/support/html_matchers.rb +7 -0
- data/spec/support/migrate.rb +9 -0
- data/spec/support/models/course.rb +5 -0
- data/spec/support/models/grade.rb +6 -0
- data/spec/support/models/level.rb +5 -0
- data/spec/support/models/school.rb +15 -0
- data/spec/support/models/unit.rb +13 -0
- data/spec/support/shoulda.rb +10 -0
- metadata +321 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
class DummyHelper
|
6
|
+
include Breadcrumby::ViewHelper
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.describe DummyHelper, '.breadcrumby' do
|
10
|
+
let!(:object) { create :school, name: 'School 1' }
|
11
|
+
let!(:options) { { key: :value } }
|
12
|
+
let!(:helper) { DummyHelper.new }
|
13
|
+
let!(:viewer) { double Breadcrumby::Viewer, breadcrumb: :breadcrumb }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(Breadcrumby::Viewer).to receive(:new).with(object, options, helper) { viewer }
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'calls breadcrumb from viewer' do
|
20
|
+
expect(helper.breadcrumby(object, options)).to eq :breadcrumb
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Extension, '.breadcrumby_options' do
|
6
|
+
describe ':i18n_key' do
|
7
|
+
context 'when is not given' do
|
8
|
+
before do
|
9
|
+
stub_const 'Dummy', Class.new
|
10
|
+
|
11
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
12
|
+
Dummy.class_eval { breadcrumby }
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'uses a default' do
|
16
|
+
expect(Dummy.new.breadcrumby_options[:i18n_key]).to eq 'dummy'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when is given' do
|
21
|
+
before do
|
22
|
+
stub_const 'Dummy', Class.new
|
23
|
+
|
24
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
25
|
+
Dummy.class_eval { breadcrumby i18n_key: :key }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'uses the given one' do
|
29
|
+
expect(Dummy.new.breadcrumby_options[:i18n_key]).to eq :key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ':method_name' do
|
35
|
+
context 'when is not given' do
|
36
|
+
before do
|
37
|
+
stub_const 'Dummy', Class.new
|
38
|
+
|
39
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
40
|
+
Dummy.class_eval { breadcrumby }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'uses a default' do
|
44
|
+
expect(Dummy.new.breadcrumby_options[:method_name]).to eq :name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when is given' do
|
49
|
+
before do
|
50
|
+
stub_const 'Dummy', Class.new
|
51
|
+
|
52
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
53
|
+
Dummy.class_eval { breadcrumby method_name: :some_name }
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'uses the given one' do
|
57
|
+
expect(Dummy.new.breadcrumby_options[:method_name]).to eq :some_name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ':actions' do
|
63
|
+
context 'when is not given' do
|
64
|
+
before do
|
65
|
+
stub_const 'Dummy', Class.new
|
66
|
+
|
67
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
68
|
+
Dummy.class_eval { breadcrumby }
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'uses a default' do
|
72
|
+
expect(Dummy.new.breadcrumby_options[:actions]).to eq({})
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when is given' do
|
77
|
+
before do
|
78
|
+
stub_const 'Dummy', Class.new
|
79
|
+
|
80
|
+
Dummy.class_eval { include Breadcrumby::Extension }
|
81
|
+
Dummy.class_eval { breadcrumby actions: { key: :value } }
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'uses the given one' do
|
85
|
+
expect(Dummy.new.breadcrumby_options[:actions]).to eq(key: :value)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Extension, '.breadcrumby' do
|
6
|
+
context 'when object has no path option' do
|
7
|
+
let!(:school) { create :school, name: 'School 1' }
|
8
|
+
|
9
|
+
it 'returns itself' do
|
10
|
+
expect(school.breadcrumby).to eq [school]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when object has an empty path option' do
|
15
|
+
let!(:school) { create :school }
|
16
|
+
|
17
|
+
before { School.class_eval { breadcrumby path: [] } }
|
18
|
+
|
19
|
+
it 'returns itself' do
|
20
|
+
expect(school.breadcrumby).to eq [school]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when object has a nil path option' do
|
25
|
+
let!(:school) { create :school }
|
26
|
+
|
27
|
+
before { School.class_eval { breadcrumby path: nil } }
|
28
|
+
|
29
|
+
it 'returns itself' do
|
30
|
+
expect(school.breadcrumby).to eq [school]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when object is the second level' do
|
35
|
+
let!(:course) { create :course }
|
36
|
+
|
37
|
+
context 'and has one item on path option' do
|
38
|
+
before { Course.class_eval { breadcrumby path: [:school] } }
|
39
|
+
|
40
|
+
it 'returns itself and the parents' do
|
41
|
+
expect(course.breadcrumby).to eq [course, course.school]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'and has just one symbol on path option' do
|
46
|
+
before { Course.class_eval { breadcrumby path: :school } }
|
47
|
+
|
48
|
+
it 'returns itself and the parents' do
|
49
|
+
expect(course.breadcrumby).to eq [course, course.school]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when object is on a deep level' do
|
55
|
+
let!(:school) { create :school }
|
56
|
+
let!(:unit) { create :unit, school: school }
|
57
|
+
let!(:course) { create :course, school: school }
|
58
|
+
let!(:level) { create :level, course: course }
|
59
|
+
let!(:grade) { create :grade, level: level, unit: unit }
|
60
|
+
|
61
|
+
context 'and parents just point to it parent' do
|
62
|
+
before do
|
63
|
+
Course.class_eval { breadcrumby path: :school }
|
64
|
+
Level.class_eval { breadcrumby path: :course }
|
65
|
+
Grade.class_eval { breadcrumby path: :level }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns itself and the parents' do
|
69
|
+
expect(grade.breadcrumby).to eq [grade, grade.level, grade.level.course, grade.level.course.school]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'and object points an specific path' do
|
74
|
+
context 'and last parent has no path' do
|
75
|
+
before do
|
76
|
+
# TODO: was need to declare again, site the other Course.class_eval keeped the callback on memory. Why if it is inside a before block?
|
77
|
+
Course.class_eval { breadcrumby }
|
78
|
+
Grade.class_eval { breadcrumby path: %i[course level] }
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns itself and the parents until the last parent path' do
|
82
|
+
expect(grade.breadcrumby).to eq [grade, grade.level, grade.level.course]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'and last parent has path' do
|
87
|
+
before do
|
88
|
+
Course.class_eval { breadcrumby path: :school }
|
89
|
+
Grade.class_eval { breadcrumby path: %i[course level] }
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'returns itself and the following parents' do
|
93
|
+
expect(grade.breadcrumby).to eq [grade, grade.level, grade.level.course, grade.level.course.school]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'and i want follow different paths' do
|
98
|
+
context 'until the end' do
|
99
|
+
before do
|
100
|
+
Unit.class_eval { breadcrumby path: :school }
|
101
|
+
Course.class_eval { breadcrumby path: :school }
|
102
|
+
Level.class_eval { breadcrumby path: :course }
|
103
|
+
Grade.class_eval { breadcrumby path: [[:unit], [:level]] }
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'follows each one of the path groups' do
|
107
|
+
expect(grade.breadcrumby).to eq [grade, grade.level, grade.level.course, grade.level.course.school, grade.unit, grade.level.course.school]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'stopping on a specific point' do
|
112
|
+
before do
|
113
|
+
Unit.class_eval { breadcrumby path: :school }
|
114
|
+
Course.class_eval { breadcrumby path: :school }
|
115
|
+
Level.class_eval { breadcrumby path: :course }
|
116
|
+
Grade.class_eval { breadcrumby path: [[:unit], [nil, :course, :level]] }
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'follows each one of the path groups until end of until the nil break point' do
|
120
|
+
expect(grade.breadcrumby).to eq [grade, grade.level, grade.level.course, grade.unit, grade.level.course.school]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Home, '.name' do
|
6
|
+
subject { described_class.new view }
|
7
|
+
|
8
|
+
let!(:view) { double }
|
9
|
+
|
10
|
+
context 'when i18n key is not defined' do
|
11
|
+
it 'returns a default name' do
|
12
|
+
expect(subject.name).to eq 'Home'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when i18n key is defined' do
|
17
|
+
before do
|
18
|
+
allow(I18n).to receive(:t).with('breadcrumby.home.name', default: 'Home') { 'Start' }
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns a default name' do
|
22
|
+
expect(subject.name).to eq 'Start'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Home, '.show_path' do
|
6
|
+
context 'when route :root_path is not present' do
|
7
|
+
subject { described_class.new view }
|
8
|
+
|
9
|
+
let!(:view) { double }
|
10
|
+
|
11
|
+
it 'returns the root path' do
|
12
|
+
expect(subject.show_path).to eq '/'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when route :root_path is present' do
|
17
|
+
subject { described_class.new view }
|
18
|
+
|
19
|
+
let!(:view) { double root_path: :root_path }
|
20
|
+
|
21
|
+
it 'returns the :root_path value' do
|
22
|
+
expect(subject.show_path).to eq :root_path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.breadcrumb' do
|
6
|
+
context 'when object does not respond to :breadcrumby' do
|
7
|
+
subject { described_class.new object, options }
|
8
|
+
|
9
|
+
let!(:object) { {} }
|
10
|
+
let!(:options) { {} }
|
11
|
+
let!(:view) { double root_path: :root_path }
|
12
|
+
|
13
|
+
it 'returns an empty string' do
|
14
|
+
expect(subject.breadcrumb).to eq ''
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when object responds to :breadcrumby' do
|
19
|
+
subject { described_class.new object, options }
|
20
|
+
|
21
|
+
let!(:object) { create :school, name: 'The School' }
|
22
|
+
let!(:view) { double root_path: :root_path }
|
23
|
+
let!(:list) { [object] }
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(subject).to receive(:breadcrumbs).with(object) { [object] }
|
27
|
+
allow(subject).to receive(:object_extra).with(list.size) { ['<li class="object_extra"></li>'] }
|
28
|
+
allow(subject).to receive(:list_options) { { class: :list_options } }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with no :actions' do
|
32
|
+
let!(:options) { {} }
|
33
|
+
|
34
|
+
before do
|
35
|
+
Unit.class_eval { breadcrumby }
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the default breadcrumb' do
|
39
|
+
expect(subject.breadcrumb).to have_tag(:ol, with: { class: 'list_options' }) do
|
40
|
+
with_tag(:li, with: { itemprop: 'itemListElement', itemscope: 'itemscope', itemtype: 'http://schema.org/ListItem' }) do
|
41
|
+
with_tag(:a, with: { itemprop: 'item', itemscope: 'itemscope', itemtype: 'http://schema.org/Thing', title: 'translation missing: en.breadcrumby.title', href: 'school.show.path' }) do
|
42
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
43
|
+
with_text 'The School'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
with_tag(:meta, with: { content: '1', itemprop: 'position' })
|
48
|
+
end
|
49
|
+
|
50
|
+
with_tag :li, with: { class: 'object_extra' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.breadcrumbs' do
|
6
|
+
subject { described_class.new object, options, view }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
let!(:options) { {} }
|
10
|
+
let!(:view) { double }
|
11
|
+
let!(:home) { double Breadcrumby::Home }
|
12
|
+
|
13
|
+
before do
|
14
|
+
Unit.class_eval { breadcrumby }
|
15
|
+
|
16
|
+
allow(Breadcrumby::Home).to receive(:new).with(view) { home }
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns the objects including the home' do
|
20
|
+
expect(subject.breadcrumbs(object)).to eq [
|
21
|
+
Breadcrumby::Home.new(view),
|
22
|
+
object
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.current_object' do
|
6
|
+
subject { described_class.new object, options, view }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
let!(:view) { double }
|
10
|
+
|
11
|
+
context 'when object has no :actions' do
|
12
|
+
let!(:options) { {} }
|
13
|
+
|
14
|
+
before { School.class_eval { breadcrumby } }
|
15
|
+
|
16
|
+
it 'returns the self object' do
|
17
|
+
expect(subject.current_object).to eq object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when object has :actions' do
|
22
|
+
before do
|
23
|
+
School.class_eval { breadcrumby actions: {} }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'but view action is not provided' do
|
27
|
+
let!(:options) { {} }
|
28
|
+
|
29
|
+
it 'returns the self object' do
|
30
|
+
expect(subject.current_object).to eq object
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'and view action is provided' do
|
35
|
+
let!(:options) { { action: :new } }
|
36
|
+
|
37
|
+
context 'but object has not this action' do
|
38
|
+
it 'returns the self object' do
|
39
|
+
expect(subject.current_object).to eq object
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'and object has this action' do
|
44
|
+
context 'but actions is not callable' do
|
45
|
+
before do
|
46
|
+
School.class_eval { breadcrumby actions: { new: :uncallable } }
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns the self value' do
|
50
|
+
expect(subject.current_object).to eq :uncallable
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'and actions is callable' do
|
55
|
+
before do
|
56
|
+
School.class_eval do
|
57
|
+
breadcrumby actions: { new: ->(view) { view } }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns the result call' do
|
62
|
+
expect(subject.current_object).to eq view
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|