Repository: obsidian-tasks-group/obsidian-tasks
Pull request #1493 (2023-01-08 18:08:40)

refactor!: Encapsulate & test custom status settings code
# Description

<!--- Describe your changes in detail -->

Introduce new `StatusSettings` class to encapsulate the code for reading and using the settings for custom statuses.

The visible behaviour of the status settings is unchanged. But the name of the setting has had to change - from `statusTypes` to `statusSettings` - because of the changed storage.

> Important: In the unlikely event that anyone other than me is running this code, any custom statuses will need to be recreated.
> This can be done by copying-and-pasting within the plugin's `data.json` settings file.
> (At this development stage, it wasn't worth spending time worrying about implementing backwards compatibility)

## Motivation and Context

This is encapsulation and testing is in preparation for fixing a number of the remaining bugs and inconsistencies in the code for editing statuses.

## How has this been tested?

- By adding new tests
- By manual testing of the Tasks plugin settings code

## Screenshots (if appropriate)

## Types of changes



Internal changes:

- [x] **Refactor** (prefix: `refactor` - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [ ] My change requires a change to the documentation.
- [ ] I have [updated the documentation](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CONTRIBUTING.md#updating-documentation) accordingly.
- [x] My change has adequate [Unit Test coverage](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CONTRIBUTING.md#maintaining-the-tests).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CONTRIBUTING.md) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follow this project's [contributing guide](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CONTRIBUTING.md)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/src/Config/Settings.ts b/src/Config/Settings.ts
index 032cf375..c15a6b65 100644
--- a/src/Config/Settings.ts
+++ b/src/Config/Settings.ts
@@ -1,4 +1,4 @@
-import type { StatusConfiguration } from '../Status';
+import { StatusSettings } from './StatusSettings';
 import { Feature } from './Feature';
 import type { FeatureFlag } from './Feature';
 
@@ -22,7 +22,7 @@ export interface Settings {
     filenameAsDateFolders: string[];
 
     // The custom status states.
-    statusTypes: StatusConfiguration[];
+    statusSettings: StatusSettings;
 
     // Collection of feature flag IDs and their state.
     features: FeatureFlag;
@@ -45,7 +45,7 @@ const defaultSettings: Settings = {
     provideAccessKeys: true,
     useFilenameAsScheduledDate: false,
     filenameAsDateFolders: [],
-    statusTypes: [],
+    statusSettings: new StatusSettings(),
     features: Feature.settingsFlags,
     generalSettings: {
         /* Prevent duplicate values in user settings for now,
diff --git a/src/Config/SettingsTab.ts b/src/Config/SettingsTab.ts
index 674b64c1..593c12a7 100644
--- a/src/Config/SettingsTab.ts
+++ b/src/Config/SettingsTab.ts
@@ -3,6 +3,7 @@ import { Status, StatusConfiguration } from 'Status';
 import type TasksPlugin from '../main';
 import type { HeadingState } from './Settings';
 import { getSettings, isFeatureEnabled, updateGeneralSetting, updateSettings } from './Settings';
+import { StatusSettings } from './StatusSettings';
 import settingsJson from './settingsConfiguration.json';
 
 import { CustomStatusModal } from './CustomStatusModal';
@@ -365,11 +366,14 @@ export class SettingsTab extends PluginSettingTab {
      */
     insertTaskCoreStatusSettings(containerEl: HTMLElement, settings: SettingsTab) {
         // TODO Make these statuses editable
-        const coreStatuses: StatusConfiguration[] = [];
-        coreStatuses.push(Status.TODO, Status.IN_PROGRESS, Status.DONE, Status.CANCELLED);
+        const coreStatuses: StatusSettings = new StatusSettings();
+        StatusSettings.addCustomStatus(coreStatuses, Status.TODO.configuration);
+        StatusSettings.addCustomStatus(coreStatuses, Status.IN_PROGRESS.configuration);
+        StatusSettings.addCustomStatus(coreStatuses, Status.DONE.configuration);
+        StatusSettings.addCustomStatus(coreStatuses, Status.CANCELLED.configuration);
 
         /* -------------------- One row per status in the settings -------------------- */
-        coreStatuses.forEach((status_type) => {
+        coreStatuses.customStatusTypes.forEach((status_type) => {
             createRowForTaskStatus(containerEl, status_type, coreStatuses, settings, settings.plugin, false, false);
         });
     }
@@ -382,11 +386,11 @@ export class SettingsTab extends PluginSettingTab {
      * @memberof SettingsTab
      */
     insertTaskStatusSettings(containerEl: HTMLElement, settings: SettingsTab) {
-        const { statusTypes } = getSettings();
+        const { statusSettings } = getSettings();
 
         /* -------------------- One row per status in the settings -------------------- */
-        statusTypes.forEach((status_type) => {
-            createRowForTaskStatus(containerEl, status_type, statusTypes, settings, settings.plugin, true, true);
+        statusSettings.customStatusTypes.forEach((status_type) => {
+            createRowForTaskStatus(containerEl, status_type, statusSettings, settings, settings.plugin, true, true);
         });
 
         containerEl.createEl('div');
@@ -397,8 +401,8 @@ export class SettingsTab extends PluginSettingTab {
                 .setButtonText('Add New Task Status')
                 .setCta()
                 .onClick(async () => {
-                    statusTypes.push(new StatusConfiguration('', '', '', false));
-                    await updateAndSaveStatusSettings(statusTypes, settings);
+                    StatusSettings.addCustomStatus(statusSettings, new StatusConfiguration('', '', '', false));
+                    await updateAndSaveStatusSettings(statusSettings, settings);
                 });
         });
         setting.infoEl.remove();
@@ -411,7 +415,7 @@ export class SettingsTab extends PluginSettingTab {
                 .onClick(async () => {
                     await addCustomStatesToSettings(
                         StatusSettingsHelpers.minimalSupportedStatuses(),
-                        statusTypes,
+                        statusSettings,
                         settings,
                     );
                 });
@@ -426,7 +430,7 @@ export class SettingsTab extends PluginSettingTab {
                 .onClick(async () => {
                     await addCustomStatesToSettings(
                         StatusSettingsHelpers.itsSupportedStatuses(),
-                        statusTypes,
+                        statusSettings,
                         settings,
                     );
                 });
@@ -439,7 +443,7 @@ export class SettingsTab extends PluginSettingTab {
  * Create the row to see and modify settings for a single task status type.
  * @param containerEl
  * @param statusType - The status type to be edited.
- * @param statusTypes - All the status types already in the user's settings, EXCEPT the standard ones.
+ * @param statusSettings - All the status types already in the user's settings, EXCEPT the standard ones.
  * @param settings
  * @param plugin
  * @param deletable - whether the delete button wil be shown
@@ -448,7 +452,7 @@ export class SettingsTab extends PluginSettingTab {
 function createRowForTaskStatus(
     containerEl: HTMLElement,
     statusType: StatusConfiguration,
-    statusTypes: StatusConfiguration[],
+    statusSettings: StatusSettings,
     settings: SettingsTab,
     plugin: TasksPlugin,
     deletable: boolean,
@@ -469,10 +473,8 @@ function createRowForTaskStatus(
                 .setIcon('cross')
                 .setTooltip('Delete')
                 .onClick(async () => {
-                    const index = statusTypes.indexOf(statusType);
-                    if (index > -1) {
-                        statusTypes.splice(index, 1);
-                        await updateAndSaveStatusSettings(statusTypes, settings);
+                    if (StatusSettings.deleteCustomStatus(statusSettings, statusType)) {
+                        await updateAndSaveStatusSettings(statusSettings, settings);
                     }
                 });
         });
@@ -488,10 +490,14 @@ function createRowForTaskStatus(
 
                     modal.onClose = async () => {
                         if (modal.saved) {
-                            const index = statusTypes.indexOf(statusType);
-                            if (index > -1) {
-                                statusTypes.splice(index, 1, modal.statusConfiguration());
-                                await updateAndSaveStatusSettings(statusTypes, settings);
+                            if (
+                                StatusSettings.replaceCustomStatus(
+                                    statusSettings,
+                                    statusType,
+                                    modal.statusConfiguration(),
+                                )
+                            ) {
+                                await updateAndSaveStatusSettings(statusSettings, settings);
                             }
                         }
                     };
@@ -506,21 +512,21 @@ function createRowForTaskStatus(
 
 async function addCustomStatesToSettings(
     supportedStatuses: Array<[string, string, string]>,
-    statusTypes: StatusConfiguration[],
+    statusSettings: StatusSettings,
     settings: SettingsTab,
 ) {
-    const notices = StatusSettingsHelpers.addCustomStatusesCollection(supportedStatuses, statusTypes);
+    const notices = StatusSettings.bulkAddStatusCollection(statusSettings, supportedStatuses);
 
     notices.forEach((notice) => {
         new Notice(notice);
     });
 
-    await updateAndSaveStatusSettings(statusTypes, settings);
+    await updateAndSaveStatusSettings(statusSettings, settings);
 }
 
-async function updateAndSaveStatusSettings(statusTypes: StatusConfiguration[], settings: SettingsTab) {
+async function updateAndSaveStatusSettings(statusTypes: StatusSettings, settings: SettingsTab) {
     updateSettings({
-        statusTypes: statusTypes,
+        statusSettings: statusTypes,
     });
 
     await settings.saveSettings(true);
diff --git a/src/Config/StatusSettings.ts b/src/Config/StatusSettings.ts
new file mode 100644
index 00000000..5abbc994
--- /dev/null
+++ b/src/Config/StatusSettings.ts
@@ -0,0 +1,134 @@
+import { StatusConfiguration } from '../Status';
+import type { StatusRegistry } from '../StatusRegistry';
+
+/**
+ * Class for encapsulating the settings that control custom statuses.
+ *
+ * Most methods are static to allow them to be called from call-backs.
+ *
+ * @see Status
+ */
+export class StatusSettings {
+    constructor() {
+        this.customStatusTypes = []; // Do not modify directly: use the static mutation methods in this class.
+    }
+    customStatusTypes: StatusConfiguration[];
+
+    /**
+     * Add a new custom status.
+     *
+     * This is static so that it can be called from modal onClick() call-backs.
+     *
+     * - Currently, duplicates are allowed.
+     * - Allows empty StatusConfiguration objects - where every string is empty
+     * @param statusSettings
+     * @param newStatus
+     */
+    public static addCustomStatus(statusSettings: StatusSettings, newStatus: StatusConfiguration) {
+        statusSettings.customStatusTypes.push(newStatus);
+    }
+
+    /**
+     * Replace the given status, to effectively edit it.
+     * Returns true if the settings were changed.
+     *
+     * This is static so that it can be called from modal onClick() call-backs.
+     *
+     * - Does not currently check whether the status character is the same
+     * - If the status character is different, does not check whether the new one is already used in another status
+     * @param statusSettings
+     * @param originalStatus
+     * @param newStatus
+     */
+    public static replaceCustomStatus(
+        statusSettings: StatusSettings,
+        originalStatus: StatusConfiguration,
+        newStatus: StatusConfiguration,
+    ): boolean {
+        const index = statusSettings.customStatusTypes.indexOf(originalStatus);
+        if (index <= -1) {
+            return false;
+        }
+        statusSettings.customStatusTypes.splice(index, 1, newStatus);
+        return true;
+    }
+
+    /**
+     * Delete the given custom status.
+     * Returns true if deleted, and false if not.
+     *
+     * This is static so that it can be called from modal onClick() call-backs.
+     *
+     * @param statusSettings
+     * @param status
+     */
+    public static deleteCustomStatus(statusSettings: StatusSettings, status: StatusConfiguration) {
+        const index = statusSettings.customStatusTypes.indexOf(status);
+        if (index <= -1) {
+            return false;
+        }
+        statusSettings.customStatusTypes.splice(index, 1);
+        return true;
+    }
+
+    /**
+     * Add a collection of custom supported statuses to a StatusSettings.
+     * This can be used to quickly populate the user's settings.
+     * If there are any exact duplicates already present, they are skipped, and noted in the returned value.
+     *
+     * This is static so that it can be called from modal onClick() call-backs.
+     *
+     * @param statusSettings a StatusSettings
+     * @param supportedStatuses - an array of status specifications, for example `['b', 'Bookmark', 'x']`
+     * @return An array of warning messages to show the user, one for each rejected exact duplicate status.
+     *
+     * @see {@link minimalSupportedStatuses}, {@link itsSupportedStatuses}
+     */
+    public static bulkAddStatusCollection(
+        statusSettings: StatusSettings,
+        supportedStatuses: Array<[string, string, string]>,
+    ): string[] {
+        const notices: string[] = [];
+        supportedStatuses.forEach((importedStatus) => {
+            const hasStatus = statusSettings.customStatusTypes.find((element) => {
+                return (
+                    element.indicator == importedStatus[0] &&
+                    element.name == importedStatus[1] &&
+                    element.nextStatusIndicator == importedStatus[2]
+                );
+            });
+            if (!hasStatus) {
+                StatusSettings.addCustomStatus(
+                    statusSettings,
+                    new StatusConfiguration(importedStatus[0], importedStatus[1], importedStatus[2], false),
+                );
+            } else {
+                notices.push(`The status ${importedStatus[1]} (${importedStatus[0]}) is already added.`);
+            }
+        });
+        return notices;
+    }
+
+    /**
+     * Apply the custom statuses in the statusSettings object to the statusRegistry.
+     * @param statusSettings
+     * @param statusRegistry
+     */
+    public static applyToStatusRegistry(statusSettings: StatusSettings, statusRegistry: StatusRegistry) {
+        // Reset the registry as this may also come from a settings add/delete.
+        statusRegistry.clearStatuses();
+        statusSettings.customStatusTypes.forEach((statusType) => {
+            statusRegistry.add(statusType);
+        });
+
+        console.debug('Custom statuses read from settings:');
+        console.debug(statusSettings.customStatusTypes);
+
+        console.debug('All statuses registered in Tasks StatusRegistry (including the core ones):');
+        const registeredStatusTypes: StatusConfiguration[] = [];
+        statusRegistry.registeredStatuses.forEach((s) => {
+            registeredStatusTypes.push(s.configuration);
+        });
+        console.debug(registeredStatusTypes);
+    }
+}
diff --git a/src/Config/StatusSettingsHelpers.ts b/src/Config/StatusSettingsHelpers.ts
index e9a25a61..1514b035 100644
--- a/src/Config/StatusSettingsHelpers.ts
+++ b/src/Config/StatusSettingsHelpers.ts
@@ -17,44 +17,11 @@ export function statusPreviewText(status: StatusConfiguration) {
     return `- [${status.indicator}] ${status.name}, next status is '${status.nextStatusIndicator}'. ${commandNotice}`;
 }
 
-/**
- * Add a collection of supported statuses to an existing collection of StatusConfiguration objects.
- * This can be used to quickly populate the user's settings.
- * If there are any exact duplicates already present, they are skipped, and noted in the returned value.
- *
- * @param supportedStatuses - an array of status specifications, for example `['b', 'Bookmark', 'x']`
- * @param statusTypes {@link StatusConfiguration} - an array of existing known statuses
- * @return An array of warning messages to show the user, one for each rejected exact duplicate status.
- *
- * @see {@link minimalSupportedStatuses}, {@link itsSupportedStatuses}
- */
-export function addCustomStatusesCollection(
-    supportedStatuses: Array<[string, string, string]>,
-    statusTypes: StatusConfiguration[],
-): string[] {
-    const notices: string[] = [];
-    supportedStatuses.forEach((importedStatus) => {
-        const hasStatus = statusTypes.find((element) => {
-            return (
-                element.indicator == importedStatus[0] &&
-                element.name == importedStatus[1] &&
-                element.nextStatusIndicator == importedStatus[2]
-            );
-        });
-        if (!hasStatus) {
-            statusTypes.push(new StatusConfiguration(importedStatus[0], importedStatus[1], importedStatus[2], false));
-        } else {
-            notices.push(`The status ${importedStatus[1]} (${importedStatus[0]}) is already added.`);
-        }
-    });
-    return notices;
-}
-
 /**
  * Status supported by the Minimal theme. {@link https://github.com/kepano/obsidian-minimal}
  * Values recognised by Tasks are excluded.
  * @todo Check if this is up-to-date.
- * @see {@link addCustomStatusesCollection}
+ * @see {@link StatusSettings.bulkAddStatusCollection}
  */
 export function minimalSupportedStatuses() {
     const zzz: Array<[string, string, string]> = [
@@ -86,7 +53,7 @@ export function minimalSupportedStatuses() {
  * Status supported by the ITS theme. {@link https://github.com/SlRvb/Obsidian--ITS-Theme}
  * Values recognised by Tasks are excluded.
  * @todo  Check if this is up-to-date.
- * @see {@link addCustomStatusesCollection}
+ * @see {@link StatusSettings.bulkAddStatusCollection}
  */
 export function itsSupportedStatuses() {
     const zzz: Array<[string, string, string]> = [
diff --git a/src/Status.ts b/src/Status.ts
index 70af4c44..f3fc325f 100644
--- a/src/Status.ts
+++ b/src/Status.ts
@@ -59,6 +59,13 @@ export class StatusConfiguration {
 /**
  * Tracks the possible states that a task can be in.
  *
+ * Related classes:
+ * @see StatusConfiguration
+ * @see StatusRegistry
+ * @see StatusSettings
+ * @see StatusSettingsHelpers.ts
+ * @see CustomStatusModal
+ *
  * @export
  * @class Status
  */
@@ -114,7 +121,7 @@ export class Status {
      * @type {StatusConfiguration}
      * @memberof Status
      */
-    private readonly configuration: StatusConfiguration;
+    public readonly configuration: StatusConfiguration;
 
     /**
      * Whether Tasks can yet create 'Toggle Status' commands for statuses
diff --git a/src/main.ts b/src/main.ts
index 54df0a03..efb2b5e3 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -11,6 +11,7 @@ import { getSettings, updateSettings } from './Config/Settings';
 import { SettingsTab } from './Config/SettingsTab';
 import { StatusRegistry } from './StatusRegistry';
 import { EditorSuggestor } from './Suggestor/EditorSuggestorPopup';
+import { StatusSettings } from './Config/StatusSettings';
 
 export default class TasksPlugin extends Plugin {
     private cache: Cache | undefined;
@@ -46,13 +47,8 @@ export default class TasksPlugin extends Plugin {
     }
 
     async loadTaskStatuses() {
-        const { statusTypes } = getSettings();
-
-        // Reset the registry as this may also come from a settings add/delete.
-        StatusRegistry.getInstance().clearStatuses();
-        statusTypes.forEach((statusType) => {
-            StatusRegistry.getInstance().add(statusType);
-        });
+        const { statusSettings } = getSettings();
+        StatusSettings.applyToStatusRegistry(statusSettings, StatusRegistry.getInstance());
     }
 
     onunload() {


Test patch:
diff --git a/tests/Config/StatusSettings.test.StatusSettings_verify default status settings.approved.json b/tests/Config/StatusSettings.test.StatusSettings_verify default status settings.approved.json
new file mode 100644
index 00000000..b598a249
--- /dev/null
+++ b/tests/Config/StatusSettings.test.StatusSettings_verify default status settings.approved.json
@@ -0,0 +1,3 @@
+{
+  "customStatusTypes": []
+}
diff --git a/tests/Config/StatusSettings.test.ts b/tests/Config/StatusSettings.test.ts
new file mode 100644
index 00000000..2ba3122a
--- /dev/null
+++ b/tests/Config/StatusSettings.test.ts
@@ -0,0 +1,111 @@
+import { verifyAsJson } from 'approvals/lib/Providers/Jest/JestApprovals';
+import { StatusSettings } from '../../src/Config/StatusSettings';
+import { Status, StatusConfiguration } from '../../src/Status';
+import { StatusRegistry } from '../../src/StatusRegistry';
+
+describe('StatusSettings', () => {
+    it('verify default status settings', () => {
+        const defaultStatusSettings = new StatusSettings();
+        verifyAsJson(defaultStatusSettings);
+    });
+
+    function addThreeStatuses(settings: StatusSettings) {
+        const pro = new StatusConfiguration('P', 'Pro', 'C', false);
+        const imp = new StatusConfiguration('!', 'Important', 'x', false);
+        const con = new StatusConfiguration('C', 'Con', 'P', false);
+        StatusSettings.addCustomStatus(settings, pro);
+        StatusSettings.addCustomStatus(settings, imp);
+        StatusSettings.addCustomStatus(settings, con);
+        return { pro, imp, con };
+    }
+
+    it('should add a status', () => {
+        // Arrange
+        const settings = new StatusSettings();
+        expect(settings.customStatusTypes.length).toEqual(0);
+
+        // Act
+        const newStatus = new StatusConfiguration('!', 'Important', 'x', false);
+        StatusSettings.addCustomStatus(settings, newStatus);
+
+        // Assert
+        expect(settings.customStatusTypes.length).toEqual(1);
+        expect(settings.customStatusTypes[0]).toStrictEqual(newStatus);
+    });
+
+    it('should replace a status, if present', () => {
+        // Arrange
+        const settings = new StatusSettings();
+        const { imp } = addThreeStatuses(settings);
+        expect(settings.customStatusTypes.length).toEqual(3);
+        expect(settings.customStatusTypes[1]).toStrictEqual(imp);
+
+        // Act
+        const newImp = new StatusConfiguration('!', 'ReallyImportant', 'X', true);
+        StatusSettings.replaceCustomStatus(settings, imp, newImp);
+
+        // Assert
+        expect(settings.customStatusTypes.length).toEqual(3);
+        expect(settings.customStatusTypes[1]).toStrictEqual(newImp);
+    });
+
+    it('should bulk-add new statuses, reporting errors', () => {
+        // Arrange
+        const newStatuses: Array<[string, string, string]> = [
+            ['>', 'Forwarded', 'x'],
+            ['<', 'Schedule', 'x'],
+            ['?', 'Question', 'x'],
+            ['-', 'Dropped - should not be added as duplicate of core Cancelled', 'x'],
+            ['>', 'Forwarded', 'x'], // is a duplicate so should not be added
+            ['<', 'Duplicate - should not be added as duplicate of Schedule above', 'x'],
+            ['', 'Empty - should not be added as no status character', 'x'],
+        ];
+        const settings = new StatusSettings();
+
+        // Act
+        const result = StatusSettings.bulkAddStatusCollection(settings, newStatuses);
+
+        // Assert
+        expect(result).toStrictEqual(['The status Forwarded (>) is already added.']);
+    });
+
+    it('should delete a status', () => {
+        // Arrange
+        const settings = new StatusSettings();
+        const { pro, imp, con } = addThreeStatuses(settings);
+        expect(settings.customStatusTypes.length).toEqual(3);
+
+        // Act
+        const result = StatusSettings.deleteCustomStatus(settings, imp);
+
+        // Assert
+        expect(result).toEqual(true);
+        expect(settings.customStatusTypes.length).toEqual(2);
+        expect(settings.customStatusTypes[0]).toStrictEqual(pro);
+        expect(settings.customStatusTypes[1]).toStrictEqual(con);
+
+        // Delete a second time. It should now report that nothing was deleted.
+        const result2 = StatusSettings.deleteCustomStatus(settings, imp);
+        expect(result2).toEqual(false);
+    });
+
+    it('should apply settings to a StatusRegistry', () => {
+        // Arrange
+        const settings = new StatusSettings();
+        const { pro, imp, con } = addThreeStatuses(settings);
+        expect(settings.customStatusTypes.length).toEqual(3);
+
+        const statusRegistry = new StatusRegistry();
+        expect(statusRegistry.registeredStatuses.length).toEqual(4);
+
+        // Act
+        StatusSettings.applyToStatusRegistry(settings, statusRegistry);
+
+        // Assert
+        const statuses = statusRegistry.registeredStatuses;
+        expect(statuses.length).toEqual(7);
+        expect(statuses[4]).toStrictEqual(new Status(pro));
+        expect(statuses[5]).toStrictEqual(new Status(imp));
+        expect(statuses[6]).toStrictEqual(new Status(con));
+    });
+});