diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4c7ade2..aba502d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,97 +4,95 @@ on: [push, pull_request] jobs: lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ruby - bundler-cache: true - - - name: Lint - run: bundle exec rake rubocop + - name: Checkout + uses: actions/checkout@v3 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby + bundler-cache: true + bundler: 2 + - name: Lint + run: bundle exec rubocop test: - runs-on: ${{ matrix.os }} - strategy: + fail-fast: false matrix: - os: [macos-latest, ubuntu-latest, windows-latest] - ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2', 'ruby', 'jruby'] + os: + - macos-latest + - ubuntu-latest + - windows-latest + ruby: + - '3.1' + - '3.2' + - '3.3' + - ruby + - jruby + - truffleruby + gemfile: + - gemfiles/rails_6_1.gemfile + - gemfiles/rails_7_0.gemfile + - gemfiles/rails_7_1.gemfile exclude: - os: windows-latest - ruby-version: jruby - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby-version }} - bundler-cache: true - - - name: Test - run: bundle exec rake test - - test-vendor: - - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] - ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2', 'ruby', 'jruby'] - submodule: - - vendor/github.com/sass/sassc-rails - - vendor/github.com/twbs/bootstrap - exclude: + ruby: jruby - os: windows-latest - ruby-version: jruby - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby-version }} - bundler-cache: true - - - name: Test - run: bundle exec rake git:submodule:test[${{matrix.submodule}}] - - release: - - if: github.event.repository.fork == false && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - - needs: [lint, test, test-vendor] - - runs-on: ubuntu-latest - + ruby: truffleruby steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ssh-key: ${{ secrets.DEPLOY_KEY }} - - - name: Setup ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ruby - - - name: Release - run: | - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - git config user.name github-actions[bot] - rake -f -r bundler/gem_tasks release gem_push=no + - name: Checkout + uses: actions/checkout@v3 + env: + BUNDLE_GEMFILE: "${{matrix.gemfile}}" + - name: Setup ruby + uses: ruby/setup-ruby@v1 + env: + BUNDLE_GEMFILE: "${{matrix.gemfile}}" + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + bundler: 2 + - name: Test + run: bundle exec rake test + env: + BUNDLE_GEMFILE: "${{matrix.gemfile}}" + +# test-vendor: +# runs-on: ${{ matrix.os }} +# strategy: +# fail-fast: false +# matrix: +# os: +# - macos-latest +# - ubuntu-latest +# - windows-latest +# ruby: +# - '3.3' +# - jruby +# gemfile: +# - Gemfile +# submodule: +# - vendor/github.com/twbs/bootstrap +# exclude: +# - os: windows-latest +# ruby: jruby +# steps: +# - name: Checkout +# uses: actions/checkout@v3 +# env: +# BUNDLE_GEMFILE: "${{matrix.gemfile}}" +# - name: Setup ruby +# uses: ruby/setup-ruby@v1 +# env: +# BUNDLE_GEMFILE: "${{matrix.gemfile}}" +# with: +# ruby-version: ${{ matrix.ruby }} +# bundler-cache: true +# bundler: 2 +# - name: Test +# run: bundle exec rake git:submodule:test[${{matrix.submodule}}] +# env: +# BUNDLE_GEMFILE: "${{matrix.gemfile}}" diff --git a/.gitignore b/.gitignore index 1376fd3..fb0a09e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.bundle/ +/.idea/ /.yardoc /Gemfile.lock /gemfiles/*.lock diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..b4d7d29 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,27 @@ +inherit_from: .rubocop_todo.yml + +AllCops: + NewCops: enable + SuggestExtensions: false + TargetRubyVersion: 3.1 + Exclude: + - vendor/**/* + +Layout/LineLength: + Max: 120 + Exclude: + - test/**/* + +Metrics: + Exclude: + - test/**/* + +Naming/BlockForwarding: + Enabled: false + +Naming/FileName: + Exclude: + - 'lib/dartsass-sprockets.rb' + +Style/HashSyntax: + EnforcedShorthandSyntax: never diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..25618c5 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,44 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2023-12-31 06:58:36 UTC using RuboCop version 1.59.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 3 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 33 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 9 + +# Offense count: 3 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 29 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/PerceivedComplexity: + Max: 9 + +# Offense count: 17 +# Configuration parameters: AllowedConstants. +Style/Documentation: + Exclude: + - 'spec/**/*' + - 'test/**/*' + - 'lib/rails/generators/sass/assets/assets_generator.rb' + - 'lib/rails/generators/sass/scaffold/scaffold_generator.rb' + - 'lib/rails/generators/sass_scaffold.rb' + - 'lib/rails/generators/scss/assets/assets_generator.rb' + - 'lib/rails/generators/scss/scaffold/scaffold_generator.rb' + - 'lib/sassc/rails/compressor.rb' + - 'lib/sassc/rails/functions.rb' + - 'lib/sassc/rails/importer.rb' + - 'lib/sassc/rails/railtie.rb' + - 'lib/sassc/rails/template.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 73cb73d..493d4ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +- **3.1.0** + - Change dependency from dartsass-ruby to sassc-embedded. + - Drop support for Ruby prior to 3.1. + - Add Rubocop and fix all issues. + - **3.0.0** - [Release as dartsass-sprockets gem](https://github.com/tablecheck/dartsass-sprockets/pull/1) diff --git a/Gemfile b/Gemfile index 9ca0677..1e9e61b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,13 @@ +# frozen_string_literal: true + source 'https://rubygems.org' platforms :windows do gem 'tzinfo-data' end -# for working locally -# gem "sassc", :path => "../sassc" +gem 'mocha' +gem 'rake' +gem 'rubocop' -# Specify your gem's dependencies in sassc-rails.gemspec gemspec diff --git a/README.md b/README.md index 7a7e926..0a9066f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Use [Dart Sass](https://sass-lang.com/dart-sass) with Sprockets and the Ruby on This gem is a fork of [sass/sassc-rails](https://github.com/sass/sassc-rails) which maintains API compatibility but delegates to the -[dartsass-ruby](https://github.com/tablecheck/dartsass-ruby) gem +[sass-embedded](https://github.com/sass-contrib/sass-embedded-host-ruby) gem which uses Dart Sass instead of the libsass C implmentation. For ease of upgrading, the root namespace `::SassC` is still used by this gem, @@ -25,6 +25,14 @@ gem 'dartsass-sprockets' This will automatically configure your default Rails `config.assets.css_compressor` to use `:sass`. +### Version Support + +The current version of `dartsass-sprockets` supports: +- Ruby 3.1+ +- Rails 6.1+ + +For older versions of Ruby and Rails may be supported with earlier versions of this gem. + ### Upgrading to Dart Sass This gem is a drop-in replacement to [sass-rails](https://github.com/rails/sass-rails). @@ -59,10 +67,11 @@ Note these source maps are *inline* and will be appended to the compiled ## Credits * This gem is maintained and used in production by [TableCheck](https://www.tablecheck.com/en/join). (We'd be very glad if the Sass organization could take over maintainership in the future!) +* Thank you to [Natsuki](https://ntk.me) for the [sass-embedded](https://github.com/sass-contrib/sass-embedded-host-ruby) gem. * Credit to [Ryan Boland](https://ryanboland.com) and the authors of the original [sass/sassc-rails](https://github.com/sass/sassc-rails) and [sass-rails](https://github.com/rails/sass-rails) gems. -* See our [awesome contributors](https://github.com/tablecheck/sassc-ruby/graphs/contributors). +* See our [awesome contributors](https://github.com/tablecheck/dartsass-sprockets/graphs/contributors). ### Contributing diff --git a/Rakefile b/Rakefile index bb58a69..52ab318 100644 --- a/Rakefile +++ b/Rakefile @@ -1,20 +1,15 @@ -require "bundler/gem_tasks" +# frozen_string_literal: true + +require 'bundler/gem_tasks' task :test do $LOAD_PATH.unshift('lib', 'test') - Dir.glob('./test/**/*_test.rb') { |f| require f } + Dir.glob('./test/**/*_test.rb').each { |f| require f } end -task :default => [:test] +task default: [:test] namespace :tests do - gemfiles = %w[ - sprockets-rails_3_0 - sprockets-rails_2_3 - sprockets_3_0 - sprockets_4_0 - rails_4_2 - rails_5_2 - ] + gemfiles = Dir['gemfiles/*.gemfile'].map { |f| File.basename(f, '.gemfile') }.freeze gemfiles.each do |gemfile| desc "Run tests against #{gemfile}" @@ -24,7 +19,7 @@ namespace :tests do end end - desc "Run tests against all common asset pipeline setups" + desc 'Run tests against all common asset pipeline setups' task :all do gemfiles.each do |gemfile| Rake::Task["tests:#{gemfile}"].invoke diff --git a/dartsass-sprockets.gemspec b/dartsass-sprockets.gemspec index 89aa582..1cf1ee6 100644 --- a/dartsass-sprockets.gemspec +++ b/dartsass-sprockets.gemspec @@ -1,30 +1,26 @@ -# coding: utf-8 -lib = File.expand_path('../lib', __FILE__) +# frozen_string_literal: true + +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'sassc/rails/version' Gem::Specification.new do |spec| - spec.name = "dartsass-sprockets" - spec.version = SassC::Rails::VERSION - spec.authors = ["Ryan Boland", "Johnny Shields"] - spec.email = ["ryan@tanookilabs.com"] - spec.summary = 'Use Dart Sass with Sprockets and the Ruby on Rails asset pipeline.' - spec.description = 'Use Dart Sass with Sprockets and the Ruby on Rails asset pipeline.' - spec.homepage = "https://github.com/tablecheck/dartsass-sprockets" - spec.license = "MIT" + spec.name = 'dartsass-sprockets' + spec.version = SassC::Rails::VERSION + spec.authors = ['Ryan Boland', 'Johnny Shields'] + spec.email = ['ryan@tanookilabs.com'] + spec.summary = 'Use Dart Sass with Sprockets and the Ruby on Rails asset pipeline.' + spec.description = 'Use Dart Sass with Sprockets and the Ruby on Rails asset pipeline.' + spec.homepage = 'https://github.com/tablecheck/dartsass-sprockets' + spec.license = 'MIT' spec.files = Dir['lib/**/*.rb'] + %w[LICENSE.txt README.md] - spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) - spec.required_ruby_version = '>= 3.1.0' - - spec.add_development_dependency 'pry' - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake" - spec.add_development_dependency 'mocha' + spec.required_ruby_version = '>= 3.1' - spec.add_dependency 'sassc-embedded', '~> 1.69' - spec.add_dependency "tilt" spec.add_dependency 'railties', '>= 4.0.0' + spec.add_dependency 'sassc-embedded', '~> 1.69' spec.add_dependency 'sprockets', '> 3.0' spec.add_dependency 'sprockets-rails' + spec.add_dependency 'tilt' + spec.metadata['rubygems_mfa_required'] = 'true' end diff --git a/gemfiles/rails_4_2.gemfile b/gemfiles/rails_4_2.gemfile deleted file mode 100644 index c27b143..0000000 --- a/gemfiles/rails_4_2.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "rails", "~> 4.2.0" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/rails_5_2.gemfile b/gemfiles/rails_5_2.gemfile deleted file mode 100644 index 3682fc7..0000000 --- a/gemfiles/rails_5_2.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "rails", "~> 5.2.1" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/rails_6_0.gemfile b/gemfiles/rails_6_0.gemfile deleted file mode 100644 index 8f7e3da..0000000 --- a/gemfiles/rails_6_0.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "rails", "~> 6.0.a" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/rails_6_1.gemfile b/gemfiles/rails_6_1.gemfile new file mode 100644 index 0000000..8701e52 --- /dev/null +++ b/gemfiles/rails_6_1.gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +eval_gemfile('../Gemfile') + +gem 'rails', '~> 6.1.0' diff --git a/gemfiles/rails_7_0.gemfile b/gemfiles/rails_7_0.gemfile new file mode 100644 index 0000000..a42c27c --- /dev/null +++ b/gemfiles/rails_7_0.gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +eval_gemfile('../Gemfile') + +gem 'rails', '~> 7.0.0' diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile new file mode 100644 index 0000000..243c651 --- /dev/null +++ b/gemfiles/rails_7_1.gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +eval_gemfile('../Gemfile') + +gem 'rails', '~> 7.1.0' diff --git a/gemfiles/sprockets-rails_2_3.gemfile b/gemfiles/sprockets-rails_2_3.gemfile deleted file mode 100644 index e378718..0000000 --- a/gemfiles/sprockets-rails_2_3.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "sprockets-rails", "~> 2.3.3" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/sprockets-rails_3_0.gemfile b/gemfiles/sprockets-rails_3_0.gemfile deleted file mode 100644 index 3426de8..0000000 --- a/gemfiles/sprockets-rails_3_0.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "sprockets-rails", "~> 3.2" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/sprockets_3_0.gemfile b/gemfiles/sprockets_3_0.gemfile deleted file mode 100644 index 98bf2fd..0000000 --- a/gemfiles/sprockets_3_0.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "sprockets", "~> 3.7" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/gemfiles/sprockets_4_0.gemfile b/gemfiles/sprockets_4_0.gemfile deleted file mode 100644 index bf7d65c..0000000 --- a/gemfiles/sprockets_4_0.gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem "sprockets", "~> 4.0.x" - -# Specify your gem's dependencies in sassc-rails.gemspec -gemspec path: "../" diff --git a/lib/dartsass-sprockets.rb b/lib/dartsass-sprockets.rb index d28f25b..e97d56a 100644 --- a/lib/dartsass-sprockets.rb +++ b/lib/dartsass-sprockets.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -require_relative "sassc/rails" +require_relative 'sassc/rails' diff --git a/lib/rails/generators/sass/assets/assets_generator.rb b/lib/rails/generators/sass/assets/assets_generator.rb index fd792dc..7ad7522 100644 --- a/lib/rails/generators/sass/assets/assets_generator.rb +++ b/lib/rails/generators/sass/assets/assets_generator.rb @@ -1,12 +1,14 @@ -require "rails/generators/named_base" +# frozen_string_literal: true + +require 'rails/generators/named_base' module Sass module Generators class AssetsGenerator < ::Rails::Generators::NamedBase - source_root File.expand_path("../templates", __FILE__) + source_root File.expand_path('templates', __dir__) def copy_sass - template "stylesheet.sass", File.join('app/assets/stylesheets', class_path, "#{file_name}.sass") + template 'stylesheet.sass', File.join('app/assets/stylesheets', class_path, "#{file_name}.sass") end end end diff --git a/lib/rails/generators/sass/scaffold/scaffold_generator.rb b/lib/rails/generators/sass/scaffold/scaffold_generator.rb index 99cbbe6..a0540bb 100644 --- a/lib/rails/generators/sass/scaffold/scaffold_generator.rb +++ b/lib/rails/generators/sass/scaffold/scaffold_generator.rb @@ -1,9 +1,13 @@ -require "rails/generators/sass_scaffold" +# frozen_string_literal: true + +require 'rails/generators/sass_scaffold' module Sass module Generators class ScaffoldGenerator < ::Sass::Generators::ScaffoldBase - def syntax() :sass end + def syntax + :sass + end end end end diff --git a/lib/rails/generators/sass_scaffold.rb b/lib/rails/generators/sass_scaffold.rb index bdfd435..dd51d37 100644 --- a/lib/rails/generators/sass_scaffold.rb +++ b/lib/rails/generators/sass_scaffold.rb @@ -1,12 +1,14 @@ -require "sassc/engine" -require "rails/generators/named_base" +# frozen_string_literal: true + +require 'sassc/engine' +require 'rails/generators/named_base' module Sass module Generators class ScaffoldBase < ::Rails::Generators::NamedBase def copy_stylesheet dir = ::Rails::Generators::ScaffoldGenerator.source_root - file = File.join(dir, "scaffold.css") + file = File.join(dir, 'scaffold.css') converted_contents = ::SassC::Engine.new(File.read(file)).render create_file "app/assets/stylesheets/scaffolds.#{syntax}", converted_contents end diff --git a/lib/rails/generators/scss/assets/assets_generator.rb b/lib/rails/generators/scss/assets/assets_generator.rb index 403f1eb..c7379b7 100644 --- a/lib/rails/generators/scss/assets/assets_generator.rb +++ b/lib/rails/generators/scss/assets/assets_generator.rb @@ -1,12 +1,14 @@ -require "rails/generators/named_base" +# frozen_string_literal: true + +require 'rails/generators/named_base' module Scss module Generators class AssetsGenerator < ::Rails::Generators::NamedBase - source_root File.expand_path("../templates", __FILE__) + source_root File.expand_path('templates', __dir__) def copy_scss - template "stylesheet.scss", File.join('app/assets/stylesheets', class_path, "#{file_name}.scss") + template 'stylesheet.scss', File.join('app/assets/stylesheets', class_path, "#{file_name}.scss") end end end diff --git a/lib/rails/generators/scss/scaffold/scaffold_generator.rb b/lib/rails/generators/scss/scaffold/scaffold_generator.rb index 1f9ac4e..c023d60 100644 --- a/lib/rails/generators/scss/scaffold/scaffold_generator.rb +++ b/lib/rails/generators/scss/scaffold/scaffold_generator.rb @@ -1,10 +1,13 @@ -require "rails/generators/sass_scaffold" +# frozen_string_literal: true + +require 'rails/generators/sass_scaffold' module Scss module Generators class ScaffoldGenerator < ::Sass::Generators::ScaffoldBase - def syntax() :scss end + def syntax + :scss + end end end end - diff --git a/lib/sassc/rails.rb b/lib/sassc/rails.rb index 24f8b9e..94723db 100644 --- a/lib/sassc/rails.rb +++ b/lib/sassc/rails.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -require_relative "rails/version" +require_relative 'rails/version' -require "sassc-embedded" -require_relative "rails/functions" -require_relative "rails/importer" -require_relative "rails/template" -require_relative "rails/compressor" -require_relative "rails/railtie" +require 'sassc-embedded' +require_relative 'rails/functions' +require_relative 'rails/importer' +require_relative 'rails/template' +require_relative 'rails/compressor' +require_relative 'rails/railtie' diff --git a/lib/sassc/rails/compressor.rb b/lib/sassc/rails/compressor.rb index a8e32fd..0d5a195 100644 --- a/lib/sassc/rails/compressor.rb +++ b/lib/sassc/rails/compressor.rb @@ -3,32 +3,29 @@ require 'sprockets/sass_compressor' require 'securerandom' -class Sprockets::SassCompressor - def initialize(options = {}) - @options = { - syntax: :scss, - cache: false, - read_cache: false, - style: :compressed - }.merge(options).freeze - @cache_key = SecureRandom.uuid - end +module Sprockets + class SassCompressor + def initialize(options = {}) + @options = { + syntax: :scss, + cache: false, + read_cache: false, + style: :compressed + }.merge(options).freeze + @cache_key = SecureRandom.uuid + end - def call(*args) - input = if defined?(data) - data # sprockets 2.x - else - args[0][:data] #sprockets 3.x + def call(*args) + input = if defined?(data) + data # sprockets 2.x + else + args[0][:data] # sprockets 3.x + end + + SassC::Engine.new(input, { style: :compressed }).render end - SassC::Engine.new( - input, - { - style: :compressed - } - ).render + # sprockets 2.x + alias evaluate call end - - # sprockets 2.x - alias :evaluate :call end diff --git a/lib/sassc/rails/functions.rb b/lib/sassc/rails/functions.rb index fbb84dc..0d22949 100644 --- a/lib/sassc/rails/functions.rb +++ b/lib/sassc/rails/functions.rb @@ -5,9 +5,9 @@ module Sprockets module SassFunctions def asset_data_url(path) - ::SassC::Script::Value::String.new("url(" + sprockets_context.asset_data_uri(path.value) + ")") + ::SassC::Script::Value::String.new("url(#{sprockets_context.asset_data_uri(path.value)})") end end end -::SassC::Script::Functions.send :include, Sprockets::SassFunctions +SassC::Script::Functions.include Sprockets::SassFunctions diff --git a/lib/sassc/rails/importer.rb b/lib/sassc/rails/importer.rb index a44c81b..a21a78c 100644 --- a/lib/sassc/rails/importer.rb +++ b/lib/sassc/rails/importer.rb @@ -8,44 +8,44 @@ class Importer < SassC::Importer class Extension attr_reader :postfix - def initialize(postfix=nil) + def initialize(postfix = nil) @postfix = postfix end - def import_for(full_path, parent_dir, options) + def import_for(full_path, _parent_dir, _options) SassC::Importer::Import.new(full_path) end end class CSSExtension def postfix - ".css" + '.css' end - def import_for(full_path, parent_dir, options) - import_path = full_path.gsub(/\.css$/,"") + def import_for(full_path, _parent_dir, _options) + import_path = full_path.gsub(/\.css$/, '') SassC::Importer::Import.new(import_path) end end class CssScssExtension < Extension def postfix - ".css.scss" + '.css.scss' end - def import_for(full_path, parent_dir, options) - source = File.open(full_path, 'rb') { |f| f.read } + def import_for(full_path, _parent_dir, _options) + source = File.binread(full_path) SassC::Importer::Import.new(full_path, source: source) end end class CssSassExtension < Extension def postfix - ".css.sass" + '.css.sass' end - def import_for(full_path, parent_dir, options) - sass = File.open(full_path, 'rb') { |f| f.read } + def import_for(full_path, _parent_dir, _options) + sass = File.binread(full_path) parsed_scss = SassC::Sass2Scss.convert(sass) SassC::Importer::Import.new(full_path, source: parsed_scss) end @@ -53,10 +53,10 @@ def import_for(full_path, parent_dir, options) class SassERBExtension < Extension def postfix - ".sass.erb" + '.sass.erb' end - def import_for(full_path, parent_dir, options) + def import_for(full_path, _parent_dir, options) template = Tilt::ERBTemplate.new(full_path) parsed_erb = template.render(options[:sprockets][:context], {}) parsed_scss = SassC::Sass2Scss.convert(parsed_erb) @@ -65,7 +65,7 @@ def import_for(full_path, parent_dir, options) end class ERBExtension < Extension - def import_for(full_path, parent_dir, options) + def import_for(full_path, _parent_dir, options) template = Tilt::ERBTemplate.new(full_path) parsed_erb = template.render(options[:sprockets][:context], {}) SassC::Importer::Import.new(full_path, source: parsed_erb) @@ -76,29 +76,29 @@ def import_for(full_path, parent_dir, options) CssScssExtension.new, CssSassExtension.new, SassERBExtension.new, - ERBExtension.new(".scss.erb"), - ERBExtension.new(".css.erb"), - Extension.new(".scss"), - Extension.new(".sass"), + ERBExtension.new('.scss.erb'), + ERBExtension.new('.css.erb'), + Extension.new('.scss'), + Extension.new('.sass'), CSSExtension.new ].freeze - PREFIXS = [ "", "_" ] - GLOB = /(\A|\/)(\*|\*\*\/\*)\z/ + PREFIXS = ['', '_'].freeze + GLOB = %r{(\A|/)(\*|\*\*/\*)\z} def imports(path, parent_path) - parent_dir, _ = File.split(parent_path) + parent_dir, = File.split(parent_path) specified_dir, specified_file = File.split(path) - if m = path.match(GLOB) - path = path.sub(m[0], "") + if (m = path.match(GLOB)) + path = path.sub(m[0], '') base = File.expand_path(path, File.dirname(parent_path)) return glob_imports(base, m[2], parent_path) end search_paths = ([parent_dir] + load_paths).uniq - if specified_dir != "." + if specified_dir != '.' search_paths.map! do |path| File.join(path, specified_dir) end @@ -157,15 +157,15 @@ def glob_imports(base, glob, current_file) def globbed_files(base, glob) # TODO: Raise an error from SassC here - raise ArgumentError unless glob == "*" || glob == "**/*" + raise ArgumentError unless ['*', '**/*'].include?(glob) extensions = EXTENSIONS.map(&:postfix) - exts = extensions.map { |ext| Regexp.escape("#{ext}") }.join("|") + exts = extensions.map { |ext| Regexp.escape(ext.to_s) }.join('|') sass_re = Regexp.compile("(#{exts})$") record_import_as_dependency(base) - files = Dir["#{base}/#{glob}"].sort.map do |path| + files = Dir["#{base}/#{glob}"].map do |path| if File.directory?(path) record_import_as_dependency(path) nil diff --git a/lib/sassc/rails/railtie.rb b/lib/sassc/rails/railtie.rb index 407635c..a366743 100644 --- a/lib/sassc/rails/railtie.rb +++ b/lib/sassc/rails/railtie.rb @@ -3,78 +3,81 @@ require 'active_support/core_ext/class/attribute' require 'sprockets/railtie' -module SassC::Rails - class Railtie < ::Rails::Railtie - config.sass = ActiveSupport::OrderedOptions.new +module SassC + module Rails + class Railtie < ::Rails::Railtie + config.sass = ActiveSupport::OrderedOptions.new - # Establish static configuration defaults - # Emit scss files during stylesheet generation of scaffold - config.sass.preferred_syntax = :scss - # Initialize the load paths to an empty array - config.sass.load_paths = [] + # Establish static configuration defaults + # Emit scss files during stylesheet generation of scaffold + config.sass.preferred_syntax = :scss - # Display line comments above each selector as a debugging aid - config.sass.line_comments = true + # Initialize the load paths to an empty array + config.sass.load_paths = [] - # Set the default stylesheet engine - # It can be overridden by passing: - # --stylesheet_engine=sass - # to the rails generate command - config.app_generators.stylesheet_engine config.sass.preferred_syntax + # Display line comments above each selector as a debugging aid + config.sass.line_comments = true - if config.respond_to?(:annotations) - config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } - end + # Set the default stylesheet engine + # It can be overridden by passing: + # --stylesheet_engine=sass + # to the rails generate command + config.app_generators.stylesheet_engine config.sass.preferred_syntax - # Remove the sass middleware if it gets inadvertently enabled by applications. - config.after_initialize do |app| - app.config.middleware.delete(Sass::Plugin::Rack) if defined?(Sass::Plugin::Rack) - end + if config.respond_to?(:annotations) + config.annotations.register_extensions('scss', 'sass') { |annotation| %r{//\s*(#{annotation}):?\s*(.*)$} } + end - initializer :setup_sass, group: :all do |app| - # Only emit one kind of syntax because though we have registered two kinds of generators - syntax = app.config.sass.preferred_syntax.to_sym - alt_syntax = syntax == :sass ? "scss" : "sass" - app.config.generators.hide_namespace alt_syntax + # Remove the sass middleware if it gets inadvertently enabled by applications. + config.after_initialize do |app| + app.config.middleware.delete(Sass::Plugin::Rack) if defined?(Sass::Plugin::Rack) + end - # Override stylesheet engine to the preferred syntax - config.app_generators.stylesheet_engine syntax + initializer :setup_sass, group: :all do |app| + # Only emit one kind of syntax because though we have registered two kinds of generators + syntax = app.config.sass.preferred_syntax.to_sym + alt_syntax = syntax == :sass ? 'scss' : 'sass' + app.config.generators.hide_namespace alt_syntax - # Establish configuration defaults that are environmental in nature - # if config.sass.full_exception.nil? - # # Display a stack trace in the css output when in development-like environments. - # config.sass.full_exception = app.config.consider_all_requests_local - # end + # Override stylesheet engine to the preferred syntax + config.app_generators.stylesheet_engine syntax - app.config.assets.configure do |env| - env.context_class.class_eval do - class_attribute :sass_config - self.sass_config = app.config.sass - end + # Establish configuration defaults that are environmental in nature + # if config.sass.full_exception.nil? + # # Display a stack trace in the css output when in development-like environments. + # config.sass.full_exception = app.config.consider_all_requests_local + # end - if env.respond_to?(:register_transformer) - env.register_transformer 'text/sass', 'text/css', SassC::Rails::SassTemplate.new - env.register_transformer 'text/scss', 'text/css', SassC::Rails::ScssTemplate.new - end + app.config.assets.configure do |env| + env.context_class.class_eval do + class_attribute :sass_config + self.sass_config = app.config.sass + end + + if env.respond_to?(:register_transformer) + env.register_transformer 'text/sass', 'text/css', SassC::Rails::SassTemplate.new + env.register_transformer 'text/scss', 'text/css', SassC::Rails::ScssTemplate.new + end - if env.respond_to?(:register_engine) - [ - ['.sass', SassC::Rails::SassTemplate], - ['.scss', SassC::Rails::ScssTemplate] - ].each do |engine| - engine << { silence_deprecation: true } if Sprockets::VERSION.start_with?("3") - env.register_engine(*engine) + if env.respond_to?(:register_engine) + [ + ['.sass', SassC::Rails::SassTemplate], + ['.scss', SassC::Rails::ScssTemplate] + ].each do |engine| + engine << { silence_deprecation: true } if Sprockets::VERSION.start_with?('3') + env.register_engine(*engine) + end end end end - end - initializer :setup_compression, group: :all do |app| - if !Rails.env.development? - app.config.assets.css_compressor = :sass unless app.config.assets.has_key?(:css_compressor) - else - # Use expanded output instead of the sass default of :nested unless specified - app.config.sass.style ||= :expanded + initializer :setup_compression, group: :all do |app| + if ::Rails.env.development? + # Use expanded output instead of the sass default of :nested unless specified + app.config.sass.style ||= :expanded + else + app.config.assets.css_compressor = :sass unless app.config.assets.key?(:css_compressor) + end end end end diff --git a/lib/sassc/rails/template.rb b/lib/sassc/rails/template.rb index 3a5d92f..a0acc13 100644 --- a/lib/sassc/rails/template.rb +++ b/lib/sassc/rails/template.rb @@ -1,113 +1,112 @@ # frozen_string_literal: true -require "sprockets/version" +require 'sprockets/version' require 'sprockets/sass_processor' -require "sprockets/utils" - -module SassC::Rails - class SassTemplate < Sprockets::SassProcessor - def initialize(options = {}, &block) - @cache_version = options[:cache_version] - @cache_key = "#{self.class.name}:#{VERSION}:#{SassC::VERSION}:#{@cache_version}".freeze - #@importer_class = options[:importer] || Sass::Importers::Filesystem - @sass_config = options[:sass_config] || {} - @functions = Module.new do - include Functions - include options[:functions] if options[:functions] - class_eval(&block) if block_given? +require 'sprockets/utils' + +module SassC + module Rails + class SassTemplate < Sprockets::SassProcessor + def initialize(options = {}, &block) # rubocop:disable Lint/MissingSuper + @cache_version = options[:cache_version] + @cache_key = "#{self.class.name}:#{VERSION}:#{SassC::VERSION}:#{@cache_version}" + # @importer_class = options[:importer] || Sass::Importers::Filesystem + @sass_config = options[:sass_config] || {} + @functions = Module.new do + include Functions + include options[:functions] if options[:functions] + class_eval(&block) if block_given? + end end - end - def call(input) - context = input[:environment].context_class.new(input) - - options = { - filename: input[:filename], - line_comments: line_comments?, - syntax: self.class.syntax, - load_paths: input[:environment].paths, - importer: SassC::Rails::Importer, - sprockets: { - context: context, - environment: input[:environment], - dependencies: context.metadata[:dependency_paths] - } - }.merge!(config_options) { |key, left, right| safe_merge(key, left, right) } - - engine = ::SassC::Engine.new(input[:data], options) - - css = Sprockets::Utils.module_include(::SassC::Script::Functions, @functions) do - engine.render + def call(input) + context = input[:environment].context_class.new(input) + + options = { + filename: input[:filename], + line_comments: line_comments?, + syntax: self.class.syntax, + load_paths: input[:environment].paths, + importer: SassC::Rails::Importer, + sprockets: { + context: context, + environment: input[:environment], + dependencies: context.metadata[:dependency_paths] + } + }.merge!(config_options) { |key, left, right| safe_merge(key, left, right) } + + engine = ::SassC::Engine.new(input[:data], options) + + css = Sprockets::Utils.module_include(::SassC::Script::Functions, @functions) do + engine.render + end + + context.metadata.merge(data: css) end - context.metadata.merge(data: css) - end - - def config_options - opts = { style: sass_style, load_paths: load_paths } + def config_options + opts = { style: sass_style, load_paths: load_paths } + if ::Rails.application.config.sass.inline_source_maps + opts.merge!(source_map_file: '.', + source_map_embed: true, + source_map_contents: true) + end - if Rails.application.config.sass.inline_source_maps - opts.merge!({ - source_map_file: ".", - source_map_embed: true, - source_map_contents: true, - }) + opts end - opts - end - - def sass_style - (Rails.application.config.sass.style || :expanded).to_sym - end + def sass_style + (::Rails.application.config.sass.style || :expanded).to_sym + end - def load_paths - Rails.application.config.sass.load_paths || [] - end + def load_paths + ::Rails.application.config.sass.load_paths || [] + end - def line_comments? - Rails.application.config.sass.line_comments - end + def line_comments? + ::Rails.application.config.sass.line_comments + end - def safe_merge(_key, left, right) - if [left, right].all? { |v| v.is_a? Hash } - left.merge(right) { |k, l, r| safe_merge(k, l, r) } - elsif [left, right].all? { |v| v.is_a? Array } - (left + right).uniq - else - right + def safe_merge(_key, left, right) + if [left, right].all? { |v| v.is_a? Hash } + left.merge(right) { |k, l, r| safe_merge(k, l, r) } + elsif [left, right].all? { |v| v.is_a? Array } + (left + right).uniq + else + right + end end - end - # The methods in the Functions module were copied here from sprockets in order to - # override the Value class names (e.g. ::SassC::Script::Value::String) - module Functions - def asset_path(path, options = {}) - path = path.value + # The methods in the Functions module were copied here from sprockets in order to + # override the Value class names (e.g. ::SassC::Script::Value::String) + module Functions + def asset_path(path, options = {}) + path = path.value - path, _, query, fragment = URI.split(path)[5..8] - path = sprockets_context.asset_path(path, options) - query = "?#{query}" if query - fragment = "##{fragment}" if fragment + path, _, query, fragment = URI.split(path)[5..8] + path = sprockets_context.asset_path(path, options) + query = "?#{query}" if query + fragment = "##{fragment}" if fragment - ::SassC::Script::Value::String.new("#{path}#{query}#{fragment}", :string) - end + ::SassC::Script::Value::String.new("#{path}#{query}#{fragment}", :string) + end - def asset_url(path, options = {}) - ::SassC::Script::Value::String.new("url(#{asset_path(path, options).value})") - end + def asset_url(path, options = {}) + ::SassC::Script::Value::String.new("url(#{asset_path(path, options).value})") + end - def asset_data_url(path) - url = sprockets_context.asset_data_uri(path.value) - ::SassC::Script::Value::String.new("url(" + url + ")") + def asset_data_url(path) + url = sprockets_context.asset_data_uri(path.value) + ::SassC::Script::Value::String.new("url(#{url})") + end end end - end - class ScssTemplate < SassTemplate - def self.syntax - :scss + class ScssTemplate < SassTemplate + def self.syntax + :scss + end end end end diff --git a/lib/sassc/rails/version.rb b/lib/sassc/rails/version.rb index b425146..43b1c90 100644 --- a/lib/sassc/rails/version.rb +++ b/lib/sassc/rails/version.rb @@ -2,6 +2,6 @@ module SassC module Rails - VERSION = "3.0.0" + VERSION = '3.1.0' end end diff --git a/test/sassc_rails_test.rb b/test/sassc_rails_test.rb index 69cfe74..800fef7 100644 --- a/test/sassc_rails_test.rb +++ b/test/sassc_rails_test.rb @@ -1,32 +1,35 @@ # frozen_string_literal: true -require_relative "test_helper" +require_relative 'test_helper' -class SassRailsTest < MiniTest::Test +class SassRailsTest < Minitest::Test attr_reader :app def setup - Rails.application = nil - - @app = Class.new(Rails::Application) + @app = Class.new(Rails::Application).new @app.config.active_support.deprecation = :log @app.config.eager_load = false - @app.config.root = File.join(File.dirname(__FILE__), "dummy") + @app.config.root = File.join(File.dirname(__FILE__), 'dummy') @app.config.log_level = :debug # reset config back to default @app.config.assets.delete(:css_compressor) @app.config.sass = ActiveSupport::OrderedOptions.new @app.config.sass.preferred_syntax = :scss - @app.config.sass.load_paths = [] + @app.config.sass.load_paths = [] # Not actually a default, but it makes assertions more complicated - @app.config.sass.line_comments = false + @app.config.sass.line_comments = false # Add a fake compressor for testing purposes - Sprockets.register_compressor "text/css", :test, TestCompressor + Sprockets.register_compressor 'text/css', :test, TestCompressor + + # Necessary for tests on Rails 7 + ActiveSupport::Dependencies.autoload_paths = [] + ActiveSupport::Dependencies.autoload_once_paths = [] - Rails.backtrace_cleaner.remove_silencers! + ::Rails.application = @app + ::Rails.backtrace_cleaner.remove_silencers! end def teardown @@ -39,29 +42,29 @@ def render_asset(asset) end def initialize! - Rails.env = "test" + Rails.env = 'test' @app.initialize! end def initialize_dev! - Rails.env = "development" + Rails.env = 'development' @app.initialize! end def initialize_prod! - Rails.env = "production" + Rails.env = 'production' @app.initialize! end def test_setup_works initialize_dev! - asset = render_asset("application.css") + asset = render_asset('application.css') - assert_equal <<-CSS, asset -.hello { - color: #FFF; -} + assert_equal <<~CSS, asset + .hello { + color: #FFF; + } CSS end @@ -69,51 +72,58 @@ def test_raises_sassc_syntax_error initialize! assert_raises(SassC::SyntaxError) do - render_asset("syntax_error.css") + render_asset('syntax_error.css') end end def test_all_sass_asset_paths_work - skip - initialize! - css_output = render_asset("helpers_test.css") + css_output = render_asset('helpers_test.css') - assert_match %r{asset-path:\s*"/assets/rails.png"}, css_output, 'asset-path:\s*"/assets/rails.png"' - assert_match %r{asset-url:\s*url\(/assets/rails.png\)}, css_output, 'asset-url:\s*url\(/assets/rails.png\)' - assert_match %r{image-path:\s*"/assets/rails.png"}, css_output, 'image-path:\s*"/assets/rails.png"' - assert_match %r{image-url:\s*url\(/assets/rails.png\)}, css_output, 'image-url:\s*url\(/assets/rails.png\)' + assert_match %r{asset-path:\s*"/assets/rails-322506f9917889126e81df2833a6eecdf2e394658d53dad347e9882dd4dbf28e\.png"}, + css_output, 'asset-path:\s*"/assets/rails.png"' + assert_match %r{asset-url:\s*url\(/assets/rails-322506f9917889126e81df2833a6eecdf2e394658d53dad347e9882dd4dbf28e\.png\)}, + css_output, 'asset-url:\s*url\(/assets/rails.png\)' + assert_match %r{image-path:\s*"/assets/rails-322506f9917889126e81df2833a6eecdf2e394658d53dad347e9882dd4dbf28e\.png"}, + css_output, 'image-path:\s*"/assets/rails.png"' + assert_match %r{image-url:\s*url\(/assets/rails-322506f9917889126e81df2833a6eecdf2e394658d53dad347e9882dd4dbf28e\.png\)}, + css_output, 'image-url:\s*url\(/assets/rails.png\)' end def test_sass_asset_paths_work initialize! - css_output = render_asset("helpers_test.css") - - assert_match %r{video-path:\s*"/videos/rails.mp4"}, css_output, 'video-path:\s*"/videos/rails.mp4"' - assert_match %r{video-url:\s*url\(/videos/rails.mp4\)}, css_output, 'video-url:\s*url\(/videos/rails.mp4\)' - assert_match %r{audio-path:\s*"/audios/rails.mp3"}, css_output, 'audio-path:\s*"/audios/rails.mp3"' - assert_match %r{audio-url:\s*url\(/audios/rails.mp3\)}, css_output, 'audio-url:\s*url\(/audios/rails.mp3\)' - assert_match %r{font-path:\s*"/fonts/rails.ttf"}, css_output, 'font-path:\s*"/fonts/rails.ttf"' - assert_match %r{font-url:\s*url\(/fonts/rails.ttf\)}, css_output, 'font-url:\s*url\(/fonts/rails.ttf\)' - assert_match %r{font-url-with-query-hash:\s*url\(/fonts/rails.ttf\?#iefix\)}, css_output, 'font-url:\s*url\(/fonts/rails.ttf?#iefix\)' - assert_match %r{javascript-path:\s*"/javascripts/rails.js"}, css_output, 'javascript-path:\s*"/javascripts/rails.js"' - assert_match %r{javascript-url:\s*url\(/javascripts/rails.js\)}, css_output, 'javascript-url:\s*url\(/javascripts/rails.js\)' - assert_match %r{stylesheet-path:\s*"/stylesheets/rails.css"}, css_output, 'stylesheet-path:\s*"/stylesheets/rails.css"' - assert_match %r{stylesheet-url:\s*url\(/stylesheets/rails.css\)}, css_output, 'stylesheet-url:\s*url\(/stylesheets/rails.css\)' - - asset_data_url_regexp = %r{asset-data-url:\s*url\((.*?)\)} + css_output = render_asset('helpers_test.css') + + assert_match %r{video-path:\s*"/videos/rails.mp4"}, css_output, 'video-path:\s*"/videos/rails.mp4"' + assert_match %r{video-url:\s*url\(/videos/rails.mp4\)}, css_output, 'video-url:\s*url\(/videos/rails.mp4\)' + assert_match %r{audio-path:\s*"/audios/rails.mp3"}, css_output, 'audio-path:\s*"/audios/rails.mp3"' + assert_match %r{audio-url:\s*url\(/audios/rails.mp3\)}, css_output, 'audio-url:\s*url\(/audios/rails.mp3\)' + assert_match %r{font-path:\s*"/fonts/rails.ttf"}, css_output, 'font-path:\s*"/fonts/rails.ttf"' + assert_match %r{font-url:\s*url\(/fonts/rails.ttf\)}, css_output, 'font-url:\s*url\(/fonts/rails.ttf\)' + assert_match %r{font-url-with-query-hash:\s*url\(/fonts/rails.ttf\?#iefix\)}, css_output, + 'font-url:\s*url\(/fonts/rails.ttf?#iefix\)' + assert_match %r{javascript-path:\s*"/javascripts/rails.js"}, css_output, + 'javascript-path:\s*"/javascripts/rails.js"' + assert_match %r{javascript-url:\s*url\(/javascripts/rails.js\)}, css_output, + 'javascript-url:\s*url\(/javascripts/rails.js\)' + assert_match %r{stylesheet-path:\s*"/stylesheets/rails.css"}, css_output, + 'stylesheet-path:\s*"/stylesheets/rails.css"' + assert_match %r{stylesheet-url:\s*url\(/stylesheets/rails.css\)}, css_output, + 'stylesheet-url:\s*url\(/stylesheets/rails.css\)' + + asset_data_url_regexp = /asset-data-url:\s*url\((.*?)\)/ assert_match asset_data_url_regexp, css_output, 'asset-data-url:\s*url\((.*?)\)' asset_data_url_match = css_output.match(asset_data_url_regexp)[1] - asset_data_url_expected = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%" + - "2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjA" + - "xMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRw" + - "Oi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDc" + - "mVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCNzY5NDE1QkQ2NkMxMUUwOUUzM0E5Q0E2RTgyQUExQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCNzY5NDE1Q0" + - "Q2NkMxMUUwOUUzM0E5Q0E2RTgyQUExQiI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE3MzcyNTQ2RDY2QjExRTA5RTMzQTlDQTZFODJBQTFCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkI3Njk0M" + - "TVBRDY2QzExRTA5RTMzQTlDQTZFODJBQTFCIi8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2B0HhJ9AAAABBJREFUeNpi%2BP%2F%2FPwNAgAEACPwC%2FtuiTRYAAAAA" + - "SUVORK5CYII%3D" + asset_data_url_expected = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%' \ + '2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjA' \ + 'xMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRw' \ + 'Oi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDc' \ + 'mVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCNzY5NDE1QkQ2NkMxMUUwOUUzM0E5Q0E2RTgyQUExQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCNzY5NDE1Q0' \ + 'Q2NkMxMUUwOUUzM0E5Q0E2RTgyQUExQiI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE3MzcyNTQ2RDY2QjExRTA5RTMzQTlDQTZFODJBQTFCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkI3Njk0M' \ + 'TVBRDY2QzExRTA5RTMzQTlDQTZFODJBQTFCIi8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2B0HhJ9AAAABBJREFUeNpi%2BP%2F%2FPwNAgAEACPwC%2FtuiTRYAAAAA' \ + 'SUVORK5CYII%3D' assert_equal asset_data_url_expected, asset_data_url_match end @@ -121,35 +131,32 @@ def test_sass_imports_work_correctly app.config.sass.load_paths << Rails.root.join('app/assets/stylesheets/in_load_paths') initialize! - css_output = render_asset("imports_test.css") - assert_match /main/, css_output - assert_match /top-level/, css_output - assert_match /partial-sass/, css_output - assert_match /partial-scss/, css_output - assert_match /partial-foo/, css_output - assert_match /sub-folder-relative-sass/, css_output - assert_match /sub-folder-relative-scss/, css_output - assert_match /not-a-partial/, css_output - assert_match /plain-old-css/, css_output - assert_match /another-plain-old-css/, css_output - assert_match /without-css-ext/, css_output - assert_match /css-scss-handler/, css_output - assert_match /css-sass-handler/, css_output - assert_match /css-erb-handler/, css_output - assert_match /scss-erb-handler/, css_output - assert_match /sass-erb-handler/, css_output + css_output = render_asset('imports_test.css') + assert_match(/main/, css_output) + assert_match(/top-level/, css_output) + assert_match(/partial-sass/, css_output) + assert_match(/partial-scss/, css_output) + assert_match(/partial-foo/, css_output) + assert_match(/sub-folder-relative-sass/, css_output) + assert_match(/sub-folder-relative-scss/, css_output) + assert_match(/not-a-partial/, css_output) + assert_match(/plain-old-css/, css_output) + assert_match(/another-plain-old-css/, css_output) + assert_match(/without-css-ext/, css_output) + assert_match(/css-scss-handler/, css_output) + assert_match(/css-sass-handler/, css_output) + assert_match(/css-erb-handler/, css_output) + assert_match(/scss-erb-handler/, css_output) + assert_match(/sass-erb-handler/, css_output) # do these two actually test anything? # should the extension be changed? - assert_match /css-sass-erb-handler/, css_output - assert_match /css-scss-erb-handler/, css_output - - assert_match /default-old-css/, css_output - - assert_match /globbed/, css_output - assert_match /nested-glob/, css_output - - assert_match /partial_in_load_paths/, css_output + assert_match(/css-sass-erb-handler/, css_output) + assert_match(/css-scss-erb-handler/, css_output) + assert_match(/default-old-css/, css_output) + assert_match(/globbed/, css_output) + assert_match(/nested-glob/, css_output) + assert_match(/partial_in_load_paths/, css_output) end def test_style_config_item_is_defaulted_to_expanded_in_development_mode @@ -167,7 +174,7 @@ def test_line_comments_option_is_ignored @app.config.sass.line_comments = true initialize_dev! - css_output = render_asset("css_scss_handler.css") + css_output = render_asset('css_scss_handler.css') refute_match %r{/* line 1}, css_output refute_match %r{.+test/dummy/app/assets/stylesheets/css_scss_handler.css.scss}, css_output end @@ -175,13 +182,13 @@ def test_line_comments_option_is_ignored def test_context_is_being_passed_to_erb_render initialize! - css_output = render_asset("erb_render_with_context.css.erb") - assert_match /@font-face/, css_output + css_output = render_asset('erb_render_with_context.css.erb') + assert_match(/@font-face/, css_output) end def test_special_characters_compile initialize! - css_output = render_asset("special_characters.css") + render_asset('special_characters.css') end def test_css_compressor_config_item_is_honored_if_not_development_mode @@ -209,41 +216,32 @@ def test_css_compressor_is_defined_in_prod_mode def test_compression_works initialize_prod! - asset = render_asset("application.css") - assert_equal <<-CSS, asset -.hello{color:#FFF} - CSS - end - - def test_compression_works - initialize_prod! - - asset = render_asset("application.css") - assert_equal <<-CSS, asset -.hello{color:#fff} + asset = render_asset('application.css') + assert_equal <<~CSS, asset + .hello{color:#fff} CSS end def test_sassc_compression_is_used - engine = stub(render: "") + engine = stub(render: '') SassC::Engine.expects(:new).returns(engine) - SassC::Engine.expects(:new).with("", {style: :compressed}).returns(engine) + SassC::Engine.expects(:new).with('', { style: :compressed }).returns(engine) initialize_prod! - render_asset("application.css") + render_asset('application.css') end def test_allows_for_inclusion_of_inline_source_maps @app.config.sass.inline_source_maps = true initialize_dev! - asset = render_asset("application.css") - assert_match /.hello/, asset - assert_match /sourceMappingURL/, asset + asset = render_asset('application.css') + assert_match(/.hello/, asset) + assert_match(/sourceMappingURL/, asset) end - #test 'sprockets require works correctly' do + # test 'sprockets require works correctly' do # skip # within_rails_app('scss_project') do |app_root| @@ -261,28 +259,28 @@ def test_allows_for_inclusion_of_inline_source_maps # log_output = File.open(log_file).read # refute_match /Warning/, log_output # end - #end + # end - #test 'sprockets directives are ignored within an import' do + # test 'sprockets directives are ignored within an import' do # skip # css_output = sprockets_render('scss_project', 'import_css_application.css') # assert_match /\.css-application/, css_output # assert_match /\.import-css-application/, css_output - #end + # end def test_globbed_imports_work_with_multiple_extensions initialize! - asset = render_asset("glob_multiple_extensions_test.css") + asset = render_asset('glob_multiple_extensions_test.css') - assert_equal <<-CSS, asset -.glob{margin:0} + assert_equal <<~CSS, asset + .glob{margin:0} CSS end def test_globbed_imports_work_when_globbed_file_is_changed - skip "This seems to work in practice, possible test setup problem" + skip 'This seems to work in practice, possible test setup problem' begin initialize! @@ -293,15 +291,15 @@ def test_globbed_imports_work_when_globbed_file_is_changed file.puts '.new-file-test { color: #000; }' end - css_output = render_asset("glob_test.css") - assert_match /new-file-test/, css_output + css_output = render_asset('glob_test.css') + assert_match(/new-file-test/, css_output) File.open(new_file, 'w') do |file| file.puts '.changed-file-test { color: #000; }' end - new_css_output = render_asset("glob_test.css") - assert_match /changed-file-test/, new_css_output + new_css_output = render_asset('glob_test.css') + assert_match(/changed-file-test/, new_css_output) refute_equal css_output, new_css_output ensure File.delete(new_file) @@ -309,23 +307,21 @@ def test_globbed_imports_work_when_globbed_file_is_changed end def test_globbed_imports_work_when_globbed_file_is_added - begin - initialize! - - css_output = render_asset("glob_test.css") - refute_match /changed-file-test/, css_output - new_file = File.join(File.dirname(__FILE__), 'dummy', 'app', 'assets', 'stylesheets', 'globbed', 'new_glob.scss') + initialize! - File.open(new_file, 'w') do |file| - file.puts '.changed-file-test { color: #000; }' - end + css_output = render_asset('glob_test.css') + refute_match(/changed-file-test/, css_output) + new_file = File.join(File.dirname(__FILE__), 'dummy', 'app', 'assets', 'stylesheets', 'globbed', 'new_glob.scss') - new_css_output = render_asset("glob_test.css") - assert_match /changed-file-test/, new_css_output - refute_equal css_output, new_css_output - ensure - File.delete(new_file) + File.open(new_file, 'w') do |file| + file.puts '.changed-file-test { color: #000; }' end + + new_css_output = render_asset('glob_test.css') + assert_match(/changed-file-test/, new_css_output) + refute_equal css_output, new_css_output + ensure + File.delete(new_file) end class TestCompressor diff --git a/test/test_helper.rb b/test/test_helper.rb index 442e8ea..facd35d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,15 +1,14 @@ # frozen_string_literal: true -ENV["RAILS_ENV"] = "test" +ENV['RAILS_ENV'] = 'test' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'dartsass-sprockets' -require "pry" -require "fileutils" +require 'fileutils' require 'rails' require 'bundler/setup' -require "minitest/autorun" +require 'minitest/autorun' require 'mocha/minitest' Bundler.require