11import { describe , it , expect , vi , beforeEach , afterEach } from 'vitest' ;
2- import { parseContractId } from '../../src/fetcher.js' ;
3- import { generateTypescript , generateJson } from '../../src/codegen.js' ;
2+ import { fetchCommand } from '../../src/commands/fetch.js' ;
43import { sampleAbi } from './fixtures.js' ;
54
6- describe ( 'CLI integration' , ( ) => {
5+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6+ const runFetch = ( args : Record < string , any > ) =>
7+ fetchCommand . run ! ( { args, rawArgs : [ ] , cmd : fetchCommand } as never ) ;
8+
9+ describe ( 'fetchCommand' , ( ) => {
710 const originalFetch = globalThis . fetch ;
811
912 beforeEach ( ( ) => {
@@ -14,46 +17,72 @@ describe('CLI integration', () => {
1417 globalThis . fetch = originalFetch ;
1518 } ) ;
1619
17- it ( 'end-to-end: parse contract, fetch ABI, generate TypeScript ' , async ( ) => {
20+ it ( 'writes TypeScript to stdout ' , async ( ) => {
1821 vi . mocked ( globalThis . fetch ) . mockResolvedValueOnce ( {
1922 ok : true ,
2023 json : async ( ) => sampleAbi ,
2124 } as Response ) ;
2225
23- const contractId = 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait' ;
24- const { address, name } = parseContractId ( contractId ) ;
26+ const chunks : string [ ] = [ ] ;
27+ const writeSpy = vi . spyOn ( process . stdout , 'write' ) . mockImplementation ( ( chunk ) => {
28+ chunks . push ( String ( chunk ) ) ;
29+ return true ;
30+ } ) ;
31+ const errorSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
2532
26- expect ( address ) . toBe ( 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9' ) ;
27- expect ( name ) . toBe ( 'nft-trait' ) ;
33+ await runFetch ( {
34+ contract : 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait' ,
35+ network : 'mainnet' ,
36+ format : 'ts' ,
37+ stdout : true ,
38+ } ) ;
2839
29- const response = await globalThis . fetch (
30- `https://api.hiro.so/v2/contracts/interface/ ${ address } / ${ name } ` ,
31- ) ;
32- const abi = await ( response as Response ) . json ( ) ;
40+ const output = chunks . join ( '' ) ;
41+ expect ( output ) . toContain ( 'export const abi =' ) ;
42+ expect ( output ) . toContain ( 'as const;' ) ;
43+ expect ( output ) . toContain ( '"transfer"' ) ;
3344
34- const tsOutput = generateTypescript ( contractId , abi ) ;
35- expect ( tsOutput ) . toContain ( 'export const abi =' ) ;
36- expect ( tsOutput ) . toContain ( 'as const;' ) ;
37- expect ( tsOutput ) . toContain ( '"transfer"' ) ;
45+ writeSpy . mockRestore ( ) ;
46+ errorSpy . mockRestore ( ) ;
3847 } ) ;
3948
40- it ( 'end-to-end: parse contract, fetch ABI, generate JSON ' , async ( ) => {
49+ it ( 'writes JSON to stdout ' , async ( ) => {
4150 vi . mocked ( globalThis . fetch ) . mockResolvedValueOnce ( {
4251 ok : true ,
4352 json : async ( ) => sampleAbi ,
4453 } as Response ) ;
4554
46- const contractId = 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait' ;
47- const { address, name } = parseContractId ( contractId ) ;
55+ const chunks : string [ ] = [ ] ;
56+ const writeSpy = vi . spyOn ( process . stdout , 'write' ) . mockImplementation ( ( chunk ) => {
57+ chunks . push ( String ( chunk ) ) ;
58+ return true ;
59+ } ) ;
60+ const errorSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
4861
49- const response = await globalThis . fetch (
50- `https://api.hiro.so/v2/contracts/interface/${ address } /${ name } ` ,
51- ) ;
52- const abi = await ( response as Response ) . json ( ) ;
62+ await runFetch ( {
63+ contract : 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait' ,
64+ network : 'mainnet' ,
65+ format : 'json' ,
66+ stdout : true ,
67+ } ) ;
5368
54- const jsonOutput = generateJson ( abi ) ;
55- const parsed = JSON . parse ( jsonOutput ) ;
69+ const output = chunks . join ( '' ) ;
70+ const parsed = JSON . parse ( output ) ;
5671 expect ( parsed . functions ) . toBeDefined ( ) ;
5772 expect ( parsed . functions . length ) . toBe ( 4 ) ;
73+
74+ writeSpy . mockRestore ( ) ;
75+ errorSpy . mockRestore ( ) ;
76+ } ) ;
77+
78+ it ( 'throws on invalid format' , async ( ) => {
79+ await expect (
80+ runFetch ( {
81+ contract : 'SP2P.nft-trait' ,
82+ network : 'mainnet' ,
83+ format : 'yaml' ,
84+ stdout : true ,
85+ } ) ,
86+ ) . rejects . toThrow ( 'Invalid format "yaml"' ) ;
5887 } ) ;
5988} ) ;
0 commit comments