├── src ├── ArraySchema.js ├── NumberSchema.js ├── ObjectSchema.js ├── StringSchema.js └── Validator.js ├── .gitignore ├── .npmrc ├── index.js ├── .gitattributes ├── .eslintrc.yml ├── Makefile ├── .github └── workflows │ └── test-check.yml ├── package.json ├── __tests__ └── index.test.js └── README.md /src/ArraySchema.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/NumberSchema.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/ObjectSchema.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/StringSchema.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Validator.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | node-options=--no-warnings --experimental-vm-modules 2 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Validator from './src/Validator.js'; 2 | 3 | export default Validator; 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | index.js Validator.js StringSchema.js NumberSchema.js ObjectSchema.js ArraySchema.js filter=crypt diff=crypt merge=crypt -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | env: 4 | browser: true 5 | es2021: true 6 | extends: airbnb-base 7 | overrides: [] 8 | parserOptions: 9 | ecmaVersion: latest 10 | sourceType: module 11 | rules: 12 | import/extensions: 13 | - error 14 | # - ignorePackages 15 | - js: always 16 | no-console: 0 17 | no-underscore-dangle: [2, {"allow": ["__filename", "__dirname"]}] 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | setup: install 2 | npx simple-git-hooks 3 | 4 | install: 5 | npm ci 6 | 7 | test: 8 | npm test 9 | 10 | lint: 11 | npx eslint . 12 | 13 | lint-fix: 14 | npx eslint . --fix 15 | 16 | update-deps: 17 | npx ncu -u 18 | 19 | test-steps: 20 | node --test --test-name-pattern step1 21 | node --test --test-name-pattern step2 22 | node --test --test-name-pattern step3 23 | node --test --test-name-pattern step4 24 | node --test --test-name-pattern step5 25 | -------------------------------------------------------------------------------- /.github/workflows/test-check.yml: -------------------------------------------------------------------------------- 1 | name: test-check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | matrix: 14 | node-version: [20.x] 15 | 16 | permissions: 17 | contents: write 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Use Node.js ${{ matrix.node-version }} 22 | uses: actions/setup-node@v2 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | cache: 'npm' 26 | - run: make install 27 | - run: make lint 28 | - run: make test 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "work", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "node --test" 9 | }, 10 | "simple-git-hooks": { 11 | "pre-push": "make lint" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/sseezov/tst.git" 16 | }, 17 | "author": "", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/sseezov/tst/issues" 21 | }, 22 | "homepage": "https://github.com/sseezov/tst#readme", 23 | "dependencies": { 24 | "@faker-js/faker": "^7.6.0", 25 | "lodash": "^4.17.21" 26 | }, 27 | "devDependencies": { 28 | "eslint": "^8.40.0", 29 | "eslint-config-airbnb-base": "^15.0.0", 30 | "eslint-plugin-import": "^2.27.5", 31 | "npm-check-updates": "^16.10.11", 32 | "simple-git-hooks": "^2.8.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import { test } from 'node:test'; 4 | import assert from 'assert/strict'; 5 | import Validator from '../index.js'; 6 | 7 | test('task1', () => { 8 | const validator = new Validator(); 9 | 10 | const schema1 = validator.string(); 11 | assert.equal(schema1.isValid('Hexlet'), true); 12 | assert.equal(schema1.isValid(''), true); 13 | assert.equal(schema1.isValid(true), false); 14 | assert.equal(schema1.isValid(123), false); 15 | assert.equal(schema1.isValid(), false); 16 | }); 17 | 18 | test('task2', () => { 19 | const validator = new Validator(); 20 | const schema1 = validator.string().startsFromUpperCase(); 21 | 22 | assert.equal(schema1.isValid(''), false); 23 | assert.equal(schema1.isValid('Hexlet'), true); 24 | assert.equal(schema1.isValid(' '), false); 25 | assert.equal(schema1.isValid('!H!'), false); 26 | assert.equal(schema1.isValid('1H!'), false); 27 | assert.equal(schema1.isValid('3H!'), false); 28 | assert.equal(schema1.isValid('0H!'), false); 29 | 30 | const schema2 = validator.string().length(5).startsFromUpperCase(); 31 | assert.equal(schema2.isValid('hexlet'), false); 32 | assert.equal(schema2.isValid(' hello?'), false); 33 | assert.equal(schema2.isValid('Hieee'), true); 34 | assert.equal(schema2.isValid('!Hide'), false); 35 | 36 | const schema3 = validator.string().length(5).startsFromUpperCase().hasExclamation(); 37 | assert.equal(schema3.isValid('hexlet'), false); 38 | assert.equal(schema3.isValid(' hello?'), false); 39 | assert.equal(schema3.isValid('Hieee'), false); 40 | assert.equal(schema3.isValid('Hide!'), true); 41 | 42 | const schema4 = validator.string().hasExclamation().length(5); 43 | assert.equal(schema4.isValid('hexle'), false); 44 | assert.equal(schema4.isValid(' hello?'), false); 45 | assert.equal(schema4.isValid('Hieee'), false); 46 | assert.equal(schema4.isValid('Hide!'), true); 47 | }); 48 | 49 | test('task3', () => { 50 | const validator = new Validator(); 51 | const schema = validator.array(); 52 | 53 | assert.equal(schema.isValid('Hello!'), false); 54 | assert.equal(schema.isValid(123), false); 55 | assert.equal(schema.isValid([]), true); 56 | assert.equal(schema.isValid([1, 23, 4]), true); 57 | assert.equal(schema.isValid({}), false); 58 | assert.equal(schema.isValid(() => { }), false); 59 | }); 60 | 61 | test('task4', () => { 62 | const validator = new Validator(); 63 | const schema1 = validator.array().maxDepth(1); 64 | const schema2 = validator.array().maxDepth(8); 65 | const schema3 = validator.array().maxDepth(3); 66 | 67 | assert.equal(schema1.isValid(null), false); 68 | assert.equal(schema1.isValid([]), true); 69 | assert.equal(schema1.isValid([0, 0, 0, 0]), true); 70 | assert.equal(schema1.isValid([0, 0, 0, 0, [1], [1, [2]]]), false); 71 | 72 | assert.equal(schema2.isValid([1, 2, 3, [0, [1, [2, [3, [4]]]]]]), true); 73 | assert.equal(schema2 74 | .isValid([1, [2], [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11]]]]]]]]]]]]), false); 75 | 76 | assert.equal(schema3.isValid([0, 0, 0, [1, [2], [2, [3]], [1, [2, [3, [4]]]]]]), false); 77 | assert.equal(schema3.isValid([[1], [[2]], [[[3]]]]), true); 78 | }); 79 | 80 | test('task5', () => { 81 | const validator = new Validator(); 82 | const schema1 = validator.object().shape({ 83 | name: validator.string().startsFromUpperCase(), 84 | basket: validator.array().maxDepth(1), 85 | }); 86 | 87 | const schema2 = validator.object().shape({ 88 | name: validator.string(), 89 | basket: validator.array().maxDepth(0), 90 | payment: validator.array().maxDepth(2), 91 | }); 92 | 93 | assert.equal(schema1.isValid({ name: 'B11', basket: ['potatos', 'tomatos', 'oranges', ['carrots']] }), true); 94 | assert.equal(schema1.isValid({ name: '12', basket: ['potatos', 'tomatos', 'oranges'] }), false); 95 | assert.equal(schema1.isValid({}), false); 96 | 97 | assert.equal(schema2.isValid({ name: 'sergey', basket: ['apple', 'cucumber'], payment: ['10 dollars', '10 cents', [0, [1]]] }), true); 98 | assert.equal(schema2.isValid({ name: 17, basket: ['apple', 'cucumber'], payment: ['10 dollars', '10 cents'] }), false); 99 | assert.equal(schema2.isValid({ name: '213', basket: ['apple'], payment: ['10 dollars', '10 cents'] }), true); 100 | }); 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Правила и регламент 2 | 3 | - [Экзамен: правила, рекомендации и порядок проведения](https://hexly.notion.site/d9289c18871c44508bc7c7f05a51d94f) 4 | 5 | ## Задание 6 | 7 | Ваша задача написать валидатор, в котором есть ряд методов и свойств и экспортировать его из файла *index.js*. Валидатор позволяет проверять аргументы на соответствие необходимым условиям, которые были заданы с помощью методов валидатора. 8 | 9 | Пример использования: 10 | 11 | ```javascript 12 | // создаем экземпляр валидатора 13 | const v = new Validator(); 14 | // определяем метод для валидации строк и связываем его с валидатором, обращаясь к нему через переменную 15 | const schema = v.string(); 16 | 17 | // проверяем данные на соответствие строковому типу, с помощью метода isValid() 18 | schema.isValid('Hexlet'); // true 19 | schema.isValid(''); // true 20 | schema.isValid(null); // false 21 | schema.isValid(123); // false 22 | ``` 23 | 24 | ### Примечания 25 | 26 | Вы можете самостоятельно протестировать работу валидатора. В каталоге *src* разрешено использовать любые файлы и создавать новые, если это делает вашу разработку более удобной. 27 | 28 | Для тестирования валидатора, достаточно создать экземпляр валидатора, настроить валидацию с помощью методов и вызвать метод `validate()` с необходимым аргументом, после чего написать в терминале: 29 | 30 | ```bash 31 | node index.js 32 | ``` 33 | 34 | ## 1 задача 35 | 36 | Вам необходимо создать валидатор, который способен принимать аргумент и проводить его проверку на соответствие определенным условиям. В данной задаче мы ограничиваемся валидацией только строк. Для этого в вашем валидаторе должен быть метод `string()`, который создает экземпляр валидатора строк. Этот экземпляр обладает методом `isValid()`, который принимает данные на вход и возвращает значение true или false в зависимости от того, являются ли входные данные строкой или нет. 37 | 38 | **Параметры и методы** 39 | 40 | - аргумент, который мы валидируем (проверяем) 41 | - метод валидатора `string()`, который создает экземпляр валидатора строк 42 | - метод экземпляра `isValid()`, который вызывается у экземпляра `string()`, он принимает данные на вход и валидирует 43 | 44 | ```javascript 45 | const v = new Validator(); 46 | const schema = v.string(); 47 | 48 | schema.isValid(null); // false 49 | schema.isValid(''); // true 50 | schema.isValid(true); // false 51 | schema.isValid('123'); // true 52 | schema.isValid(0); // false 53 | ``` 54 | 55 | После добавления методов `string()` и `isValid()`, экземпляр валидатора будет проверять является ли аргумент типом данных *String*. 56 | 57 | ## 2 задача 58 | 59 | а) Вам необходимо расширить функциональность экземпляра валидатора строк, добавив к нему метод `startsFromUpperCase()` . 60 | При вызове метода `startsFromUpperCase()`, он добавляет дополнительную проверку, 61 | которая будет выполняться при вызове метода `isValid()` на то, начинается ли строка с заглвной буквы. 62 | 63 | б) Вам необходимо расширить функциональность экземпляра валидатора строк, добавив к нему метод `length()` . 64 | При вызове метода `length()` c переданным аргументом, он добавляет дополнительную проверку, 65 | которая будет выполняться при вызове метода `isValid()` на то, соответствует ли длина строки заданной. 66 | 67 | в) Вам необходимо расширить функциональность экземпляра валидатора строк, добавив к нему метод `hasExclamation()` . 68 | При вызове метода `hasExclamation()`, он добавляет дополнительную проверку, 69 | которая будет выполняться при вызове метода `isValid()` на то, включает ли строка восклицательные знаки. 70 | 71 | **Методы** 72 | 73 | - метод `startsFromUpperCase()`, который вызывается у экземпляра `string()`. Он добавляет проверку первой буквы в слове на то, является ли она заглавной 74 | - метод `length()`, который вызывается у экземпляра `string()`. Он добавляет проверку строки на соответствие заданной длине 75 | - метод `hasExclamation()`, который вызывается у экземпляра `string()`. Он добавляет проверку строки на наличие восклицательных знаков 76 | 77 | ```javascript 78 | const v = new Validator(); 79 | 80 | const schema1 = v.string(); 81 | schema1.isValid('hexlet'); // true; 82 | 83 | const schema2 = v.string().startsFromUpperCase() 84 | schema2.isValid('hexlet'); // false; 85 | schema2.isValid(' hello?'); // false; 86 | schema2.isValid('Hi'); // true; 87 | schema2.isValid('!Hi'); // false; 88 | schema2.isValid('1Hi'); // false; 89 | 90 | const schema2 = v.string().length(5).startsFromUpperCase() 91 | schema2.isValid('hexlet'); // false; 92 | schema2.isValid(' hello?'); // false; 93 | schema2.isValid('Hieee'); // true; 94 | schema2.isValid('!Hide'); // false; 95 | 96 | const schema2 = v.string().length(5).startsFromUpperCase().hasExclamation() 97 | schema2.isValid('hexlet'); // false; 98 | schema2.isValid(' hello?'); // false; 99 | schema2.isValid('Hieee'); // false; 100 | schema2.isValid('Hide!'); // true; 101 | ``` 102 | 103 | После добавления методов `startsFromUpperCase()`, экземпляр валидатора строк будет проверять содержит ли аргумент заглавные буквы. 104 | 105 | ## 3 задача 106 | 107 | Вам необходимо создать валидатор массивов, добавив к нему метод `array()`. Аналогично методу `string()`, метод `array()` создает экземпляр валидатора массивов. Для валидации массива у этого экземпляра также есть метод `isValid()`, который проверяет, является ли переданный аргумент массивом. 108 | 109 | **Методы** 110 | 111 | - метод валидатора `array()`, который создает экземпляр валидатора массивов 112 | - метод `isValid()`, который вызывается у экземпляра `array()`. Он проверяет является ли аргумент массивом 113 | 114 | ```javascript 115 | const v = new Validator(); 116 | const schema = v.array(); 117 | 118 | schema.isValid([]); // true 119 | schema.isValid({}); // false 120 | schema.isValid(123); // false 121 | schema.isValid('Hexlet'); // false 122 | ``` 123 | 124 | После добавления метода `array()`, экземпляр валидатора сможет проверять переданные значения на соответствие экземпляру глобального объекта Array. 125 | 126 | ## 4 задача 127 | 128 | Вам необходимо расширить функциональность экземпляра валидатора массивов. Кроме того, что он может валидировать, является ли аргумент массивом, он должен также иметь возможность проверять, соответствует ли какой-либо из вложенных массивов указанной глубине, если бы вызван метод `maxDepth()`, аргументом в котором является число, означающее необходимую глубину массива, где 0 - это отсутствие вложенных массивов. 129 | 130 | **Методы** 131 | 132 | - метод `maxDepth()`, который вызывается у экземпляра `array()`. Он проверяет соответствует ли глубина вложенности в массиве заданному в `maxDepth()` аргументу. То есть в массиве не должно быть массивов с глубиной вложенности более чем значение аргумента. 133 | 134 | ```javascript 135 | const v = new Validator(); 136 | const schema1 = v.array(); 137 | schema1.isValid([1, 2]); // true 138 | 139 | const schema2 = v.array().maxDepth(3); 140 | schema2.isValid([1, 2]); // true 141 | schema2.isValid([1, [2, [3]]]); // true 142 | schema2.isValid([1, [2, [3, [4]]]]); // false 143 | ``` 144 | 145 | После добавления метода `maxDepth()`, экземпляр валидатора массивов будет способен проверять, соответствует ли длина массива заданной в методе длине. 146 | 147 | ## 5 задача 148 | 149 | Вам необходимо создать валидатор полей объекта, используя методы, представленные в предыдущих задачах. Для этого необходимо создать метод `object()`, который проверяет не сам объект, а данные внутри него на соответствием заданным валидаторам. Метод `Validator.object()` должен содержать метод `shape()`, позволяющий задать поля, подлежащие валидации, для объекта. Метод `shape()` принимает объект, в котором ключи представляют поля, которые требуется проверить, а значения - экземпляры валидаторов. 150 | 151 | **Методы** 152 | 153 | - метод валидатора (экземпляр класса *Validator*) `object()`, который проверяет данные внутри объекта (поля объекта) 154 | - метод `shape()`, который вызывается у экземпляра `object()`. Он позволяет задать поля валидации для объекта 155 | 156 | ```javascript 157 | const v = new Validator(); 158 | 159 | // Позволяет описывать валидацию для свойств объекта 160 | const schema = v.object().shape({ 161 | name: v.string().startsFromUpperCase(), // теперь, при валидации объекта с ключом id, значение этого ключа пройдет валидацию в соответствии с текущими методами 162 | friends: v.array().maxDepth(0), 163 | }); 164 | 165 | schema.isValid({ name: 'Sergey', friends: ['mark', 'john', 'anna'] }); // true 166 | schema.isValid({ name: 12, friends: ['potatos', 'tomatos', 'oranges'] }); // false 167 | schema.isValid({ name: 'andrey', friends: ['sergey',['ivan', 'anatoly']] }); // false 168 | ``` 169 | 170 | После добавления методов `object()` и `shape()`, экземпляр валидатора сможет проверять поля объекта на соответствие заданным валидаторам 171 | --------------------------------------------------------------------------------