2006-11-28 15:33:22 -05:00
#!/usr/bin/env ruby
2008-06-08 12:54:36 -04:00
require File . dirname ( __FILE__ ) + '/../test_helper'
2006-12-03 21:47:37 -05:00
require 'sass/plugin'
2008-06-08 12:54:36 -04:00
require 'fileutils'
2006-11-28 15:33:22 -05:00
class SassPluginTest < Test :: Unit :: TestCase
2007-05-03 05:04:20 -04:00
@@templates = %w{
2008-10-12 22:03:06 -04:00
complex script parent_ref import alt
2007-05-03 05:04:20 -04:00
subdir / subdir subdir / nested_subdir / nested_subdir
2010-01-20 23:30:14 -05:00
options
2007-05-03 05:04:20 -04:00
}
2006-12-03 21:47:37 -05:00
2006-11-28 15:33:22 -05:00
def setup
2008-07-14 14:32:08 -04:00
FileUtils . mkdir tempfile_loc
FileUtils . mkdir tempfile_loc ( nil , " more_ " )
2007-11-17 14:55:26 -05:00
set_plugin_opts
2006-12-03 21:47:37 -05:00
Sass :: Plugin . update_stylesheets
2010-01-23 19:06:31 -05:00
reset_mtimes
2006-11-28 15:33:22 -05:00
end
2007-08-28 01:33:57 -04:00
2006-12-03 18:17:45 -05:00
def teardown
2009-04-15 22:35:13 -04:00
clean_up_sassc
2010-01-23 18:37:39 -05:00
clear_callbacks
2008-07-14 14:32:08 -04:00
FileUtils . rm_r tempfile_loc
FileUtils . rm_r tempfile_loc ( nil , " more_ " )
2006-12-03 18:17:45 -05:00
end
2006-11-28 15:39:33 -05:00
2009-07-19 17:56:11 -04:00
@@templates . each do | name |
define_method ( " test_template_renders_correctly ( #{ name } ) " ) do
assert_renders_correctly ( name )
end
2006-11-28 15:39:33 -05:00
end
2007-08-28 01:33:57 -04:00
2006-11-28 15:39:33 -05:00
def test_no_update
2006-12-03 21:47:37 -05:00
File . delete ( tempfile_loc ( 'basic' ) )
2010-01-23 19:06:31 -05:00
assert_needs_update 'basic'
2006-12-03 21:47:37 -05:00
Sass :: Plugin . update_stylesheets
2009-12-24 15:06:51 -05:00
assert_stylesheet_updated 'basic'
2006-12-03 21:47:37 -05:00
end
2007-08-28 01:33:57 -04:00
2007-09-01 21:48:25 -04:00
def test_update_needed_when_modified
2010-01-23 19:06:31 -05:00
touch 'basic'
assert_needs_update 'basic'
2007-09-01 21:48:25 -04:00
Sass :: Plugin . update_stylesheets
2009-12-24 15:06:51 -05:00
assert_stylesheet_updated 'basic'
2007-09-01 21:48:25 -04:00
end
def test_update_needed_when_dependency_modified
2010-01-23 19:06:31 -05:00
touch 'basic'
assert_needs_update 'import'
2007-09-01 21:48:25 -04:00
Sass :: Plugin . update_stylesheets
2009-12-24 15:06:51 -05:00
assert_stylesheet_updated 'basic'
2007-09-01 21:48:25 -04:00
end
2007-11-17 14:55:26 -05:00
def test_full_exception_handling
2009-09-13 22:27:56 -04:00
File . delete ( tempfile_loc ( 'bork1' ) )
2007-02-06 00:24:13 -05:00
Sass :: Plugin . update_stylesheets
2009-09-13 22:27:56 -04:00
File . open ( tempfile_loc ( 'bork1' ) ) do | file |
2009-09-13 23:34:59 -04:00
assert_equal ( <<CSS.strip, file.read.split("\n")[0...6].join("\n"))
2009-09-13 23:28:56 -04:00
/ *
2009-09-13 23:34:59 -04:00
Syntax error : Undefined variable : " !bork " .
on line 2 of #{template_loc('bork1')}
2009-09-13 23:28:56 -04:00
1 : bork
2 : :bork = ! bork
CSS
2006-12-22 01:59:38 -05:00
end
2009-09-13 22:27:56 -04:00
File . delete ( tempfile_loc ( 'bork1' ) )
2006-12-03 21:47:37 -05:00
end
2007-02-06 00:24:13 -05:00
2007-11-17 14:55:26 -05:00
def test_nonfull_exception_handling
2009-12-24 15:00:46 -05:00
old_full_exception = Sass :: Plugin . options [ :full_exception ]
2007-11-17 14:55:26 -05:00
Sass :: Plugin . options [ :full_exception ] = false
2007-02-06 00:24:13 -05:00
2009-09-13 22:27:56 -04:00
File . delete ( tempfile_loc ( 'bork1' ) )
2009-12-24 15:00:46 -05:00
assert_raise ( Sass :: SyntaxError ) { Sass :: Plugin . update_stylesheets }
ensure
Sass :: Plugin . options [ :full_exception ] = old_full_exception
2007-02-06 00:24:13 -05:00
end
2008-06-19 19:10:50 -04:00
def test_two_template_directories
2008-07-14 14:32:08 -04:00
set_plugin_opts :template_location = > {
template_loc = > tempfile_loc ,
template_loc ( nil , 'more_' ) = > tempfile_loc ( nil , 'more_' )
}
2008-06-19 19:10:50 -04:00
Sass :: Plugin . update_stylesheets
2008-08-09 12:43:15 -04:00
[ 'more1' , 'more_import' ] . each { | name | assert_renders_correctly ( name , :prefix = > 'more_' ) }
2008-06-19 19:10:50 -04:00
end
2007-08-28 01:33:57 -04:00
2008-08-09 12:44:40 -04:00
def test_two_template_directories_with_line_annotations
set_plugin_opts :line_comments = > true ,
:style = > :nested ,
:template_location = > {
template_loc = > tempfile_loc ,
template_loc ( nil , 'more_' ) = > tempfile_loc ( nil , 'more_' )
}
Sass :: Plugin . update_stylesheets
assert_renders_correctly ( 'more1_with_line_comments' , 'more1' , :prefix = > 'more_' )
end
2007-11-17 14:55:26 -05:00
def test_merb_update
begin
require 'merb'
rescue LoadError
puts " \n merb couldn't be loaded, skipping a test "
return
end
require 'sass/plugin/merb'
2009-01-09 04:58:30 -05:00
if defined? ( MerbHandler )
MerbHandler . send ( :define_method , :process_without_sass ) { | * args | }
else
Merb :: Rack :: Application . send ( :define_method , :call_without_sass ) { | * args | }
end
2007-11-17 14:55:26 -05:00
set_plugin_opts
File . delete ( tempfile_loc ( 'basic' ) )
2010-01-23 19:06:31 -05:00
assert_needs_update 'basic'
2007-11-17 14:55:26 -05:00
2009-01-09 04:58:30 -05:00
if defined? ( MerbHandler )
MerbHandler . new ( '.' ) . process nil , nil
else
Merb :: Rack :: Application . new . call ( :: Rack :: MockRequest . env_for ( '/' ) )
end
2007-11-17 14:55:26 -05:00
2009-12-24 15:06:51 -05:00
assert_stylesheet_updated 'basic'
2007-11-17 14:55:26 -05:00
end
2007-08-28 01:33:57 -04:00
def test_doesnt_render_partials
assert ! File . exists? ( tempfile_loc ( '_partial' ) )
end
2010-01-23 18:37:39 -05:00
# Callbacks
def test_updating_stylesheets_callback
# Should run even when there's nothing to update
assert_callback :updating_stylesheets , [ ]
end
def test_updating_stylesheets_callback_with_individual_files
files = [ [ template_loc ( " basic " ) , tempfile_loc ( " basic " ) ] ]
assert_callback ( :updating_stylesheets , files ) { Sass :: Plugin . update_stylesheets ( files ) }
end
def test_updating_stylesheets_callback_with_never_update
Sass :: Plugin . options [ :never_update ] = true
assert_no_callback :updating_stylesheets
end
def test_updating_stylesheet_callback_for_updated_template
Sass :: Plugin . options [ :always_update ] = false
2010-01-23 19:09:11 -05:00
touch 'basic'
2010-01-23 18:37:39 -05:00
assert_no_callback :updating_stylesheet , template_loc ( " complex " ) , tempfile_loc ( " complex " ) do
assert_callbacks (
[ :updating_stylesheet , template_loc ( " basic " ) , tempfile_loc ( " basic " ) ] ,
[ :updating_stylesheet , template_loc ( " import " ) , tempfile_loc ( " import " ) ] )
end
end
def test_updating_stylesheet_callback_for_fresh_template
Sass :: Plugin . options [ :always_update ] = false
assert_no_callback :updating_stylesheet
end
def test_updating_stylesheet_callback_for_error_template
Sass :: Plugin . options [ :always_update ] = false
2010-01-23 19:09:11 -05:00
touch 'bork1'
2010-01-23 18:37:39 -05:00
assert_no_callback :updating_stylesheet
end
2009-07-11 16:40:23 -04:00
## Regression
def test_cached_dependencies_update
FileUtils . mv ( template_loc ( " basic " ) , template_loc ( " basic " , " more_ " ) )
set_plugin_opts :load_paths = > [ result_loc , template_loc ( nil , " more_ " ) ]
2010-01-23 19:06:31 -05:00
touch 'basic' , 'more_'
assert_needs_update " import "
2009-07-11 16:40:23 -04:00
Sass :: Plugin . update_stylesheets
assert_renders_correctly ( " import " )
ensure
FileUtils . mv ( template_loc ( " basic " , " more_ " ) , template_loc ( " basic " ) )
end
2006-11-28 15:39:33 -05:00
private
2007-08-28 01:33:57 -04:00
2008-08-09 12:43:15 -04:00
def assert_renders_correctly ( * arguments )
options = arguments . last . is_a? ( Hash ) ? arguments . pop : { }
prefix = options [ :prefix ]
result_name = arguments . shift
tempfile_name = arguments . shift || result_name
expected_lines = File . read ( result_loc ( result_name , prefix ) ) . split ( " \n " )
actual_lines = File . read ( tempfile_loc ( tempfile_name , prefix ) ) . split ( " \n " )
2009-04-21 17:12:43 -04:00
if actual_lines . first == " /* " && expected_lines . first != " /* "
assert ( false , actual_lines [ 0 .. actual_lines . enum_with_index . find { | l , i | l == " */ " } . last ] . join ( " \n " ) )
end
2008-07-14 14:32:08 -04:00
expected_lines . zip ( actual_lines ) . each_with_index do | pair , line |
2008-08-09 12:43:15 -04:00
message = " template: #{ result_name } \n line: #{ line + 1 } "
2006-12-03 18:17:45 -05:00
assert_equal ( pair . first , pair . last , message )
end
2008-07-27 15:46:57 -04:00
if expected_lines . size < actual_lines . size
2008-08-09 12:43:15 -04:00
assert ( false , " #{ actual_lines . size - expected_lines . size } Trailing lines found in #{ tempfile_name } .css: #{ actual_lines [ expected_lines . size .. - 1 ] . join ( '\n' ) } " )
2008-07-27 15:46:57 -04:00
end
2006-12-03 18:17:45 -05:00
end
2007-08-28 01:33:57 -04:00
2009-12-24 15:06:51 -05:00
def assert_stylesheet_updated ( name )
2010-01-23 19:06:31 -05:00
assert_doesnt_need_update name
2009-12-24 15:06:51 -05:00
# Make sure it isn't an exception
expected_lines = File . read ( result_loc ( name ) ) . split ( " \n " )
actual_lines = File . read ( tempfile_loc ( name ) ) . split ( " \n " )
if actual_lines . first == " /* " && expected_lines . first != " /* "
assert ( false , actual_lines [ 0 .. actual_lines . enum_with_index . find { | l , i | l == " */ " } . last ] . join ( " \n " ) )
end
end
2010-01-23 18:37:39 -05:00
def assert_callback ( name , * expected_args )
run = false
Sass :: Plugin . send ( " on_ #{ name } " ) do | * a |
run = true if expected_args == a
end
if block_given?
yield
else
Sass :: Plugin . update_stylesheets
end
assert run , " Expected #{ name } callback to be run with arguments: \n #{ expected_args . inspect } "
end
def assert_no_callback ( name , * unexpected_args )
Sass :: Plugin . send ( " on_ #{ name } " ) do | * a |
next unless unexpected_args . empty? || a == unexpected_args
msg = " Expected #{ name } callback not to be run "
if ! unexpected_args . empty?
msg << " with arguments #{ unexpected_args . inspect } "
elsif ! a . empty?
msg << " , \n was run with arguments #{ a . inspect } "
end
flunk msg
end
if block_given?
yield
else
Sass :: Plugin . update_stylesheets
end
end
def assert_callbacks ( * args )
return Sass :: Plugin . update_stylesheets if args . empty?
assert_callback ( * args . pop ) { assert_callbacks ( * args ) }
end
def clear_callbacks
Sass :: Plugin . instance_variable_set ( '@_sass_callbacks' , { } )
end
2010-01-23 19:06:31 -05:00
def assert_needs_update ( name )
assert ( Sass :: Plugin . stylesheet_needs_update? ( name , template_loc , tempfile_loc ) ,
" Expected #{ template_loc ( name ) } to need an update. " )
end
def assert_doesnt_need_update ( name )
assert ( ! Sass :: Plugin . stylesheet_needs_update? ( name , template_loc , tempfile_loc ) ,
" Expected #{ template_loc ( name ) } not to need an update. " )
end
def touch ( * args )
FileUtils . touch ( template_loc ( * args ) )
end
def reset_mtimes
Dir [ " { #{ template_loc } , #{ tempfile_loc } }/**/*.{css,sass} " ] . each { | f | File . utime ( Time . now , Time . now - 1 , f ) }
end
2008-07-14 14:32:08 -04:00
def template_loc ( name = nil , prefix = nil )
if name
absolutize " #{ prefix } templates/ #{ name } .sass "
else
absolutize " #{ prefix } templates "
end
2007-09-01 21:48:25 -04:00
end
2008-07-14 14:32:08 -04:00
def tempfile_loc ( name = nil , prefix = nil )
if name
absolutize " #{ prefix } tmp/ #{ name } .css "
else
absolutize " #{ prefix } tmp "
end
end
def result_loc ( name = nil , prefix = nil )
if name
absolutize " #{ prefix } results/ #{ name } .css "
else
absolutize " #{ prefix } results "
end
2006-11-28 15:39:33 -05:00
end
2007-08-28 01:33:57 -04:00
2008-07-14 14:32:08 -04:00
def absolutize ( file )
" #{ File . dirname ( __FILE__ ) } / #{ file } "
2006-12-03 21:47:37 -05:00
end
2007-11-17 14:55:26 -05:00
2008-07-14 14:32:08 -04:00
def set_plugin_opts ( overrides = { } )
2007-11-17 14:55:26 -05:00
Sass :: Plugin . options = {
2008-07-14 14:32:08 -04:00
:template_location = > template_loc ,
:css_location = > tempfile_loc ,
2007-11-17 14:55:26 -05:00
:style = > :compact ,
2008-07-14 14:32:08 -04:00
:load_paths = > [ result_loc ] ,
2007-11-17 14:55:26 -05:00
:always_update = > true ,
2008-07-14 14:32:08 -04:00
} . merge ( overrides )
2007-11-17 14:55:26 -05:00
end
2006-12-03 21:47:37 -05:00
end
module Sass::Plugin
class << self
public :stylesheet_needs_update?
2006-11-28 15:33:22 -05:00
end
end
2006-12-03 21:47:37 -05:00
2006-12-22 01:59:38 -05:00
class Sass :: Engine
alias_method :old_render , :render
2007-08-28 01:33:57 -04:00
2006-12-22 01:59:38 -05:00
def render
raise " bork bork bork! " if @template [ 0 ] == " {bork now!} "
old_render
end
end