Skip to content

Commit

Permalink
Merge pull request #162 from ahorek/custom_functions
Browse files Browse the repository at this point in the history
allow passing functions directly
  • Loading branch information
bolandrm authored Mar 3, 2020
2 parents 242ba4f + 5c6c7ae commit cf574f7
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 13 deletions.
3 changes: 2 additions & 1 deletion lib/sassc/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Engine
def initialize(template, options = {})
@template = template
@options = options
@functions = options.fetch(:functions, Script::Functions)
end

def render
Expand All @@ -37,7 +38,7 @@ def render
Native.option_set_omit_source_map_url(native_options, true) if omit_source_map_url?

import_handler.setup(native_options)
functions_handler.setup(native_options)
functions_handler.setup(native_options, functions: @functions)

status = Native.compile_data_context(data_context)

Expand Down
16 changes: 8 additions & 8 deletions lib/sassc/functions_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@ def initialize(options)
@options = options
end

def setup(native_options)
def setup(native_options, functions: Script::Functions)
@callbacks = {}
@function_names = {}

list = Native.make_function_list(Script.custom_functions.count)
list = Native.make_function_list(Script.custom_functions(functions: functions).count)

# use an anonymous class wrapper to avoid mutations in a threaded environment
functions = Class.new do
functions_wrapper = Class.new do
attr_accessor :options
include Script::Functions
include functions
end.new
functions.options = @options
functions_wrapper.options = @options

Script.custom_functions.each_with_index do |custom_function, i|
Script.custom_functions(functions: functions).each_with_index do |custom_function, i|
@callbacks[custom_function] = FFI::Function.new(:pointer, [:pointer, :pointer]) do |native_argument_list, cookie|
begin
function_arguments = arguments_from_native_list(native_argument_list)
result = functions.send(custom_function, *function_arguments)
result = functions_wrapper.send(custom_function, *function_arguments)
to_native_value(result)
rescue StandardError => exception
# This rescues any exceptions that occur either in value conversion
Expand All @@ -32,7 +32,7 @@ def setup(native_options)
end
end

@function_names[custom_function] = Script.formatted_function_name(custom_function)
@function_names[custom_function] = Script.formatted_function_name(custom_function, functions: functions)

callback = Native.make_function(
@function_names[custom_function],
Expand Down
8 changes: 4 additions & 4 deletions lib/sassc/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
module SassC
module Script

def self.custom_functions
Functions.public_instance_methods
def self.custom_functions(functions: Functions)
functions.public_instance_methods
end

def self.formatted_function_name(function_name)
params = Functions.instance_method(function_name).parameters
def self.formatted_function_name(function_name, functions: Functions)
params = functions.instance_method(function_name).parameters
params = params.map { |param_type, name| "$#{name}#{': null' if param_type == :opt}" }.join(", ")
return "#{function_name}(#{params})"
end
Expand Down
17 changes: 17 additions & 0 deletions test/functions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ def test_concurrency
end
end

def test_pass_custom_functions_as_a_parameter
out = Engine.new("div { url: test-function(); }", {functions: ExternalFunctions}).render
assert_match /custom_function/, out
end

def test_pass_incompatible_type_to_custom_functions
assert_raises(TypeError) do
Engine.new("div { url: test-function(); }", {functions: Class.new}).render
end
end

private

def assert_sass(sass, expected_css)
Expand Down Expand Up @@ -319,5 +330,11 @@ def returns_sass_list

end

module ExternalFunctions
def test_function
SassC::Script::Value::String.new("custom_function", :string)
end
end

end
end

0 comments on commit cf574f7

Please sign in to comment.