epuber-stylus 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|