Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 6 additions & 4 deletions ui/app/lib/kv-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,21 @@ export default ArrayProxy.extend({
return this.fromJSON(JSON.parse(jsonString));
},

toJSON(includeBlanks = false) {
toJSON(includeBlanks = false, defaultKey = 'key') {
return this.reduce((obj, item) => {
if (!includeBlanks && item.value === '' && item.name === '') {
return obj;
}
const val = typeof item.value === 'undefined' ? '' : item.value;
obj[item.name || ''] = val;
// Use defaultKey if name is empty and value is not empty
const keyName = item.name || (val !== '' ? defaultKey : '');
obj[keyName] = val;
return obj;
}, {});
},

toJSONString(includeBlanks) {
return JSON.stringify(this.toJSON(includeBlanks), null, 2);
toJSONString(includeBlanks, defaultKey) {
return JSON.stringify(this.toJSON(includeBlanks, defaultKey), null, 2);
},

isAdvanced() {
Expand Down
4 changes: 2 additions & 2 deletions ui/lib/core/addon/components/kv-object-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ export default class KvObjectEditor extends Component {
}
@action
updateRow() {
this.args.onChange(this.kvData.toJSON());
this.args.onChange(this.kvData.toJSON(false, this.placeholders.key));
}
@action
deleteRow(object, index) {
const oldObj = this.kvData.objectAt(index);
assert('object guids match', guidFor(oldObj) === guidFor(object));
this.kvData.removeAt(index);
this.args.onChange(this.kvData.toJSON());
this.args.onChange(this.kvData.toJSON(false, this.placeholders.key));
}
@action
handleKeyUp(event) {
Expand Down
23 changes: 23 additions & 0 deletions ui/tests/integration/components/kv-object-editor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,27 @@ module('Integration | Component | kv-object-editor', function (hooks) {
await fillIn('[data-test-kv-value="0"]', 7);
assert.dom('[data-test-kv-object-warning="0"]').exists();
});

test('it defaults empty key to "key" when value is not empty', async function (assert) {
await render(hbs`<KvObjectEditor @onChange={{this.spy}} />`);
// Fill in only the value, leave the key empty
await component.rows.objectAt(0).kvVal('myvalue');
assert.strictEqual(this.spy.callCount, 1, 'calls onChange when value changes');
assert.deepEqual(
this.spy.lastCall.args[0],
{ key: 'myvalue' },
'uses "key" as default when key is empty but value is not'
);
});

test('it uses custom placeholder as default key when keyPlaceholder is provided', async function (assert) {
await render(hbs`<KvObjectEditor @onChange={{this.spy}} @keyPlaceholder="customKey" />`);
// Fill in only the value, leave the key empty
await component.rows.objectAt(0).kvVal('myvalue');
assert.deepEqual(
this.spy.lastCall.args[0],
{ customKey: 'myvalue' },
'uses custom placeholder as default key'
);
});
});
27 changes: 21 additions & 6 deletions ui/tests/unit/lib/kv-object-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,41 @@ module('Unit | Lib | kv object', function () {
[
'types',
false,
'key',
{ string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } },
{ false: false, null: null, number: 1, object: { one: 'two' }, string: 'string', true: true, zero: 0 },
],
['include blanks = true', true, { string: 'string', '': '' }, { string: 'string', '': '' }],
['include blanks = false', false, { string: 'string', '': '' }, { string: 'string' }],
['include blanks = true', true, 'key', { string: 'string', '': '' }, { string: 'string', '': '' }],
['include blanks = false', false, 'key', { string: 'string', '': '' }, { string: 'string' }],
[
'empty key with value defaults to "key"',
false,
'key',
{ string: 'string', '': 'value' },
{ string: 'string', key: 'value' },
],
[
'empty key with value and custom default',
false,
'custom',
{ string: 'string', '': 'value' },
{ string: 'string', custom: 'value' },
],
];

toJSONTests.forEach(function ([name, includeBlanks, input, output]) {
toJSONTests.forEach(function ([name, includeBlanks, defaultKey, input, output]) {
test(`toJSON: ${name}`, function (assert) {
const data = KVObject.create({ content: [] }).fromJSON(input);
const result = data.toJSON(includeBlanks);
const result = data.toJSON(includeBlanks, defaultKey);
assert.deepEqual(result, output, 'has expected output');
});
});

toJSONTests.forEach(function ([name, includeBlanks, input, output]) {
toJSONTests.forEach(function ([name, includeBlanks, defaultKey, input, output]) {
test(`toJSONString: ${name}`, function (assert) {
const expected = JSON.stringify(output, null, 2);
const data = KVObject.create({ content: [] }).fromJSON(input);
const result = data.toJSONString(includeBlanks);
const result = data.toJSONString(includeBlanks, defaultKey);
assert.strictEqual(result, expected, 'has expected output string');
});
});
Expand Down