Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e980e44
Linting/formatting
camdecoster Sep 29, 2025
212f892
Return empty string for undefined value in templateFormatString
camdecoster Sep 29, 2025
75b157f
Refactoring
camdecoster Oct 2, 2025
5f3670f
Add fallback value for template strings
camdecoster Oct 3, 2025
336e9ae
Add fallback to calls to hovertemplateString
camdecoster Oct 3, 2025
02a4cad
Add fallback to calls to texttemplateString
camdecoster Oct 3, 2025
77bc2b9
Add fallback to calls to texttemplateStringForShapes
camdecoster Oct 7, 2025
85b67e9
Update defaults calculations
camdecoster Oct 6, 2025
680c793
Add helper function for template fallback attributes
camdecoster Oct 6, 2025
52c29cc
Add fallback value to attributes files
camdecoster Oct 7, 2025
f623b22
Update esbuild strip meta plugin to handle more joined arrays
camdecoster Oct 8, 2025
074f8a0
Return array from ternary
camdecoster Oct 8, 2025
6f3daa8
Update tests per default fallback value
camdecoster Oct 8, 2025
6719bd3
Update schema
camdecoster Oct 8, 2025
84fc044
Update test baselines
camdecoster Oct 8, 2025
e719f74
Rename object keys
camdecoster Oct 8, 2025
fb7a40c
Add/update tests to check fallback value
camdecoster Oct 9, 2025
faaae28
Add draftlog
camdecoster Oct 9, 2025
5c032c6
Fix typos
camdecoster Oct 21, 2025
a0ce641
Update fallback `editType` to match template
camdecoster Oct 21, 2025
14ab31c
Handle undefined values and missing values differently
camdecoster Oct 23, 2025
4f79efe
Update default fallback value and template attribute descriptions
camdecoster Oct 23, 2025
257475c
Add tests for missing and undefined values
camdecoster Oct 23, 2025
a148edd
Update schema
camdecoster Oct 23, 2025
c40fe9f
Merge remote-tracking branch 'origin/master' into cam/7564/return-emp…
camdecoster Oct 23, 2025
6a66148
Revert "Update test baselines"
camdecoster Oct 23, 2025
5215f13
Always use fallback for missing values, except when fallback is false
camdecoster Oct 24, 2025
30f87f3
Update schema
camdecoster Oct 24, 2025
b61d70d
Update mocks to show fallback values
camdecoster Oct 24, 2025
d900ca3
Update tests per final behavior
camdecoster Oct 24, 2025
a061787
Update baseline images
camdecoster Oct 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update tests per default fallback value
  • Loading branch information
camdecoster committed Oct 9, 2025
commit 6f3daa804b2858ad8ebe53cf5bda02ac71d2274f
6 changes: 3 additions & 3 deletions test/jasmine/tests/icicle_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ describe('Test icicle texttemplate without `values` should work at root level:',
[
'%{percentParent} of %{parent}',
[
'%{percentParent} of %{parent}',
' of ',
'100% of Seth',
'33% of Eve',
'17% of Eve',
Expand All @@ -957,7 +957,7 @@ describe('Test icicle texttemplate without `values` should work at root level:',
[
'label: Eve',
'text: fourteen',
'value: %{value}', // N.B. there is no `values` array
'value: ', // N.B. there is no `values` array
'17% of Eve',
'17% of Eve',
'17% of Eve',
Expand Down Expand Up @@ -1085,7 +1085,7 @@ describe('Test icicle texttemplate with *total* `values` should work at root lev
[
'%{percentParent} of %{parent}',
[
'%{percentParent} of %{parent}',
' of ',
'22% of Eve',
'18% of Eve',
'9% of Eve',
Expand Down
203 changes: 157 additions & 46 deletions test/jasmine/tests/lib_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2522,134 +2522,245 @@ describe('Test lib.js:', function () {
});

describe('hovertemplateString', function () {
var locale = false;
it('evaluates attributes', function () {
expect(Lib.hovertemplateString('foo %{bar}', {}, locale, { bar: 'baz' })).toEqual('foo baz');
expect(
Lib.hovertemplateString({
args: [{ bar: 'baz' }],
fallback: '',
string: 'foo %{bar}'
})
).toEqual('foo baz');
});

it('evaluates attributes with a dot in their name', function () {
expect(
Lib.hovertemplateString('%{marker.size}', {}, locale, { 'marker.size': 12 }, { marker: { size: 14 } })
Lib.hovertemplateString({
args: [{ 'marker.size': 12 }, { marker: { size: 14 } }],
fallback: '',
string: '%{marker.size}'
})
).toEqual('12');
});

it('evaluates nested properties', function () {
expect(Lib.hovertemplateString('foo %{bar.baz}', {}, locale, { bar: { baz: 'asdf' } })).toEqual('foo asdf');
expect(
Lib.hovertemplateString({
args: [{ bar: { baz: 'asdf' } }],
fallback: '',
string: 'foo %{bar.baz}'
})
).toEqual('foo asdf');
});

it('evaluates array nested properties', function () {
expect(Lib.hovertemplateString('foo %{bar[0].baz}', {}, locale, { bar: [{ baz: 'asdf' }] })).toEqual(
'foo asdf'
);
expect(
Lib.hovertemplateString({
args: [{ bar: [{ baz: 'asdf' }] }],
fallback: '',
string: 'foo %{bar[0].baz}'
})
).toEqual('foo asdf');
});

it('should work with the number *0*', function () {
expect(Lib.hovertemplateString('%{group}', {}, locale, { group: 0 })).toEqual('0');
expect(
Lib.hovertemplateString({
args: [{ group: 0 }],
fallback: '',
string: '%{group}'
})
).toEqual('0');
});

it('should work with the number *0* (nested case)', function () {
expect(Lib.hovertemplateString('%{x.y}', {}, locale, { x: { y: 0 } })).toEqual('0');
expect(
Lib.hovertemplateString({
args: [{ x: { y: 0 } }],
fallback: '',
string: '%{x.y}'
})
).toEqual('0');
});

it('preserves null and NaN', function () {
expect(
Lib.hovertemplateString('%{a} %{b} %{c.d} %{c.e} %{f[0]} %{f[1]}', {}, locale, {
a: null,
b: NaN,
c: { d: null, e: NaN },
f: [null, NaN]
Lib.hovertemplateString({
args: [{ a: null, b: NaN, c: { d: null, e: NaN }, f: [null, NaN] }],
fallback: '',
string: '%{a} %{b} %{c.d} %{c.e} %{f[0]} %{f[1]}'
})
).toEqual('null NaN null NaN null NaN');
});

it('subtitutes multiple matches', function () {
expect(
Lib.hovertemplateString('foo %{group} %{trace}', {}, locale, { group: 'asdf', trace: 'jkl;' })
Lib.hovertemplateString({
args: [{ group: 'asdf', trace: 'jkl;' }],
fallback: '',
string: 'foo %{group} %{trace}'
})
).toEqual('foo asdf jkl;');
});

it('replaces missing matches with template string', function () {
expect(Lib.hovertemplateString('foo %{group} %{trace}', {}, locale, { group: 1 })).toEqual(
'foo 1 %{trace}'
);
it('replaces missing matches with fallback value', function () {
expect(
Lib.hovertemplateString({
args: [{ group: 1 }],
fallback: '',
string: 'foo %{group} %{trace}'
})
).toEqual('foo 1 ');
});

it('uses the value from the first object with the specified key', function () {
var obj1 = { a: 'first' };
var obj2 = { a: 'second', foo: { bar: 'bar' } };

// Simple key
expect(Lib.hovertemplateString('foo %{a}', {}, locale, obj1, obj2)).toEqual('foo first');
expect(Lib.hovertemplateString('foo %{a}', {}, locale, obj2, obj1)).toEqual('foo second');
expect(
Lib.hovertemplateString({
args: [obj1, obj2],
fallback: '',
string: 'foo %{a}'
})
).toEqual('foo first');
expect(
Lib.hovertemplateString({
args: [obj2, obj1],
fallback: '',
string: 'foo %{a}'
})
).toEqual('foo second');

// Nested Keys
expect(Lib.hovertemplateString('foo %{foo.bar}', {}, locale, obj1, obj2)).toEqual('foo bar');
expect(
Lib.hovertemplateString({
args: [obj1, obj2],
fallback: '',
string: 'foo %{foo.bar}'
})
).toEqual('foo bar');

// Nested keys with 0
expect(Lib.hovertemplateString('y: %{y}', {}, locale, { y: 0 }, { y: 1 })).toEqual('y: 0');
expect(
Lib.hovertemplateString({
args: [{ y: 0 }, { y: 1 }],
fallback: '',
string: 'y: %{y}'
})
).toEqual('y: 0');
});

it('formats numbers using d3-format mini-language when `:`', function () {
expect(Lib.hovertemplateString('a: %{a:.0%}', {}, locale, { a: 0.123 })).toEqual('a: 12%');
expect(Lib.hovertemplateString('a: %{a:0.2%}', {}, locale, { a: 0.123 })).toEqual('a: 12.30%');
expect(Lib.hovertemplateString('b: %{b:2.2f}', {}, locale, { b: 43 })).toEqual('b: 43.00');
expect(
Lib.hovertemplateString({
args: [{ a: 0.123 }],
fallback: '',
string: 'a: %{a:.0%}'
})
).toEqual('a: 12%');
expect(
Lib.hovertemplateString({
args: [{ a: 0.123 }],
fallback: '',
string: 'a: %{a:0.2%}'
})
).toEqual('a: 12.30%');
expect(
Lib.hovertemplateString({
args: [{ b: 43 }],
fallback: '',
string: 'b: %{b:2.2f}'
})
).toEqual('b: 43.00');
});

it('formats date using d3-time-format mini-language `|`', function () {
expect(Lib.hovertemplateString('a: %{a|%A}', {}, locale, { a: '2019-05-22' })).toEqual('a: Wednesday');
expect(Lib.hovertemplateString('%{x|%b %-d, %Y}', {}, locale, { x: '2019-01-01' })).toEqual('Jan 1, 2019');
expect(
Lib.hovertemplateString({
args: [{ a: '2019-05-22' }],
fallback: '',
string: 'a: %{a|%A}'
})
).toEqual('a: Wednesday');
expect(
Lib.hovertemplateString({
args: [{ x: '2019-01-01' }],
fallback: '',
string: '%{x|%b %-d, %Y}'
})
).toEqual('Jan 1, 2019');
});

it('looks for default label if no format is provided', function () {
expect(Lib.hovertemplateString('y: %{y}', { yLabel: '0.1' }, locale, { y: 0.123 })).toEqual('y: 0.1');
expect(
Lib.hovertemplateString({
args: [{ y: 0.123 }],
fallback: '',
labels: { yLabel: '0.1' },
string: 'y: %{y}'
})
).toEqual('y: 0.1');
});

it('warns user up to 10 times if a variable cannot be found', function () {
spyOn(Lib, 'warn').and.callThrough();
Lib.hovertemplateString('%{idontexist}', {});
Lib.hovertemplateString({
fallback: '',
string: '%{idontexist}'
});
expect(Lib.warn.calls.count()).toBe(1);

for (var i = 0; i < 15; i++) {
Lib.hovertemplateString('%{idontexist}', {});
Lib.hovertemplateString({
fallback: '',
string: '%{idontexist}'
});
}
expect(Lib.warn.calls.count()).toBe(10);
});

it('does not error out when arguments are undefined', function () {
expect(function () {
Lib.hovertemplateString('y: %{y}', undefined, locale, undefined);
}).not.toThrow();
});
});

describe('texttemplateString', function () {
var locale = false;
it('evaluates attributes', function () {
expect(Lib.texttemplateString('foo %{bar}', {}, locale, { bar: 'baz' })).toEqual('foo baz');
expect(
Lib.texttemplateString({
args: [{ bar: 'baz' }],
fallback: '',
string: 'foo %{bar}'
})
).toEqual('foo baz');
});

it('looks for default label if no format is provided', function () {
expect(Lib.texttemplateString('y: %{y}', { yLabel: '0.1' }, locale, { y: 0.123 })).toEqual('y: 0.1');
expect(
Lib.texttemplateString({
args: [{ y: 0.123 }],
fallback: '',
labels: { yLabel: '0.1' },
string: 'y: %{y}'
})
).toEqual('y: 0.1');
});

it('preserves null and NaN', function () {
expect(
Lib.texttemplateString('%{a} %{b} %{c.d} %{c.e} %{f[0]} %{f[1]}', {}, locale, {
a: null,
b: NaN,
c: { d: null, e: NaN },
f: [null, NaN]
Lib.texttemplateString({
args: [{ a: null, b: NaN, c: { d: null, e: NaN }, f: [null, NaN] }],
fallback: '',
string: '%{a} %{b} %{c.d} %{c.e} %{f[0]} %{f[1]}'
})
).toEqual('null NaN null NaN null NaN');
});

it('warns user up to 10 times if a variable cannot be found', function () {
spyOn(Lib, 'warn').and.callThrough();
Lib.texttemplateString('%{idontexist}', {});
Lib.texttemplateString({ fallback: '', string: '%{idontexist}' });
expect(Lib.warn.calls.count()).toBe(1);

for (var i = 0; i < 15; i++) {
Lib.texttemplateString('%{idontexist}', {});
Lib.texttemplateString({ fallback: '', string: '%{idontexist}' });
}
expect(Lib.warn.calls.count()).toBe(11);
});
Expand Down
8 changes: 4 additions & 4 deletions test/jasmine/tests/sunburst_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2293,7 +2293,7 @@ describe('Test sunburst texttemplate without `values` should work at root level:
[
'%{percentParent} of %{parent}',
[
'%{percentParent} of %{parent}',
' of ',
'100% of Seth',
'33% of Eve',
'17% of Eve',
Expand All @@ -2319,7 +2319,7 @@ describe('Test sunburst texttemplate without `values` should work at root level:
[
'label: Eve',
'text: fourteen',
'value: %{value}', // N.B. there is no `values` array
'value: ', // N.B. there is no `values` array
'17% of Eve',
'17% of Eve',
'17% of Eve',
Expand Down Expand Up @@ -2447,7 +2447,7 @@ describe('Test sunburst texttemplate with *total* `values` should work at root l
[
'%{percentParent} of %{parent}',
[
'%{percentParent} of %{parent}',
' of ',
'22% of Eve',
'18% of Eve',
'9% of Eve',
Expand Down Expand Up @@ -2601,7 +2601,7 @@ describe('Test sunburst texttemplate with *remainder* `values` should work at ro
[
'%{percentParent} of %{parent}',
[
'%{percentParent} of %{parent}',
' of ',
'20% of Eve',
'12% of Eve',
'6% of Eve',
Expand Down
2 changes: 1 addition & 1 deletion test/jasmine/tests/treemap_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1937,7 +1937,7 @@ describe('Test treemap texttemplate without `values` should work:', function ()
'Eve',
'label: Cain, text: fourteen',
'Seth',
'value: %{value}', // N.B. there is no `values` array
'value: ', // N.B. there is no `values` array
'17% of Eve',
'17% of Eve',
'Awan',
Expand Down