showcase 0.1.7 → 0.2.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.travis.yml +9 -1
- data/Appraisals +8 -0
- data/Gemfile +3 -0
- data/README.md +186 -21
- data/Rakefile +14 -1
- data/gemfiles/activerecord3.gemfile +8 -0
- data/gemfiles/activerecord4.gemfile +8 -0
- data/lib/generators/showcase/presenter/presenter_generator.rb +2 -0
- data/lib/generators/showcase/presenter/templates/presenter.rb +2 -1
- data/lib/showcase/helpers/config_object.rb +28 -0
- data/lib/showcase/helpers/html_options.rb +22 -0
- data/lib/showcase/helpers/seo_meta_builder.rb +56 -0
- data/lib/showcase/presenter.rb +1 -0
- data/lib/showcase/railtie.rb +12 -0
- data/lib/showcase/traits/base.rb +23 -0
- data/lib/showcase/traits/link_to.rb +37 -0
- data/lib/showcase/traits/record.rb +61 -0
- data/lib/showcase/traits/seo.rb +27 -0
- data/lib/showcase/traits/share.rb +61 -0
- data/lib/showcase/traits.rb +11 -0
- data/lib/showcase/version.rb +1 -1
- data/lib/showcase.rb +2 -0
- data/showcase.gemspec +3 -0
- data/spec/fixtures.rb +16 -0
- data/spec/helpers/config_object_spec.rb +45 -0
- data/spec/helpers/seo_meta_builder_spec.rb +95 -0
- data/spec/helpers_spec.rb +34 -0
- data/spec/{showcase_spec.rb → presenter_spec.rb} +1 -37
- data/spec/spec_helper.rb +12 -0
- data/spec/traits/base_spec.rb +56 -0
- data/spec/traits/link_to_spec.rb +123 -0
- data/spec/traits/record_spec.rb +59 -0
- data/spec/traits/seo_spec.rb +37 -0
- data/spec/traits/share_spec.rb +60 -0
- metadata +67 -8
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'showcase/helpers/config_object'
|
2
|
+
require 'active_support/core_ext/object/to_query'
|
3
|
+
|
4
|
+
module Showcase
|
5
|
+
module Traits
|
6
|
+
module Share
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include LinkTo
|
9
|
+
|
10
|
+
PROVIDERS = {
|
11
|
+
twitter: {
|
12
|
+
url: "https://twitter.com/intent/tweet",
|
13
|
+
params: { url: :url, text: :text },
|
14
|
+
label: 'Tweet it!'
|
15
|
+
},
|
16
|
+
gplus: {
|
17
|
+
url: "https://plus.google.com/share",
|
18
|
+
params: { url: :url },
|
19
|
+
label: 'Share it on Google Plus!'
|
20
|
+
},
|
21
|
+
facebook: {
|
22
|
+
url: "http://www.facebook.com/sharer/sharer.php",
|
23
|
+
params: { u: :url },
|
24
|
+
label: 'Share it on Facebook!'
|
25
|
+
},
|
26
|
+
linkedin: {
|
27
|
+
url: "http://www.linkedin.com/shareArticle",
|
28
|
+
params: { url: :url, title: :text },
|
29
|
+
label: 'Share it on LinkedIn!'
|
30
|
+
},
|
31
|
+
pinterest: {
|
32
|
+
url: "http://www.pinterest.com/pin/create/button/",
|
33
|
+
params: { url: :url, media: :image_url, title: :text },
|
34
|
+
label: 'Pin it!'
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
module ClassMethods
|
39
|
+
def share(name = nil, &block)
|
40
|
+
PROVIDERS.each do |social, settings|
|
41
|
+
link_name = [ name, social, "share" ].map(&:presence).compact.join("_")
|
42
|
+
|
43
|
+
link_to link_name do |c|
|
44
|
+
meta = Helpers::ConfigObject.new(self, &block).to_struct
|
45
|
+
params = Hash[
|
46
|
+
settings[:params].map do |param, meta_key|
|
47
|
+
[ param, meta.send(meta_key) ]
|
48
|
+
end
|
49
|
+
]
|
50
|
+
c.url "#{settings[:url]}?#{params.to_query}"
|
51
|
+
c.label settings[:label]
|
52
|
+
c.html_options = { target: :blank }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
data/lib/showcase/version.rb
CHANGED
data/lib/showcase.rb
CHANGED
data/showcase.gemspec
CHANGED
@@ -18,7 +18,10 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ['lib']
|
19
19
|
|
20
20
|
gem.add_dependency 'activesupport'
|
21
|
+
|
21
22
|
gem.add_development_dependency 'rspec'
|
22
23
|
gem.add_development_dependency 'coveralls'
|
24
|
+
gem.add_development_dependency 'rails'
|
25
|
+
gem.add_development_dependency 'rspec-html-matchers'
|
23
26
|
end
|
24
27
|
|
data/spec/fixtures.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
class RailsViewContext < ActionView::Base
|
2
|
+
include ActionView::Helpers::TagHelper
|
3
|
+
|
4
|
+
def capture(*args, &block)
|
5
|
+
block.call(*args)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Model
|
10
|
+
extend ActiveModel::Naming
|
11
|
+
|
12
|
+
def to_key
|
13
|
+
Array('1')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
1
17
|
class Person < Struct.new(:name)
|
2
18
|
end
|
3
19
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Helpers
|
4
|
+
describe ConfigObject do
|
5
|
+
|
6
|
+
let(:context_class) {
|
7
|
+
Class.new do
|
8
|
+
def foo
|
9
|
+
'foo'
|
10
|
+
end
|
11
|
+
|
12
|
+
def bar
|
13
|
+
'bar'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
}
|
17
|
+
let(:context) { context_class.new }
|
18
|
+
|
19
|
+
describe 'to_hash' do
|
20
|
+
it 'accepts attr=() notation' do
|
21
|
+
result = ConfigObject.new(context) do |c|
|
22
|
+
c.first = foo
|
23
|
+
c.second = bar
|
24
|
+
c.third = '3rd'
|
25
|
+
end.to_hash
|
26
|
+
|
27
|
+
hash = { first: 'foo', second: 'bar', third: '3rd' }
|
28
|
+
expect(result).to eq hash
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'accepts attr() notation' do
|
32
|
+
result = ConfigObject.new(context) do |c|
|
33
|
+
c.first foo
|
34
|
+
c.second bar
|
35
|
+
c.third '3rd'
|
36
|
+
end.to_hash
|
37
|
+
|
38
|
+
hash = { first: 'foo', second: 'bar', third: '3rd' }
|
39
|
+
expect(result).to eq hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Helpers
|
4
|
+
describe SeoMetaBuilder do
|
5
|
+
|
6
|
+
let(:view) { RailsViewContext.new }
|
7
|
+
let(:builder) { double('SeoMetaBuilder') }
|
8
|
+
|
9
|
+
subject { SeoMetaBuilder.new(view) }
|
10
|
+
|
11
|
+
describe '#title' do
|
12
|
+
it 'produces a <title/> tag' do
|
13
|
+
expect(subject.title('foo')).to have_tag(:title, text: 'foo')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'produces a og:title meta tag' do
|
17
|
+
expect(subject.title('foo')).to have_tag(:meta, with: { property: 'og:title', content: 'foo' })
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'produces a twitter:title meta tag' do
|
21
|
+
expect(subject.title('foo')).to have_tag(:meta, with: { name: 'twitter:title', content: 'foo' })
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with multiple values' do
|
25
|
+
it 'uses the first non-blank' do
|
26
|
+
expect(subject.title(['', nil, 'foo'])).to have_tag(:title, text: 'foo')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a :title_suffix option' do
|
31
|
+
it 'produces a <title/> tag with the suffix' do
|
32
|
+
expect(subject.title('foo', title_suffix: ' - bar')).to have_tag(:title, text: 'foo - bar')
|
33
|
+
end
|
34
|
+
it 'does not suffix meta tags' do
|
35
|
+
expect(subject.title('foo')).to have_tag(:meta, with: { property: 'og:title', content: 'foo' })
|
36
|
+
expect(subject.title('foo')).to have_tag(:meta, with: { name: 'twitter:title', content: 'foo' })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#description' do
|
42
|
+
it 'produces a description meta tag' do
|
43
|
+
expect(subject.description('foo')).to have_tag(:meta, with: { name: 'description', content: 'foo' })
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'produces a og:description meta tag' do
|
47
|
+
expect(subject.description('foo')).to have_tag(:meta, with: { property: 'og:description', content: 'foo' })
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'produces a twitter:description meta tag' do
|
51
|
+
expect(subject.description('foo')).to have_tag(:meta, with: { name: 'twitter:description', content: 'foo' })
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with multiple values' do
|
55
|
+
it 'uses the first non-blank' do
|
56
|
+
expect(subject.description(['', nil, 'foo'])).to have_tag(:meta, with: { name: 'description', content: 'foo' })
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#image_url' do
|
62
|
+
it 'produces a og:image meta tag' do
|
63
|
+
expect(subject.image_url('foo')).to have_tag(:meta, with: { property: 'og:image', content: 'foo' })
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'produces a twitter:image meta tag' do
|
67
|
+
expect(subject.image_url('foo')).to have_tag(:meta, with: { name: 'twitter:image', content: 'foo' })
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with multiple values' do
|
71
|
+
it 'uses the first non-blank' do
|
72
|
+
expect(subject.image_url(['', nil, 'foo'])).to have_tag(:meta, with: { property: 'og:image', content: 'foo' })
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#canonical_url' do
|
78
|
+
it 'produces a og:url meta tag' do
|
79
|
+
expect(subject.canonical_url('foo')).to have_tag(:meta, with: { property: 'og:url', content: 'foo' })
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'produces a canonical link tag' do
|
83
|
+
expect(subject.canonical_url('foo')).to have_tag(:link, with: { rel: 'canonical', href: 'foo' })
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with multiple values' do
|
87
|
+
it 'uses the first non-blank' do
|
88
|
+
expect(subject.canonical_url(['', nil, 'foo'])).to have_tag(:meta, with: { property: 'og:url', content: 'foo' })
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Showcase::Helpers do
|
4
|
+
let(:object) { Person.new('Steve Ballmer') }
|
5
|
+
let(:context) { Context.new }
|
6
|
+
|
7
|
+
describe '.present' do
|
8
|
+
it 'instanciate a new presenter, inferring the class' do
|
9
|
+
PersonPresenter.stub(:new).with(object, context).and_return 'Presenter'
|
10
|
+
context.present(object, PersonPresenter).should == 'Presenter'
|
11
|
+
end
|
12
|
+
it 'the presenter class to use can be specified as the second parameter' do
|
13
|
+
ProjectPresenter.stub(:new).with(object, context).and_return 'Presenter'
|
14
|
+
context.present(object, ProjectPresenter).should == 'Presenter'
|
15
|
+
end
|
16
|
+
it 'the context to use can be specified as third parameter' do
|
17
|
+
different_context = double
|
18
|
+
context.present(object, ProjectPresenter, different_context).view_context.should == different_context
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.present_collection' do
|
23
|
+
it 'returns a presenter for each object in the collection' do
|
24
|
+
collection = [ Person.new('Mark'), Person.new('Luke') ]
|
25
|
+
|
26
|
+
PersonPresenter.stub(:new).with(collection[0], context).and_return 'foo'
|
27
|
+
PersonPresenter.stub(:new).with(collection[1], context).and_return 'bar'
|
28
|
+
|
29
|
+
presented_collection = context.present_collection(collection)
|
30
|
+
presented_collection.should == [ 'foo', 'bar' ]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -1,8 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
Coveralls.wear!
|
3
|
-
|
4
|
-
require 'showcase'
|
5
|
-
require_relative './fixtures'
|
1
|
+
require 'spec_helper'
|
6
2
|
|
7
3
|
describe Showcase::Presenter do
|
8
4
|
let(:context) { Context.new }
|
@@ -73,35 +69,3 @@ describe Showcase::Presenter do
|
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
76
|
-
describe Showcase::Helpers do
|
77
|
-
let(:object) { Person.new('Steve Ballmer') }
|
78
|
-
let(:context) { Context.new }
|
79
|
-
|
80
|
-
describe '.present' do
|
81
|
-
it 'instanciate a new presenter, inferring the class' do
|
82
|
-
PersonPresenter.stub(:new).with(object, context).and_return 'Presenter'
|
83
|
-
context.present(object, PersonPresenter).should == 'Presenter'
|
84
|
-
end
|
85
|
-
it 'the presenter class to use can be specified as the second parameter' do
|
86
|
-
ProjectPresenter.stub(:new).with(object, context).and_return 'Presenter'
|
87
|
-
context.present(object, ProjectPresenter).should == 'Presenter'
|
88
|
-
end
|
89
|
-
it 'the context to use can be specified as third parameter' do
|
90
|
-
different_context = double
|
91
|
-
context.present(object, ProjectPresenter, different_context).view_context.should == different_context
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe '.present_collection' do
|
96
|
-
it 'returns a presenter for each object in the collection' do
|
97
|
-
collection = [ Person.new('Mark'), Person.new('Luke') ]
|
98
|
-
|
99
|
-
PersonPresenter.stub(:new).with(collection[0], context).and_return 'foo'
|
100
|
-
PersonPresenter.stub(:new).with(collection[1], context).and_return 'bar'
|
101
|
-
|
102
|
-
presented_collection = context.present_collection(collection)
|
103
|
-
presented_collection.should == [ 'foo', 'bar' ]
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Traits
|
4
|
+
describe Base do
|
5
|
+
describe '.define_method?' do
|
6
|
+
|
7
|
+
it 'defines an instance method' do
|
8
|
+
klass = Class.new do
|
9
|
+
include Base
|
10
|
+
define_method? :foo do
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
expect(klass.new.foo).to be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'if the method is already present' do
|
19
|
+
it 'no-ops ' do
|
20
|
+
klass = Class.new do
|
21
|
+
include Base
|
22
|
+
def foo; false; end
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(klass.new.foo).to be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'if method name is an array of chunks' do
|
30
|
+
it 'joins them in snake case' do
|
31
|
+
klass = Class.new do
|
32
|
+
include Base
|
33
|
+
define_method? [:foo, :bar] do
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(klass.new.foo_bar).to be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'ignores blank chunks' do
|
42
|
+
klass = Class.new do
|
43
|
+
include Base
|
44
|
+
define_method? ["", :bar] do
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
expect(klass.new.bar).to be_true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Traits
|
4
|
+
describe LinkTo do
|
5
|
+
|
6
|
+
let(:view) { RailsViewContext.new }
|
7
|
+
let(:record) { Model.new }
|
8
|
+
subject { presenter.new(record, view) }
|
9
|
+
|
10
|
+
let(:active) { false }
|
11
|
+
before do
|
12
|
+
record.stub(:active).and_return(active)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:presenter) {
|
16
|
+
Class.new(Showcase::Presenter) do
|
17
|
+
include LinkTo
|
18
|
+
|
19
|
+
link_to do |c|
|
20
|
+
c.url = url
|
21
|
+
c.label = 'Label'
|
22
|
+
c.active = active
|
23
|
+
c.html_options role: 'label'
|
24
|
+
end
|
25
|
+
|
26
|
+
link_to :foo do |c|
|
27
|
+
c.url = '#foo'
|
28
|
+
c.active_class = 'current'
|
29
|
+
c.active = active
|
30
|
+
end
|
31
|
+
|
32
|
+
def url
|
33
|
+
'#bar'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
describe '#link_to' do
|
39
|
+
|
40
|
+
context 'defines a link method' do
|
41
|
+
it 'pointing to the specified url' do
|
42
|
+
expect(subject.link).to have_tag(:a, with: { href: '#bar' })
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'with the specified label' do
|
46
|
+
expect(subject.link).to have_tag(:a, text: 'Label')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'with the specified html attributes' do
|
50
|
+
expect(subject.link).to have_tag(:a, with: { role: 'label' })
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with a different label as parameter' do
|
54
|
+
it 'uses it' do
|
55
|
+
expect(subject.link('Foo')).to have_tag(:a, text: 'Foo')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with additional options' do
|
60
|
+
it 'uses them as html options' do
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with a block' do
|
65
|
+
it 'uses it instead of the label' do
|
66
|
+
result = subject.link { 'Foo' }
|
67
|
+
expect(result).to have_tag(:a, text: 'Foo')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'if active' do
|
72
|
+
let(:active) { true }
|
73
|
+
|
74
|
+
it 'adds an active class to the link' do
|
75
|
+
expect(subject.link('label')).to have_tag(:a, with: { class: 'active' })
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with additional classes' do
|
79
|
+
it 'it sums them' do
|
80
|
+
expect(subject.link('label', class: 'extra')).to have_tag(:a, with: { class: 'extra active' })
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'if a different CSS class was specified' do
|
85
|
+
it 'adds it to the link' do
|
86
|
+
expect(subject.foo_link('label')).to have_tag(:a, with: { class: 'current' })
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'defines an link_active? method' do
|
93
|
+
let(:active) { double }
|
94
|
+
|
95
|
+
it 'returns the active flag' do
|
96
|
+
expect(subject.link_active?).to eq active
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'defines an url method' do
|
101
|
+
it 'returns the url' do
|
102
|
+
expect(subject.url).to eq '#bar'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with prefix' do
|
107
|
+
it 'prefixes link method' do
|
108
|
+
expect(subject).to respond_to :foo_link
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'prefixes link_active? method' do
|
112
|
+
expect(subject).to respond_to :foo_link_active?
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'prefixes url method' do
|
116
|
+
expect(subject).to respond_to :foo_url
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Traits
|
4
|
+
describe Record do
|
5
|
+
|
6
|
+
let(:view) { RailsViewContext.new }
|
7
|
+
let(:record) { Model.new }
|
8
|
+
let(:presenter) {
|
9
|
+
Class.new(Showcase::Presenter) do
|
10
|
+
include Record
|
11
|
+
|
12
|
+
box do |c|
|
13
|
+
c.html_options role: 'actor', class: 'first'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
}
|
17
|
+
subject { presenter.new(record, view) }
|
18
|
+
|
19
|
+
describe '#dom_id' do
|
20
|
+
it 'returns a CSS ID for the model' do
|
21
|
+
expect(subject.dom_id).to eq 'model_1'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#dom_class' do
|
26
|
+
it 'returns a CSS class for model' do
|
27
|
+
expect(subject.dom_class).to eq 'model'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#box' do
|
32
|
+
it 'wraps content inside an element that uniquely identifies the record' do
|
33
|
+
result = subject.box { "foo" }
|
34
|
+
expect(result).to have_tag(:div, with: { class: 'model', id: 'model_1' })
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'adds attributes specified within box block' do
|
38
|
+
result = subject.box { "foo" }
|
39
|
+
expect(result).to have_tag(:div, with: { role: 'actor', class: 'first' })
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with a specified tag' do
|
43
|
+
it 'uses it' do
|
44
|
+
result = subject.box(:span) { "foo" }
|
45
|
+
expect(result).to have_tag(:span)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with some class' do
|
50
|
+
it 'uses it' do
|
51
|
+
result = subject.box(class: 'bar') { "foo" }
|
52
|
+
expect(result).to have_tag(:div, with: { class: 'model bar'})
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Traits
|
4
|
+
describe Seo do
|
5
|
+
|
6
|
+
let(:view) { RailsViewContext.new }
|
7
|
+
let(:record) { Model.new }
|
8
|
+
let(:builder) { double('SeoMetaBuilder') }
|
9
|
+
subject { presenter.new(record, view) }
|
10
|
+
|
11
|
+
let(:presenter) {
|
12
|
+
Class.new(Showcase::Presenter) do
|
13
|
+
include Seo
|
14
|
+
|
15
|
+
seo do |c|
|
16
|
+
c.title = 'foo'
|
17
|
+
c.description 'bar'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
22
|
+
describe '#seo' do
|
23
|
+
let(:options) { double('options') }
|
24
|
+
before do
|
25
|
+
Showcase::Helpers::SeoMetaBuilder.stub(:new).with(view).and_return(builder)
|
26
|
+
builder.stub(:title).with('foo', options).and_return('<title>')
|
27
|
+
builder.stub(:description).with('bar', options).and_return('<description>')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'defines a seo_tags method that ouputs seo meta tags' do
|
31
|
+
expect(subject.seo_tags(options)).to eq '<title><description>'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Showcase::Traits
|
4
|
+
describe Share do
|
5
|
+
|
6
|
+
let(:view) { RailsViewContext.new }
|
7
|
+
let(:record) { Model.new }
|
8
|
+
subject { presenter.new(record, view) }
|
9
|
+
|
10
|
+
let(:presenter) {
|
11
|
+
Class.new(Showcase::Presenter) do
|
12
|
+
include Share
|
13
|
+
|
14
|
+
share do |c|
|
15
|
+
c.url = 'url'
|
16
|
+
c.text = 'text'
|
17
|
+
c.image_url = 'image'
|
18
|
+
end
|
19
|
+
|
20
|
+
share :foo do |c|
|
21
|
+
c.url = 'url'
|
22
|
+
c.text = 'text'
|
23
|
+
c.image_url = 'image'
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
}
|
28
|
+
|
29
|
+
describe '#social_share' do
|
30
|
+
expected_urls = {
|
31
|
+
twitter: "https://twitter.com/intent/tweet?text=text&url=url",
|
32
|
+
facebook: "http://www.facebook.com/sharer/sharer.php?u=url",
|
33
|
+
gplus: "https://plus.google.com/share?url=url",
|
34
|
+
pinterest: "http://www.pinterest.com/pin/create/button/?media=image&title=text&url=url",
|
35
|
+
linkedin: "http://www.linkedin.com/shareArticle?title=text&url=url",
|
36
|
+
}
|
37
|
+
|
38
|
+
expected_urls.each do |provider, url|
|
39
|
+
it "produces a #{provider} share link" do
|
40
|
+
expect(subject.send("#{provider}_share_link")).to have_tag(:a)
|
41
|
+
end
|
42
|
+
it "produces a #{provider} share url" do
|
43
|
+
expect(subject.send("#{provider}_share_url")).to eq url
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with prefix' do
|
47
|
+
it 'prefixes link method' do
|
48
|
+
expect(subject).to respond_to "foo_#{provider}_share_link"
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'prefixes link_active? method' do
|
52
|
+
expect(subject).to respond_to "foo_#{provider}_share_url"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|