diff --git a/.github/ISSUE_TEMPLATE/story.md b/.github/ISSUE_TEMPLATE/story.md index c3b08f9..5f7f1a1 100644 --- a/.github/ISSUE_TEMPLATE/story.md +++ b/.github/ISSUE_TEMPLATE/story.md @@ -1,7 +1,7 @@ --- name: Story about: Story to organize development -title: "[STORY]" +title: "[STORY] - AOE - NUMBER -" labels: enhancement assignees: gastonpereyra diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md index e57bc62..a2a96cb 100644 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -1,9 +1,17 @@ +--- +name: PR +title: "PR - AOE - NUMBER -" +labels: enhancement +assignees: gastonpereyra + +--- + # :speech_balloon: Pull Request ## :link: Story Closes #NUMBER -Link [TITLE](https://github.com/gastonpereyra/REPO_NAME/issues/NUMBER) +Link [TITLE](https://github.com/gastonpereyra/are-objects-equals/issues/NUMBER) ## :sparkles: Solution diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5fee2f4..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: node_js -node_js: - - "lts/*" -cache: npm -script: - - | - # Run test script - npm run test-ci -after_script: - - | - # Upload coverage to coveralls - if [[ -d .nyc_output ]]; then - npm install --save-dev coveralls@2 - nyc report --reporter=text-lcov | coveralls - fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 103050a..1cb661b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.0.0] 2020-13-09 ### Added -- Github Actions \ No newline at end of file +- Github Actions +- Compare Function +- Documentation \ No newline at end of file diff --git a/README.md b/README.md index 335554b..193adb3 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,10 @@ ![Build Status](https://github.com/gastonpereyra/are-objects-equals/workflows/Build%20Status/badge.svg) [![Coverage Status](https://img.shields.io/coveralls/github/gastonpereyra/are-objects-equals/master.svg)](https://coveralls.io/r/gastonpereyra/are-objects-equals?branch=master) +![npm-are-objects-equals](https://user-images.githubusercontent.com/39351850/93023968-0f2c1400-f5c9-11ea-8e4c-c567dee98b44.png) + ## Description -A tool to compare objects easyly +A Function to compare and normalize objects easier ## Installation @@ -13,15 +15,123 @@ A tool to compare objects easyly npm i are-objects-equals ``` -## Methods +## Parmas + +`areObjectsEquals(objectBase, objectToCompare, options)` + +### objectBase and objectToCompare + +* Items to compare +* Type: `Object` +* Required + +Example + +```js +{ + name: "Juan Román", + lastname: "Riquelme", + clubs: ["Boca", "Barcelona", "Villareal", "Argentinos"], + number: 10, + stillPlaying: false, + birthPlace: { country: "Argentina", province: "Buenos Aires", city: "Don Torcuato" } +} +``` + +### options + +* Options to normalize the objects before compare +* Type: `Object` +* Optional + +Example + +```js +{ + fieldsToKeep: ["name", "number"] +} +``` + +:link: See more in [Object Normalize](https://github.com/gastonpereyra/objects-normalizer#options) + ## Usage +### areObjectsEquals(objectBase, objectToCompare) + +Will compare the 2 objects without any formatting + ```js const areObjectsEquals = require('are-objects-equals'); +const playerSample1 = { + name: "Juan Román", + lastname: "Riquelme", + clubs: ["Boca", "Barcelona", "Villareal", "Argentinos"], + number: 10, + stillPlaying: false, + birthPlace: { country: "Argentina", province: "Buenos Aires", city: "Don Torcuato" } +}; + +const playerSample2 = { + name: "Juan Román", + lastname: "Riquelme", + clubs: ["Boca", "Barcelona", "Villareal", "Argentinos"], + number: 10 +} + +areObjectsEquals(playerSample1, playerSample2); + +/* +output: false +*/ + +areObjectsEquals(playerSample1, playerSample1); + /* -output: +output: true */ ``` -## Extra \ No newline at end of file + +### areObjectsEquals(objectBase, objectToCompare, options) + +Will compare objects after normalize them + +```js +const areObjectsEquals = require('are-objects-equals'); + +const playerSample1 = { + name: "Juan Román", + lastname: "Riquelme", + clubs: ["Boca", "Barcelona", "Villareal", "Argentinos"], + number: 10, + stillPlaying: false, + birthPlace: { country: "Argentina", province: "Buenos Aires", city: "Don Torcuato" } +}; + +const playerSample2 = { + name: "Juan Román", + lastname: "Riquelme", + clubs: ["Boca", "Barcelona", "Villareal", "Argentinos"], + number: 10 +} + +areObjectsEquals(playerSample1, playerSample2, { fieldsToKeep: ["name", "lastname", "clubs", "number"]}); + +/* +output: true +*/ + +const playerSample3 = { + name: "Lionel", + lastname: "Messi", + clubs: ["Barcelona"], + number: 10, + stillPlaying: true +} + +areObjectsEquals(playerSample1, playerSample3, { fieldsToRemove: ["name", "lastname", "clubs", "stillPlaying"]}); + +/* +output: true +*/ \ No newline at end of file diff --git a/lib/are-objects-equals.js b/lib/are-objects-equals.js index d4f4469..f793077 100644 --- a/lib/are-objects-equals.js +++ b/lib/are-objects-equals.js @@ -1,3 +1,31 @@ -'use strict' +'use strict'; -module.exports = class areObjectsEquals {} \ No newline at end of file +const assert = require('assert'); +const objectNormalizer = require('objects-normalizer'); +const F = require('press-f'); + +const ERROR_NAME = 'AreObjectsEquals'; + +/** + * Normalize Objects and returns if both objects are equal + * @param {object} objectBase Base object + * @param {object} objectToCompare Object to Compare + * @param {object} options To normalize objects, FieldsToKeep or FieldsToRemove + * @returns {boolean} True if are equals, false if not + */ +const areObjectsEquals = (objectBase, objectToCompare, options) => { + + if(!objectBase || !objectToCompare) + throw new F('No objects to compare', ERROR_NAME); + + const [objectFormatted1, objectFormatted2] = objectNormalizer([objectBase, objectToCompare], options); + + try { + assert.deepStrictEqual(objectFormatted1, objectFormatted2); + return true; + } catch(error) { + return false; + } +}; + +module.exports = areObjectsEquals; diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 99dd866..0000000 --- a/lib/index.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -const AreObjectsEquals = require('./are-objects-equals'); - -module.exports = { - AreObjectsEquals -}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cd1992b..ab59860 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "are-objects-equals", - "version": "0.1.0", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -328,51 +328,6 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, - "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@sinonjs/formatio": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", - "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^5.0.2" - } - }, - "@sinonjs/samsam": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.1.0.tgz", - "integrity": "sha512-42nyaQOVunX5Pm6GRJobmzbS7iLI+fhERITnETXzzwDZh+TtDr/Au3yAvXVjFmZ4wEUaE4Y3NFZfKv0bV0cbtg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.6.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -1790,12 +1745,6 @@ "minimist": "^1.2.0" } }, - "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -1840,12 +1789,6 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -2019,19 +1962,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^6.0.0", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - } - }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -2314,6 +2244,14 @@ "has": "^1.0.3" } }, + "objects-normalizer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/objects-normalizer/-/objects-normalizer-1.0.3.tgz", + "integrity": "sha512-SZcrXgvTvTkeUqq650RydGsuzGrmotC5y7UcAOBRzaDZhhjzStpqpi1mjNnj7zDU/xCBHN9NQ+IpeI8Jre6lFg==", + "requires": { + "press-f": "^1.1.0" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2424,23 +2362,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -2477,6 +2398,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "press-f": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/press-f/-/press-f-1.1.0.tgz", + "integrity": "sha512-Za52UK2/6//ns/HwOI82SiwoctSx9jvizW7b7a10zDdmkIvux/G8wkzBXWgcm4o/KfH8uvyyGCUwqQSw7Buxtw==" + }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -2649,38 +2575,6 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "sinon": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz", - "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.2", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.1.0", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -2904,12 +2798,6 @@ "prelude-ls": "^1.2.1" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", diff --git a/package.json b/package.json index 14e5c56..2828c68 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "are-objects-equals", - "version": "0.1.0", + "version": "1.0.0", "description": "A tool to compare objects easyly", - "main": "lib/index.js", + "main": "lib/are-objects-equals.js", "files": [ "lib/" ], @@ -31,7 +31,10 @@ "eslint-config-airbnb-base": "^13.2.0", "eslint-plugin-import": "^2.22.0", "mocha": "^8.0.1", - "nyc": "^15.1.0", - "sinon": "^9.0.2" + "nyc": "^15.1.0" + }, + "dependencies": { + "objects-normalizer": "^1.0.3", + "press-f": "^1.1.0" } } diff --git a/tests/are-objects-equals.js b/tests/are-objects-equals.js index 9a10bd9..395d555 100644 --- a/tests/are-objects-equals.js +++ b/tests/are-objects-equals.js @@ -1,24 +1,111 @@ 'use strict'; const assert = require('assert'); -// const sandbox = require('sinon'); -const { AreObjectsEquals } = require('../lib/index'); +const areObjectsEquals = require('../lib/are-objects-equals'); describe('are-objects-equals', () => { - context('When Some condition', () => { - - it('Should return something', () => { - const areObjectsEquals = new AreObjectsEquals(); - assert(areObjectsEquals); - }) - }) - - context('When Other condition', () => { - - it('Should reject otherthing', () => { - - }) - }) -}) \ No newline at end of file + context('When Errors found', () => { + + it('Should throw if no objects are passed', () => { + + assert.throws(() => areObjectsEquals()); + }); + + it('Should throw if one objects are passed', () => { + + assert.throws(() => areObjectsEquals({ name: 'first' })); + assert.throws(() => areObjectsEquals(null, { name: 'first' })); + }); + + it('Should throw if items are not objects', () => { + + assert.throws(() => areObjectsEquals({ name: 'first' }, 'first')); + assert.throws(() => areObjectsEquals('first', { name: 'first' })); + assert.throws(() => areObjectsEquals({ name: 'first' }, ['first'])); + assert.throws(() => areObjectsEquals(['first'], { name: 'first' })); + }); + + it('Should throw if options are invalid', () => { + + assert.throws(() => areObjectsEquals({ name: 'first' }, { name: 'first' }, 'options')); + }); + + }); + + const sameObject = { + name: 'same', + quantity: 100, + items: ['door', 'glass'], + place: { + city: 'Central', + country: 'Fake' + } + }; + + const sameObjectLess = { + name: 'same', + quantity: 100, + items: ['door', 'glass'] + }; + + const sameObjectMore = { + name: 'same', + quantity: 100, + items: ['door', 'glass'], + place: { + city: 'Central', + country: 'Fake' + }, + isActive: true + }; + + context('When Compare Objects without Normalize', () => { + + it('Should return true if both objects are equals', () => { + + assert(areObjectsEquals(sameObject, sameObject)); + assert(areObjectsEquals(sameObjectLess, sameObjectLess)); + assert(areObjectsEquals(sameObjectMore, sameObjectMore)); + }); + + it('Should return false if objects are differents', () => { + + assert(!areObjectsEquals(sameObject, sameObjectMore)); + assert(!areObjectsEquals(sameObjectLess, sameObject)); + assert(!areObjectsEquals(sameObjectMore, sameObjectLess)); + }); + }); + + context('When Compare Objects with Normalize', () => { + + it('Should return false if both objects remove equals fields', () => { + + assert(!areObjectsEquals(sameObject, sameObjectMore, { fieldsToRemove: ['name', 'quantity', 'items'] })); + assert(!areObjectsEquals(sameObjectLess, sameObject, { fieldsToRemove: ['name', 'quantity', 'items'] })); + assert(!areObjectsEquals(sameObjectMore, sameObjectLess, { fieldsToRemove: ['name', 'quantity', 'items'] })); + }); + + it('Should return false if objects keep differents fields', () => { + + assert(!areObjectsEquals(sameObject, sameObjectMore, { fieldsToKeep: ['isActive'] })); + assert(!areObjectsEquals(sameObjectLess, sameObject, { fieldsToKeep: ['place'] })); + assert(!areObjectsEquals(sameObjectMore, sameObjectLess, { fieldsToKeep: ['place', 'isActive'] })); + }); + + it('Should return true if both objects keep equals fields', () => { + + assert(areObjectsEquals(sameObject, sameObjectMore, { fieldsToKeep: ['name', 'quantity'] })); + assert(areObjectsEquals(sameObjectLess, sameObject, { fieldsToKeep: ['name', 'quantity'] })); + assert(areObjectsEquals(sameObjectMore, sameObjectLess, { fieldsToKeep: ['name', 'quantity'] })); + }); + + it('Should return true if objects remove differents fields', () => { + + assert(areObjectsEquals(sameObject, sameObjectMore, { fieldsToRemove: ['isActive'] })); + assert(areObjectsEquals(sameObjectLess, sameObject, { fieldsToRemove: ['place'] })); + assert(areObjectsEquals(sameObjectMore, sameObjectLess, { fieldsToRemove: ['place', 'isActive'] })); + }); + }); +});