diff --git a/lib/index.js b/lib/index.js index ce576dd88..7f1275d19 100644 --- a/lib/index.js +++ b/lib/index.js @@ -301,27 +301,27 @@ module.exports.render = function(options, cb) { if (Array.isArray(importer)) { importer.forEach(function(subject, index) { options.importer[index] = function(file, prev, bridge) { - function done(data) { - bridge.success(data); + function done(result) { + bridge.success(result === module.exports.NULL ? null : result); } var result = subject.call(options.context, file, prev, done); - if (result) { - done(result === module.exports.NULL ? null : result); + if (result !== undefined) { + done(result); } }; }); } else { options.importer = function(file, prev, bridge) { - function done(data) { - bridge.success(data); + function done(result) { + bridge.success(result === module.exports.NULL ? null : result); } var result = importer.call(options.context, file, prev, done); - if (result) { - done(result === module.exports.NULL ? null : result); + if (result !== undefined) { + done(result); } }; } diff --git a/src/custom_function_bridge.cpp b/src/custom_function_bridge.cpp index f0e49b6c8..110b7d3d0 100644 --- a/src/custom_function_bridge.cpp +++ b/src/custom_function_bridge.cpp @@ -4,9 +4,13 @@ #include "sass_types/factory.h" #include "sass_types/value.h" +#include + Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local val) const { SassTypes::Value *v_; - if ((v_ = SassTypes::Factory::unwrap(val))) { + if (val->IsNull()) { + return sass_make_null(); + } else if ((v_ = SassTypes::Factory::unwrap(val))) { return v_->get_sass_value(); } else { return sass_make_error("A SassValue object was expected."); @@ -17,7 +21,15 @@ std::vector> CustomFunctionBridge::pre_process_args(std::ve std::vector> argv = std::vector>(); for (void* value : in) { - argv.push_back(SassTypes::Factory::create(static_cast(value))->get_js_object()); + Sass_Value *vptr = static_cast(value); + v8::Local item; + + if (sass_value_is_null(vptr)) { + item = Nan::Null(); + } else { + item = SassTypes::Factory::create(vptr)->get_js_object(); + } + argv.push_back(item); } return argv; diff --git a/src/sass_types/boolean.cpp b/src/sass_types/boolean.cpp index 89c7a9659..61e2879c2 100644 --- a/src/sass_types/boolean.cpp +++ b/src/sass_types/boolean.cpp @@ -54,12 +54,12 @@ namespace SassTypes if (info.IsConstructCall()) { if (constructor_locked) { - return Nan::ThrowTypeError(Nan::New("Cannot instantiate SassBoolean").ToLocalChecked()); + return Nan::ThrowTypeError("Cannot instantiate SassBoolean"); } } else { if (info.Length() != 1 || !info[0]->IsBoolean()) { - return Nan::ThrowTypeError(Nan::New("Expected one boolean argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected one boolean argument"); } info.GetReturnValue().Set(get_singleton(Nan::To(info[0]).FromJust()).get_js_object()); diff --git a/src/sass_types/color.cpp b/src/sass_types/color.cpp index ed22b13cb..f484b196e 100644 --- a/src/sass_types/color.cpp +++ b/src/sass_types/color.cpp @@ -79,11 +79,11 @@ namespace SassTypes NAN_METHOD(Color::SetR) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a number").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a number"); } sass_color_set_r(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); @@ -91,11 +91,11 @@ namespace SassTypes NAN_METHOD(Color::SetG) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a number").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a number"); } sass_color_set_g(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); @@ -103,11 +103,11 @@ namespace SassTypes NAN_METHOD(Color::SetB) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a number").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a number"); } sass_color_set_b(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); @@ -115,11 +115,11 @@ namespace SassTypes NAN_METHOD(Color::SetA) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a number").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a number"); } sass_color_set_a(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); diff --git a/src/sass_types/factory.cpp b/src/sass_types/factory.cpp index 1c91f7a2f..a4aa1b924 100644 --- a/src/sass_types/factory.cpp +++ b/src/sass_types/factory.cpp @@ -40,13 +40,16 @@ namespace SassTypes default: const char *msg = "Unknown type encountered."; - Nan::ThrowTypeError(Nan::New(msg).ToLocalChecked()); + Nan::ThrowTypeError(msg); return new Error(sass_make_error(msg)); } } NAN_MODULE_INIT(Factory::initExports) { Nan::HandleScope scope; + v8::Local fake_null = Nan::New(); + Nan::Set(fake_null, Nan::New("NULL").ToLocalChecked(), Nan::Null()); + v8::Local types = Nan::New(); Nan::Set(types, Nan::New("Number").ToLocalChecked(), Number::get_constructor()); @@ -55,7 +58,7 @@ namespace SassTypes Nan::Set(types, Nan::New("Boolean").ToLocalChecked(), Boolean::get_constructor()); Nan::Set(types, Nan::New("List").ToLocalChecked(), List::get_constructor()); Nan::Set(types, Nan::New("Map").ToLocalChecked(), Map::get_constructor()); - Nan::Set(types, Nan::New("Null").ToLocalChecked(), Null::get_constructor()); + Nan::Set(types, Nan::New("Null").ToLocalChecked(), fake_null); Nan::Set(types, Nan::New("Error").ToLocalChecked(), Error::get_constructor()); Nan::Set(target, Nan::New("types").ToLocalChecked(), types); } diff --git a/src/sass_types/list.cpp b/src/sass_types/list.cpp index a337d638e..0d68b2831 100644 --- a/src/sass_types/list.cpp +++ b/src/sass_types/list.cpp @@ -39,11 +39,11 @@ namespace SassTypes NAN_METHOD(List::GetValue) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } Sass_Value* list = unwrap(info.This())->value; @@ -54,27 +54,36 @@ namespace SassTypes return Nan::ThrowRangeError(Nan::New("Out of bound index").ToLocalChecked()); } - info.GetReturnValue().Set(Factory::create(sass_list_get_value(list, Nan::To(info[0]).FromJust()))->get_js_object()); + Sass_Value *item = sass_list_get_value(list, Nan::To(info[0]).FromJust()); + if (sass_value_is_null(item)) { + info.GetReturnValue().Set(Nan::Null()); + } else { + info.GetReturnValue().Set(Factory::create(item)->get_js_object()); + } } NAN_METHOD(List::SetValue) { if (info.Length() != 2) { - return Nan::ThrowTypeError(Nan::New("Expected two arguments").ToLocalChecked()); + return Nan::ThrowTypeError("Expected two arguments"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } + if (info[1]->IsNull()) { + sass_list_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_make_null()); + return; + } if (!info[1]->IsObject()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); } Value* sass_value = Factory::unwrap(info[1]); if (sass_value) { sass_list_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); } else { - Nan::ThrowTypeError(Nan::New("A SassValue is expected as the list item").ToLocalChecked()); + Nan::ThrowTypeError("A SassValue is expected as the list item"); } } @@ -84,11 +93,11 @@ namespace SassTypes NAN_METHOD(List::SetSeparator) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsBoolean()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a boolean").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a boolean"); } sass_list_set_separator(unwrap(info.This())->value, Nan::To(info[0]).FromJust() ? SASS_COMMA : SASS_SPACE); diff --git a/src/sass_types/map.cpp b/src/sass_types/map.cpp index 147de42f4..ad147e6f9 100644 --- a/src/sass_types/map.cpp +++ b/src/sass_types/map.cpp @@ -30,11 +30,11 @@ namespace SassTypes NAN_METHOD(Map::GetValue) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } Sass_Value* map = unwrap(info.This())->value; @@ -50,33 +50,33 @@ namespace SassTypes NAN_METHOD(Map::SetValue) { if (info.Length() != 2) { - return Nan::ThrowTypeError(Nan::New("Expected two arguments").ToLocalChecked()); + return Nan::ThrowTypeError("Expected two arguments"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } if (!info[1]->IsObject()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); } Value* sass_value = Factory::unwrap(info[1]); if (sass_value) { sass_map_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); } else { - Nan::ThrowTypeError(Nan::New("A SassValue is expected as a map value").ToLocalChecked()); + Nan::ThrowTypeError("A SassValue is expected as a map value"); } } NAN_METHOD(Map::GetKey) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } Sass_Value* map = unwrap(info.This())->value; @@ -92,22 +92,22 @@ namespace SassTypes NAN_METHOD(Map::SetKey) { if (info.Length() != 2) { - return Nan::ThrowTypeError(Nan::New("Expected two arguments").ToLocalChecked()); + return Nan::ThrowTypeError("Expected two arguments"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied index should be an integer").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied index should be an integer"); } if (!info[1]->IsObject()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); } Value* sass_value = Factory::unwrap(info[1]); if (sass_value) { sass_map_set_key(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); } else { - Nan::ThrowTypeError(Nan::New("A SassValue is expected as a map key").ToLocalChecked()); + Nan::ThrowTypeError("A SassValue is expected as a map key"); } } diff --git a/src/sass_types/null.cpp b/src/sass_types/null.cpp index 4e3536d6c..766cdf935 100644 --- a/src/sass_types/null.cpp +++ b/src/sass_types/null.cpp @@ -49,7 +49,7 @@ namespace SassTypes if (info.IsConstructCall()) { if (constructor_locked) { - return Nan::ThrowTypeError(Nan::New("Cannot instantiate SassNull").ToLocalChecked()); + return Nan::ThrowTypeError("Cannot instantiate SassNull"); } } else { diff --git a/src/sass_types/number.cpp b/src/sass_types/number.cpp index 1605516b2..e98d1e302 100644 --- a/src/sass_types/number.cpp +++ b/src/sass_types/number.cpp @@ -47,11 +47,11 @@ namespace SassTypes NAN_METHOD(Number::SetValue) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsNumber()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a number").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a number"); } sass_number_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); @@ -59,11 +59,11 @@ namespace SassTypes NAN_METHOD(Number::SetUnit) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsString()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a string").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a string"); } sass_number_set_unit(unwrap(info.This())->value, create_string(info[0])); diff --git a/src/sass_types/string.cpp b/src/sass_types/string.cpp index d97095bbc..c72a93a95 100644 --- a/src/sass_types/string.cpp +++ b/src/sass_types/string.cpp @@ -31,11 +31,11 @@ namespace SassTypes NAN_METHOD(String::SetValue) { if (info.Length() != 1) { - return Nan::ThrowTypeError(Nan::New("Expected just one argument").ToLocalChecked()); + return Nan::ThrowTypeError("Expected just one argument"); } if (!info[0]->IsString()) { - return Nan::ThrowTypeError(Nan::New("Supplied value should be a string").ToLocalChecked()); + return Nan::ThrowTypeError("Supplied value should be a string"); } sass_string_set_value(unwrap(info.This())->value, create_string(info[0])); diff --git a/test/api.js b/test/api.js index f289272c1..a9f7d8e6a 100644 --- a/test/api.js +++ b/test/api.js @@ -956,50 +956,49 @@ describe('api', function() { data: 'div { color: foo(bar(null)); background-color: baz("foo" == "bar"); }', functions: { foo: function(a) { - assert.ok( - 'Supplied value should be the same instance as sass.TRUE', - a === sass.TRUE + assert.strictEqual(a, sass.TRUE, + 'Supplied value should be the same instance as sass.TRUE' ); - assert.ok( - 'sass.types.Boolean(true) should return a singleton', - sass.types.Boolean(true) === sass.types.Boolean(true) && - sass.types.Boolean(true) === sass.TRUE - ); + assert.strictEqual( + sass.types.Boolean(true), sass.types.Boolean(true), + 'sass.types.Boolean(true) should return a singleton'); + + assert.strictEqual( + sass.types.Boolean(true), sass.TRUE, + 'sass.types.Boolean(true) should be the same instance as sass.TRUE'); counter++; return sass.types.String('foo'); }, bar: function(a) { - assert.ok( - 'Supplied value should be the same instance as sass.NULL', - a === sass.NULL - ); + assert.strictEqual(a, sass.NULL, + 'Supplied value should be the same instance as sass.NULL'); assert.throws(function() { return new sass.types.Null(); - }, /Cannot instantiate SassNull/); + }); counter++; return sass.TRUE; }, baz: function(a) { - assert.ok( - 'Supplied value should be the same instance as sass.FALSE', - a === sass.FALSE - ); + assert.strictEqual(a, sass.FALSE, + 'Supplied value should be the same instance as sass.FALSE'); assert.throws(function() { return new sass.types.Boolean(false); }, /Cannot instantiate SassBoolean/); - assert.ok( - 'sass.types.Boolean(false) should return a singleton', - sass.types.Boolean(false) === sass.types.Boolean(false) && - sass.types.Boolean(false) === sass.FALSE - ); + assert.strictEqual( + sass.types.Boolean(false), sass.types.Boolean(false), + 'sass.types.Boolean(false) should return a singleton'); + + assert.strictEqual( + sass.types.Boolean(false), sass.FALSE, + 'sass.types.Boolean(false) should return singleton identical to sass.FALSE'); counter++; @@ -1007,7 +1006,7 @@ describe('api', function() { } } }, function() { - assert.ok(counter === 3); + assert.strictEqual(counter, 3); done(); }); }); @@ -1021,7 +1020,7 @@ describe('api', function() { file: fixture('include-files/index.scss') }, function(error, result) { assert(!error); - assert(typeof result.stats.start === 'number'); + assert.strictEqual(typeof result.stats.start, 'number'); assert(result.stats.start >= start); done(); }); @@ -1032,7 +1031,7 @@ describe('api', function() { file: fixture('include-files/index.scss') }, function(error, result) { assert(!error); - assert(typeof result.stats.end === 'number'); + assert.strictEqual(typeof result.stats.end, 'number'); assert(result.stats.end >= result.stats.start); done(); }); @@ -1043,7 +1042,7 @@ describe('api', function() { file: fixture('include-files/index.scss') }, function(error, result) { assert(!error); - assert(typeof result.stats.duration === 'number'); + assert.strictEqual(typeof result.stats.duration, 'number'); assert.equal(result.stats.end - result.stats.start, result.stats.duration); done(); }); @@ -1504,19 +1503,19 @@ describe('api', function() { }); it('should provide a start timestamp', function(done) { - assert(typeof result.stats.start === 'number'); + assert.strictEqual(typeof result.stats.start, 'number'); assert(result.stats.start >= start); done(); }); it('should provide an end timestamp', function(done) { - assert(typeof result.stats.end === 'number'); + assert.strictEqual(typeof result.stats.end, 'number'); assert(result.stats.end >= result.stats.start); done(); }); it('should provide a duration', function(done) { - assert(typeof result.stats.duration === 'number'); + assert.strictEqual(typeof result.stats.duration, 'number'); assert.equal(result.stats.end - result.stats.start, result.stats.duration); done(); }); diff --git a/test/cli.js b/test/cli.js index ba48fb864..b377bd602 100644 --- a/test/cli.js +++ b/test/cli.js @@ -244,7 +244,7 @@ describe('cli', function() { bin.stderr.setEncoding('utf8'); bin.stderr.once('data', function(data) { - assert(data.trim() === '=> changed: ' + src); + assert.strictEqual(data.trim(), '=> changed: ' + src); fs.unlinkSync(src); bin.kill(); done(); @@ -290,7 +290,7 @@ describe('cli', function() { bin.stdout.setEncoding('utf8'); bin.stdout.once('data', function(data) { - assert(data.trim() === 'body{background:white}'); + assert.strictEqual(data.trim(), 'body{background:white}'); fs.unlinkSync(src); bin.kill(); done(); @@ -314,7 +314,7 @@ describe('cli', function() { bin.stdout.setEncoding('utf8'); bin.stdout.once('data', function(data) { - assert.equal(data.trim(), 'body{background:blue}'); + assert.strictEqual(data.trim(), 'body{background:blue}'); bin.kill(); done(); }); @@ -337,7 +337,7 @@ describe('cli', function() { bin.stdout.setEncoding('utf8'); bin.stdout.once('data', function(data) { - assert.equal(data.trim(), 'body{background:red}'); + assert.strictEqual(data.trim(), 'body{background:red}'); bin.kill(); done(); }); @@ -442,7 +442,7 @@ describe('cli', function() { ]); bin.once('close', function() { - assert(read(dest, 'utf8').indexOf('sourceMappingURL') === -1); + assert.strictEqual(read(dest, 'utf8').indexOf('sourceMappingURL'), -1); assert(fs.existsSync(map)); fs.unlinkSync(map); fs.unlinkSync(dest); @@ -570,8 +570,8 @@ describe('cli', function() { var bin = spawn(cli, [src]); bin.once('close', function(code) { - assert(code !== 0); - assert.equal(glob.sync(fixture('input-directory/**/*.css')).length, 0); + assert.notStrictEqual(code, 0); + assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0); done(); }); }); @@ -582,7 +582,7 @@ describe('cli', function() { var bin = spawn(cli, [src, '--output', dest]); bin.once('close', function(code) { - assert(code !== 0); + assert.notStrictEqual(code, 0); assert.equal(glob.sync(fixture('input-directory/**/*.css')).length, 0); done(); }); @@ -745,7 +745,7 @@ describe('cli', function() { ]); bin.once('close', function(code) { - assert(code !== 0); + assert.notStrictEqual(code, 0); done(); }); });