vanilla 1.0.2 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
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