@@ -14,3 +14,159 @@ pub trait Registry {
14
14
/// Fetch full package by its ID.
15
15
async fn download ( & mut self , package_id : PackageId ) -> Result < Package > ;
16
16
}
17
+
18
+ #[ cfg( test) ]
19
+ pub ( crate ) mod mock {
20
+ use std:: collections:: hash_map:: Entry ;
21
+ use std:: collections:: { HashMap , HashSet } ;
22
+ use std:: path:: PathBuf ;
23
+
24
+ use anyhow:: { anyhow, bail, Result } ;
25
+ use async_trait:: async_trait;
26
+ use itertools:: Itertools ;
27
+
28
+ use crate :: core:: package:: PackageName ;
29
+ use crate :: core:: registry:: Registry ;
30
+ use crate :: core:: { Manifest , ManifestDependency , Package , PackageId , SourceId , Summary } ;
31
+
32
+ #[ derive( Clone , Debug , Default ) ]
33
+ pub struct MockRegistry {
34
+ index : HashMap < ( PackageName , SourceId ) , HashSet < PackageId > > ,
35
+ dependencies : HashMap < PackageId , Vec < ManifestDependency > > ,
36
+ packages : HashMap < PackageId , Package > ,
37
+ }
38
+
39
+ impl MockRegistry {
40
+ pub fn new ( ) -> Self {
41
+ Default :: default ( )
42
+ }
43
+
44
+ pub fn put ( & mut self , package_id : PackageId , mut dependencies : Vec < ManifestDependency > ) {
45
+ assert ! (
46
+ !self . has_package( package_id) ,
47
+ "Package {} is already in registry" ,
48
+ package_id
49
+ ) ;
50
+
51
+ self . index
52
+ . entry ( ( package_id. name . clone ( ) , package_id. source_id ) )
53
+ . or_default ( )
54
+ . insert ( package_id) ;
55
+
56
+ self . dependencies
57
+ . entry ( package_id)
58
+ . or_default ( )
59
+ . append ( & mut dependencies) ;
60
+ }
61
+
62
+ pub fn has_package ( & self , package_id : PackageId ) -> bool {
63
+ self . dependencies . contains_key ( & package_id)
64
+ }
65
+
66
+ pub fn get_package ( & mut self , package_id : PackageId ) -> Result < Package > {
67
+ if !self . has_package ( package_id) {
68
+ bail ! ( "MockRegistry/get_package: unknown package {package_id}" ) ;
69
+ }
70
+
71
+ match self . packages . entry ( package_id) {
72
+ Entry :: Occupied ( entry) => Ok ( entry. get ( ) . clone ( ) ) ,
73
+ Entry :: Vacant ( entry) => {
74
+ let summary = Summary :: new ( package_id, self . dependencies [ & package_id] . clone ( ) ) ;
75
+ let manifest = Box :: new ( Manifest {
76
+ summary,
77
+ metadata : Default :: default ( ) ,
78
+ } ) ;
79
+ let package = Package :: new ( package_id, PathBuf :: new ( ) , manifest) ;
80
+ entry. insert ( package. clone ( ) ) ;
81
+ Ok ( package)
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ #[ async_trait( ?Send ) ]
88
+ impl Registry for MockRegistry {
89
+ async fn query ( & mut self , dependency : & ManifestDependency ) -> Result < Vec < Summary > > {
90
+ Ok ( self
91
+ . index
92
+ . get ( & ( dependency. name . clone ( ) , dependency. source_id ) )
93
+ . ok_or_else ( || {
94
+ anyhow ! (
95
+ "MockRegistry/query: unknown package {} ({})" ,
96
+ dependency. name,
97
+ dependency. source_id
98
+ )
99
+ } ) ?
100
+ . iter ( )
101
+ . copied ( )
102
+ . filter ( |id| dependency. version_req . matches ( & id. version ) )
103
+ . sorted_unstable_by ( |a, b| b. version . cmp ( & a. version ) )
104
+ . map ( |id| self . get_package ( id) . unwrap ( ) . manifest . summary . clone ( ) )
105
+ . collect ( ) )
106
+ }
107
+
108
+ async fn download ( & mut self , package_id : PackageId ) -> Result < Package > {
109
+ self . get_package ( package_id)
110
+ }
111
+ }
112
+
113
+ macro_rules! registry {
114
+ [ $( $x: tt) ,* $( , ) ?] => { {
115
+ #[ allow( unused_imports) ]
116
+ use $crate:: core:: registry:: mock;
117
+ #[ allow( unused_mut) ]
118
+ let mut registry = mock:: MockRegistry :: new( ) ;
119
+ $( {
120
+ let ( package_id, dependencies) = mock:: registry_entry!( $x) ;
121
+ registry. put( package_id, dependencies) ;
122
+ } ) *
123
+ registry
124
+ } } ;
125
+ }
126
+
127
+ pub ( crate ) use registry;
128
+
129
+ macro_rules! registry_entry {
130
+ ( ( $p: literal, [ $( $d: tt) ,* $( , ) ? ] $( , ) ?) ) => { {
131
+ #[ allow( unused_imports) ]
132
+ use $crate:: core:: registry:: mock;
133
+ let package_id = $crate:: core:: PackageId :: from_display_str( $p) . unwrap( ) ;
134
+ let dependencies = mock:: deps![ $( $d) ,* ] . iter( ) . cloned( ) . collect( ) ;
135
+ ( package_id, dependencies)
136
+ } } ;
137
+ }
138
+
139
+ pub ( crate ) use registry_entry;
140
+
141
+ macro_rules! deps {
142
+ [ $( $x: tt) ,* $( , ) ?] => (
143
+ & [
144
+ $( $crate:: core:: registry:: mock:: dep!( $x) ) ,*
145
+ ]
146
+ ) ;
147
+ }
148
+
149
+ pub ( crate ) use deps;
150
+
151
+ macro_rules! dep {
152
+ ( ( $n: literal, $v: literal, $s: literal) ) => {
153
+ $crate:: core:: ManifestDependency {
154
+ name: ( $n) . into( ) ,
155
+ version_req: :: semver:: VersionReq :: parse( $v) . unwrap( ) ,
156
+ source_id: $crate:: core:: SourceId :: from_display_str( $s) . unwrap( ) ,
157
+ }
158
+ } ;
159
+ }
160
+
161
+ pub ( crate ) use dep;
162
+
163
+ macro_rules! pkgs {
164
+ [ $( $x: expr) ,* $( , ) ?] => (
165
+ & [
166
+ $( $crate:: core:: PackageId :: from_display_str( $x) . unwrap( ) ) ,*
167
+ ]
168
+ ) ;
169
+ }
170
+
171
+ pub ( crate ) use pkgs;
172
+ }
0 commit comments