capdag 0.157.363 → 0.161.384
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/RULES.md +6 -6
- package/capdag.js +458 -2
- package/capdag.test.js +241 -241
- package/machine.pegjs +2 -2
- package/package.json +2 -2
package/capdag.test.js
CHANGED
|
@@ -119,7 +119,7 @@ function makeCap(urnString, title) {
|
|
|
119
119
|
|
|
120
120
|
// Helper to create caps with specific in/out media URNs for graph testing
|
|
121
121
|
function makeGraphCap(inUrn, outUrn, title) {
|
|
122
|
-
const urnString = `cap:in="${inUrn}";
|
|
122
|
+
const urnString = `cap:in="${inUrn}";convert;out="${outUrn}"`;
|
|
123
123
|
const capUrn = CapUrn.fromString(urnString);
|
|
124
124
|
return new Cap(capUrn, title, 'convert', title);
|
|
125
125
|
}
|
|
@@ -130,7 +130,7 @@ function makeGraphCap(inUrn, outUrn, title) {
|
|
|
130
130
|
|
|
131
131
|
// TEST001: Test that cap URN is created with tags parsed correctly and direction specs accessible
|
|
132
132
|
function test001_capUrnCreation() {
|
|
133
|
-
const cap = CapUrn.fromString(testUrn('
|
|
133
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf;target=thumbnail'));
|
|
134
134
|
assertEqual(cap.getTag('op'), 'generate', 'Should get op tag');
|
|
135
135
|
assertEqual(cap.getTag('target'), 'thumbnail', 'Should get target tag');
|
|
136
136
|
assertEqual(cap.getTag('ext'), 'pdf', 'Should get ext tag');
|
|
@@ -156,11 +156,11 @@ function test003_directionMatching() {
|
|
|
156
156
|
assert(cap.accepts(request), 'Same direction specs should match');
|
|
157
157
|
|
|
158
158
|
// Different direction should not match
|
|
159
|
-
const requestDiff = CapUrn.fromString('cap:in="media:textable";
|
|
159
|
+
const requestDiff = CapUrn.fromString('cap:in="media:textable";generate;out="media:record;textable"');
|
|
160
160
|
assert(!cap.accepts(requestDiff), 'Different inSpec should not match');
|
|
161
161
|
|
|
162
162
|
// Wildcard direction matches any
|
|
163
|
-
const wildcardCap = CapUrn.fromString('cap:in=*;
|
|
163
|
+
const wildcardCap = CapUrn.fromString('cap:in=*;generate;out=*');
|
|
164
164
|
assert(wildcardCap.accepts(request), 'Wildcard direction should match any');
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -237,7 +237,7 @@ function test011_serializationSmartQuoting() {
|
|
|
237
237
|
|
|
238
238
|
// TEST012: Test that simple cap URN round-trips (parse -> serialize -> parse equals original)
|
|
239
239
|
function test012_roundTripSimple() {
|
|
240
|
-
const original = CapUrn.fromString(testUrn('
|
|
240
|
+
const original = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
241
241
|
const serialized = original.toString();
|
|
242
242
|
const reparsed = CapUrn.fromString(serialized);
|
|
243
243
|
assert(original.equals(reparsed), 'Simple round-trip should produce equal URN');
|
|
@@ -276,18 +276,18 @@ function test015_capPrefixRequired() {
|
|
|
276
276
|
|
|
277
277
|
// TEST016: Test that trailing semicolon is equivalent (same hash, same string, matches)
|
|
278
278
|
function test016_trailingSemicolonEquivalence() {
|
|
279
|
-
const cap1 = CapUrn.fromString(testUrn('
|
|
280
|
-
const cap2 = CapUrn.fromString(testUrn('
|
|
279
|
+
const cap1 = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
280
|
+
const cap2 = CapUrn.fromString(testUrn('generate;ext=pdf') + ';');
|
|
281
281
|
assert(cap1.equals(cap2), 'With/without trailing semicolon should be equal');
|
|
282
282
|
assertEqual(cap1.toString(), cap2.toString(), 'Canonical forms should match');
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
// TEST017: Test tag matching: exact match, subset match, wildcard match, value mismatch
|
|
286
286
|
function test017_tagMatching() {
|
|
287
|
-
const cap = CapUrn.fromString(testUrn('
|
|
287
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf;target=thumbnail'));
|
|
288
288
|
|
|
289
289
|
// Exact match — both directions accept
|
|
290
|
-
const exact = CapUrn.fromString(testUrn('
|
|
290
|
+
const exact = CapUrn.fromString(testUrn('generate;ext=pdf;target=thumbnail'));
|
|
291
291
|
assert(cap.accepts(exact), 'Should accept exact match');
|
|
292
292
|
assert(exact.accepts(cap), 'Exact match should accept in reverse too');
|
|
293
293
|
|
|
@@ -320,7 +320,7 @@ function test019_missingTagHandling() {
|
|
|
320
320
|
assert(!cap.accepts(request), 'Pattern requiring op should reject instance missing op');
|
|
321
321
|
assert(!request.accepts(cap), 'Pattern requiring ext should reject instance missing ext');
|
|
322
322
|
|
|
323
|
-
const cap2 = CapUrn.fromString(testUrn('
|
|
323
|
+
const cap2 = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
324
324
|
const request2 = CapUrn.fromString(testUrn('op=generate'));
|
|
325
325
|
assert(!cap2.accepts(request2), 'Specific pattern should reject instance missing ext');
|
|
326
326
|
assert(request2.accepts(cap2), 'General request should accept more specific instance');
|
|
@@ -386,8 +386,8 @@ function test023_builderPreservesCase() {
|
|
|
386
386
|
|
|
387
387
|
// TEST024: Directional accepts — pattern's tags are constraints, instance must satisfy
|
|
388
388
|
function test024_compatibility() {
|
|
389
|
-
const cap1 = CapUrn.fromString(testUrn('
|
|
390
|
-
const cap2 = CapUrn.fromString(testUrn('
|
|
389
|
+
const cap1 = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
390
|
+
const cap2 = CapUrn.fromString(testUrn('generate;format=*'));
|
|
391
391
|
const cap3 = CapUrn.fromString(testUrn('type=image;op=extract'));
|
|
392
392
|
|
|
393
393
|
assert(!cap1.accepts(cap2), 'Pattern requiring ext should reject instance missing ext');
|
|
@@ -399,7 +399,7 @@ function test024_compatibility() {
|
|
|
399
399
|
assert(general.accepts(cap1), 'General request should accept more specific instance');
|
|
400
400
|
assert(!cap1.accepts(general), 'Specific pattern should reject general instance');
|
|
401
401
|
|
|
402
|
-
const broadIn = CapUrn.fromString('cap:in="media:";
|
|
402
|
+
const broadIn = CapUrn.fromString('cap:in="media:";generate;out="media:record;textable"');
|
|
403
403
|
assert(!cap1.accepts(broadIn), 'Specific input should not accept broad wildcard input');
|
|
404
404
|
assert(broadIn.accepts(cap1), 'Wildcard input should accept specific input');
|
|
405
405
|
}
|
|
@@ -409,7 +409,7 @@ function test025_bestMatch() {
|
|
|
409
409
|
const caps = [
|
|
410
410
|
CapUrn.fromString('cap:in=*;out=*;op=*'),
|
|
411
411
|
CapUrn.fromString(testUrn('op=generate')),
|
|
412
|
-
CapUrn.fromString(testUrn('
|
|
412
|
+
CapUrn.fromString(testUrn('generate;ext=pdf'))
|
|
413
413
|
];
|
|
414
414
|
const request = CapUrn.fromString(testUrn('op=generate'));
|
|
415
415
|
const best = CapMatcher.findBestMatch(caps, request);
|
|
@@ -573,67 +573,67 @@ function test039_getTagReturnsDirectionSpecs() {
|
|
|
573
573
|
|
|
574
574
|
// TEST040: Matching semantics - exact match succeeds
|
|
575
575
|
function test040_matchingSemanticsExactMatch() {
|
|
576
|
-
const cap = CapUrn.fromString(testUrn('
|
|
577
|
-
const request = CapUrn.fromString(testUrn('
|
|
576
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
577
|
+
const request = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
578
578
|
assert(cap.accepts(request), 'Exact match should accept');
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
// TEST041: Matching semantics - cap missing tag matches (implicit wildcard)
|
|
582
582
|
function test041_matchingSemanticsCapMissingTag() {
|
|
583
583
|
const cap = CapUrn.fromString(testUrn('op=generate'));
|
|
584
|
-
const request = CapUrn.fromString(testUrn('
|
|
584
|
+
const request = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
585
585
|
assert(cap.accepts(request), 'General pattern with only op should accept specific instance');
|
|
586
586
|
assert(!request.accepts(cap), 'Pattern requiring ext should reject instance missing ext');
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
// TEST042: Pattern rejects instance missing required tags
|
|
590
590
|
function test042_matchingSemanticsCapHasExtraTag() {
|
|
591
|
-
const cap = CapUrn.fromString(testUrn('
|
|
592
|
-
const request = CapUrn.fromString(testUrn('
|
|
591
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf;version=2'));
|
|
592
|
+
const request = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
593
593
|
assert(!cap.accepts(request), 'Pattern requiring version should reject instance missing version');
|
|
594
594
|
assert(request.accepts(cap), 'General request should accept refined instance');
|
|
595
595
|
}
|
|
596
596
|
|
|
597
597
|
// TEST043: Matching semantics - request wildcard matches specific cap value
|
|
598
598
|
function test043_matchingSemanticsRequestHasWildcard() {
|
|
599
|
-
const cap = CapUrn.fromString(testUrn('
|
|
600
|
-
const request = CapUrn.fromString(testUrn('
|
|
599
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
600
|
+
const request = CapUrn.fromString(testUrn('generate;ext=*'));
|
|
601
601
|
assert(cap.accepts(request), 'Request wildcard should match specific cap value');
|
|
602
602
|
}
|
|
603
603
|
|
|
604
604
|
// TEST044: Matching semantics - cap wildcard matches specific request value
|
|
605
605
|
function test044_matchingSemanticsCapHasWildcard() {
|
|
606
|
-
const cap = CapUrn.fromString(testUrn('
|
|
607
|
-
const request = CapUrn.fromString(testUrn('
|
|
606
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=*'));
|
|
607
|
+
const request = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
608
608
|
assert(cap.accepts(request), 'Cap wildcard should match specific request value');
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
// TEST045: Matching semantics - value mismatch does not match
|
|
612
612
|
function test045_matchingSemanticsValueMismatch() {
|
|
613
|
-
const cap = CapUrn.fromString(testUrn('
|
|
614
|
-
const request = CapUrn.fromString(testUrn('
|
|
613
|
+
const cap = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
614
|
+
const request = CapUrn.fromString(testUrn('generate;ext=docx'));
|
|
615
615
|
assert(!cap.accepts(request), 'Value mismatch should not accept');
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
// TEST046: Matching semantics - fallback pattern (cap missing tag = implicit wildcard)
|
|
619
619
|
function test046_matchingSemanticsFallbackPattern() {
|
|
620
|
-
const cap = CapUrn.fromString('cap:in="media:binary";
|
|
621
|
-
const request = CapUrn.fromString('cap:ext=wav;in="media:binary";
|
|
620
|
+
const cap = CapUrn.fromString('cap:in="media:binary";generate-thumbnail;out="media:binary"');
|
|
621
|
+
const request = CapUrn.fromString('cap:ext=wav;in="media:binary";generate-thumbnail;out="media:binary"');
|
|
622
622
|
assert(cap.accepts(request), 'General pattern without ext should accept specific instance');
|
|
623
623
|
assert(!request.accepts(cap), 'Pattern requiring ext should reject instance missing ext');
|
|
624
624
|
}
|
|
625
625
|
|
|
626
626
|
// TEST047: Matching semantics - thumbnail fallback with void input
|
|
627
627
|
function test047_matchingSemanticsThumbnailVoidInput() {
|
|
628
|
-
const cap = CapUrn.fromString('cap:in="media:void";
|
|
629
|
-
const request = CapUrn.fromString('cap:ext=pdf;in="media:void";
|
|
628
|
+
const cap = CapUrn.fromString('cap:in="media:void";generate-thumbnail;out="media:image;png;thumbnail"');
|
|
629
|
+
const request = CapUrn.fromString('cap:ext=pdf;in="media:void";generate-thumbnail;out="media:image"');
|
|
630
630
|
assert(cap.accepts(request), 'Void input cap should accept request; cap output conforms to less-specific request output');
|
|
631
631
|
}
|
|
632
632
|
|
|
633
633
|
// TEST048: Matching semantics - wildcard direction matches anything
|
|
634
634
|
function test048_matchingSemanticsWildcardDirection() {
|
|
635
635
|
const cap = CapUrn.fromString('cap:in=*;out=*');
|
|
636
|
-
const request = CapUrn.fromString(testUrn('
|
|
636
|
+
const request = CapUrn.fromString(testUrn('generate;ext=pdf'));
|
|
637
637
|
assert(cap.accepts(request), 'Wildcard cap should accept any request');
|
|
638
638
|
}
|
|
639
639
|
|
|
@@ -648,10 +648,10 @@ function test049_matchingSemanticsCrossDimension() {
|
|
|
648
648
|
// TEST050: Matching semantics - direction mismatch prevents matching
|
|
649
649
|
function test050_matchingSemanticsDirectionMismatch() {
|
|
650
650
|
const cap = CapUrn.fromString(
|
|
651
|
-
`cap:in="${MEDIA_STRING}";
|
|
651
|
+
`cap:in="${MEDIA_STRING}";generate;out="${MEDIA_OBJECT}"`
|
|
652
652
|
);
|
|
653
653
|
const request = CapUrn.fromString(
|
|
654
|
-
`cap:in="${MEDIA_IDENTITY}";
|
|
654
|
+
`cap:in="${MEDIA_IDENTITY}";generate;out="${MEDIA_OBJECT}"`
|
|
655
655
|
);
|
|
656
656
|
assert(!cap.accepts(request), 'Incompatible direction types should not match');
|
|
657
657
|
}
|
|
@@ -660,25 +660,25 @@ function test050_matchingSemanticsDirectionMismatch() {
|
|
|
660
660
|
function test890_directionSemanticMatching() {
|
|
661
661
|
// Generic wildcard cap accepts specific pdf request
|
|
662
662
|
const genericCap = CapUrn.fromString(
|
|
663
|
-
'cap:in="media:";
|
|
663
|
+
'cap:in="media:";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
664
664
|
);
|
|
665
665
|
const pdfRequest = CapUrn.fromString(
|
|
666
|
-
'cap:in="media:pdf";
|
|
666
|
+
'cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
667
667
|
);
|
|
668
668
|
assert(genericCap.accepts(pdfRequest), 'Generic wildcard cap must accept pdf request');
|
|
669
669
|
|
|
670
670
|
// Also accepts epub
|
|
671
671
|
const epubRequest = CapUrn.fromString(
|
|
672
|
-
'cap:in="media:epub";
|
|
672
|
+
'cap:in="media:epub";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
673
673
|
);
|
|
674
674
|
assert(genericCap.accepts(epubRequest), 'Generic wildcard cap must accept epub request');
|
|
675
675
|
|
|
676
676
|
// Reverse: specific pdf cap does NOT accept generic bytes request
|
|
677
677
|
const pdfCap = CapUrn.fromString(
|
|
678
|
-
'cap:in="media:pdf";
|
|
678
|
+
'cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
679
679
|
);
|
|
680
680
|
const genericRequest = CapUrn.fromString(
|
|
681
|
-
'cap:in="media:";
|
|
681
|
+
'cap:in="media:";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
682
682
|
);
|
|
683
683
|
assert(!pdfCap.accepts(genericRequest), 'Specific pdf cap must NOT accept generic wildcard request');
|
|
684
684
|
|
|
@@ -687,20 +687,20 @@ function test890_directionSemanticMatching() {
|
|
|
687
687
|
|
|
688
688
|
// Output direction: cap producing more specific output satisfies less specific request
|
|
689
689
|
const specificOutCap = CapUrn.fromString(
|
|
690
|
-
'cap:in="media:";
|
|
690
|
+
'cap:in="media:";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
691
691
|
);
|
|
692
692
|
const genericOutRequest = CapUrn.fromString(
|
|
693
|
-
'cap:in="media:";
|
|
693
|
+
'cap:in="media:";generate-thumbnail;out="media:image"'
|
|
694
694
|
);
|
|
695
695
|
assert(specificOutCap.accepts(genericOutRequest),
|
|
696
696
|
'Cap producing image;png;thumbnail must satisfy request for image');
|
|
697
697
|
|
|
698
698
|
// Reverse output: generic output cap does NOT satisfy specific output request
|
|
699
699
|
const genericOutCap = CapUrn.fromString(
|
|
700
|
-
'cap:in="media:";
|
|
700
|
+
'cap:in="media:";generate-thumbnail;out="media:image"'
|
|
701
701
|
);
|
|
702
702
|
const specificOutRequest = CapUrn.fromString(
|
|
703
|
-
'cap:in="media:";
|
|
703
|
+
'cap:in="media:";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
704
704
|
);
|
|
705
705
|
assert(!genericOutCap.accepts(specificOutRequest),
|
|
706
706
|
'Generic output cap must NOT satisfy specific output request');
|
|
@@ -709,10 +709,10 @@ function test890_directionSemanticMatching() {
|
|
|
709
709
|
// TEST891: Semantic direction specificity - more media URN tags = higher specificity
|
|
710
710
|
function test891_directionSemanticSpecificity() {
|
|
711
711
|
const genericCap = CapUrn.fromString(
|
|
712
|
-
'cap:in="media:";
|
|
712
|
+
'cap:in="media:";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
713
713
|
);
|
|
714
714
|
const specificCap = CapUrn.fromString(
|
|
715
|
-
'cap:in="media:pdf";
|
|
715
|
+
'cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
716
716
|
);
|
|
717
717
|
|
|
718
718
|
assertEqual(genericCap.specificity(), 4, 'media:(0) + image;png;thumbnail(3) + op(1) = 4');
|
|
@@ -721,7 +721,7 @@ function test891_directionSemanticSpecificity() {
|
|
|
721
721
|
|
|
722
722
|
// CapMatcher should prefer more specific
|
|
723
723
|
const pdfRequest = CapUrn.fromString(
|
|
724
|
-
'cap:in="media:pdf";
|
|
724
|
+
'cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"'
|
|
725
725
|
);
|
|
726
726
|
const best = CapMatcher.findBestMatch([genericCap, specificCap], pdfRequest);
|
|
727
727
|
assert(best !== null, 'Should find a match');
|
|
@@ -1494,7 +1494,7 @@ function testJS_getExtensionMappings() {
|
|
|
1494
1494
|
}
|
|
1495
1495
|
|
|
1496
1496
|
function testJS_capWithMediaSpecs() {
|
|
1497
|
-
const urn = CapUrn.fromString('cap:in="media:string";
|
|
1497
|
+
const urn = CapUrn.fromString('cap:in="media:string";test;out="media:custom"');
|
|
1498
1498
|
const cap = new Cap(urn, 'Test Cap', 'test_command');
|
|
1499
1499
|
cap.mediaSpecs = [
|
|
1500
1500
|
{ urn: MEDIA_STRING, media_type: 'text/plain', title: 'String', profile_uri: 'https://capdag.com/schema/str' },
|
|
@@ -1664,12 +1664,12 @@ const sampleRegistry = {
|
|
|
1664
1664
|
adapter_urns: ['media:pdf'],
|
|
1665
1665
|
caps: [
|
|
1666
1666
|
{
|
|
1667
|
-
urn: 'cap:in="media:pdf";
|
|
1667
|
+
urn: 'cap:in="media:pdf";disbind;out="media:disbound-page;textable;list"',
|
|
1668
1668
|
title: 'Disbind PDF',
|
|
1669
1669
|
description: 'Extract pages'
|
|
1670
1670
|
},
|
|
1671
1671
|
{
|
|
1672
|
-
urn: 'cap:in="media:pdf";
|
|
1672
|
+
urn: 'cap:in="media:pdf";extract-metadata;out="media:file-metadata;textable;record"',
|
|
1673
1673
|
title: 'Extract Metadata',
|
|
1674
1674
|
description: 'Get PDF metadata'
|
|
1675
1675
|
}
|
|
@@ -1709,7 +1709,7 @@ const sampleRegistry = {
|
|
|
1709
1709
|
adapter_urns: ['media:txt;textable'],
|
|
1710
1710
|
caps: [
|
|
1711
1711
|
{
|
|
1712
|
-
urn: 'cap:in="media:txt;textable";
|
|
1712
|
+
urn: 'cap:in="media:txt;textable";disbind;out="media:disbound-page;textable;list"',
|
|
1713
1713
|
title: 'Disbind Text',
|
|
1714
1714
|
description: 'Extract text pages'
|
|
1715
1715
|
}
|
|
@@ -1751,7 +1751,7 @@ const sampleRegistry = {
|
|
|
1751
1751
|
adapter_urns: ['media:json'],
|
|
1752
1752
|
caps: [
|
|
1753
1753
|
{
|
|
1754
|
-
urn: 'cap:in="media:json";
|
|
1754
|
+
urn: 'cap:in="media:json";pretty;out="media:json;textable"',
|
|
1755
1755
|
title: 'Pretty Print JSON',
|
|
1756
1756
|
description: 'Format JSON',
|
|
1757
1757
|
command: 'pretty'
|
|
@@ -1795,7 +1795,7 @@ function test320_cartridgeInfoConstruction() {
|
|
|
1795
1795
|
cap_groups: [{
|
|
1796
1796
|
name: 'test-group',
|
|
1797
1797
|
adapter_urns: ['media:void'],
|
|
1798
|
-
caps: [{urn: 'cap:in="media:void";
|
|
1798
|
+
caps: [{urn: 'cap:in="media:void";test;out="media:void"', title: 'Test', description: ''}]
|
|
1799
1799
|
}],
|
|
1800
1800
|
versions: {
|
|
1801
1801
|
'1.0.0': {
|
|
@@ -1811,7 +1811,7 @@ function test320_cartridgeInfoConstruction() {
|
|
|
1811
1811
|
assert(cartridge.id === 'testcartridge', 'ID should match');
|
|
1812
1812
|
assert(cartridge.teamId === 'TEAM123', 'Team ID should match');
|
|
1813
1813
|
assert(cartridge.cap_groups.length === 1, 'Should have 1 cap_group');
|
|
1814
|
-
assert(cartridge.cap_groups[0].caps[0].urn === 'cap:in="media:void";
|
|
1814
|
+
assert(cartridge.cap_groups[0].caps[0].urn === 'cap:in="media:void";test;out="media:void"', 'Cap URN should match');
|
|
1815
1815
|
assert(cartridge.allCaps().length === 1, 'allCaps() should return 1 cap');
|
|
1816
1816
|
}
|
|
1817
1817
|
|
|
@@ -2029,13 +2029,13 @@ function test328_cartridgeRepoServerGetByCategory() {
|
|
|
2029
2029
|
function test329_cartridgeRepoServerGetByCap() {
|
|
2030
2030
|
const server = new CartridgeRepoServer(sampleRegistry);
|
|
2031
2031
|
|
|
2032
|
-
const disbindCap = 'cap:in="media:pdf";
|
|
2032
|
+
const disbindCap = 'cap:in="media:pdf";disbind;out="media:disbound-page;textable;list"';
|
|
2033
2033
|
const cartridges = server.getCartridgesByCap(disbindCap);
|
|
2034
2034
|
|
|
2035
2035
|
assert(cartridges.length === 1, 'Should find 1 cartridge with this cap');
|
|
2036
2036
|
assert(cartridges[0].id === 'pdfcartridge', 'Should be pdfcartridge');
|
|
2037
2037
|
|
|
2038
|
-
const metadataCap = 'cap:in="media:pdf";
|
|
2038
|
+
const metadataCap = 'cap:in="media:pdf";extract-metadata;out="media:file-metadata;textable;record"';
|
|
2039
2039
|
const metadataCartridges = server.getCartridgesByCap(metadataCap);
|
|
2040
2040
|
assert(metadataCartridges.length === 1, 'Should find metadata cap');
|
|
2041
2041
|
}
|
|
@@ -2078,7 +2078,7 @@ function test331_cartridgeRepoClientGetSuggestions() {
|
|
|
2078
2078
|
|
|
2079
2079
|
client.updateCache('https://example.com/api/cartridges', cartridges);
|
|
2080
2080
|
|
|
2081
|
-
const disbindCap = 'cap:in="media:pdf";
|
|
2081
|
+
const disbindCap = 'cap:in="media:pdf";disbind;out="media:disbound-page;textable;list"';
|
|
2082
2082
|
const suggestions = client.getSuggestionsForCap(disbindCap);
|
|
2083
2083
|
|
|
2084
2084
|
assert(suggestions.length === 1, 'Should find 1 suggestion');
|
|
@@ -2093,7 +2093,7 @@ function test331_cartridgeRepoClientGetSuggestions() {
|
|
|
2093
2093
|
assert(suggestions[0].capTitle === 'Disbind PDF', 'Should have cap title');
|
|
2094
2094
|
|
|
2095
2095
|
// Nightly cap should also surface a suggestion, with channel set to nightly.
|
|
2096
|
-
const prettyCap = 'cap:in="media:json";
|
|
2096
|
+
const prettyCap = 'cap:in="media:json";pretty;out="media:json;textable"';
|
|
2097
2097
|
const nightlySuggestions = client.getSuggestionsForCap(prettyCap);
|
|
2098
2098
|
assert(nightlySuggestions.length === 1, 'Should find nightly cap suggestion');
|
|
2099
2099
|
assert(nightlySuggestions[0].channel === 'nightly', 'Should report nightly channel');
|
|
@@ -2202,7 +2202,7 @@ function test335_cartridgeRepoServerClientIntegration() {
|
|
|
2202
2202
|
assert(cartridge.buildForPlatform('darwin-arm64') !== null, 'Cartridge should have darwin-arm64 build');
|
|
2203
2203
|
|
|
2204
2204
|
// Client can get suggestions
|
|
2205
|
-
const capUrn = 'cap:in="media:pdf";
|
|
2205
|
+
const capUrn = 'cap:in="media:pdf";disbind;out="media:disbound-page;textable;list"';
|
|
2206
2206
|
const suggestions = client.getSuggestionsForCap(capUrn);
|
|
2207
2207
|
assert(suggestions.length === 1, 'Should get suggestions');
|
|
2208
2208
|
assert(suggestions[0].cartridgeId === 'pdfcartridge', 'Should suggest correct cartridge');
|
|
@@ -2338,7 +2338,7 @@ function test1302_predicateConstantConsistency() {
|
|
|
2338
2338
|
|
|
2339
2339
|
// TEST1303: without_tag removes tag, ignores in/out, case-insensitive for keys
|
|
2340
2340
|
function test1303_withoutTag() {
|
|
2341
|
-
const cap = CapUrn.fromString('cap:in="media:void";
|
|
2341
|
+
const cap = CapUrn.fromString('cap:in="media:void";test;ext=pdf;out="media:void"');
|
|
2342
2342
|
const removed = cap.withoutTag('ext');
|
|
2343
2343
|
assertEqual(removed.getTag('ext'), undefined, 'withoutTag should remove ext');
|
|
2344
2344
|
assertEqual(removed.getTag('op'), 'test', 'withoutTag should preserve op');
|
|
@@ -2360,7 +2360,7 @@ function test1303_withoutTag() {
|
|
|
2360
2360
|
|
|
2361
2361
|
// TEST1304: with_in_spec and with_out_spec change direction specs
|
|
2362
2362
|
function test1304_withInOutSpec() {
|
|
2363
|
-
const cap = CapUrn.fromString('cap:in="media:void";
|
|
2363
|
+
const cap = CapUrn.fromString('cap:in="media:void";test;out="media:void"');
|
|
2364
2364
|
|
|
2365
2365
|
const changedIn = cap.withInSpec('media:');
|
|
2366
2366
|
assertEqual(changedIn.getInSpec(), 'media:', 'withInSpec should change inSpec');
|
|
@@ -2384,15 +2384,15 @@ function test1304_withInOutSpec() {
|
|
|
2384
2384
|
// TEST1305: CapMatcher::find_all_matches returns all matching caps sorted by specificity
|
|
2385
2385
|
function test1305_findAllMatches() {
|
|
2386
2386
|
const caps = [
|
|
2387
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2388
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2389
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2387
|
+
CapUrn.fromString('cap:in="media:void";test;out="media:void"'),
|
|
2388
|
+
CapUrn.fromString('cap:in="media:void";test;ext=pdf;out="media:void"'),
|
|
2389
|
+
CapUrn.fromString('cap:in="media:void";different;out="media:void"'),
|
|
2390
2390
|
];
|
|
2391
2391
|
|
|
2392
|
-
const request = CapUrn.fromString('cap:in="media:void";
|
|
2392
|
+
const request = CapUrn.fromString('cap:in="media:void";test;out="media:void"');
|
|
2393
2393
|
const matches = CapMatcher.findAllMatches(caps, request);
|
|
2394
2394
|
|
|
2395
|
-
// Should find 2 matches (op=test and
|
|
2395
|
+
// Should find 2 matches (op=test and test;ext=pdf), not op=different
|
|
2396
2396
|
assertEqual(matches.length, 2, 'Should find 2 matches');
|
|
2397
2397
|
// Sorted by specificity descending: ext=pdf first (more specific)
|
|
2398
2398
|
assert(matches[0].specificity() >= matches[1].specificity(), 'First match should be more specific');
|
|
@@ -2402,16 +2402,16 @@ function test1305_findAllMatches() {
|
|
|
2402
2402
|
// TEST1306: CapMatcher::are_compatible detects bidirectional overlap
|
|
2403
2403
|
function test1306_areCompatible() {
|
|
2404
2404
|
const caps1 = [
|
|
2405
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2405
|
+
CapUrn.fromString('cap:in="media:void";test;out="media:void"'),
|
|
2406
2406
|
];
|
|
2407
2407
|
const caps2 = [
|
|
2408
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2408
|
+
CapUrn.fromString('cap:in="media:void";test;ext=pdf;out="media:void"'),
|
|
2409
2409
|
];
|
|
2410
2410
|
const caps3 = [
|
|
2411
|
-
CapUrn.fromString('cap:in="media:void";
|
|
2411
|
+
CapUrn.fromString('cap:in="media:void";different;out="media:void"'),
|
|
2412
2412
|
];
|
|
2413
2413
|
|
|
2414
|
-
// caps1 (op=test) accepts caps2 (
|
|
2414
|
+
// caps1 (op=test) accepts caps2 (test;ext=pdf) -> compatible
|
|
2415
2415
|
assert(CapMatcher.areCompatible(caps1, caps2), 'caps1 and caps2 should be compatible');
|
|
2416
2416
|
|
|
2417
2417
|
// caps1 (op=test) vs caps3 (op=different) -> not compatible
|
|
@@ -2426,7 +2426,7 @@ function test1306_areCompatible() {
|
|
|
2426
2426
|
|
|
2427
2427
|
// TEST1307: with_tag silently ignores in/out keys
|
|
2428
2428
|
function test1307_withTagIgnoresInOut() {
|
|
2429
|
-
const cap = CapUrn.fromString('cap:in="media:void";
|
|
2429
|
+
const cap = CapUrn.fromString('cap:in="media:void";test;out="media:void"');
|
|
2430
2430
|
// Attempting to set in/out via withTag is silently ignored
|
|
2431
2431
|
const same = cap.withTag('in', 'media:');
|
|
2432
2432
|
assertEqual(same.getInSpec(), 'media:void', 'withTag must not change in_spec');
|
|
@@ -2437,7 +2437,7 @@ function test1307_withTagIgnoresInOut() {
|
|
|
2437
2437
|
|
|
2438
2438
|
// TEST1294: RULE11 - void-input cap with stdin source rejected
|
|
2439
2439
|
function test1294_rule11VoidInputWithStdinRejected() {
|
|
2440
|
-
const urn = CapUrn.fromString('cap:in="media:void";
|
|
2440
|
+
const urn = CapUrn.fromString('cap:in="media:void";test;out="media:string"');
|
|
2441
2441
|
const cap = new Cap(urn, 'Test', 'test-cmd');
|
|
2442
2442
|
const stdinSource = ArgSource.fromJSON({ stdin: 'media:string' });
|
|
2443
2443
|
cap.args = [new CapArg('media:string', true, [stdinSource])];
|
|
@@ -2452,7 +2452,7 @@ function test1294_rule11VoidInputWithStdinRejected() {
|
|
|
2452
2452
|
|
|
2453
2453
|
// TEST1295: RULE11 - non-void-input cap without stdin source rejected
|
|
2454
2454
|
function test1295_rule11NonVoidInputWithoutStdinRejected() {
|
|
2455
|
-
const urn = CapUrn.fromString('cap:in="media:string";
|
|
2455
|
+
const urn = CapUrn.fromString('cap:in="media:string";test;out="media:string"');
|
|
2456
2456
|
const cap = new Cap(urn, 'Test', 'test-cmd');
|
|
2457
2457
|
const posSource = ArgSource.fromJSON({ cli_flag: '--name' });
|
|
2458
2458
|
cap.args = [new CapArg('media:string', true, [posSource])];
|
|
@@ -2467,7 +2467,7 @@ function test1295_rule11NonVoidInputWithoutStdinRejected() {
|
|
|
2467
2467
|
|
|
2468
2468
|
// TEST1296: RULE11 - void-input cap with only cli_flag sources passes
|
|
2469
2469
|
function test1296_rule11VoidInputCliFlagOnly() {
|
|
2470
|
-
const urn = CapUrn.fromString('cap:in="media:void";
|
|
2470
|
+
const urn = CapUrn.fromString('cap:in="media:void";test;out="media:string"');
|
|
2471
2471
|
const cap = new Cap(urn, 'Test', 'test-cmd');
|
|
2472
2472
|
const flagSource = ArgSource.fromJSON({ cli_flag: '--name' });
|
|
2473
2473
|
cap.args = [new CapArg('media:string', true, [flagSource])];
|
|
@@ -2477,7 +2477,7 @@ function test1296_rule11VoidInputCliFlagOnly() {
|
|
|
2477
2477
|
|
|
2478
2478
|
// TEST1297: RULE11 - non-void-input cap with stdin source passes
|
|
2479
2479
|
function test1297_rule11NonVoidInputWithStdin() {
|
|
2480
|
-
const urn = CapUrn.fromString('cap:in="media:string";
|
|
2480
|
+
const urn = CapUrn.fromString('cap:in="media:string";test;out="media:string"');
|
|
2481
2481
|
const cap = new Cap(urn, 'Test', 'test-cmd');
|
|
2482
2482
|
const stdinSource = ArgSource.fromJSON({ stdin: 'media:string' });
|
|
2483
2483
|
cap.args = [new CapArg('media:string', true, [stdinSource])];
|
|
@@ -2602,7 +2602,7 @@ function test651_identityFormsEquivalent() {
|
|
|
2602
2602
|
// TEST653: Identity (no tags) does not match specific requests via routing
|
|
2603
2603
|
function test653_identityRoutingIsolation() {
|
|
2604
2604
|
const identity = CapUrn.fromString('cap:in=*;out=*');
|
|
2605
|
-
const specificRequest = CapUrn.fromString('cap:in="media:void";
|
|
2605
|
+
const specificRequest = CapUrn.fromString('cap:in="media:void";test;out="media:void"');
|
|
2606
2606
|
|
|
2607
2607
|
// Identity has specificity 0 (no tags, wildcard directions)
|
|
2608
2608
|
assertEqual(identity.specificity(), 0, 'Identity specificity should be 0');
|
|
@@ -2612,7 +2612,7 @@ function test653_identityRoutingIsolation() {
|
|
|
2612
2612
|
'Specific request should have higher specificity than identity');
|
|
2613
2613
|
|
|
2614
2614
|
// CapMatcher should prefer specific over identity
|
|
2615
|
-
const specificCap = CapUrn.fromString('cap:in="media:void";
|
|
2615
|
+
const specificCap = CapUrn.fromString('cap:in="media:void";test;out="media:void"');
|
|
2616
2616
|
const best = CapMatcher.findBestMatch([identity, specificCap], specificRequest);
|
|
2617
2617
|
assert(best !== null, 'Should find a match');
|
|
2618
2618
|
assertEqual(best.getTag('op'), 'test', 'CapMatcher should prefer specific cap over identity');
|
|
@@ -2634,7 +2634,7 @@ function testMachine_whitespaceOnly() {
|
|
|
2634
2634
|
|
|
2635
2635
|
function testMachine_headerOnlyNoWirings() {
|
|
2636
2636
|
assertThrowsWithCode(
|
|
2637
|
-
() => Machine.fromString('[extract cap:in="media:pdf";
|
|
2637
|
+
() => Machine.fromString('[extract cap:in="media:pdf";extract;out="media:txt;textable"]'),
|
|
2638
2638
|
MachineSyntaxErrorCodes.NO_EDGES
|
|
2639
2639
|
);
|
|
2640
2640
|
}
|
|
@@ -2642,8 +2642,8 @@ function testMachine_headerOnlyNoWirings() {
|
|
|
2642
2642
|
function testMachine_duplicateAlias() {
|
|
2643
2643
|
assertThrowsWithCode(
|
|
2644
2644
|
() => Machine.fromString(
|
|
2645
|
-
'[ex cap:in="media:pdf";
|
|
2646
|
-
'[ex cap:in="media:pdf";
|
|
2645
|
+
'[ex cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2646
|
+
'[ex cap:in="media:pdf";summarize;out="media:txt;textable"]' +
|
|
2647
2647
|
'[a -> ex -> b]'
|
|
2648
2648
|
),
|
|
2649
2649
|
MachineSyntaxErrorCodes.DUPLICATE_ALIAS
|
|
@@ -2652,7 +2652,7 @@ function testMachine_duplicateAlias() {
|
|
|
2652
2652
|
|
|
2653
2653
|
function testMachine_simpleLinearChain() {
|
|
2654
2654
|
const g = Machine.fromString(
|
|
2655
|
-
'[extract cap:in="media:pdf";
|
|
2655
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2656
2656
|
'[doc -> extract -> text]'
|
|
2657
2657
|
);
|
|
2658
2658
|
assertEqual(g.edgeCount(), 1);
|
|
@@ -2667,8 +2667,8 @@ function testMachine_simpleLinearChain() {
|
|
|
2667
2667
|
|
|
2668
2668
|
function testMachine_twoStepChain() {
|
|
2669
2669
|
const g = Machine.fromString(
|
|
2670
|
-
'[extract cap:in="media:pdf";
|
|
2671
|
-
'[embed cap:in="media:txt;textable";
|
|
2670
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2671
|
+
'[embed cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"]' +
|
|
2672
2672
|
'[doc -> extract -> text]' +
|
|
2673
2673
|
'[text -> embed -> vectors]'
|
|
2674
2674
|
);
|
|
@@ -2681,9 +2681,9 @@ function testMachine_twoStepChain() {
|
|
|
2681
2681
|
|
|
2682
2682
|
function testMachine_fanOut() {
|
|
2683
2683
|
const g = Machine.fromString(
|
|
2684
|
-
'[meta cap:in="media:pdf";
|
|
2685
|
-
'[outline cap:in="media:pdf";
|
|
2686
|
-
'[thumb cap:in="media:pdf";
|
|
2684
|
+
'[meta cap:in="media:pdf";extract-metadata;out="media:file-metadata;record;textable"]' +
|
|
2685
|
+
'[outline cap:in="media:pdf";extract-outline;out="media:document-outline;record;textable"]' +
|
|
2686
|
+
'[thumb cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"]' +
|
|
2687
2687
|
'[doc -> meta -> metadata]' +
|
|
2688
2688
|
'[doc -> outline -> outline_data]' +
|
|
2689
2689
|
'[doc -> thumb -> thumbnail]'
|
|
@@ -2698,9 +2698,9 @@ function testMachine_fanOut() {
|
|
|
2698
2698
|
|
|
2699
2699
|
function testMachine_fanInSecondaryAssignedByPriorWiring() {
|
|
2700
2700
|
const g = Machine.fromString(
|
|
2701
|
-
'[thumb cap:in="media:pdf";
|
|
2702
|
-
'[model_dl cap:in="media:model-spec;textable";
|
|
2703
|
-
'[describe cap:in="media:image;png";
|
|
2701
|
+
'[thumb cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"]' +
|
|
2702
|
+
'[model_dl cap:in="media:model-spec;textable";download;out="media:model-spec;textable"]' +
|
|
2703
|
+
'[describe cap:in="media:image;png";describe-image;out="media:image-description;textable"]' +
|
|
2704
2704
|
'[doc -> thumb -> thumbnail]' +
|
|
2705
2705
|
'[spec_input -> model_dl -> model_spec]' +
|
|
2706
2706
|
'[(thumbnail, model_spec) -> describe -> description]'
|
|
@@ -2711,7 +2711,7 @@ function testMachine_fanInSecondaryAssignedByPriorWiring() {
|
|
|
2711
2711
|
|
|
2712
2712
|
function testMachine_fanInSecondaryUnassignedGetsWildcard() {
|
|
2713
2713
|
const g = Machine.fromString(
|
|
2714
|
-
'[describe cap:in="media:image;png";
|
|
2714
|
+
'[describe cap:in="media:image;png";describe-image;out="media:image-description;textable"]\n' +
|
|
2715
2715
|
'[(thumbnail, model_spec) -> describe -> description]'
|
|
2716
2716
|
);
|
|
2717
2717
|
assertEqual(g.edges().length, 1);
|
|
@@ -2722,7 +2722,7 @@ function testMachine_fanInSecondaryUnassignedGetsWildcard() {
|
|
|
2722
2722
|
|
|
2723
2723
|
function testMachine_loopEdge() {
|
|
2724
2724
|
const g = Machine.fromString(
|
|
2725
|
-
'[p2t cap:in="media:disbound-page;textable";
|
|
2725
|
+
'[p2t cap:in="media:disbound-page;textable";page-to-text;out="media:txt;textable"]' +
|
|
2726
2726
|
'[pages -> LOOP p2t -> texts]'
|
|
2727
2727
|
);
|
|
2728
2728
|
assertEqual(g.edgeCount(), 1);
|
|
@@ -2739,7 +2739,7 @@ function testMachine_undefinedAliasFails() {
|
|
|
2739
2739
|
function testMachine_nodeAliasCollision() {
|
|
2740
2740
|
assertThrowsWithCode(
|
|
2741
2741
|
() => Machine.fromString(
|
|
2742
|
-
'[extract cap:in="media:pdf";
|
|
2742
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2743
2743
|
'[extract -> extract -> text]'
|
|
2744
2744
|
),
|
|
2745
2745
|
MachineSyntaxErrorCodes.NODE_ALIAS_COLLISION
|
|
@@ -2749,8 +2749,8 @@ function testMachine_nodeAliasCollision() {
|
|
|
2749
2749
|
function testMachine_conflictingMediaTypesFail() {
|
|
2750
2750
|
assertThrowsWithCode(
|
|
2751
2751
|
() => Machine.fromString(
|
|
2752
|
-
'[cap1 cap:in="media:txt;textable";
|
|
2753
|
-
'[cap2 cap:in="media:audio;wav";
|
|
2752
|
+
'[cap1 cap:in="media:txt;textable";a;out="media:pdf"]' +
|
|
2753
|
+
'[cap2 cap:in="media:audio;wav";b;out="media:txt;textable"]' +
|
|
2754
2754
|
'[src -> cap1 -> mid]' +
|
|
2755
2755
|
'[mid -> cap2 -> dst]'
|
|
2756
2756
|
),
|
|
@@ -2760,8 +2760,8 @@ function testMachine_conflictingMediaTypesFail() {
|
|
|
2760
2760
|
|
|
2761
2761
|
function testMachine_multilineFormat() {
|
|
2762
2762
|
const g = Machine.fromString(
|
|
2763
|
-
'[extract cap:in="media:pdf";
|
|
2764
|
-
'[embed cap:in="media:txt;textable";
|
|
2763
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]\n' +
|
|
2764
|
+
'[embed cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"]\n' +
|
|
2765
2765
|
'[doc -> extract -> text]\n' +
|
|
2766
2766
|
'[text -> embed -> vectors]\n'
|
|
2767
2767
|
);
|
|
@@ -2770,11 +2770,11 @@ function testMachine_multilineFormat() {
|
|
|
2770
2770
|
|
|
2771
2771
|
function testMachine_differentAliasesSameGraph() {
|
|
2772
2772
|
const g1 = Machine.fromString(
|
|
2773
|
-
'[ex cap:in="media:pdf";
|
|
2773
|
+
'[ex cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2774
2774
|
'[a -> ex -> b]'
|
|
2775
2775
|
);
|
|
2776
2776
|
const g2 = Machine.fromString(
|
|
2777
|
-
'[xt cap:in="media:pdf";
|
|
2777
|
+
'[xt cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2778
2778
|
'[x -> xt -> y]'
|
|
2779
2779
|
);
|
|
2780
2780
|
assert(g1.isEquivalent(g2), 'Different aliases should produce equivalent graphs');
|
|
@@ -2798,7 +2798,7 @@ function testMachine_unterminatedBracketFails() {
|
|
|
2798
2798
|
|
|
2799
2799
|
function testMachine_lineBasedSimpleChain() {
|
|
2800
2800
|
const g = Machine.fromString(
|
|
2801
|
-
'extract cap:in="media:pdf";
|
|
2801
|
+
'extract cap:in="media:pdf";extract;out="media:txt;textable"\n' +
|
|
2802
2802
|
'doc -> extract -> text'
|
|
2803
2803
|
);
|
|
2804
2804
|
assertEqual(g.edgeCount(), 1);
|
|
@@ -2811,8 +2811,8 @@ function testMachine_lineBasedSimpleChain() {
|
|
|
2811
2811
|
|
|
2812
2812
|
function testMachine_lineBasedTwoStepChain() {
|
|
2813
2813
|
const g = Machine.fromString(
|
|
2814
|
-
'extract cap:in="media:pdf";
|
|
2815
|
-
'embed cap:in="media:txt;textable";
|
|
2814
|
+
'extract cap:in="media:pdf";extract;out="media:txt;textable"\n' +
|
|
2815
|
+
'embed cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"\n' +
|
|
2816
2816
|
'doc -> extract -> text\n' +
|
|
2817
2817
|
'text -> embed -> vectors'
|
|
2818
2818
|
);
|
|
@@ -2821,7 +2821,7 @@ function testMachine_lineBasedTwoStepChain() {
|
|
|
2821
2821
|
|
|
2822
2822
|
function testMachine_lineBasedLoop() {
|
|
2823
2823
|
const g = Machine.fromString(
|
|
2824
|
-
'p2t cap:in="media:disbound-page;textable";
|
|
2824
|
+
'p2t cap:in="media:disbound-page;textable";page-to-text;out="media:txt;textable"\n' +
|
|
2825
2825
|
'pages -> LOOP p2t -> texts'
|
|
2826
2826
|
);
|
|
2827
2827
|
assertEqual(g.edgeCount(), 1);
|
|
@@ -2830,9 +2830,9 @@ function testMachine_lineBasedLoop() {
|
|
|
2830
2830
|
|
|
2831
2831
|
function testMachine_lineBasedFanIn() {
|
|
2832
2832
|
const g = Machine.fromString(
|
|
2833
|
-
'thumb cap:in="media:pdf";
|
|
2834
|
-
'model_dl cap:in="media:model-spec;textable";
|
|
2835
|
-
'describe cap:in="media:image;png";
|
|
2833
|
+
'thumb cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"\n' +
|
|
2834
|
+
'model_dl cap:in="media:model-spec;textable";download;out="media:model-spec;textable"\n' +
|
|
2835
|
+
'describe cap:in="media:image;png";describe-image;out="media:image-description;textable"\n' +
|
|
2836
2836
|
'doc -> thumb -> thumbnail\n' +
|
|
2837
2837
|
'spec_input -> model_dl -> model_spec\n' +
|
|
2838
2838
|
'(thumbnail, model_spec) -> describe -> description'
|
|
@@ -2843,7 +2843,7 @@ function testMachine_lineBasedFanIn() {
|
|
|
2843
2843
|
|
|
2844
2844
|
function testMachine_mixedBracketedAndLineBased() {
|
|
2845
2845
|
const g = Machine.fromString(
|
|
2846
|
-
'[extract cap:in="media:pdf";
|
|
2846
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]\n' +
|
|
2847
2847
|
'doc -> extract -> text'
|
|
2848
2848
|
);
|
|
2849
2849
|
assertEqual(g.edgeCount(), 1);
|
|
@@ -2851,11 +2851,11 @@ function testMachine_mixedBracketedAndLineBased() {
|
|
|
2851
2851
|
|
|
2852
2852
|
function testMachine_lineBasedEquivalentToBracketed() {
|
|
2853
2853
|
const g1 = Machine.fromString(
|
|
2854
|
-
'[extract cap:in="media:pdf";
|
|
2854
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
2855
2855
|
'[doc -> extract -> text]'
|
|
2856
2856
|
);
|
|
2857
2857
|
const g2 = Machine.fromString(
|
|
2858
|
-
'extract cap:in="media:pdf";
|
|
2858
|
+
'extract cap:in="media:pdf";extract;out="media:txt;textable"\n' +
|
|
2859
2859
|
'doc -> extract -> text'
|
|
2860
2860
|
);
|
|
2861
2861
|
assert(g1.isEquivalent(g2), 'Line-based and bracketed must produce equivalent graphs');
|
|
@@ -2865,7 +2865,7 @@ function testMachine_lineBasedFormatSerialization() {
|
|
|
2865
2865
|
const g = new Machine([
|
|
2866
2866
|
new MachineEdge(
|
|
2867
2867
|
[MediaUrn.fromString('media:pdf')],
|
|
2868
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2868
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2869
2869
|
MediaUrn.fromString('media:txt;textable'),
|
|
2870
2870
|
false
|
|
2871
2871
|
),
|
|
@@ -2885,13 +2885,13 @@ function testMachine_lineBasedAndBracketedParseSameGraph() {
|
|
|
2885
2885
|
const g = new Machine([
|
|
2886
2886
|
new MachineEdge(
|
|
2887
2887
|
[MediaUrn.fromString('media:pdf')],
|
|
2888
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2888
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2889
2889
|
MediaUrn.fromString('media:txt;textable'),
|
|
2890
2890
|
false
|
|
2891
2891
|
),
|
|
2892
2892
|
new MachineEdge(
|
|
2893
2893
|
[MediaUrn.fromString('media:txt;textable')],
|
|
2894
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
2894
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
2895
2895
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
2896
2896
|
false
|
|
2897
2897
|
),
|
|
@@ -2910,13 +2910,13 @@ function testMachine_lineBasedAndBracketedParseSameGraph() {
|
|
|
2910
2910
|
function testMachine_edgeEquivalenceSameUrns() {
|
|
2911
2911
|
const e1 = new MachineEdge(
|
|
2912
2912
|
[MediaUrn.fromString('media:pdf')],
|
|
2913
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2913
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2914
2914
|
MediaUrn.fromString('media:txt;textable'),
|
|
2915
2915
|
false
|
|
2916
2916
|
);
|
|
2917
2917
|
const e2 = new MachineEdge(
|
|
2918
2918
|
[MediaUrn.fromString('media:pdf')],
|
|
2919
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2919
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2920
2920
|
MediaUrn.fromString('media:txt;textable'),
|
|
2921
2921
|
false
|
|
2922
2922
|
);
|
|
@@ -2926,13 +2926,13 @@ function testMachine_edgeEquivalenceSameUrns() {
|
|
|
2926
2926
|
function testMachine_edgeEquivalenceDifferentCapUrns() {
|
|
2927
2927
|
const e1 = new MachineEdge(
|
|
2928
2928
|
[MediaUrn.fromString('media:pdf')],
|
|
2929
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2929
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2930
2930
|
MediaUrn.fromString('media:txt;textable'),
|
|
2931
2931
|
false
|
|
2932
2932
|
);
|
|
2933
2933
|
const e2 = new MachineEdge(
|
|
2934
2934
|
[MediaUrn.fromString('media:pdf')],
|
|
2935
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2935
|
+
CapUrn.fromString('cap:in="media:pdf";summarize;out="media:txt;textable"'),
|
|
2936
2936
|
MediaUrn.fromString('media:txt;textable'),
|
|
2937
2937
|
false
|
|
2938
2938
|
);
|
|
@@ -2942,13 +2942,13 @@ function testMachine_edgeEquivalenceDifferentCapUrns() {
|
|
|
2942
2942
|
function testMachine_edgeEquivalenceDifferentTargets() {
|
|
2943
2943
|
const e1 = new MachineEdge(
|
|
2944
2944
|
[MediaUrn.fromString('media:pdf')],
|
|
2945
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2945
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2946
2946
|
MediaUrn.fromString('media:txt;textable'),
|
|
2947
2947
|
false
|
|
2948
2948
|
);
|
|
2949
2949
|
const e2 = new MachineEdge(
|
|
2950
2950
|
[MediaUrn.fromString('media:pdf')],
|
|
2951
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2951
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2952
2952
|
MediaUrn.fromString('media:json;record;textable'),
|
|
2953
2953
|
false
|
|
2954
2954
|
);
|
|
@@ -2958,13 +2958,13 @@ function testMachine_edgeEquivalenceDifferentTargets() {
|
|
|
2958
2958
|
function testMachine_edgeEquivalenceDifferentLoopFlag() {
|
|
2959
2959
|
const e1 = new MachineEdge(
|
|
2960
2960
|
[MediaUrn.fromString('media:pdf')],
|
|
2961
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2961
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2962
2962
|
MediaUrn.fromString('media:txt;textable'),
|
|
2963
2963
|
false
|
|
2964
2964
|
);
|
|
2965
2965
|
const e2 = new MachineEdge(
|
|
2966
2966
|
[MediaUrn.fromString('media:pdf')],
|
|
2967
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
2967
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
2968
2968
|
MediaUrn.fromString('media:txt;textable'),
|
|
2969
2969
|
true
|
|
2970
2970
|
);
|
|
@@ -2974,13 +2974,13 @@ function testMachine_edgeEquivalenceDifferentLoopFlag() {
|
|
|
2974
2974
|
function testMachine_edgeEquivalenceSourceOrderIndependent() {
|
|
2975
2975
|
const e1 = new MachineEdge(
|
|
2976
2976
|
[MediaUrn.fromString('media:txt;textable'), MediaUrn.fromString('media:model-spec;textable')],
|
|
2977
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
2977
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
2978
2978
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
2979
2979
|
false
|
|
2980
2980
|
);
|
|
2981
2981
|
const e2 = new MachineEdge(
|
|
2982
2982
|
[MediaUrn.fromString('media:model-spec;textable'), MediaUrn.fromString('media:txt;textable')],
|
|
2983
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
2983
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
2984
2984
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
2985
2985
|
false
|
|
2986
2986
|
);
|
|
@@ -2990,13 +2990,13 @@ function testMachine_edgeEquivalenceSourceOrderIndependent() {
|
|
|
2990
2990
|
function testMachine_edgeEquivalenceDifferentSourceCount() {
|
|
2991
2991
|
const e1 = new MachineEdge(
|
|
2992
2992
|
[MediaUrn.fromString('media:txt;textable')],
|
|
2993
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
2993
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
2994
2994
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
2995
2995
|
false
|
|
2996
2996
|
);
|
|
2997
2997
|
const e2 = new MachineEdge(
|
|
2998
2998
|
[MediaUrn.fromString('media:txt;textable'), MediaUrn.fromString('media:model-spec;textable')],
|
|
2999
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
2999
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
3000
3000
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
3001
3001
|
false
|
|
3002
3002
|
);
|
|
@@ -3008,12 +3008,12 @@ function testMachine_graphEquivalenceSameEdges() {
|
|
|
3008
3008
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3009
3009
|
);
|
|
3010
3010
|
const g1 = new Machine([
|
|
3011
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3012
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3011
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3012
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3013
3013
|
]);
|
|
3014
3014
|
const g2 = new Machine([
|
|
3015
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3016
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3015
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3016
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3017
3017
|
]);
|
|
3018
3018
|
assert(g1.isEquivalent(g2), 'Same edges should be equivalent');
|
|
3019
3019
|
}
|
|
@@ -3023,12 +3023,12 @@ function testMachine_graphEquivalenceReorderedEdges() {
|
|
|
3023
3023
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3024
3024
|
);
|
|
3025
3025
|
const g1 = new Machine([
|
|
3026
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3027
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3026
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3027
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3028
3028
|
]);
|
|
3029
3029
|
const g2 = new Machine([
|
|
3030
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3031
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3030
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3031
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3032
3032
|
]);
|
|
3033
3033
|
assert(g1.isEquivalent(g2), 'Reordered edges should still be equivalent');
|
|
3034
3034
|
}
|
|
@@ -3038,11 +3038,11 @@ function testMachine_graphNotEquivalentDifferentEdgeCount() {
|
|
|
3038
3038
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3039
3039
|
);
|
|
3040
3040
|
const g1 = new Machine([
|
|
3041
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3041
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3042
3042
|
]);
|
|
3043
3043
|
const g2 = new Machine([
|
|
3044
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3045
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3044
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3045
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3046
3046
|
]);
|
|
3047
3047
|
assert(!g1.isEquivalent(g2), 'Different edge counts should not be equivalent');
|
|
3048
3048
|
}
|
|
@@ -3052,10 +3052,10 @@ function testMachine_graphNotEquivalentDifferentCap() {
|
|
|
3052
3052
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3053
3053
|
);
|
|
3054
3054
|
const g1 = new Machine([
|
|
3055
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3055
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3056
3056
|
]);
|
|
3057
3057
|
const g2 = new Machine([
|
|
3058
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3058
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";summarize;out="media:txt;textable"', 'media:txt;textable'),
|
|
3059
3059
|
]);
|
|
3060
3060
|
assert(!g1.isEquivalent(g2), 'Different caps should not be equivalent');
|
|
3061
3061
|
}
|
|
@@ -3077,8 +3077,8 @@ function testMachine_rootSourcesLinearChain() {
|
|
|
3077
3077
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3078
3078
|
);
|
|
3079
3079
|
const g = new Machine([
|
|
3080
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3081
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3080
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3081
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3082
3082
|
]);
|
|
3083
3083
|
const roots = g.rootSources();
|
|
3084
3084
|
assertEqual(roots.length, 1);
|
|
@@ -3091,8 +3091,8 @@ function testMachine_leafTargetsLinearChain() {
|
|
|
3091
3091
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3092
3092
|
);
|
|
3093
3093
|
const g = new Machine([
|
|
3094
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3095
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3094
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3095
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3096
3096
|
]);
|
|
3097
3097
|
const leaves = g.leafTargets();
|
|
3098
3098
|
assertEqual(leaves.length, 1);
|
|
@@ -3103,7 +3103,7 @@ function testMachine_leafTargetsLinearChain() {
|
|
|
3103
3103
|
function testMachine_rootSourcesFanIn() {
|
|
3104
3104
|
const e = new MachineEdge(
|
|
3105
3105
|
[MediaUrn.fromString('media:txt;textable'), MediaUrn.fromString('media:model-spec;textable')],
|
|
3106
|
-
CapUrn.fromString('cap:in="media:txt;textable";
|
|
3106
|
+
CapUrn.fromString('cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"'),
|
|
3107
3107
|
MediaUrn.fromString('media:embedding-vector;record;textable'),
|
|
3108
3108
|
false
|
|
3109
3109
|
);
|
|
@@ -3115,7 +3115,7 @@ function testMachine_rootSourcesFanIn() {
|
|
|
3115
3115
|
function testMachine_displayEdge() {
|
|
3116
3116
|
const e = new MachineEdge(
|
|
3117
3117
|
[MediaUrn.fromString('media:pdf')],
|
|
3118
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3118
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3119
3119
|
MediaUrn.fromString('media:txt;textable'),
|
|
3120
3120
|
false
|
|
3121
3121
|
);
|
|
@@ -3126,7 +3126,7 @@ function testMachine_displayEdge() {
|
|
|
3126
3126
|
function testMachine_displayGraph() {
|
|
3127
3127
|
const e = new MachineEdge(
|
|
3128
3128
|
[MediaUrn.fromString('media:pdf')],
|
|
3129
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3129
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3130
3130
|
MediaUrn.fromString('media:txt;textable'),
|
|
3131
3131
|
false
|
|
3132
3132
|
);
|
|
@@ -3139,7 +3139,7 @@ function testMachine_displayGraph() {
|
|
|
3139
3139
|
function testMachine_serializeSingleEdge() {
|
|
3140
3140
|
const g = new Machine([new MachineEdge(
|
|
3141
3141
|
[MediaUrn.fromString('media:pdf')],
|
|
3142
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3142
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3143
3143
|
MediaUrn.fromString('media:txt;textable'),
|
|
3144
3144
|
false
|
|
3145
3145
|
)]);
|
|
@@ -3155,8 +3155,8 @@ function testMachine_serializeTwoEdgeChain() {
|
|
|
3155
3155
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3156
3156
|
);
|
|
3157
3157
|
const g = new Machine([
|
|
3158
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3159
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3158
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3159
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3160
3160
|
]);
|
|
3161
3161
|
const notation = g.toMachineNotation();
|
|
3162
3162
|
const bracketCount = (notation.match(/\[/g) || []).length;
|
|
@@ -3170,7 +3170,7 @@ function testMachine_serializeEmptyGraph() {
|
|
|
3170
3170
|
function testMachine_roundtripSingleEdge() {
|
|
3171
3171
|
const original = new Machine([new MachineEdge(
|
|
3172
3172
|
[MediaUrn.fromString('media:pdf')],
|
|
3173
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3173
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3174
3174
|
MediaUrn.fromString('media:txt;textable'),
|
|
3175
3175
|
false
|
|
3176
3176
|
)]);
|
|
@@ -3185,8 +3185,8 @@ function testMachine_roundtripTwoEdgeChain() {
|
|
|
3185
3185
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3186
3186
|
);
|
|
3187
3187
|
const original = new Machine([
|
|
3188
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3189
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3188
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3189
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3190
3190
|
]);
|
|
3191
3191
|
const notation = original.toMachineNotation();
|
|
3192
3192
|
const reparsed = Machine.fromString(notation);
|
|
@@ -3199,9 +3199,9 @@ function testMachine_roundtripFanOut() {
|
|
|
3199
3199
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3200
3200
|
);
|
|
3201
3201
|
const original = new Machine([
|
|
3202
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3203
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3204
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3202
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract-metadata;out="media:file-metadata;record;textable"', 'media:file-metadata;record;textable'),
|
|
3203
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract-outline;out="media:document-outline;record;textable"', 'media:document-outline;record;textable'),
|
|
3204
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"', 'media:image;png;thumbnail'),
|
|
3205
3205
|
]);
|
|
3206
3206
|
const notation = original.toMachineNotation();
|
|
3207
3207
|
const reparsed = Machine.fromString(notation);
|
|
@@ -3212,7 +3212,7 @@ function testMachine_roundtripFanOut() {
|
|
|
3212
3212
|
function testMachine_roundtripLoopEdge() {
|
|
3213
3213
|
const original = new Machine([new MachineEdge(
|
|
3214
3214
|
[MediaUrn.fromString('media:disbound-page;textable')],
|
|
3215
|
-
CapUrn.fromString('cap:in="media:disbound-page;textable";
|
|
3215
|
+
CapUrn.fromString('cap:in="media:disbound-page;textable";page-to-text;out="media:txt;textable"'),
|
|
3216
3216
|
MediaUrn.fromString('media:txt;textable'),
|
|
3217
3217
|
true
|
|
3218
3218
|
)]);
|
|
@@ -3227,8 +3227,8 @@ function testMachine_serializationIsDeterministic() {
|
|
|
3227
3227
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3228
3228
|
);
|
|
3229
3229
|
const g = new Machine([
|
|
3230
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3231
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3230
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3231
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3232
3232
|
]);
|
|
3233
3233
|
const n1 = g.toMachineNotation();
|
|
3234
3234
|
const n2 = g.toMachineNotation();
|
|
@@ -3240,12 +3240,12 @@ function testMachine_reorderedEdgesProduceSameNotation() {
|
|
|
3240
3240
|
[MediaUrn.fromString(src)], CapUrn.fromString(cap), MediaUrn.fromString(tgt), false
|
|
3241
3241
|
);
|
|
3242
3242
|
const g1 = new Machine([
|
|
3243
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3244
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3243
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3244
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3245
3245
|
]);
|
|
3246
3246
|
const g2 = new Machine([
|
|
3247
|
-
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";
|
|
3248
|
-
mkEdge('media:pdf', 'cap:in="media:pdf";
|
|
3247
|
+
mkEdge('media:txt;textable', 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable'),
|
|
3248
|
+
mkEdge('media:pdf', 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable'),
|
|
3249
3249
|
]);
|
|
3250
3250
|
assertEqual(g1.toMachineNotation(), g2.toMachineNotation(),
|
|
3251
3251
|
'Same graph with reordered edges must produce identical notation');
|
|
@@ -3254,7 +3254,7 @@ function testMachine_reorderedEdgesProduceSameNotation() {
|
|
|
3254
3254
|
function testMachine_multilineSerializeFormat() {
|
|
3255
3255
|
const g = new Machine([new MachineEdge(
|
|
3256
3256
|
[MediaUrn.fromString('media:pdf')],
|
|
3257
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3257
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3258
3258
|
MediaUrn.fromString('media:txt;textable'),
|
|
3259
3259
|
false
|
|
3260
3260
|
)]);
|
|
@@ -3268,7 +3268,7 @@ function testMachine_multilineSerializeFormat() {
|
|
|
3268
3268
|
function testMachine_aliasFromOpTag() {
|
|
3269
3269
|
const g = new Machine([new MachineEdge(
|
|
3270
3270
|
[MediaUrn.fromString('media:pdf')],
|
|
3271
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3271
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3272
3272
|
MediaUrn.fromString('media:txt;textable'),
|
|
3273
3273
|
false
|
|
3274
3274
|
)]);
|
|
@@ -3291,13 +3291,13 @@ function testMachine_duplicateOpTagsDisambiguated() {
|
|
|
3291
3291
|
const g = new Machine([
|
|
3292
3292
|
new MachineEdge(
|
|
3293
3293
|
[MediaUrn.fromString('media:pdf')],
|
|
3294
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3294
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"'),
|
|
3295
3295
|
MediaUrn.fromString('media:txt;textable'),
|
|
3296
3296
|
false
|
|
3297
3297
|
),
|
|
3298
3298
|
new MachineEdge(
|
|
3299
3299
|
[MediaUrn.fromString('media:pdf')],
|
|
3300
|
-
CapUrn.fromString('cap:in="media:pdf";
|
|
3300
|
+
CapUrn.fromString('cap:in="media:pdf";extract;out="media:json;record;textable"'),
|
|
3301
3301
|
MediaUrn.fromString('media:json;record;textable'),
|
|
3302
3302
|
false
|
|
3303
3303
|
),
|
|
@@ -3313,7 +3313,7 @@ function testMachine_builderSingleEdge() {
|
|
|
3313
3313
|
const builder = new MachineBuilder();
|
|
3314
3314
|
builder.addEdge(
|
|
3315
3315
|
['media:pdf'],
|
|
3316
|
-
'cap:in="media:pdf";
|
|
3316
|
+
'cap:in="media:pdf";extract;out="media:txt;textable"',
|
|
3317
3317
|
'media:txt;textable'
|
|
3318
3318
|
);
|
|
3319
3319
|
const g = builder.build();
|
|
@@ -3325,7 +3325,7 @@ function testMachine_builderWithLoop() {
|
|
|
3325
3325
|
const builder = new MachineBuilder();
|
|
3326
3326
|
builder.addEdge(
|
|
3327
3327
|
['media:disbound-page;textable'],
|
|
3328
|
-
'cap:in="media:disbound-page;textable";
|
|
3328
|
+
'cap:in="media:disbound-page;textable";page-to-text;out="media:txt;textable"',
|
|
3329
3329
|
'media:txt;textable',
|
|
3330
3330
|
true
|
|
3331
3331
|
);
|
|
@@ -3335,19 +3335,19 @@ function testMachine_builderWithLoop() {
|
|
|
3335
3335
|
|
|
3336
3336
|
function testMachine_builderChaining() {
|
|
3337
3337
|
const g = new MachineBuilder()
|
|
3338
|
-
.addEdge(['media:pdf'], 'cap:in="media:pdf";
|
|
3339
|
-
.addEdge(['media:txt;textable'], 'cap:in="media:txt;textable";
|
|
3338
|
+
.addEdge(['media:pdf'], 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable')
|
|
3339
|
+
.addEdge(['media:txt;textable'], 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable')
|
|
3340
3340
|
.build();
|
|
3341
3341
|
assertEqual(g.edgeCount(), 2);
|
|
3342
3342
|
}
|
|
3343
3343
|
|
|
3344
3344
|
function testMachine_builderEquivalentToParsed() {
|
|
3345
3345
|
const parsed = Machine.fromString(
|
|
3346
|
-
'[extract cap:in="media:pdf";
|
|
3346
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
3347
3347
|
'[doc -> extract -> text]'
|
|
3348
3348
|
);
|
|
3349
3349
|
const built = new MachineBuilder()
|
|
3350
|
-
.addEdge(['media:pdf'], 'cap:in="media:pdf";
|
|
3350
|
+
.addEdge(['media:pdf'], 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable')
|
|
3351
3351
|
.build();
|
|
3352
3352
|
assert(parsed.isEquivalent(built),
|
|
3353
3353
|
'Builder-constructed graph should be equivalent to parsed graph');
|
|
@@ -3355,8 +3355,8 @@ function testMachine_builderEquivalentToParsed() {
|
|
|
3355
3355
|
|
|
3356
3356
|
function testMachine_builderRoundTrip() {
|
|
3357
3357
|
const built = new MachineBuilder()
|
|
3358
|
-
.addEdge(['media:pdf'], 'cap:in="media:pdf";
|
|
3359
|
-
.addEdge(['media:txt;textable'], 'cap:in="media:txt;textable";
|
|
3358
|
+
.addEdge(['media:pdf'], 'cap:in="media:pdf";extract;out="media:txt;textable"', 'media:txt;textable')
|
|
3359
|
+
.addEdge(['media:txt;textable'], 'cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"', 'media:embedding-vector;record;textable')
|
|
3360
3360
|
.build();
|
|
3361
3361
|
const notation = built.toMachineNotation();
|
|
3362
3362
|
const reparsed = Machine.fromString(notation);
|
|
@@ -3366,29 +3366,29 @@ function testMachine_builderRoundTrip() {
|
|
|
3366
3366
|
// --- CapUrn.isEquivalent/isComparable tests ---
|
|
3367
3367
|
|
|
3368
3368
|
function testMachine_capUrnIsEquivalent() {
|
|
3369
|
-
const a = CapUrn.fromString('cap:in="media:pdf";
|
|
3370
|
-
const b = CapUrn.fromString('cap:in="media:pdf";
|
|
3369
|
+
const a = CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"');
|
|
3370
|
+
const b = CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"');
|
|
3371
3371
|
assert(a.isEquivalent(b), 'Same cap URNs should be equivalent');
|
|
3372
|
-
const c = CapUrn.fromString('cap:in="media:pdf";
|
|
3372
|
+
const c = CapUrn.fromString('cap:in="media:pdf";summarize;out="media:txt;textable"');
|
|
3373
3373
|
assert(!a.isEquivalent(c), 'Different cap URNs should not be equivalent');
|
|
3374
3374
|
}
|
|
3375
3375
|
|
|
3376
3376
|
function testMachine_capUrnIsComparable() {
|
|
3377
3377
|
const general = CapUrn.fromString('cap:in="media:pdf";out="media:txt;textable"');
|
|
3378
|
-
const specific = CapUrn.fromString('cap:in="media:pdf";
|
|
3378
|
+
const specific = CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"');
|
|
3379
3379
|
assert(general.isComparable(specific), 'General should be comparable to specific');
|
|
3380
3380
|
assert(specific.isComparable(general), 'isComparable should be symmetric');
|
|
3381
3381
|
}
|
|
3382
3382
|
|
|
3383
3383
|
function testMachine_capUrnInMediaUrn() {
|
|
3384
|
-
const cap = CapUrn.fromString('cap:in="media:pdf";
|
|
3384
|
+
const cap = CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"');
|
|
3385
3385
|
const inUrn = cap.inMediaUrn();
|
|
3386
3386
|
assert(inUrn instanceof MediaUrn, 'inMediaUrn should return MediaUrn');
|
|
3387
3387
|
assert(inUrn.isEquivalent(MediaUrn.fromString('media:pdf')), 'inMediaUrn should be media:pdf');
|
|
3388
3388
|
}
|
|
3389
3389
|
|
|
3390
3390
|
function testMachine_capUrnOutMediaUrn() {
|
|
3391
|
-
const cap = CapUrn.fromString('cap:in="media:pdf";
|
|
3391
|
+
const cap = CapUrn.fromString('cap:in="media:pdf";extract;out="media:txt;textable"');
|
|
3392
3392
|
const outUrn = cap.outMediaUrn();
|
|
3393
3393
|
assert(outUrn instanceof MediaUrn, 'outMediaUrn should return MediaUrn');
|
|
3394
3394
|
assert(outUrn.isEquivalent(MediaUrn.fromString('media:txt;textable')), 'outMediaUrn should be media:txt;textable');
|
|
@@ -3418,7 +3418,7 @@ function testMachine_mediaUrnIsComparable() {
|
|
|
3418
3418
|
// ============================================================================
|
|
3419
3419
|
|
|
3420
3420
|
function testMachine_parseMachineWithAST_headerLocation() {
|
|
3421
|
-
const input = '[extract cap:in="media:pdf";
|
|
3421
|
+
const input = '[extract cap:in="media:pdf";extract;out="media:txt;textable"][doc -> extract -> text]';
|
|
3422
3422
|
const result = parseMachineWithAST(input);
|
|
3423
3423
|
assert(result.statements.length === 2, 'Should have 2 statements');
|
|
3424
3424
|
const stmt = result.statements[0];
|
|
@@ -3434,7 +3434,7 @@ function testMachine_parseMachineWithAST_headerLocation() {
|
|
|
3434
3434
|
}
|
|
3435
3435
|
|
|
3436
3436
|
function testMachine_parseMachineWithAST_wiringLocation() {
|
|
3437
|
-
const input = '[extract cap:in="media:pdf";
|
|
3437
|
+
const input = '[extract cap:in="media:pdf";extract;out="media:txt;textable"]\n[doc -> extract -> text]';
|
|
3438
3438
|
const result = parseMachineWithAST(input);
|
|
3439
3439
|
assert(result.statements.length === 2, 'Should have 2 statements');
|
|
3440
3440
|
const wiring = result.statements[1];
|
|
@@ -3448,7 +3448,7 @@ function testMachine_parseMachineWithAST_wiringLocation() {
|
|
|
3448
3448
|
}
|
|
3449
3449
|
|
|
3450
3450
|
function testMachine_parseMachineWithAST_multilinePositions() {
|
|
3451
|
-
const input = '[extract cap:in="media:pdf";
|
|
3451
|
+
const input = '[extract cap:in="media:pdf";extract;out="media:txt;textable"]\n[doc -> extract -> text]';
|
|
3452
3452
|
const result = parseMachineWithAST(input);
|
|
3453
3453
|
const headerLoc = result.statements[0].location;
|
|
3454
3454
|
const wiringLoc = result.statements[1].location;
|
|
@@ -3458,7 +3458,7 @@ function testMachine_parseMachineWithAST_multilinePositions() {
|
|
|
3458
3458
|
|
|
3459
3459
|
function testMachine_parseMachineWithAST_fanInSourceLocations() {
|
|
3460
3460
|
const input = [
|
|
3461
|
-
'[describe cap:in="media:image;png";
|
|
3461
|
+
'[describe cap:in="media:image;png";describe-image;out="media:image-description;textable"]',
|
|
3462
3462
|
'[(thumbnail, model_spec) -> describe -> description]'
|
|
3463
3463
|
].join('\n');
|
|
3464
3464
|
const result = parseMachineWithAST(input);
|
|
@@ -3469,8 +3469,8 @@ function testMachine_parseMachineWithAST_fanInSourceLocations() {
|
|
|
3469
3469
|
|
|
3470
3470
|
function testMachine_parseMachineWithAST_aliasMap() {
|
|
3471
3471
|
const input = [
|
|
3472
|
-
'[extract cap:in="media:pdf";
|
|
3473
|
-
'[embed cap:in="media:txt;textable";
|
|
3472
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]',
|
|
3473
|
+
'[embed cap:in="media:txt;textable";embed;out="media:embedding-vector;record;textable"]',
|
|
3474
3474
|
'[doc -> extract -> text]',
|
|
3475
3475
|
'[text -> embed -> vectors]',
|
|
3476
3476
|
].join('\n');
|
|
@@ -3487,7 +3487,7 @@ function testMachine_parseMachineWithAST_aliasMap() {
|
|
|
3487
3487
|
|
|
3488
3488
|
function testMachine_parseMachineWithAST_nodeMedia() {
|
|
3489
3489
|
const input = [
|
|
3490
|
-
'[extract cap:in="media:pdf";
|
|
3490
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]',
|
|
3491
3491
|
'[doc -> extract -> text]',
|
|
3492
3492
|
].join('\n');
|
|
3493
3493
|
const result = parseMachineWithAST(input);
|
|
@@ -3510,8 +3510,8 @@ function testMachine_errorLocation_parseError() {
|
|
|
3510
3510
|
function testMachine_errorLocation_duplicateAlias() {
|
|
3511
3511
|
try {
|
|
3512
3512
|
parseMachine(
|
|
3513
|
-
'[extract cap:in="media:pdf";
|
|
3514
|
-
'[extract cap:in="media:pdf";
|
|
3513
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
3514
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
3515
3515
|
'[doc -> extract -> text]'
|
|
3516
3516
|
);
|
|
3517
3517
|
throw new Error('Expected MachineSyntaxError');
|
|
@@ -3537,7 +3537,7 @@ function testMachine_errorLocation_undefinedAlias() {
|
|
|
3537
3537
|
|
|
3538
3538
|
function testMachine_toMermaid_linearChain() {
|
|
3539
3539
|
const machine = Machine.fromString(
|
|
3540
|
-
'[extract cap:in="media:pdf";
|
|
3540
|
+
'[extract cap:in="media:pdf";extract;out="media:txt;textable"]' +
|
|
3541
3541
|
'[doc -> extract -> text]'
|
|
3542
3542
|
);
|
|
3543
3543
|
const mermaid = machine.toMermaid();
|
|
@@ -3552,7 +3552,7 @@ function testMachine_toMermaid_linearChain() {
|
|
|
3552
3552
|
|
|
3553
3553
|
function testMachine_toMermaid_loopEdge() {
|
|
3554
3554
|
const machine = Machine.fromString(
|
|
3555
|
-
'[p2t cap:in="media:disbound-page;textable";
|
|
3555
|
+
'[p2t cap:in="media:disbound-page;textable";page-to-text;out="media:txt;textable"]' +
|
|
3556
3556
|
'[pages -> LOOP p2t -> texts]'
|
|
3557
3557
|
);
|
|
3558
3558
|
const mermaid = machine.toMermaid();
|
|
@@ -3569,7 +3569,7 @@ function testMachine_toMermaid_emptyGraph() {
|
|
|
3569
3569
|
|
|
3570
3570
|
function testMachine_toMermaid_fanIn() {
|
|
3571
3571
|
const machine = Machine.fromString(
|
|
3572
|
-
'[describe cap:in="media:image;png";
|
|
3572
|
+
'[describe cap:in="media:image;png";describe-image;out="media:image-description;textable"]' +
|
|
3573
3573
|
'[(thumbnail, model_spec) -> describe -> description]'
|
|
3574
3574
|
);
|
|
3575
3575
|
const mermaid = machine.toMermaid();
|
|
@@ -3580,8 +3580,8 @@ function testMachine_toMermaid_fanIn() {
|
|
|
3580
3580
|
|
|
3581
3581
|
function testMachine_toMermaid_fanOut() {
|
|
3582
3582
|
const input = [
|
|
3583
|
-
'[meta cap:in="media:pdf";
|
|
3584
|
-
'[thumb cap:in="media:pdf";
|
|
3583
|
+
'[meta cap:in="media:pdf";extract-metadata;out="media:file-metadata;record;textable"]',
|
|
3584
|
+
'[thumb cap:in="media:pdf";generate-thumbnail;out="media:image;png;thumbnail"]',
|
|
3585
3585
|
'[doc -> meta -> metadata]',
|
|
3586
3586
|
'[doc -> thumb -> thumbnail]'
|
|
3587
3587
|
].join('');
|
|
@@ -3600,7 +3600,7 @@ function testMachine_toMermaid_fanOut() {
|
|
|
3600
3600
|
|
|
3601
3601
|
function testMachine_capRegistryEntry_construction() {
|
|
3602
3602
|
const entry = new CapRegistryEntry({
|
|
3603
|
-
urn: 'cap:in="media:pdf";
|
|
3603
|
+
urn: 'cap:in="media:pdf";extract;out="media:txt;textable"',
|
|
3604
3604
|
title: 'PDF Extractor',
|
|
3605
3605
|
command: 'extract',
|
|
3606
3606
|
cap_description: 'Extracts text from PDF',
|
|
@@ -3613,7 +3613,7 @@ function testMachine_capRegistryEntry_construction() {
|
|
|
3613
3613
|
in_media_title: 'PDF Document',
|
|
3614
3614
|
out_media_title: 'Text'
|
|
3615
3615
|
});
|
|
3616
|
-
assertEqual(entry.urn, 'cap:in="media:pdf";
|
|
3616
|
+
assertEqual(entry.urn, 'cap:in="media:pdf";extract;out="media:txt;textable"', 'URN should match');
|
|
3617
3617
|
assertEqual(entry.title, 'PDF Extractor', 'Title should match');
|
|
3618
3618
|
assertEqual(entry.description, 'Extracts text from PDF', 'Description should match');
|
|
3619
3619
|
assertEqual(entry.inSpec, 'media:pdf', 'inSpec should match');
|
|
@@ -3643,8 +3643,8 @@ function testMachine_capRegistryClient_construction() {
|
|
|
3643
3643
|
|
|
3644
3644
|
function testMachine_capRegistryEntry_defaults() {
|
|
3645
3645
|
// Verify that missing fields default gracefully
|
|
3646
|
-
const entry = new CapRegistryEntry({ urn: 'cap:in=media:;
|
|
3647
|
-
assertEqual(entry.urn, 'cap:in=media:;
|
|
3646
|
+
const entry = new CapRegistryEntry({ urn: 'cap:in=media:;test;out=media:' });
|
|
3647
|
+
assertEqual(entry.urn, 'cap:in=media:;test;out=media:', 'URN should match');
|
|
3648
3648
|
assertEqual(entry.title, '', 'Title should default to empty');
|
|
3649
3649
|
assertEqual(entry.description, '', 'Description should default to empty');
|
|
3650
3650
|
assertEqual(entry.command, '', 'Command should default to empty');
|
|
@@ -3726,7 +3726,7 @@ function testRenderer_cardinalityFromCap_findsStdinArgNotFirstArg() {
|
|
|
3726
3726
|
// A naive implementation that reads args[0] would see `cli-only` (not a
|
|
3727
3727
|
// sequence) and report 1→1 even though the stdin arg is a sequence.
|
|
3728
3728
|
const cap = {
|
|
3729
|
-
urn: 'cap:in="media:textable;list";
|
|
3729
|
+
urn: 'cap:in="media:textable;list";transcribe;out="media:textable"',
|
|
3730
3730
|
args: [
|
|
3731
3731
|
{
|
|
3732
3732
|
display_name: 'cli-only',
|
|
@@ -3748,7 +3748,7 @@ function testRenderer_cardinalityFromCap_findsStdinArgNotFirstArg() {
|
|
|
3748
3748
|
function testRenderer_cardinalityFromCap_scalarDefaultsWhenFieldsMissing() {
|
|
3749
3749
|
// No args and no output: both sides collapse to 1 (scalar default).
|
|
3750
3750
|
// If a bug makes the function return "n" for missing data, this fails.
|
|
3751
|
-
const cap = { urn: 'cap:in="media:";
|
|
3751
|
+
const cap = { urn: 'cap:in="media:";noop;out="media:"' };
|
|
3752
3752
|
assertEqual(rendererCardinalityFromCap(cap), '1\u21921',
|
|
3753
3753
|
'missing args/output must default to scalar on both sides');
|
|
3754
3754
|
}
|
|
@@ -3756,7 +3756,7 @@ function testRenderer_cardinalityFromCap_scalarDefaultsWhenFieldsMissing() {
|
|
|
3756
3756
|
function testRenderer_cardinalityFromCap_outputOnlySequence() {
|
|
3757
3757
|
// One scalar stdin arg, output is a sequence: expects 1→n.
|
|
3758
3758
|
const cap = {
|
|
3759
|
-
urn: 'cap:in="media:textable";
|
|
3759
|
+
urn: 'cap:in="media:textable";generate;out="media:textable;list"',
|
|
3760
3760
|
args: [{ sources: [{ stdin: {} }], is_sequence: false }],
|
|
3761
3761
|
output: { is_sequence: true },
|
|
3762
3762
|
};
|
|
@@ -3769,7 +3769,7 @@ function testRenderer_cardinalityFromCap_rejectsStringIsSequence() {
|
|
|
3769
3769
|
// as booleans. "true" is a string, not a boolean — it must NOT be treated
|
|
3770
3770
|
// as a sequence, because downstream renderers expect boolean semantics.
|
|
3771
3771
|
const cap = {
|
|
3772
|
-
urn: 'cap:in="media:";
|
|
3772
|
+
urn: 'cap:in="media:";x;out="media:"',
|
|
3773
3773
|
args: [{ sources: [{ stdin: {} }], is_sequence: 'true' }],
|
|
3774
3774
|
output: { is_sequence: 'true' },
|
|
3775
3775
|
};
|
|
@@ -3815,7 +3815,7 @@ function testRenderer_canonicalMediaUrn_rejectsCapUrn() {
|
|
|
3815
3815
|
// canonicalMediaUrn must fail hard.
|
|
3816
3816
|
let threw = false;
|
|
3817
3817
|
try {
|
|
3818
|
-
rendererCanonicalMediaUrn('cap:
|
|
3818
|
+
rendererCanonicalMediaUrn('cap:x;in="media:";out="media:"');
|
|
3819
3819
|
} catch (e) {
|
|
3820
3820
|
threw = true;
|
|
3821
3821
|
}
|
|
@@ -3842,7 +3842,7 @@ function testRenderer_buildBrowseGraphData_rejectsMissingMediaTitles() {
|
|
|
3842
3842
|
try {
|
|
3843
3843
|
rendererBuildBrowseGraphData([
|
|
3844
3844
|
{
|
|
3845
|
-
urn: 'cap:in="media:pdf";
|
|
3845
|
+
urn: 'cap:in="media:pdf";extract;out="media:txt;textable"',
|
|
3846
3846
|
title: 'Extract Text',
|
|
3847
3847
|
in_spec: 'media:pdf',
|
|
3848
3848
|
out_spec: 'media:txt;textable',
|
|
@@ -3917,7 +3917,7 @@ function testRenderer_validateStrandStep_requiresBooleanIsSequence() {
|
|
|
3917
3917
|
try {
|
|
3918
3918
|
rendererValidateStrandStep({
|
|
3919
3919
|
step_type: { Cap: {
|
|
3920
|
-
cap_urn: 'cap:in="media:a";
|
|
3920
|
+
cap_urn: 'cap:in="media:a";x;out="media:b"',
|
|
3921
3921
|
title: 't',
|
|
3922
3922
|
input_is_sequence: 1, // number, not boolean
|
|
3923
3923
|
output_is_sequence: false,
|
|
@@ -3938,9 +3938,9 @@ function testRenderer_classifyStrandCapSteps_capFlags() {
|
|
|
3938
3938
|
// have neither.
|
|
3939
3939
|
const steps = [
|
|
3940
3940
|
makeForEachStep('media:pdf;list'),
|
|
3941
|
-
makeCapStep('cap:in="media:pdf";
|
|
3942
|
-
makeCapStep('cap:in="media:png";
|
|
3943
|
-
makeCapStep('cap:in="media:jpg";
|
|
3941
|
+
makeCapStep('cap:in="media:pdf";a;out="media:image;png"', 'a', 'media:pdf', 'media:image;png', false, false),
|
|
3942
|
+
makeCapStep('cap:in="media:image;png";b;out="media:jpg"', 'b', 'media:image;png', 'media:jpg', false, false),
|
|
3943
|
+
makeCapStep('cap:in="media:jpg";c;out="media:txt"', 'c', 'media:jpg', 'media:txt', false, false),
|
|
3944
3944
|
makeCollectStep('media:txt'),
|
|
3945
3945
|
];
|
|
3946
3946
|
const { capStepIndices, capFlags } = rendererClassifyStrandCapSteps(steps);
|
|
@@ -3959,11 +3959,11 @@ function testRenderer_classifyStrandCapSteps_nestedForks() {
|
|
|
3959
3959
|
// nextCollect (inner), cap3 has nextCollect (outer).
|
|
3960
3960
|
const steps = [
|
|
3961
3961
|
makeForEachStep('media:a;list'),
|
|
3962
|
-
makeCapStep('cap:in="media:a";
|
|
3962
|
+
makeCapStep('cap:in="media:a";a;out="media:b"', 'a', 'media:a', 'media:b', false, false),
|
|
3963
3963
|
makeForEachStep('media:b;list'),
|
|
3964
|
-
makeCapStep('cap:in="media:b";
|
|
3964
|
+
makeCapStep('cap:in="media:b";b;out="media:c"', 'b', 'media:b', 'media:c', false, false),
|
|
3965
3965
|
makeCollectStep('media:c'),
|
|
3966
|
-
makeCapStep('cap:in="media:c";
|
|
3966
|
+
makeCapStep('cap:in="media:c";c;out="media:d"', 'c', 'media:c', 'media:d', false, false),
|
|
3967
3967
|
makeCollectStep('media:d'),
|
|
3968
3968
|
];
|
|
3969
3969
|
const { capFlags } = rendererClassifyStrandCapSteps(steps);
|
|
@@ -3992,7 +3992,7 @@ function testRenderer_buildStrandGraphData_singleCapPlain() {
|
|
|
3992
3992
|
source_spec: 'media:a',
|
|
3993
3993
|
target_spec: 'media:b',
|
|
3994
3994
|
steps: [
|
|
3995
|
-
makeCapStep('cap:in="media:a";
|
|
3995
|
+
makeCapStep('cap:in="media:a";x;out="media:b"', 'x', 'media:a', 'media:b', false, false),
|
|
3996
3996
|
],
|
|
3997
3997
|
}, {
|
|
3998
3998
|
'media:a': 'Source A',
|
|
@@ -4017,7 +4017,7 @@ function testRenderer_buildStrandGraphData_sequenceShowsCardinality() {
|
|
|
4017
4017
|
source_spec: 'media:a;list',
|
|
4018
4018
|
target_spec: 'media:b',
|
|
4019
4019
|
steps: [
|
|
4020
|
-
makeCapStep('cap:in="media:a;list";
|
|
4020
|
+
makeCapStep('cap:in="media:a;list";x;out="media:b"', 'x', 'media:a;list', 'media:b', true, false),
|
|
4021
4021
|
],
|
|
4022
4022
|
}, {
|
|
4023
4023
|
'media:a;list': 'Source A List',
|
|
@@ -4048,7 +4048,7 @@ function testRenderer_buildStrandGraphData_foreachCollectSpan() {
|
|
|
4048
4048
|
target_spec: 'media:txt;list',
|
|
4049
4049
|
steps: [
|
|
4050
4050
|
makeForEachStep('media:pdf;list'),
|
|
4051
|
-
makeCapStep('cap:in="media:pdf";
|
|
4051
|
+
makeCapStep('cap:in="media:pdf";extract;out="media:txt"', 'extract', 'media:pdf', 'media:txt', false, false),
|
|
4052
4052
|
makeCollectStep('media:txt'),
|
|
4053
4053
|
],
|
|
4054
4054
|
}, {
|
|
@@ -4089,7 +4089,7 @@ function testRenderer_buildStrandGraphData_standaloneCollect() {
|
|
|
4089
4089
|
source_spec: 'media:a',
|
|
4090
4090
|
target_spec: 'media:b;list',
|
|
4091
4091
|
steps: [
|
|
4092
|
-
makeCapStep('cap:in="media:a";
|
|
4092
|
+
makeCapStep('cap:in="media:a";x;out="media:b"', 'x', 'media:a', 'media:b', false, false),
|
|
4093
4093
|
makeCollectStep('media:b'),
|
|
4094
4094
|
],
|
|
4095
4095
|
}, {
|
|
@@ -4117,9 +4117,9 @@ function testRenderer_buildStrandGraphData_unclosedForEachBody() {
|
|
|
4117
4117
|
source_spec: 'media:a',
|
|
4118
4118
|
target_spec: 'media:c',
|
|
4119
4119
|
steps: [
|
|
4120
|
-
makeCapStep('cap:in="media:a";
|
|
4120
|
+
makeCapStep('cap:in="media:a";a;out="media:b"', 'a', 'media:a', 'media:b', false, false),
|
|
4121
4121
|
makeForEachStep('media:b'),
|
|
4122
|
-
makeCapStep('cap:in="media:b";
|
|
4122
|
+
makeCapStep('cap:in="media:b";b;out="media:c"', 'b', 'media:b', 'media:c', false, false),
|
|
4123
4123
|
],
|
|
4124
4124
|
}, {
|
|
4125
4125
|
'media:a': 'Source A',
|
|
@@ -4156,7 +4156,7 @@ function testRenderer_buildStrandGraphData_nestedForEachThrows() {
|
|
|
4156
4156
|
steps: [
|
|
4157
4157
|
makeForEachStep('media:a;list'),
|
|
4158
4158
|
makeForEachStep('media:a'),
|
|
4159
|
-
makeCapStep('cap:in="media:a";
|
|
4159
|
+
makeCapStep('cap:in="media:a";x;out="media:a"', 'x', 'media:a', 'media:a', false, false),
|
|
4160
4160
|
],
|
|
4161
4161
|
}, {
|
|
4162
4162
|
'media:a;list': 'Source A List',
|
|
@@ -4192,7 +4192,7 @@ function testRenderer_collapseStrand_singleCapBodyKeepsCapOwnLabel() {
|
|
|
4192
4192
|
target_spec: 'media:txt;list',
|
|
4193
4193
|
steps: [
|
|
4194
4194
|
makeForEachStep('media:pdf;list'),
|
|
4195
|
-
makeCapStep('cap:in="media:pdf";
|
|
4195
|
+
makeCapStep('cap:in="media:pdf";extract;out="media:txt"', 'extract', 'media:pdf', 'media:txt', false, false),
|
|
4196
4196
|
makeCollectStep('media:txt'),
|
|
4197
4197
|
],
|
|
4198
4198
|
}, {
|
|
@@ -4240,9 +4240,9 @@ function testRenderer_collapseStrand_unclosedForEachBodyCollapses() {
|
|
|
4240
4240
|
source_spec: 'media:a',
|
|
4241
4241
|
target_spec: 'media:c',
|
|
4242
4242
|
steps: [
|
|
4243
|
-
makeCapStep('cap:in="media:a";
|
|
4243
|
+
makeCapStep('cap:in="media:a";a;out="media:b"', 'a', 'media:a', 'media:b', false, false),
|
|
4244
4244
|
makeForEachStep('media:b'),
|
|
4245
|
-
makeCapStep('cap:in="media:b";
|
|
4245
|
+
makeCapStep('cap:in="media:b";b;out="media:c"', 'b', 'media:b', 'media:c', false, false),
|
|
4246
4246
|
],
|
|
4247
4247
|
}, {
|
|
4248
4248
|
'media:a': 'Source A',
|
|
@@ -4297,7 +4297,7 @@ function testRenderer_collapseStrand_standaloneCollectCollapses() {
|
|
|
4297
4297
|
source_spec: 'media:a',
|
|
4298
4298
|
target_spec: 'media:b;list',
|
|
4299
4299
|
steps: [
|
|
4300
|
-
makeCapStep('cap:in="media:a";
|
|
4300
|
+
makeCapStep('cap:in="media:a";x;out="media:b"', 'x', 'media:a', 'media:b', false, false),
|
|
4301
4301
|
makeCollectStep('media:b'),
|
|
4302
4302
|
],
|
|
4303
4303
|
}, {
|
|
@@ -4345,9 +4345,9 @@ function testRenderer_collapseStrand_sequenceProducingCapBeforeForeach() {
|
|
|
4345
4345
|
source_spec: 'media:pdf',
|
|
4346
4346
|
target_spec: 'media:decision',
|
|
4347
4347
|
steps: [
|
|
4348
|
-
makeCapStep('cap:in="media:pdf";
|
|
4348
|
+
makeCapStep('cap:in="media:pdf";disbind;out="media:page"', 'Disbind', 'media:pdf', 'media:page', false, true),
|
|
4349
4349
|
makeForEachStep('media:page'),
|
|
4350
|
-
makeCapStep('cap:in="media:page";
|
|
4350
|
+
makeCapStep('cap:in="media:page";decide;out="media:decision"', 'Make a Decision', 'media:page', 'media:decision', false, false),
|
|
4351
4351
|
],
|
|
4352
4352
|
}, {
|
|
4353
4353
|
'media:pdf': 'PDF',
|
|
@@ -4400,7 +4400,7 @@ function testRenderer_collapseStrand_plainCapMergesTrailingOutput() {
|
|
|
4400
4400
|
source_spec: 'media:a',
|
|
4401
4401
|
target_spec: 'media:b',
|
|
4402
4402
|
steps: [
|
|
4403
|
-
makeCapStep('cap:in="media:a";
|
|
4403
|
+
makeCapStep('cap:in="media:a";x;out="media:b"', 'x', 'media:a', 'media:b', false, false),
|
|
4404
4404
|
],
|
|
4405
4405
|
}, {
|
|
4406
4406
|
'media:a': 'Source A',
|
|
@@ -4432,7 +4432,7 @@ function testRenderer_collapseStrand_plainCapDistinctTargetNoMerge() {
|
|
|
4432
4432
|
source_spec: 'media:a',
|
|
4433
4433
|
target_spec: 'media:b;list',
|
|
4434
4434
|
steps: [
|
|
4435
|
-
makeCapStep('cap:in="media:a";
|
|
4435
|
+
makeCapStep('cap:in="media:a";x;out="media:b"', 'x', 'media:a', 'media:b', false, false),
|
|
4436
4436
|
],
|
|
4437
4437
|
}, {
|
|
4438
4438
|
'media:a': 'Source A',
|
|
@@ -4489,8 +4489,8 @@ function testRenderer_buildRunGraphData_pagesSuccessesAndFailures() {
|
|
|
4489
4489
|
target_spec: 'media:txt',
|
|
4490
4490
|
steps: [
|
|
4491
4491
|
makeForEachStep('media:pdf;list'),
|
|
4492
|
-
makeCapStep('cap:in="media:pdf";
|
|
4493
|
-
makeCapStep('cap:in="media:png";
|
|
4492
|
+
makeCapStep('cap:in="media:pdf";a;out="media:image;png"', 'a', 'media:pdf', 'media:image;png', false, false),
|
|
4493
|
+
makeCapStep('cap:in="media:image;png";b;out="media:txt"', 'b', 'media:image;png', 'media:txt', false, false),
|
|
4494
4494
|
makeCollectStep('media:txt'),
|
|
4495
4495
|
],
|
|
4496
4496
|
};
|
|
@@ -4506,7 +4506,7 @@ function testRenderer_buildRunGraphData_pagesSuccessesAndFailures() {
|
|
|
4506
4506
|
saved_paths: [],
|
|
4507
4507
|
total_bytes: 0,
|
|
4508
4508
|
duration_ms: 0,
|
|
4509
|
-
failed_cap: 'cap:in="media:png";
|
|
4509
|
+
failed_cap: 'cap:in="media:image;png";b;out="media:txt"',
|
|
4510
4510
|
error: 'oom',
|
|
4511
4511
|
});
|
|
4512
4512
|
}
|
|
@@ -4515,7 +4515,7 @@ function testRenderer_buildRunGraphData_pagesSuccessesAndFailures() {
|
|
|
4515
4515
|
media_display_names: {
|
|
4516
4516
|
'media:pdf;list': 'PDF List',
|
|
4517
4517
|
'media:pdf': 'PDF',
|
|
4518
|
-
'media:png': 'PNG',
|
|
4518
|
+
'media:image;png': 'PNG',
|
|
4519
4519
|
'media:txt': 'Text',
|
|
4520
4520
|
},
|
|
4521
4521
|
body_outcomes: outcomes,
|
|
@@ -4555,7 +4555,7 @@ function testRenderer_buildRunGraphData_failureWithoutFailedCapRendersFullTrace(
|
|
|
4555
4555
|
target_spec: 'media:txt',
|
|
4556
4556
|
steps: [
|
|
4557
4557
|
makeForEachStep('media:pdf;list'),
|
|
4558
|
-
makeCapStep('cap:in="media:pdf";
|
|
4558
|
+
makeCapStep('cap:in="media:pdf";a;out="media:txt"', 'a', 'media:pdf', 'media:txt', false, false),
|
|
4559
4559
|
makeCollectStep('media:txt'),
|
|
4560
4560
|
],
|
|
4561
4561
|
};
|
|
@@ -4593,11 +4593,11 @@ function testRenderer_buildRunGraphData_usesCapUrnIsEquivalentForFailedCap() {
|
|
|
4593
4593
|
makeForEachStep('media:a;list'),
|
|
4594
4594
|
// Canonical form places tags alphabetically: op after in/out.
|
|
4595
4595
|
makeCapStep(
|
|
4596
|
-
'cap:in="media:a";
|
|
4596
|
+
'cap:in="media:a";x;out="media:b"',
|
|
4597
4597
|
'x', 'media:a', 'media:b', false, false
|
|
4598
4598
|
),
|
|
4599
4599
|
makeCapStep(
|
|
4600
|
-
'cap:in="media:b";
|
|
4600
|
+
'cap:in="media:b";y;out="media:c"',
|
|
4601
4601
|
'y', 'media:b', 'media:c', false, false
|
|
4602
4602
|
),
|
|
4603
4603
|
makeCollectStep('media:c'),
|
|
@@ -4656,9 +4656,9 @@ function testRenderer_buildRunGraphData_backboneHasNoForeachNode() {
|
|
|
4656
4656
|
source_spec: 'media:pdf',
|
|
4657
4657
|
target_spec: 'media:decision',
|
|
4658
4658
|
steps: [
|
|
4659
|
-
makeCapStep('cap:in="media:pdf";
|
|
4659
|
+
makeCapStep('cap:in="media:pdf";disbind;out="media:page"', 'Disbind', 'media:pdf', 'media:page', false, true),
|
|
4660
4660
|
makeForEachStep('media:page'),
|
|
4661
|
-
makeCapStep('cap:in="media:page";
|
|
4661
|
+
makeCapStep('cap:in="media:page";decide;out="media:decision"', 'Make a Decision', 'media:page', 'media:decision', false, false),
|
|
4662
4662
|
],
|
|
4663
4663
|
};
|
|
4664
4664
|
const payload = {
|
|
@@ -4704,12 +4704,12 @@ function testRenderer_buildRunGraphData_allFailedDropsTargetPlaceholder() {
|
|
|
4704
4704
|
source_spec: 'media:pdf',
|
|
4705
4705
|
target_spec: 'media:decision',
|
|
4706
4706
|
steps: [
|
|
4707
|
-
makeCapStep('cap:in="media:pdf";
|
|
4707
|
+
makeCapStep('cap:in="media:pdf";disbind;out="media:page"', 'Disbind', 'media:pdf', 'media:page', false, true),
|
|
4708
4708
|
makeForEachStep('media:page'),
|
|
4709
|
-
makeCapStep('cap:in="media:page";
|
|
4709
|
+
makeCapStep('cap:in="media:page";decide;out="media:decision"', 'Make a Decision', 'media:page', 'media:decision', false, false),
|
|
4710
4710
|
],
|
|
4711
4711
|
};
|
|
4712
|
-
const failedCapUrn = 'cap:in="media:page";
|
|
4712
|
+
const failedCapUrn = 'cap:in="media:page";decide;out="media:decision"';
|
|
4713
4713
|
const payload = {
|
|
4714
4714
|
resolved_strand: strand,
|
|
4715
4715
|
media_display_names: {
|
|
@@ -4774,9 +4774,9 @@ function testRenderer_buildRunGraphData_unclosedForeachSuccessNoMerge() {
|
|
|
4774
4774
|
source_spec: 'media:pdf',
|
|
4775
4775
|
target_spec: 'media:decision',
|
|
4776
4776
|
steps: [
|
|
4777
|
-
makeCapStep('cap:in="media:pdf";
|
|
4777
|
+
makeCapStep('cap:in="media:pdf";disbind;out="media:page"', 'Disbind', 'media:pdf', 'media:page', false, true),
|
|
4778
4778
|
makeForEachStep('media:page'),
|
|
4779
|
-
makeCapStep('cap:in="media:page";
|
|
4779
|
+
makeCapStep('cap:in="media:page";decide;out="media:decision"', 'Make a Decision', 'media:page', 'media:decision', false, false),
|
|
4780
4780
|
],
|
|
4781
4781
|
};
|
|
4782
4782
|
const payload = {
|
|
@@ -4834,7 +4834,7 @@ function testRenderer_buildRunGraphData_closedForeachSuccessMergesAtCollectTarge
|
|
|
4834
4834
|
target_spec: 'media:txt;list',
|
|
4835
4835
|
steps: [
|
|
4836
4836
|
makeForEachStep('media:pdf;list'),
|
|
4837
|
-
makeCapStep('cap:in="media:pdf";
|
|
4837
|
+
makeCapStep('cap:in="media:pdf";extract;out="media:txt"', 'extract', 'media:pdf', 'media:txt', false, false),
|
|
4838
4838
|
makeCollectStep('media:txt'),
|
|
4839
4839
|
],
|
|
4840
4840
|
};
|
|
@@ -5014,7 +5014,7 @@ function testRenderer_buildResolvedMachineGraphData_singleStrandLinearChain() {
|
|
|
5014
5014
|
edges: [
|
|
5015
5015
|
{
|
|
5016
5016
|
alias: 'edge_0',
|
|
5017
|
-
cap_urn: 'cap:in=media:pdf;
|
|
5017
|
+
cap_urn: 'cap:in=media:pdf;extract;out=media:txt;textable',
|
|
5018
5018
|
title: 'Extract Text',
|
|
5019
5019
|
is_loop: false,
|
|
5020
5020
|
assignment: [
|
|
@@ -5024,7 +5024,7 @@ function testRenderer_buildResolvedMachineGraphData_singleStrandLinearChain() {
|
|
|
5024
5024
|
},
|
|
5025
5025
|
{
|
|
5026
5026
|
alias: 'edge_1',
|
|
5027
|
-
cap_urn: 'cap:in=media:textable;
|
|
5027
|
+
cap_urn: 'cap:in=media:textable;embed;out=media:embedding;record',
|
|
5028
5028
|
title: 'Generate Embedding',
|
|
5029
5029
|
is_loop: false,
|
|
5030
5030
|
assignment: [
|
|
@@ -5069,7 +5069,7 @@ function testRenderer_buildResolvedMachineGraphData_loopEdgeGetsLoopClass() {
|
|
|
5069
5069
|
edges: [
|
|
5070
5070
|
{
|
|
5071
5071
|
alias: 'edge_0',
|
|
5072
|
-
cap_urn: 'cap:in=media:textable;
|
|
5072
|
+
cap_urn: 'cap:in=media:textable;make-decision;out=media:decision;json;record;textable',
|
|
5073
5073
|
title: 'Make Decision',
|
|
5074
5074
|
is_loop: true,
|
|
5075
5075
|
assignment: [
|
|
@@ -5105,7 +5105,7 @@ function testRenderer_buildResolvedMachineGraphData_fanInProducesEdgePerAssignme
|
|
|
5105
5105
|
edges: [
|
|
5106
5106
|
{
|
|
5107
5107
|
alias: 'edge_0',
|
|
5108
|
-
cap_urn: 'cap:in=media:image;png;
|
|
5108
|
+
cap_urn: 'cap:in=media:image;png;describe-image;out=media:image-description;textable',
|
|
5109
5109
|
title: 'Describe Image',
|
|
5110
5110
|
is_loop: false,
|
|
5111
5111
|
assignment: [
|
|
@@ -5145,7 +5145,7 @@ function testRenderer_buildResolvedMachineGraphData_multiStrandKeepsStrandsDisjo
|
|
|
5145
5145
|
edges: [
|
|
5146
5146
|
{
|
|
5147
5147
|
alias: 'edge_0',
|
|
5148
|
-
cap_urn: 'cap:in=media:pdf;
|
|
5148
|
+
cap_urn: 'cap:in=media:pdf;extract;out=media:txt;textable',
|
|
5149
5149
|
title: 'Extract Text',
|
|
5150
5150
|
is_loop: false,
|
|
5151
5151
|
assignment: [
|
|
@@ -5165,7 +5165,7 @@ function testRenderer_buildResolvedMachineGraphData_multiStrandKeepsStrandsDisjo
|
|
|
5165
5165
|
edges: [
|
|
5166
5166
|
{
|
|
5167
5167
|
alias: 'edge_1',
|
|
5168
|
-
cap_urn: 'cap:in=media:json;record;textable;
|
|
5168
|
+
cap_urn: 'cap:in=media:json;record;textable;convert-format;out=media:csv;list;record;textable',
|
|
5169
5169
|
title: 'Convert Format',
|
|
5170
5170
|
is_loop: false,
|
|
5171
5171
|
assignment: [
|