nov-stylus 1.0.2
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 +168 -0
- data/lib/rails/generators/stylus/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/stylus/assets/templates/stylesheet.css.styl +3 -0
- data/lib/rails/generators/stylus/scaffold/scaffold_generator.rb +11 -0
- data/lib/stylus/import_processor.rb +71 -0
- data/lib/stylus/railtie.rb +32 -0
- data/lib/stylus/runtime/compiler.js +40 -0
- data/lib/stylus/runtime/runner.js +20 -0
- data/lib/stylus/runtime.rb +54 -0
- data/lib/stylus/sprockets.rb +59 -0
- data/lib/stylus/tilt/rails.rb +53 -0
- data/lib/stylus/tilt/stylus.rb +52 -0
- data/lib/stylus/tilt.rb +2 -0
- data/lib/stylus/version.rb +3 -0
- data/lib/stylus.rb +174 -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/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 +131 -0
    
        data/lib/stylus.rb
    ADDED
    
    | @@ -0,0 +1,174 @@ | |
| 1 | 
            +
            require 'stylus/runtime'
         | 
| 2 | 
            +
            require 'stylus/source'
         | 
| 3 | 
            +
            require 'stylus/version'
         | 
| 4 | 
            +
            require 'stylus/railtie' if defined?(::Rails)
         | 
| 5 | 
            +
            ## Stylus
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # `stylus` is a bridge between your Ruby code and the [Stylus](https://github.com/LearnBoost/stylus)
         | 
| 8 | 
            +
            # library that runs on Node.js. It's aims to be a replacement for the
         | 
| 9 | 
            +
            # [stylus_rails](https://github.com/lucasmazza/stylus_rails) gem and to support the Rails 3.1 asset pipeline
         | 
| 10 | 
            +
            # (via [Tilt](https://github.com/rtomayko/tilt)) and other scenarios,
         | 
| 11 | 
            +
            # backed by the [ExecJS](https://github.com/sstephenson/execjs) gem.
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            ### Usage
         | 
| 14 | 
            +
            #
         | 
| 15 | 
            +
            # To compile a `.styl` file or an arbitrary String to .CSS using stylus, just use the `compile` method.
         | 
| 16 | 
            +
            #
         | 
| 17 | 
            +
            # `Stylus.compile(File.new('application.styl'))`
         | 
| 18 | 
            +
            #
         | 
| 19 | 
            +
            # A hash of options for the stylus API is accepted.
         | 
| 20 | 
            +
            #
         | 
| 21 | 
            +
            # `Stylus.compile(File.read('application.styl'), :compress => true)`
         | 
| 22 | 
            +
            #
         | 
| 23 | 
            +
            module Stylus
         | 
| 24 | 
            +
              extend Runtime
         | 
| 25 | 
            +
              class << self
         | 
| 26 | 
            +
                @@compress  = false
         | 
| 27 | 
            +
                @@debug     = false
         | 
| 28 | 
            +
                @@paths     = []
         | 
| 29 | 
            +
                @@imports   = []
         | 
| 30 | 
            +
                @@definitions = {}
         | 
| 31 | 
            +
                @@plugins   = {}
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # Stores a list of plugins to import inside `Stylus`, with an optional hash.
         | 
| 34 | 
            +
                def use(*options)
         | 
| 35 | 
            +
                  arguments = options.last.is_a?(Hash) ? options.pop : {}
         | 
| 36 | 
            +
                  options.each do |plugin|
         | 
| 37 | 
            +
                    @@plugins[plugin] = arguments
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                alias :plugin :use
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                # Stores a list of stylesheets to import on every compile process.
         | 
| 43 | 
            +
                def import(*paths)
         | 
| 44 | 
            +
                  if paths.any?
         | 
| 45 | 
            +
                    @@imports = @@imports.concat(paths)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                @@imports
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                alias :imports :import
         | 
| 50 | 
            +
             | 
| 51 | 
            +
             | 
| 52 | 
            +
                # Stores a list of defined variables to create on every compile process.
         | 
| 53 | 
            +
                def define(variable, value, options = {})
         | 
| 54 | 
            +
                  literal = true if options[:literal]
         | 
| 55 | 
            +
                  @@definitions[variable] = { value: value, literal: literal }
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                # Retrieves all the registered plugins.
         | 
| 59 | 
            +
                def plugins
         | 
| 60 | 
            +
                  @@plugins
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # Retrieves all the registered variables.
         | 
| 64 | 
            +
                def definitions
         | 
| 65 | 
            +
                  @@definitions
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                # Returns the global load path `Array` for your stylesheets.
         | 
| 69 | 
            +
                def paths
         | 
| 70 | 
            +
                  @@paths
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                # Replaces the global load path `Array` of paths.
         | 
| 74 | 
            +
                def paths=(val)
         | 
| 75 | 
            +
                  @@paths = Array(val)
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                # Returns the `debug` flag used to set the `linenos` and `firebug` option for Stylus.
         | 
| 79 | 
            +
                def debug
         | 
| 80 | 
            +
                  @@debug
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
                alias :debug? :debug
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                # Marks the `nib` plugin to be loaded and included on every stylesheet.
         | 
| 85 | 
            +
                def nib=(flag)
         | 
| 86 | 
            +
                  if flag
         | 
| 87 | 
            +
                    use :nib
         | 
| 88 | 
            +
                    import :nib
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                # Sets the `debug` flag.
         | 
| 93 | 
            +
                def debug=(val)
         | 
| 94 | 
            +
                  @@debug = val
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                # Returns the global compress flag.
         | 
| 98 | 
            +
                def compress
         | 
| 99 | 
            +
                  @@compress
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
                alias :compress? :compress
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                # Sets the global flag for the `compress` option.
         | 
| 104 | 
            +
                def compress=(val)
         | 
| 105 | 
            +
                  @@compress = val
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                # Compiles a given input - a plain String, `File` or some sort of IO object that
         | 
| 109 | 
            +
                # responds to `read`.
         | 
| 110 | 
            +
                # It accepts a hash of options that will be merged with the global configuration.
         | 
| 111 | 
            +
                # If the source has a `path`, it will be expanded and used as the :filename option
         | 
| 112 | 
            +
                # So the debug options can be used.
         | 
| 113 | 
            +
                def compile(source, options = {})
         | 
| 114 | 
            +
                  if source.respond_to?(:path) && source.path
         | 
| 115 | 
            +
                    options[:filename] ||= File.expand_path(source.path)
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
                  source  = source.read if source.respond_to?(:read)
         | 
| 118 | 
            +
                  options = merge_options(options)
         | 
| 119 | 
            +
                  exec('compile', source, options, plugins, imports, definitions)
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                # Converts back an input of plain CSS to the `Stylus` syntax. The source object can be
         | 
| 123 | 
            +
                #  a `File`, `StringIO`, `String` or anything that responds to `read`.
         | 
| 124 | 
            +
                def convert(source)
         | 
| 125 | 
            +
                  source = source.read if source.respond_to?(:read)
         | 
| 126 | 
            +
                  exec('convert', source)
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                # Returns a `Hash` of the given `options` merged with the default configuration.
         | 
| 130 | 
            +
                # It also concats the global load path with a given `:paths` option.
         | 
| 131 | 
            +
                def merge_options(options)
         | 
| 132 | 
            +
                  filename = options[:filename]
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                  _paths  = options.delete(:paths)
         | 
| 135 | 
            +
                  options = defaults.merge(options)
         | 
| 136 | 
            +
                  options[:paths] = paths.concat(Array(_paths))
         | 
| 137 | 
            +
                  if filename
         | 
| 138 | 
            +
                    options = options.merge(debug_options)
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
                  options
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                # Returns the default `Hash` of options:
         | 
| 144 | 
            +
                # the compress flag and the global load path.
         | 
| 145 | 
            +
                def defaults
         | 
| 146 | 
            +
                  { compress: self.compress?, paths: self.paths }
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                # Returns a Hash with the debug options to pass to
         | 
| 150 | 
            +
                # Stylus.
         | 
| 151 | 
            +
                def debug_options
         | 
| 152 | 
            +
                  { linenos: self.debug?, firebug: self.debug? }
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                # Return the gem version alongside with the current `Stylus` version of your system.
         | 
| 156 | 
            +
                def version
         | 
| 157 | 
            +
                  "Stylus - gem #{VERSION} library #{exec('version')}"
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                protected
         | 
| 161 | 
            +
                def bundled_path
         | 
| 162 | 
            +
                  File.dirname(Stylus::Source.bundled_path)
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
              end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
              # Exports the `.node_modules` folder on the working directory so npm can
         | 
| 167 | 
            +
              # require modules installed locally.
         | 
| 168 | 
            +
              ENV['NODE_PATH'] = [
         | 
| 169 | 
            +
                File.expand_path('node_modules'),
         | 
| 170 | 
            +
                File.expand_path('vendor/node_modules'),
         | 
| 171 | 
            +
                bundled_path,
         | 
| 172 | 
            +
                ENV['NODE_PATH']
         | 
| 173 | 
            +
              ].join(File::PATH_SEPARATOR)
         | 
| 174 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'rails/generators/stylus/assets/assets_generator'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Stylus::Generators::AssetsGenerator do
         | 
| 5 | 
            +
              include Generators::TestCase
         | 
| 6 | 
            +
              arguments  %w(posts)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              it 'generates a .styl file' do
         | 
| 9 | 
            +
                expect(file('app/assets/stylesheets/posts.css.styl')).to exist
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'rails/generators/rails/controller/controller_generator'
         | 
| 3 | 
            +
            require 'rails/generators/stylus/assets/assets_generator'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe Rails::Generators::ControllerGenerator do
         | 
| 6 | 
            +
              include Generators::TestCase
         | 
| 7 | 
            +
              arguments  %w(posts --stylesheet-engine=stylus)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              it 'generates a .styl file' do
         | 
| 10 | 
            +
                expect(file('app/assets/stylesheets/posts.css.styl')).to exist
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'rails/generators/rails/scaffold/scaffold_generator'
         | 
| 3 | 
            +
            require 'rails/generators/stylus/assets/assets_generator'
         | 
| 4 | 
            +
            require 'rails/generators/stylus/scaffold/scaffold_generator'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            describe Rails::Generators::ScaffoldGenerator do
         | 
| 7 | 
            +
              include Generators::TestCase
         | 
| 8 | 
            +
              arguments  %w(posts --stylesheet-engine=stylus --orm=false)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              it 'generates the default scaffold stylesheet' do
         | 
| 11 | 
            +
                expect(file('app/assets/stylesheets/scaffold.css')).to exist
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              it 'generates a named .styl file' do
         | 
| 15 | 
            +
                expect(file('app/assets/stylesheets/posts.css.styl')).to exist
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Stylus::ImportProcessor do
         | 
| 4 | 
            +
              let(:env) do
         | 
| 5 | 
            +
                Sprockets::Environment.new do |assets|
         | 
| 6 | 
            +
                  assets.append_path fixture_root
         | 
| 7 | 
            +
                  Stylus.setup(assets)
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              it 'adds an imported stylesheet as a dependency' do
         | 
| 12 | 
            +
                asset = env['import']
         | 
| 13 | 
            +
                dependencies = dependencies_on(asset)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                expect(dependencies).to include(fixture_path('mixins/vendor'))
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              context 'nested dependencies' do
         | 
| 19 | 
            +
                it 'walks the dependency chain of imported files' do
         | 
| 20 | 
            +
                  asset = env['nested_import']
         | 
| 21 | 
            +
                  dependencies = dependencies_on(asset)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  expect(dependencies).to include(fixture_path('mixins/nested'))
         | 
| 24 | 
            +
                  expect(dependencies).to include(fixture_path('mixins/vendor'))
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "adds files referenced in a directory's index file" do
         | 
| 28 | 
            +
                  asset = env['indexed_nested_import']
         | 
| 29 | 
            +
                  dependencies = dependencies_on(asset)
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/index'))
         | 
| 32 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/first_dep'))
         | 
| 33 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/second_dep'))
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                it 'walks dependency chains through indexes' do
         | 
| 37 | 
            +
                  asset = env['indexed_recursive_import']
         | 
| 38 | 
            +
                  dependencies = dependencies_on(asset)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  expect(dependencies).to include(fixture_path('indexed_nested_import'))
         | 
| 41 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/index'))
         | 
| 42 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/first_dep'))
         | 
| 43 | 
            +
                  expect(dependencies).to include(fixture_path('indexed/second_dep'))
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              it 'does not process non-stylus files' do
         | 
| 48 | 
            +
                source = '@import "nib"'
         | 
| 49 | 
            +
                template = Stylus::ImportProcessor.new('stylesheet.scss') { source }
         | 
| 50 | 
            +
                context = double
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                expect(context).to_not receive(:depend_on)
         | 
| 53 | 
            +
                template.render(context)
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it 'swallows errors from files outside the Sprockets paths' do
         | 
| 57 | 
            +
                source = '@import "nib"'
         | 
| 58 | 
            +
                template = Stylus::ImportProcessor.new { source }
         | 
| 59 | 
            +
                sprockets = double
         | 
| 60 | 
            +
                expect(sprockets).to receive(:resolve).twice.and_raise(::Sprockets::FileNotFound)
         | 
| 61 | 
            +
                expect(template).to receive(:stylus_file?).and_return(true)
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                expect {
         | 
| 64 | 
            +
                  template.render(sprockets)
         | 
| 65 | 
            +
                }.to_not raise_error
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
            end
         | 
    
        data/spec/rails_spec.rb
    ADDED
    
    | @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe 'Rails integration' do
         | 
| 4 | 
            +
              it "copies all folders from the Sprockets load path" do
         | 
| 5 | 
            +
                app = create_app
         | 
| 6 | 
            +
                Stylus.paths.should include fixture_root
         | 
| 7 | 
            +
                Stylus.paths.should == app.assets.paths
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              it 'process .styl files with the asset pipeline' do
         | 
| 11 | 
            +
                result = fixture(:simple).last
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                app = create_app
         | 
| 14 | 
            +
                app.assets['simple'].to_s.should == result
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              it 'enables @import definitions' do
         | 
| 18 | 
            +
                result = fixture(:import).last
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                app = create_app
         | 
| 21 | 
            +
                app.assets['import'].to_s.should == result
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              it 'skips debug info by default' do
         | 
| 25 | 
            +
                app = create_app
         | 
| 26 | 
            +
                asset = app.assets['simple']
         | 
| 27 | 
            +
                asset.to_s.should_not match(/line 1 : #{asset.pathname}/)
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              it 'provides debug info if required' do
         | 
| 31 | 
            +
                app = create_app(:debug => true)
         | 
| 32 | 
            +
                asset = app.assets['simple']
         | 
| 33 | 
            +
                asset.to_s.should match(/line 1 : #{asset.pathname}/)
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it 'compress the output if Rails is configured to compress them too' do
         | 
| 37 | 
            +
                result = fixture(:compressed).last
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                app = create_app(:compress => true)
         | 
| 40 | 
            +
                app.assets['compressed'].to_s.should == result
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              it 'loads the app normally even when the asset pipeline is disabled' do
         | 
| 44 | 
            +
                pending "TODO: supress the sprockets-rails railtie to test this."
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -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 '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)
         | 
| 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)
         | 
| 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,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
         |