Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / WPF

Catel - Part 4 of n: Unit testing with Catel

Rate me:
Please Sign up or sign in to vote.
4.55/5 (10 votes)
28 Jan 2011CPOL11 min read 48.6K   572   11  
This article explains how to write unit tests for MVVM using Catel.
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="File.cs" company="Catel development team">
//   Copyright (c) 2008 - 2011 Catel development team. All rights reserved.
// </copyright>
// <summary>
//   File class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using Catel.Properties;
using Microsoft.Win32.SafeHandles;

namespace Catel.IO
{
    /// <summary>
    /// File class.
    /// </summary>
    public static class File
    {
        /// <summary>
        /// Copies the specified file to the destination path. Overwriting of the destination file is allowed.
        /// </summary>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="destinationFileName">Name of the destination file.</param>
        /// <returns>
        /// 	<c>true</c> if the file is copied; otherwise <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="sourceFileName"/> is <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentException">when <paramref name="destinationFileName"/> is <c>null</c> or empty.</exception>
        public static bool Copy(string sourceFileName, string destinationFileName)
        {
            return Copy(sourceFileName, destinationFileName, false);
        }

        /// <summary>
        /// Copies the specified file to the destination path.
        /// </summary>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="destinationFileName">Name of the destination file.</param>
        /// <param name="failIfExist">if set to <c>true</c>, the copy action will fail if the destination file already exists.</param>
        /// <returns>
        /// 	<c>true</c> if the file is copied; otherwise <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="sourceFileName"/> is <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentException">when <paramref name="destinationFileName"/> is <c>null</c> or empty.</exception>
        public static bool Copy(string sourceFileName, string destinationFileName, bool failIfExist)
        {
            if (string.IsNullOrEmpty(sourceFileName))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "sourceFileName");
            }

            if (string.IsNullOrEmpty(destinationFileName))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "destinationFileName");
            }

            sourceFileName = Path.AddWin32LongFileNamePrefix(sourceFileName);
            destinationFileName = Path.AddWin32LongFileNamePrefix(destinationFileName);

            return Win32IOApi.CopyFile(sourceFileName, destinationFileName, failIfExist);
        }

        /// <summary>
        /// Creates the specified file.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>
        /// 	<see cref="System.IO.FileStream"/> of the file.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static FileStream Create(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "filePath");
            }

            return Open(filePath, FileMode.Create, FileAccess.ReadWrite);
        }

        /// <summary>
        /// Deletes the specified file.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>
        ///		<c>true</c> if the file is deleted; otherwise <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static bool Delete(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "filePath");
            }

            filePath = Path.AddWin32LongFileNamePrefix(filePath);

            return Win32IOApi.DeleteFile(filePath);
        }

        /// <summary>
        /// Checks whether the specified file exists.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>
        /// 	<c>true</c> if the file exists; otherwise <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">when <paramref name="filePath"/> is <c>null</c>.</exception>
        public static bool Exists(string filePath)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }

            if (string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            Win32IOApi.WIN32_FIND_DATA findData;

            filePath = Path.AddWin32LongFileNamePrefix(filePath);

            IntPtr findHandle = Win32IOApi.FindFirstFile(filePath, out findData);
            if (findHandle != Win32IOApi.INVALID_HANDLE_VALUE)
            {
                Win32IOApi.FindClose(findHandle);
                return true;
            }

            return false;
        }

        /// <summary>
        /// Gets the size of the file.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>Length of the file or <c>0</c> if file is not found.</returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static long GetFileSize(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "filePath");
            }

            filePath = Path.AddWin32LongFileNamePrefix(filePath);

            try
            {
                using (FileStream fileStream = OpenRead(filePath))
                {
                    return fileStream.Length;
                }
            }
            catch (Exception)
            {
                return 0L;
            }
        }

        /// <summary>
        /// Opens the specified filePath as a filestream with read and write access and no share permissions.
        /// </summary>
        /// <param name="filePath">The filePath.</param>
        /// <param name="mode">The file mode.</param>
        /// <returns><see cref="System.IO.FileStream"/> of the file.</returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static FileStream Open(string filePath, FileMode mode)
        {
            return Open(filePath, mode, FileAccess.ReadWrite);
        }

        /// <summary>
        /// Opens the specified filePath as a filestream with the specified access and no share permissions.
        /// </summary>
        /// <param name="filePath">The filePath.</param>
        /// <param name="mode">The file mode.</param>
        /// <param name="access">The file access.</param>
        /// <returns>
        /// 	<see cref="System.IO.FileStream"/> of the file.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static FileStream Open(string filePath, FileMode mode, FileAccess access)
        {
            return Open(filePath, mode, access, FileShare.None);
        }

        /// <summary>
        /// Opens the specified filePath as a filestream for reading only.
        /// </summary>
        /// <param name="filePath">The filePath.</param>
        /// <returns>
        /// 	<see cref="System.IO.FileStream"/> of the file.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static FileStream OpenRead(string filePath)
        {
            return Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        /// <summary>
        /// Opens the specified filePath as a filestream for writing only.
        /// </summary>
        /// <param name="filePath">The filePath.</param>
        /// <returns>
        /// 	<see cref="System.IO.FileStream"/> of the file.
        /// </returns>
        public static FileStream OpenWrite(string filePath)
        {
            return Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
        }

        /// <summary>
        /// Opens the specified filePath as a filestream with the specified access and share permissions.
        /// </summary>
        /// <param name="filePath">The filePath.</param>
        /// <param name="mode">The file mode.</param>
        /// <param name="access">The file access.</param>
        /// <param name="share">The file share.</param>
        /// <returns>
        /// 	<see cref="System.IO.FileStream"/> of the file.
        /// </returns>
        /// <exception cref="ArgumentException">when <paramref name="filePath"/> is <c>null</c> or empty.</exception>
        public static FileStream Open(string filePath, FileMode mode, FileAccess access, FileShare share)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(Exceptions.ArgumentCannotBeNullOrEmpty, "filePath");
            }

            uint umode = GetMode(mode);
            uint uaccess = GetAccess(access);
            uint ushare = GetShare(share);
            if (mode == FileMode.Append)
            {
                uaccess = Win32IOApi.FILE_APPEND_DATA;
            }

            filePath = Path.AddWin32LongFileNamePrefix(filePath);

            SafeFileHandle sh = Win32IOApi.CreateFileW(filePath, uaccess, ushare, IntPtr.Zero, umode, Win32IOApi.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            int errorInterface = Marshal.GetLastWin32Error();
            if ((errorInterface > 0 && !(mode == FileMode.Append && errorInterface != Win32IOApi.ERROR_ALREADY_EXISTS)) || sh.IsInvalid)
            {
                throw new FileNotFoundException(string.Format(CultureInfo.CurrentCulture, Exceptions.ErrorOpeningFileViaWin32, errorInterface), filePath);
            }

            FileStream fs = new FileStream(sh, access);

            if (mode == FileMode.Append)
            {
                if (!sh.IsInvalid)
                {
                    Win32IOApi.SetFilePointer(sh, 0, IntPtr.Zero, Win32IOApi.FILE_END);
                }
            }

            return fs;
        }

        /// <summary>
        /// Gets the mode.
        /// </summary>
        /// <param name="mode">The file mode.</param>
        /// <returns>Win32 mode of the file.</returns>
        private static uint GetMode(FileMode mode)
        {
            uint umode = 0;
            switch (mode)
            {
                case FileMode.CreateNew:
                    umode = Win32IOApi.CREATE_NEW;
                    break;

                case FileMode.Create:
                    umode = Win32IOApi.CREATE_ALWAYS;
                    break;

                case FileMode.Append:
                    umode = Win32IOApi.OPEN_ALWAYS;
                    break;

                case FileMode.Open:
                    umode = Win32IOApi.OPEN_EXISTING;
                    break;

                case FileMode.OpenOrCreate:
                    umode = Win32IOApi.OPEN_ALWAYS;
                    break;

                case FileMode.Truncate:
                    umode = Win32IOApi.TRUNCATE_EXISTING;
                    break;
            }

            return umode;
        }

        /// <summary>
        /// Converts the FileAccess constant to win32 constant.
        /// </summary>
        /// <param name="access">The access.</param>
        /// <returns>Win32 access of the file.</returns>
        private static uint GetAccess(FileAccess access)
        {
            uint uaccess = 0;
            switch (access)
            {
                case FileAccess.Read:
                    uaccess = Win32IOApi.GENERIC_READ;
                    break;

                case FileAccess.ReadWrite:
                    uaccess = Win32IOApi.GENERIC_READ | Win32IOApi.GENERIC_WRITE;
                    break;

                case FileAccess.Write:
                    uaccess = Win32IOApi.GENERIC_WRITE;
                    break;
            }

            return uaccess;
        }

        /// <summary>
        /// Converts the FileShare constant to win32 constant.
        /// </summary>
        /// <param name="share">The share.</param>
        /// <returns>Win32 share of the file.</returns>
        private static uint GetShare(FileShare share)
        {
            uint ushare = 0;
            switch (share)
            {
                case FileShare.Read:
                    ushare = Win32IOApi.FILE_SHARE_READ;
                    break;

                case FileShare.ReadWrite:
                    ushare = Win32IOApi.FILE_SHARE_READ | Win32IOApi.FILE_SHARE_WRITE;
                    break;

                case FileShare.Write:
                    ushare = Win32IOApi.FILE_SHARE_WRITE;
                    break;

                case FileShare.Delete:
                    ushare = Win32IOApi.FILE_SHARE_DELETE;
                    break;

                case FileShare.None:
                    ushare = 0;
                    break;
            }

            return ushare;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions