breadcrumby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.i18n_action_name' do
|
6
|
+
subject { described_class.new object, options, view }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
let!(:options) { {} }
|
10
|
+
let!(:view) { double }
|
11
|
+
let!(:action) { :edit }
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow(I18n).to receive(:t).with(:edit) { 'edit' }
|
15
|
+
|
16
|
+
allow(I18n).to receive(:t).with(
|
17
|
+
'actions.edit.name', scope: [:breadcrumby], default: 'edit'
|
18
|
+
) { 'root || edit' }
|
19
|
+
|
20
|
+
allow(I18n).to receive(:t).with(
|
21
|
+
'actions.edit.name', scope: [:breadcrumby, 'school'], default: 'root || edit'
|
22
|
+
) { 'translation' }
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns a name for object fetched from i18n with root fallback' do
|
26
|
+
expect(subject.i18n_action_name(object, action)).to eq 'translation'
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.i18n_name' do
|
6
|
+
subject { described_class.new object, options, view }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
let!(:options) { {} }
|
10
|
+
let!(:view) { double }
|
11
|
+
|
12
|
+
context 'when :method_name responds with value' do
|
13
|
+
before do
|
14
|
+
allow(object).to receive(:breadcrumby_options) do
|
15
|
+
{
|
16
|
+
i18n_key: :i18n_key,
|
17
|
+
method_name: :custom_method_name
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
allow(I18n).to receive(:t).with(:edit, default: 'Edition') { 'edit || Edition' }
|
22
|
+
|
23
|
+
allow(I18n).to receive(:t).with(
|
24
|
+
:name, scope: %i[breadcrumby i18n_key], default: :custom_method_name
|
25
|
+
) { 'translation' }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'uses the returned value as the object name' do
|
29
|
+
expect(subject.i18n_name(object)).to eq 'translation'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when :method_name does not respond with value' do
|
34
|
+
before do
|
35
|
+
allow(object).to receive(:breadcrumby_options) do
|
36
|
+
{
|
37
|
+
i18n_key: :i18n_key,
|
38
|
+
method_name: :custom_method_name_nil
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
allow(I18n).to receive(:t).with(:edit, default: 'Edition') { 'edit || Edition' }
|
43
|
+
|
44
|
+
allow(I18n).to receive(:t).with(
|
45
|
+
:name, scope: %i[breadcrumby i18n_key], default: '--'
|
46
|
+
) { 'translation' }
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'uses a default name as fallback' do
|
50
|
+
expect(subject.i18n_name(object)).to eq 'translation'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.item_options' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
|
10
|
+
it 'returns the options used on list element' do
|
11
|
+
expect(subject.item_options).to eq(
|
12
|
+
itemprop: :itemListElement,
|
13
|
+
itemscope: true,
|
14
|
+
itemtype: 'http://schema.org/ListItem'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.item' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:content) { :content }
|
9
|
+
let!(:object) { build :school }
|
10
|
+
|
11
|
+
it 'returns a item element as node of the list' do
|
12
|
+
expect(subject.item(content)).to have_tag :li, with: {
|
13
|
+
itemprop: :itemListElement,
|
14
|
+
itemscope: :itemscope,
|
15
|
+
itemtype: 'http://schema.org/ListItem'
|
16
|
+
} do
|
17
|
+
with_text :content
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when options is given' do
|
22
|
+
let!(:options) { { alt: :custom } }
|
23
|
+
|
24
|
+
it 'is used' do
|
25
|
+
expect(subject.item(content, options)).to have_tag :li, with: { alt: :custom } do
|
26
|
+
with_text :content
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.link_action' do
|
6
|
+
subject { described_class.new object, options }
|
7
|
+
|
8
|
+
let!(:action) { :edit }
|
9
|
+
let!(:object) { build :school }
|
10
|
+
let!(:options) { {} }
|
11
|
+
|
12
|
+
context 'when action is not given' do
|
13
|
+
it 'returns the object show route' do
|
14
|
+
expect(subject.link_action(object, nil)).to eq object.show_path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when action is given' do
|
19
|
+
it 'returns an avoid link' do
|
20
|
+
expect(subject.link_action(object, action)).to eq 'javascript:void(0);'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.link_options' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(subject).to receive(:i18n_name).with(object) { :i18n_name }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when action is not given' do
|
15
|
+
let!(:action) { nil }
|
16
|
+
|
17
|
+
before do
|
18
|
+
allow(I18n).to receive(:t).with(:title, scope: [:breadcrumby, 'school'], name: :i18n_name, default: 'title') { 'breadcrumby.school.title' }
|
19
|
+
allow(I18n).to receive(:t).with(:title, scope: [:breadcrumby]) { 'title' }
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the link options' do
|
23
|
+
expect(subject.link_options(object, action)).to eq(
|
24
|
+
itemprop: :item,
|
25
|
+
itemscope: true,
|
26
|
+
itemtype: 'http://schema.org/Thing',
|
27
|
+
title: 'breadcrumby.school.title'
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when action is given' do
|
33
|
+
let!(:action) { :edit }
|
34
|
+
|
35
|
+
before do
|
36
|
+
allow(I18n).to receive(:t).with('actions.edit.title', scope: [:breadcrumby, 'school'], name: :i18n_name, default: 'breadcrumby.actions.edit.title') { 'breadcrumby.school.actions.edit.title' }
|
37
|
+
allow(I18n).to receive(:t).with('actions.edit.title', scope: [:breadcrumby]) { 'breadcrumby.actions.edit.title' }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns the link options with title scoped by action fetched from i18n with root fallback' do
|
41
|
+
expect(subject.link_options(object, action)).to eq(
|
42
|
+
itemprop: :item,
|
43
|
+
itemscope: true,
|
44
|
+
itemtype: 'http://schema.org/Thing',
|
45
|
+
title: 'breadcrumby.school.actions.edit.title'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.link' do
|
6
|
+
subject { described_class.new object, options }
|
7
|
+
|
8
|
+
let!(:action) { :edit }
|
9
|
+
let!(:object) { build :school }
|
10
|
+
let!(:options) { {} }
|
11
|
+
|
12
|
+
context 'when action is not given' do
|
13
|
+
before do
|
14
|
+
allow(subject).to receive(:i18n_name).with(object) { :i18n_name }
|
15
|
+
allow(subject).to receive(:link_options).with(object, nil) { { class: :custom } }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'build a link with object properties' do
|
19
|
+
expect(subject.link(object)).to have_tag(:a, with: { href: 'school.show.path' }) do
|
20
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
21
|
+
with_text 'i18n_name'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when action is given' do
|
28
|
+
before do
|
29
|
+
allow(subject).to receive(:i18n_action_name).with(object, action) { :i18n_action_name }
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'build a link with object and action properties' do
|
33
|
+
expect(subject.link(object, action: action)).to have_tag(:a, with: { itemprop: 'item', itemscope: 'itemscope', itemtype: 'http://schema.org/Thing', title: 'translation missing: en.breadcrumby.actions.edit.title', href: 'javascript:void(0);' }) do
|
34
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
35
|
+
with_text 'i18n_action_name'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.link_tag_name_options' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
|
10
|
+
it 'returns options used on link' do
|
11
|
+
expect(subject.link_tag_name_options).to eq(itemprop: :name)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.link_tag_name' do
|
6
|
+
subject { described_class.new object, options }
|
7
|
+
|
8
|
+
let!(:action) { :edit }
|
9
|
+
let!(:object) { build :school }
|
10
|
+
let!(:options) { {} }
|
11
|
+
|
12
|
+
context 'when action is not given' do
|
13
|
+
before do
|
14
|
+
allow(subject).to receive(:i18n_name).with(object) { :i18n_name }
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'build a ta name with object properties' do
|
18
|
+
expect(subject.link_tag_name(object, nil)).to have_tag(:span, with: { itemprop: 'name' }) do
|
19
|
+
with_text 'i18n_name'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when action is given' do
|
25
|
+
before do
|
26
|
+
allow(subject).to receive(:i18n_action_name).with(object, action) { :i18n_action_name }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'build a ta name with object and action properties' do
|
30
|
+
expect(subject.link_tag_name(object, action)).to have_tag(:span, with: { itemprop: 'name' }) do
|
31
|
+
with_text 'i18n_action_name'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.list_options' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
|
10
|
+
it 'returns the options used on list element' do
|
11
|
+
expect(subject.list_options).to eq(
|
12
|
+
class: :breadcrumby,
|
13
|
+
itemscope: true,
|
14
|
+
itemtype: 'http://schema.org/BreadcrumbList'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.meta' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:index) { 7 }
|
9
|
+
let!(:object) { build :school }
|
10
|
+
|
11
|
+
it 'returns a meta element used to count the crumbs' do
|
12
|
+
expect(subject.meta(index)).to have_tag :meta, with: { content: 7, itemprop: :position }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.object_extra(0)' do
|
6
|
+
context 'when :action is empty' do
|
7
|
+
subject { described_class.new object, options }
|
8
|
+
|
9
|
+
let!(:object) { {} }
|
10
|
+
let!(:options) { {} }
|
11
|
+
|
12
|
+
it 'returns an empty array' do
|
13
|
+
expect(subject.object_extra(0)).to eq []
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when :action is given' do
|
18
|
+
subject { described_class.new object, options }
|
19
|
+
|
20
|
+
let!(:object) { create :unit }
|
21
|
+
|
22
|
+
context 'with normal relationship' do
|
23
|
+
let!(:options) { { action: :edit } }
|
24
|
+
|
25
|
+
before { Unit.class_eval { breadcrumby } }
|
26
|
+
|
27
|
+
it 'builds the :action crumb' do
|
28
|
+
result = subject.object_extra(0)
|
29
|
+
|
30
|
+
expect(result.size).to eq 1
|
31
|
+
|
32
|
+
expect(result[0]).to have_tag(:li, with: { itemprop: 'itemListElement', itemscope: 'itemscope', itemtype: 'http://schema.org/ListItem' }) do
|
33
|
+
with_tag(:a, with: { itemprop: 'item', itemscope: 'itemscope', itemtype: 'http://schema.org/Thing', title: 'translation missing: en.breadcrumby.actions.edit.title', href: 'javascript:void(0);' }) do
|
34
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
35
|
+
with_text 'translation missing: en.edit'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
with_tag(:meta, with: { content: '1', itemprop: 'position' })
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with no relationship as a new record' do
|
45
|
+
let!(:options) { { action: :new } }
|
46
|
+
|
47
|
+
before do
|
48
|
+
Unit.class_eval do
|
49
|
+
breadcrumby actions: { new: ->(_view) { School.last } }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'builds the :action crumb' do
|
54
|
+
result = subject.object_extra(0)
|
55
|
+
|
56
|
+
expect(result.size).to eq 2
|
57
|
+
|
58
|
+
expect(result[0]).to have_tag(:li, with: { itemprop: 'itemListElement', itemscope: 'itemscope', itemtype: 'http://schema.org/ListItem' }) do
|
59
|
+
with_tag(:a, with: { itemprop: 'item', itemscope: 'itemscope', itemtype: 'http://schema.org/Thing', title: 'translation missing: en.breadcrumby.actions.index.title', href: 'unit.index.path' }) do
|
60
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
61
|
+
with_text 'translation missing: en.index'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
with_tag(:meta, with: { content: '1', itemprop: 'position' })
|
66
|
+
end
|
67
|
+
|
68
|
+
expect(result[1]).to have_tag(:li, with: { itemprop: 'itemListElement', itemscope: 'itemscope', itemtype: 'http://schema.org/ListItem' }) do
|
69
|
+
with_tag(:a, with: { itemprop: 'item', itemscope: 'itemscope', itemtype: 'http://schema.org/Thing', title: 'translation missing: en.breadcrumby.actions.new.title', href: 'javascript:void(0);' }) do
|
70
|
+
with_tag(:span, with: { itemprop: 'name' }) do
|
71
|
+
with_text 'translation missing: en.new'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
with_tag(:meta, with: { content: '2', itemprop: 'position' })
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe Breadcrumby::Viewer, '.scope' do
|
6
|
+
subject { described_class.new object }
|
7
|
+
|
8
|
+
let!(:object) { build :school }
|
9
|
+
|
10
|
+
context 'with default :i18n_key' do
|
11
|
+
it 'returns a i18n scope path based on class name' do
|
12
|
+
expect(subject.scope(object)).to eq [:breadcrumby, 'school']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with custom :i18n_key' do
|
17
|
+
before do
|
18
|
+
allow(object).to receive(:breadcrumby_options) { { i18n_key: :custom } }
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns a i18n scope path based on given name' do
|
22
|
+
expect(subject.scope(object)).to eq %i[breadcrumby custom]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when :include_model is false' do
|
27
|
+
before do
|
28
|
+
allow(object).to receive(:breadcrumby_options) { { i18n_key: :custom } }
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns a i18n scope path with only root key' do
|
32
|
+
expect(subject.scope(object, include_model: false)).to eq %i[breadcrumby]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|