diff --git a/src/exo3/exo3.test.ts b/src/exo3/exo3.test.ts new file mode 100644 index 0000000..ecc2375 --- /dev/null +++ b/src/exo3/exo3.test.ts @@ -0,0 +1,104 @@ +import * as Option from 'fp-ts/lib/Option'; + +import { + sortStrings, + sortNumbers, + sortNumbersDescending, + sortOptionalNumbers, + sortPersonsByName, + sortPersonsByAge, + sortPersonsByAgeThenByName, +} from './exo3'; + +describe('exo3', () => { + describe('sortStrings', () => { + it('should return an alphabetically sorted array of strings', () => { + const strings = ['xyz', 'aba', 'ori', 'aab', 'ghl']; + + const result = sortStrings(strings); + const expected = ['aab', 'aba', 'ghl', 'ori', 'xyz']; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortNumbers', () => { + it('should return a sorted array of numbers', () => { + const numbers = [1337, 42, 5701]; + + const result = sortNumbers(numbers); + const expected = [42, 1337, 5701]; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortNumbersDescending', () => { + it('should return a sorted array of descending numbers', () => { + const numbers = [1337, 42, 5701]; + + const result = sortNumbersDescending(numbers); + const expected = [5701, 1337, 42]; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortOptionalNumbers', () => { + it('should return a sorted array of optional numbers', () => { + const optionalNumbers = [Option.some(1337), Option.none, Option.some(42)]; + + const result = sortOptionalNumbers(optionalNumbers); + const expected = [Option.none, Option.some(42), Option.some(1337)]; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortPersonsByName', () => { + it('should return an array of persons alphabetically sorted by their name', () => { + const alice = { name: 'Alice', age: Option.none }; + const bob = { name: 'Bob', age: Option.none }; + const crystal = { name: 'Crystal', age: Option.none }; + + const persons = [crystal, alice, bob]; + + const result = sortPersonsByName(persons); + const expected = [alice, bob, crystal]; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortPersonsByName', () => { + it('should return an array of persons sorted by their age', () => { + const alice = { name: 'Alice', age: Option.some(42) }; + const bob = { name: 'Bob', age: Option.none }; + const crystal = { name: 'Crystal', age: Option.some(29) }; + + const persons = [crystal, alice, bob]; + + const result = sortPersonsByAge(persons); + const expected = [bob, crystal, alice]; + + expect(result).toStrictEqual(expected); + }); + }); + + describe('sortPersonsByName', () => { + it('should return an array of persons sorted first by age and then by name', () => { + const alice = { name: 'Alice', age: Option.some(42) }; + const bob = { name: 'Bob', age: Option.none }; + const crystal = { name: 'Crystal', age: Option.some(29) }; + const dorian = { name: 'Dorian', age: Option.some(29) }; + const edgar = { name: 'Edgar', age: Option.none }; + + const persons = [dorian, alice, edgar, bob, crystal]; + + const result = sortPersonsByAgeThenByName(persons); + const expected = [bob, edgar, crystal, dorian, alice]; + + expect(result).toStrictEqual(expected); + }); + }); +}); diff --git a/src/exo3/exo3.ts b/src/exo3/exo3.ts new file mode 100644 index 0000000..3b97f2e --- /dev/null +++ b/src/exo3/exo3.ts @@ -0,0 +1,59 @@ +// `fp-ts` training Exercice 3 +// Sort things out with `Ord` + +import * as Option from 'fp-ts/lib/Option'; + +import { unimplemented } from '../utils'; + +/////////////////////////////////////////////////////////////////////////////// +// SORT PRIMITIVE TYPES // +/////////////////////////////////////////////////////////////////////////////// + +export const sortStrings: ( + strings: ReadonlyArray, +) => ReadonlyArray = unimplemented; + +export const sortNumbers: ( + numbers: ReadonlyArray, +) => ReadonlyArray = unimplemented; + +/////////////////////////////////////////////////////////////////////////////// +// REVERSE SORT // +/////////////////////////////////////////////////////////////////////////////// + +export const sortNumbersDescending: ( + numbers: ReadonlyArray, +) => ReadonlyArray = unimplemented; + +/////////////////////////////////////////////////////////////////////////////// +// SORT OPTIONAL VALUES // +/////////////////////////////////////////////////////////////////////////////// + +export const sortOptionalNumbers: ( + optionalNumbers: ReadonlyArray>, +) => ReadonlyArray> = unimplemented; + +/////////////////////////////////////////////////////////////////////////////// +// SORT COMPLEX OBJECTS // +/////////////////////////////////////////////////////////////////////////////// + +export interface Person { + readonly name: string; + readonly age: Option.Option; +} + +export const sortPersonsByName: ( + person: ReadonlyArray, +) => ReadonlyArray = unimplemented; + +export const sortPersonsByAge: ( + person: ReadonlyArray, +) => ReadonlyArray = unimplemented; + +/////////////////////////////////////////////////////////////////////////////// +// COMBINE SORTING SCHEMES // +/////////////////////////////////////////////////////////////////////////////// + +export const sortPersonsByAgeThenByName: ( + person: ReadonlyArray, +) => ReadonlyArray = unimplemented; diff --git a/src/exo3/index.ts b/src/exo3/index.ts new file mode 100644 index 0000000..756b59b --- /dev/null +++ b/src/exo3/index.ts @@ -0,0 +1 @@ +export * from './exo3';