feat(sync): Add JS unittests for updateObjectValue, and refactor.

The new implementation uses `reduce`, in the hopes of producing a more
readable version than old-style loops and reassignment of object values.
This commit is contained in:
Alexis Métaireau 2024-05-14 10:35:01 +02:00
parent 9be613e3ce
commit 74a1670c9d
2 changed files with 86 additions and 15 deletions

View file

@ -11,20 +11,23 @@ class BaseUpdater {
} }
updateObjectValue(obj, key, value) { updateObjectValue(obj, key, value) {
// XXX refactor so it's cleaner const parts = key.split('.')
let path = key.split('.') const lastKey = parts.pop()
let what
for (var i = 0, l = path.length; i < l; i++) { // Reduce the current list of attributes,
what = path[i] // to find the object to set the property onto
if (what === path[l - 1]) { const objectToSet = parts.reduce((currentObj, part) => {
if (typeof value === 'undefined') { if (part in currentObj) return currentObj[part]
delete obj[what] }, obj)
} else {
obj[what] = value // In case the given path doesn't exist, bail out
} if (objectToSet === undefined) return
} else {
obj = obj[what] // Set the value (or delete it)
} if (typeof value === 'undefined') {
delete objectToSet[lastKey]
} else {
objectToSet[lastKey] = value
} }
} }
@ -54,7 +57,7 @@ export class MapUpdater extends BaseUpdater {
} }
export class DataLayerUpdater extends BaseUpdater { export class DataLayerUpdater extends BaseUpdater {
upsert({ key, metadata, value }) { upsert({ value }) {
// Inserts does not happen (we use multiple updates instead). // Inserts does not happen (we use multiple updates instead).
this.map.createDataLayer(value, false) this.map.createDataLayer(value, false)
} }

View file

@ -0,0 +1,68 @@
import { describe, it } from 'mocha'
import pkg from 'chai'
const { expect } = pkg
import {
MapUpdater,
DataLayerUpdater,
FeatureUpdater,
} from '../js/modules/sync/updaters.js'
describe('Updaters', () => {
describe('BaseUpdater', function () {
let updater
let map
let obj
this.beforeEach(function () {
map = {}
updater = new MapUpdater(map)
obj = {}
})
it('should be able to set object properties', function () {
let obj = {}
updater.updateObjectValue(obj, 'foo', 'foo')
expect(obj).deep.equal({ foo: 'foo' })
})
it('should be able to set object properties recursively on existing objects', function () {
let obj = { foo: {} }
updater.updateObjectValue(obj, 'foo.bar', 'foo')
expect(obj).deep.equal({ foo: { bar: 'foo' } })
})
it('should be able to set object properties recursively on deep objects', function () {
let obj = { foo: { bar: { baz: {} } } }
updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
})
it('should be able to replace object properties recursively on deep objects', function () {
let obj = { foo: { bar: { baz: { test: 'test' } } } }
updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
})
it('should not set object properties recursively on non-existing objects', function () {
let obj = { foo: {} }
updater.updateObjectValue(obj, 'bar.bar', 'value')
expect(obj).deep.equal({ foo: {} })
})
it('should delete keys for undefined values', function () {
let obj = { foo: 'foo' }
updater.updateObjectValue(obj, 'foo', undefined)
expect(obj).deep.equal({})
})
it('should delete keys for undefined values, recursively', function () {
let obj = { foo: { bar: 'bar' } }
updater.updateObjectValue(obj, 'foo.bar', undefined)
expect(obj).deep.equal({ foo: {} })
})
})
})