vanilla 1.15.1 → 1.16
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/lib/vanilla.rb +2 -1
- data/lib/vanilla/renderers/base.rb +2 -2
- data/lib/vanilla/routes.rb +5 -18
- data/lib/vanilla/snip_reference_parser.rb +87 -64
- data/pristine_app/Gemfile.lock +2 -2
- data/pristine_app/README +11 -0
- data/pristine_app/soups/dynasnips/current_snip.rb +7 -7
- data/pristine_app/soups/tutorial/vanilla-rb.snip +2 -2
- data/pristine_app/soups/tutorial/vanilla.snip +1 -1
- data/test/dynasnip_test.rb +13 -0
- data/test/dynasnips/link_to_current_snip_test.rb +19 -0
- data/test/dynasnips/link_to_test.rb +27 -0
- data/test/dynasnips/page_title_test.rb +19 -0
- data/test/{base_renderer_test.rb → renderers/base_renderer_test.rb} +0 -0
- data/test/{erb_renderer_test.rb → renderers/erb_renderer_test.rb} +0 -0
- data/test/{haml_renderer_test.rb → renderers/haml_renderer_test.rb} +0 -0
- data/test/{markdown_renderer_test.rb → renderers/markdown_renderer_test.rb} +0 -0
- data/test/{raw_renderer_test.rb → renderers/raw_renderer_test.rb} +0 -0
- data/test/{ruby_renderer_test.rb → renderers/ruby_renderer_test.rb} +0 -0
- data/test/{snip_reference_test.rb → snip_inclusion_test.rb} +1 -1
- data/test/snip_reference_parser_test.rb +110 -42
- data/test/vanilla_presenting_test.rb +1 -5
- metadata +46 -57
- data/lib/vanilla/snip_reference.rb +0 -754
- data/lib/vanilla/snip_reference.treetop +0 -67
- data/pristine_app/tmp/restart.txt +0 -0
- data/test/soup/blah.snip +0 -4
- data/test/soup/blah.snip.erb +0 -4
- data/test/soup/blah.snip.haml +0 -4
- data/test/soup/blah.snip.markdown +0 -4
- data/test/soup/blah.snip.rb +0 -4
- data/test/soup/blah.snip.textile +0 -4
- data/test/soup/current_snip.snip +0 -14
- data/test/soup/layout.snip +0 -4
- data/test/soup/test.snip +0 -3
- data/test/soup/test_dyna.snip +0 -7
data/Rakefile
CHANGED
@@ -46,10 +46,10 @@ if Object.const_defined?(:Gem)
|
|
46
46
|
s.add_dependency("ratom", ">= 0.3.5")
|
47
47
|
s.add_dependency("RedCloth", ">= 4.1.1")
|
48
48
|
s.add_dependency("BlueCloth", ">= 1.0.0")
|
49
|
-
s.add_dependency("treetop", ">= 1.4.1")
|
50
49
|
s.add_dependency("haml")
|
50
|
+
s.add_dependency("parslet", ">= 1.2.0")
|
51
51
|
|
52
|
-
s.add_development_dependency("kintama", ">= 0.1.
|
52
|
+
s.add_development_dependency("kintama", ">= 0.1.6") # add any other gems for testing/development
|
53
53
|
s.add_development_dependency("mocha")
|
54
54
|
|
55
55
|
# If you want to publish automatically to rubyforge, you'll may need
|
data/lib/vanilla.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Vanilla
|
2
|
-
VERSION = "1.
|
2
|
+
VERSION = "1.16"
|
3
3
|
|
4
4
|
autoload :Renderers, "vanilla/renderers"
|
5
5
|
autoload :App, "vanilla/app"
|
@@ -7,6 +7,7 @@ module Vanilla
|
|
7
7
|
autoload :Request, "vanilla/request"
|
8
8
|
autoload :Routes, "vanilla/routes"
|
9
9
|
autoload :Static, "vanilla/static"
|
10
|
+
autoload :SnipReferenceParser, "vanilla/snip_reference_parser"
|
10
11
|
end
|
11
12
|
|
12
13
|
# Load all the base dynasnip classes
|
@@ -26,7 +26,7 @@ module Vanilla
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.snip_regexp
|
29
|
-
%r{(\{[\w\-_\d\.\"]+(\s+[^\}.]+)?\})}
|
29
|
+
%r{(\{[\w\-_\d\.\"\'\s]+(\s+[^\}.]+)?\})}
|
30
30
|
end
|
31
31
|
|
32
32
|
def default_layout_snip
|
@@ -61,7 +61,7 @@ module Vanilla
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def parse_snip_reference(string)
|
64
|
-
@parser ||= SnipReferenceParser.new
|
64
|
+
@parser ||= Vanilla::SnipReferenceParser.new
|
65
65
|
@parser.parse(string)
|
66
66
|
end
|
67
67
|
|
data/lib/vanilla/routes.rb
CHANGED
@@ -2,7 +2,11 @@ module Vanilla
|
|
2
2
|
# Expects to be able to call 'soup' on whatever it is included into
|
3
3
|
module Routes
|
4
4
|
def link_to(link_text, snip_name=link_text, part=nil)
|
5
|
-
soup[snip_name]
|
5
|
+
if soup[snip_name]
|
6
|
+
%{<a href="#{url_to(snip_name, part)}">#{link_text}</a>}
|
7
|
+
else
|
8
|
+
%{<a class="missing" href="#{url_to(snip_name, part)}">#{link_text}</a>}
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
def url_to(snip_name, part=nil)
|
@@ -10,22 +14,5 @@ module Vanilla
|
|
10
14
|
url += "/#{part}" if part
|
11
15
|
url
|
12
16
|
end
|
13
|
-
|
14
|
-
def url_to_raw(snip_name, part=nil)
|
15
|
-
url = url_to(snip_name, part)
|
16
|
-
url += ".raw"
|
17
|
-
end
|
18
|
-
|
19
|
-
def existing_link(link_text, snip_name=link_text, part=nil)
|
20
|
-
%{<a href="#{url_to(snip_name, part)}">#{link_text}</a>}
|
21
|
-
end
|
22
|
-
|
23
|
-
def edit_link(snip_name, link_text)
|
24
|
-
%[<a href="/edit?name=#{snip_name.gsub(" ", "+")}">#{link_text}</a>]
|
25
|
-
end
|
26
|
-
|
27
|
-
def new_link(snip_name="New")
|
28
|
-
%[<a href="/new?name=#{snip_name ? snip_name.gsub(" ", "+") : nil}" class="new">#{snip_name}</a>]
|
29
|
-
end
|
30
17
|
end
|
31
18
|
end
|
@@ -1,71 +1,94 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
def arguments
|
10
|
-
if elements[2] && elements[2].elements
|
11
|
-
r = elements[2].elements[1].to_arguments
|
12
|
-
r.flatten! if r.respond_to?(:flatten!)
|
13
|
-
r
|
14
|
-
else
|
15
|
-
[]
|
1
|
+
require "parslet"
|
2
|
+
|
3
|
+
module Vanilla
|
4
|
+
class SnipReferenceParser
|
5
|
+
class Reference
|
6
|
+
def initialize(attributes)
|
7
|
+
@attributes = attributes
|
16
8
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
module SnipNameWithAttribute
|
28
|
-
def name
|
29
|
-
elements[0].text_value
|
30
|
-
end
|
31
|
-
def attribute
|
32
|
-
elements[2].text_value
|
33
|
-
end
|
34
|
-
end
|
35
|
-
module QuotedWord
|
36
|
-
def text_value
|
37
|
-
elements[1].text_value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
module ArgumentList
|
41
|
-
def to_arguments
|
42
|
-
args = elements[0].to_arguments
|
43
|
-
if args.is_a?(Array)
|
44
|
-
args << elements[1].elements[1].to_arguments if elements[1].elements
|
45
|
-
elsif args.is_a?(Hash)
|
46
|
-
args.merge!(elements[1].elements[1].to_arguments) if elements[1].elements
|
9
|
+
def snip
|
10
|
+
@attributes[:snip]
|
11
|
+
end
|
12
|
+
def attribute
|
13
|
+
@attributes[:attribute]
|
14
|
+
end
|
15
|
+
def arguments
|
16
|
+
@attributes[:arguments] || []
|
47
17
|
end
|
48
|
-
args
|
49
18
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
key = elements[0].text_value
|
54
|
-
key = $1 if key =~ /\A:(.*)\Z/
|
55
|
-
{key.to_sym => elements[4].text_value}
|
19
|
+
|
20
|
+
def parse(string)
|
21
|
+
Reference.new(SnipTransform.new.apply(SnipParser.new.parse(string)))
|
56
22
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
23
|
+
|
24
|
+
class SnipParser < Parslet::Parser
|
25
|
+
rule(:spaces) { match('\s').repeat(1) }
|
26
|
+
rule(:spaces?) { spaces.maybe }
|
27
|
+
rule(:comma) { match(',') }
|
28
|
+
rule(:dot) { str(".") }
|
29
|
+
rule(:squote) { str("'") }
|
30
|
+
rule(:dquote) { str('"') }
|
31
|
+
rule(:escaped_dquote) { str('"') }
|
32
|
+
rule(:left_brace) { str("{") }
|
33
|
+
rule(:right_brace) { str("}") }
|
34
|
+
|
35
|
+
rule(:word) { match("[a-zA-Z0-9_\\-]").repeat(1) }
|
36
|
+
rule(:quotables) { word | comma | spaces }
|
37
|
+
rule(:double_quoted_string) do
|
38
|
+
dquote >> (quotables | squote).repeat(1).as(:string) >> dquote
|
39
|
+
end
|
40
|
+
rule(:single_quoted_string) do
|
41
|
+
squote >> (quotables | dquote).repeat(1).as(:string) >> squote
|
42
|
+
end
|
43
|
+
rule(:string) do
|
44
|
+
single_quoted_string | double_quoted_string | str("nil").as(:nil) | word.as(:string)
|
45
|
+
end
|
46
|
+
rule(:symbol) { str(":") >> string }
|
47
|
+
|
48
|
+
rule(:comma_separator) { spaces? >> comma >> spaces? }
|
49
|
+
rule(:hash_separator) { spaces? >> str("=>") >> spaces? }
|
50
|
+
rule(:named_separator) { spaces? >> str(":") >> spaces? }
|
51
|
+
|
52
|
+
rule(:hash_arg) { (symbol | string).as(:key) >> hash_separator >> string.as(:value) }
|
53
|
+
rule(:named_arg) { string.as(:key) >> named_separator >> string.as(:value) }
|
54
|
+
|
55
|
+
rule(:string_arg_list) { (string.as(:string_arg) >> further_string_args.repeat).as(:string_arg_list) }
|
56
|
+
rule(:further_string_args) { comma_separator >> string.as(:string_arg) }
|
57
|
+
|
58
|
+
rule(:hash_arg_list) { (hash_arg.as(:hash_arg) >> further_hash_args.repeat).as(:key_value_arg_list) }
|
59
|
+
rule(:further_hash_args) { comma_separator >> hash_arg.as(:hash_arg) }
|
60
|
+
|
61
|
+
rule(:named_arg_list) { (named_arg.as(:named_arg) >> further_named_args.repeat).as(:key_value_arg_list) }
|
62
|
+
rule(:further_named_args) { comma_separator >> named_arg.as(:named_arg) }
|
63
|
+
|
64
|
+
rule(:arguments) { hash_arg_list | named_arg_list | string_arg_list }
|
65
|
+
rule(:snip_part) { string.as(:snip) >> (dot >> string.as(:attribute)).maybe }
|
66
|
+
|
67
|
+
rule(:snip_reference) do
|
68
|
+
left_brace >> spaces? >>
|
69
|
+
snip_part >> (spaces >> arguments.as(:arguments)).maybe >>
|
70
|
+
spaces? >> right_brace
|
71
|
+
end
|
72
|
+
|
73
|
+
root(:snip_reference)
|
61
74
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
75
|
+
|
76
|
+
class SnipTransform < Parslet::Transform
|
77
|
+
rule(:nil => simple(:x)) { nil }
|
78
|
+
rule(:string => simple(:x)) { x.to_s }
|
79
|
+
rule(:string_arg => simple(:x)) { x }
|
80
|
+
rule(:string_arg_list => simple(:x)) { [x] }
|
81
|
+
rule(:string_arg_list => sequence(:x)) { x }
|
82
|
+
|
83
|
+
class Arg
|
84
|
+
def initialize(k, v); @k, @v = k, v; end
|
85
|
+
def to_h; {@k.to_sym => @v}; end
|
86
|
+
end
|
87
|
+
|
88
|
+
rule(:hash_arg => subtree(:x)) { Arg.new(x[:key], x[:value]) }
|
89
|
+
rule(:named_arg => subtree(:x)) { Arg.new(x[:key], x[:value]) }
|
90
|
+
rule(:key_value_arg_list => simple(:x)) { x.to_h }
|
91
|
+
rule(:key_value_arg_list => sequence(:x)) { x.inject({}) { |h, kv| h.merge(kv.to_h) } }
|
66
92
|
end
|
67
93
|
end
|
68
|
-
end
|
69
|
-
|
70
|
-
require 'treetop'
|
71
|
-
require 'vanilla/snip_reference'
|
94
|
+
end
|
data/pristine_app/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: /Users/james/Code/lazyatom/vanilla-rb
|
3
3
|
specs:
|
4
|
-
vanilla (1.
|
4
|
+
vanilla (1.14.1)
|
5
5
|
BlueCloth (>= 1.0.0)
|
6
6
|
RedCloth (>= 4.1.1)
|
7
7
|
haml
|
@@ -15,7 +15,7 @@ GEM
|
|
15
15
|
specs:
|
16
16
|
BlueCloth (1.0.1)
|
17
17
|
RedCloth (4.2.7)
|
18
|
-
haml (3.
|
18
|
+
haml (3.1.1)
|
19
19
|
libxml-ruby (2.0.2)
|
20
20
|
polyglot (0.3.1)
|
21
21
|
rack (1.2.2)
|
data/pristine_app/README
CHANGED
@@ -16,6 +16,8 @@ For an overview of vanilla, start your site and look at the tutorial:
|
|
16
16
|
$ rackup # then open http://localhost:9292/tutorial
|
17
17
|
|
18
18
|
|
19
|
+
Editing snips
|
20
|
+
-------------
|
19
21
|
You can edit any file in the soup directory using your favourite editor,
|
20
22
|
and the changes will be reflected automatically. The snip files are
|
21
23
|
slightly modified YAML files. Here's an example, which you might save
|
@@ -34,3 +36,12 @@ in a file called 'soup.snip':
|
|
34
36
|
|
35
37
|
The 'content' of the snip is at the top of the file, followed by the
|
36
38
|
rest of the snip attributes on lines starting with ':'.
|
39
|
+
|
40
|
+
|
41
|
+
The console
|
42
|
+
-----------
|
43
|
+
|
44
|
+
Within a vanilla app directory, you can run `vanilla console` to start
|
45
|
+
an IRB session and interact with your app and snips. The `app` method
|
46
|
+
returns your application object, and `app.soup['start']` will return
|
47
|
+
the start snip from your soup(s).
|
@@ -14,15 +14,15 @@ class CurrentSnip < Dynasnip
|
|
14
14
|
|
|
15
15
|
|
16
16
|
def handle(attribute=nil)
|
17
|
-
if
|
18
|
-
app.request.
|
19
|
-
|
20
|
-
if app.request.snip
|
21
|
-
app.render(app.request.snip, app.request.part)
|
17
|
+
if app.request.snip
|
18
|
+
if attribute ||= app.request.part
|
19
|
+
"{#{app.request.snip_name}.#{attribute}}"
|
22
20
|
else
|
23
|
-
app.
|
24
|
-
%{Couldn't find snip "#{app.request.snip_name}"}
|
21
|
+
"{#{app.request.snip_name}}"
|
25
22
|
end
|
23
|
+
else
|
24
|
+
app.response.status = 404
|
25
|
+
%{Couldn't find snip "#{app.request.snip_name}"}
|
26
26
|
end
|
27
27
|
end
|
28
28
|
self
|
@@ -4,9 +4,9 @@ Here's the [introductory blog post][3].
|
|
4
4
|
|
5
5
|
It's developed on [github][1], and has a [lighthouse bug tracker][2]. At the moment it's not very well documented, since I'm exploring how the concept might work and the internals are subject to change. However, please do play around with it.
|
6
6
|
|
7
|
-
Here's the tutorial (helpfully included from {link_to
|
7
|
+
Here's the tutorial (helpfully included from {link_to tutorial}).
|
8
8
|
|
9
|
-
{
|
9
|
+
{tutorial}
|
10
10
|
|
11
11
|
|
12
12
|
[1]: http://github.com/lazyatom/vanilla
|
data/test/dynasnip_test.rb
CHANGED
@@ -26,4 +26,17 @@ describe Dynasnip do
|
|
26
26
|
assert_equal "altered content", TestDyna.new(@app).test_attribute
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
context "when rendering usage" do
|
31
|
+
class ::ShowUsage < Dynasnip
|
32
|
+
usage "This is the usage"
|
33
|
+
def handle
|
34
|
+
usage
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
should "show the usage defined in the snip" do
|
39
|
+
assert_equal "This is the usage", ShowUsage.new(@app).handle
|
40
|
+
end
|
41
|
+
end
|
29
42
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../../../pristine_app/soups/dynasnips", __FILE__)
|
3
|
+
require "link_to_current_snip"
|
4
|
+
|
5
|
+
context "The link_to_current_snip dynasnip" do
|
6
|
+
setup do
|
7
|
+
@app.soup << LinkToCurrentSnip.snip_attributes
|
8
|
+
create_snip :name => "test", :content => "test {link_to_current_snip}"
|
9
|
+
end
|
10
|
+
|
11
|
+
should "render a link to the snip that was requested" do
|
12
|
+
assert_response_body %{test <a href="/test">test</a>}, "/test"
|
13
|
+
end
|
14
|
+
|
15
|
+
should "render a link to the snip that was requested even if it isn't the snip that included the dyna" do
|
16
|
+
create_snip :name => "othertest", :content => "othertest {test}"
|
17
|
+
assert_response_body %{othertest test <a href="/othertest">othertest</a>}, "/othertest"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../../../pristine_app/soups/dynasnips", __FILE__)
|
3
|
+
require "link_to"
|
4
|
+
|
5
|
+
context "The link_to dynasnip" do
|
6
|
+
setup do
|
7
|
+
create_snip :name => "start", :content => "hello"
|
8
|
+
end
|
9
|
+
|
10
|
+
should "render a link to a snip that exists" do
|
11
|
+
assert_equal %{<a href="/start">start</a>}, render_dynasnip(LinkTo, "start")
|
12
|
+
end
|
13
|
+
|
14
|
+
should "allow specification of the link text" do
|
15
|
+
assert_equal %{<a href="/start">the start snip</a>}, render_dynasnip(LinkTo, "start", "the start snip")
|
16
|
+
end
|
17
|
+
|
18
|
+
should "mark snips that are missing with a class" do
|
19
|
+
assert_equal %{<a class="missing" href="/missing">missing</a>}, render_dynasnip(LinkTo, "missing")
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def render_dynasnip(klass, *args)
|
25
|
+
klass.new(@app).handle(*args)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../../../pristine_app/soups/dynasnips", __FILE__)
|
3
|
+
require "page_title"
|
4
|
+
|
5
|
+
context "The page_title dynasnip" do
|
6
|
+
setup do
|
7
|
+
@app.soup << PageTitle.snip_attributes
|
8
|
+
end
|
9
|
+
|
10
|
+
should "render as the requested snip name if that snip has no title" do
|
11
|
+
create_snip :name => "test", :content => "{page_title}"
|
12
|
+
assert_response_body %{test}, "/test"
|
13
|
+
end
|
14
|
+
|
15
|
+
should "render as the requested snip's page_title when that attribute is present" do
|
16
|
+
create_snip :name => "test", :content => "{page_title}", :page_title => "This is a test"
|
17
|
+
assert_response_body %{This is a test}, "/test"
|
18
|
+
end
|
19
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,55 +1,123 @@
|
|
1
1
|
require "test_helper"
|
2
|
-
Treetop.load File.join(File.dirname(__FILE__), *%w[.. lib vanilla snip_reference])
|
3
2
|
|
4
3
|
context "The SnipReference parser" do
|
4
|
+
|
5
5
|
setup do
|
6
|
-
@parser = SnipReferenceParser.new
|
6
|
+
@parser = Vanilla::SnipReferenceParser.new
|
7
7
|
end
|
8
8
|
|
9
9
|
examples = {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
10
|
+
:snip_names => {
|
11
|
+
%|{snip}| => {:snip => 'snip', :attribute => nil, :arguments => []},
|
12
|
+
%|{Snip}| => {:snip => 'Snip', :attribute => nil, :arguments => []},
|
13
|
+
%|{123snip}| => {:snip => '123snip', :attribute => nil, :arguments => []},
|
14
|
+
%|{Snip123}| => {:snip => 'Snip123', :attribute => nil, :arguments => []},
|
15
|
+
%|{snip-with-dashes}| => {:snip => 'snip-with-dashes', :attribute => nil, :arguments => []},
|
16
|
+
%|{snip_with_underscores}| => {:snip => 'snip_with_underscores', :attribute => nil, :arguments => []},
|
17
|
+
},
|
18
|
+
|
19
|
+
:snip_attributes => {
|
20
|
+
%|{snip.snip_attribute}| => {:snip => 'snip', :attribute => 'snip_attribute', :arguments => []},
|
21
|
+
%|{snip.snip_attribute arg}| => {:snip => 'snip', :attribute => 'snip_attribute', :arguments => ['arg']},
|
22
|
+
%|{snip."spaced attribute"}| => {:snip => 'snip', :attribute => 'spaced attribute', :arguments => []},
|
23
|
+
%|{snip.'spaced attribute'}| => {:snip => 'snip', :attribute => 'spaced attribute', :arguments => []}
|
24
|
+
},
|
25
|
+
|
26
|
+
:simple_arguments => {
|
27
|
+
%|{snip argument}| => {:snip => 'snip', :attribute => nil, :arguments => ["argument"]},
|
28
|
+
%|{snip1 argument}| => {:snip => 'snip1', :attribute => nil, :arguments => ["argument"]},
|
29
|
+
%|{snip arg-dashes}| => {:snip => 'snip', :attribute => nil, :arguments => ["arg-dashes"]},
|
30
|
+
%|{snip arg_underscores}| => {:snip => 'snip', :attribute => nil, :arguments => ["arg_underscores"]},
|
31
|
+
%|{snip arg1,arg2}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg1', 'arg2']},
|
32
|
+
%|{snip arg1, arg2}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg1', 'arg2']},
|
33
|
+
%|{snip arg1, arg2}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg1', 'arg2']},
|
34
|
+
%|{snip 1ARG, arg_2, arg-3}| => {:snip => 'snip', :attribute => nil, :arguments => ['1ARG', 'arg_2', 'arg-3']}
|
35
|
+
},
|
36
|
+
|
37
|
+
:snip_name_spaces => {
|
38
|
+
%|{"snip with spaces"}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => []},
|
39
|
+
%|{'snip with spaces'}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => []},
|
40
|
+
%|{"snip with spaces" argument}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => ['argument']},
|
41
|
+
%|{'snip with spaces' argument}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => ['argument']},
|
42
|
+
%|{"snip with spaces" a, b}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => ['a', 'b']},
|
43
|
+
%|{'snip with spaces' a, b}| => {:snip => 'snip with spaces', :attribute => nil, :arguments => ['a', 'b']},
|
44
|
+
%|{"snip with spaces".attribute}| => {:snip => 'snip with spaces', :attribute => 'attribute', :arguments => []},
|
45
|
+
%|{'snip with spaces'.attribute}| => {:snip => 'snip with spaces', :attribute => 'attribute', :arguments => []}
|
46
|
+
},
|
47
|
+
|
48
|
+
:arguments_with_spaces => {
|
49
|
+
# %|{snip arg spaces}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg spaces']},
|
50
|
+
# %|{snip arg spaces, and this}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg spaces', 'and this']},
|
51
|
+
%|{snip "arg spaces"}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg spaces']},
|
52
|
+
%|{snip 'arg spaces'}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg spaces']},
|
53
|
+
%|{snip "arg spaces", arg2}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg spaces', 'arg2']}
|
54
|
+
},
|
55
|
+
|
56
|
+
:nil_arguments => {
|
57
|
+
%|{snip arg1,nil,arg3}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg1', nil, 'arg3']},
|
58
|
+
%|{snip arg1, nil ,arg3}| => {:snip => 'snip', :attribute => nil, :arguments => ['arg1', nil, 'arg3']}
|
59
|
+
},
|
60
|
+
|
61
|
+
:classic_ruby_hash_arguments => {
|
62
|
+
%|{s key1=>value1, key2 => value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
63
|
+
%|{s key1 => value1, key2 => value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
64
|
+
%|{s :key1 => value1, :key2 => value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
65
|
+
%|{s key1 => "value with spaces"}| => {:snip => 's', :arguments => {:key1 => "value with spaces"}},
|
66
|
+
%|{s.attr key1=>value1}| => {:snip => 's', :attribute => 'attr', :arguments => {:key1 => 'value1'}},
|
67
|
+
# %|{s "key with spaces" => value}| => {:snip => 's', :arguments => {:"key with spaces" => "value"}}
|
68
|
+
},
|
69
|
+
|
70
|
+
:named_arguments => {
|
71
|
+
%|{s key1:value1,key2:value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
72
|
+
%|{s key1:value1, key2:value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
73
|
+
%|{s key1: value1, key2: value2}| => {:snip => 's', :arguments => {:key1 => 'value1', :key2 => 'value2'}},
|
74
|
+
%|{s key1:"value with spaces"}| => {:snip => 's', :arguments => {:key1 => 'value with spaces'}}
|
75
|
+
},
|
76
|
+
|
77
|
+
:quoting_arguments => {
|
78
|
+
# %|{s "arg \\" double"}| => {:snip => 's', :attribute => nil, :arguments => ['arg " double']},
|
79
|
+
# %|{s 'arg \\' single'}| => {:snip => 's', :attribute => nil, :arguments => ["arg ' single"]},
|
80
|
+
%|{s "arg ' single"}| => {:snip => 's', :attribute => nil, :arguments => ["arg ' single"]},
|
81
|
+
%|{s 'arg " double'}| => {:snip => 's', :attribute => nil, :arguments => ['arg " double']},
|
82
|
+
%|{s "arg, comma"}| => {:snip => 's', :attribute => nil, :arguments => ['arg, comma']},
|
83
|
+
%|{s 'arg, comma'}| => {:snip => 's', :attribute => nil, :arguments => ['arg, comma']},
|
84
|
+
# %|{s "arg { open"}| => {:snip => 's', :attribute => nil, :arguments => ['arg { open']},
|
85
|
+
# %|{s "arg } close"}| => {:snip => 's', :attribute => nil, :arguments => ['arg } close']}
|
86
|
+
}
|
41
87
|
}
|
42
88
|
|
43
|
-
examples.each do |
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
89
|
+
examples.each do |type, set|
|
90
|
+
context type.to_s.gsub("_", " ") do
|
91
|
+
set.each do |example, expected|
|
92
|
+
should "parse '#{example}' into #{expected.inspect}" do
|
93
|
+
reference = @parser.parse(example)
|
94
|
+
if reference
|
95
|
+
assert_equal expected[:snip], reference.snip
|
96
|
+
assert_equal expected[:attribute], reference.attribute
|
97
|
+
assert_equal expected[:arguments], reference.arguments
|
98
|
+
assert_parsable_by_vanilla example, expected
|
99
|
+
else
|
100
|
+
flunk "failed to parse: #{example} - #{@parser.failure_reason}"
|
101
|
+
end
|
102
|
+
end
|
52
103
|
end
|
53
104
|
end
|
54
105
|
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def assert_parsable_by_vanilla(example, expected)
|
110
|
+
create_snip_from_expected expected
|
111
|
+
create_snip :name => "test", :content => "alpha #{example} beta"
|
112
|
+
assert_response_body "alpha ok beta", "/test"
|
113
|
+
end
|
114
|
+
|
115
|
+
def create_snip_from_expected(expected)
|
116
|
+
simple_dyna = %|class SimpleDyna;def handle(*args); 'ok'; end;self;end|
|
117
|
+
attributes = {:name => expected[:snip], :content => simple_dyna, :render_as => "ruby"}
|
118
|
+
if expected[:attribute]
|
119
|
+
attributes[expected[:attribute]] = simple_dyna
|
120
|
+
end
|
121
|
+
create_snip(attributes)
|
122
|
+
end
|
55
123
|
end
|