blob: 7df32b052c475e3b06f7a757c34d813ea0237f7e [file]
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
module WriterTest (writerTests) where
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.ByteString.Char8 as BS8
import OpenDAL
import Test.Tasty
import Test.Tasty.HUnit
writerTests :: TestTree
writerTests =
testGroup
"Writer Tests"
[ testCase "testWriterSequentialWrites" testWriterSequentialWrites,
testCase "testWriterLargeData" testWriterLargeData,
testCase "testWriterEmptyData" testWriterEmptyData,
testCase "testWriterBinaryData" testWriterBinaryData,
testCase "testAppendToNonExistent" testAppendToNonExistent,
testCase "testAppendMultipleTimes" testAppendMultipleTimes,
testCase "testWriterErrorHandling" testWriterErrorHandling
]
testWriterSequentialWrites :: Assertion
testWriterSequentialWrites = do
Right op <- newOperator "memory"
Right writer <- writerOpRaw op "sequential-test" defaultWriterOption
-- Write in multiple chunks
writerWrite writer "Line 1\n" ?= Right ()
writerWrite writer "Line 2\n" ?= Right ()
writerWrite writer "Line 3\n" ?= Right ()
Right meta <- writerClose writer
mContentLength meta @?= 21
-- Verify content
readOpRaw op "sequential-test" ?= Right "Line 1\nLine 2\nLine 3\n"
testWriterLargeData :: Assertion
testWriterLargeData = do
Right op <- newOperator "memory"
Right writer <- writerOpRaw op "large-data-test" defaultWriterOption
-- Write 1KB of data in chunks
let chunk = BS8.replicate 100 'A'
mapM_ (\_ -> writerWrite writer chunk ?= Right ()) [1..10 :: Int]
Right meta <- writerClose writer
mContentLength meta @?= 1000
-- Verify first few bytes
Right content <- readOpRaw op "large-data-test"
BS8.take 10 content @?= "AAAAAAAAAA"
BS8.length content @?= 1000
testWriterEmptyData :: Assertion
testWriterEmptyData = do
Right op <- newOperator "memory"
Right writer <- writerOpRaw op "empty-test" defaultWriterOption
-- Write empty data
writerWrite writer "" ?= Right ()
Right meta <- writerClose writer
mContentLength meta @?= 0
-- Verify content
readOpRaw op "empty-test" ?= Right ""
testWriterBinaryData :: Assertion
testWriterBinaryData = do
Right op <- newOperator "memory"
Right writer <- writerOpRaw op "binary-test" defaultWriterOption
-- Write binary data (all bytes 0-255)
let binaryData = BS8.pack ['\0'..'\255']
writerWrite writer binaryData ?= Right ()
Right meta <- writerClose writer
mContentLength meta @?= 256
-- Verify content
Right content <- readOpRaw op "binary-test"
content @?= binaryData
testAppendToNonExistent :: Assertion
testAppendToNonExistent = do
Right op <- newOperator "memory"
-- Verify file doesn't exist
isExistOpRaw op "new-append-file" ?= Right False
-- Write to non-existent file using writer API (should create it)
Right writer <- writerOpRaw op "new-append-file" defaultWriterOption
writerWrite writer "First content" ?= Right ()
writerClose writer >>= \case
Right _ -> return ()
Left err -> assertFailure $ "Failed to close writer: " ++ show err
-- Verify file was created
isExistOpRaw op "new-append-file" ?= Right True
readOpRaw op "new-append-file" ?= Right "First content"
testAppendMultipleTimes :: Assertion
testAppendMultipleTimes = do
Right op <- newOperator "memory"
-- Multiple write operations using writer API
Right writer <- writerOpRaw op "multi-append" defaultWriterOption
writerWrite writer "Hello" ?= Right ()
writerWrite writer " " ?= Right ()
writerWrite writer "World" ?= Right ()
writerWrite writer "!" ?= Right ()
writerClose writer >>= \case
Right _ -> return ()
Left err -> assertFailure $ "Failed to close writer: " ++ show err
-- Verify final content
readOpRaw op "multi-append" ?= Right "Hello World!"
testWriterErrorHandling :: Assertion
testWriterErrorHandling = do
Right op <- newOperator "memory"
-- Test writing to invalid path (should work with memory backend)
-- Memory backend is permissive, so let's test a more complex scenario
Right writer <- writerOpRaw op "test-file" defaultWriterOption
writerWrite writer "some data" ?= Right ()
-- Close writer successfully
Right meta <- writerClose writer
mContentLength meta @?= 9
-- helper function
(?=) :: (MonadIO m, Eq a, Show a) => m a -> a -> m ()
result ?= except = result >>= liftIO . (@?= except)