<commit_before>﻿namespace Eventful.Testing

open System
open Eventful
open FSharpx.Collections
open FSharpx
open FSharpx.Choice
open FSharpx.Option
open Eventful.EventStream

type TestSystemState<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent when 'TMetadata : equality and 'TEventContext :> IDisposable> = {
    Handlers : EventfulHandlers<'TCommandContext,'TEventContext,'TMetadata, 'TBaseEvent> 
    LastResult : CommandResult<'TBaseEvent,'TMetadata>
    AllEvents : TestEventStore<'TMetadata>
    BuildEventContext: PersistedEvent<'TMetadata> -> 'TEventContext
    OnTimeChange : UtcDateTime -> unit
    UseSnapshots : bool
}

type TestSystem<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent when 'TMetadata : equality and 'TEventContext :> IDisposable>
    (
        state : TestSystemState<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent>
    ) =

    let interpret prog (testEventStore : TestEventStore<'TMetadata>) =
        TestInterpreter.interpret 
            prog 
            testEventStore 
            state.UseSnapshots
            state.Handlers.EventStoreTypeToClassMap 
            state.Handlers.ClassToEventStoreTypeMap
            Map.empty 
            Vector.empty

    let interpreter = {
        new IInterpreter<'TMetadata> with
            member x.Run program testEventStore = 
                interpret program testEventStore
    }

    member x.RunCommandNoThrow (cmd : obj) (context : 'TCommandContext) =    
        let program = EventfulHandlers.getCommandProgram context cmd state.Handlers
        let (allEvents, result) = interpret program state.AllEvents
<commit_msg>Added RunStreamProgram to TestSystem<commit_after>﻿namespace Eventful.Testing

open System
open Eventful
open FSharpx.Collections
open FSharpx
open FSharpx.Choice
open FSharpx.Option
open Eventful.EventStream

type TestSystemState<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent when 'TMetadata : equality and 'TEventContext :> IDisposable> = {
    Handlers : EventfulHandlers<'TCommandContext,'TEventContext,'TMetadata, 'TBaseEvent> 
    LastResult : CommandResult<'TBaseEvent,'TMetadata>
    AllEvents : TestEventStore<'TMetadata>
    BuildEventContext: PersistedEvent<'TMetadata> -> 'TEventContext
    OnTimeChange : UtcDateTime -> unit
    UseSnapshots : bool
}

type TestSystem<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent when 'TMetadata : equality and 'TEventContext :> IDisposable>
    (
        state : TestSystemState<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent>
    ) =

    let interpret prog (testEventStore : TestEventStore<'TMetadata>) =
        TestInterpreter.interpret 
            prog 
            testEventStore 
            state.UseSnapshots
            state.Handlers.EventStoreTypeToClassMap 
            state.Handlers.ClassToEventStoreTypeMap
            Map.empty 
            Vector.empty

    let interpreter = {
        new IInterpreter<'TMetadata> with
            member x.Run program testEventStore = 
                interpret program testEventStore
    }

    member x.RunStreamProgram program = 
        let (allEvents, result) = interpret program state.AllEvents
        (result, new TestSystem<'TMetadata, 'TCommandContext, 'TEventContext, 'TBaseEvent>({ state with AllEvents = allEvents }))

    member x.RunCommandNoThrow (cmd : obj) (context : 'TCommandContext) =    
        let program = EventfulHandlers.getCommandProgram context cmd state.Handlers
        let (allEvents, result) = interpret program state.AllEvents

{'fraction_non_alphanumeric': 0.07694483734087694, 'fraction_numerical': 0.0, 'mean_word_length': 3.5044585987261145, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7130788', 'n_tokens_mistral': 988, 'n_tokens_neox': 976, 'n_words': 224}