frank 0.2.6 → 0.3.0.beta

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 (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