rack-less 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.bundle/config +2 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +53 -0
  5. data/Rakefile +5 -43
  6. data/lib/rack/less.rb +6 -12
  7. data/lib/rack/less/config.rb +13 -25
  8. data/lib/rack/less/request.rb +36 -22
  9. data/lib/rack/less/source.rb +7 -7
  10. data/lib/rack/less/version.rb +3 -11
  11. data/rack-less.gemspec +29 -0
  12. data/test/app_helper.rb +25 -0
  13. data/test/config_test.rb +215 -0
  14. data/test/env.rb +9 -0
  15. data/test/fixtures/mock_options.rb +9 -0
  16. data/test/fixtures/sinatra/app.rb +9 -0
  17. data/test/fixtures/sinatra/app/stylesheets/all_compiled.css +7 -0
  18. data/test/fixtures/sinatra/app/stylesheets/all_one.less +10 -0
  19. data/test/fixtures/sinatra/app/stylesheets/all_two.less +4 -0
  20. data/test/fixtures/sinatra/app/stylesheets/css.css +4 -0
  21. data/test/fixtures/sinatra/app/stylesheets/css_compiled.css +4 -0
  22. data/test/fixtures/sinatra/app/stylesheets/nested/file.css +10 -0
  23. data/test/fixtures/sinatra/app/stylesheets/nested/file_compiled.css +2 -0
  24. data/test/fixtures/sinatra/app/stylesheets/nested/really/really.less +10 -0
  25. data/test/fixtures/sinatra/app/stylesheets/nested/really/really_compiled.css +2 -0
  26. data/test/fixtures/sinatra/app/stylesheets/normal.less +10 -0
  27. data/test/fixtures/sinatra/app/stylesheets/normal_compiled.css +2 -0
  28. data/test/fixtures/sinatra/app/stylesheets/some-styles.less +8 -0
  29. data/test/fixtures/sinatra/app/stylesheets/some_styles.less +8 -0
  30. data/test/fixtures/sinatra/app/stylesheets/styles1.less +8 -0
  31. data/test/helper.rb +77 -0
  32. data/test/options_test.rb +60 -0
  33. data/test/request_test.rb +142 -0
  34. data/test/response_test.rb +41 -0
  35. data/test/sinatra_test.rb +54 -0
  36. data/test/source_test.rb +158 -0
  37. metadata +93 -57
@@ -0,0 +1,60 @@
1
+ require "test/helper"
2
+ require 'rack/less/options'
3
+ require 'fixtures/mock_options'
4
+
5
+ class OptionsTest < Test::Unit::TestCase
6
+ context 'Rack::Less::Options' do
7
+ setup { @options = MockOptions.new }
8
+
9
+ should "use a namespace" do
10
+ assert_equal 'rack-less', Rack::Less::Options::RACK_ENV_NS
11
+ end
12
+
13
+ should "provide an option_name helper" do
14
+ assert_respond_to MockOptions, :option_name
15
+ end
16
+
17
+ should "provide defaults" do
18
+ assert_respond_to MockOptions, :defaults
19
+ end
20
+
21
+ should "allow access to the options" do
22
+ assert_respond_to @options, :options, 'no #options accessor'
23
+ assert_kind_of Hash, @options.options, '#options is not a Hash'
24
+ assert_equal MockOptions.defaults[MockOptions.option_name(:source)], @options.options(:source)
25
+ end
26
+
27
+ { :root => ".",
28
+ :source => 'app/stylesheets',
29
+ :public => 'public',
30
+ :hosted_at => '/stylesheets'
31
+ }.each do |k,v|
32
+ should "default #{k} correctly" do
33
+ assert_equal v, @options.options[MockOptions.option_name(k)]
34
+ end
35
+ end
36
+
37
+ context '#set' do
38
+ should "set a Symbol option as #{Rack::Less::Options::RACK_ENV_NS}.symbol" do
39
+ @options.set :foo, 'bar'
40
+ assert_equal 'bar', @options.options[MockOptions.option_name(:foo)]
41
+ end
42
+ should 'set a String option as string' do
43
+ @options.set 'foo.bar', 'baz'
44
+ assert_equal 'baz', @options.options['foo.bar']
45
+ end
46
+ should 'set all key/value pairs when given a Hash' do
47
+ @options.set :foo => 'bar', 'foo.bar' => 'baz'
48
+ assert_equal 'bar', @options.options[MockOptions.option_name(:foo)]
49
+ assert_equal 'baz', @options.options['foo.bar']
50
+ end
51
+ end
52
+
53
+ should 'allow setting multiple options via assignment' do
54
+ @options.options = { :foo => 'bar', 'foo.bar' => 'baz' }
55
+ assert_equal 'bar', @options.options[MockOptions.option_name(:foo)]
56
+ assert_equal 'baz', @options.options['foo.bar']
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,142 @@
1
+ require "test/helper"
2
+ require 'rack/less/request'
3
+
4
+ class RequestTest < Test::Unit::TestCase
5
+
6
+ context 'Rack::Less::Request' do
7
+ setup do
8
+ @defaults = env_defaults
9
+ end
10
+
11
+ context "basic object" do
12
+ should "have some attributes" do
13
+ [ :options,
14
+ :hosted_at_option,
15
+ :request_method,
16
+ :path_info,
17
+ :path_info_format,
18
+ :path_info_resource,
19
+ :source,
20
+ :hosted_at?,
21
+ :cached?,
22
+ :for_css?,
23
+ :for_less?
24
+ ].each do |a|
25
+ assert_respond_to less_request("GET", "/foo.css"), a, "request does not respond to #{a.inspect}"
26
+ end
27
+ end
28
+
29
+ should "know it's resource format" do
30
+ assert_equal '.css', less_request("GET", "/foo.css").path_info_format
31
+ assert_equal '.css', less_request("GET", "/foo/bar.css").path_info_format
32
+ assert_equal '', less_request("GET", "/foo/bar").path_info_format
33
+ end
34
+
35
+ should "sanitize the :hosted_at options" do
36
+ req = less_request("GET", "/something.css")
37
+ req.options = {:hosted_at => "/here"}
38
+ assert_equal "/here", req.hosted_at_option
39
+
40
+ req = less_request("GET", "/something.css")
41
+ req.options = {:hosted_at => "//there"}
42
+ assert_equal "/there", req.hosted_at_option
43
+
44
+ req = less_request("GET", "/something.css")
45
+ req.options = {:hosted_at => "/where/"}
46
+ assert_equal "/where", req.hosted_at_option
47
+
48
+ req = less_request("GET", "/something.css")
49
+ req.options = {:hosted_at => "what/"}
50
+ assert_equal "/what", req.hosted_at_option
51
+
52
+ req = less_request("GET", "/something.css")
53
+ req.options = {:hosted_at => "why//"}
54
+ assert_equal "/why", req.hosted_at_option
55
+ end
56
+
57
+ should "know it's resource" do
58
+ assert_equal '/something', less_request("GET", "/stylesheets/something.css").path_info_resource
59
+ assert_equal '/something.awesome', less_request("GET", "/stylesheets/something.awesome.css").path_info_resource
60
+ assert_equal '/nested/something', less_request("GET", "/stylesheets/nested/something.css").path_info_resource
61
+ assert_equal '/something/really/awesome', less_request("GET", "/stylesheets/something/really/awesome.css").path_info_resource
62
+ assert_equal '/something', less_request("GET", "/something.css").path_info_resource
63
+ assert_equal '/something', less_request("GET", "///something.css").path_info_resource
64
+ assert_equal '/nested/something', less_request("GET", "/nested/something.css").path_info_resource
65
+ assert_equal '/nested/something', less_request("GET", "/nested///something.css").path_info_resource
66
+ end
67
+ end
68
+
69
+ context "#source " do
70
+ should "match :compress settings with Rack::Less:Config" do
71
+ req = less_request("GET", "/stylesheets/normal.css")
72
+ assert_equal Rack::Less.config.compress?, req.source.compress?
73
+ end
74
+
75
+ should "set it's cache value to nil when Rack::Less not configured to cache" do
76
+ Rack::Less.config = Rack::Less::Config.new
77
+ req = less_request("GET", "/stylesheets/normal.css")
78
+
79
+ assert_equal false, req.source.cache?
80
+ assert_equal nil, req.source.cache
81
+ end
82
+
83
+ should "set it's cache to the appropriate path when Rack::Less configured to cache" do
84
+ Rack::Less.config = Rack::Less::Config.new :cache => true
85
+ req = less_request("GET", "/stylesheets/normal.css")
86
+ cache_path = File.join(req.options(:root), req.options(:public), req.hosted_at_option)
87
+
88
+ assert_equal true, req.source.cache?
89
+ assert_equal cache_path, req.source.cache
90
+ end
91
+ end
92
+
93
+ should_not_be_a_valid_rack_less_request({
94
+ :method => "POST",
95
+ :resource => "/foo.html",
96
+ :description => "a non-css resource"
97
+ })
98
+
99
+ should_not_be_a_valid_rack_less_request({
100
+ :method => "POST",
101
+ :resource => "/foo.css",
102
+ :description => "a css resource"
103
+ })
104
+
105
+ should_not_be_a_valid_rack_less_request({
106
+ :method => "GET",
107
+ :resource => "/foo.css",
108
+ :description => "a css resource hosted somewhere other than where Rack::Less expects them"
109
+ })
110
+
111
+ should_not_be_a_valid_rack_less_request({
112
+ :method => "GET",
113
+ :resource => "/stylesheets/foo.css",
114
+ :description => "a css resource hosted where Rack::Less expects them but does not match any source"
115
+ })
116
+
117
+ should_be_a_valid_rack_less_request({
118
+ :method => "GET",
119
+ :resource => "/stylesheets/normal.css",
120
+ :description => "a css resource hosted where Rack::Less expects them that matches source"
121
+ })
122
+
123
+ should_be_a_valid_rack_less_request({
124
+ :method => "GET",
125
+ :resource => "/stylesheets/some-styles.css",
126
+ :description => "a proper css resource with a '-' in the name"
127
+ })
128
+
129
+ should_be_a_valid_rack_less_request({
130
+ :method => "GET",
131
+ :resource => "/stylesheets/some_styles.css",
132
+ :description => "a proper css resource with a '_' in the name"
133
+ })
134
+
135
+ should_be_a_valid_rack_less_request({
136
+ :method => "GET",
137
+ :resource => "/stylesheets/styles1.css",
138
+ :description => "a proper css resource with a number in the name"
139
+ })
140
+ end
141
+
142
+ end
@@ -0,0 +1,41 @@
1
+ require "test/helper"
2
+ require 'rack/less/response'
3
+
4
+ class RequestTest < Test::Unit::TestCase
5
+
6
+ context 'Rack::Less::Response' do
7
+ setup do
8
+ @defaults = env_defaults
9
+ @css = File.read(file_path('test','fixtures','sinatra','app','stylesheets', 'css_compiled.css'))
10
+ @response = less_response(@css)
11
+ end
12
+
13
+ should "have some attributes" do
14
+ [ :options,
15
+ :status,
16
+ :headers,
17
+ :body,
18
+ :content_length,
19
+ :content_type,
20
+ :to_rack
21
+ ].each do |a|
22
+ assert_respond_to @response, a, "request does not respond to #{a.inspect}"
23
+ end
24
+ end
25
+
26
+ should "set it's status to '#{Rack::Utils::HTTP_STATUS_CODES[200]}'" do
27
+ assert_equal 200, @response.status
28
+ end
29
+
30
+ should "set it's Content-Type to '#{Rack::Less::MIME_TYPE}'" do
31
+ assert_equal Rack::Less::MIME_TYPE, @response.content_type, 'the content_type accessor is incorrect'
32
+ assert_equal Rack::Less::MIME_TYPE, @response.headers['Content-Type'], 'the Content-Type header is incorrect'
33
+ end
34
+
35
+ should "set it's Content-Length appropriately" do
36
+ assert_equal Rack::Less::Response.content_length(@css), @response.content_length, 'the content_length accessor is incorrect'
37
+ assert_equal Rack::Less::Response.content_length(@css), @response.headers['Content-Length'].to_i
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,54 @@
1
+ require "test/helper"
2
+ require "test/app_helper"
3
+ require 'test/fixtures/sinatra/app'
4
+
5
+ class SinatraTest < Test::Unit::TestCase
6
+
7
+ def app
8
+ @app ||= SinatraApp
9
+ end
10
+ def default_value(name)
11
+ Rack::Less::Base.defaults["#{Rack::Less::Options::RACK_ENV_NS}.#{name}"]
12
+ end
13
+
14
+ context "A Sinatra app using Rack::Less" do
15
+
16
+ context "requesting valid LESS" do
17
+ setup do
18
+ app.use Rack::Less,
19
+ :root => file_path('test','fixtures','sinatra')
20
+
21
+ @compiled = File.read(file_path('test','fixtures','sinatra','app','stylesheets', 'normal_compiled.css'))
22
+ @response = visit "/stylesheets/normal.css"
23
+ end
24
+
25
+ should_respond_with_compiled_css
26
+ end
27
+
28
+ context "requesting a nested valid LESS" do
29
+ setup do
30
+ app.use Rack::Less,
31
+ :root => file_path('test','fixtures','sinatra')
32
+
33
+ @compiled = File.read(file_path('test','fixtures','sinatra','app','stylesheets', 'nested', 'file_compiled.css'))
34
+ @response = visit "/stylesheets/nested/file.css"
35
+ end
36
+
37
+ should_respond_with_compiled_css
38
+ end
39
+
40
+ context "requesting a really nested valid LESS" do
41
+ setup do
42
+ app.use Rack::Less,
43
+ :root => file_path('test','fixtures','sinatra')
44
+
45
+ @compiled = File.read(file_path('test','fixtures','sinatra','app','stylesheets', 'nested', 'really', 'really_compiled.css'))
46
+ @response = visit "/stylesheets/nested/really/really.css"
47
+ end
48
+
49
+ should_respond_with_compiled_css
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,158 @@
1
+ require "test/helper"
2
+ require 'rack/less/source'
3
+
4
+ class SourceTest < Test::Unit::TestCase
5
+ context 'Rack::Less::Source' do
6
+ setup do
7
+ @source_folder = file_path('test','fixtures','sinatra','app','stylesheets')
8
+ @cache = file_path('test','fixtures','sinatra','public','stylesheets')
9
+ end
10
+
11
+ should "require an existing :folder" do
12
+ assert_raise ArgumentError do
13
+ Rack::Less::Source.new('foo')
14
+ end
15
+ assert_raise ArgumentError do
16
+ Rack::Less::Source.new('foo', :folder => file_path('does','not','exist'))
17
+ end
18
+ assert_nothing_raised do
19
+ Rack::Less::Source.new('foo', :folder => @source_folder)
20
+ end
21
+ end
22
+
23
+ should "accept both .less and .css extensions, prefering .less over .css though" do
24
+ assert_equal [:less, :css], Rack::Less::Source::PREFERRED_EXTENSIONS
25
+ end
26
+
27
+ context "object" do
28
+ setup do
29
+ @basic = Rack::Less::Source.new('basic', :folder => @source_folder)
30
+ @nested = Rack::Less::Source.new('this/source/is/nested', :folder => @source_folder)
31
+ @ugly = Rack::Less::Source.new('//this/source/is/ugly', :folder => @source_folder)
32
+ @compressed = Rack::Less::Source.new('compressed', {
33
+ :folder => @source_folder,
34
+ :compress => true
35
+ })
36
+ @cached = Rack::Less::Source.new('cached', {
37
+ :folder => @source_folder,
38
+ :cache => @cache,
39
+ :compress => false
40
+ })
41
+ end
42
+
43
+ should "have accessors for path and cache values" do
44
+ assert_respond_to @basic, :css_resource
45
+ assert_equal 'basic', @basic.css_resource
46
+ assert_respond_to @basic, :cache
47
+ assert_equal 'this/source/is/nested', @nested.css_resource
48
+ assert_equal 'this/source/is/ugly', @ugly.css_resource
49
+ end
50
+
51
+ should "have an option for using compression" do
52
+ assert_equal false, @basic.compress?, 'the basic app should not compress'
53
+ assert_equal true, @compressed.compress?, 'the compressed app should compress'
54
+ assert_equal false, @cached.compress?, 'the cached app should not compress'
55
+ end
56
+
57
+ should "have an option for caching output to files" do
58
+ assert_equal false, @basic.cache?, 'the basic app should not cache'
59
+ assert_equal true, @cached.cache?, 'the cached app should cache'
60
+ end
61
+
62
+ should "have a source files list" do
63
+ assert_respond_to @basic, :files, 'engine does not respond to :files'
64
+ assert_kind_of Array, @basic.files, 'the engine files is not an Array'
65
+ end
66
+
67
+ should "have compiled css" do
68
+ assert_respond_to @basic, :to_css, 'engine does not respond to :to_css'
69
+ assert_respond_to @basic, :css, 'engine does not respond to :css'
70
+ end
71
+ end
72
+
73
+ context "with no corresponding source" do
74
+ setup do
75
+ @none = Rack::Less::Source.new('none', :folder => @source_folder)
76
+ end
77
+
78
+ should "have an empty file list" do
79
+ assert @none.files.empty?, 'engine file list is not empty'
80
+ end
81
+
82
+ should "generate no css" do
83
+ assert @none.to_css.empty?, 'engine generated css when it should not have'
84
+ end
85
+ end
86
+
87
+ should_compile_source('normal', "needing to be compiled")
88
+ should_compile_source('nested/file', "that is nested, needing to be compiled")
89
+ should_compile_source('css', "that is a CSS stylesheet")
90
+
91
+
92
+ context "with whitespace compression" do
93
+ setup do
94
+ @compiled = File.read(File.join(@source_folder, "normal_compiled.css"))
95
+ @compressed_normal = Rack::Less::Source.new('normal', {
96
+ :folder => @source_folder,
97
+ :compress => :whitespace
98
+ })
99
+ end
100
+
101
+ should "compress the compiled css" do
102
+ assert_equal @compiled.strip.delete("\n"), @compressed_normal.to_css, "the compiled css is compressed incorrectly"
103
+ end
104
+ end
105
+
106
+ context "with yui compression" do
107
+ setup do
108
+ @compiled = File.read(File.join(@source_folder, "normal_compiled.css"))
109
+ @compressed_normal = Rack::Less::Source.new('normal', {
110
+ :folder => @source_folder,
111
+ :compress => :yui
112
+ })
113
+ end
114
+
115
+ should "compress the compiled css" do
116
+ comp = YUI::CssCompressor.new(Rack::Less::Source::YUI_OPTS).compress(@compiled.strip)
117
+ assert_equal comp, @compressed_normal.to_css, "the compiled css is compressed incorrectly"
118
+ end
119
+ end
120
+
121
+ context "with caching" do
122
+ setup do
123
+ FileUtils.rm_rf(File.dirname(@cache)) if File.exists?(File.dirname(@cache))
124
+ @expected = Rack::Less::Source.new('normal', {
125
+ :folder => @source_folder,
126
+ :cache => @cache
127
+ }).to_css
128
+ @cached_file = File.join(@cache, "normal.css")
129
+ end
130
+ teardown do
131
+ FileUtils.rm_rf(File.dirname(@cache)) if File.exists?(File.dirname(@cache))
132
+ end
133
+
134
+ should "store the compiled css to a file in the cache" do
135
+ assert File.exists?(@cache), 'the cache folder does not exist'
136
+ assert File.exists?(@cached_file), 'the css was not cached to a file'
137
+ assert_equal @expected.strip, File.read(@cached_file).strip, "the compiled css is incorrect"
138
+ end
139
+ end
140
+
141
+ context "that is a combination of multiple files" do
142
+ setup do
143
+ @compiled = File.read(File.join(@source_folder, "all_compiled.css"))
144
+ @combinations_before = Rack::Less.config.combinations
145
+ Rack::Less.config.combinations = {'all' => ['all_one', 'all_two']}
146
+ @all = Rack::Less::Source.new('all', :folder => @source_folder)
147
+ end
148
+ teardown do
149
+ Rack::Less.config.combinations = @combinations_before
150
+ end
151
+
152
+ should "combine the compiled css" do
153
+ assert_equal @compiled.strip, @all.to_css.strip, "the compiled css is combined incorrectly"
154
+ end
155
+ end
156
+
157
+ end
158
+ end