import { existsSync , readFileSync } from 'fs' ; import { mocked } from 'jest-mock' ; import { parseBoolean , parseJsonProperty } from '@fc/common' ; import { ConfigParser } from './config-parser' ; jest . mock ( 'fs' , ( ) => ( { readFileSync : jest . fn ( ) , existsSync : jest . fn ( ) , } ) ) ; jest . mock ( '@fc/common' , ( ) => ( { parseBoolean : jest . fn ( ) , parseJsonProperty : jest . fn ( ) , } ) ) ; describe ( 'ConfigParser' , ( ) => { let reader ; const configMock = { 'someprefix/foo' : 'bar' , 'someprefix/bar' : '{"fizz":"buzz"}' , 'someprefix/baz' : 'true' , 'someprefix/woo' : '42' , 'someprefix/zin' : '/some/path/to/read.txt' , } ; const prefixMock = 'someprefix' ; const separatorMock = '/' ; const parseBooleanMock = mocked ( parseBoolean ) ; const parseJsonPropertyMock = mocked ( parseJsonProperty ) ; const readFileSyncMock = mocked ( readFileSync ) ; const existsSyncMock = mocked ( existsSync ) ; beforeEach ( ( ) => { reader = new ConfigParser ( configMock , prefixMock , separatorMock ) ; jest . resetAllMocks ( ) ; parseBooleanMock . mockReturnValue ( true ) ; parseJsonPropertyMock . mockReturnValue ( { fizz : 'baz' } ) ; } ) ; describe ( 'constructor' , ( ) => { it ( 'should use default separator' , ( ) => { const config = { } ; const prefix = 'test' ; const result = new ConfigParser ( config , prefix ) ; expect ( result ) . toHaveProperty ( 'separator' ) ; expect ( result [ 'separator' ] ) . toBe ( '_' ) ; } ) ; it ( 'should use given separator' , ( ) => { const config = { } ; const prefix = 'test' ; const separator = '#' ; const result = new ConfigParser ( config , prefix , separator ) ; expect ( result ) . toHaveProperty ( 'separator' ) ; expect ( result [ 'separator' ] ) . toBe ( '#' ) ; } ) ; } ) ; describe ( 'getFullPath' , ( ) => { it ( 'should return prefixed path' , ( ) => { const path = 'blah' ; const result = reader [ 'getFullPath' ] ( path ) ; expect ( result ) . toBe ( 'someprefix/blah' ) ; } ) ; } ) ; describe ( 'boolean' , ( ) => { it ( 'should execute parseBoolean with given value' , ( ) => { const path = 'baz' ; reader . boolean ( path ) ; expect ( parseBooleanMock ) . toHaveBeenCalledTimes ( 1 ) ; expect ( parseBooleanMock ) . toHaveBeenCalledWith ( configMock [ 'someprefix/baz' ] ) ; } ) ; it ( 'should return result from parseBoolean' , ( ) => { const path = 'baz' ; const parseBooleanMockReturnValue = Symbol ( 'true' ) ; parseBooleanMock . mockReturnValue ( parseBooleanMockReturnValue as unknown as boolean ) ; const result = reader . boolean ( path ) ; expect ( result ) . toBe ( parseBooleanMockReturnValue ) ; } ) ; } ) ; describe ( 'json' , ( ) => { it ( 'should execute parseJsonProperty with given value' , ( ) => { const path = 'baz' ; reader . json ( path ) ; expect ( parseJsonPropertyMock ) . toHaveBeenCalledTimes ( 1 ) ; expect ( parseJsonPropertyMock ) . toHaveBeenCalledWith ( configMock , 'someprefix/baz' ) ; } ) ; it ( 'should return result from parseJsonProperty' , ( ) => { const path = 'baz' ; const parseJsonPropertyMockReturnValue = Symbol ( 'someobject' ) ; parseJsonPropertyMock . mockReturnValue ( parseJsonPropertyMockReturnValue as unknown as object ) ; const result = reader . json ( path ) ; expect ( result ) . toBe ( parseJsonPropertyMockReturnValue ) ; } ) ; } ) ; describe ( 'string' , ( ) => { it ( 'should return simple variable' , ( ) => { const path = 'foo' ; const result = reader . string ( path ) ; expect ( result ) . toBe ( 'bar' ) ; } ) ; } ) ; describe ( 'number' , ( ) => { it ( 'should return a number' , ( ) => { const path = 'woo' ; const result = reader . number ( path ) ; expect ( typeof result ) . toBe ( 'number' ) ; expect ( result ) . toBe ( 42 ) ; } ) ; } ) ; describe ( 'file' , ( ) => { const fileContentMock = 'fileContentMockValue' ; beforeEach ( ( ) => { readFileSyncMock . mockReturnValue ( fileContentMock ) ; } ) ; it ( 'should call readfilesync with given path' , ( ) => { const path = 'zin' ; existsSyncMock . mockReturnValueOnce ( true ) ; const result = reader . file ( path ) ; expect ( existsSyncMock ) . toHaveBeenCalledTimes ( 1 ) ; expect ( existsSyncMock ) . toHaveBeenCalledWith ( '/some/path/to/read.txt' ) ; expect ( readFileSyncMock ) . toHaveBeenCalledTimes ( 1 ) ; expect ( readFileSyncMock ) . toHaveBeenCalledWith ( '/some/path/to/read.txt' , 'utf-8' ) ; expect ( result ) . toBe ( fileContentMock ) ; } ) ; it ( 'should return result null if file is missing and optional' , ( ) => { const path = 'zin' ; existsSyncMock . mockReturnValueOnce ( false ) ; const result = reader . file ( path , { optional : true } ) ; expect ( result ) . toBe ( null ) ; } ) ; it ( 'should throw an error if file is missing but not optional' , ( ) => { const path = 'zin' ; existsSyncMock . mockReturnValueOnce ( false ) ; expect ( ( ) => reader . file ( path , { optional : false } ) ) . toThrow ( 'file at path /some/path/to/read.txt is missing' ) ; } ) ; } ) ; } ) ;