Friday, 28 October 2011

Practical TDD Interview Test

If you're given a task to be done in TDD, it's not usually whether you can resolve that problem. It's about testing whether you have the right mindset, process and coding style that TDD suggests:

  • Do you really understand the TDD Process? Benefits? Disadvantages?
  • Can you explain the TDD process?
  • Do you follow the TDD process in practice if you say you understand? e.g. if add something to the production code for which you don't have test, you have failed TDD!
  • Will you choose a small behaviour from the spec before writing any test or you think big and complex?!
  • Will you write a very small test method before writing any production code? how committed are you to this mindset?
  • Will you run all your tests after writing your test, after making a production change?
  • Would your test method names follow a proper pattern?
  • Will you make sure that you write the minimum amount of implementation code so that only one test passes? You may be able to write all the solution quickly but that’s not TDD! only write the minimum possible amount of code to pass your failed test. remember code quality is not important at this stage. Will you write the minimum possible amount of code for your tests and production code? or you make things complicated or write production code without having the test for it.
  • Will you refactor your production code after your tests passed?
When should you run all tests according to TDD?
  • After adding a test
  • After each change to the production code to pass 1 test
  • After each refactoring
How to fail TDD Process?!

A TDD practical test in an interview often means that you should rigidly demonstrate TDD:
  • If you write 1 single line of production code before you have a failing test for it, you have failed TDD!
  • If you don't run all your tests after you made a production code change, you have failed TDD!
  • If what you write is not minimized and focused only to pass your failed test and covers more scenarios than what tests you have, you have failed TDD!
  • If you don't run all your tests after your refactoring, you have failed TDD!

Monday, 17 October 2011

OUTER APPLY

a good sample for OUTER APPLY:

Returning the latest record of a child table:

SELECT ST.[SystemDetailID], ST.[SystemName], LH.LatestLoadStatus
FROM [SystemTable] AS ST
LEFT OUTER JOIN
(
SELECT LHInner.LoadStatus AS LatestLoadStatus, LHInner.SystemDetailID FROM [dbo].[LoadHistory] AS LHInner
WHERE LHInner.LoadHistoryID in
(
SELECT LatestLoadHisotoryID FROM
(
SELECT MAX(LoadHistoryID) as LatestLoadHisotoryID, SystemDetailID FROM [dbo].[LoadHistory]
GROUP BY SystemDetailID
) l
)
) AS LH ON ST.SystemDetailID = LH.SystemDetailID


A simpler/shorter approach is:



SELECT ST.[SystemDetailID],
ST.[SystemName],
LH.LatestLoadStatus
FROM [SystemTable] AS ST
OUTER APPLY (SELECT TOP 1 *
FROM [dbo].[LoadHistory] LH
WHERE ST.SystemDetailID = LH.SystemDetailID
ORDER BY LoadHistoryID DESC) LH



More info: http://technet.microsoft.com/en-us/library/ms175156.aspx

Monday, 10 October 2011

Symmetric Encryption with Rijndael Algorithm

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace MyProject
{
public interface IEncryptionManager
{
string Encrypt(string originalText);
string Decrypt(string encryptedText);
}

/// <summary>
/// This class uses the Rijndael Encryption Algorithm
/// </summary>
public class RijndaelEncryptionManager : IEncryptionManager
{
#region Fields

/// <summary>
/// The key can only be 16, 24 or 32 bytes.
/// </summary>
private static readonly byte[] EncryptionKey = new byte[] { 0x00, 0x11, 0x22, 0x03, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xC0, 0xDD, 0x0E, 0xFF };

/// <summary>
/// The vector also can only be 16, 24 or 32 bytes.
/// </summary>
private static readonly byte[] InitializationVector = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFD, 0x0E, 0x0F};

#endregion

#region Methods

public string Encrypt(string originalText)
{
using (var myRijndael = new RijndaelManaged { Key = EncryptionKey, IV = InitializationVector })
{
// Encrypt the string to an array of bytes.
var encryptedBytes = EncryptStringToBytes(originalText, myRijndael.Key, myRijndael.IV);

return Convert.ToBase64String(encryptedBytes);
}
}

public string Decrypt(string encryptedText)
{
using (var myRijndael = new RijndaelManaged { Key = EncryptionKey, IV = InitializationVector })
{
// Encrypt the string to an array of bytes.
var encryptedBytes = Convert.FromBase64String(encryptedText);

// Decrypt the bytes to a string.
return DecryptStringFromBytes(encryptedBytes, myRijndael.Key, myRijndael.IV);
}
}

/// <summary>
/// Encrypts the string to bytes.
/// </summary>
/// <param name="plainText">The plain text.</param>
/// <param name="key">The key.</param>
/// <param name="iv">The IV.</param>
/// <returns></returns>
static byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("key");
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException("key");
byte[] encrypted;
// Create an Rijndael object
// with the specified key and IV.
using (var rijAlg = Rijndael.Create())
{
rijAlg.Key = key;
rijAlg.IV = iv;

// Create a decrytor to perform the stream transform.
var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}

// Return the encrypted bytes from the memory stream.
return encrypted;

}

/// <summary>
/// Decrypts the string from bytes.
/// </summary>
/// <param name="cipherText">The cipher text.</param>
/// <param name="key">The key.</param>
/// <param name="iv">The IV.</param>
/// <returns></returns>
static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("key");
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException("key");

// Declare the string used to hold
// the decrypted text.
string plaintext = null;

// Create an Rijndael object
// with the specified key and IV.
using (var rijAlg = Rijndael.Create())
{
rijAlg.Key = key;
rijAlg.IV = iv;

// Create a decrytor to perform the stream transform.
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}

}

return plaintext;

}

#endregion
}
}

Text Encryption and Decryption

Encryption Algorithms:
  • TripleDES
  • MD5
  • SH1
  • RC4
  • CRC32