• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MeltyPlayer / MeltyTool / 20982513833

14 Jan 2026 04:35AM UTC coverage: 41.138% (-0.8%) from 41.907%
20982513833

push

github

MeltyPlayer
Fixed broken shader source tests.

6752 of 18485 branches covered (36.53%)

Branch coverage included in aggregate %.

28650 of 67572 relevant lines covered (42.4%)

64006.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.35
/FinModelUtility/ImaginaryFileSystem/ImaginaryFileStream.cs
1
using System.Runtime.Versioning;
2
using System.Security.AccessControl;
3

4
namespace System.IO.Abstractions.TestingHelpers;
5

6
/// <inheritdoc />
7
#if FEATURE_SERIALIZABLE
8
[Serializable]
9
#endif
10
public class ImaginaryFileStream : FileSystemStream, IFileSystemAclSupport {
11
  /// <summary>
12
  ///     Wrapper around a <see cref="Stream" /> with no backing store, which
13
  ///     is used as a replacement for a <see cref="FileSystemStream" />. As such
14
  ///     it implements the same properties and methods as a <see cref="FileSystemStream" />.
15
  /// </summary>
16
  public new static FileSystemStream Null { get; } = new NullFileSystemStream();
×
17

18
  private class NullFileSystemStream : FileSystemStream {
19
    /// <summary>
20
    /// Initializes a new instance of <see cref="NullFileSystemStream" />.
21
    /// </summary>
22
    public NullFileSystemStream() : base(Null, ".", true) { }
×
23
  }
24

25
  private readonly IImaginaryFileDataAccessor imaginaryFileDataAccessor_;
26
  private readonly string path;
27
  private readonly FileAccess access = FileAccess.ReadWrite;
10,530✔
28
  private readonly FileOptions options;
29
  private readonly ImaginaryFileData fileData;
30
  private bool disposed;
31

32
  /// <inheritdoc />
33
  public ImaginaryFileStream(
34
      IImaginaryFileDataAccessor imaginaryFileDataAccessor,
35
      string path,
36
      FileMode mode,
37
      FileAccess access = FileAccess.ReadWrite,
38
      FileOptions options = FileOptions.None)
39
      : base(new MemoryStream(),
10,530!
40
             path == null ? null : Path.GetFullPath(path),
10,530✔
41
             (options & FileOptions.Asynchronous) != 0) {
21,060✔
42
    ThrowIfInvalidModeAccess(mode, access);
10,530✔
43

44
    this.imaginaryFileDataAccessor_ = imaginaryFileDataAccessor ??
10,530!
45
                                      throw new ArgumentNullException(
10,530✔
46
                                          nameof(imaginaryFileDataAccessor));
10,530✔
47
    this.path = path;
10,530✔
48
    this.options = options;
10,530✔
49

50
    if (imaginaryFileDataAccessor.FileExists(path)) {
21,060!
51
      if (mode.Equals(FileMode.CreateNew)) {
10,530!
52
        throw CommonExceptions.FileAlreadyExists(path);
×
53
      }
54

55
      fileData = imaginaryFileDataAccessor.GetFile(path);
10,530✔
56
      fileData.CheckFileAccess(path, access);
10,530✔
57

58
      var timeAdjustments
10,530✔
59
          = GetTimeAdjustmentsForFileStreamWhenFileExists(mode, access);
10,530✔
60
      imaginaryFileDataAccessor.AdjustTimes(fileData, timeAdjustments);
10,530✔
61
      var existingContents = fileData.Contents;
10,530✔
62
      var keepExistingContents =
10,530✔
63
          existingContents?.Length > 0 &&
10,530✔
64
          mode != FileMode.Truncate &&
10,530✔
65
          mode != FileMode.Create;
10,530✔
66
      if (keepExistingContents) {
16,253✔
67
        base.Write(existingContents, 0, existingContents.Length);
5,723✔
68
        base.Seek(0,
5,723!
69
                  mode == FileMode.Append
5,723✔
70
                      ? SeekOrigin.End
5,723✔
71
                      : SeekOrigin.Begin);
5,723✔
72
      }
5,723✔
73
    } else {
10,530✔
74
      var directoryPath = imaginaryFileDataAccessor.Path.GetDirectoryName(path);
×
75
      if (!string.IsNullOrEmpty(directoryPath) &&
×
76
          !imaginaryFileDataAccessor.Directory.Exists(directoryPath)) {
×
77
        throw CommonExceptions.CouldNotFindPartOfPath(path);
×
78
      }
79

80
      if (mode.Equals(FileMode.Open) || mode.Equals(FileMode.Truncate)) {
×
81
        throw CommonExceptions.FileNotFound(path);
×
82
      }
83

84
      fileData = new ImaginaryFileData(new byte[] { });
×
85
      imaginaryFileDataAccessor.AdjustTimes(fileData,
×
86
                                            TimeAdjustments.CreationTime |
×
87
                                            TimeAdjustments.LastAccessTime);
×
88
      imaginaryFileDataAccessor.AddFile(path, fileData);
×
89
    }
×
90

91
    this.access = access;
10,530✔
92
  }
10,530✔
93

94
  private static void
95
      ThrowIfInvalidModeAccess(FileMode mode, FileAccess access) {
10,530✔
96
    if (mode == FileMode.Append) {
10,530!
97
      if (access == FileAccess.Read) {
×
98
        throw CommonExceptions.InvalidAccessCombination(mode, access);
×
99
      }
100

101
      if (access != FileAccess.Write) {
×
102
        throw CommonExceptions.AppendAccessOnlyInWriteOnlyMode();
×
103
      }
104
    }
×
105

106
    if (!access.HasFlag(FileAccess.Write) &&
10,530!
107
        (mode == FileMode.Truncate ||
10,530✔
108
         mode == FileMode.CreateNew ||
10,530✔
109
         mode == FileMode.Create ||
10,530✔
110
         mode == FileMode.Append)) {
10,530✔
111
      throw CommonExceptions.InvalidAccessCombination(mode, access);
×
112
    }
113
  }
10,530✔
114

115
  /// <inheritdoc />
116
  public override bool CanRead => access.HasFlag(FileAccess.Read);
5,897✔
117

118
  /// <inheritdoc />
119
  public override bool CanWrite => access.HasFlag(FileAccess.Write);
30,789✔
120

121
  /// <inheritdoc />
122
  public override int Read(byte[] buffer, int offset, int count) {
15,621✔
123
    this.imaginaryFileDataAccessor_.AdjustTimes(fileData,
15,621✔
124
                                                TimeAdjustments.LastAccessTime);
15,621✔
125
    return base.Read(buffer, offset, count);
15,621✔
126
  }
15,621✔
127

128
  /// <inheritdoc />
129
  protected override void Dispose(bool disposing) {
10,608✔
130
    if (disposed) {
10,686✔
131
      return;
78✔
132
    }
133

134
    InternalFlush();
10,530✔
135
    base.Dispose(disposing);
10,530✔
136
    OnClose();
10,530✔
137
    disposed = true;
10,530✔
138
  }
10,608✔
139

140
  /// <inheritdoc cref="FileSystemStream.EndWrite(IAsyncResult)" />
141
  public override void EndWrite(IAsyncResult asyncResult) {
×
142
    if (!CanWrite) {
×
143
      throw new NotSupportedException("Stream does not support writing.");
×
144
    }
145

146
    base.EndWrite(asyncResult);
×
147
  }
×
148

149
  /// <inheritdoc />
150
  public override void SetLength(long value) {
×
151
    if (!CanWrite) {
×
152
      throw new NotSupportedException("Stream does not support writing.");
×
153
    }
154

155
    base.SetLength(value);
×
156
  }
×
157

158
  /// <inheritdoc cref="FileSystemStream.Write(byte[], int, int)" />
159
  public override void Write(byte[] buffer, int offset, int count) {
1,271✔
160
    if (!CanWrite) {
1,271!
161
      throw new NotSupportedException("Stream does not support writing.");
×
162
    }
163

164
    this.imaginaryFileDataAccessor_.AdjustTimes(fileData,
1,271✔
165
                                                TimeAdjustments.LastAccessTime |
1,271✔
166
                                                TimeAdjustments.LastWriteTime);
1,271✔
167
    base.Write(buffer, offset, count);
1,271✔
168
  }
1,271✔
169

170
#if FEATURE_SPAN
171
        /// <inheritdoc />
172
        public override void Write(ReadOnlySpan<byte> buffer)
173
        {
26,015✔
174
            if (!CanWrite)
26,015!
175
            {
×
176
                throw new NotSupportedException("Stream does not support writing.");
×
177
            }
178
            imaginaryFileDataAccessor_.AdjustTimes(fileData,
26,015✔
179
                TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime);
26,015✔
180
            base.Write(buffer);
26,015✔
181
        }
26,015✔
182
#endif
183

184
  /// <inheritdoc cref="FileSystemStream.WriteAsync(byte[], int, int, CancellationToken)" />
185
  public override Task WriteAsync(byte[] buffer,
186
                                  int offset,
187
                                  int count,
188
                                  CancellationToken cancellationToken) {
×
189
    if (!CanWrite) {
×
190
      throw new NotSupportedException("Stream does not support writing.");
×
191
    }
192

193
    this.imaginaryFileDataAccessor_.AdjustTimes(fileData,
×
194
                                                TimeAdjustments.LastAccessTime |
×
195
                                                TimeAdjustments.LastWriteTime);
×
196
    return base.WriteAsync(buffer, offset, count, cancellationToken);
×
197
  }
×
198

199
#if FEATURE_SPAN
200
        /// <inheritdoc />
201
        public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer,
202
                                             CancellationToken cancellationToken
203
 = new())
204
        {
×
205
            if (!CanWrite)
×
206
            {
×
207
                throw new NotSupportedException("Stream does not support writing.");
×
208
            }
209
            imaginaryFileDataAccessor_.AdjustTimes(fileData,
×
210
                                                   TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime);
×
211
            return base.WriteAsync(buffer, cancellationToken);
×
212
        }
×
213
#endif
214

215
  /// <inheritdoc cref="FileSystemStream.WriteByte(byte)" />
216
  public override void WriteByte(byte value) {
124✔
217
    if (!CanWrite) {
124!
218
      throw new NotSupportedException("Stream does not support writing.");
×
219
    }
220

221
    this.imaginaryFileDataAccessor_.AdjustTimes(fileData,
124✔
222
                                                TimeAdjustments.LastAccessTime |
124✔
223
                                                TimeAdjustments.LastWriteTime);
124✔
224
    base.WriteByte(value);
124✔
225
  }
124✔
226

227
  /// <inheritdoc />
228
  public override void Flush() {
4,721✔
229
    InternalFlush();
4,721✔
230
  }
4,721✔
231

232
  /// <inheritdoc />
233
  public override void Flush(bool flushToDisk)
234
    => InternalFlush();
×
235

236
  /// <inheritdoc />
237
  public override Task FlushAsync(CancellationToken cancellationToken) {
×
238
    InternalFlush();
×
239
    return Task.CompletedTask;
×
240
  }
×
241

242
  /// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl()" />
243
  [SupportedOSPlatform("windows")]
244
  public object GetAccessControl() {
×
245
    return GetMockFileData().AccessControl;
×
246
  }
×
247

248
  /// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl(IFileSystemAclSupport.AccessControlSections)" />
249
  [SupportedOSPlatform("windows")]
250
  public object GetAccessControl(
251
      IFileSystemAclSupport.AccessControlSections includeSections) {
×
252
    return GetMockFileData().AccessControl;
×
253
  }
×
254

255
  /// <inheritdoc cref="IFileSystemAclSupport.SetAccessControl(object)" />
256
  [SupportedOSPlatform("windows")]
257
  public void SetAccessControl(object value) {
×
258
    GetMockFileData().AccessControl = value as FileSecurity;
×
259
  }
×
260

261
  private ImaginaryFileData GetMockFileData() {
×
262
    return this.imaginaryFileDataAccessor_.GetFile(path) ??
×
263
           throw CommonExceptions.FileNotFound(path);
×
264
  }
×
265

266
  private void InternalFlush() {
15,251✔
267
    if (this.imaginaryFileDataAccessor_.FileExists(path)) {
30,502✔
268
      var mockFileData = this.imaginaryFileDataAccessor_.GetFile(path);
15,251✔
269
      /* reset back to the beginning .. */
270
      var position = Position;
15,251✔
271
      Seek(0, SeekOrigin.Begin);
15,251✔
272
      /* .. read everything out */
273
      var data = new byte[Length];
15,251✔
274
      _ = Read(data, 0, (int) Length);
15,251✔
275
      /* restore to original position */
276
      Seek(position, SeekOrigin.Begin);
15,251✔
277
      /* .. put it in the mock system */
278
      mockFileData.Contents = data;
15,251✔
279
    }
15,251✔
280
  }
15,251✔
281

282
  private void OnClose() {
10,530✔
283
    if (options.HasFlag(FileOptions.DeleteOnClose) &&
10,530!
284
        this.imaginaryFileDataAccessor_.FileExists(path)) {
10,530✔
285
      this.imaginaryFileDataAccessor_.RemoveFile(path);
×
286
    }
×
287

288
    if (options.HasFlag(FileOptions.Encrypted) &&
10,530!
289
        this.imaginaryFileDataAccessor_.FileExists(path)) {
10,530✔
290
#pragma warning disable CA1416 // Ignore SupportedOSPlatform for testing helper encryption
291
      this.imaginaryFileDataAccessor_.FileInfo.New(path).Encrypt();
×
292
#pragma warning restore CA1416
293
    }
×
294
  }
10,530✔
295

296
  private TimeAdjustments GetTimeAdjustmentsForFileStreamWhenFileExists(
297
      FileMode mode,
298
      FileAccess access) {
10,530✔
299
    switch (mode) {
10,530!
300
      case FileMode.Append:
301
      case FileMode.CreateNew:
302
        if (access.HasFlag(FileAccess.Read)) {
×
303
          return TimeAdjustments.LastAccessTime;
×
304
        }
305

306
        return TimeAdjustments.None;
×
307
      case FileMode.Create:
308
      case FileMode.Truncate:
309
        if (access.HasFlag(FileAccess.Write)) {
×
310
          return TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime;
×
311
        }
312

313
        return TimeAdjustments.LastAccessTime;
×
314
      case FileMode.Open:
315
      case FileMode.OpenOrCreate:
316
      default:
317
        return TimeAdjustments.None;
10,530✔
318
    }
319
  }
10,530✔
320
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc