epuber-stylus 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/LICENSE +22 -0
- data/README.md +154 -0
- data/lib/epuber-stylus.rb +174 -0
- data/lib/epuber-stylus/import_processor.rb +71 -0
- data/lib/epuber-stylus/railtie.rb +32 -0
- data/lib/epuber-stylus/runtime.rb +54 -0
- data/lib/epuber-stylus/runtime/compiler.js +40 -0
- data/lib/epuber-stylus/runtime/runner.js +20 -0
- data/lib/epuber-stylus/sprockets.rb +58 -0
- data/lib/epuber-stylus/tilt.rb +2 -0
- data/lib/epuber-stylus/tilt/rails.rb +51 -0
- data/lib/epuber-stylus/tilt/stylus.rb +52 -0
- data/lib/epuber-stylus/version.rb +3 -0
- data/lib/rails/generators/epuber-stylus/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/epuber-stylus/assets/templates/stylesheet.css.styl +3 -0
- data/lib/rails/generators/epuber-stylus/scaffold/scaffold_generator.rb +11 -0
- data/spec/generators/assets_generator_spec.rb +11 -0
- data/spec/generators/controller_generator_spec.rb +12 -0
- data/spec/generators/scaffold_generator_spec.rb +17 -0
- data/spec/import_processor_spec.rb +67 -0
- data/spec/rails_spec.rb +46 -0
- data/spec/runtime_spec.rb +11 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/sprockets_spec.rb +36 -0
- data/spec/stylus_spec.rb +118 -0
- data/spec/support/generators/test_case.rb +59 -0
- data/spec/support/generators/tmp/app/controllers/posts_controller.rb +58 -0
- data/spec/support/generators/tmp/app/helpers/posts_helper.rb +2 -0
- data/spec/support/generators/tmp/config/routes.rb +0 -0
- data/spec/support/helpers.rb +63 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/tilt/rails_spec.rb +64 -0
- data/spec/tilt/stylus_spec.rb +24 -0
- metadata +137 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stylus::Runtime do
|
4
|
+
it 'raises an error if the runtime is not available' do
|
5
|
+
allow(Stylus).to receive(:runtime) { double('An unavailable Runtime', available?: false) }
|
6
|
+
|
7
|
+
expect {
|
8
|
+
Stylus.version
|
9
|
+
}.to raise_error RuntimeError, %r[The Node.JS runtime is not available to Stylus.]
|
10
|
+
end
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
require 'rails'
|
5
|
+
require 'rails/generators/test_case'
|
6
|
+
|
7
|
+
require 'active_support/railtie'
|
8
|
+
require 'action_controller/railtie'
|
9
|
+
require 'sprockets'
|
10
|
+
require 'sprockets/rails'
|
11
|
+
require 'epuber-stylus'
|
12
|
+
|
13
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
14
|
+
|
15
|
+
require 'support/helpers'
|
16
|
+
require 'support/matchers'
|
17
|
+
require 'support/generators/test_case'
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.include Helpers
|
21
|
+
|
22
|
+
config.after :each do
|
23
|
+
Stylus.compress = false
|
24
|
+
Stylus.debug = false
|
25
|
+
Stylus.paths = []
|
26
|
+
Stylus.plugins.clear
|
27
|
+
Stylus.definitions.clear
|
28
|
+
Stylus.imports.clear
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Sprockets setup' do
|
4
|
+
let(:env) do
|
5
|
+
Sprockets::Environment.new do |assets|
|
6
|
+
assets.append_path fixture_root
|
7
|
+
assets.append_path 'javascripts'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'register the default Tilt template' do
|
12
|
+
expect(env).to receive(:register_engine).with('.styl', Tilt::StylusTemplate)
|
13
|
+
Stylus.setup(env)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'register a Rails specific Tilt template' do
|
17
|
+
expect(env).to receive(:register_engine).with('.styl', Stylus::Rails::StylusTemplate)
|
18
|
+
Stylus.setup(env, rails: true)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'register the import processor' do
|
22
|
+
expect(env).to receive(:register_preprocessor).with('text/css', Stylus::ImportProcessor)
|
23
|
+
Stylus.setup(env)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'copies the asset paths' do
|
27
|
+
Stylus.setup(env)
|
28
|
+
expect(Stylus.paths).to eq(env.paths)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'configure the debug and compress flags' do
|
32
|
+
Stylus.setup(env, debug: true, compress: true)
|
33
|
+
expect(Stylus.debug).to be_true
|
34
|
+
expect(Stylus.compress).to be_true
|
35
|
+
end
|
36
|
+
end
|
data/spec/stylus_spec.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stylus do
|
4
|
+
it 'compiles the given source' do
|
5
|
+
input, output = fixture(:simple)
|
6
|
+
expect(Stylus.compile(input)).to eq(output)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'accepts an IO object' do
|
10
|
+
input, output = fixture(:simple)
|
11
|
+
input = StringIO.new(input)
|
12
|
+
expect(Stylus.compile(input)).to eq(output)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'compress the file when the "compress" flag is given' do
|
16
|
+
input, output = fixture(:compressed)
|
17
|
+
expect(Stylus.compile(input, compress: true)).to eq(output.rstrip)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'handles the compress flag globally' do
|
21
|
+
Stylus.compress = true
|
22
|
+
input, output = fixture(:compressed)
|
23
|
+
expect(Stylus.compile(input)).to eq(output.rstrip)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'imports the given paths' do
|
27
|
+
path = fixture_root
|
28
|
+
input, output = fixture(:import)
|
29
|
+
expect(Stylus.compile(input, paths: path)).to eq(output)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'handles the import paths globally' do
|
33
|
+
Stylus.paths << fixture_root
|
34
|
+
input, output = fixture(:import)
|
35
|
+
expect(Stylus.compile(input)).to eq(output)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'implicit imports the given paths' do
|
39
|
+
path = File.expand_path('mixins/vendor.styl', fixture_root)
|
40
|
+
input, output = fixture(:implicit)
|
41
|
+
Stylus.import path
|
42
|
+
expect(Stylus.compile(input)).to eq(output)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'outputs both gem and library version' do
|
46
|
+
expect(Stylus.version).to match(/Stylus - gem .+ library .+/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'converts CSS to Stylus' do
|
50
|
+
stylus, css = fixture(:stylesheet)
|
51
|
+
expect(Stylus.convert(css)).to eq(stylus)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'stores the given plugins' do
|
55
|
+
Stylus.use :one, :two, argument: true
|
56
|
+
expect(Stylus).to have(2).plugins
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'includes the given plugins' do
|
60
|
+
Stylus.use :nib
|
61
|
+
input, output = fixture(:plugin)
|
62
|
+
expect(Stylus.compile(input)).to eq(output)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'stores the define calls' do
|
66
|
+
Stylus.define "mystring", "test"
|
67
|
+
expect(Stylus).to have(1).definitions
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'defines a global variable string' do
|
71
|
+
Stylus.define "mystring", "test"
|
72
|
+
input, output = fixture(:definition)
|
73
|
+
expect(Stylus.compile(input)).to match(/content: 'test'/)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'defines a global variable literal' do
|
77
|
+
Stylus.define "mystring", "red", :literal => true
|
78
|
+
input, output = fixture(:definition)
|
79
|
+
expect(Stylus.compile(input)).to match(/content: red/)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'includes and imports "nib" automatically' do
|
83
|
+
Stylus.nib = true
|
84
|
+
input, output = fixture(:nib)
|
85
|
+
expect(Stylus.compile(input)).to eq(output)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'share variables between imported stylesheets' do
|
89
|
+
input, output = fixture(:variables)
|
90
|
+
path = fixture_root
|
91
|
+
|
92
|
+
expect(Stylus.compile(input, paths: path)).to eq(output)
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'The debug flag' do
|
96
|
+
let(:path) { fixture_path(:debug) }
|
97
|
+
let(:fixture) { File.read(path) }
|
98
|
+
let(:file) { File.new(path) }
|
99
|
+
|
100
|
+
before { Stylus.debug = true }
|
101
|
+
|
102
|
+
it 'turns the "linenos" option on' do
|
103
|
+
expect(Stylus.compile(file)).to match(/line 1 : #{path}/)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'skips the "linenos" option if no filename is given' do
|
107
|
+
expect(Stylus.compile(fixture)).to_not match(/line 1 : #{path}/)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'turns the "firebug" option on' do
|
111
|
+
expect(Stylus.compile(file)).to match(/@media -stylus-debug-info/)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'skips the "firebug" option if no filename is given' do
|
115
|
+
expect(Stylus.compile(fixture)).to_not match(/@media -stylus-debug-info/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Extracted from generator_spec https://github.com/stevehodgkiss/generator_spec
|
2
|
+
# But `RSpec::Rails::RailsExampleGroup` loads a truckload of things from rails and rspec-rails
|
3
|
+
# That we don't need.
|
4
|
+
|
5
|
+
module Generators
|
6
|
+
module TestCase
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include FileUtils
|
9
|
+
|
10
|
+
included do
|
11
|
+
cattr_accessor :test_case, :test_case_instance
|
12
|
+
|
13
|
+
self.test_case = Class.new(Rails::Generators::TestCase) do
|
14
|
+
def fake_test_case; end
|
15
|
+
def add_assertion; end
|
16
|
+
end
|
17
|
+
self.test_case_instance = self.test_case.new(:fake_test_case)
|
18
|
+
self.test_case.tests described_class
|
19
|
+
|
20
|
+
before do
|
21
|
+
prepare_destination
|
22
|
+
create_routes
|
23
|
+
run_generator
|
24
|
+
end
|
25
|
+
|
26
|
+
destination File.expand_path('../tmp', __FILE__)
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def tests(klass)
|
31
|
+
self.test_case.generator_class = klass
|
32
|
+
end
|
33
|
+
|
34
|
+
def arguments(array)
|
35
|
+
self.test_case.default_arguments = array
|
36
|
+
end
|
37
|
+
|
38
|
+
def destination(path)
|
39
|
+
self.test_case.destination_root = path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def file(relative)
|
44
|
+
File.expand_path(relative, destination_root)
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(method_sym, *arguments, &block)
|
48
|
+
self.test_case_instance.send(method_sym, *arguments, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to?(method_sym, include_private = false)
|
52
|
+
if self.test_case_instance.respond_to?(method_sym)
|
53
|
+
true
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
before_action :set_post, only: [:show, :edit, :update, :destroy]
|
3
|
+
|
4
|
+
# GET /posts
|
5
|
+
def index
|
6
|
+
@posts = Post.all
|
7
|
+
end
|
8
|
+
|
9
|
+
# GET /posts/1
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /posts/new
|
14
|
+
def new
|
15
|
+
@post = Post.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# GET /posts/1/edit
|
19
|
+
def edit
|
20
|
+
end
|
21
|
+
|
22
|
+
# POST /posts
|
23
|
+
def create
|
24
|
+
@post = Post.new(post_params)
|
25
|
+
|
26
|
+
if @post.save
|
27
|
+
redirect_to @post, notice: 'Post was successfully created.'
|
28
|
+
else
|
29
|
+
render action: 'new'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# PATCH/PUT /posts/1
|
34
|
+
def update
|
35
|
+
if @post.update(post_params)
|
36
|
+
redirect_to @post, notice: 'Post was successfully updated.'
|
37
|
+
else
|
38
|
+
render action: 'edit'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# DELETE /posts/1
|
43
|
+
def destroy
|
44
|
+
@post.destroy
|
45
|
+
redirect_to posts_url, notice: 'Post was successfully destroyed.'
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
# Use callbacks to share common setup or constraints between actions.
|
50
|
+
def set_post
|
51
|
+
@post = Post.find(params[:id])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Only allow a trusted parameter "white list" through.
|
55
|
+
def post_params
|
56
|
+
params[:post]
|
57
|
+
end
|
58
|
+
end
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Helpers
|
2
|
+
def create_routes
|
3
|
+
destination = File.join(destination_root, 'config')
|
4
|
+
|
5
|
+
FileUtils.mkdir_p(destination)
|
6
|
+
FileUtils.touch File.join(destination, 'routes.rb')
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_app(options = {})
|
10
|
+
Rails.application = nil
|
11
|
+
|
12
|
+
Class.new(Rails::Application).tap do |app|
|
13
|
+
config = app.config.assets
|
14
|
+
assets = app.assets
|
15
|
+
config.paths = []
|
16
|
+
|
17
|
+
assets.cache = ActiveSupport::Cache.lookup_store(:null_store)
|
18
|
+
config.compress = options[:compress]
|
19
|
+
config.debug = options[:debug]
|
20
|
+
config.paths << fixture_root
|
21
|
+
config.paths << File.expand_path('javascripts')
|
22
|
+
yield(app) if block_given?
|
23
|
+
|
24
|
+
app.config.eager_load = false
|
25
|
+
app.config.active_support.deprecation = :log
|
26
|
+
app.initialize!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def fixture_root
|
31
|
+
File.expand_path('../../stylesheets', __FILE__)
|
32
|
+
end
|
33
|
+
|
34
|
+
def images_root
|
35
|
+
File.expand_path('../../images', __FILE__)
|
36
|
+
end
|
37
|
+
|
38
|
+
def output_root
|
39
|
+
File.expand_path('../../cases', __FILE__)
|
40
|
+
end
|
41
|
+
|
42
|
+
def fixture(name)
|
43
|
+
source = fixture_path(name)
|
44
|
+
output = css_path(name)
|
45
|
+
[source, output].map do |path|
|
46
|
+
File.read(path) if File.file?(path)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def css_path(name)
|
51
|
+
File.join(output_root, "#{name}.css")
|
52
|
+
end
|
53
|
+
|
54
|
+
def fixture_path(name)
|
55
|
+
File.join(fixture_root, "#{name}.styl")
|
56
|
+
end
|
57
|
+
|
58
|
+
def dependencies_on(asset)
|
59
|
+
context = env.context_class.new(env, asset.logical_path, asset.pathname)
|
60
|
+
context.evaluate(asset.pathname)
|
61
|
+
context._dependency_paths
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'epuber-stylus/tilt/rails'
|
3
|
+
|
4
|
+
describe Stylus::Rails::StylusTemplate do
|
5
|
+
it 'registers the template for .styl files' do
|
6
|
+
expect(Tilt['application.styl']).to eq(Stylus::Rails::StylusTemplate)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a content-type' do
|
10
|
+
expect(Stylus::Rails::StylusTemplate.default_mime_type).to eq('text/css')
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when no resources other then css found' do
|
14
|
+
it 'compiles the given source without changes' do
|
15
|
+
result = fixture(:simple).last
|
16
|
+
|
17
|
+
app = create_app
|
18
|
+
expect(app.assets['simple'].to_s).to eq(result)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
it 'substitutes asset_path with path' do
|
24
|
+
app = create_app do |app|
|
25
|
+
app.config.assets.paths << images_root
|
26
|
+
app.config.asset_host = 'http://localhost'
|
27
|
+
end
|
28
|
+
result = fixture(:asset_path).last
|
29
|
+
expect(app.assets['asset_path'].to_s).to eq(result)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'substitutes asset_url with url' do
|
33
|
+
app = create_app do |app|
|
34
|
+
app.config.assets.paths << images_root
|
35
|
+
app.config.asset_host = 'http://localhost'
|
36
|
+
end
|
37
|
+
result = fixture(:asset_url).last
|
38
|
+
expect(app.assets['asset_url'].to_s).to eq(result)
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when config.assets.digest = true' do
|
42
|
+
let(:app) do
|
43
|
+
create_app do |app|
|
44
|
+
app.config.assets.paths << images_root
|
45
|
+
app.config.asset_host = 'http://localhost'
|
46
|
+
app.config.assets.digest = true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'appends fingerprint to asset path' do
|
51
|
+
digested_image_path = app.assets['rails.png'].digest_path
|
52
|
+
expect(digested_image_path).to match(/^rails-(\w+)\.png$/)
|
53
|
+
asset = app.assets['digested_asset_path']
|
54
|
+
expect(asset.to_s).to eq("body {\n background-image: url(\"http://localhost/assets/#{digested_image_path}\");\n}\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'appends fingerprint to asset url' do
|
58
|
+
digested_image_path = app.assets['rails.png'].digest_path
|
59
|
+
expect(digested_image_path).to match(/^rails-(\w+)\.png$/)
|
60
|
+
asset = app.assets['digested_asset_url']
|
61
|
+
expect(asset.to_s).to eq("body {\n background-image: url(\"http://localhost/assets/#{digested_image_path}\");\n}\n")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|