@@ -333,8 +333,101 @@ final class WorkspaceTests2: XCTestCase {
333
333
}
334
334
}
335
335
336
+ func testCanResolveWithIncompatiblePins( ) throws {
337
+ let sandbox = AbsolutePath ( " /tmp/ws/ " )
338
+ let fs = InMemoryFileSystem ( )
339
+
340
+ let workspace = try TestWorkspace (
341
+ sandbox: sandbox,
342
+ fs: fs,
343
+ roots: [ ] ,
344
+ packages: [
345
+ TestPackage (
346
+ name: " A " ,
347
+ targets: [
348
+ TestTarget ( name: " A " , dependencies: [ " AA " ] ) ,
349
+ ] ,
350
+ products: [ ] ,
351
+ dependencies: [
352
+ TestDependency ( name: " AA " , requirement: . exact( " 1.0.0 " ) ) ,
353
+ ] ,
354
+ versions: [ " 1.0.0 " ]
355
+ ) ,
356
+ TestPackage (
357
+ name: " A " ,
358
+ targets: [
359
+ TestTarget ( name: " A " , dependencies: [ " AA " ] ) ,
360
+ ] ,
361
+ products: [ ] ,
362
+ dependencies: [
363
+ TestDependency ( name: " AA " , requirement: . exact( " 2.0.0 " ) ) ,
364
+ ] ,
365
+ versions: [ " 1.0.1 " ]
366
+ ) ,
367
+ TestPackage (
368
+ name: " AA " ,
369
+ targets: [
370
+ TestTarget ( name: " AA " ) ,
371
+ ] ,
372
+ products: [
373
+ TestProduct ( name: " AA " , targets: [ " AA " ] ) ,
374
+ ] ,
375
+ versions: [ " 1.0.0 " , " 2.0.0 " ]
376
+ ) ,
377
+ ]
378
+ )
379
+
380
+ // Resolve when A = 1.0.0.
381
+ do {
382
+ let deps : [ TestWorkspace . PackageDependency ] = [
383
+ . init( name: " A " , requirement: . exact( " 1.0.0 " ) )
384
+ ]
385
+ workspace. checkPackageGraph ( deps: deps) { ( graph, diagnostics) in
386
+ PackageGraphTester ( graph) { result in
387
+ result. check ( packages: " A " , " AA " )
388
+ result. check ( targets: " A " , " AA " )
389
+ result. check ( dependencies: " AA " , target: " A " )
390
+ }
391
+ XCTAssertNoDiagnostics ( diagnostics)
392
+ }
393
+ workspace. checkManagedDependencies ( ) { result in
394
+ result. check ( dependency: " a " , at: . checkout( . version( " 1.0.0 " ) ) )
395
+ result. check ( dependency: " aa " , at: . checkout( . version( " 1.0.0 " ) ) )
396
+ }
397
+ workspace. checkResolved ( ) { result in
398
+ result. check ( dependency: " a " , at: . checkout( . version( " 1.0.0 " ) ) )
399
+ result. check ( dependency: " aa " , at: . checkout( . version( " 1.0.0 " ) ) )
400
+ }
401
+ }
402
+
403
+ // Resolve when A = 1.0.1.
404
+ do {
405
+ let deps : [ TestWorkspace . PackageDependency ] = [
406
+ . init( name: " A " , requirement: . exact( " 1.0.1 " ) )
407
+ ]
408
+ workspace. checkPackageGraph ( deps: deps) { ( graph, diagnostics) in
409
+ PackageGraphTester ( graph) { result in
410
+ result. check ( dependencies: " AA " , target: " A " )
411
+ }
412
+ XCTAssertNoDiagnostics ( diagnostics)
413
+ }
414
+ workspace. checkManagedDependencies ( ) { result in
415
+ result. check ( dependency: " a " , at: . checkout( . version( " 1.0.1 " ) ) )
416
+ result. check ( dependency: " aa " , at: . checkout( . version( " 2.0.0 " ) ) )
417
+ }
418
+ workspace. checkResolved ( ) { result in
419
+ result. check ( dependency: " a " , at: . checkout( . version( " 1.0.1 " ) ) )
420
+ result. check ( dependency: " aa " , at: . checkout( . version( " 2.0.0 " ) ) )
421
+ }
422
+ XCTAssertMatch ( workspace. delegate. events, [ . equal( " updating repo: /tmp/ws/pkgs/A " ) ] )
423
+ XCTAssertMatch ( workspace. delegate. events, [ . equal( " updating repo: /tmp/ws/pkgs/AA " ) ] )
424
+ XCTAssertEqual ( workspace. delegate. events. filter ( { $0. hasPrefix ( " updating repo " ) } ) . count, 2 )
425
+ }
426
+ }
427
+
336
428
static var allTests = [
337
429
( " testBasics " , testBasics) ,
430
+ ( " testCanResolveWithIncompatiblePins " , testCanResolveWithIncompatiblePins) ,
338
431
( " testMultipleRootPackages " , testMultipleRootPackages) ,
339
432
( " testRootAsDependency1 " , testRootAsDependency1) ,
340
433
( " testRootAsDependency2 " , testRootAsDependency1) ,
@@ -501,6 +594,33 @@ private final class TestWorkspace {
501
594
return packages. map ( { rootsDir. appending ( component: $0) } )
502
595
}
503
596
597
+ struct PackageDependency {
598
+ typealias Requirement = PackageGraphRoot . PackageDependency . Requirement
599
+
600
+ let name : String
601
+ let requirement : Requirement
602
+
603
+ init ( name: String , requirement: Requirement ) {
604
+ self . name = name
605
+ self . requirement = requirement
606
+ }
607
+ }
608
+
609
+ func checkPackageGraph(
610
+ roots: [ String ] = [ ] ,
611
+ deps: [ TestWorkspace . PackageDependency ] ,
612
+ _ result: ( PackageGraph , DiagnosticsEngine ) -> ( )
613
+ ) {
614
+ let dependencies = deps. map ( {
615
+ PackageGraphRootInput . PackageDependency (
616
+ url: packagesDir. appending ( component: $0. name) . asString,
617
+ requirement: $0. requirement,
618
+ location: $0. name
619
+ )
620
+ } )
621
+ checkPackageGraph ( roots: roots, dependencies: dependencies, result)
622
+ }
623
+
504
624
func checkPackageGraph(
505
625
roots: [ String ] = [ ] ,
506
626
dependencies: [ PackageGraphRootInput . PackageDependency ] = [ ] ,
@@ -514,6 +634,15 @@ private final class TestWorkspace {
514
634
result ( graph, diagnostics)
515
635
}
516
636
637
+ enum State {
638
+ enum CheckoutState {
639
+ case version( Utility . Version )
640
+ case revision( String )
641
+ }
642
+ case checkout( CheckoutState )
643
+ case edited
644
+ }
645
+
517
646
struct ManagedDependencyResult {
518
647
519
648
let managedDependencies : ManagedDependencies
@@ -522,15 +651,6 @@ private final class TestWorkspace {
522
651
self . managedDependencies = managedDependencies
523
652
}
524
653
525
- enum State {
526
- enum CheckoutState {
527
- case version( Utility . Version )
528
- case revision( String )
529
- }
530
- case checkout( CheckoutState )
531
- case edited
532
- }
533
-
534
654
func check( notPresent name: String ) {
535
655
XCTAssert ( managedDependencies [ forIdentity: name] == nil , " Unexpectedly found \( name) in managed dependencies " )
536
656
}
@@ -562,6 +682,41 @@ private final class TestWorkspace {
562
682
XCTFail ( " Failed with error \( error) " )
563
683
}
564
684
}
685
+
686
+ struct ResolvedResult {
687
+ let store : PinsStore
688
+
689
+ init ( _ store: PinsStore ) {
690
+ self . store = store
691
+ }
692
+
693
+ func check( dependency package : String , at state: State ) {
694
+ guard let pin = store. pinsMap [ package ] else {
695
+ XCTFail ( " Pin for \( package ) not found " )
696
+ return
697
+ }
698
+ switch state {
699
+ case . checkout( let state) :
700
+ switch state {
701
+ case . version( let version) :
702
+ XCTAssertEqual ( pin. state. version, version)
703
+ case . revision:
704
+ XCTFail ( " Unimplemented " )
705
+ }
706
+ case . edited:
707
+ XCTFail ( " Unimplemented " )
708
+ }
709
+ }
710
+ }
711
+
712
+ func checkResolved( _ result: ( ResolvedResult ) throws -> ( ) ) {
713
+ do {
714
+ let workspace = createWorkspace ( )
715
+ try result ( ResolvedResult ( workspace. pinsStore. load ( ) ) )
716
+ } catch {
717
+ XCTFail ( " Failed with error \( error) " )
718
+ }
719
+ }
565
720
}
566
721
567
722
private struct TestTarget {
0 commit comments