{-# LANGUAGE MultiParamTypeClasses,GeneralizedNewtypeDeriving,TypeSynonymInstances,UndecidableInstances,FlexibleContexts,FlexibleInstances #-}
-- | some framework to test Editor m w functions, intercepting the console part of the IO
module Test where
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Error

import Control.Monad.Writer

import Editor
import Eval
import Operation
import Parser
import Undo

type Line = String

[ebuffer,eend] = ["Buffer index error","End"]

data Emulator = Emulator {
	cinput	:: [Line],
	coutput :: [Line],
	cerror 	:: [Line],
	chistory:: [Line]
	} deriving Show
type CState = State Emulator

outputT :: String -> CState () 
outputT x = modify (\y -> y{coutput = x:coutput y})
errorT :: String -> CState () 
errorT x = modify (\y -> y{cerror = x:cerror y})
historyT x = modify (\y -> y{chistory = x:chistory y})


inputT :: String -> CState (Maybe String)
inputT _ = get >>= \y -> let t = cinput y in if null t then return Nothing else put y{cinput = tail t} >> return (Just (head t))


instance SIO CState where
	inputSio 	= inputT
	outputSio	= outputT
	errorSIO	= errorT
	historySio	= historyT
	readfileSio 	= undefined
	writefileSio	= undefined
	externalSio	= undefined
	commandhelpSIO	= undefined

runT = execState (run (commandLoop parse eval) zeroState :: CState Stato)
--test is mos mes mhs = let Emulator _ os es hs = runT is [] [] []
	-- in maybe True (== os) mos && maybe True (== es) mes && maybe True (== hs) mhs

{-
tStrings xs field = Just $ (\e -> field e == reverse xs
type TestT = Maybe (Emulator -> Writer String Bool)

andTest 	:: Emulator -> [TestT] -> Writer [String] Bool
andTest	_ [] 		= return True
andTest e (t:ts)	= do 	s <- andTest e ts
				r <- maybe (return True) (t e)  
				return (r && s)

loadFile x = readFile x >>= return  . ("a" :) . lines
-}