diff --git a/gyp/pylib/gyp/easy_xml.py b/gyp/pylib/gyp/easy_xml.py index 2b0bb60cb4..841f31f925 100644 --- a/gyp/pylib/gyp/easy_xml.py +++ b/gyp/pylib/gyp/easy_xml.py @@ -4,6 +4,7 @@ import re import os +import locale def XmlToString(content, encoding='utf-8', pretty=False): @@ -115,11 +116,10 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, xml_string = XmlToString(content, encoding, pretty) if win32 and os.linesep != '\r\n': xml_string = xml_string.replace('\n', '\r\n') - - try: - xml_string = xml_string.encode(encoding) - except Exception: - xml_string = unicode(xml_string, 'latin-1').encode(encoding) + + default_encoding = locale.getdefaultlocale()[1] + if default_encoding.upper() != encoding.upper(): + xml_string = xml_string.decode(default_encoding).encode(encoding) # Get the old content try: diff --git a/test/fixtures/test-charmap.py b/test/fixtures/test-charmap.py new file mode 100644 index 0000000000..43e0c5ffc8 --- /dev/null +++ b/test/fixtures/test-charmap.py @@ -0,0 +1,19 @@ +import sys +import locale + +reload(sys) + +def main(): + encoding = locale.getdefaultlocale()[1] + sys.setdefaultencoding(encoding) + textmap = { + 'cp936': u'\u4e2d\u6587', + 'cp1252': u'Lat\u012Bna', + 'cp932': u'\u306b\u307b\u3093\u3054' + } + if textmap.has_key(encoding): + print textmap[encoding] + return True + +if __name__ == '__main__': + print main() diff --git a/test/test-addon.js b/test/test-addon.js index c2a71f4498..f4bfd930e4 100644 --- a/test/test-addon.js +++ b/test/test-addon.js @@ -1,10 +1,35 @@ 'use strict' var test = require('tape') -var execFile = require('child_process').execFile var path = require('path') +var fs = require('graceful-fs') +var child_process = require('child_process') var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') +var execFileSync = child_process.execFileSync +var execFile = child_process.execFile + +function runHello() { + var testCode = "console.log(require('hello_world').hello())" + return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString() +} + +function getEncoding() { + var code = 'import locale;print locale.getdefaultlocale()[1]' + return execFileSync('python', ['-c', code]).toString().trim() +} + +function checkCharmapValid() { + var data + try { + data = execFileSync('python', ['fixtures/test-charmap.py'], + { cwd: __dirname }) + } catch (err) { + return false + } + var lines = data.toString().trim().split('\n') + return lines.pop() === 'True' +} test('build simple addon', function (t) { t.plan(3) @@ -16,12 +41,72 @@ test('build simple addon', function (t) { var lastLine = logLines[logLines.length-1] t.strictEqual(err, null) t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + t.strictEqual(runHello().trim(), 'world') + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') +}) + +test('build simple addon in path with non-ascii characters', function (t) { + t.plan(1) + + if (!checkCharmapValid()) { + return t.skip('python console app can\'t encode non-ascii character.') + } + + var testDirNames = { + 'cp936': '文件夹', + 'cp1252': 'Latīna', + 'cp932': 'フォルダ' + } + // Select non-ascii characters by current encoding + var testDirName = testDirNames[getEncoding()] + // If encoding is UTF-8 or other then no need to test + if (!testDirName) { + return t.skip('no need to test') + } + + t.plan(3) + + var data, configPath = path.join(addonPath, 'build', 'config.gypi') + try { + data = fs.readFileSync(configPath, 'utf8') + } catch (err) { + t.error(err) + return + } + var config = JSON.parse(data.replace(/\#.+\n/, '')) + var nodeDir = config.variables.nodedir + var testNodeDir = path.join(addonPath, testDirName) + // Create symbol link to path with non-ascii characters + try { + fs.symlinkSync(nodeDir, testNodeDir, 'dir') + } catch (err) { + switch (err.code) { + case 'EEXIST': break + case 'EPERM': + t.error(err, 'Please try to running console as an administrator') + return + default: + t.error(err) + return + } + } + + var cmd = [nodeGyp, 'rebuild', '-C', addonPath, + '--loglevel=verbose', '-nodedir=' + testNodeDir] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { try { - var binding = require('hello_world') - t.strictEqual(binding.hello(), 'world') - } catch (error) { - t.error(error, 'load module') + fs.unlink(testNodeDir) + } catch (err) { + t.error(err) } + + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length-1] + t.strictEqual(err, null) + t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + t.strictEqual(runHello().trim(), 'world') }) proc.stdout.setEncoding('utf-8') proc.stderr.setEncoding('utf-8')