addIteration(1, 0, 0.5, []); $buffer->addIteration(1, 1, 0.25, []); $buffer->flush(); Event::assertDispatched(PerceptronTrainingIteration::class, function (PerceptronTrainingIteration $event): bool { return count($event->iterations) === 2; }); } public function test_limited_buffer_sends_the_latest_non_selected_epoch_on_final_flush(): void { Event::fake(); $buffer = new PerceptronLimitedEpochEventBuffer('session', 'training', 2); $buffer->addIteration(1, 0, 0.5, []); $buffer->addIteration(2, 0, 0.25, []); $buffer->addIteration(2, 1, 0.125, []); $buffer->flush(); Event::assertDispatchedTimes(PerceptronTrainingIteration::class, 2); Event::assertDispatched(PerceptronTrainingIteration::class, function (PerceptronTrainingIteration $event): bool { return count($event->iterations) === 2 && $event->iterations[0]['epoch'] === 2; }); } public function test_non_finite_values_are_normalized_before_broadcasting(): void { $event = new PerceptronTrainingIteration([ [ 'epoch' => 1, 'exampleIndex' => 0, 'error' => NAN, 'weights' => [[[INF]]], ], ], 'session', 'training'); $payload = $event->broadcastWith(); $this->assertNull($payload['iterations'][0]['error']); $this->assertNull($payload['iterations'][0]['weights'][0][0][0]); $this->assertJson(json_encode($payload, JSON_THROW_ON_ERROR)); } }