Commit 43286a1a by Marcin Cieslak

Merge branch 'noexceptions'

parents c5a16a9f 228b39d5
...@@ -60,22 +60,12 @@ ...@@ -60,22 +60,12 @@
'-std=c++11' '-std=c++11'
], ],
'OTHER_LDFLAGS': [], 'OTHER_LDFLAGS': [],
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO',
'MACOSX_DEPLOYMENT_TARGET': '10.7' 'MACOSX_DEPLOYMENT_TARGET': '10.7'
} }
}], }],
['OS=="win"', {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [
'/EHsc'
]
}
}
}],
['OS!="win"', { ['OS!="win"', {
'cflags_cc+': [ 'cflags_cc+': [
'-fexceptions',
'-std=c++0x' '-std=c++0x'
] ]
}] }]
......
...@@ -29,12 +29,7 @@ union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Func ...@@ -29,12 +29,7 @@ union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Func
argv.push_back((void*)sass_list_get_value(s_args, i)); argv.push_back((void*)sass_list_get_value(s_args, i));
} }
try { return bridge(argv);
return bridge(argv);
}
catch (const std::exception& e) {
return sass_make_error(e.what());
}
} }
int ExtractOptions(v8::Local<v8::Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) { int ExtractOptions(v8::Local<v8::Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
......
...@@ -98,7 +98,12 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) { ...@@ -98,7 +98,12 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
* post_process_args(). * post_process_args().
*/ */
Nan::HandleScope scope; Nan::HandleScope scope;
Nan::TryCatch try_catch;
std::vector<v8::Local<v8::Value>> argv_v8 = pre_process_args(argv); std::vector<v8::Local<v8::Value>> argv_v8 = pre_process_args(argv);
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
}
argv_v8.push_back(Nan::New(wrapper)); argv_v8.push_back(Nan::New(wrapper));
return this->post_process_return_value( return this->post_process_return_value(
...@@ -149,6 +154,9 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) { ...@@ -149,6 +154,9 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
Nan::TryCatch try_catch; Nan::TryCatch try_catch;
std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv); std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
}
argv_v8.push_back(Nan::New(bridge->wrapper)); argv_v8.push_back(Nan::New(bridge->wrapper));
bridge->callback->Call(argv_v8.size(), &argv_v8[0]); bridge->callback->Call(argv_v8.size(), &argv_v8[0]);
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
#include <stdexcept> #include <stdexcept>
#include "custom_function_bridge.h" #include "custom_function_bridge.h"
#include "sass_types/factory.h" #include "sass_types/factory.h"
#include "sass_types/value.h"
Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> val) const { Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> val) const {
try { SassTypes::Value *v_;
return SassTypes::Factory::unwrap(val)->get_sass_value(); if ((v_ = SassTypes::Factory::unwrap(val))) {
} return v_->get_sass_value();
catch (const std::invalid_argument& e) { } else {
return sass_make_error(e.what()); return sass_make_error("A SassValue object was expected.");
} }
} }
......
...@@ -67,6 +67,9 @@ namespace SassTypes ...@@ -67,6 +67,9 @@ namespace SassTypes
} }
NAN_METHOD(Boolean::GetValue) { NAN_METHOD(Boolean::GetValue) {
info.GetReturnValue().Set(Nan::New(static_cast<Boolean*>(Factory::unwrap(info.This()))->value)); Boolean *out;
if ((out = static_cast<Boolean*>(Factory::unwrap(info.This())))) {
info.GetReturnValue().Set(Nan::New(out->value));
}
} }
} }
...@@ -5,14 +5,14 @@ namespace SassTypes ...@@ -5,14 +5,14 @@ namespace SassTypes
{ {
Color::Color(Sass_Value* v) : SassValueWrapper(v) {} Color::Color(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
double a = 1.0, r = 0, g = 0, b = 0; double a = 1.0, r = 0, g = 0, b = 0;
unsigned argb; unsigned argb;
switch (raw_val.size()) { switch (raw_val.size()) {
case 1: case 1:
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("Only argument should be an integer."); return fail("Only argument should be an integer.", out);
} }
argb = Nan::To<int32_t>(raw_val[0]).FromJust(); argb = Nan::To<int32_t>(raw_val[0]).FromJust();
...@@ -24,7 +24,7 @@ namespace SassTypes ...@@ -24,7 +24,7 @@ namespace SassTypes
case 4: case 4:
if (!raw_val[3]->IsNumber()) { if (!raw_val[3]->IsNumber()) {
throw std::invalid_argument("Constructor arguments should be numbers exclusively."); return fail("Constructor arguments should be numbers exclusively.", out);
} }
a = Nan::To<double>(raw_val[3]).FromJust(); a = Nan::To<double>(raw_val[3]).FromJust();
...@@ -32,7 +32,7 @@ namespace SassTypes ...@@ -32,7 +32,7 @@ namespace SassTypes
case 3: case 3:
if (!raw_val[0]->IsNumber() || !raw_val[1]->IsNumber() || !raw_val[2]->IsNumber()) { if (!raw_val[0]->IsNumber() || !raw_val[1]->IsNumber() || !raw_val[2]->IsNumber()) {
throw std::invalid_argument("Constructor arguments should be numbers exclusively."); return fail("Constructor arguments should be numbers exclusively.", out);
} }
r = Nan::To<double>(raw_val[0]).FromJust(); r = Nan::To<double>(raw_val[0]).FromJust();
...@@ -44,10 +44,10 @@ namespace SassTypes ...@@ -44,10 +44,10 @@ namespace SassTypes
break; break;
default: default:
throw std::invalid_argument("Constructor should be invoked with either 0, 1, 3 or 4 arguments."); return fail("Constructor should be invoked with either 0, 1, 3 or 4 arguments.", out);
} }
return sass_make_color(r, g, b, a); return *out = sass_make_color(r, g, b, a);
} }
void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
public: public:
Color(Sass_Value*); Color(Sass_Value*);
static char const* get_constructor_name() { return "SassColor"; } static char const* get_constructor_name() { return "SassColor"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -6,18 +6,18 @@ namespace SassTypes ...@@ -6,18 +6,18 @@ namespace SassTypes
{ {
Error::Error(Sass_Value* v) : SassValueWrapper(v) {} Error::Error(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsString()) { if (!raw_val[0]->IsString()) {
throw std::invalid_argument("Argument should be a string."); return fail("Argument should be a string.", out);
} }
value = create_string(raw_val[0]); value = create_string(raw_val[0]);
} }
return sass_make_error(value); return *out = sass_make_error(value);
} }
void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {} void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {}
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
public: public:
Error(Sass_Value*); Error(Sass_Value*);
static char const* get_constructor_name() { return "SassError"; } static char const* get_constructor_name() { return "SassError"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
}; };
......
...@@ -39,7 +39,9 @@ namespace SassTypes ...@@ -39,7 +39,9 @@ namespace SassTypes
return new Error(v); return new Error(v);
default: default:
throw std::invalid_argument("Unknown type encountered."); const char *msg = "Unknown type encountered.";
Nan::ThrowTypeError(Nan::New<v8::String>(msg).ToLocalChecked());
return new Error(sass_make_error(msg));
} }
} }
...@@ -61,7 +63,7 @@ namespace SassTypes ...@@ -61,7 +63,7 @@ namespace SassTypes
Value* Factory::unwrap(v8::Local<v8::Value> obj) { Value* Factory::unwrap(v8::Local<v8::Value> obj) {
// Todo: non-SassValue objects could easily fall under that condition, need to be more specific. // Todo: non-SassValue objects could easily fall under that condition, need to be more specific.
if (!obj->IsObject() || obj.As<v8::Object>()->InternalFieldCount() != 1) { if (!obj->IsObject() || obj.As<v8::Object>()->InternalFieldCount() != 1) {
throw std::invalid_argument("A SassValue object was expected."); return NULL;
} }
return static_cast<Value*>(Nan::GetInternalFieldPointer(obj.As<v8::Object>(), 0)); return static_cast<Value*>(Nan::GetInternalFieldPointer(obj.As<v8::Object>(), 0));
......
...@@ -5,27 +5,27 @@ namespace SassTypes ...@@ -5,27 +5,27 @@ namespace SassTypes
{ {
List::List(Sass_Value* v) : SassValueWrapper(v) {} List::List(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
size_t length = 0; size_t length = 0;
bool comma = true; bool comma = true;
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be an integer."); return fail("First argument should be an integer.", out);
} }
length = Nan::To<uint32_t>(raw_val[0]).FromJust(); length = Nan::To<uint32_t>(raw_val[0]).FromJust();
if (raw_val.size() >= 2) { if (raw_val.size() >= 2) {
if (!raw_val[1]->IsBoolean()) { if (!raw_val[1]->IsBoolean()) {
throw std::invalid_argument("Second argument should be a boolean."); return fail("Second argument should be a boolean.", out);
} }
comma = Nan::To<bool>(raw_val[1]).FromJust(); comma = Nan::To<bool>(raw_val[1]).FromJust();
} }
} }
return sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE); return *out = sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE);
} }
void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
...@@ -71,7 +71,11 @@ namespace SassTypes ...@@ -71,7 +71,11 @@ namespace SassTypes
} }
Value* sass_value = Factory::unwrap(info[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_list_set_value(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value()); if (sass_value) {
sass_list_set_value(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value());
} else {
Nan::ThrowTypeError(Nan::New<v8::String>("A SassValue is expected as the list item").ToLocalChecked());
}
} }
NAN_METHOD(List::GetSeparator) { NAN_METHOD(List::GetSeparator) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
public: public:
List(Sass_Value*); List(Sass_Value*);
static char const* get_constructor_name() { return "SassList"; } static char const* get_constructor_name() { return "SassList"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -5,18 +5,18 @@ namespace SassTypes ...@@ -5,18 +5,18 @@ namespace SassTypes
{ {
Map::Map(Sass_Value* v) : SassValueWrapper(v) {} Map::Map(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
size_t length = 0; size_t length = 0;
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be an integer."); return fail("First argument should be an integer.", out);
} }
length = Nan::To<uint32_t>(raw_val[0]).FromJust(); length = Nan::To<uint32_t>(raw_val[0]).FromJust();
} }
return sass_make_map(length); return *out = sass_make_map(length);
} }
void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
...@@ -62,7 +62,11 @@ namespace SassTypes ...@@ -62,7 +62,11 @@ namespace SassTypes
} }
Value* sass_value = Factory::unwrap(info[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_value(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value()); if (sass_value) {
sass_map_set_value(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value());
} else {
Nan::ThrowTypeError(Nan::New<v8::String>("A SassValue is expected as a map value").ToLocalChecked());
}
} }
NAN_METHOD(Map::GetKey) { NAN_METHOD(Map::GetKey) {
...@@ -100,7 +104,11 @@ namespace SassTypes ...@@ -100,7 +104,11 @@ namespace SassTypes
} }
Value* sass_value = Factory::unwrap(info[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_key(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value()); if (sass_value) {
sass_map_set_key(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value());
} else {
Nan::ThrowTypeError(Nan::New<v8::String>("A SassValue is expected as a map key").ToLocalChecked());
}
} }
NAN_METHOD(Map::GetLength) { NAN_METHOD(Map::GetLength) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
public: public:
Map(Sass_Value*); Map(Sass_Value*);
static char const* get_constructor_name() { return "SassMap"; } static char const* get_constructor_name() { return "SassMap"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -6,27 +6,27 @@ namespace SassTypes ...@@ -6,27 +6,27 @@ namespace SassTypes
{ {
Number::Number(Sass_Value* v) : SassValueWrapper(v) {} Number::Number(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
double value = 0; double value = 0;
char const* unit = ""; char const* unit = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be a number."); return fail("First argument should be a number.", out);
} }
value = Nan::To<double>(raw_val[0]).FromJust(); value = Nan::To<double>(raw_val[0]).FromJust();
if (raw_val.size() >= 2) { if (raw_val.size() >= 2) {
if (!raw_val[1]->IsString()) { if (!raw_val[1]->IsString()) {
throw std::invalid_argument("Second argument should be a string."); return fail("Second argument should be a string.", out);
} }
unit = create_string(raw_val[1]); unit = create_string(raw_val[1]);
} }
} }
return sass_make_number(value, unit); return *out = sass_make_number(value, unit);
} }
void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -11,7 +11,7 @@ namespace SassTypes ...@@ -11,7 +11,7 @@ namespace SassTypes
public: public:
Number(Sass_Value*); Number(Sass_Value*);
static char const* get_constructor_name() { return "SassNumber"; } static char const* get_constructor_name() { return "SassNumber"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **out);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -25,6 +25,7 @@ namespace SassTypes ...@@ -25,6 +25,7 @@ namespace SassTypes
static v8::Local<v8::Function> get_constructor(); static v8::Local<v8::Function> get_constructor();
static v8::Local<v8::FunctionTemplate> get_constructor_template(); static v8::Local<v8::FunctionTemplate> get_constructor_template();
static NAN_METHOD(New); static NAN_METHOD(New);
static Sass_Value *fail(const char *, Sass_Value **);
protected: protected:
Sass_Value* value; Sass_Value* value;
...@@ -94,15 +95,15 @@ namespace SassTypes ...@@ -94,15 +95,15 @@ namespace SassTypes
localArgs[i] = info[i]; localArgs[i] = info[i];
} }
if (info.IsConstructCall()) { if (info.IsConstructCall()) {
try { Sass_Value* value;
Sass_Value* value = T::construct(localArgs); if (T::construct(localArgs, &value) != NULL) {
T* obj = new T(value); T* obj = new T(value);
sass_delete_value(value); sass_delete_value(value);
Nan::SetInternalFieldPointer(info.This(), 0, obj); Nan::SetInternalFieldPointer(info.This(), 0, obj);
obj->js_object.Reset(info.This()); obj->js_object.Reset(info.This());
} catch (const std::exception& e) { } else {
return Nan::ThrowError(Nan::New<v8::String>(e.what()).ToLocalChecked()); return Nan::ThrowError(Nan::New<v8::String>(sass_error_get_message(value)).ToLocalChecked());
} }
} else { } else {
v8::Local<v8::Function> cons = T::get_constructor(); v8::Local<v8::Function> cons = T::get_constructor();
...@@ -117,8 +118,15 @@ namespace SassTypes ...@@ -117,8 +118,15 @@ namespace SassTypes
template <class T> template <class T>
T* SassValueWrapper<T>::unwrap(v8::Local<v8::Object> obj) { T* SassValueWrapper<T>::unwrap(v8::Local<v8::Object> obj) {
/* This maybe NULL */
return static_cast<T*>(Factory::unwrap(obj)); return static_cast<T*>(Factory::unwrap(obj));
} }
template <class T>
Sass_Value *SassValueWrapper<T>::fail(const char *reason, Sass_Value **out) {
*out = sass_make_error(reason);
return NULL;
}
} }
......
...@@ -6,18 +6,18 @@ namespace SassTypes ...@@ -6,18 +6,18 @@ namespace SassTypes
{ {
String::String(Sass_Value* v) : SassValueWrapper(v) {} String::String(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsString()) { if (!raw_val[0]->IsString()) {
throw std::invalid_argument("Argument should be a string."); return fail("Argument should be a string.", out);
} }
value = create_string(raw_val[0]); value = create_string(raw_val[0]);
} }
return sass_make_string(value); return *out = sass_make_string(value);
} }
void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
public: public:
String(Sass_Value*); String(Sass_Value*);
static char const* get_constructor_name() { return "SassString"; } static char const* get_constructor_name() { return "SassString"; }
static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -859,6 +859,72 @@ describe('api', function() { ...@@ -859,6 +859,72 @@ describe('api', function() {
}); });
}); });
it('should fail when trying to set a bare number as the List item', function(done) {
sass.render({
data: 'div { color: foo(); }',
functions: {
'foo()': function() {
var out = new sass.types.List(1);
out.setValue(0, 2);
return out;
}
}
}, function(error) {
assert.ok(/Supplied value should be a SassValue object/.test(error.message));
done();
});
});
it('should fail when trying to set a bare Object as the List item', function(done) {
sass.render({
data: 'div { color: foo(); }',
functions: {
'foo()': function() {
var out = new sass.types.List(1);
out.setValue(0, {});
return out;
}
}
}, function(error) {
assert.ok(/A SassValue is expected as the list item/.test(error.message));
done();
});
});
it('should fail when trying to set a bare Object as the Map key', function(done) {
sass.render({
data: 'div { color: foo(); }',
functions: {
'foo()': function() {
var out = new sass.types.Map(1);
out.setKey(0, {});
out.setValue(0, new sass.types.String('aaa'));
return out;
}
}
}, function(error) {
assert.ok(/A SassValue is expected as a map key/.test(error.message));
done();
});
});
it('should fail when trying to set a bare Object as the Map value', function(done) {
sass.render({
data: 'div { color: foo(); }',
functions: {
'foo()': function() {
var out = new sass.types.Map(1);
out.setKey(0, new sass.types.String('aaa'));
out.setValue(0, {});
return out;
}
}
}, function(error) {
assert.ok(/A SassValue is expected as a map value/.test(error.message));
done();
});
});
it('should always map null, true and false to the same (immutable) object', function(done) { it('should always map null, true and false to the same (immutable) object', function(done) {
var counter = 0; var counter = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment