Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions js/src/javascript/beautifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,17 @@ Beautifier.prototype.handle_operator = function(current_token) {
// The conditional starts the statement if appropriate.
} else {
var preserve_statement_flags = !isGeneratorAsterisk;
var is_prefix_operator = current_token.newlines && in_array(current_token.text, ['--', '++', '~', '!']) &&
!is_expression(this._flags.mode) &&
(this._flags.last_token.type !== TOKEN.OPERATOR || (this._flags.last_token.text === '--' || this._flags.last_token.text === '++')) &&
this._flags.last_token.type !== TOKEN.EQUALS;
if (is_prefix_operator) {
preserve_statement_flags = false;
}
this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
if (is_prefix_operator) {
this.print_newline(false, false);
}
}

// hack for actionscript's import .*;
Expand Down Expand Up @@ -1294,13 +1304,7 @@ Beautifier.prototype.handle_operator = function(current_token) {

// http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
// if there is a newline between -- or ++ and anything else we should preserve it.
if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines;
if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) {
this.restore_mode();
}
this.print_newline(new_line_needed, true);
}


if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
// for (;; ++i)
Expand Down
65 changes: 65 additions & 0 deletions js/test/core/test_output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*jshint mocha:true */
'use strict';

var assert = require('assert');
var Output = require('../../src/core/output').Output;

function makeOutput(overrides) {
var options = {
indent_size: 4,
indent_char: ' ',
indent_with_tabs: false,
indent_level: 0,
end_with_newline: false,
wrap_line_length: 0,
indent_empty_lines: false
};

Object.keys(overrides || {}).forEach(function(key) {
options[key] = overrides[key];
});

return new Output(options);
}

describe('Output', function() {
describe('ensure_empty_line_above', function() {
it('should insert a blank line before the current line when the previous line does not match', function() {
var output = makeOutput();

output.add_token('alpha');
output.add_new_line();
output.add_token('beta');
output.add_new_line();
output.add_token('gamma');

output.ensure_empty_line_above('skip', 'end');

assert.strictEqual(output.get_code('\n'), 'alpha\nbeta\n\ngamma');
});

it('should not insert a blank line when the previous line starts with the requested prefix', function() {
var output = makeOutput();

output.add_token('skip-this');
output.add_new_line();
output.add_token('gamma');

output.ensure_empty_line_above('skip', 'end');

assert.strictEqual(output.get_code('\n'), 'skip-this\ngamma');
});

it('should not insert a blank line when the previous line ends with the requested suffix', function() {
var output = makeOutput();

output.add_token('end');
output.add_new_line();
output.add_token('gamma');

output.ensure_empty_line_above('skip', 'end');

assert.strictEqual(output.get_code('\n'), 'end\ngamma');
});
});
});
251 changes: 251 additions & 0 deletions js/test/web-common-function-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
'use strict';

var assert = require('assert');
var fs = require('fs');
var path = require('path');
var vm = require('vm');

function createElementStub() {
var state = {
focused: false,
selected: false
};

var api = {
val: function(value) {
if (arguments.length > 0) {
state.value = value;
return api;
}
return state.value;
},
prop: function(name, value) {
if (arguments.length > 1) {
state[name] = value;
return api;
}
return state[name];
},
text: function(value) {
if (arguments.length > 0) {
state.text = value;
return api;
}
return state.text;
},
html: function(value) {
if (arguments.length > 0) {
state.html = value;
return api;
}
return state.html;
},
attr: function(name, value) {
if (arguments.length > 1) {
state[name] = value;
return api;
}
return state[name];
},
addClass: function(className) {
state.classes = state.classes || [];
state.classes.push(className);
return api;
},
removeClass: function(className) {
state.removedClasses = state.removedClasses || [];
state.removedClasses.push(className);
return api;
},
children: function() {
return api;
},
bind: function() {
return api;
},
change: function() {
return api;
},
click: function() {
return api;
},
show: function() {
state.hidden = false;
return api;
},
hide: function() {
state.hidden = true;
return api;
},
select: function() {
state.selected = true;
return api;
},
focus: function() {
state.focused = true;
return api;
},
remove: function() {
state.removed = true;
return api;
},
append: function() {
return api;
},
valState: state
};

return api;
}

function createContext() {
var elements = {};
var cookies = {};

function getElement(selector) {
if (!elements[selector]) {
elements[selector] = createElementStub();
}
return elements[selector];
}

var windowObject = {
location: {
href: 'http://localhost/'
},
navigator: {
platform: ''
},
screen: {
orientation: {
lock: function() {}
}
},
open: function() {
return {
focus: function() {}
};
},
matchMedia: function() {
return {
matches: false
};
}
};

var context = {
console: console,
window: windowObject,
document: {
querySelector: function() {
return null;
},
createElement: function() {
return {
style: {},
click: function() {},
setAttribute: function() {},
remove: function() {}
};
},
execCommand: function() {
return true;
},
body: {
appendChild: function() {}
}
},
Cookies: {
get: function(name) {
return cookies[name];
},
set: function(name, value) {
cookies[name] = value;
}
},
requirejs: function(deps, callback) {
if (typeof deps === 'function') {
deps();
return;
}
if (typeof callback === 'function') {
callback({});
}
},
$: function(selector) {
if (typeof selector === 'function') {
selector();
return;
}
return getElement(selector);
},
_elements: elements,
_cookies: cookies
};

context.requirejs.config = function() {};

return context;
}

function loadWebCommonFunctions() {
var context = createContext();
var source = fs.readFileSync(path.join(__dirname, '../../web/common-function.js'), 'utf8');
vm.runInNewContext(source, context, {
filename: 'web/common-function.js'
});
return context;
}

describe('web/common-function.js', function() {
it('hydrates the UI from stored cookie values', function() {
var context = loadWebCommonFunctions();

context._cookies.tabsize = '2';
context._cookies['brace-style'] = 'expand';
context._cookies['wrap-line-length'] = '80';
context._cookies['unescape-strings'] = 'on';
context._cookies.language = 'html';

context.read_settings_from_cookie();

assert.strictEqual(context._elements['#tabsize'].val(), '2');
assert.strictEqual(context._elements['#brace-style'].val(), 'expand');
assert.strictEqual(context._elements['#wrap-line-length'].val(), '80');
assert.strictEqual(context._elements['#unescape-strings'].prop('checked'), true);
assert.strictEqual(context._elements['#language'].val(), 'html');
});

it('clears the CodeMirror editor and restores focus', function() {
var context = loadWebCommonFunctions();
var calls = [];

context.the.editor = {
setValue: function(value) {
calls.push(['setValue', value]);
},
focus: function() {
calls.push(['focus']);
}
};

context.clearAll();

assert.deepStrictEqual(calls, [
['setValue', ''],
['focus']
]);
});

it('clears the textarea and restores focus when CodeMirror is not active', function() {
var context = loadWebCommonFunctions();
var source = context.$('#source');

context.the.editor = null;

context.clearAll();

assert.strictEqual(source.val(), '');
assert.strictEqual(source.prop('focused'), true);
});
});
Loading