Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
The tcompare npm package is a tool for deep comparison of JavaScript objects. It is useful for testing and validation purposes, allowing developers to compare complex data structures and identify differences.
Deep Comparison
This feature allows for deep comparison of two objects. The code sample compares two nested objects and logs the differences.
const tcompare = require('tcompare');
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const result = tcompare.compare(obj1, obj2);
console.log(result);
Custom Comparison
This feature allows for custom comparison logic. The code sample demonstrates how to use a custom comparison function to compare two objects.
const tcompare = require('tcompare');
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 3 };
const customCompare = (a, b) => a === b;
const result = tcompare.compare(obj1, obj2, { customCompare });
console.log(result);
Detailed Difference Reporting
This feature provides detailed reporting of differences between objects. The code sample shows how to access and log the differences between two objects.
const tcompare = require('tcompare');
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 3 } };
const result = tcompare.compare(obj1, obj2);
console.log(result.diff);
The deep-equal package provides deep comparison of objects and arrays. It is similar to tcompare in that it allows for deep comparison, but it does not offer as detailed difference reporting as tcompare.
The lodash.isequal package is a part of the Lodash library that provides deep comparison of objects. It is similar to tcompare in functionality but is part of a larger utility library, making it more versatile for various use cases.
The fast-deep-equal package is a highly optimized deep comparison library. It is similar to tcompare in that it provides deep comparison, but it is focused on performance and may not offer as detailed difference reporting.
A comprehensive comparison library, for use in test frameworks. Walks an object once, generating both a simple true/false result, as well as a string representation of both the actual and expected values (highlighting just the parts that differ) and a patch-style diff string.
// require() is fine too
import {
match,
same,
strict,
has,
hasStrict,
matchOnly,
matchStrict,
} from 'tcompare'
import type { Result } from 'tcompare'
const result: Result = match(object, pattern)
if (!result.match) {
console.log(`item did not match pattern`)
console.log(result.diff)
} else {
console.log(`it's a match!`)
}
// raw classes exported also
import { MatchOnly } from 'tcompare'
const mo = new MatchOnly({ a: 1, b: 2 }, { expect: { a: Number } })
const diff: string = mo.print()
console.log(mo.match) // false
console.log(diff)
/*
--- expected
+++ actual
@@ -1,2 +1,3 @@
Object {
+ "b": 2,
}
*/
indent
- String to indent each nested level. Defaults to ' '
.## METHODSEach method corresponds to an exported class. Except for
format()
(which returns a string), they all return a Result
object. (That is, {diff:string, match:boolean}
.)
format(object, [options])
- No comparisons performed. Just print out the
object. Returns just the formatted string.same(object, pattern, [options])
- Deep equivalence. Ensure
that all items in the pattern are found in the object, and vice
versa, matching loosely (so, for example 1
will match with
'1'
).strict(object, pattern, [options])
- Deep equality. Ensure
that all items in the pattern are found in the object, and vice
versa, matching strictly (so, for example 1
will not match
with '1'
). Objects must have the same constructors, and all
fields will be matched recursively using the same strict
test.has(object, pattern, [options])
- Ensure that all items in
the pattern are found in the object, but ignore additional
items found in the object, matching loosely. Classes only need
to match loosely, so a plain JavaScript object can be used to
check for fields on a class instance.hasStrict(object, pattern, [options])
- Ensure that all items
in the pattern are found in the object, but ignore additional
items found in the object, matching strictly. Constructors do
not have to match between objects, but if constructor
is
set as an ownProperty on the pattern object, then it will be
checked for strict equality.match(object, pattern, [options])
- Verify that all items in
pattern
are found in object
, and that they match in an
extremely loose way. This is the loosest possible algorithm,
allowing cases where we just want to verify that an object
contains a few important properties. In summary:
arguments
objects), which are cast to Arrays.matchOnly(object, pattern, [options])
- Same comparison
testing as match()
, but will fail if the object
has any
properties that are not present in the pattern
.matchStrict(object, pattern, [options])
- Same comparison
testing as match()
, but will fail when two values are
equivalent but not strictly equal. (That is, when a == b && !(a === b)
.)There are classes exported to correspond to each of these. All of these are
instantiated like new Format(object, options)
. An expect
option is
required for all classes except Format
. Call obj.print()
on the resulting
object to generate a diff. Once the diff (or format) is generated, it'll have
a match
boolean member.
The exported classes should usually not be used directly, and their implementation details are subject to change as needed between versions.
The class heirarchy is:
Format
+-- Same
+-- Strict
+-- Has
| +-- HasStrict (uses Strict.prototype.test)
| +-- Match
| +-- MatchStrict (fails if a==b && a!==b)
+-- MatchOnly (uses Match.prototype.test)
In order to compare or print an object, instantiate one of the
classes, and call then the print()
method, which will return
the diff or formatted value. The match
boolean property will
be set after calling print()
. If the objects match, then the
returned diff
will also be an empty string.
FormatOptions
typeEvery method and class can take the following options.
sort
- Set to true
to sort object keys. This is important when
serializing in a deterministic way.
style
- Set to pretty
for a very human-readable style of object printing.
Set to js
for a copy-and-paste friendly valid JavaScript output. Set to
tight
for a minimal white-space js format. Default is pretty
. Example:
// pretty style
Object {
"myMap": Map {
Object {
"a": 1,
} => Object {
"b": 2,
}
}
}
// js style
{
"myMap": new Map([
[{
"a": 1,
}, {
"b": 2,
}]
])
}
// tight style
{"myMap":new Map([[{"a":1,},{"b":2,}],]),}
Note that tight
is not suitable for comparisons, only formatting.
bufferChunkSize
- The number of bytes to show per line when
printing long Buffer
objects. Defaults to 32.
indent
- String to indent each nested level. Defaults to ' '
.
includeEnumerable
- Set to true
to walk over all
enumerable properties of a given object when comparing or
formatting, rather than the default of only showing enumerable
own-properties. Note that calling getter functions may be
hazardous, as they may trigger side-effects.
includeGetters
- Set to true
to walk over all enumerable
getters on an object's prototype (but not from further down the
prototype chain), in addition to own-properties. This is useful
in cases where you want to compare or print an object with
enumerable getters that return internal values in a read-only
manner. Note that calling getter functions can be hazardous, as
they may trigger side-effects.
SameOptions
typeComparison classes also take the following options.
expect
- required. The pattern object to compare against.diffContext
- Optional, default 10. Number of lines of
context to show in diff output.Circular references are displayed using YAML-like references, in order to determine which item is circularly referenced.
When doing comparisons, a pattern and object will be considered matching if they contain the same circularity. So, for example, if a pattern refers to itself, then an object should refer to itself as well.
const a = { list: [], b: {} }
a.list.push(a)
a.list.push(a.b)
a.b.a = a
console.log(format(a))
/*
&ref_1 Object {
"list": Array [
<*ref_1>,
Object {
"a": <*ref_1>,
},
],
"b": Object {
"a": <*ref_1>,
},
}
*/
Note that circular references are never going to be valid
JavaScript, even when using the js
style.
It's possible to get strange output when an object and pattern refer to one another.
import { same } from 'tcompare'
const a = {}
a.o = a
const b = { o: a }
console.error(same(a, b).diff)
// produces this confusing output:
/*
--- expected
+++ actual
@@ -1,5 +1,3 @@
&ref_1 Object {
- "o": &ref_1 Object {
- "o": <*ref_1>,
- },
+ "o": <*ref_1>,
}
*/
The more correct output would be something like:
--- expected
+++ actual
@@ -1,5 +1,3 @@
&ref_1 Object {
- "o": &ref_2 Object {
- "o": <*ref_2>,
- },
+ "o": <*ref_1>,
}
However, this requires tracking IDs in a much more complicated way, being aware of whether the object is being read as an pattern object or test object when determining its reference ID.
Since this is a relatively unusual thing to happen, and only affects the output (but still properly detects whether it should be treated as a match or not), it will likely not be addressed.
FAQs
A comprehensive comparison library, for use in test frameworks
The npm package tcompare receives a total of 90,420 weekly downloads. As such, tcompare popularity was classified as popular.
We found that tcompare demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.