Merge branch 'js-translations' into 28433-internationalise-cycle-analytics-page
Conflicts: config/webpack.config.js
This commit is contained in:
commit
086700fa5b
27 changed files with 214 additions and 43 deletions
|
@ -7,3 +7,4 @@
|
|||
/vendor/
|
||||
karma.config.js
|
||||
webpack.config.js
|
||||
/app/assets/javascripts/locale/**/*.js
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -256,6 +256,7 @@ gem 'premailer-rails', '~> 1.9.0'
|
|||
|
||||
# I18n
|
||||
gem 'gettext_i18n_rails', '~> 1.8.0'
|
||||
gem 'gettext_i18n_rails_js', '~> 1.2.0'
|
||||
gem 'gettext', '~> 3.2.2', require: false, group: :development
|
||||
|
||||
# Metrics
|
||||
|
|
|
@ -259,6 +259,11 @@ GEM
|
|||
text (>= 1.3.0)
|
||||
gettext_i18n_rails (1.8.0)
|
||||
fast_gettext (>= 0.9.0)
|
||||
gettext_i18n_rails_js (1.2.0)
|
||||
gettext (>= 3.0.2)
|
||||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly (0.5.0)
|
||||
google-protobuf (~> 3.1)
|
||||
|
@ -534,6 +539,8 @@ GEM
|
|||
ast (~> 2.2)
|
||||
path_expander (1.0.1)
|
||||
pg (0.18.4)
|
||||
po_to_json (1.0.1)
|
||||
json (>= 1.6.0)
|
||||
poltergeist (1.9.0)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
|
@ -914,6 +921,7 @@ DEPENDENCIES
|
|||
gemojione (~> 3.0)
|
||||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.2.0)
|
||||
gitaly (~> 0.5.0)
|
||||
github-linguist (~> 4.7.0)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
|
|
|
@ -11,7 +11,7 @@ export default {
|
|||
aria-hidden="true"
|
||||
title="Limited to showing 50 events at most"
|
||||
data-placement="top"></i>
|
||||
Showing 50 events
|
||||
{{ 'Showing %d event' | translate-plural('Showing %d events', 50) }}
|
||||
</span>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -28,11 +28,11 @@ global.cycleAnalytics.StageCodeComponent = Vue.extend({
|
|||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
Opened
|
||||
{{ 'Opened' | translate }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
by
|
||||
{{ 'by' | translate }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -28,11 +28,11 @@ global.cycleAnalytics.StageIssueComponent = Vue.extend({
|
|||
<a :href="issue.url" class="issue-link">#{{ issue.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
Opened
|
||||
{{ 'Opened' | translate }}
|
||||
<a :href="issue.url" class="issue-date">{{ issue.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
by
|
||||
{{ 'by' | translate }}
|
||||
<a :href="issue.author.webUrl" class="issue-author-link">
|
||||
{{ issue.author.name }}
|
||||
</a>
|
||||
|
|
|
@ -31,10 +31,10 @@ global.cycleAnalytics.StagePlanComponent = Vue.extend({
|
|||
</a>
|
||||
</h5>
|
||||
<span>
|
||||
First
|
||||
{{ 'First' | translate }}
|
||||
<span class="commit-icon">${iconCommit}</span>
|
||||
<a :href="commit.commitUrl" class="commit-hash-link monospace">{{ commit.shortSha }}</a>
|
||||
pushed by
|
||||
{{ 'pushed by' | translate }}
|
||||
<a :href="commit.author.webUrl" class="commit-author-link">
|
||||
{{ commit.author.name }}
|
||||
</a>
|
||||
|
|
|
@ -28,11 +28,11 @@ global.cycleAnalytics.StageProductionComponent = Vue.extend({
|
|||
<a :href="issue.url" class="issue-link">#{{ issue.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
Opened
|
||||
{{ 'Opened' | translate }}
|
||||
<a :href="issue.url" class="issue-date">{{ issue.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
by
|
||||
{{ 'by' | translate }}
|
||||
<a :href="issue.author.webUrl" class="issue-author-link">
|
||||
{{ issue.author.name }}
|
||||
</a>
|
||||
|
|
|
@ -28,11 +28,11 @@ global.cycleAnalytics.StageReviewComponent = Vue.extend({
|
|||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
Opened
|
||||
{{ 'Opened' | translate }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
by
|
||||
{{ 'by' | translate }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
<template v-if="mergeRequest.state === 'closed'">
|
||||
|
|
|
@ -32,7 +32,7 @@ global.cycleAnalytics.StageStagingComponent = Vue.extend({
|
|||
</h5>
|
||||
<span>
|
||||
<a :href="build.url" class="build-date">{{ build.date }}</a>
|
||||
by
|
||||
{{ 'by' | translate }}
|
||||
<a :href="build.author.webUrl" class="issue-author-link">
|
||||
{{ build.author.name }}
|
||||
</a>
|
||||
|
|
|
@ -12,9 +12,9 @@ global.cycleAnalytics.TotalTimeComponent = Vue.extend({
|
|||
template: `
|
||||
<span class="total-time">
|
||||
<template v-if="Object.keys(time).length">
|
||||
<template v-if="time.days">{{ time.days }} <span>{{ time.days === 1 ? 'day' : 'days' }}</span></template>
|
||||
<template v-if="time.hours">{{ time.hours }} <span>hr</span></template>
|
||||
<template v-if="time.mins && !time.days">{{ time.mins }} <span>mins</span></template>
|
||||
<template v-if="time.days">{{ time.days }} <span>{{ 'day' | translate-plural('days', time.days) }}</span></template>
|
||||
<template v-if="time.hours">{{ time.hours }} <span v-translate>hr</span></template>
|
||||
<template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ 'min' | translate-plural('mins', time.mins) }}</span></template>
|
||||
<template v-if="time.seconds && Object.keys(time).length === 1 || time.seconds === 0">{{ time.seconds }} <span>s</span></template>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import Vue from 'vue';
|
||||
import Cookies from 'js-cookie';
|
||||
import Translate from '../vue_shared/translate';
|
||||
import LimitWarningComponent from './components/limit_warning_component';
|
||||
|
||||
require('./components/stage_code_component');
|
||||
|
@ -16,6 +17,8 @@ require('./cycle_analytics_service');
|
|||
require('./cycle_analytics_store');
|
||||
require('./default_event_objects');
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
$(() => {
|
||||
const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
|
||||
const cycleAnalyticsEl = document.querySelector('#cycle-analytics');
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
|
||||
import locale from '~/locale';
|
||||
|
||||
require('../lib/utils/text_utility');
|
||||
const DEFAULT_EVENT_OBJECTS = require('./default_event_objects');
|
||||
|
||||
|
@ -7,13 +9,13 @@ const global = window.gl || (window.gl = {});
|
|||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
const EMPTY_STAGE_TEXTS = {
|
||||
issue: 'The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.',
|
||||
plan: 'The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.',
|
||||
code: 'The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.',
|
||||
test: 'The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.',
|
||||
review: 'The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.',
|
||||
staging: 'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.',
|
||||
production: 'The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.',
|
||||
issue: locale.gettext('The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.'),
|
||||
plan: locale.gettext('The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.'),
|
||||
code: locale.gettext('The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.'),
|
||||
test: locale.gettext('The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.'),
|
||||
review: locale.gettext('The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.'),
|
||||
staging: locale.gettext('The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.'),
|
||||
production: locale.gettext('The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.'),
|
||||
};
|
||||
|
||||
global.cycleAnalytics.CycleAnalyticsStore = {
|
||||
|
|
1
app/assets/javascripts/locale/de/app.js
Normal file
1
app/assets/javascripts/locale/de/app.js
Normal file
|
@ -0,0 +1 @@
|
|||
var locales = locales || {}; locales['de'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-12 22:37-0500","Last-Translator":"FULL NAME <EMAIL@ADDRESS>","Language-Team":"German","Language":"de","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","lang":"de","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"Deutsch":[""],"English":[""],"Spanish":[""]}}};
|
1
app/assets/javascripts/locale/en/app.js
Normal file
1
app/assets/javascripts/locale/en/app.js
Normal file
|
@ -0,0 +1 @@
|
|||
var locales = locales || {}; locales['en'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-12 22:36-0500","Last-Translator":"FULL NAME <EMAIL@ADDRESS>","Language-Team":"English","Language":"en","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","lang":"en","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"Deutsch":[""],"English":[""],"Spanish":[""]}}};
|
1
app/assets/javascripts/locale/es/app.js
Normal file
1
app/assets/javascripts/locale/es/app.js
Normal file
|
@ -0,0 +1 @@
|
|||
var locales = locales || {}; locales['es'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-13 00:07-0500","Language-Team":"Spanish","Language":"es","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"","X-Generator":"Poedit 2.0.1","lang":"es","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"Deutsch":["Alemán"],"English":["Inglés"],"Spanish":["Español"]}}};
|
15
app/assets/javascripts/locale/index.js
Normal file
15
app/assets/javascripts/locale/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import Jed from 'jed';
|
||||
import de from './de/app';
|
||||
import es from './es/app';
|
||||
import en from './en/app';
|
||||
|
||||
const locales = {
|
||||
de,
|
||||
es,
|
||||
en,
|
||||
};
|
||||
|
||||
const lang = document.querySelector('html').getAttribute('lang') || 'en';
|
||||
|
||||
export { lang };
|
||||
export default new Jed(locales[lang]);
|
17
app/assets/javascripts/vue_shared/translate.js
Normal file
17
app/assets/javascripts/vue_shared/translate.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import locale from '../locale';
|
||||
|
||||
export default (Vue) => {
|
||||
Vue.filter('translate', text => locale.gettext(text));
|
||||
|
||||
Vue.filter('translate-plural', (text, pluralText, count) =>
|
||||
locale.ngettext(text, pluralText, count).replace(/%d/g, count));
|
||||
|
||||
Vue.directive('translate', {
|
||||
bind(el) {
|
||||
const $el = el;
|
||||
const text = $el.textContent.trim();
|
||||
|
||||
$el.textContent = locale.gettext(text);
|
||||
},
|
||||
});
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
!!! 5
|
||||
%html{ lang: "en", class: "#{page_class}" }
|
||||
%html{ lang: I18n.locale, class: "#{page_class}" }
|
||||
= render "layouts/head"
|
||||
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}" } }
|
||||
= Gon::Base.render_data
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
.empty-stage
|
||||
.icon-no-data
|
||||
= custom_icon ('icon_no_data')
|
||||
%h4 We don't have enough data to show this stage.
|
||||
%h4 {{ 'We don\'t have enough data to show this stage.' | translate }}
|
||||
%p
|
||||
{{currentStage.emptyStageText}}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
.no-access-stage
|
||||
.icon-lock
|
||||
= custom_icon ('icon_lock')
|
||||
%h4 You need permission.
|
||||
%h4 {{ 'You need permission.' | translate }}
|
||||
%p
|
||||
Want to see the data? Please ask administrator for access.
|
||||
{{ 'Want to see the data? Please ask administrator for access.' | translate }}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
- page_title "Cycle Analytics"
|
||||
- content_for :page_specific_javascripts do
|
||||
= page_specific_javascript_bundle_tag('common_vue')
|
||||
= page_specific_javascript_bundle_tag('locale')
|
||||
= page_specific_javascript_bundle_tag('cycle_analytics')
|
||||
|
||||
= render "projects/head"
|
||||
|
@ -15,16 +16,17 @@
|
|||
= custom_icon('icon_cycle_analytics_splash')
|
||||
.col-sm-8.col-xs-12.inner-content
|
||||
%h4
|
||||
Introducing Cycle Analytics
|
||||
{{ 'Introducing Cycle Analytics' | translate }}
|
||||
%p
|
||||
Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.
|
||||
{{ 'Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.' | translate }}
|
||||
|
||||
= link_to "Read more", help_page_path('user/project/cycle_analytics'), target: '_blank', class: 'btn'
|
||||
= link_to help_page_path('user/project/cycle_analytics'), target: '_blank', class: 'btn' do
|
||||
{{ 'Read more' | translate }}
|
||||
= icon("spinner spin", "v-show" => "isLoading")
|
||||
.wrapper{ "v-show" => "!isLoading && !hasError" }
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
Pipeline Health
|
||||
{{ 'Pipeline Health' | translate }}
|
||||
.content-block
|
||||
.container-fluid
|
||||
.row
|
||||
|
@ -34,15 +36,15 @@
|
|||
.col-sm-3.col-xs-12.column
|
||||
.dropdown.inline.js-ca-dropdown
|
||||
%button.dropdown-menu-toggle{ "data-toggle" => "dropdown", :type => "button" }
|
||||
%span.dropdown-label Last 30 days
|
||||
%span.dropdown-label {{ 'Last 30 days' | translate }}
|
||||
%i.fa.fa-chevron-down
|
||||
%ul.dropdown-menu.dropdown-menu-align-right
|
||||
%li
|
||||
%a{ "href" => "#", "data-value" => "30" }
|
||||
Last 30 days
|
||||
{{ 'Last 30 days' | translate }}
|
||||
%li
|
||||
%a{ "href" => "#", "data-value" => "90" }
|
||||
Last 90 days
|
||||
{{ 'Last 90 days' | translate }}
|
||||
.stage-panel-container
|
||||
.panel.panel-default.stage-panel
|
||||
.panel-heading
|
||||
|
@ -50,19 +52,19 @@
|
|||
%ul
|
||||
%li.stage-header
|
||||
%span.stage-name
|
||||
Stage
|
||||
{{ 'Stage' | translate }}
|
||||
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: "The phase of the development lifecycle.", "aria-hidden" => "true" }
|
||||
%li.median-header
|
||||
%span.stage-name
|
||||
Median
|
||||
{{ 'Median' | translate }}
|
||||
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.", "aria-hidden" => "true" }
|
||||
%li.event-header
|
||||
%span.stage-name
|
||||
{{ currentStage ? currentStage.legend : 'Related Issues' }}
|
||||
{{ currentStage ? currentStage.legend : 'Related Issues' | translate }}
|
||||
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: "The collection of events added to the data gathered for that stage.", "aria-hidden" => "true" }
|
||||
%li.total-time-header
|
||||
%span.stage-name
|
||||
Total Time
|
||||
{{ 'Total Time' | translate }}
|
||||
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: "The time taken by each data entry gathered by that stage.", "aria-hidden" => "true" }
|
||||
.stage-panel-body
|
||||
%nav.stage-nav
|
||||
|
@ -75,10 +77,10 @@
|
|||
%span{ "v-if" => "stage.value" }
|
||||
{{ stage.value }}
|
||||
%span.stage-empty{ "v-else" => true }
|
||||
Not enough data
|
||||
{{ 'Not enough data' | translate }}
|
||||
%template{ "v-else" => true }
|
||||
%span.not-available
|
||||
Not available
|
||||
{{ 'Not available' | translate }}
|
||||
.section.stage-events
|
||||
%template{ "v-if" => "isLoadingStage" }
|
||||
= icon("spinner spin")
|
||||
|
|
|
@ -35,6 +35,7 @@ var config = {
|
|||
groups_list: './groups_list.js',
|
||||
issuable: './issuable/issuable_bundle.js',
|
||||
issue_show: './issue_show/index.js',
|
||||
locale: './locale/index.js',
|
||||
main: './main.js',
|
||||
merge_conflicts: './merge_conflicts/merge_conflicts_bundle.js',
|
||||
merge_request_widget: './merge_request_widget/ci_bundle.js',
|
||||
|
@ -82,6 +83,10 @@ var config = {
|
|||
exclude: /node_modules/,
|
||||
loader: 'file-loader',
|
||||
},
|
||||
{
|
||||
test: /locale\/[a-z]+\/(.*)\.js$/,
|
||||
loader: 'exports-loader?locales',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -146,6 +151,14 @@ var config = {
|
|||
new webpack.optimize.CommonsChunkPlugin({
|
||||
names: ['main', 'common', 'runtime'],
|
||||
}),
|
||||
|
||||
// locale common library
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'locale',
|
||||
chunks: [
|
||||
'cycle_analytics',
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
||||
resolve: {
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
"dropzone": "^4.2.0",
|
||||
"emoji-unicode-version": "^0.2.1",
|
||||
"eslint-plugin-html": "^2.0.1",
|
||||
"exports-loader": "^0.6.4",
|
||||
"file-loader": "^0.11.1",
|
||||
"jed": "^1.1.1",
|
||||
"jquery": "^2.2.1",
|
||||
"jquery-ujs": "^1.2.1",
|
||||
"js-cookie": "^2.1.3",
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import Vue from 'vue';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import limitWarningComp from '~/cycle_analytics/components/limit_warning_component';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
describe('Limit warning component', () => {
|
||||
let component;
|
||||
let LimitWarningComponent;
|
||||
|
|
90
spec/javascripts/vue_shared/translate_spec.js
Normal file
90
spec/javascripts/vue_shared/translate_spec.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
import Vue from 'vue';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
describe('Vue translate filter', () => {
|
||||
let el;
|
||||
|
||||
beforeEach(() => {
|
||||
el = document.createElement('div');
|
||||
|
||||
document.body.appendChild(el);
|
||||
});
|
||||
|
||||
it('translate single text', (done) => {
|
||||
const comp = new Vue({
|
||||
el,
|
||||
template: `
|
||||
<span>
|
||||
{{ 'testing' | translate }}
|
||||
</span>
|
||||
`,
|
||||
}).$mount();
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(
|
||||
comp.$el.textContent.trim(),
|
||||
).toBe('testing');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('translate plural text with single count', (done) => {
|
||||
const comp = new Vue({
|
||||
el,
|
||||
template: `
|
||||
<span>
|
||||
{{ '%d day' | translate-plural('%d days', 1) }}
|
||||
</span>
|
||||
`,
|
||||
}).$mount();
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(
|
||||
comp.$el.textContent.trim(),
|
||||
).toBe('1 day');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('translate plural text with multiple count', (done) => {
|
||||
const comp = new Vue({
|
||||
el,
|
||||
template: `
|
||||
<span>
|
||||
{{ '%d day' | translate-plural('%d days', 2) }}
|
||||
</span>
|
||||
`,
|
||||
}).$mount();
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(
|
||||
comp.$el.textContent.trim(),
|
||||
).toBe('2 days');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('translate plural without replacing any text', (done) => {
|
||||
const comp = new Vue({
|
||||
el,
|
||||
template: `
|
||||
<span>
|
||||
{{ 'day' | translate-plural('days', 2) }}
|
||||
</span>
|
||||
`,
|
||||
}).$mount();
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(
|
||||
comp.$el.textContent.trim(),
|
||||
).toBe('days');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
19
yarn.lock
19
yarn.lock
|
@ -2143,6 +2143,13 @@ expand-range@^1.8.1:
|
|||
dependencies:
|
||||
fill-range "^2.1.0"
|
||||
|
||||
exports-loader@^0.6.4:
|
||||
version "0.6.4"
|
||||
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.6.4.tgz#d70fc6121975b35fc12830cf52754be2740fc886"
|
||||
dependencies:
|
||||
loader-utils "^1.0.2"
|
||||
source-map "0.5.x"
|
||||
|
||||
express@^4.13.3, express@^4.14.1:
|
||||
version "4.14.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.14.1.tgz#646c237f766f148c2120aff073817b9e4d7e0d33"
|
||||
|
@ -3080,6 +3087,10 @@ jasmine-jquery@^2.1.1:
|
|||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-jquery/-/jasmine-jquery-2.1.1.tgz#d4095e646944a26763235769ab018d9f30f0d47b"
|
||||
|
||||
jed@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"
|
||||
|
||||
jodid25519@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
|
||||
|
@ -5071,6 +5082,10 @@ source-map-support@^0.4.2:
|
|||
dependencies:
|
||||
source-map "^0.5.3"
|
||||
|
||||
source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
|
||||
source-map@^0.1.41:
|
||||
version "0.1.43"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
|
||||
|
@ -5083,10 +5098,6 @@ source-map@^0.4.4:
|
|||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
|
||||
source-map@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
|
||||
|
|
Loading…
Reference in a new issue