baron 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/LICENSE +38 -0
  2. data/Rakefile +34 -0
  3. data/Readme.md +168 -0
  4. data/VERSION +1 -0
  5. data/lib/baron.rb +373 -0
  6. data/spec/baron_article_spec.rb +53 -0
  7. data/spec/baron_blog_engine_spec.rb +62 -0
  8. data/spec/baron_spec.rb +174 -0
  9. data/spec/sample_data/Gemfile +6 -0
  10. data/spec/sample_data/Rakefile +42 -0
  11. data/spec/sample_data/articles/2012-11-09-sample-post.txt +11 -0
  12. data/spec/sample_data/articles/poems/1909-01-02-If.txt +48 -0
  13. data/spec/sample_data/articles/poems/1916-01-01-the-road-not-taken.txt +26 -0
  14. data/spec/sample_data/config.ru +46 -0
  15. data/spec/sample_data/images/import-csv-file-1.png +0 -0
  16. data/spec/sample_data/images/import-csv-file-2.png +0 -0
  17. data/spec/sample_data/images/import-csv-file-3.png +0 -0
  18. data/spec/sample_data/images/instagram.png +0 -0
  19. data/spec/sample_data/pages/about.rhtml +14 -0
  20. data/spec/sample_data/resources/feed.rss +18 -0
  21. data/spec/sample_data/resources/redirects.txt +44 -0
  22. data/spec/sample_data/resources/robots.txt +1 -0
  23. data/spec/sample_data/themes/test/css/app.css +27 -0
  24. data/spec/sample_data/themes/test/css/bootstrap-responsive.css +1092 -0
  25. data/spec/sample_data/themes/test/css/bootstrap-responsive.min.css +9 -0
  26. data/spec/sample_data/themes/test/css/bootstrap.css +6039 -0
  27. data/spec/sample_data/themes/test/css/bootstrap.min.css +9 -0
  28. data/spec/sample_data/themes/test/img/glyphicons-halflings-white.png +0 -0
  29. data/spec/sample_data/themes/test/img/glyphicons-halflings.png +0 -0
  30. data/spec/sample_data/themes/test/img/instagram.png +0 -0
  31. data/spec/sample_data/themes/test/js/bootstrap.js +2159 -0
  32. data/spec/sample_data/themes/test/js/bootstrap.min.js +6 -0
  33. data/spec/sample_data/themes/test/js/image_alt.js +12 -0
  34. data/spec/sample_data/themes/test/js/read_later.js +14 -0
  35. data/spec/sample_data/themes/test/templates/archives.rhtml +14 -0
  36. data/spec/sample_data/themes/test/templates/article.rhtml +14 -0
  37. data/spec/sample_data/themes/test/templates/category.rhtml +15 -0
  38. data/spec/sample_data/themes/test/templates/error.rhtml +3 -0
  39. data/spec/sample_data/themes/test/templates/index.rhtml +26 -0
  40. data/spec/sample_data/themes/test/templates/layout.rhtml +86 -0
  41. data/spec/spec_helper.rb +19 -0
  42. metadata +150 -0
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ ###
4
+ # Tests Baron::ArticleModel class
5
+ #
6
+ # This class represents an individual article
7
+
8
+ describe "Baron::ArticleModel" do
9
+ before :all do
10
+ @config = load_config()
11
+ @article_parts = {:filename_and_path => "#{SAMPLE_DATA_PATH}articles/poems/1916-01-01-the-road-not-taken.txt",
12
+ :date => '1916-01-01',
13
+ :filename => 'the-road-not-taken',
14
+ :category => 'poems'}
15
+ @article = Baron::Article.new(@article_parts, @config)
16
+ end
17
+
18
+ describe "Provides access to properties" do
19
+ it "should return input parameters" do
20
+ @article[:filename_and_path].should eq(@article_parts[:filename_and_path])
21
+ @article[:date].should be_instance_of(Date)
22
+ @article[:category].should eq(@article_parts[:category])
23
+ end
24
+
25
+ it "should return article data correctly" do
26
+ @article[:title].should eq('The Road Not Taken')
27
+ @article.title.should eq('The Road Not Taken')
28
+ @article[:author].should eq('Robert Frost')
29
+ @article.author.should eq('Robert Frost')
30
+ @article[:body].length.should > 0
31
+ @article[:category].should eq('poems')
32
+ @article.category.should eq('poems')
33
+ @article[:slug].should eq('the-road-not-taken')
34
+ @article.slug.should eq('the-road-not-taken')
35
+ end
36
+
37
+ it "should handle different path configuations" do
38
+ @article.path('', :no_date).should eq('/poems/the-road-not-taken/')
39
+ @article.path('', :year_month_day_date).should eq('/poems/1916/01/01/the-road-not-taken/')
40
+ @article.path('', :year_month_date).should eq('/poems/1916/01/the-road-not-taken/')
41
+ @article.path('', :year_date).should eq('/poems/1916/the-road-not-taken/')
42
+ @article.path('posts', :no_date).should eq('/posts/poems/the-road-not-taken/')
43
+ @article.path('posts', :year_month_day_date).should eq('/posts/poems/1916/01/01/the-road-not-taken/')
44
+ @article.path('posts', :year_month_date).should eq('/posts/poems/1916/01/the-road-not-taken/')
45
+ @article.path('posts', :year_date).should eq('/posts/poems/1916/the-road-not-taken/')
46
+ @article.path('/foo/bar/', :no_date).should eq('/foo/bar/poems/the-road-not-taken/')
47
+ @article.path('/foo/bar/', :no_date).should eq('/foo/bar/poems/the-road-not-taken/')
48
+ @article.path('/foo/bar/', :year_month_day_date).should eq('/foo/bar/poems/1916/01/01/the-road-not-taken/')
49
+ @article.path('/foo/bar/', :year_month_date).should eq('/foo/bar/poems/1916/01/the-road-not-taken/')
50
+ @article.path('/foo/bar/', :year_date).should eq('/foo/bar/poems/1916/the-road-not-taken/')
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ ###
4
+ # Tests Baron::BlogEngine class
5
+ #
6
+ # This class understands how the blog directory structure works, and is used by the app to access
7
+ # all content from the directory structure.
8
+
9
+ describe "Baron::BlogEngine" do
10
+ before :all do
11
+ @config = load_config()
12
+ @blog_engine = Baron::BlogEngine.new @config
13
+ end
14
+
15
+ describe "Access all content" do
16
+ it "finds application paths" do
17
+ @blog_engine.get_pages_path.should == SAMPLE_DATA_PATH + 'pages/'
18
+ @blog_engine.get_articles_path.should == SAMPLE_DATA_PATH + 'articles'
19
+ @blog_engine.get_page_template('about').should == SAMPLE_DATA_PATH + 'pages/about.rhtml'
20
+ @blog_engine.get_theme_template('article').should == SAMPLE_DATA_PATH + 'themes/test/templates/article.rhtml'
21
+ @blog_engine.get_theme_template('category').should == SAMPLE_DATA_PATH + 'themes/test/templates/category.rhtml'
22
+ @blog_engine.get_theme_template('error').should == SAMPLE_DATA_PATH + 'themes/test/templates/error.rhtml'
23
+ @blog_engine.get_theme_template('index').should == SAMPLE_DATA_PATH + 'themes/test/templates/index.rhtml'
24
+ @blog_engine.get_theme_template('layout').should == SAMPLE_DATA_PATH + 'themes/test/templates/layout.rhtml'
25
+ @blog_engine.get_system_resource('redirects.txt').should == SAMPLE_DATA_PATH + 'resources/redirects.txt'
26
+ @blog_engine.get_system_resource('robots.txt').should == SAMPLE_DATA_PATH + 'resources/robots.txt'
27
+ @blog_engine.get_system_resource('feeds.rss').should == SAMPLE_DATA_PATH + 'resources/feeds.rss'
28
+ end
29
+
30
+ it "finds all categories" do
31
+ categories = @blog_engine.get_all_categories
32
+ categories.count.should == 2
33
+ categories.first[:name].should == 'Code Projects'
34
+ categories.first[:path].should == '/code-projects/'
35
+ categories.first[:count].should == 0
36
+ categories.last[:name].should == 'Poems'
37
+ categories.last[:path].should == '/poems/'
38
+ categories.last[:count].should == 2
39
+ end
40
+
41
+ it "finds all articles" do
42
+ articles_fileparts = @blog_engine.get_all_articles()
43
+ articles_fileparts.count.should == 3
44
+ articles_fileparts.first[:filename_and_path].should == SAMPLE_DATA_PATH + 'articles/2012-11-09-sample-post.txt'
45
+ articles_fileparts.first[:date].should == '2012-11-09'
46
+ articles_fileparts.first[:filename].should == 'sample-post'
47
+ articles_fileparts.first[:category].should == ''
48
+ articles_fileparts.last[:filename_and_path].should == SAMPLE_DATA_PATH + 'articles/poems/1909-01-02-If.txt'
49
+ articles_fileparts.last[:date].should == '1909-01-02'
50
+ articles_fileparts.last[:filename].should == 'if'
51
+ articles_fileparts.last[:category].should == 'poems'
52
+ end
53
+
54
+ it "returns all article parts" do
55
+ @blog_engine.get_all_articles().each do |article_parts|
56
+ article_parts[:filename_and_path].should_not == nil
57
+ article_parts[:date].should_not == nil
58
+ article_parts[:filename].should_not == nil
59
+ end
60
+ end
61
+ end # Access all content
62
+ end
@@ -0,0 +1,174 @@
1
+ require 'spec_helper'
2
+
3
+ ##
4
+ # Integration testing for the Baron Blog Engine to make sure things are
5
+ # working end-to-end
6
+
7
+ shared_examples_for "Server Response" do
8
+ it "should be valid" do
9
+ @response.status.should == 200
10
+ @response.body.length.should > 0
11
+ end
12
+ end
13
+
14
+ shared_examples_for "Server HTML Response" do
15
+ it "should be instrumented" do
16
+ @response.body.should include(GOOGLE_ANALYTICS) unless GOOGLE_ANALYTICS.empty?
17
+ end
18
+
19
+ it "should generate valid HTML" do
20
+ @response.body.scan(/<html/).count.should == 1
21
+ @response.body.scan(/<\/html>/).count.should == 1
22
+ @response.body.scan(/<head>/).count.should == 1
23
+ @response.body.scan(/<\/head>/).count.should == 1
24
+ @response.body.scan(/<body/).count.should == 1
25
+ @response.body.scan(/<\/body>/).count.should == 1
26
+ end
27
+ end
28
+
29
+ describe "Baron" do
30
+ before :all do
31
+ @config = load_config
32
+ @baron = Rack::MockRequest.new(Baron::Server.new(@config))
33
+ end
34
+
35
+ describe "GET /" do
36
+ before :all do
37
+ @response = @baron.get('/')
38
+ end
39
+
40
+ it_behaves_like "Server Response"
41
+ it_behaves_like "Server HTML Response"
42
+
43
+ it "is instrumented for Google Webmaster Tools" do
44
+ @response.body.should include(GOOGLE_WEBMASTER) unless GOOGLE_WEBMASTER.empty?
45
+ end
46
+ end
47
+
48
+ describe "GET /archives" do
49
+ before :all do
50
+ @response = @baron.get('/archives')
51
+ end
52
+
53
+ it_behaves_like "Server Response"
54
+ it_behaves_like "Server HTML Response"
55
+ end
56
+
57
+ describe "GET custom page" do
58
+ before :all do
59
+ @response = @baron.get('/about')
60
+ end
61
+
62
+ it_behaves_like "Server Response"
63
+ it_behaves_like "Server HTML Response"
64
+ end
65
+
66
+ describe "GET category index page" do
67
+ before :all do
68
+ @response = @baron.get('/poems/')
69
+ end
70
+
71
+ it_behaves_like "Server Response"
72
+ it_behaves_like "Server HTML Response"
73
+ end
74
+
75
+ describe "GET single article" do
76
+ before :all do
77
+ @response = @baron.get('/poems/the-road-not-taken')
78
+ end
79
+
80
+ it_behaves_like "Server Response"
81
+ it_behaves_like "Server HTML Response"
82
+ end
83
+
84
+ describe "GET pagination" do
85
+ before :all do
86
+ config = load_config()
87
+ config.set(:article_max, 2)
88
+ @baron = Rack::MockRequest.new(Baron::Server.new(config))
89
+ end
90
+
91
+ it "should not render a page out of bounds" do
92
+ @baron.get('/page/0/').status.should == 404
93
+ @baron.get('/page/100/').status.should == 404
94
+ end
95
+
96
+ it "should not render a mal-formed URL" do
97
+ @baron.get('/page/foobar/').status.should == 404
98
+ end
99
+
100
+ it "should render a valid request" do
101
+ response = @baron.get('/page/2/')
102
+ response.status.should == 200
103
+ response.body.length.should > 0
104
+ response.body.should include(GOOGLE_WEBMASTER) unless GOOGLE_WEBMASTER.empty?
105
+ end
106
+ end
107
+
108
+ describe "GET error page" do
109
+ it "returns proper error data" do
110
+ response = @baron.get('/fake-url-of-impossible-page-give-me-your-404-error')
111
+ response.status.should == 404
112
+ response.body.should include('Page not found')
113
+ response.body.should include('404')
114
+ end
115
+ end
116
+
117
+ describe "GET /feed.rss" do
118
+ before :all do
119
+ @response = @baron.get('/feed.rss')
120
+ end
121
+
122
+ it_behaves_like "Server Response"
123
+
124
+ it "returns expected content" do
125
+ @response.body.should include(@config[:title])
126
+ @response.body.should include("#{@config[:url]}/feed.rss")
127
+ @response.body.scan(/<entry>/).count.should == 3
128
+ @response.body.scan(/<\/entry>/).count.should == 3
129
+ @response.body.should include('<feed')
130
+ @response.body.should include('</feed>')
131
+ end
132
+ end
133
+
134
+ describe "GET /robots.txt" do
135
+ before :all do
136
+ @response = @baron.get('/robots.txt')
137
+ end
138
+
139
+ it_behaves_like "Server Response"
140
+ end
141
+
142
+ describe "Redirect URLs" do
143
+ it "should redirect with 301" do
144
+ @response = @baron.get('/foobar-test-1')
145
+ @response.status.should == 301
146
+ @response['Location'].should == '/'
147
+ @response = @baron.get('/foobar-test-2')
148
+ @response.status.should == 301
149
+ @response['Location'].should == '/archives'
150
+ end
151
+
152
+ it "should canonicalize pagination at page 1" do
153
+ @response = @baron.get('/page/1/')
154
+ @response.status.should == 301
155
+ @response['Location'].should == '/'
156
+ @response = @baron.get('/page/1')
157
+ @response.status.should == 301
158
+ @response['Location'].should == '/'
159
+ end
160
+
161
+ it "should redirect with 302" do
162
+ @response = @baron.get('/foobar-test-3')
163
+ @response.status.should == 302
164
+ @response['Location'].should == '/posts/poems/the-road-not-taken/'
165
+ end
166
+ end
167
+
168
+ describe "Helper Functions" do
169
+ it "should return a titleized string" do
170
+ "the quick red fox".titleize.should == "The Quick Red Fox"
171
+ end
172
+ end
173
+
174
+ end
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby '1.9.3'
4
+ gem 'baron'
5
+ gem 'rack'
6
+ gem 'rdiscount'
@@ -0,0 +1,42 @@
1
+ require 'baron'
2
+
3
+ @config = Baron::Config::Defaults
4
+
5
+ task :default => :new
6
+
7
+ desc "Create a new article."
8
+ task :new do
9
+ title = ask('Title: ')
10
+ slug = title.empty?? nil : title.strip.slugize
11
+
12
+ article = {'title' => title, 'date' => Time.now.strftime("%d/%m/%Y")}.to_yaml
13
+ article << "\n"
14
+ article << "Once upon a time...\n\n"
15
+
16
+ path = "#{Baron::Paths[:articles]}/#{Time.now.strftime("%Y-%m-%d")}#{'-' + slug if slug}.#{@config[:ext]}"
17
+
18
+ unless File.exist? path
19
+ File.open(path, "w") do |file|
20
+ file.write article
21
+ end
22
+ baron "an article was created for you at #{path}."
23
+ else
24
+ baron "I can't create the article, #{path} already exists."
25
+ end
26
+ end
27
+
28
+ desc "Publish my blog."
29
+ task :publish do
30
+ baron "publishing your article(s)..."
31
+ `git push heroku master`
32
+ end
33
+
34
+ def baron msg
35
+ puts "\n toto ~ #{msg}\n\n"
36
+ end
37
+
38
+ def ask message
39
+ print message
40
+ STDIN.gets.chomp
41
+ end
42
+
@@ -0,0 +1,11 @@
1
+ title: Sample Post
2
+
3
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mauris justo, lobortis et posuere eget, condimentum a sem. In hac habitasse platea dictumst. Vestibulum congue commodo blandit. Quisque lacinia tempus elit quis pulvinar. Pellentesque sit amet pellentesque arcu. Nulla facilisi. Nam aliquet metus sit amet mi pulvinar ornare. Integer et mi non nunc scelerisque tristique. Etiam mattis malesuada rutrum. Fusce eu erat quis neque lacinia mattis sit amet at leo.
4
+
5
+ Maecenas sit amet consequat lorem. Praesent id risus quis eros molestie interdum nec nec lacus. Cras ultrices arcu sit amet urna mollis in sagittis nibh auctor. Ut non sem at ipsum commodo gravida in eu est. Suspendisse pellentesque euismod mauris, vitae aliquet lectus condimentum at. Praesent nec augue vitae turpis sollicitudin gravida. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat malesuada lectus, vel faucibus velit accumsan at. Cras rhoncus vulputate sem, et pharetra ipsum rutrum sed. Fusce nibh elit, dapibus et posuere eget, tempus sagittis orci. Nunc in nisi id orci facilisis imperdiet sit amet fringilla orci. Ut scelerisque est ut libero posuere nec accumsan lectus sollicitudin.
6
+
7
+ Morbi euismod, metus nec rhoncus pulvinar, felis mi ultricies turpis, vitae cursus mi eros eu metus. Morbi condimentum pretium sem, non congue sem ultricies eget. Sed nisi libero, tempor a viverra id, iaculis suscipit ante. Suspendisse potenti. Morbi faucibus fringilla fringilla. Fusce eget orci turpis. Phasellus eleifend lectus sit amet elit eleifend eget venenatis felis fermentum.
8
+
9
+ Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce eu sodales est. Donec lobortis tristique luctus. Integer pharetra congue nisi vel iaculis. Sed convallis convallis tristique. Aliquam erat volutpat. Maecenas sed volutpat felis. Duis sollicitudin lorem vel felis molestie placerat. Nulla nec lacus lorem, eu sollicitudin lectus. Suspendisse quis ipsum vitae erat rutrum suscipit sit amet non justo. Praesent dignissim pulvinar facilisis. Vivamus vel risus id magna lacinia euismod. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi ultricies nisi sit amet turpis suscipit rhoncus aliquam eros luctus.
10
+
11
+ Nunc sit amet leo lectus, a eleifend lectus. Nam pulvinar, purus sed dapibus vestibulum, ligula ligula volutpat purus, at blandit enim elit ut risus. Ut rhoncus ultrices magna, id dignissim ligula pharetra vulputate. Ut rutrum pulvinar urna, quis egestas erat facilisis ac. Integer volutpat euismod accumsan. Donec cursus arcu eget sem bibendum ullamcorper. Quisque enim justo, pharetra vel porta vitae, hendrerit id justo. Sed semper congue dapibus. Fusce suscipit iaculis sapien, vel facilisis justo viverra a. Pellentesque augue turpis, imperdiet ut volutpat eu, viverra quis orci.
@@ -0,0 +1,48 @@
1
+ title: If
2
+ author: Rudyard Kipling
3
+
4
+
5
+ If you can keep your head when all about you
6
+ Are losing theirs and blaming it on you,
7
+
8
+ If you can trust yourself when all men doubt you,
9
+ But make allowance for their doubting too;
10
+
11
+ If you can wait and not be tired by waiting,
12
+ Or being lied about, don’t deal in lies,
13
+ Or being hated, don’t give way to hating,
14
+ And yet don’t look too good, nor talk too wise:
15
+
16
+ If you can dream—and not make dreams your master;
17
+
18
+ If you can think—and not make thoughts your aim;
19
+
20
+ If you can meet with Triumph and Disaster
21
+ And treat those two impostors just the same;
22
+
23
+ If you can bear to hear the truth you’ve spoken
24
+ Twisted by knaves to make a trap for fools,
25
+ Or watch the things you gave your life to, broken,
26
+ And stoop and build ’em up with worn-out tools:
27
+
28
+ If you can make one heap of all your winnings
29
+ And risk it on one turn of pitch-and-toss,
30
+ And lose, and start again at your beginnings
31
+ And never breathe a word about your loss;
32
+
33
+ If you can force your heart and nerve and sinew
34
+ To serve your turn long after they are gone,
35
+ And so hold on when there is nothing in you
36
+ Except the Will which says to them: ‘Hold on!’
37
+
38
+ If you can talk with crowds and keep your virtue,
39
+ Or walk with Kings—nor lose the common touch,
40
+
41
+ If neither foes nor loving friends can hurt you,
42
+
43
+ If all men count with you, but none too much;
44
+
45
+ If you can fill the unforgiving minute
46
+ With sixty seconds’ worth of distance run,
47
+ Yours is the Earth and everything that’s in it,
48
+ And—which is more—you’ll be a Man, my son!
@@ -0,0 +1,26 @@
1
+ title: The Road Not Taken
2
+ author: Robert Frost
3
+
4
+ Two roads diverged in a yellow wood,
5
+ And sorry I could not travel both
6
+ And be one traveler, long I stood
7
+ And looked down one as far as I could
8
+ To where it bent in the undergrowth;
9
+
10
+ Then took the other, as just as fair,
11
+ And having perhaps the better claim,
12
+ Because it was grassy and wanted wear;
13
+ Though as for that the passing there
14
+ Had worn them really about the same,
15
+
16
+ And both that morning equally lay
17
+ In leaves no step had trodden black.
18
+ Oh, I kept the first for another day!
19
+ Yet knowing how way leads on to way,
20
+ I doubted if I should ever come back.
21
+
22
+ I shall be telling this with a sigh
23
+ Somewhere ages and ages hence:
24
+ Two roads diverged in a wood, and I –
25
+ I took the one less traveled by,
26
+ And that has made all the difference.
@@ -0,0 +1,46 @@
1
+ #
2
+ # Baron configuration
3
+
4
+ require 'baron'
5
+
6
+ baron = Baron::Server.new do
7
+ #
8
+ # Add your settings here
9
+ # set [:setting], [value]
10
+ #
11
+ # set :author, ENV['USER'] # blog author
12
+ # set :title, Dir.pwd.split('/').last # site title
13
+ # set :root, "index" # page to load on /
14
+ # set :date, lambda {|now| now.strftime("%d/%m/%Y") } # date format for articles
15
+ # set :markdown, :smart # use markdown + smart-mode
16
+ # set :disqus, false # disqus id, or false
17
+ # set :summary, :max => 150, :delim => /~/ # length of article summary and delimiter
18
+ # set :ext, 'txt' # file extension for articles
19
+ # set :cache, 28800 # cache duration, in seconds
20
+ # set :custom_pages "about, contact-us" # custom pages, should match filename
21
+ # set :permalink_prefix, "" # common path prefix for article permalinks
22
+ # set :permalink_date_format, :no_date, # :year_date, :year_month_date, :year_month_day_date, :no_date
23
+
24
+ set :disqus, true
25
+ set :title, 'test blog'
26
+ set :date, lambda {|now| now.strftime("%B #{now.day.ordinal} %Y") }
27
+ set :permalink_prefix, 'posts'
28
+ set :theme, 'test'
29
+ set :permalink_date_format, :no_date
30
+ set :article_max, 2
31
+ end
32
+
33
+ #
34
+ # Rack configuration
35
+
36
+ use Rack::Static, :urls => ['/themes', '/downloads', '/images']
37
+ use Rack::CommonLogger
38
+
39
+ if ENV['RACK_ENV'] == 'development'
40
+ use Rack::ShowExceptions
41
+ end
42
+
43
+ # RUN!
44
+ run baron
45
+
46
+