diff --git a/@types/index.d.ts b/@types/index.d.ts index 2cecc93..c3e9532 100644 --- a/@types/index.d.ts +++ b/@types/index.d.ts @@ -1,5 +1,5 @@ -import type { OrderedSet, Set } from 'immutable'; import React from 'react'; +import type { Set } from '../sources/client/src/vo/set'; import { BaseEntityRecords, Context } from '@wordpress/core-data'; @@ -19,7 +19,7 @@ declare namespace EntitiesSearch { fields: EntitiesSearch.SearchQueryFields; [p: string]: unknown; }> - > {} + > { } interface SearchEntityFields extends Readonly<{ @@ -28,7 +28,7 @@ declare namespace EntitiesSearch { url: string; type: string; subtype: string; - }> {} + }> { } type ControlOption = Readonly<{ value: V; @@ -37,39 +37,39 @@ declare namespace EntitiesSearch { type SingularControl = { [K in keyof BaseControl]: K extends 'value' - ? V - : K extends 'onChange' - ? (value: V) => void - : BaseControl[K]; + ? V + : K extends 'onChange' + ? (value: V) => void + : BaseControl[K]; }; interface BaseControl extends Readonly<{ - value: OrderedSet; - options: OrderedSet>; + value: Set; + options: Set>; onChange(values: BaseControl['value']): void; - }> {} + }> { } /* * Hooks */ type ViewablePostType = Readonly<{ [K in keyof PostType<'edit'>]: K extends 'viewable' - ? true - : PostType<'edit'>[K]; + ? true + : PostType<'edit'>[K]; }>; // TODO Need Type Test. type ViewableTaxonomy = Readonly<{ [K in keyof Taxonomy<'edit'>]: K extends 'visibility' - ? BaseEntityRecords.TaxonomyVisibility & { - publicly_queryable: true; - } - : Taxonomy<'edit'>[K]; + ? BaseEntityRecords.TaxonomyVisibility & { + publicly_queryable: true; + } + : Taxonomy<'edit'>[K]; }>; type EntitiesRecords = Readonly<{ - records(): OrderedSet; + records(): Set; isResolving(): boolean; errored(): boolean; succeed(): boolean; @@ -88,45 +88,45 @@ declare namespace EntitiesSearch { interface EntitiesState< E, K, - OptionSet = OrderedSet> + OptionSet = Set> > extends Readonly<{ - entities: BaseControl['value']; - kind: BaseControl['value']; - contextualEntitiesOptions: OptionSet; - currentEntitiesOptions: OptionSet; - selectedEntitiesOptions: OptionSet; - }> {} + entities: BaseControl['value']; + kind: BaseControl['value']; + contextualEntitiesOptions: OptionSet; + currentEntitiesOptions: OptionSet; + selectedEntitiesOptions: OptionSet; + }> { } type StoreAction = | { - type: 'UPDATE_ENTITIES'; - entities: EntitiesState['entities']; - } + type: 'UPDATE_ENTITIES'; + entities: EntitiesState['entities']; + } | { - type: 'UPDATE_KIND'; - kind: EntitiesState['kind']; - } + type: 'UPDATE_KIND'; + kind: EntitiesState['kind']; + } | { - type: 'UPDATE_CURRENT_ENTITIES_OPTIONS'; - currentEntitiesOptions: EntitiesState< - E, - K - >['currentEntitiesOptions']; - } + type: 'UPDATE_CURRENT_ENTITIES_OPTIONS'; + currentEntitiesOptions: EntitiesState< + E, + K + >['currentEntitiesOptions']; + } | { - type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS'; - contextualEntitiesOptions: EntitiesState< - E, - K - >['contextualEntitiesOptions']; - } + type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS'; + contextualEntitiesOptions: EntitiesState< + E, + K + >['contextualEntitiesOptions']; + } | { - type: 'UPDATE_SELECTED_ENTITIES_OPTIONS'; - selectedEntitiesOptions: EntitiesState< - E, - K - >['selectedEntitiesOptions']; - }; + type: 'UPDATE_SELECTED_ENTITIES_OPTIONS'; + selectedEntitiesOptions: EntitiesState< + E, + K + >['selectedEntitiesOptions']; + }; /* * Components @@ -135,7 +135,7 @@ declare namespace EntitiesSearch { extends Readonly<{ id?: string; onChange(phrase: string | React.ChangeEvent); - }> {} + }> { } interface CompositeEntitiesKinds extends Readonly<{ @@ -155,5 +155,5 @@ declare namespace EntitiesSearch { phrase: Parameters['search']>[0] ) => ReturnType['search']> ): React.ReactNode; - }> {} + }> { } } diff --git a/package.json b/package.json index a52cc9a..e54aade 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "@wordpress/core-data": "~6.12.0", "@wordpress/i18n": "~4.24.0", "classnames": "^2.3.2", - "immutable": "~4.3.0", "react": "~18.2.0" }, "scripts": { diff --git a/sources/client/src/api/search-entities.ts b/sources/client/src/api/search-entities.ts index 8a00660..ab6a751 100644 --- a/sources/client/src/api/search-entities.ts +++ b/sources/client/src/api/search-entities.ts @@ -1,14 +1,14 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; import { fetch } from './fetch'; export async function searchEntities( type: string, - subtype: OrderedSet, + subtype: Set, phrase: string, queryArguments?: EntitiesSearch.QueryArguments -): Promise> { +): Promise> { const { exclude, include, @@ -26,7 +26,7 @@ export async function searchEntities( include: include?.toArray() ?? [], ...restArguments, }, - type: type, + type, search: phrase, subtype: subtype.toArray(), _fields: serializeFields(fields), @@ -37,7 +37,7 @@ export async function searchEntities( path: `?rest_route=/wp/v2/search&${params.toString()}`, }); - return OrderedSet(entities); + return new Set(entities); } function serializeFields(fields: EntitiesSearch.SearchQueryFields): string { diff --git a/sources/client/src/components/composite-entities-by-kind.tsx b/sources/client/src/components/composite-entities-by-kind.tsx index d5aa508..bb163f0 100644 --- a/sources/client/src/components/composite-entities-by-kind.tsx +++ b/sources/client/src/components/composite-entities-by-kind.tsx @@ -1,18 +1,14 @@ import type EntitiesSearch from '@types'; -import { OrderedSet, Set } from 'immutable'; import React, { JSX, useState, useEffect } from 'react'; import { useEntitiesOptionsStorage } from '../hooks/use-entities-options-storage'; import { orderSelectedOptionsAtTheTop } from '../utils/order-selected-options-at-the-top'; import { uniqueControlOptions } from '../utils/unique-control-options'; +import { Set } from '../vo/set'; type SearchPhrase = Parameters[0]; type Entities = EntitiesSearch.BaseControl['value']; type Kind = EntitiesSearch.BaseControl['value'] | V; -type SearchEntities = EntitiesSearch.CompositeEntitiesKinds< - P, - T ->['searchEntities']; export function CompositeEntitiesByKind( props: EntitiesSearch.CompositeEntitiesKinds @@ -25,27 +21,20 @@ export function CompositeEntitiesByKind( const [searchPhrase, setSearchPhrase] = useState(''); useEffect(() => { - const promises = Set>>().asMutable(); - - promises.add( + Promise.all([ props.searchEntities('', state.kind, { exclude: state.entities, - }) - ); - - if (state.entities.size > 0) { - promises.add( - props.searchEntities('', state.kind, { - include: state.entities, - per_page: '-1', - }) - ); - } - - Promise.all(promises) + }), + state.entities.length() > 0 + ? props.searchEntities('', state.kind, { + include: state.entities, + per_page: '-1', + }) + : undefined, + ]) .then((result) => { - const currentEntitiesOptions = result[0] ?? OrderedSet([]); - const selectedEntitiesOptions = result[1] ?? OrderedSet([]); + const currentEntitiesOptions = result[0] ?? new Set(); + const selectedEntitiesOptions = result[1] ?? new Set(); dispatch({ type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', @@ -57,10 +46,11 @@ export function CompositeEntitiesByKind( }); dispatch({ type: 'UPDATE_CURRENT_ENTITIES_OPTIONS', - currentEntitiesOptions: currentEntitiesOptions, + currentEntitiesOptions, }); }) .catch((error) => { + // TODO Move logging outside of the component scope. console.error(`Composite Entities by Kind: ${error}`); }); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -69,26 +59,24 @@ export function CompositeEntitiesByKind( const onChangeEntities = (entities: Entities) => { props.entities.onChange(entities); - if ((entities?.size ?? 0) <= 0) { + if ((entities?.length() ?? 0) <= 0) { dispatch({ type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', - selectedEntitiesOptions: OrderedSet([]), + selectedEntitiesOptions: new Set(), }); return; } - const promises = Set>>([ + Promise.all([ props.searchEntities(searchPhrase, state.kind), props.searchEntities('', state.kind, { include: entities, per_page: '-1', }), - ]); - - Promise.all(promises) + ]) .then((result) => { - const currentEntitiesOptions = result[0] ?? OrderedSet([]); - const selectedEntitiesOptions = result[1] ?? OrderedSet([]); + const currentEntitiesOptions = result[0] ?? new Set(); + const selectedEntitiesOptions = result[1] ?? new Set(); dispatch({ type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', @@ -96,10 +84,11 @@ export function CompositeEntitiesByKind( }); dispatch({ type: 'UPDATE_CURRENT_ENTITIES_OPTIONS', - currentEntitiesOptions: currentEntitiesOptions, + currentEntitiesOptions, }); }) .catch((error) => { + // TODO Move logging outside of the component scope. console.warn( `Composite Entities by Kind - on Change Entities: ${error}` ); @@ -107,29 +96,28 @@ export function CompositeEntitiesByKind( }; const onChangeKind = (kind: Kind) => { - const _kind = - kind instanceof OrderedSet ? kind : OrderedSet([kind as K]); + const _kind = kind instanceof Set ? kind : new Set([kind]); + const emptySet = new Set(); - const entities = OrderedSet([]); dispatch({ type: 'UPDATE_ENTITIES', - entities, + entities: emptySet, }); dispatch({ type: 'UPDATE_KIND', kind: _kind, }); props.kind.onChange(_kind); - props.entities.onChange(entities); + props.entities.onChange(emptySet); - if (_kind.size <= 0) { + if (_kind.length() <= 0) { dispatch({ type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', - selectedEntitiesOptions: entities, + selectedEntitiesOptions: emptySet, }); dispatch({ type: 'UPDATE_CURRENT_ENTITIES_OPTIONS', - currentEntitiesOptions: entities, + currentEntitiesOptions: emptySet, }); return; } @@ -149,11 +137,24 @@ export function CompositeEntitiesByKind( }); dispatch({ type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', - selectedEntitiesOptions: entities, + selectedEntitiesOptions: emptySet, }); }) .catch((error) => { - console.warn( + dispatch({ + type: 'UPDATE_SELECTED_ENTITIES_OPTIONS', + selectedEntitiesOptions: emptySet, + }); + dispatch({ + type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS', + contextualEntitiesOptions: emptySet, + }); + dispatch({ + type: 'UPDATE_CURRENT_ENTITIES_OPTIONS', + currentEntitiesOptions: emptySet, + }); + // TODO Move logging outside of the component scope. + console.error( `Composite Entities by Kind - on Change Kind: ${error}` ); }); @@ -164,7 +165,7 @@ export function CompositeEntitiesByKind( value: state.entities, options: orderSelectedOptionsAtTheTop( uniqueControlOptions( - state.selectedEntitiesOptions.merge( + state.selectedEntitiesOptions.concat( state.currentEntitiesOptions ) ), @@ -205,7 +206,7 @@ export function CompositeEntitiesByKind( ) .catch(() => { // TODO Add warning for user feedback. - const emptySet = OrderedSet([]); + const emptySet = new Set>(); dispatch({ type: 'UPDATE_CURRENT_ENTITIES_OPTIONS', currentEntitiesOptions: emptySet, diff --git a/sources/client/src/components/plural-select-control.tsx b/sources/client/src/components/plural-select-control.tsx index 44909ae..75b8b50 100644 --- a/sources/client/src/components/plural-select-control.tsx +++ b/sources/client/src/components/plural-select-control.tsx @@ -1,8 +1,8 @@ import EntitiesSearch from '@types'; import classnames from 'classnames'; -import { OrderedSet } from 'immutable'; import React, { JSX } from 'react'; +import { Set } from '../vo/set'; import { NoOptionsMessage } from './no-options-message'; export function PluralSelectControl( @@ -16,7 +16,7 @@ export function PluralSelectControl( 'wz-select-control--plural' ); - if (props.options.size <= 0) { + if (props.options.length() <= 0) { return ; } @@ -30,7 +30,7 @@ export function PluralSelectControl( .filter((option) => option.selected) .map((option) => option.value); - props.onChange(OrderedSet(values)); + props.onChange(new Set(values)); }} > {props.options.map((option) => ( diff --git a/sources/client/src/components/singular-select-control.tsx b/sources/client/src/components/singular-select-control.tsx index f877504..eab2dcf 100644 --- a/sources/client/src/components/singular-select-control.tsx +++ b/sources/client/src/components/singular-select-control.tsx @@ -15,7 +15,7 @@ export function SingularSelectControl( 'wz-select-control--singular' ); - if (props.options.size <= 0) { + if (props.options.length() <= 0) { return ; } diff --git a/sources/client/src/components/toggle-control.tsx b/sources/client/src/components/toggle-control.tsx index 383bd8b..4110c1e 100644 --- a/sources/client/src/components/toggle-control.tsx +++ b/sources/client/src/components/toggle-control.tsx @@ -1,6 +1,5 @@ import EntitiesSearch from '@types'; import classnames from 'classnames'; -import { OrderedSet } from 'immutable'; import React, { JSX } from 'react'; import { NoOptionsMessage } from './no-options-message'; @@ -10,24 +9,19 @@ export function ToggleControl( ): JSX.Element { const className = classnames(props.className, 'wz-toggle-control'); - if (props.options.size <= 0) { + if (props.options.length() <= 0) { return ; } const onChange = (event: React.ChangeEvent) => { const { target } = event; - if (target.checked && !props.value?.has(target.value)) { - props.onChange( - OrderedSet(props.value?.add(target.value).toArray() ?? []) - ); + if (target.checked && !props.value.has(target.value)) { + props.onChange(props.value.add(target.value)); return; } - // TODO Stop handling `undefined`. - props.onChange( - OrderedSet(props.value?.delete(target.value).toArray() ?? []) - ); + props.onChange(props.value.delete(target.value)); }; return ( diff --git a/sources/client/src/hooks/use-entity-records.ts b/sources/client/src/hooks/use-entity-records.ts index 57756c0..e3c7e63 100644 --- a/sources/client/src/hooks/use-entity-records.ts +++ b/sources/client/src/hooks/use-entity-records.ts @@ -1,5 +1,5 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; import { useEntityRecords as useCoreEntityRecords } from '@wordpress/core-data'; @@ -28,7 +28,7 @@ export function useEntityRecords( const status = entities.status as any as ResolveStatus; return Object.freeze({ - records: () => OrderedSet(entities.records ?? []), + records: () => new Set(entities.records ?? []), isResolving: () => entities.isResolving && !entities.hasResolved && diff --git a/sources/client/src/hooks/use-query-viewable-post-types.ts b/sources/client/src/hooks/use-query-viewable-post-types.ts index 96d6153..ede60e9 100644 --- a/sources/client/src/hooks/use-query-viewable-post-types.ts +++ b/sources/client/src/hooks/use-query-viewable-post-types.ts @@ -1,5 +1,5 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; import { useEntityRecords } from './use-entity-records'; @@ -20,10 +20,10 @@ export function useQueryViewablePostTypes(): EntitiesSearch.EntitiesRecords postType.viewable - ) as OrderedSet; + ) as Set; return { ...entitiesRecords, - records: () => OrderedSet(viewablePostTypes), + records: () => viewablePostTypes, }; } diff --git a/sources/client/src/hooks/use-query-viewable-taxonomies.ts b/sources/client/src/hooks/use-query-viewable-taxonomies.ts index d8f5746..6473e6e 100644 --- a/sources/client/src/hooks/use-query-viewable-taxonomies.ts +++ b/sources/client/src/hooks/use-query-viewable-taxonomies.ts @@ -1,5 +1,5 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; import { useEntityRecords } from './use-entity-records'; @@ -20,10 +20,10 @@ export function useQueryViewableTaxonomies(): EntitiesSearch.EntitiesRecords taxonomy.visibility.publicly_queryable - ) as OrderedSet; + ) as Set; return { ...entitiesRecords, - records: () => OrderedSet(viewableTaxonomies), + records: () => viewableTaxonomies, }; } diff --git a/sources/client/src/index.ts b/sources/client/src/index.ts index e87e9fd..35c8f26 100644 --- a/sources/client/src/index.ts +++ b/sources/client/src/index.ts @@ -13,3 +13,5 @@ export * from './hooks/use-query-viewable-post-types'; export * from './hooks/use-query-viewable-taxonomies'; export * from './utils/convert-entities-to-control-options'; + +export * from './vo/set'; diff --git a/sources/client/src/storage/entities/initial-state.ts b/sources/client/src/storage/entities/initial-state.ts index 3a33c9f..7c13484 100644 --- a/sources/client/src/storage/entities/initial-state.ts +++ b/sources/client/src/storage/entities/initial-state.ts @@ -1,5 +1,6 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; + +import { Set } from '../../vo/set'; type Options = EntitiesSearch.ControlOption; @@ -7,11 +8,11 @@ export function makeInitialState( initialState: Partial> ): EntitiesSearch.EntitiesState { return { - entities: OrderedSet([]), - kind: OrderedSet([]), - contextualEntitiesOptions: OrderedSet>([]), - currentEntitiesOptions: OrderedSet>([]), - selectedEntitiesOptions: OrderedSet>([]), + entities: new Set([]), + kind: new Set([]), + contextualEntitiesOptions: new Set>(), + currentEntitiesOptions: new Set>(), + selectedEntitiesOptions: new Set>(), ...initialState, }; } diff --git a/sources/client/src/utils/convert-entities-to-control-options.ts b/sources/client/src/utils/convert-entities-to-control-options.ts index 4dff043..294e028 100644 --- a/sources/client/src/utils/convert-entities-to-control-options.ts +++ b/sources/client/src/utils/convert-entities-to-control-options.ts @@ -1,23 +1,21 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; import { makeControlOption } from './make-control-option'; export function convertEntitiesToControlOptions< EntitiesFields extends { [p: string]: any } >( - entities: OrderedSet, + entities: Set, labelKey: string, valueKey: string -): OrderedSet> { - const mutableOptions = entities.map((entity) => { +): Set> { + return entities.map((entity) => { const label = entity[labelKey]; const value = entity[valueKey]; labelKeyIsString(label); return makeControlOption(label, String(value)); }); - - return OrderedSet(mutableOptions); } function labelKeyIsString(label: unknown): asserts label is string { diff --git a/sources/client/src/utils/order-selected-options-at-the-top.ts b/sources/client/src/utils/order-selected-options-at-the-top.ts index c9dd9db..7b3636b 100644 --- a/sources/client/src/utils/order-selected-options-at-the-top.ts +++ b/sources/client/src/utils/order-selected-options-at-the-top.ts @@ -1,26 +1,28 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; + +import { Set } from '../vo/set'; export function orderSelectedOptionsAtTheTop( - options: OrderedSet>, - collection: OrderedSet | undefined -): OrderedSet> { - if (options.size <= 0) { + options: Set>, + collection: Set | undefined +): Set> { + if (options.length() <= 0) { return options; } - if (collection === undefined || collection.size <= 0) { + if (collection === undefined || collection.length() <= 0) { return options; } - const _collection = - OrderedSet>().asMutable(); - const _options = OrderedSet>().asMutable(); + let _collection = new Set>(); + let _options = new Set>(); options.forEach((option) => { - collection.includes(option.value) - ? _collection.add(option) - : _options.add(option); + if (collection.has(option.value)) { + _collection = _collection.add(option); + } else { + _options = _options.add(option); + } }); - return _collection.concat(_options).asImmutable(); + return _collection.concat(_options); } diff --git a/sources/client/src/utils/unique-control-options.ts b/sources/client/src/utils/unique-control-options.ts index 31f092e..1b88658 100644 --- a/sources/client/src/utils/unique-control-options.ts +++ b/sources/client/src/utils/unique-control-options.ts @@ -1,19 +1,20 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../vo/set'; +// TODO Is this necessary due the new Set implementation? export function uniqueControlOptions( - set: OrderedSet> -): OrderedSet> { - const uniqueOptions = OrderedSet>( - [] - ).asMutable(); - + set: Set> +): Set> { + let uniqueOptions = new Set>(); const temp: Array['value']> = []; for (const option of set) { - !temp.includes(option.value) && uniqueOptions.add(option); + if (!temp.includes(option.value)) { + uniqueOptions = uniqueOptions.add(option); + } + temp.push(option.value); } - return uniqueOptions.asImmutable(); + return uniqueOptions; } diff --git a/sources/client/src/vo/set.tsx b/sources/client/src/vo/set.tsx new file mode 100644 index 0000000..0fbd81b --- /dev/null +++ b/sources/client/src/vo/set.tsx @@ -0,0 +1,73 @@ +export class Set { + #data: ReadonlyArray; + + public constructor(data: Array = []) { + this.#data = data; + } + + public add(value: T): Set { + if (this.has(value)) { + return this; + } + + return new Set([...this.#data, value]); + } + + public addConditionally(value: T, condition: () => boolean): Set { + return condition() ? this.add(value) : this; + } + + public delete(value: T): Set { + if (!this.has(value)) { + return this; + } + + return new Set(this.#data.filter((item) => item !== value)); + } + + public has(value: T): boolean { + return this.#data.includes(value); + } + + public map(fn: (value: T) => R): Set { + return new Set(this.#data.map(fn)); + } + + public toArray(): Array { + return [...this.#data]; + } + + public forEach(fn: (value: T) => void): void { + this.#data.forEach(fn); + } + + public length(): number { + return this.#data.length; + } + + public concat(set: Set): Set { + return new Set([...this.#data, ...set.toArray()]); + } + + public filter(fn: (value: T) => boolean): Set { + return new Set(this.#data.filter(fn)); + } + + public first(): T | undefined { + return this.#data.slice(0)[0]; + } + + public last(): T | undefined { + return this.#data.slice(-1)[0]; + } + + public slice(start: number, end: number): Set { + return new Set(this.#data.slice(start, end)); + } + + public *[Symbol.iterator]() { + for (const value of this.#data) { + yield value; + } + } +} diff --git a/sources/server/src/Modules/E2e/Module.php b/sources/server/src/Modules/E2e/Module.php index 08ae8d7..937b4eb 100644 --- a/sources/server/src/Modules/E2e/Module.php +++ b/sources/server/src/Modules/E2e/Module.php @@ -79,19 +79,10 @@ private static function postTypesExample(Modularity\Properties\Properties $prope { $baseUrl = \untrailingslashit($properties->baseUrl()); - // TODO: Immutable must be removed from being a dependency of the block. - \wp_register_script( - 'immutable', - "{$baseUrl}/node_modules/immutable/dist/immutable.min.js", - [], - '4.3.4', - false - ); - \wp_register_script( 'wp-entities-search-e2e-post-types-example-block', "{$baseUrl}/sources/server/src/Modules/E2e/resources/js/post-types-example-block/index.js", - ['wp-entities-search', 'immutable'], + ['wp-entities-search'], '0.0.0', true, ); @@ -99,7 +90,7 @@ private static function postTypesExample(Modularity\Properties\Properties $prope \wp_register_script( 'wp-entities-search-e2e-taxonomies-example-block', "{$baseUrl}/sources/server/src/Modules/E2e/resources/js/taxonomies-example-block/index.js", - ['wp-entities-search', 'immutable'], + ['wp-entities-search'], '0.0.0', true, ); diff --git a/sources/server/src/Modules/E2e/resources/js/post-types-example-block/index.js b/sources/server/src/Modules/E2e/resources/js/post-types-example-block/index.js index af5cb4e..905cfbd 100644 --- a/sources/server/src/Modules/E2e/resources/js/post-types-example-block/index.js +++ b/sources/server/src/Modules/E2e/resources/js/post-types-example-block/index.js @@ -1,7 +1,7 @@ document.addEventListener('DOMContentLoaded', () => { const UNSUPPORTED_CPTS = ['attachment']; - const { wp, wpEntitiesSearch, Immutable } = window; + const { wp, wpEntitiesSearch } = window; const { createElement } = wp.element; const { registerBlockType } = wp.blocks; @@ -9,6 +9,7 @@ document.addEventListener('DOMContentLoaded', () => { const { Spinner } = wp.components; const { + Set, searchEntities, PluralSelectControl, ToggleControl, @@ -58,12 +59,12 @@ document.addEventListener('DOMContentLoaded', () => { ); }, entities: { - value: Immutable.OrderedSet(props.attributes.posts), + value: new Set(props.attributes.posts), onChange: (posts) => props.setAttributes({ posts: posts?.toArray() }), }, kind: { - value: Immutable.OrderedSet(props.attributes.postType), + value: new Set(props.attributes.postType), options: convertEntitiesToControlOptions( postTypesEntities .records() diff --git a/tests/client/integration/components/composite-entities-by-kind.test.tsx b/tests/client/integration/components/composite-entities-by-kind.test.tsx index d3c76c7..2909597 100644 --- a/tests/client/integration/components/composite-entities-by-kind.test.tsx +++ b/tests/client/integration/components/composite-entities-by-kind.test.tsx @@ -1,5 +1,4 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import React from 'react'; import { describe, it, expect, beforeAll, jest } from '@jest/globals'; @@ -11,6 +10,7 @@ import { CompositeEntitiesByKind } from '../../../../sources/client/src/componen import { PluralSelectControl } from '../../../../sources/client/src/components/plural-select-control'; import { SearchControl } from '../../../../sources/client/src/components/search-control'; import { SingularSelectControl } from '../../../../sources/client/src/components/singular-select-control'; +import { Set } from '../../../../sources/client/src/vo/set'; describe('CompositeEntitiesByKind', () => { beforeAll(() => { @@ -23,14 +23,14 @@ describe('CompositeEntitiesByKind', () => { const rendered = render( Promise.resolve(OrderedSet([]))} + searchEntities={() => Promise.resolve(new Set())} entities={{ - value: OrderedSet([]), + value: new Set(), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([ + value: new Set(['post']), + options: new Set([ { label: 'Post', value: 'post' }, { label: 'Page', value: 'page' }, ]), @@ -41,9 +41,9 @@ describe('CompositeEntitiesByKind', () => { return ( - kind.onChange(OrderedSet([value])) + kind.onChange(new Set([value])) } /> ); @@ -63,26 +63,26 @@ describe('CompositeEntitiesByKind', () => { it('Allow to select an entity', async () => { let expectedPosts: EntitiesSearch.BaseControl['value'] = - OrderedSet(); + new Set(); const rendered = await act(async () => { return render( Promise.resolve( - OrderedSet([ + new Set([ { label: 'Post 1', value: 'post-1' }, { label: 'Post 2', value: 'post-2' }, ]) ) } entities={{ - value: OrderedSet([]), + value: new Set(), onChange: (value) => (expectedPosts = value), }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([]), + value: new Set(['post']), + options: new Set(), onChange: () => {}, }} > @@ -104,26 +104,26 @@ describe('CompositeEntitiesByKind', () => { it('Reset the selected entities when the kind change', async () => { let expectedPosts: EntitiesSearch.BaseControl['value'] = - OrderedSet(); + new Set(); const rendered = await act(async () => render( Promise.resolve( - OrderedSet([ + new Set([ { label: 'Post 1', value: 'post-1' }, { label: 'Post 2', value: 'post-2' }, ]) ) } entities={{ - value: OrderedSet([]), + value: new Set(), onChange: (value) => (expectedPosts = value), }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([ + value: new Set(['post']), + options: new Set([ { label: 'Post', value: 'post' }, { label: 'Page', value: 'page' }, ]), @@ -135,9 +135,9 @@ describe('CompositeEntitiesByKind', () => { <> - kind.onChange(OrderedSet([value])) + kind.onChange(new Set([value])) } /> @@ -159,12 +159,11 @@ describe('CompositeEntitiesByKind', () => { expect(expectedPosts?.has('post-2')).toBe(true); await userEvent.selectOptions(postTypeSelect, 'page'); - expect(expectedPosts?.size).toBe(0); + expect(expectedPosts?.length()).toBe(0); }); it('Pass to the children the updated entities options when the kind change', async () => { - let expectedPosts: EntitiesSearch.BaseControl['options'] = - OrderedSet(); + let expectedPosts = new Set>(); const rendered = await act(() => render( @@ -172,7 +171,7 @@ describe('CompositeEntitiesByKind', () => { searchEntities={(_phrase, _postType) => { if (_postType.first() === 'page') { return Promise.resolve( - OrderedSet([ + new Set([ { label: 'Page 1', value: 'page-1' }, { label: 'Page 2', value: 'page-2' }, ]) @@ -180,19 +179,19 @@ describe('CompositeEntitiesByKind', () => { } return Promise.resolve( - OrderedSet([ + new Set([ { label: 'Post 1', value: 'post-1' }, { label: 'Post 2', value: 'post-2' }, ]) ); }} entities={{ - value: OrderedSet([]), + value: new Set(), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([ + value: new Set(['post']), + options: new Set([ { label: 'Post', value: 'post' }, { label: 'Page', value: 'page' }, ]), @@ -206,9 +205,9 @@ describe('CompositeEntitiesByKind', () => { <> - kind.onChange(OrderedSet([value])) + kind.onChange(new Set([value])) } /> @@ -223,13 +222,13 @@ describe('CompositeEntitiesByKind', () => { '.wz-select-control' ) as HTMLSelectElement; - expect(expectedPosts.size).toBe(2); + expect(expectedPosts.length()).toBe(2); let options = expectedPosts.toArray(); expect(options[0]?.value).toBe('post-1'); expect(options[1]?.value).toBe('post-2'); await userEvent.selectOptions(postTypeSelect, 'page'); - expect(expectedPosts.size).toBe(2); + expect(expectedPosts.length()).toBe(2); options = expectedPosts.toArray(); expect(options[0]?.value).toBe('page-1'); expect(options[1]?.value).toBe('page-2'); @@ -237,19 +236,32 @@ describe('CompositeEntitiesByKind', () => { it('Set the entities options to an empty collection when there is an issue in retrieving them', async () => { let expectedPosts: EntitiesSearch.BaseControl['options'] = - OrderedSet(); + new Set(); const rendered = await act(() => render( Promise.reject('Error')} + // @ts-ignore + searchEntities={(phrase, kind) => { + switch (kind.first()) { + case 'post': + return Promise.resolve( + new Set([ + { label: 'Post 1', value: 'post-1' }, + { label: 'Post 2', value: 'post-2' }, + ]) + ); + case 'page': + return Promise.reject('Error'); + } + }} entities={{ - value: OrderedSet([]), + value: new Set(), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([ + value: new Set(['post']), + options: new Set([ { label: 'Post', value: 'post' }, { label: 'Page', value: 'page' }, ]), @@ -262,9 +274,9 @@ describe('CompositeEntitiesByKind', () => { <> - kind.onChange(OrderedSet([value])) + kind.onChange(new Set([value])) } /> @@ -280,7 +292,7 @@ describe('CompositeEntitiesByKind', () => { ) as HTMLSelectElement; await userEvent.selectOptions(postTypeSelect, 'page'); - expect(expectedPosts.size).toBe(0); + expect(expectedPosts.length()).toBe(0); }); it('Search entities by kind by a search phrase excluding the given entities', async () => { @@ -293,22 +305,22 @@ describe('CompositeEntitiesByKind', () => { { if (phrase === '') { - return Promise.resolve(OrderedSet([])); + return Promise.resolve(new Set()); } expectedSearchPhrase = phrase; - expectedKind = kind.first(); + expectedKind = kind.first() ?? ''; expectedQuery = query; - return Promise.resolve(OrderedSet([])); + return Promise.resolve(new Set()); }} entities={{ - value: OrderedSet(['entity-3']), + value: new Set(['entity-3']), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([]), + value: new Set(['post']), + options: new Set(), onChange: () => {}, }} > @@ -317,9 +329,9 @@ describe('CompositeEntitiesByKind', () => { <> - kind.onChange(OrderedSet([value])) + kind.onChange(new Set([value])) } /> @@ -338,7 +350,7 @@ describe('CompositeEntitiesByKind', () => { await userEvent.type(searchInput, 'Hello World'); expect(expectedSearchPhrase).toBe('Hello World'); expect(expectedKind).toBe('post'); - expect(expectedQuery?.['exclude']).toEqual(OrderedSet([])); + expect(expectedQuery?.['exclude']).toEqual(new Set()); }); it('Does not call searchEntities when the phrase is empty string', async () => { @@ -348,15 +360,15 @@ describe('CompositeEntitiesByKind', () => { { searchEntitiesCalled = true; - return Promise.resolve(OrderedSet([])); + return Promise.resolve(new Set()); }} entities={{ - value: OrderedSet([]), + value: new Set(), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([]), + value: new Set(['post']), + options: new Set(), onChange: () => {}, }} > @@ -380,7 +392,7 @@ describe('CompositeEntitiesByKind', () => { }); it('Call searchEntities with the right parameters when mounting the component', async () => { - const entities = OrderedSet(['1', '2']); + const entities = new Set(['1', '2']); const searchEntities = jest.fn() as jest.Mock< EntitiesSearch.CompositeEntitiesKinds< @@ -398,8 +410,8 @@ describe('CompositeEntitiesByKind', () => { onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([]), + value: new Set(['post']), + options: new Set(), onChange: () => {}, }} > @@ -413,7 +425,7 @@ describe('CompositeEntitiesByKind', () => { expect(searchEntities).toHaveBeenNthCalledWith( 2, '', - OrderedSet(['post']), + new Set(['post']), { include: entities, per_page: '-1', @@ -423,8 +435,6 @@ describe('CompositeEntitiesByKind', () => { it('Catch the error thrown by searchEntities when the component mount', async () => { let errorMessage = ''; - const searchEntities = jest.fn(() => Promise.reject('Error')); - jest.spyOn(console, 'error').mockImplementation((_errorMessage) => { errorMessage = _errorMessage; }); @@ -432,14 +442,14 @@ describe('CompositeEntitiesByKind', () => { await act(() => { render( Promise.reject('Error')} entities={{ - value: OrderedSet([]), + value: new Set(), onChange: () => {}, }} kind={{ - value: OrderedSet(['post']), - options: OrderedSet([]), + value: new Set(['post']), + options: new Set(), onChange: () => {}, }} > diff --git a/tests/client/unit/api/search-entities.test.ts b/tests/client/unit/api/search-entities.test.ts index e3b865b..d366955 100644 --- a/tests/client/unit/api/search-entities.test.ts +++ b/tests/client/unit/api/search-entities.test.ts @@ -1,10 +1,10 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, expect, it, jest } from '@jest/globals'; import { fetch } from '../../../../sources/client/src/api/fetch'; import { searchEntities } from '../../../../sources/client/src/api/search-entities'; +import { Set } from '../../../../sources/client/src/vo/set'; jest.mock('../../../../sources/client/src/api/fetch', () => ({ fetch: jest.fn(), @@ -20,9 +20,9 @@ describe('Search Posts', () => { ); }); - searchEntities('post', OrderedSet(['post']), 'foo', { - exclude: OrderedSet(['1', '3']), - include: OrderedSet(['2', '5']), + searchEntities('post', new Set(['post']), 'foo', { + exclude: new Set(['1', '3']), + include: new Set(['2', '5']), }); }); @@ -37,11 +37,11 @@ describe('Search Posts', () => { const entities = await searchEntities( 'post', - OrderedSet(['post']), + new Set(['post']), 'foo', { - exclude: OrderedSet(['1', '3']), - include: OrderedSet(['2', '5']), + exclude: new Set(['1', '3']), + include: new Set(['2', '5']), } ); diff --git a/tests/client/unit/components/entities-toggle-control.test.tsx b/tests/client/unit/components/entities-toggle-control.test.tsx index c3a9a7a..be8dcb7 100644 --- a/tests/client/unit/components/entities-toggle-control.test.tsx +++ b/tests/client/unit/components/entities-toggle-control.test.tsx @@ -1,4 +1,3 @@ -import { OrderedSet } from 'immutable'; import React from 'react'; import { describe, expect, it, jest } from '@jest/globals'; @@ -6,8 +5,9 @@ import { describe, expect, it, jest } from '@jest/globals'; import { render, screen, fireEvent } from '@testing-library/react'; import { ToggleControl } from '../../../../sources/client/src/components/toggle-control'; +import { Set } from '../../../../sources/client/src/vo/set'; -const options = OrderedSet([ +const options = new Set([ { label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }, @@ -18,7 +18,7 @@ describe('EntitiesToggleControl', () => { const { container } = render( {}} /> @@ -31,8 +31,8 @@ describe('EntitiesToggleControl', () => { const { container } = render( {}} /> ); @@ -47,14 +47,14 @@ describe('EntitiesToggleControl', () => { ); fireEvent.click(screen.getByLabelText('Option 1')); - expect(onChange).toHaveBeenCalledWith(OrderedSet(['1'])); + expect(onChange).toHaveBeenCalledWith(new Set(['1'])); }); it('updates the value when one or more option are unselected', () => { @@ -64,13 +64,13 @@ describe('EntitiesToggleControl', () => { ); fireEvent.click(screen.getByLabelText('Option 1')); - expect(onChange).toHaveBeenCalledWith(OrderedSet(['2'])); + expect(onChange).toHaveBeenCalledWith(new Set(['2'])); }); }); diff --git a/tests/client/unit/components/plural-select-control.test.tsx b/tests/client/unit/components/plural-select-control.test.tsx index 36923c1..f8c8114 100644 --- a/tests/client/unit/components/plural-select-control.test.tsx +++ b/tests/client/unit/components/plural-select-control.test.tsx @@ -1,5 +1,4 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import React from 'react'; import { describe, it, expect } from '@jest/globals'; @@ -10,24 +9,25 @@ import userEvent from '@testing-library/user-event'; import { faker } from '@faker-js/faker'; import { PluralSelectControl } from '../../../../sources/client/src/components/plural-select-control'; +import { Set } from '../../../../sources/client/src/vo/set'; import { buildOptions } from '../utils'; describe('Posts Select', () => { it('call the given onChange handler', async () => { let expectedValue: EntitiesSearch.BaseControl['value'] = - OrderedSet(); + new Set(); const option: EntitiesSearch.ControlOption = { label: faker.word.words(2), value: faker.word.noun(), }; - const options = OrderedSet>([]) + const options = new Set>([]) .add(option) - .merge(buildOptions()); + .concat(buildOptions()); const rendered = render( (expectedValue = value)} /> ); diff --git a/tests/client/unit/components/radio-control.test.tsx b/tests/client/unit/components/radio-control.test.tsx index 39a2595..d047895 100644 --- a/tests/client/unit/components/radio-control.test.tsx +++ b/tests/client/unit/components/radio-control.test.tsx @@ -1,8 +1,4 @@ -// Write a test for the KindRadioControl component here -// - the test must ensure the correctness of the component's rendering -// - the test expects the value change accordingly to the selection -// - the test expects no rendering when the options are empty -import { OrderedSet } from 'immutable'; +import EntitiesSearch from '@types'; import React from 'react'; import { expect, jest, describe, it } from '@jest/globals'; @@ -10,12 +6,13 @@ import { expect, jest, describe, it } from '@jest/globals'; import { render, screen, fireEvent } from '@testing-library/react'; import { RadioControl } from '../../../../sources/client/src/components/radio-control'; +import { Set } from '../../../../sources/client/src/vo/set'; describe('KindRadioControl', () => { it('renders the component', () => { const props = { className: 'test-class', - options: OrderedSet([ + options: new Set([ { label: 'Option 1', value: 'option-one', @@ -32,7 +29,7 @@ describe('KindRadioControl', () => { it('renders the NoOptionsMessage when there are no options', () => { const props = { className: 'test-class', - options: OrderedSet([]), + options: new Set>(), value: 'option-one', onChange: jest.fn(), }; @@ -44,7 +41,7 @@ describe('KindRadioControl', () => { it('check the input based on the value given', () => { const props = { className: 'test-class', - options: OrderedSet([ + options: new Set([ { label: 'Option 1', value: 'option-one', @@ -64,7 +61,7 @@ describe('KindRadioControl', () => { it('changes the value when an option is selected', () => { const props = { - options: OrderedSet([ + options: new Set([ { label: 'Option 1', value: 'option-one', diff --git a/tests/client/unit/components/singular-select-control.test.tsx b/tests/client/unit/components/singular-select-control.test.tsx index 3f17ed7..d11f0d6 100644 --- a/tests/client/unit/components/singular-select-control.test.tsx +++ b/tests/client/unit/components/singular-select-control.test.tsx @@ -1,5 +1,4 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import React from 'react'; import { describe, it, expect } from '@jest/globals'; @@ -10,6 +9,7 @@ import userEvent from '@testing-library/user-event'; import { faker } from '@faker-js/faker'; import { SingularSelectControl } from '../../../../sources/client/src/components/singular-select-control'; +import { Set } from '../../../../sources/client/src/vo/set'; import { buildOptions } from '../utils'; describe('Post Types Select', () => { @@ -23,9 +23,9 @@ describe('Post Types Select', () => { label: faker.word.words(2), value: faker.word.noun(), }; - const options = OrderedSet>([]) + const options = new Set>() .add(option) - .merge(buildOptions()); + .concat(buildOptions()); const rendered = render( { 'postType' ); - expect(result.records().size).toEqual(2); + expect(result.records().length()).toEqual(2); for (const record of records) { expect(result.records()).toContain(record); } @@ -66,7 +66,7 @@ describe('useEntityRecords', () => { 'postType' ); - expect(result.records().isEmpty()).toEqual(true); + expect(result.records().length()).toEqual(0); expect(result.isResolving()).toEqual(true); expect(result.errored()).toEqual(false); expect(result.succeed()).toEqual(false); diff --git a/tests/client/unit/hooks/use-query-viewable-post-types.test.ts b/tests/client/unit/hooks/use-query-viewable-post-types.test.ts index 51fd2c4..cb58de3 100644 --- a/tests/client/unit/hooks/use-query-viewable-post-types.test.ts +++ b/tests/client/unit/hooks/use-query-viewable-post-types.test.ts @@ -1,11 +1,11 @@ import { fromPartial } from '@total-typescript/shoehorn'; import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, it, jest, expect } from '@jest/globals'; import { useEntityRecords } from '../../../../sources/client/src/hooks/use-entity-records'; import { useQueryViewablePostTypes } from '../../../../sources/client/src/hooks/use-query-viewable-post-types'; +import { Set } from '../../../../sources/client/src/vo/set'; jest.mock('@wordpress/data', () => { return { @@ -25,7 +25,7 @@ describe('Post Types Query', () => { errored: () => false, succeed: () => true, records: () => - OrderedSet([ + new Set([ fromPartial>({ slug: 'viewable-post-type', viewable: true, @@ -38,7 +38,7 @@ describe('Post Types Query', () => { }); const postTypes = useQueryViewablePostTypes(); - expect(postTypes.records().size).toEqual(1); + expect(postTypes.records().length()).toEqual(1); for (const viewablePostType of postTypes.records()) { expect(viewablePostType.viewable).toEqual(true); } @@ -49,10 +49,10 @@ describe('Post Types Query', () => { isResolving: () => true, errored: () => false, succeed: () => false, - records: () => OrderedSet([]), + records: () => new Set(), }); const viewablePostTypes = useQueryViewablePostTypes(); - expect(viewablePostTypes.records().size).toEqual(0); + expect(viewablePostTypes.records().length()).toEqual(0); }); }); diff --git a/tests/client/unit/hooks/use-query-viewable-taxonomies.test.ts b/tests/client/unit/hooks/use-query-viewable-taxonomies.test.ts index eb4e8df..d602561 100644 --- a/tests/client/unit/hooks/use-query-viewable-taxonomies.test.ts +++ b/tests/client/unit/hooks/use-query-viewable-taxonomies.test.ts @@ -1,11 +1,11 @@ import { fromPartial } from '@total-typescript/shoehorn'; import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, expect, it, jest } from '@jest/globals'; import { useEntityRecords } from '../../../../sources/client/src/hooks/use-entity-records'; import { useQueryViewableTaxonomies } from '../../../../sources/client/src/hooks/use-query-viewable-taxonomies'; +import { Set } from '../../../../sources/client/src/vo/set'; jest.mock('../../../../sources/client/src/hooks/use-entity-records', () => { return { @@ -20,7 +20,7 @@ describe('useQueryViewableTaxonomies', () => { errored: () => false, succeed: () => true, records: () => - OrderedSet([ + new Set([ fromPartial>({ name: 'Category', visibility: { @@ -43,7 +43,7 @@ describe('useQueryViewableTaxonomies', () => { }); const taxonomies = useQueryViewableTaxonomies(); - expect(taxonomies.records().size).toEqual(2); + expect(taxonomies.records().length()).toEqual(2); for (const viewableTaxonomy of taxonomies.records()) { expect(viewableTaxonomy.visibility.publicly_queryable).toEqual( true diff --git a/tests/client/unit/storage/initial-state.test.ts b/tests/client/unit/storage/initial-state.test.ts index e1769f6..36a4763 100644 --- a/tests/client/unit/storage/initial-state.test.ts +++ b/tests/client/unit/storage/initial-state.test.ts @@ -5,8 +5,8 @@ import { makeInitialState } from '../../../../sources/client/src/storage/entitie describe('Initial state', () => { it('ensure all options are empty', () => { const initialState = makeInitialState({}); - expect(initialState.contextualEntitiesOptions.size).toBe(0); - expect(initialState.currentEntitiesOptions.size).toBe(0); - expect(initialState.selectedEntitiesOptions.size).toBe(0); + expect(initialState.contextualEntitiesOptions.length()).toBe(0); + expect(initialState.currentEntitiesOptions.length()).toBe(0); + expect(initialState.selectedEntitiesOptions.length()).toBe(0); }); }); diff --git a/tests/client/unit/storage/reducer.test.ts b/tests/client/unit/storage/reducer.test.ts index 502b5e5..f736835 100644 --- a/tests/client/unit/storage/reducer.test.ts +++ b/tests/client/unit/storage/reducer.test.ts @@ -1,17 +1,17 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, expect, it } from '@jest/globals'; import { faker } from '@faker-js/faker'; import { reducer } from '../../../../sources/client/src/storage/entities/reducer'; +import { Set } from '../../../../sources/client/src/vo/set'; let state: EntitiesSearch.EntitiesState; describe('reducer', () => { it('Update the Contextual Posts Options', () => { - const contextualPostsOptions = OrderedSet([ + const contextualPostsOptions = new Set([ { value: faker.number.int(10), label: 'Post One', @@ -32,7 +32,7 @@ describe('reducer', () => { }); it('Update the Posts Options', () => { - const postsOptions = OrderedSet([ + const postsOptions = new Set([ { value: faker.number.int(10), label: 'Post Two', @@ -51,7 +51,7 @@ describe('reducer', () => { }); it('Update the Selected Posts Options with Control Options', () => { - const posts = OrderedSet([ + const posts = new Set([ { value: 55, label: 'Post FiftyFive', diff --git a/tests/client/unit/utils.ts b/tests/client/unit/utils.ts index 4d3087f..c322306 100644 --- a/tests/client/unit/utils.ts +++ b/tests/client/unit/utils.ts @@ -1,10 +1,10 @@ import EntitiesSearch from '@types'; -import { Set } from 'immutable'; +import { Set } from '../../../sources/client/src/vo/set'; import { faker } from '@faker-js/faker'; export function buildOptions(): Set> { - let options = Set>([]); + let options = new Set>(); for (let count = 0; count < 9; ++count) { options = options.add({ diff --git a/tests/client/unit/utils/convert-entities-to-control-options.test.ts b/tests/client/unit/utils/convert-entities-to-control-options.test.ts index dd0b1dd..6cd48e6 100644 --- a/tests/client/unit/utils/convert-entities-to-control-options.test.ts +++ b/tests/client/unit/utils/convert-entities-to-control-options.test.ts @@ -1,12 +1,12 @@ import { fromPartial } from '@total-typescript/shoehorn'; import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, expect, it } from '@jest/globals'; import { faker } from '@faker-js/faker'; import { convertEntitiesToControlOptions } from '../../../../sources/client/src/utils/convert-entities-to-control-options'; +import { Set } from '../../../../sources/client/src/vo/set'; describe('Convert Entities To Control Options', () => { it('correctly convert entities to control options', () => { @@ -20,8 +20,9 @@ describe('Convert Entities To Control Options', () => { ); } - const entities = - OrderedSet(rawEntities); + const entities = new Set( + rawEntities + ); const options = convertEntitiesToControlOptions( entities, @@ -29,7 +30,7 @@ describe('Convert Entities To Control Options', () => { 'id' ).map((option) => option.value); for (const entity of entities) { - expect(options.includes(`${entity.id}`)).toEqual(true); + expect(options.has(`${entity.id}`)).toEqual(true); } }); @@ -44,8 +45,9 @@ describe('Convert Entities To Control Options', () => { ); } - const entities = - OrderedSet(rawEntities); + const entities = new Set( + rawEntities + ); expect(() => { // To make the test fail, we pass the id as the label key diff --git a/tests/client/unit/utils/ordered-selected-options-at-the-top.test.ts b/tests/client/unit/utils/ordered-selected-options-at-the-top.test.ts index 227e82c..647dcba 100644 --- a/tests/client/unit/utils/ordered-selected-options-at-the-top.test.ts +++ b/tests/client/unit/utils/ordered-selected-options-at-the-top.test.ts @@ -1,11 +1,11 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; import { describe, expect, it } from '@jest/globals'; import { faker } from '@faker-js/faker'; import { orderSelectedOptionsAtTheTop } from '../../../../sources/client/src/utils/order-selected-options-at-the-top'; +import { Set } from '../../../../sources/client/src/vo/set'; describe('Ordered Selected Options at the Top', () => { /* @@ -44,8 +44,8 @@ describe('Ordered Selected Options at the Top', () => { it('should return the given options at the top', () => { const rawCollection = generateRandomNumbersAsStringCollection(); - const collection = OrderedSet(rawCollection); - const options = OrderedSet(generateOptions()); + const collection = new Set(rawCollection); + const options = new Set(generateOptions()); const result = orderSelectedOptionsAtTheTop(options, collection) .slice(0, 4) @@ -63,26 +63,20 @@ describe('Ordered Selected Options at the Top', () => { }); it('should return the given selected options when the collection is empty', () => { - const options = OrderedSet>( + const options = new Set>( generateOptions() ); - const result = orderSelectedOptionsAtTheTop( - options, - OrderedSet() - ); + const result = orderSelectedOptionsAtTheTop(options, new Set()); expect(result).toBe(options); }); it('should return the given options when the options are empty', () => { - const options = OrderedSet>(); + const options = new Set>(); - const result = orderSelectedOptionsAtTheTop( - options, - OrderedSet() - ); + const result = orderSelectedOptionsAtTheTop(options, new Set()); - expect(result.isEmpty()).toEqual(true); + expect(result.length()).toEqual(0); }); }); diff --git a/tests/client/unit/utils/unique-control-options.test.ts b/tests/client/unit/utils/unique-control-options.test.ts index 7027fc3..dbd17f6 100644 --- a/tests/client/unit/utils/unique-control-options.test.ts +++ b/tests/client/unit/utils/unique-control-options.test.ts @@ -1,5 +1,5 @@ import EntitiesSearch from '@types'; -import { OrderedSet } from 'immutable'; +import { Set } from '../../../../sources/client/src/vo/set'; import { describe, expect, it } from '@jest/globals'; @@ -7,16 +7,16 @@ import { uniqueControlOptions } from '../../../../sources/client/src/utils/uniqu describe('Unique Control Options', () => { it('Do not allow same control options within the same set', () => { - const set = OrderedSet>([ + const set = new Set>([ { label: 'foo', value: 'foo' }, { label: 'bar', value: 'bar' }, { label: 'foo', value: 'foo' }, { label: 'bar', value: 'bar' }, ]); - expect(set.size).toBe(4); + expect(set.length()).toBe(4); const uniqueSet = uniqueControlOptions(set); - expect(uniqueSet.size).toBe(2); + expect(uniqueSet.length()).toBe(2); expect(uniqueSet.first()?.value).toBe('foo'); expect(uniqueSet.last()?.value).toBe('bar'); }); diff --git a/yarn.lock b/yarn.lock index a2f1883..aefc8b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7039,7 +7039,7 @@ ignore@^5.1.9, ignore@^5.2.0, ignore@^5.2.1, ignore@~5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -immutable@^4.0.0, immutable@~4.3.0: +immutable@^4.0.0: version "4.3.2" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.2.tgz#f89d910f8dfb6e15c03b2cae2faaf8c1f66455fe" integrity sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==