/* * Copyright 2021 Juan Cruz Viotti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import tap from 'tap' import * as fc from 'fast-check' import * as util from 'util' import { JSONValue } from '../../lib/json' import { ChoiceOptions } from '../../lib/encoder/enum/options' import { TOP_LEVEL_8BIT_CHOICE_INDEX as ENCODE_TOP_LEVEL_8BIT_CHOICE_INDEX, BOUNDED_CHOICE_INDEX as ENCODE_BOUNDED_CHOICE_INDEX, LARGE_BOUNDED_CHOICE_INDEX as ENCODE_LARGE_BOUNDED_CHOICE_INDEX } from '../../lib/encoder/enum/encode' import { EnumResult, TOP_LEVEL_8BIT_CHOICE_INDEX as DECODE_TOP_LEVEL_8BIT_CHOICE_INDEX, BOUNDED_CHOICE_INDEX as DECODE_BOUNDED_CHOICE_INDEX, LARGE_BOUNDED_CHOICE_INDEX as DECODE_LARGE_BOUNDED_CHOICE_INDEX } from '../../lib/encoder/enum/decode' import { ResizableBuffer, EncodingContext, getDefaultEncodingContext } from '../../lib/encoder' tap.test('TOP_LEVEL_8BIT_CHOICE_INDEX: should handle 1 of [ 1, 0, 0 ]', (test) => { const context: EncodingContext = getDefaultEncodingContext() const buffer: ResizableBuffer = new ResizableBuffer(Buffer.allocUnsafe(0)) const offset: number = 0 const value: number = 1 const options: ChoiceOptions = { choices: [ 1, 0, 0 ] } const bytesWritten: number = ENCODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, value, options, context) test.is(bytesWritten, 0) const result: EnumResult = DECODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, options) test.is(result.value, value) test.is(result.bytes, bytesWritten) test.end() }) tap.test('TOP_LEVEL_8BIT_CHOICE_INDEX: should handle 1 of [ 0, 1, 0 ]', (test) => { const context: EncodingContext = getDefaultEncodingContext() const buffer: ResizableBuffer = new ResizableBuffer(Buffer.allocUnsafe(0)) const offset: number = 0 const value: number = 1 const options: ChoiceOptions = { choices: [ 0, 1, 0 ] } const bytesWritten: number = ENCODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, value, options, context) test.is(bytesWritten, 1) const result: EnumResult = DECODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, options) test.is(result.value, value) test.is(result.bytes, bytesWritten) test.end() }) tap.test('TOP_LEVEL_8BIT_CHOICE_INDEX: should handle 1 of [ 0, 0, 1 ]', (test) => { const context: EncodingContext = getDefaultEncodingContext() const buffer: ResizableBuffer = new ResizableBuffer(Buffer.allocUnsafe(0)) const offset: number = 0 const value: number = 1 const options: ChoiceOptions = { choices: [ 0, 0, 1 ] } const bytesWritten: number = ENCODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, value, options, context) test.is(bytesWritten, 1) const result: EnumResult = DECODE_TOP_LEVEL_8BIT_CHOICE_INDEX(buffer, offset, options) test.is(result.value, value) test.is(result.bytes, bytesWritten) test.end() }) tap.test('BOUNDED_CHOICE_INDEX', (test) => { const arbitrary = fc.integer(1, 20).chain((length: number) => { return fc.tuple( fc.integer(0, length - 1), fc.array(fc.json(), { minLength: 1, maxLength: length })) }) fc.assert(fc.property(arbitrary, ([ index, array ]): boolean => { fc.pre(index < array.length) const context: EncodingContext = getDefaultEncodingContext() const choices: JSONValue[] = array.map((json: string) => { const value: JSONValue = JSON.parse(json) return value }) const buffer: ResizableBuffer = new ResizableBuffer(Buffer.allocUnsafe(1)) const bytesWritten: number = ENCODE_BOUNDED_CHOICE_INDEX(buffer, 0, choices[index], { choices }, context) const result: EnumResult = DECODE_BOUNDED_CHOICE_INDEX(buffer, 0, { choices }) return bytesWritten === 1 && result.bytes === bytesWritten && util.isDeepStrictEqual(result.value, choices[index]) }), { verbose: false }) test.end() }) tap.test('LARGE_BOUNDED_CHOICE_INDEX', (test) => { const arbitrary = fc.integer(1, 20).chain((length: number) => { return fc.tuple( fc.integer(0, length - 1), fc.array(fc.json(), { minLength: 1, maxLength: length })) }) fc.assert(fc.property(arbitrary, ([ index, array ]): boolean => { fc.pre(index < array.length) const context: EncodingContext = getDefaultEncodingContext() const choices: JSONValue[] = array.map((json: string) => { const value: JSONValue = JSON.parse(json) return value }) const buffer: ResizableBuffer = new ResizableBuffer(Buffer.allocUnsafe(1)) const bytesWritten: number = ENCODE_LARGE_BOUNDED_CHOICE_INDEX(buffer, 0, choices[index], { choices }, context) const result: EnumResult = DECODE_LARGE_BOUNDED_CHOICE_INDEX(buffer, 0, { choices }) return bytesWritten === 1 && result.bytes === bytesWritten && util.isDeepStrictEqual(result.value, choices[index]) }), { verbose: false }) test.end() })