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) }) }) })