sir_trevor_rails 0.5.0b1 → 0.5.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 +4 -4
- data/.travis.yml +8 -0
- data/app/views/sir_trevor/blocks/_heading_block.html.erb +3 -1
- data/app/views/sir_trevor/blocks/_list_block.html.erb +9 -1
- data/app/views/sir_trevor/blocks/_quote_block.html.erb +7 -1
- data/app/views/sir_trevor/blocks/_text_block.html.erb +1 -1
- data/app/views/sir_trevor/blocks/_tweet_block.html.erb +3 -3
- data/lib/generators/sir_trevor_rails/block/block_generator.rb +16 -11
- data/lib/generators/sir_trevor_rails/block/templates/_block.html.erb +3 -3
- data/lib/generators/sir_trevor_rails/block/templates/{_block.js → _block.js.erb} +4 -6
- data/lib/generators/sir_trevor_rails/block/templates/_block.rb.erb +2 -0
- data/lib/sir_trevor_rails/block.rb +15 -5
- data/lib/sir_trevor_rails/block_array.rb +17 -5
- data/lib/sir_trevor_rails/blocks/tweet_block.rb +6 -4
- data/lib/sir_trevor_rails/helpers/view_helper.rb +21 -2
- data/lib/sir_trevor_rails/version.rb +1 -1
- data/lib/sir_trevor_rails/view_resolver.rb +3 -3
- data/sir_trevor_rails.gemspec +4 -2
- data/spec/fixtures/blocks/custom.json +7 -0
- data/spec/fixtures/blocks/heading_html.json +7 -0
- data/spec/fixtures/blocks/heading_markdown.json +6 -0
- data/spec/fixtures/blocks/image.json +26 -0
- data/spec/fixtures/blocks/list_html.json +10 -0
- data/spec/fixtures/blocks/list_markdown.json +6 -0
- data/spec/fixtures/blocks/quote_html.json +8 -0
- data/spec/fixtures/blocks/quote_markdown.json +7 -0
- data/spec/fixtures/blocks/text_html.json +7 -0
- data/spec/fixtures/blocks/text_markdown.json +6 -0
- data/spec/fixtures/blocks/tweet.json +21 -0
- data/spec/integration/editing_spec.rb +19 -0
- data/spec/integration/rendering_spec.rb +121 -0
- data/spec/internal/app/controllers/posts_controller.rb +33 -0
- data/spec/internal/app/models/post.rb +2 -0
- data/spec/internal/app/views/posts/_form.html.erb +3 -0
- data/spec/internal/app/views/posts/edit.html.erb +3 -0
- data/spec/internal/app/views/posts/new.html.erb +3 -0
- data/spec/internal/app/views/posts/show.html.erb +1 -0
- data/spec/internal/config/routes.rb +1 -1
- data/spec/spec_helper.rb +42 -1
- data/spec/unit/block_array_spec.rb +21 -11
- data/spec/unit/block_spec.rb +10 -4
- data/spec/unit/custom_block_spec.rb +10 -8
- data/spec/unit/has_sir_trevor_content_spec.rb +2 -8
- data/spec/unit/helpers_spec.rb +44 -0
- metadata +96 -10
- data/lib/generators/sir_trevor_rails/block/templates/_block.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63883a02cdf49d08e2ecfc4b3ecd307396d4b9c8
|
4
|
+
data.tar.gz: 81b858f079c3632f141414bd4ed19b197edd1b05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d80735fb35626d3be73f46a844007c8b6541118b65f5d5db1b48401475dad94e9840b9564d236493457fb463e0eed2c9e35bb00d4043cd681b33021e9170cec2
|
7
|
+
data.tar.gz: 9e9d4e118c9c541d7afa0f2ce96152de64b1e136fb83561f3cc0f31c460e749515b96237b399c2534dfa04bdbd10dc1a46c5ffd79c613d570142f9f4827908ca
|
data/.travis.yml
ADDED
@@ -1,3 +1,11 @@
|
|
1
1
|
<div class="st__content-block st__content-block--list">
|
2
|
-
|
2
|
+
<% if list_block.format == :html %>
|
3
|
+
<ul>
|
4
|
+
<% list_block.listItems.each do |item| %>
|
5
|
+
<li><%= sir_trevor_format item[:content], format: list_block.format %></li>
|
6
|
+
<% end %>
|
7
|
+
</ul>
|
8
|
+
<% else %>
|
9
|
+
<%= sir_trevor_markdown list_block.text %>
|
10
|
+
<% end %>
|
3
11
|
</div>
|
@@ -1,7 +1,13 @@
|
|
1
1
|
<div class="st__content-block st__content-block--quote">
|
2
2
|
<div class="quote">
|
3
3
|
<div class="quote__content">
|
4
|
-
|
4
|
+
<% if quote_block.format == :html %>
|
5
|
+
<blockquote>
|
6
|
+
<%= sir_trevor_format quote_block.text, format: quote_block.format %>
|
7
|
+
</blockquote>
|
8
|
+
<% else %>
|
9
|
+
<%= sir_trevor_markdown quote_block.text %>
|
10
|
+
<% end %>
|
5
11
|
</div>
|
6
12
|
|
7
13
|
<% if quote_block.cite.present? %>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<div class="st__content-block st__content-block--tweet">
|
2
|
-
<%= link_to image_tag(tweet_block.profile_image_url, class: 'img'), tweet_block.
|
2
|
+
<%= link_to image_tag(tweet_block.profile_image_url, class: 'img'), tweet_block.profile_url %>
|
3
3
|
<p>
|
4
4
|
<%= tweet_block.render_tweet_body %>
|
5
5
|
</p>
|
6
|
-
<cite>From <%= link_to tweet_block.at_name, tweet_block.
|
7
|
-
<time datetime="<%= tweet_block.created_at %>">(<%= link_to Time.parse(tweet_block.created_at), tweet_block.status_url %>)</time>
|
6
|
+
<cite>From <%= link_to tweet_block.at_name, tweet_block.profile_url %> on Twitter:</cite>
|
7
|
+
<time datetime="<%= tweet_block.created_at %>">(<%= link_to Time.zone.parse(tweet_block.created_at), tweet_block.status_url %>)</time>
|
8
8
|
</div>
|
9
9
|
|
@@ -11,23 +11,28 @@ module SirTrevorRails
|
|
11
11
|
def create_block
|
12
12
|
|
13
13
|
# Copy the JS
|
14
|
-
|
15
|
-
|
16
|
-
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /SirTrevor\.Blocks\.Example/, "SirTrevor.Blocks.#{name.capitalize}"
|
17
|
-
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /return "Example"/, "return: '#{name.capitalize}'"
|
18
|
-
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /type: 'example'/, "type: '#{name.downcase}'"
|
14
|
+
template "_block.js.erb", "app/assets/javascripts/sir_trevor/blocks/#{file_name}.js"
|
19
15
|
|
20
16
|
# Copy the HTML
|
21
|
-
|
22
|
-
gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(-block)/, " #{name}-block"
|
23
|
-
gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(_block)/, " #{name}_block"
|
17
|
+
template "_block.html.erb", "app/views/sir_trevor/blocks/_#{file_name}_block.html.erb"
|
24
18
|
|
25
19
|
# Copy the BlockDecorator
|
26
|
-
|
27
|
-
|
20
|
+
template "_block.rb.erb", "app/sir_trevor_blocks/#{file_name}_block.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
28
24
|
|
25
|
+
def file_name
|
26
|
+
name.underscore
|
29
27
|
end
|
30
28
|
|
29
|
+
def block_name
|
30
|
+
file_name.camelize
|
31
|
+
end
|
32
|
+
|
33
|
+
def css_class
|
34
|
+
file_name.dasherize
|
35
|
+
end
|
31
36
|
end
|
32
37
|
end
|
33
|
-
end
|
38
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<div class="content-block
|
2
|
-
<%=
|
3
|
-
</div>
|
1
|
+
<div class="content-block <%= css_class %>-block">
|
2
|
+
<%%= <%= file_name %>_block %>
|
3
|
+
</div>
|
@@ -4,20 +4,18 @@
|
|
4
4
|
Author: C J Bell @ madebymany
|
5
5
|
*/
|
6
6
|
|
7
|
-
SirTrevor.Blocks
|
8
|
-
|
7
|
+
SirTrevor.Blocks.<%= block_name %> = (function(){
|
9
8
|
return SirTrevor.Block.extend({
|
10
|
-
|
11
9
|
// String; Names the block
|
12
10
|
// Note – please use underscores when naming
|
13
11
|
// Eg example_block should be ExampleBlock
|
14
|
-
type: '
|
12
|
+
type: '<%= file_name %>',
|
15
13
|
|
16
14
|
// Function; the title displayed in the toolbar
|
17
15
|
// Can return a translated string (if required)
|
18
16
|
title: function() {
|
19
17
|
// return i18n.t('blocks:example:title');
|
20
|
-
return "
|
18
|
+
return "<%= block_name %>";
|
21
19
|
},
|
22
20
|
|
23
21
|
// Boolean; show this blockType of the toolbar
|
@@ -200,4 +198,4 @@ SirTrevor.Blocks.Example = (function(){
|
|
200
198
|
}
|
201
199
|
});
|
202
200
|
|
203
|
-
})();
|
201
|
+
})();
|
@@ -2,26 +2,37 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module SirTrevorRails
|
4
4
|
class Block < OpenStruct
|
5
|
+
DEFAULT_FORMAT = :markdown
|
5
6
|
|
6
7
|
def self.from_hash(hash, parent)
|
7
|
-
hash = hash.deep_dup
|
8
|
+
hash = hash.deep_dup.with_indifferent_access
|
8
9
|
self.type_klass(hash).new(hash, parent)
|
9
10
|
end
|
10
11
|
|
12
|
+
def format
|
13
|
+
send(:[], :format).present? ? send(:[], :format).to_sym : DEFAULT_FORMAT
|
14
|
+
end
|
15
|
+
|
11
16
|
def initialize(hash, parent)
|
12
|
-
@
|
17
|
+
@raw_data = hash
|
13
18
|
@parent = parent
|
14
19
|
@type = hash[:type].to_sym
|
15
|
-
|
16
20
|
super(hash[:data])
|
17
21
|
end
|
18
22
|
|
19
|
-
attr_reader :parent, :type
|
23
|
+
attr_reader :parent, :type
|
20
24
|
|
21
25
|
def to_partial_path
|
22
26
|
"sir_trevor/blocks/" << self.class.name.demodulize.underscore
|
23
27
|
end
|
24
28
|
|
29
|
+
def as_json(*attrs)
|
30
|
+
{
|
31
|
+
type: @type.to_s,
|
32
|
+
data: marshal_dump
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
25
36
|
private
|
26
37
|
|
27
38
|
# Infers the block class.
|
@@ -58,6 +69,5 @@ module SirTrevorRails
|
|
58
69
|
self
|
59
70
|
end
|
60
71
|
end
|
61
|
-
|
62
72
|
end
|
63
73
|
end
|
@@ -1,11 +1,23 @@
|
|
1
1
|
module SirTrevorRails
|
2
2
|
class BlockArray < Array
|
3
3
|
|
4
|
-
def self.from_json(
|
5
|
-
blocks
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def self.from_json(blocks, parent = nil)
|
5
|
+
if blocks.is_a?(String)
|
6
|
+
blocks = MultiJson.load(blocks, symbolize_keys: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
if blocks.is_a?(Hash)
|
10
|
+
blocks = blocks[:data] || blocks['data'] or
|
11
|
+
raise IndexError, "No block data found"
|
12
|
+
end
|
13
|
+
|
14
|
+
new blocks.map { |obj|
|
15
|
+
SirTrevorRails::Block.from_hash(obj.deep_symbolize_keys, parent)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
{data: as_json}.to_json
|
9
21
|
end
|
10
22
|
|
11
23
|
def has_block_of_type?(type)
|
@@ -25,11 +25,13 @@ module SirTrevorRails
|
|
25
25
|
"@" << screen_name
|
26
26
|
end
|
27
27
|
|
28
|
-
def profile_image_url
|
29
|
-
|
30
|
-
|
28
|
+
def profile_image_url
|
29
|
+
# TODO: add support for different size images: https://dev.twitter.com/overview/general/user-profile-images-and-banners
|
30
|
+
|
31
|
+
# Split the URL to omit the protocol and let the browser define the context (note: assumes asset is available over both HTTP and HTTPS)
|
32
|
+
"//" << self.user[:profile_image_url].split("://")[1]
|
31
33
|
end
|
32
34
|
|
33
35
|
end
|
34
36
|
end
|
35
|
-
end
|
37
|
+
end
|
@@ -2,15 +2,34 @@ module SirTrevorRails
|
|
2
2
|
module Helpers
|
3
3
|
module ViewHelper
|
4
4
|
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
include ActionView::Helpers::SanitizeHelper
|
7
|
+
end
|
8
|
+
|
9
|
+
def sir_trevor_format(text, format: :markdown)
|
10
|
+
if format.to_s.to_sym == :html
|
11
|
+
sir_trevor_html(text)
|
12
|
+
else
|
13
|
+
sir_trevor_markdown(text)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def sir_trevor_html(text)
|
18
|
+
sanitize(text, tags: %w(b i a br p))
|
19
|
+
end
|
5
20
|
|
6
21
|
def sir_trevor_markdown(text)
|
7
|
-
|
22
|
+
rndr = CustomMarkdownFormatter.new(hard_wrap: true, filter_html: true,
|
8
23
|
autolink: true, no_intraemphasis: true,
|
9
24
|
fenced_code: true)
|
10
25
|
|
11
|
-
markdown = Redcarpet::Markdown.new(
|
26
|
+
markdown = Redcarpet::Markdown.new(rndr)
|
12
27
|
markdown.render(text).html_safe
|
13
28
|
end
|
29
|
+
|
30
|
+
def without_p_wrap(html)
|
31
|
+
Regexp.new('^<p>(.*)<\/p>$').match(html)[1].html_safe rescue html
|
32
|
+
end
|
14
33
|
end
|
15
34
|
end
|
16
35
|
end
|
@@ -5,9 +5,9 @@ module SirTrevorRails
|
|
5
5
|
super("app/views")
|
6
6
|
end
|
7
7
|
|
8
|
-
def find_templates(name, prefix,
|
9
|
-
super(name, prefix.gsub(/^(.)+(sir_trevor)/, '\2'),
|
8
|
+
def find_templates(name, prefix, *args)
|
9
|
+
super(name, prefix.gsub(/^(.)+(sir_trevor)/, '\2'), *args)
|
10
10
|
end
|
11
11
|
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
data/sir_trevor_rails.gemspec
CHANGED
@@ -31,9 +31,11 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency "pry-rails"
|
32
32
|
spec.add_development_dependency "combustion"
|
33
33
|
spec.add_development_dependency "sqlite3"
|
34
|
+
spec.add_development_dependency "capybara"
|
35
|
+
spec.add_development_dependency "launchy"
|
34
36
|
|
35
|
-
spec.add_dependency "rails"
|
37
|
+
spec.add_dependency "rails", ">= 3", "< 5"
|
36
38
|
spec.add_dependency "redcarpet", ">= 2.0.1", "< 4"
|
37
39
|
spec.add_dependency "twitter-text", "~> 1.4"
|
38
|
-
|
40
|
+
spec.add_dependency 'multi_json', '~> 1.0'
|
39
41
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"type":"image",
|
3
|
+
"data":{
|
4
|
+
"id":1,
|
5
|
+
"updated_at":"2015-01-01T01:00:00+01:00",
|
6
|
+
"created_at":"2015-01-01T01:00:00+01:00",
|
7
|
+
"file":{
|
8
|
+
"url":"http://placeimg.com/1000/600/any",
|
9
|
+
"thumb":{
|
10
|
+
"url":"http://placeimg.com/100/100/any"
|
11
|
+
},
|
12
|
+
"large":{
|
13
|
+
"url":"http://placeimg.com/800/400/any"
|
14
|
+
},
|
15
|
+
"xlarge":{
|
16
|
+
"url":"http://placeimg.com/1000/600/any"
|
17
|
+
},
|
18
|
+
"medium":{
|
19
|
+
"url":"http://placeimg.com/600/300/any"
|
20
|
+
},
|
21
|
+
"mobile":{
|
22
|
+
"url":"http://placeimg.com/800/400/any"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"type":"tweet",
|
3
|
+
"data":{
|
4
|
+
"user":{
|
5
|
+
"profile_image_url":"http://pbs.twimg.com/profile_images/613336689893896192/5nQjxG2o_normal.jpg",
|
6
|
+
"profile_image_url_https":"https://pbs.twimg.com/profile_images/613336689893896192/5nQjxG2o_normal.jpg",
|
7
|
+
"screen_name":"SachseInTheCity",
|
8
|
+
"name":"Nelson Sachse"
|
9
|
+
},
|
10
|
+
"id":"615846875078504448",
|
11
|
+
"text":"There's no pain without some gain !\n\nlet's run \\o/",
|
12
|
+
"created_at":"Tue Jun 30 11:38:31 +0000 2015",
|
13
|
+
"entities":{
|
14
|
+
"hashtags":[],
|
15
|
+
"symbols":[],
|
16
|
+
"user_mentions":[],
|
17
|
+
"urls":[]
|
18
|
+
},
|
19
|
+
"status_url":"https://twitter.com/SachseInTheCity/status/615846875078504448"
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class EditingSpec < ActionDispatch::IntegrationTest
|
4
|
+
describe 'Edit form' do
|
5
|
+
let(:post) { Post.create(body: blocks_json(:text_html)) }
|
6
|
+
|
7
|
+
it 'serializes BlockArray to correct json' do
|
8
|
+
visit edit_post_path(post)
|
9
|
+
expect { find_field('Body').value == {data: post.body.as_json}.to_json }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'serializes empty BlockArray to empty array json' do
|
13
|
+
post = Post.create()
|
14
|
+
|
15
|
+
visit edit_post_path(post)
|
16
|
+
expect { find_field('Body').value == "{\"data\":[]}" }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class RenderingSpec < ActionDispatch::IntegrationTest
|
4
|
+
describe 'SirTrevorContent rendering' do
|
5
|
+
it 'renders all blocks as separate divs' do
|
6
|
+
post = Post.create(body: blocks_json(:list_html, :text_html))
|
7
|
+
visit post_path(post)
|
8
|
+
|
9
|
+
expect { all('.st__content-block').length == 2 }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'Text block' do
|
14
|
+
it 'renders markdown format' do
|
15
|
+
create_and_visit(blocks_json(:text_markdown))
|
16
|
+
|
17
|
+
expect { find_block(:text).text == "One two three four" }
|
18
|
+
expect { find_block(:text).find('em').text == "two" }
|
19
|
+
expect { find_block(:text).find('strong').text == "three" }
|
20
|
+
expect { find_block(:text).find('a').text == "four" }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'renders html format' do
|
24
|
+
create_and_visit(blocks_json(:text_html))
|
25
|
+
|
26
|
+
expect { find_block(:text).text == "One two three four" }
|
27
|
+
expect { find_block(:text).find('i').text == "two" }
|
28
|
+
expect { find_block(:text).find('b').text == "three" }
|
29
|
+
expect { find_block(:text).find('a').text == "four" }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'List block' do
|
34
|
+
it 'renders markdown format' do
|
35
|
+
create_and_visit(blocks_json(:list_markdown))
|
36
|
+
|
37
|
+
expect { find_block(:list).text == "List Item 1 List Item 2" }
|
38
|
+
expect { find_block(:list).all('li').first.text == "List Item 1" }
|
39
|
+
expect { find_block(:list).all('li').last.text == "List Item 2" }
|
40
|
+
expect { find_block(:list).first('strong').text == "List Item 2" }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'renders html format' do
|
44
|
+
create_and_visit(blocks_json(:list_html))
|
45
|
+
|
46
|
+
expect { find_block(:list).text == "List Item 1 List Item 2" }
|
47
|
+
expect { find_block(:list).all('li').first.text == "List Item 1" }
|
48
|
+
expect { find_block(:list).all('li').last.text == "List Item 2" }
|
49
|
+
expect { find_block(:list).first('b').text == "List Item 2" }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'Image block' do
|
54
|
+
it 'renders correctly' do
|
55
|
+
create_and_visit(blocks_json(:image))
|
56
|
+
expect { find_block(:image).find("img")[:src] == "http://placeimg.com/1000/600/any" }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'Heading block' do
|
61
|
+
it 'renders markdown format' do
|
62
|
+
create_and_visit(blocks_json(:heading_markdown))
|
63
|
+
|
64
|
+
expect { find_block(:heading).text == "Heading 1" }
|
65
|
+
expect { find_block(:heading).find('em').text == "1" }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'renders html format' do
|
69
|
+
create_and_visit(blocks_json(:heading_html))
|
70
|
+
|
71
|
+
expect { find_block(:heading).text == "Heading 1" }
|
72
|
+
expect { find_block(:heading).find('i').text == "1" }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'Quote block' do
|
77
|
+
it 'renders markdown format' do
|
78
|
+
create_and_visit(blocks_json(:quote_markdown))
|
79
|
+
|
80
|
+
expect { find_block(:quote).find('blockquote').text == "This is quoted text" }
|
81
|
+
expect { find_block(:quote).find('cite').text == "– Author" }
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'renders html format' do
|
85
|
+
create_and_visit(blocks_json(:quote_html))
|
86
|
+
|
87
|
+
expect { find_block(:quote).find('blockquote').text == "This is quoted text" }
|
88
|
+
expect { find_block(:quote).find('cite').text == "– Author" }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'Tweet block' do
|
93
|
+
it 'renders correctly' do
|
94
|
+
create_and_visit(blocks_json(:tweet))
|
95
|
+
expect { find_block(:tweet).all('a')[0][:href] == "//twitter.com/SachseInTheCity" }
|
96
|
+
expect { find_block(:tweet).find('img')[:src] == "//pbs.twimg.com/profile_images/613336689893896192/5nQjxG2o_normal.jpg" }
|
97
|
+
|
98
|
+
expect { find_block(:tweet).find('p').text == "There's no pain without some gain ! let's run \\o/" }
|
99
|
+
|
100
|
+
expect { find_block(:tweet).find('cite').text == "From @SachseInTheCity on Twitter:" }
|
101
|
+
|
102
|
+
expect { find_block(:tweet).all('a')[1][:href] == "//twitter.com/SachseInTheCity" }
|
103
|
+
expect { find_block(:tweet).all('a')[1].text == "@SachseInTheCity" }
|
104
|
+
|
105
|
+
expect { find_block(:tweet).find('time')[:datetime] == "Tue Jun 30 11:38:31 +0000 2015" }
|
106
|
+
expect { find_block(:tweet).find('time').text == "(#{Time.zone.parse("Tue Jun 30 11:38:31 +0000 2015")})" }
|
107
|
+
|
108
|
+
expect { find_block(:tweet).all('a')[2][:href] == "https://twitter.com/SachseInTheCity/status/615846875078504448" }
|
109
|
+
expect { find_block(:tweet).all('a')[2].text == Time.zone.parse("Tue Jun 30 11:38:31 +0000 2015").to_s }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_and_visit(json)
|
114
|
+
post = Post.create(body: json)
|
115
|
+
visit post_path(post)
|
116
|
+
end
|
117
|
+
|
118
|
+
def find_block(type)
|
119
|
+
first(".st__content-block--#{type}")
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class PostsController < ActionController::Base
|
2
|
+
def new
|
3
|
+
@post = Post.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def edit
|
7
|
+
@post = Post.find(params[:id])
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@post = Post.new(post_attributes)
|
12
|
+
|
13
|
+
if @post.save
|
14
|
+
redirect_to post_show_path(@post)
|
15
|
+
else
|
16
|
+
render :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def update
|
21
|
+
@post = Post.find(params[:id])
|
22
|
+
|
23
|
+
if @post.update_attributes(post_attributes)
|
24
|
+
redirect_to post_show_path(@post)
|
25
|
+
else
|
26
|
+
render :edit
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def show
|
31
|
+
@post = Post.find(params[:id])
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render @post.body %>
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
require 'sir_trevor_rails'
|
2
2
|
require 'combustion'
|
3
|
+
|
4
|
+
Combustion.initialize! :active_record, :action_view do
|
5
|
+
config.active_support.test_order = :random
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
require 'capybara/rails'
|
3
10
|
require 'minitest/autorun'
|
4
11
|
require 'minitest/spec'
|
5
12
|
require 'minitest/pride'
|
6
13
|
require 'wrong/adapters/minitest'
|
7
14
|
require 'pry'
|
8
15
|
|
9
|
-
Combustion.initialize! :active_record, :action_view
|
10
16
|
|
11
17
|
Wrong.config.alias_assert :expect, override: true
|
12
18
|
|
@@ -14,3 +20,38 @@ MiniTest::Spec.class_eval do
|
|
14
20
|
include Wrong::Assert
|
15
21
|
include Wrong::Helpers
|
16
22
|
end
|
23
|
+
|
24
|
+
module SirTrevorRails::Fixtures
|
25
|
+
def blocks_json(*names)
|
26
|
+
"[" + names.map { |name| block_json(name) }.join(',') + "]"
|
27
|
+
end
|
28
|
+
|
29
|
+
def block_json(name)
|
30
|
+
filename = File.join('fixtures', 'blocks', name.to_s + '.json')
|
31
|
+
path = File.expand_path(filename, File.dirname(__FILE__))
|
32
|
+
|
33
|
+
File.read(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def block_hash(name)
|
37
|
+
MultiJson.load(block_json(name))
|
38
|
+
end
|
39
|
+
|
40
|
+
def blocks_hash(*names)
|
41
|
+
MultiJson.load(blocks_json(*names))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ActiveSupport::TestCase
|
46
|
+
extend MiniTest::Spec::DSL
|
47
|
+
include Wrong::Assert
|
48
|
+
include Wrong::Helpers
|
49
|
+
|
50
|
+
include SirTrevorRails::Fixtures
|
51
|
+
include SirTrevorRails # bad, but we don't have to use full class names
|
52
|
+
end
|
53
|
+
|
54
|
+
class ActionDispatch::IntegrationTest
|
55
|
+
# Make the Capybara DSL available in all integration tests
|
56
|
+
include Capybara::DSL
|
57
|
+
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
class BlockArraySpec < ActiveSupport::TestCase
|
4
4
|
describe BlockArray do
|
5
5
|
describe 'intialization' do
|
6
6
|
subject { BlockArray }
|
7
|
-
let(:text_block) { {type: 'text', data: {text: 'Lorem ipsum'}} }
|
8
|
-
let(:heading_block) { {type: 'heading', data: {text: 'Heading 1'}} }
|
9
7
|
|
10
8
|
it 'can be initialized with an empty JSON array' do
|
11
9
|
array = subject.from_json('[]')
|
@@ -13,25 +11,37 @@ module SirTrevorRails
|
|
13
11
|
end
|
14
12
|
|
15
13
|
it 'can be initialized with multiple block hashes' do
|
16
|
-
|
17
|
-
array = subject.from_json(json)
|
14
|
+
array = subject.from_json(blocks_json(:text_html, :heading_html))
|
18
15
|
|
19
16
|
expect { array.is_a? BlockArray }
|
20
17
|
expect { array.size == 2 }
|
21
18
|
end
|
19
|
+
|
20
|
+
it 'can be initialized with a hash' do
|
21
|
+
ar = subject.from_json({data: blocks_hash(:text_html, :image)})
|
22
|
+
|
23
|
+
expect { ar.is_a? BlockArray }
|
24
|
+
expect { ar.first.type == :text }
|
25
|
+
expect { ar.last.type == :image }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can be initialized with an array' do
|
29
|
+
ar = subject.from_json(blocks_hash(:text_html, :image))
|
30
|
+
|
31
|
+
expect { ar.is_a? BlockArray }
|
32
|
+
expect { ar.first.type == :text }
|
33
|
+
expect { ar.last.type == :image }
|
34
|
+
end
|
22
35
|
end
|
23
36
|
|
24
37
|
describe 'instance methods' do
|
25
|
-
let(:
|
26
|
-
let(:other_text_block) { {type: 'text', data: {text: 'Other text block'}} }
|
27
|
-
let(:image_block) { {type: 'image', data: {file: {url: 'http://example.com'}}} }
|
28
|
-
let(:heading_block) { {type: 'heading', data: {text: 'Heading 1'}} }
|
29
|
-
let(:json) { [image_block, text_block, heading_block, other_text_block].to_json }
|
38
|
+
let(:json) { blocks_json :image, :text_html, :heading_html, :text_markdown }
|
30
39
|
|
31
40
|
subject { BlockArray.from_json(json) }
|
32
41
|
|
33
42
|
describe 'has_block_of_type?' do
|
34
43
|
it 'can be called with nonexistent block type' do
|
44
|
+
# no assert needed, if anything was wrong it would raise an exception
|
35
45
|
subject.has_block_of_type? :nonexistent
|
36
46
|
end
|
37
47
|
|
@@ -47,7 +57,7 @@ module SirTrevorRails
|
|
47
57
|
describe 'first_block_of_type' do
|
48
58
|
it 'returns first block of given type in the array' do
|
49
59
|
block = subject.first_block_of_type(:text)
|
50
|
-
assert { block.text
|
60
|
+
assert { block.text.starts_with? "One <i>two</i>" }
|
51
61
|
end
|
52
62
|
|
53
63
|
it 'returns nil if called with block type not in the array' do
|
data/spec/unit/block_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
class BlockSpec < ActiveSupport::TestCase
|
4
4
|
describe Block do
|
5
5
|
describe '.block_class' do
|
6
6
|
subject { Block }
|
@@ -46,11 +46,17 @@ module SirTrevorRails
|
|
46
46
|
end
|
47
47
|
|
48
48
|
describe 'JSON representation' do
|
49
|
-
let(:
|
50
|
-
let(:
|
49
|
+
let(:empty_source_hash) { { type: 'test', data: {} } }
|
50
|
+
let(:empty_block) { Block.from_hash(empty_source_hash, nil) }
|
51
|
+
let(:data_source_hash) { { type: 'test', data: { one: 2, three: 4 } } }
|
52
|
+
let(:data_block) { Block.from_hash(data_source_hash, nil) }
|
51
53
|
|
52
54
|
it 'returns source hash when #as_json is called' do
|
53
|
-
expect {
|
55
|
+
expect { empty_block.as_json == empty_source_hash }
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'serializes block data' do
|
59
|
+
expect { data_block.as_json == data_source_hash }
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
@@ -4,16 +4,18 @@ require 'spec_helper'
|
|
4
4
|
# `spec/internal/app/models/custom_block.rb`, just like it would in real
|
5
5
|
# Rails app.
|
6
6
|
|
7
|
-
|
8
|
-
describe
|
9
|
-
|
7
|
+
class CustomBlockTest < ActiveSupport::TestCase
|
8
|
+
describe CustomBlock do
|
9
|
+
describe "SirTrevorRails::Block" do
|
10
|
+
let(:custom_block_hash) { {type: 'custom', data: {text: 'Body', title: 'name'}} }
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
it 'initialises class defined in the file' do
|
13
|
+
block = SirTrevorRails::Block.from_hash(block_hash(:custom), nil)
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
assert { block.is_a? CustomBlock }
|
16
|
+
assert { block.respond_to? :upcase_title }
|
17
|
+
assert { block.upcase_title == "NAME" }
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -1,15 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
class HasSirTrevorContentSpec < ActiveSupport::TestCase
|
4
4
|
describe 'HasSirTrevorContent' do
|
5
5
|
describe 'initialized for body field' do
|
6
|
-
before do
|
7
|
-
Post.send(:include, HasSirTrevorContent)
|
8
|
-
Post.send(:sir_trevor_content, :body)
|
9
|
-
end
|
10
|
-
|
11
6
|
let(:post) { Post.new }
|
12
|
-
let(:text_block) { {type: 'text', data: {text: 'Lorem ipsum'}} }
|
13
7
|
|
14
8
|
it 'returns BlockArray for initialised field' do
|
15
9
|
assert { post.body.is_a? BlockArray }
|
@@ -28,7 +22,7 @@ module SirTrevorRails
|
|
28
22
|
end
|
29
23
|
|
30
24
|
it 'returns blocks if field is SirTrevor JSON' do
|
31
|
-
post.body =
|
25
|
+
post.body = blocks_json(:text_html)
|
32
26
|
|
33
27
|
assert { post.body.size == 1 }
|
34
28
|
assert { post.body.first.is_a? Block }
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SirTrevorRails
|
4
|
+
describe Helpers do
|
5
|
+
let(:subject) { Class.new.send(:include, Helpers::ViewHelper).new }
|
6
|
+
|
7
|
+
describe 'sir_trevor_format' do
|
8
|
+
it 'is callable' do
|
9
|
+
expect { subject.respond_to? :sir_trevor_format }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'calls sir_trevor_markdown if format is not provided' do
|
13
|
+
subject.stub :sir_trevor_markdown, 'markdown-called' do
|
14
|
+
expect { subject.sir_trevor_format('test') == 'markdown-called' }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'calls sir_trevor_markdown if format == markdown' do
|
19
|
+
subject.stub :sir_trevor_markdown, 'markdown-called' do
|
20
|
+
expect { subject.sir_trevor_format('test', format: :markdown) == 'markdown-called' }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'calls sir_trevor_html if format == html' do
|
25
|
+
subject.stub :sir_trevor_html, 'html-called' do
|
26
|
+
expect { subject.sir_trevor_format('test', format: :html) == 'html-called' }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'sir_trevor_html' do
|
32
|
+
it 'removes not allowed html tags' do
|
33
|
+
html = '<strong><i>Hello<br><a href="http://example.com/">World</a>!</i></strong>'
|
34
|
+
escaped_html = "<i>Hello<br><a href=\"http://example.com/\">World</a>!</i>"
|
35
|
+
expect { subject.sir_trevor_html(html) != html }
|
36
|
+
expect { subject.sir_trevor_html(html) == escaped_html }
|
37
|
+
end
|
38
|
+
it 'retains formatting html tags' do
|
39
|
+
html = '<b><i>Hello<br><a href="http://example.com/">World</a>!</i></b>'
|
40
|
+
expect { subject.sir_trevor_html(html) == html }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sir_trevor_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Sprinz
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2016-01-28 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -112,19 +112,53 @@ dependencies:
|
|
112
112
|
- !ruby/object:Gem::Version
|
113
113
|
version: '0'
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
|
-
name:
|
115
|
+
name: capybara
|
116
116
|
requirement: !ruby/object:Gem::Requirement
|
117
117
|
requirements:
|
118
118
|
- - ">="
|
119
119
|
- !ruby/object:Gem::Version
|
120
120
|
version: '0'
|
121
|
-
type: :
|
121
|
+
type: :development
|
122
122
|
prerelease: false
|
123
123
|
version_requirements: !ruby/object:Gem::Requirement
|
124
124
|
requirements:
|
125
125
|
- - ">="
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '0'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: launchy
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rails
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '3'
|
149
|
+
- - "<"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '5'
|
152
|
+
type: :runtime
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '3'
|
159
|
+
- - "<"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '5'
|
128
162
|
- !ruby/object:Gem::Dependency
|
129
163
|
name: redcarpet
|
130
164
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,6 +193,20 @@ dependencies:
|
|
159
193
|
- - "~>"
|
160
194
|
- !ruby/object:Gem::Version
|
161
195
|
version: '1.4'
|
196
|
+
- !ruby/object:Gem::Dependency
|
197
|
+
name: multi_json
|
198
|
+
requirement: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - "~>"
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '1.0'
|
203
|
+
type: :runtime
|
204
|
+
prerelease: false
|
205
|
+
version_requirements: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - "~>"
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '1.0'
|
162
210
|
description:
|
163
211
|
email:
|
164
212
|
- andrew@madebymany.co.uk
|
@@ -170,6 +218,7 @@ extensions: []
|
|
170
218
|
extra_rdoc_files: []
|
171
219
|
files:
|
172
220
|
- ".gitignore"
|
221
|
+
- ".travis.yml"
|
173
222
|
- CHANGELOG
|
174
223
|
- Gemfile
|
175
224
|
- LICENSE.txt
|
@@ -188,8 +237,8 @@ files:
|
|
188
237
|
- config/initializers/validators.rb
|
189
238
|
- lib/generators/sir_trevor_rails/block/block_generator.rb
|
190
239
|
- lib/generators/sir_trevor_rails/block/templates/_block.html.erb
|
191
|
-
- lib/generators/sir_trevor_rails/block/templates/_block.js
|
192
|
-
- lib/generators/sir_trevor_rails/block/templates/_block.rb
|
240
|
+
- lib/generators/sir_trevor_rails/block/templates/_block.js.erb
|
241
|
+
- lib/generators/sir_trevor_rails/block/templates/_block.rb.erb
|
193
242
|
- lib/generators/sir_trevor_rails/views/views_generator.rb
|
194
243
|
- lib/sir_trevor_rails.rb
|
195
244
|
- lib/sir_trevor_rails/block.rb
|
@@ -202,8 +251,26 @@ files:
|
|
202
251
|
- lib/sir_trevor_rails/version.rb
|
203
252
|
- lib/sir_trevor_rails/view_resolver.rb
|
204
253
|
- sir_trevor_rails.gemspec
|
254
|
+
- spec/fixtures/blocks/custom.json
|
255
|
+
- spec/fixtures/blocks/heading_html.json
|
256
|
+
- spec/fixtures/blocks/heading_markdown.json
|
257
|
+
- spec/fixtures/blocks/image.json
|
258
|
+
- spec/fixtures/blocks/list_html.json
|
259
|
+
- spec/fixtures/blocks/list_markdown.json
|
260
|
+
- spec/fixtures/blocks/quote_html.json
|
261
|
+
- spec/fixtures/blocks/quote_markdown.json
|
262
|
+
- spec/fixtures/blocks/text_html.json
|
263
|
+
- spec/fixtures/blocks/text_markdown.json
|
264
|
+
- spec/fixtures/blocks/tweet.json
|
265
|
+
- spec/integration/editing_spec.rb
|
266
|
+
- spec/integration/rendering_spec.rb
|
267
|
+
- spec/internal/app/controllers/posts_controller.rb
|
205
268
|
- spec/internal/app/models/custom_block.rb
|
206
269
|
- spec/internal/app/models/post.rb
|
270
|
+
- spec/internal/app/views/posts/_form.html.erb
|
271
|
+
- spec/internal/app/views/posts/edit.html.erb
|
272
|
+
- spec/internal/app/views/posts/new.html.erb
|
273
|
+
- spec/internal/app/views/posts/show.html.erb
|
207
274
|
- spec/internal/config/database.yml
|
208
275
|
- spec/internal/config/routes.rb
|
209
276
|
- spec/internal/db/schema.rb
|
@@ -214,6 +281,7 @@ files:
|
|
214
281
|
- spec/unit/block_spec.rb
|
215
282
|
- spec/unit/custom_block_spec.rb
|
216
283
|
- spec/unit/has_sir_trevor_content_spec.rb
|
284
|
+
- spec/unit/helpers_spec.rb
|
217
285
|
homepage: https://github.com/madebymany/sir-trevor-rails
|
218
286
|
licenses:
|
219
287
|
- MIT
|
@@ -229,18 +297,36 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
229
297
|
version: '0'
|
230
298
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
299
|
requirements:
|
232
|
-
- - "
|
300
|
+
- - ">="
|
233
301
|
- !ruby/object:Gem::Version
|
234
|
-
version:
|
302
|
+
version: '0'
|
235
303
|
requirements: []
|
236
304
|
rubyforge_project:
|
237
|
-
rubygems_version: 2.
|
305
|
+
rubygems_version: 2.4.5.1
|
238
306
|
signing_key:
|
239
307
|
specification_version: 4
|
240
308
|
summary: A ruby wrapper for sir trevor content
|
241
309
|
test_files:
|
310
|
+
- spec/fixtures/blocks/custom.json
|
311
|
+
- spec/fixtures/blocks/heading_html.json
|
312
|
+
- spec/fixtures/blocks/heading_markdown.json
|
313
|
+
- spec/fixtures/blocks/image.json
|
314
|
+
- spec/fixtures/blocks/list_html.json
|
315
|
+
- spec/fixtures/blocks/list_markdown.json
|
316
|
+
- spec/fixtures/blocks/quote_html.json
|
317
|
+
- spec/fixtures/blocks/quote_markdown.json
|
318
|
+
- spec/fixtures/blocks/text_html.json
|
319
|
+
- spec/fixtures/blocks/text_markdown.json
|
320
|
+
- spec/fixtures/blocks/tweet.json
|
321
|
+
- spec/integration/editing_spec.rb
|
322
|
+
- spec/integration/rendering_spec.rb
|
323
|
+
- spec/internal/app/controllers/posts_controller.rb
|
242
324
|
- spec/internal/app/models/custom_block.rb
|
243
325
|
- spec/internal/app/models/post.rb
|
326
|
+
- spec/internal/app/views/posts/_form.html.erb
|
327
|
+
- spec/internal/app/views/posts/edit.html.erb
|
328
|
+
- spec/internal/app/views/posts/new.html.erb
|
329
|
+
- spec/internal/app/views/posts/show.html.erb
|
244
330
|
- spec/internal/config/database.yml
|
245
331
|
- spec/internal/config/routes.rb
|
246
332
|
- spec/internal/db/schema.rb
|
@@ -251,4 +337,4 @@ test_files:
|
|
251
337
|
- spec/unit/block_spec.rb
|
252
338
|
- spec/unit/custom_block_spec.rb
|
253
339
|
- spec/unit/has_sir_trevor_content_spec.rb
|
254
|
-
|
340
|
+
- spec/unit/helpers_spec.rb
|