Commit 9ec016f0 by Marcel Greter Committed by Adeel

Fix segfaults (testing)

parent 150c6851
...@@ -65,14 +65,12 @@ function getStats(options) { ...@@ -65,14 +65,12 @@ function getStats(options) {
/** /**
* End stats * End stats
* *
* @param {Object} options * @param {Object} stats
* @param {Object} sourceMap * @param {Object} sourceMap
* @api private * @api private
*/ */
function endStats(options) { function endStats(stats) {
var stats = options.stats || {};
stats.end = Date.now(); stats.end = Date.now();
stats.duration = stats.end - stats.start; stats.duration = stats.end - stats.start;
...@@ -144,8 +142,6 @@ function getOptions(options) { ...@@ -144,8 +142,6 @@ function getOptions(options) {
throw new Error('`imagePath` needs to be a string'); throw new Error('`imagePath` needs to be a string');
} }
options.stats = getStats(options);
var error = options.error; var error = options.error;
var success = options.success; var success = options.success;
var importer = options.importer; var importer = options.importer;
...@@ -164,16 +160,16 @@ function getOptions(options) { ...@@ -164,16 +160,16 @@ function getOptions(options) {
} }
}; };
options.success = function(css, sourceMap) { options.success = function() {
sourceMap = JSON.parse(sourceMap); options.result.sourceMap = JSON.parse(options.result.sourceMap);
endStats(options, sourceMap); var stats = endStats(options.result.stats);
if (success) { if (success) {
success({ success({
css: css, css: options.result.css,
map: sourceMap, map: options.result.sourceMap,
stats: options.stats stats: stats
}); });
} }
}; };
...@@ -195,6 +191,10 @@ function getOptions(options) { ...@@ -195,6 +191,10 @@ function getOptions(options) {
delete options.source_comments; delete options.source_comments;
delete options.sourceComments; delete options.sourceComments;
options.result = {
stats: getStats(options)
};
return options; return options;
} }
...@@ -213,6 +213,7 @@ var binding = require(getBinding()); ...@@ -213,6 +213,7 @@ var binding = require(getBinding());
module.exports.render = function(options) { module.exports.render = function(options) {
options = getOptions(options); options = getOptions(options);
options.data ? binding.render(options) : binding.renderFile(options); options.data ? binding.render(options) : binding.renderFile(options);
}; };
...@@ -224,23 +225,15 @@ module.exports.render = function(options) { ...@@ -224,23 +225,15 @@ module.exports.render = function(options) {
*/ */
module.exports.renderSync = function(options) { module.exports.renderSync = function(options) {
var output;
options = getOptions(options); options = getOptions(options);
output = options.data ? binding.renderSync(options) : binding.renderFileSync(options);
endStats(options);
var result = { var result = options.data ? binding.renderSync(options) : binding.renderFileSync(options);
css: output,
map: options.stats.sourceMap
};
delete options.stats.sourceMap; if(result) {
options.result.stats = endStats(options.result.stats);
result.stats = options.stats; return options.result;
}
return result;
}; };
/** /**
......
...@@ -15,7 +15,7 @@ char* CreateString(Local<Value> value) { ...@@ -15,7 +15,7 @@ char* CreateString(Local<Value> value) {
std::vector<sass_context_wrapper*> imports_collection; std::vector<sass_context_wrapper*> imports_collection;
void dispatched_async_uv_callback(uv_async_t *req){ void dispatched_async_uv_callback(uv_async_t *req) {
NanScope(); NanScope();
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data); sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
...@@ -24,8 +24,8 @@ void dispatched_async_uv_callback(uv_async_t *req){ ...@@ -24,8 +24,8 @@ void dispatched_async_uv_callback(uv_async_t *req){
imports_collection.push_back(ctx_w); imports_collection.push_back(ctx_w);
Handle<Value> argv[] = { Handle<Value> argv[] = {
NanNew<String>(strdup(ctx_w->file)), NanNew<String>(strdup(ctx_w->file ? ctx_w->file : 0)),
NanNew<String>(strdup(ctx_w->prev)), NanNew<String>(strdup(ctx_w->prev ? ctx_w->prev : 0)),
NanNew<Number>(imports_collection.size() - 1) NanNew<Number>(imports_collection.size() - 1)
}; };
...@@ -40,8 +40,8 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo ...@@ -40,8 +40,8 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo
{ {
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(cookie); sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(cookie);
ctx_w->file = strdup(file); ctx_w->file = file ? strdup(file) : 0;
ctx_w->prev = strdup(prev); ctx_w->prev = prev ? strdup(prev) : 0;
ctx_w->async.data = (void*)ctx_w; ctx_w->async.data = (void*)ctx_w;
uv_async_send(&ctx_w->async); uv_async_send(&ctx_w->async);
...@@ -52,7 +52,7 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo ...@@ -52,7 +52,7 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo
*/ */
uv_cond_wait(&ctx_w->importer_condition_variable, &ctx_w->importer_mutex); uv_cond_wait(&ctx_w->importer_condition_variable, &ctx_w->importer_mutex);
} }
else{ else {
/* that is sync: RenderSync() or RenderFileSync, /* that is sync: RenderSync() or RenderFileSync,
* we need to explicitly uv_run as the event loop * we need to explicitly uv_run as the event loop
* is blocked; waiting down the chain. * is blocked; waiting down the chain.
...@@ -66,6 +66,8 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo ...@@ -66,6 +66,8 @@ struct Sass_Import** sass_importer(const char* file, const char* prev, void* coo
void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool isFile, bool isSync) { void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool isFile, bool isSync) {
struct Sass_Context* ctx; struct Sass_Context* ctx;
NanAssignPersistent(ctx_w->result, options->Get(NanNew("result"))->ToObject());
if (isFile) { if (isFile) {
ctx = sass_file_context_get_context((struct Sass_File_Context*) cptr); ctx = sass_file_context_get_context((struct Sass_File_Context*) cptr);
ctx_w->fctx = (struct Sass_File_Context*) cptr; ctx_w->fctx = (struct Sass_File_Context*) cptr;
...@@ -78,8 +80,6 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -78,8 +80,6 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
struct Sass_Options* sass_options = sass_context_get_options(ctx); struct Sass_Options* sass_options = sass_context_get_options(ctx);
if (!isSync) { if (!isSync) {
NanAssignPersistent(ctx_w->stats, options->Get(NanNew("stats"))->ToObject());
ctx_w->request.data = ctx_w; ctx_w->request.data = ctx_w;
// async (callback) style // async (callback) style
...@@ -113,7 +113,7 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -113,7 +113,7 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value()); sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
} }
void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) { void GetStats(Handle<Object> result, Sass_Context* ctx) {
char** included_files = sass_context_get_included_files(ctx); char** included_files = sass_context_get_included_files(ctx);
Handle<Array> arr = NanNew<Array>(); Handle<Array> arr = NanNew<Array>();
...@@ -123,8 +123,10 @@ void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) { ...@@ -123,8 +123,10 @@ void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) {
} }
} }
(*stats)->Set(NanNew("includedFiles"), arr); (*result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
}
void GetSourceMap(Handle<Object> result, Sass_Context* ctx) {
Handle<Value> source_map; Handle<Value> source_map;
if (sass_context_get_error_status(ctx)) { if (sass_context_get_error_status(ctx)) {
...@@ -138,7 +140,19 @@ void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) { ...@@ -138,7 +140,19 @@ void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) {
source_map = NanNew<String>("{}"); source_map = NanNew<String>("{}");
} }
(*stats)->Set(NanNew("sourceMap"), source_map); (*result)->Set(NanNew("sourceMap"), source_map);
}
int GetResult(Handle<Object> result, Sass_Context* ctx) {
int status = sass_context_get_error_status(ctx);
if (status == 0) {
(*result)->Set(NanNew("css"), NanNew<String>(sass_context_get_output_string(ctx)));
GetStats(result, ctx);
GetSourceMap(result, ctx);
}
return status;
} }
void make_callback(uv_work_t* req) { void make_callback(uv_work_t* req) {
...@@ -146,35 +160,27 @@ void make_callback(uv_work_t* req) { ...@@ -146,35 +160,27 @@ void make_callback(uv_work_t* req) {
TryCatch try_catch; TryCatch try_catch;
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data); sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
int error_status;
struct Sass_Context* ctx; struct Sass_Context* ctx;
if (ctx_w->dctx) { if (ctx_w->dctx) {
ctx = sass_data_context_get_context(ctx_w->dctx); ctx = sass_data_context_get_context(ctx_w->dctx);
FillStatsObj(NanNew(ctx_w->stats), ctx);
error_status = sass_context_get_error_status(ctx);
} }
else { else {
ctx = sass_file_context_get_context(ctx_w->fctx); ctx = sass_file_context_get_context(ctx_w->fctx);
FillStatsObj(NanNew(ctx_w->stats), ctx);
error_status = sass_context_get_error_status(ctx);
} }
if (error_status == 0) { int status = GetResult(ctx_w->result, ctx);
if (status == 0) {
// if no error, do callback(null, result) // if no error, do callback(null, result)
const char* val = sass_context_get_output_string(ctx); ctx_w->success_callback->Call(0, 0);
Local<Value> argv[] = {
NanNew<String>(val),
NanNew(ctx_w->stats)->Get(NanNew("sourceMap"))
};
ctx_w->success_callback->Call(2, argv);
} }
else { else {
// if error, do callback(error) // if error, do callback(error)
const char* err = sass_context_get_error_json(ctx); const char* err = sass_context_get_error_json(ctx);
Local<Value> argv[] = { Local<Value> argv[] = {
NanNew<String>(err), NanNew<String>(err),
NanNew<Integer>(error_status) NanNew<Integer>(status)
}; };
ctx_w->error_callback->Call(2, argv); ctx_w->error_callback->Call(2, argv);
} }
...@@ -213,21 +219,22 @@ NAN_METHOD(RenderSync) { ...@@ -213,21 +219,22 @@ NAN_METHOD(RenderSync) {
ExtractOptions(options, dctx, ctx_w, false, true); ExtractOptions(options, dctx, ctx_w, false, true);
compile_data(dctx); compile_data(dctx);
FillStatsObj(options->Get(NanNew("stats"))->ToObject(), ctx);
if (sass_context_get_error_status(ctx) == 0) { int result = GetResult(ctx_w->result, ctx);
Local<String> output = NanNew<String>(sass_context_get_output_string(ctx)); Local<String> error;
sass_delete_data_context(dctx); if (result != 0) {
NanReturnValue(output); error = NanNew<String>(sass_context_get_error_json(ctx));
} }
Local<String> error = NanNew<String>(sass_context_get_error_json(ctx));
sass_free_context_wrapper(ctx_w); sass_free_context_wrapper(ctx_w);
free(source_string);
if (result != 0) {
NanThrowError(error); NanThrowError(error);
}
NanReturnUndefined(); NanReturnValue(NanNew<Boolean>(result == 0));
} }
NAN_METHOD(RenderFile) { NAN_METHOD(RenderFile) {
...@@ -259,22 +266,22 @@ NAN_METHOD(RenderFileSync) { ...@@ -259,22 +266,22 @@ NAN_METHOD(RenderFileSync) {
ExtractOptions(options, fctx, ctx_w, true, true); ExtractOptions(options, fctx, ctx_w, true, true);
compile_file(fctx); compile_file(fctx);
FillStatsObj(options->Get(NanNew("stats"))->ToObject(), ctx);
free(input_path);
if (sass_context_get_error_status(ctx) == 0) { int result = GetResult(ctx_w->result, ctx);
Local<String> output = NanNew<String>(sass_context_get_output_string(ctx)); Local<String> error;
sass_delete_file_context(fctx); if (result != 0) {
NanReturnValue(output); error = NanNew<String>(sass_context_get_error_json(ctx));
} }
Local<String> error = NanNew<String>(sass_context_get_error_json(ctx));
sass_free_context_wrapper(ctx_w); sass_free_context_wrapper(ctx_w);
free(input_path);
if (result != 0) {
NanThrowError(error); NanThrowError(error);
}
NanReturnUndefined(); NanReturnValue(NanNew<Boolean>(result == 0));
} }
NAN_METHOD(ImportedCallback) { NAN_METHOD(ImportedCallback) {
...@@ -283,9 +290,7 @@ NAN_METHOD(ImportedCallback) { ...@@ -283,9 +290,7 @@ NAN_METHOD(ImportedCallback) {
TryCatch try_catch; TryCatch try_catch;
Local<Object> options = args[0]->ToObject(); Local<Object> options = args[0]->ToObject();
char* source_string = CreateString(options->Get(NanNew("index")));
Local<Value> returned_value = options->Get(NanNew("objectLiteral")); Local<Value> returned_value = options->Get(NanNew("objectLiteral"));
size_t index = options->Get(NanNew("index"))->Int32Value(); size_t index = options->Get(NanNew("index"))->Int32Value();
if (index >= imports_collection.size()) { if (index >= imports_collection.size()) {
......
Subproject commit 7aaa45a979ce65d50b3158ff50bf9409f8955063 Subproject commit 9852e41a11f16e8d52992a0f6e4d08068e9cd0ad
...@@ -31,24 +31,23 @@ extern "C" { ...@@ -31,24 +31,23 @@ extern "C" {
void sass_free_context_wrapper(sass_context_wrapper* ctx_w) { void sass_free_context_wrapper(sass_context_wrapper* ctx_w) {
if (ctx_w->dctx) { if (ctx_w->dctx) {
sass_delete_data_context(ctx_w->dctx); // sass_delete_data_context(ctx_w->dctx);
} }
else if (ctx_w->fctx) { else if (ctx_w->fctx) {
sass_delete_file_context(ctx_w->fctx); sass_delete_file_context(ctx_w->fctx);
} }
NanDisposePersistent(ctx_w->stats); NanDisposePersistent(ctx_w->result);
delete ctx_w->success_callback; delete ctx_w->success_callback;
delete ctx_w->error_callback; delete ctx_w->error_callback;
delete ctx_w->importer_callback; delete ctx_w->importer_callback;
delete ctx_w->file; delete ctx_w->file;
delete ctx_w->prev; delete ctx_w->prev;
delete ctx_w->cookie;
uv_mutex_destroy(&ctx_w->importer_mutex); uv_mutex_destroy(&ctx_w->importer_mutex);
uv_cond_destroy(&ctx_w->importer_condition_variable); uv_cond_destroy(&ctx_w->importer_condition_variable);
free(ctx_w); // free(ctx_w);
} }
} }
...@@ -14,7 +14,7 @@ extern "C" { ...@@ -14,7 +14,7 @@ extern "C" {
struct sass_context_wrapper { struct sass_context_wrapper {
Sass_Data_Context* dctx; Sass_Data_Context* dctx;
Sass_File_Context* fctx; Sass_File_Context* fctx;
Persistent<Object> stats; Persistent<Object> result;
uv_work_t request; uv_work_t request;
uv_mutex_t importer_mutex; uv_mutex_t importer_mutex;
uv_cond_t importer_condition_variable; uv_cond_t importer_condition_variable;
......
...@@ -8,7 +8,19 @@ var assert = require('assert'), ...@@ -8,7 +8,19 @@ var assert = require('assert'),
describe('api', function() { describe('api', function() {
describe('.render(options)', function() { describe('.render(options)', function() {
it('should compile sass to css', function(done) { it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
sass.render({
file: fixture('simple/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();
}
});
});
it('should compile sass to css with data', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8'); var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8').trim(); var expected = read(fixture('simple/expected.css'), 'utf8').trim();
...@@ -104,19 +116,6 @@ describe('api', function() { ...@@ -104,19 +116,6 @@ describe('api', function() {
}); });
}); });
it('should compile with stats', function(done) {
var src = fixture('precision/index.scss');
sass.render({
file: src,
sourceMap: true,
success: function(result) {
assert.equal(result.stats.entry, src);
done();
}
});
});
it('should contain all included files in stats when data is passed', function(done) { it('should contain all included files in stats when data is passed', function(done) {
var src = fixture('include-files/index.scss'); var src = fixture('include-files/index.scss');
var expected = [ var expected = [
...@@ -134,7 +133,7 @@ describe('api', function() { ...@@ -134,7 +133,7 @@ describe('api', function() {
}); });
}); });
it('should override imports with custom importer', function(done) { it('should override imports with custom importer with data', function(done) {
var src = read(fixture('include-files/index.scss'), 'utf8'); var src = read(fixture('include-files/index.scss'), 'utf8');
sass.render({ sass.render({
...@@ -151,10 +150,34 @@ describe('api', function() { ...@@ -151,10 +150,34 @@ describe('api', function() {
} }
}); });
}); });
it('should override imports with custom importer with file', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev, done) {
done({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
});
}); });
describe('.renderSync(options)', function() { describe('.renderSync(options)', function() {
it('should compile sass to css', function(done) { it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({file: fixture('simple/index.scss')});
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();
});
it('should compile sass to css with data', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8'); var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8').trim(); var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({data: src}); var result = sass.renderSync({data: src});
...@@ -183,7 +206,7 @@ describe('api', function() { ...@@ -183,7 +206,7 @@ describe('api', function() {
done(); done();
}); });
it('should override imports with custom importer', function(done) { it('should override imports with custom importer with data', function(done) {
var src = read(fixture('include-files/index.scss'), 'utf8'); var src = read(fixture('include-files/index.scss'), 'utf8');
var result = sass.renderSync({ var result = sass.renderSync({
...@@ -199,6 +222,21 @@ describe('api', function() { ...@@ -199,6 +222,21 @@ describe('api', function() {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
it('should override imports with custom importer with file', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev, finish) {
finish({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
}); });
describe('.render({stats: {}})', function() { describe('.render({stats: {}})', function() {
......
Subproject commit 074ae3b24bfc3ff19a98efdec02415ed6fd5759a Subproject commit be28a5a4dbfb8b6bc137609733ca46eed3d6b3aa
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