diff --git a/README.md b/README.md
index 5f5996d..ac9570a 100644
--- a/README.md
+++ b/README.md
@@ -21,233 +21,406 @@ A JavaScript SDK for Switcher API

-# About
-JavaScript SDK for working with Switcher-API.
-https://github.com/switcherapi/switcher-api
+## Table of Contents
+
+- [๐ฏ About](#-about)
+- [๐ Quick Start](#-quick-start)
+- [โ๏ธ Installation & Setup](#๏ธ-installation--setup)
+ - [Installation](#installation)
+ - [Basic Configuration](#basic-configuration)
+ - [Advanced Options](#advanced-options)
+- [๐ก Usage Examples](#-usage-examples)
+ - [Basic Usage](#basic-usage)
+ - [Strategy Validation](#strategy-validation)
+ - [Throttling](#throttling)
+ - [Hybrid Mode](#hybrid-mode)
+- [๐งช Testing Features](#-testing-features)
+ - [Built-in Stub Feature](#built-in-stub-feature)
+ - [Test Mode](#test-mode)
+ - [Smoke Testing](#smoke-testing)
+- [๐ Snapshot Management](#-snapshot-management)
+ - [Loading Snapshots](#loading-snapshots)
+ - [Watching for Changes](#watching-for-changes)
+ - [Version Checking](#version-checking)
+ - [Auto-Update Scheduler](#auto-update-scheduler)
+
+---
+
+## ๐ฏ About
+
+**Switcher Client JS** is a feature-rich SDK for integrating [Switcher API](https://github.com/switcherapi/switcher-api) into your JS-based applications (Web, Node.js, Bun, Cloudflare Workers). It provides robust feature flag management with enterprise-grade capabilities.
+
+### โจ Key Features
+
+- ๐ **Zero Latency**: Local mode with snapshot files or in-memory for instant feature flag resolution
+- ๐ **Hybrid Configuration**: Silent mode with automatic fallback handling
+- ๐งช **Testing Ready**: Built-in stub implementation for comprehensive testing
+- โก **Performance Optimized**: Throttling optimizes remote API calls to reduce bottlenecks in critical code paths
+- ๐ ๏ธ **Developer Tools**: Runtime snapshot updates without app restart and automatic sync with remote API
+
+---
+
+## ๐ Quick Start
+
+Get up and running with Switcher Client in 3 simple steps:
+
+```bash
+npm install switcher-client
+```
-- Flexible and robust functions that will keep your code clean and maintainable.
-- Able to work locally using a snapshot file downloaded from your remote Switcher-API Domain.
-- Silent mode is a hybrid configuration that automatically enables a contingent sub-process in case of any connectivity issue.
-- Built-in stub implementation for clear and easy implementation of automated testing.
-- Easy to setup. Switcher Context is responsible to manage all the complexity between your application and API.
+```js
+import { Client } from 'switcher-client';
-# Usage
+// 1. Initialize the client
+Client.buildContext({
+ url: 'https://api.switcherapi.com',
+ apiKey: '[YOUR_API_KEY]',
+ domain: 'My Domain',
+ component: 'MyApp',
+ environment: 'default'
+});
-## Install
-`npm install switcher-client`
+// 2. Get a switcher instance
+const switcher = Client.getSwitcher();
-## Module initialization
-The context properties stores all information regarding connectivity.
+// 3. Check if a feature is enabled
+const isFeatureEnabled = await switcher.isItOn('FEATURE01');
+console.log('Feature enabled:', isFeatureEnabled);
+```
-```js
-import { Client } from 'switcher-client';
+---
-const apiKey = '[API_KEY]';
-const environment = 'default';
-const domain = 'My Domain';
-const component = 'MyApp';
-const url = 'https://api.switcherapi.com';
+## โ๏ธ Installation & Setup
+
+### Installation
+
+```bash
+npm install switcher-client
```
-- **domain**: Domain name.
-- **url**: (optional) Swither-API endpoint.
-- **apiKey**: (optional) Switcher-API key generated to your component.
-- **component**: (optional) Application name.
-- **environment**: (optional) Environment name. Production environment is named as 'default'.
+### Basic Configuration
-## Options
-You can also activate features such as local and silent mode:
+The context properties store all information regarding connectivity:
```js
-const local = true;
-const freeze = true;
-const logger = true;
-const snapshotLocation = './snapshot/';
-const snapshotAutoUpdateInterval = 3;
-const snapshotWatcher = true;
-const silentMode = '5m';
-const restrictRelay = true;
-const certPath = './certs/ca.pem';
+import { Client } from 'switcher-client';
-Client.buildContext({ url, apiKey, domain, component, environment }, {
- local, freeze, logger, snapshotLocation, snapshotAutoUpdateInterval,
- snapshotWatcher, silentMode, restrictRelay, certPath
-});
+// Required configuration
+const config = {
+ apiKey: '[API_KEY]', // Switcher-API key for your component
+ environment: 'default', // Environment name ('default' for production)
+ domain: 'My Domain', // Your domain name
+ component: 'MyApp', // Your application name
+ url: 'https://api.switcherapi.com' // Switcher-API endpoint (optional)
+};
+Client.buildContext(config);
const switcher = Client.getSwitcher();
```
-- **local**: If activated, the client will only fetch the configuration inside your snapshot file. The default value is 'false'
-- **freeze**: If activated, prevents the execution of background cache update when using throttle. The default value is 'false'
-- **logger**: If activated, it is possible to retrieve the last results from a given Switcher key using Client.getLogger('KEY')
-- **snapshotLocation**: Location of snapshot files
-- **snapshotAutoUpdateInterval**: Enable Snapshot Auto Update given an interval in seconds (default: 0 disabled)
-- **snapshotWatcher**: Enable Snapshot Watcher to monitor changes in the snapshot file (default: false)
-- **silentMode**: Enable contigency given the time for the client to retry - e.g. 5s (s: seconds - m: minutes - h: hours)
-- **restrictRelay**: Enable Relay Restriction - Allow managing Relay restrictions when running in local mode (default: true)
-- **regexSafe**: Enable REGEX Safe mode - Prevent agaist reDOS attack (default: true)
-- **regexMaxBlackList**: Number of entries cached when REGEX Strategy fails to perform (reDOS safe) - default: 50
-- **regexMaxTimeLimit**: Time limit (ms) used by REGEX workers (reDOS safe) - default - 3000ms
-- **certPath**: Path to the certificate file used to establish a secure connection with the API
+#### Configuration Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `domain` | string | โ
| Your Switcher domain name |
+| `url` | string | | Switcher API endpoint |
+| `apiKey` | string | | API key for your component |
+| `component` | string | | Your application name |
+| `environment` | string | | Environment name (default: 'default' for production) |
+
+### Advanced Options
+
+Configure additional features for enhanced functionality:
+
+```ts
+Client.buildContext({
+ url, apiKey, domain, component, environment
+}, {
+ local: true, // Enable local mode
+ freeze: false, // Prevent background updates
+ logger: true, // Enable request logging
+ snapshotLocation: './snapshot/', // Snapshot files directory
+ snapshotAutoUpdateInterval: 300, // Auto-update interval (seconds)
+ snapshotWatcher: true, // Monitor snapshot changes
+ silentMode: '5m', // Fallback timeout
+ restrictRelay: true, // Relay restrictions in local mode
+ regexSafe: true, // Prevent reDOS attacks
+ certPath: './certs/ca.pem' // SSL certificate path
+});
+```
+
+#### Options Reference
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `local` | boolean | Use only snapshot files/in-memory (no API calls) |
+| `freeze` | boolean | Disable background cache updates with throttling |
+| `logger` | boolean | Enable logging for debugging (`Client.getLogger('KEY')`) |
+| `snapshotLocation` | string | Directory for snapshot files |
+| `snapshotAutoUpdateInterval` | number | Auto-update interval in seconds (0 = disabled) |
+| `snapshotWatcher` | boolean | Watch for snapshot file changes |
+| `silentMode` | string | Fallback timeout (e.g., '5s', '2m', '1h') |
+| `restrictRelay` | boolean | Enable relay restrictions in local mode |
+| `regexSafe` | boolean | Protection against reDOS attacks |
+| `regexMaxBlackList` | number | Max cached regex failures |
+| `regexMaxTimeLimit` | number | Regex timeout in milliseconds |
+| `certPath` | string | Path to SSL certificate file |
-(*) regexSafe is a feature that prevents your application from being exposed to a reDOS attack. It is recommended to keep this feature enabled.
+> **Security Note:** `regexSafe` prevents ReDoS attacks. Keep this enabled in production.
-## Executing
-There are a few different ways to call the API.
-Here are some examples:
+---
-1. **Basic usage**
-Some of the ways you can check if a feature is enabled or not.
+## ๐ก Usage Examples
+
+### Basic Usage
+
+Multiple ways to check if a feature is enabled:
```js
const switcher = Client.getSwitcher();
-// Local (synchronous) execution
-const isOnBool = switcher.isItOn('FEATURE01'); // true or false
-const isOnBool = switcher.isItOnBool('FEATURE01'); // true or false
-const isOnDetail = switcher.detail().isItOn('FEATURE01'); // { result: true, reason: 'Success', metadata: {} }
-const isOnDetail = switcher.isItOnDetail('FEATURE01'); // { result: true, reason: 'Success', metadata: {} }
-
-// Remote (asynchronous) execution or hybrid (local/remote) execution
-const isOnBoolAsync = await switcher.isItOn('FEATURE01'); // Promise
-const isOnBoolAsync = await switcher.isItOnBool('FEATURE01', true); // Promise
-const isOnDetailAsync = await switcher.detail().isItOn('FEATURE01'); // Promise
-const isOnDetailAsync = await switcher.isItOnDetail('FEATURE01', true); // Promise
+// ๐ Synchronous (local mode only)
+const isEnabled = switcher.isItOn('FEATURE01'); // Returns: boolean
+const isEnabledBool = switcher.isItOnBool('FEATURE01'); // Returns: boolean
+const detailResult = switcher.detail().isItOn('FEATURE01'); // Returns: { result, reason, metadata }
+const detailDirect = switcher.isItOnDetail('FEATURE01'); // Returns: { result, reason, metadata }
+
+// ๐ Asynchronous (remote/hybrid mode)
+const isEnabledAsync = await switcher.isItOn('FEATURE01'); // Returns: Promise
+const isEnabledBoolAsync = await switcher.isItOnBool('FEATURE01', true); // Returns: Promise
+const detailResultAsync = await switcher.detail().isItOn('FEATURE01'); // Returns: Promise
+const detailDirectAsync = await switcher.isItOnDetail('FEATURE01', true); // Returns: Promise
```
-2. **Strategy validation - preparing input**
-Loading information into the switcher can be made by using *prepare*, in case you want to include input from a different place of your code. Otherwise, it is also possible to include everything in the same call.
+### Strategy Validation
+
+#### Method 1: Prepare Input Separately
+
+Load information into the switcher using `prepare()` when input comes from different parts of your code:
```js
+// Prepare the switcher with input data
await switcher.checkValue('USER_1').prepare('FEATURE01');
-await switcher.isItOn();
+
+// Execute the check
+const result = await switcher.isItOn();
```
-3. **Strategy validation - all-in-one execution**
-All-in-one method is fast and include everything you need to execute a complex call to the API.
+#### Method 2: All-in-One Execution
+
+Fast method that includes everything in a single call:
```js
-await switcher
- .defaultResult(true) // Default result to be returned in case of no API response
- .throttle(1000) // Throttle the API call to improve performance
- .checkValue('User 1')
- .checkNetwork('192.168.0.1')
- .isItOn('FEATURE01');
+const result = await switcher
+ .defaultResult(true) // ๐ก๏ธ Fallback result if API is unavailable
+ .throttle(1000) // โก Cache result for 1 second
+ .checkValue('User 1') // ๐ค User-based strategy
+ .checkNetwork('192.168.0.1') // ๐ Network-based strategy
+ .isItOn('FEATURE01');
```
-4. **Throttle**
-Throttling is useful when placing Feature Flags at critical code blocks that require zero-latency.
-API calls will be scheduled to be executed after the throttle time has passed.
+### Throttling
+
+Perfect for critical code blocks requiring zero-latency. API calls are scheduled after the throttle time:
```js
const switcher = Client.getSwitcher();
-await switcher
- .throttle(1000)
- .isItOn('FEATURE01');
+
+// Cache result for 1 second
+const result = await switcher
+ .throttle(1000)
+ .isItOn('FEATURE01');
```
-In order to capture issues that may occur during the process, it is possible to log the error by subscribing to the error events.
+#### Error Handling for Throttled Calls
+
+Subscribe to error events to capture issues during throttled execution:
```js
Client.subscribeNotifyError((error) => {
- console.log(error);
+ console.error('Switcher error:', error);
});
```
-5. **Hybrid mode**
-Forcing Switchers to resolve remotely can help you define exclusive features that cannot be resolved locally.
-This feature is ideal if you want to run the SDK in local mode but still want to resolve a specific switcher remotely.
+### Hybrid Mode
-A particular use case is when a swithcer has a Relay Strategy that requires a remote call to resolve the value.
+Force specific switchers to resolve remotely while running in local mode. Ideal for features requiring remote validation (e.g., Relay Strategies):
```js
const switcher = Client.getSwitcher();
-await switcher.remote().isItOn('FEATURE01');
+
+// Force remote resolution for this specific call
+const result = await switcher.remote().isItOn('FEATURE01');
```
-## Built-in stub feature
-You can also bypass your switcher configuration with 'Client.assume' API. This is perfect for your test code where you want to validate both scenarios when the switcher is true and false.
+---
+
+## ๐งช Testing Features
+
+### Built-in Stub Feature
+
+Bypass switcher configuration for testing scenarios. Perfect for validating both enabled and disabled states:
+
+#### Basic Stubbing
```js
+// โ
Force feature to be enabled
Client.assume('FEATURE01').true();
-switcher.isItOn('FEATURE01'); // true
+const result = switcher.isItOn('FEATURE01'); // Returns: true
+
+// โ Force feature to be disabled
+Client.assume('FEATURE01').false();
+const result = switcher.isItOn('FEATURE01'); // Returns: false
+// ๐ Reset to normal behavior
Client.forget('FEATURE01');
-switcher.isItOn('FEATURE01'); // Now, it's going to return the result retrieved from the API or the Snaopshot file
+const result = switcher.isItOn('FEATURE01'); // Returns: actual API/snapshot result
+```
+
+#### Advanced Stubbing with Metadata
+
+```js
+// Add custom metadata to simulate Relay responses
+Client.assume('FEATURE01')
+ .false()
+ .withMetadata({ message: 'Feature is disabled' });
+
+const response = await switcher.detail().isItOn('FEATURE01');
+console.log(response.result); // false
+console.log(response.metadata.message); // "Feature is disabled"
+```
+
+#### Conditional Stubbing
+
+```js
+import { StrategiesType } from 'switcher-client';
-Client.assume('FEATURE01').false().withMetadata({ message: 'Feature is disabled' }); // Include metadata to emulate Relay response
-const response = await switcher.detail().isItOn('FEATURE01'); // false
-console.log(response.metadata.message); // Feature is disabled
+// โ
True only for specific value
+Client.assume('FEATURE01')
+ .true()
+ .when(StrategiesType.VALUE, 'USER_1');
-Client.assume('FEATURE01').true().when(StrategiesType.VALUE, 'USER_1');
-switcher.checkValue('USER_1').isItOn('FEATURE01'); // true when the value is 'USER_1'
+const resultUser1 = switcher.checkValue('USER_1').isItOn('FEATURE01'); // true
+const resultUser2 = switcher.checkValue('USER_2').isItOn('FEATURE01'); // false
-Client.assume('FEATURE01').true().when(StrategiesType.NETWORK, ['USER_2', 'USER_3']);
-switcher.checkValue('USER_1').isItOn('FEATURE01'); // false as the value is not in the list
+// โ
True for multiple values
+Client.assume('FEATURE01')
+ .true()
+ .when(StrategiesType.NETWORK, ['192.168.1.1', '192.168.1.2']);
+
+const resultNetwork1 = switcher.checkNetwork('192.168.1.1').isItOn('FEATURE01'); // true
+const resultNetwork2 = switcher.checkNetwork('192.168.1.3').isItOn('FEATURE01'); // false
```
-**Enabling Test Mode**
-You may want to enable this feature while using Switcher Client with automated testing.
-It prevents the Switcher Client from locking snapshot files even after the test execution.
+### Test Mode
+
+Enable test mode to prevent snapshot file locking during automated testing:
-To enable this feature, it is recommended to place the following on your test setup files:
```js
+// Add this to your test setup files
Client.testMode();
```
-**Smoke Test**
-Validate Switcher Keys on your testing pipelines before deploying a change.
-Switcher Keys may not be configured correctly and can cause your code to have undesired results.
+> **๐ก Tip:** This prevents the Switcher Client from locking snapshot files even after test execution completes.
-This feature will validate using the context provided to check if everything is up and running.
-In case something is missing, this operation will throw an exception pointing out which Switcher Keys are not configured.
-```js
-Client.checkSwitchers(['FEATURE01', 'FEATURE02'])
+### Smoke Testing
+
+Validate feature flag during startup to catch configuration issues early:
+
+```ts
+try {
+ await Client.checkSwitchers(['FEATURE01', 'FEATURE02', 'CRITICAL_FEATURE']);
+ console.log('โ
All switchers configured correctly');
+} catch (error) {
+ console.error('โ Configuration issues found:', error.message);
+ process.exit(1);
+}
```
-## Loading Snapshot from the API
-This step is optional if you want to load a copy of the configuration that can be used to eliminate latency when local mode is activated.
-Activate watchSnapshot optionally passing true in the arguments.
-Auto load Snapshot from API passing true as second argument.
+This feature validates using the current context and throws an exception if any Switcher Keys are not properly configured.
+
+---
+
+## ๐ Snapshot Management
+
+### Loading Snapshots
+
+Load a local copy of your configuration to eliminate latency when local mode is activated:
```js
-Client.loadSnapshot();
+// Basic snapshot loading
+await Client.loadSnapshot();
+
+// Load snapshot and enable auto-watching
+await Client.loadSnapshot({ watchSnapshot: true });
+
+// Fetch remote snapshot and enable auto-watching
+await Client.loadSnapshot({ watchSnapshot: true, fetchRemote: true });
```
-## Watch for Snapshot file changes
-Activate and monitor snapshot changes using this feature. Optionally, you can implement any action based on the callback response.
+### Watching for Changes
+
+#### Method 1: Programmatic Watching
+
+Monitor snapshot changes and implement custom actions:
```js
Client.watchSnapshot({
- success: () => console.log('In-memory snapshot updated'),
- reject: (err) => console.log(err)
+ success: () => console.log('โ
In-memory snapshot updated'),
+ reject: (err) => console.error('โ Snapshot update failed:', err)
});
```
-Alternatively, you can also use the client context configuration to monitor changes in the snapshot file.
+#### Method 2: Configuration-based Watching
+
+Enable snapshot monitoring through client configuration:
```js
-Client.buildContext({ domain, component, environment }, {
+Client.buildContext(
+ { domain, component, environment },
+ {
local: true,
snapshotLocation: './snapshot/',
- snapshotWatcher: true
-});
+ snapshotWatcher: true // ๐๏ธ Enable automatic monitoring
+ }
+);
```
-## Snapshot version check
-For convenience, an implementation of a domain version checker is available if you have external processes that manage snapshot files.
+### Version Checking
+
+Check if your snapshot is up to date with the remote domain:
```js
-Client.checkSnapshot();
+try {
+ const versionInfo = await Client.checkSnapshot();
+ console.log('Snapshot version info:', versionInfo);
+} catch (error) {
+ console.error('Version check failed:', error);
+}
```
-## Snapshot Update Scheduler
-You can also schedule a snapshot update using the method below.
-It allows you to run the Client SDK in local mode (zero latency) and still have the snapshot updated automatically.
+> **๐ก Use Case:** Perfect for external processes that manage snapshot files independently.
+
+### Auto-Update Scheduler
+
+Run the SDK in local mode (zero latency) while keeping snapshots automatically updated:
```js
+// Update every 3 seconds (3000 milliseconds)
Client.scheduleSnapshotAutoUpdate(3000, {
success: (updated) => console.log('Snapshot updated', updated),
- reject: (err) => console.log(err)
+ reject: (err: Error) => console.log(err)
});
+```
+
+#### Alternative: Configuration-based Auto-Update
+
+```js
+Client.buildContext(
+ { domain, component, environment },
+ {
+ local: true,
+ snapshotAutoUpdateInterval: 60 // ๐ Update every 60 seconds
+ }
+);
```
\ No newline at end of file
diff --git a/package.json b/package.json
index 53da36e..8e04405 100644
--- a/package.json
+++ b/package.json
@@ -32,12 +32,12 @@
],
"devDependencies": {
"@babel/eslint-parser": "^7.28.4",
- "@typescript-eslint/eslint-plugin": "^8.46.0",
- "@typescript-eslint/parser": "^8.46.0",
+ "@typescript-eslint/eslint-plugin": "^8.46.1",
+ "@typescript-eslint/parser": "^8.46.1",
"c8": "^10.1.3",
"chai": "^6.2.0",
"env-cmd": "^11.0.0",
- "eslint": "^9.37.0",
+ "eslint": "^9.38.0",
"mocha": "^11.7.4",
"mocha-sonarqube-reporter": "^1.0.2",
"sinon": "^21.0.0"
diff --git a/tests/helper/utils.js b/tests/helper/utils.js
index 167a66d..9e06aa3 100644
--- a/tests/helper/utils.js
+++ b/tests/helper/utils.js
@@ -43,10 +43,11 @@ export async function assertUntilResolve(assert, actual, expected) {
await Promise.race([promise, sleep(2000)]);
- if (!actual()) {
- console.warn('Async test could not resolve in time');
+ const resolved = actual();
+ if (resolved) {
+ assert.equal(resolved, expected);
} else {
- assert.equal(actual(), expected);
+ console.warn('Async test could not resolve in time');
}
}
diff --git a/tests/strategy-operations/date.test.js b/tests/strategy-operations/date.test.js
index 33ce8ec..a8d0d2a 100644
--- a/tests/strategy-operations/date.test.js
+++ b/tests/strategy-operations/date.test.js
@@ -22,69 +22,69 @@ describe('Processing strategy: DATE', () => {
activated: true,
});
- it('should agree when input is LOWER', async () => {
+ it('should agree when input is LOWER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-11-26');
+ const result = processOperation(strategyConfig, '2019-11-26');
assert.isTrue(result);
});
- it('should agree when input is LOWER or SAME', async () => {
+ it('should agree when input is LOWER or SAME', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-12-01');
+ const result = processOperation(strategyConfig, '2019-12-01');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT LOWER', async () => {
+ it('should NOT agree when input is NOT LOWER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-12-02');
+ const result = processOperation(strategyConfig, '2019-12-02');
assert.isFalse(result);
});
- it('should agree when input is GREATER', async () => {
+ it('should agree when input is GREATER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-12-02');
+ const result = processOperation(strategyConfig, '2019-12-02');
assert.isTrue(result);
});
- it('should agree when input is GREATER or SAME', async () => {
+ it('should agree when input is GREATER or SAME', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-12-01');
+ const result = processOperation(strategyConfig, '2019-12-01');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT GREATER', async () => {
+ it('should NOT agree when input is NOT GREATER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-11-10');
+ const result = processOperation(strategyConfig, '2019-11-10');
assert.isFalse(result);
});
- it('should agree when input is in BETWEEN', async () => {
+ it('should agree when input is in BETWEEN', () => {
const strategyConfig = givenStrategyConfig(OperationsType.BETWEEN, mock_values2);
- const result = await processOperation(strategyConfig, '2019-12-03');
+ const result = processOperation(strategyConfig, '2019-12-03');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT in BETWEEN', async () => {
+ it('should NOT agree when input is NOT in BETWEEN', () => {
const strategyConfig = givenStrategyConfig(OperationsType.BETWEEN, mock_values2);
- const result = await processOperation(strategyConfig, '2019-12-12');
+ const result = processOperation(strategyConfig, '2019-12-12');
assert.isFalse(result);
});
- it('should agree when input is LOWER including time', async () => {
+ it('should agree when input is LOWER including time', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values3);
- const result = await processOperation(strategyConfig, '2019-12-01T07:00');
+ const result = processOperation(strategyConfig, '2019-12-01T07:00');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT LOWER including time', async () => {
+ it('should NOT agree when input is NOT LOWER including time', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '2019-12-01T07:00');
+ const result = processOperation(strategyConfig, '2019-12-01T07:00');
assert.isFalse(result);
});
- it('should agree when input is GREATER including time', async () => {
+ it('should agree when input is GREATER including time', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values3);
- const result = await processOperation(strategyConfig, '2019-12-01T08:40');
+ const result = processOperation(strategyConfig, '2019-12-01T08:40');
assert.isTrue(result);
});
diff --git a/tests/strategy-operations/network.test.js b/tests/strategy-operations/network.test.js
index 45247f6..626a498 100644
--- a/tests/strategy-operations/network.test.js
+++ b/tests/strategy-operations/network.test.js
@@ -25,57 +25,57 @@ describe('Processing strategy: NETWORK', () => {
activated: true,
});
- it('should agree when input range EXIST', async () => {
+ it('should agree when input range EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values1);
- const result = await processOperation(strategyConfig, '10.0.0.3');
+ const result = processOperation(strategyConfig, '10.0.0.3');
assert.isTrue(result);
});
it('should agree when input range EXIST - Irregular CIDR', async function () {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, ['10.0.0.3/24']);
- const result = await processOperation(strategyConfig, '10.0.0.3');
+ const result = processOperation(strategyConfig, '10.0.0.3');
assert.isTrue(result);
});
- it('should NOT agree when input range DOES NOT EXIST', async () => {
+ it('should NOT agree when input range DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values1);
- const result = await processOperation(strategyConfig, '10.0.0.4');
+ const result = processOperation(strategyConfig, '10.0.0.4');
assert.isFalse(result);
});
- it('should agree when input DOES NOT EXIST', async () => {
+ it('should agree when input DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values1);
- const result = await processOperation(strategyConfig, '10.0.0.4');
+ const result = processOperation(strategyConfig, '10.0.0.4');
assert.isTrue(result);
});
- it('should NOT agree when input EXIST but assumed that it DOES NOT EXIST', async () => {
+ it('should NOT agree when input EXIST but assumed that it DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values1);
- const result = await processOperation(strategyConfig, '10.0.0.3');
+ const result = processOperation(strategyConfig, '10.0.0.3');
assert.isFalse(result);
});
- it('should agree when input IP EXIST', async () => {
+ it('should agree when input IP EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values3);
- const result = await processOperation(strategyConfig, '192.168.56.58');
+ const result = processOperation(strategyConfig, '192.168.56.58');
assert.isTrue(result);
});
- it('should agree when input IP DOES NOT EXIST', async () => {
+ it('should agree when input IP DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values3);
- const result = await processOperation(strategyConfig, '192.168.56.50');
+ const result = processOperation(strategyConfig, '192.168.56.50');
assert.isTrue(result);
});
- it('should agree when input range EXIST for multiple ranges', async () => {
+ it('should agree when input range EXIST for multiple ranges', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values2);
- const result = await processOperation(strategyConfig, '192.168.0.3');
+ const result = processOperation(strategyConfig, '192.168.0.3');
assert.isTrue(result);
});
- it('should NOT agree when input range DOES NOT EXIST for multiple ranges', async () => {
+ it('should NOT agree when input range DOES NOT EXIST for multiple ranges', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values2);
- const result = await processOperation(strategyConfig, '127.0.0.0');
+ const result = processOperation(strategyConfig, '127.0.0.0');
assert.isTrue(result);
});
diff --git a/tests/strategy-operations/numeric.test.js b/tests/strategy-operations/numeric.test.js
index 601c2fa..cee497a 100644
--- a/tests/strategy-operations/numeric.test.js
+++ b/tests/strategy-operations/numeric.test.js
@@ -22,100 +22,100 @@ describe('Processing strategy: NUMERIC', () => {
activated: true,
});
- it('should agree when input EXIST in values - String type', async () => {
+ it('should agree when input EXIST in values - String type', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values2);
- const result = await processOperation(strategyConfig, '3');
+ const result = processOperation(strategyConfig, '3');
assert.isTrue(result);
});
- it('should agree when input EXIST in values - Number type', async () => {
+ it('should agree when input EXIST in values - Number type', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values2);
- const result = await processOperation(strategyConfig, 3);
+ const result = processOperation(strategyConfig, 3);
assert.isTrue(result);
});
- it('should NOT agree when input exist but test as DOES NOT EXIST ', async () => {
+ it('should NOT agree when input exist but test as DOES NOT EXIST ', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values2);
- const result = await processOperation(strategyConfig, '1');
+ const result = processOperation(strategyConfig, '1');
assert.isFalse(result);
});
- it('should agree when input DOES NOT EXIST in values', async () => {
+ it('should agree when input DOES NOT EXIST in values', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values2);
- const result = await processOperation(strategyConfig, '2');
+ const result = processOperation(strategyConfig, '2');
assert.isTrue(result);
});
- it('should agree when input is EQUAL to value', async () => {
+ it('should agree when input is EQUAL to value', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EQUAL, mock_values1);
- const result = await processOperation(strategyConfig, '1');
+ const result = processOperation(strategyConfig, '1');
assert.isTrue(result);
});
- it('should NOT agree when input is not equal but test as EQUAL', async () => {
+ it('should NOT agree when input is not equal but test as EQUAL', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EQUAL, mock_values1);
- const result = await processOperation(strategyConfig, '2');
+ const result = processOperation(strategyConfig, '2');
assert.isFalse(result);
});
- it('should agree when input is NOT EQUAL to value', async () => {
+ it('should agree when input is NOT EQUAL to value', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EQUAL, mock_values1);
- const result = await processOperation(strategyConfig, '2');
+ const result = processOperation(strategyConfig, '2');
assert.isTrue(result);
});
- it('should agree when input is GREATER than value', async () => {
+ it('should agree when input is GREATER than value', () => {
let strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- let result = await processOperation(strategyConfig, '2');
+ let result = processOperation(strategyConfig, '2');
assert.isTrue(result);
// test decimal
- result = await processOperation(strategyConfig, '1.01');
+ result = processOperation(strategyConfig, '1.01');
assert.isTrue(result);
strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values3);
- result = await processOperation(strategyConfig, '1.55');
+ result = processOperation(strategyConfig, '1.55');
assert.isTrue(result);
});
- it('should NOT agree when input is lower but tested as GREATER than value', async () => {
+ it('should NOT agree when input is lower but tested as GREATER than value', () => {
let strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- let result = await processOperation(strategyConfig, '0');
+ let result = processOperation(strategyConfig, '0');
assert.isFalse(result);
// test decimal
- result = await processOperation(strategyConfig, '0.99');
+ result = processOperation(strategyConfig, '0.99');
assert.isFalse(result);
strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values3);
- result = await processOperation(strategyConfig, '1.49');
+ result = processOperation(strategyConfig, '1.49');
assert.isFalse(result);
});
- it('should agree when input is LOWER than value', async () => {
+ it('should agree when input is LOWER than value', () => {
let strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- let result = await processOperation(strategyConfig, '0');
+ let result = processOperation(strategyConfig, '0');
assert.isTrue(result);
// test decimal
- result = await processOperation(strategyConfig, '0.99');
+ result = processOperation(strategyConfig, '0.99');
assert.isTrue(result);
strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values3);
- result = await processOperation(strategyConfig, '1.49');
+ result = processOperation(strategyConfig, '1.49');
assert.isTrue(result);
});
- it('should agree when input is BETWEEN values', async () => {
+ it('should agree when input is BETWEEN values', () => {
const strategyConfig = givenStrategyConfig(OperationsType.BETWEEN, mock_values2);
- let result = await processOperation(strategyConfig, '1');
+ let result = processOperation(strategyConfig, '1');
assert.isTrue(result);
// test decimal
- result = await processOperation(strategyConfig, '2.99');
+ result = processOperation(strategyConfig, '2.99');
assert.isTrue(result);
- result = await processOperation(strategyConfig, '1.001');
+ result = processOperation(strategyConfig, '1.001');
assert.isTrue(result);
});
});
\ No newline at end of file
diff --git a/tests/strategy-operations/payload.test.js b/tests/strategy-operations/payload.test.js
index c629229..8913fc7 100644
--- a/tests/strategy-operations/payload.test.js
+++ b/tests/strategy-operations/payload.test.js
@@ -84,33 +84,33 @@ describe('Processing strategy: PAYLOAD', () => {
]);
});
- it('should return TRUE when payload has field', async () => {
+ it('should return TRUE when payload has field', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ONE, ['login']);
- assert.isTrue(await processOperation(strategyConfig, fixture_1));
+ assert.isTrue(processOperation(strategyConfig, fixture_1));
});
- it('should return FALSE when payload does not have field', async () => {
+ it('should return FALSE when payload does not have field', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ONE, ['user']);
- assert.isFalse(await processOperation(strategyConfig, fixture_1));
+ assert.isFalse(processOperation(strategyConfig, fixture_1));
});
- it('should return TRUE when payload has nested field', async () => {
+ it('should return TRUE when payload has nested field', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ONE, [
'order.qty', 'order.total'
]);
- assert.isTrue(await processOperation(strategyConfig, fixture_values2));
+ assert.isTrue(processOperation(strategyConfig, fixture_values2));
});
- it('should return TRUE when payload has nested field with arrays', async () => {
+ it('should return TRUE when payload has nested field with arrays', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ONE, [
'order.deliver.tracking.status'
]);
- assert.isTrue(await processOperation(strategyConfig, fixture_values2));
+ assert.isTrue(processOperation(strategyConfig, fixture_values2));
});
- it('should return TRUE when payload has all', async () => {
+ it('should return TRUE when payload has all', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ALL, [
'product',
'order',
@@ -122,21 +122,21 @@ describe('Processing strategy: PAYLOAD', () => {
'order.deliver.tracking.status'
]);
- assert.isTrue(await processOperation(strategyConfig, fixture_values2));
+ assert.isTrue(processOperation(strategyConfig, fixture_values2));
});
- it('should return FALSE when payload does not have all', async () => {
+ it('should return FALSE when payload does not have all', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ALL, [
'product',
'order',
'order.NOT_EXIST_KEY',
]);
- assert.isFalse(await processOperation(strategyConfig, fixture_values2));
+ assert.isFalse(processOperation(strategyConfig, fixture_values2));
});
- it('should return FALSE when payload is not a JSON string', async () => {
+ it('should return FALSE when payload is not a JSON string', () => {
const strategyConfig = givenStrategyConfig(OperationsType.HAS_ALL, []);
- assert.isFalse(await processOperation(strategyConfig, 'NOT_JSON'));
+ assert.isFalse(processOperation(strategyConfig, 'NOT_JSON'));
});
});
\ No newline at end of file
diff --git a/tests/strategy-operations/regex.test.js b/tests/strategy-operations/regex.test.js
index 62e2500..e0a57b8 100644
--- a/tests/strategy-operations/regex.test.js
+++ b/tests/strategy-operations/regex.test.js
@@ -4,11 +4,11 @@ import TimedMatch from '../../src/lib/utils/timed-match/index.js';
import { processOperation, StrategiesType, OperationsType } from '../../src/lib/snapshot.js';
const mock_values1 = [
- '\\bUSER_[0-9]{1,2}\\b'
+ String.raw`\bUSER_[0-9]{1,2}\b`
];
const mock_values2 = [
- '\\bUSER_[0-9]{1,2}\\b', '\\buser-[0-9]{1,2}\\b'
+ String.raw`\bUSER_[0-9]{1,2}\b`, String.raw`\buser-[0-9]{1,2}\b`
];
const mock_values3 = [
diff --git a/tests/strategy-operations/time.test.js b/tests/strategy-operations/time.test.js
index 2df57f6..f3532de 100644
--- a/tests/strategy-operations/time.test.js
+++ b/tests/strategy-operations/time.test.js
@@ -18,51 +18,51 @@ describe('Processing strategy: TIME', () => {
activated: true,
});
- it('should agree when input is LOWER', async () => {
+ it('should agree when input is LOWER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '06:00');
+ const result = processOperation(strategyConfig, '06:00');
assert.isTrue(result);
});
- it('should agree when input is LOWER or SAME', async () => {
+ it('should agree when input is LOWER or SAME', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '08:00');
+ const result = processOperation(strategyConfig, '08:00');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT LOWER', async () => {
+ it('should NOT agree when input is NOT LOWER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.LOWER, mock_values1);
- const result = await processOperation(strategyConfig, '10:00');
+ const result = processOperation(strategyConfig, '10:00');
assert.isFalse(result);
});
- it('should agree when input is GREATER', async () => {
+ it('should agree when input is GREATER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '10:00');
+ const result = processOperation(strategyConfig, '10:00');
assert.isTrue(result);
});
- it('should agree when input is GREATER or SAME', async () => {
+ it('should agree when input is GREATER or SAME', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '08:00');
+ const result = processOperation(strategyConfig, '08:00');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT GREATER', async () => {
+ it('should NOT agree when input is NOT GREATER', () => {
const strategyConfig = givenStrategyConfig(OperationsType.GREATER, mock_values1);
- const result = await processOperation(strategyConfig, '06:00');
+ const result = processOperation(strategyConfig, '06:00');
assert.isFalse(result);
});
- it('should agree when input is in BETWEEN', async () => {
+ it('should agree when input is in BETWEEN', () => {
const strategyConfig = givenStrategyConfig(OperationsType.BETWEEN, mock_values2);
- const result = await processOperation(strategyConfig, '09:00');
+ const result = processOperation(strategyConfig, '09:00');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT in BETWEEN', async () => {
+ it('should NOT agree when input is NOT in BETWEEN', () => {
const strategyConfig = givenStrategyConfig(OperationsType.BETWEEN, mock_values2);
- const result = await processOperation(strategyConfig, '07:00');
+ const result = processOperation(strategyConfig, '07:00');
assert.isFalse(result);
});
diff --git a/tests/strategy-operations/value.test.js b/tests/strategy-operations/value.test.js
index 3af5a8d..93607c2 100644
--- a/tests/strategy-operations/value.test.js
+++ b/tests/strategy-operations/value.test.js
@@ -18,45 +18,45 @@ describe('Processing strategy: VALUE', () => {
activated: true,
});
- it('should agree when input EXIST', async () => {
+ it('should agree when input EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values1);
- const result = await processOperation(strategyConfig, 'USER_1');
+ const result = processOperation(strategyConfig, 'USER_1');
assert.isTrue(result);
});
- it('should NOT agree when input DOES NOT EXIST', async () => {
+ it('should NOT agree when input DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EXIST, mock_values1);
- const result = await processOperation(strategyConfig, 'USER_123');
+ const result = processOperation(strategyConfig, 'USER_123');
assert.isFalse(result);
});
- it('should agree when input DOES NOT EXIST', async () => {
+ it('should agree when input DOES NOT EXIST', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EXIST, mock_values1);
- const result = await processOperation(strategyConfig, 'USER_123');
+ const result = processOperation(strategyConfig, 'USER_123');
assert.isTrue(result);
});
- it('should agree when input is EQUAL', async () => {
+ it('should agree when input is EQUAL', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EQUAL, mock_values1);
- const result = await processOperation(strategyConfig, 'USER_1');
+ const result = processOperation(strategyConfig, 'USER_1');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT EQUAL', async () => {
+ it('should NOT agree when input is NOT EQUAL', () => {
const strategyConfig = givenStrategyConfig(OperationsType.EQUAL, mock_values1);
- const result = await processOperation(strategyConfig, 'USER_2');
+ const result = processOperation(strategyConfig, 'USER_2');
assert.isFalse(result);
});
- it('should agree when input is NOT EQUAL', async () => {
+ it('should agree when input is NOT EQUAL', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EQUAL, mock_values2);
- const result = await processOperation(strategyConfig, 'USER_123');
+ const result = processOperation(strategyConfig, 'USER_123');
assert.isTrue(result);
});
- it('should NOT agree when input is NOT EQUAL', async () => {
+ it('should NOT agree when input is NOT EQUAL', () => {
const strategyConfig = givenStrategyConfig(OperationsType.NOT_EQUAL, mock_values2);
- const result = await processOperation(strategyConfig, 'USER_2');
+ const result = processOperation(strategyConfig, 'USER_2');
assert.isFalse(result);
});
});
\ No newline at end of file
diff --git a/tests/switcher-client.test.js b/tests/switcher-client.test.js
index fe3fa86..f5065e3 100644
--- a/tests/switcher-client.test.js
+++ b/tests/switcher-client.test.js
@@ -1,4 +1,4 @@
-import { rmdir } from 'fs';
+import { rmdir } from 'node:fs';
import { assert } from 'chai';
import { spy } from 'sinon';
diff --git a/tests/switcher-functional.test.js b/tests/switcher-functional.test.js
index 96867a4..54282e2 100644
--- a/tests/switcher-functional.test.js
+++ b/tests/switcher-functional.test.js
@@ -1,6 +1,6 @@
import { assert } from 'chai';
import { stub, spy } from 'sinon';
-import { unwatchFile } from 'fs';
+import { unwatchFile } from 'node:fs';
import FetchFacade from '../src/lib/utils/fetchFacade.js';
import ExecutionLogger from '../src/lib/utils/executionLogger.js';
@@ -383,7 +383,7 @@ describe('Integrated test - Switcher:', function () {
.checkNetwork('192.168.0.1')
.checkDate('2019-12-01T08:30')
.checkTime('08:00')
- .checkRegex('\\bUSER_[0-9]{1,2}\\b')
+ .checkRegex(String.raw`\bUSER_[0-9]{1,2}\b`)
.checkPayload(JSON.stringify({ name: 'User 1' }))
.prepare('SWITCHER_MULTIPLE_INPUT');
@@ -393,7 +393,7 @@ describe('Integrated test - Switcher:', function () {
[ 'NETWORK_VALIDATION', '192.168.0.1' ],
[ 'DATE_VALIDATION', '2019-12-01T08:30' ],
[ 'TIME_VALIDATION', '08:00' ],
- [ 'REGEX_VALIDATION', '\\bUSER_[0-9]{1,2}\\b' ],
+ [ 'REGEX_VALIDATION', String.raw`\bUSER_[0-9]{1,2}\b` ],
[ 'PAYLOAD_VALIDATION', '{"name":"User 1"}' ]
]);
});
diff --git a/tests/switcher-snapshot.test.js b/tests/switcher-snapshot.test.js
index 35e6c4d..7db8df1 100644
--- a/tests/switcher-snapshot.test.js
+++ b/tests/switcher-snapshot.test.js
@@ -1,6 +1,6 @@
import { assert } from 'chai';
import { stub } from 'sinon';
-import { readFileSync, unlinkSync, existsSync } from 'fs';
+import { readFileSync, unlinkSync, existsSync } from 'node:fs';
import { Client } from '../switcher-client.js';
import FetchFacade from '../src/lib/utils/fetchFacade.js';