mtcute/packages/tl-utils/src/codegen/reader.test.ts

131 lines
5.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { parseTlToEntries } from '../parse.js'
import { generateReaderCodeForTlEntries, generateReaderCodeForTlEntry } from './reader.js'
describe('generateReaderCodeForTlEntry', () => {
const test = (...tl: string[]) => {
const entry = parseTlToEntries(tl.join('\n')).slice(-1)[0]
expect(generateReaderCodeForTlEntry(entry)).toMatchSnapshot()
}
it('generates code for constructors without arguments', () => {
test('topPeerCategoryBotsPM#ab661b5b = TopPeerCategory;')
})
it('generates code for constructors with simple arguments', () => {
test('inputBotInlineMessageID#890c3d89 dc_id:int id:long access_hash:long = InputBotInlineMessageID;')
test('contact#145ade0b user_id:long mutual:Bool = Contact;')
test('maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;')
})
it('generates code for constructors with true flags', () => {
test('messages.messageEditData#26b5dde6 flags:# caption:flags.0?true = messages.MessageEditData;')
})
it('generates code for constructors with optional arguments', () => {
test(
'updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int = updates.ChannelDifference;',
)
})
it('generates code for constructors with arguments before flags field', () => {
test('poll#86e18161 id:long flags:# quiz:flags.3?true question:string = Poll;')
})
it('generates code for constructors with multiple flags fields', () => {
test(
'updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int flags2:# can_delete_channel:flags2.0?true = updates.ChannelDifference;',
)
})
it('generates code for constructors with vector arguments', () => {
test('contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;')
})
it('generates code for constructors with optional vector arguments', () => {
test(
'messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;',
)
})
it('generates code for constructors with generics', () => {
test('invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;')
})
it('generates code for bare types', () => {
test('message#0949d9dc = Message;', 'msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;')
test(
'future_salt#0949d9dc = FutureSalt;',
'future_salts#ae500895 salts:Vector<future_salt> current:FutureSalt = FutureSalts;',
)
test(
'future_salt#0949d9dc = FutureSalt;\n',
'future_salts#ae500895 salts:vector<future_salt> current:future_salt = FutureSalts;',
)
})
it('generates code with raw flags for constructors with flags', () => {
const entry = parseTlToEntries('test flags:# flags2:# = Test;')[0]
expect(generateReaderCodeForTlEntry(entry, { includeFlags: true })).toMatchSnapshot()
})
})
describe('generateReaderCodeForTlEntries', () => {
it('generates code for multiple entries', () => {
const entries = parseTlToEntries('test = Test;\ntest2 = Test2;\n')
expect(generateReaderCodeForTlEntries(entries)).toMatchSnapshot()
})
it("doesn't generate code for methods by default", () => {
const entries = parseTlToEntries(['test = Test;', '---functions---', 'test2 = Test2;'].join('\n'))
expect(generateReaderCodeForTlEntries(entries)).toMatchSnapshot()
})
it('generates code for methods if asked to', () => {
const entries = parseTlToEntries(['test = Test;', '---functions---', 'test2 = Test2;'].join('\n'))
expect(generateReaderCodeForTlEntries(entries, { includeMethods: true })).toMatchSnapshot()
})
it('updates readers used in bare vectors', () => {
const entries = parseTlToEntries(['test = Test;', 'test2 a:vector<test> = Test2;'].join('\n'))
expect(generateReaderCodeForTlEntries(entries)).toMatchSnapshot()
})
describe('method return readers', () => {
it('includes primitive return type parsing info', () => {
const entries = parseTlToEntries(['test1 = Test;', '---functions---', 'test = int;'].join('\n'))
expect(generateReaderCodeForTlEntries(entries, { includeMethodResults: true })).toMatchSnapshot()
})
it('includes primitive vectors return type parsing info', () => {
const entries = parseTlToEntries(['---functions---', 'test = Vector<int>;'].join('\n'), {
parseMethodTypes: true,
})
expect(generateReaderCodeForTlEntries(entries, { includeMethodResults: true })).toMatchSnapshot()
})
it('includes primitive vectors return type parsing info', () => {
const entries = parseTlToEntries(['---functions---', 'test = Vector<int>;'].join('\n'), {
parseMethodTypes: true,
})
expect(generateReaderCodeForTlEntries(entries, { includeMethodResults: true })).toMatchSnapshot()
})
it("doesn't include Bool parsing", () => {
const entries = parseTlToEntries(['---functions---', 'test = Bool;'].join('\n'), {
parseMethodTypes: true,
})
expect(generateReaderCodeForTlEntries(entries, { includeMethodResults: true })).toMatchSnapshot()
})
})
})