Skip to content

Commit

Permalink
add failing test case and add typing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aleclarson committed Jul 19, 2024
1 parent ac36679 commit 0168241
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 24 deletions.
53 changes: 53 additions & 0 deletions tests/object/crush.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as _ from 'radashi'

describe('crush', () => {
test('direct properties are preserved in the result type', () => {
const obj = _.crush({ a: 1, b: '2', c: true })
expectTypeOf(obj).toEqualTypeOf<{ a: number; b: string; c: boolean }>()
})
test('nested objects add Record to result type', () => {
const obj = _.crush({ a: { b: 1 } })
expectTypeOf(obj).toEqualTypeOf<Record<string, unknown>>()

const obj2 = _.crush({ a: 1, b: { c: 2 } })
expectTypeOf(obj2).toEqualTypeOf<{ a: number; [key: string]: unknown }>()
expectTypeOf(obj2.a).toEqualTypeOf<number>()
expectTypeOf(obj2['b.c']).toEqualTypeOf<unknown>()
})
test('optional property', () => {
const obj = _.crush({} as { a?: number })
// FIXME: Try to preserve optionality.
expectTypeOf(obj).toEqualTypeOf<{ a: number | undefined }>()
})
test('crushed Record type', () => {
const obj = _.crush({} as Record<number, number>)
expectTypeOf(obj).toEqualTypeOf<Record<number, number>>()

const obj2 = _.crush({} as Record<string, string>)
expectTypeOf(obj2).toEqualTypeOf<Record<string, string>>()

const obj3 = _.crush({} as Record<number, number | object>)
expectTypeOf(obj3).toEqualTypeOf<Record<string, unknown>>()

const obj4 = _.crush({} as Record<string, string | unknown[]>)
expectTypeOf(obj4).toEqualTypeOf<Record<string, unknown>>()
})
test('crushed array', () => {
// We cannot assume the keys from "number[]" input value, but we
// *can* assume the value type. Note that the value type doesn't
// contain "undefined" (which matches array behavior).
const obj = _.crush([1, 2, 3])
expectTypeOf(obj).toEqualTypeOf<Record<string, number>>()

const obj2 = _.crush([1, { b: 2 }])
expectTypeOf(obj2).toEqualTypeOf<Record<string, unknown>>()
expectTypeOf(obj2[0]).toEqualTypeOf<unknown>()
})
test('union type with object and primitive', () => {
// Since "a" may be an object, we cannot assume the result will
// have an "a" property. Therefore, the keys and values of the
// result are unknown.
const obj = _.crush({ a: {} as number | object })
expectTypeOf(obj).toEqualTypeOf<Record<string, unknown>>()
})
})
79 changes: 55 additions & 24 deletions tests/object/crush.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,6 @@ describe('crush', () => {
timestamp: now,
})
})
test('handles property names with dots 1', () => {
const obj = {
a: { 'b.c': 'value' },
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value',
})
})
test('handles property names with dots 2', () => {
const obj = {
'a.b': { c: 'value' },
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value',
})
})
test('handles property names with dots 3', () => {
const obj = {
'a.b': { 'c.d': 123.4 },
}
expect(_.crush(obj)).toEqual({
'a.b.c.d': 123.4,
})
})
test('handles arrays', () => {
const obj = ['value', 123.4, true]
expect(_.crush(obj)).toEqual({
Expand All @@ -65,4 +41,59 @@ describe('crush', () => {
'2': true,
})
})
describe('property names containing period', () => {
test('inside the root object', () => {
const obj = {
'a.b': { c: 'value' },
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value',
})
})
test('inside a nested object', () => {
const obj = {
a: { 'b.c': 'value' },
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value',
})
})
test('inside both root and nested object', () => {
const obj = {
'a.b': { 'c.d': 123.4 },
}
expect(_.crush(obj)).toEqual({
'a.b.c.d': 123.4,
})
})
test('crush array containing object with nested property', () => {
const arr = [{ 'c.d': { 'e.f': 'g' } }]
const obj = {
'a.b': arr,
}
expect(_.crush(obj)).toEqual({
'a.b.0.c.d.e.f': 'g',
})
})
test('do not crush Date objects', () => {
const date = new Date()
const obj = {
'a.b': date,
}
expect(_.crush(obj)).toEqual({
'a.b': date,
})
})
test('do not crush Map objects', () => {
const map = new Map()
map.set('a', 'b')
map.set('c', 'd')
const obj = {
'a.b': map,
}
expect(_.crush(obj)).toEqual({
'a.b': map,
})
})
})
})

0 comments on commit 0168241

Please sign in to comment.