rf-web/vendor/bundle/gems/sassc-2.2.1/test/functions_test.rb
2019-10-21 10:18:17 +02:00

324 lines
9.2 KiB
Ruby

# frozen_string_literal: true
require_relative "test_helper"
require "stringio"
module SassC
class FunctionsTest < MiniTest::Test
include FixtureHelper
def setup
@real_stderr, $stderr = $stderr, StringIO.new
end
def teardown
$stderr = @real_stderr
end
def test_functions_may_return_sass_string_type
assert_sass <<-SCSS, <<-CSS
div { url: url(sass_return_path("foo.svg")); }
SCSS
div { url: url("foo.svg"); }
CSS
end
def test_functions_work_with_varying_quotes_and_string_types
assert_sass <<-SCSS, <<-CSS
div {
url: url(asset-path("foo.svg"));
url: url(image-path("foo.png"));
url: url(video-path("foo.mov"));
url: url(audio-path("foo.mp3"));
url: url(font-path("foo.woff"));
url: url(javascript-path('foo.js'));
url: url(javascript-path("foo.js"));
url: url(stylesheet-path("foo.css"));
}
SCSS
div {
url: url(asset-path("foo.svg"));
url: url(image-path("foo.png"));
url: url(video-path("foo.mov"));
url: url(audio-path("foo.mp3"));
url: url(font-path("foo.woff"));
url: url("/js/foo.js");
url: url("/js/foo.js");
url: url(/css/foo.css);
}
CSS
end
def test_function_with_no_return_value
assert_sass <<-SCSS, <<-CSS
div {url: url(no-return-path('foo.svg'));}
SCSS
div { url: url(); }
CSS
end
def test_function_that_returns_a_color
assert_sass <<-SCSS, <<-CSS
div { background: returns-a-color(); }
SCSS
div { background: black; }
CSS
end
def test_function_that_returns_a_number
assert_sass <<-SCSS, <<-CSS
div { width: returns-a-number(); }
SCSS
div { width: -312rem; }
CSS
end
def test_function_that_takes_a_number
assert_sass <<-SCSS, <<-CSS
div { display: inspect-number(42.1px); }
SCSS
div { display: 42.1px; }
CSS
end
def test_function_that_returns_a_bool
assert_sass <<-SCSS, <<-CSS
div { width: returns-a-bool(); }
SCSS
div { width: true; }
CSS
end
def test_function_that_takes_a_bool
assert_sass <<-SCSS, <<-CSS
div { display: inspect-bool(true)}
SCSS
div { display: true; }
CSS
end
def test_function_with_optional_arguments
assert_sass <<-SCSS, <<-EXPECTED_CSS
div {
url: optional_arguments('first');
url: optional_arguments('second', 'qux');
}
SCSS
div {
url: "first/bar";
url: "second/qux";
}
EXPECTED_CSS
end
def test_functions_may_accept_sass_color_type
assert_sass <<-SCSS, <<-EXPECTED_CSS
div { color: nice_color_argument(red); }
SCSS
div { color: rgb(255, 0, 0); }
EXPECTED_CSS
end
def test_function_with_unsupported_tag
skip('What are other unsupported tags?')
engine = Engine.new("div {url: function_with_unsupported_tag(());}")
exception = assert_raises(SassC::SyntaxError) do
engine.render
end
assert_match /Sass argument of type sass_list unsupported/, exception.message
assert_equal "[SassC::FunctionsHandler] Sass argument of type sass_list unsupported", stderr_output
end
def test_function_with_error
engine = Engine.new("div {url: function_that_raises_errors();}")
exception = assert_raises(SassC::SyntaxError) do
engine.render
end
assert_match /Error: error in C function function_that_raises_errors/, exception.message
assert_match /Intentional wrong thing happened somewhere inside the custom function/, exception.message
assert_equal "[SassC::FunctionsHandler] Intentional wrong thing happened somewhere inside the custom function", stderr_output
end
def test_function_that_returns_a_sass_value
assert_sass <<-SCSS, <<-CSS
div { background: returns-sass-value(); }
SCSS
div { background: black; }
CSS
end
def test_function_that_returns_a_sass_map
assert_sass <<-SCSS, <<-CSS
$my-map: returns-sass-map();
div { background: map-get( $my-map, color ); }
SCSS
div { background: black; }
CSS
end
def test_function_that_takes_a_sass_map
assert_sass <<-SCSS, <<-CSS
div { background-color: map-get( inspect-map(( color: black, number: 1.23px, string: "abc", map: ( x: 'y' ))), color ); }
SCSS
div { background-color: black; }
CSS
end
def test_function_that_returns_a_sass_list
assert_sass <<-SCSS, <<-CSS
$my-list: returns-sass-list();
div { width: nth( $my-list, 2 ); }
SCSS
div { width: 20; }
CSS
end
def test_function_that_takes_a_sass_list
assert_sass <<-SCSS, <<-CSS
div { width: nth(inspect-list((10 20 30)), 2); }
SCSS
div { width: 20; }
CSS
end
def test_concurrency
10.times do
threads = []
10.times do |i|
threads << Thread.new(i) do |id|
out = Engine.new("div { url: inspect_options(); }", {test_key1: 'test_value', test_key2: id}).render
assert_match /test_key1/, out
assert_match /test_key2/, out
assert_match /test_value/, out
assert_match /#{id}/, out
end
end
threads.each(&:join)
end
end
private
def assert_sass(sass, expected_css)
engine = Engine.new(sass)
assert_equal expected_css.strip.gsub!(/\s+/, " "), # poor man's String#squish
engine.render.strip.gsub!(/\s+/, " ")
end
def stderr_output
$stderr.string.gsub("\u0000\n", '').chomp
end
module Script::Functions
def javascript_path(path)
SassC::Script::Value::String.new("/js/#{path.value}", :string)
end
def stylesheet_path(path)
SassC::Script::Value::String.new("/css/#{path.value}", :identifier)
end
def no_return_path(path)
nil
end
def sass_return_path(path)
SassC::Script::Value::String.new("#{path.value}", :string)
end
def optional_arguments(path, optional = nil)
optional ||= SassC::Script::Value::String.new("bar")
SassC::Script::Value::String.new("#{path.value}/#{optional.value}", :string)
end
def function_that_raises_errors
raise StandardError, "Intentional wrong thing happened somewhere inside the custom function"
end
def function_with_unsupported_tag(value)
end
def nice_color_argument(color)
return SassC::Script::Value::String.new(color.to_s, :identifier)
end
def returns_a_color
return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
end
def returns_a_number
return SassC::Script::Value::Number.new(-312,'rem')
end
def returns_a_bool
return SassC::Script::Value::Bool.new(true)
end
def inspect_bool ( argument )
raise StandardError.new "passed value is not a Sass::Script::Value::Bool" unless argument.is_a? SassC::Script::Value::Bool
return argument
end
def inspect_number ( argument )
raise StandardError.new "passed value is not a Sass::Script::Value::Number" unless argument.is_a? SassC::Script::Value::Number
return argument
end
def inspect_map ( argument )
argument.to_h.each_pair do |key, value|
raise StandardError.new "key #{key.inspect} is not a string" unless key.is_a? SassC::Script::Value::String
valueClass = case key.value
when 'string'
SassC::Script::Value::String
when 'number'
SassC::Script::Value::Number
when 'color'
SassC::Script::Value::Color
when 'map'
SassC::Script::Value::Map
end
raise StandardError.new "unknown key #{key.inspect}" unless valueClass
raise StandardError.new "value for #{key.inspect} is not a #{valueClass}" unless value.is_a? valueClass
end
return argument
end
def inspect_list(argument)
raise StandardError.new "passed value is not a Sass::Script::Value::List" unless argument.is_a? SassC::Script::Value::List
return argument
end
def inspect_options
SassC::Script::Value::String.new(self.options.inspect, :string)
end
def returns_sass_value
return SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
end
def returns_sass_map
key = SassC::Script::Value::String.new("color", "string")
value = SassC::Script::Value::Color.new(red: 0, green: 0, blue: 0)
values = {}
values[key] = value
map = SassC::Script::Value::Map.new values
return map
end
def returns_sass_list
numbers = [10, 20, 30].map { |n| SassC::Script::Value::Number.new(n, '') }
SassC::Script::Value::List.new(numbers, separator: :space)
end
end
end
end