• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i18next / i18next / #11860

18 Aug 2017 09:06AM UTC coverage: 84.185% (+0.2%) from 83.97%
#11860

push

jamuhl
adds the defaultValue option for getFixedT

0 of 1 new or added line in 1 file covered. (0.0%)

3 existing lines in 1 file now uncovered.

692 of 822 relevant lines covered (84.18%)

35.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.6
/src/Interpolator.js
1
import * as utils from './utils';
1✔
2
import baseLogger from './logger';
1✔
3

4
class Interpolator {
5
  constructor(options = {}) {
33✔
6
    this.logger = baseLogger.create('interpolator');
33✔
7

8
    this.init(options, true);
33✔
9
  }
10

11
  /* eslint no-param-reassign: 0 */
12
  init(options = {}, reset) {
33✔
13
    if (reset) {
33✔
14
      this.options = options;
33✔
15
      this.format = (options.interpolation && options.interpolation.format) || (value => value);
33✔
16
      this.escape = (options.interpolation && options.interpolation.escape) || utils.escape;
33✔
17
    }
18
    if (!options.interpolation) options.interpolation = { escapeValue: true };
33✔
19

20
    const iOpts = options.interpolation;
33✔
21

22
    this.escapeValue = iOpts.escapeValue !== undefined ? iOpts.escapeValue : true;
33✔
23

24
    this.prefix = iOpts.prefix ? utils.regexEscape(iOpts.prefix) : iOpts.prefixEscaped || '{{';
33✔
25
    this.suffix = iOpts.suffix ? utils.regexEscape(iOpts.suffix) : iOpts.suffixEscaped || '}}';
33✔
26

27
    this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
33✔
28

29
    this.unescapePrefix = iOpts.unescapeSuffix ? '' : iOpts.unescapePrefix || '-';
33✔
30
    this.unescapeSuffix = this.unescapePrefix ? '' : iOpts.unescapeSuffix || '';
33✔
31

32
    this.nestingPrefix = iOpts.nestingPrefix ? utils.regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || utils.regexEscape('$t(');
33✔
33
    this.nestingSuffix = iOpts.nestingSuffix ? utils.regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || utils.regexEscape(')');
33✔
34

35
    // the regexp
36
    this.resetRegExp();
33✔
37
  }
38

39
  reset() {
40
    if (this.options) this.init(this.options);
×
41
  }
42

43
  resetRegExp() {
44
    // the regexp
45
    const regexpStr = `${this.prefix}(.+?)${this.suffix}`;
231✔
46
    this.regexp = new RegExp(regexpStr, 'g');
231✔
47

48
    const regexpUnescapeStr = `${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`;
231✔
49
    this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g');
231✔
50

51
    const nestingRegexpStr = `${this.nestingPrefix}(.+?)${this.nestingSuffix}`;
231✔
52
    this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
231✔
53
  }
54

55
  interpolate(str, data, lng) {
99✔
56
    let match;
99✔
57
    let value;
58

1✔
59
    function regexSafe(val) {
29✔
60
      return val.replace(/\$/g, '$$$$');
61
    }
62

99✔
63
    const handleFormat = (key) => {
35✔
64
      if (key.indexOf(this.formatSeparator) < 0) return utils.getPath(data, key);
65

5✔
66
      const p = key.split(this.formatSeparator);
5✔
67
      const k = p.shift().trim();
5✔
68
      const f = p.join(this.formatSeparator).trim();
69

5✔
70
      return this.format(utils.getPath(data, k), f, lng);
71
    };
72

99✔
73
    this.resetRegExp();
74

75
    // unescape if has unescapePrefix/Suffix
99✔
76
    /* eslint no-cond-assign: 0 */
99✔
77
    while (match = this.regexpUnescape.exec(str)) {
99✔
78
      value = handleFormat(match[1].trim());
99✔
79
      str = str.replace(match[0], value);
5✔
80
      this.regexpUnescape.lastIndex = 0;
5✔
81
    }
5✔
82

5✔
83
    // regular escape on demand
84
    while (match = this.regexp.exec(str)) {
99✔
85
      value = handleFormat(match[1].trim());
99✔
86
      if (typeof value !== 'string') value = utils.makeString(value);
87
      if (!value) {
88
        this.logger.warn(`missed to pass in variable ${match[1]} for interpolating ${str}`);
99✔
89
        value = '';
99✔
90
      }
99✔
91
      value = this.escapeValue ? regexSafe(this.escape(value)) : regexSafe(value);
99✔
92
      str = str.replace(match[0], value);
99✔
93
      this.regexp.lastIndex = 0;
30✔
94
    }
30✔
95
    return str;
29✔
96
  }
29✔
97

5✔
98
  nest(str, fc, options = {}) {
5✔
99
    let match;
100
    let value;
29✔
101

29✔
102
    let clonedOptions = { ...options };
29✔
103
    clonedOptions.applyPostProcessor = false; // avoid post processing on nested lookup
104

98✔
105
    // if value is something like "myKey": "lorem $(anotherKey, { "count": {{aValueInOptions}} })"
106
    function handleHasOptions(key) {
98✔
107
      if (key.indexOf(',') < 0) return key;
108

109
      const p = key.split(',');
75✔
110
      key = p.shift();
75✔
111
      let optionsString = p.join(',');
75✔
112
      optionsString = this.interpolate(optionsString, clonedOptions);
113
      optionsString = optionsString.replace(/'/g, '"');
75✔
114

75✔
115
      try {
116
        clonedOptions = JSON.parse(optionsString);
117
      } catch (e) {
1✔
118
        this.logger.error(`failed parsing options string in nesting for key ${key}`, e);
6✔
119
      }
120

2✔
121
      return key;
2✔
122
    }
2✔
123

2✔
124
    // regular escape on demand
2✔
125
    while (match = this.nestingRegexp.exec(str)) {
126
      value = fc(handleHasOptions.call(this, match[1].trim()), clonedOptions);
2✔
127

2✔
128
      // is only the nesting key (key1 = '$(key2)') return the value without stringify
UNCOV
129
      if (value && match[0] === str && typeof value !== 'string') return value;
×
130

131
      // no string to include or empty
132
      if (typeof value !== 'string') value = utils.makeString(value);
2✔
133
      if (!value) {
134
        this.logger.warn(`missed to resolve ${match[1]} for nesting ${str}`);
135
        value = '';
136
      }
75✔
137
      // Nested keys should not be escaped by default #854
6✔
138
      // value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value);
139
      str = str.replace(match[0], value);
140
      this.regexp.lastIndex = 0;
6✔
141
    }
142
    return str;
143
  }
5✔
144
}
5✔
UNCOV
145

×
UNCOV
146

×
147
export default Interpolator;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc