vanilla 1.0.2 → 1.2

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.
Files changed (105) hide show
  1. data/Rakefile +112 -109
  2. data/bin/vanilla +35 -6
  3. data/lib/vanilla.rb +10 -14
  4. data/lib/vanilla/app.rb +109 -41
  5. data/lib/vanilla/console.rb +22 -2
  6. data/lib/vanilla/dynasnip.rb +4 -36
  7. data/lib/vanilla/renderers.rb +12 -0
  8. data/lib/vanilla/renderers/base.rb +58 -34
  9. data/lib/vanilla/renderers/bold.rb +0 -2
  10. data/lib/vanilla/renderers/erb.rb +1 -3
  11. data/lib/vanilla/renderers/haml.rb +13 -0
  12. data/lib/vanilla/renderers/markdown.rb +0 -2
  13. data/lib/vanilla/renderers/raw.rb +0 -2
  14. data/lib/vanilla/renderers/ruby.rb +12 -6
  15. data/lib/vanilla/renderers/textile.rb +0 -2
  16. data/lib/vanilla/request.rb +19 -17
  17. data/lib/vanilla/routes.rb +9 -20
  18. data/lib/vanilla/snip_reference_parser.rb +94 -0
  19. data/lib/vanilla/static.rb +28 -0
  20. data/pristine_app/Gemfile +3 -0
  21. data/pristine_app/Gemfile.lock +32 -0
  22. data/pristine_app/README +47 -0
  23. data/pristine_app/config.ru +26 -0
  24. data/pristine_app/public/vanilla.css +15 -0
  25. data/pristine_app/soups/base/layout.snip +18 -0
  26. data/pristine_app/soups/base/start.snip +19 -0
  27. data/pristine_app/soups/dynasnips/current_snip.rb +29 -0
  28. data/{lib/vanilla → pristine_app/soups}/dynasnips/debug.rb +5 -3
  29. data/pristine_app/soups/dynasnips/index.rb +12 -0
  30. data/{lib/vanilla → pristine_app/soups}/dynasnips/link_to.rb +4 -2
  31. data/pristine_app/soups/dynasnips/link_to_current_snip.rb +14 -0
  32. data/pristine_app/soups/dynasnips/page_title.rb +9 -0
  33. data/{lib/vanilla → pristine_app/soups}/dynasnips/pre.rb +7 -5
  34. data/{lib/vanilla → pristine_app/soups}/dynasnips/raw.rb +8 -5
  35. data/pristine_app/soups/extras/comments.rb +78 -0
  36. data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/kind.rb +19 -17
  37. data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/rand.rb +2 -0
  38. data/pristine_app/soups/extras/url_to.rb +7 -0
  39. data/pristine_app/soups/tutorial/bad_dynasnip.snip +8 -0
  40. data/pristine_app/soups/tutorial/hello_world.snip +20 -0
  41. data/pristine_app/soups/tutorial/markdown_example.snip +13 -0
  42. data/pristine_app/soups/tutorial/snip.snip +9 -0
  43. data/pristine_app/soups/tutorial/soup.snip +3 -0
  44. data/pristine_app/soups/tutorial/test.snip +30 -0
  45. data/pristine_app/soups/tutorial/textile_example.snip +11 -0
  46. data/pristine_app/soups/tutorial/tutorial-another-snip.snip +1 -0
  47. data/pristine_app/soups/tutorial/tutorial-basic-snip-inclusion.snip +1 -0
  48. data/pristine_app/soups/tutorial/tutorial-dynasnips.snip.markdown +56 -0
  49. data/pristine_app/soups/tutorial/tutorial-layout.snip +56 -0
  50. data/pristine_app/soups/tutorial/tutorial-links.snip +4 -0
  51. data/pristine_app/soups/tutorial/tutorial-renderers.snip.markdown +77 -0
  52. data/pristine_app/soups/tutorial/tutorial.snip.markdown +69 -0
  53. data/pristine_app/soups/tutorial/vanilla-rb.snip +16 -0
  54. data/pristine_app/soups/tutorial/vanilla.snip +8 -0
  55. data/test/dynasnip_test.rb +42 -0
  56. data/test/dynasnips/link_to_current_snip_test.rb +19 -0
  57. data/test/dynasnips/link_to_test.rb +27 -0
  58. data/test/dynasnips/page_title_test.rb +19 -0
  59. data/test/renderers/base_renderer_test.rb +43 -0
  60. data/test/renderers/erb_renderer_test.rb +29 -0
  61. data/test/renderers/haml_renderer_test.rb +35 -0
  62. data/test/renderers/markdown_renderer_test.rb +31 -0
  63. data/test/renderers/raw_renderer_test.rb +23 -0
  64. data/test/renderers/ruby_renderer_test.rb +59 -0
  65. data/test/snip_inclusion_test.rb +56 -0
  66. data/test/snip_reference_parser_test.rb +123 -0
  67. data/test/test_helper.rb +75 -0
  68. data/test/vanilla_app_test.rb +83 -0
  69. data/test/vanilla_presenting_test.rb +125 -0
  70. data/test/vanilla_request_test.rb +87 -0
  71. metadata +179 -78
  72. data/config.example.yml +0 -5
  73. data/config.ru +0 -9
  74. data/lib/defensio.rb +0 -59
  75. data/lib/tasks/vanilla.rake +0 -177
  76. data/lib/vanilla/dynasnips/comments.rb +0 -108
  77. data/lib/vanilla/dynasnips/current_snip.rb +0 -32
  78. data/lib/vanilla/dynasnips/edit.rb +0 -63
  79. data/lib/vanilla/dynasnips/edit_link.rb +0 -24
  80. data/lib/vanilla/dynasnips/index.rb +0 -11
  81. data/lib/vanilla/dynasnips/link_to_current_snip.rb +0 -16
  82. data/lib/vanilla/dynasnips/login.rb +0 -56
  83. data/lib/vanilla/dynasnips/new.rb +0 -14
  84. data/lib/vanilla/dynasnips/notes.rb +0 -42
  85. data/lib/vanilla/dynasnips/url_to.rb +0 -7
  86. data/lib/vanilla/snip_handling.rb +0 -33
  87. data/lib/vanilla/snips/start.rb +0 -27
  88. data/lib/vanilla/snips/system.rb +0 -76
  89. data/lib/vanilla/snips/tutorial.rb +0 -157
  90. data/lib/vanilla/test_snips.rb +0 -85
  91. data/public/hatch.png +0 -0
  92. data/public/javascripts/jquery.js +0 -3549
  93. data/public/javascripts/vanilla.js +0 -21
  94. data/spec/dynasnip_spec.rb +0 -31
  95. data/spec/renderers/base_renderer_spec.rb +0 -40
  96. data/spec/renderers/erb_renderer_spec.rb +0 -27
  97. data/spec/renderers/markdown_renderer_spec.rb +0 -29
  98. data/spec/renderers/raw_renderer_spec.rb +0 -21
  99. data/spec/renderers/ruby_renderer_spec.rb +0 -42
  100. data/spec/renderers/vanilla_app_detecting_renderer_spec.rb +0 -35
  101. data/spec/spec_helper.rb +0 -64
  102. data/spec/vanilla_app_spec.rb +0 -38
  103. data/spec/vanilla_presenting_spec.rb +0 -84
  104. data/spec/vanilla_request_spec.rb +0 -73
  105. data/spec/vanilla_snip_finding_spec.rb +0 -28
@@ -0,0 +1,123 @@
1
+ require "test_helper"
2
+
3
+ context "The SnipReference parser" do
4
+
5
+ setup do
6
+ @parser = Vanilla::SnipReferenceParser.new
7
+ end
8
+
9
+ examples = {
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
+ }
87
+ }
88
+
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
103
+ end
104
+ end
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
123
+ end
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require "kintama"
6
+ require "kintama/mocha"
7
+ require "fileutils"
8
+ require "rack/mock"
9
+ require "vanilla"
10
+
11
+ module Vanilla
12
+ module Test
13
+ def setup_clean_environment
14
+ clean_environment
15
+ @app = Vanilla::App.new(:soup => soup_path)
16
+
17
+ require File.expand_path("../../pristine_app/soups/dynasnips/current_snip", __FILE__)
18
+ @app.soup << CurrentSnip.snip_attributes
19
+ create_snip :name => "layout", :content => "{current_snip}"
20
+ end
21
+
22
+ def response_for(url)
23
+ @app.call(mock_env_for_url(url))
24
+ end
25
+
26
+ def response_body_for(url)
27
+ response_for(url)[2].body[0]
28
+ end
29
+
30
+ def response_code_for(url)
31
+ response_for(url)[0]
32
+ end
33
+
34
+ def assert_response_body(expected, uri)
35
+ assert_equal expected.strip, response_body_for(uri).strip
36
+ end
37
+
38
+ def set_main_template(template_content)
39
+ @app.soup << {:name => "layout", :content => template_content}
40
+ end
41
+
42
+ def create_snip(params)
43
+ @app.soup << params
44
+ end
45
+
46
+ def mock_env_for_url(url)
47
+ Rack::MockRequest.env_for(url)
48
+ end
49
+
50
+ def mock_request(url)
51
+ Rack::Request.new(mock_env_for_url(url))
52
+ end
53
+
54
+ def test_app_directory
55
+ File.join(File.dirname(__FILE__), "tmp")
56
+ end
57
+
58
+ def soup_path
59
+ File.expand_path(File.join(test_app_directory, "soup"))
60
+ end
61
+
62
+ def clean_environment
63
+ FileUtils.rm_rf(test_app_directory)
64
+ end
65
+ end
66
+ end
67
+
68
+ Kintama.include Vanilla::Test
69
+ Kintama.setup do
70
+ setup_clean_environment
71
+ end
72
+
73
+ Kintama.teardown do
74
+ clean_environment
75
+ end
@@ -0,0 +1,83 @@
1
+ require "test_helper"
2
+
3
+ describe Vanilla::App do
4
+ context "when behaving as a Rack application" do
5
+ should "return an array of status code, headers and response" do
6
+ create_snip(:name => "test", :content => "content")
7
+ result = @app.call(mock_env_for_url("/test.text"))
8
+ assert_kind_of Array, result
9
+ assert_equal 200, result[0]
10
+ assert_kind_of Hash, result[1]
11
+ result[2].each{ |output| assert_equal "content", output }
12
+ end
13
+ end
14
+
15
+ context "when being configured" do
16
+ should "default the root snip to 'start'" do
17
+ create_snip :name => "start", :content => "default"
18
+ assert_response_body "default", "/"
19
+ end
20
+
21
+ should "allow a customised root snip" do
22
+ create_snip :name => "start", :content => "default"
23
+ create_snip :name => "custom", :content => "custom"
24
+ @app = Vanilla::App.new(:soup => soup_path, :root_snip => "custom")
25
+ assert_response_body "custom", "/"
26
+ end
27
+ end
28
+
29
+ context "when detecting the snip renderer" do
30
+ setup do
31
+ @app = Vanilla::App.new(:soup => soup_path)
32
+ end
33
+
34
+ should "return the constant refered to in the render_as property of the snip" do
35
+ snip = create_snip(:name => "blah", :render_as => "Raw")
36
+ assert_equal Vanilla::Renderers::Raw, @app.renderer_for(snip)
37
+ end
38
+
39
+ context "using the snip extension" do
40
+ {
41
+ "markdown" => Vanilla::Renderers::Markdown,
42
+ "textile" => Vanilla::Renderers::Textile,
43
+ "erb" => Vanilla::Renderers::Erb,
44
+ "rb" => Vanilla::Renderers::Ruby,
45
+ "haml" => Vanilla::Renderers::Haml
46
+ }.each do |extension, renderer|
47
+ should "return the renderer #{renderer} when the snip has extension #{extension}" do
48
+ snip = create_snip(:name => "blah", :extension => extension)
49
+ assert_equal renderer, @app.renderer_for(snip)
50
+ end
51
+ end
52
+ end
53
+
54
+ should "respect snip renderers passed in the config" do
55
+ app = Vanilla::App.new(:soup => soup_path, :renderers => {"markdown" => "Vanilla::Renderers::Bold"})
56
+ snip = create_snip(:name => "blah", :extension => "markdown")
57
+ assert_equal Vanilla::Renderers::Bold, app.renderer_for(snip)
58
+ end
59
+
60
+ should "return Vanilla::Renderers::Base if no render_as property exists" do
61
+ snip = create_snip(:name => "blah")
62
+ assert_equal Vanilla::Renderers::Base, @app.renderer_for(snip)
63
+ end
64
+
65
+ should "return Vanilla::Renderers::Base if the render_as property is blank" do
66
+ snip = create_snip(:name => "blah", :render_as => '')
67
+ assert_equal Vanilla::Renderers::Base, @app.renderer_for(snip)
68
+ end
69
+
70
+ should "raise an error if the specified renderer doesn't exist" do
71
+ snip = create_snip(:name => "blah", :render_as => "NonExistentClass")
72
+ assert_raises(NameError) { @app.renderer_for(snip) }
73
+ end
74
+
75
+ should "load constants presented as a string" do
76
+ class ::MyRenderer
77
+ end
78
+ app = Vanilla::App.new(:soup => soup_path, :renderers => {"my_renderer" => "MyRenderer"})
79
+ snip = create_snip(:name => "blah", :render_as => "my_renderer")
80
+ assert_equal MyRenderer, app.renderer_for(snip)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,125 @@
1
+ require "test_helper"
2
+
3
+ context "When presenting" do
4
+ setup do
5
+ set_main_template "<tag>{current_snip}</tag>"
6
+ create_snip :name => "test", :content => "blah {other_snip}", :part => 'part content'
7
+ create_snip :name => "other_snip", :content => "blah!"
8
+ end
9
+
10
+ context "HTML" do
11
+ should "render the snip's content in the system template if no format or part is given" do
12
+ assert_response_body "<tag>blah blah!</tag>", "/test"
13
+ end
14
+
15
+ should "render the snip's content in the system template if the HTML format is given" do
16
+ assert_response_body "<tag>blah blah!</tag>", "/test.html"
17
+ end
18
+
19
+ should "render the requested part within the main template when a part is given" do
20
+ assert_response_body "<tag>part content</tag>", "/test/part"
21
+ end
22
+
23
+ should "have a response code of 200" do
24
+ assert_equal 200, response_code_for("/test")
25
+ assert_equal 200, response_code_for("/test.html")
26
+ assert_equal 200, response_code_for("/test/part")
27
+ assert_equal 200, response_code_for("/test/part.html")
28
+ end
29
+
30
+ should "not allow rendering of the layout to produce infinite recursion" do
31
+ assert_response_body "Rendering of the current layout would result in infinite recursion.", "/layout"
32
+ end
33
+ end
34
+
35
+ context "as text" do
36
+ should "render the snip's content outside of the main template with its default renderer" do
37
+ assert_response_body "blah blah!", "/test.text"
38
+ end
39
+
40
+ should "render the snip part outside the main template when a format is given" do
41
+ assert_response_body "part content", "/test/part.text"
42
+ end
43
+
44
+ should "have a response code of 200" do
45
+ assert_equal 200, response_code_for("/test.text")
46
+ assert_equal 200, response_code_for("/test/part.text")
47
+ end
48
+ end
49
+
50
+ context "raw content" do
51
+ should "render the snips contents exactly as they are" do
52
+ assert_response_body "blah {other_snip}", "/test.raw"
53
+ end
54
+
55
+ should "render the snip content exactly even if a render_as attribute exists" do
56
+ assert_response_body "CurrentSnip", "/current_snip.raw"
57
+ end
58
+
59
+ should "render a snips part if requested" do
60
+ assert_response_body "part content", "/test/part.raw"
61
+ end
62
+
63
+ should "have a response code of 200" do
64
+ assert_equal 200, response_code_for("/test.raw")
65
+ assert_equal 200, response_code_for("/test/part.raw")
66
+ end
67
+ end
68
+
69
+ context "a snip with a custom layout" do
70
+ should "render the snips contents within that layout" do
71
+ create_snip :name => "custom-layout", :content => "<custom>{current_snip}</custom>"
72
+ create_snip :name => "test", :content => "this is a test", :layout => "custom-layout"
73
+ assert_response_body "<custom>this is a test</custom>", "/test"
74
+ end
75
+ end
76
+
77
+ class CustomRenderer < ::Vanilla::Renderers::Base
78
+ def default_layout_snip
79
+ soup['custom-layout']
80
+ end
81
+ end
82
+
83
+ context "a snip using a renderer that specifies a template" do
84
+ setup do
85
+ @app.register_renderer CustomRenderer, "custom"
86
+ create_snip :name => "custom-layout", :content => "<custom>{current_snip}</custom>"
87
+ end
88
+
89
+ should "use the renderer's specified layout" do
90
+ create_snip :name => "test", :content => "this is a test", :render_as => "custom"
91
+ assert_response_body "<custom>this is a test</custom>", "/test"
92
+ end
93
+
94
+ should "use the snips layout when given" do
95
+ create_snip :name => "snip-custom-layout", :content => "<snipcustom>{current_snip}</snipcustom>"
96
+ create_snip :name => "test", :content => "this is a test", :render_as => "custom", :layout => "snip-custom-layout"
97
+ assert_response_body "<snipcustom>this is a test</snipcustom>", "/test"
98
+ end
99
+ end
100
+
101
+ context "and a custom default renderer has been provided" do
102
+ should "use that renderer" do
103
+ @app = Vanilla::App.new(:soup => soup_path, :default_renderer => ::Vanilla::Renderers::Bold)
104
+ create_snip :name => "layout", :content => "{test}", :render_as => "base"
105
+ create_snip :name => "test", :content => "test"
106
+ assert_response_body "<b>test</b>", "/test"
107
+ end
108
+ end
109
+
110
+ context "and a missing snip is requested" do
111
+ should "render missing snip content in the main template" do
112
+ assert_response_body %{<tag>Couldn't find snip "missing_snip"</tag>}, "/missing_snip"
113
+ end
114
+
115
+ should "have a 404 response code" do
116
+ assert_equal 404, response_code_for("/missing_snip")
117
+ end
118
+ end
119
+
120
+ context "requesting an unknown format" do
121
+ should "return a 500 status code" do
122
+ assert_equal 500, response_code_for("/test.monkey")
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,87 @@
1
+ require "test_helper"
2
+
3
+ describe Vanilla::Request do
4
+ context "when requesting the root" do
5
+ setup { @request = Vanilla::Request.new(mock_env_for_url("/"), @app) }
6
+
7
+ should "set snip to 'start' by default" do
8
+ assert_equal "start", @request.snip_name
9
+ end
10
+
11
+ should "set format to 'html'" do
12
+ assert_equal "html", @request.format
13
+ end
14
+ end
15
+
16
+ context "when requesting urls" do
17
+ setup { @request = Vanilla::Request.new(mock_env_for_url("/snip"), @app) }
18
+
19
+ should "use the first segement as the snip name" do
20
+ assert_equal "snip", @request.snip_name
21
+ end
22
+
23
+ should "try to load the snip based on the snip name" do
24
+ @app.soup.expects(:[]).with('snip').returns(:snip)
25
+ assert_equal :snip, @request.snip
26
+ end
27
+
28
+ should "have no part if the url contains only a single segment" do
29
+ assert_equal nil, @request.part
30
+ end
31
+
32
+ should "have a default format of html" do
33
+ assert_equal 'html', @request.format
34
+ end
35
+
36
+ should "determine the request method" do
37
+ assert_equal 'get', @request.method
38
+ end
39
+ end
40
+
41
+ context "when requesting a snip part" do
42
+ setup { @request = Vanilla::Request.new(mock_env_for_url("/snip/part"), @app) }
43
+
44
+ should "use the first segment as the snip, and the second segment as the part" do
45
+ assert_equal "snip", @request.snip_name
46
+ assert_equal "part", @request.part
47
+ end
48
+
49
+ should "have a default format of html" do
50
+ assert_equal "html", @request.format
51
+ end
52
+ end
53
+
54
+ context "when requesting a snip with a format" do
55
+ setup { @request = Vanilla::Request.new(mock_env_for_url("/snip.raw"), @app) }
56
+
57
+ should "use the extension as the format" do
58
+ assert_equal "raw", @request.format
59
+ end
60
+
61
+ should "retain the filename part of the path as the snip" do
62
+ assert_equal "snip", @request.snip_name
63
+ end
64
+ end
65
+
66
+ context "when requesting a snip part with a format" do
67
+ setup { @request = Vanilla::Request.new(mock_env_for_url("/snip/part.raw"), @app) }
68
+
69
+ should "use the extension as the format" do
70
+ assert_equal "raw", @request.format
71
+ end
72
+
73
+ should "retain the first segment of the path as the snip" do
74
+ assert_equal "snip", @request.snip_name
75
+ end
76
+
77
+ should "use the filename part of the second segment as the snip part" do
78
+ assert_equal "part", @request.part
79
+ end
80
+ end
81
+
82
+ context "when requested with a _method parameter" do
83
+ should "return the method using the parameter" do
84
+ assert_equal 'put', Vanilla::Request.new(mock_env_for_url("/snip?_method=put"), @app).method
85
+ end
86
+ end
87
+ end