import { expect as c_expect } from 'chai' import Utils from '../../src/Util/Utils.js' describe('isHybridlessContainer', () => { test('Simple isHybridlessContainer test', () => { const v = Utils.isHybridlessContainer() c_expect(v).to.be.a('boolean') // this is done, so tests are reliable based on the testing .env c_expect(v).to.be[process.env.HYBRIDLESS_RUNTIME ? 'true' : 'false'] }) }) describe('isValidString', () => { test('Empty string is not valid', () => { const v = Utils.isValidString('') c_expect(v).to.be.a('boolean') c_expect(v).to.be.false }) test('Number is not a valid string', () => { // @ts-ignore const v = Utils.isValidString(12) c_expect(v).to.be.a('boolean') c_expect(v).to.be.false }) test('Simple string is valid', () => { const v = Utils.isValidString('abc') c_expect(v).to.be.a('boolean') c_expect(v).to.be.true }) }) describe('parseIntNullIfNaN', () => { test('Null if only chars', () => { const v = Utils.parseIntNullIfNaN('abc') c_expect(v).to.be.null }) test('Null if chars with numbers', () => { const v = Utils.parseIntNullIfNaN('abc123') c_expect(v).to.be.null }) test('Null if null', () => { // @ts-ignore const v = Utils.parseIntNullIfNaN(null) c_expect(v).to.be.null }) test('Not null if starts with numbers (js behavior)', () => { const v = Utils.parseIntNullIfNaN('123abc') c_expect(v).to.be.a('number') c_expect(v).to.be.equals(123) }) test('Not null if numbers', () => { const v = Utils.parseIntNullIfNaN('123') c_expect(v).to.be.a('number') c_expect(v).to.be.equals(123) }) test('Not null if number type', () => { // @ts-ignore const v = Utils.parseIntNullIfNaN(123) c_expect(v).to.be.a('number') c_expect(v).to.be.equals(123) }) }) describe('parseObjectNullIfEmpty', () => { test('Null if only chars', () => { const v = Utils.parseObjectNullIfEmpty('abc') c_expect(v).to.be.null }) test('Null if chars with numbers', () => { const v = Utils.parseObjectNullIfEmpty('abc123') c_expect(v).to.be.null }) test('Null if null', () => { // @ts-ignore const v = Utils.parseObjectNullIfEmpty(null) c_expect(v).to.be.null }) test('Null if malformed object', () => { const v = Utils.parseObjectNullIfEmpty('{d: 123}') c_expect(v).to.be.null }) test('Null if empty object', () => { const v = Utils.parseObjectNullIfEmpty('{}') c_expect(v).to.be.null }) test('Not null if object with a key', () => { const v = Utils.parseObjectNullIfEmpty('{"d": 123}') c_expect(v).to.be.a('object') c_expect(v?.['d']).to.be.equals(123) }) }) describe('isValidNumber', () => { test('Not a valid number if only chars', () => { const v = Utils.isValidNumber('abc') c_expect(v).to.be.false }) test('Not a valid number if only chars and numbers', () => { const v = Utils.isValidNumber('abc123') c_expect(v).to.be.false }) test('Not a valid number if causes a crash on conversion', () => { // @ts-ignore const v = Utils.isValidNumber({ toString: () => { throw new Error('Evil object') }, }) c_expect(v).to.be.false }) test('Valid number if numbers and chars after', () => { const v = Utils.isValidNumber('123abc') c_expect(v).to.be.true }) test('Valid number if numbers', () => { const v = Utils.isValidNumber('123') c_expect(v).to.be.true }) }) describe('caseInsensitiveObjectForKey', () => { test('Get a key that is lowercase, asking uppercase', () => { const v = Utils.caseInsensitiveObjectForKey({ abc: 123 }, 'ABC') c_expect(v).to.be.a('number') c_expect(v).to.be.equals(123) }) test('Get a key that is uppercase, asking lowercase', () => { const v = Utils.caseInsensitiveObjectForKey({ ABC: 123 }, 'abc') c_expect(v).to.be.a('number') c_expect(v).to.be.equals(123) }) test('Fails gracefully if key is not found', () => { const v = Utils.caseInsensitiveObjectForKey({ ABC: 123 }, 'asd') c_expect(v).to.be.null }) test('Fails gracefully for null object', () => { const v = Utils.caseInsensitiveObjectForKey(null, 'abc') c_expect(v).to.be.null }) test('Fails gracefully for invalid object', () => { const v = Utils.caseInsensitiveObjectForKey('', 'abc') c_expect(v).to.be.null }) }) describe('ddbMarshall', () => { test('Marshalling of a simple object', () => { const input = { key: 'value' } const output = Utils.ddbMarshall(input) expect(output).toEqual({ key: { S: 'value' } }) }) test('Marshalling of an array', () => { const input = [1, 2, 3] const output = Utils.ddbMarshall(input) expect(output).toEqual({ L: [{ N: '1' }, { N: '2' }, { N: '3' }] }) }) test('Marshalling of a nested object', () => { const input = { key: { nestedKey: 'nestedValue' } } const output = Utils.ddbMarshall(input) expect(output).toEqual({ key: { M: { nestedKey: { S: 'nestedValue' } } } }) }) test('Marshalling of a complex object with undefined values', () => { const input = { key1: 'value1', key2: undefined, key3: null } const output = Utils.ddbMarshall(input) expect(output).toEqual({ key1: { S: 'value1' }, key3: { NULL: true } }) }) test('Marshalling of a primitive value', () => { const input = 42 const output = Utils.ddbMarshall(input) expect(output).toEqual({ N: '42' }) }) }) describe('ddbUnmarshall', () => { test('Unmarshalling of a simple DynamoDB object', () => { const input = { key: { S: 'value' } } const output = Utils.ddbUnmarshall(input) expect(output).toEqual({ key: 'value' }) }) test('Unmarshalling of a DynamoDB array', () => { const input = { array: { L: [{ N: '1' }, { N: '2' }, { N: '3' }] } } const output = Utils.ddbUnmarshall(input) expect(output.array).toEqual([1, 2, 3]) }) test('Unmarshalling of a nested DynamoDB object', () => { const input = { key: { M: { nestedKey: { S: 'nestedValue' } } } } const output = Utils.ddbUnmarshall(input) expect(output).toEqual({ key: { nestedKey: 'nestedValue' } }) }) test('Unmarshalling of a complex DynamoDB object with null values', () => { const input = { key1: { S: 'value1' }, key3: { NULL: true } } const output = Utils.ddbUnmarshall(input) expect(output).toEqual({ key1: 'value1', key3: null }) }) test('Unmarshalling of a primitive value', () => { const input = { key: { N: '42' } } const output = Utils.ddbUnmarshall(input) expect(output.key).toEqual(42) }) })