Skip to content

Commit

Permalink
Adds shareContext to LogFake (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmachado-studocu authored May 19, 2024
1 parent 600bf55 commit 6d3ce08
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 1 deletion.
42 changes: 42 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,48 @@ Log::assertCurrentContext(
); // ❌ the 'env' key is set to "production"
```

### assertHasSharedContext()

Assert that the Log manager currently has the given shared context. It is possible to provide the expected context as an array or alternatively you can provide a truth-test closure to check the current context.

#### Can be called on

- [x] Facade base (default channel)
- [ ] Channels
- [ ] Stacks

#### Example tests

```php
/*
* implementation...
*/

Log::shareContext([
'invocation-id' => '54',
]);

/*
* assertions...
*/

Log::assertHasSharedContext([
'invocation-id' => '54',
]); // ✅

Log::assertCurrentContext(
fn (array $context) => $context['invocation-id'] === '54')
); // ✅

Log::assertCurrentContext([
'invocation-id' => '99',
]); // ❌ wrong invocation ID

Log::assertCurrentContext(
fn (array $context) => $context['invocation-id'] === '99')
); // ❌ wrong invocation ID
```

## Inspection

Sometimes when debugging tests it's useful to be able to take a peek at the messages that have been logged. There are a couple of helpers to assist with this.
Expand Down
42 changes: 41 additions & 1 deletion src/LogFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ class LogFake implements LoggerInterface
*/
private array $stacks = [];

/**
* The context shared across channels and stacks.
*
* @var array<string, mixed>
*/
protected $sharedContext = [];

/**
* @link https://github.com/timacdonald/log-fake#basic-usage Documentation
*/
Expand Down Expand Up @@ -84,6 +91,25 @@ public function assertChannelIsCurrentlyForgotten(string $name, ?string $message
return $this;
}

/**
* @link ... Documentation
*
* @param (Closure(array<string, mixed>): bool)|array<string, mixed> $callback
*/
public function assertHasSharedContext(Closure|array $callback, ?string $message = null): LogFake
{
$callback = is_array($callback)
? fn ($context) => $context === $callback
: $callback;

PHPUnit::assertTrue(
$callback($this->sharedContext),
$message ?? 'Expected shared context was not found.'
);

return $this;
}

/**
* @see LogManager::build()
*
Expand Down Expand Up @@ -127,7 +153,7 @@ public function driver(?string $driver = null): ChannelFake

$channel = $this->channels[$name] ??= new ChannelFake($name);

return $channel->remember();
return $channel->remember()->withContext($this->sharedContext);
}

/**
Expand Down Expand Up @@ -225,4 +251,18 @@ private static function parseStackDriver(array $channels, ?string $channel): str
{
return 'stack::'.($channel ?? 'unnamed').':'.Collection::make($channels)->sort()->implode(',');
}

/**
* @param array<string, mixed> $context
*/
public function shareContext(array $context): LogFake
{
foreach ($this->channels as $channel) {
$channel->withContext($context);
}

$this->sharedContext = array_merge($this->sharedContext, $context);

return $this;
}
}
23 changes: 23 additions & 0 deletions tests/AssertionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -540,4 +540,27 @@ public function testAssertLoggedFuncWithNonBoolReturnedFromClosure(): void
'Expected log was not created in the [stack] channel.'
);
}

public function testAssertHasSharedContext(): void
{
$log = new LogFake();
$log->shareContext(['shared' => 'context']);

$log->assertHasSharedContext(fn ($context) => $context === ['shared' => 'context']);
self::assertFailsWithMessage(
fn () => $log->assertHasSharedContext(fn ($context) => false),
'Expected shared context was not found.'
);
}

public function testItCanProvideCustomMessageWithAssertHasSharedContext(): void
{
$log = new LogFake();
$log->shareContext(['shared' => 'context']);

self::assertFailsWithMessage(
fn () => $log->assertHasSharedContext(fn ($context) => false, 'Whoops!'),
'Whoops!'
);
}
}
52 changes: 52 additions & 0 deletions tests/LogFakeApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -632,4 +632,56 @@ public function testItClearsContextWhenAChannelIsForgotten(): void

$log->channel('channel')->assertLogged(fn (LogEntry $log) => $log->context === []);
}

public function testItSupportsSharedContextForAlreadyBuiltDrivers(): void
{
$log = new LogFake();
$channel = $log->channel('channel');
$log->shareContext([
'shared' => 'context',
]);
$channel->info('expected message', [
'local' => 'context',
]);

$log->channel('channel')->assertLogged(fn (LogEntry $log) => $log->context === [
'shared' => 'context',
'local' => 'context',
]);
}

public function testItSupportsSharedContextForNewlyBuiltDrivers(): void
{
$log = new LogFake();
$log->shareContext([
'shared' => 'context',
]);

$log->channel('channel')->info('expected message', [
'local' => 'context',
]);

$log->channel('channel')->assertLogged(fn (LogEntry $log) => $log->context === [
'shared' => 'context',
'local' => 'context',
]);
}

public function testItMergesSharedContext(): void
{
$log = new LogFake();
$log->shareContext([
'shared' => 'first',
'more' => 'context',
])->shareContext([
'shared' => 'second',
]);

$log->channel('channel')->info('expected message');

$log->channel('channel')->assertLogged(fn (LogEntry $log) => $log->context === [
'shared' => 'second',
'more' => 'context',
]);
}
}

0 comments on commit 6d3ce08

Please sign in to comment.