two-bit/word.test.ts

126 lines
4.2 KiB
TypeScript

import bit from "./bit"
import { emptyWord, wordFromBits, wordFromNumber, wordFromString } from "./word"
describe("word", () => {
test("can be created with an array of bits", () => {
const sourceBits = [bit(0), bit(1), bit(1)]
const subject = wordFromBits(sourceBits)
expect(subject.bits).toEqual(sourceBits)
})
test("can be created from a binary literal", () => {
const subject = wordFromNumber(0b10100111)
expect(subject.bits.map(bit => bit.value)).toEqual([1, 0, 1, 0, 0, 1, 1, 1])
})
test("can be created from a binary literal with length", () => {
const subject = wordFromNumber(0b1, 3)
expect(subject.bits.map(bit => bit.value)).toEqual([0, 0, 1])
})
test("can be created from string", () => {
const subject = wordFromString("01100")
expect(subject.bits.map(bit => bit.value)).toEqual([0, 1, 1, 0, 0])
})
test("can be created from length", () => {
const subject = emptyWord(5)
expect(subject.equals(wordFromString("00000"))).toBe(true)
})
test("can be converted to number", () => {
const subject = wordFromString("11001")
expect(subject.toNumber()).toEqual(25)
})
test("can be converted to string", () => {
const subject = wordFromString("01110001111")
expect(subject.toString()).toBe("01110001111")
})
describe("subword", () => {
test("returns the bits from the start position up to but not including start plus length", () => {
const result = wordFromString("1001101000101000010111111").subword(3, 6)
expect(result.equals(wordFromString("110100"))).toBe(true)
})
test("returns the word starting from the start position when length is omitted", () => {
const result = wordFromString("1001101").subword(2)
expect(result.equals(wordFromString("01101"))).toBe(true)
})
test("returns a truncated word when the requested length overflows the word width", () => {
const result = wordFromString("11000011110").subword(7, 9999)
expect(result.equals(wordFromString("1110")))
})
test("returns an empty word when the start position is past the end of the word", () => {
const result = wordFromString("11000011110").subword(9999)
expect(result.equals(wordFromBits([])))
})
})
describe("concat", () => {
test("returns the combined bits from this word and the other word", () => {
const result = wordFromString("100").concat(wordFromString("110"))
expect(result.equals(wordFromString("100110"))).toBe(true)
})
})
describe("equals", () => {
test("is true when two words have the same bits", () => {
expect(wordFromString("01100").equals(wordFromString("01100"))).toBe(true)
})
test("is false when two words have different lengths", () => {
expect(wordFromString("01100").equals(wordFromString("011000"))).toBe(false)
})
test("is false when two words have different bits", () => {
expect(wordFromString("0111").equals(wordFromString("1010"))).toBe(false)
})
})
describe("addition", () => {
test("returns a carry of 0 when there is no overflow", () => {
const a = wordFromBits([bit(0), bit(0), bit(1)])
const b = wordFromNumber(0b101)
expect(a.plus(b).carry.value).toEqual(0)
})
test("returns a carry of 1 when there is overflow", () => {
const a = wordFromBits([bit(0), bit(1), bit(1)])
const b = wordFromNumber(0b111)
expect(a.plus(b).carry.value).toEqual(1)
})
test("returns the sum", () => {
const a = wordFromBits([bit(0), bit(0), bit(1)])
const b = wordFromNumber(0b101)
expect(a.plus(b).sum.bits.map(bit => bit.value)).toEqual([1, 1, 0])
})
test("returns a word with a width equal to the greater of the two input widths", () => {
const a = wordFromNumber(0b10)
const b = wordFromNumber(0b101010111)
expect(a.plus(b).sum.bits).toHaveLength(9)
})
})
})