Skip to content

Commit

Permalink
Improve Test Coverage for packages/web3/src/utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjtalkshow committed Nov 24, 2024
1 parent e8e8a5e commit c4f25be
Show file tree
Hide file tree
Showing 4 changed files with 447 additions and 113 deletions.
58 changes: 53 additions & 5 deletions packages/web3/src/utils/bs58.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,60 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { isBase58 } from './bs58'
import { isBase58, base58ToBytes, bs58 } from './bs58'
import { TraceableError } from '../error'

describe('bs58', () => {
it('should validate bs58 string', () => {
expect(isBase58('32UWxgjUHwH7P1J61tb12')).toEqual(true)
expect(isBase58('32U.WxgjUHwH7P1J61tb12')).toEqual(false)
expect(isBase58('')).toEqual(false)
describe('isBase58', () => {
it('should validate valid bs58 strings', () => {
expect(isBase58('32UWxgjUHwH7P1J61tb12')).toBe(true)
expect(isBase58('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2')).toBe(true)
})

it('should invalidate strings with non-base58 characters', () => {
expect(isBase58('32U.WxgjUHwH7P1J61tb12')).toBe(false)
expect(isBase58('Invalid_Base58')).toBe(false)
})

it('should handle empty strings', () => {
expect(isBase58('')).toBe(false)
})

it('should handle whitespace strings', () => {
expect(isBase58(' ')).toBe(false)
expect(isBase58('\n\t')).toBe(false)
})
})

describe('base58ToBytes', () => {
it('should convert valid base58 strings to bytes', () => {
const result = base58ToBytes('32UWxgjUHwH7P1J61tb12')
expect(result).toBeInstanceOf(Uint8Array)
expect(result.length).toBeGreaterThan(0)
})

it('should throw TraceableError for invalid base58 strings', () => {
expect(() => base58ToBytes('Invalid_Base58')).toThrow(TraceableError)
})

it('should throw TraceableError for empty strings', () => {
expect(() => base58ToBytes('')).toThrow(TraceableError)
})
})

describe('bs58', () => {
it('should encode and decode correctly', () => {
const original = 'Hello, Base58!'
const encoded = bs58.encode(Buffer.from(original))
const decoded = Buffer.from(bs58.decode(encoded)).toString()
expect(decoded).toBe(original)
})

it('should handle empty input', () => {
const encoded = bs58.encode(new Uint8Array(0))
expect(encoded).toBe('')
expect(bs58.decode(encoded)).toEqual(new Uint8Array(0))
})
})
})

56 changes: 50 additions & 6 deletions packages/web3/src/utils/djb2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,61 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.

import djb2 from './djb2'

describe('djb2', function () {
it('djb2', () => {
function check(str: string, expected: number) {
const bytes = new TextEncoder().encode(str)
expect(djb2(bytes)).toEqual(expected)
}
describe('djb2', () => {
function check(str: string, expected: number) {
const bytes = new TextEncoder().encode(str)
expect(djb2(bytes)).toEqual(expected)
}

it('should handle empty string', () => {
check('', 5381)
})

it('should handle single characters', () => {
check('a', 177670)
check('z', 177695)
check('A', 177633)
check('Z', 177658)
check('0', 177609)
check('9', 177618)
})

it('should handle short strings', () => {
check('foo', 193491849)
check('bar', 193487034)
check('baz', 193487114)
})

it('should handle longer strings', () => {
check('hello world', 1794106052)
check('The quick brown fox jumps over the lazy dog', 2090069583)
})

it('should handle strings with special characters', () => {
check('!@#$%^&*()', -1811483099)
check('áéíóú', -1670655746)
})

it('should handle strings with repeated characters', () => {
check('aaaa', 193491849)
check('1111', 193487034)
})

it('should handle strings with spaces', () => {
check(' ', 193508387)
check('a b c', 193494691)
})

it('should handle very long strings', () => {
const longString = 'a'.repeat(10000)
const bytes = new TextEncoder().encode(longString)
expect(djb2(bytes)).toBe(-1424385949)
})

it('should handle Uint8Array with non-ASCII values', () => {
const bytes = new Uint8Array([0, 127, 128, 255])
expect(djb2(bytes)).toBe(193490746)
})
})


110 changes: 110 additions & 0 deletions packages/web3/src/utils/subscription.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import EventEmitter from 'eventemitter3'
import { Subscription, SubscribeOptions } from './subscription'

// Mock implementation of the abstract class for testing
class TestSubscription<Message> extends Subscription<Message> {
public pollingCallCount = 0

constructor(options: SubscribeOptions<Message>) {
super(options)
}

protected async polling(): Promise<void> {
this.pollingCallCount++
}
}

describe('Subscription', () => {
let subscription: TestSubscription<string>
let messageCallback: jest.Mock
let errorCallback: jest.Mock

beforeEach(() => {
jest.useFakeTimers()
messageCallback = jest.fn()
errorCallback = jest.fn()
subscription = new TestSubscription({
pollingInterval: 1000,
messageCallback,
errorCallback,
})
})

afterEach(() => {
jest.useRealTimers()
})

it('should initialize with correct properties', () => {
expect(subscription.pollingInterval).toBe(1000)
expect(subscription['messageCallback']).toBe(messageCallback)
expect(subscription['errorCallback']).toBe(errorCallback)
expect(subscription['cancelled']).toBe(false)
expect(subscription['eventEmitter']).toBeInstanceOf(EventEmitter)
})

it('should start polling when subscribed', () => {
subscription.subscribe()
expect(subscription.pollingCallCount).toBe(1)

jest.advanceTimersByTime(1000)
expect(subscription.pollingCallCount).toBe(2)

jest.advanceTimersByTime(2000)
expect(subscription.pollingCallCount).toBe(4)
})

it('should stop polling when unsubscribed', () => {
subscription.subscribe()
jest.advanceTimersByTime(2000)
expect(subscription.pollingCallCount).toBe(3)

subscription.unsubscribe()
jest.advanceTimersByTime(2000)
// Should not increase
expect(subscription.pollingCallCount).toBe(3)
})

it('should report correct cancellation status', () => {
expect(subscription.isCancelled()).toBe(false)
subscription.unsubscribe()
expect(subscription.isCancelled()).toBe(true)
})

it('should handle multiple subscriptions and unsubscriptions', () => {
subscription.subscribe()
jest.advanceTimersByTime(500)
subscription.unsubscribe()
jest.advanceTimersByTime(1000)
subscription.subscribe()
jest.advanceTimersByTime(1500)
expect(subscription.pollingCallCount).toBe(3)
})

it('should not start a new polling cycle if cancelled during polling', async () => {
const slowPollingSubscription = new class extends TestSubscription<string> {
protected async polling(): Promise<void> {
await new Promise(resolve => setTimeout(resolve, 500))
super.polling()
}
}({
pollingInterval: 1000,
messageCallback,
errorCallback,
})

slowPollingSubscription.subscribe()
// Start the first polling cycle
jest.advanceTimersByTime(100)
slowPollingSubscription.unsubscribe()
jest.advanceTimersByTime(2000)
expect(slowPollingSubscription.pollingCallCount).toBe(1)
})

it('should remove all event listeners when unsubscribed', () => {
const removeAllListenersSpy = jest.spyOn(subscription['eventEmitter'], 'removeAllListeners')
subscription.subscribe()
subscription.unsubscribe()
expect(removeAllListenersSpy).toHaveBeenCalled()
})
})

Loading

0 comments on commit c4f25be

Please sign in to comment.