@@ -3,25 +3,31 @@ import assert from 'assert';
33import {
44 ActualOutput ,
55 ExpectedOutput ,
6+ getMissingOutputs ,
67 matchingOutput ,
78 outputDifference ,
89 outputDifferencesWithExpected ,
9- } from '../../../../ src/transaction/outputDifference' ;
10+ } from '../../../src/transaction/outputDifference' ;
1011
1112describe ( 'outputDifference' , function ( ) {
12- function output ( script : string , value : bigint | number ) : ActualOutput ;
13- function output ( script : string , value : 'max' ) : ExpectedOutput ;
14- function output ( script : string , value : bigint | number | 'max' ) : ActualOutput | ExpectedOutput {
13+ function output ( script : string , value : bigint | number , optional ?: boolean ) : ActualOutput ;
14+ function output ( script : string , value : 'max' , optional ?: boolean ) : ExpectedOutput ;
15+ function output ( script : string , value : bigint | number | 'max' , optional ?: boolean ) : ActualOutput | ExpectedOutput {
1516 const scriptBuffer = Buffer . from ( script , 'hex' ) ;
1617 if ( scriptBuffer . toString ( 'hex' ) !== script ) {
1718 throw new Error ( 'invalid script' ) ;
1819 }
1920 return {
2021 script : Buffer . from ( script , 'hex' ) ,
2122 value : value === 'max' ? 'max' : BigInt ( value ) ,
23+ ...( optional !== undefined ? { optional } : { } ) ,
2224 } ;
2325 }
2426
27+ function expectedOutput ( script : string , value : bigint | number | 'max' , optional ?: boolean ) : ExpectedOutput {
28+ return output ( script , value as 'max' , optional ) as ExpectedOutput ;
29+ }
30+
2531 const a = output ( 'aa' , 1 ) ;
2632 const a2 = output ( 'aa' , 2 ) ;
2733 const aMax = output ( 'aa' , 'max' ) ;
@@ -64,6 +70,32 @@ describe('outputDifference', function () {
6470 } ) ;
6571 } ) ;
6672
73+ describe ( 'getMissingOutputs' , function ( ) {
74+ it ( 'returns missing non-optional outputs' , function ( ) {
75+ const aOptional = expectedOutput ( 'aa' , 1 , true ) ;
76+ const bOptional = expectedOutput ( 'bb' , 1 , true ) ;
77+
78+ // No expected outputs means no missing outputs
79+ assert . deepStrictEqual ( getMissingOutputs ( [ a ] , [ ] ) , [ ] ) ;
80+
81+ // Missing required output is returned
82+ assert . deepStrictEqual ( getMissingOutputs ( [ ] , [ a ] ) , [ a ] ) ;
83+ assert . deepStrictEqual ( getMissingOutputs ( [ b ] , [ a ] ) , [ a ] ) ;
84+
85+ // Missing optional output is filtered out
86+ assert . deepStrictEqual ( getMissingOutputs ( [ ] , [ aOptional ] ) , [ ] ) ;
87+ assert . deepStrictEqual ( getMissingOutputs ( [ b ] , [ aOptional ] ) , [ ] ) ;
88+
89+ // Mix of optional and required: only required missing outputs returned
90+ assert . deepStrictEqual ( getMissingOutputs ( [ ] , [ a , bOptional ] ) , [ a ] ) ;
91+ assert . deepStrictEqual ( getMissingOutputs ( [ ] , [ aOptional , b ] ) , [ b ] ) ;
92+
93+ // Present outputs are not returned regardless of optional flag
94+ assert . deepStrictEqual ( getMissingOutputs ( [ a ] , [ a ] ) , [ ] ) ;
95+ assert . deepStrictEqual ( getMissingOutputs ( [ a ] , [ aOptional ] ) , [ ] ) ;
96+ } ) ;
97+ } ) ;
98+
6799 describe ( 'outputDifferencesWithExpected' , function ( ) {
68100 function test (
69101 outputs : ActualOutput [ ] ,
@@ -91,5 +123,27 @@ describe('outputDifference', function () {
91123 test ( [ a , a ] , [ a ] , { missing : [ ] , explicit : [ a ] , implicit : [ a ] } ) ;
92124 test ( [ a , b ] , [ a ] , { missing : [ ] , explicit : [ a ] , implicit : [ b ] } ) ;
93125 } ) ;
126+
127+ it ( 'handles optional expected outputs' , function ( ) {
128+ const aOptional = expectedOutput ( 'aa' , 1 , true ) ;
129+ const bOptional = expectedOutput ( 'bb' , 1 , true ) ;
130+
131+ // Missing optional output is not reported as missing
132+ test ( [ ] , [ aOptional ] , { missing : [ ] , explicit : [ ] , implicit : [ ] } ) ;
133+ test ( [ b ] , [ aOptional ] , { missing : [ ] , explicit : [ ] , implicit : [ b ] } ) ;
134+
135+ // Present optional output is still explicit
136+ test ( [ a ] , [ aOptional ] , { missing : [ ] , explicit : [ a ] , implicit : [ ] } ) ;
137+
138+ // Mix of required and optional outputs
139+ test ( [ ] , [ a , bOptional ] , { missing : [ a ] , explicit : [ ] , implicit : [ ] } ) ;
140+ test ( [ a ] , [ a , bOptional ] , { missing : [ ] , explicit : [ a ] , implicit : [ ] } ) ;
141+ test ( [ a , b ] , [ a , bOptional ] , { missing : [ ] , explicit : [ a , b ] , implicit : [ ] } ) ;
142+
143+ // Multiple optional outputs
144+ test ( [ ] , [ aOptional , bOptional ] , { missing : [ ] , explicit : [ ] , implicit : [ ] } ) ;
145+ test ( [ a ] , [ aOptional , bOptional ] , { missing : [ ] , explicit : [ a ] , implicit : [ ] } ) ;
146+ test ( [ a , b ] , [ aOptional , bOptional ] , { missing : [ ] , explicit : [ a , b ] , implicit : [ ] } ) ;
147+ } ) ;
94148 } ) ;
95149} ) ;
0 commit comments