frank 0.2.6 → 0.3.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/Featurelist +6 -0
  2. data/README.md +44 -32
  3. data/Rakefile +3 -3
  4. data/frank.gemspec +51 -45
  5. data/lib/frank.rb +1 -0
  6. data/lib/frank/base.rb +144 -94
  7. data/lib/frank/lorem.rb +77 -36
  8. data/lib/frank/middleware/imager.rb +43 -0
  9. data/lib/frank/middleware/refresh.rb +42 -0
  10. data/lib/frank/middleware/statik.rb +41 -0
  11. data/lib/frank/output.rb +25 -37
  12. data/lib/frank/rescue.rb +13 -6
  13. data/lib/frank/template_helpers.rb +34 -3
  14. data/lib/frank/templates/404.haml +1 -0
  15. data/lib/frank/templates/500.haml +2 -0
  16. data/lib/frank/tilt.rb +389 -141
  17. data/lib/template/{dynamic/layout.haml → layouts/default.haml} +0 -0
  18. data/lib/template/settings.yml +15 -28
  19. data/spec/base_spec.rb +88 -0
  20. data/{test → spec}/helper.rb +0 -7
  21. data/spec/output_spec.rb +220 -0
  22. data/spec/render_spec.rb +106 -0
  23. data/spec/template/dynamic/500.haml +1 -0
  24. data/{test → spec}/template/dynamic/_partial.haml +0 -0
  25. data/{test → spec}/template/dynamic/builder.builder +0 -0
  26. data/{test → spec}/template/dynamic/coffee.coffee +0 -0
  27. data/{test → spec}/template/dynamic/erb.erb +0 -0
  28. data/{test → spec}/template/dynamic/helper_test.haml +0 -0
  29. data/spec/template/dynamic/index.haml +5 -0
  30. data/spec/template/dynamic/layout2_test.haml +4 -0
  31. data/{test → spec}/template/dynamic/liquid.liquid +0 -0
  32. data/spec/template/dynamic/lorem_test.haml +7 -0
  33. data/{test → spec}/template/dynamic/markdown.md +0 -0
  34. data/spec/template/dynamic/markdown_in_haml.md +4 -0
  35. data/{test → spec}/template/dynamic/mustache.mustache +0 -0
  36. data/spec/template/dynamic/nested/child.haml +1 -0
  37. data/spec/template/dynamic/nested/deeper/deep.haml +1 -0
  38. data/spec/template/dynamic/no_layout.haml +4 -0
  39. data/spec/template/dynamic/partial_test.haml +2 -0
  40. data/{test → spec}/template/dynamic/redcloth.textile +0 -0
  41. data/spec/template/dynamic/refresh.haml +1 -0
  42. data/{test → spec}/template/dynamic/sass.sass +0 -0
  43. data/{test → spec}/template/helpers.rb +0 -0
  44. data/spec/template/layouts/default.haml +3 -0
  45. data/{test/template/dynamic → spec/template/layouts/explicit}/layout2.haml +0 -0
  46. data/spec/template/layouts/nested/default.haml +2 -0
  47. data/spec/template/settings.yml +45 -0
  48. data/{test/template/static → spec/template/static/files}/static.html +0 -0
  49. data/spec/template_helpers_spec.rb +78 -0
  50. metadata +57 -49
  51. data/lib/frank/imager.rb +0 -39
  52. data/lib/frank/statik.rb +0 -39
  53. data/test/suite.rb +0 -4
  54. data/test/template/dynamic/index.haml +0 -2
  55. data/test/template/dynamic/layout.haml +0 -2
  56. data/test/template/dynamic/layout2_test.haml +0 -1
  57. data/test/template/dynamic/layout_test.haml +0 -1
  58. data/test/template/dynamic/lorem_test.haml +0 -7
  59. data/test/template/dynamic/partial_test.haml +0 -2
  60. data/test/template/settings.yml +0 -62
  61. data/test/test_base.rb +0 -81
  62. data/test/test_helpers.rb +0 -71
  63. data/test/test_output.rb +0 -160
  64. data/test/test_render.rb +0 -89
@@ -1,17 +1,3 @@
1
- # -----------------------------------------------
2
- # Frank settings:
3
- #
4
- # These settings will apply to this project only.
5
- # If you would like to use this project as a
6
- # template for new projects, just copy this
7
- # project folder to `~/.frank` and it will be
8
- # duplicated for you every time you run the
9
- # `frank` command.
10
- #
11
- # Feel free to trash all these comments, too.
12
- #
13
-
14
-
15
1
  # ----------------------
16
2
  # Server settings:
17
3
  #
@@ -41,17 +27,18 @@ static_folder: static
41
27
  dynamic_folder: dynamic
42
28
 
43
29
  # ----------------------
44
- # Templates:
45
- #
46
- # 'layouts' is a list of layouts to use, where
47
- # 'name' is the filename (without extension).
48
- # You can also use multiple layouts, and limit
49
- # their scopes like so:
50
- # - name: blog_layout
51
- # only: [blog]
52
- # - name: normal
53
- # not: [blog, ajax]
54
- templates:
55
- layouts:
56
- - name: layout
57
-
30
+ # Layouts folder:
31
+ #
32
+ # Frank will look for layouts in this folder
33
+ # the default layout is `default'
34
+ # it respects nested layouts that correspond to nested
35
+ # folders in the `dynamic_folder'
36
+ # for example: a template: `dynamic_folder/blog/a-blog-post.haml'
37
+ # would look for a layout: `layouts/blog/default.haml'
38
+ # and if not found use the default: `layouts/default.haml'
39
+ #
40
+ # Frank also supports defining layouts on an
41
+ # individual template basis using meta data
42
+ # you can do this by defining a meta field `layout: my_layout.haml'
43
+ #
44
+ layouts_folder: layouts
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe Frank::Base do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ proj_dir = File.join(File.dirname(__FILE__), 'template')
8
+ settings = YAML.load_file(File.join(proj_dir, 'settings.yml'))
9
+ Frank.new do
10
+ settings.each do |name, value|
11
+ set name.to_s, value
12
+ end
13
+ set :environment, :test
14
+ set :proj_dir, proj_dir
15
+ end
16
+ end
17
+
18
+ it 'has all of the required settings set' do
19
+ app.proj_dir.should_not be_nil
20
+ app.server.should_not be_nil
21
+ app.static_folder.should_not be_nil
22
+ app.dynamic_folder.should_not be_nil
23
+ app.layouts_folder.should_not be_nil
24
+ end
25
+
26
+ it 'renders a dynamic template given a request' do
27
+ get '/'
28
+
29
+ last_response.should be_ok
30
+ last_response.body.should == "<div id='p'>/</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <h2>/</h2>\n</div>\n"
31
+ end
32
+
33
+ it 'renders a page and uses a helper' do
34
+ get '/helper_test'
35
+
36
+ last_response.should be_ok
37
+ last_response.body.should == "<div id='p'>/helper_test</div>\n<div id='layout'>\n <h1>hello from helper</h1>\n</div>\n"
38
+ end
39
+
40
+ it 'renders a nested template given a request' do
41
+ get '/nested/child'
42
+
43
+ last_response.should be_ok
44
+ last_response.body.should == "<div id='nested_layout'>\n <h1>hello from child</h1>\n</div>\n"
45
+ end
46
+
47
+ it 'renders dynamic css without a layout' do
48
+ get '/sass.css'
49
+
50
+ last_response.should be_ok
51
+ last_response.body.should == "#hello-worlds {\n background: red; }\n"
52
+ end
53
+
54
+ it 'renders dynamic javascript without a layout' do
55
+ get '/coffee.js'
56
+
57
+ last_response.should be_ok
58
+ last_response.body.should == "(function(){\n var greeting;\n greeting = \"Hello CoffeeScript\";\n})();"
59
+ end
60
+
61
+ it 'renders a 404 page if template not found' do
62
+ get '/not_here.css'
63
+
64
+ last_response.should_not be_ok
65
+ last_response.content_type.should == 'text/html'
66
+ last_response.body.should =~ /Not Found/
67
+ end
68
+
69
+ it 'renders a 500 page for error' do
70
+ capture_stdout { get '/500' }
71
+
72
+ last_response.should_not be_ok
73
+ last_response.content_type.should == 'text/html'
74
+ last_response.body.should =~ /undefined local variable or method `non_method'/
75
+ end
76
+
77
+ it 'stubs out a project' do
78
+ out = capture_stdout { Frank.stub('stubbed') }
79
+ Dir.entries('stubbed').should == Dir.entries(File.join(LIBDIR, 'template'))
80
+ response = "\nFrank is...\n - \e[32mCreating\e[0m your project 'stubbed'\n - \e[32mCopying\e[0m Frank template\n\n \e[32mCongratulations, 'stubbed' is ready to go!\e[0m\n"
81
+ out.string.should == response
82
+ end
83
+
84
+ after(:all) do
85
+ FileUtils.rm_r File.join(Dir.pwd, 'stubbed')
86
+ end
87
+
88
+ end
@@ -6,12 +6,9 @@ $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
6
6
 
7
7
  require 'stringio'
8
8
  require 'rubygems'
9
- require 'test/unit'
10
9
  require 'rack/test'
11
- require 'shoulda'
12
10
  require 'template/helpers'
13
11
  require 'frank'
14
- require 'ruby-debug'
15
12
 
16
13
  module Kernel
17
14
  def capture_stdout
@@ -23,7 +20,3 @@ module Kernel
23
20
  $stdout = STDOUT
24
21
  end
25
22
  end
26
-
27
- class Test::Unit::TestCase
28
- include Rack::Test::Methods
29
- end
@@ -0,0 +1,220 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe Frank::Output do
4
+ include Rack::Test::Methods
5
+
6
+ context 'default output' do
7
+ before(:all) do
8
+ proj_dir = File.join(File.dirname(__FILE__), 'template')
9
+ settings = YAML.load_file(File.join(proj_dir, 'settings.yml'))
10
+ require File.join(proj_dir, 'helpers')
11
+ capture_stdout do
12
+ Frank::Output.new do
13
+ settings.each do |name, value|
14
+ set name.to_s, value
15
+ end
16
+ set :environment, :output
17
+ set :proj_dir, proj_dir
18
+ set :output_folder, File.join(File.dirname(__FILE__), 'template/output')
19
+ end.dump
20
+ end
21
+ end
22
+
23
+ it 'creates the output folder' do
24
+ File.exist?(File.join(File.dirname(__FILE__), 'template/output')).should be_true
25
+ end
26
+
27
+ it 'creates index.html' do
28
+ output = File.join(File.dirname(__FILE__), 'template/output/index.html')
29
+ File.read(output).should == "<div id='p'>/</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <h2>/</h2>\n</div>\n"
30
+ end
31
+
32
+ it 'creates partial_test.html' do
33
+ output = File.join(File.dirname(__FILE__), 'template/output/partial_test.html')
34
+ File.read(output).should == "<div id='p'>/partial_test</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <p>hello from partial</p>\n</div>\n"
35
+ end
36
+
37
+ it 'creates child.html' do
38
+ output = File.join(File.dirname(__FILE__), 'template/output/nested/child.html')
39
+ File.read(output).should == "<div id='nested_layout'>\n <h1>hello from child</h1>\n</div>\n"
40
+ end
41
+
42
+ it 'creates deep.html' do
43
+ output = File.join(File.dirname(__FILE__), 'template/output/nested/deeper/deep.html')
44
+ File.read(output).should == "<div id='nested_layout'>\n <h1>really deep</h1>\n</div>\n"
45
+ end
46
+
47
+ it 'creates no_layout.html' do
48
+ output = File.join(File.dirname(__FILE__), 'template/output/no_layout.html')
49
+ File.read(output).should == "<h1>i have no layout</h1>\n"
50
+ end
51
+
52
+ it 'creates erb.html' do
53
+ output = File.join(File.dirname(__FILE__), 'template/output/erb.html')
54
+ File.read(output).should == "<h1>hello worlds</h1>\n\n"
55
+ end
56
+
57
+ it 'creates redcloth.html' do
58
+ output = File.join(File.dirname(__FILE__), 'template/output/redcloth.html')
59
+ File.read(output).should == "<h1>hello worlds</h1>"
60
+ end
61
+
62
+ it 'creates markdown.html' do
63
+ output = File.join(File.dirname(__FILE__), 'template/output/markdown.html')
64
+ File.read(output).should == "<h1>hello worlds</h1>\n"
65
+ end
66
+
67
+ it 'creates mustache.html' do
68
+ output = File.join(File.dirname(__FILE__), 'template/output/mustache.html')
69
+ File.read(output).should == "<h1>hello worlds</h1>\n\n"
70
+ end
71
+
72
+ it 'creates liquid.html' do
73
+ output = File.join(File.dirname(__FILE__), 'template/output/liquid.html')
74
+ File.read(output).should == "<h1>hello worlds</h1>\n"
75
+ end
76
+
77
+ it 'creates builder.html' do
78
+ output = File.join(File.dirname(__FILE__), 'template/output/builder.html')
79
+ File.read(output).should == "<h1>hello worlds</h1>\n"
80
+ end
81
+
82
+ it 'copies static.html' do
83
+ output = File.join(File.dirname(__FILE__), 'template/output/files/static.html')
84
+ File.read(output).should == "hello from static"
85
+ end
86
+
87
+ it "doesn't create partials" do
88
+ File.exist?(File.join(File.dirname(__FILE__), 'template/output/_partial.html')).should be_false
89
+ end
90
+
91
+ it 'handles lorem replacement fields' do
92
+ output = File.join(File.dirname(__FILE__), 'template/output/lorem_test.html')
93
+ File.read(output).should include("<p class='words'>replace-this</p>")
94
+ File.read(output).should include("<p class='sentences'>replace-this</p>")
95
+ File.read(output).should include("<p class='paragraphs'>replace-this</p>")
96
+ File.read(output).should include("<p class='date'>replace-this</p>")
97
+ File.read(output).should include("<p class='name'>replace-this</p>")
98
+ File.read(output).should include("<p class='email'>replace-this</p>")
99
+ File.read(output).should include("<img src='replace-this' />")
100
+ end
101
+
102
+ it 'should not render the refresh js' do
103
+ output = File.join(File.dirname(__FILE__), 'template/output/refresh.html')
104
+ File.read(output).should == "<div id='p'>/refresh</div>\n<div id='layout'>\n \n</div>\n"
105
+ end
106
+
107
+ after(:all) do
108
+ FileUtils.rm_r File.join(File.dirname(__FILE__), 'template/output')
109
+ end
110
+
111
+ end
112
+
113
+ context 'productions output' do
114
+ before(:all) do
115
+ proj_dir = File.join(File.dirname(__FILE__), 'template')
116
+ settings = YAML.load_file(File.join(proj_dir, 'settings.yml'))
117
+ require File.join(proj_dir, 'helpers')
118
+ capture_stdout do
119
+ Frank::Output.new do
120
+ settings.each do |name, value|
121
+ set name.to_s, value
122
+ end
123
+ set :environment, :output
124
+ set :proj_dir, proj_dir
125
+ set :output_folder, File.join(File.dirname(__FILE__), 'template/output')
126
+ end.dump(production=true)
127
+ end
128
+ end
129
+
130
+ it 'creates the output folder' do
131
+ File.exist?(File.join(File.dirname(__FILE__), 'template/output')).should be_true
132
+ end
133
+
134
+ it 'creates index.html' do
135
+ output = File.join(File.dirname(__FILE__), 'template/output/index.html')
136
+ File.read(output).should == "<div id='p'>/</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <h2>/</h2>\n</div>\n"
137
+ end
138
+
139
+ it 'creates partial_test.html' do
140
+ output = File.join(File.dirname(__FILE__), 'template/output/partial_test/index.html')
141
+ File.read(output).should == "<div id='p'>/partial_test</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <p>hello from partial</p>\n</div>\n"
142
+ end
143
+
144
+ it 'creates child.html' do
145
+ output = File.join(File.dirname(__FILE__), 'template/output/nested/child/index.html')
146
+ File.read(output).should == "<div id='nested_layout'>\n <h1>hello from child</h1>\n</div>\n"
147
+ end
148
+
149
+ it 'creates deep.html' do
150
+ output = File.join(File.dirname(__FILE__), 'template/output/nested/deeper/deep/index.html')
151
+ File.read(output).should == "<div id='nested_layout'>\n <h1>really deep</h1>\n</div>\n"
152
+ end
153
+
154
+ it 'creates no_layout.html' do
155
+ output = File.join(File.dirname(__FILE__), 'template/output/no_layout/index.html')
156
+ File.read(output).should == "<h1>i have no layout</h1>\n"
157
+ end
158
+
159
+ it 'creates erb.html' do
160
+ output = File.join(File.dirname(__FILE__), 'template/output/erb/index.html')
161
+ File.read(output).should == "<h1>hello worlds</h1>\n\n"
162
+ end
163
+
164
+ it 'creates redcloth.html' do
165
+ output = File.join(File.dirname(__FILE__), 'template/output/redcloth/index.html')
166
+ File.read(output).should == "<h1>hello worlds</h1>"
167
+ end
168
+
169
+ it 'creates markdown.html' do
170
+ output = File.join(File.dirname(__FILE__), 'template/output/markdown/index.html')
171
+ File.read(output).should == "<h1>hello worlds</h1>\n"
172
+ end
173
+
174
+ it 'creates mustache.html' do
175
+ output = File.join(File.dirname(__FILE__), 'template/output/mustache/index.html')
176
+ File.read(output).should == "<h1>hello worlds</h1>\n\n"
177
+ end
178
+
179
+ it 'creates liquid.html' do
180
+ output = File.join(File.dirname(__FILE__), 'template/output/liquid/index.html')
181
+ File.read(output).should == "<h1>hello worlds</h1>\n"
182
+ end
183
+
184
+ it 'creates builder.html' do
185
+ output = File.join(File.dirname(__FILE__), 'template/output/builder/index.html')
186
+ File.read(output).should == "<h1>hello worlds</h1>\n"
187
+ end
188
+
189
+ it 'copies static.html' do
190
+ output = File.join(File.dirname(__FILE__), 'template/output/files/static.html')
191
+ File.read(output).should == "hello from static"
192
+ end
193
+
194
+ it "doesn't create partials" do
195
+ File.exist?(File.join(File.dirname(__FILE__), 'template/output/_partial/index.html')).should be_false
196
+ end
197
+
198
+ it 'handles lorem replacement fields' do
199
+ output = File.join(File.dirname(__FILE__), 'template/output/lorem_test/index.html')
200
+ File.read(output).should include("<p class='words'>replace-this</p>")
201
+ File.read(output).should include("<p class='sentences'>replace-this</p>")
202
+ File.read(output).should include("<p class='paragraphs'>replace-this</p>")
203
+ File.read(output).should include("<p class='date'>replace-this</p>")
204
+ File.read(output).should include("<p class='name'>replace-this</p>")
205
+ File.read(output).should include("<p class='email'>replace-this</p>")
206
+ File.read(output).should include("<img src='replace-this' />")
207
+ end
208
+
209
+ it 'should not render the refresh js' do
210
+ output = File.join(File.dirname(__FILE__), 'template/output/refresh/index.html')
211
+ File.read(output).should == "<div id='p'>/refresh</div>\n<div id='layout'>\n \n</div>\n"
212
+ end
213
+
214
+ after(:all) do
215
+ FileUtils.rm_r File.join(File.dirname(__FILE__), 'template/output')
216
+ end
217
+
218
+ end
219
+
220
+ end
@@ -0,0 +1,106 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe Frank::Render do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ proj_dir = File.join(File.dirname(__FILE__), 'template')
8
+ settings = YAML.load_file(File.join(proj_dir, 'settings.yml'))
9
+ Frank.new do
10
+ settings.each do |name, value|
11
+ set name.to_s, value
12
+ end
13
+ set :environment, :test
14
+ set :proj_dir, proj_dir
15
+ end
16
+ end
17
+
18
+ before(:all) do
19
+ @app = app
20
+ end
21
+
22
+ it 'renders a template using layout' do
23
+ template = @app.render('index.haml')
24
+ template.should == "<div id='p'>/</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <h2>/</h2>\n</div>\n"
25
+ end
26
+
27
+ it 'renders a template using layout2' do
28
+ template = @app.render('layout2_test.haml')
29
+ template.should == "<div id='layout2'>\n <h1>hi inside layout2</h1>\n</div>\n"
30
+ end
31
+
32
+ it 'renders a markdown template inside haml layout' do
33
+ template = @app.render('markdown_in_haml.md')
34
+ template.should == "<div id='p'>/markdown_in_haml</div>\n<div id='layout'>\n <h1>hi inside layout</h1>\n</div>\n"
35
+ end
36
+
37
+ it 'renders a nested template with a nested layout' do
38
+ template = @app.render('/nested/child.haml')
39
+ template.should == "<div id='nested_layout'>\n <h1>hello from child</h1>\n</div>\n"
40
+ end
41
+
42
+ it 'renders a deeply nested template with a nested layout' do
43
+ template = @app.render('/nested/deeper/deep.haml')
44
+ template.should == "<div id='nested_layout'>\n <h1>really deep</h1>\n</div>\n"
45
+ end
46
+
47
+ it 'renders a haml template with no layout' do
48
+ template = @app.render('no_layout.haml')
49
+ template.should == "<h1>i have no layout</h1>\n"
50
+ end
51
+
52
+ it 'renders haml template' do
53
+ template = @app.render('index.haml')
54
+ template.should == "<div id='p'>/</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <h2>/</h2>\n</div>\n"
55
+ end
56
+
57
+ it 'renders haml template with a haml partial' do
58
+ template = @app.render('partial_test.haml')
59
+ template.should == "<div id='p'>/partial_test</div>\n<div id='layout'>\n <h1>hello worlds</h1>\n <p>hello from partial</p>\n</div>\n"
60
+ end
61
+
62
+ it 'renders sass template' do
63
+ template = @app.render('sass.sass')
64
+ template.should == "#hello-worlds {\n background: red; }\n"
65
+ end
66
+
67
+ it 'renders coffee template' do
68
+ template = @app.render('coffee.coffee')
69
+ template.should == "(function(){\n var greeting;\n greeting = \"Hello CoffeeScript\";\n})();"
70
+ end
71
+
72
+ it 'renders erb template' do
73
+ template = @app.render('erb.erb')
74
+ template.should == "<h1>hello worlds</h1>\n\n"
75
+ end
76
+
77
+ it 'renders redcloth template' do
78
+ template = @app.render('redcloth.textile')
79
+ template.should == "<h1>hello worlds</h1>"
80
+ end
81
+
82
+ it 'renders rdiscount template' do
83
+ template = @app.render('markdown.md')
84
+ template.should == "<h1>hello worlds</h1>\n"
85
+ end
86
+
87
+ it 'renders mustache template' do
88
+ template = @app.render('mustache.mustache')
89
+ template.should == "<h1>hello worlds</h1>\n\n"
90
+ end
91
+
92
+ it 'renders liquid template' do
93
+ template = @app.render('liquid.liquid')
94
+ template.should == "<h1>hello worlds</h1>\n"
95
+ end
96
+
97
+ it 'renders builder template' do
98
+ template = @app.render('builder.builder')
99
+ template.should == "<h1>hello worlds</h1>\n"
100
+ end
101
+
102
+ it 'raise template error' do
103
+ lambda { @app.render('not_a.template') }.should raise_error(Frank::TemplateError)
104
+ end
105
+
106
+ end