-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Array picking and sampling (#8)
- Loading branch information
1 parent
82f8829
commit db00881
Showing
9 changed files
with
330 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { randomItemFromArray } from '../../utils'; | ||
import { | ||
GeneratedValue, | ||
ValueGenerator, | ||
ValueGeneratorConfig, | ||
} from '../ValueGenerator'; | ||
|
||
/** | ||
* Configuration for the array picker defining the array | ||
*/ | ||
export type ArrayPickerConfig = { | ||
array: any[]; | ||
} & ValueGeneratorConfig; | ||
|
||
/** | ||
* Randomly picks a single element from the given array and returns it as a value. | ||
*/ | ||
export class ArrayPicker extends ValueGenerator< | ||
GeneratedValue, | ||
ArrayPickerConfig | ||
> { | ||
constructor(config: ArrayPickerConfig) { | ||
if (config.array === null || config.array === undefined) { | ||
throw new Error(`Property 'array' is required`); | ||
} else if (!Array.isArray(config.array)) { | ||
throw new Error(`Property 'array' must be of type 'array'`); | ||
} else if (config.array.length < 1) { | ||
throw new Error(`Property 'array' must have at least one item`); | ||
} | ||
|
||
super(config); | ||
} | ||
|
||
get = (): GeneratedValue => { | ||
let value = randomItemFromArray(this.config.array); | ||
return this.pipe(value); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { | ||
GeneratedValue, | ||
ValueGenerator, | ||
ValueGeneratorConfig, | ||
} from '../ValueGenerator'; | ||
import { randomSampleFromArray } from '../../utils'; | ||
|
||
/** | ||
* Configuration for taking a sample from the given array. | ||
*/ | ||
export type ArraySampleConfig = { | ||
array: any[]; | ||
sampleSize: number; | ||
} & ValueGeneratorConfig; | ||
|
||
/** | ||
* This constant generator simply returns the number specified | ||
* in the configuration. | ||
*/ | ||
export class ArraySampleGenerator extends ValueGenerator< | ||
GeneratedValue, | ||
ArraySampleConfig | ||
> { | ||
constructor(config: ArraySampleConfig) { | ||
if (config.array === null || config.array === undefined) { | ||
throw new Error(`Property 'array' is required`); | ||
} else if (!Array.isArray(config.array)) { | ||
throw new Error(`Property 'array' must be of type 'array'`); | ||
} else if (config.array.length < 1) { | ||
throw new Error(`Property 'array' must have at least one item`); | ||
} else if (config.sampleSize === undefined || config.sampleSize === null) { | ||
throw new Error(`Property 'sampleSize' is required`); | ||
} else if (config.sampleSize < 1) { | ||
throw new Error( | ||
`Property 'sampleSize' has to be at least 1 (got: ${config.sampleSize})`, | ||
); | ||
} else if (config.sampleSize > config.array.length) { | ||
throw new Error( | ||
`Property 'sampleSize' has to be less or equal to size of the given array`, | ||
); | ||
} | ||
|
||
super(config); | ||
} | ||
|
||
get = (): GeneratedValue => { | ||
return this.pipe( | ||
randomSampleFromArray(this.config.array, this.config.sampleSize), | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { | ||
GeneratedValue, | ||
ValueGenerator, | ||
ValueGeneratorConfig, | ||
} from '../ValueGenerator'; | ||
|
||
/** | ||
* Configuration specifying which array of given items should the | ||
* constant generator produce. | ||
*/ | ||
export type ConstantArrayConfig = { | ||
array: any[]; | ||
} & ValueGeneratorConfig; | ||
|
||
/** | ||
* This constant generator simply returns the whole array specified | ||
* in the configuration. | ||
*/ | ||
export class ConstantArrayGenerator extends ValueGenerator< | ||
GeneratedValue, | ||
ConstantArrayConfig | ||
> { | ||
constructor(config: ConstantArrayConfig) { | ||
if (config.array === null || config.array === undefined) { | ||
throw new Error(`Property 'array' is required`); | ||
} else if (!Array.isArray(config.array)) { | ||
throw new Error(`Property 'array' must be of type 'array'`); | ||
} else if (config.array.length < 1) { | ||
throw new Error(`Property 'array' must have at least one item`); | ||
} | ||
|
||
super(config); | ||
} | ||
|
||
get = (): GeneratedValue => { | ||
return this.pipe(this.arrayDeepCopy(this.config.array)); | ||
}; | ||
|
||
private arrayDeepCopy = (arr: any[]) => { | ||
return JSON.parse(JSON.stringify(arr)); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './ArrayPicker'; | ||
export * from './ConstantArrayGenerator'; | ||
export * from './ArraySampleGenerator'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { ArrayPicker } from '../../../src'; | ||
|
||
describe('ArrayPicker generator class', () => { | ||
it('should return an item from the given array', () => { | ||
const array = ['a', 'b', 'c']; | ||
const generator = new ArrayPicker({ array }); | ||
expect(array.includes(generator.get())).toBe(true); | ||
}); | ||
|
||
it('should fail on empty array', () => { | ||
const array: any[] = []; | ||
expect(() => new ArrayPicker({ array })).toThrow(); | ||
}); | ||
|
||
it('should fail on non-array', () => { | ||
const array: string = ''; | ||
// @ts-ignore | ||
expect(() => new ArrayPicker({ array })).toThrow(); | ||
}); | ||
|
||
it('should fail on null', () => { | ||
// @ts-ignore | ||
const array: any[] = null; | ||
// @ts-ignore | ||
expect(() => new ArrayPicker({ array })).toThrow(); | ||
}); | ||
|
||
it('should fail on undefined', () => { | ||
// @ts-ignore | ||
const array: any[] = undefined; | ||
// @ts-ignore | ||
expect(() => new ArrayPicker({ array })).toThrow(); | ||
}); | ||
|
||
it('should pipe the value', () => { | ||
const array: any[] = ['a']; | ||
const generator = new ArrayPicker({ | ||
array, | ||
pipes: [(value: string) => value.toUpperCase()], | ||
}); | ||
|
||
expect(generator.get()).toBe('A'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { ArraySampleGenerator } from '../../../src'; | ||
|
||
describe('ArraySampleGenerator class', () => { | ||
it('should return a specified number of items', () => { | ||
const array = ['a', 'b', 'c', 'd']; | ||
const generator = new ArraySampleGenerator({ | ||
array, | ||
sampleSize: 2, | ||
}); | ||
|
||
expect(generator.get().length).toBe(2); | ||
}); | ||
|
||
it('should return a subset of the configured array', () => { | ||
const array = ['a', 'b', 'c', 'd']; | ||
const generator = new ArraySampleGenerator({ | ||
array, | ||
sampleSize: 2, | ||
}); | ||
|
||
const generatedItems = generator.get(); | ||
|
||
generatedItems.forEach((item: string) => { | ||
expect(array.includes(item)).toBe(true); | ||
}); | ||
}); | ||
|
||
it('should throw on zero sample size', () => { | ||
const config = { | ||
array: ['a', 'b', 'c', 'd'], | ||
sampleSize: 0, | ||
}; | ||
|
||
expect(() => new ArraySampleGenerator(config)).toThrow(); | ||
}); | ||
|
||
it('should throw on negative sample size', () => { | ||
const config = { | ||
array: ['a', 'b', 'c', 'd'], | ||
sampleSize: -1, | ||
}; | ||
|
||
expect(() => new ArraySampleGenerator(config)).toThrow(); | ||
}); | ||
|
||
it('should throw on empty array', () => { | ||
const config = { | ||
array: [], | ||
sampleSize: 1, | ||
}; | ||
|
||
expect(() => new ArraySampleGenerator(config)).toThrow(); | ||
}); | ||
|
||
it('should throw on greater sample size than array length', () => { | ||
const config = { | ||
array: ['a', 'b', 'c', 'd'], | ||
sampleSize: 15, | ||
}; | ||
|
||
expect(() => new ArraySampleGenerator(config)).toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { ConstantArrayGenerator } from '../../../src'; | ||
|
||
describe('ConstantArrayGenerator class', () => { | ||
it('should return array of the same size', () => { | ||
const array = ['a', 'b', 'c']; | ||
const generator = new ConstantArrayGenerator({ array }); | ||
|
||
expect(generator.get().length).toBe(array.length); | ||
}); | ||
|
||
it('should return exactly same array as given', () => { | ||
const array = ['a', 'b', 'c']; | ||
const generator = new ConstantArrayGenerator({ array }); | ||
|
||
const generated = generator.get(); | ||
|
||
generated.forEach((item: any, idx: number) => { | ||
expect(item).toBe(array[idx]); | ||
}); | ||
}); | ||
|
||
it('should throw on empty array', () => { | ||
const array: any[] = []; | ||
|
||
expect(() => new ConstantArrayGenerator({ array })).toThrow(); | ||
}); | ||
|
||
it('should throw on null', () => { | ||
const array = null; | ||
// @ts-ignore | ||
expect(() => new ConstantArrayGenerator({ array })).toThrow(); | ||
}); | ||
|
||
it('should throw on undefined', () => { | ||
const array = undefined; | ||
// @ts-ignore | ||
expect(() => new ConstantArrayGenerator({ array })).toThrow(); | ||
}); | ||
|
||
it('should throw on non-array argument', () => { | ||
const array = 'not array'; | ||
// @ts-ignore | ||
expect(() => new ConstantArrayGenerator({ array })).toThrow(); | ||
}); | ||
}); |