Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
24dc40d
Prepare to rewrite in modern TypeScript
novemberborn Feb 20, 2025
037d59e
Reimplement deep comparison and (de)serialization
novemberborn Feb 21, 2025
b219c6d
Test BoxedPrimiteRepresentation
novemberborn Apr 13, 2025
3df9a40
Pack annotations to enable compression optimizations
novemberborn Apr 13, 2025
fc2094c
fixup! Prepare to rewrite in modern TypeScript
novemberborn Apr 15, 2025
d945880
Test DateRepresentation
novemberborn Apr 15, 2025
27699be
Test ErrorRepresentation
novemberborn Apr 15, 2025
7f54a24
Test FunctionRepresentation
novemberborn Apr 15, 2025
8765028
Test MapRepresentation
novemberborn May 2, 2025
fa277d4
Fix and test ModuleNamespaceObjectRepresentation
novemberborn May 2, 2025
cc5d9ca
fixup! Reimplement deep comparison and (de)serialization
novemberborn May 2, 2025
47b432c
Test PromiseRepresentation
novemberborn May 3, 2025
bb2ad5f
More efficient serialization of string tags that are the same as the …
novemberborn May 3, 2025
88872d3
Test RegExpRepresentation
novemberborn May 3, 2025
a0142ed
fixup! Reimplement deep comparison and (de)serialization
novemberborn May 3, 2025
e200dff
Test SetRepresentation
novemberborn May 3, 2025
e114ae5
Test WeakMapRepresentation
novemberborn May 3, 2025
c3a8e17
Test WeakSetRepresentation
novemberborn May 3, 2025
bd46a0e
Test ExternalRepresentation; improve deserialized comparisons
novemberborn May 5, 2025
aae0641
Further optimize serialization of string tags that are the same as co…
novemberborn May 5, 2025
7380d51
Test CryptoKeyRepresentation
novemberborn May 5, 2025
375af03
Test BytesAccessor
novemberborn May 5, 2025
9e29018
Test ElementAccessor and SparseValueRepresentation
novemberborn May 5, 2025
f2afba0
Test IteratorValueAccessor
novemberborn May 5, 2025
bd9d358
Test MapEntryAccessor
novemberborn May 5, 2025
79fc20e
Test property accessors
novemberborn May 6, 2025
1887afd
Refactor compare() tests focusing on algorithmic accuracy not behavio…
novemberborn May 6, 2025
025055e
Test describe()
novemberborn May 6, 2025
2a65532
Test serialization types
novemberborn May 7, 2025
7f75486
Test serialization
novemberborn May 7, 2025
0a7cdd9
Test deserialization
novemberborn May 16, 2025
78437fb
c8: Exclude *.d.ts files from report
novemberborn May 18, 2025
8d15d93
Split DescriptionContext and isPrimitive/representPrimitive into sepa…
novemberborn May 18, 2025
1377318
Split Encoder into its own file
novemberborn May 19, 2025
45b521d
Use cbor2 directly
novemberborn May 19, 2025
9fee1b3
Target Node.js 24 and update related dependencies & configuration
novemberborn May 19, 2025
8c88547
Support integers larger than int64
novemberborn May 19, 2025
9cf3312
Encode / decode non-wellformed strings
novemberborn May 19, 2025
0fe1c0a
Implement flags to control behavior
novemberborn May 19, 2025
1c444a5
Remove exports test file
novemberborn May 19, 2025
90d0471
Make comparing objects with null prototypes to regular object prototy…
novemberborn May 21, 2025
6526af5
Stop using interfaces
novemberborn May 21, 2025
e07ae2d
Add missing tests for flags getter in context implementations
novemberborn Jun 3, 2025
aa3c0c8
Treat empty constructor names as such
novemberborn May 24, 2025
6f25269
Refactor so property groups are not value representations
novemberborn May 31, 2025
bfb271a
Change BytesAccessor to be shallow
novemberborn May 29, 2025
a1e5fc2
Implement formatting for accessors and values
novemberborn May 21, 2025
d5e2c79
Upgrade XO
novemberborn Jun 9, 2025
fc40ba8
Update dependencies
novemberborn Jun 9, 2025
0d1d49d
Rename concepts
novemberborn Jun 9, 2025
1b2dc8a
Add method to fully (recursively) deserialize a representation
novemberborn Jun 9, 2025
aa46eb4
Change stack iteration to return undefined when done
novemberborn Jun 10, 2025
41ab11d
Simplify symbol property serialization
novemberborn Jun 10, 2025
a569ba5
Move iterator out of stack entry into internal state
novemberborn Jun 15, 2025
f206ec5
Implement Stack#peekNext() to access the next iterated value
novemberborn Jun 15, 2025
a6445fc
Implement Stack#takeWhile() to iterate over values while a condition …
novemberborn Jun 15, 2025
9a97460
Group accessors depending on applied algorithm, not in the context
novemberborn Jun 15, 2025
f2d0c84
Improve comparison logic for Error, RegExp, WeakMap, WeakSet and Cryp…
novemberborn Jun 16, 2025
19d124d
Exclude Error#stack from the iterated properties
novemberborn Jun 18, 2025
6f85dc6
Always include Error#code
novemberborn Jun 18, 2025
94aa64d
Implement fuzzy comparison mode
novemberborn Jun 16, 2025
79570f6
Refactor array-like handling
novemberborn Aug 17, 2025
00e5da1
Clean up unnecessary static is() from mocks
novemberborn Aug 17, 2025
05c8cc5
Give RHS control over being compared
novemberborn Aug 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Test DateRepresentation
  • Loading branch information
novemberborn committed Jun 5, 2025
commit d94588079419a8a31efb20ae20b95fbee12edd92
167 changes: 167 additions & 0 deletions src/values/objects/test/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import test from 'ava'
import { DescriptionContext } from '../../../describe.ts'
import { Encoder } from '../../../serialize.ts'
import { Decoder, DeserializationContext } from '../../../deserialize.ts'
import { DateRepresentation } from '../date.ts'
import { comparable, strictlyEqual, unequal } from '../../../comparison.ts'
import { staticTypeTable } from '../../../serialization-types.ts'
import { snapshotEncoded } from '../../test/helpers/snapshot-encoded.ts'

// Use the first commit timestamp for testing
const FIRST_COMMIT_DATE = new Date('2017-02-17T16:58:13Z')

// Deserialize method test
test('deserialize creates a comparable DateRepresentation', (t) => {
const originalContext = new DescriptionContext()
const date = FIRST_COMMIT_DATE
const original = originalContext.represent(date) as DateRepresentation

const encoder = new Encoder()
original.serialize(encoder)

const decoder = new Decoder(encoder.bytes)
decoder.staticType() // Consume the type
const deserializationContext = new DeserializationContext(decoder)
const deserialized = DateRepresentation.deserialize(deserializationContext, decoder)

// The deserialized representation should be comparable to the original
t.is(original.compare(deserialized), comparable)
})

// Compare method tests
test('compare returns strictlyEqual when comparing the same date instance', (t) => {
const context = new DescriptionContext()
const date = FIRST_COMMIT_DATE

const dateRep1 = context.represent(date) as DateRepresentation
const dateRep2 = context.represent(date) as DateRepresentation

t.is(dateRep1.compare(dateRep2), strictlyEqual)
})

test('compare returns unequal when comparing to non-DateRepresentation', (t) => {
const context = new DescriptionContext()
const date = FIRST_COMMIT_DATE
const obj = {}

const dateRep = context.represent(date) as DateRepresentation
const objRep = context.represent(obj)

t.is(dateRep.compare(objRep), unequal)
})

test('compare returns unequal when comparing dates with different timestamps', (t) => {
const context = new DescriptionContext()
const date1 = FIRST_COMMIT_DATE
const date2 = new Date(FIRST_COMMIT_DATE.getTime() + 1000) // Add 1 second

const dateRep1 = context.represent(date1) as DateRepresentation
const dateRep2 = context.represent(date2) as DateRepresentation

t.is(dateRep1.compare(dateRep2), unequal)
})

test('compare returns comparable when comparing different date instances with same timestamp', (t) => {
const context = new DescriptionContext()
// Create two different Date instances with the same timestamp
const date1 = new Date(FIRST_COMMIT_DATE.getTime())
const date2 = new Date(FIRST_COMMIT_DATE.getTime())

const dateRep1 = context.represent(date1) as DateRepresentation
const dateRep2 = context.represent(date2) as DateRepresentation

// Should be comparable, not strictly equal, as they are different instances
t.is(dateRep1.compare(dateRep2), comparable)
})

test('compare handles invalid dates correctly', (t) => {
const context = new DescriptionContext()

// Create invalid date objects
const invalidDate1 = new Date('invalid')
const invalidDate2 = new Date('invalid')

// Verify that these are indeed invalid dates
t.true(Number.isNaN(invalidDate1.getTime()))
t.true(Number.isNaN(invalidDate2.getTime()))

const invalidDateRep1 = context.represent(invalidDate1) as DateRepresentation
const invalidDateRep2 = context.represent(invalidDate2) as DateRepresentation

// Two invalid dates should be comparable
t.is(invalidDateRep1.compare(invalidDateRep2), comparable)

// An invalid date should be unequal to a valid date
const validDate = FIRST_COMMIT_DATE
const validDateRep = context.represent(validDate) as DateRepresentation

t.is(invalidDateRep1.compare(validDateRep), unequal)
})

// iterateArrayLike and iterateIterable tests
test('iterateArrayLike yields no elements for dates', (t) => {
const context = new DescriptionContext()
const date = FIRST_COMMIT_DATE
const dateRep = context.represent(date) as DateRepresentation

const elements = [...dateRep.iterateArrayLike()]

t.is(elements.length, 0)
})

test('iterateIterable yields no elements for dates', (t) => {
const context = new DescriptionContext()
const date = FIRST_COMMIT_DATE
const dateRep = context.represent(date) as DateRepresentation

const iterables = [...dateRep.iterateIterable()]

t.is(iterables.length, 0)
})

// Serialization tests
test('serialize uses date static type and includes valueOf annotation', (t) => {
const context = new DescriptionContext()
const date = FIRST_COMMIT_DATE
const dateRep = context.represent(date) as DateRepresentation

const encoder = new Encoder()
dateRep.serialize(encoder)

// Check the overall structure and type
snapshotEncoded(t, encoder, 'date serialization')

// Verify the static type and annotations manually
const decoder = new Decoder(encoder.bytes)
t.is(decoder.staticType(), staticTypeTable.date)

// Check that the valueOf annotation (v) contains the correct timestamp
const annotations = decoder.annotations<{ v: number }>()
t.is(annotations.v, date.valueOf())
})

test('serializing and deserializing a Date preserves its timestamp', (t) => {
const originalContext = new DescriptionContext()

// Test with various dates including the first commit date
const dates = [
FIRST_COMMIT_DATE,
new Date(0), // Epoch
new Date('invalid'), // Invalid date
]

for (const date of dates) {
const original = originalContext.represent(date) as DateRepresentation

const encoder = new Encoder()
original.serialize(encoder)

const decoder = new Decoder(encoder.bytes)
decoder.staticType() // Consume the type
const deserializationContext = new DeserializationContext(decoder)
const deserialized = DateRepresentation.deserialize(deserializationContext, decoder)

// The original and deserialized representations should be comparable
t.is(original.compare(deserialized), comparable, `Failed for date: ${date}`)
}
})
58 changes: 58 additions & 0 deletions src/values/objects/test/snapshots/date.ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Snapshot report for `src/values/objects/test/date.ts`

The actual snapshot is saved in `date.ts.snap`.

Generated by [AVA](https://avajs.dev).

## serialize uses date static type and includes valueOf annotation

> Serialized bytes (date serialization)

Uint8Array [
0ea36163 64446174 6561761b 0000015a 4d027c88 617001
]

> Decoded bytes (date serialization)

[
[
0,
14,
14,
],
[
5,
3,
3,
],
[
3,
1,
'c',
],
[
3,
4,
'Date',
],
[
3,
1,
'v',
],
[
0,
27,
1487350693000,
],
[
3,
1,
'p',
],
[
0,
1,
1,
],
]
Binary file added src/values/objects/test/snapshots/date.ts.snap
Binary file not shown.