curly-templates 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +4 -2
- data/README.md +76 -3
- data/Rakefile +3 -116
- data/circle.yml +1 -1
- data/curly-templates.gemspec +6 -83
- data/lib/curly.rb +1 -1
- data/lib/curly/compiler.rb +2 -12
- data/lib/curly/component_compiler.rb +6 -3
- data/lib/curly/presenter.rb +32 -20
- data/lib/curly/presenter_name_error.rb +16 -0
- data/lib/curly/rspec.rb +16 -0
- data/lib/curly/version.rb +3 -0
- metadata +14 -72
- data/perf/compile_benchmark.rb +0 -71
- data/perf/compile_profile.rb +0 -64
- data/perf/component_benchmark.rb +0 -41
- data/spec/attribute_scanner_spec.rb +0 -44
- data/spec/collection_blocks_spec.rb +0 -78
- data/spec/compiler/collections_spec.rb +0 -230
- data/spec/compiler/context_blocks_spec.rb +0 -106
- data/spec/compiler_spec.rb +0 -192
- data/spec/component_compiler_spec.rb +0 -107
- data/spec/component_scanner_spec.rb +0 -36
- data/spec/components_spec.rb +0 -43
- data/spec/conditional_blocks_spec.rb +0 -40
- data/spec/dummy/.gitignore +0 -1
- data/spec/dummy/app/controllers/application_controller.rb +0 -2
- data/spec/dummy/app/controllers/dashboards_controller.rb +0 -14
- data/spec/dummy/app/helpers/application_helper.rb +0 -5
- data/spec/dummy/app/presenters/dashboards/collection_presenter.rb +0 -7
- data/spec/dummy/app/presenters/dashboards/item_presenter.rb +0 -23
- data/spec/dummy/app/presenters/dashboards/new_presenter.rb +0 -29
- data/spec/dummy/app/presenters/dashboards/partials_presenter.rb +0 -5
- data/spec/dummy/app/presenters/dashboards/show_presenter.rb +0 -12
- data/spec/dummy/app/presenters/layouts/application_presenter.rb +0 -21
- data/spec/dummy/app/views/dashboards/_item.html.curly +0 -1
- data/spec/dummy/app/views/dashboards/collection.html.curly +0 -8
- data/spec/dummy/app/views/dashboards/new.html.curly +0 -7
- data/spec/dummy/app/views/dashboards/partials.html.curly +0 -3
- data/spec/dummy/app/views/dashboards/show.html.curly +0 -3
- data/spec/dummy/app/views/layouts/application.html.curly +0 -11
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -12
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/test.rb +0 -36
- data/spec/dummy/config/routes.rb +0 -6
- data/spec/generators/controller_generator_spec.rb +0 -34
- data/spec/integration/application_layout_spec.rb +0 -22
- data/spec/integration/collection_blocks_spec.rb +0 -37
- data/spec/integration/context_blocks_spec.rb +0 -27
- data/spec/integration/partials_spec.rb +0 -24
- data/spec/matchers/have_structure.rb +0 -29
- data/spec/parser_spec.rb +0 -92
- data/spec/presenter_spec.rb +0 -247
- data/spec/scanner_spec.rb +0 -124
- data/spec/spec_helper.rb +0 -45
- data/spec/syntax_error_spec.rb +0 -12
- data/spec/template_handler_spec.rb +0 -209
@@ -1,23 +0,0 @@
|
|
1
|
-
class Dashboards::ItemPresenter < Curly::Presenter
|
2
|
-
presents :item, :name
|
3
|
-
|
4
|
-
def item
|
5
|
-
@item
|
6
|
-
end
|
7
|
-
|
8
|
-
def name
|
9
|
-
@name
|
10
|
-
end
|
11
|
-
|
12
|
-
def subitems
|
13
|
-
%w[1 2 3]
|
14
|
-
end
|
15
|
-
|
16
|
-
class SubitemPresenter < Curly::Presenter
|
17
|
-
presents :item, :subitem
|
18
|
-
|
19
|
-
def name
|
20
|
-
@subitem
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class Dashboards::NewPresenter < Curly::Presenter
|
2
|
-
presents :name
|
3
|
-
|
4
|
-
def form(&block)
|
5
|
-
form_for(:dashboard, &block)
|
6
|
-
end
|
7
|
-
|
8
|
-
class FormPresenter < Curly::Presenter
|
9
|
-
presents :form, :name
|
10
|
-
|
11
|
-
def name_field(&block)
|
12
|
-
content_tag :div, class: "field" do
|
13
|
-
block.call
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class NameFieldPresenter < Curly::Presenter
|
18
|
-
presents :form, :name
|
19
|
-
|
20
|
-
def label
|
21
|
-
"Name"
|
22
|
-
end
|
23
|
-
|
24
|
-
def input
|
25
|
-
@form.text_field :name, value: @name
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class Layouts::ApplicationPresenter < Curly::Presenter
|
2
|
-
def title
|
3
|
-
"Dummy app"
|
4
|
-
end
|
5
|
-
|
6
|
-
def content
|
7
|
-
yield
|
8
|
-
end
|
9
|
-
|
10
|
-
def header(&block)
|
11
|
-
block.call
|
12
|
-
end
|
13
|
-
|
14
|
-
class HeaderPresenter < Curly::Presenter
|
15
|
-
|
16
|
-
def title
|
17
|
-
"Dummy app"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
<li>{{item}} ({{name}})</li>
|
data/spec/dummy/config.ru
DELETED
data/spec/dummy/config/boot.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
Rails.application.configure do
|
2
|
-
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
-
|
4
|
-
# The test environment is used exclusively to run your application's
|
5
|
-
# test suite. You never need to work with it otherwise. Remember that
|
6
|
-
# your test database is "scratch space" for the test suite and is wiped
|
7
|
-
# and recreated between test runs. Don't rely on the data there!
|
8
|
-
config.cache_classes = true
|
9
|
-
|
10
|
-
# Do not eager load code on boot. This avoids loading your whole application
|
11
|
-
# just for the purpose of running a single test. If you are using a tool that
|
12
|
-
# preloads Rails for running tests, you may have to set it to true.
|
13
|
-
config.eager_load = false
|
14
|
-
|
15
|
-
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
config.serve_static_files = true
|
17
|
-
config.static_cache_control = 'public, max-age=3600'
|
18
|
-
|
19
|
-
# Show full error reports and disable caching.
|
20
|
-
config.consider_all_requests_local = true
|
21
|
-
config.action_controller.perform_caching = false
|
22
|
-
|
23
|
-
# Raise exceptions instead of rendering exception templates.
|
24
|
-
config.action_dispatch.show_exceptions = false
|
25
|
-
|
26
|
-
# Disable request forgery protection in test environment.
|
27
|
-
config.action_controller.allow_forgery_protection = false
|
28
|
-
|
29
|
-
# Print deprecation notices to the stderr.
|
30
|
-
config.active_support.deprecation = :stderr
|
31
|
-
|
32
|
-
# Raises error for missing translations
|
33
|
-
# config.action_view.raise_on_missing_translations = true
|
34
|
-
|
35
|
-
config.secret_key_base = "yolo"
|
36
|
-
end
|
data/spec/dummy/config/routes.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'genspec'
|
2
|
-
require 'generators/curly/controller/controller_generator'
|
3
|
-
|
4
|
-
describe Curly::Generators::ControllerGenerator do
|
5
|
-
with_args "animals/cows", "foo"
|
6
|
-
|
7
|
-
it "generates a Curly template for each action" do
|
8
|
-
subject.should generate("app/views/animals/cows/foo.html.curly") {|content|
|
9
|
-
expected_content = "<h1>Animals::Cows#foo</h1>\n" +
|
10
|
-
"<p>Find me in app/views/animals/cows/foo.html.curly</p>\n"
|
11
|
-
|
12
|
-
content.should == expected_content
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
it "generates a Curly presenter for each action" do
|
17
|
-
subject.should generate("app/presenters/animals/cows/foo_presenter.rb") {|content|
|
18
|
-
expected_content = (<<-RUBY).gsub(/^\s{8}/, "")
|
19
|
-
class Animals::Cows::FooPresenter < Curly::Presenter
|
20
|
-
# If you need to assign variables to the presenter, you can use the
|
21
|
-
# `presents` method.
|
22
|
-
#
|
23
|
-
# presents :foo, :bar
|
24
|
-
#
|
25
|
-
# Any public method defined in a presenter class will be available
|
26
|
-
# to the Curly template as a variable. Consider making these methods
|
27
|
-
# idempotent.
|
28
|
-
end
|
29
|
-
RUBY
|
30
|
-
|
31
|
-
content.should == expected_content
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
describe "Using Curly for the application layout", type: :request do
|
2
|
-
example "A simple layout view" do
|
3
|
-
get '/'
|
4
|
-
|
5
|
-
response.body.should == <<-HTML.strip_heredoc
|
6
|
-
<html>
|
7
|
-
<head>
|
8
|
-
<title>Dummy app</title>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<header>
|
12
|
-
<h1>Dummy app</h1>
|
13
|
-
</header>
|
14
|
-
<h1>Dashboard</h1>
|
15
|
-
<p>Hello, World!</p>
|
16
|
-
<p>Welcome!</p>
|
17
|
-
|
18
|
-
</body>
|
19
|
-
</html>
|
20
|
-
HTML
|
21
|
-
end
|
22
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
describe "Collection blocks", type: :request do
|
2
|
-
example "Rendering collections" do
|
3
|
-
get '/collection'
|
4
|
-
|
5
|
-
response.body.should == <<-HTML.strip_heredoc
|
6
|
-
<html>
|
7
|
-
<head>
|
8
|
-
<title>Dummy app</title>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<header>
|
12
|
-
<h1>Dummy app</h1>
|
13
|
-
</header>
|
14
|
-
<ul>
|
15
|
-
|
16
|
-
<li>uno</li>
|
17
|
-
<ul>
|
18
|
-
<li>1</li><li>2</li><li>3</li>
|
19
|
-
</ul>
|
20
|
-
|
21
|
-
<li>dos</li>
|
22
|
-
<ul>
|
23
|
-
<li>1</li><li>2</li><li>3</li>
|
24
|
-
</ul>
|
25
|
-
|
26
|
-
<li>tres!</li>
|
27
|
-
<ul>
|
28
|
-
<li>1</li><li>2</li><li>3</li>
|
29
|
-
</ul>
|
30
|
-
|
31
|
-
</ul>
|
32
|
-
|
33
|
-
</body>
|
34
|
-
</html>
|
35
|
-
HTML
|
36
|
-
end
|
37
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'matchers/have_structure'
|
2
|
-
|
3
|
-
describe "Context blocks", type: :request do
|
4
|
-
example "A context block" do
|
5
|
-
get '/new'
|
6
|
-
|
7
|
-
response.body.should have_structure <<-HTML.strip_heredoc
|
8
|
-
<html>
|
9
|
-
<head>
|
10
|
-
<title>Dummy app</title>
|
11
|
-
</head>
|
12
|
-
<body>
|
13
|
-
<header>
|
14
|
-
<h1>Dummy app</h1>
|
15
|
-
</header>
|
16
|
-
<form accept-charset="UTF-8" action="/new" method="post"><input name="utf8" type="hidden" value="✓" />
|
17
|
-
<div class="field">
|
18
|
-
<b>Name</b> <input id="dashboard_name" name="dashboard[name]" type="text" value="test" />
|
19
|
-
</div>
|
20
|
-
</form>
|
21
|
-
|
22
|
-
<p>Thank you!</p>
|
23
|
-
</body>
|
24
|
-
</html>
|
25
|
-
HTML
|
26
|
-
end
|
27
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
describe "Using Curly for Rails partials", type: :request do
|
2
|
-
example "Rendering a partial" do
|
3
|
-
get '/partials'
|
4
|
-
|
5
|
-
response.body.should == <<-HTML.strip_heredoc
|
6
|
-
<html>
|
7
|
-
<head>
|
8
|
-
<title>Dummy app</title>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<header>
|
12
|
-
<h1>Dummy app</h1>
|
13
|
-
</header>
|
14
|
-
<ul>
|
15
|
-
<li>One (yo)</li>
|
16
|
-
<li>Two (yo)</li>
|
17
|
-
|
18
|
-
</ul>
|
19
|
-
|
20
|
-
</body>
|
21
|
-
</html>
|
22
|
-
HTML
|
23
|
-
end
|
24
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'rspec/expectations'
|
2
|
-
require 'nokogiri'
|
3
|
-
|
4
|
-
RSpec::Matchers.define(:have_structure) do |expected|
|
5
|
-
match do |actual|
|
6
|
-
normalized(actual).should == normalized(expected)
|
7
|
-
end
|
8
|
-
|
9
|
-
failure_message_for_should do |actual|
|
10
|
-
"Expected\n\n#{actual}\n\n" \
|
11
|
-
"to have the same structure as\n\n#{expected}"
|
12
|
-
end
|
13
|
-
|
14
|
-
failure_message_for_should_not do |actual|
|
15
|
-
"Expected\n\n#{actual}\n\n" \
|
16
|
-
"to NOT have the same canonicalized structure as\n\n#{expected}"
|
17
|
-
end
|
18
|
-
|
19
|
-
def normalized(text)
|
20
|
-
document = Nokogiri::XML("<snippet>#{text}</snippet>")
|
21
|
-
document.traverse do |node|
|
22
|
-
node.content = node.text.strip if node.text?
|
23
|
-
end
|
24
|
-
|
25
|
-
document.canonicalize do |node, parent|
|
26
|
-
!(node.text? && node.text.empty?)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/spec/parser_spec.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
describe Curly::Parser do
|
2
|
-
it "parses component tokens" do
|
3
|
-
tokens = [
|
4
|
-
[:component, "a", nil, {}],
|
5
|
-
]
|
6
|
-
|
7
|
-
parse(tokens).should == [
|
8
|
-
component("a")
|
9
|
-
]
|
10
|
-
end
|
11
|
-
|
12
|
-
it "parses conditional blocks" do
|
13
|
-
tokens = [
|
14
|
-
[:conditional_block_start, "a?", nil, {}],
|
15
|
-
[:component, "hello", nil, {}],
|
16
|
-
[:block_end, "a?", nil],
|
17
|
-
]
|
18
|
-
|
19
|
-
parse(tokens).should == [
|
20
|
-
conditional_block(component("a?"), [component("hello")])
|
21
|
-
]
|
22
|
-
end
|
23
|
-
|
24
|
-
it "parses inverse conditional blocks" do
|
25
|
-
tokens = [
|
26
|
-
[:inverse_conditional_block_start, "a?", nil, {}],
|
27
|
-
[:component, "hello", nil, {}],
|
28
|
-
[:block_end, "a?", nil],
|
29
|
-
]
|
30
|
-
|
31
|
-
parse(tokens).should == [
|
32
|
-
inverse_conditional_block(component("a?"), [component("hello")])
|
33
|
-
]
|
34
|
-
end
|
35
|
-
|
36
|
-
it "parses collection blocks" do
|
37
|
-
tokens = [
|
38
|
-
[:collection_block_start, "mice", nil, {}],
|
39
|
-
[:component, "hello", nil, {}],
|
40
|
-
[:block_end, "mice", nil],
|
41
|
-
]
|
42
|
-
|
43
|
-
parse(tokens).should == [
|
44
|
-
collection_block(component("mice"), [component("hello")])
|
45
|
-
]
|
46
|
-
end
|
47
|
-
|
48
|
-
it "fails if a block is not closed" do
|
49
|
-
tokens = [
|
50
|
-
[:collection_block_start, "mice", nil, {}],
|
51
|
-
]
|
52
|
-
|
53
|
-
expect { parse(tokens) }.to raise_exception(Curly::IncompleteBlockError)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "fails if a block is closed with the wrong component" do
|
57
|
-
tokens = [
|
58
|
-
[:collection_block_start, "mice", nil, {}],
|
59
|
-
[:block_end, "men", nil, {}],
|
60
|
-
]
|
61
|
-
|
62
|
-
expect { parse(tokens) }.to raise_exception(Curly::IncorrectEndingError)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "fails if there is a closing component too many" do
|
66
|
-
tokens = [
|
67
|
-
[:block_end, "world", nil, {}],
|
68
|
-
]
|
69
|
-
|
70
|
-
expect { parse(tokens) }.to raise_exception(Curly::IncorrectEndingError)
|
71
|
-
end
|
72
|
-
|
73
|
-
def parse(tokens)
|
74
|
-
described_class.parse(tokens)
|
75
|
-
end
|
76
|
-
|
77
|
-
def component(*args)
|
78
|
-
Curly::Parser::Component.new(*args)
|
79
|
-
end
|
80
|
-
|
81
|
-
def conditional_block(*args)
|
82
|
-
Curly::Parser::Block.new(:conditional, *args)
|
83
|
-
end
|
84
|
-
|
85
|
-
def inverse_conditional_block(*args)
|
86
|
-
Curly::Parser::Block.new(:inverse_conditional, *args)
|
87
|
-
end
|
88
|
-
|
89
|
-
def collection_block(*args)
|
90
|
-
Curly::Parser::Block.new(:collection, *args)
|
91
|
-
end
|
92
|
-
end
|