@@ -2,6 +2,7 @@ package datafs
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"io"
6
7
"io/fs"
7
8
"mime"
@@ -31,19 +32,7 @@ func setupMergeFsys(ctx context.Context, t *testing.T) fs.FS {
31
32
yamlContent := "hello: earth\n goodnight: moon\n "
32
33
arrayContent := `["hello", "world"]`
33
34
34
- wd , _ := os .Getwd ()
35
-
36
- // MapFS doesn't support windows path separators, so we use / exclusively
37
- // in this test
38
- vol := filepath .VolumeName (wd )
39
- if vol != "" && wd != vol {
40
- wd = wd [len (vol )+ 1 :]
41
- } else if wd [0 ] == '/' {
42
- wd = wd [1 :]
43
- }
44
- wd = filepath .ToSlash (wd )
45
-
46
- t .Logf ("wd: %s" , wd )
35
+ wd := wdForTest (t )
47
36
48
37
fsys := WrapWdFS (fstest.MapFS {
49
38
"tmp" : {Mode : fs .ModeDir | 0o777 },
@@ -90,84 +79,22 @@ func setupMergeFsys(ctx context.Context, t *testing.T) fs.FS {
90
79
return fsys
91
80
}
92
81
93
- // func TestReadMerge(t *testing.T) {
94
- // ctx := context.Background()
95
-
96
- // jsonContent := `{"hello": "world"}`
97
- // yamlContent := "hello: earth\ngoodnight: moon\n"
98
- // arrayContent := `["hello", "world"]`
99
-
100
- // mergedContent := "goodnight: moon\nhello: world\n"
101
-
102
- // fsys := fstest.MapFS{}
103
- // fsys["tmp"] = &fstest.MapFile{Mode: fs.ModeDir | 0777}
104
- // fsys["tmp/jsonfile.json"] = &fstest.MapFile{Data: []byte(jsonContent)}
105
- // fsys["tmp/array.json"] = &fstest.MapFile{Data: []byte(arrayContent)}
106
- // fsys["tmp/yamlfile.yaml"] = &fstest.MapFile{Data: []byte(yamlContent)}
107
- // fsys["tmp/textfile.txt"] = &fstest.MapFile{Data: []byte(`plain text...`)}
108
-
109
- // // workding dir with volume name trimmed
110
- // wd, _ := os.Getwd()
111
- // vol := filepath.VolumeName(wd)
112
- // wd = wd[len(vol)+1:]
113
-
114
- // fsys[path.Join(wd, "jsonfile.json")] = &fstest.MapFile{Data: []byte(jsonContent)}
115
- // fsys[path.Join(wd, "array.json")] = &fstest.MapFile{Data: []byte(arrayContent)}
116
- // fsys[path.Join(wd, "yamlfile.yaml")] = &fstest.MapFile{Data: []byte(yamlContent)}
117
- // fsys[path.Join(wd, "textfile.txt")] = &fstest.MapFile{Data: []byte(`plain text...`)}
118
-
119
- // fsmux := fsimpl.NewMux()
120
- // fsmux.Add(fsimpl.WrappedFSProvider(&fsys, "file"))
121
- // ctx = datafs.ContextWithFSProvider(ctx, fsmux)
122
-
123
- // source := &Source{Alias: "foo", URL: mustParseURL("merge:file:///tmp/jsonfile.json|file:///tmp/yamlfile.yaml")}
124
- // d := &Data{
125
- // Sources: map[string]*Source{
126
- // "foo": source,
127
- // "bar": {Alias: "bar", URL: mustParseURL("file:///tmp/jsonfile.json")},
128
- // "baz": {Alias: "baz", URL: mustParseURL("file:///tmp/yamlfile.yaml")},
129
- // "text": {Alias: "text", URL: mustParseURL("file:///tmp/textfile.txt")},
130
- // "badscheme": {Alias: "badscheme", URL: mustParseURL("bad:///scheme.json")},
131
- // "badtype": {Alias: "badtype", URL: mustParseURL("file:///tmp/textfile.txt?type=foo/bar")},
132
- // "array": {Alias: "array", URL: mustParseURL("file:///tmp/array.json?type=" + url.QueryEscape(jsonArrayMimetype))},
133
- // },
134
- // Ctx: ctx,
135
- // }
136
-
137
- // actual, err := d.readMerge(ctx, source)
138
- // require.NoError(t, err)
139
- // assert.Equal(t, mergedContent, string(actual))
140
-
141
- // source.URL = mustParseURL("merge:bar|baz")
142
- // actual, err = d.readMerge(ctx, source)
143
- // require.NoError(t, err)
144
- // assert.Equal(t, mergedContent, string(actual))
145
-
146
- // source.URL = mustParseURL("merge:./jsonfile.json|baz")
147
- // actual, err = d.readMerge(ctx, source)
148
- // require.NoError(t, err)
149
- // assert.Equal(t, mergedContent, string(actual))
150
-
151
- // source.URL = mustParseURL("merge:file:///tmp/jsonfile.json")
152
- // _, err = d.readMerge(ctx, source)
153
- // require.Error(t, err)
154
-
155
- // source.URL = mustParseURL("merge:bogusalias|file:///tmp/jsonfile.json")
156
- // _, err = d.readMerge(ctx, source)
157
- // require.Error(t, err)
158
-
159
- // source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|badscheme")
160
- // _, err = d.readMerge(ctx, source)
161
- // require.Error(t, err)
162
-
163
- // source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|badtype")
164
- // _, err = d.readMerge(ctx, source)
165
- // require.Error(t, err)
166
-
167
- // source.URL = mustParseURL("merge:file:///tmp/jsonfile.json|array")
168
- // _, err = d.readMerge(ctx, source)
169
- // require.Error(t, err)
170
- // }
82
+ func wdForTest (t * testing.T ) string {
83
+ t .Helper ()
84
+
85
+ wd , _ := os .Getwd ()
86
+
87
+ // MapFS doesn't support windows path separators, so we use / exclusively
88
+ vol := filepath .VolumeName (wd )
89
+ if vol != "" && wd != vol {
90
+ wd = wd [len (vol )+ 1 :]
91
+ } else if wd [0 ] == '/' {
92
+ wd = wd [1 :]
93
+ }
94
+ wd = filepath .ToSlash (wd )
95
+
96
+ return wd
97
+ }
171
98
172
99
func TestMergeData (t * testing.T ) {
173
100
def := map [string ]interface {}{
@@ -228,7 +155,6 @@ func TestMergeData(t *testing.T) {
228
155
}
229
156
230
157
func TestMergeFS_Open (t * testing.T ) {
231
- // u, _ := url.Parse("merge:")
232
158
fsys := setupMergeFsys (context .Background (), t )
233
159
assert .IsType (t , & mergeFS {}, fsys )
234
160
@@ -354,3 +280,55 @@ func TestMergeFS_ReadFile(t *testing.T) {
354
280
})
355
281
}
356
282
}
283
+
284
+ func TestMergeFS_ReadsSubFilesOnce (t * testing.T ) {
285
+ mergedContent := "goodnight: moon\n hello: world\n "
286
+
287
+ wd := wdForTest (t )
288
+
289
+ fsys := WrapWdFS (
290
+ openOnce (& fstest.MapFS {
291
+ path .Join (wd , "tmp/jsonfile.json" ): {Data : []byte (`{"hello": "world"}` )},
292
+ path .Join (wd , "tmp/yamlfile.yaml" ): {Data : []byte ("hello: earth\n goodnight: moon\n " )},
293
+ }))
294
+
295
+ mux := fsimpl .NewMux ()
296
+ mux .Add (MergeFS )
297
+ mux .Add (WrappedFSProvider (fsys , "file" , "" ))
298
+
299
+ ctx := ContextWithFSProvider (context .Background (), mux )
300
+
301
+ reg := NewRegistry ()
302
+ reg .Register ("jsonfile" , config.DataSource {URL : mustParseURL ("tmp/jsonfile.json" )})
303
+ reg .Register ("yamlfile" , config.DataSource {URL : mustParseURL ("tmp/yamlfile.yaml" )})
304
+
305
+ fsys , err := NewMergeFS (mustParseURL ("merge:///" ))
306
+ require .NoError (t , err )
307
+
308
+ fsys = WithDataSourceRegistryFS (reg , fsys )
309
+ fsys = fsimpl .WithContextFS (ctx , fsys )
310
+
311
+ b , err := fs .ReadFile (fsys , "jsonfile|yamlfile" )
312
+ require .NoError (t , err )
313
+ assert .Equal (t , mergedContent , string (b ))
314
+ }
315
+
316
+ type openOnceFS struct {
317
+ fs * fstest.MapFS
318
+ opened map [string ]struct {}
319
+ }
320
+
321
+ // a filesystem that only allows opening or stating a file once
322
+ func openOnce (fsys * fstest.MapFS ) fs.FS {
323
+ return & openOnceFS {fs : fsys , opened : map [string ]struct {}{}}
324
+ }
325
+
326
+ func (f * openOnceFS ) Open (name string ) (fs.File , error ) {
327
+ if _ , ok := f .opened [name ]; ok {
328
+ return nil , fmt .Errorf ("open: %q already opened" , name )
329
+ }
330
+
331
+ f .opened [name ] = struct {}{}
332
+
333
+ return f .fs .Open (name )
334
+ }
0 commit comments