"Missing translation" 当 运行 与 ember-i18n 包相关的 Ember 验收测试
"Missing translation" when running an Ember acceptance test related to ember-i18n package
我正在为 Ember 组件编写验收测试,该组件允许用户通过 ember-select-list
包提供的下拉菜单切换其 i18n 设置。我还使用 ember-i18n
包进行 i18n 设置。下拉组件如下所示:
import Ember from 'ember';
export default Ember.Component.extend({
i18n: Ember.inject.service(),
languagePreference: Ember.inject.service(),
classNames: ['language-dropdown'],
languageOptions: Ember.computed('i18n.locale', function() {
let i18n = this.get('i18n');
return i18n.get('locales').map((item) => {
return {
id: item,
name: i18n.t(`languages.${item}`)
};
});
}),
onFinish: null,
actions: {
selectLanguage(i18n) {
this.get('languagePreference').setUserI18nPreference(i18n);
this.get('onFinish')();
}
}
});
language-preference
服务如下所示:
import Ember from 'ember';
export default Ember.Service.extend({
i18n: Ember.inject.service(),
config: Ember.inject.service(),
setSessionI18nPreference() {
let setSessionI18n = (results) => {
let { preferences, userName } = results;
if (userName && preferences[userName]) {
this.set('i18n.locale', preferences[userName].i18n);
}
};
this._fetchUserPreferencesDB().then(setSessionI18n);
},
setUserI18nPreference(i18n) {
let setUserI18n = (results) => {
let { preferences, userName } = results;
if (preferences[userName] === undefined) {
preferences[userName] = {};
}
preferences[userName].i18n = i18n;
this.get('config.configDB').put(preferences);
this.set('i18n.locale', i18n);
};
this._fetchUserPreferencesDB().then(setUserI18n);
},
_fetchUserPreferencesDB() {
let configDB = this.get('config.configDB');
let userName;
return configDB.get('current_user').then((user) => {
userName = this._fetchUsername(user);
let preferences = configDB.get('preferences');
return Ember.RSVP.hash({ userName, preferences });
}).catch((err) => {
console.log(err);
if (err.status === 404) {
this._initPreferencesDB(userName, 'en');
}
});
},
_fetchUsername(user) {
switch (typeof user.value) {
case 'string':
return user.value;
case 'object':
return user.value.name;
default:
return undefined;
}
},
_initPreferencesDB(username, i18n) {
let doc = {
_id: 'preferences'
};
if (username != undefined) {
doc[username] = {
i18n: i18n || 'en'
};
}
this.get('config.configDB').put(doc);
}
});
对于验收测试,目前我有的是:
import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from 'hospitalrun/tests/helpers/start-app';
module('Acceptance | language dropdown', {
beforeEach() {
this.application = startApp();
},
afterEach() {
Ember.run(this.application, 'destroy');
}
});
test('setting a language preference persists after logout', (assert) => {
runWithPouchDump('default', () => {
authenticateUser({ name: 'foobar', prefix: 'p2' });
visit('/');
andThen(() => {
assert.equal(currentURL(), '/');
assert.equal(find('.view-current-title').text(), 'Welcome to HospitalRun!');
});
andThen(() => {
click('a.settings-trigger');
waitToAppear('.settings-nav');
// andThen(() => {
// select('.language-dropdown', 'French');
// andThen(() => {
// debugger;
// });
// });
});
});
});
这很好用,我的所有测试都通过了。但是当我取消注释当前被注释掉的块,并重新 运行 测试时,我看到多个测试失败,从全局错误开始:
not ok 66 PhantomJS 2.1 - Global error: Error: Missing translation: navigation.subnav.textReplacements at http://localhost:7357/assets/tests.js, line 12058
---
Log: |
{ type: 'error',
text: 'Error: Missing translation: navigation.subnav.textReplacements at http://localhost:7357/assets/tests.js, line 12058\n' }
...
not ok 67 PhantomJS 2.1 - Acceptance | language dropdown: setting a language preference persists after logout
---
actual: >
null
expected: >
null
stack: >
http://localhost:7357/assets/tests.js:12058
message: >
Error: Missing translation: navigation.subnav.textReplacements
Log: |
...
该应用程序在我的浏览器中运行良好(翻译文件都已就位,切换 i18n 时我可以在浏览器中看到正确的 i18n 输出)。 ember-i18n
文档说它应该与调用 startApp()
的测试一起正常工作,这个测试就是这样做的。对我来说奇怪的是,注释掉的行在未注释时不仅会破坏此测试,还会破坏其他文件中的测试。我猜它正在影响某些全局(在测试过程中)i18n 设置,并且此设置在测试完成后不会被拆除,但我不能确定。
代码在这里- https://github.com/richiethomas/hospitalrun-frontend/tree/debug
最新提交代表测试失败。
编辑:当我在 language-preference
内的 _fetchUserPreferencesDB
函数中放置一个调试器时,我能够调用 this.get('i18n.locales')
并看到我期望的语言环境,所以我知道原因在不同的环境中不是不同的语言环境(即 development
与 test
)。我什至调用了 this.get('i18n').t('navigation.subnav.textReplacements')
,这与失败测试所说的缺少相同的翻译值,我得到了正确的翻译。所以我真的不确定为什么测试失败。
所以显然我的测试试图使用德语翻译文件(没有 navigation.subnav.textReplacements
键),即使我的验收测试指定了法语。我通过 运行 Chrome 控制台中的测试验证了这一点,在失败行之前放置了一个调试器,并检查了 this.get('i18n._locale')
对象的 translations
属性。不知为何,我发现它们都是德语的。
因此,缺少翻译元素的谜团实际上掩盖了另一个谜团,这就是为什么即使在 PhantomJS 选择了法语 i18n 选项后,我的验收测试仍默认为德语。但这是另一个 post.
的主题
我正在为 Ember 组件编写验收测试,该组件允许用户通过 ember-select-list
包提供的下拉菜单切换其 i18n 设置。我还使用 ember-i18n
包进行 i18n 设置。下拉组件如下所示:
import Ember from 'ember';
export default Ember.Component.extend({
i18n: Ember.inject.service(),
languagePreference: Ember.inject.service(),
classNames: ['language-dropdown'],
languageOptions: Ember.computed('i18n.locale', function() {
let i18n = this.get('i18n');
return i18n.get('locales').map((item) => {
return {
id: item,
name: i18n.t(`languages.${item}`)
};
});
}),
onFinish: null,
actions: {
selectLanguage(i18n) {
this.get('languagePreference').setUserI18nPreference(i18n);
this.get('onFinish')();
}
}
});
language-preference
服务如下所示:
import Ember from 'ember';
export default Ember.Service.extend({
i18n: Ember.inject.service(),
config: Ember.inject.service(),
setSessionI18nPreference() {
let setSessionI18n = (results) => {
let { preferences, userName } = results;
if (userName && preferences[userName]) {
this.set('i18n.locale', preferences[userName].i18n);
}
};
this._fetchUserPreferencesDB().then(setSessionI18n);
},
setUserI18nPreference(i18n) {
let setUserI18n = (results) => {
let { preferences, userName } = results;
if (preferences[userName] === undefined) {
preferences[userName] = {};
}
preferences[userName].i18n = i18n;
this.get('config.configDB').put(preferences);
this.set('i18n.locale', i18n);
};
this._fetchUserPreferencesDB().then(setUserI18n);
},
_fetchUserPreferencesDB() {
let configDB = this.get('config.configDB');
let userName;
return configDB.get('current_user').then((user) => {
userName = this._fetchUsername(user);
let preferences = configDB.get('preferences');
return Ember.RSVP.hash({ userName, preferences });
}).catch((err) => {
console.log(err);
if (err.status === 404) {
this._initPreferencesDB(userName, 'en');
}
});
},
_fetchUsername(user) {
switch (typeof user.value) {
case 'string':
return user.value;
case 'object':
return user.value.name;
default:
return undefined;
}
},
_initPreferencesDB(username, i18n) {
let doc = {
_id: 'preferences'
};
if (username != undefined) {
doc[username] = {
i18n: i18n || 'en'
};
}
this.get('config.configDB').put(doc);
}
});
对于验收测试,目前我有的是:
import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from 'hospitalrun/tests/helpers/start-app';
module('Acceptance | language dropdown', {
beforeEach() {
this.application = startApp();
},
afterEach() {
Ember.run(this.application, 'destroy');
}
});
test('setting a language preference persists after logout', (assert) => {
runWithPouchDump('default', () => {
authenticateUser({ name: 'foobar', prefix: 'p2' });
visit('/');
andThen(() => {
assert.equal(currentURL(), '/');
assert.equal(find('.view-current-title').text(), 'Welcome to HospitalRun!');
});
andThen(() => {
click('a.settings-trigger');
waitToAppear('.settings-nav');
// andThen(() => {
// select('.language-dropdown', 'French');
// andThen(() => {
// debugger;
// });
// });
});
});
});
这很好用,我的所有测试都通过了。但是当我取消注释当前被注释掉的块,并重新 运行 测试时,我看到多个测试失败,从全局错误开始:
not ok 66 PhantomJS 2.1 - Global error: Error: Missing translation: navigation.subnav.textReplacements at http://localhost:7357/assets/tests.js, line 12058
---
Log: |
{ type: 'error',
text: 'Error: Missing translation: navigation.subnav.textReplacements at http://localhost:7357/assets/tests.js, line 12058\n' }
...
not ok 67 PhantomJS 2.1 - Acceptance | language dropdown: setting a language preference persists after logout
---
actual: >
null
expected: >
null
stack: >
http://localhost:7357/assets/tests.js:12058
message: >
Error: Missing translation: navigation.subnav.textReplacements
Log: |
...
该应用程序在我的浏览器中运行良好(翻译文件都已就位,切换 i18n 时我可以在浏览器中看到正确的 i18n 输出)。 ember-i18n
文档说它应该与调用 startApp()
的测试一起正常工作,这个测试就是这样做的。对我来说奇怪的是,注释掉的行在未注释时不仅会破坏此测试,还会破坏其他文件中的测试。我猜它正在影响某些全局(在测试过程中)i18n 设置,并且此设置在测试完成后不会被拆除,但我不能确定。
代码在这里- https://github.com/richiethomas/hospitalrun-frontend/tree/debug
最新提交代表测试失败。
编辑:当我在 language-preference
内的 _fetchUserPreferencesDB
函数中放置一个调试器时,我能够调用 this.get('i18n.locales')
并看到我期望的语言环境,所以我知道原因在不同的环境中不是不同的语言环境(即 development
与 test
)。我什至调用了 this.get('i18n').t('navigation.subnav.textReplacements')
,这与失败测试所说的缺少相同的翻译值,我得到了正确的翻译。所以我真的不确定为什么测试失败。
所以显然我的测试试图使用德语翻译文件(没有 navigation.subnav.textReplacements
键),即使我的验收测试指定了法语。我通过 运行 Chrome 控制台中的测试验证了这一点,在失败行之前放置了一个调试器,并检查了 this.get('i18n._locale')
对象的 translations
属性。不知为何,我发现它们都是德语的。
因此,缺少翻译元素的谜团实际上掩盖了另一个谜团,这就是为什么即使在 PhantomJS 选择了法语 i18n 选项后,我的验收测试仍默认为德语。但这是另一个 post.
的主题