From 43e87278e23c239d7c3a7f4a30d0ee09bb10cc90 Mon Sep 17 00:00:00 2001 From: Maxim Kremnev Date: Sun, 20 Sep 2020 18:54:46 +0300 Subject: [PATCH 1/5] Init branch --- public/index.html | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/public/index.html b/public/index.html index 7d4e559..d3bf9cd 100644 --- a/public/index.html +++ b/public/index.html @@ -1,12 +1,14 @@ - - - - Document - - -
- + + + + Otus project Game of Life + + + +
+ + From a0724eaa9b6f6a0735a72e7bfd0026b599779f05 Mon Sep 17 00:00:00 2001 From: Maxim Kremnev Date: Mon, 21 Sep 2020 22:37:13 +0300 Subject: [PATCH 2/5] Installing ramda --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 83cc4ef..24f6bbe 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@types/enzyme": "^3.10.5", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/jest": "^26.0.5", + "@types/ramda": "^0.27.17", "@types/react": "^16.9.42", "@types/react-dom": "^16.9.8", "@types/react-redux": "^7.1.9", @@ -86,6 +87,7 @@ "loki": "^0.24.0", "postcss-loader": "^3.0.0", "prettier": "^2.0.5", + "ramda": "^0.27.1", "react-test-renderer": "^16.13.1", "redux-mock-store": "^1.5.4", "style-loader": "^1.2.1", From 49d77e463342cce265b08c2bf2a15b5a58787a9a Mon Sep 17 00:00:00 2001 From: Maxim Kremnev Date: Mon, 21 Sep 2020 22:37:59 +0300 Subject: [PATCH 3/5] Lesson 1 --- src/lesson14/immutability.test.ts | 56 +++++++++++++++++++++++++++++ src/lesson14/immutability.ts | 59 +++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/lesson14/immutability.test.ts create mode 100644 src/lesson14/immutability.ts diff --git a/src/lesson14/immutability.test.ts b/src/lesson14/immutability.test.ts new file mode 100644 index 0000000..6d1f528 --- /dev/null +++ b/src/lesson14/immutability.test.ts @@ -0,0 +1,56 @@ +import { + OriginalTeam, + ExpectedTeam, + originalTeamToExpectedTeam, + originalTeamToExpectedTeamObject, + originalArrayToExpectedArray, +} from './immutability'; + +// Задание 1 +test('team to team', () => { + const originalTeam: OriginalTeam = Object.freeze({ + size: 15, + name: 'Tampa Bay Roosters', + league: 'Minor', + }); + + const expectedTeam: ExpectedTeam = { + name: 'New York Badgers', + league: 'Minor', + roster: 25, + }; + + expect(originalTeamToExpectedTeamObject(originalTeam)).toEqual( + expectedTeam, + ); +}); + +// Задание 2 +test('array to array', () => { + const originalArray = Object.freeze([1, 2, 3, 4]); + + const expectedArray = ['two', 3, 4, 5]; + + expect(originalArrayToExpectedArray(originalArray)).toEqual(expectedArray); +}); + +// Задание 3 +test('team to team deep', () => { + const originalTeam = Object.freeze({ + name: 'Tampa Bay Roosters', + captain: { + name: 'Bryan Downey', + age: 27, + }, + }); + + const expectedTeam = { + name: 'Tampa Bay Roosters', + captain: { + name: 'Bryan Downey', + age: 28, + }, + }; + + expect(originalTeamToExpectedTeam(originalTeam)).toEqual(expectedTeam); +}); diff --git a/src/lesson14/immutability.ts b/src/lesson14/immutability.ts new file mode 100644 index 0000000..43873d3 --- /dev/null +++ b/src/lesson14/immutability.ts @@ -0,0 +1,59 @@ +// Задание 1 +export type OriginalTeam = { + size: number; + name: string; + league: string; +}; + +export type ExpectedTeam = { + name: string; + league: string; + roster: number; +}; + +export const originalTeamToExpectedTeamObject = ( + originalTeam: OriginalTeam, +): ExpectedTeam => { + const withoutSize = Object.entries(originalTeam).filter( + (value) => value[0] !== 'size', + ); + const newValueKeyOfName = withoutSize.map((value) => { + if (value[0] === 'name' && value[1] !== 'New York Badgers') + value[1] = 'New York Badgers'; + return value; + }); + const teamNew = Object.fromEntries( + (newValueKeyOfName as unknown) as string[], + ); + + return { ...teamNew, roster: 25 }; +}; + +// Задание 2 +type SomeArray = Array; + +export const originalArrayToExpectedArray = ( + originalArray: SomeArray, +): SomeArray => { + const cloneArrayWithoutFirstElement = originalArray.slice(2); + return ['two', ...cloneArrayWithoutFirstElement, 5]; +}; + +// Задание 3 + +export type Team = { + name: string; + captain: { + name: string; + age: number; + }; +}; + +export const originalTeamToExpectedTeam = (originalTeam: Team): Team => { + const cloneOriginalTeam = Object.assign({}, originalTeam); + const newCaptain = { + name: 'Bryan Downey', + age: 28, + }; + return { ...cloneOriginalTeam, captain: newCaptain }; +}; From 6385bbfe15ffc98a0fd5dbc9358e13ac749044f2 Mon Sep 17 00:00:00 2001 From: Maxim Kremnev Date: Mon, 21 Sep 2020 22:38:24 +0300 Subject: [PATCH 4/5] Lesson 2 --- src/lesson14/pureFunctions.test.ts | 36 ++++++++++++++++++++++++++++++ src/lesson14/pureFunctions.ts | 31 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/lesson14/pureFunctions.test.ts create mode 100644 src/lesson14/pureFunctions.ts diff --git a/src/lesson14/pureFunctions.test.ts b/src/lesson14/pureFunctions.test.ts new file mode 100644 index 0000000..8d3fe54 --- /dev/null +++ b/src/lesson14/pureFunctions.test.ts @@ -0,0 +1,36 @@ +import { getTopName, Team, QsObj, createQs, parseQs } from './pureFunctions'; + +test('getTopName', () => { + const teams: Team[] = [ + { name: 'Lions', score: 5 }, + { name: 'Tigers', score: 4 }, + { name: 'Bears', score: 6 }, + { name: 'Monkeys', score: 2 }, + ]; + + expect(getTopName(teams)).toBe('Bears'); +}); + +test('createQs', () => { + const qsObj: QsObj = { + page: '2', + pageSize: '10', + total: '205', + somethingElse: 'value', + }; + + expect(createQs(qsObj)).toBe( + '?page=2&pageSize=10&total=205&somethingElse=value', + ); +}); + +test('parseQs', () => { + const qs = '?page=2&pageSize=10&total=205&somethingElse=value'; + + expect(parseQs(qs)).toEqual({ + page: '2', + pageSize: '10', + total: '205', + somethingElse: 'value', + }); +}); diff --git a/src/lesson14/pureFunctions.ts b/src/lesson14/pureFunctions.ts new file mode 100644 index 0000000..eaeda57 --- /dev/null +++ b/src/lesson14/pureFunctions.ts @@ -0,0 +1,31 @@ +// Задание 1 +export type Team = { name: string; score: number }; + +export const getTopName = (teams: Team[]): string => { + const copyTeams = teams.map((value) => Object.assign({}, value)); + const sorted = copyTeams.sort((x, y) => (x.score > y.score ? 1 : -1)); + return sorted[sorted.length - 1].name; +}; + +// Задание 2 +export type QsObj = Record; + +export const createQs = (qsObj: QsObj): string => { + const objectToArray = Object.entries(qsObj); + const elementJoinEquals = objectToArray.map((val) => val.join('=')); + const stringJoinAmp = elementJoinEquals.join('&'); + const propsWithSymbol = stringJoinAmp.replace(/^/, '?'); + return propsWithSymbol; +}; + +// Задание 3 + +export const parseQs = (qs: string): QsObj => { + const propsWithoutSymbol = qs.replace(/\?/y, ''); + const stringSplitAmp = propsWithoutSymbol.split('&'); + const elementSplitEquals = stringSplitAmp.map((v) => v.split('=')); + const desiredObject = Object.fromEntries( + (elementSplitEquals as unknown) as string[], + ); + return desiredObject; +}; From 9e9a181fb786896cef2bc7e5aa8a9eb13d83396e Mon Sep 17 00:00:00 2001 From: Maxim Kremnev Date: Mon, 21 Sep 2020 22:38:51 +0300 Subject: [PATCH 5/5] Lesson 3 --- src/lesson14/ramdaPureFunctions.test.ts | 42 +++++++++++++++++++++++++ src/lesson14/ramdaPureFunctions.ts | 40 +++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/lesson14/ramdaPureFunctions.test.ts create mode 100644 src/lesson14/ramdaPureFunctions.ts diff --git a/src/lesson14/ramdaPureFunctions.test.ts b/src/lesson14/ramdaPureFunctions.test.ts new file mode 100644 index 0000000..98e353b --- /dev/null +++ b/src/lesson14/ramdaPureFunctions.test.ts @@ -0,0 +1,42 @@ +import { + getTopName, + Team, + QsObj, + createQs, + parseQs, +} from './ramdaPureFunctions'; + +test('getTopName', () => { + const teams: Team[] = [ + { name: 'Lions', score: 5 }, + { name: 'Tigers', score: 4 }, + { name: 'Bears', score: 6 }, + { name: 'Monkeys', score: 2 }, + ]; + + expect(getTopName(teams)).toBe('Bears'); +}); + +test('createQs', () => { + const qsObj: QsObj = { + page: '2', + pageSize: '10', + total: '205', + somethingElse: 'value', + }; + + expect(createQs(qsObj)).toBe( + '?page=2&pageSize=10&total=205&somethingElse=value', + ); +}); + +test('parseQs', () => { + const qs = '?page=2&pageSize=10&total=205&somethingElse=value'; + + expect(parseQs(qs)).toEqual({ + page: '2', + pageSize: '10', + total: '205', + somethingElse: 'value', + }); +}); diff --git a/src/lesson14/ramdaPureFunctions.ts b/src/lesson14/ramdaPureFunctions.ts new file mode 100644 index 0000000..3422d17 --- /dev/null +++ b/src/lesson14/ramdaPureFunctions.ts @@ -0,0 +1,40 @@ +import { compose, last, sortBy, prop, map, join, replace, split } from 'ramda'; + +// Задание 1 +export type Team = { name: string; score: number }; + +const copyTeams = (teams: Team[]) => + teams.map((value) => Object.assign({}, value)); +const sortByObj = sortBy((t) => t.score); +const getName = prop('name'); + +export const getTopName = compose(getName, last, sortByObj, copyTeams); + +// Задание 2 +export type QsObj = Record; +export type CreateQs = (x: QsObj) => string; + +const objectToArray = (qsObj: QsObj): string[][] => + Object.entries(qsObj as any); +const elementJoinEquals = map((val: string[]) => val.join('=')); +const stringJoinAmp = join('&'); +const propsWithSymbol = replace(/^/, '?'); +export const createQs: CreateQs = compose( + propsWithSymbol, + stringJoinAmp, + elementJoinEquals, + objectToArray, +); + +// Задание 3 +const propsWithoutSymbol = replace(/\?/y, ''); +const stringSplitAmp = split('&'); +const elementSplitEquals = map((v: string) => v.split('=')); +const desiredObject = (desiredObject: string[][]) => + Object.fromEntries(desiredObject as any); +export const parseQs = compose( + desiredObject, + elementSplitEquals, + stringSplitAmp, + propsWithoutSymbol, +);