Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Middleware to fetch static pages

  • Loading branch information...
commit dc9a2d7c1e8016815d352ddb5f390dfc17fc14a6 1 parent 595f002
Joe Ferris and Mike Burns authored jferris committed
2  lib/turning.rb
@@ -2,3 +2,5 @@
2 2 require 'turning/callbacks'
3 3 require 'turning/controller'
4 4 require 'turning/renderer'
  5 +require 'turning/static_cascade'
  6 +require 'turning/railtie'
32 lib/turning/file_storage.rb
... ... @@ -0,0 +1,32 @@
  1 +module Turning
  2 + class FileStorage
  3 + def initialize(root_path)
  4 + @root_path = root_path
  5 + end
  6 +
  7 + def put(file_path, contents)
  8 + FileUtils.mkdir_p(parent_directory(file_path))
  9 + File.open(resolve(file_path), 'w') do |file|
  10 + file.write(contents)
  11 + end
  12 + end
  13 +
  14 + def get(file_path)
  15 + begin
  16 + IO.read(resolve(file_path))
  17 + rescue Errno::ENOENT
  18 + nil
  19 + end
  20 + end
  21 +
  22 + private
  23 +
  24 + def resolve(file_path)
  25 + File.join(@root_path, file_path)
  26 + end
  27 +
  28 + def parent_directory(file_path)
  29 + File.dirname(resolve(file_path))
  30 + end
  31 + end
  32 +end
12 lib/turning/railtie.rb
... ... @@ -0,0 +1,12 @@
  1 +require 'rails/railtie'
  2 +require 'turning/static_cascade'
  3 +require 'turning/file_storage'
  4 +
  5 +module Turning
  6 + class Railtie < ::Rails::Railtie
  7 + initializer('turning.middleware') do
  8 + config.app_middleware.use StaticCascade,
  9 + FileStorage.new(Rails.root.join('public', 'static'))
  10 + end
  11 + end
  12 +end
2  lib/turning/renderer.rb
@@ -54,7 +54,7 @@ def render_to_file(template_name, assigns)
54 54 private
55 55
56 56 def target_path
57   - Rails.root.join('public', 'cached', @controller_path)
  57 + Rails.root.join('public', 'static', @controller_path)
58 58 end
59 59 end
60 60 end
18 lib/turning/static_cascade.rb
... ... @@ -0,0 +1,18 @@
  1 +module Turning
  2 + class StaticCascade
  3 + def initialize(app, storage)
  4 + @app = app
  5 + @storage = storage
  6 + end
  7 +
  8 + def call(env)
  9 + if body = @storage.get(env['PATH_INFO'])
  10 + content_length = body.size
  11 + headers = { 'Content-Type' => 'text/html', 'Content-Length' => content_length.to_s }
  12 + [200, headers, [body]]
  13 + else
  14 + @app.call(env)
  15 + end
  16 + end
  17 + end
  18 +end
1  spec/spec_helper.rb
... ... @@ -1,6 +1,7 @@
1 1 require 'rspec'
2 2 require 'turning'
3 3 require 'bourne'
  4 +require 'rack/test'
4 5
5 6 require './spec/testapp/config/application'
6 7 Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
6 spec/support/views.rb
@@ -7,8 +7,8 @@ def create_view(path, contents)
7 7 @view_files << full_path
8 8 end
9 9
10   - def read_cached_view(path)
11   - IO.read(Rails.root.join('public', 'cached', path))
  10 + def read_static_view(path)
  11 + IO.read(Rails.root.join('public', 'static', path))
12 12 end
13 13
14 14 def cleanup_views
@@ -16,7 +16,7 @@ def cleanup_views
16 16 FileUtils.rm_rf(view_file)
17 17 end
18 18
19   - FileUtils.rm_rf(Rails.root.join('public', 'cached'))
  19 + FileUtils.rm_rf(Rails.root.join('public', 'static'))
20 20 end
21 21 end
22 22
50 spec/testapp/log/development.log
@@ -82,3 +82,53 @@
82 82 Rendered examples/greet_hello.html.erb (0.2ms)
83 83 Rendered examples/form.html.erb (0.5ms)
84 84 Rendered examples/simple.html.erb within layouts/static (0.2ms)
  85 + Rendered examples/index.html.erb (1.1ms)
  86 +
  87 +
  88 +Started GET "/" for 127.0.0.1 at 2012-08-03 11:51:44 -0400
  89 + Rendered examples/index.html.erb (1.0ms)
  90 +
  91 +
  92 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:08:42 -0400
  93 + Rendered examples/index.html.erb (1.1ms)
  94 +
  95 +
  96 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:10:16 -0400
  97 + Rendered examples/index.html.erb (1.0ms)
  98 +
  99 +
  100 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:21:18 -0400
  101 + Rendered examples/say_hello.html.erb (0.3ms)
  102 + Rendered examples/go_home.html.erb (13.0ms)
  103 + Rendered examples/greet_hello.html.erb (0.2ms)
  104 + Rendered examples/form.html.erb (0.5ms)
  105 + Rendered examples/simple.html.erb within layouts/static (0.2ms)
  106 + Rendered examples/index.html.erb (1.0ms)
  107 +
  108 +
  109 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:56:47 -0400
  110 + Rendered examples/index.html.erb (1.0ms)
  111 +
  112 +
  113 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:59:04 -0400
  114 + Rendered examples/index.html.erb (1.0ms)
  115 +
  116 +
  117 +Started GET "/" for 127.0.0.1 at 2012-08-03 12:59:43 -0400
  118 + Rendered examples/index.html.erb (1.0ms)
  119 +
  120 +
  121 +Started GET "/" for 127.0.0.1 at 2012-08-03 13:00:24 -0400
  122 + Rendered examples/index.html.erb (1.0ms)
  123 +
  124 +
  125 +Started GET "/examples/index.html" for 127.0.0.1 at 2012-08-03 13:03:18 -0400
  126 + Rendered examples/index.html.erb (1.0ms)
  127 +
  128 +
  129 +Started GET "/examples/index.html" for 127.0.0.1 at 2012-08-03 13:03:22 -0400
  130 + Rendered examples/say_hello.html.erb (0.2ms)
  131 + Rendered examples/go_home.html.erb (0.4ms)
  132 + Rendered examples/greet_hello.html.erb (0.2ms)
  133 + Rendered examples/form.html.erb (0.5ms)
  134 + Rendered examples/simple.html.erb within layouts/static (0.2ms)
22 spec/turning/file_storage_spec.rb
... ... @@ -0,0 +1,22 @@
  1 +require 'spec_helper'
  2 +require 'turning/file_storage'
  3 +
  4 +describe Turning::FileStorage do
  5 + it 'returns the content of a file from the filesystem' do
  6 + root = Rails.root.join('public', 'static')
  7 + putter = Turning::FileStorage.new(root)
  8 + getter = Turning::FileStorage.new(root)
  9 +
  10 + putter.put('examples/awesomeness.html', 'awesome!')
  11 + results = getter.get('examples/awesomeness.html')
  12 +
  13 + results.should == 'awesome!'
  14 + end
  15 +
  16 + it 'returns nil for a file that does not exist' do
  17 + root = Rails.root.join('public', 'static')
  18 + getter = Turning::FileStorage.new(root)
  19 +
  20 + getter.get('snakes').should be_nil
  21 + end
  22 +end
9 spec/turning/integration_spec.rb
@@ -2,6 +2,8 @@
2 2 require 'turning'
3 3
4 4 describe Turning do
  5 + include Rack::Test::Methods
  6 +
5 7 it 'listens to events and renders the view to a static file' do
6 8 controller_class = Class.new(Turning::Controller) do
7 9 def initialize(renderer, model)
@@ -35,6 +37,11 @@ def trigger_update
35 37 controller.listen
36 38 model.trigger_update
37 39
38   - read_cached_view('examples/index.html').should == 'Hello'
  40 + get '/examples/index.html'
  41 + last_response.body.should == 'Hello'
  42 + end
  43 +
  44 + def app
  45 + TestApp::Application
39 46 end
40 47 end
8 spec/turning/renderer_spec.rb
@@ -7,7 +7,7 @@
7 7 renderer = Turning::Renderer.new('examples')
8 8 renderer.render_to_file('say_hello', greeting: 'Hello')
9 9
10   - read_cached_view('examples/say_hello.html').should include 'Hello'
  10 + read_static_view('examples/say_hello.html').should include 'Hello'
11 11 end
12 12
13 13 it 'supplies built-in helpers' do
@@ -15,7 +15,7 @@
15 15 renderer = Turning::Renderer.new('examples')
16 16 renderer.render_to_file('go_home', {})
17 17
18   - read_cached_view('examples/go_home.html').should match(%r{<a href=".*">go home</a>})
  18 + read_static_view('examples/go_home.html').should match(%r{<a href=".*">go home</a>})
19 19 end
20 20
21 21 it 'supplies custom helpers' do
@@ -30,7 +30,7 @@ def greet
30 30 renderer = Turning::Renderer.new('examples')
31 31 renderer.render_to_file('greet_hello', {})
32 32
33   - read_cached_view('examples/greet_hello.html').should include 'Hello'
  33 + read_static_view('examples/greet_hello.html').should include 'Hello'
34 34 end
35 35
36 36 it 'disables forgery protection for static forms' do
@@ -45,6 +45,6 @@ def greet
45 45 renderer = Turning::Renderer.new('examples')
46 46 renderer.render_to_file('simple', {})
47 47
48   - read_cached_view('examples/simple.html').should == 'Check this: Hello'
  48 + read_static_view('examples/simple.html').should == 'Check this: Hello'
49 49 end
50 50 end
31 spec/turning/static_cascade_spec.rb
... ... @@ -0,0 +1,31 @@
  1 +require 'spec_helper'
  2 +require 'turning/static_cascade'
  3 +
  4 +describe Turning::StaticCascade do
  5 + it 'serves the file if it exists' do
  6 + app = stub('app')
  7 + fake_content_storage = stub('fake content storage', get: 'contents')
  8 + static_file_name = '/ponies'
  9 + static_cascade = Turning::StaticCascade.new(app, fake_content_storage)
  10 +
  11 + response = static_cascade.call('PATH_INFO' => static_file_name)
  12 + fake_content_storage.should have_received(:get).with(static_file_name)
  13 + response.should == [
  14 + 200,
  15 + { 'Content-Type' => 'text/html', 'Content-Length' => 'contents'.size.to_s },
  16 + ['contents']
  17 + ]
  18 + end
  19 +
  20 + it 'cascades if the file does not exist' do
  21 + app = stub('app', call: 'app response')
  22 + fake_content_storage = stub('fake content storage', get: nil)
  23 + env = { 'PATH_INFO' => '/ponies' }
  24 + static_cascade = Turning::StaticCascade.new(app, fake_content_storage)
  25 +
  26 + response = static_cascade.call(env)
  27 +
  28 + app.should have_received(:call).with(env)
  29 + response.should == 'app response'
  30 + end
  31 +end
1  turning.gemspec
@@ -22,4 +22,5 @@ Gem::Specification.new do |gem|
22 22 gem.add_development_dependency 'rake'
23 23 gem.add_development_dependency 'bourne'
24 24 gem.add_development_dependency 'tzinfo'
  25 + gem.add_development_dependency 'rack-test'
25 26 end

0 comments on commit dc9a2d7

Please sign in to comment.
Something went wrong with that request. Please try again.