vanilla 1.15.1 → 1.16
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.
- 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
|