diff --git a/README.md b/README.md index 09ce36b..a2ba949 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ koa-locales koa locales, i18n solution for koa: 1. All locales resources location on `options.dirs`. -2. resources file supports: `*.js`, `*.json` and `*.properties`, see [examples](test/locales/). +2. resources file supports: `*.js`, `*.json`, `*.yml`, `*.yaml` and `*.properties`, see [examples](test/locales/). 3. One api: `__(key[, value, ...])`. 4. Auto detect request locale from `query`, `cookie` and `header: Accept-Language`. diff --git a/index.js b/index.js index 9f3ee2b..52b88e2 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ const fs = require('fs'); const path = require('path'); const ms = require('humanize-ms'); const assign = require('object-assign'); +const yaml = require('js-yaml'); const DEFAULT_OPTIONS = { defaultLocale: 'en-US', @@ -18,7 +19,7 @@ const DEFAULT_OPTIONS = { writeCookie: true, cookieMaxAge: '1y', dir: undefined, - dirs: [ path.join(process.cwd(), 'locales') ], + dirs: [path.join(process.cwd(), 'locales')], functionName: '__', }; @@ -62,6 +63,8 @@ module.exports = function (app, options) { resource = flattening(require(filepath)); } else if (name.endsWith('.properties')) { resource = ini.parse(fs.readFileSync(filepath, 'utf8')); + } else if (name.endsWith('.yml') || name.endsWith('.yaml')) { + resource = flattening(yaml.safeLoad(fs.readFileSync(filepath, 'utf8'))); } resources[locale] = resources[locale] || {}; @@ -122,7 +125,7 @@ module.exports = function (app, options) { // __(locale, key, value1, ...) const args = new Array(arguments.length - 1); args[0] = text; - for(let i = 2; i < arguments.length; i++) { + for (let i = 2; i < arguments.length; i++) { args[i - 1] = arguments[i]; } return util.format.apply(util, args); @@ -145,7 +148,7 @@ module.exports = function (app, options) { } const args = new Array(arguments.length + 1); args[0] = locale; - for(let i = 0; i < arguments.length; i++) { + for (let i = 0; i < arguments.length; i++) { args[i + 1] = arguments[i]; } return gettext.apply(this, args); @@ -293,8 +296,8 @@ function flattening(data) { const result = {}; - function deepFlat (data, keys) { - Object.keys(data).forEach(function(key) { + function deepFlat(data, keys) { + Object.keys(data).forEach(function (key) { const value = data[key]; const k = keys ? keys + '.' + key : key; if (isObject(value)) { diff --git a/package.json b/package.json index e0647d0..18e243b 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "debug": "^2.6.0", "humanize-ms": "^1.2.0", "ini": "^1.3.4", + "js-yaml": "^3.13.1", + "npminstall": "^3.23.0", "object-assign": "^4.1.0" }, "devDependencies": { diff --git a/test/index.test.js b/test/index.test.js index e0e9a40..78e4d96 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -15,37 +15,37 @@ describe('koa-locales.test.js', function () { it('should use default locale: en-US', function (done) { request(app.callback()) - .get('/') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=[^;]+ GMT$/) - .expect(200, done); + .get('/') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=[^;]+ GMT$/) + .expect(200, done); }); - it('should not set locale cookie after header sent', function(done) { + it('should not set locale cookie after header sent', function (done) { request(app.callback()) - .get('/headerSent') - .expect('foo') - .expect(200, function(err) { - assert(!err, err && err.message); - setTimeout(done, 50); - }); + .get('/headerSent') + .expect('foo') + .expect(200, function (err) { + assert(!err, err && err.message); + setTimeout(done, 50); + }); }); }); @@ -56,27 +56,27 @@ describe('koa-locales.test.js', function () { it('should use default locale: en-US', function (done) { request(app.callback()) - .get('/') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=[^;]+; domain=.foo.com$/) - .expect(200, done); + .get('/') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=[^;]+; domain=.foo.com$/) + .expect(200, done); }); }); @@ -98,118 +98,7 @@ describe('koa-locales.test.js', function () { it('should use default locale: en-US', function (done) { request(app.callback()) - .get('/') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) - .expect(200, done); - }); - - it('should gettext work on app.__(locale, key, value)', function (done) { - request(app.callback()) - .get('/app_locale_zh') - .expect({ - email: '邮箱1', - }) - .expect(200, done); - }); - - describe('query.locale', function () { - it('should use query locale: zh-CN', function (done) { - request(app.callback()) - .get('/?locale=zh-CN') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) - .expect(200, done); - }); - - it('should use query locale: de on *.properties format', function (done) { - request(app.callback()) - .get('/?locale=de') - .expect({ - email: 'Emailde', - hello: 'Hallo fengmk2, wie geht es dir heute?', - message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) - .expect(200, done); - }); - - it('should use query locale and change cookie locale', function (done) { - request(app.callback()) - .get('/?locale=zh-CN') - .set('cookie', 'locale=zh-TW') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) - .expect(200, done); - }); - - it('should ignore invalid locale value', function (done) { - request(app.callback()) - .get('/?locale=xss') + .get('/') .expect({ email: 'Email', hello: 'Hello fengmk2, how are you today?', @@ -230,60 +119,171 @@ describe('koa-locales.test.js', function () { }) .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) .expect(200, done); + }); + + it('should gettext work on app.__(locale, key, value)', function (done) { + request(app.callback()) + .get('/app_locale_zh') + .expect({ + email: '邮箱1', + }) + .expect(200, done); + }); + + describe('query.locale', function () { + it('should use query locale: zh-CN', function (done) { + request(app.callback()) + .get('/?locale=zh-CN') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) + .expect(200, done); + }); + + it('should use query locale: de on *.properties format', function (done) { + request(app.callback()) + .get('/?locale=de') + .expect({ + email: 'Emailde', + hello: 'Hallo fengmk2, wie geht es dir heute?', + message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) + .expect(200, done); + }); + + it('should use query locale and change cookie locale', function (done) { + request(app.callback()) + .get('/?locale=zh-CN') + .set('cookie', 'locale=zh-TW') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) + .expect(200, done); + }); + + it('should ignore invalid locale value', function (done) { + request(app.callback()) + .get('/?locale=xss') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) + .expect(200, done); }); it('should use localeAlias', function (done) { request(cookieFieldMapApp.callback()) - .get('/?locale=de-de') - .expect({ - email: 'Emailde', - hello: 'Hallo fengmk2, wie geht es dir heute?', - message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=de-de') + .expect({ + email: 'Emailde', + hello: 'Hallo fengmk2, wie geht es dir heute?', + message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) + .expect(200, done); }); it('should use query locale and response without set-cookie', function (done) { request(appNotWriteCookie.callback()) - .get('/?locale=zh-CN') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect(function(res) { - if(res.headers['set-cookie'] || res.headers['Set-Cookie']){ - throw new Error('should not write cookie'); - } - }) - .expect(200, done); + .get('/?locale=zh-CN') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect(function (res) { + if (res.headers['set-cookie'] || res.headers['Set-Cookie']) { + throw new Error('should not write cookie'); + } + }) + .expect(200, done); }); }); @@ -291,30 +291,30 @@ describe('koa-locales.test.js', function () { describe('cookie.locale', function () { it('should use cookie locale: zh-CN', function (done) { request(app.callback()) - .get('/?locale=') - .set('cookie', 'locale=zh-cn') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect(function (res) { - assert(!res.headers['set-cookie']); - }) - .expect(200, done); + .get('/?locale=') + .set('cookie', 'locale=zh-cn') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect(function (res) { + assert(!res.headers['set-cookie']); + }) + .expect(200, done); }); }); @@ -323,154 +323,154 @@ describe('koa-locales.test.js', function () { done = pedding(3, done); request(app.callback()) - .get('/?locale=') - .set('Accept-Language', 'zh-CN') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .set('Accept-Language', 'zh-CN') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) + .expect(200, done); request(app.callback()) - .get('/?locale=') - .set('Accept-Language', 'zh-CN,zh;q=0.8') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .set('Accept-Language', 'zh-CN,zh;q=0.8') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) + .expect(200, done); request(app.callback()) - .get('/?locale=') - .set('Accept-Language', 'en;q=0.8, es, zh_CN') - .expect({ - email: '邮箱1', - hello: 'fengmk2,今天过得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性别', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .set('Accept-Language', 'en;q=0.8, es, zh_CN') + .expect({ + email: '邮箱1', + hello: 'fengmk2,今天过得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性别', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/) + .expect(200, done); }); it('should work with "Accept-Language: " header', function (done) { request(app.callback()) - .get('/?locale=') - .set('Accept-Language', '') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .set('Accept-Language', '') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) + .expect(200, done); }); it('should work with "Accept-Language: en"', function (done) { request(app.callback()) - .get('/') - .set('Accept-Language', 'en') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) - .expect(200, done); + .get('/') + .set('Accept-Language', 'en') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) + .expect(200, done); }); it('should work with "Accept-Language: de-de" by localeAlias', function (done) { request(cookieFieldMapApp.callback()) - .get('/') - .set('Accept-Language', 'ja,de-de;q=0.8') - .expect({ - email: 'Emailde', - hello: 'Hallo fengmk2, wie geht es dir heute?', - message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) - .expect(200, done); + .get('/') + .set('Accept-Language', 'ja,de-de;q=0.8') + .expect({ + email: 'Emailde', + hello: 'Hallo fengmk2, wie geht es dir heute?', + message: 'Hallo fengmk2, wie geht es dir heute? Wie war dein 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/) + .expect(200, done); }); it('should mock acceptsLanguages return string', function (done) { @@ -478,27 +478,56 @@ describe('koa-locales.test.js', function () { return 'zh-TW'; }); request(app.callback()) - .get('/?locale=') - .expect({ - email: '郵箱', - hello: 'fengmk2,今天過得如何?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: '', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': '性別', - 'name': '姓名', - }) - .expect('Set-Cookie', /^locale=zh\-tw; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .expect({ + email: '郵箱', + hello: 'fengmk2,今天過得如何?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': '性別', + 'name': '姓名', + }) + .expect('Set-Cookie', /^locale=zh\-tw; path=\/; expires=\w+/) + .expect(200, done); + }); + + it('should mock acceptsLanguages return string', function (done) { + mm(app.request, 'acceptsLanguages', function () { + return 'fr'; + }); + request(app.callback()) + .get('/?locale=fr') + .set('Accept-Language', 'fr;q=0.8, fr, fr') + .expect({ + email: 'le email', + hello: 'fengmk2, Comment allez-vous', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: '', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + gender: 'le sexe', + name: 'prénom', + }) + .expect('Set-Cookie', /^locale=fr; path=\/; expires=\w+/) + .expect(200, done); }); it('should mock acceptsLanguages return null', function (done) { @@ -506,31 +535,31 @@ describe('koa-locales.test.js', function () { return null; }); request(app.callback()) - .get('/?locale=') - .expect({ - email: 'Email', - hello: 'Hello fengmk2, how are you today?', - message: 'Hello fengmk2, how are you today? How was your 18.', - empty: '', - notexists_key: 'key not exists', - empty_string: '', - empty_value: 'emptyValue', - novalue: 'key %s ok', - arguments3: '1 2 3', - arguments4: '1 2 3 4', - arguments5: '1 2 3 4 5', - arguments6: '1 2 3 4 5. 6', - values: 'foo bar foo bar {2} {100}', - object: 'foo bar foo bar {z}', - 'gender': 'model.user.fields.gender', - 'name': 'model.user.fields.name', - }) - .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) - .expect(200, done); + .get('/?locale=') + .expect({ + email: 'Email', + hello: 'Hello fengmk2, how are you today?', + message: 'Hello fengmk2, how are you today? How was your 18.', + empty: '', + notexists_key: 'key not exists', + empty_string: '', + empty_value: 'emptyValue', + novalue: 'key %s ok', + arguments3: '1 2 3', + arguments4: '1 2 3 4', + arguments5: '1 2 3 4 5', + arguments6: '1 2 3 4 5. 6', + values: 'foo bar foo bar {2} {100}', + object: 'foo bar foo bar {z}', + 'gender': 'model.user.fields.gender', + 'name': 'model.user.fields.name', + }) + .expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/) + .expect(200, done); }); }); - describe('__getLocale and __getLocaleOrigin', function() { + describe('__getLocale and __getLocaleOrigin', function () { it('should __getLocale and __getLocaleOrigin from cookie', function () { return request(app.callback()) .get('/origin') @@ -558,7 +587,7 @@ describe('koa-locales.test.js', function () { }); }); - describe('__setLocale', function() { + describe('__setLocale', function () { it('should set locale and cookie', function () { return request(app.callback()) .get('/set') @@ -606,7 +635,7 @@ function createApp(options) { if (this.url === '/headerSent') { this.body = 'foo'; const that = this; - setTimeout(function() { + setTimeout(function () { that[fname]('Email'); }, 10); return; @@ -628,7 +657,7 @@ function createApp(options) { arguments5: this[fname]('%s %s %s %s %s', 1, 2, 3, 4, 5), arguments6: this[fname]('%s %s %s %s %s.', 1, 2, 3, 4, 5, 6), values: this[fname]('{0} {1} {0} {1} {2} {100}', ['foo', 'bar']), - object: this[fname]('{foo} {bar} {foo} {bar} {z}', {foo: 'foo', bar: 'bar'}), + object: this[fname]('{foo} {bar} {foo} {bar} {z}', { foo: 'foo', bar: 'bar' }), }; }); diff --git a/test/locales/fr.yml b/test/locales/fr.yml new file mode 100644 index 0000000..c206209 --- /dev/null +++ b/test/locales/fr.yml @@ -0,0 +1,8 @@ +Email: "le email" +emptyValue: "" +Hello %s, how are you today?: "%s, Comment allez-vous" +model: + user: + fields: + name: "prénom" + gender: "le sexe" \ No newline at end of file