Commit 65619ba4 by Adeel

API: Returns result as `Buffer`s not string.

* CSS and Map is casted as Buffer from binding.
Advantages:
  * Buffers are super fast.
  * User can write them to file as is.
  * User can forward to response stream as is.
  * User can strigify it as is:
    * `result.css.toString()`
    * `result.map.toString()` or
      `JSON.stringify(result.map)`
* Updates tests and CLI usage accordingly.
* Updates README to reflect the changes.

Issue URL: #711.
PR URL: #729.
parent b04137d0
......@@ -157,21 +157,21 @@ Default: `false`
node-sass supports standard node style asynchronous callbacks with the signature of `function(err, result)`. In error conditions, the `error` argument is populated with the error object. In success conditions, the `result` object is populated with an object describing the result of the render call.
### Error Object
* `message` - The error message.
* `line` - The line number of error.
* `column` - The column number of error.
* `status` - The status code.
* `file` - The filename of error. In case `file` option was not set (in favour of `data`), this will reflect the value `stdin`.
* `message` (String) - The error message.
* `line` (Number) - The line number of error.
* `column` (Number) - The column number of error.
* `status` (Number) - The status code.
* `file` (String) - The filename of error. In case `file` option was not set (in favour of `data`), this will reflect the value `stdin`.
### Result Object
* `css` - The compiled CSS. Write this to a file, or serve it out as needed.
* `map` - The source map
* `stats` - An object containing information about the compile. It contains the following keys:
* `entry` - The path to the scss file, or `data` if the source was not a file
* `start` - Date.now() before the compilation
* `end` - Date.now() after the compilation
* `duration` - *end* - *start*
* `includedFiles` - Absolute paths to all related scss files in no particular order.
* `css` (Buffer) - The compiled CSS. Write this to a file, or serve it out as needed.
* `map` (Buffer) - The source map
* `stats` (Object) - An object containing information about the compile. It contains the following keys:
* `entry` (String) - The path to the scss file, or `data` if the source was not a file
* `start` (Number) - Date.now() before the compilation
* `end` (Number) - Date.now() after the compilation
* `duration` (Number) - *end* - *start*
* `includedFiles` (Array) - Absolute paths to all related scss files in no particular order.
### Examples
......@@ -205,9 +205,9 @@ sass.render({
console.log(error.line);
}
else {
console.log(result.css);
console.log(result.css.toString());
console.log(result.stats);
console.log(result.map);
console.log(result.map.toString()); // or console.log(JSON.stringify(result.map));
}
});
// OR
......
......@@ -42,10 +42,10 @@ module.exports = function(options, emitter) {
};
if (!options.dest || options.stdin) {
emitter.emit('log', result.css);
emitter.emit('log', result.css.toString());
if (options.sourceMap) {
emitter.emit('log', result.map);
emitter.emit('log', result.map.toString());
}
return done();
......@@ -58,13 +58,13 @@ module.exports = function(options, emitter) {
return emitter.emit('error', chalk.red(err));
}
fs.writeFile(options.dest, result.css, function(err) {
fs.writeFile(options.dest, result.css.toString(), function(err) {
if (err) {
return emitter.emit('error', chalk.red(err));
}
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.dest));
emitter.emit('write', err, options.dest, result.css);
emitter.emit('write', err, options.dest, result.css.toString());
done();
});
});
......@@ -78,12 +78,12 @@ module.exports = function(options, emitter) {
}
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, result.sourceMap);
emitter.emit('write-source-map', err, options.sourceMap, result.map);
done();
});
}
emitter.emit('render', result.css);
emitter.emit('render', result.css.toString());
};
var error = function(error) {
......
......@@ -146,7 +146,7 @@ void extract_options(Local<Object> options, void* cptr, sass_context_wrapper* ct
sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w));
}
if(!is_file) {
if (!is_file) {
sass_option_set_input_path(sass_options, create_string(options->Get(NanNew("file"))));
}
......@@ -177,34 +177,22 @@ void get_stats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
}
void get_source_map(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanScope();
Handle<Value> source_map;
if (sass_context_get_error_status(ctx)) {
return;
}
if (sass_context_get_source_map_string(ctx)) {
source_map = NanNew<String>(sass_context_get_source_map_string(ctx));
}
else {
source_map = NanNew<String>("{}");
}
NanNew(ctx_w->result)->Set(NanNew("map"), source_map);
}
int get_result(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
NanScope();
int status = sass_context_get_error_status(ctx);
if (status == 0) {
NanNew(ctx_w->result)->Set(NanNew("css"), NanNew<String>(sass_context_get_output_string(ctx)));
const char* css = sass_context_get_output_string(ctx);
const char* map = sass_context_get_source_map_string(ctx);
NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, strlen(css)));
get_stats(ctx_w, ctx);
get_source_map(ctx_w, ctx);
if (map) {
NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, strlen(map)));
}
}
else if (is_sync) {
NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx)));
......@@ -233,7 +221,7 @@ void make_callback(uv_work_t* req) {
// if no error, do callback(null, result)
ctx_w->success_callback->Call(0, 0);
}
else if(ctx_w->error_callback) {
else if (ctx_w->error_callback) {
// if error, do callback(error)
const char* err = sass_context_get_error_json(ctx);
Local<Value> argv[] = {
......
......@@ -14,7 +14,7 @@ describe('api', function() {
sass.render({
file: fixture('simple/index.scss')
}, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
});
......@@ -59,7 +59,7 @@ describe('api', function() {
sass.render({
data: src
}, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
});
......@@ -72,7 +72,7 @@ describe('api', function() {
data: src,
indentedSyntax: true
}, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
});
......@@ -98,7 +98,7 @@ describe('api', function() {
fixture('include-path/lib')
]
}, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
});
......@@ -132,7 +132,7 @@ describe('api', function() {
data: src,
precision: 10
}, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
});
......@@ -167,7 +167,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -182,7 +182,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -197,7 +197,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -212,7 +212,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -226,7 +226,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
});
......@@ -240,7 +240,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
});
......@@ -254,7 +254,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
});
......@@ -268,7 +268,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
});
......@@ -282,7 +282,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -296,7 +296,7 @@ describe('api', function() {
});
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -310,7 +310,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -324,7 +324,7 @@ describe('api', function() {
};
}
}, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});
......@@ -382,7 +382,7 @@ describe('api', function() {
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'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
......@@ -424,19 +424,19 @@ describe('api', function() {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({ data: src });
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
it('should compile sass to css using indented syntax', function(done) {
var src = read(fixture('indent/index.sass'), 'utf8');
var expected = read(fixture('indent/expected.css'), 'utf8').trim();
var css = sass.renderSync({
var result = sass.renderSync({
data: src,
indentedSyntax: true
}).css.trim();
});
assert.equal(css, expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done();
});
......@@ -463,7 +463,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
......@@ -478,7 +478,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
......@@ -492,7 +492,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
......@@ -506,7 +506,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), '');
assert.equal(result.css.toString().trim(), '');
done();
});
......@@ -520,7 +520,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
......@@ -534,7 +534,7 @@ describe('api', function() {
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
......
......@@ -42,7 +42,7 @@ describe('spec', function() {
includePaths: t.paths
}, function(error, result) {
assert(!error);
assert.equal(util.normalize(result.css), expected);
assert.equal(util.normalize(result.css.toString()), expected);
done();
});
});
......
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