more cucumber stuff

This commit is contained in:
tdreyno 2009-11-22 15:37:11 -08:00
parent b49f9fda6b
commit b872dad760
24 changed files with 220 additions and 248 deletions

View file

@ -1,5 +1,6 @@
require 'lib/middleman' require 'lib/middleman'
require 'rake' require 'rake'
require 'spec/rake/spectask'
require 'cucumber/rake/task' require 'cucumber/rake/task'
begin begin
@ -13,23 +14,8 @@ begin
gem.rubyforge_project = "middleman" gem.rubyforge_project = "middleman"
gem.executables = %w(mm-init mm-build mm-server) gem.executables = %w(mm-init mm-build mm-server)
gem.add_dependency("thin") gem.add_dependency("thin")
# gem.add_dependency("shotgun") gem.add_development_dependency("rspec")
# gem.add_dependency("templater") gem.add_development_dependency("cucumber")
# gem.add_dependency("sprockets")
# gem.add_dependency("sinatra")
# gem.add_dependency("sinatra-content-for")
# gem.add_dependency("rack-test")
# gem.add_dependency("yui-compressor")
# gem.add_dependency("smusher")
# gem.add_dependency("haml", ">=2.1.0")
# gem.add_dependency("compass")
# gem.add_development_dependency("rdoc")
# gem.add_development_dependency("rspec")
# gem.add_development_dependency("sdoc")
# gem.add_development_dependency("cucumber")
# Ignore vendored files
gem.files = gem.files.exclude("vendor/*")
end end
Jeweler::GemcutterTasks.new Jeweler::GemcutterTasks.new
@ -37,51 +23,15 @@ rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
end end
require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:spec) do |spec| Spec::Rake::SpecTask.new(:spec) do |spec|
spec.libs << 'lib' << 'spec' spec.libs << 'lib' << 'spec'
spec.spec_files = FileList['spec/**/*_spec.rb'] spec.spec_files = FileList['spec/**/*_spec.rb']
end end
Spec::Rake::SpecTask.new(:rcov) do |spec| Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t|
spec.libs << 'lib' << 'spec' t.cucumber_opts = "--color --tags ~@wip --strict --format #{ENV['CUCUMBER_FORMAT'] || 'pretty'}"
spec.pattern = 'spec/**/*_spec.rb'
spec.rcov = true
end end
task :spec => :check_dependencies task :spec => :check_dependencies
task :default => :spec task :default => :spec
require 'rake/rdoctask'
require 'sdoc'
Rake::RDocTask.new do |rdoc|
if File.exist?('VERSION')
version = File.read('VERSION')
else
version = ""
end
# rdoc.template = 'direct'
rdoc.rdoc_dir = 'rdoc'
rdoc.title = "middleman #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
rdoc.rdoc_files.exclude('lib/middleman/features/sprockets+ruby19.rb')
rdoc.rdoc_files.exclude('lib/middleman/templater+dynamic_renderer.rb')
end
desc "Build and publish documentation using GitHub Pages."
task :pages do
if !`git status`.include?('nothing to commit')
abort "dirty index - not publishing!"
end
Rake::Task[:rerdoc].invoke
`git checkout gh-pages`
`ls -1 | grep -v rdoc | xargs rm -rf; mv rdoc/* .; rm -rf rdoc`
`git commit -a -m "update docs"; git push origin gh-pages`
`git checkout master`
end

View file

@ -0,0 +1,14 @@
Feature: Automatically detect and insert image dimensions into tags
In order to speed up development and appease YSlow
Scenario: Rendering an image with the feature enabled
Given "automatic_image_sizes" feature is "enabled"
When I go to "/auto-image-sizes.html"
Then I should see "width="
And I should see "height="
Scenario: Rendering an image with the feature disabled
Given "automatic_image_sizes" feature is "disabled"
When I go to "/auto-image-sizes.html"
Then I should not see "width="
And I should not see "height="

View file

@ -0,0 +1,22 @@
Feature: Generate mtime-based query string for busting browser caches
In order to display the most recent content for IE & CDNs and appease YSlow
Scenario: Rendering css with the feature enabled
Given "cache_buster" feature is "enabled"
When I go to "/stylesheets/relative_assets.css"
Then I should see "?"
Scenario: Rendering html with the feature enabled
Given "cache_buster" feature is "enabled"
When I go to "/cache-buster.html"
Then I should not see "?"
Scenario: Rendering css with the feature disabled
Given "cache_buster" feature is "disabled"
When I go to "/stylesheets/relative_assets.css"
Then I should not see "?"
Scenario: Rendering html with the feature disabled
Given "cache_buster" feature is "disabled"
When I go to "/cache-buster.html"
Then I should not see "?"

View file

@ -0,0 +1,22 @@
Feature: Minify CSS
In order reduce bytes sent to client and appease YSlow
Scenario: Rendering inline css with the feature enabled
Given "minify_css" feature is "enabled"
When I go to "/inline-css.html"
Then I should see "1" lines
Scenario: Rendering inline css with the feature disabled
Given "minify_css" feature is "disabled"
When I go to "/inline-css.html"
Then I should see "3" lines
Scenario: Rendering external css with the feature enabled
Given "minify_css" feature is "enabled"
When I go to "/stylesheets/site.css"
Then I should see "1" lines
Scenario: Rendering external css with the feature disabled
Given "minify_css" feature is "disabled"
When I go to "/stylesheets/site.css"
Then I should see "47" lines

View file

@ -0,0 +1,12 @@
Feature: Minify Javascript
In order reduce bytes sent to client and appease YSlow
Scenario: Rendering inline js with the feature enabled
Given "minify_javascript" feature is "enabled"
When I go to "/inline-js.html"
Then I should see "1" lines
Scenario: Rendering inline js with the feature disabled
Given "minify_javascript" feature is "disabled"
When I go to "/inline-js.html"
Then I should see "10" lines

View file

@ -0,0 +1,12 @@
Feature: Custom layouts
In order easily switch between relative and absolute paths
Scenario: Using custom :layout attribute
Given page "/custom-layout.html" has layout "custom"
When I go to "/custom-layout.html"
Then I should see "Custom Layout"
Scenario: Using with_layout block
Given "/custom-layout.html" with_layout block has layout "custom"
When I go to "/custom-layout.html"
Then I should see "Custom Layout"

View file

@ -0,0 +1,12 @@
Feature: Relative Assets
In order easily switch between relative and absolute paths
Scenario: Rendering css with the feature disabled
Given "relative_assets" feature is "disabled"
When I go to "/stylesheets/relative_assets.css"
Then I should not see "../"
Scenario: Rendering css with the feature enabled
Given "relative_assets" feature is "enabled"
When I go to "/stylesheets/relative_assets.css"
Then I should see "../"

View file

@ -0,0 +1,2 @@
require File.join(File.dirname(File.dirname(File.dirname(__FILE__))), 'lib', 'middleman')
require "rack/test"

View file

@ -0,0 +1,22 @@
Given /^"([^\"]*)" feature is "([^\"]*)"$/ do |feature, state|
enable_or_disable = (state == "enabled") ? :enable : :disable
Middleman::Base.set :root, File.join(File.dirname(File.dirname(File.dirname(__FILE__))), "spec", "fixtures", "sample")
Middleman::Base.send(enable_or_disable, feature.to_sym)
@browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman::Base.new))
end
When /^I go to "([^\"]*)"$/ do |url|
@browser.get(url)
end
Then /^I should see "([^\"]*)"$/ do |expected|
@browser.last_response.body.should include(expected)
end
Then /^I should not see "([^\"]*)"$/ do |expected|
@browser.last_response.body.should_not include(expected)
end
Then /^I should see "([^\"]*)" lines$/ do |lines|
@browser.last_response.body.chomp.split($/).length.should == lines.to_i
end

View file

@ -0,0 +1,13 @@
Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout|
Middleman::Base.set :root, File.join(File.dirname(File.dirname(File.dirname(__FILE__))), "spec", "fixtures", "sample")
Middleman::Base.page(url, :layout => layout.to_sym)
@browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman::Base.new))
end
Given /^"([^\"]*)" with_layout block has layout "([^\"]*)"$/ do |url, layout|
Middleman::Base.set :root, File.join(File.dirname(File.dirname(File.dirname(__FILE__))), "spec", "fixtures", "sample")
Middleman::Base.with_layout(:layout => layout.to_sym) do
page(url)
end
@browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman::Base.new))
end

View file

@ -1,5 +1,6 @@
# We're riding on Sinatra, so let's include it # We're riding on Sinatra, so let's include it
require 'sinatra/base' require "sinatra/base"
require "sinatra/content_for"
class Sinatra::Request class Sinatra::Request
attr_accessor :layout attr_accessor :layout
@ -21,6 +22,7 @@ module Middleman
set :http_prefix, nil set :http_prefix, nil
use Rack::ConditionalGet if environment == :development use Rack::ConditionalGet if environment == :development
helpers Sinatra::ContentFor
@@features = [] @@features = []
@ -45,11 +47,11 @@ module Middleman
::Rack::Mime::MIME_TYPES[ext.to_s] = type ::Rack::Mime::MIME_TYPES[ext.to_s] = type
end end
# Convenience function to discover if a tempalte exists for the requested renderer (haml, sass, etc) # Convenience function to discover if a template exists for the requested renderer (haml, sass, etc)
def template_exists?(path, renderer=nil) def template_exists?(path, renderer=nil)
template_path = path.dup template_path = path.dup
template_path << ".#{renderer}" if renderer template_path << ".#{renderer}" if renderer
File.exists? File.join(options.views, template_path) File.readable? File.join(options.views, template_path)
end end
# Base case renderer (do nothing), Should be over-ridden # Base case renderer (do nothing), Should be over-ridden
@ -63,24 +65,6 @@ module Middleman
end end
end end
include StaticRender include StaticRender
def process_request
# Normalize the path and add index if we're looking at a directory
path = request.path
path << options.index_file if path.match(%r{/$})
path.gsub!(%r{^/}, '')
# layout(:"layout.html") # Insert the .html into the layout name like the rest of the templates
# If the enabled renderers succeed, return the content, mime-type and an HTTP 200
if content = render_path(path, (request.layout || :layout))
content_type media_type(File.extname(path)), :charset => 'utf-8'
status 200
content
else
status 404
end
end
def self.page(url, options={}, &block) def self.page(url, options={}, &block)
get(url) do get(url) do
@ -106,19 +90,34 @@ module Middleman
not_found do not_found do
process_request process_request
end end
private
def process_request
# Normalize the path and add index if we're looking at a directory
path = request.path
path << options.index_file if path.match(%r{/$})
path.gsub!(%r{^/}, '')
# If the enabled renderers succeed, return the content, mime-type and an HTTP 200
if content = render_path(path, (request.layout || :layout))
content_type media_type(File.extname(path)), :charset => 'utf-8'
status 200
content
else
status 404
end
end
end end
end end
# Haml is required & includes helpers # Haml is required & includes helpers
require "middleman/haml" require "middleman/haml"
require "middleman/sass" require "middleman/sass"
require "sinatra/content_for"
require "middleman/helpers" require "middleman/helpers"
require "middleman/rack/static" require "middleman/rack/static"
require "middleman/rack/sprockets" require "middleman/rack/sprockets"
class Middleman::Base class Middleman::Base
helpers Sinatra::ContentFor
helpers Middleman::Helpers helpers Middleman::Helpers
use Middleman::Rack::Static use Middleman::Rack::Static

View file

@ -4,10 +4,14 @@ class Middleman::Base
alias_method :pre_automatic_image_tag, :image_tag alias_method :pre_automatic_image_tag, :image_tag
helpers do helpers do
def image_tag(path, params={}) def image_tag(path, params={})
if !options.respond_to?(:automatic_image_sizes?) || !options.automatic_image_sizes?
return pre_automatic_image_tag(path, params)
end
if (!params[:width] || !params[:height]) && !path.include?("://") if (!params[:width] || !params[:height]) && !path.include?("://")
params[:alt] ||= "" params[:alt] ||= ""
http_prefix = options.http_images_path rescue options.images_dir http_prefix = options.http_images_path rescue options.images_dir
begin begin
real_path = File.join(options.public, options.images_dir, path) real_path = File.join(options.public, options.images_dir, path)
if File.exists? real_path if File.exists? real_path
@ -18,9 +22,7 @@ class Middleman::Base
rescue rescue
end end
params = params.merge(:src => asset_url(path, http_prefix)) capture_haml { haml_tag(:img, params.merge(:src => asset_url(path, http_prefix))) }
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
"<img #{params} />"
else else
pre_automatic_image_tag(path, params) pre_automatic_image_tag(path, params)
end end

View file

@ -1,9 +1,18 @@
class Middleman::Base module Middleman
after_feature_init do module Minified
::Compass.configuration do |config| module Sass
config.output_style = :compressed include ::Haml::Filters::Base
end
::Compass.configure_sass_plugin! def render(text)
result = ::Sass::Engine.new(text, ::Sass::Plugin.engine_options).render
if Middleman::Base.respond_to?(:minify_css?) && Middleman::Base.minify_css?
compressor = YUI::CssCompressor.new
compressor.compress(result)
else
result
end
end
end
end end
end end

View file

@ -1,18 +1,22 @@
require "middleman/builder"
module Middleman module Middleman
module Minified module Minified
module Javascript module Javascript
include ::Haml::Filters::Base include ::Haml::Filters::Base
def render_with_options(text, options) def render_with_options(text, options)
compressor = ::YUI::JavaScriptCompressor.new(:munge => true) if Middleman::Base.respond_to?(:minify_javascript?) && Middleman::Base.minify_javascript?
data = compressor.compress(text) compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
<<END data = compressor.compress(text)
<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script> %Q{<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script>}
else
<<END
<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>
//<![CDATA[
#{text.rstrip.gsub("\n", "\n ")}
//]]>
</script>
END END
end
end end
end end
end end
end end
Middleman::Base.supported_formats << "js"

View file

@ -1,10 +1,22 @@
::Compass.configuration do |config| class Middleman::Base
config.relative_assets = true after_feature_init do
::Compass.configuration do |config|
config.relative_assets = Proc.new do
Middleman::Base.respond_to?(:relative_assets?) && Middleman::Base.relative_assets?
end
end
::Compass.configure_sass_plugin!
end
end end
class << Middleman::Base class << Middleman::Base
alias_method :pre_relative_asset_url, :asset_url alias_method :pre_relative_asset_url, :asset_url
def asset_url(path, prefix="", request=nil) def asset_url(path, prefix="", request=nil)
if !self.respond_to?(:relative_assets?) || !self.relative_assets?
return pre_relative_asset_url(path, prefix, request)
end
begin begin
prefix = self.images_dir if prefix == self.http_images_path prefix = self.images_dir if prefix == self.http_images_path
rescue rescue
@ -26,7 +38,6 @@ class << Middleman::Base
(parts.length - 1).times { arry << ".." } (parts.length - 1).times { arry << ".." }
arry << path arry << path
File.join(*arry) File.join(*arry)
#"../" * (parts.length - 1) + path
else else
path path
end end

View file

@ -9,7 +9,7 @@ end
begin begin
require "yui/compressor" require "yui/compressor"
rescue LoadError rescue LoadError
puts "Sprockets not available. Install it with: gem install yui-compressor" puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
end end
module Middleman module Middleman

View file

@ -1,7 +1,12 @@
require "sass" require "sass"
#gem "compass-edge"
require "compass" require "compass"
begin
require "yui/compressor"
rescue LoadError
puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
end
module Middleman module Middleman
module Sass module Sass
def self.included(base) def self.included(base)
@ -17,7 +22,12 @@ module Middleman
location_of_sass_file = options.environment == "build" ? File.join(Dir.pwd, options.build_dir) : options.public location_of_sass_file = options.environment == "build" ? File.join(Dir.pwd, options.build_dir) : options.public
css_filename = File.join(location_of_sass_file, request.path_info) css_filename = File.join(location_of_sass_file, request.path_info)
sass(path.to_sym, ::Compass.sass_engine_options.merge({ :css_filename => css_filename })) result = sass(path.to_sym, ::Compass.sass_engine_options.merge({ :css_filename => css_filename }))
if options.respond_to?(:minify_css?) && options.minify_css?
YUI::CssCompressor.new.compress(result)
else
result
end
rescue Exception => e rescue Exception => e
sass_exception_string(e) sass_exception_string(e)
end end

View file

@ -1,22 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
describe "Auto Image sizes Feature" do
it "should not append width and height if off" do
base.disable :automatic_image_sizes
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/auto-image-sizes.html")
browser.last_response.body.should_not include("width=")
browser.last_response.body.should_not include("height=")
end
it "should append width and height if off" do
base.enable :automatic_image_sizes
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/auto-image-sizes.html")
browser.last_response.body.should include("width=")
browser.last_response.body.should include("height=")
end
end

View file

@ -1,20 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
describe "Cache Buster Feature in CSS" do
before do
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
base.disable :cache_buster
@browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
end
it "should not append query string in CSS if off" do
@browser.get("/stylesheets/relative_assets.css")
@browser.last_response.body.count("?").should == 0
end
it "should not append query string in HTML if off" do
@browser.get("/cache-buster.html")
@browser.last_response.body.count("?").should == 0
end
end

View file

@ -1,20 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
describe "Cache Buster Feature in CSS" do
before do
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
base.enable :cache_buster
@browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
end
it "should append query string in CSS if on" do
@browser.get("/stylesheets/relative_assets.css")
@browser.last_response.body.should include("?")
end
it "should not append query string in HTML if on IN DEVELOPMENT" do
@browser.get("/cache-buster.html")
@browser.last_response.body.count("?").should == 0
end
end

View file

@ -1,20 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
describe "Minify Javascript Feature" do
it "should not minify inline css if off" do
base.disable :minify_css
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/inline-css.html")
browser.last_response.body.chomp.split($/).length.should == 3
end
it "should minify inline css if on" do
base.enable :minify_css
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/inline-css.html")
browser.last_response.body.chomp.split($/).length.should == 1
end
end

View file

@ -1,20 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
describe "Minify Javascript Feature" do
it "should not minify inline js if off" do
base.disable :minify_javascript
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/inline-js.html")
browser.last_response.body.chomp.split($/).length.should == 10
end
it "should minify inline js if on" do
base.enable :minify_javascript
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/inline-js.html")
browser.last_response.body.chomp.split($/).length.should == 1
end
end

View file

@ -1,22 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
describe "Custom layout" do
it "should use custom layout" do
base.page "/custom-layout.html", :layout => :custom
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/custom-layout.html")
browser.last_response.body.should include("Custom Layout")
end
it "should use custom layout with_layout method" do
base.with_layout :layout => :custom do
page "/custom-layout.html"
end
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/custom-layout.html")
browser.last_response.body.should include("Custom Layout")
end
end

View file

@ -1,20 +0,0 @@
require File.join(File.dirname(__FILE__), "spec_helper")
base = ::Middleman::Base
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
describe "Relative Assets Feature" do
it "should not contain ../ if off" do
base.disable :relative_assets
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/stylesheets/relative_assets.css")
browser.last_response.body.should_not include("../")
end
it "should contain ../ if on" do
base.enable :relative_assets
browser = Rack::Test::Session.new(Rack::MockSession.new(base.new))
browser.get("/stylesheets/relative_assets.css")
browser.last_response.body.should include("../")
end
end