Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,39 +238,3 @@ jobs:
state: released
skip-label: |
state: released
Comment on lines 238 to 240

build-pages:
name: "Build Pages"
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup .NET SDKs
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
10.0.x
- name: Get documentation from extensions
run: ./build.sh Pages
env:
GithubToken: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v6
with:
node-version: 20
cache: npm
cache-dependency-path: ./Docs/pages/package-lock.json
- name: Install dependencies
working-directory: ./Docs/pages
run: npm ci --ignore-scripts
- name: Build website
working-directory: ./Docs/pages
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./Docs/pages/build
22 changes: 22 additions & 0 deletions .github/workflows/notify-docs-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Notify Docs Site

on:
push:
branches: [ main ]
paths:
- 'Docs/pages/docs/**'
- '.github/workflows/notify-docs-site.yml'
workflow_dispatch:

jobs:
dispatch:
name: Trigger Site rebuild
runs-on: ubuntu-latest
steps:
- name: Dispatch extension-documentation-updated-event to Testably/Testably.Site
uses: peter-evans/repository-dispatch@v3
Comment on lines +16 to +17
with:
token: ${{ secrets.SITE_DISPATCH_TOKEN }}
repository: Testably/Testably.Site
event-type: extension-documentation-updated-event
client-payload: '{"source": "${{ github.repository }}", "sha": "${{ github.sha }}"}'
42 changes: 0 additions & 42 deletions .github/workflows/pages.yml

This file was deleted.

20 changes: 0 additions & 20 deletions Docs/pages/.gitignore

This file was deleted.

55 changes: 0 additions & 55 deletions Docs/pages/README.md

This file was deleted.

112 changes: 112 additions & 0 deletions Docs/pages/docs/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Testably.Abstractions
slug: /abstractions/
sidebar_position: -1
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

[![Testably.Abstractions](https://img.shields.io/nuget/v/Testably.Abstractions?label=Testably.Abstractions&logo=nuget)](https://www.nuget.org/packages/Testably.Abstractions)
[![Testably.Abstractions.Testing](https://img.shields.io/nuget/v/Testably.Abstractions.Testing?label=Testably.Abstractions.Testing&logo=nuget)](https://www.nuget.org/packages/Testably.Abstractions.Testing)

`Testably.Abstractions` is a feature-complete testing helper for the [`IFileSystem`](https://github.com/TestableIO/System.IO.Abstractions) abstractions of the `System.IO` namespace, plus matching abstractions for time and randomness.

## Inject. Mock. Test.

Depend on `IFileSystem`, `ITimeSystem` and `IRandomSystem` in production. Swap in the in-memory mocks for tests — deterministic, cross-platform, no temp folders or `Thread.Sleep`.

<Tabs groupId="testablyAbstractionsSample">
<TabItem value="file" label="File system" default>

```csharp title="ReportService.cs"
public class ReportService(IFileSystem fileSystem)
{
public void Save(string content)
{
fileSystem.Directory.CreateDirectory("reports");
fileSystem.File.WriteAllText("reports/latest.xml", content);
}
}
```

```csharp title="ReportServiceTests.cs"
[Fact]
public async Task Save_WritesReportToReportsFolder()
{
var fileSystem = new MockFileSystem();
var sut = new ReportService(fileSystem);

sut.Save("<report />");

await Expect.That(fileSystem.File.ReadAllText("reports/latest.xml"))
.IsEqualTo("<report />");
}
```

</TabItem>
<TabItem value="time" label="Time system">

```csharp title="CacheEntry.cs"
public class CacheEntry(ITimeSystem timeSystem, TimeSpan ttl)
{
private readonly DateTime _expiresAt = timeSystem.DateTime.UtcNow + ttl;

public bool IsExpired => timeSystem.DateTime.UtcNow >= _expiresAt;
}
```

```csharp title="CacheEntryTests.cs"
[Fact]
public async Task IsExpired_ReturnsTrue_AfterTtlPasses()
{
MockTimeSystem timeSystem = new(new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc));
var entry = new CacheEntry(timeSystem, TimeSpan.FromMinutes(5));

await timeSystem.Task.Delay(TimeSpan.FromMinutes(6));

await Expect.That(entry.IsExpired).IsTrue();
}
```

</TabItem>
<TabItem value="random" label="Random system">

```csharp title="CorrelationIdProvider.cs"
public class CorrelationIdProvider(IRandomSystem randomSystem)
{
public string Next() => randomSystem.Guid.NewGuid().ToString();
}
```

```csharp title="CorrelationIdProviderTests.cs"
[Fact]
public async Task Next_ReturnsConfiguredGuid_ForDeterministicTests()
{
MockRandomSystem randomSystem = new(RandomProvider.Generate(
guidGenerator: () => Guid.Parse("11111111-1111-1111-1111-111111111111")));
var sut = new CorrelationIdProvider(randomSystem);

await Expect.That(sut.Next())
.IsEqualTo("11111111-1111-1111-1111-111111111111");
}
```

</TabItem>
</Tabs>

## Why another file system mock?

`Testably.Abstractions` shares the `IFileSystem` interface with [TestableIO.System.IO.Abstractions](https://github.com/TestableIO/System.IO.Abstractions) - your **production code does not change** when you switch testing libraries. What you get on top:

- Advanced testing scenarios: `FileSystemWatcher`, `SafeFileHandle`, multiple drives with size limits.
- Cross-platform simulation: run a Linux file system on Windows (and vice versa) to exercise platform-specific behaviour from a single CI job.
- A second abstraction layer for time and randomness.

See [Migration from TestableIO](./migration-from-testableio) if you are already using TestableIO.

## Where to go next

- **[Getting Started](./getting-started)** — install the packages and wire them up.
- **[File system](./file-system)**, **[Time system](./time-system)**, **[Random system](./random-system)** — explore each abstraction.
- **[Companion libraries](./companion-libraries)** — ZIP and ACL helpers.
60 changes: 0 additions & 60 deletions Docs/pages/docs/intro.mdx

This file was deleted.

Loading
Loading