نظرات مطالب
Subversion 1.6.0
RocketSVN for Visual Studio رایگان شد! (+)
همچنین RocketSVN Server : (+)
مطالب
بازسازی LocalDb
LocalDb یک نسخه‌ی کوچک شده از SQL Express 2012 است که نیازی به سرویس ندارد که سبب سهولت استفاده از آن را در پروژه‌های Visual Studio  فراهم می‌آورد و یک ویژگی بسیار خوب برای برنامه‌هایی است که نیاز به استفاده از کلیه‌ی امکانات مهیای SQL Server را ندارند. یکی دیگر از ویژگی‌های آن استفاده در محیط هایی است که اطمینانی از نصب بودن SQL Express در آن‌ها نداریم.
در حین توسعه‌ی نرم افزار ممکن است استفاده از LocalDb امکان پذیر نباشد و خللی در کارکرد آن ایجاد شده باشد و عملا استفاده از آن میسر نشود. اتفاقی که برای من روز گذشته رخ داد و مجبور شدم LocalDb را مجددا نصب نمایم ولی همچنان مشکل وجود داشت. بعد از جستجو به این لینک و این لینک رسیدم که جمع بندی آن بشرح زیر است:
ابتدا command  prompt را اجرا می‌نماییم (ترجیحا بصورت Administrator اجرا شود) سپس به محلی که Instanceهای LocalDb قرار دارد
 (localappdata\Microsoft\Microsoft SQL Server Local DB\Instances\v11.0) رفته و دستور زیر را صادر می‌نماییم:
sqllocaldb create "v11.0"
در صورتیکه خطای زیر نمایش داده شد، مراحل بعد را انجام می‌دهیم.
Creation of LocalDB instance "v11.0" with version 11.0 failed because of the following error: 
LocalDB instance is corrupted. See the Windows Application event log for event details.
هنگامیکه خطای فوق نمایش داده شده، باید ابتدا LocalDb را حذف و مجددا آن را ساخت.
sqllocaldb delete "v11.0"
دستور فوق عملیات حذف را انجام می‌دهد.
و دستور زیر مجددا یک وهله‌ی نسخه 11.0 بنام"v11.0" را از LocalDb ایجاد می‌کند.
sqllocaldb create "v11.0"
تا اینجا کلیه‌ی اقدامات لازم جهت راه اندازی مجدد LocalDb انجام شد و هم اکنون می‌توانید از آن استفاده نمایید.
مطالب
Serialization #1
در این نوشتار به Serialization و Deserialization  یعنی مکانیزمی که توسط آن اشیاء می‌توانند به صورت متنی مسطح و یا به شکل باینری درآیند، پرداخته می‌شود.

مفهوم Serialization
سریالی کردن، عملیاتی است که یک شیء و یا مجموعه اشیائی که به یکدیگر ارجاع می‌دهند را به شکل گروهی از بایت‎ها یا فرمت XML درآورده که می‌توان آن‎ها را ذخیره کرد و یا انتقال داد. 
Deserialization  معکوس عملیات بالاست که گروهی از داده‌ها را دریافت کرده و بصورت یک شیء  و یا مجموعه‌ای از اشیائی که به یکدیگر ارجاع می‌دهند، تبدیل می‌کند.
Serialization و Deserialization  نوعاً برای موارد زیر بکار می‌روند:
  1. انتقال اشیاء از طریق یک شبکه یا مرز یک نرم افزار .
  2. ذخیره اشیاء در یک فایل یا بانک اطلاعاتی.
موتورهای سریالی‌کننده
چهار شیوه برای سریالی کردن در دات نت فریم ورک وجود دارد:
  1. سریالی‌کننده قرارداد داده (Data Contract Serializer)
  2. سریالی‌کننده باینری
  3. سریالی‌کننده XML مبتنی بر صفت
  4. سریالی‌کننده اینترفیس IXmlSerializer
سه مورد اول، موتورهای سریالی‌کننده‌ای هستند که بیشترین یا تقریباً همه کارهای سریالی‌کردن را انجام می‌دهند.  مورد آخر برای انجام مواردی است که خودتان قصد سریالی‌سازی دارید که این موتور با استفاده از XmlReader  و XmlWriter این کار را انجام می‌دهد. IXmlSerializer می‌تواند به همراه سریالی‌کننده قرارداد داده و یا سریالی‌کننده XML در موارد پیچیده سریالی‌کردن استفاده شود.
سریالی‌کننده Data Contract 
برای انجام این کار دو نوع سریالی‌کننده وجود دارد :
  1. DataContractSerializer، که اصطلاحاً loosely Coupled شده است به نوع سریالی‌کننده  Data Contract.
  2. NetDataContractSerializer که اصطلاحاً tightly Coupled شده است به نوع سریالی‌کننده  Data Contract.
مدل زیر را در نظر بگیرید:
public class News
    {
        public int Id;
        public string Body;
        public DateTime NewsDate;
    }
برای سریالی‌کردن نوع News به شیوه  Data Contract، باید:
  1. فضای نام System.Runtime.Serialization را به کد برنامه اضافه کنیم.
  2. صفت [DataContract] را به نوعی که تعریف کرده‌ایم، اضافه کنیم.
  3. صفت [DataMember] را به اعضایی که می‌خواهیم در سریالی شدن شرکت‌کنند، اضافه کنیم.
و به این ترتیب کلاس News به شکل زیر درمی‌آید:
using System.Runtime.Serialization;
using System.Xml;
using System;
using System.IO;
namespace ConsoleApplication1
{  
    [DataContract]
    public class News
    {
        [DataMember] public int Id;
        [DataMember] public string Body;
        [DataMember] public DateTime NewsDate;
    }
}
سپس به شکل زیر از مدل خود نمونه‌ای ساخته و با ایجاد یک فایل، نتیجه سریالی شده مدل را در آن ذخیره میکنیم .
var news = new News
                           {
                               Id = 1,
                               Body = "NewsBody",
                               NewsDate = new DateTime(2012, 10, 4)
                           };
 var ds = new DataContractSerializer(typeof (News));
 using (Stream s=File.Create("News.Xml"))
 {
        ds.WriteObject(s, news);//سریالی‌کردن
 }
که محتویات فایل News.Xml به صورت زیر است:
<News xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication7" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Body>NewsBody</Body><Id>1</Id><NewsDate>2012-10-04T00:00:00</NewsDate></News>
و برای Deserialize  کردن این فایل داریم:
News deserializednews;
using (Stream s = File.OpenRead("News.Xml"))
{
       deserializednews = (News)ds.ReadObject(s);//Deserializing
}
Console.WriteLine(deserializednews.Body);
همان‌طور که ملاحظه می‌کنید فایل ایجاد شده از خوانایی خوبی برخوردار نیست که برای دستیابی به فایلی با خوانایی بالاتر از XmlWriter استفاده میکنیم:
XmlWriterSettings settings = new XmlWriterSettings {Indent = true}; 
using (XmlWriter writer = XmlWriter.Create("News.Xml", settings))
{
          ds.WriteObject(writer, news);
}
System.Diagnostics.Process.Start("News.Xml");
به این ترتیب موفق به ایجاد فایلی با خوانایی بالاتر می‌شویم:
<?xml version="1.0" encoding="utf-8"?>
<News xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication7">
  <Body>NewsBody</Body>
  <Id>1</Id>
  <NewsDate>2012-10-04T00:00:00</NewsDate>
</News> 
نظرات اشتراک‌ها
نظرات یک استفاده کننده از TFS پس از سه سال تجربه کار با آن
من از نسخه 2005 که در حقیقت Source Safe بود به صورت مداوم با این محصول کار کردم. نقاط ضعف بسیاری داشت که به مرور در نسخه‌های 2008 و 2010 برطرف شدند. به نظرم TFS 2010 به تکامل خوبی رسیده و نیاز‌مندی‌های ما رو تاکنون پوشش داده است.
اما اخیرا در نسخه ویژوال استودیو 2012 احساس کردم کار با TFS در گنگ‌تر شده است. (منظورم Team Explorer آن هست) نسخه نهایی TFS 2012 را دریافت کرده‌ام اما هنوز برنامه‌ای برای مهاجرت به آن از نسخه 2010 نداریم. بسیاری از مواردی که در این لینک به شکل انتقادی بیان شده‌اند قرار است در نسخه جدید رفع شده و یا بهبود یابند.
به هر حال نظرات متفاوت‌اند و هر نظری محترم. هر کسی از دید نیاز‌های خود می‌سنجد و از این لحاظ اینجانب TFS رو محصولی قوی و کارساز می‌دونم.
اشتراک‌ها
Xamarin Live Player - VS 2017 version 15.4 & 15.5 فوق العاده

Last week Visual Studio 2017 version 15.4 and VS for Mac 7.2 were released into the stable channel. They include the very first release of the Xamarin Live Player capabilities in Visual Studios. This means you can simply update Visual Studio, turn on Xamarin Live Player (Preview), and get started visualizing your mobile apps with nothing more than VS and your iOS or Android device! 
Xamarin Live Player - VS 2017 version 15.4 & 15.5 فوق العاده
مطالب
Microsoft® SQL Server® 2012

نگارش نهایی Microsoft® SQL Server® 2012 چند روزی هست که ارائه شده. فعلا نسخه آزمایشی RTM آن در اختیار عموم است.
در ادامه جمع آوری لینک‌های مرتبط به این ارائه را مشاهده خواهید نمود:


و یک جدول مقایسه‌ای بین امکانات نگارش‌های رایگان SQL Server 2012 در اینجا

مطالب
استفاده از EF7 با پایگاه داده SQLite تحت NET Core. به کمک Visual Studio Code
در این مقاله سعی داریم مراحل نوشتن و اجرای یک برنامه‌ی ساده را تحت NET Core. و با بهره گیری از دیتابیس SQLite و EF7، دنبال کنیم. همچنین از آنجایی‌که NET Core. به صورت چندسکویی طراحی شده‌است و تحت لینوکس و مکینتاش هم قابل اجراست، در نتیجه مناسب دیدم که ابزار نوشتن این پروژه‌ی ساده نیز قابلیت چندسکویی داشته و تحت لینوکس و مکینتاش نیز قابل اجرا باشد. در نتیجه به جای Visual Studio در این مقاله از Visual Studio Code استفاده شده است.

ابزارهای پیش نیاز:
  1. Visual Studio Code
  2. .NET Core
در اولین قدم، برنامه‌ی متن باز Visual Studio Code را از اینجا دانلود و نصب کنید. برنامه‌ی Visual Studio Code که در ادامه‌ی فعالیت‌های جدید متن باز مایکروسافت به بازار عرضه شده است، سریع، سبک و کاملا قابل توسعه و سفارشی سازی است و از اکثر زبان‌های معروف پشتیبانی می‌کند.
در قدم بعدی، شما باید NET Core. را از اینجا (64 بیتی) دانلود و نصب کنید.

 .NET Core چیست؟
NET Core. در واقع پیاده سازی بخشی از NET. اصلی است که به صورت متن باز در حال توسعه می‌باشد و بر روی لینوکس و مکینتاش هم قابل اجراست. موتور اجرای دات نت کامل CLR نام دارد و NET Core. نیز دارای موتور اجرایی CoreCLR است و شامل فریمورک CoreFX می‌باشد.

در حال حاضر شما می‌توانید با استفاده از NET Core. برنامه‌های کنسولی و تحت وب با ASP.NET 5 بنویسید و احتمالا در آینده می‌توان امیدوار بود که از ساختارهای پیچیده‌تری مثل WPF نیز پشتیبانی کند.

پس از آنکه NET Core. را دانلود و نصب کردید، جهت شروع پروژه، یک پوشه را در یکی از درایوها ساخته (در این مثال E:\Projects\EF7-SQLite-NETCore) و Command prompt را در آنجا باز کنید. سپس دستورات زیر را به ترتیب اجرا کنید:

dotnet new
dotnet restore
dotnet run

دستور dotnet new یک پروژه‌ی ساده‌ی Hello World را در پوشه‌ی جاری ایجاد می‌کند که حاوی فایل‌های زیر است:
  • NuGet.Config (این فایل، تنظیمات مربوط به نیوگت را جهت کشف و دریافت وابستگی‌های پروژه، شامل می‌شود)
  •  Program.cs (این فایل سی شارپ حاوی کد برنامه است)
  • project.json (این فایل حاوی اطلاعات پلتفرم هدف و لیست وابستگی‌های پروژه است)

دستور dotnet restore بر اساس لیست وابستگی‌ها و پلتفرم هدف، وابستگی‌های لازم را از مخزن نیوگت دریافت می‌کند. (در صورتی که در هنگام اجرای این دستور با خطای NullReferenceException مواجه شدید از دستور dnu restore استفاده کنید. این خطا در گیت هاب در حال بررسی است)

دستور dotnet run هم سورس برنامه را کامپایل و اجرا می‌کند. در صورتی که پیام Hello World را مشاهده کردید، یعنی برنامه‌ی شما تحت NET Core. با موفقیت اجرا شده است.

توسعه‌ی پروژه با Visual Studio Code

در ادامه، قصد داریم پروژه‌ی HelloWorld را تحت Visual Studio Code باز کرده و تغییرات بعدی را در آنجا اعمال کنیم. پس از باز کردن Visual Studio Code از منوی File گزینه‌ی Open Folder را انتخاب کنید و پوشه‌ی حاوی پروژه (EF7-SQLite-NETCore) را انتخاب کنید. اکنون پروژه‌ی شما تحت VS Code باز شده و قابل ویرایش است.

سپس از لیست فایل‌های پروژه، فایل project.json را باز کرده و در بخش "dependencies" یک ردیف را برای EntityFramework.SQLite به صورت زیر اضافه کنید. به محض افزودن این خط در project.json و ذخیره‌ی آن، در صورتیکه قبلا این وابستگی دریافت نشده باشد، Visual Studio Code با نمایش یک هشدار در بالای برنامه به شما امکان دریافت اتوماتیک این وابستگی را می‌دهد. در نتیجه کافیست دکمه‌ی Restore را زده و منتظر شوید تا وابستگی EntityFramework.SQLite از مخزن ناگت دانلود و برای پروژه‌ی شما تنظیم شود.

"EntityFramework.SQLite": "7.0.0-rc1-final"

دریافت اتوماتیک وابستگی‌ها توسط Visual Studio Code


پس از کامل شدن این مرحله، در پروژه‌های بعدی تمام ارجاعات به وابستگی‌های دریافت شده، از طریق مخزن موجود در سیستم خود شما، برطرف خواهد شد و نیاز به دانلود مجدد وابستگی‌ها نیست.

اکنون همه‌ی موارد، جهت توسعه‌ی پروژه آماده است. ماوس خود را بر روی ریشه‌ی پروژه در VS Code قرار داده و New Folder را انتخاب کنید و نام Models را برای آن تایپ کنید. این پوشه قرار است مدل کلاس‌های پروژه را شامل شود. در اینجا ما یک مدل به نام Book داریم و نام کانتکست اصلی پروژه را هم LibraryContext گذاشته‌ایم.

بر روی پوشه‌ی Models راست کلیک کرده و گزینه‌ی New File را انتخاب کنید. سپس فایل‌های Book.cs و LibraryContext.cs را ایجاد کرده و کدهای زیر را برای مدل و کانتکست، در درون این دو فایل قرار دهید.

Book.cs

namespace Models
{
    public class Book
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Author{get;set;}
        public int PublishYear { get; set; }
    }
}
LibraryContext.cs
using Microsoft.Data.Entity;
using Microsoft.Data.Sqlite;

namespace Models
{
    public class LibraryContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = "test.db" };
            var connectionString = connectionStringBuilder.ToString();
            var connection = new SqliteConnection(connectionString);
            optionsBuilder.UseSqlite(connection);
        }
        public DbSet<Book> Books { get; set; }
    }
}
در فایل Book.cs یک مدل ساده به نام Book داریم که حاوی اطلاعات یک کتاب است. فایل LibraryContext.cs نیز حاوی کلاس LibraryContext است که یک مجموعه از کتاب‌ها را با نام Books نگهداری می‌کند. در متد OnConfiguring تنظیمات لازم را جهت استفاده از دیتابیس SQLite با نام test.db، قرار داده‌ایم که البته این کد را در پروژه‌های کامل می‌توان در خارج از LibraryContext قرار داد تا بتوان مسیر ذخیره سازی دیتابیس را کنترل و قابل تنظیم کرد.

در قدم آخر هم کافیست که فایل Program.cs را تغییر دهید و مقادیری را در دیتابیس ذخیره و بازخوانی کنید.
Program.cs
using System;
using Models;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("EF7 + Sqlite with the taste of .NET Core");

            try
            {
                using (var context = new LibraryContext())
                {
                    context.Database.EnsureCreated();

                    var book1 = new Book()
                    {
                        Title = "Adaptive Code via C#: Agile coding with design patterns and SOLID principles ",
                        Author = "Gary McLean Hall",
                        PublishYear = 2014
                    };

                    var book2 = new Book()
                    {
                        Title = "CLR via C# (4th Edition)",
                        Author = "Jefrey Ritcher",
                        PublishYear = 2012
                    };

                    context.Books.Add(book1);
                    context.Books.Add(book2);

                    context.SaveChanges();

                    ReadData(context);
                }

                Console.WriteLine("Press any key to exit ...");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"An exception occured: {ex.Message}\n{ex.StackTrace}");
            }
        }

        private static void ReadData(LibraryContext context)
        {
            Console.WriteLine("Books in database:");
            foreach (var b in context.Books)
            {
                Console.WriteLine($"Book {b.ID}");
                Console.WriteLine($"\tName: {b.Title}");
                Console.WriteLine($"\tAuthor: {b.Author}");
                Console.WriteLine($"\tPublish Year: {b.PublishYear}");
                Console.WriteLine();
            }
        }
    }
}
در فایل Program.cs جهت تست پروژه، از روی کلاس Book دو نمونه ساخته و آن‌ها را به دیتابیس افزوده و ذخیره می‌کنیم و در انتها، اطلاعات تمامی کتاب‌های موجود در دیتابیس را با جزییات نمایش می‌دهیم.

جهت اجرای برنامه کافیست Command prompt را در آدرس پروژه باز کرده و دستور dotnet run را اجرا کنید. پروژه‌ی شما کامپایل و اجرا می‌شود و خروجی مشابه زیر را مشاهده خواهید کرد. اگر برنامه را مجددا اجرا کنید، به جای دو کتاب اطلاعات چهار کتاب نمایش داده خواهد شد؛ چرا که در هر مرحله اطلاعات دو کتاب در دیتابیس درج می‌شود.

.NET Core + EF7 + SQLite

اگر به پوشه‌ی bin که در پوشه‌ی پروژه ایجاد شده است، نگاهی بیندازید، خبری از فایل باینری نیست. چرا که در لحظه‌، تولید و اجرا شده است. جهت build کردن پروژه و تولید فایل باینری کافیست دستور dotnet build را اجرا کنید، تا فایل باینری در پوشه‌ی bin ایجاد شود.

جهت انتشار برنامه می‌توانید دستور dotnet publish را اجرا کنید. این دستور نه تنها برنامه، که تمام وابستگی‌های مورد نیاز آن را برای اجرای در یک پلتفرم خاص تولید می‌کند. برای مثال بعد از اجرای این دستور یک پوشه‌ی win7-x64 حاوی 211 فایل در مجموع تولید شده است که تمامی وابستگی‌های این پروژه را شامل می‌شود.

Publishing .NET Core app

در واقع این پوشه تمام وابستگی‌های مورد نیاز پروژه را همراه خود دارد و در نتیجه جهت اجرای این برنامه برخلاف برنامه‌های معمولی دات نت، دیگر نیازی به نصب هیچ وابستگی مجزایی نیست و حتی پروژه‌های نوشته شده تحت NET Core. را می‌توانید در سیستم‌های عامل‌های دیگری مثل لینوکس و مکینتاش و یا  Windows IoT بر روی سخت افزار Raspberry Pi 2 هم اجرا کنید.

جهت مطالعه‌ی بیشتر:
مطالب
آموزش QUnit #2
فریم ورک تست جاوا اسکریپت QUnit:
 انتخاب و استفاده از یک فریم ورک برای تست کد‌های جاوا اسکریپت، قطعا نتیجه بهتری را به همراه خواهد داشت. من در این جا از QUnit که یکی از بهترین‌های تست واحد است، استفاده می‌کنم. برای این کار فایل‌های qunit.js و qunit.css را دانلود و مانند زیر برای تست واحد آماده کنید:
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Refactored date examples</title>

  <link rel="stylesheet" href="../qunit.css">
  <script src="../qunit.js"></script>
  <script src="prettydate.js"></script>
 
  <script>
  test("prettydate basics", function() {
    var now = "2013/01/28 22:25:00";
    equal(prettyDate(now, "2013/01/28 22:24:30"), "just now");
    equal(prettyDate(now, "201308/01/28 22:23:30"), "1 minute ago");
    equal(prettyDate(now, "2013/01/28 21:23:30"), "1 hour ago");
    equal(prettyDate(now, "2013/01/27 22:23:30"), "Yesterday");
    equal(prettyDate(now, "2013/01/26 22:23:30"), "2 days ago");
    equal(prettyDate(now, "2012/01/26 22:23:30"), undefined);
  });
  </script>
</head>
<body>
 
<div id="qunit"></div>
 
</body>
</html>
در کد بالا ابتدا فایل‌های فریم ورک و فایل prettydate.js را اضافه کردیم. برای نمایش نتیجه تست، یک تگ div با نام qunit در بین تگ body اضافه می‌کنیم. 
تابع test:
این تابع برای تست توابع نوشته شده، استفاده می‌شود. ورودی‌های این تابع، یکی عنوان تست و دومی یک متود دیگر، به عنوان ورودی دریافت می‌کند که در آن بدنه تست نوشته می‌شود.
تابع equal:
اولین تابع برای سنجش تست واحد equal است و در آن، تابعی که می‌خواهیم تست کنیم با مقدار خروجی آن مقایسه می‌شود.
فایل را با نام test.htm ذخیره و آن را در مرورگر خود باز نمایید. خروجی در شکل آورده شده است:

همین طور که در تصویر بزرگ می‌بینید اطلاعات مرورگر، زمان تکمیل تست و تعداد تست، تعداد تست پاس شده و تعداد تست شکست خورده، نشان داده شده است.

اگر یکی از تست‌ها با شکست روبرو شود رنگ پس زمینه قرمز و جزئیات شکست نمایش داده می‌شوند.
بهینه سازی، مرحله اول:
در حال حاضر تست ما کامل نیست زیرا امکان تست n weeks ago یا تعداد هفته پیش میسر نیست. قبل از آنکه این را به آزمون اضافه کنیم، تغییراتی در تست می‌دهیم
test("prettydate basics", function() {
  function date(then, expected) {
    equal(prettyDate("2013/01/28 22:25:00", then), expected);
  }
  date("2013/01/28 22:24:30", "just now");
  date("2013/01/28 22:23:30", "1 minute ago");
  date("2013/01/28 21:23:30", "1 hour ago");
  date("2013/01/27 22:23:30", "Yesterday");
  date("2013/01/26 22:23:30", "2 days ago");
  date("2012/01/26 22:23:30", undefined);
});
تابع prettyDate را در تابع دیگری به نام date قرار می‌دهیم. این تغییر سبب می‌شود تا امکان مقایسه زمان ورودی تست جاری با تست قبلی فراهم شود.
تست دستکاری عناصر DOM:
تا اینجا با تست توایع آشنا شدید، حالا می‌خواهیم تغییراتی در prettyDate دهیم تا امکان انتخاب عناصر DOM و به روزرسانی آن نیز وجود داشته باشد. فایل prettyDate2.js در زیر آورده شده است:
var prettyDate = {
  format: function(now, time){
    var date = new Date(time || ""),
      diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
      day_diff = Math.floor(diff / 86400);
 
    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
      return;
 
    return day_diff === 0 && (
        diff < 60 && "just now" ||
        diff < 120 && "1 minute ago" ||
        diff < 3600 && Math.floor( diff / 60 ) +
          " minutes ago" ||
        diff < 7200 && "1 hour ago" ||
        diff < 86400 && Math.floor( diff / 3600 ) +
          " hours ago") ||
      day_diff === 1 && "Yesterday" ||
      day_diff < 7 && day_diff + " days ago" ||
      day_diff < 31 && Math.ceil( day_diff / 7 ) +
        " weeks ago";
  },
 
  update: function(now) {
    var links = document.getElementsByTagName("a");
    for ( var i = 0; i < links.length; i++ ) {
      if ( links[i].title ) {
        var date = prettyDate.format(now, links[i].title);
        if ( date ) {
          links[i].innerHTML = date;
        }
      }
    }
  }
};
prettyDate شامل دو تابع، یکی format که weeks ago به آن اضافه گردیده و تابع update که با انتخاب تگ‌ها، مقدار title را به تابع فرمت و خروجی آن را در Html هر عنصر قرار می‌دهد. حال یک تست واحد می‌نویسیم:
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Refactored date examples</title>
  <link rel="stylesheet" href="../qunit.css">
  <script src="../qunit.js"></script>
  <script src="prettydate2.js"></script>
  <script>
  test("prettydate.format", function() {
    function date(then, expected) {
      equal(prettyDate.format("2013/01/28 22:25:00", then),
        expected);
    }
    date("2013/01/28 22:24:30", "just now");
    date("2013/01/28 22:23:30", "1 minute ago");
    date("2013/01/28 21:23:30", "1 hour ago");
    date("2013/01/27 22:23:30", "Yesterday");
    date("2013/01/26 22:23:30", "2 days ago");
    date("2012/01/26 22:23:30", undefined);
  });
 
  function domtest(name, now, first, second) {
    test(name, function() {
      var links = document.getElementById("qunit-fixture")
        .getElementsByTagName("a");
      equal(links[0].innerHTML, "January 28th, 2013");
      equal(links[2].innerHTML, "January 27th, 2013");
      prettyDate.update(now);
      equal(links[0].innerHTML, first);
      equal(links[2].innerHTML, second);
    });
  }
  domtest("prettyDate.update", "2013-01-28T22:25:00Z",
    "2 hours ago", "Yesterday");
  domtest("prettyDate.update, one day later", "2013/01/29 22:25:00",
    "Yesterday", "2 days ago");
  </script>
</head>
<body>
 
<div id="qunit"></div>
<div id="qunit-fixture">
 
<ul>
  <li id="post57">
    <p>blah blah blah...</p>
    <small>
      Posted <span>
        <a href="/2013/01/blah/57/" title="2013-01-28T20:24:17Z"
          >January 28th, 2013</a>
      </span>
      by <span><a href=""></a></span>
    </small>
  </li>
  <li id="post57">
    <p>blah blah blah...</p>
    <small>
      Posted <span>
        <a href="/2013/01/blah/57/" title="2013-01-27T22:24:17Z"
          >January 27th, 2013</a>
      </span>
      by <span><a href=""></a></span>
    </small>
  </li>
</ul>
 
</div>
 
</body>
</html>
همین طور که مشاهد می‌کنید در تست واحد اول خود تابع prettyDate.format را تست نموده ایم. در تست بعدی عناصر DOM نیز دستکاری و تست شده است. تابع domtest با جستجوی تگ qunit-fixture و تگ‌های a درون آن، مقدار نهایی html آن با مقدار داده شده، مقایسه شده است.

در شکل بالا نتیجه تست واحد نشان داده شده است.