NUnit-2.6.0.12051/0000775000175000017500000000000011742560362013165 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/0000775000175000017500000000000011742560362014631 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/vb/0000775000175000017500000000000011742560362015240 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/vb/money/0000775000175000017500000000000011742560362016367 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/vb/money/vb-money.build0000664000175000017500000000055111504175260021140 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/money/MoneyBag.vb0000664000175000017500000001173111504175260020417 0ustar jtaylorjtaylor' **************************************************************** ' This is free software licensed under the NUnit license. You ' may obtain a copy of the license as well as information regarding ' copyright ownership at http://nunit.org/?p=license&r=2.4. ' **************************************************************** Option Explicit On Namespace NUnit.Samples Public Class MoneyBag Implements IMoney Private fmonies As ArrayList = New ArrayList(5) Private Sub New() End Sub Public Sub New(ByVal bag As Money()) For Each m As Money In bag If Not m.IsZero Then AppendMoney(m) End If Next End Sub Public Sub New(ByVal m1 As Money, ByVal m2 As Money) AppendMoney(m1) AppendMoney(m2) End Sub Public Sub New(ByVal m As Money, ByVal bag As MoneyBag) AppendMoney(m) AppendBag(bag) End Sub Public Sub New(ByVal m1 As MoneyBag, ByVal m2 As MoneyBag) AppendBag(m1) AppendBag(m2) End Sub Public Function Add(ByVal m As IMoney) As IMoney Implements IMoney.Add Return m.AddMoneyBag(Me) End Function Public Function AddMoney(ByVal m As Money) As IMoney Implements IMoney.AddMoney Return New MoneyBag(m, Me).Simplify End Function Public Function AddMoneyBag(ByVal s As MoneyBag) As IMoney Implements IMoney.AddMoneyBag Return New MoneyBag(s, Me).Simplify() End Function Private Sub AppendBag(ByVal aBag As MoneyBag) For Each m As Money In aBag.fmonies AppendMoney(m) Next End Sub Private Sub AppendMoney(ByVal aMoney As Money) Dim old As Money = FindMoney(aMoney.Currency) If old Is Nothing Then fmonies.Add(aMoney) Return End If fmonies.Remove(old) Dim sum As IMoney = old.Add(aMoney) If (sum.IsZero) Then Return End If fmonies.Add(sum) End Sub Private Function Contains(ByVal aMoney As Money) As Boolean Dim m As Money = FindMoney(aMoney.Currency) Return m.Amount.Equals(aMoney.Amount) End Function Public Overloads Overrides Function Equals(ByVal anObject As Object) As Boolean If IsZero Then If TypeOf anObject Is IMoney Then Dim aMoney As IMoney = anObject Return aMoney.IsZero End If End If If TypeOf anObject Is MoneyBag Then Dim aMoneyBag As MoneyBag = anObject If Not aMoneyBag.fmonies.Count.Equals(fmonies.Count) Then Return False End If For Each m As Money In fmonies If Not aMoneyBag.Contains(m) Then Return False End If Return True Next End If Return False End Function Private Function FindMoney(ByVal currency As String) As Money For Each m As Money In fmonies If m.Currency.Equals(currency) Then Return m End If Next Return Nothing End Function Public Overrides Function GetHashCode() As Int32 Dim hash As Int32 = 0 For Each m As Money In fmonies hash += m.GetHashCode() Next Return hash End Function Public ReadOnly Property IsZero() As Boolean Implements IMoney.IsZero Get Return fmonies.Count.Equals(0) End Get End Property Public Function Multiply(ByVal factor As Integer) As IMoney Implements IMoney.Multiply Dim result As New MoneyBag If Not factor.Equals(0) Then For Each m As Money In fmonies result.AppendMoney(m.Multiply(factor)) Next End If Return result End Function Public Function Negate() As IMoney Implements IMoney.Negate Dim result As New MoneyBag For Each m As Money In fmonies result.AppendMoney(m.Negate()) Next Return result End Function Private Function Simplify() As IMoney If fmonies.Count.Equals(1) Then Return fmonies(0) End If Return Me End Function Public Function Subtract(ByVal m As IMoney) As IMoney Implements IMoney.Subtract Return Add(m.Negate()) End Function End Class End Namespace NUnit-2.6.0.12051/samples/vb/money/MoneyTest.vb0000664000175000017500000001676111504175260020655 0ustar jtaylorjtaylor' **************************************************************** ' This is free software licensed under the NUnit license. You ' may obtain a copy of the license as well as information regarding ' copyright ownership at http://nunit.org/?p=license&r=2.4. ' **************************************************************** Option Explicit On Imports System Imports NUnit.Framework Namespace NUnit.Samples _ Public Class MoneyTest Private f12CHF As Money Private f14CHF As Money Private f7USD As Money Private f21USD As Money Private fMB1 As MoneyBag Private fMB2 As MoneyBag _ Protected Sub SetUp() f12CHF = New Money(12, "CHF") f14CHF = New Money(14, "CHF") f7USD = New Money(7, "USD") f21USD = New Money(21, "USD") fMB1 = New MoneyBag(f12CHF, f7USD) fMB2 = New MoneyBag(f14CHF, f21USD) End Sub _ Public Sub BagMultiply() ' {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]} Dim bag() As Money = New Money() {New Money(24, "CHF"), New Money(14, "USD")} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, fMB1.Multiply(2)) Assert.AreEqual(fMB1, fMB1.Multiply(1)) Assert.IsTrue(fMB1.Multiply(0).IsZero) End Sub _ Public Sub BagNegate() ' {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]} Dim bag() As Money = New Money() {New Money(-12, "CHF"), New Money(-7, "USD")} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, fMB1.Negate()) End Sub _ Public Sub BagSimpleAdd() ' {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]} Dim bag() As Money = New Money() {New Money(26, "CHF"), New Money(7, "USD")} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, fMB1.Add(f14CHF)) End Sub _ Public Sub BagSubtract() ' {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]} Dim bag() As Money = New Money() {New Money(-2, "CHF"), New Money(-14, "USD")} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, fMB1.Subtract(fMB2)) End Sub _ Public Sub BagSumAdd() ' {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]} Dim bag() As Money = New Money() {New Money(26, "CHF"), New Money(28, "USD")} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, fMB1.Add(fMB2)) End Sub _ Public Sub IsZero() Assert.IsTrue(fMB1.Subtract(fMB1).IsZero) Dim bag() As Money = New Money() {New Money(0, "CHF"), New Money(0, "USD")} Assert.IsTrue(New MoneyBag(bag).IsZero) End Sub _ Public Sub MixedSimpleAdd() ' [12 CHF] + [7 USD] == {[12 CHF][7 USD]} Dim bag() As Money = New Money() {f12CHF, f7USD} Dim expected As New MoneyBag(bag) Assert.AreEqual(expected, f12CHF.Add(f7USD)) End Sub _ Public Sub MoneyBagEquals() ' NOTE: Normally we use Assert.AreEqual to test whether two ' objects are equal. But here we are testing the MoneyBag.Equals() ' method itself, so using AreEqual would not serve the purpose. Assert.IsFalse(fMB1.Equals(Nothing)) Assert.IsTrue(fMB1.Equals(fMB1)) Dim equal As MoneyBag = New MoneyBag(New Money(12, "CHF"), New Money(7, "USD")) Assert.IsTrue(fMB1.Equals(equal)) Assert.IsFalse(fMB1.Equals(f12CHF)) Assert.IsFalse(f12CHF.Equals(fMB1)) Assert.IsFalse(fMB1.Equals(fMB2)) End Sub _ Public Sub MoneyBagHash() Dim equal As MoneyBag = New MoneyBag(New Money(12, "CHF"), New Money(7, "USD")) Assert.AreEqual(fMB1.GetHashCode(), equal.GetHashCode()) End Sub _ Public Sub MoneyEquals() ' NOTE: Normally we use Assert.AreEqual to test whether two ' objects are equal. But here we are testing the MoneyBag.Equals() ' method itself, so using AreEqual would not serve the purpose. Assert.IsFalse(f12CHF.Equals(Nothing)) Dim equalMoney As Money = New Money(12, "CHF") Assert.IsTrue(f12CHF.Equals(f12CHF)) Assert.IsTrue(f12CHF.Equals(equalMoney)) Assert.IsFalse(f12CHF.Equals(f14CHF)) End Sub _ Public Sub MoneyHash() Assert.IsFalse(f12CHF.Equals(Nothing)) Dim equal As Money = New Money(12, "CHF") Assert.AreEqual(f12CHF.GetHashCode(), equal.GetHashCode()) End Sub _ Public Sub Normalize() Dim bag() As Money = New Money() {New Money(26, "CHF"), New Money(28, "CHF"), New Money(6, "CHF")} Dim moneyBag As New MoneyBag(bag) Dim expected() As Money = New Money() {New Money(60, "CHF")} ' // note: expected is still a MoneyBag Dim expectedBag As New MoneyBag(expected) Assert.AreEqual(expectedBag, moneyBag) End Sub _ Public Sub Normalize2() ' {[12 CHF][7 USD]} - [12 CHF] == [7 USD] Dim expected As Money = New Money(7, "USD") Assert.AreEqual(expected, fMB1.Subtract(f12CHF)) End Sub _ Public Sub Normalize3() ' {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD] Dim s1() As Money = New Money() {New Money(12, "CHF"), New Money(3, "USD")} Dim ms1 As New MoneyBag(s1) Dim expected As New Money(4, "USD") Assert.AreEqual(expected, fMB1.Subtract(ms1)) End Sub _ Public Sub Normalize4() ' [12 CHF] - {[12 CHF][3 USD]} == [-3 USD] Dim s1() As Money = New Money() {New Money(12, "CHF"), New Money(3, "USD")} Dim ms1 As New MoneyBag(s1) Dim expected As New Money(-3, "USD") Assert.AreEqual(expected, f12CHF.Subtract(ms1)) End Sub _ Public Sub Print() Assert.AreEqual("[12 CHF]", f12CHF.ToString()) End Sub _ Public Sub SimpleAdd() ' [12 CHF] + [14 CHF] == [26 CHF] Dim expected As Money = New Money(26, "CHF") Assert.AreEqual(expected, f12CHF.Add(f14CHF)) End Sub _ Public Sub SimpleNegate() ' [14 CHF] negate == [-14 CHF] Dim expected As New Money(-14, "CHF") Assert.AreEqual(expected, f14CHF.Negate()) End Sub _ Public Sub SimpleSubtract() ' [14 CHF] - [12 CHF] == [2 CHF] Dim expected As New Money(2, "CHF") Assert.AreEqual(expected, f14CHF.Subtract(f12CHF)) End Sub _ Public Sub SimpleMultiply() ' [14 CHF] *2 == [28 CHF] Dim expected As New Money(28, "CHF") Assert.AreEqual(expected, f14CHF.Multiply(2)) End Sub End Class End Namespace NUnit-2.6.0.12051/samples/vb/money/Money.vb0000664000175000017500000000642511504175260020011 0ustar jtaylorjtaylor' **************************************************************** ' This is free software licensed under the NUnit license. You ' may obtain a copy of the license as well as information regarding ' copyright ownership at http://nunit.org/?p=license&r=2.4. ' **************************************************************** Option Explicit On Namespace NUnit.Samples ' A Simple Money. Public Class Money Implements IMoney Private fAmount As Int32 Private fCurrency As String ' Constructs a money from a given amount and currency. Public Sub New(ByVal amount As Int32, ByVal currency As String) Me.fAmount = amount Me.fCurrency = currency End Sub ' Adds a money to this money. Forwards the request ' to the AddMoney helper. Public Overloads Function Add(ByVal m As IMoney) As IMoney Implements IMoney.Add Return m.AddMoney(Me) End Function Public Overloads Function AddMoney(ByVal m As Money) As IMoney Implements IMoney.AddMoney If m.Currency.Equals(Currency) Then Return New Money(Amount + m.Amount, Currency) End If Return New MoneyBag(Me, m) End Function Public Function AddMoneyBag(ByVal s As MoneyBag) As IMoney Implements IMoney.AddMoneyBag Return s.AddMoney(Me) End Function Public ReadOnly Property Amount() As Integer Get Return fAmount End Get End Property Public ReadOnly Property Currency() As String Get Return fCurrency End Get End Property Public Overloads Overrides Function Equals(ByVal anObject As Object) As Boolean If IsZero And TypeOf anObject Is IMoney Then Dim aMoney As IMoney = anObject Return aMoney.IsZero End If If TypeOf anObject Is Money Then Dim aMoney As Money = anObject If (IsZero) Then Return aMoney.IsZero End If Return Currency.Equals(aMoney.Currency) And Amount.Equals(aMoney.Amount) End If Return False End Function Public Overrides Function GetHashCode() As Int32 Return fCurrency.GetHashCode() + fAmount End Function Public ReadOnly Property IsZero() As Boolean Implements IMoney.IsZero Get Return Amount.Equals(0) End Get End Property Public Function Multiply(ByVal factor As Integer) As IMoney Implements IMoney.Multiply Return New Money(Amount * factor, Currency) End Function Public Function Negate() As IMoney Implements IMoney.Negate Return New Money(-Amount, Currency) End Function Public Function Subtract(ByVal m As IMoney) As IMoney Implements IMoney.Subtract Return Add(m.Negate()) End Function Public Overrides Function ToString() As String Return String.Format("[{0} {1}]", Amount, Currency) End Function End Class End Namespace NUnit-2.6.0.12051/samples/vb/money/AssemblyInfo.vb0000664000175000017500000000202411504175260021304 0ustar jtaylorjtaylorImports System Imports System.Reflection Imports System.Runtime.InteropServices ' General Information about an assembly is controlled through the following ' set of attributes. Change these attribute values to modify the information ' associated with an assembly. ' Review the values of the assembly attributes 'The following GUID is for the ID of the typelib if this project is exposed to COM ' Version information for an assembly consists of the following four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the Build and Revision Numbers ' by using the '*' as shown below: NUnit-2.6.0.12051/samples/vb/money/vb-money.vbproj0000664000175000017500000000424111720516414021343 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/money/IMoney.vb0000664000175000017500000000241011504175260020110 0ustar jtaylorjtaylor' **************************************************************** ' This is free software licensed under the NUnit license. You ' may obtain a copy of the license as well as information regarding ' copyright ownership at http://nunit.org/?p=license&r=2.4. ' **************************************************************** Namespace NUnit.Samples 'The common interface for simple Monies and MoneyBags. Public Interface IMoney 'Adds a money to this money Function Add(ByVal m As IMoney) As IMoney 'Adds a simple Money to this money. This is a helper method for 'implementing double dispatch. Function AddMoney(ByVal m As Money) As IMoney 'Adds a MoneyBag to this money. This is a helper method for 'implementing double dispatch. Function AddMoneyBag(ByVal s As MoneyBag) As IMoney 'True if this money is zero. ReadOnly Property IsZero() As Boolean 'Multiplies a money by the given factor. Function Multiply(ByVal factor As Int32) As IMoney 'Negates this money. Function Negate() As IMoney 'Subtracts a money from this money. Function Subtract(ByVal m As IMoney) As IMoney End Interface End Namespace NUnit-2.6.0.12051/samples/vb/syntax/0000775000175000017500000000000011742560362016566 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/vb/syntax/vb-syntax.build0000664000175000017500000000041511504175260021535 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/syntax/AssertSyntaxTests.vb0000664000175000017500000006523311504175260022616 0ustar jtaylorjtaylor' **************************************************************** ' Copyright 2007, Charlie Poole ' This is free software licensed under the NUnit license. You may ' obtain a copy of the license at http:'nunit.org/?p=license&r=2.4 ' **************************************************************** Option Explicit On Imports System Imports NUnit.Framework Imports NUnit.Framework.Constraints Imports Text = NUnit.Framework.Text Namespace NUnit.Samples ' This test fixture attempts to exercise all the syntactic ' variations of Assert without getting into failures, errors ' or corner cases. Thus, some of the tests may be duplicated ' in other fixtures. ' ' Each test performs the same operations using the classic ' syntax (if available) and the new syntax in both the ' helper-based and inherited forms. ' ' This Fixture will eventually be duplicated in other ' supported languages. _ Public Class AssertSyntaxTests Inherits AssertionHelper #Region "Simple Constraint Tests" _ Public Sub IsNull() Dim nada As Object = Nothing ' Classic syntax Assert.IsNull(nada) ' Helper syntax Assert.That(nada, Iz.Null) ' Inherited syntax Expect(nada, Null) End Sub _ Public Sub IsNotNull() ' Classic syntax Assert.IsNotNull(42) ' Helper syntax Assert.That(42, Iz.Not.Null) ' Inherited syntax Expect(42, Iz.Not.Null) End Sub _ Public Sub IsTrue() ' Classic syntax Assert.IsTrue(2 + 2 = 4) ' Helper syntax Assert.That(2 + 2 = 4, Iz.True) Assert.That(2 + 2 = 4) ' Inherited syntax Expect(2 + 2 = 4, Iz.True) Expect(2 + 2 = 4) End Sub _ Public Sub IsFalse() ' Classic syntax Assert.IsFalse(2 + 2 = 5) ' Helper syntax Assert.That(2 + 2 = 5, Iz.False) ' Inherited syntax Expect(2 + 2 = 5, Iz.False) End Sub _ Public Sub IsNaN() Dim d As Double = Double.NaN Dim f As Single = Single.NaN ' Classic syntax Assert.IsNaN(d) Assert.IsNaN(f) ' Helper syntax Assert.That(d, Iz.NaN) Assert.That(f, Iz.NaN) ' Inherited syntax Expect(d, NaN) Expect(f, NaN) End Sub _ Public Sub EmptyStringTests() ' Classic syntax Assert.IsEmpty("") Assert.IsNotEmpty("Hello!") ' Helper syntax Assert.That("", Iz.Empty) Assert.That("Hello!", Iz.Not.Empty) ' Inherited syntax Expect("", Empty) Expect("Hello!", Iz.Not.Empty) End Sub _ Public Sub EmptyCollectionTests() Dim boolArray As Boolean() = New Boolean() {} Dim nonEmpty As Integer() = New Integer() {1, 2, 3} ' Classic syntax Assert.IsEmpty(boolArray) Assert.IsNotEmpty(nonEmpty) ' Helper syntax Assert.That(boolArray, Iz.Empty) Assert.That(nonEmpty, Iz.Not.Empty) ' Inherited syntax Expect(boolArray, Iz.Empty) Expect(nonEmpty, Iz.Not.Empty) End Sub #End Region #Region "TypeConstraint Tests" _ Public Sub ExactTypeTests() ' Classic syntax workarounds Assert.AreEqual(GetType(String), "Hello".GetType()) Assert.AreEqual("System.String", "Hello".GetType().FullName) Assert.AreNotEqual(GetType(Integer), "Hello".GetType()) Assert.AreNotEqual("System.Int32", "Hello".GetType().FullName) ' Helper syntax Assert.That("Hello", Iz.TypeOf(GetType(String))) Assert.That("Hello", Iz.Not.TypeOf(GetType(Integer))) ' Inherited syntax Expect("Hello", Iz.TypeOf(GetType(String))) Expect("Hello", Iz.Not.TypeOf(GetType(Integer))) End Sub _ Public Sub InstanceOfTypeTests() ' Classic syntax Assert.IsInstanceOf(GetType(String), "Hello") Assert.IsNotInstanceOf(GetType(String), 5) ' Helper syntax Assert.That("Hello", Iz.InstanceOf(GetType(String))) Assert.That(5, Iz.Not.InstanceOf(GetType(String))) ' Inherited syntax Expect("Hello", InstanceOf(GetType(String))) Expect(5, Iz.Not.InstanceOf(GetType(String))) End Sub _ Public Sub AssignableFromTypeTests() ' Classic syntax Assert.IsAssignableFrom(GetType(String), "Hello") Assert.IsNotAssignableFrom(GetType(String), 5) ' Helper syntax Assert.That("Hello", Iz.AssignableFrom(GetType(String))) Assert.That(5, Iz.Not.AssignableFrom(GetType(String))) ' Inherited syntax Expect("Hello", AssignableFrom(GetType(String))) Expect(5, Iz.Not.AssignableFrom(GetType(String))) End Sub #End Region #Region "StringConstraintTests" _ Public Sub SubstringTests() Dim phrase As String = "Hello World!" Dim array As String() = New String() {"abc", "bad", "dba"} ' Classic Syntax StringAssert.Contains("World", phrase) ' Helper syntax Assert.That(phrase, Text.Contains("World")) ' Only available using new syntax Assert.That(phrase, Text.DoesNotContain("goodbye")) Assert.That(phrase, Text.Contains("WORLD").IgnoreCase) Assert.That(phrase, Text.DoesNotContain("BYE").IgnoreCase) Assert.That(array, Text.All.Contains("b")) ' Inherited syntax Expect(phrase, Contains("World")) ' Only available using new syntax Expect(phrase, Text.DoesNotContain("goodbye")) Expect(phrase, Contains("WORLD").IgnoreCase) Expect(phrase, Text.DoesNotContain("BYE").IgnoreCase) Expect(array, All.Contains("b")) End Sub _ Public Sub StartsWithTests() Dim phrase As String = "Hello World!" Dim greetings As String() = New String() {"Hello!", "Hi!", "Hola!"} ' Classic syntax StringAssert.StartsWith("Hello", phrase) ' Helper syntax Assert.That(phrase, Text.StartsWith("Hello")) ' Only available using new syntax Assert.That(phrase, Text.DoesNotStartWith("Hi!")) Assert.That(phrase, Text.StartsWith("HeLLo").IgnoreCase) Assert.That(phrase, Text.DoesNotStartWith("HI").IgnoreCase) Assert.That(greetings, Text.All.StartsWith("h").IgnoreCase) ' Inherited syntax Expect(phrase, StartsWith("Hello")) ' Only available using new syntax Expect(phrase, Text.DoesNotStartWith("Hi!")) Expect(phrase, StartsWith("HeLLo").IgnoreCase) Expect(phrase, Text.DoesNotStartWith("HI").IgnoreCase) Expect(greetings, All.StartsWith("h").IgnoreCase) End Sub _ Public Sub EndsWithTests() Dim phrase As String = "Hello World!" Dim greetings As String() = New String() {"Hello!", "Hi!", "Hola!"} ' Classic Syntax StringAssert.EndsWith("!", phrase) ' Helper syntax Assert.That(phrase, Text.EndsWith("!")) ' Only available using new syntax Assert.That(phrase, Text.DoesNotEndWith("?")) Assert.That(phrase, Text.EndsWith("WORLD!").IgnoreCase) Assert.That(greetings, Text.All.EndsWith("!")) ' Inherited syntax Expect(phrase, EndsWith("!")) ' Only available using new syntax Expect(phrase, Text.DoesNotEndWith("?")) Expect(phrase, EndsWith("WORLD!").IgnoreCase) Expect(greetings, All.EndsWith("!")) End Sub _ Public Sub EqualIgnoringCaseTests() Dim phrase As String = "Hello World!" Dim array1 As String() = New String() {"Hello", "World"} Dim array2 As String() = New String() {"HELLO", "WORLD"} Dim array3 As String() = New String() {"HELLO", "Hello", "hello"} ' Classic syntax StringAssert.AreEqualIgnoringCase("hello world!", phrase) ' Helper syntax Assert.That(phrase, Iz.EqualTo("hello world!").IgnoreCase) 'Only available using new syntax Assert.That(phrase, Iz.Not.EqualTo("goodbye world!").IgnoreCase) Assert.That(array1, Iz.EqualTo(array2).IgnoreCase) Assert.That(array3, Iz.All.EqualTo("hello").IgnoreCase) ' Inherited syntax Expect(phrase, EqualTo("hello world!").IgnoreCase) 'Only available using new syntax Expect(phrase, Iz.Not.EqualTo("goodbye world!").IgnoreCase) Expect(array1, EqualTo(array2).IgnoreCase) Expect(array3, All.EqualTo("hello").IgnoreCase) End Sub _ Public Sub RegularExpressionTests() Dim phrase As String = "Now is the time for all good men to come to the aid of their country." Dim quotes As String() = New String() {"Never say never", "It's never too late", "Nevermore!"} ' Classic syntax StringAssert.IsMatch("all good men", phrase) StringAssert.IsMatch("Now.*come", phrase) ' Helper syntax Assert.That(phrase, Text.Matches("all good men")) Assert.That(phrase, Text.Matches("Now.*come")) ' Only available using new syntax Assert.That(phrase, Text.DoesNotMatch("all.*men.*good")) Assert.That(phrase, Text.Matches("ALL").IgnoreCase) Assert.That(quotes, Text.All.Matches("never").IgnoreCase) ' Inherited syntax Expect(phrase, Matches("all good men")) Expect(phrase, Matches("Now.*come")) ' Only available using new syntax Expect(phrase, Text.DoesNotMatch("all.*men.*good")) Expect(phrase, Matches("ALL").IgnoreCase) Expect(quotes, All.Matches("never").IgnoreCase) End Sub #End Region #Region "Equality Tests" _ Public Sub EqualityTests() Dim i3 As Integer() = {1, 2, 3} Dim d3 As Double() = {1.0, 2.0, 3.0} Dim iunequal As Integer() = {1, 3, 2} ' Classic Syntax Assert.AreEqual(4, 2 + 2) Assert.AreEqual(i3, d3) Assert.AreNotEqual(5, 2 + 2) Assert.AreNotEqual(i3, iunequal) ' Helper syntax Assert.That(2 + 2, Iz.EqualTo(4)) Assert.That(2 + 2 = 4) Assert.That(i3, Iz.EqualTo(d3)) Assert.That(2 + 2, Iz.Not.EqualTo(5)) Assert.That(i3, Iz.Not.EqualTo(iunequal)) ' Inherited syntax Expect(2 + 2, EqualTo(4)) Expect(2 + 2 = 4) Expect(i3, EqualTo(d3)) Expect(2 + 2, Iz.Not.EqualTo(5)) Expect(i3, Iz.Not.EqualTo(iunequal)) End Sub _ Public Sub EqualityTestsWithTolerance() ' CLassic syntax Assert.AreEqual(5.0R, 4.99R, 0.05R) Assert.AreEqual(5.0F, 4.99F, 0.05F) ' Helper syntax Assert.That(4.99R, Iz.EqualTo(5.0R).Within(0.05R)) Assert.That(4D, Iz.Not.EqualTo(5D).Within(0.5D)) Assert.That(4.99F, Iz.EqualTo(5.0F).Within(0.05F)) Assert.That(4.99D, Iz.EqualTo(5D).Within(0.05D)) Assert.That(499, Iz.EqualTo(500).Within(5)) Assert.That(4999999999L, Iz.EqualTo(5000000000L).Within(5L)) ' Inherited syntax Expect(4.99R, EqualTo(5.0R).Within(0.05R)) Expect(4D, Iz.Not.EqualTo(5D).Within(0.5D)) Expect(4.99F, EqualTo(5.0F).Within(0.05F)) Expect(4.99D, EqualTo(5D).Within(0.05D)) Expect(499, EqualTo(500).Within(5)) Expect(4999999999L, EqualTo(5000000000L).Within(5L)) End Sub _ Public Sub EqualityTestsWithTolerance_MixedFloatAndDouble() ' Bug Fix 1743844 Assert.That(2.20492R, Iz.EqualTo(2.2R).Within(0.01F), _ "Double actual, Double expected, Single tolerance") Assert.That(2.20492R, Iz.EqualTo(2.2F).Within(0.01R), _ "Double actual, Single expected, Double tolerance") Assert.That(2.20492R, Iz.EqualTo(2.2F).Within(0.01F), _ "Double actual, Single expected, Single tolerance") Assert.That(2.20492F, Iz.EqualTo(2.2F).Within(0.01R), _ "Single actual, Single expected, Double tolerance") Assert.That(2.20492F, Iz.EqualTo(2.2R).Within(0.01R), _ "Single actual, Double expected, Double tolerance") Assert.That(2.20492F, Iz.EqualTo(2.2R).Within(0.01F), _ "Single actual, Double expected, Single tolerance") End Sub _ Public Sub EqualityTestsWithTolerance_MixingTypesGenerally() ' Extending tolerance to all numeric types Assert.That(202.0R, Iz.EqualTo(200.0R).Within(2), _ "Double actual, Double expected, int tolerance") Assert.That(4.87D, Iz.EqualTo(5).Within(0.25R), _ "Decimal actual, int expected, Double tolerance") Assert.That(4.87D, Iz.EqualTo(5L).Within(1), _ "Decimal actual, long expected, int tolerance") Assert.That(487, Iz.EqualTo(500).Within(25), _ "int actual, int expected, int tolerance") Assert.That(487L, Iz.EqualTo(500).Within(25), _ "long actual, int expected, int tolerance") End Sub #End Region #Region "Comparison Tests" _ Public Sub ComparisonTests() ' Classic Syntax Assert.Greater(7, 3) Assert.GreaterOrEqual(7, 3) Assert.GreaterOrEqual(7, 7) ' Helper syntax Assert.That(7, Iz.GreaterThan(3)) Assert.That(7, Iz.GreaterThanOrEqualTo(3)) Assert.That(7, Iz.AtLeast(3)) Assert.That(7, Iz.GreaterThanOrEqualTo(7)) Assert.That(7, Iz.AtLeast(7)) ' Inherited syntax Expect(7, GreaterThan(3)) Expect(7, GreaterThanOrEqualTo(3)) Expect(7, AtLeast(3)) Expect(7, GreaterThanOrEqualTo(7)) Expect(7, AtLeast(7)) ' Classic syntax Assert.Less(3, 7) Assert.LessOrEqual(3, 7) Assert.LessOrEqual(3, 3) ' Helper syntax Assert.That(3, Iz.LessThan(7)) Assert.That(3, Iz.LessThanOrEqualTo(7)) Assert.That(3, Iz.AtMost(7)) Assert.That(3, Iz.LessThanOrEqualTo(3)) Assert.That(3, Iz.AtMost(3)) ' Inherited syntax Expect(3, LessThan(7)) Expect(3, LessThanOrEqualTo(7)) Expect(3, AtMost(7)) Expect(3, LessThanOrEqualTo(3)) Expect(3, AtMost(3)) End Sub #End Region #Region "Collection Tests" _ Public Sub AllItemsTests() Dim ints As Object() = {1, 2, 3, 4} Dim doubles As Object() = {0.99, 2.1, 3.0, 4.05} Dim strings As Object() = {"abc", "bad", "cab", "bad", "dad"} ' Classic syntax CollectionAssert.AllItemsAreNotNull(ints) CollectionAssert.AllItemsAreInstancesOfType(ints, GetType(Integer)) CollectionAssert.AllItemsAreInstancesOfType(strings, GetType(String)) CollectionAssert.AllItemsAreUnique(ints) ' Helper syntax Assert.That(ints, Iz.All.Not.Null) Assert.That(ints, Has.None.Null) Assert.That(ints, Iz.All.InstanceOfType(GetType(Integer))) Assert.That(ints, Has.All.InstanceOfType(GetType(Integer))) Assert.That(strings, Iz.All.InstanceOfType(GetType(String))) Assert.That(strings, Has.All.InstanceOfType(GetType(String))) Assert.That(ints, Iz.Unique) ' Only available using new syntax Assert.That(strings, Iz.Not.Unique) Assert.That(ints, Iz.All.GreaterThan(0)) Assert.That(ints, Has.All.GreaterThan(0)) Assert.That(ints, Has.None.LessThanOrEqualTo(0)) Assert.That(strings, Text.All.Contains("a")) Assert.That(strings, Has.All.Contains("a")) Assert.That(strings, Has.Some.StartsWith("ba")) Assert.That(strings, Has.Some.Property("Length").EqualTo(3)) Assert.That(strings, Has.Some.StartsWith("BA").IgnoreCase) Assert.That(doubles, Has.Some.EqualTo(1.0).Within(0.05)) ' Inherited syntax Expect(ints, All.Not.Null) Expect(ints, None.Null) Expect(ints, All.InstanceOfType(GetType(Integer))) Expect(strings, All.InstanceOfType(GetType(String))) Expect(ints, Unique) ' Only available using new syntax Expect(strings, Iz.Not.Unique) Expect(ints, All.GreaterThan(0)) Expect(strings, All.Contains("a")) Expect(strings, Some.StartsWith("ba")) Expect(strings, Some.StartsWith("BA").IgnoreCase) Expect(doubles, Some.EqualTo(1.0).Within(0.05)) End Sub _ Public Sub SomeItemsTests() Dim mixed As Object() = {1, 2, "3", Nothing, "four", 100} Dim strings As Object() = {"abc", "bad", "cab", "bad", "dad"} ' Not available using the classic syntax ' Helper syntax Assert.That(mixed, Has.Some.Null) Assert.That(mixed, Has.Some.InstanceOfType(GetType(Integer))) Assert.That(mixed, Has.Some.InstanceOfType(GetType(String))) Assert.That(strings, Has.Some.StartsWith("ba")) Assert.That(strings, Has.Some.Not.StartsWith("ba")) ' Inherited syntax Expect(mixed, Some.Null) Expect(mixed, Some.InstanceOfType(GetType(Integer))) Expect(mixed, Some.InstanceOfType(GetType(String))) Expect(strings, Some.StartsWith("ba")) Expect(strings, Some.Not.StartsWith("ba")) End Sub _ Public Sub NoItemsTests() Dim ints As Object() = {1, 2, 3, 4, 5} Dim strings As Object() = {"abc", "bad", "cab", "bad", "dad"} ' Not available using the classic syntax ' Helper syntax Assert.That(ints, Has.None.Null) Assert.That(ints, Has.None.InstanceOfType(GetType(String))) Assert.That(ints, Has.None.GreaterThan(99)) Assert.That(strings, Has.None.StartsWith("qu")) ' Inherited syntax Expect(ints, None.Null) Expect(ints, None.InstanceOfType(GetType(String))) Expect(ints, None.GreaterThan(99)) Expect(strings, None.StartsWith("qu")) End Sub _ Public Sub CollectionContainsTests() Dim iarray As Integer() = {1, 2, 3} Dim sarray As String() = {"a", "b", "c"} ' Classic syntax Assert.Contains(3, iarray) Assert.Contains("b", sarray) CollectionAssert.Contains(iarray, 3) CollectionAssert.Contains(sarray, "b") CollectionAssert.DoesNotContain(sarray, "x") ' Showing that Contains uses NUnit equality CollectionAssert.Contains(iarray, 1.0R) ' Helper syntax Assert.That(iarray, Has.Member(3)) Assert.That(sarray, Has.Member("b")) Assert.That(sarray, Has.No.Member("x")) ' Showing that Contains uses NUnit equality Assert.That(iarray, Has.Member(1.0R)) ' Only available using the new syntax ' Note that EqualTo and SameAs do NOT give ' identical results to Contains because ' Contains uses Object.Equals() Assert.That(iarray, Has.Some.EqualTo(3)) Assert.That(iarray, Has.Member(3)) Assert.That(sarray, Has.Some.EqualTo("b")) Assert.That(sarray, Has.None.EqualTo("x")) Assert.That(iarray, Has.None.SameAs(1.0R)) Assert.That(iarray, Has.All.LessThan(10)) Assert.That(sarray, Has.All.Length.EqualTo(1)) Assert.That(sarray, Has.None.Property("Length").GreaterThan(3)) ' Inherited syntax Expect(iarray, Contains(3)) Expect(sarray, Contains("b")) Expect(sarray, Has.No.Member("x")) ' Only available using new syntax ' Note that EqualTo and SameAs do NOT give ' identical results to Contains because ' Contains uses Object.Equals() Expect(iarray, Some.EqualTo(3)) Expect(sarray, Some.EqualTo("b")) Expect(sarray, None.EqualTo("x")) Expect(iarray, All.LessThan(10)) Expect(sarray, All.Length.EqualTo(1)) Expect(sarray, None.Property("Length").GreaterThan(3)) End Sub _ Public Sub CollectionEquivalenceTests() Dim ints1to5 As Integer() = {1, 2, 3, 4, 5} Dim twothrees As Integer() = {1, 2, 3, 3, 4, 5} Dim twofours As Integer() = {1, 2, 3, 4, 4, 5} ' Classic syntax CollectionAssert.AreEquivalent(New Integer() {2, 1, 4, 3, 5}, ints1to5) CollectionAssert.AreNotEquivalent(New Integer() {2, 2, 4, 3, 5}, ints1to5) CollectionAssert.AreNotEquivalent(New Integer() {2, 4, 3, 5}, ints1to5) CollectionAssert.AreNotEquivalent(New Integer() {2, 2, 1, 1, 4, 3, 5}, ints1to5) CollectionAssert.AreNotEquivalent(twothrees, twofours) ' Helper syntax Assert.That(New Integer() {2, 1, 4, 3, 5}, Iz.EquivalentTo(ints1to5)) Assert.That(New Integer() {2, 2, 4, 3, 5}, Iz.Not.EquivalentTo(ints1to5)) Assert.That(New Integer() {2, 4, 3, 5}, Iz.Not.EquivalentTo(ints1to5)) Assert.That(New Integer() {2, 2, 1, 1, 4, 3, 5}, Iz.Not.EquivalentTo(ints1to5)) Assert.That(twothrees, Iz.Not.EquivalentTo(twofours)) ' Inherited syntax Expect(New Integer() {2, 1, 4, 3, 5}, EquivalentTo(ints1to5)) End Sub _ Public Sub SubsetTests() Dim ints1to5 As Integer() = {1, 2, 3, 4, 5} ' Classic syntax CollectionAssert.IsSubsetOf(New Integer() {1, 3, 5}, ints1to5) CollectionAssert.IsSubsetOf(New Integer() {1, 2, 3, 4, 5}, ints1to5) CollectionAssert.IsNotSubsetOf(New Integer() {2, 4, 6}, ints1to5) CollectionAssert.IsNotSubsetOf(New Integer() {1, 2, 2, 2, 5}, ints1to5) ' Helper syntax Assert.That(New Integer() {1, 3, 5}, Iz.SubsetOf(ints1to5)) Assert.That(New Integer() {1, 2, 3, 4, 5}, Iz.SubsetOf(ints1to5)) Assert.That(New Integer() {2, 4, 6}, Iz.Not.SubsetOf(ints1to5)) ' Inherited syntax Expect(New Integer() {1, 3, 5}, SubsetOf(ints1to5)) Expect(New Integer() {1, 2, 3, 4, 5}, SubsetOf(ints1to5)) Expect(New Integer() {2, 4, 6}, Iz.Not.SubsetOf(ints1to5)) End Sub #End Region #Region "Property Tests" _ Public Sub PropertyTests() Dim array As String() = {"abc", "bca", "xyz", "qrs"} Dim array2 As String() = {"a", "ab", "abc"} Dim list As New ArrayList(array) ' Not available using the classic syntax ' Helper syntax ' Assert.That(list, Has.Property("Count")) ' Assert.That(list, Has.No.Property("Length")) Assert.That("Hello", Has.Length.EqualTo(5)) Assert.That("Hello", Has.Property("Length").EqualTo(5)) Assert.That("Hello", Has.Property("Length").GreaterThan(3)) Assert.That(array, Has.Property("Length").EqualTo(4)) Assert.That(array, Has.Length.EqualTo(4)) Assert.That(array, Has.Property("Length").LessThan(10)) Assert.That(array, Has.All.Property("Length").EqualTo(3)) Assert.That(array, Has.All.Length.EqualTo(3)) Assert.That(array, Iz.All.Length.EqualTo(3)) Assert.That(array, Has.All.Property("Length").EqualTo(3)) Assert.That(array, Iz.All.Property("Length").EqualTo(3)) Assert.That(array2, Iz.Not.Property("Length").EqualTo(4)) Assert.That(array2, Iz.Not.Length.EqualTo(4)) Assert.That(array2, Has.No.Property("Length").GreaterThan(3)) ' Inherited syntax ' Expect(list, Has.Property("Count")) ' Expect(list, Has.No.Property("Nada")) Expect(array, All.Property("Length").EqualTo(3)) Expect(array, All.Length.EqualTo(3)) End Sub #End Region #Region "Not Tests" _ Public Sub NotTests() ' Not available using the classic syntax ' Helper syntax Assert.That(42, Iz.Not.Null) Assert.That(42, Iz.Not.True) Assert.That(42, Iz.Not.False) Assert.That(2.5, Iz.Not.NaN) Assert.That(2 + 2, Iz.Not.EqualTo(3)) Assert.That(2 + 2, Iz.Not.Not.EqualTo(4)) Assert.That(2 + 2, Iz.Not.Not.Not.EqualTo(5)) ' Inherited syntax Expect(42, Iz.Not.Null) Expect(42, Iz.Not.True) Expect(42, Iz.Not.False) Expect(2.5, Iz.Not.NaN) Expect(2 + 2, Iz.Not.EqualTo(3)) Expect(2 + 2, Iz.Not.Not.EqualTo(4)) Expect(2 + 2, Iz.Not.Not.Not.EqualTo(5)) End Sub #End Region End Class End Namespace NUnit-2.6.0.12051/samples/vb/syntax/AssemblyInfo.vb0000664000175000017500000000202411504175260021503 0ustar jtaylorjtaylorImports System Imports System.Reflection Imports System.Runtime.InteropServices ' General Information about an assembly is controlled through the following ' set of attributes. Change these attribute values to modify the information ' associated with an assembly. ' Review the values of the assembly attributes 'The following GUID is for the ID of the typelib if this project is exposed to COM ' Version information for an assembly consists of the following four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the Build and Revision Numbers ' by using the '*' as shown below: NUnit-2.6.0.12051/samples/vb/syntax/vb-syntax.vbproj0000664000175000017500000000431311720516414021741 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/failures/0000775000175000017500000000000011742560362017052 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/vb/failures/vb-failures.build0000664000175000017500000000041011504175260022300 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/failures/AssemblyInfo.vb0000664000175000017500000000201011504175260021762 0ustar jtaylorjtaylorImports System.Reflection Imports System.Runtime.InteropServices ' General Information about an assembly is controlled through the following ' set of attributes. Change these attribute values to modify the information ' associated with an assembly. ' Review the values of the assembly attributes 'The following GUID is for the ID of the typelib if this project is exposed to COM ' Version information for an assembly consists of the following four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the Build and Revision Numbers ' by using the '*' as shown below: NUnit-2.6.0.12051/samples/vb/failures/vb-failures.vbproj0000664000175000017500000000365211720516414022516 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/vb/failures/SimpleVBTest.vb0000664000175000017500000000324611504175260021724 0ustar jtaylorjtaylor' **************************************************************** ' This is free software licensed under the NUnit license. You ' may obtain a copy of the license as well as information regarding ' copyright ownership at http://nunit.org/?p=license&r=2.4. ' **************************************************************** Option Explicit On Imports System Imports NUnit.Framework Namespace NUnit.Samples Public Class SimpleVBTest Private fValue1 As Integer Private fValue2 As Integer Public Sub New() MyBase.New() End Sub Public Sub Init() fValue1 = 2 fValue2 = 3 End Sub Public Sub Add() Dim result As Double result = fValue1 + fValue2 Assert.AreEqual(6, result) End Sub Public Sub DivideByZero() Dim zero As Integer Dim result As Integer zero = 0 result = 8 / zero End Sub Public Sub TestEquals() Assert.AreEqual(12, 12) Assert.AreEqual(CLng(12), CLng(12)) Assert.AreEqual(12, 13, "Size") Assert.AreEqual(12, 11.99, 0, "Capacity") End Sub Public Sub ExpectAnException() Throw New InvalidCastException() End Sub Public Sub IgnoredTest() ' does not matter what we type the test is not run Throw New ArgumentException() End Sub End Class End NamespaceNUnit-2.6.0.12051/samples/vb/vb-samples.sln0000664000175000017500000000360511504175260020026 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vb-failures", "failures\vb-failures.vbproj", "{F199991B-6C8E-4AB0-9AAA-703CD4897700}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vb-money", "money\vb-money.vbproj", "{95394B96-A794-48EA-9879-0E4EC79C5724}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vb-syntax", "syntax\vb-syntax.vbproj", "{6BEF566A-2691-4EE8-91AF-0390CCCDDAF1}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug.ActiveCfg = Debug|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug.Build.0 = Debug|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release.ActiveCfg = Release|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release.Build.0 = Release|.NET {95394B96-A794-48EA-9879-0E4EC79C5724}.Debug.ActiveCfg = Debug|.NET {95394B96-A794-48EA-9879-0E4EC79C5724}.Debug.Build.0 = Debug|.NET {95394B96-A794-48EA-9879-0E4EC79C5724}.Release.ActiveCfg = Release|.NET {95394B96-A794-48EA-9879-0E4EC79C5724}.Release.Build.0 = Release|.NET {6BEF566A-2691-4EE8-91AF-0390CCCDDAF1}.Debug.ActiveCfg = Debug|.NET {6BEF566A-2691-4EE8-91AF-0390CCCDDAF1}.Debug.Build.0 = Debug|.NET {6BEF566A-2691-4EE8-91AF-0390CCCDDAF1}.Release.ActiveCfg = Release|.NET {6BEF566A-2691-4EE8-91AF-0390CCCDDAF1}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/cpp/0000775000175000017500000000000011742560362015413 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/managed/0000775000175000017500000000000011742560362017007 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/managed/managed-cpp.sln0000664000175000017500000000165211504175260021700 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-managed-failures", "failures\cpp-managed-failures.vcproj", "{7E5849C7-0469-4AD2-91B9-C87203934254}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug.ActiveCfg = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug.Build.0 = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release.ActiveCfg = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/cpp/managed/failures/0000775000175000017500000000000011742560362020621 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/managed/failures/AssemblyInfo.cpp0000664000175000017500000000440511504175260023716 0ustar jtaylorjtaylorusing namespace System::Reflection; using namespace System::Runtime::CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly:AssemblyTitleAttribute("")]; [assembly:AssemblyDescriptionAttribute("")]; [assembly:AssemblyConfigurationAttribute("")]; [assembly:AssemblyCompanyAttribute("")]; [assembly:AssemblyProductAttribute("")]; [assembly:AssemblyCopyrightAttribute("")]; [assembly:AssemblyTrademarkAttribute("")]; [assembly:AssemblyCultureAttribute("")]; // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly:AssemblyVersionAttribute("2.2.0.0")]; // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project directory. // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly:AssemblyDelaySignAttribute(false)]; [assembly:AssemblyKeyFileAttribute("")]; [assembly:AssemblyKeyNameAttribute("")]; NUnit-2.6.0.12051/samples/cpp/managed/failures/cppsample.h0000664000175000017500000000143711504175260022756 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** #pragma once using namespace System; using namespace NUnit::Framework; namespace NUnitSamples { [TestFixture] public __gc class SimpleCPPSample { int fValue1; int fValue2; public: [SetUp] void Init(); [Test] void Add(); [Test] void DivideByZero(); [Test] void Equals(); [Test] [Ignore("ignored test")] void IgnoredTest(); [Test] [ExpectedException(__typeof(InvalidOperationException))] void ExpectAnException(); }; } NUnit-2.6.0.12051/samples/cpp/managed/failures/cpp-managed-failures.build0000664000175000017500000000174311504175260025626 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/cpp/managed/failures/cppsample.cpp0000664000175000017500000000214411504175260023305 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** #include "cppsample.h" namespace NUnitSamples { void SimpleCPPSample::Init() { fValue1 = 2; fValue2 = 3; } void SimpleCPPSample::Add() { int result = fValue1 + fValue2; Assert::AreEqual(6,result); } void SimpleCPPSample::DivideByZero() { int zero= 0; int result= 8/zero; } void SimpleCPPSample::Equals() { Assert::AreEqual(12, 12, "Integer"); Assert::AreEqual(12L, 12L, "Long"); Assert::AreEqual('a', 'a', "Char"); Assert::AreEqual(12, 13, "Expected Failure (Integer)"); Assert::AreEqual(12.0, 11.99, 0.0, "Expected Failure (Double)"); } void SimpleCPPSample::IgnoredTest() { throw new InvalidCastException(); } void SimpleCPPSample::ExpectAnException() { throw new InvalidCastException(); } } NUnit-2.6.0.12051/samples/cpp/managed/failures/cpp-managed-failures.vcproj0000664000175000017500000000717711504175260026041 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/cpp/cpp-cli/0000775000175000017500000000000011742560362016742 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/cpp-cli/cpp-cli.sln0000664000175000017500000000503011504175260021000 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-cli-failures", "failures\cpp-cli-failures.vcproj", "{A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-cli-syntax", "syntax\cpp-cli-syntax.vcproj", "{72448C2D-17C9-419E-B28D-3B533E7E0CD5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Release|Any CPU = Release|Any CPU Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Debug|Any CPU.ActiveCfg = Debug|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Debug|Win32.ActiveCfg = Debug|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Debug|Win32.Build.0 = Debug|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Release|Any CPU.ActiveCfg = Release|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Release|Mixed Platforms.Build.0 = Release|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Release|Win32.ActiveCfg = Release|Win32 {A0987BCD-AFE6-40E4-95A8-ADA7ADB7E97D}.Release|Win32.Build.0 = Release|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Debug|Any CPU.ActiveCfg = Debug|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Debug|Win32.ActiveCfg = Debug|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Debug|Win32.Build.0 = Debug|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Release|Any CPU.ActiveCfg = Release|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Release|Mixed Platforms.Build.0 = Release|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Release|Win32.ActiveCfg = Release|Win32 {72448C2D-17C9-419E-B28D-3B533E7E0CD5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/cpp/cpp-cli/syntax/0000775000175000017500000000000011742560362020270 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/cpp-cli/syntax/cpp-cli-syntax.vcproj0000664000175000017500000001025611504175260024367 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/cpp/cpp-cli/syntax/AssemblyInfo.cpp0000664000175000017500000000247411504175260023371 0ustar jtaylorjtaylor#include "stdafx.h" using namespace System; using namespace System::Reflection; using namespace System::Runtime::CompilerServices; using namespace System::Runtime::InteropServices; using namespace System::Security::Permissions; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly:AssemblyTitleAttribute("cppclisyntax")]; [assembly:AssemblyDescriptionAttribute("")]; [assembly:AssemblyConfigurationAttribute("")]; [assembly:AssemblyCompanyAttribute("")]; [assembly:AssemblyProductAttribute("cppclisyntax")]; [assembly:AssemblyCopyrightAttribute("Copyright (c) 2007")]; [assembly:AssemblyTrademarkAttribute("")]; [assembly:AssemblyCultureAttribute("")]; // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly:AssemblyVersionAttribute("1.0.*")]; [assembly:ComVisible(false)]; [assembly:CLSCompliantAttribute(true)]; [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; NUnit-2.6.0.12051/samples/cpp/cpp-cli/syntax/cpp-cli-syntax.cpp0000664000175000017500000004615511504175260023655 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** using namespace NUnit::Framework; using NUnit::Framework::Is; using NUnit::Framework::Text; using NUnit::Framework::List; using NUnit::Framework::Has; using System::String; namespace NUnitSamples { [TestFixture] public ref class AssertSyntaxTests : AssertionHelper { public: [Test] void IsNull() { Object ^nada = nullptr; // Classic syntax Assert::IsNull(nada); // Helper syntax Assert::That(nada, Is::Null); // Inherited syntax Expect(nada, Null); } [Test] void IsNotNull() { // Classic syntax Assert::IsNotNull(42); // Helper syntax Assert::That(42, Is::Not->Null); // Inherited syntax Expect( 42, Not->Null ); } [Test] void IsTrue() { // Classic syntax Assert::IsTrue(2+2==4); // Helper syntax Assert::That(2+2==4, Is::True); Assert::That(2+2==4); // Inherited syntax Expect(2+2==4, True); Expect(2+2==4); } [Test] void IsFalse() { // Classic syntax Assert::IsFalse(2+2==5); // Helper syntax Assert::That(2+2==5, Is::False); // Inherited syntax Expect(2+2==5, False); } [Test] void IsNaN() { double d = double::NaN; float f = float::NaN; // Classic syntax Assert::IsNaN(d); Assert::IsNaN(f); // Helper syntax Assert::That(d, Is::NaN); Assert::That(f, Is::NaN); // Inherited syntax Expect(d, NaN); Expect(f, NaN); } [Test] void EmptyStringTests() { // Classic syntax Assert::IsEmpty(""); Assert::IsNotEmpty("Hello!"); // Helper syntax Assert::That("", Is::Empty); Assert::That("Hello!", Is::Not->Empty); // Inherited syntax Expect("", Empty); Expect("Hello!", Not->Empty); } [Test] void EmptyCollectionTests() { // Classic syntax Assert::IsEmpty(gcnew array(0)); Assert::IsNotEmpty(gcnew array(3)); // Helper syntax Assert::That(gcnew array(0), Is::Empty); Assert::That(gcnew array(3), Is::Not->Empty); // Inherited syntax Expect(gcnew array(0), Empty); Expect(gcnew array(3), Not->Empty); } [Test] void ExactTypeTests() { // Classic syntax workarounds) String^ greeting = "Hello"; Assert::AreEqual(String::typeid, greeting->GetType()); Assert::AreEqual("System.String", greeting->GetType()->FullName); Assert::AreNotEqual(int::typeid, greeting->GetType()); Assert::AreNotEqual("System.Int32", greeting->GetType()->FullName); // Helper syntax Assert::That(greeting, Is::TypeOf(String::typeid)); Assert::That(greeting, Is::Not->TypeOf(int::typeid)); // Inherited syntax Expect( "Hello", TypeOf(String::typeid)); Expect( "Hello", Not->TypeOf(int::typeid)); } [Test] void InstanceOfTypeTests() { // Classic syntax Assert::IsInstanceOfType(String::typeid, "Hello"); Assert::IsNotInstanceOfType(String::typeid, 5); // Helper syntax Assert::That("Hello", Is::InstanceOfType(String::typeid)); Assert::That(5, Is::Not->InstanceOfType(String::typeid)); // Inherited syntax Expect("Hello", InstanceOfType(String::typeid)); Expect(5, Not->InstanceOfType(String::typeid)); } [Test] void AssignableFromTypeTests() { // Classic syntax Assert::IsAssignableFrom(String::typeid, "Hello"); Assert::IsNotAssignableFrom(String::typeid, 5); // Helper syntax Assert::That( "Hello", Is::AssignableFrom(String::typeid)); Assert::That( 5, Is::Not->AssignableFrom(String::typeid)); // Inherited syntax Expect( "Hello", AssignableFrom(String::typeid)); Expect( 5, Not->AssignableFrom(String::typeid)); } [Test] void SubstringTests() { String^ phrase = "Hello World!"; array^ strings = {"abc", "bad", "dba" }; // Classic Syntax StringAssert::Contains("World", phrase); // Helper syntax Assert::That(phrase, Contains("World")); // Only available using new syntax Assert::That(phrase, Text::DoesNotContain("goodbye")); Assert::That(phrase, Text::Contains("WORLD")->IgnoreCase); Assert::That(phrase, Text::DoesNotContain("BYE")->IgnoreCase); Assert::That(strings, Text::All->Contains( "b" ) ); // Inherited syntax Expect(phrase, Contains("World")); // Only available using new syntax Expect(phrase, Not->Contains("goodbye")); Expect(phrase, Contains("WORLD")->IgnoreCase); Expect(phrase, Not->Contains("BYE")->IgnoreCase); Expect(strings, All->Contains("b")); } [Test] void StartsWithTests() { String^ phrase = "Hello World!"; array^ greetings = { "Hello!", "Hi!", "Hola!" }; // Classic syntax StringAssert::StartsWith("Hello", phrase); // Helper syntax Assert::That(phrase, Text::StartsWith("Hello")); // Only available using new syntax Assert::That(phrase, Text::DoesNotStartWith("Hi!")); Assert::That(phrase, Text::StartsWith("HeLLo")->IgnoreCase); Assert::That(phrase, Text::DoesNotStartWith("HI")->IgnoreCase); Assert::That(greetings, Text::All->StartsWith("h")->IgnoreCase); // Inherited syntax Expect(phrase, StartsWith("Hello")); // Only available using new syntax Expect(phrase, Not->StartsWith("Hi!")); Expect(phrase, StartsWith("HeLLo")->IgnoreCase); Expect(phrase, Not->StartsWith("HI")->IgnoreCase); Expect(greetings, All->StartsWith("h")->IgnoreCase); } [Test] void EndsWithTests() { String^ phrase = "Hello World!"; array^ greetings = { "Hello!", "Hi!", "Hola!" }; // Classic Syntax StringAssert::EndsWith("!", phrase); // Helper syntax Assert::That(phrase, Text::EndsWith("!")); // Only available using new syntax Assert::That(phrase, Text::DoesNotEndWith("?")); Assert::That(phrase, Text::EndsWith("WORLD!")->IgnoreCase); Assert::That(greetings, Text::All->EndsWith("!")); // Inherited syntax Expect(phrase, EndsWith("!")); // Only available using new syntax Expect(phrase, Not->EndsWith("?")); Expect(phrase, EndsWith("WORLD!")->IgnoreCase); Expect(greetings, All->EndsWith("!") ); } [Test] void EqualIgnoringCaseTests() { String^ phrase = "Hello World!"; // Classic syntax StringAssert::AreEqualIgnoringCase("hello world!",phrase); // Helper syntax Assert::That(phrase, Is::EqualTo("hello world!")->IgnoreCase); //Only available using new syntax Assert::That(phrase, Is::Not->EqualTo("goodbye world!")->IgnoreCase); Assert::That(gcnew array { "Hello", "World" }, Is::EqualTo(gcnew array { "HELLO", "WORLD" })->IgnoreCase); Assert::That(gcnew array {"HELLO", "Hello", "hello" }, Is::All->EqualTo( "hello" )->IgnoreCase); // Inherited syntax Expect(phrase, EqualTo("hello world!")->IgnoreCase); //Only available using new syntax Expect(phrase, Not->EqualTo("goodbye world!")->IgnoreCase); Expect(gcnew array { "Hello", "World" }, EqualTo(gcnew array { "HELLO", "WORLD" })->IgnoreCase); Expect(gcnew array {"HELLO", "Hello", "hello" }, All->EqualTo( "hello" )->IgnoreCase); } [Test] void RegularExpressionTests() { String^ phrase = "Now is the time for all good men to come to the aid of their country."; array^ quotes = { "Never say never", "It's never too late", "Nevermore!" }; // Classic syntax StringAssert::IsMatch( "all good men", phrase ); StringAssert::IsMatch( "Now.*come", phrase ); // Helper syntax Assert::That( phrase, Text::Matches( "all good men" ) ); Assert::That( phrase, Text::Matches( "Now.*come" ) ); // Only available using new syntax Assert::That(phrase, Text::DoesNotMatch("all.*men.*good")); Assert::That(phrase, Text::Matches("ALL")->IgnoreCase); Assert::That(quotes, Text::All->Matches("never")->IgnoreCase); // Inherited syntax Expect( phrase, Matches( "all good men" ) ); Expect( phrase, Matches( "Now.*come" ) ); // Only available using new syntax Expect(phrase, Not->Matches("all.*men.*good")); Expect(phrase, Matches("ALL")->IgnoreCase); Expect(quotes, All->Matches("never")->IgnoreCase); } [Test] void EqualityTests() { array^ i3 = { 1, 2, 3 }; array^ d3 = { 1.0, 2.0, 3.0 }; array^ iunequal = { 1, 3, 2 }; // Classic Syntax Assert::AreEqual(4, 2 + 2); Assert::AreEqual(i3, d3); Assert::AreNotEqual(5, 2 + 2); Assert::AreNotEqual(i3, iunequal); // Helper syntax Assert::That(2 + 2, Is::EqualTo(4)); Assert::That(2 + 2 == 4); Assert::That(i3, Is::EqualTo(d3)); Assert::That(2 + 2, Is::Not->EqualTo(5)); Assert::That(i3, Is::Not->EqualTo(iunequal)); // Inherited syntax Expect(2 + 2, EqualTo(4)); Expect(2 + 2 == 4); Expect(i3, EqualTo(d3)); Expect(2 + 2, Not->EqualTo(5)); Expect(i3, Not->EqualTo(iunequal)); } [Test] void EqualityTestsWithTolerance() { // CLassic syntax Assert::AreEqual(5.0, 4.99, 0.05); Assert::AreEqual(5.0F, 4.99F, 0.05F); // Helper syntax Assert::That(4.99L, Is::EqualTo(5.0L)->Within(0.05L)); Assert::That(4.99f, Is::EqualTo(5.0f)->Within(0.05f)); // Inherited syntax Expect(4.99L, EqualTo(5.0L)->Within(0.05L)); Expect(4.99f, EqualTo(5.0f)->Within(0.05f)); } [Test] void ComparisonTests() { // Classic Syntax Assert::Greater(7, 3); Assert::GreaterOrEqual(7, 3); Assert::GreaterOrEqual(7, 7); // Helper syntax Assert::That(7, Is::GreaterThan(3)); Assert::That(7, Is::GreaterThanOrEqualTo(3)); Assert::That(7, Is::AtLeast(3)); Assert::That(7, Is::GreaterThanOrEqualTo(7)); Assert::That(7, Is::AtLeast(7)); // Inherited syntax Expect(7, GreaterThan(3)); Expect(7, GreaterThanOrEqualTo(3)); Expect(7, AtLeast(3)); Expect(7, GreaterThanOrEqualTo(7)); Expect(7, AtLeast(7)); // Classic syntax Assert::Less(3, 7); Assert::LessOrEqual(3, 7); Assert::LessOrEqual(3, 3); // Helper syntax Assert::That(3, Is::LessThan(7)); Assert::That(3, Is::LessThanOrEqualTo(7)); Assert::That(3, Is::AtMost(7)); Assert::That(3, Is::LessThanOrEqualTo(3)); Assert::That(3, Is::AtMost(3)); // Inherited syntax Expect(3, LessThan(7)); Expect(3, LessThanOrEqualTo(7)); Expect(3, AtMost(7)); Expect(3, LessThanOrEqualTo(3)); Expect(3, AtMost(3)); } [Test] void AllItemsTests() { array^ ints = { 1, 2, 3, 4 }; array^ strings = { "abc", "bad", "cab", "bad", "dad" }; // Classic syntax CollectionAssert::AllItemsAreNotNull(ints); CollectionAssert::AllItemsAreInstancesOfType(ints, int::typeid); CollectionAssert::AllItemsAreInstancesOfType(strings, String::typeid); CollectionAssert::AllItemsAreUnique(ints); // Helper syntax Assert::That(ints, Is::All->Not->Null); Assert::That(ints, Is::All->InstanceOfType(int::typeid)); Assert::That(strings, Is::All->InstanceOfType(String::typeid)); Assert::That(ints, Is::Unique); // Only available using new syntax Assert::That(strings, Is::Not->Unique); Assert::That(ints, Is::All->GreaterThan(0)); Assert::That(strings, Text::All->Contains( "a" ) ); Assert::That(strings, Has::Some->StartsWith( "ba" ) ); // Inherited syntax Expect(ints, All->Not->Null); Expect(ints, All->InstanceOfType(int::typeid)); Expect(strings, All->InstanceOfType(String::typeid)); Expect(ints, Unique); // Only available using new syntax Expect(strings, Not->Unique); Expect(ints, All->GreaterThan(0)); Expect(strings, All->Contains( "a" ) ); Expect(strings, Some->StartsWith( "ba" ) ); } [Test] void SomeItemsTests() { array^ mixed = { 1, 2, "3", nullptr, "four", 100 }; array^ strings = { "abc", "bad", "cab", "bad", "dad" }; // Not available using the classic syntax // Helper syntax Assert::That(mixed, Has::Some->Null); Assert::That(mixed, Has::Some->InstanceOfType(int::typeid)); Assert::That(mixed, Has::Some->InstanceOfType(String::typeid)); Assert::That(strings, Has::Some->StartsWith( "ba" ) ); Assert::That(strings, Has::Some->Not->StartsWith( "ba" ) ); // Inherited syntax Expect(mixed, Some->Null); Expect(mixed, Some->InstanceOfType(int::typeid)); Expect(mixed, Some->InstanceOfType(String::typeid)); Expect(strings, Some->StartsWith( "ba" ) ); Expect(strings, Some->Not->StartsWith( "ba" ) ); } [Test] void NoItemsTests() { array^ ints = { 1, 2, 3, 4, 5 }; array^ strings = { "abc", "bad", "cab", "bad", "dad" }; // Not available using the classic syntax // Helper syntax Assert::That(ints, Has::None->Null); Assert::That(ints, Has::None->InstanceOfType(String::typeid)); Assert::That(ints, Has::None->GreaterThan(99)); Assert::That(strings, Has::None->StartsWith( "qu" ) ); // Inherited syntax Expect(ints, None->Null); Expect(ints, None->InstanceOfType(String::typeid)); Expect(ints, None->GreaterThan(99)); Expect(strings, None->StartsWith( "qu" ) ); } [Test] void CollectionContainsTests() { array^ iarray = { 1, 2, 3 }; array^ sarray = { "a", "b", "c" }; // Classic syntax Assert::Contains(3, iarray); Assert::Contains("b", sarray); CollectionAssert::Contains(iarray, 3); CollectionAssert::Contains(sarray, "b"); CollectionAssert::DoesNotContain(sarray, "x"); // Helper syntax Assert::That(iarray, Has::Member(3)); Assert::That(sarray, Has::Member("b")); Assert::That(sarray, Has::No->Member("x")); // Yuck! Assert::That(sarray, !Has::Member("x")); // Inherited syntax Expect(iarray, Contains(3)); Expect(sarray, Contains("b")); Expect(sarray, Not->Contains("x")); Expect(sarray, !Contains("x")); } [Test] void CollectionEquivalenceTests() { array^ ints1to5 = { 1, 2, 3, 4, 5 }; // Classic syntax CollectionAssert::AreEquivalent(gcnew array { 2, 1, 4, 3, 5 }, ints1to5); CollectionAssert::AreNotEquivalent(gcnew array { 2, 2, 4, 3, 5 }, ints1to5); CollectionAssert::AreNotEquivalent(gcnew array { 2, 4, 3, 5 }, ints1to5); CollectionAssert::AreNotEquivalent(gcnew array { 2, 2, 1, 1, 4, 3, 5 }, ints1to5); // Helper syntax Assert::That(gcnew array { 2, 1, 4, 3, 5 }, Is::EquivalentTo(ints1to5)); Assert::That(gcnew array { 2, 2, 4, 3, 5 }, Is::Not->EquivalentTo(ints1to5)); Assert::That(gcnew array { 2, 4, 3, 5 }, Is::Not->EquivalentTo(ints1to5)); Assert::That(gcnew array { 2, 2, 1, 1, 4, 3, 5 }, Is::Not->EquivalentTo(ints1to5)); // Inherited syntax Expect(gcnew array { 2, 1, 4, 3, 5 }, EquivalentTo(ints1to5)); Expect(gcnew array { 2, 2, 4, 3, 5 }, Not->EquivalentTo(ints1to5)); Expect(gcnew array { 2, 4, 3, 5 }, Not->EquivalentTo(ints1to5)); Expect(gcnew array { 2, 2, 1, 1, 4, 3, 5 }, Not->EquivalentTo(ints1to5)); } [Test] void SubsetTests() { array^ ints1to5 = { 1, 2, 3, 4, 5 }; // Classic syntax CollectionAssert::IsSubsetOf(gcnew array { 1, 3, 5 }, ints1to5); CollectionAssert::IsSubsetOf(gcnew array { 1, 2, 3, 4, 5 }, ints1to5); CollectionAssert::IsNotSubsetOf(gcnew array { 2, 4, 6 }, ints1to5); CollectionAssert::IsNotSubsetOf(gcnew array { 1, 2, 2, 2, 5 }, ints1to5); // Helper syntax Assert::That(gcnew array { 1, 3, 5 }, Is::SubsetOf(ints1to5)); Assert::That(gcnew array { 1, 2, 3, 4, 5 }, Is::SubsetOf(ints1to5)); Assert::That(gcnew array { 2, 4, 6 }, Is::Not->SubsetOf(ints1to5)); Assert::That(gcnew array { 1, 2, 2, 2, 5 }, Is::Not->SubsetOf(ints1to5)); // Inherited syntax Expect(gcnew array { 1, 3, 5 }, SubsetOf(ints1to5)); Expect(gcnew array { 1, 2, 3, 4, 5 }, SubsetOf(ints1to5)); Expect(gcnew array { 2, 4, 6 }, Not->SubsetOf(ints1to5)); Expect(gcnew array { 1, 2, 2, 2, 5 }, Not->SubsetOf(ints1to5)); } [Test] void PropertyTests() { array^ strings = { "abc", "bca", "xyz" }; // Helper syntax Assert::That( "Hello", Has::Property("Length")->EqualTo(5) ); Assert::That( "Hello", Has::Length->EqualTo( 5 ) ); Assert::That( strings , Has::All->Property( "Length")->EqualTo(3) ); Assert::That( strings, Has::All->Length->EqualTo( 3 ) ); // Inherited syntax Expect( "Hello", Property("Length")->EqualTo(5) ); Expect( "Hello", Length->EqualTo( 5 ) ); Expect( strings, All->Property("Length")->EqualTo(3) ); Expect( strings, All->Length->EqualTo( 3 ) ); } [Test] void NotTests() { // Not available using the classic syntax // Helper syntax Assert::That(42, Is::Not->Null); Assert::That(42, Is::Not->True); Assert::That(42, Is::Not->False); Assert::That(2.5, Is::Not->NaN); Assert::That(2 + 2, Is::Not->EqualTo(3)); Assert::That(2 + 2, Is::Not->Not->EqualTo(4)); Assert::That(2 + 2, Is::Not->Not->Not->EqualTo(5)); // Inherited syntax Expect(42, Not->Null); Expect(42, Not->True); Expect(42, Not->False); Expect(2.5, Not->NaN); Expect(2 + 2, Not->EqualTo(3)); Expect(2 + 2, Not->Not->EqualTo(4)); Expect(2 + 2, Not->Not->Not->EqualTo(5)); } [Test] void NotOperator() { // The ! operator is only available in the new syntax Assert::That(42, !Is::Null); // Inherited syntax Expect( 42, !Null ); } [Test] void AndOperator() { // The & operator is only available in the new syntax Assert::That(7, Is::GreaterThan(5) & Is::LessThan(10)); // Inherited syntax Expect( 7, GreaterThan(5) & LessThan(10)); } [Test] void OrOperator() { // The | operator is only available in the new syntax Assert::That(3, Is::LessThan(5) | Is::GreaterThan(10)); Expect( 3, LessThan(5) | GreaterThan(10)); } [Test] void ComplexTests() { Assert::That(7, Is::Not->Null & Is::Not->LessThan(5) & Is::Not->GreaterThan(10)); Expect(7, Not->Null & Not->LessThan(5) & Not->GreaterThan(10)); Assert::That(7, !Is::Null & !Is::LessThan(5) & !Is::GreaterThan(10)); Expect(7, !Null & !LessThan(5) & !GreaterThan(10)); } // This method contains assertions that should not compile // You can check by uncommenting it. //void WillNotCompile() //{ // Assert::That(42, Is::Not); // Assert::That(42, Is::All); // Assert::That(42, Is::Null->Not); // Assert::That(42, Is::Not->Null->GreaterThan(10)); // Assert::That(42, Is::GreaterThan(10)->LessThan(99)); // object[] c = new object[0]; // Assert::That(c, Is::Null->All); // Assert::That(c, Is::Not->All); // Assert::That(c, Is::All->Not); //} }; }NUnit-2.6.0.12051/samples/cpp/cpp-cli/syntax/cpp-cli-syntax.build0000664000175000017500000000042311504175260024156 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/0000775000175000017500000000000011742560362020554 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/AssemblyInfo.cpp0000664000175000017500000000440511504175260023651 0ustar jtaylorjtaylorusing namespace System::Reflection; using namespace System::Runtime::CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly:AssemblyTitleAttribute("")]; [assembly:AssemblyDescriptionAttribute("")]; [assembly:AssemblyConfigurationAttribute("")]; [assembly:AssemblyCompanyAttribute("")]; [assembly:AssemblyProductAttribute("")]; [assembly:AssemblyCopyrightAttribute("")]; [assembly:AssemblyTrademarkAttribute("")]; [assembly:AssemblyCultureAttribute("")]; // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly:AssemblyVersionAttribute("2.2.0.0")]; // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project directory. // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly:AssemblyDelaySignAttribute(false)]; [assembly:AssemblyKeyFileAttribute("")]; [assembly:AssemblyKeyNameAttribute("")]; NUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/cppsample.h0000664000175000017500000000143411504175260022706 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** #pragma once using namespace System; using namespace NUnit::Framework; namespace NUnitSamples { [TestFixture] public ref class SimpleCPPSample { int fValue1; int fValue2; public: [SetUp] void Init(); [Test] void Add(); [Test] void DivideByZero(); [Test] void Equals(); [Test] [Ignore("ignored test")] void IgnoredTest(); [Test] [ExpectedException(InvalidOperationException::typeid)] void ExpectAnException(); }; } NUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/cpp-cli-failures.build0000664000175000017500000000127711504175260024736 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/cppsample.cpp0000664000175000017500000000215011504175260023235 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** #include "cppsample.h" namespace NUnitSamples { void SimpleCPPSample::Init() { fValue1 = 2; fValue2 = 3; } void SimpleCPPSample::Add() { int result = fValue1 + fValue2; Assert::AreEqual(6,result); } void SimpleCPPSample::DivideByZero() { int zero= 0; int result= 8/zero; } void SimpleCPPSample::Equals() { Assert::AreEqual(12, 12, "Integer"); Assert::AreEqual(12L, 12L, "Long"); Assert::AreEqual('a', 'a', "Char"); Assert::AreEqual(12, 13, "Expected Failure (Integer)"); Assert::AreEqual(12.0, 11.99, 0.0, "Expected Failure (Double)"); } void SimpleCPPSample::IgnoredTest() { throw gcnew InvalidCastException(); } void SimpleCPPSample::ExpectAnException() { throw gcnew InvalidCastException(); } } NUnit-2.6.0.12051/samples/cpp/cpp-cli/failures/cpp-cli-failures.vcproj0000664000175000017500000001026011504175260025132 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/samples.common0000664000175000017500000002343011535406000017475 0ustar jtaylorjtaylor te NUnit-2.6.0.12051/samples/ReadMe.txt0000664000175000017500000000424311504175260016525 0ustar jtaylorjtaylorNUnit Samples This directory contains sample applications demonstrating the use of NUnit and organized as follows... CSharp: Samples in C# Failures: Demonstrates 4 failing tests and one that is not run. Money: This is a C# version of the money example which is found in most xUnit implementations. Thanks to Kent Beck. Money-Port: This shows how the Money example can be ported from Version 1 of NUnit with minimal changes. Syntax: Illustrates most Assert methods using both the classic and constraint-based syntax. JSharp: Samples in J# Failures: Demonstrates 4 failing tests and one that is not run. CPP: C++ Samples MANAGED: Managed C++ Samples (VS 2003 compatible) Failures: Demonstrates 4 failing tests and one that is not run. CPP-CLI: C++/CLI Samples (VS 2005 only) Failures: Demonstrates 4 failing tests and one that is not run. Syntax: Illustrates most Assert methods using both the classic and constraint-based syntax. VB: Samples in VB.NET Failures: Demonstrates 4 failing tests and one that is not run. Money: This is a VB.NET version of the money example found in most xUnit implementations. Thanks to Kent Beck. Syntax: Illustrates most Assert methods using both the classic and constraint-based syntax. Extensibility: Examples of extending NUnit Framework: Core: TestSuiteExtension TestFixtureExtension Building the Samples A Visual Studio 2003 project is included for most samples. Visual Studio 2005 will convert the format automatically upon opening it. The C++/CLI samples, as well as other samples that depend on .NET 2.0 features, include Visual Studio 2005 projects. In most cases, you will need to remove the reference to the nunit.framework assembly and replace it with a reference to your installed copy of NUnit. To build using the Microsoft compiler, use a command similar to the following: csc /target:library /r:/nunit.framework.dll example.cs To build using the mono compiler, use a command like this: msc /target:library /r:/nunit.framework.dll example.cs NUnit-2.6.0.12051/samples/jsharp/0000775000175000017500000000000011742560362016120 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/jsharp/jsharp.sln0000664000175000017500000000163511504175260020125 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}") = "jsharp-failures", "failures\jsharp-failures.vjsproj", "{B55A6E53-57A9-4205-B396-C9983B3AF46A}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug.ActiveCfg = Debug|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug.Build.0 = Debug|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release.ActiveCfg = Release|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/jsharp/failures/0000775000175000017500000000000011742560362017732 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/jsharp/failures/JSharpTest.jsl0000664000175000017500000000343311504175260022471 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** package NUnit.Samples; import System.*; import NUnit.Framework.Assert; /** @attribute NUnit.Framework.TestFixture() */ public class SimpleJSharpTest { protected int fValue1; protected int fValue2; /** @attribute NUnit.Framework.SetUp() */ public void Init() { fValue1 = 2; fValue2 = 3; } /** @attribute NUnit.Framework.Test() */ public void Add() { int result= fValue1 + fValue2; Assert.AreEqual(6,result, "Expected Failure"); } /** @attribute NUnit.Framework.Test() */ public void DivideByZero() { int zero= 0; int result = 8/zero; KeepCompilerFromWarning(result); // never executed, here to avoid compiler warning that result is unused. } /** @attribute NUnit.Framework.Test() */ public void Equals() { Assert.AreEqual(12, 12, "Integer"); Assert.AreEqual(new Long(12), new Long(13), "Long"); Assert.AreEqual('a', 'a', "Char"); Assert.AreEqual(new Integer(12), new Integer(12), "Integer Object Cast"); Assert.AreEqual(12, 13, "Expected Failure (Integer)"); Assert.AreEqual(12.0, 11.99, 0.0, "Expected Failure (Double)."); } /** @attribute NUnit.Framework.Test() */ /** @attribute NUnit.Framework.Ignore("ignored test") */ public void IgnoredTest() { throw new InvalidCastException(); } // A useless function, designed to avoid a compiler warning in the the DivideByZero test. private int KeepCompilerFromWarning(int dummy) { return dummy; } }NUnit-2.6.0.12051/samples/jsharp/failures/AssemblyInfo.jsl0000664000175000017500000000456711504175260023046 0ustar jtaylorjtaylorimport System.Reflection.*; import System.Runtime.CompilerServices.*; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // /** @assembly AssemblyTitle("") */ /** @assembly AssemblyDescription("") */ /** @assembly AssemblyConfiguration("") */ /** @assembly AssemblyCompany("") */ /** @assembly AssemblyProduct("") */ /** @assembly AssemblyCopyright("") */ /** @assembly AssemblyTrademark("") */ /** @assembly AssemblyCulture("") */ // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build // Numbers by using the '*' as shown below: /** @assembly AssemblyVersion("2.2.0.0") */ // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project directory. For example, if your KeyFile is // located in the project directory itself, you would specify the // AssemblyKeyFile attribute as @assembly AssemblyKeyFile("mykey.snk") // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // /** @assembly AssemblyDelaySign(false) */ /** @assembly AssemblyKeyFile("") */ /** @assembly AssemblyKeyName("") */ NUnit-2.6.0.12051/samples/jsharp/failures/jsharp-failures.build0000664000175000017500000000041611504175260024046 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/jsharp/failures/jsharp-failures.vjsproj0000664000175000017500000000327411720516414024451 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/0000775000175000017500000000000011742560362017465 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/Extensibility/Core/0000775000175000017500000000000011742560362020355 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/0000775000175000017500000000000011742560362024505 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/SampleSuiteExtensionAttribute.cs0000664000175000017500000000116011504175260033041 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; namespace NUnit.Core.Extensions { /// /// SampleSuiteExtensionAttribute is used to identify a SampleSuiteExtension fixture /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public sealed class SampleSuiteExtensionAttribute : Attribute { } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/Addin.cs0000664000175000017500000000161411504175260026050 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using NUnit.Core.Extensibility; namespace NUnit.Core.Extensions { /// /// Summary description for Addin. /// [NUnitAddin(Name="SampleSuiteExtension", Description = "Recognizes Tests starting with SampleTest...")] public class Addin : IAddin { #region IAddin Members public bool Install(IExtensionHost host) { IExtensionPoint builders = host.GetExtensionPoint( "SuiteBuilders" ); if ( builders == null ) return false; builders.Install( new SampleSuiteExtensionBuilder() ); return true; } #endregion } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/SampleSuiteExtension.cs0000664000175000017500000000303311504175260031156 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using System.Reflection; namespace NUnit.Core.Extensions { /// /// SampleSuiteExtension is a minimal example of a suite extension. It /// extends test suite and creates a fixture that runs every test starting /// with "SampleTest..." Because it inherits from TestSuite, rather than /// TestFixture, it has to construct its own fixture object and find its /// own tests. Everything is done in the constructor for simplicity. /// class SampleSuiteExtension : TestSuite { public SampleSuiteExtension( Type fixtureType ) : base( fixtureType ) { // Create the fixture object. We could wait to do this when // it is needed, but we do it here for simplicity. this.Fixture = Reflect.Construct( fixtureType ); // Locate our test methods and add them to the suite using // the Add method of TestSuite. Note that we don't do a simple // Tests.Add, because that wouldn't set the parent of the tests. foreach( MethodInfo method in fixtureType.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ) ) { if ( method.Name.StartsWith( "SampleTest" ) ) this.Add( new NUnitTestMethod( method ) ); } } } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/SampleSuiteExtension.build0000664000175000017500000000104111504175260031645 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/AssemblyInfo.cs0000664000175000017500000000457211504175260027432 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/Tests/0000775000175000017500000000000011742560362025607 5ustar jtaylorjtaylor././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootNUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/Tests/SampleSuiteExtensionTests.csprojNUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/Tests/SampleSuiteExtensionTests.cs0000664000175000017500000000705111504175260033307 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/Tests/SampleSuiteExtensionTests.cs0000664000175000017500000000150611504175260033306 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using System.Reflection; namespace NUnit.Core.Extensions.Tests { /// /// Test class that demonstrates SampleSuiteExtension /// [SampleSuiteExtension] public class SampleSuiteExtensionTests { public void SampleTest1() { Console.WriteLine( "Hello from sample test 1" ); } public void SampleTest2() { Console.WriteLine( "Hello from sample test 2" ); } public void NotATest() { Console.WriteLine( "I shouldn't be called!" ); } } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/SampleSuiteExtensionBuilder.cs0000664000175000017500000000265611504175260032477 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using NUnit.Core.Extensibility; namespace NUnit.Core.Extensions { /// /// SampleSuiteExtensionBuilder knows how to build a SampleSuiteExtension /// public class SampleSuiteExtensionBuilder : ISuiteBuilder { #region ISuiteBuilder Members // This builder delegates all the work to the constructor of the // extension suite. Many builders will need to do more work, // looking for other attributes, setting properties on the // suite and locating methods for tests, setup and teardown. public Test BuildFrom(Type type) { if ( CanBuildFrom( type ) ) return new SampleSuiteExtension( type ); return null; } // The builder recognizes the types that it can use by the presense // of SampleSuiteExtensionAttribute. Note that an attribute does not // have to be used. You can use any arbitrary set of rules that can be // implemented using reflection on the type. public bool CanBuildFrom(Type type) { return Reflect.HasAttribute( type, "NUnit.Core.Extensions.SampleSuiteExtensionAttribute", false ); } #endregion } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/SampleSuiteExtension.csproj0000664000175000017500000001034711504175260032057 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/SampleSuiteExtension/ReadMe.txt0000664000175000017500000000340411504175260026377 0ustar jtaylorjtaylorSampleSuiteExtension Example This is a minimal example of a SuiteBuilder extension. It extends NUnit.Core.TestSuite test suite and creates a fixture that runs every test starting with "SampleTest..." It packages both the core extension and the attribute used in the tests in the same assembly. SampleSuiteExtension Class This class derives from NUnit.Framework.TestSuite and represents the extended suite within NUnit. Because it inherits from TestSuite, rather than TestFixture, it has to construct its own fixture object and find its own tests. Everything is done in the constructor for simplicity. SampleSuiteExtensionBuilder This class is the actual SuiteBuilder loaded by NUnit as an add-in. It recognizes the SampleSuiteExtensionAttribute and invokes the SampleSuiteExtension constructor to build the suite. SampleSuiteExtensionAttribute This is the special attribute used to mark tests to be constructed using this add-in. It is the only class referenced from the user tests. Note on Building this Extension If you use the Visual Studio solution, the NUnit references in both included projects must be changed so that they refer to the copy of NUnit in which you want to install the extension. The post-build step for the SampleSuiteExtension project must be changed to copy the extension into the addins directory for your NUnit install. NOTE: The references to nunit.core and nunit.common in the SampleSuiteExtension project have their Copy Local property set to false, rather than the Visual Studio default of true. In developing extensions, it is essential there be no extra copies of these assemblies be created. Once the extension is complete, those who install it in binary form will not need to deal with this issue. NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/0000775000175000017500000000000011742560362025042 5ustar jtaylorjtaylor././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtensionAttribute.csNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtensionAttribute.0000664000175000017500000000116411504175260033411 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; namespace NUnit.Core.Extensions { /// /// SampleFixtureExtensionAttribute is used to identify a SampleFixtureExtension class /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public sealed class SampleFixtureExtensionAttribute : Attribute { } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/AssemblyInfo.cs0000664000175000017500000000457211504175260027767 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtension.csproj0000664000175000017500000001024111504175260032742 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/0000775000175000017500000000000011742560362026144 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/AssemblyInfo.cs0000664000175000017500000000457211504175260031071 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/SampleFixtureExtensionTests.csprojNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/SampleFixtureExtensionTest0000664000175000017500000000705411504175260033415 0ustar jtaylorjtaylor ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/SampleFixtureExtensionTests.csNUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/Tests/SampleFixtureExtensionTest0000664000175000017500000000213611504175260033411 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Extensions; namespace NUnit.Extensions.Tests { /// /// Test class that demonstrates SampleFixtureExtension /// [SampleFixtureExtension] public class SampleFixtureExtensionTests { [TestFixtureSetUp] public void SetUpTests() { Console.WriteLine( "TestFixtureSetUp called" ); } [TestFixtureTearDown] public void FixtureTearDown() { Console.WriteLine( "TestFixtureTearDown called" ); } [Test] public void SomeTest() { Console.WriteLine( "Hello from some test" ); } [Test] public void AnotherTest() { Console.WriteLine( "Hello from another test" ); } public void NotATest() { Console.WriteLine( "I shouldn't be called!" ); } } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtensionBuilder.cs0000664000175000017500000000352311504175260033363 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using NUnit.Core.Builders; using NUnit.Core.Extensibility; namespace NUnit.Core.Extensions { /// /// MockFixtureExtensionBuilder knows how to build /// a MockFixtureExtension. /// [NUnitAddin(Description="Wraps an NUnitTestFixture with an additional level of SetUp and TearDown")] public class SampleFixtureExtensionBuilder : ISuiteBuilder, IAddin { #region NUnitTestFixtureBuilder Overrides /// /// Makes a SampleFixtureExtension instance /// /// The type to be used /// A SampleFixtureExtension as a TestSuite // protected override TestSuite MakeSuite(Type type) // { // return new SampleFixtureExtension( type ); // } // The builder recognizes the types that it can use by the presense // of SampleFixtureExtensionAttribute. Note that an attribute does not // have to be used. You can use any arbitrary set of rules that can be // implemented using reflection on the type. public bool CanBuildFrom(Type type) { return Reflect.HasAttribute( type, "NUnit.Core.Extensions.SampleFixtureExtensionAttribute", false ); } public Test BuildFrom(Type type) { return null; } #endregion #region IAddin Members public bool Install(IExtensionHost host) { IExtensionPoint suiteBuilders = host.GetExtensionPoint( "SuiteBuilders" ); if ( suiteBuilders == null ) return false; suiteBuilders.Install( this ); return true; } #endregion } } NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/ReadMe.txt0000664000175000017500000000340411504175260026734 0ustar jtaylorjtaylorSampleSuiteExtension Example This is a minimal example of a SuiteBuilder extension. It extends NUnit.Core.TestSuite test suite and creates a fixture that runs every test starting with "SampleTest..." It packages both the core extension and the attribute used in the tests in the same assembly. SampleSuiteExtension Class This class derives from NUnit.Framework.TestSuite and represents the extended suite within NUnit. Because it inherits from TestSuite, rather than TestFixture, it has to construct its own fixture object and find its own tests. Everything is done in the constructor for simplicity. SampleSuiteExtensionBuilder This class is the actual SuiteBuilder loaded by NUnit as an add-in. It recognizes the SampleSuiteExtensionAttribute and invokes the SampleSuiteExtension constructor to build the suite. SampleSuiteExtensionAttribute This is the special attribute used to mark tests to be constructed using this add-in. It is the only class referenced from the user tests. Note on Building this Extension If you use the Visual Studio solution, the NUnit references in both included projects must be changed so that they refer to the copy of NUnit in which you want to install the extension. The post-build step for the SampleSuiteExtension project must be changed to copy the extension into the addins directory for your NUnit install. NOTE: The references to nunit.core and nunit.common in the SampleSuiteExtension project have their Copy Local property set to false, rather than the Visual Studio default of true. In developing extensions, it is essential there be no extra copies of these assemblies be created. Once the extension is complete, those who install it in binary form will not need to deal with this issue. NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtension.build0000664000175000017500000000106411504175260032544 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/SampleFixtureExtension/SampleFixtureExtension.cs0000664000175000017500000000313411504175260032052 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; namespace NUnit.Core.Extensions { /// /// SampleFixtureExtension extends NUnitTestFixture and adds a custom setup /// before running TestFixtureSetUp and after running TestFixtureTearDown. /// Because it inherits from NUnitTestFixture, a lot of work is done for it. /// class SampleFixtureExtension : NUnitTestFixture { public SampleFixtureExtension( Type fixtureType ) : base( fixtureType ) { // NOTE: Since we are inheriting from NUnitTestFixture we don't // have to do anything if we don't want to. All the attributes // that are normally used with an NUnitTestFixture will be // recognized. // // Just to have something to do, we override DoOneTimeSetUp and // DoOneTimeTearDown below to do some special processing before // and after the normal TestFixtureSetUp and TestFixtureTearDown. // In this example, we simply display a message. } protected override void DoOneTimeSetUp(TestResult suiteResult) { Console.WriteLine( "Extended Fixture SetUp called" ); base.DoOneTimeSetUp (suiteResult); } protected override void DoOneTimeTearDown(TestResult suiteResult) { base.DoOneTimeTearDown (suiteResult); Console.WriteLine( "Extended Fixture TearDown called" ); } } } NUnit-2.6.0.12051/samples/Extensibility/Core/CoreExtensibility.sln0000664000175000017500000000605711504175260024543 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Minimal", "Minimal\Minimal.csproj", "{EF428E5B-B3E7-4C2F-B005-98DE7D6E7CDB}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleFixtureExtension", "SampleFixtureExtension\SampleFixtureExtension.csproj", "{ED281A23-9579-4A70-B608-1B86DCDEB78C}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleFixtureExtensionTests", "SampleFixtureExtension\Tests\SampleFixtureExtensionTests.csproj", "{0DE6C90F-BB74-4BC8-887A-2222DB56D2EB}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleSuiteExtension", "SampleSuiteExtension\SampleSuiteExtension.csproj", "{0C4269EE-3266-45DD-9062-E356C067FBEF}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleSuiteExtensionTests", "SampleSuiteExtension\Tests\SampleSuiteExtensionTests.csproj", "{9F609A0D-FF7E-4F0C-B2DF-417EBC557CFF}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {EF428E5B-B3E7-4C2F-B005-98DE7D6E7CDB}.Debug.ActiveCfg = Debug|.NET {EF428E5B-B3E7-4C2F-B005-98DE7D6E7CDB}.Debug.Build.0 = Debug|.NET {EF428E5B-B3E7-4C2F-B005-98DE7D6E7CDB}.Release.ActiveCfg = Release|.NET {EF428E5B-B3E7-4C2F-B005-98DE7D6E7CDB}.Release.Build.0 = Release|.NET {ED281A23-9579-4A70-B608-1B86DCDEB78C}.Debug.ActiveCfg = Debug|.NET {ED281A23-9579-4A70-B608-1B86DCDEB78C}.Debug.Build.0 = Debug|.NET {ED281A23-9579-4A70-B608-1B86DCDEB78C}.Release.ActiveCfg = Release|.NET {ED281A23-9579-4A70-B608-1B86DCDEB78C}.Release.Build.0 = Release|.NET {0DE6C90F-BB74-4BC8-887A-2222DB56D2EB}.Debug.ActiveCfg = Debug|.NET {0DE6C90F-BB74-4BC8-887A-2222DB56D2EB}.Debug.Build.0 = Debug|.NET {0DE6C90F-BB74-4BC8-887A-2222DB56D2EB}.Release.ActiveCfg = Release|.NET {0DE6C90F-BB74-4BC8-887A-2222DB56D2EB}.Release.Build.0 = Release|.NET {0C4269EE-3266-45DD-9062-E356C067FBEF}.Debug.ActiveCfg = Debug|.NET {0C4269EE-3266-45DD-9062-E356C067FBEF}.Debug.Build.0 = Debug|.NET {0C4269EE-3266-45DD-9062-E356C067FBEF}.Release.ActiveCfg = Release|.NET {0C4269EE-3266-45DD-9062-E356C067FBEF}.Release.Build.0 = Release|.NET {9F609A0D-FF7E-4F0C-B2DF-417EBC557CFF}.Debug.ActiveCfg = Debug|.NET {9F609A0D-FF7E-4F0C-B2DF-417EBC557CFF}.Debug.Build.0 = Debug|.NET {9F609A0D-FF7E-4F0C-B2DF-417EBC557CFF}.Release.ActiveCfg = Release|.NET {9F609A0D-FF7E-4F0C-B2DF-417EBC557CFF}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/Extensibility/Core/Minimal/0000775000175000017500000000000011742560362021743 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/Extensibility/Core/Minimal/Minimal.csproj0000664000175000017500000000654611504175260024561 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/Extensibility/Core/Minimal/ReadMe.txt0000664000175000017500000000176711504175260023647 0ustar jtaylorjtaylorMinimal Addin Example MinimalAddin Class This class represents the addin. It is marked by the NUnitAddinAttribute and implements the required IAddin interface. When called by NUnit to install itself, it simply returns false. Note on Building this Extension If you use the Visual Studio solution, the NUnit references in both included projects must be changed so that they refer to the copy of NUnit in which you want to install the extension. The post-build step for the SampleSuiteExtension project must be changed to copy the extension into the addins directory for your NUnit install. NOTE: The references to nunit.core and nunit.common in the SampleSuiteExtension project have their Copy Local property set to false, rather than the Visual Studio default of true. In developing extensions, it is essential there be no extra copies of these assemblies be created. Once the extension is complete, those who install it in binary form will not need to deal with this issue. NUnit-2.6.0.12051/samples/Extensibility/Core/Minimal/Minimal.cs0000664000175000017500000000234211504175260023654 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using NUnit.Core.Extensibility; namespace NUnit.Samples.Extensibility { /// /// This is the smallest possible Addin, which does nothing /// but is recognized by NUnit and listed in the Addins dialog. /// /// The Addin class is marked by the NUnitAddin attribute and /// implements IAddin, as required. Optional property syntax /// is used here to override the default name of the addin and /// to provide a description. Both are displayed by NUnit in the /// Addin Dialog. /// /// The addin doesn't actually install anything, but simply /// returns false in its Install method. /// [NUnitAddin(Name="Minimal Addin", Description="This Addin doesn't do anything")] public class Minimal : IAddin { #region IAddin Members public bool Install(IExtensionHost host) { // TODO: Add Minimal.Install implementation return true; } #endregion } } NUnit-2.6.0.12051/samples/Extensibility/Core/Minimal/Minimal.build0000664000175000017500000000107411504175260024347 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/0000775000175000017500000000000011742560362016111 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/csharp/money/0000775000175000017500000000000011742560362017240 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/csharp/money/AssemblyInfo.cs0000664000175000017500000000457411504175260022167 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.2.0.0")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/samples/csharp/money/IMoney.cs0000664000175000017500000000230111504175260020756 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** namespace NUnit.Samples.Money { /// The common interface for simple Monies and MoneyBags. interface IMoney { /// Adds a money to this money. IMoney Add(IMoney m); /// Adds a simple Money to this money. This is a helper method for /// implementing double dispatch. IMoney AddMoney(Money m); /// Adds a MoneyBag to this money. This is a helper method for /// implementing double dispatch. IMoney AddMoneyBag(MoneyBag s); /// True if this money is zero. bool IsZero { get; } /// Multiplies a money by the given factor. IMoney Multiply(int factor); /// Negates this money. IMoney Negate(); /// Subtracts a money from this money. IMoney Subtract(IMoney m); } } NUnit-2.6.0.12051/samples/csharp/money/MoneyTest.cs0000664000175000017500000001666511504175260021527 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** namespace NUnit.Samples.Money { using System; using NUnit.Framework; /// /// /// /// [TestFixture] public class MoneyTest { private Money f12CHF; private Money f14CHF; private Money f7USD; private Money f21USD; private MoneyBag fMB1; private MoneyBag fMB2; /// /// /// /// [SetUp] protected void SetUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); f7USD= new Money( 7, "USD"); f21USD= new Money(21, "USD"); fMB1= new MoneyBag(f12CHF, f7USD); fMB2= new MoneyBag(f14CHF, f21USD); } /// /// /// /// [Test] public void BagMultiply() { // {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]} Money[] bag = { new Money(24, "CHF"), new Money(14, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, fMB1.Multiply(2)); Assert.AreEqual(fMB1, fMB1.Multiply(1)); Assert.IsTrue(fMB1.Multiply(0).IsZero); } /// /// /// /// [Test] public void BagNegate() { // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]} Money[] bag= { new Money(-12, "CHF"), new Money(-7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, fMB1.Negate()); } /// /// /// /// [Test] public void BagSimpleAdd() { // {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]} Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, fMB1.Add(f14CHF)); } /// /// /// /// [Test] public void BagSubtract() { // {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]} Money[] bag= { new Money(-2, "CHF"), new Money(-14, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, fMB1.Subtract(fMB2)); } /// /// /// /// [Test] public void BagSumAdd() { // {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]} Money[] bag= { new Money(26, "CHF"), new Money(28, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, fMB1.Add(fMB2)); } /// /// /// /// [Test] public void IsZero() { Assert.IsTrue(fMB1.Subtract(fMB1).IsZero); Money[] bag = { new Money(0, "CHF"), new Money(0, "USD") }; Assert.IsTrue(new MoneyBag(bag).IsZero); } /// /// /// /// [Test] public void MixedSimpleAdd() { // [12 CHF] + [7 USD] == {[12 CHF][7 USD]} Money[] bag= { f12CHF, f7USD }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, f12CHF.Add(f7USD)); } /// /// /// /// [Test] public void MoneyBagEquals() { //NOTE: Normally we use Assert.AreEqual to test whether two // objects are equal. But here we are testing the MoneyBag.Equals() // method itself, so using AreEqual would not serve the purpose. Assert.IsFalse(fMB1.Equals(null)); Assert.IsTrue(fMB1.Equals( fMB1 )); MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD")); Assert.IsTrue(fMB1.Equals(equal)); Assert.IsTrue(!fMB1.Equals(f12CHF)); Assert.IsTrue(!f12CHF.Equals(fMB1)); Assert.IsTrue(!fMB1.Equals(fMB2)); } /// /// /// /// [Test] public void MoneyBagHash() { MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD")); Assert.AreEqual(fMB1.GetHashCode(), equal.GetHashCode()); } /// /// /// /// [Test] public void MoneyEquals() { //NOTE: Normally we use Assert.AreEqual to test whether two // objects are equal. But here we are testing the MoneyBag.Equals() // method itself, so using AreEqual would not serve the purpose. Assert.IsFalse(f12CHF.Equals(null)); Money equalMoney= new Money(12, "CHF"); Assert.IsTrue(f12CHF.Equals( f12CHF )); Assert.IsTrue(f12CHF.Equals( equalMoney )); Assert.IsFalse(f12CHF.Equals(f14CHF)); } /// /// /// /// [Test] public void MoneyHash() { Assert.IsFalse(f12CHF.Equals(null)); Money equal= new Money(12, "CHF"); Assert.AreEqual(f12CHF.GetHashCode(), equal.GetHashCode()); } /// /// /// /// [Test] public void Normalize() { Money[] bag= { new Money(26, "CHF"), new Money(28, "CHF"), new Money(6, "CHF") }; MoneyBag moneyBag= new MoneyBag(bag); Money[] expected = { new Money(60, "CHF") }; // note: expected is still a MoneyBag MoneyBag expectedBag= new MoneyBag(expected); Assert.AreEqual(expectedBag, moneyBag); } /// /// /// /// [Test] public void Normalize2() { // {[12 CHF][7 USD]} - [12 CHF] == [7 USD] Money expected= new Money(7, "USD"); Assert.AreEqual(expected, fMB1.Subtract(f12CHF)); } /// /// /// /// [Test] public void Normalize3() { // {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD] Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") }; MoneyBag ms1= new MoneyBag(s1); Money expected= new Money(4, "USD"); Assert.AreEqual(expected, fMB1.Subtract(ms1)); } /// /// /// /// [Test] public void Normalize4() { // [12 CHF] - {[12 CHF][3 USD]} == [-3 USD] Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") }; MoneyBag ms1= new MoneyBag(s1); Money expected= new Money(-3, "USD"); Assert.AreEqual(expected, f12CHF.Subtract(ms1)); } /// /// /// /// [Test] public void Print() { Assert.AreEqual("[12 CHF]", f12CHF.ToString()); } /// /// /// /// [Test] public void SimpleAdd() { // [12 CHF] + [14 CHF] == [26 CHF] Money expected= new Money(26, "CHF"); Assert.AreEqual(expected, f12CHF.Add(f14CHF)); } /// /// /// /// [Test] public void SimpleBagAdd() { // [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]} Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assert.AreEqual(expected, f14CHF.Add(fMB1)); } /// /// /// /// [Test] public void SimpleMultiply() { // [14 CHF] *2 == [28 CHF] Money expected= new Money(28, "CHF"); Assert.AreEqual(expected, f14CHF.Multiply(2)); } /// /// /// /// [Test] public void SimpleNegate() { // [14 CHF] negate == [-14 CHF] Money expected= new Money(-14, "CHF"); Assert.AreEqual(expected, f14CHF.Negate()); } /// /// /// /// [Test] public void SimpleSubtract() { // [14 CHF] - [12 CHF] == [2 CHF] Money expected= new Money(2, "CHF"); Assert.AreEqual(expected, f14CHF.Subtract(f12CHF)); } } }NUnit-2.6.0.12051/samples/csharp/money/cs-money.build0000664000175000017500000000055311504175260022011 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/money/MoneyBag.cs0000664000175000017500000000771511504175260021275 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** namespace NUnit.Samples.Money { using System; using System.Collections; using System.Text; /// A MoneyBag defers exchange rate conversions. /// For example adding /// 12 Swiss Francs to 14 US Dollars is represented as a bag /// containing the two Monies 12 CHF and 14 USD. Adding another /// 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to /// the deferred exchange rate conversion we can later value a /// MoneyBag with different exchange rates. /// /// A MoneyBag is represented as a list of Monies and provides /// different constructors to create a MoneyBag. class MoneyBag: IMoney { private ArrayList fMonies= new ArrayList(5); private MoneyBag() { } public MoneyBag(Money[] bag) { for (int i= 0; i < bag.Length; i++) { if (!bag[i].IsZero) AppendMoney(bag[i]); } } public MoneyBag(Money m1, Money m2) { AppendMoney(m1); AppendMoney(m2); } public MoneyBag(Money m, MoneyBag bag) { AppendMoney(m); AppendBag(bag); } public MoneyBag(MoneyBag m1, MoneyBag m2) { AppendBag(m1); AppendBag(m2); } public IMoney Add(IMoney m) { return m.AddMoneyBag(this); } public IMoney AddMoney(Money m) { return (new MoneyBag(m, this)).Simplify(); } public IMoney AddMoneyBag(MoneyBag s) { return (new MoneyBag(s, this)).Simplify(); } private void AppendBag(MoneyBag aBag) { foreach (Money m in aBag.fMonies) AppendMoney(m); } private void AppendMoney(Money aMoney) { IMoney old= FindMoney(aMoney.Currency); if (old == null) { fMonies.Add(aMoney); return; } fMonies.Remove(old); IMoney sum= old.Add(aMoney); if (sum.IsZero) return; fMonies.Add(sum); } private bool Contains(Money aMoney) { Money m= FindMoney(aMoney.Currency); return m.Amount == aMoney.Amount; } public override bool Equals(Object anObject) { if (IsZero) if (anObject is IMoney) return ((IMoney)anObject).IsZero; if (anObject is MoneyBag) { MoneyBag aMoneyBag= (MoneyBag)anObject; if (aMoneyBag.fMonies.Count != fMonies.Count) return false; foreach (Money m in fMonies) { if (!aMoneyBag.Contains(m)) return false; } return true; } return false; } private Money FindMoney(String currency) { foreach (Money m in fMonies) { if (m.Currency.Equals(currency)) return m; } return null; } public override int GetHashCode() { int hash= 0; foreach (Money m in fMonies) { hash^= m.GetHashCode(); } return hash; } public bool IsZero { get { return fMonies.Count == 0; } } public IMoney Multiply(int factor) { MoneyBag result= new MoneyBag(); if (factor != 0) { foreach (Money m in fMonies) { result.AppendMoney((Money)m.Multiply(factor)); } } return result; } public IMoney Negate() { MoneyBag result= new MoneyBag(); foreach (Money m in fMonies) { result.AppendMoney((Money)m.Negate()); } return result; } private IMoney Simplify() { if (fMonies.Count == 1) return (IMoney)fMonies[0]; return this; } public IMoney Subtract(IMoney m) { return Add(m.Negate()); } public override String ToString() { StringBuilder buffer = new StringBuilder(); buffer.Append("{"); foreach (Money m in fMonies) buffer.Append(m); buffer.Append("}"); return buffer.ToString(); } } } NUnit-2.6.0.12051/samples/csharp/money/Money.cs0000664000175000017500000000425011504175260020652 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** namespace NUnit.Samples.Money { using System; using System.Text; /// A simple Money. class Money: IMoney { private int fAmount; private String fCurrency; /// Constructs a money from the given amount and /// currency. public Money(int amount, String currency) { fAmount= amount; fCurrency= currency; } /// Adds a money to this money. Forwards the request to /// the AddMoney helper. public IMoney Add(IMoney m) { return m.AddMoney(this); } public IMoney AddMoney(Money m) { if (m.Currency.Equals(Currency) ) return new Money(Amount+m.Amount, Currency); return new MoneyBag(this, m); } public IMoney AddMoneyBag(MoneyBag s) { return s.AddMoney(this); } public int Amount { get { return fAmount; } } public String Currency { get { return fCurrency; } } public override bool Equals(Object anObject) { if (IsZero) if (anObject is IMoney) return ((IMoney)anObject).IsZero; if (anObject is Money) { Money aMoney= (Money)anObject; return aMoney.Currency.Equals(Currency) && Amount == aMoney.Amount; } return false; } public override int GetHashCode() { return fCurrency.GetHashCode()+fAmount; } public bool IsZero { get { return Amount == 0; } } public IMoney Multiply(int factor) { return new Money(Amount*factor, Currency); } public IMoney Negate() { return new Money(-Amount, Currency); } public IMoney Subtract(IMoney m) { return Add(m.Negate()); } public override String ToString() { StringBuilder buffer = new StringBuilder(); buffer.Append("["+Amount+" "+Currency+"]"); return buffer.ToString(); } } } NUnit-2.6.0.12051/samples/csharp/money/cs-money.csproj0000664000175000017500000000423611720516414022214 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/CSharp.sln0000664000175000017500000000360511504175260020006 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cs-failures", "failures\cs-failures.csproj", "{15D66EEE-A852-4A52-89C2-83E74ECF3770}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cs-money", "money\cs-money.csproj", "{11EDF872-A04D-4F75-A1BF-71168DC86AF3}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cs-syntax", "syntax\cs-syntax.csproj", "{06F46FA2-687B-4B46-A912-C1B0B4CC1B20}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug.ActiveCfg = Debug|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug.Build.0 = Debug|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release.ActiveCfg = Release|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release.Build.0 = Release|.NET {11EDF872-A04D-4F75-A1BF-71168DC86AF3}.Debug.ActiveCfg = Debug|.NET {11EDF872-A04D-4F75-A1BF-71168DC86AF3}.Debug.Build.0 = Debug|.NET {11EDF872-A04D-4F75-A1BF-71168DC86AF3}.Release.ActiveCfg = Release|.NET {11EDF872-A04D-4F75-A1BF-71168DC86AF3}.Release.Build.0 = Release|.NET {06F46FA2-687B-4B46-A912-C1B0B4CC1B20}.Debug.ActiveCfg = Debug|.NET {06F46FA2-687B-4B46-A912-C1B0B4CC1B20}.Debug.Build.0 = Debug|.NET {06F46FA2-687B-4B46-A912-C1B0B4CC1B20}.Release.ActiveCfg = Release|.NET {06F46FA2-687B-4B46-A912-C1B0B4CC1B20}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/samples/csharp/syntax/0000775000175000017500000000000011742560362017437 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/csharp/syntax/cs-syntax.build0000664000175000017500000000041311504175260022402 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/syntax/AssertSyntaxTests.cs0000664000175000017500000006476211504175260023473 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests { /// /// This test fixture attempts to exercise all the syntactic /// variations of Assert without getting into failures, errors /// or corner cases. Thus, some of the tests may be duplicated /// in other fixtures. /// /// Each test performs the same operations using the classic /// syntax (if available) and the new syntax in both the /// helper-based and inherited forms. /// /// This Fixture will eventually be duplicated in other /// supported languages. /// [TestFixture] public class AssertSyntaxTests : AssertionHelper { #region Simple Constraint Tests [Test] public void IsNull() { object nada = null; // Classic syntax Assert.IsNull(nada); // Helper syntax Assert.That(nada, Is.Null); // Inherited syntax Expect(nada, Null); } [Test] public void IsNotNull() { // Classic syntax Assert.IsNotNull(42); // Helper syntax Assert.That(42, Is.Not.Null); // Inherited syntax Expect( 42, Not.Null ); } [Test] public void IsTrue() { // Classic syntax Assert.IsTrue(2+2==4); // Helper syntax Assert.That(2+2==4, Is.True); Assert.That(2+2==4); // Inherited syntax Expect(2+2==4, True); Expect(2+2==4); } [Test] public void IsFalse() { // Classic syntax Assert.IsFalse(2+2==5); // Helper syntax Assert.That(2+2== 5, Is.False); // Inherited syntax Expect(2+2==5, False); } [Test] public void IsNaN() { double d = double.NaN; float f = float.NaN; // Classic syntax Assert.IsNaN(d); Assert.IsNaN(f); // Helper syntax Assert.That(d, Is.NaN); Assert.That(f, Is.NaN); // Inherited syntax Expect(d, NaN); Expect(f, NaN); } [Test] public void EmptyStringTests() { // Classic syntax Assert.IsEmpty(""); Assert.IsNotEmpty("Hello!"); // Helper syntax Assert.That("", Is.Empty); Assert.That("Hello!", Is.Not.Empty); // Inherited syntax Expect("", Empty); Expect("Hello!", Not.Empty); } [Test] public void EmptyCollectionTests() { // Classic syntax Assert.IsEmpty(new bool[0]); Assert.IsNotEmpty(new int[] { 1, 2, 3 }); // Helper syntax Assert.That(new bool[0], Is.Empty); Assert.That(new int[] { 1, 2, 3 }, Is.Not.Empty); // Inherited syntax Expect(new bool[0], Empty); Expect(new int[] { 1, 2, 3 }, Not.Empty); } #endregion #region TypeConstraint Tests [Test] public void ExactTypeTests() { // Classic syntax workarounds Assert.AreEqual(typeof(string), "Hello".GetType()); Assert.AreEqual("System.String", "Hello".GetType().FullName); Assert.AreNotEqual(typeof(int), "Hello".GetType()); Assert.AreNotEqual("System.Int32", "Hello".GetType().FullName); // Helper syntax Assert.That("Hello", Is.TypeOf(typeof(string))); Assert.That("Hello", Is.Not.TypeOf(typeof(int))); // Inherited syntax Expect( "Hello", TypeOf(typeof(string))); Expect( "Hello", Not.TypeOf(typeof(int))); } [Test] public void InstanceOfTypeTests() { // Classic syntax Assert.IsInstanceOf(typeof(string), "Hello"); Assert.IsNotInstanceOf(typeof(string), 5); // Helper syntax Assert.That("Hello", Is.InstanceOf(typeof(string))); Assert.That(5, Is.Not.InstanceOf(typeof(string))); // Inherited syntax Expect("Hello", InstanceOf(typeof(string))); Expect(5, Not.InstanceOf(typeof(string))); } [Test] public void AssignableFromTypeTests() { // Classic syntax Assert.IsAssignableFrom(typeof(string), "Hello"); Assert.IsNotAssignableFrom(typeof(string), 5); // Helper syntax Assert.That( "Hello", Is.AssignableFrom(typeof(string))); Assert.That( 5, Is.Not.AssignableFrom(typeof(string))); // Inherited syntax Expect( "Hello", AssignableFrom(typeof(string))); Expect( 5, Not.AssignableFrom(typeof(string))); } #endregion #region StringConstraint Tests [Test] public void SubstringTests() { string phrase = "Hello World!"; string[] array = new string[] { "abc", "bad", "dba" }; // Classic Syntax StringAssert.Contains("World", phrase); // Helper syntax Assert.That(phrase, Text.Contains("World")); // Only available using new syntax Assert.That(phrase, Text.DoesNotContain("goodbye")); Assert.That(phrase, Text.Contains("WORLD").IgnoreCase); Assert.That(phrase, Text.DoesNotContain("BYE").IgnoreCase); Assert.That(array, Text.All.Contains( "b" ) ); // Inherited syntax Expect(phrase, Contains("World")); // Only available using new syntax Expect(phrase, Not.Contains("goodbye")); Expect(phrase, Contains("WORLD").IgnoreCase); Expect(phrase, Not.Contains("BYE").IgnoreCase); Expect(array, All.Contains("b")); } [Test] public void StartsWithTests() { string phrase = "Hello World!"; string[] greetings = new string[] { "Hello!", "Hi!", "Hola!" }; // Classic syntax StringAssert.StartsWith("Hello", phrase); // Helper syntax Assert.That(phrase, Text.StartsWith("Hello")); // Only available using new syntax Assert.That(phrase, Text.DoesNotStartWith("Hi!")); Assert.That(phrase, Text.StartsWith("HeLLo").IgnoreCase); Assert.That(phrase, Text.DoesNotStartWith("HI").IgnoreCase); Assert.That(greetings, Text.All.StartsWith("h").IgnoreCase); // Inherited syntax Expect(phrase, StartsWith("Hello")); // Only available using new syntax Expect(phrase, Not.StartsWith("Hi!")); Expect(phrase, StartsWith("HeLLo").IgnoreCase); Expect(phrase, Not.StartsWith("HI").IgnoreCase); Expect(greetings, All.StartsWith("h").IgnoreCase); } [Test] public void EndsWithTests() { string phrase = "Hello World!"; string[] greetings = new string[] { "Hello!", "Hi!", "Hola!" }; // Classic Syntax StringAssert.EndsWith("!", phrase); // Helper syntax Assert.That(phrase, Text.EndsWith("!")); // Only available using new syntax Assert.That(phrase, Text.DoesNotEndWith("?")); Assert.That(phrase, Text.EndsWith("WORLD!").IgnoreCase); Assert.That(greetings, Text.All.EndsWith("!")); // Inherited syntax Expect(phrase, EndsWith("!")); // Only available using new syntax Expect(phrase, Not.EndsWith("?")); Expect(phrase, EndsWith("WORLD!").IgnoreCase); Expect(greetings, All.EndsWith("!") ); } [Test] public void EqualIgnoringCaseTests() { string phrase = "Hello World!"; // Classic syntax StringAssert.AreEqualIgnoringCase("hello world!",phrase); // Helper syntax Assert.That(phrase, Is.EqualTo("hello world!").IgnoreCase); //Only available using new syntax Assert.That(phrase, Is.Not.EqualTo("goodbye world!").IgnoreCase); Assert.That(new string[] { "Hello", "World" }, Is.EqualTo(new object[] { "HELLO", "WORLD" }).IgnoreCase); Assert.That(new string[] {"HELLO", "Hello", "hello" }, Is.All.EqualTo( "hello" ).IgnoreCase); // Inherited syntax Expect(phrase, EqualTo("hello world!").IgnoreCase); //Only available using new syntax Expect(phrase, Not.EqualTo("goodbye world!").IgnoreCase); Expect(new string[] { "Hello", "World" }, EqualTo(new object[] { "HELLO", "WORLD" }).IgnoreCase); Expect(new string[] {"HELLO", "Hello", "hello" }, All.EqualTo( "hello" ).IgnoreCase); } [Test] public void RegularExpressionTests() { string phrase = "Now is the time for all good men to come to the aid of their country."; string[] quotes = new string[] { "Never say never", "It's never too late", "Nevermore!" }; // Classic syntax StringAssert.IsMatch( "all good men", phrase ); StringAssert.IsMatch( "Now.*come", phrase ); // Helper syntax Assert.That( phrase, Text.Matches( "all good men" ) ); Assert.That( phrase, Text.Matches( "Now.*come" ) ); // Only available using new syntax Assert.That(phrase, Text.DoesNotMatch("all.*men.*good")); Assert.That(phrase, Text.Matches("ALL").IgnoreCase); Assert.That(quotes, Text.All.Matches("never").IgnoreCase); // Inherited syntax Expect( phrase, Matches( "all good men" ) ); Expect( phrase, Matches( "Now.*come" ) ); // Only available using new syntax Expect(phrase, Not.Matches("all.*men.*good")); Expect(phrase, Matches("ALL").IgnoreCase); Expect(quotes, All.Matches("never").IgnoreCase); } #endregion #region Equality Tests [Test] public void EqualityTests() { int[] i3 = new int[] { 1, 2, 3 }; double[] d3 = new double[] { 1.0, 2.0, 3.0 }; int[] iunequal = new int[] { 1, 3, 2 }; // Classic Syntax Assert.AreEqual(4, 2 + 2); Assert.AreEqual(i3, d3); Assert.AreNotEqual(5, 2 + 2); Assert.AreNotEqual(i3, iunequal); // Helper syntax Assert.That(2 + 2, Is.EqualTo(4)); Assert.That(2 + 2 == 4); Assert.That(i3, Is.EqualTo(d3)); Assert.That(2 + 2, Is.Not.EqualTo(5)); Assert.That(i3, Is.Not.EqualTo(iunequal)); // Inherited syntax Expect(2 + 2, EqualTo(4)); Expect(2 + 2 == 4); Expect(i3, EqualTo(d3)); Expect(2 + 2, Not.EqualTo(5)); Expect(i3, Not.EqualTo(iunequal)); } [Test] public void EqualityTestsWithTolerance() { // CLassic syntax Assert.AreEqual(5.0d, 4.99d, 0.05d); Assert.AreEqual(5.0f, 4.99f, 0.05f); // Helper syntax Assert.That(4.99d, Is.EqualTo(5.0d).Within(0.05d)); Assert.That(4.0d, Is.Not.EqualTo(5.0d).Within(0.5d)); Assert.That(4.99f, Is.EqualTo(5.0f).Within(0.05f)); Assert.That(4.99m, Is.EqualTo(5.0m).Within(0.05m)); Assert.That(3999999999u, Is.EqualTo(4000000000u).Within(5u)); Assert.That(499, Is.EqualTo(500).Within(5)); Assert.That(4999999999L, Is.EqualTo(5000000000L).Within(5L)); Assert.That(5999999999ul, Is.EqualTo(6000000000ul).Within(5ul)); // Inherited syntax Expect(4.99d, EqualTo(5.0d).Within(0.05d)); Expect(4.0d, Not.EqualTo(5.0d).Within(0.5d)); Expect(4.99f, EqualTo(5.0f).Within(0.05f)); Expect(4.99m, EqualTo(5.0m).Within(0.05m)); Expect(499u, EqualTo(500u).Within(5u)); Expect(499, EqualTo(500).Within(5)); Expect(4999999999L, EqualTo(5000000000L).Within(5L)); Expect(5999999999ul, EqualTo(6000000000ul).Within(5ul)); } [Test] public void EqualityTestsWithTolerance_MixedFloatAndDouble() { // Bug Fix 1743844 Assert.That(2.20492d, Is.EqualTo(2.2d).Within(0.01f), "Double actual, Double expected, Single tolerance"); Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01d), "Double actual, Single expected, Double tolerance" ); Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01f), "Double actual, Single expected, Single tolerance" ); Assert.That(2.20492f, Is.EqualTo(2.2f).Within(0.01d), "Single actual, Single expected, Double tolerance"); Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01d), "Single actual, Double expected, Double tolerance"); Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01f), "Single actual, Double expected, Single tolerance"); } [Test] public void EqualityTestsWithTolerance_MixingTypesGenerally() { // Extending tolerance to all numeric types Assert.That(202d, Is.EqualTo(200d).Within(2), "Double actual, Double expected, int tolerance"); Assert.That( 4.87m, Is.EqualTo(5).Within(.25), "Decimal actual, int expected, Double tolerance" ); Assert.That( 4.87m, Is.EqualTo(5ul).Within(1), "Decimal actual, ulong expected, int tolerance" ); Assert.That( 487, Is.EqualTo(500).Within(25), "int actual, int expected, int tolerance" ); Assert.That( 487u, Is.EqualTo(500).Within(25), "uint actual, int expected, int tolerance" ); Assert.That( 487L, Is.EqualTo(500).Within(25), "long actual, int expected, int tolerance" ); Assert.That( 487ul, Is.EqualTo(500).Within(25), "ulong actual, int expected, int tolerance" ); } #endregion #region Comparison Tests [Test] public void ComparisonTests() { // Classic Syntax Assert.Greater(7, 3); Assert.GreaterOrEqual(7, 3); Assert.GreaterOrEqual(7, 7); // Helper syntax Assert.That(7, Is.GreaterThan(3)); Assert.That(7, Is.GreaterThanOrEqualTo(3)); Assert.That(7, Is.AtLeast(3)); Assert.That(7, Is.GreaterThanOrEqualTo(7)); Assert.That(7, Is.AtLeast(7)); // Inherited syntax Expect(7, GreaterThan(3)); Expect(7, GreaterThanOrEqualTo(3)); Expect(7, AtLeast(3)); Expect(7, GreaterThanOrEqualTo(7)); Expect(7, AtLeast(7)); // Classic syntax Assert.Less(3, 7); Assert.LessOrEqual(3, 7); Assert.LessOrEqual(3, 3); // Helper syntax Assert.That(3, Is.LessThan(7)); Assert.That(3, Is.LessThanOrEqualTo(7)); Assert.That(3, Is.AtMost(7)); Assert.That(3, Is.LessThanOrEqualTo(3)); Assert.That(3, Is.AtMost(3)); // Inherited syntax Expect(3, LessThan(7)); Expect(3, LessThanOrEqualTo(7)); Expect(3, AtMost(7)); Expect(3, LessThanOrEqualTo(3)); Expect(3, AtMost(3)); } #endregion #region Collection Tests [Test] public void AllItemsTests() { object[] ints = new object[] { 1, 2, 3, 4 }; object[] doubles = new object[] { 0.99, 2.1, 3.0, 4.05 }; object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" }; // Classic syntax CollectionAssert.AllItemsAreNotNull(ints); CollectionAssert.AllItemsAreInstancesOfType(ints, typeof(int)); CollectionAssert.AllItemsAreInstancesOfType(strings, typeof(string)); CollectionAssert.AllItemsAreUnique(ints); // Helper syntax Assert.That(ints, Is.All.Not.Null); Assert.That(ints, Has.None.Null); Assert.That(ints, Is.All.InstanceOfType(typeof(int))); Assert.That(ints, Has.All.InstanceOfType(typeof(int))); Assert.That(strings, Is.All.InstanceOfType(typeof(string))); Assert.That(strings, Has.All.InstanceOfType(typeof(string))); Assert.That(ints, Is.Unique); // Only available using new syntax Assert.That(strings, Is.Not.Unique); Assert.That(ints, Is.All.GreaterThan(0)); Assert.That(ints, Has.All.GreaterThan(0)); Assert.That(ints, Has.None.LessThanOrEqualTo(0)); Assert.That(strings, Text.All.Contains( "a" ) ); Assert.That(strings, Has.All.Contains( "a" ) ); Assert.That(strings, Has.Some.StartsWith( "ba" ) ); Assert.That( strings, Has.Some.Property( "Length" ).EqualTo( 3 ) ); Assert.That( strings, Has.Some.StartsWith( "BA" ).IgnoreCase ); Assert.That( doubles, Has.Some.EqualTo( 1.0 ).Within( .05 ) ); // Inherited syntax Expect(ints, All.Not.Null); Expect(ints, None.Null); Expect(ints, All.InstanceOfType(typeof(int))); Expect(strings, All.InstanceOfType(typeof(string))); Expect(ints, Unique); // Only available using new syntax Expect(strings, Not.Unique); Expect(ints, All.GreaterThan(0)); Expect(ints, None.LessThanOrEqualTo(0)); Expect(strings, All.Contains( "a" ) ); Expect(strings, Some.StartsWith( "ba" ) ); Expect(strings, Some.StartsWith( "BA" ).IgnoreCase ); Expect(doubles, Some.EqualTo( 1.0 ).Within( .05 ) ); } [Test] public void SomeItemTests() { object[] mixed = new object[] { 1, 2, "3", null, "four", 100 }; object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" }; // Not available using the classic syntax // Helper syntax Assert.That(mixed, Has.Some.Null); Assert.That(mixed, Has.Some.InstanceOfType(typeof(int))); Assert.That(mixed, Has.Some.InstanceOfType(typeof(string))); Assert.That(strings, Has.Some.StartsWith( "ba" ) ); Assert.That(strings, Has.Some.Not.StartsWith( "ba" ) ); // Inherited syntax Expect(mixed, Some.Null); Expect(mixed, Some.InstanceOfType(typeof(int))); Expect(mixed, Some.InstanceOfType(typeof(string))); Expect(strings, Some.StartsWith( "ba" ) ); Expect(strings, Some.Not.StartsWith( "ba" ) ); } [Test] public void NoItemTests() { object[] ints = new object[] { 1, 2, 3, 4, 5 }; object[] strings = new object[] { "abc", "bad", "cab", "bad", "dad" }; // Not available using the classic syntax // Helper syntax Assert.That(ints, Has.None.Null); Assert.That(ints, Has.None.InstanceOfType(typeof(string))); Assert.That(ints, Has.None.GreaterThan(99)); Assert.That(strings, Has.None.StartsWith( "qu" ) ); // Inherited syntax Expect(ints, None.Null); Expect(ints, None.InstanceOfType(typeof(string))); Expect(ints, None.GreaterThan(99)); Expect(strings, None.StartsWith( "qu" ) ); } [Test] public void CollectionContainsTests() { int[] iarray = new int[] { 1, 2, 3 }; string[] sarray = new string[] { "a", "b", "c" }; // Classic syntax Assert.Contains(3, iarray); Assert.Contains("b", sarray); CollectionAssert.Contains(iarray, 3); CollectionAssert.Contains(sarray, "b"); CollectionAssert.DoesNotContain(sarray, "x"); // Showing that Contains uses NUnit equality CollectionAssert.Contains( iarray, 1.0d ); // Helper syntax Assert.That(iarray, Has.Member(3)); Assert.That(sarray, Has.Member("b")); Assert.That(sarray, Has.No.Member("x")); // Showing that Contains uses NUnit equality Assert.That(iarray, Has.Member( 1.0d )); // Only available using the new syntax // Note that EqualTo and SameAs do NOT give // identical results to Contains because // Contains uses Object.Equals() Assert.That(iarray, Has.Some.EqualTo(3)); Assert.That(iarray, Has.Member(3)); Assert.That(sarray, Has.Some.EqualTo("b")); Assert.That(sarray, Has.None.EqualTo("x")); Assert.That(iarray, Has.None.SameAs( 1.0d )); Assert.That(iarray, Has.All.LessThan(10)); Assert.That(sarray, Has.All.Length.EqualTo(1)); Assert.That(sarray, Has.None.Property("Length").GreaterThan(3)); // Inherited syntax Expect(iarray, Contains(3)); Expect(sarray, Contains("b")); Expect(sarray, Not.Contains("x")); // Only available using new syntax // Note that EqualTo and SameAs do NOT give // identical results to Contains because // Contains uses Object.Equals() Expect(iarray, Some.EqualTo(3)); Expect(sarray, Some.EqualTo("b")); Expect(sarray, None.EqualTo("x")); Expect(iarray, All.LessThan(10)); Expect(sarray, All.Length.EqualTo(1)); Expect(sarray, None.Property("Length").GreaterThan(3)); } [Test] public void CollectionEquivalenceTests() { int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 }; int[] twothrees = new int[] { 1, 2, 3, 3, 4, 5 }; int[] twofours = new int[] { 1, 2, 3, 4, 4, 5 }; // Classic syntax CollectionAssert.AreEquivalent(new int[] { 2, 1, 4, 3, 5 }, ints1to5); CollectionAssert.AreNotEquivalent(new int[] { 2, 2, 4, 3, 5 }, ints1to5); CollectionAssert.AreNotEquivalent(new int[] { 2, 4, 3, 5 }, ints1to5); CollectionAssert.AreNotEquivalent(new int[] { 2, 2, 1, 1, 4, 3, 5 }, ints1to5); CollectionAssert.AreNotEquivalent(twothrees, twofours); // Helper syntax Assert.That(new int[] { 2, 1, 4, 3, 5 }, Is.EquivalentTo(ints1to5)); Assert.That(new int[] { 2, 2, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5)); Assert.That(new int[] { 2, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5)); Assert.That(new int[] { 2, 2, 1, 1, 4, 3, 5 }, Is.Not.EquivalentTo(ints1to5)); // Inherited syntax Expect(new int[] { 2, 1, 4, 3, 5 }, EquivalentTo(ints1to5)); Expect(new int[] { 2, 2, 4, 3, 5 }, Not.EquivalentTo(ints1to5)); Expect(new int[] { 2, 4, 3, 5 }, Not.EquivalentTo(ints1to5)); Expect(new int[] { 2, 2, 1, 1, 4, 3, 5 }, Not.EquivalentTo(ints1to5)); } [Test] public void SubsetTests() { int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 }; // Classic syntax CollectionAssert.IsSubsetOf(new int[] { 1, 3, 5 }, ints1to5); CollectionAssert.IsSubsetOf(new int[] { 1, 2, 3, 4, 5 }, ints1to5); CollectionAssert.IsNotSubsetOf(new int[] { 2, 4, 6 }, ints1to5); CollectionAssert.IsNotSubsetOf(new int[] { 1, 2, 2, 2, 5 }, ints1to5); // Helper syntax Assert.That(new int[] { 1, 3, 5 }, Is.SubsetOf(ints1to5)); Assert.That(new int[] { 1, 2, 3, 4, 5 }, Is.SubsetOf(ints1to5)); Assert.That(new int[] { 2, 4, 6 }, Is.Not.SubsetOf(ints1to5)); // Inherited syntax Expect(new int[] { 1, 3, 5 }, SubsetOf(ints1to5)); Expect(new int[] { 1, 2, 3, 4, 5 }, SubsetOf(ints1to5)); Expect(new int[] { 2, 4, 6 }, Not.SubsetOf(ints1to5)); } #endregion #region Property Tests [Test] public void PropertyTests() { string[] array = { "abc", "bca", "xyz", "qrs" }; string[] array2 = { "a", "ab", "abc" }; ArrayList list = new ArrayList( array ); // Not available using the classic syntax // Helper syntax Assert.That( list, Has.Property( "Count" ) ); Assert.That( list, Has.No.Property( "Length" ) ); Assert.That( "Hello", Has.Length.EqualTo( 5 ) ); Assert.That( "Hello", Has.Length.LessThan( 10 ) ); Assert.That( "Hello", Has.Property("Length").EqualTo(5) ); Assert.That( "Hello", Has.Property("Length").GreaterThan(3) ); Assert.That( array, Has.Property( "Length" ).EqualTo( 4 ) ); Assert.That( array, Has.Length.EqualTo( 4 ) ); Assert.That( array, Has.Property( "Length" ).LessThan( 10 ) ); Assert.That( array, Has.All.Property("Length").EqualTo(3) ); Assert.That( array, Has.All.Length.EqualTo( 3 ) ); Assert.That( array, Is.All.Length.EqualTo( 3 ) ); Assert.That( array, Has.All.Property("Length").EqualTo(3) ); Assert.That( array, Is.All.Property("Length").EqualTo(3) ); Assert.That( array2, Has.Some.Property("Length").EqualTo(2) ); Assert.That( array2, Has.Some.Length.EqualTo(2) ); Assert.That( array2, Has.Some.Property("Length").GreaterThan(2) ); Assert.That( array2, Is.Not.Property("Length").EqualTo(4) ); Assert.That( array2, Is.Not.Length.EqualTo( 4 ) ); Assert.That( array2, Has.No.Property("Length").GreaterThan(3) ); Assert.That( List.Map( array2 ).Property("Length"), Is.EqualTo( new int[] { 1, 2, 3 } ) ); Assert.That( List.Map( array2 ).Property("Length"), Is.EquivalentTo( new int[] { 3, 2, 1 } ) ); Assert.That( List.Map( array2 ).Property("Length"), Is.SubsetOf( new int[] { 1, 2, 3, 4, 5 } ) ); Assert.That( List.Map( array2 ).Property("Length"), Is.Unique ); Assert.That( list, Has.Count.EqualTo( 4 ) ); // Inherited syntax Expect( list, Property( "Count" ) ); Expect( list, Not.Property( "Nada" ) ); Expect( "Hello", Length.EqualTo( 5 ) ); Expect( "Hello", Property("Length").EqualTo(5) ); Expect( "Hello", Property("Length").GreaterThan(0) ); Expect( array, Property("Length").EqualTo(4) ); Expect( array, Length.EqualTo(4) ); Expect( array, Property("Length").LessThan(10)); Expect( array, All.Length.EqualTo( 3 ) ); Expect( array, All.Property("Length").EqualTo(3)); Expect( array2, Some.Property("Length").EqualTo(2) ); Expect( array2, Some.Length.EqualTo( 2 ) ); Expect( array2, Some.Property("Length").GreaterThan(2)); Expect( array2, None.Property("Length").EqualTo(4) ); Expect( array2, None.Length.EqualTo( 4 ) ); Expect( array2, None.Property("Length").GreaterThan(3)); Expect( Map( array2 ).Property("Length"), EqualTo( new int[] { 1, 2, 3 } ) ); Expect( Map( array2 ).Property("Length"), EquivalentTo( new int[] { 3, 2, 1 } ) ); Expect( Map( array2 ).Property("Length"), SubsetOf( new int[] { 1, 2, 3, 4, 5 } ) ); Expect( Map( array2 ).Property("Length"), Unique ); Expect( list, Count.EqualTo( 4 ) ); } #endregion #region Not Tests [Test] public void NotTests() { // Not available using the classic syntax // Helper syntax Assert.That(42, Is.Not.Null); Assert.That(42, Is.Not.True); Assert.That(42, Is.Not.False); Assert.That(2.5, Is.Not.NaN); Assert.That(2 + 2, Is.Not.EqualTo(3)); Assert.That(2 + 2, Is.Not.Not.EqualTo(4)); Assert.That(2 + 2, Is.Not.Not.Not.EqualTo(5)); // Inherited syntax Expect(42, Not.Null); Expect(42, Not.True); Expect(42, Not.False); Expect(2.5, Not.NaN); Expect(2 + 2, Not.EqualTo(3)); Expect(2 + 2, Not.Not.EqualTo(4)); Expect(2 + 2, Not.Not.Not.EqualTo(5)); } #endregion #region Operator Tests [Test] public void NotOperator() { // The ! operator is only available in the new syntax Assert.That(42, !Is.Null); // Inherited syntax Expect( 42, !Null ); } [Test] public void AndOperator() { // The & operator is only available in the new syntax Assert.That(7, Is.GreaterThan(5) & Is.LessThan(10)); // Inherited syntax Expect( 7, GreaterThan(5) & LessThan(10)); } [Test] public void OrOperator() { // The | operator is only available in the new syntax Assert.That(3, Is.LessThan(5) | Is.GreaterThan(10)); Expect( 3, LessThan(5) | GreaterThan(10)); } [Test] public void ComplexTests() { Assert.That(7, Is.Not.Null & Is.Not.LessThan(5) & Is.Not.GreaterThan(10)); Expect(7, Not.Null & Not.LessThan(5) & Not.GreaterThan(10)); Assert.That(7, !Is.Null & !Is.LessThan(5) & !Is.GreaterThan(10)); Expect(7, !Null & !LessThan(5) & !GreaterThan(10)); // TODO: Remove #if when mono compiler can handle null #if MONO Constraint x = null; Assert.That(7, !x & !Is.LessThan(5) & !Is.GreaterThan(10)); Expect(7, !x & !LessThan(5) & !GreaterThan(10)); #else Assert.That(7, !(Constraint)null & !Is.LessThan(5) & !Is.GreaterThan(10)); Expect(7, !(Constraint)null & !LessThan(5) & !GreaterThan(10)); #endif } #endregion #region Invalid Code Tests // This method contains assertions that should not compile // You can check by uncommenting it. //public void WillNotCompile() //{ // Assert.That(42, Is.Not); // Assert.That(42, Is.All); // Assert.That(42, Is.Null.Not); // Assert.That(42, Is.Not.Null.GreaterThan(10)); // Assert.That(42, Is.GreaterThan(10).LessThan(99)); // object[] c = new object[0]; // Assert.That(c, Is.Null.All); // Assert.That(c, Is.Not.All); // Assert.That(c, Is.All.Not); //} #endregion } } NUnit-2.6.0.12051/samples/csharp/syntax/AssemblyInfo.cs0000664000175000017500000000457211504175260022364 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/samples/csharp/syntax/cs-syntax.csproj0000664000175000017500000000371211720516414022610 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/failures/0000775000175000017500000000000011742560362017723 5ustar jtaylorjtaylorNUnit-2.6.0.12051/samples/csharp/failures/AssemblyInfo.cs0000664000175000017500000000506711504175260022650 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("csharp.sample.dll")] [assembly: AssemblyDescription("C# Sample Unit Tests")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("NUnit")] [assembly: AssemblyProduct("NUnit")] [assembly: AssemblyCopyright("Copyright (C) 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov. \nCopyright (C) 2000-2003 Philip Craig.\nAll Rights Reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.2.0.0")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/samples/csharp/failures/cs-failures.csproj0000664000175000017500000000371011720516414023356 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/failures/cs-failures.build0000664000175000017500000000040511504175260023153 0ustar jtaylorjtaylor NUnit-2.6.0.12051/samples/csharp/failures/CSharpTest.cs0000664000175000017500000000342711504175260022273 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org/?p=license&r=2.4. // **************************************************************** namespace NUnit.Samples { using System; using NUnit.Framework; /// Some simple Tests. /// [TestFixture] public class SimpleCSharpTest { /// /// /// protected int fValue1; /// /// /// protected int fValue2; /// /// /// [SetUp] public void Init() { fValue1= 2; fValue2= 3; } /// /// /// /// [Test] public void Add() { double result= fValue1 + fValue2; // forced failure result == 5 Assert.AreEqual(6, result, "Expected Failure."); } /// /// /// /// [Test] public void DivideByZero() { int zero= 0; int result= 8/zero; } /// /// /// /// [Test] public void Equals() { Assert.AreEqual(12, 12, "Integer"); Assert.AreEqual(12L, 12L, "Long"); Assert.AreEqual('a', 'a', "Char"); Assert.AreEqual((object)12, (object)12, "Integer Object Cast"); Assert.AreEqual(12, 13, "Expected Failure (Integer)"); Assert.AreEqual(12.0, 11.99, 0.0, "Expected Failure (Double)."); } [Test] [ExpectedException(typeof(InvalidOperationException))] public void ExpectAnException() { throw new InvalidCastException(); } [Test] [Ignore("ignored test")] public void IgnoredTest() { throw new Exception(); } } }NUnit-2.6.0.12051/doc/0000775000175000017500000000000011742560362013732 5ustar jtaylorjtaylorNUnit-2.6.0.12051/doc/conditionAsserts.html0000664000175000017500000001311411720512704020144 0ustar jtaylorjtaylor NUnit - ConditionAsserts

Condition Asserts

Methods that test a specific condition are named for the condition they test and take the value tested as their first argument and, optionally a message as the second. The following methods are provided:

Assert.IsTrue( bool condition );
Assert.IsTrue( bool condition, string message );
Assert.IsTrue( bool condition, string message, object[] parms );

Assert.True( bool condition );
Assert.True( bool condition, string message );
Assert.True( bool condition, string message, object[] parms );

Assert.IsFalse( bool condition);
Assert.IsFalse( bool condition, string message );
Assert.IsFalse( bool condition, string message, object[] parms );

Assert.False( bool condition);
Assert.False( bool condition, string message );
Assert.False( bool condition, string message, object[] parms );

Assert.IsNull( object anObject );
Assert.IsNull( object anObject, string message );
Assert.IsNull( object anObject, string message, object[] parms );

Assert.Null( object anObject );
Assert.Null( object anObject, string message );
Assert.Null( object anObject, string message, object[] parms );

Assert.IsNotNull( object anObject );
Assert.IsNotNull( object anObject, string message );
Assert.IsNotNull( object anObject, string message, object[] parms );

Assert.NotNull( object anObject );
Assert.NotNull( object anObject, string message );
Assert.NotNull( object anObject, string message, object[] parms );

Assert.IsNaN( double aDouble );
Assert.IsNaN( double aDouble, string message );
Assert.IsNaN( double aDouble, string message, object[] parms );

Assert.IsEmpty( string aString );
Assert.IsEmpty( string aString, string message );
Assert.IsEmpty( string aString, string message,
          params object[] args );

Assert.IsNotEmpty( string aString );
Assert.IsNotEmpty( string aString, string message );
Assert.IsNotEmpty( string aString, string message,
          params object[] args );

Assert.IsEmpty( ICollection collection );
Assert.IsEmpty( ICollection collection, string message );
Assert.IsEmpty( ICollection collection, string message,
          params object[] args );

Assert.IsNotEmpty( ICollection collection );
Assert.IsNotEmpty( ICollection collection, string message );
Assert.IsNotEmpty( ICollection collection, string message,
          params object[] args );

Two forms are provided for the True, False, Null and NotNull conditions. The "Is" forms are compatible with earlier versions of the NUnit framework, while those without "Is" are provided for compatibility with NUnitLite.

Assert.IsEmpty and Assert.IsNotEmpty may be used to test either a string or a collection.

NUnit-2.6.0.12051/doc/multiAssembly.html0000664000175000017500000001441511720512704017450 0ustar jtaylorjtaylor NUnit - MultiAssembly

Multiple-Assembly Support

Since version 2.1, NUnit has allowed loading suites of tests from multiple assemblies in both the console and GUI runners. This may be done on an adhoc basis or by creating NUnit test projects saved as files of type '.nunit'. In either case, a top-level suite is constructed, which contains the root suite for each assembly. Tests are run and reported just as for a single assembly.

Adhoc Usage

Using the console runner, multiple assemblies may be run simply by specifying their names on the command line. See NUnit-Console Command Line Options for an example of this usage.

The gui runner does not support specifying multiple assemblies on the command-line. However, you can load a single assembly and then use the Project menu to add additional assemblies. Additionally, you can drag multiple assemblies to the tree view pane, in which case they will replace any assemblies already loaded.

NUnit Test Projects

Running tests from multiple assemblies is facilitated by the use of NUnit test projects. These are files with the extension .nunit containing information about the assemblies to be loaded. The following is an example of a hypothetical test project file:

<NUnitProject>
  <Settings activeconfig="Debug"/>
  <Config name="Debug">
    <assembly path="LibraryCore\bin\Debug\Library.dll"/>
    <assembly path="LibraryUI\bin\Debug\LibraryUI.dll"/>
  </Config>
  <Config name="Release">
    <assembly path="LibraryCore\bin\Release\Library.dll"/>
    <assembly path="LibraryUI\bin\Release\LibraryUI.dll"/>
  </Config>
</NUnitProject>

This project contains two configurations, each of which contains two assemblies. The Debug configuration is currently active. By default, the assemblies will be loaded using the directory containing this file as the ApplicationBase. The PrivateBinPath will be set automatically to LibraryCore\bin\Debug;LibraryUI\bin\Debug or to the corresonding release path. XML attributes are used to specify non-default values for the ApplicationBase, Configuration File and PrivateBinPath. The Project Editor may be used to create or modify NUnit projects.

Even when you are running a single test assembly, NUnit creates an internal project to contain that assembly. If you are using the gui, you can save this project, edit it, add additional assemblies, etc. Note that the gui does not display the internal project unless you add assemblies or modify it in some other way.

If you use Visual Studio Support to load Visual Studio .Net project or solution files, NUnit converts them to Test projects internally. As with other internal projects, these test projects are not saved automatically but may be saved by use of the File menu.

Loading and Running

In the past, test writers have been able to rely on the current directory being set to the directory containing the single loaded assembly. For the purpose of compatibility, NUnit continues to set the current directory to the directory containing each assembly whenever any test from that assembly is run.

Additionally, because some assemblies may rely on unmanaged dlls in the same directory, the current directory is also set to that of the assembly at the time the assembly is loaded. However, in cases where multiple assemblies reference the same unmanaged assembly, this may not be sufficient and the user may need to place the directory containing the unmanaged dll on the path.

NUnit-2.6.0.12051/doc/nunitAddins.html0000664000175000017500000002137211720512704017076 0ustar jtaylorjtaylor NUnit - NunitAddins

NUnit Addins

NUnit originally identified tests in the time-honored way used in many xUnit test frameworks. Test classes inherited from the framework's TestCase class. Individual test case methods were identified by having names starting with "test..."

With NUnit 2.0, we introduced the use of attributes to identify both fixtures and test cases. Use of attributes in this way was a natural outcome of their presence in .NET and gave us a way of identifying tests that was completely independent of both inheritance and naming conventions.

However, by moving away from an inheritance-based mechanism we no longer had an easy way for others to extend NUnit's internal behavior. NUnit Addins are intended to fill that gap, providing an mechanism to introduce new or changed behavior without modifying NUnit itself.

Extension Points, Extensions and Addins

NUnit provides a number of Extension Points, places where it is possible to extend its behavior. Because NUnit works with various hosts and uses separate AppDomains to run tests, Extension Points are categorized into three types: Core, Client and Gui. Each of these types is supported by a different Extension Host.

An NUnit Addin provides enhanced functionality through one or more extensions, which it installs at identified Extension Points. Each Addin is characterized by the types of extensions it supplies, so that an Extension Host knows whether to invoke it.

Note: In the current release, only Core extensions are actually supported. An Addin may characterize itself as a Client or Gui extension and will be listed as such in the Addins Dialog, but no other action is taken.

Addin Identification, Loading and Installation

NUnit examines all assemblies in the bin/addins directory, looking for public classes with the NUnitAddinAttribute and implementing the IAddin interface. It loads all those it finds as Addins.

NUnitAddinAttribute supports three optional named parameters: Type, Name and Description. Name and Description are strings representing the name of the extension and a description of what it does. If no name is provided, the name of the class is used. Type may be any one or a combination of the ExtensionType enum members:

	[Flags]
	public enum ExtensionType
	{
		Core=1,
		Client=2,
		Gui=4
	}
The values may be or'ed together, allowing for future Addins that require extensions at multiple levels of the application. If not provided, Type defaults to ExtensionType.Core.

The IAddin interface, which must be implemented by each Addin, is defined as follows:

	public interface IAddin
	{
		bool Install( IExtensionHost host );
	}

The Install method is called by each host for which the addin has specified an ExtensionType. The addin should check that the necessary extension points are available and install itself, returning true for success or false for failure to install. The method will be called once for each extension host and - for Core extensions - each time a new test domain is loaded.

The Install method uses the IExtensionHost interface to locate extension points. It is defined as follows:

	public interface IExtensionHost
	{
	 	IExtensionPoint[] ExtensionPoints { get; }
		IExtensionPoint GetExtensionPoint( string name );
		ExtensionType ExtensionTypes { get; }
	}

The ExtensionPoints property returns an array of all extension points for those extensions that need the information. The ExtensionTypes property returns the flags for the type of extension supported by this host, allowing, for example, Gui extensions to only load in a Gui host.

Most addins will only need to use the GetExtensionPoint method to get the interface to a particular extension point. The IExtensionPoint interface is defined as follows:

	public interface IExtensionPoint
	{
		string Name { get; }
		IExtensionHost Host { get; }
		void Install( object extension );
		void Remove( object extension );
	}

Once again, most addins will only need to use one method - the Install method in this case. This method passes an extension object to the Extension Point where it is installed. Generally, extensions do not need to remove themselves once installed, but the method is provided in any case.

With NUnit 2.5, an additional interface, IExtensionPoint2 is available. It derives from IExtensionPoint and also allows setting the priority order in which the extension will be called in comparison to other extensions on the same extension point. The interface is defined as follows:

	public interface IExtensionPoint2 : IExtensionPoint
	{
		void Install( object extension, int priority );
	}

Only extension points that use a priority scheme implement this interface. In general, extension points with a priority scheme will use a default value for priority if the Install method without a priority is called.

In the NUnit 2.5 release, only the TestDecorators extension point implements IExtensionPoint2.

Extension Point Details

Depending on the particular extension point, the object passed will need to implement one or more interfaces. The following ExtensionPoints are implemented in this release of NUnit:

For examples of implementing each type of extension, see the Extensibility samples provided with NUnit. More complete examples are available in the code of NUnit itself, since NUnit uses the same mechanism internally.

See also...

NUnit-2.6.0.12051/doc/vsSupport.html0000664000175000017500000001612211720512704016640 0ustar jtaylorjtaylor NUnit - VsSupport

Visual Studio Support

NUnit supports the Visual Studio project and solution format, which are also used by a number of other IDEs. Visual Studio support is enabled/disabled by use of the Settings Dialog

Running From Within Visual Studio

The most convenient way to do this is to set up a custom tool entry specifying the path to NUnit as the command. For a VS2003 C# project, you can use $(TargetPath) for the arguments and $(TargetDir) for the initial directory.

With Visual Studio VS2005 this becomes a bit harder, because that release changed the meaning of the 'Target' macros so they now point to the intermediate 'obj' directories rather than the final output in one of the 'bin' directories. Here are some alternatives that work in both versions:

  • $(ProjectDir)$(ProjectFileName) to open the VS Project rather than the assembly. If you use this approach, be sure to rename your config file accordingly and put it in the same directory as the VS project file.
  • $(ProjectDir)bin/Debug/$(TargetName)$(TargetExt) to run the assembly directly. Note that this requires hard-coding part of the path, including the configuration.

If you would like to debug your tests, use the Visual Studio Debug | Processes menu item to attach to NUnit after starting it and set breakpoints in your test code as desired before running the tests.

Using Console Interface to Debug Applications

When the nunit-console program is run in debug mode under Visual Studio, it detects that it is running in this mode and sends output to the Visual Studio output window. Output is formatted so that double clicking any error or failure entries opens the appropriate test file at the location where the failure was detected.

Opening Visual Studio Projects

When Visual Studio support is enabled, the File Open dialog displays the following supported Visual Studio project types: C#, VB.Net, J# and C++. The project file is read and the configurations and output assembly locations are identified. Since the project files do not contain information about the most recently opened configuration, the output assembly for the first configuration found (usually Debug) is loaded in the GUI. The tree shows the project as the toplevel node with the assembly shown as its descendant.

Beginning with NUnit 2.2.2, you may also open a Visual Studio project by dragging it to the gui tree control.

When tests are run for a Visual studio project, they run just as if the output assembly had been loaded with one exception. The default location for the config file is the directory containing the project file and it's default name is the same as the project file with an extension of .config. For example, the following command would load the tests in the nunit.tests assembly using the configuration file nunit.tests.dll.config located in the same directory as the dll.

        nunit.exe nunit.tests.dll
On the other hand, the following command would load the tests using the configuration file nunit.tests.config located in the same directory as the csproj file.
        nunit.exe nunit.tests.csproj
The same consideration applies to running tests using the console runner.

Opening Visual Studio Solutions

When Visual Studio support is enabled, solution files may be opened as well. All the output assemblies from contained projects of the types supported will be loaded in the tree. In the case where all contained projects are located in the subdirectories beneath the solution, it will be possible to load and run tests using this method directly.

Beginning with NUnit 2.2.2, you may also open a Visual Studio solution by dragging it to the gui tree control.

When a solution contains projects located elsewhere in the file system, it may not be possible to run the tests - although the solution will generally load without problem. In this case, the Project Editor should be use to modify and save the NUnit test project so that there is all referenced assemblies are located in or beneath the application base directory.

Adding Visual Studio Projects to the Open Test Project

When Visual Studio support is enabled, the Project menu contains an active entry to add a VS project to the loaded project. The output assembly will be added for each of the configurations specified in the VS project.

NUnit-2.6.0.12051/doc/stringAssert.html0000664000175000017500000001064611720512704017310 0ustar jtaylorjtaylor NUnit - StringAssert

StringAssert (NUnit 2.2.3)

The StringAssert class provides a number of methods that are useful when examining string values.

StringAssert.Contains( string expected, string actual );
StringAssert.Contains( string expected, string actual, 
                string message );
StringAssert.Contains( string expected, string actual,
                string message, params object[] args );

StringAssert.StartsWith( string expected, string actual );
StringAssert.StartsWith( string expected, string actual, 
                string message );
StringAssert.StartsWith( string expected, string actual,
                string message, params object[] args );

StringAssert.EndsWith( string expected, string actual );
StringAssert.EndsWith( string expected, string actual, 
                string message );
StringAssert.EndsWith( string expected, string actual,
                string message, params object[] args );

StringAssert.AreEqualIgnoringCase( string expected, string actual );
StringAssert.AreEqualIgnoringCase( string expected, string actual, 
                string message );
StringAssert.AreEqualIgnoringCase( string expected, string actual,
                string message params object[] args );
				
StringAssert.IsMatch( string regexPattern, string actual );
StringAssert.IsMatch( string regexPattern, string actual, 
                string message );
StringAssert.IsMatch( string regexPattern, string actual,
                string message, params object[] args );
NUnit-2.6.0.12051/doc/valueSource.html0000664000175000017500000001554411720512704017117 0ustar jtaylorjtaylor NUnit - ValueSource

ValueSourceAttribute (NUnit 2.5)

ValueSourceAttribute is used on individual parameters of a test method to identify a named source for the argument values to be supplied. The attribute has two public constructors.

ValueSourceAttribute(Type sourceType, string sourceName);
ValueSourceAttribute(string sourceName);

If sourceType is specified, it represents the class that provides the data. It must have a default constructor.

If sourceType is not specified, the class containing the test method is used. NUnit will construct it using either the default constructor or - if arguments are provided - the appropriate constructor for those arguments.

The sourceName, represents the name of the source that will provide the arguments. It should have the following characteristics:

  • It may be a field, a non-indexed property or a method taking no arguments.
  • It may be either an instance or a static member.
  • It must return an IEnumerable or a type that implements IEnumerable.
  • The individual items returned from the enumerator must be compatible with the type of the parameter on which the attribute appears.

Order of Execution

In NUnit 2.5, individual test cases are sorted alphabetically and executed in that order. With NUnit 2.5.1, the individual cases are not sorted, but are executed in the order in which NUnit discovers them. This order does not follow the lexical order of the attributes and will often vary between different compilers or different versions of the CLR.

As a result, when ValueSourceAttribute appears multiple times on a parameter or when other data-providing attributes are used in combination with ValueSourceAttribute, the order of the arguments is undefined.

However, when a single ValueSourceAttribute is used by itself, the order of the arguments follows exactly the order in which the data is returned from the source.

Note on Object Construction

NUnit locates the test cases at the time the tests are loaded, creates instances of each class with non-static sources and builds a list of tests to be executed. Each source object is only created once at this time and is destroyed after all tests are loaded.

If the data source is in the test fixture itself, the object is created using the appropriate constructor for the fixture parameters provided on the TestFixtureAttribute, or the default constructor if no parameters were specified. Since this object is destroyed before the tests are run, no communication is possible between these two phases - or between different runs - except through the parameters themselves.

NUnit-2.6.0.12051/doc/sameasConstraint.html0000664000175000017500000000740411720512704020134 0ustar jtaylorjtaylor NUnit - SameasConstraint

Same As Constraint (NUnit 2.4)

A SameAsConstraint is used to test whether the object passed as an actual value has the same identity as the object supplied in its constructor.

Constructor

SameAsConstraint( object expected )

Syntax

Is.SameAs( object expected )

Examples of Use

Exception ex1 = new Exception();
Exception ex2 = ex1;
Assert.That( ex2, Is.SameAs( ex1 ) );

Exception ex3 = new Exception();
Assert.That( ex3, Is.Not.SameAs( ex1 ) );
NUnit-2.6.0.12051/doc/consoleCommandLine.html0000664000175000017500000004436411720512704020375 0ustar jtaylorjtaylor NUnit - ConsoleCommandLine

NUnit-Console Command Line Options

The console interface has a few additional options compared to the forms interface. The command line must always specify one or more file names. The console interface normally creates an XML representation of the test results. This file by default is called TestResult.xml and is placed in the working directory.

Note: By default the nunit-console program is not added to your path. You must do this manually if this is the desired behavior.

Note: Under the Windows operating system, options may be prefixed by either a forward slash or a hyphen. Under Linux, a hyphen must be used. Options that take values may use an equal sign, a colon or a space to separate the option from its value.

Specifying Which Tests to Run

Specifying an Assembly

The console program must always have an assembly or project specified. To run the tests contained in the nunit.tests.dll use the following command:

        nunit-console nunit.tests.dll

To run the tests in nunit.tests.dll through the Visual Studio project, use:

        nunit-console nunit.tests.csproj

To run the same tests through an NUnit test project you have defined, use:

        nunit-console nunit.tests.nunit

Specifying an Assembly and a Test to be Run

You may specify a test to be run by providing the full name of the test along with the containing assembly. For example to run NUnit.Tests.AssertionTests in the nunit.tests assembly use the following command:

        nunit-console /run:NUnit.Tests.AssertionTests nunit.tests.dll

The name of the test to be run may be that of a test case, test fixture or a namespace containing tests.

You can specify multiple tests by separating names with commas (without spaces). For example:

        nunit-console /run:NUnit.Tests.AssertionTests,NUnit.Tests.ConstraintTests nunit.tests.dll

Unlike the deprecated /fixture option, this option affects the running rather than the loading of the tests. Consequently it supports much broader use, including situations involving SetUpFixtures, which are not run if the class in question is not loaded. You should use /run in lieu of /fixture in most cases.

Specifying Tests to be Run Using a Separate File

You may specify a list of tests to be run by creating a separate file listing those tests and using the /runlist option:

        nunit-console /runlist:testlist.txt nunit.tests.dll

The file 'testlist.txt' should contain the full name of each test, listed one per line. Each test named may be a test case, test fixture or a namesspace containing tests. Lines with the character '#' in the first column are treated as comments.

Specifying an Assembly and a Fixture to be Loaded (Deprecated)

When specifying a fixture, you must give the full name of the test fixture along with the containing assembly. For example, to load the NUnit.Tests.AssertionTests in the nunit.tests.dll assembly use the following command:

        nunit-console /fixture:NUnit.Tests.AssertionTests nunit.tests.dll

The name specified after the /fixture option may be that of a TestFixture class, a legacy suite (using the Suite property ) or a namespace. If a namespace is given, then all fixtures under that namespace are loaded.

This option is provided for backward compatibility. In most cases, you will be better served by using the /test option.

Specifying Multiple Assemblies

You may run tests from multiple assemblies in one run using the console interface even if you have not defined an NUnit test project file. The following command would run a suite of tests contained in assembly1.dll, assembly2.dll and assembly3.dll.

        nunit-console assembly1.dll assembly2.dll assembly3.dll

Notes: You may specify multiple assemblies, but not multiple NUnit or Visual Studio projects on the command line. Further, you may not specify an NUnit or Visual Studio project together with a list of assemblies.

Beginning with NUnit 2.4, the console loads multiple assemblies specified in this way into separate AppDomains by default. You may provide a separate config file for each assembly. You may override the default by use of the /domain option.

Beginning with NUnit 2.4, the /fixture option, when used with multiple assemblies, will run tests matching the fixture name in all the assemblies. In earlier versions, only the first test found was executed.

Specifying which Configuration to run

When running tests from a Visual Studio or NUnit project, the first configuration found will be loaded by default. Usually this is Debug. The configuration loaded may be controlled by using the /config switch. The following will load and run tests for the Release configuration of nunit.tests.dll.

        nunit-console nunit.tests.csproj /config:Release

Note: This option has no effect when loading an assembly directly.

Specifying Test Categories to Include or Exclude

NUnit provides CategoryAttribute for use in marking tests as belonging to one or more categories. Categories may be included or excluded in a test run using the /include and /exclude options. The following command runs only the tests in the BaseLine category:

        nunit-console myassembly.dll /include:BaseLine

The following command runs all tests except those in the Database category:

        nunit-console myassembly.dll /exclude:Database

Multiple categories may be specified on either option, by using commas to separate them.

Notes: Beginning with NUnit 2.4, the /include and /exclude options may be combined on the command line. When both are used, all tests with the included categories are run except for those with the excluded categories.

Beginning with NUnit 2.4.6, you may use a Category Expression with /include or /exclude. The table shows some examples:
Expression Action
A|B|C Selects tests having any of the categories A, B or C.
A,B,C Selects tests having any of the categories A, B or C.
A+B+C Selects only tests having all three of the categories assigned
A+B|C Selects tests with both A and B OR with category C.
A+B-C Selects tests with both A and B but not C.
-A Selects tests not having category A assigned
A+(B|C) Selects tests having both category A and either of B or C
A+B,C Selects tests having both category A and either of B or C

Note: As shown by the last two examples, the comma operator is equivalent to | but has a higher precendence. Order of evaluation is as follows:

  1. Unary exclusion operator (-)
  2. High-precendence union operator (,)
  3. Intersection and set subtraction operators (+ and binary -)
  4. Low-precedence union operator (|)

Note: Because the operator characters have special meaning, you should avoid creating a category that uses any of them in it's name. For example, the category "db-tests" could not be used on the command line, since it appears to means "run category db, except for category tests." The same limitation applies to characters that have special meaning for the shell you are using.

For a clear understanding of how category selection works, review the documentation for both the Category Attribute and the Explicit Attribute.

Controlling How Tests Are Run

Specifying the .NET Framework Version

Most applications are written to run under a specific version of the CLR. A few are designed to operate correctly under multiple versions. In either case, it is important to be able to specify the CLR version to be used for testing.

Prior to NUnit 2.5, it was necessary to run the console program itself using the CLR version under which you wanted to run tests. This was done either by editing the nunit-console.exe.config file or by setting the COMPLUS_Version environment variable before running the program.

Under NUnit 2.5 and later versions, you may still use either of these approaches, but a simpler method is available.

The /framework option allows you to specify the version of the runtime to be used in executing tests. If that version specified is different from the one being used by NUnit, the tests are run in a separate process. For example, you may enter

        nunit-console myassembly.dll /framework:net-1.1

This command will run tests under .NET 1.1 even if you are running the .NET 2.0 build of the nunit-console. Beginning with version 2.5.3, all versions of .NET through 4.0 as well as Mono profiles 1.0, 2.0 and 3.5 are supported.

Note: This option is not available using the .NET 1.1 build of nunit-console.

Controlling the Use of Processes

The /process option controls how NUnit loads tests in processes. The following values are recognized.

Single
All the tests are run in the nunit-console process. This is the default.
Separate
A separate process is created to run the tests.
Multiple
A separate process is created for each test assembly, whether specified on the command line or listed in an NUnit project file.

Note: This option is not available using the .NET 1.1 build of nunit-console.

Controlling the Use of AppDomains

The /domain option controls of the creation of AppDomains for running tests. The following values are recognized:

None
No domain is created - the tests are run in the primary domain. This normally requires copying the NUnit assemblies into the same directory as your tests.
Single
A test domain is created - this is how NUnit worked prior to version 2.4
Multiple
A separate test domain is created for each assembly

The default is to use multiple domains if multiple assemblies are listed on the command line. Otherwise a single domain is used.

Controlling the Apartment in Which Tests Run

The /apartment option may be used to specify the ApartmentState (STA or MTA) of the test runner thread. Since the default is MTA, the option is only needed to force execution in the Single Threaded Apartment.

Note: If a given test must always run in a particular apartment, as is the case with many Gui tests, you should use an attribute on the test rather than specifying this option at the command line.

Specifying a Default Timeout Value

The /timeout option takes an int value representing the default timeout to be used for test cases in this run. If any test exceeds the timeout value, it is cancelled and reported as an error. The default value may be overridden for selected tests by use of TimeoutAttribute.

Note: If you do not use this option, no timeout is set and tests may run for any amount of time.

Controlling the Output of a Test Run

Redirecting Text Output

Output created by the test, which is normally shown on the console, may be redirected to a file. The following command redirects standard output to the file TestResult.txt:

        nunit-console nunit.tests.dll /out:TestResult.txt

The following command redirects standard error output to the StdErr.txt file.

        nunit-console nunit.tests.dll /err:StdErr.txt

Note:This option only redirects output produced by the tests, together with selected NUnit output that is interspersed with the test output. It does not redirect all console output. If you want to redirect all output to a file, you should use command line redirection as supported by the shell you are using. This option exists for the purpose of separating test output from other output, such as the NUnit summary report.

Labeling Text Output

The output from each test normally follows right after that of the preceding test. You may use the /labels option to cause an identifying label to be displayed at the start of each test case.

Specifying the XML result file name

As stated above, the console program normally creates an XML representation of the test results. To change the name of the output file to "console-test.xml" use the following command line option:

        nunit-console /result:console-test.xml nunit.tests.dll

The XML output may be entirely eliminated by use of the /noresult option.

Note: For compatibility with earlier releases, NUnit 2.6 also recognizes /xml and /noxml as synonyms for the /result and /noresult options.

Note: For additional information see the XML schema for the test results. This file is in the same directory as the executable and is called Results.xsd.

Specifying a Directory for Output

By default, all output files are created in the current directory. You may change the location for such files by specifying the /work option. For example, the following command would cause the TestResult.xml and Output.txt files to be created in the results directory.

        nunit-console /work:results /out:Output.txt nunit.tests.dll

Miscellaneous Options

The /trace option allows you to control the amount of information that NUnit writes to its internal trace log. Valid values are Off, Error, Warning,Info and Debug. The default is Off.

The /noshadow option disables shadow copying of the assembly in order to provide improved performance.

The /nothread option suppresses use of a separate thread for running the tests and uses the main thread instead.

The /stoponerror option causes execution of the test run to terminate immediately on the first test failure or error.

The /wait option causes the program to wait for user input before exiting. This is useful when running nunit-console from a shortcut.

The /xmlconsole option displays raw XML output on the console rather than transforming it. This is useful when debugging problems with the XML format.

The /nologo option disables display of the copyright information at the start of the program.

The /cleanup option clears the shadow copy cache and exits.

The /help or /? option displays a brief help message

NUnit-2.6.0.12051/doc/property.html0000664000175000017500000001776111720512704016511 0ustar jtaylorjtaylor NUnit - Property

PropertyAttribute (NUnit 2.4)

The Property attribute provides a generalized approach to setting named properties on any test case or fixture, using a name/value pair.

In the example below, the fixture class MathTests is given a Location value of 723 while the test case AdditionTest is given a Severity of "Critical"

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture, Property("Location",723)]
  public class MathTests
  {
    [Test, Property("Severity", "Critical")]
	public void AdditionTest()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Property("Location",723)>
    Public Class MathTests
	
    <Test(), Property("Severity","Critical")>
	  Public Sub AdditionTest()
    ' ...
    End Sub
	
  End Class
  
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture, Property("Location",723)]
  public __gc class MathTests
  {
    [Test, Property("Severity","Critical")] void AdditionTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Property("Location",723) */
public class MathTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Property("Severity","Critical") */
  public void AdditionTest()
  { /* ... */ }
}

Usage Note

The PropertyAttribute is not used for any purpose by NUnit itself, but it does display them in the XML output file and in the Test Properties dialog of the gui.

It is possible to write extensions that access the value of specific properties. It is also possible to access the value of properties from within a test using reflection.

Custom Property Attributes

Users can define custom attributes that derive from PropertyAttribute and have them recognized by NUnit. PropertyAttribute provides a protected constructor that takes the value of the property and sets the property name to the name of the derived class. NUnit itself uses this facility: some of it's specialized attributes are actually specializations of PropertyAttribute.

Here's an example that creates a Severity property. It works just like any other property, but has a simpler syntax and is type-safe. A test reporting system might make use of the property to provide special reports.

public enum SeverityLevel
{
    Critical,
    Major,
    Normal,
    Minor
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false)]
public class SeverityAttribute : PropertyAttribute
{
    public SeverityAttribute( SeverityLevel level )
	    : base( level ); 
}

...

[Test, Severity( SeverityLevel.Critical)]
public void MyTest()
{ /*...*/ }

Beginning with NUnit 2.5, a property attribute is able to contain multiple name/value pairs. This capability is not exposed publicly but may be used by derived property classes. NUnit uses this feature itself for certain attributes. See, for example, RequiresThreadAttribute.

NUnit-2.6.0.12051/doc/comparisonConstraints.html0000664000175000017500000001652711720512704021226 0ustar jtaylorjtaylor NUnit - ComparisonConstraints

Comparison Constraints (NUnit 2.4 / 2.5)

Comparison constraints are able to test whether one value is greater or less than another. Comparison constraints work on numeric values, as well as other objects that implement the IComparable interface or - beginning with NUnit 2.5 - IComparable<T>.

Beginning with NUnit 2.5, you may supply your own comparison algorithm through the Using modifier.

GreaterThanConstraint

Action

Tests that one value is greater than another.

Constructor

GreaterThanConstraint(object expected)

Syntax

Is.GreaterThan(object expected)
Is.Positive // Equivalent to Is.GreaterThan(0)

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

Assert.That(7, Is.GreaterThan(3));
Assert.That(myOwnObject, 
    Is.GreaterThan(theExpected).Using(myComparer));
Assert.That(42, Is.Positive);

GreaterThanOrEqualConstraint

Action

Tests that one value is greater than or equal to another.

Constructor

GreaterThanOrEqualConstraint(object expected)

Syntax

Is.GreaterThanOrEqualTo(object expected)
Is.AtLeast(object expected)

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

Assert.That(7, Is.GreaterThanOrEqualTo(3));
Assert.That(7, Is.AtLeast(3));
Assert.That(7, Is.GreaterThanOrEqualTo(7));
Assert.That(7, Is.AtLeast(7));
Assert.That(myOwnObject, 
    Is.GreaterThanOrEqualTo(theExpected).Using(myComparer));

LessThanConstraint

Action

Tests that one value is less than another.

Constructor

LessThanConstraint(object expected)

Syntax

Is.LessThan(object expected)
Is.Negative // Equivalent to Is.LessThan(0)

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

Assert.That(3, Is.LessThan(7));
Assert.That(myOwnObject, 
    Is.LessThan(theExpected).Using(myComparer));
Assert.That(-5, Is.Negative);

LessThanOrEqualConstraint

Action

Tests that one value is less than or equal to another.

Constructor

LessThanOrEqualConstraint(object expected)

Syntax

Is.LessThanOrEqualTo(object expected)
Is.AtMost(object expected)

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

Assert.That(3, Is.LessThanOrEqualTo(7));
Assert.That(3, Is.AtMost(7));
Assert.That(3, Is.LessThanOrEqualTo(3));
Assert.That(3, Is.AtMost(3));
Assert.That(myOwnObject, 
    Is.LessThanOrEqualTo(theExpected).Using(myComparer));

RangeConstraint

Action

Constructor

RangeConstraint(IComparable from, IComparable to)

Syntax

Is.InRange(IComparable from, IComparable to)

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

int[] iarray = new int[] { 1, 2, 3 }

Assert.That( 42, Is.InRange(1, 100) );
Assert.That( iarray, Is.All.InRange(1, 3) );
Assert.That(myOwnObject, 
    Is.InRange(lowExpected, highExpected).Using(myComparer));
NUnit-2.6.0.12051/doc/test.html0000664000175000017500000001660511720512704015600 0ustar jtaylorjtaylor NUnit - Test

TestAttribute (NUnit 2.0 / 2.5)

The Test attribute is one way of marking a method inside a TestFixture class as a test. For backwards compatibility with previous versions of Nunit a test method may also be found if the first 4 letters are "test" regardless of case. This option is available by setting a value in the config file for the test.

Prior to NUnit 2.5, the signature for a test method was:

        public void MethodName()

Beginning with NUnit 2.5, static methods may be used as tests:

        public static void MethodName()

In addition, with 2.5, test methods may have arguments and return values, provided that NUnit is told what values to use for the arguments and how to handle the return value. For more information on these capabilities, see Parameterized Tests as well as some of the related attributes listed at the end of this page.

Parameterized test methods may also be generic, provided that NUnit is able to deduce the proper argument types from the types of the data arguments supplied.

If the programmer marks a test method that does not have the correct signature it will be considered as not runnable and be indicated as such by the console or gui runner. In the Gui, such tests are marked in red.

In the examples on this page, NUnit would have no way of knowing what values to supply as arguments, so methods without parameters are used.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test] public void Add()
    { /* ... */ }

    public void TestSubtract()
    { /* backwards compatibility */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <Test()> Public Sub Add()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test] void Add();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  public void Add()
  { /* ... */ }
}

See also...

NUnit-2.6.0.12051/doc/attributes.html0000664000175000017500000001156411720512704017006 0ustar jtaylorjtaylor NUnit - Attributes

Attributes

Version 1 of NUnit used the classic approach to identifying tests based on inheritance and naming conventions. From version 2.0 on, NUnit has used custom attributes for this purpose.

Because NUnit test fixtures do not inherit from a framework class, the developer is free to use inheritance in other ways. And because there is no arbitrary convention for naming tests, the choice of names can be entirely oriented toward communicating the purpose of the test.

All NUnit attributes are contained in the NUnit.Framework namespace. Each source file that contains tests must include a using statement for that namespace and the project must reference the framework assembly, nunit.framework.dll.

Beginning with NUnit 2.4.6, NUnit's attributes are no longer sealed and any attributes that derive from them will be recognized by NUnit.

NUnit-2.6.0.12051/doc/samples.html0000664000175000017500000001002311720512704016251 0ustar jtaylorjtaylor NUnit - Samples

Samples

The samples installed with NUnit continue to be organized by language, with an additional folder for Extensibility examples. The 'money-port' example has been removed as of NUnit 2.5.

C# Samples

Failures
This sample written in C# demonstrates 4 failing unit tests and one test that is not run.
Money
This is a C# version of the money example which is found in most xUnit implementations. Thanks to Kent Beck.

J# Samples

Failures
This has three failing tests and one ignored test written in J#.

VB.NET Samples

Failures
This sample written in VB.NET demonstrates 4 failing unit tests and one test that is not run.
Money
This is a VB.NET version of the money example which is found in most xUnit implementations. Thanks to Kent Beck.

Managed C++ Samples

Failures
This is the same example as the others with four failing unit tests and one ignored test. NOTE:  The results are as expected when compiled in Debug mode. In Release mode the divide by zero test succeeds.

C++/CLI Samples

Failures
This is the same example as the others with four failing unit tests and one ignored test.

Extensibility Examples

Minimal
The smallest possible Addin: it does nothing but is recognized by NUnit and listed in the Addins dialog.
SampleSuiteExtension
A "toy" SuiteBuilder. It recognizes a special attribute and identifies tests right in the suite extension. This example uses separate objects for the addin and the suite builder.
SampleFixtureExtension
A slightly more involved SuiteBuilder. It recognizes a special attribute and registers a test case builder to identify its tests. It inherits from NUnitTestFixture and so gets all the features of that class as well for free. This example uses the same object to implement both the addin and the suite builder.
NUnit-2.6.0.12051/doc/extensionTips.html0000664000175000017500000000763211720512704017475 0ustar jtaylorjtaylor NUnit - ExtensionTips

Tips for Writing Extensions

An Extenders Guide will be published in the future. At the moment, writing an extension is a bit of an adventure. Extension authors are advised to join the nunit-developer list and post questions and comments there.

For the moment, the following tips may be of assistance.

  • The nunit.core.interfaces assembly is intended to be stable in the future while the nunit.core assembly will change from release to release. Right now, both assemblies are still in flux, but extensions that depend solely on the interfaces assembly will have a much better chance of surviving NUnit version changes. Unfortunately, this is rather difficult to do without duplicating a great deal of NUnit code. Most of the add-in samples provided with NUnit are currently version dependent.
  • If you place the definition of a custom attribute in the same assembly as your add-in, then user tests are dependent on the add-in assembly. If the add-in is version-dependent, then the user tests will also be version-dependent. We suggest placing any types referenced by user tests in a separate assembly, particularly if your extension relies on nunit.core.
  • If using Visual Studio, set Copy Local to false for any references to nunit.core or nunit.core.interfaces. This is especially important if you are also building NUnit itself.
  • There is currently no mechanism to allow decorators to apply in a particular order. NUnit applies decorators in the order in which they are returned through reflection, which may vary among different runtimes.
  • Avoid trying to "stretch" the existing extension points to do more than they were intended to do. Rather, let us know what further extension points you would like to see!
NUnit-2.6.0.12051/doc/quickStart.html0000664000175000017500000003043311720512704016746 0ustar jtaylorjtaylor NUnit - QuickStart

NUnit Quick Start

Note: This page is based on the original QuickStart.doc, found in earlier releases of NUnit. It has been pointed out that it isn't a good example of Test-Driven Development. However, we're keeping it in the docs because it does illustrate the basics of using NUnit. We'll revise or replace it in a future release.

Lets start with a simple example. Suppose we are writing a bank application and we have a basic domain class Account. Account supports operations to deposit, withdraw, and transfer funds. The Account class may look like this:

namespace bank
{
  public class Account
  {
    private float balance;
    public void Deposit(float amount)
    {
      balance+=amount;
    }

    public void Withdraw(float amount)
    {
      balance-=amount;
    }

    public void TransferFunds(Account destination, float amount)
    {
    }

    public float Balance
    {
      get{ return balance;}
    }
  }
}

Now lets write a test for this class AccountTest. The first method we will test is TransferFunds.

namespace bank
{
  using NUnit.Framework;

  [TestFixture]
  public class AccountTest
  {
    [Test]
    public void TransferFunds()
    {
      Account source = new Account();
      source.Deposit(200.00F);
      Account destination = new Account();
      destination.Deposit(150.00F);

      source.TransferFunds(destination, 100.00F);
      Assert.AreEqual(250.00F, destination.Balance);
      Assert.AreEqual(100.00F, source.Balance);
	
    }
  }
}

The first thing to notice about this class is that it has a [TestFixture] attribute associated with it this is the way to indicate that the class contains test code (this attribute can be inherited). The class has to be public and there are no restrictions on its superclass. The class also has to have a default constructor.

The only method in the class TransferFunds, has a [Test] attribute associated with it this is an indication that it is a test method. Test methods have to return void and take no parameters. In our test method we do the usual initialization of the required test objects, execute the tested business method and check the state of the business objects. The Assert class defines a collection of methods used to check the post-conditions and in our example we use the AreEqual method to make sure that after the transfer both accounts have the correct balances (there are several overloadings of this method, the version that was used in this example has the following parameters : the first parameter is an expected value and the second parameter is the actual value).

Compile and run this example. Assume that you have compiled your test code into a bank.dll. Start the NUnit Gui (the installer will have created a shortcut on your desktop and in the Program Files folder), after the GUI starts, select the File->Open menu item, navigate to the location of your bank.dll and select it in the Open dialog box. When the bank.dll is loaded you will see a test tree structure in the left panel and a collection of status panels on the right. Click the Run button, the status bar and the TransferFunds node in the test tree turn red our test has failed. The Errors and Failures panel displayed the following message:

    TransferFunds : expected <250> but was <150>
and the stack trace panel right below it reported where in the test code the failure has occurred
    at bank.AccountTest.TransferFunds() in C:\nunit\BankSampleTests\AccountTest.cs:line 17

That is expected behavior; the test has failed because we have not implemented the TransferFunds method yet. Now lets get it to work. Dont close the GUI and go back to your IDE and fix the code, make your TransferFunds method look like this:

public void TransferFunds(Account destination, float amount)
{
	destination.Deposit(amount);
	Withdraw(amount);
}

Now recompile your code and click the run button in GUI again the status bar and the test tree turn green. (Note how the GUI has reloaded the assembly automatically for you; we will keep the GUI open all the time and continue working with our code in IDE and write more tests).

Lets add some error checking to our Account code. We are adding the minimum balance requirement for the account to make sure that banks continue to make their money by charging your minimal overdraft protection fee. Lets add the minimum balance property to our Account class:

private float minimumBalance = 10.00F;
public float MinimumBalance
{
	get{ return minimumBalance;}
}

We will use an exception to indicate an overdraft:

namespace bank
{
  using System;
  public class InsufficientFundsException : ApplicationException
  {
  }
}

Add a new test method to our AccountTest class:

[Test]
[ExpectedException(typeof(InsufficientFundsException))]
public void TransferWithInsufficientFunds()
{
	Account source = new Account();
	source.Deposit(200.00F);
	Account destination = new Account();
	destination.Deposit(150.00F);
	source.TransferFunds(destination, 300.00F);
}

This test method in addition to [Test] attribute has an [ExpectedException] attribute associated with it this is the way to indicate that the test code is expecting an exception of a certain type; if such an exception is not thrown during the execution the test will fail. Compile your code and go back to the GUI. As you compiled your test code, the GUI has grayed out and collapsed the test tree as if the tests were not run yet (GUI watches for the changes made to the test assemblies and updates itself when the structure of the test tree has changed e.g. new test is added). Click the Run button we have a red status bar again. We got the following Failure :

    TransferWithInsufficentFunds : InsufficientFundsException was expected
Lets fix our Account code again, modify the TransferFunds method this way:

public void TransferFunds(Account destination, float amount)
{
	destination.Deposit(amount);
	if(balance-amount<minimumBalance)
		throw new InsufficientFundsException();
	Withdraw(amount);
}

Compile and run the tests green bar. Success! But wait, looking at the code weve just written we can see that the bank may be loosing money on every unsuccessful funds Transfer operation. Lets write a test to confirm our suspicions. Add this test method:

[Test]
public void TransferWithInsufficientFundsAtomicity()
{
	Account source = new Account();
	source.Deposit(200.00F);
	Account destination = new Account();
	destination.Deposit(150.00F);
	try
	{
		source.TransferFunds(destination, 300.00F);
	}
	catch(InsufficientFundsException expected)
	{
	}

	Assert.AreEqual(200.00F,source.Balance);
	Assert.AreEqual(150.00F,destination.Balance);
}

We are testing the transactional property of our business method all operations are successful or none. Compile and run red bar. OK, weve made $300.00 out of a thin air (1999.com dj vu?) the source account has the correct balance of 200.00 but the destination account shows : $450.00. How do we fix this? Can we just move the minimum balance check call in front of the updates:

public void TransferFunds(Account destination, float amount)
{
	if(balance-amount<minimumBalance) 
		throw new InsufficientFundsException();
	destination.Deposit(amount);
	Withdraw(amount);
}

What if the Withdraw() method throws another exception? Should we execute a compensating transaction in the catch block or rely on our transaction manager to restore the state of the objects? We need to answer those questions at some point, but not now; but what do we do with the failing test in the meantime remove it? A better way is to temporarily ignore it, add the following attribute to your test method

[Test]
[Ignore("Decide how to implement transaction management")]
public void TransferWithInsufficientFundsAtomicity()
{
	// code is the same
}

Compile and run yellow bar. Click on Tests Not Run tab and you will see bank.AccountTest.TransferWithInsufficientFundsAtomicity() in the list along with the Reason this test is ignored.

Looking at our test code we can see that some refactoring is in order. All test methods share a common set of test objects. Lets extract this initialization code into a setup method and reuse it in all of our tests. The refactored version of our test class looks like this:

namespace bank
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class AccountTest
  {
    Account source;
    Account destination;

    [SetUp]
    public void Init()
    {
      source = new Account();
      source.Deposit(200.00F);
      destination = new Account();
      destination.Deposit(150.00F);
    }

    [Test]
    public void TransferFunds()
    {
      source.TransferFunds(destination, 100.00f);
      Assert.AreEqual(250.00F, destination.Balance);
      Assert.AreEqual(100.00F, source.Balance);
    }

    [Test]
    [ExpectedException(typeof(InsufficientFundsException))]
    public void TransferWithInsufficientFunds()
    {
      source.TransferFunds(destination, 300.00F);
    }

    [Test]
    [Ignore("Decide how to implement transaction management")]
    public void TransferWithInsufficientFundsAtomicity()
    {
      try
      {
        source.TransferFunds(destination, 300.00F);
      }
      catch(InsufficientFundsException expected)
      {
      }

      Assert.AreEqual(200.00F,source.Balance);
      Assert.AreEqual(150.00F,destination.Balance);
    }
  }
}

Note that Init method has the common initialization code, it has void return type, no parameters, and it is marked with [SetUp] attribute. Compile and run same yellow bar!

NUnit-2.6.0.12051/doc/vsTestAdapter.html0000664000175000017500000001100111720512704017373 0ustar jtaylorjtaylor NUnit - VsTestAdapter

NUnit Test Adapter for Visual Studio 11

The NUnit Test Adapter allows you to run NUnit tests inside Visual Studio. The current release, version 0.90, only works with the Visual Studio 11 Developer Preview, which is available for download from Microsoft. Earlier releases of Visual Studio did not have the ability to recognize tests built with Open Source testing frameworks like NUnit.

Installation

The easiest way to install the NUnit Test Adapter is using the Extension Manager within Visual Studio. Follow these steps:

  1. From within Visual Studio 11, select Tools | Extension Manager.
  2. In the left panel of the Extension Manager, select Online Extensions.
  3. Locate the NUnit Test Adapter in the center panel and highlight it.
  4. Click 'Download' and follow the instructions.

Use the Extension Manager to ensure that the NUnit Test Adapter is enabled.

Usage

In preparation for using the test adapter, make sure that the Unit Test Explorer is shown in your window. If you don't see it, use View | Other Windows | Unit Test Explorer to show it and position the window where you would like it within Visual Studio.

When you initially open a solution, no tests will be displayed. After compiling the assemblies in the solution, Visual Studio will interact with the NUnit Test Adapter to discover tests and a list of them will be shown in the Unit Test Explorer.

Click on Run All Tests in the Unit Test Explorer to run all the tests. You may also select one or more tests in the list and run them by right-clicking and using the context menu.

The context menu also contains entries for debugging tests and for navigating to the source code of a test.

Known Problems

  1. There is no test status corresponding to NUnit's Inconclusive result, so tests with this result are reported as Not Run.
  2. Test cases appear in a flat list, without any grouping by fixture or namespace. This can make it hard to select a group of related tests to be run. It is, however, relatively easy to rerun all failing tests.
  3. Theories are reported as individual cases, rather as a single unit.
  4. Startup performance is rather poor in this release.

Reporting Problems

Until a separate project is created, bugs should be reported using the NUnit bug list.

NUnit-2.6.0.12051/doc/pathConstraints.html0000664000175000017500000001460711720512704020005 0ustar jtaylorjtaylor NUnit - PathConstraints

Path Constraints (NUnit 2.5)

Path constraints perform tests on paths, without reference to any actual files or directories. This allows testing paths that are created by an application for reference or later use, without any effect on the environment.

Path constraints are intended to work across multiple file systems, and convert paths to a canonical form before comparing them.

It is usually not necessary to know the file system of the paths in order to compare them. Where necessary, the programmer may use the IgnoreCase and RespectCase modifiers to provide behavior other than the system default.

SamePathConstraint

Action

Tests that two paths are equivalent.

Constructor

SamePathConstraint( string expectedPath )

Syntax

Is.SamePath( string expectedPath )

Modifiers

...IgnoreCase
...RespectCase

Examples of Use

Assert.That( "/folder1/./junk/../folder2", 
	Is.SamePath( "/folder1/folder2" ) );
Assert.That( "/folder1/./junk/../folder2/x", 
	Is.Not.SamePath( "/folder1/folder2" ) );

Assert.That( @"C:\folder1\folder2",
	Is.SamePath( @"C:\Folder1\Folder2" ).IgnoreCase );
Assert.That( "/folder1/folder2",
	Is.Not.SamePath( "/Folder1/Folder2" ).RespectCase );

SubPathConstraint

Action

Tests that one path is under another path.

Constructor

SubPathConstraint( string expectedPath )

Syntax

Is.SubPath( string expectedPath )

Modifiers

...IgnoreCase
...RespectCase

Examples of Use

Assert.That( "/folder1/./junk/../folder2", 
	Is.SubPath( "/folder1/folder2" ) );
Assert.That( "/folder1/junk/folder2",
	Is.Not.SubPath( "/folder1/folder2" ) );

Assert.That( @"C:\folder1\folder2\folder3",
	Is.SubPath( @"C:\Folder1\Folder2/Folder3" ).IgnoreCase );
Assert.That( "/folder1/folder2/folder3",
	Is.Not.SubPath( "/Folder1/Folder2/Folder3" ).RespectCase );

SamePathOrUnderConstraint

Action

Tests that one path is equivalent another path or that it is under it.

Constructor

SamePathOrUnderConstraint( string expectedPath )

Syntax

Is.SamePathOrUnder( string expectedPath )

Modifiers

...IgnoreCase
...RespectCase

Examples of Use

Assert.That( "/folder1/./junk/../folder2", 
	Is.SamePathOrUnder( "/folder1/folder2" ) );
Assert.That( "/folder1/junk/../folder2/./folder3",
	Is.SamePathOrUnder( "/folder1/folder2" ) );
Assert.That( "/folder1/junk/folder2/folder3",
	Is.Not.SamePathOrUnder( "/folder1/folder2" ) );

Assert.That( @"C:\folder1\folder2\folder3",
	Is.SamePathOrUnder( @"C:\Folder1\Folder2" ).IgnoreCase );
Assert.That( "/folder1/folder2/folder3",
	Is.Not.SamePathOrUnder( "/Folder1/Folder2" ).RespectCase );
NUnit-2.6.0.12051/doc/index.html0000664000175000017500000000544511720512704015730 0ustar jtaylorjtaylor NUnit - DocHome

NUnit 2.6

This documentation covers the NUnit 2.6 release, introducing a large set of new features to NUnit, particularly in the area of parameterized or data-driven testing.

Where applicable, we have marked sections with the version in which a feature first appeared.

If you are new to NUnit, we suggest you begin by reading the Getting Started section of this site. Those who have used earlier releases may want to begin with the Upgrading section.

See the Release Notes for more information on this release.

All documentation is included in the release packages of NUnit. Beginning with NUnit 2.4.2, you may choose to download the documentation separately.

NUnit-2.6.0.12051/doc/assemblyIsolation.html0000664000175000017500000001130411720512704020311 0ustar jtaylorjtaylor NUnit - AssemblyIsolation

Assembly Isolation

NUnit isolates test assemblies from its own code and from one another by use of separate AppDomains and/or Processes.

By default, NUnit loads a test assembly into a separate AppDomain, while its own code runs in the primary AppDomain.

When multiple assemblies are run at the same time, NUnit loads them differently depending on how they were specified. For assemblies that are part of an NUnit project, then a single AppDomain is used. If the assemblies were specified on the console runner command line, then a separate AppDomain is used for each of them.

If greater separation is desired, test assemblies may be loaded into a separate Process or into multiple processes. This is done automatically by NUnit in the case where the tests are to be run under a different runtime from the one that NUnit is currently using. Tests running in a separate process are executed under the control of the nunit-agent program.

Controlling Isolation

Beyond the NUnit default behavior, the user may control the level of isolation through the command line or through NUnit's general settings. Process and AppDomain isolation may also be specified as part of the settings of an NUnit project.

Command Line

Assembly Isolation may be specified on the console runner commandline using the /process and /domain options. See NUnit-Console Command Line Options for more information.

General Settings

The built-in NUnit defaults may be overridden using the Assembly Isolation panel of the NUnit Settings Dialog. Settings made here are saved and become the new default values for all executions of NUnit until changed. For more info, see the Settings Dialog page.

Project Settings

Isolation settings may be specified for an individual NUnit project using the Project Editor.

NUnit-2.6.0.12051/doc/explicit.html0000664000175000017500000002020711720512704016433 0ustar jtaylorjtaylor NUnit - Explicit

ExplicitAttribute (NUnit 2.2)

The Explicit attribute causes a test or test fixture to be ignored unless it is explicitly selected for running. The test or fixture will be run if it is selected in the gui, if its name is specified on the console runner command line as the fixture to run or if it is included by use of a Category filter.

An optional string argument may be used to give the reason for marking the test Explicit.

If a test or fixture with the Explicit attribute is encountered in the course of running tests, it is skipped unless it has been specifically selected by one of the above means. The test does not affect the outcome of the run at all: it is not considered as ignored and is not even counted in the total number of tests. In the gui, the tree node for the test remains gray and the status bar color is not affected.

Note: In versions of NUnit prior to 2.4, these tests were shown as ignored.

Test Fixture Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture, Explicit]
  public class ExplicitTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Explicit()>
  Public Class ExplicitTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [Explicit]
  public __gc class ExplicitTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Explicit() */
public class ExplicitTests
{
  // ...
}

Test Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test, Explicit]
    public void ExplicitTest()
    { /* ... */ }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()>
  Public Class SuccessTests
    <Test(), Explicit()> Public Sub ExplicitTest()
      ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test][Explicit] void ExplicitTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Explicit() */
  public void ExplicitTest()
  { /* ... */ }
}
NUnit-2.6.0.12051/doc/equalConstraint.html0000664000175000017500000003136111720512704017771 0ustar jtaylorjtaylor NUnit - EqualConstraint

Equal Constraint (NUnit 2.4 / 2.5)

An EqualConstraint is used to test whether an actual value is equal to the expected value supplied in its constructor, optionally within a specified tolerance.

Constructor

EqualConstraint(object expected )

Syntax

Is.EqualTo( object expected )

Modifiers

...IgnoreCase
...AsCollection
...NoClip
...Within(object tolerance)
      .Ulps
      .Percent
      .Days
      .Hours
      .Minutes
      .Seconds
      .Milliseconds
      .Ticks
...Using(IEqualityComparer comparer)
...Using(IEqualityComparer<T> comparer)
...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Comparing Numerics

Numerics are compared based on their values. Different types may be compared successfully if their values are equal.

Using the Within modifier, numerics may be tested for equality within a fixed or percent tolerance.

Assert.That(2 + 2, Is.EqualTo(4.0));
Assert.That(2 + 2 == 4);
Assert.That(2 + 2, Is.Not.EqualTo(5));
Assert.That(2 + 2 != 5);
Assert.That( 5.0, Is.EqualTo( 5 );
Assert.That( 5.5, Is.EqualTo( 5 ).Within(0.075);
Assert.That( 5.5, Is.EqualTo( 5 ).Within(1.5).Percent;

Comparing Floating Point Values

Values of type float and double are normally compared using a tolerance specified by the Within modifier. The special values PositiveInfinity, NegativeInfinity and NaN compare as equal to themselves.

With version 2.5, floating-point values may be compared using a tolerance in "Units in the Last Place" or ULPs. For certain types of numerical work, this is safer than a fixed tolerance because it automatically compensates for the added inaccuracy of larger numbers.

Assert.That( 2.1 + 1.2, Is.EqualTo( 3.3 ).Within( .0005 );
Assert.That( double.PositiveInfinity, Is.EqualTo( double.PositiveInfinity ) );
Assert.That( double.NegativeInfinity, Is.EqualTo( double.NegativeInfinity ) );
Assert.That( double.NaN, Is.EqualTo( double.NaN ) );
Assert.That( 20000000000000004.0, Is.EqualTo(20000000000000000.0).Within(1).Ulps);

Comparing Strings

String comparisons normally respect case. The IgnoreCase modifier causes the comparison to be case-insensitive. It may also be used when comparing arrays or collections of strings.

Assert.That( "Hello!", Is.Not.EqualTo( "HELLO!" ) );
Assert.That( "Hello!", Is.EqualTo( "HELLO!" ).IgnoreCase );

string[] expected = new string[] { "Hello", World" };
string[] actual = new string[] { "HELLO", "world" };
Assert.That( actual, Is.EqualTo( expected ).IgnoreCase;

Comparing DateTimes and TimeSpans

DateTimes and TimeSpans may be compared either with or without a tolerance. A tolerance is specified using Within with either a TimeSpan as an argument or with a numeric value followed by a one of the time conversion modifiers: Days, Hours, Minutes, Seconds, Milliseconds or Ticks.

DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);

Assert.That( now, Is.EqualTo(now) );
Assert.That( later. Is.EqualTo(now).Within(TimeSpan.FromHours(3.0);
Assert.That( later, Is.EqualTo(now).Within(3).Hours;

Comparing Arrays and Collections

Since version 2.2, NUnit has been able to compare two single-dimensioned arrays. Beginning with version 2.4, multi-dimensioned arrays, nested arrays (arrays of arrays) and collections may be compared. With version 2.5, any IEnumerable is supported. Two arrays, collections or IEnumerables are considered equal if they have the the same dimensions and if each of the corresponding elements is equal.

If you want to treat two arrays of different shapes as simple collections for purposes of comparison, use the AsCollection modifier, which causes the comparison to be made element by element, without regard for the rank or dimensions of the array. Note that jagged arrays (arrays of arrays) do not have a single underlying collection. The modifier would be applied to each array separately, which has no effect in most cases.

int[] i3 = new int[] { 1, 2, 3 };
double[] d3 = new double[] { 1.0, 2.0, 3.0 };
int[] iunequal = new int[] { 1, 3, 2 };
Assert.That(i3, Is.EqualTo(d3));
Assert.That(i3, Is.Not.EqualTo(iunequal));

int array2x2 = new int[,] { { 1, 2 } { 3, 4 } };
int array4 = new int[] { 1, 2, 3, 4 };		
Assert.That( array2x2, Is.Not.EqualTo( array4 ) );
Assert.That( array2x2, Is.EqualTo( array4 ).AsCollection );

Comparing Dictionaries

Dictionaries implement ICollection, and NUnit has treated them as collections since version 2.4. However, this did not give useful results, since the dictionary entries had to be in the same order for the comparison to succeed and the underlying implementation had to be the same.

Beginning with NUnit 2.5.6, NUnit has specific code for comparing dictionaries. Two dictionaries are considered equal if

  1. The list of keys is the same - without regard to ordering.
  2. The values associated with each key are equal.

You can use this capability to compare any two objects implementing IDictionary. Generic and non-generic dictionaries (Hashtables) may be successfully compared.

User-Specified Comparers

If the default NUnit or .NET behavior for testing equality doesn't meet your needs, you can supply a comparer of your own through the Using modifier. When used with EqualConstraint, you may supply an IEqualityComparer, IEqualityComparer<T>, IComparer, IComparer<T>; or Comparison<T> as the argument to Using.

Assert.That( myObj1, Is.EqualTo( myObj2 ).Using( myComparer ) );

Prior to NUnit 2.6, only one comparer could be used. If multiple comparers were specified, all but one was ignored. Beginning with NUnit 2.6, multiple generic comparers for different types may be specified. NUnit will use the appropriate comparer for any two types being compared. As a result, it is now possible to provide a comparer for an array, a collection type or a dictionary. The user-provided comparer will be used directly, bypassing the default NUnit logic for array, collection or dictionary equality.

class ListOfIntComparer : IEqualityComparer<List<int>>
{
	...
}

var list1 = new List<int>();
var list2 = new List<int>();
var myComparer = new ListOfIntComparer();
...
Assert.That( list1, Is.EqualTo(list2).Using( myComparer ) );

Notes

  1. When checking the equality of user-defined classes, NUnit first examines each class to determine whether it implements IEquatable<T>. If either object implements the interface for the type of the other object, then that implementation is used in making the comparison. If neither class implements the appropriate interface, NUnit makes use of the Equals override on the expected object. If you neglect to either implement IEquatable<T> or to override Equals, you can expect failures comparing non-identical objects. In particular, overriding operator== without overriding Equals or implementing the interface has no effect.

  2. The Within modifier was originally designed for use with floating point values only. Beginning with NUnit 2.4, comparisons of DateTime values may use a TimeSpan as a tolerance. Beginning with NUnit 2.4.2, non-float numeric comparisons may also specify a tolerance.

  3. Beginning with NUnit 2.4.4, float and double comparisons for which no tolerance is specified use a default, use the value of GlobalSettings.DefaultFloatingPointTolerance. If this is not set, a tolerance of 0.0d is used.

  4. Prior to NUnit 2.2.3, comparison of two NaN values would always fail, as specified by IEEE floating point standards. The new behavior, was introduced after some discussion becuase it seems more useful in tests. To avoid confusion, consider using Is.NaN where appropriate.

  5. When an equality test between two strings fails, the relevant portion of of both strings is displayed in the error message, clipping the strings to fit the length of the line as needed. Beginning with 2.4.4, this behavior may be modified by use of the NoClip modifier on the constraint. In addition, the maximum line length may be modified for all tests by setting the value of TextMessageWriter.MaximumLineLength in the appropriate level of setup.

  6. When used with arrays, collections or dictionaries, EqualConstraint operates recursively. Any modifiers are saved and used as they apply to individual items.

  7. A user-specified comparer will not be called by EqualConstraint if either or both arguments are null. If both are null, the Constraint succeeds. If only one is null, it fails.

  8. NUnit has special semantics for comparing Streams and DirectoryInfos. For a Stream, the contents are compared. For a DirectoryInfo, the first-level directory contents are compared.

NUnit-2.6.0.12051/doc/pnunit.html0000664000175000017500000000776111720512704016141 0ustar jtaylorjtaylor NUnit - Pnunit

PNUnit

PNUnit stands for "Parallel NUnit." It is an extension of NUNit developed by Pablo Santos Luaces and his team at Codice Software for their internal use in testing the Plastic (TM) Software Configuration Management System. Codice released PNUnit to the community in 2007.

As part of the NUnit 2.5 release, we worked with the NUnit and PNUnit teams worked together to make PNUnit work with NUnit without any modifications. PNUnit is now included in the NUnit distribution.

How it Works

PNUnit is not intended for "casual" parallelism merely to make the tests run faster. Rather, it's intended as a way to test applications composed of distributed, communicating components. Tests of each component run in parallel and use memory barriers to synchronize their operation.

PNUnit uses a special executable to launch its tests. The launcher reads an xml file that specifies the tests to be executed and where they should run, whether on the same machine or on another machine on the network.

For more information about using PNUnit, consult the documentation at www.codicesoftware.com

Future Plans

PNUnit will be integrated with NUnit so that parallel, distributed tests may be used through the normal NUnit console or gui runners.

NUnit-2.6.0.12051/doc/configFiles.html0000664000175000017500000001326111720512704017044 0ustar jtaylorjtaylor NUnit - ConfigFiles

Configuration Files

NUnit uses configuration files for the test runner executable either nunit-console.exe or nunitgui.exe as well as for the tests being run. Only settings that pertain to NUnit itself should be in the nunit-console.exe.config and nunit-gui.exe.config, while those that pertain to your own application and tests should be in a separate configuration file.

NUnit Configuration Files

One main purpose of the nunit-console and nunit-gui config files is to allow NUnit to run with various versions of the .NET framework. NUnit is built using versions 1.1 and 2.0 of the framework. The two builds are provided as separate downloads and either build can be made to run against other versions of the CLR.

As delivered, the section of each config file is commented out, causing NUnit to run with the version of .NET used to build it. If you uncomment the section, the entries there control the order in which alternate framework versions are selected.

Test Configuration File

When a configuration file is used to provide settings or to control the environment in which a test is run, specific naming conventions must be followed.

If a single assembly is being loaded, then the configuration file is given the name of the assembly file with the config extension. For example, the configuration file used to run nunit.tests.dll must be named nunit.tests.dll.config and located in the same directory as the dll.

If an NUnit project is being loaded into a single AppDomain, the configuration file uses the name of the project file with the extension changed to config. For example, the project AllTests.nunit would require a configuration file named AllTests.config, located in the same directory as AllTests.nunit. The same rule is followed when loading Visual Studio projects or solutions.

Note: The above only applies if a single AppDomain is being used. If an NUnit project is loaded using a separate AppDomain for each assembly, then the individual configuration files for each of the assemblies are used.

Generally, you should be able to simply copy your application config file and rename it as described above.

In versions of NUnit prior to 2.6, it was possible to change the behavior of NUnit by adding special sections to the test config file. This feature is no longer supported.

The following recommendations are provided in the case of each of the settings that are no longer available:

OldStyleTestCases

NUnit no longer recognizes test methods without attributes.Use TestAttribute.

ApartmentState

We recommend the use of RequiresSTAAttribute or RequiresMTAAttribute on those test cases, test fixtures or setup fixtures that require a particular apartment. As a temporary measure, the nunit-console -apartment option may be used.

ThreadPriority

This is no longer supported.

DefaultLogThreshold

This is now controlled by a setting in the NUnit Gui runner.

NUnit-2.6.0.12051/doc/listMapper.html0000664000175000017500000001015211720512704016730 0ustar jtaylorjtaylor NUnit - ListMapper

List Mapper (NUnit 2.4.2)

Unlike Constraint classes, ListMapper is used to modify the actual value argument to Assert.That(). It transforms the actual value, which must be a collection, creating a new collection to be tested against the supplied constraint. Currently, ListMapper supports one transformation: creating a collection of property values.

Normally, ListMapper will be used through the List.Map() syntax helper or the inherited syntax equivalent, Map(). The following example shows three forms of the same assert:

string[] strings = new string[] { "a", "ab", "abc" };
int[] lengths = new int[] { 1, 2, 3 };

Assert.That(List.Map(strings).Property("Length"), 
       Is.EqualTo(lengths));
	   
Assert.That(new ListMapper(strings).Property("Length"),
       Is.EqualTo(lengths));

// Assuming inheritance from AssertionHelper
Expect(Map(strings).Property("Length"), EqualTo(lengths));
NUnit-2.6.0.12051/doc/installation.html0000664000175000017500000001036011720512704017312 0ustar jtaylorjtaylor NUnit - Installation

Installation

By default the NUnit installation program places all of the files into the C:\Program Files\NUnit 2.6 directory. In the installation directory there are up to three sub-directories, depending on what the user has chosen to install: bin, doc and samples. Source code is no longer provided with the binary installation package but may be downloaded separately.

Running NUnit

The installation program places a number of shortcuts in the start menu, which run NUnit under .NET or Mono, depending on what is installed on your system. For NUnit 2.5, the gui only runs under version 2.0 of the CLR, although tests may be executed under other versions using a separate process.

Installation Verification

NUnit's own tests are available as an installation option. If you installed the tests, you may verify that the installation has worked successfully by running the NUnit gui and loading and running NUnitTests.nunit. All tests should pass.

Additional Tests

Additional tests are included with the samples and in separate assemblies used as data by the verification tests themselves. Failures or not run conditions in these tests are intentional.

Manual Installation

You may build NUnit from source using one of the Visual Studio solutions or the NAnt script. In either case, an output directory is created, which contains all files needed in the proper relative location. Just copy this directory to a permanent location and create shortcuts if desired.

.NET 1.1 Support

NUnit's .NET 1.1 support is packaged as a separate download. It may be installed independently, in which case it provides only a restricted version of the console runner, or as part of the overall NUnit installation. When used together with the primary NUnit installation, it allows you to run .NET 1.1 tests under the Gui. For complete functionality, install in the same disk location used to install NUnit itself.

NUnit-2.6.0.12051/doc/testCase.html0000664000175000017500000001716411720512704016375 0ustar jtaylorjtaylor NUnit - TestCase

TestCaseAttribute (NUnit 2.5)

TestCaseAttribute serves the dual purpose of marking a method with parameters as a test method and providing inline data to be used when invoking that method. Here is an example of a test being run three times, with three different sets of data:

[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}

Note: Because arguments to .NET attributes are limited in terms of the Types that may be used, NUnit will make some attempt to convert the supplied values using Convert.ChangeType() before supplying it to the test.

TestCaseAttribute may appear one or more times on a test method, which may also carry other attributes providing test data, such as the FactoriesAttribute. The method may optionally be marked with the TestAttribute as well.

By using the named parameter Result this test set may be simplified further:

[TestCase(12,3, Result=4)]
[TestCase(12,2, Result=6)]
[TestCase(12,4, Result=3)]
public int DivideTest(int n, int d)
{
  return( n / d );
}

In the above example, NUnit checks that the return value of the method is equal to the expected result provided on the attribut

TestCaseAttribute supports a number of additional named parameters, which may be used as follows:

Description
Sets the description property of the test
ExpectedException
Specifies a the Type of an exception that should be thrown by this invocation
ExpectedExceptionName
Specifies a the FullName of an exception that should be thrown by this invocation
ExpectedMessage
Specifies the message text of the expected exception
Explicit
Set to true in order to make the individual test case Explicit. Use Reason to explain why.
Ignore
Set to true in order to ignore the individual test case. Use Reason to explain why.
IgnoreReason
Causes this test case to be ignored and specifies the reason. Equivalent to Ignore combined with Reason. This attribute will be removed in a later release.
MatchType
A MessageMatch enum value indicating how to test the expected message (See ExpectedExceptionAttribute)
Reason
Specifies the reason for not running this test case. Use in conjunction with Ignore or Explicit.
Result
The expected result to be returned from the method, which must have a compatible return type.
TestName
Provides a name for the test. If not specified, a name is generated based on the method name and the arguments provided.

Order of Execution

In NUnit 2.5, individual test cases are sorted alphabetically and executed in that order. Beginning with NUnit 2.5.1, the individual cases are not sorted, but are executed in the order in which NUnit discovers them. This order does not follow the lexical order of the attributes and will often vary between different compilers or different versions of the CLR.

As a result, when TestCaseAttribute appears multiple times on a method or when other data-providing attributes are used in combination with TestCaseAttribute, the order of the test cases is undefined.

NUnit-2.6.0.12051/doc/setupFixture.html0000664000175000017500000001613611720512704017327 0ustar jtaylorjtaylor NUnit - SetupFixture

SetUpFixtureAttribute (NUnit 2.4)

This is the attribute that marks a class that contains the one-time setup or teardown methods for all the test fixtures under a given namespace. The class may contain at most one method marked with the SetUpAttribute and one method marked with the TearDownAttribute.

There are a few restrictions on a class that is used as a setup fixture.

  • It must be a publicly exported type or NUnit will not see it.
  • It must have a default constructor or NUnit will not be able to construct it.

The SetUp method in a SetUpFixture is executed once before any of the fixtures contained in its namespace. The TearDown method is executed once after all the fixtures have completed execution. In the examples below, the method RunBeforeAnyTests() is called before any tests or setup methods in the NUnit.Tests namespace. The method RunAfterAnyTests() is called after all the tests in the namespace as well as their individual or fixture teardowns have completed exection.

Only one SetUpFixture should be created in a given namespace. A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [SetUpFixture]
  public class MySetUpClass
  {
    [SetUp]
	RunBeforeAnyTests()
	{
	  // ...
	}

    [TearDown]
	RunAfterAnyTests()
	{
	  // ...
	}
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class MySetUpClass
    <SetUp()> Public Sub RunBeforeAnyTests()
	  ' ...
	End Sub
	
	<TearDown()> Public Sub RunAfterAnyTests()
	  ' ...
	End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class MySetUpClass
  {
    [SetUp] public void RunBeforeAnyTests();
	[TearDown] public void RunAfterAnyTests();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class MySetUpClass
{
  /** @attribute NUnit.Framework.SetUp() */
  public void RunBeforeAnyTests()
  { /* ... */ }

  /** @attribute NUnit.Framework.TearDown() */
  public void RunAfterAnyTests()
  { /* ... */ }
}
NUnit-2.6.0.12051/doc/nunit.css0000664000175000017500000001501311713252032015567 0ustar jtaylorjtaylor/* HTML Elements */ html, body { margin: 0; padding: 0; } body { font: 90% "Verdana", "Arial", "Helvetica", sans-serif; } img { border: none; padding: 0; margin: 0;} table { font: 1em "Verdana", "Arial", "Helvetica", sans-serif; } h1 { font-size: 1.8em; font-weight: bold; } h2 { font-size: 1.5em; font-weight: bold; } h3 { font-size: 1.2em; font-weight: bold; } h4 { font-size: 1em; font-weight: bold; } ul.across { width: 100%; display: block; list-style: none; } ul.across li { float: left; display: block; width: 9em } /* Masthead and Main Menu */ #header { margin: 0; padding: 0; width: 100%; } #header img { border: none; padding: 0; margin: 0;} #header #logo { margin: 0; padding: 0; position: absolute; top: 15px; left: 15px} #header #nav { min-width: 670px; margin: 25px 0 10px 200px; padding: 15px 0 15px 5px; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; white-space: nowrap; } /* Hide from IE-mac \*/ * html #nav { height: 1%; } /* End of IE-mac hack */ #nav a{ text-decoration: none; color: #000; font: small "Times New Roman", Roman, serif; text-transform: uppercase; margin: 0 5px; padding: 5px 10px; border: 1px solid black; } #nav a.active { background: #999; } #nav a:hover { background: #CCC; } /* Submenu */ #subnav { position: absolute; top: 100px; left: 76%; background-color: #ffd; width: 24%; margin: 1em 0 0; padding: .25em ; border: solid #ccc; border-width: .1em 0 .1em .1em; } #subnav ul { margin: 0; padding: 0; list-style: none; } #subnav li{ margin: 0; padding: 2px 0 2px; } #subnav a { font: 1em "Times New Roman", Roman, serif; margin: 0; padding: 0 0 0 26px; text-transform: uppercase; text-decoration: none; color: #000; white-space: nowrap; background: url(img/bulletOff.gif) no-repeat 10px 50%; display: block} #subnav ul ul a { padding: 0 0 0 46px; background-position: 30px 50%; } #subnav ul ul ul a { padding: 0 0 0 66px; background-position: 50px 50%; } #subnav ul ul ul ul a { padding: 0 0 0 86px; background-position: 70px 50%; } #subnav ul ul ul ul ul a { padding: 0 0 0 106px; background-position: 90px 50%; } #subnav li#current a{ background-image: url(img/bulletOn.gif) } #subnav li a:hover { background-image: url(img/bulletOn.gif) } /* Main Content */ #content { margin: 3em 25% 10px 0; padding: 0 5% 1em 5%; } #content.wide { margin: 3em 5% 0 5%; padding: 0 5% 1em 5%; } #content p { padding: 0; margin: 0 0 1em 0; max-width: 660px; } #content ul { max-width: 660px; } #content ol { max-width: 660px; } #content blockquote { max-width: 580px } #content div.screenshot { text-align: center; margin: 1em 0; } #content div.screenshot-right { text-align: center; float: right; margin: 0 0 0 1em; } #content img { padding: 0; margin: 0; border: 0 } /* Page Footer */ #footer { text-align: center; font-size: .8em; color: #444; clear: both; border-top: 2px solid #999; margin: 0 30% 10px 5%; padding: 5px 0 0 0; page-break-after: always } #sig { text-align: right; font-size: .8em; width: 95%; display: none } table.nunit { margin: 1em 5%; padding: 0; width: auto; border-collapse: collapse; } table.nunit td, table.nunit th { border: 1px solid black; padding: 6px; text-align: left } table.nunit th { background: #ccf; font-weight: bold; } table.articles { margin: 20px 0 0 5%; padding: 0 10px 0 0; } table.downloads { margin: 1em 5%; padding: 0; width: 24em; border-collapse: collapse; } table.downloads td, table.downloads th { border: 1px solid black; padding: 2px; text-align: left } table.downloads th { background: #ccf; font-weight: bold; } table.platforms { margin: 1em 0; padding: 0; width: 24em; border-collapse: collapse; } table.platforms td, table.platforms th { border: 1px solid black; padding: 5px; text-align: center } table.platforms th { background: #ccf; font-weight: bold; } table.constraints { margin: 1em 0; padding: 0; width: auto; border-collapse: collapse; } table.constraints td, table.constraints th { border: 1px solid black; padding: 6px; text-align: left } table.constraints th { background: #ccf; font-weight: bold; text-align: center } table.roadmap { margin: 1em 0; padding: 0; width: auto; border-collapse: collapse; } table.roadmap td, table.roadmap th { border: 1px solid black; padding: 10px; text-align: left } table.roadmap th { background: #eef; font-weight: bold; } table.extensions { margin: 1em 2%; border-collapse: collapse; width: 96%; } table.extensions td, table.extensions th { border: solid black 1px; padding: 6px } table.extensions th { background: #bbf; font-weight: bold; text-align: center } table.extensions td.label { font-weight: bold; text-align: left; width: 10em } table.quote { margin-left: 30px; margin-right: 30px; background: #FFFFFF; border: 3px black solid; font: 1.1em/1.5em "Times New Roman", Roman, serif; font-variant: small-caps; letter-spacing: .1em; padding: 0 } table.quote td { padding: 0 } table.quote td.sig { border-left: solid black 1px; padding-left: 15px } #news { position: absolute; top: 100px; left: 76%; border-left: 1px solid black; width: 14%; margin: 1em 0 0; padding: 0 5%; font-size: .8em; background-color: #fff } #news h4 { font: 1.2em "Times New Roman", Roman, serif; font-variant: small-caps; text-align: center; margin: 0 0 1em; } div.code { border: 1px solid #888; background-color: #ccf; width: 36em; margin: 1.5em 0; padding: 2px 0; position: relative; } div.code pre { font: .8em "Courier New", Courier, monospace; margin: 0 1em .25em; } div.langFilter { position: absolute; top: 100px; left: 5%; } div.code div.langFilter { position: absolute; top: -15px; left: 0;} div.dropdown { position: absolute; top: 0; left: 14px; padding: 0 10px; width: 20px; text-align: left; border: 1px solid #888; background-color: #ffd; } div.code div.dropdown { position: absolute; left: 14px; top: 0; padding: 0 10px; width: 20px; text-align: left; border: 1px solid #888; background-color: #ffd; } div.notice { margin-left: 2em; margin-right: 2em; text-align: center; font-style: italic; font-weight: bold; } /* #content.wide p { width: expression( document.documentElement.clientWidth > 700 ? "660px" : "auto" ); } #content.wide blockquote { width: expression( document.documentElement.clientWidth > 700 ? "580px" : "auto" ); } pre, .programText { font-family: "Courier New", Courier, Monospace; color: #000; font-size: 1em } // The following was needed for IE in quirks mode - probably still needed for IE 5 div.code div.langFilter { position: absolute; top: -14px; left: -1em; } // Special handling for absence of max-width in IE */ NUnit-2.6.0.12051/doc/testDecorators.html0000664000175000017500000000751111720512704017622 0ustar jtaylorjtaylor NUnit - TestDecorators

TestDecorators (NUnit 2.4)

Purpose

TestDecorators are able to modify a test after it has been constructed.

Extension Point

Addins use the host to access this extension point by name:

	IExtensionPoint testDecorators = host.GetExtensionPoint( "TestDecorators" );

Interface

The extension object passed to Install must implement the ITestDecorator interface:

	public interface ITestDecorator
	{
		Test Decorate( Test test, MemberInfo member );
	}

The Decorate method may do several things, depending on what it needs to accomplish:

  1. Return test unmodified
  2. Modify properties of the test object and return it
  3. Replace test with another object, either discarding the original or aggregating it in the new test.

Depending on what the decorator does, it may need to run ahead of other decorators or after them. Decorators should be installed using the Install method overload that takes a priority. The priorities range from 1 to 9 and decorators with lower priority values are installed first. The following standard values are defined for use if desired:

  • DecoratorPriority.Default = 0
  • DecoratorPriority.First = 1
  • DecoratorPriority.Normal = 5
  • DecoratorPriority.Last = 9
NUnit-2.6.0.12051/doc/fixtureSetup.html0000664000175000017500000002011311720512704017315 0ustar jtaylorjtaylor NUnit - FixtureSetup

TestFixtureSetUpAttribute (NUnit 2.1 / 2.5)

This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture.

Before NUnit 2.5, a TestFixture could have only one TestFixtureSetUp method and it was required to be an instance method.

Beginning with NUnit 2.5, TestFixtureSetUp methods may be either static or instance methods and you may define more than one of them in a fixture. Normally, multiple TestFixtureSetUp methods are only defined at different levels of an inheritance hierarchy, as explained below.

If a TestFixtueSetUp method fails or throws an exception, none of the tests in the fixure are executed and a failure or error is reported.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [TestFixtureSetUp] public void Init()
    { /* ... */ }

    [TestFixtureTearDown] public void Cleanup()
    { /* ... */ }

    [Test] public void Add()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <TestFixtureSetUp()> Public Sub Init()
    ' ...
    End Sub

    <TestFixtureTearDown()> Public Sub Cleanup()
    ' ...
    End Sub

    <Test()> Public Sub Add()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [TestFixtureSetUp] void Init();
    [TestFixtureTearDown] void Cleanup();

    [Test] void Add();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.TestFixtureSetUp() */
  public void Init()
  { /* ... */ }

  /** @attribute NUnit.Framework.TestFixtureTearDown() */
  public void Cleanup()
  { /* ... */ }

  /** @attribute NUnit.Framework.Test() */
  public void Add()
  { /* ... */ }
}

Inheritance

The TestFixtureSetUp attribute is inherited from any base class. Therefore, if a base class has defined a SetFixtureSetUp method, that method will be called after each test method in the derived class.

Before NUnit 2.5, you were permitted only one TestFixtureSetUp method. If you wanted to have some TestFixtureSetUp functionality in the base class and add more in the derived class you needed to call the base class method yourself.

With NUnit 2.5, you can achieve the same result by defining a TestFixtureSetUp method in the base class and another in the derived class. NUnit will call base class TestFixtureSetUp methods before those in the derived classes.

Note: Although it is possible to define multiple TestFixtureSetUp methods in the same class, you should rarely do so. Unlike methods defined in separate classes in the inheritance hierarchy, the order in which they are executed is not guaranteed.

See also...

NUnit-2.6.0.12051/doc/typeConstraints.html0000664000175000017500000001050111720512704020017 0ustar jtaylorjtaylor NUnit - TypeConstraints

Type Constraints (NUnit 2.4)

Type constraints perform tests that are specific to Types. The following type constraints are provided:
Syntax HelperConstructorOperation
Is.TypeOf( Type )ExactTypeConstraint( Type )tests that an object is an exact Type
Is.InstanceOfType( Type )InstanceOfTypeConstraint( Type )tests that an object is an instance of a Type
Is.AssignableFrom( Type )AssignableFromConstraint( Type )tests that one type is assignable from another

Examples of Use

Assert.That("Hello", Is.TypeOf(typeof(string)));
Assert.That("Hello", Is.Not.TypeOf(typeof(int)));

Assert.That("Hello", Is.InstanceOfType(typeof(string)));
Assert.That(5, Is.Not.InstanceOfType(typeof(string)));

Assert.That( "Hello", Is.AssignableFrom(typeof(string)));
Assert.That( 5, Is.Not.AssignableFrom(typeof(string)));

// Using inheritance
Expect( 5, Not.InstanceOfType(typeof(string)));
Expect( "Hello", AssignableFrom(typeOf(string)));
NUnit-2.6.0.12051/doc/description.html0000664000175000017500000001523011720512704017135 0ustar jtaylorjtaylor NUnit - Description

Description (NUnit 2.4)

The Description attribute is used to apply descriptive text to a Test, TestFixture or Assembly. The text appears in the XML output file and is shown in the Test Properties dialog.

Example:

[assembly: Description("Assembly description here")]

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture, Description("Fixture description here")]
  public class SomeTests
  {
    [Test, Description("Test description here")] 
    public void OneTest()
    { /* ... */ }
  }
}
<assembly: Description("Assembly description here")>

Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Description("Fixture description here")>_
  Public Class SomeTests
    <Test(), Description("Test description here")>_
    Public Sub OneTest()
    ' ...
    End Sub
  End Class
End Namespace
[assembly:Description("Assembly description here")]

#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture, Description("Fixture description here")]
  public __gc class SomeTests
  {
    [Test, Description("Test description here")]
    void OneTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
/** @assembly NUnit.Framework.Description("Assembly description here") */

package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Description("Fixture description here") */
public class SomeTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Description("Test description here") */
  public void OneTest()
  { /* ... */ }
}

Note: The Test and TestFixture attributes continue to support an optional Description property. The Description attribute should be used for new applciations. If both are used, the Description attribute takes precedence.

NUnit-2.6.0.12051/doc/exception.html0000664000175000017500000002561511720512704016620 0ustar jtaylorjtaylor NUnit - Exception

ExpectedExceptionAttribute (NUnit 2.0 plus Updates)

This is the way to specify that the execution of a test will throw an exception. This attribute has a number of positional and named parameters, which we will discuss in separate sections according to the purpose they serve.

Specifying the Expected Exception Type

The original attribute, introduced with NUnit 2.0 took a single argument giving the exact type of the expected exception. For example...

[ExpectedException( typeof( ArgumentException ) )]
public void TestMethod()
{
...

Beginning with NUnit 2.2.4, it became possible to specify the type of exception as a string, avoiding the need for a reference to the defining assembly...

[ExpectedException( "System.ArgumentException" ) )]
public void TestMethod()
{
...

The above two examples function identically: the test only succeeds if a System.Argument exception is thrown.

Specifying the Expected Message

NUnit 2.1 introduced a constructor with a second argument, specifying the exact text of the message property of the exception. After NUnit 2.2.4, the same extension was made to the constructor taking a string argument. With NUnit 2.4, these arguments are marked obsolete, and a named parameter is provided instead...

// Obsolete form:
[ExpectedException( typeof( ArgumentException ), "expected message" )]
[ExpectedException( "System.ArgumentException", "expected message" )]

// Prefered form:
[ExpectedException( typeof( ArgumentException ), ExpectedMessage="expected message" )]
[ExpectedException( "System.ArgumentException", ExpectedMessage="expected message" )]

With NUnit 2.4, it is possible to specify additional tests on the exception message, beyond a simple exact match. This is done using the MatchType named parameter, whose argument is an enumeration, defined as follows:

public enum MessageMatch
{
    /// Expect an exact match
    Exact,	
    /// Expect a message containing the parameter string
    Contains,
    /// Match the regular expression provided as a parameter
    Regex,
    /// Expect a message starting with the parameter string
    StartsWith
}

The following example is for a test that passes only if an ArgumentException with a message containing "unspecified" is received.

[ExpectedException( typeof( ArgumentException), ExpectedMessage="unspecified", MatchType=MessageMatch.Contains )]
public void TestMethod()
{
...

If MatchType is not specified, an exact match is used as before.

Specifying a Custom Error Message

With NUnit 2.4, it is possible to specify a custom message to be displayed if the ExpectedException attribute is not satisfied. This is done through the UserMessage named parameter...

[ExpectedException( typeof( ArgumentException ), UserMessage="Custom message" )]
public void TestMethod()
{
...

Handling the Exception in Code

If the processing required for an exception is too complex to express in the attribute declaration, the normal practice is to process it in the test code using a try/catch block. As an alternative, NUnit 2.4 allows designating a method that will be called to process the exception. This is particularly useful when multiple exceptions need to be processed in the same way.

An common exception handler may be designated by implementing the IExpectExceptionInterface, which is defined as follows...

public interface IExpectException
{
    void HandleException( System.Exception ex );
}

The exception handler is only called for methods marked with the ExpectedException attribute. If all checks - including the type of the exception - are to be performed in code, the attribute may be specified without any arguments in order to indicate that an exception is expected.

An handler may be designated for a particular method using the Handler named parameter.

[ExpectedException( Handler="HandlerMethod" )]
public void TestMethod()
{
...
}

public void HandlerMethod( System.Exception ex )
{
...
}

This technique may be used without implementing IExpectException or in combination with it. In the latter case, the designated handler applies to any method that specifies it, while the normal exception handler applies to any other methods that specify an ExpectedException.

However it is specified, the handler method should examine the exception and Assert on whatever properties are relevant. Any resulting failure message will then be consistent in format with other assertions performed in the tests.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [ExpectedException(typeof(InvalidOperationException))]
    public void ExpectAnExceptionByType()
    { /* ... */ }

    [Test]
    [ExpectedException("System.InvalidOperationException")]
    public void ExpectAnExceptionByName()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <Test(), ExpectedException(GetType(Exception))>
      Public Sub ExpectAnExceptionByType()
    ' ...
    End Sub

  <TestFixture()> Public Class SuccessTests
    <Test(), ExpectedException("System.Exception")>
      Public Sub ExpectAnExceptionByName()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test]
    [ExpectedException(__typeof(InvalidOperationException))]
    void ExpectAnExceptionByType();

    [Test]
    [ExpectedException(S"SystemInvalidOperationException")]
    void ExpectAnExceptionByName();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
NUnit-2.6.0.12051/doc/typeAsserts.html0000664000175000017500000001230411720512704017137 0ustar jtaylorjtaylor NUnit - TypeAsserts

Type Asserts (NUnit 2.2.3 / 2.5)

These methods allow us to make assertions about the type of an object.


Assert.IsInstanceOfType( Type expected, object actual );
Assert.IsInstanceOfType( Type expected, object actual, 
                string message );
Assert.IsInstanceOfType( Type expected, object actual, 
                string message, params object[] parms );
				
Assert.IsNotInstanceOfType( Type expected, object actual );
Assert.IsNotInstanceOfType( Type expected, object actual, 
                string message );
Assert.IsNotInstanceOfType( Type expected, object actual, 
                string message, params object[] parms );
			
Assert.IsAssignableFrom( Type expected, object actual );
Assert.IsAssignableFrom( Type expected, object actual, 
                string message );
Assert.IsAssignableFrom( Type expected, object actual, 
                string message, params object[] parms );
				
Assert.IsNotAssignableFrom( Type expected, object actual );
Assert.IsNotAssignableFrom( Type expected, object actual, 
                string message );
Assert.IsNotAssignableFrom( Type expected, object actual, 
                string message, params object[] parms );
				
Beginning with NUnit 2.5, generic equivalents are available in .NET 2.0 NUnit packages.

Assert.IsInstanceOf<T>( object actual );
Assert.IsInstanceOf<T>( object actual, string message );
Assert.IsInstanceOf<T>( object actual, 
                string message, params object[] parms );
				
Assert.IsNotInstanceOf<T>( object actual );
Assert.IsNotInstanceOf<T>( object actual, string message ); 
Assert.IsNotInstanceOf<T>( object actual, 
                string message, params object[] parms );
			
Assert.IsAssignableFrom<T>( object actual );
Assert.IsAssignableFrom<T>( object actual, string message );
Assert.IsAssignableFrom<T>( object actual, 
                string message, params object[] parms );
				
Assert.IsNotAssignableFrom<T>( object actual );
Assert.IsNotAssignableFrom<T>( object actual, string message );
Assert.IsNotAssignableFrom<T>( object actual, 
                string message, params object[] parms );
				
NUnit-2.6.0.12051/doc/testcaseBuilders.html0000664000175000017500000000761711720512704020131 0ustar jtaylorjtaylor NUnit - TestcaseBuilders

TestCaseBuilders (NUnit 2.4)

Purpose

TestCaseBuilders create Tests based on a MethodInfo. NUnit uses several TestCaseBuilders internally to create various kinds of TestMethods.

Extension Point

Addins use the host to access this extension point by name:
	IExtensionPoint testCaseBuilders = host.GetExtensionPoint( "TestCaseBuilders" );

Interfaces

The extension object passed to Install must implement either the ITestCaseBuilder or the ITestCaseBuilder2 interface:

	public interface ITestCaseBuilder
	{
		bool CanBuildFrom( MethodInfo method );
		Test BuildFrom( MethodInfo method );
	}

	public interface ITestCaseBuilder2 : ITestCaseBuilder
	{
		bool CanBuildFrom( MethodInfo method, Test suite );
		Test BuildFrom( MethodInfo method, Test suite );
	}

NUnit will call ITestCaseBuilder2 if it is available. Otherwise ITestCaseBuilder will be used.

The CanBuildFrom method should return true if the addin can build a test from the MethodInfo provided. Some TestCaseBuilder addins are only intended to apply to methods within a specific type of fixture. The suite argument of the ITestCaseBuilder2 interface may be used to make this determination.

The BuildFrom method should return a test constructed over the MethodInfo provided as an argument or null if the method cannot be used.

NUnit-2.6.0.12051/doc/nunit-gui.html0000664000175000017500000001452511720512704016537 0ustar jtaylorjtaylor NUnit - Nunit-gui

NUnit Gui Runner

The nunit.exe program is a graphical runner. It shows the tests in an explorer-like browser window and provides a visual indication of the success or failure of the tests. It allows you to selectively run single tests or suites and reloads automatically as you modify and re-compile your code. The following is a screenshot of NUnit running the same mock-assembly.dll shown in the nunit-console example.

Tree Display

This version of NUnit uses symbols in the test tree, which allow those who are unable to easily distinguish colors to determine the test status. Successful tests are colored green, with a check mark. Tests that are ignored are marked with a yellow circle, containing a question mark. If any tests had failed, they would be marked red, with an X symbol.

In this example, there were a total of 11 test cases, but one of them was not counted because it was marked Explicit. Note that it is shown as a gray circle in the tree. Of the remaining 10 tests, 5 were run successfully and 5 were ignored.

The symbols shown in the tree are actually files in the NUnit bin directory. These files are named Success.jpg, Failure.jpg and Ignored.jpg and may be modified or replaced by the user.

Note: Beginning with NUnit 2.6, tests marked with the IgnoreAttribtute are shown in yellow immediately upon loading. Similarly, non-runnable tests (e.g.: wrong argument type) are shown in red at load time.

Progress Bar

The progress bar shows the progress of the test. It is colored according to the "worst" result obtained: red if there were any failures, yellow if some tests were ignored and green for success.

Result Summary

At the end of the test run, a summary of the results is displayed immediately below the progress bar. If the result information does not fit in the space available, hovering over it shows the full information.

Result Tabs

The tabs along the bottom of the display show the results of running a test. The Errors and Failures tab displays the error message and stack trace for both unexpected exceptions and assertion failures. Beginning with NUnit 2.5, source code for each stack location can be displayed in this tab - as is seen above - provided that the program was compiled with debug information.

The Tests Not Run tab provides a list of all tests that were selected for running but were not run, together with the reason.

The Text Output tab displays text output from the tests, potentially including console output, trace output and log output. The default display provides a single tab, but additional tabs may be created by the user to hold specific kinds of output. For more information on creating new tabs, see the documentation for the Settings Dialog.

Mini-Gui

Since the release of NUnit 2.4, an alternate "mini-gui" is also available. It may be selected from the View menu. In the following screenshot, the mini gui window has been positioned next to the Visual Studio IDE so that both windows can be seen.

NUnit-2.6.0.12051/doc/throwsConstraint.html0000664000175000017500000001433011720512704020205 0ustar jtaylorjtaylor NUnit - ThrowsConstraint

Throws Constraint (NUnit 2.5)

ThrowsConstraint is used to test that some code, represented as a delegate, throws a particular exception. It may be used alone, to merely test the type of constraint, or with an additional constraint to be applied to the exception specified as an argument. p>The related ThrowsNothingConstraint simply asserts that the delegate does not throw an exception.

Constructors

ThrowsConstraint(Type expectedType)
ThrowsConstraint<T>()
ThrowsConstraint(Type expectedType, Constraint constraint)
ThrowsConstraint<T>(Constraint constraint)
ThrowsNothingConstraint()

Syntax

Throws.Exception
Throws.TargetInvocationException
Throws.ArgumentException
Throws.InvalidOperationException
Throws.TypeOf(Type expectedType)
Throws.TypeOf<T>()
Throws.InstanceOf(Type expectedType)
Throws.InstanceOf<T>()
Throws.Nothing
Throws.InnerException

Examples of Use

// .NET 1.1
Assert.That( new TestDelegate(SomeMethod),
  Throws.TypeOf(typeof(ArgumentException)));
Assert.That( new TestDelegate(SomeMethod),
  Throws.Exception.TypeOf(typeof(ArgumentException)));
Assert.That( new TestDelegate(SomeMethod),
  Throws.TypeOf(typeof(ArgumentException))
    .With.Property("Parameter").EqualTo("myParam"));
Assert.That( new TestDelegate(SomeMethod),
  Throws.ArgumentException );
Assert.That( new TestDelegate(SomeMethod), 
  Throws.TargetInvocationException
    .With.InnerException.TypeOf(ArgumentException));
	
// .NET 2.0
Assert.That( SomeMethod, 
  Throws.TypeOf<ArgumentException>());
Assert.That( SomeMethod, 
  Throws.Exception.TypeOf<ArgumentException>());
Assert.That( SomeMethod, 
  Throws.TypeOf<ArgumentException>()
    .With.Property("Parameter").EqualTo("myParam"));
Assert.That( SomeMethod, Throws.ArgumentException );
Assert.That( SomeMethod, 
  Throws.TargetInvocationException
    .With.InnerException.TypeOf<ArgumentException>());

Notes

  1. Throws.Exception may be followed by further constraints, which are applied to the exception itself as shown in the last two examples above. It may also be used alone to verify that some exception has been thrown, without regard to type. This is not a recommended practice since you should normally know what exception you are expecting.
  2. Throws.TypeOf and Throws.InstanceOf are provided as a shorter syntax for this common test. They work exactly like the corresponding forms following Throws.Exception.
  3. Throws.TargetInvocationException/b>, Throws.ArgumentException and Throws.InvalidOperationException provide a shortened form for some common exceptions.
  4. Used alone, Throws.InnerException simply tests the InnerException value of the thrown exception. More commonly, it will be used in combination with a test for the type of the outer exception as shown in the examples above.
NUnit-2.6.0.12051/doc/combinatorial.html0000664000175000017500000001145011720512704017435 0ustar jtaylorjtaylor NUnit - Combinatorial

CombinatorialAttribute (NUnit 2.5)

The CombinatorialAttribute is used on a test to specify that NUnit should generate test cases for all possible combinations of the individual data items provided for the parameters of a test. Since this is the default, use of this attribute is optional.

Example

The following test will be executed six times, as follows:

	MyTest(1, "A")
	MyTest(1, "B")
	MyTest(2, "A")
	MyTest(2, "B")
	MyTest(3, "A")
	MyTest(3, "B")
[Test, Combinatorial]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    ...
}

See also...

NUnit-2.6.0.12051/doc/platform.html0000664000175000017500000002257311720512704016446 0ustar jtaylorjtaylor NUnit - Platform

PlatformAttribute (NUnit 2.2.2)

The Platform attribute is used to specify platforms for which a test or fixture should be run. Platforms are specified using case-insensitive string values and may be either included or excluded from the run by use of the Include or Exclude properties respectively. Platforms to be included may alternatively be specified as an argument to the PlatformAttribute constructor. In either case, multiple comma-separated values may be specified.

If a test or fixture with the Platform attribute does not satisfy the specified platform requirements it is skipped. The test does not affect the outcome of the run at all: it is not considered as ignored and is not even counted in the total number of tests. In the gui, the tree node for the test remains gray and the status bar color is not affected.

Note: In versions of NUnit prior to 2.4, these tests were shown as ignored.

Test Fixture Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [Platform("NET-2.0")]
  public class DotNetTwoTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Platform("NET-2.0")>
  Public Class DotNetTwoTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [Platform("NET-2.0")]
  public __gc class DotNetTwoTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Platform("NET-2.0") */
public class DotNetTwoTests
{
  // ...
}

Test Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [Platform(Exclude="Win98,WinME")]
    public void SomeTest()
    { /* ... */ }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()>
  Public Class SuccessTests
    <Test(), Platform(Exclude="Win98,WinME")> Public Sub SomeTest()
      ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test][Platform(Exclude="Win98,WinME")] void SomeTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Platform(Exclude="Win98,WinME") */
  public void SomeTest()
  { /* ... */ }
}

Platform Specifiers

The following values are recognized as platform specifiers. They may be expressed in upper, lower or mixed case.

  • Win
  • Win32
  • Win32S
  • Win32Windows
  • Win32NT
  • WinCE
  • Win95
  • Win98
  • WinMe
  • NT3
  • NT4
  • NT5
  • NT6
  • Win2K
  • WinXP
  • Win2003Server
  • Vista
  • Win2008Server
  • Win2008ServerR2
  • Windows7
  • Win2012Server
  • Windows8
  • Unix
  • Linux
  • Net
  • Net-1.0
  • Net-1.1
  • Net-2.0
  • Net-3.0 (1)
  • Net-3.5 (2)
  • Net-4.0
  • NetCF
  • SSCLI
  • Rotor
  • Mono
  • Mono-1.0
  • Mono-2.0
  • Mono-3.0 (3)
  • Mono-3.5 (4)

Notes:

  1. Includes Net-2.0
  2. Includes Net-2.0 and Net-3.0
  3. Includes Mono-2.0
  4. Includes Mono-2.0 and Mono-3.0
NUnit-2.6.0.12051/doc/getStarted.html0000664000175000017500000000610211720512704016716 0ustar jtaylorjtaylor NUnit - GetStarted

Getting Started with NUnit

If you haven't already done so, go to our Download page, select a version of NUnit and download it. The Installation page contains instructions for installing on your system.

To get started using NUnit, read the Quick Start page. This article demonstrates the development process with NUnit in the context of a C# banking application. Check the Samples page for additional examples, including some in VB.Net, J# and managed C++.

Which Test Runner to use?

NUnit has two different ways to run your tests. The console runner, nunit-console.exe, is the fastest to launch, but is not interactive. The gui runner, nunit.exe, is a Windows Forms application that allows you to work selectively with your tests and provides graphical feedback.

NUnit-2.6.0.12051/doc/requiresSTA.html0000664000175000017500000001262311720512704017024 0ustar jtaylorjtaylor NUnit - RequiresSTA

RequiresSTAAttribute (NUnit 2.5)

The RequiresSTAAttribute is used on a test method, class or assembly to specify that the tests should be run in the Single-threaded apartment. It causes creation of a new thread if the parent test is not already running in the STA.

Note: On test methods, you may also use the STAThreadAttribute. Although the runtime only recognizes this attribute on the entrypoint of an executable assembly, many users have expected it to work on tests, so we treat it as a synonym.

Examples


// An STA thread will be created and used to run
// all the tests in the assembly
[assembly:RequiresSTA]

...

// TestFixture requiring a separate thread
[TestFixture, RequiresSTA]
public class FixtureRequiringSTA
{
  // An STA thread will be created and all
  // tests in the fixture will run on it
  // unless the containing assembly is
  // already running on an STA Thread
}

[TestFixture]
public class AnotherFixture
{
  [Test, RequiresSTA]
  public void TestRequiringSTA()
  {
    // A separate thread will be created for this test
	// unless the containing fixture is already running 
	// in the STA.
  }
}

See also...

NUnit-2.6.0.12051/doc/utilityAsserts.html0000664000175000017500000001266311720512704017671 0ustar jtaylorjtaylor NUnit - UtilityAsserts

Utility Methods

Four utility methods, Pass(), Fail(), Ignore() and Inconclusive() are provided in order to allow more direct control of the test process:

Assert.Pass();
Assert.Pass( string message );
Assert.Pass( string message, object[] parms );

Assert.Fail();
Assert.Fail( string message );
Assert.Fail( string message, object[] parms );

Assert.Ignore();
Assert.Ignore( string message );
Assert.Ignore( string message, object[] parms );

Assert.Inconclusive();
Assert.Inconclusive( string message );
Assert.Inconclusive( string message, object[] parms );

The Assert.Pass method allows you to immediately end the test, recording it as successful. Since it causes an exception to be thrown, it is more efficient to simply allow the test to return. However, Assert.Pass allows you to record a message in the test result and may also make the test easier to read in some situations. Additionally, like the other methods on this page, it can be invoked from a nested method call with the result of immediately terminating test execution.

The Assert.Fail method provides you with the ability to generate a failure based on tests that are not encapsulated by the other methods. It is also useful in developing your own project-specific assertions.

Here's an example of its use to create a private assertion that tests whether a string contains an expected value.

public void AssertStringContains( string expected, string actual )
{
    AssertStringContains( expected, actual, string.Empty );
}

public void AssertStringContains( string expected, string actual,
    string message )
{
    if ( actual.IndexOf( expected ) < 0 )
        Assert.Fail( message );
}

The Assert.Ignore method provides you with the ability to dynamically cause a test or suite to be ignored at runtime. It may be called in a test, setup or fixture setup method. We recommend that you use this only in isolated cases. The category facility is provided for more extensive inclusion or exclusion of tests or you may elect to simply divide tests run on different occasions into different assemblies.

The Assert.Inconclusive method indicates that the test could not be completed with the data available. It should be used in situations where another run with different data might run to completion, with either a success or failure outcome.

NUnit-2.6.0.12051/doc/fixtureTeardown.html0000664000175000017500000002020111720512704017776 0ustar jtaylorjtaylor NUnit - FixtureTeardown

TestFixtureTearDownAttribute (NUnit 2.1 / 2.5)

This attribute is used inside a TestFixture to provide a single set of functions that are performed once after all tests are completed.

Before NUnit 2.5, a TestFixture could have only one SetUp method and it was required to be an instance method.

Beginning with NUnit 2.5, TestFixtureTearDown methods may be either static or instance methods and you may define more than one of them in a fixture. Normally, multiple TestFixtureTearDown methods are only defined at different levels of an inheritance hierarchy, as explained below.

So long as any TestFixtureSetUp method runs without error, the TestFixtureTearDown method is guaranteed to run. It will not run if a TestFixtureSetUp method fails or throws an exception.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [TestFixtureSetUp] public void Init()
    { /* ... */ }

    [TestFixtureTearDown] public void Cleanup()
    { /* ... */ }

    [Test] public void Add()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <TestFixtureSetUp()> Public Sub Init()
    ' ...
    End Sub

    <TestFixtureTearDown()> Public Sub Cleanup()
    ' ...
    End Sub

    <Test()> Public Sub Add()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [TestFixtureSetUp] void Init();
    [TestFixtureTearDown] void Cleanup();

    [Test] void Add();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.TestFixtureSetUp() */
  public void Init()
  { /* ... */ }

  /** @attribute NUnit.Framework.TestFixtureTearDown() */
  public void Cleanup()
  { /* ... */ }

  /** @attribute NUnit.Framework.Test() */
  public void Add()
  { /* ... */ }
}

Inheritance

The TestFixtureTearDown attribute is inherited from any base class. Therefore, if a base class has defined a TestFixtureTearDown method, that method will be called after each test method in the derived class.

Before NUnit 2.5, you were permitted only one TestFixtureTearDown method. If you wanted to have some TestFixtureTearDown functionality in the base class and add more in the derived class you needed to call the base class method yourself.

With NUnit 2.5, you can achieve the same result by defining a TestFixtureTearDown method in the base class and another in the derived class. NUnit will call base class TestFixtureTearDown methods after those in the derived classes.

Note: Although it is possible to define multiple TestFixtureTearDown methods in the same class, you should rarely do so. Unlike methods defined in separate classes in the inheritance hierarchy, the order in which they are executed is not guaranteed.

See also...

NUnit-2.6.0.12051/doc/reusableConstraint.html0000664000175000017500000001423411720512704020464 0ustar jtaylorjtaylor NUnit - ReusableConstraint

ReusableConstraint (NUnit 2.5.6)

Normally constraints just work. However, attempting to reuse the same constraint in several places can lead to unexpected results.

Consider the following code as an example:

    Constraint myConstraint = Is.Not.Null;
    Assert.That("not a null", myConstraint); // Passes, of course
    Assert.That("not a null", myConstraint); // Fails! What's that about?

We'll save the technical explanation for later and show the solution first:

    ReusableConstraint myConstraint = Is.Not.Null;
    Assert.That("not a null", myConstraint); // Passes
    Assert.That("not a null", myConstraint); // Passes
Or alternatively..
    var myConstraint = new ReusableConstraint(Is.Not.Null);
    Assert.That("not a null", myConstraint); // Passes
    Assert.That("not a null", myConstraint); // Passes

Technical Explanation

In the original example, the value assigned to myConstraint is known as an unresolved constraint. In fact, it's an unresolved NullConstraint, because that was the last constraint encountered in the expression. It's associated with a Not operator that has not yet been applied.

That's OK for use with Assert.That(), because the method knows how to resolve a constraint before using it. Assert.That() resolves this constraint to a NotConstraint referencing the original NullConstraint.

Of course, the original reference in myConstraint is left unchanged in all of this. But the EqualConstraint it points to has now been resolved. It is now a resolved constraint and can't be resolved again by the second Assert.That(), which only sees the NullConstraint and not the NotConstraint.

So, for reusability, what we want to save is the result of resolving the constraint, in this case

    NotConstraint => NullConstraint
That's what ReusableConstraint does for us. It resolves the full expression and saves the result. Then it passes all operations on to that saved result.

When to Use It

Use this constraint any time you want to reuse a constraint expression and you'll be safe.

If you like to take chances, you'll find that you can avoid using it in the following cases...

  1. With a simple constraint involving no operators, like...
        Constraint myConstraint = Is.Null;
        Constraint myConstraint = Is.EqualTo(42);
    
  2. With any constraint you construct using new, without using the "dotted" constraint syntax...
        Constraint myConstraint = new NotConstraint(new NullConstraint());
        Constraint myConstraint = new AndConstraint(
            new GreaterThanConstraint(0), 
            new LessThanConstraint(100));
    

    However, there is no significant penalty to using ReusableConstraint. It makes your intent much clearer and the exceptions listed are accidents of the internal implementation and could disappear in future releases.

NUnit-2.6.0.12051/doc/requiresThread.html0000664000175000017500000001263411720512704017606 0ustar jtaylorjtaylor NUnit - RequiresThread

RequiresThreadAttribute (NUnit 2.5)

The RequiresThreadAttribute is used to indicate that a test method, class or assembly should be run on a separate thread. Optionally, the desired apartment for the thread may be specified in the constructor.

Note: This attribute, used with or without an ApartmentState argument will always result in creation of a new thread. To create a thread only if the current ApartmentState is not appropriate, use RequiresSTAAttribute or RequiresMTAAttribute.

Examples


// A thread will be created and used to run
// all the tests in the assembly
[assembly:RequiresThread]

...

// TestFixture requiring a separate thread
[TestFixture, RequiresThread]
public class FixtureOnThread
{
  // A separate thread will be created and all
  // tests in the fixture will run on it.
}

[TestFixture]
public class AnotherFixture
{
  [Test, RequiresThread]
  public void TestRequiringThread()
  {
    // A separate thread will be created for this test
  }
  
  [Test, RequiresThread(ApartmentState.STA)]
  public void TestRequiringSTAThread()
  {
    // A separate STA thread will be created for tnis test.
  }
}

See also...

NUnit-2.6.0.12051/doc/repeat.html0000664000175000017500000001101111720512704016063 0ustar jtaylorjtaylor NUnit - Repeat

RepeatAttribute (NUnit 2.5)

RepeatAttribute is used on a test method to specify that it should be executed multiple times. If any repetition fails, the remaining ones are not run and a failure is reported.

Notes:

  1. It is not currently possible to use RepeatAttribute on a TestFixture or any other type of test suite. Only single tests may be repeated.
  2. Since a parameterized test method represents a suite, RepeatAttribute is ignored when it appears on such a method.
NUnit-2.6.0.12051/doc/datapoint.html0000664000175000017500000001374211720512704016603 0ustar jtaylorjtaylor NUnit - Datapoint

DatapointAttribute / DatapointsAttribute (NUnit 2.5) (Experimental)

The Datapoint and Datapoints attributes are used to provide data for Theories and are ignored for ordinary tests - including tests with parameters.

DataPointAttribute

When a Theory is loaded, NUnit creates arguments for each of its parameters by using any fields of the same type as the parameter annotated with the DatapointAttribute. Fields must be members of the class containing the Theory and their Type must exactly match the argument for which data is being supplied.

DataPointsAttribute

In addition to specifying individual datapoints, collections of datapoints may be provided by use of the DatapointsAttribute - note the spelling. This attribute may be placed on methods or properties in addition to fields. The returned value must be either an array of the required type or (beginning with NUnit 2.5.5) an IEnumerable<T> returning an enumeration of the required type. The data Type must exactly match the argument for which data is being supplied.

Automatically Supplied Datapoints

It is normally not necessary to specify datapoints for boolean or enum arguments. Beginning with version 2.5.4, NUnit automatically supplies values of true and false for boolean arguments and will supply all defined values of any enumeration.

If for some reason you don't wish to use all possible values, you can override this behavior by supplying your own datapoints. If you supply any datapoints for an argument, automatic datapoint generation is suppressed.

Example

For an example of use, see TheoryAttribute.

See also...

NUnit-2.6.0.12051/doc/collectionConstraints.html0000664000175000017500000002441111720512704021176 0ustar jtaylorjtaylor NUnit - CollectionConstraints

Collection Constraints (NUnit 2.4 / 2.5)

Collection constraints perform tests that are specific to collections. The following collection constraints are provided. Before NUnit 2.4.6, these constraints only operated on true Collections. Beginning with 2.4.6, they can work with any object that implements IEnumerable.

Beginning with NUnit 2.4.2, use of an improper argument type caused tests to fail. Later releases give an error rather than a failure, so that negated constraints will not appear to succeed.

For example, both of the following statements give an error in later releases, but the second would have succeeded in earlier versions of NUnit.

int[] iarray = new int[] { 1, 2, 3 };

Assert.That( 5, Is.SubsetOf( iarray ) );  // Fails in early releases
Assert.That( 5, Is.Not.SubsetOf( iarray ) ); /

AllItemsConstraint

Action

Applies a constraint to each item in a collection, succeeding only if all of them succeed.

Constructor

AllItemsConstraint(Constraint itemConstraint)

Syntax

Is.All...
Has.All...

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "a", "b", "c" };

Assert.That( iarray, Is.All.Not.Null );
Assert.That( sarray, Is.All.InstanceOf() );
Assert.That( iarray, Is.All.GreaterThan(0) );
Assert.That( iarray, Has.All.GreaterThan(0) );

SomeItemsConstraint

Action

Applies a constraint to each item in a collection, succeeding if at least one of them succeeds.

Constructor

SomeItemsConstraint(Constraint itemConstraint)

Syntax

Has.Some...

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "a", "b", "c" };

Assert.That( iarray, Has.Some.GreaterThan(2) );
Assert.That( sarray, Has.Some.Length(1) );

ExactCountConstraint

Action

Applies a constraint to each item in a collection, succeeding if the specified number of items succeed.

Constructor

ExactCountConstraint(int expectedCount, Constraint itemConstraint)

Syntax

Has.Exactly(int expectedCount)...

Examples of Use

int[] array = new int[] { 1, 2, 3 };

Assert.That( array, Has.Exactly(1).EqualTo(3) );
Assert.That( array, Has.Exactly(2).GreaterThan(1) );
Assert.That( array, Has.Exactly(3).LessThan(100) );

NoItemConstraint

Action

Applies a constraint to each item in a collection, succeeding only if all of them fail.

Constructor

NoItemConstraint(Constraint itemConstraint)

Syntax

Has.None...
Has.No...

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "a", "b", "c" };

Assert.That( iarray, Has.None.Null );
Assert.That( iarray, Has.No.Null );
Assert.That( sarray, Has.None.EqualTo("d") );
Assert.That( iarray, Has.None.LessThan(0) );

UniqueItemsConstraint

Action

Tests that a collection contains only unique items.

Constructor

UniqueItemsConstraint()

Syntax

Is.Unique

Example of Use

string[] sarray = new string[] { "a", "b", "c" };

Assert.That( sarray, Is.Unique );

Notes

  1. ??

CollectionContainsConstraint

Action

Tests that a collection contains an object.

Constructor

CollectionContainsConstraint( object )

Syntax

Has.Member( object )
Contains.Item( object )

Modifiers

...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "a", "b", "c" };

Assert.That( iarray, Has.Member(3) );
Assert.That( sarray, Has.Member("b") );
Assert.That( sarray, Contains.Item("c") );
Assert.That( sarray, Has.No.Member("x") );

Notes

  1. For references, Has.Member uses object equality to find a member in a collection. To check for an object equal to an item the collection, use Has.Some.EqualTo(...).

CollectionEquivalentConstraint

Action

Tests that two collections are equivalent - that they contain the same items, in any order.

Constructor

CollectionEquivalentConstraint( IEnumerable other )

Syntax

Is.EquivalentTo( IEnumerable other )

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "a", "b", "c" };

Assert.That( new string[] { "c", "a", "b" }, Is.EquivalentTo( sarray ) );
Assert.That( new int[] { 1, 2, 2 }, Is.Not.EquivalentTo( iarray ) );

Notes

  1. To compare collections for equality, use Is.EqualTo().

CollectionSubsetConstraint

Action

Tests that one collection is a subset of another.

Constructor

CollectionSubsetConstraint( ICollection )

Syntax

Is.SubsetOf( IEnumerable )

Example of Use

int[] iarray = new int[] { 1, 2, 3 };

Assert.That( new int[] { 1, 3 }, Is.SubsetOf( iarray ) );

CollectionOrderedConstraint (NUnit 2.5)

Action

Tests that a collection is ordered.

Constructor

CollectionOrderedConstraint()

Syntax

Is.Ordered

Modifiers

...Descending
...By(string propertyName)
...Using(IComparer comparer)
...Using(IComparer<T> comparer)
...Using(Comparison<T> comparer)

Examples of Use

int[] iarray = new int[] { 1, 2, 3 };
string[] sarray = new string[] { "c", "b", "a" };
string[] sarray2 = new string[] ( "a", "aa", "aaa" );

Assert.That( iarray, Is.Ordered );
Assert.That( sarray, Is.Ordered.Descending );
Assert.That( sarray2, Is.Ordered.By("Length");

Notes

  1. Modifiers may be combined and may appear in any order. If the same modifier is used more than once, the result is undefined.
  2. The syntax of Is.Ordered has changed from earlier betas.
NUnit-2.6.0.12051/doc/datapointProviders.html0000664000175000017500000001100511720512704020467 0ustar jtaylorjtaylor NUnit - DatapointProviders

DataPointProviders (NUnit 2.5)

Purpose

DataPointProviders are used to supply data for an individual parameter of a parameterized test method.

Extension Point

Addins use the host to access this extension point by name:

	IExtensionPoint listeners = host.GetExtensionPoint( "DataPointProviders" );

Interface

The extension object passed to Install must implement either the IDataPointProvider or the IDataPointProvider2 interface:

	public interface IDataPointProvider
	{
		bool HasDataFor( ParameterInfo parameter );
		IEnumerable GetDataFor( ParameterInfo parameter );
	}
	
	public interface IDataPointProvider2 : IDatapointProvider
	{
		bool HasDataFor( ParameterInfo parameter, Test parentSuite );
		IEnumerable GetDataFor( ParameterInfo parameter, Test parentSuite );
	}

NUnit will call IDataPointProvider2 if it is available. Otherwise IDataPointProvider will be used.

The HasDataFor method should return true if the provider is able to supply data for the specified parameter. If a provider only wants to be used on certain types of tests, it can examine the supplied ParameterInfo and its associated MethodInfo and Type and/or the parent test suite.

The GetDataFor method should return a list of individual values to use for the supplied parameter in running the test.

Notes:

  1. Most providers will delegate one of the interface implementations to the other if they implement both.
  2. DataPointProviders that use data from the fixture class should use IDataPointProvider2 interface so that they are able to access any arguments supplied for constructing the fixture object.
  3. Providers that acquire data from outside the fixture will usually be able to work with IDataPointProvider alone.
  4. The IDataPointProvider2 interface was added in the NUnit 2.5.1 release.
NUnit-2.6.0.12051/doc/releaseBreakdown.html0000664000175000017500000004767211720512704020106 0ustar jtaylorjtaylor NUnit - ReleaseBreakdown

Release Notes

NUnit 2.6 Final Release - Version 2.6.0.12051 - February 20, 2012

Bug Fixes

  • 881715 Frequent socketexception in nUnit GUI
  • 881958 nunit-console-x86 crashes with socketexception
  • 928018 Issue with test time print out
  • 930774 Adding or Removing a category in the Gui causes an exception
  • 933800 NUnit will crash when started and dll from previous project doesn't compile

NUnit 2.6 Release Candidate - Version 2.6.0.12035 - February 4, 2012

General

  • The Windows installer is now built using WiX 3.5, upgraded from 2.0.

Framework

  • The API used to create Action Attributes has been changed from the earlier beta releases. See the docs for more info.
  • Visual Basic users may now use Assert.ByVal rather than Assert.That() to avoid errors when the first argument is a property with a non-public setter.
  • PlatformAttribute now supports arguments 'Windows8' and 'Windows2012Server'.

Bug Fixes

  • 498659 Registry entries and shortcuts remain after install
  • 498690 Assert.That() doesn't like properties with scoped setters
  • 638289 Install uses CURRENT_USER instead of LOCAL_MACHINE for AssemblyFoldersEx
  • 910189 Eliminate NUnit Configuration Section in config file
  • 919876 NUnit.Util.Transform.resources missing from nunit.util.dll
  • 920472 CollectionAssert.IsNotEmpty must dispose Enumerator
  • 922455 Add Support for Windows 8 and Windows 2012 Server to PlatformAttribute
  • 924504 NUnit project files should have an Edit command association with the project editor

NUnit 2.6 Beta 4 - Version 2.6.0.12017 - January 17, 2012

General

  • NUnit no longer stores settings in the test configuration file, as it did in earlier versions. Specifically, we no longer recognize or support OldStyleTestCases, ApartmentState, ThreadPriority or DefaultLogThreshold in the configuration file. Further details on each of these features are included in the appropriate sections below.
  • The TestRunner interface has been modified. Applications using this interface will need to be modified but general users are not effected.
  • The build now uses the NAnt 0.91 final release.

Framework

  • User-defined equality comparers specified with the Using syntax element may now be used with arrays and dictionaries. Essentially, this means that there are no longer any restrictions on the Types for which a user-defined equality comparer may be specified.
  • So-called "old-style" tests, identified by having a name beginning with "Test" are no longer supported in NUnit 2.6.
  • Setting a ThreadPriority for the test runner thread is no longer supported under NUnit 2.6.

Console

  • The following new command-line options are provided:
    • -stoponerror causes execution of the test run to terminate immediately on the first test failure or error.
    • -apartment is used to specify the ApartmentState (STA or MTA) of the test runner thread. Since the default is MTA, the option is only needed to force execution in the Single Threaded Apartment.

Gui

  • A number of new settings are available using the Settings Dialog:
    • The Tree Display page allows the user to select alternate image sets for use in the test tree. Additional user-provided image sets may be added if desired.
    • The Text Output page allows setting the threshold for capture and display of log4net output (previously controlled by the test config file).
  • By default, test Cases under a Theory that fail an assumption are no longer shown in the tree. A context menu item has been added to allow the user to view them.
  • The properties dialog has been redesigned to be more compact and readable.
  • The context menu for the test tree has been simplified.

Bug Fixes

  • 605034 Log4net not working with NUnit
  • 708173 NUnit's logic for comparing arrays - use Comparer<T[]> if it is provided
  • 719184 Platformdependency in src/ClientUtilities/util/Services/DomainManager.cs:40
  • 761579 Tests using log4net run very slowly
  • 848713 Feature request: Add switch for console to break on any test case error
  • 882192 Ignored test icon should be more prominent
  • 885173 Tests are still executed after cancellation by user
  • 896615 Tests can't be run in existing AppDomain
  • 897289 Is.Empty constraint has unclear failure message
  • 899178 Wrong failure message for parameterized tests that expect exceptions
  • 902305 Gui should not normally display Inconclusive test cases for a Theory
  • 902343 Gui 'Hide Tests' function no longer works
  • 903078 DomainUsage.None setting crashes nunit-gui
  • 903080 Test tree context menu needs to be simplified
  • 904841 After exiting for timeout the teardown method is not executed
  • 907270 Gui enables run when the assembly specified on the command line is not found
  • 908829 TestCase attribute does not play well with variadic test functions
  • 910218 NUnit should add a trailing separator to the ApplicationBase
  • 912955 Project files missing in source code package

NUnit 2.6 Beta 3 - Version 2.6.0.11340 - December 6, 2011

Framework

  • The Constraint syntax now supports Is.Positive, which is interpreted as greater than zero, and Is.Negative, which is interpreted as less than zero.

Bug Fixes

  • 892844 Not using Mono 4.0 profile under Windows
  • 892845 "Mono" is not clearly shown in About box or Test Assemblies dialog
  • 892847 Gui offers to load assemblies under a lower CLR version
  • 893919 DelayedConstraint fails polling properties on references which are initially null
  • 893991 When working directory contains # sign, it is truncated
  • 898192 Feature Request: Is.Negative, Is.Positive
  • 898256 IEnumerable for Datapoints doesn't work
  • 898850 NUnit 2.6 beta 2 crashes on assemblies without tests

NUnit 2.6 Beta 2 - Version 2.6.0.11324 - November 20, 2011

General

  • NUnit's executables now use config files that allow smoother running of mixed assemblies built for .NET 2.0 under .NET 4.0.
  • When opening Visual Studio formatted solutions, NUnit now uses the solution configuration by default, resulting in changed behavior from previous releases. The Settings Dialog may be used to revert NUnit to the earlier behavior, which ignored solution configurations.
  • Changing the URL to be used for NUnit help through the config file is no longer supported.

Framework

  • TestCaseAttribute now accepts Explicit and Reason named parameters.
  • TestCaseSourceAttribute now accepts a Category named parameter.
  • TestCaseData now supports marking individual test cases as Explicit.
  • EqualConstraint now recognizes and uses IEquatable<T> if it is implemented on either the actual or the expected value. The interface is used in preference to any override of Object.Equals(), so long as the other argument is of Type T. Note that this applies to all equality tests performed by NUnit.
  • When Assert.Throws() fails due to an exception of the wrong Type being thrown, the error message now includes the Message and Stack Trace from the exception.
  • The constraint syntax now supports Has.Exactly(n)... in place of Has.Some... in order to allow tests over collections that must be satisfied a specific number of times.
  • The Using(...) syntactic element may now be repeated multiple times in an expression, so long as each comparer applies to a different Type. NUnit will use the appropriate comparer, depending on the Type of the arguments. Among other things, this allows overriding the default NUnit comparison of collections.
  • Documentation is provided for the previously undocumented TestContext. A new property TestContext.WorkDirectory allows tests to access the name of a directory to be used for file output. This directory may be specified by use of the /work option of nunit-console.

Gui

  • The test reload functionality in the Gui has been rewritten and simplified so that the same logic is used for all cases where the visual state of the tree is to be recovered. Test results are now found even if changes to the assembly have resulted in the assignment of new ids to the tests.
  • The Gui now displays invalid tests in red immediately upon load, without waiting for the user to run them. Tests marked with the IgnoreAttribute are displayed in yellow immediately as well.
  • The directory containing the log files may be opened directly from the Gui by use of a new item on the Tools menu.
  • Test summary results are truncated when the window size is too small. The full summary is displayed when hovering over the field.
  • A number of new settings are available using the Settings Dialog:
    • The Project Editor page allows the user to select whether the NUnit Project Editor or another external program will be used when editing the settings file.
    • The Runtime Selection page allows enabling or disabling automatic detection of the target runtime for each test assembly.
    • The Advanced Loader Settings page now allows specifying the argument to use in calling SetPrincipalPolicy for each test AppDomain.
    • The Visual Studio page now includes a setting that enables or disables the use of solution configs when loading Visual Studio solution files.
    • The Internal Trace page now shows the directory path to which log files will be saved.
  • The location of the settings dialog under the Windows AppData directory has been changed from Roaming to Local. Users will need to reset their preferences in some cases.

Bug Fixes

  • 602761 nunit-agent hangs after tests complete
  • 625672 NUnit GUI bounces to background on reload
  • 657801 Help URL should not be in config file
  • 676560 Assert.AreEqual does not support IEquatable<T>
  • 697069 Feature request: dynamic location for TestResult.xml
  • 697329 NUnit tries to test disabled projects
  • 709062 "System.ArgumentException : Cannot compare" when the element is a list
  • 712156 Tests cannot use AppDomain.SetPrincipalPolicy
  • 766749 net-2.0\nunit-console-x86.exe.config should have a startup element and also enable loadFromRemoteSources
  • 770471 Assert.IsEmpty does not support IEnumerable
  • 785460 Add Category parameter to TestCaseSourceAttribute
  • 794115 HashSet incorrectly reported
  • 800089 Assert.Throws() hides details of inner AssertionException
  • 836080 Log Directory shown incorrectly in settings dialog
  • 836360 When size of the Gui window is reduced, test result info may not fit in the field provided
  • 841894 UI won't run tests marked Explicit from the context menu
  • 878376 Add 'Exactly(n)' to the NUnit constraint syntax
  • 878899 Changing logging level has no effect until NUnit is restarted
  • 878955 ParameterizedTest not in their parent test-suite when FixtureSetup fails in .xml result file
  • 881617 Tests with invalid category attributes should be more visible
  • 882137 When no tests are run, higher level suites display as Inconclusive
  • 882517 NUnit 2.5.10 doesn't recognize TestFixture if there are only TestCaseSource inside
  • 883271 Reload Tests sometimes "loses" tests
  • 885277 Exception when project calls for a runtime using only 2 digits
  • 885604 Feature request: Explicit named parameter to TestCaseAttribute
  • 887005 NUnit.exe ignores categories when using /run option
  • 890129 DelayedConstraint doesn't appear to poll properties of objects
  • 890384 When font is enlarged, layout of settings pages is incorrect
  • 891237 When font is enlarged, gui Test Result disappears and suite name is truncated
  • 891265 Add /cleanup to nunit-console.exe
  • 891326 Non-runnable and statically ignored tests should disable the Run item on the context menu

NUnit 2.6 Beta 1 - Version 2.6.0.11240 - August 28, 2011

General

  • NUnit is now built using .NET 3.5. All NUnit assemblies and most tests target .NET 2.0 but the full set of tests requires 3.5 to execute.
  • The build script now supports building from source under .NET 4.0. The script selects either .NET 3.5 or .NET 4.0 to perform the build, depending on what is available.
  • NAnt 0.91 alpha2 release is now used for building on Windows. The 0.90 release is still used on Linux.
  • Support for .NET 1.0 / 1.1 is no longer included in the main distribution for NUnit but is provided as a separate package.
  • NUnit Mocks is now deprecated. All classes are now marked as obsolete.
  • NUnit now uses the NSubstitute mock framework its own tests. A copy of the NSubstitute dll is included in the distribution.

Framework

  • NUnit now supports composable Action Attributes, which allow the test developer to put reusable test actions into attributes and attach these actions to suites, tests, and test cases. The actions can run arbitrary code before and after suites, tests, and test cases execute. It enables the test developer to build smaller reusable actions and to compose them in unique ways for each suite, test, or test case.

    Note: This feature is experimental and details are likely to change in the final release.

  • PlatformAttribute accepts "Net-3.0", "Net-3.5", "Mono-3.0" and "Mono-3.5" as arguments. Since these frameworks all use the 2.0 runtime, the semantics of their use is slightly different from other key words. The "3.5" arguments also include "3.0" and "2.0" and the "3.0" arguments include "2.0" in their interpretation.
  • TestFixtureAttribute now accepts a Category named parameter, allowing individual fixture instances to be included in or excluded from a test run.

Console

  • The .NET 1.1 build of nunit-console no longer supports the -process or -framework option. There is no automatic runtime detection and tests execute under same runtime as the console runner itself. If this functionality is needed when running tests under .NET 1.1, use the standard console runner to execute the tests in a separate process.
  • The following new command-line options are provided:
    • -result is a synonym for -xml, specifying the file to be used for output of the test results in XML form. The -xml option is still recognized but will be removed in a future release.
    • -noresult allows supressing the xml result output entirely.
    • -work is used to specify the directory to be used for output files. Any relative paths specified with the -output, -err or -result options are resolved using this directory as a base.
    • -runlist allows the user to specify a file that contains the names of the tests to be executed rather than listing them directly on the command line.

Gui

  • The Project Editor is now a separate program, which may be executed directly or run through the Project | Edit dropdown menu of the NUnit GUI. The editor now provides two main views of the project: a property-oriented view based on the Project Editor that was built into earlier versions of the NUnit GUI and an xml view, which allows simple editing of the .nunit file.

PNUnit

  • The PNUnit code has been updated using the latest build from the developers at Codice Software and additional examples are provided in the source.

Bug Fixes

  • 691129 Add Category parameter to TestFixture
  • 692180 Script should allow building for net-2.0 under 3.5 or 4.0
  • 701331 TestFixture attributes on base classes are not ignored
  • 702734 Separate packaging of NUnit for .NET 1.1 and 2.0
  • 711330 Test-free assembly given failure icon in tree display
  • 712444 nunit-console /run don't execute parameterized test-cases (with commas in test-case name)
  • 726313 Failure in Assembly level Action attribute causes crash
  • 728500 TestDomain should unload the test AppDomain
  • 735851 Add detection of 3.0, 3.5 and 4.0 frameworks to PlatformAttribute
  • 736062 Deadlock when EventListener performs a Trace call + EventPump synchronisation
  • 739039 Add noxml option to console runner
  • 741402 Error running .NET 1.1 console tests
  • 746247 Add AllowPartiallyTrustedCallersAttribute to nunit.framework assembly
  • 747581 Failure in TestFixtureTearDown not reported in console runner
  • 756843 Failing assertion does not show non-linear tolerance mode
  • 787106 EqualConstraint provides inadequate failure information for IEnumerables
  • 806198 nunit console crashes when opening certain projects with common output path
  • 816863 System.NullReferenceException 2.6.0.11089
  • 828739 Run NUnit tests listed in a file
NUnit-2.6.0.12051/doc/timeout.html0000664000175000017500000001144511720512704016304 0ustar jtaylorjtaylor NUnit - Timeout

TimeoutAttribute (NUnit 2.5)

The TimeoutAttribute is used to specify a timeout value in milliseconds for a test case. If the test case runs longer than the time specified it is immediately cancelled and reported as a failure, with a message indicating that the timeout was exceeded.

The attribute may also be specified on a fixture or assembly, in which case it indicates the default timeout for any subordinate test cases.

Example

[Test, Timeout(2000)]
public void PotentiallyLongRunningTest()
{
    ...
}

Notes

  1. Beginning with NUnit 2.5.5, timeouts are suppressed when running under a debugger.

See Also...

NUnit-2.6.0.12051/doc/category.html0000664000175000017500000002140411720512704016427 0ustar jtaylorjtaylor NUnit - Category

CategoryAttribute (NUnit 2.2)

The Category attribute provides an alternative to suites for dealing with groups of tests. Either individual test cases or fixtures may be identified as belonging to a particular category. Both the gui and console test runners allow specifying a list of categories to be included in or excluded from the run. When categories are used, only the tests in the selected categories will be run. Those tests in categories that are not selected are not reported at all.

This feature is accessible by use of the /include and /exclude arguments to the console runner and through a separate "Categories" tab in the gui. The gui provides a visual indication of which categories are selected at any time.

Test Fixture Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [Category("LongRunning")]
  public class LongRunningTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Category("LongRunning")>
  Public Class LongRunningTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [Category("LongRunning")]
  public __gc class LongRunningTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Category("LongRunning") */
public class LongRunningTests
{
  // ...
}

Test Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [Category("Long")]
    public void VeryLongTest()
    { /* ... */ }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()>
  Public Class SuccessTests
    <Test(), Category("Long")> Public Sub VeryLongTest()
      ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test][Category("Long")] void VeryLongTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Category("Long") */
  public void VeryLongTest()
  { /* ... */ }
}

Custom Category Attributes

Beginning with NUnit 2.4, it is possible to define custom attributes that derive from CategoryAttribute and have them recognized by NUnit. The default protected constructor of CategoryAttribute sets the category name to the name of your class.

Here's an example that creates a category of Critical tests. It works just like any other category, but has a simpler syntax. A test reporting system might make use of the attribute to provide special reports.

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false)]
public class CriticalAttribute : CategoryAttribute { }

...

[Test, Critical]
public void MyTest()
{ /*...*/ }
NUnit-2.6.0.12051/doc/comparisonAsserts.html0000664000175000017500000002655311720512704020343 0ustar jtaylorjtaylor NUnit - ComparisonAsserts

Comparisons (NUnit 2.2.4)

The following methods test whether one object is greater than than another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.Greater( x, y ) asserts that x is greater than y ( x > y ).

Assert.Greater( int arg1, int arg2 );
Assert.Greater( int arg1, int arg2, string message );
Assert.Greater( int arg1, int arg2, string message, 
                object[] parms );

Assert.Greater( uint arg1, uint arg2 );
Assert.Greater( uint arg1, uint arg2, string message );
Assert.Greater( uint arg1, uint arg2, string message, 
                object[] parms );

Assert.Greater( long arg1, long arg2 );
Assert.Greater( long arg1, long arg2, string message );
Assert.Greater( long arg1, long arg2, string message, 
                object[] parms );

Assert.Greater( ulong arg1, ulong arg2 );
Assert.Greater( ulong arg1, ulong arg2, string message );
Assert.Greater( ulong arg1, ulong arg2, string message, 
                object[] parms );

Assert.Greater( decimal arg1, decimal arg2 );
Assert.Greater( decimal arg1, decimal arg2, string message );
Assert.Greater( decimal arg1, decimal arg2, string message, 
                object[] parms );

Assert.Greater( double arg1, double arg2 );
Assert.Greater( double arg1, double arg2, string message );
Assert.Greater( double arg1, double arg2, string message, 
                object[] parms );

Assert.Greater( double arg1, double arg2 );
Assert.Greater( double arg1, double arg2, string message );
Assert.Greater( double arg1, double arg2, string message, 
                object[] parms );

Assert.Greater( float arg1, float arg2 );
Assert.Greater( float arg1, float arg2, string message );
Assert.Greater( float arg1, float arg2, string message, 
                object[] parms );

Assert.Greater( IComparable arg1, IComparable arg2 );
Assert.Greater( IComparable arg1, IComparable arg2, string message );
Assert.Greater( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

The following methods test whether one object is greater than or equal to another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.GreaterOrEqual( x, y ) asserts that x is greater than or equal to y ( x >= y ).

Assert.GreaterOrEqual( int arg1, int arg2 );
Assert.GreaterOrEqual( int arg1, int arg2, string message );
Assert.GreaterOrEqual( int arg1, int arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( uint arg1, uint arg2 );
Assert.GreaterOrEqual( uint arg1, uint arg2, string message );
Assert.GreaterOrEqual( uint arg1, uint arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( long arg1, long arg2 );
Assert.GreaterOrEqual( long arg1, long arg2, string message );
Assert.GreaterOrEqual( long arg1, long arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( ulong arg1, ulong arg2 );
Assert.GreaterOrEqual( ulong arg1, ulong arg2, string message );
Assert.GreaterOrEqual( ulong arg1, ulong arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( decimal arg1, decimal arg2 );
Assert.GreaterOrEqual( decimal arg1, decimal arg2, string message );
Assert.GreaterOrEqual( decimal arg1, decimal arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( double arg1, double arg2 );
Assert.GreaterOrEqual( double arg1, double arg2, string message );
Assert.GreaterOrEqual( double arg1, double arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( double arg1, double arg2 );
Assert.GreaterOrEqual( double arg1, double arg2, string message );
Assert.GreaterOrEqual( double arg1, double arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( float arg1, float arg2 );
Assert.GreaterOrEqual( float arg1, float arg2, string message );
Assert.GreaterOrEqual( float arg1, float arg2, string message, 
                object[] parms );

Assert.GreaterOrEqual( IComparable arg1, IComparable arg2 );
Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message );
Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

The following methods test whether one object is less than than another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.Less( x, y ) asserts that x is less than y ( x < y ).

Assert.Less( int arg1, int arg2 );
Assert.Less( int arg1, int arg2, string message );
Assert.Less( int arg1, int arg2, string message, 
                object[] parms );
				
Assert.Less( uint arg1, uint arg2 );
Assert.Less( uint arg1, uint arg2, string message );
Assert.Less( uint arg1, uint arg2, string message, 
                object[] parms );
				
Assert.Less( long arg1, long arg2 );
Assert.Less( long arg1, long arg2, string message );
Assert.Less( long arg1, long arg2, string message, 
                object[] parms );

Assert.Less( ulong arg1, ulong arg2 );
Assert.Less( ulong arg1, ulong arg2, string message );
Assert.Less( ulong arg1, ulong arg2, string message, 
                object[] parms );

Assert.Less( decimal arg1, decimal arg2 );
Assert.Less( decimal arg1, decimal arg2, string message );
Assert.Less( decimal arg1, decimal arg2, string message, 
                object[] parms );
				
Assert.Less( double arg1, double arg2 );
Assert.Less( double arg1, double arg2, string message );
Assert.Less( double arg1, double arg2, string message, 
                object[] parms );
				
Assert.Less( float arg1, float arg2 );
Assert.Less( float arg1, float arg2, string message );
Assert.Less( float arg1, float arg2, string message, 
                object[] parms );
				
Assert.Less( IComparable arg1, IComparable arg2 );
Assert.Less( IComparable arg1, IComparable arg2, string message );
Assert.Less( IComparable arg1, IComparable arg2, string message, 
                object[] parms );

The following methods test whether one object is less than or equal to another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.LessOrEqual( x, y ) asserts that x is less than or equal to y ( x <= y ).

Assert.LessOrEqual( int arg1, int arg2 );
Assert.LessOrEqual( int arg1, int arg2, string message );
Assert.LessOrEqual( int arg1, int arg2, string message, 
                object[] parms );
				
Assert.LessOrEqual( uint arg1, uint arg2 );
Assert.LessOrEqual( uint arg1, uint arg2, string message );
Assert.LessOrEqual( uint arg1, uint arg2, string message, 
                object[] parms );
				
Assert.LessOrEqual( long arg1, long arg2 );
Assert.LessOrEqual( long arg1, long arg2, string message );
Assert.LessOrEqual( long arg1, long arg2, string message, 
                object[] parms );

Assert.LessOrEqual( ulong arg1, ulong arg2 );
Assert.LessOrEqual( ulong arg1, ulong arg2, string message );
Assert.LessOrEqual( ulong arg1, ulong arg2, string message, 
                object[] parms );

Assert.LessOrEqual( decimal arg1, decimal arg2 );
Assert.LessOrEqual( decimal arg1, decimal arg2, string message );
Assert.LessOrEqual( decimal arg1, decimal arg2, string message, 
                object[] parms );
				
Assert.LessOrEqual( double arg1, double arg2 );
Assert.LessOrEqual( double arg1, double arg2, string message );
Assert.LessOrEqual( double arg1, double arg2, string message, 
                object[] parms );
				
Assert.LessOrEqual( float arg1, float arg2 );
Assert.LessOrEqual( float arg1, float arg2, string message );
Assert.LessOrEqual( float arg1, float arg2, string message, 
                object[] parms );
				
Assert.LessOrEqual( IComparable arg1, IComparable arg2 );
Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message );
Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message, 
                object[] parms );
NUnit-2.6.0.12051/doc/setCulture.html0000664000175000017500000001462711720512704016762 0ustar jtaylorjtaylor NUnit - SetCulture

SetCultureAttribute (NUnit 2.4.2)

The SetCulture attribute is used to set the current Culture for the duration of a test. It may be specified at the level of a test or a fixture. The culture remains set until the test or fixture completes and is then reset to its original value. If you wish to use the current culture setting to decide whether to run a test, use the Culture attribute instead of this one.

Only one culture may be specified. Running a test under multiple cultures is a planned future enhancement. At this time, you can achieve the same result by factoring out your test code into a private method that is called by each individual test method.

Examples:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [SetCulture("fr-FR")]
  public class FrenchCultureTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), SetCulture("fr-FR")>
  Public Class FrenchCultureTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [SetCulture("fr-FR")]
  public __gc class FrenchCultureTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.SetCulture("fr-FR") */
public class FrenchCultureTests
{
  // ...
}

See also...

NUnit-2.6.0.12051/doc/img/0000775000175000017500000000000011742560362014506 5ustar jtaylorjtaylorNUnit-2.6.0.12051/doc/img/testProperties.jpg0000664000175000017500000013127111713252032020237 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?O<sGği^4O,S\!MKK,.̳;9w[lHȏ"+2^eτ?M~z|9l?Pi\\Xl-zYJ 8z1(`0ު컻^=Ç2qiad%+=#֋Kwtq~ 87_?OoF©o?OoFac:w[+U㹎^ gttfVޑkOaѼ]۩MKFk"kqps\} v9>m]GM{txsjWrsWvմrr|*qS?hH߱W±4sh^= ~߱|\`{]F:X5ȂIj#ʀ,ʡw}ˢ|gÏxź;SQδ7h2JnƎӒ>FN׋qvTkO.TO? 7#W۾6?ڮ7Oxuԇ+e]CR6a xmw2:PW>)Zߏot]:mZ$8X w4/˦B o滍SP|Ĉx.ws\ҧuWDԴ Yp-Φ$6yc17N̷Z)J1^su9}_k[[OC|?ѿ_ GяooFgßVO~$~%ޥ/hZkޗF&- ~¿plNދ`-b;H-7v\ohYRu&ֿ 1ni_ի895m.IEzjkY4zs~Ŀ GяooF7O77#V"F;Z\:M%ԭ-^Kyką@]⍣_Q k>%i3VZO{{9խ$0JmO4\m3Tf3qKt[i$ڲ]{4%u}[Zr]뢶n]*P5_  orm°O=+][n|-z\ZҴX-dSۗ[ʆ3IjOxǗ76ivq pdH$"abԯNURn]յb(ÞJ۽uim|}5Q~!>=k(jş#gvxwP:4vQ}}uknaI,&{oM 9lx ό ӵ_~.5vdiW-u ]:@i"7H.3I~V+mu{TŴ{y.۱fFy8Gk'"|$¥7TDZ?7Bq 3OZut3LT^gUgڬvNה~.<3_+úw(춋f9Y^ᢌs2g j77M%̭VGXLZtWT[ogJ> ~~ ;~޺7-ռNt:]c&VKcdQ3Tf_5-̚uW}ڦ"Z=[ExRUKONM_ݢ~jskDooiO7z"S<Dh^[v{C4'aJ;Ŗ\8ǘl _zVY.eZ5 <c{ZV׿MNsJ .#J~ Z"W5(j ҵOme[o5܊.,@!7UGl?V|;{mc!ӵZŲ1Qᄴww;bB<7 n/jI٥׿G4𸸫I=U'gfO ? /"9WkZ"Vિ' _?m&CE^h+1qq^O:4բYS.;Y50м_J$PwMcCÜ0MkFt+'kt911tM^iv}{, !u% a9Wk ևȕ=M`5 gu4}2KY_=~|w-9~x*4Uĸ4_?cOW/Lg̶ wSd;Y|$w,GDCkYޭVNs/aOWW3Kzgש~cdEַ.fυ j {@ Fj#5xZVSUͱ4'g|QOEv?ކּcG%"/5[S3 9ֲ1kУˬ܎Igiom? {KC|0*ygC~ F^cni0Ps] b}? [/ 5?m S]랰rIgZXjȾt6?}? ^Yu_.e':vXa4U@s^/#tCjoGkQMo <|#:j?gokǾ;Z6|;Ep.i6>}ʘhE~UUaԬnd>#4KG;߲K2ghFU+lGe# A5?~'|1Ѿ\|:c^OjV:VS#\ij*mʎt [Yӡ kD8h{L"ʃ.9$Mk sGxkm 㯉KGv~㊊%dvo;2D1[K-Ol ĚtK஗uiyu]: [xYbqvSA> cY ='pƊI ª u_^'otJռIv~mGx5 ȁԲ @^⏎^be mx_|;=5>yV+]G ;mʤj9_>"6wuEѠ񷌵 xz5 u]?Lky!uth `=1 ,\\(I~~ݛpF 4fՕz}D}%7o~ ן/3Sjh_ 3am.xHyPC#ɔ@ȕ?h85o~3icW lr[JNPLఈ c䡛_5X3wQjRN`Vҧ Mrrou>Ҿ,fIHmc=+ڻGc;Ɨox_gIQek[_- !\L&TY^TP*x9$hR>W?^,\9o%Ovs2OX־3וIu~~/d4riQI٤it_#gkw |o5~ɞu*QIdUKdk?!$*XVfZS%Yjv@ԮD22Am4T}NEz\W O-dIAJWup،D|ѕWz٫=7|ca]bKP2icB2 c^+(5 6kYw4LTA#=~|I]K(߉tqTqU%RKɤZ+l%K4\km߫g'Ci|$BOqi-_W6%NeԆk~~Nmz"h+xHJ/䓌f|BSX,!uM#Is.Nʱ ¶gl?iď[TRh>=o??mY(aҲit4媙mrS x{z{y/|orl}^;c;Z߻h!{^.2ϗ.x#]k:|Q״:ݙ{8:۠ h-(vv~sǿL~#ޝY|Gy\)]쭅Hf2#fe\>cVmQ7|?jl6jvݶ{lgϟ))ƄVVemֺ0kk;XG;"P69$MyW'Ox2~ ѿFoO*_&X sJ3 %'p`z/iO[UK~>駇mD?i;g=8gᇒѮ5f|gX_.m=8uoXYX~ߓjiJLQE33^=,5?O z-! $do~߿-Uo}JRJO նZYkվO[/e$^|W-^VZ.Smjmm o1yYMK_Q -My.хkCy# L7| ]Jƛ]$A-\O(WZ]"Ѿ#/ms[| z-oā?zgSwO}ckI鵬G~ u/#wlofium;jn 5Fs0$`_`_>)FZ_}4&,VL@JcȨMz(O!^8|?|B?za/~er? Z%IoRi_͵Altz!52['{k+WH~! ]P0I|hWS 7Z1lL1$1N.ea qe(Y@˸߶lcWOH.m 7˪&,A# g[}*ѳ(Ḇ1QN-65 sR%/Z e =htK5W(vFlvC+|H~J$]Uf_Ɍ.qM<7˪UpoOkXkۨcұDžOGN<)5/ksgÏi]T>|CNUM?_u6TozxI>?#^[k٤i[ዂWAuMn]uF NIB^ ~& _iW\/bRys%ݳ3>&烦Gi xH _U!&TC Q4_  s^d 'g9㥴<|_ wds_ dԃygiG\ӗߏҏ_\?-T|s/y_x6VI[ۧytk}2j1FH8i||C⭥VV:_¿iV䥵$4U$d^>'5˚ZŮ!PN~R1\xvhQ+FOZ, sXDw< :q6m%ko&>6I "Ѫ 7:çM_~כV=$LME|T~>"w~Ϳ -|>/]SudvQ4*&\DpWfs I659,==ܞ֡Ҭd1^Z;\۴!w` iEMQm7[W>P\S[͸j}KE|/,'?^('|꺔M.,9ͺI _gxJX|R ]1m52)'m;inID5#tu[mG EݔVH[[cssgq/ kk<cτ-k.wOF/LΗ46 !'y%\IEɽ%~הQE ( ( ( ( +<r[׉-8νeg{$e1ynbVWR# Ʃ*7 n ˭ گĻav2M|iqr|Zis( j)hmcZEuAu@-^ft(<'9n|% SrxydY378P{޶s%+ߦ^GQ_7~S/||=jϋ|!}{Ěƃaku4Z PI$>q}Fλ_v>CNO |$t7w}EKq8дEY!w0Bd1P|[z;gQ8G[kޛ`;j>iVcYI6og"pUdΑ1 d,v'/@tbM;hn` fHʗhYe J0ah}ߞ R]ju4Wܟ4x<;j Zjx,UC5sv+j^:Η?Z†N]>Ŭ{f3<&GFo9[hsJ9ASkD~J |&mo6>1񷇇|#ckvwKvu놑˷}wa_'_eƟ(8>%M35AđjWR>"WK٨[@ȿjg$(#Ui',~ta/ !xhFHڴNoIlRE޲ˈɢ}[}}zVE/s~?gg-_ i񦇣k ^6kkg1?ͽV Z鍤뗞s5m"?"U";mP+\ǺV%YTHLd? | >|9oeXǕ,~^#c;ۢgVRro7'ܥO$F1I/D(|mQEdjQEQEQEQEQEQEQEQEQEQEQE濵Oϋ^=4U3ik0Cqًo'fsv|ޕ^9|)۪j7+֫s+J!hc1'bf3~2~7|j?c X/ KFӼwqea'`OnYE*n!psmS5:Gִoo/-Tcp9Օ*A+Mnۢ%V?~ a'?|[ y$ц)&1"|qRIT}c' ~_ ?i-J>"Y Ym#cy 0 `^_G~:5mss]u oP[+_YMk習vHAƏ^'_(|.nvtͫMLJ56XK}Yi=.! K$ڤwd]ge4&ߣשNI=+>ן h}~IC玵M./>#-#|Ȼ\'kcK-hcNƗZ֬1A{D}šʆ$R]ᅧK YyhQ?enៈ~hw^xzt㹊bi,MI6BJj4Sv[4~ZƑ 4Ӳ/[5G)<_Zlt'M.on5gG!Q@@E~_>9Q_ Zzv-Z?P%l[k;piiqvj;"N_oRzO{i:4-SӦak2Fk ^^B6z'r_ MowUY'eo+7~,MsvEIZ-$ IG~7:|w?ĽuEԵMCUў$ƘfԴ9ndAyeV OۿxrI?:ܐZGk`1Mi_\RBoi_/_WA\ +KJ+BOZ~"|Rs=GP6"-=[Ȍ˸2=(xCO'ZԴ˸#=9c%N:"5_ٲ/xUw_붺R^:Yc3*$.qI-Ɠ{|'^^giM+šټp% )wiQE ( (9a|$5M7'/>u~kk/isŸ<̻# NIZGf=/t?CkID.,u-2;;GXGSHjvbM5tWx9/]EijlEyDn[z9xkZ_}V[Y$yHK$nIчUd`pA-W2rQH((((((((((((((((c_06iW?O x>: /?Go=}_xQi"'8oG-5ӇzK3sN#g-xiZ8M|_‡q+U-,y +KJ+ؿ^]s O>W߶w_t?'z.k\f=yqsw:BaukD0֊t/-JnMwcU%q}n1xVpjˤ^[xBK[]E%rbw$nݫXjZ3wo}Ěe#k"V=,$>bUC`WD-(W}5R^T]۷.._Ǧo:YKš,RY:%ϹMUwx`ß|?|d5imi? ~Ϣt9翙",笩{ E}"xkZޱ;; hO7لiexDIeTe8k c=|G}}źƪt}Ȇñ xjm_8$Ž}-}V׹ǣW\^|.9ko|oI<{7vz]Z?-5 jrBHCǧW_+ѥ袶I%m~QY O>WQN.ӄQ$tެ|nWC|ֺU΋kYמg1Ags(yV\3K0C^<\>"1x/ڡFQIak\kkwj8?TZ24)J_h|yA~?L6o]y?!QMK)VT_0%ƝCT4ٛ%&3AT|R1bߢTVʒI|V..Sm/ZUtݹ'=~ͿWuύZxKU k5gs(iR(g9UT$7?/?֍W\ i-VڕڪKutO2,0m9B+RTSQQ]qF)Iw}]ϖ?_<_^/>$ߊv:euD7L_hU#ypF$|ъ*II+m~N2m'}`* ( ( ( ( ( ( ( ( ( ( ( ( ( ( !?٧A\?1/4+);C-%|*F?Anzޓў^b:~ KbE XYh_9#}M_L b hڿA\TTm\ȱs:jܲW9,WW?u%JRҽ6 > Q'"i7%·/K&EHgjjk<\~ӑ/c|@ڌw[yW e3M??d~گM'ŗ~g4; .͐y6R[I<{lminrXy|_wQjv4v!ԬoEqjnm -ZlrS*q[;ɧK_IWӷ*|߱/OxmMS 4ZE3x {fef `&(\/ӿ'~ _w+ot-d?ՠu[2\Du qP^v5Wf?/5aԴ5;kiq/z׋ܩ.Qd6jOANJktsSм9\R_kz>s.6NI-3ʿWbXrC~gZi݅MGgK{X[ #O#=ŚC+46눾Z*Oz_Ê}ߑ4]K_}(0mo~._V.|?R𧉼CzW0vZ$SnCyD+jԾ躿=+w6^niz]כ m=69e$yx`\]ҿڿ)E?}]j>7>V,~;x.cMgZ_s_qir,V[?܍S H>=gj.;og׼W6xkt[€,aaU܋=W%Ҽ|=_^j:bxo:wwq%wgqP,L) `TE];Dwi6HӼ={X@t#7o32I4#L~]uIƒ~SqkM;oUZwMo>k\-wKU3W>;Z,V.:] >$W^=E^'m‡V!xl>oYwl?HoU0 fmJeqo:*Y G͂&/+1_}?WS[dYkf+!xVhͬk"z6W A<#}}/{F >-Id3Hg$bKaIOmm;.Ϧ˒ޭKo9Ir ?{aL]|:x¾φnm;_BJtӞrj.p?-Cg<#3ŞIy ݽ /g֥nyQ_KvV)g;ycE.nWYݧڒrI&エ$% ^I4F/ph/x_UgV}6 V-fmĖ6`z2\{kӫlZ^5S¾-sm[v&m+Klwptxe8HtY;w3Q75ᶽjz-,+;?jGȲGF%4$~ ظ?jcNp|h?' ^ jSOOY-ӵ}:ʹQ\8W\{ou_eϳO5 ix tk]'MѼ=xybLZGf,ijeYnۿ.׽guyWo)~`7 K֙-:Yv1gqk,*$qy-neok>櫥xmJ[+EK{(UfP-O_ßmQ V ;k_Zk6HCm n9Q|;wAxLJ5K|KaiVT{-OGkhn~g6Ybw Ҕ9R+]r4ևN 1poOV>k7?h? ˭Z(ūfK"n hH$QBqL QM~߂ ̾&3i!Nٱo,,d1l39|*~'z~؛-+Qխcʹ'(ƍJ0Ey~? _ZVJZKwpgnYgw&bѲI&~򷣌T{ꤤߪ.SyI8~fb /Bm[vwcm6OQ߼́Kv` k 'B?2^)z.wkDϦhWLym~P}'qc)tjsC4?nyln"Ix42^a5ӣNX4ߌa>84[W&ˣS/-#Y=եSlw39A 76Piun=rrI߽R}iJۣ|/K%Pӆiش˖3H)GjѪeLm-4:b$P"**]G&APJ{_P* ( ( ( ( ( ( ( ( ( !?٧A\?1/4+o VeX5 &Ѭ$o xş#ލOjQ(5(m]cw^x~:L]a#Ɛ͵e9.E~fח-ZnFiW<;5d:Gy~-˭40esUQ͟)_!b8 kϫ ˁmi. Z5f8Yvt/^K+]1^ im}a<62d$دǺǁ4 ⶛t  DU7+kZ{R [d4NpRvOmѳI^}5眦x7o;{ޭ~|? Lj`|5\UY)D\D39$|_(~4?7xzK]猯 y<4_ZrZHT*gT$r[@m)$u-Z:wư2*A wsaǺ60Btshw^W{hfsuy*m>_7}/^ŤF|5?F{ O^74vGdkqo|TWcYQxC4lt etyuHc#Dᔻ˸ׅ~ ^ _XvMo;IwX- )e *&FUfXH{?K|l^zi|=(PQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW?O x> !?٧A_~S'He3WE~kK +X%[o(CP=OO-k߿/AA_`_i߁?i^>֧n(1w9,WW?u%JRҽ6 <I{|M-:X! <0ZYsHC Nm6? ݻ7:Vj^Jc2G$8$u ך|x|} x;TwSCn-uDYฆݯf Hq+")+!~ RU̵ҭK˭s|: -%;Fl]WͽnYYӊOhi{-,+ߵkmgxUtϵ]xbizyNf0Cp#S\ l_Ə'ڴ|Gq૫/ q5FoM.=Roݛ,Cm#nccQ-`O-8I?Ѱ#fErs_֥ET ((((((((((((((((((((+'rm_u?j~ 6b?`ҿ_ԿM,WW}?l/iDzmm|E[-.{'p#pd]|{P kZOZ!qciqFzSOUw]WwlC]~ ZW:.kg?^y\ΤPX]Zpϑ,L%̒iV"s?~>ZY><|O>4OT)NJ-tH4}Bhiso+M$T*qi,]hSMKFz]i+{i eit&،H{f^= /[;?QH?_< 5|'бƷR80yξl#LGW?So@Ah>!|oPt[f-ޛgpaZVܩ!csSs?kt՞ݼyM' 3u>{OsZ&xK9& ೡ;XIS]tU$;;VzU9IwQEfhQEQEC^+ CZ5+ Gm-lE,#@M_t j^[w="OOdPwVװ\,I $eyĨìV_wU. 9+zL~>1hf>V^KiZ>k} Qe'd"VvE%T o__֧u'^k^m :<3UQKP.F/L~ܾ>E_xAҮ~"!|VmM^^Ae/Yiw3YJ"3!de2g סiAwiw$h8e _&bо-k?S?6|Q{b=NOɍ$p`>w 6_/cEhgg/[]EVd#TQ6[lc%֛BR{Yuwu=RgUAj^0~j_\geeOqq<8Afwc$@xK~/Ǎ/9 V JLnͅ7.FW9|]K |DqŭIkh,n5@r X+Q{>s~O=|u=(,(({ !?٧A_?$o3>"lֿfGx"}8EIWOC8Q~h|໙?b}E~gx#vֿO,د BQHy%&b?s_X4/+k~KbzmtdWP 5-oOE3o<7K׎—rM Ɗ\(4Ֆ8y!3! ?#m_Ei~z2SEmc{uijP[gPIm*ӲMrMۙ{9'Ֆ= *A*[+}ײvkUDSRѼ"~Myrx,ZR೼-ԏ-ΨfMJdO߈^Zޏx=+HҼ-'Q2SMӂ%H5ܜNʹmo5Z-h+I-%~WWu`߰oa'OC⸽^G+O]~R68F!~1{KoKvLWl~*FʿN(6_ I +KJ+ؿ^]yÝUaw]y&Ki'`m-YK/6|?߈&cs|.to=mBa=&kK6*%c w{c+Y.uui,rjv :L29"6x[YRUӴF=ik5vگJKVOMpQ 38T讗MSm;_{[R9G{/ۻU|=s-k?Nye'rhHc"bFg6J>^P|Kw]xGOM#ZWȺtdᙷ&|K_jRnT=~!k#]feSVu(me1O&lRTMxɑ7z?8aA=*VR[=sG5hQ^'Liگ>;OK_jhwKor%]>Ks@Ey0,[~9o?Yz5?m/C_-uetWE`Ys՗!Q^s /ߎ::?eV_@Ey0,[~9o?Yz5?m/C_-uetWE`Ys՗!Q^s /ߎ::?eV_@Ey0,[~9o?Yz5?m/C_-uetWE`Ys՗!Q^s /ߎ::?eV_@Ey0,[~9o?Yz5?m/C_-uetWE`Ys՗!Q^s /ߎ::?eV_@Ey0,[~9o?Yz5?m/C_-uetWEx_9o~'5~)|[XNյ{w˅ċn7g$ snj`l렮M}t OcBQY~W/G/%zy~?ψ)5So/ x=~rk1<)Ek_eƯ;Ӽkm[x5|:F[V2Mz12Vo^ Vᾷ} $7+iaSIu5̷ZEӞW+d%P2I2TV},Ѧw~{·t 4oiמy.tS}Oϴ%f9=I&. & PymB឵qxkC}⏆V> ?W.ʜ2@l9(_2_rmYU!ǖKK5M-w2((((((((((((((((((>!G%^>!G%r5C2Oc_06iW/G/%~W1)!{T >z<-p!ebR+¾%[oK BQ8~荸Ii`ҿ_ԿM,WW}QEQEQEQEQEWZ%roa-sLQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@QxG_69*QxG_69(M}tC2O>!7|KdBQy+>!7|KdBQy+|7_c}xVkcJR_+4<kh?` XbR6j~ۄ[ +KJ+ؿ^]yمQ@Q@Q@Q@Q@bk~%K|"2ioɑJ.8$)](C TAq?W?j H.?Q _PϬz׆Qɼn`ho.D[p@8 5G$}}Cƫς >7|^;?4J4k=_E7پKRۿ8+<{^>&ZA6|n#dDY ]99P TAq?W?j` '6Ú6z>#>mYp>ikuluJ;_՟r~\s{}_ᦆU8_kY-acp|D) ϳsCïA)}(u {Yn>^f5; r[1͵Z-G-#6+W>~\'lΙ O %v~<>&-Ɛ\ά$Ŕ2 oh_|⏅#ǚg+w o6Hy~ԮbإX݀Tj7OW_zIw_\ UGx 5u"Z?Xנ60a,#oڟx|Gּloa"/4Z|ߡ\ Up~.~?_ 5|D(:M*t%L|ÎEd|l{s\6xO_7m̾j8#>jODWԥV\ U \x Exញ6Xuf5CyV pںmS1_xk'?lj!7|KdBQy+>!7|KdBQy+|7_cYO~BǏcZWxv$4|ȩ*/O߄'SSؿ^]s_X4/+k8 (((((((/:׉MM{6T#ʣsI$;ݢ+Ϻ] Oxk@ҮX- :H+WV,vyӗ ]\ʞJ_4/Z|7gƍB9ķ~!:Ɓ :d4$x^aJ/ u Ro4a'u CӒOέ"j.-nmG]PEK]..+Nܺ=zܪ\wK\[zh>-j~/]?kF+|{m_16? &Uk6R˧K5GB˶U]λ /YO8<+ؼ"^uw8uٴX6Buu:V>ݒ.%QV~zj|M?<±|2 #]{Tm^+9f ,k5,j(Ρ {!BRRxuMcnr6{j-<ѱSɹSƑC!Ft RWNɯ%7Q/Nv_CNf{u6%O4 Ö:ͷ_ xjbLխ/e;}LZZ,YwUJ?4']:?k>2Oj:fa/x{( !J^7WTWD&ow-6;Z[+;FbKn_IGE&.<|Aw3.ﴍn+ DnuK{{h4MKOXe2\߀Pr0|' m7Je>vd 4&ybGJ)M;=}oo+h(QRK{zk}O,?)|nĝNš/H-6 A1,-m#IGEw'lÛ? iǩW^]RQy#+Qb(e%9-[iҌ_?:|9 'xwG2x/I,bΝWqKHX#FRbg?KCMG[:ȭuN;mNClZDͽJJҋKqk܊OW͠Tn4>i4QE&EPEPEPEPEPEPEP\?1/4+'(8W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCGڼc@k9x^ +>(^1W?}w4}?  (W] j!AxCSxCtS5.}Pވ$$]⌖&<.#[TP_%!{ _%!{T >__},)ֽͯ/E#5YS۱ _b?e/|cKҾӻepyqn3Gp?jxHѼWu_閺jkk˰1*~۸W&̎h~S|B}LJMd%RG6tRbgZq$R4WYWNωVkV^𽯋V!㏍/;9K׮^0Y-]oᵬ9[[rR|w{}Rb⟆m#y|GF1[\\Ew,V-$Wx?ߏ|;,xt*MN ^ #TOvJ/Ҫd`Xd-b:vcw? u{]w f|@2Xi_kwD/A+ pxz^Jh7x|R1_ψ[=5`em_87~?i_/_WA\ +KJ+>(ygS|Nk:ᆉ@kڏ;u(-t9#\g#^ FdodS綗Ki%=CQ\E3J/l^>jYobKi6>ɘm85t_xŗ~x[ŗd5Me͖UO.gʰڌNTg{|wת׿~Es>&ږ@Ic[khy;c~_6,=W^"mJydڢ4, ΧgI%m+ޕא۳Kvs:+W߇#xPA4fm#REVz EiBJFT70N*O~%H9 J/(9l V]~S%M4o]}Sh W-#ZxsPIՆ K^7 $>TM(\/JO|=i8?/K%<6 u+͈e6HZd I$\䣫}&n|nK{=棧O=\">ؤ{dHBA!i%N%a՜zƕo gNÏqu=Z–-ڵ7%WG )85f_w٘h8j/mM(&ď W[iC۫YQRzOH /"q>"Yx^uh!c'_ɨ4Nyڶ,|UEAMl^~4ZrRpoURwSGTWGuj=cJa73X_xčoqǸx-aKYZw̒lSybq Ni9yk3^&c5EฎK[W;']` gId~}N)QEQEQEQEQEW?O x> !?٧A_?&#} _?&#}T >0_?eW̷>X?Q:^k=3>fdIR3_rӷcdL]N~Kbzmt`ҿ_ԿM¾%_x-Z.x,|CēXx#/x)T8$ak=[Q|Co/w,s~d;*rF^ϙ=uZ^F;]9/k>ko&+%k^\.ImjzR)4Hlc[m.4nf;s[o77/|=WAz>xgy4_AsuH@Dڤ(hŪXAu\Ʋ#r8<ziƝ╷VqPk(Vo5U)7}rOܻ;٧%cl,GCv2PPR㢪pQzBWx${)mgmoJifRrr_m4t/Ox\>eO^\][hڱV$wey1D$DD׹c!|BVW|Zޫ94(G[U|KBݫ+$("šǎ5V>7(o]㾴,]>'WƠ()fQ*jҿQTҗݠ~SV(iH |s*j^j:W/3 :\C\Zm"Y@r4RߵZk?|3wמm=JO.$Xoxm G 6챉Dފۛ&MIv\v(Iz^//.^ƿ|w6?^|,4-s][i_cϸfe`+nEv?_Ŀ xkS|9GMݭޏs˫B]>%ntxYdJ>}S)Mn>wz38$W٭>0׿~+J-SI|+鶖!&X5+xK]: g>i-?0K) ]~?5bHa]NW7Ϣ\i16QΚ&I.7 bdYY݂J''vSIJnZwխ/+c7u|QlƩwkw\QOmd[.8Y-)[U}p[IOw|ڹӵ3Ɨ׳Xu. PI.eS4 -vujmKy?{ٴr}KkkM\(Š(((rhNӵ-ꗾ0ē ægiYb$l=*Xy/3'M;tONd4/ n4$HLVaa;.DSʟwQS~\'u.sm^YfşM?:77EcZ6\]1F9EmnuDSf-z _+P5xD^i7P43]O 0e H!Z-q\Q[RᦷO{Y,9)O[;4M36_mVҴK[a-& Ux-V,m}Wڲ |yvXWO\sFMrEKtNh\JF3uE7þ O&ɷv9CfZ[}WK.ϖ:Y5o: fFצombFXnXoO\FB")*wn!Kww⸢Z$ݞݍY;^t$,wddĚY]a?}EtN2Jַm-Q].9owvݵ (,((((((((((((((((((((+''^>o Ή뻹 ,q1٠mB¿@?e'+<iw,`/ ZXJ\7) oIo 7GCs\b~Gr>NaKc'Zd|U}t9'ߍ Ow/0X|t՛YM;&6o%m&fH-vF&9h0ylR5Y.띋\x_ë\^Ǩ˨;fI̻wV3 ;IT/.1I^Ӯ$(QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW?O x> !?٧A_5aTFQy+2; \)wxwr~-%zy~?ψ/`sþ7O ~Y):{1?NoEjqʟ ɺu~$iZZՠZK2ˑ,(rHA ՏY6 ڟ9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟMa+9Y6 ڟ9inׯgYk[q{e5IU[nq`5Q@~_[sĐ?o~ixY8>vRJz;oj-m2P8_^kVdMtՀ7Qhv|oB,uTW??MΞ^VZR\\H;YV96bYD?ʴ*>;mOfE_N{?l|oB,uTQ Sc#M *?#M *\N?>7O:*( ??Q_ŏ&Yŏ&YN^߈?c ScUxu,uTWwD_ceHk? هO~7cu8GPE(+MkTr;0EGh|) CRO>qSʊQ~*65,9R 7_G?ʎ\'f/o_o{ŋ0C?'8j?Mdc,|)SB%mouuOO?$t]kTr;1CtG&R5WP?~an?f;wImou?1 ɄAG!̡ K/ ?pԿM_K~ >:Ow/%[N&0?9R5J\<#u/SW?σ?Ξ_/iogG&8 ۛŷ /X_|?(L'fO??e '8> ~qKSZB 򚣹[m?N:)f?8L\Gk/}Ok ه??g l On? G(]gY_? Ӿ:|N~!zs#@$|'/SW }stZ< st0{~ zs#_(|'?SUi"oM_g _n,uUd str{1|>"e~>/MWl&8_ |>jS]ү?\K>| stra{0_ӟuSּ7'PGSʊA#1|22]h=NS4|821NZ,;2#zN _?QG4R{ʊT~.93Z,~.93Z,;1}c ?QG5S{ʊU?qųqgYRF|-gTr;1}c _?QG5R{ʊU-83Z,-83Z,vc=?RjO/_ |=PEC7iH-?ߨihqdۖ*_8{nz,vb=/>G98QE .*9p}cOʾ¿QE|Bc&~w{Y#}AȗF*|OikuYU ~6x+//FƝsxw@ eyn& Lѫʊ4 PN[S/ÖRo}:lNUnit-2.6.0.12051/doc/img/console-mock.jpg0000664000175000017500000033464511713252032017606 0ustar jtaylorjtaylorJFIF``C      C  z" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?OاOhy=>&4VzwVkzu7I䶒)dXQ$ʊ{ ?g> d<eH o2ׂӿQ͟2ohVZ-H9̒y`N+J]_ZBMki<|$2~|<n'Ꮘ^m!җYKx dGr77Rj6rVm_g:Wm( .> sTD?kQmς?NOE??||N׭| 3uzs47\+BX yO|IhڥÛKOѵ&KfhcI yۊ;(%%nUy_N]lٿH]<=i0Fܝw][tKN5c!'~?U/d> !Zi;_||b׾ O-F-hֵ[{kKMڡU#G^S]tWң 3ܒN8^6ukN*ޮ:wN/+ nє(ɽ:%%u%vgnZֿPo?O4Q=K&íjwkzll7j ) 7oqe \Go6#5Uʖ/-?g_~$ WYxwSm4ky 7-mplNDRFi8ѥ|!ǙNVպzr gGSUoFOYy-vz7]Ҵ|w"4A=_z'"~ޞ ޥl5P9|>Om~[O.[=`̕j0YZYoC~ l5-z}sRÖ:s}/(ۈo ;i$q)F Io$&)J}[Ks۩z'"h)UCcz'"ւA2b!Bԣˏ/R᎚r?`#5$}'Ӽc9f}$Vtycn,DhR0meZ@Zeקn5L>#[]y%HP>GeGdTCZ §29s%3O/ÿV4-ռ3-p3=Ԧwkwpθlo|cg#i}[PDu_qM!H{XdKHpѣyRFj<*-/S^vm]YyQm{Y;u쟮/溞{a4x$%2'Z"><وOsKPk(S{5Ԣlú%;l@N'8o2DP>EN]Ÿi i&fesO>HK` өJRoޏ1EyP !q%_o>Sh:¹пGⷌ<1kGӮԌK=+G!wm"wUPK2 9b3XzKdķZt]G{Lh>W)`Fe{ۦe T<2ž?\ v3, |MC?x犦6=\vPH-Ф:"sįҲ d淇RQM?$y-ufwg #ƃȔ=Ugiq%g_xZ+ZxJrIrMnU\Ry0|44?'l6NU|ojj^ü=[%_h_PwUNt/D}_&BAni{*Y&ƗI<ws%L y(\.1TBJ+4@'B7?} WܳM /߃$΅ȕx{0_??]+;曣OWb,]/ 7ZV}|kd7?'fɬQf—$1:PU+Kl]C'_=l߅|Sy헅 85COO Kѧ"cKJR(TS+;SSd,>|MCZ%5ӾԌn?_qKyY´5T@:;zMu,H|kGn$dT)*b,'f&ipo??N4DpCdb"WA=.=+M.H&Fq̱MkZ_3Et\?ys%i;5!\'"WIe)c(Ti*3qj3/. Bҽ_8|rï+y7tU߻9a^1isZ…?_qljq֭/ ;Og`?tSk:t{_)8mg_Z|C=|r/z5ap[ Gα+W/<[״[{Uw`t:\wÿ?L|;Ux9*K(^Gl0VyR3RcwÏ闇 <1& |5,gB+^Jɭ%~Lx0gYxB`7|1*4!ֽ(.*sT^}kH;WGk{VPE#9Oξ>WPT@:<ŸmCzU״2͚X?Ⱦv;ƿ}/ |47Y>| XhHj/D1_ӭem.O巉wDCm?xg~;oZeͩZG\-յ\FDLunM+//$}UUxzrkW}j?f?'h7Z#S`zCjWr/RWqDz7,Zz]Q]\٭ċo$GhDlF䟕z*8uUתTE+{;J/T W{j+mMZ4PZؐ@~|Fd/<&VQj6dmq%VXeE"nFA|_vafځUYvg忷u!W w_ |YHWx2Oqm6hj&+mTgEтƽYmU﷿_ Dg):^Gn$M۝gw/w_]Z|!:6΃-̢֒W%D|_l/௅C-od$YHcLIߴI|7o"GU]H@tV9γҌMgimk?描eKJQz|˚ɵe黿>wjT7ȸkS?Wƾ#GcI5ٌ xgi1po|`׿jJ?#|5 3kM&{8](v";;/ºOM6Ohv^3QyLK|~L@J$t5yZR'uˍRWSFcmHvU>!7D^4ӭ=?MӮ[bk{yXἙlܫ8i1*> :8L %?7i~t|]yZ?%,³*Vz+%e[uݶ߲$n>"qS~V?^:9?7~>|:¿L*Q^<ֻVw3wM~_â6'\ؿXK`254ߗcr~jh|uXK{/i:֓a|[ 2viXfCUPn?ǿ 8o?EkbouLO n5FkKjJkN.ߝt?cd)M9>"|:ۦ-ߋ<7}_ˏ+.wo+Þ!?[֏m[}S=8fx6gvM6| ;Ze?ĩ,u]j@\IF)Dƈ4ˎ5 | jO8aFm5M*}e[+ ex~o$of~bU8c#@GM_$Uhx{;x~ %ml{f7* YcؒbU?voYߡ^&~9#ۦxJTM5m}Ts]8Fپuݜ(MHK5x/_ޭsqXxg\Y[5hWEK"H|ǐ^?d8G"|/m"?ec;E#[Ec>g?Pu!hQ!+32=ʾ2~o"хӺײ{Ww&PTK7}4u?c#USI|-Qi&Z@c[M.X\v*9uԲH;&s7g,hk_t->-?]R EG9Soukޓֶve9UA% _$U?Ś wF?o"UaTX-@?x a䯥-wR÷_:h ݥE<!37}+5{jG$M_$Tq?_ҿ"G7XJ[]~rFUǻM VΓ|Yc,^@H-~qSn?i藅{{9}̹ E''oqVKoX$lŞ¿K䊳4 $oߥE7VУ^C}[ y Z1>~n"[ Fo~/{H26oYf޻6x$s^oaxz/HKW+HUamZ2ҜM ǔ潹V |go"ӵ ]_nץ#}Qb֜`-.jGsy ջ 3yv??N'lg?MT@?gնGy\7ҽ{QWf ]N_s+ͯ($K t M\4+MW$S6|?J^=}O>20H95( @9&xz؁ oOHr|>ݦ~̌_r< 06_Hx*fLR+5xbR,0|0G?~!oa~ Zqյ:%8%ԥ?,D|im5IӮ9&? ^icb_)YNԯ'0XiCWROY/qn-jR_i{!QY\ܯ>'M Am@$& k5e8+Q"m9<"ßHgM#iV|>M#kgG:ʱ_ "՞PNk{K񏚹/R|?M#j>M#j%Fq\w:v5nXj j)z1S5gsdnoü4I%Ge<5˩/IмA-cqsye\{ ݢ\FH$ch7*HelrWV|w_Wjj[?t&lI 4p1SYa.n{?&} Ѧ*MݿӠـƯ?C\BGdžyv/SxIѴLJ:j?t" &=8csxݘ溜I'.Cfk_\I/NIMgk_Wo F4I䊹 / JZ)'Zc嬩/WN!?}Y%xaoۥ͑+EkIYOwn gl`A$Ŀ3W$TPx :i_\.*_K9puCqVىkj;r?H0C7csRw_X sc>gM++Ǘ d 'i/u8gf/ wG[ x_ /Wcj'-4H aNW$T*ٯ ^_ "1pA>$Odž,krڍ֨mٱ[+n&A $8P\?,<_2ŏ M++_F,w|al5S q22  |^? TFʐX h_80xeCLKZj -io%5Fӧd-e`L12p;Hy]s泠x)t-@ǨMG<,li5F\$|~ (şï.?_NJtM.S{wx&CzӟnTvEg |E|!C s<F([v g[t$E l`1GCG<zǃG!Zur/wp=exsSCgY>(kۉ< \Al/n̈e /τ&/)}[F-.t-A5m8F PѱdF`nMOKl?cm;tZ|5{ ^jvK0h:7-J??޿K_F+O7.7nF(߲>/w5ymַ%vivKgR;YZDHȐyQ@Wa-J??޿K_F+O7.7nF(H>x ׏F!̡mX%mГq.ǻon ( ( (`cO5ž~xPNj=Bm68Yd{fH4%U~rQEWI\|!׃֚>}Y-_r"ݶm#EAn|5uVe n,nwm=|stQ]'>xm8еP[=,d26CFm9( (Tdf6Ӿ7EnW(>Oa~- * C +W\ცy]Q@Q@Q@ꚟ여~w ji/ż!eWa(aEp0uKs泠x)t-@ǨMG<,li5F\$@<~(OKmߏïkC5;{dž3+¯)$ Dv?g/Sg@o5}Y-_r"ݶm#_?E(\^Z'do{a#88T-rKMR5Mż3< ;$h&Ubc UhKs WJK^kook-[:G;Mkz:m(X2|1k|umWBh_mm;KK}^^!0Yl+ Ir.qeڢᦁ;^xϋ}cGEKWdzƗ#_ħ<0(UL~n~K|9i~ MRR,?/ln" ('?wq|Geč-4閳hmwz.ı5k)](v'ԝ'?k/ NS ~*?\`<5lP {Rkk[h\J8$- 9IF: m#Y'JckI+_\He x;.~գ Ag WⲆ;sK%$my5,rχ%ZW|yxBxRk7AԒ#ӧ"Jq#WbHP?e?)/}滫=xPI"w-aK+bGh.v*??gѩh$π xT.a|C4P%ݽ&Km6Ţ6E")??nj<'ij?>VjZv]ok]2xN8lEց~ !4=Oėz%Q ~ xã}ERi]*K~\BB|I~=u[υ!x<u&/+]mp; Ѯ?~=/v$oioᥗLF3oKv%%;YJ9C soه}>H$[PlS6 MM'PE8heҭ%Pn'<|Sk?;SZYG΂,VULH")*F1^> ]uO?XUt3Sk_Agly,2,rVwpC<ɉ{ٓ G 3?#;OD^ѱBG%":os ǒQ@:Oٳe&^w~Xxo[Ʀ VڈY ,H.#!-t BZ~2YO?>3qW6V8u9!Sb |w) (oeڢᦁ;^xϋ}cGEKWdzƗ#_ħ<0(U>+t߉߳G~!xMfO=#pm1yjѻߴS1xo⎿{>&-y ) 5;=lq N~V?v-/4k~7:mmZ> vda0YRGM>7߅f٬ xnqɣߝCƟ&'Uaw-#+npN  ϣk5;ؼ+=?GNtz"ަr {kcuk$fGGcN_Z|xVs|/6=_Om.'XԳelB~Q ~^ ?-<Z|P^}2pt&ːe;s^?|?ƭƿ,'\Ιዸq^Am:Mn#(c8GTi̟J?ho|$ǿ؞) !|z'ƍf9-|{(V\o:& i yDjz1gEc>_%7)+g4y-er$KyZfT ?fCu7<7wV15o >x/x WdUg]J=|,~ 4 WM*|_p<*_hj#4%8wB'_K_񮻠>/։j^-n5m3Ib}I^X!Yܰ +yV)O7Ǐ쨴ώSVuo ,kx>?~ xS5oz.i/,iQ 0xFk>þ1c⹯5kZu[zLt؟RWD+s4cw,%q|',xw6 Vs -I74|?5?:O5ݔ1_^io[Hs n0aO{W< O4v&mz?{W_/fH|Č/!ՠx%?<1wsn5k-S6#e gʐOtP훢/վMAx᮱:vUѿYi_6,+}Jxt+? h~&@ns7VRM',@jF@oE}߲G}MggZnj.~!h 79}Gj#iWaD {%@l8'oo>|5`W/$lVPWCų ~, 3^Zx;8e7]ۤM9!B#w?ث_zC $Ѵ LVKMIh5P#HQC|E~~? te +?ٗж+ab{+!bccL?_|k#~}szeޟ\ Ŷ0Hmlm2DOtPg~|2dx"}Nj!A[.r,淰QIcYx^BӢN4 q㗏>xÞ8֗D:\2[I{\Mmn<18ksg)qHkQ%iZuS߶&m|};R`+hڳ')M~*'C4I./4m?“>w=ՒS@c|Ag8=Mm'RPdۃL o9x|9|Mi}C]\^-?,w fUaOc=o!i\^h&}B{%qq4zO(ܤ({?j&y>/I /k]\s VO?Q> L~>|;j:_V]t>ZI}@yq xY@cK #~m?|Eo4{M#w5¢?tP?l? w)SM)G{)6 ۑMtGt1+*#O3ϊ5MW%[WORioIk%זGK*Ʉ{@o>4U .X{oᾋj~!GO6i5yyg75ź 5uu";[it&nkq&PȰF-7?df/A/zqvDٸ%[ 4~@-^+UY?ث_zC $Ѵ LVKMIh5P#HQC|E~~ƿP?b] Q ƕw[?-bf˱ӵ/62y>Rڪ~T~ϟ4˝[i]o25%hQ:6 >.^"J4O?Ÿ6CBŻ?׿EĩfxN)cM%㶴=JlP,Gd_4/ߵ|iῆO~ѵ/iɨO$vl ec d,evn,lYæ~κnKxcߋ|dz$x[[ӣ٫ܛi4Q$"y'(mƾK֮^?+^?aꚅ7;o~K-oP+y۶+'W_tW yx|DR+ @Mov\ȓF"B"W?'/> gŏ_?%lEeloq`~ǃLnOu"V Ͷ780 /:d:.}emCʶ@1*G(G0">ܪr:(<Tῄ4]?Kosge˓Uyjm)& osp ?e) OX.;CxB5-^i:dg=L"[Eyd2wtP>s٣–q7j0 oo '$^&_%CŖZ.y=ZѡxaK,R_.9XƲx~ǃLnOu"V Ͷ780 pt_ɿh/|5<#_Z7u -1P߅vqX(6P7HJN+h \ԋT|e^>1N<+_*%}+_ F W¿UJ2|MqpOШqSz):׊,O+_3-_LG+ ο%o>3B$~ǨΒzƤqYO-1ݤID~w?R~cLuao O Sio/?$ѵMEnfȼ1g1{J.>8B<5>)A}i46P}#ǪgK6O0d73:c7,#kPj%9}dMyv6>>+4*5u}DxwL)3ڮ 7Ȇ;X~*c?ԾlB[μ~bOğٯ@:O84-C: wʶ*΄# ?`oCPZ43Z>j+y"0v0 ?`,>;/A-/< n-rG ɬV[hYD10__K|V/ Sp5Ũ_]FY C-!_5䳺{v ?i >5+;uWVm*^ 绷C,Dܼ$ĞHh<sgXxU,uk JDhV 饻{s4,]W?g~?fu ;Yc6e!$lY- ]d,? |) ox/E>ԗ&8nlӯ.$WH#ɲeT!p??OuƲ5 iz{0ݖT4[R,sHc7~ |7V*[XcxZ|=q$I K2c{x%) >zOw(x? {Okk3z9 oϧ]isiP8&\Oǿg | SaXtjZr-E曦I&ZkȂ~>G7xaaAsm}KU[[h3k֚;}m2“y+wŸ~ ~x.z}šNqk:ƳZI5մ0$x^į( 滫_U־7W- :\ݣh sj7𝦋 lrj4 V;9sue$r vaT{| 7 x×?.Ԧw`Uhvv6\Y-(#W?bo(ß7O ?4׈.mOjkmmzWӓO-Ct[yRs H%Լ)z׃/xVށj-_W:\m.fޭ$FaO@H{φ!eX 🃿f OWxwm٭eyݮ^q3C)$,1#!+wŸ~ >|k> j^~5mmI|{+ +5d#tIt?km|SI|I4?Go~`v_kpdtyU]\eѕɐI ?nψjσi^x'D?x%Ť\R;4~s?M>?nٷ7ӵ/"ooWO/..mm z&,2,QKt7 ӿc'VcWWS&'t r{km){o )-܆9@gU|h?}_tX޷ 粻L{Ctǂ0 yIP ῇ}<<84mnQK][Yi$H!h!Ǽ9|?е~5Z?<'x~Fվϧ]j-qO6CHҠ,1Ꮐ?|u x 𞍣y:}uPk>DV-Bѣ'AF (M,,|uy,ݖekkLڒP|;[.ƟoiߊçhoƚM2Pۣ%l|oI ŏٟ< /x,Pj^o㤹ȳ[K=E'+mexB! ON> S:DӼ[eiX]( ,%yHgV *}~ +QR_#E,{в6VRT }7g/%]O>񽮕xYY,ѡ[8XdI,YA#O~_Q CgDǍ+Zڤ 9dmFh;ӯ`cO5ž~xPNj=Bm68Yd{fH4%U~s#{|'9 G&_y', b'O-V>V>'ƿ<7;7<X][c Ԇh(Hs((tA|E~~߷/H7,];xAxo"k{ im,ܭ5,a>o |3{xQAuzG#:%w>\o:& i yDjz( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( /B?"+8 .| msR-R>Nǿ ~>58'o|/__RJۉjkׂc͂g'6>GA(W[sFIy>46~? 1k:i:?JzO J7ߋ$ w62ڥ(d!?abx_؏q_5~2ԞC-M߆uH<k-5D|Cvazм %1QjrV~=l-bf3&:Eo>x㖱G'em<+KTh utxw%073F>? ~ 'mwk3eu-{͠YN"?ٻ_ּx>5ino]cAgT6z-ųBk:vy,I7 c'|2𧄾//|WKY 46zt-FdI.\H' Uj:,Y>EqDJA ?`o_aai |`s_hZ:V.- ߻e+"I|q~1|1uxß |P];G"M[J<Msӽ@!GG|GѼCX[ž0mo6(E}gxeŞ=֗j#xCBG@] z ƺ/!}Gi ՘k.7[eUg;ƿ+׼~|YxZ?/ ~<_/ƲzMFBΗ_jpkLd]=n'~?to(CehVojQi<-\Ͻ≮VBj,c3kς^&wgºƱ(DZgkY*ZO"tZ \!Agᙼ75YC_i&otwh^xR(Rɵ8{Uk[; x?tm#{ {`K_h8|_x~^) -3[?< kڝ|Cԯt+Iy`M庈mh<_ږW~,Vi~X,XJ ?K^POu?/OM&)uQ-Ps),__Ï QMV@} ž [Ě76A۫]*Ф夁CC$BS|9S2Eվ!xG6~/xC0Xuk[5FdV/ x+JU|Iw1|_jpC;KtI#yI bQi"- xv῅o.wVewkF'8+|3ʏ>gĿ kQ}%^$מ;Mv;}.Fq4\&G$¡^?)^wKﯾ(_@hukHʩo,\a۳|~e|Ak h֥V^46'ԕ /+^?i,> yBoT6Xkwf6+ӧK_5XڮW8m7Ь[ N_o.9B߈t91i2Ys\Im+]ynT扚)Pp# $k#콪/CS߂7|6om95?WSN+ GxbV7a)dg_R;FKR+;twbG JDU`(_r~Ş ~ʾ|῅|;>Xnuz;e].ytVC%D Rq'Zt}r\#]jƑX䶐yB:t@쎑~?ImW_2(k /OzV^W4L}N^#17VUSIhدH~. N[Lj}ϙ4gncmu(mşهZNobi&M?ٖw>N-Oh6<{  #"acdblG>^ݛ>]7?aOς!?_hB/A[g_{gc!4R]&$P]HO! WUs5 Vm椿gFXdm2A#P`/__]]x?A ɦd>WM*^6喞hmDf$v`cg^X|3þ jKoW=#̞R؅ lC=/E]A5 _Gcs5]&Ly3Əۀ|~7HH/x?[ mAnok5iyvefX-fJI>/u gi#,3VgN~C[pnϨ@|˜r~gj'a|5xxNK#M;KXM38X效E' {|Y|5_&oCgsR>$ٳk#DZApP0WO>K6gx(ƚE:-Z%w;:TLmDU߄>"4VgoMR^ݴU!XHAr$~M|z7G_gDx]X&.n H Zx;f~Ki׆Kſ4-lU!,c_'͸u bcj"IM>7躔7x:/= ܃疭A~ ֿvľ)Ӧ<9asiQG<&=U@\(cQ/t4OYΖh:jxq+z4('hQI%BMc> ~x.z}šNqk:ƳZI5մ0$y]}M7FdهźO J7jw^!ִ+]nT5(Ѵ .VgD +!1?uOjw)gΣq%̩ii;b#%X@IF0HjIK]K]b0YZ-oc_[y or|B9 2[i{q[x^ki.k(1irPW7^@h~/x࿸Q\4򫰺ˣ+!$W@x~_47  >EuXj3]7lXY]mu?/pdo7u&1Qx̳Ϩ][;hu n~i>#.qʆuߵ|wý G6oY:]Gh=̾Qʐv,v>~f i:?Wh~ 6PfY:>vlbPn0 >m|?'?A- |>&Iu g XaإI,IQ}{oiߊçhoƚM2Pۣ%l|oI ʼnS 4}f-I}jf8qs3o$s@ O٣vS_%?km즕4yREđp\n Dڃ򾽃g+_GW S/Y"o;ɶ= kkAÞ4|SMxrP()xM{,Pu?o٣?S?dl`&qako`_6ogRh^yaK(o!`+~_h Ҽ+XxX<:m_̾\1f712D0|=L+(c?ilRZBFgcR͗-|^/֙ #S{ i:i$V"L[$$!'>}ܥw:ė2Vvňb' (P?Q??O~*~m_ž )]u;h|Me4`+ʒ.$̟˂pb' oo?Z=TڟIJo-mYyf]f~MS:~w/xҼImk+ay{卞?a7Ϝ)o_ÿ<W?X}Fwپ׽y~fqHm_|LAS|5-cGWmP: ^bS'IP' .g'~;Gv=c'ٸKo6Du_& $1xo⎿{>&-y ) 5;=lq>W[w7⿰L<=bk5r[G381c ifSo_hkg?ymݟO~g|>Mt?ޡ?E4 1$P3$PIO c(e-? 9a@3'w{/_HK.k6fޗwKJ#\< ]uO?XUt3Sk_Agly,2,rVwpC<ɉx??ٯhZ^p4w{YmIQ#=G)Bl*oiߊçhoƚM2Pۣ%l|oI ň~̟J?ho|$ǿ؞) !|z'ƍf9-|{(V<~J?h?f?᡿''??|x_y_3xY{|Y- ;^_tIYt~]}5͏-i#am_|LAS|5-cGWmP: ^bS'IPW|~!ξ߅} f4[}JG<^^cg乘f"9 G_?E(\^Z'c_ρEP ҼCgO#¾ҭ~:W^8_l/g  _]XOFwQJ97QXṵC|ݜ-SgҔW?O?a n?`2c$6-+ O7=X|6V_+-MF5us5EQC<^[o~[>~kM6YJ~g6O~~8%Cm.yNW$\I?O8?u6'4|)x~ccA}-C_x'V.$>%jh'ӯf`KDB#'|1_|8xX|+umZEӠk;yYLJZsYK[]7?h k~hK:mCÖ:EqO ncجQd†;Z|Fxk_;C?_j4J(xosf* Ef.1XwmGKR> >=h3ѧMw]4m%vFaE7[|$j*|Uu4j?/ {E=S#g]o' we<:DW|.?؏;-VOӮ5%Dw2YLfi|щ L~ƿ<7/M'L=jڊGikk=6ȁ D.¸'$+5?A xE H#[mK\m2k3fB" ٫ূuhW#מ;ž6Hy#\>YXSce%4? w-wޡG8OZYiko pʲ2D,"Fh=#<sgXxU,uk JDhV 饻{s4,]'?g~?fu ;Yc6e!$lY- ]d,~Ͽ5]|S#{'L#Y,j 9UO2Erb_UOPC+?R #{I4mRnfȼ1g1ǿ_ş|iޭk"Ρ|5~jxau[alӜ K7ӟJ7S'eZuƽHK)/Һ1!aI>W}𿎴W( MmuI/5QX/,+lP//_~ Yjk|^۬u^xkWu/n$#᷷0yx1^5oo"Q!w>o> ]uO?XUt3Sk_Agly,2,rVwpC<ɉ{J7w^)Ycd7\/r vZnwG7xaaAsm}KU[[h3k֚;}m2“y+wŸ~ "ڮ>gO?_i*yi?5KZ:jiîkeżt[/%]g m|= ܃疭GbO ~xΏk?Y>mlwRi7ͼX´H| / 3AԢ׵JkveQgcj-@{b5}}S&|9o#|G/xf׭5{}94ybd7OU='2z(V>'}x浤H5-j)S-zd=Eo hvhs9 񗎾%l|J^k[kΏsuråi ۽:>֍m  w?tP_l| WmS~eA|okj}V{;eK4hd+Ŗ5Y@@H=A|93Uyg|Jro_|X~ |=ѿ[_Yg[N_^ g]J 7ϧjQEbѤ-2yt`'?W?aIu_MxU熼+RZ-qay}&)K˶`4h_~>_ms};o)nd<=%Wn <W?C'| oJxPSio/?$ѵKŻ[[k"(!/-7z_(e?*ᯎOx;׊xSt "Ķ s4S\w%זS,?K=(Ŀzžoh4.Ε%PY.@!![u>WᏀ?|u x 𞍣y:}uPk>DV-Bѣ'AF +z( ?yl<. bÿx"`>.R$yLo%dCkO|g>$G xMB֮׶@|'J<50R>޿W'J 8<%zV]s0Wo?џvOC&owG +wcgz_Q[3嵑7Jx_w*qq fǟ5{J|\aP>'ox(Fg(N#yn]f~MWEi<$|9Gc_XW?wuWTLRxm+Sh|@ kL]e߅4Nufkiekg&`- ےIE.|g'd[mèmNλQ|C~+|5miZƫķ~ѯ5qzpI$f1R!H@IϪ~VM<)Sgj&ۍ'šTRj:q5Y#1Px?~~?!ob c>mèmNλQv< :ƱuNTgSxn/ h֞K``Y{|Y- ;^_tIYt~]}5͏-i#a(T' %]Ӽ?CM"^-b;e|ۇP@v*&6*w~"o.u _UGPu]iMO30xT33( I>E{oiߊçhoƚM2Pۣ%l|oI ʼn[w7⿰L<=bk5r[G381cPZxWwg?k>mߙu/}3O|9׌^;@" XyrLtj&G@[w7⿰L<=bk5r[G381b|',4_ x6~% %,)exu'`MNL*ȎTkjI;|I|/Z_wMc.b?'mBۈ‡@ ((((((((((((((((((((((((((((((6P7HJN+h \ԋT|>ƕ"#_1 WzY:W̟,pqxoSWn_*,xef9&_7WĥP(觷4RzC:1Og](ԒH2򩄧9qW4I:k<]>1xmR'K/./]-:^͒^ϤGs%nfgi]LQfl|,ڟ)ؚtC𖏮>*M"^-bʼ_'͸u bcj"c?롗7w3F +o@x-;DմPEsp"W4#Tpέ HFO7;',?hyݿÚ[ie-fь]cIDkRPI|ou(ou?^x]k*u6<KXn$\o$ʯ,+SKz?,7υAaџUgk+n")!"O=#n pUi&Mm$HE0=Ȓ#HX 喟;.~գ Ag WⲆ;sK%$my5,rI3>O 9Ѿ  6+wX$6>TޤAd'I~͟/X ~/] &xgY`iӥ;1kۋxH?>5|[-_↱|RO4?ǨEex@d ;e>#ueQ%353xxDZ M\Ifqqwymrkѣy>{Ř-,:giv62jP)9!m#ADUPꏀV?w_Srh_oyBj4|/Xu ܯ$7_ayϴ#(p#f&?=S/|OjkO<"|c˦.l^[)WdxR-qaE~uװx१Ý>> VJ|j5Srui#61,x@B(P'ß&]e1x2 |VsᯋZ?<~_cU[CpVLQ(3M#dBaE|NNjh>)jcIk lr}EK6\scoCῊ:;?%ƏkGx7HbO+gC쿠kZg<7{-M)wk5][K+[83o(NܒIC|2~u m\?Vx?"_,'KwDwoٟm{>5|[-_↱|RO4?ǨEex@d ;e>#ueQ%353xxDZ M\Ifqqwymrkѣy6?f/?:ív#X<${4ڨ06ٯ4ոQ!M Q#/ |^C'1n.Ge ;C[~KCqksx# K;',?hyݿÚ[ie-fь]cIDkRP? k^!k ItRKN[[*R=Ď^%" Y|g+_GW S/Y"o;ɶ )~ BK1hvJw-o49J aWW^5-G' \4V_kkO qVXg oE\Y[j6zĐh+&J 7*Nρ9! Zk k#MMgT[oR0LC],ƂBą:+>xtkMbݯY 9wB {H_xc6ᵷÊPeX̧`$poGP>/|RV‹}Z[uMQm-, G{X L\)1@WE꟱여ۿ4^|7Wkv fW^&*RI .<(( 9!i4vо=xO Y1iw}5Kq#F8e;rWy"E^5OFO:%v&WmŒ$K) ,$ph(TdfOj{/&BF:i*D["Cn tQ^?ؿ7f]_^i|'oo37Ioo"|9I+ 1 PҼ#jV{/sma4Qfg V@r0@>oG?'sƾ"RƔ^44hV$,fehѤVީ /^qG_r_څ?QMN[wScgrC{j##]+"~$xR𦗭^ou [zw\skM(azII?!^?Z¯>oPҵo5%=4Rǽ #mua%N2 =Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Xmso{kjW>׶@|'Ju\~Ӿ.x߇?^ӥ|kNsS~ҝv|eu>Gjb`scZ*o9no>/E?2=p m~|+,q¿b/+Tt-M>,b~WLV5MG K^JgQ_rxMѿdanM׈l [-J;84m=geKQ5JCEyg݇Y|- 67U_gM}QqkqvGha deLJ45hO׳|T-xznj+V_S<9q\-/ln*ƓV8 n|)gZ5ֱe_oO A`|Bm!4<椛 LK? c|skhDžt+o_ŧho-̂+[vwY@᝘2XO=x_?U/$lѭ/oC8_fb8 S‘֣J?8ҵz%lLv67vVѿfO'RUC?71Ee?&_4xoT @,{[=0mِPC{;%œ%n;hO/`Y?? XZg}{.͹?;[-Z7}f/ Q1=/|pd4x3Z=!FGg3y_<?fv쵿?/5σ&ʞlkfRI4yB OlDawpL?~j)jcIk lr}EK6\'eq x7?|1ijMoa/h飄[ {)?b(o dxWſ->(h/e}>s :|WvEzeP9?Is?!4 W:8liyIk1,k;$ {goXռG_ |-:dz>7tn$ZmFې;ljG)͗|=#X/։j^-n5m3Ib}I^X!Yܰ +dx IU^|Ui ~0:y~mE,FX8$@x~R_wW {P֡+ƓEV76[W0ď%yK\UcW?AIqyi ("Ɠ 9ki< Gr;ߴO[cŽ&&oGI滲+2{mi.bA5-?`/ك7]wA|^5;}ZԼ[kfB![``WY(a?π_w:?2?eh[1=|lχ|1žx}d7>7WCK l~$s2\ ¢N j>i[~K:x]WKijZd6Owe5vE,;6%?>oj<_ L(5=.}[ƒsh&I n(7I"3pwhN[7y{>ľ&!./tٖH;߅vkh3qn'Dݽ_.'~.xľTִ4VIqc$ܴ~m0HN.Ы)_ <-xPѴGme-̒A1Dz6U؄$@r~?{?힍!Ơ,Z-Զ<[@m^Șo\ӛm];Qվ%^g(~N>.omq Bd{k. ?߱%xo|qqZJ^XxJbFwO m9|3"炭k$<=me|P+m[ݥ:72$ѥ/&O߄V? ἟?Qsr,Ҿߪji&xSO[]?"I^YdhJ@ .|3➁~ WhZI]2DQ+'6]i7n$zGeq x7?|1ijMoa/h飄[ {)c3jҾ%mwW5 oy66;M/jB{w/1z?/ .e2 VaZ0tmV,D{(ׄ_k?[Oxķ75֠'fd0ͤPS.2pߢZ?b W3#~W^~%AriJׇeQ嗖?6xO\eχh!kIu *g߭yjpam[| Tʒ?7i?%?uڏZ=jL<2.<\oHrT˝D->xO2PW]Kkǁ%|B?Q佱K.C ,C˕6_T3V//{O}>[(>eh}{3M} ,[xe>~?|s4|о2Z>g_MǺ'|5.MMJ>)fQSyg'b[7{'?|]6'ԵX6iɧ kC!xʭ)9~c@ |)>3V5'FkW YMM<5uml +xeDDͯw'ڧ\yP5/;Clj{˄Xf2]39 ӏ؛ = .u oZzA^moh!(|o~#JK5=n+Tfd ̡¸+08$s\QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW>׶_Xmso{kjt,~/߇]S|iM?.xwJ58EU~G<zETrς>~/Ѩ_őd/5{~|.wm_~ ~0^\9e_>ɍ߅3 +MH%|paCspqZuS>sTjIK]K]b0YZ-oc_[y or|B9 +>K3|7𝦋G95_ ik,S{Y&,@w2*CP=O %VӭE&,BWKp>Xa ]@}U~5 WQ/\#K,*.f8Pgv k> xφeh *QV@#dUI7 <ފşӼ5N4eΡGgK\f?kO4Ÿ~ C[?;n~G|X\40Xh|@ kL]e߅4Nufkiekg&`- ےI(<@M3DEoiqoLJQRKn~K&T)$?ş_*ODYg7O3{߳?&(OO55'Þ+&՞ioõʸ6 2mEHcn(>K3|_ GF}w}W?4B8?;𿃼C|LƕKo\i[,l3 Q|!Hz(>?> xOÚh%|<džj_\$R%"I|cOO&'L_ywq¹iWauqFW&BI$<şӼ5N4eΡGgK\f??Cහ9֏>B]WˬxkK֥̏Ie-Z$Y>?Ewo938$+Z]wW s O*YK;+;/~|/]Eމw.n-^h) ~Pz(gǿ>MOi<-?Y}?>1HHſv˻8mÊ)\C| ;?X\40X ?oo?xk~+i4;Cn˻ϼ&W%$333>?E|ŗ:ׄ5o>I[Xo-5++5ʹB*2UlnU# ? j٤fqbH)\C| ;?$ {;{XbTD Q36ÿ w x. xv{MC5x Y4%Κs3LdMUv P_K|-oS_ Ө) ; Ϩ]?O?/4W×2jV 'Iy .a] 7bҙy|*<?'*_Z O0F[=$AE\LayMt?ޡ?E4 1$P3$PIO c(e/C|u6??\M'HӮm ئdз>.dޫ&4 #3şӼ5N4eΡGgK\f?,==hu ?B?mn6jmSOe&(ι>Zjvʽ%n;hO/`Y?? XZg}{.͹?;[-Z7}Y{|Y- ;^_tIYt~]}5͏-i#a>~~ xN׆W;C4iw:wy,MscK}Hfgf,@;ƿO믊گ{Zb ;e;Ya^g3jHLJ~Ͽ5]|S#{'L#Y,j 9UO2ErbZ if+}g: k^u)4 NG/fH!wr&R?dc͗5 xo⟃|3iyff fe$#I};o@Mgk='—ִ[͒@m&V+Vix%n;hO/`Y?? XZg}{.͹?;[-Z7}O{|Y!?h_lKKYRis4O53b^Ue7ӟn_[g¿h"=o{J^}Y-_r"ݶm#?iECx?⇀x>K-7O05azmZY`(YeY|QdEU<_]ou?&Ś'ėZt[8P`Mla po|&Cn>)> \~/h%n="2quŬ/%Ҕ1/ ?oo?xk~+i4;Cn˻ϼ&W%$3338֞:h?#wOwyg(?a%fgx7Im~5Ko ROM3^{Q,MB;eR=EԒVEk#}G?/?NJgK8n|Ix5Ě:a՟bb&qlhDd (Z]=5<#K_5tI>Ͷ/*mcM oo?xKYPV 2(٠K=DXӦ0\Ke䰌(]$xK3>}<dxI_n1|?H??|7<+-j7Z,PD4ƷtG5K(65 寗\NVN晪GGOO-戶xB+B60kogsƣo |Z>ZK^]:]sbIaQUv ?oo?xk~+i4;Cn˻ϼ&W%$333 8%_~Wh7M>1Yy^#3_N;YxYTH|.x5_ k%S?k&ΐ'x$FXDѼu0ȑk⟄|1E<_yc/ÖhjN%%ǘLi?SO. 6Σg ˣMw_^Ngk ċdUyUeE` @?j|S տǫYCMbR6<lm?wq|Geč-4閳hmwz.ı5k)](v'E.|g'd[KMMF}UpF2#Oz߿~ ,_H>٣[O_?kއp<3v |> ]uO?XUt3Sk_Agly,2,rVwpC<ɉxşӼ5N4eΡGgK\f?ggව4 xoaӴ?cM&gsx{w6>j٤fqb?a%fgx7Im~5Ko ROM3^{Q,MB;eR=EԒVE9{{5;gKK-!_Mw9baVFHH',4_ x6~% %,)exu'`MNL*Ȏ?c+ 싦i?)5}UJmƓMr*)5 8,vG Ÿ%7~"u?^N]_ KEӴvN>B̻ YC~! C^?/|į?5oWg5_ hENޏM]?"tQ *1Oggව4 xoaӴ?cM&gsx{w6>j٤fqbǃOO55'Þ+&՞ioõʸ6 2mEHcnE?c gT>s]{ xE6zKt;i9ax,=bvm^[w7⿰L<=bk5r[G381bN_Z|xVs|/6=_Om.'XԳel'~=/v$oioᥗLF3oKv%%;YJ9C@ִxoOZSI/gXkI&VqfQ $ D0x+_Jcq]-46}Vv¶"R @ T'5ߏߏzl>iie:7sl[ 1*Ӽ;΍k S}[5{V+{ۺń14q3)f?=E{LZI/t;R>Ok]ڈ!U$ZKRAhć~?eZ<y>vjowM'ScY$YZI yDv@=GM4x'~0x?,n,-t>= ܃疭G |`{&xLtAVÏ[ѥ7LIA?%BI*k((((((((((((((((( .| msR-R/B?"(_:|e/3{sßQiҾk/Lx篇<;welje"#NA/EU9MG9ƣaZ+l_yY*a ~xS?!j¿( jm_BYP<ٱ#y?j ?g(Ϗ<6j0X^5vMik}1֞)"ڧlarn{&ǃAºaOÿOŸ h?Oj>+IN܊l|j;dXQdK+ļx_ҥ/'Z}]41%c:o BZ~2YO?>3qW6V8u9!Sb1:U~8֭,!X-!t(PT bWM*^6喞hmDf$v`cg^X:nXxGǤV6zfZ`;8@TEP*(jwxmr[5y RD1ˈ<=1MƏ(A~|^7;].[^qnDh1#;?b W3#~W^~%AriJׇeQ嗖οۧ>1:U~8֭,!X-!t(PT b>n 3Er|)σ!%5uq{8̰F+W[A7f??d}s:g.֮mƭyprCki5x!YR O7Ec ]F^:֔)u% W$l[ } 2xWJЬ/XԬ[MHiHcڈ"V6(¨~~S~?F'"چe♴(54boi:wr,C.o* v-rv-)tԒ͢٫II"-G_?c뫯? u4CLXF Ď ~rO|5CcI6htqi'SG.cMmXjvIp1:Oۧ>1:U~8֭,!X-!t(PT b?K?b(o dxWſ->(h/e}>s :|WvEzeP9?اDž#|G_qkOK~ؙln-K̀j̞O6(O;4_'-›^<=x_Z_iWKism$j»Eq5|`|ڧ 'i_{;-\UmwYI4{Uyi?F>!RN c?ldySQoW>=πIҬl/KƵiggi oi wqG(U)_ i>~/ W[M4|U?m.-<ڈH.,~K^tz?='J4/ե+1Αj*T WO|*doĿH5]nM7P!"iV:Ѵ,Cj#1#</Ez۟*LkVvv:Gq P1^W@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Xmso{kjW>׶@|'Jw?'⣞kti{vN3LJ|9vljb*di $QSĶ?nEG?Ouzn->|5A*<' >]> |Vk-k~~7K톳$Ocmy}{Yy'|k\*E4rcB>O7v/™AҾ~'Z}U`32uxגi!yQn~[ ?롗 <nJg?֞:h?#wOwyg()\C| ;?_5o\^h ~ \C^6k54i$[1H˕/y?;𿃼C|LƕKo\i[,l3 Q|!HsN4 q㗏>xÞ8֗D:\2[I{\Mmn<18?b d; ? OF)3sY,PE4;'sx@!E O_!о&iJ%m?s6xKb(>s?k&.n H;,/g %o}#w?yx8=2ھσ Ӵ;ĈE ٠LHcgl.N9R;g3ybCP0'?c+o'wĻ { R]V{=ۯa܈3F$>bFwïmoK[_k&qy/- \}KR[c'Id U? ~| _3fm7菑w?go ooDǃt}C_~ {P CP/H$ 5Rѐ¯~owK~DxYsKbٳA6칶 3+('//_~ Yjk|^۬u^xkWu/n$#᷷0yx1^5oo"Q!w8>k " #ٖWn7on,K{ cdeZ?%a ifSo_hkg?ymݟO~g|?;𿃼C|LƕKo\i[,l3 Q|!H)=x+?wo|U ybz؆xy1L&1ڥ|o܌࿉ axݳ\HWgE|CU_>ş |{mwܛq%ռ nxRT3R…%kؿ'9LWJ,')V֐٭F^-6ErŽZȑ? |?u/6hf),[ʉ[x%y7^l(_oo> ⿳6emyi~G^<1qS:~w/xҼImk+ay{卞?a7Ϝ)f|% |Xօ.b{ Hw3"[^LwI)I~w 5_G.CZįNyXAok rY\}7ɩa](742TGs+~!ξ߅} f4[}JG<^^cg乘f"9 GI/|d_?4fG-u8-4}^o"3OW-mql#//|\3F#O? 'D rW|1]g5IM&G1Eq,"ɇA}6~4w/ ~;Q52%Ir$%Nxjo? O1@5-u=7 #%AiFm:>>4tzY[n䵴&7N1eo-*&7O_C{/xZƱĿk2VpEgi5e\[,-_ R[t<㗆>xDŽYGҼ-?z6vAXi Fc0@ '4|c^)jkC:l1SKh4jO rv}?  gŏ_?%lEeloq`ퟱୗ.8i0Z-,Ip? ~| _3fm7菑w ӿc'VcWWS&'t r{km){o )-܆9@gUa;Okhw? 6ڇ5xb kwz~%zeu-MVuUP3|S:~w/xҼImk+ay{卞?a7Ϝ)'W㗀>X>#ŷMjvXyJ <.p ~~k!O[d$6IPb)1i> |w) (oekƓ?l5_EN]'#tc,2~!ξ߅} f4[}JG<^^cg乘f"9 G~?._ | mc.ohfLKk9&GV2¾Wc?d/|9ǁEcOG,4noJY\<ʴ~KK>Ð>?ߍeWG-恋_ _bO70 j#r2׏|u?߳GďV-~,7Ο?ڛ˴DVD|\ʻY B}Q(U7u/$``32uvגng?4?)1!/6[JWuyi [ↂW0ߛwn4W\ (yӢaOÿOŸ h?Oj>+IN܊l|j;dXQ/zf_Oe-~c>XyXX~o__߆WOOxb4L>+tG2(YD{3b>>0ž| g'W"k_gNw@>1ru?{QyC: (yg-"ƨӫUϏ֟L?_|k#~}szeޟ\ Ŷ0Hmlm2DO~_,voJclȳ$[Hd p:>! GU#}[iy&}% 71|p4Kֺ'Ʊ-ŠصIkJ1jX@BH& ?~5h5g?t ]ǭ\ۍZ hkuMCB<)$B~g].[*\x:n<_Z2$sCw*rBY[YU- \~ ?<) j>+][ͯccqoj^lmVd|)T3|~/kڷ<+Oi~^ywn$J›b9㛯l2xCOW@|SM:>7tVkmƻPKωxO/ٷWך R[=X6lW)F"p̮cGBß =~H$[PlS6 MM'PE8heҭ%Pn'<~cI~/kڷ<+Oi~^ywn$J›b9R~7?[Wƥ?hw~Q3ypK]˦g$MsF _|:ͷ-V=omͯZj6riC7Ŵn2o4{ Nd7+ Wşغ}xP > z,gc%77d7~ t xw|#>#z`3ɹ!HlE00σWV׾#Ҽ4|QxÚ/}NYҮ4 m"mmݪ+\ݿ- ?+/2|-+xj|'ORidKB{KpڛʱVxFP{~ զ|]藒;=[NіUbYTxnx:[V5]RK˹{bK$K;ŘI$ܟW?AIqyi ("Ɠ 9ki< Gr> ~ ?<) j>+][ͯccqoj^lmVd|)T3?l? w)SM)G{)6 ۑMtGt1+*#GOs=3]_/Lex'2OYl?u Oe{1,[<}n~Q ~^ ?-<Z|P^}2pt&ːe;s@Ɵ^nxxs]އ^yQ<1^x I$T"&V,uE~_ gH|uyljO[Y_+E" Dih̉4ih("%~?K<obRgh'itO ]b[AkyN.bⱺU(+|_?E(\^Z'N[$qo>MO+Ev|?9R1Z-/<k:? |,y_1X8u~ H |,8?<++K৿ |WuWM*^6喞hmDf$v`cg^X%4.Ӡ?گ ǹ.&<͙GmI?@>NYX?x:VMLW53FѢ\ECewKL5Ą:no%GOr-D^)Gđ,4ߥHm˝CWm$4{Ww}@f- O7357S< K.ƖN7Ok-I*3ܵDgh(@-\y]}i17!b }vMcG[5A_@H|1:}/.ChGn|j8j;',?hyݿÚ[ie-fь]cIDkRPO?g9ka~.I.gwwK+%|!x¿p{?&SqjV"{~;(}hU?_`~m.9KX#ڞ CLѾ{K&XZT (\7/% kO|$)zom޳uܺ{|7ŵǕ!i#X} ;',?hyݿÚ[ie-fь]cIDkRPJ?h?f?᡿''??|x_y_3xo{|YG g K%sdinoț73mߵτ<]^24xoޕ+mb 2yѪ+5O;Mk |_q[xPzziډd(jȋ.b,.R.,w?o~ў9sN:tڇ,.u ?R;hDŽDZYY wW',4_ x6~% %,)exu'`MNL*ȎCv|G G">ҿ3Zk?D }mel_T'/-w><\GOVe v6mK]HHc,jYx;ĞӾ, &|)y =kOK..o>=x%bifGnψ(RW&kMg(Auϳlm`1W<KQgsE0:h\ʒܥ}V2%DidՀ{߄>%|!x¿[*?c{]6 mX~~xOmOPh=ߓs,-*n.Mcߵ|wý G6oY:]Gh=̾Qʐv,@=_QCO~=~=~Dm/Fͱn 0 #$J$fc[@?Sh55ߎ!g}OW H-{ t? _w}צC.2Iې 8щ7,#kPj%9}dMyv6~̟J?ho|$ǿ؞) !|z'ƍf9-|{(Vvn+YJC_G66?toKu@ʙ^\[47(Udo~Gؓwş/s$zO/j٤fqbO{|Y!?h_lKKYRis4O53b^Ue0{߄>%|!x¿u`{ߏ>! >.\9NiGq=-ڧ`-E.Uw? ꟲG|ߎ|C5|YohXn\0uym';"rNͽ:>~~ xN׆W;C4iw:wy,MscK}Hfgf,@>cow g:6%]DBP%0wC$U[߄>"4VgoMR^ݴU!XHAr$~$ោkzw|i[âثŬBXy,OphDE]C~+|5miZƫķ~ѯ5qzpI$f1R!H@Iy2;t<{:ƅg_ [h<1mK^%h$vSHEEec"NX_imOU.~ jIiuT]fx2,n wgH}|Aä]Xjgl`Si $(?"Dx2`'*HVyw7&yjlfu*R&Yb B3B@; 353xxDZ M\Ifqqwymrkѣy;#I};o@Mgk='—ִ[͒@m&V+Vi|(Ɵh acd++]CXfԔzOwhXwwf4~xOÚ/W?zwwzo:\o 0&'XWdGYd s^7_~,j#jދy2 HȺ7YE- mATchxs_4+of-mL M*Aj28>?Z?`/ك7]wA|^5;}ZԼ[kfB![``WY+}aZu ٢=Yj*,qI>?> xOÚh%|<džj_\$R%"I|c~!~Vկ5MWTfi#ıf$I'4N((((((((((((((( EܖB&zĉ<:hBFo`y KY[jI֗Auiw᫨'xHOedelR  z/l^k_,t;[%lvy(?ڟ|m\υ|M^al o $hm/OG% <n3M_~~SgmG+Eۿ_ soZy>:- XO9y_1Xmq+bq~(2>W@k~L5MKV'Y'>/%`%Y.$Tc\EQU ?롇 S)4Wٟ `~m8k7DOċ 'Zhx$ taPM#&'_%km.dImEEQ_n{&ǃAº'r">'xڴ{{5o|VPn~iwؤԄ9>"ƥ.[`Z|Fxk_;C?_j4J(xosf* Ef.1@_`~J?h?f?᡿''??|x_y_3xf/ Q1=/|pd4x3Z=!FGg3y_<+߄/Sῆ?-—|I+7R%Ԙz?wǟt&þ(FbYbK1$NM}D+ώKҍvn3M_~^v|/Q1Z-suj^& EGgQ; W?"dwO0WPOѺ_hkNѼ9o'3\7ֿĨ7Oi> ƞ,^!Y'?dxVGe ̐Dꎑ^? ifSo_hkg?ymݟO~g|# ^}}[c_|;aKpPF,W 2yJT jdo>-ƽgN[nVy6${$mߙu/`~*N?_}?tue˻k7K ʋtgksg)qHkQ%iZuS߶&m|};R`+hڳ')MşӼ5N4eΡGgK\f?&Cuѯ5|>([v g[t$E l`1Gث_zC $Ѵ LVKMIh5P#HQCSn 3Er|)σ!%5uq{8̰F+W[A7f oo?<'^+ u=It; Y^7m.f淆sAS+ʲ#Cy/ 1i;м _]WH{5I x^8e̡ݚ(hJ_Oٳe&^w~Xxo[Ʀ VڈY ,H.#!-t?jo?>i15 }2:k]qoP,Eo7hMڝω|;#GLOo:WgxOFѼ~}>T(5"+!hѓu[Zg{)Íǟ <O<KP=Zh9%aM9L|ŷRk)@b!` oo?<'^+ u=It; Y^7m.f淆sAS+ʲ#'/> gŏ_?%lEeloq`ퟱୗ.8i0Z-,Ip??g)s+?N? ѶYEM qɣ7%\?JiO.ymmSlF2kꏀP];8ui:>%x?<BoxwN'Қ-LŸhc/q^lφf YsmxPdž'w,ZgX_B:g_!aMU8~|`oe~(Sιt4?.eInR;+io"4ѲH49~,>m2^mܻI1=`\BXz{'>!4 W:8liyIk1,k;$ SY{|Y- ;^_tIYt~]}5͏-i#a1z{?^i]*i(YgHESney 6xO\eχh!kIu *g߭yjpam[| Tʒ0Gcᧆ$hx3AxQGKBgnYNs Z4?) 65|Mn44{x[a.dem._߆WOOxb4L>+tG2(YD{~*c?ԾlB[μ~bn|5uVe n,nwm=|}Q|?ƭƿ,'\Ιዸq^Am:Mn#(c8GTzO|j&aX O|;omh,C/~SY>%c:MOwhOؿau;>ۨͧ}(|٠fO'?9|N].|79sWsf`Rڪث_zC $Ѵ LVKMIh5P#HQC|g\|!׃֚>}Y-_r"ݶm#ܟwhN[7y{>ľ&!./tٖH;߅vkh3q~~k!O[d$6IPb)1i> |w) (`> 8&|})s} GHG#-~9(}hFϲ&d+F8 ;|e;]wxޑΩ ]ϗ;}ΉZ|ždࣟO<|Qu_M?$n,5y.#睭|"QRڪ~T~ϟ4˝[i]o25%hQ:6 >.^"J>'df6Ӿ7EnW(>Oa~- * C +W\ც\cO5ž~xPNj=Bm68Yd{fH4%U~s'O!xGݟtk"Tzvcd<'ۦZe%Yc(v#G/ڋw>4Z'?ڗ4g['; ID2Ά22X|-J??޿K_F+O7.7nF+?1<'ώ>o?Ѵo'_O. gȊţHZ4dV(z~|2dx"}Nj!A[.r,淰QIcYx^BӢl? 5|'`2 ?KOϨ]udA4Y>FS[Ie;7>=π,,% (9_r~~SD {Qw%_MwSg;Q'LfGʈc3SGIs$-[DZg5太RJa4  . Z|U?I:ΧuO4VrE4 9dWgO3 >~/&iKLվ5)of/x 4ĥ5č꟱?اDž#|G_qkOK~ؙln-K̀j̞O6p Ak7^>]x:X2k`uBN]Pvd{l? 5|'`2 ?KOϨ]udA4Y>FS[Ie;5?;4_'-›^<=x_Z_iWKism$j»Eq5|`x'ŏFqK_<5x4O@ZFeHgxd4hq/dQot`ʼ|߲|^[5_ꚣZsi2ZXt2&PSb?mXeo|W;?ň|} \j`Eme ϙ$9'II/!ՠx%?<1wsn5k-S6#e gʐHuAn|5uVe n,nwm=|}~ g:{{?j>(m ƷqrB apn nXb?|2?ix#ź'ċ't\xLu 5Nz5$PA OIԼMKπ:,*]2{赧ݣC'/0X \rd ӿc'VcWWS&'t r{km){o )-܆9@gUq;Okhw? 6ڇ5xb kwz~%zeu-MVuUP3Sz' O>??+oy0KO8S̔z#Py ycuѾ(\|RW k>( =љR+!K:WgxOFѼ~}>T(5"+!hѓu[ß?,+? {ķ[}ȿՃlm1">oC%Tx?x~_/o#guw#N_^ g]J 7ϧjQEbѤ-2yt`P0'?c+o'wĻ { R]V{=ۯa܈3F$>bFw_H|mj˿~{G~>Fm>C72~'YrsHP[KfX i#P~+Ǜ3(((((+h \ԋT⿬6P7HJ:WiO|;}(+ߎr, ҍvn3M_~Y0sΥoV?aizoW'XW3rw~oH>x ׏F!̡mX%mГq.ǻon?c{]6 mX~~xOmOPh=ߓs,-*n.Mc~=/v$oioᥗLF3oKv%%;YJ9CcǏ~ j~kˋ˽Y@ԶO$dC+ySOO|IǏtOҘD C4YKCu'ewKL5Ą:no%GOr-D^)Gđ,>+t߉߳G~!xMfO=#pm1yjѻߴxkO@O4-/T{[;=wi$grI٣q~ߴś/j?'Nyk_ѦǨZwvZ\^]+[I8*ı?g$_4|{#xsK ,e1z]ދ,i(pWy?ÿ_~-x><<\GOVe v6mK]HHc,jY ٓ G 3?#;OD^ѱBG%":os ǒQzOW= m/|{ombxGN/MPJ\KhyI$,k& |`{&xLtAVÏ[ѥ7LIA?%BI*h?g$_4|{#xsK ,e1z]ދ,i(pWy?=?l7Mx3U}ƩmCYkcj%ɨG",GHJȱ_?Vx?"_,'KwDwoٟmt?ig]Ğԯ,<O -ZҬ_C.7RXOOMk q fR$J-mt߈><5s条/tX\~v<7 bE" >ݟQσL֚Q:$lggFf61c&:';QTرQ $#UE Pܟ |U?Xsؼa:,Eh^)jcIk lr}EK6\~ ֿvľ)Ӧ<9asiQG<&=U@\(c7%\?JiO.ymmSlF2hCv|G G">ҿ3Zk?D }mel_Tٿ G  G47$G/O ;~^OcoCῊ:;?%ƏkGx7HbO+g?_>iv,shMR[sof@$1ȍ"4l:yMsαO⏆?u~Ӽ/geiG-ᜲpX%Z<~o~h#OOP_>`4 쩞O%CqrQ.FHw>5|X~ mOMyM6эB}&%d.W&C??(czO/ky?Э>V$ߵ>(+ꏁG/wo7v>]i\Gv'P ʄfWL e9>WO WZk;Wމy-5 eV(Y ISSN ^Bm>,,% (9_r|mj˿~{G~>Fm>C72~'Y]x:X2k`uBN]Pvd{((A:.>)|+ HTh̩ ƍ%J# T+P{~ զ|]藒;=[NіUbYTx~*c?ԾlB[μ~b8+?g/Sg@o5ۨͧ}(|٠fO'o+>xtkMbݯY 9wB {He~Yh4A++<PrK+*Tm/xOxW>/6k~Yi7j $q +E#%DEQEQEQEQEQEQEQEQEQEQEQEW>׶_Xmso{kjt< '|;}(+ώ?Kҍvn3M_~YƳ}0K+Ev_cZ+l_y>uCxyf#\r++_+K ˟l|IoC?9ˮ][ ql~pD2JmqP|Tuw_1 w)] U<])8~ٺ/`M[ߴ>sm[:`eobk8DwA}W~~~W ˟{> b?:NL[4NL-koV3;JRGhSO mk?0irhP=ssqɧ7X]lۀ\1?K?b(o dxWſ->(h/e}>s :|WvEzeP9aоCV_~xgLz͸կ NHmm&T؏1#*A?@x~nV97DŽ~ \~}VkFθAe*|𲘮1+|Sz' O>??+oy0KO8S̔z#W@T~?| '/{>?:L:eݵ䛥EAo3LH}5938z5kN4wúީ o6]žyoYPE}~~k!O[d$6IPb)1i> |w) (jwhN[7y{>ľ&!./tٖH;߅vkh3qn*'C4I./4m?“>w=ՒS@c|Ag8=Mm'RP+g>ޣ/φG.uOJ|tL%P5?⋭>i &qaww=ՒS@c|Ag8=Mm'RP@x~_v>0 %捧Rg.纲Xh wO,#G2B~ ?<) j>+][ͯccqoj^lmVd|)T3o@37x1 |w) (oH)|G_|? \sټ%)J =S/_c{F? xRagE'/1&rMfxފhXx a'Uτ-;m^IKH djR@{HO 'اO4OY 'nE6>Yӵh|d|~?B?`Oo?x >(4}_ė?na]>KIM%s^ZJqE.&JC4?-WoƚԴ[)M3Rfao* سKJXJc\H@?اDž#|G_qkOK~ؙln-K̀j̞O6~?*'C4I./4m?“>w=ՒS@c|Ag8=Mm'RP@r~߷9n>rsHP[KfX i#P~+Ǜ3?mXeo|W;?ň|} \j`Eme ϙ$9'II>aоCV_~xgLz͸կ NHmm&T؏1#*A=U]->^qOQ2 F%] B-5۾؏ğ GǞn"I j%$m`CC!{G^ff2 tdK+ļx_ҥ/'Z}]41s٣–q7j02.<\oHrT˝D->xO2PW_N~͟,27þ+m>>z߆.50m"Fh`̉fAq m_ @LoG^$ Եb~e.k VʸX[uпG"|rx?'// |Ǐ 㮏x[~m5KY"h,x?J>-d_g/u`,c}sȭ'// |Ǐ 㮏x[~m5KY"h;Y`/ڗC[8>![n]JSf^Y# RK1ƄH}5938z5kN4wúީ o6]žyoYPE}~~k!O[d$6IPb)1i> |w) (jwhN[7y{>ľ&!./tٖH;߅vkh3qnCy?~~# jh^ >:ߊ -f;#k]BI^xFŒ U&Bʇ߄bjLĿ w 繴 5BࠌYd攨&7@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Xmso{kjW>׶@|'J?]kt~:F]wO?~g"xEQȁ'&z5/<uC}O¯ >xO!o(//kK<_@++S׾ >2k|^5 cWKđۘd/7R( BxZIxwS?7~ S3揬KMZ߇Ci ڪc -nBJH ei#"C߄bjLĿ w 繴 5BࠌYd攨&7ה}&֧A iW}'_0:Smf>Y>l3s'xG _7_x? K7^񾏢G=,_wmy&axcCQn~[x~ ?<) j>+][ͯccqoj^lmVd|)T3~oI\|!׃֚>}Y-_r"ݶm#gUaOc=o!i\^h&}B{%qq4zO(ܤ(߷9n>rsHP[KfX i#P~+Ǜ3sxUŨOo_-"2]K N xtFdK?b?3^+O>/𦧫[ZCfxہK :j"D,d C+as?Phyp<_n| fS/ؿ *xo>XmZ@43-DѭtQ~ ~Vo]Ҿ,]xByu 1Io=ŤHhə-&duP8ि ;GCWÍ'COnl 9,a;dKتǃ/v7|]wĆVkZt-{hDyle(!ђa@OJ5[Þ'4 [ZtvFaMHۜ qO`\}sP?oi#I[œ›dU'ꟲO|5CcI6htqi'SG.cMmXjvIp1: 9!i4vо=xO Y1iw}5Kq#F8e;rWm|9~˟C?P#T[La3 /$`=~'^u|7XNonhoZsmʎ9`WpC|o oYVKG:>M?lN[fFVE|-g%x+:w-qiCA{+˘o⻷H+s.BG |-J??޿K_F+O7.7nF*h?->*fgS}}+9"͚ndOyh |3{xQAuzG#:%w>\o:& i yDjG⯁xG|]#IQ[컶t<1H?xyIWksg)qHkQ%iZuS߶&m|};R`+hڳ')Ml? 5|'`2 ?KOϨ]udA4Y>FS[Ie;0p| 5.x<iCՙB۵K:ۡ'.(]`;v2=}'~fSǟCKkK"BIm.q`-CWh&7o W?AIqyi ("Ɠ 9ki< Gr>g߂>7Эtt;_㟲o*|mH)"c)|G_|? \sټ%)J =7 9kc7Z;^|5MVW?ny[r!!1\l\cl~c_x~_v>0 %捧Rg.纲Xh wO,#G2Bl? 5|'`2 ?KOϨ]udA4Y>FS[Ie;0Wksg)qHkQ%iZuS߶&m|};R`+hڳ')MLg/~ OLn/uvZI-#RY6ipjQ3*(}OKl?cm;tZ|5{ ^jvK0h:9ixY<[MG:o&lKWlNXUW?r|!~-F/%Ok66CqKi/YU;`n"l b>?$|rA|^WsO 7ů ~ލ}NMFxy#d@c+c!c+~*c?ԾlB[μ~bc ~,^A=FuR;x|Z4FO1n@ W~߷/H7,];xAxo"k{ im,ܭ5,a>`:+ث_zC $Ѵ LVKMIh5P#HQC|Sz' O>??+oy0KO8S̔z#P|9|k|0񿃴YBO;_G~4Yӵh|d|v?`Oo?x >(4}_ė?na]>KIM%s^ZJqE.&JB?Z2_lìwO}QOcEg$P@̟O-5|_f|4?-WoƚԴ[)M3Rfao* سKJXJc\HީC~xR=w|5 G'VoT퉛_.NԼ 7JSjg߮&Cuѯ5|>([v g[t$E l`1Gث_zC $Ѵ LVKMIh5P#HQCSn 3Er|)σ!%5uq{8̰F+W[A7f {|XtoCZϊAe4fTwHcFO%F (g^ ռ]=UQoKy.56?%hOs+a 9F+ٳe&^w~Xxo[Ʀ VڈY ,H.#!-t BZ~2YO?>3qW6V8u9!Sb%x?<BoxwN'Қ-LŸhc/q^l~{_φf YsmxPdž'w,ZgX_B:g_!aMU?>=πY>l3s'xG _7_x? K7^񾏢G=,_wmy&axcCQn~[x~ ?<) j>+][ͯccqoj^lmVd|)T3~oI\|!׃֚>}Y-_r"ݶm#gUaOc=o!i\^h&}B{%qq4zO(ܤ(߷9n>rsHP[KfX i#P~+Ǜ3;׆>jj^[X<8q8{)YvH qu 3/j.(եT[Nɒ{0ʅœ#jCگjŢ]Ka%a -쉈ʘ=9؟ӵiM[_v?H<'뺯 yG vAk7^>]x:X2k`uBN]Pvd{ OKl?cm;tZ|5{ ^jvK0h:ӟ훢/վMAx᮱:vUѿYi_6,+}Jxt?aۏmí=?Ɵ[[iWrh[tc9ڮ4[ܴG+,P~iQ¾ZEcdԖ@%ɵ?hښ>\i:MtCʑ!}7+ Oi~$ߴ@|IRK46"GYʅ'܃?k_?,<#⏈?[MD% ~]ȻPgLiw8z+#߶,fz!:K_FoZrj  ]Oχ՞HI~ ?<) j>+][ͯccqoj^lmVd|)T3~oI\|!׃֚>}Y-_r"ݶm#Y5φ?Kk8Ew.qmHY7t go3 ;Y.b #yA'gf/о/xōWƾM"'.-. )]A,gU|7-J??޿K_F+O7.7nF+?/!ՠx%?<1wsn5k-S6#e gʐO~__~,{CVN8EB\@jmn*:+/6[JWuyi [ↂW0ߛwn4W\ (yӠ(((6P7HJN+h \ԋT|_ҍvN_9Oػ(k.xg"/@aO8mC/EG.}MO ƿ __6]1_? ?;k )Ecet1O_Ϛ袊OЏO~?dD;k^"MR|7.ecUs~|gq ?oo?xk~+i4;Cn˻ϼ&W%$333>&g_|L|yi/MϊjGq44Of'س<02$H@.?v?Y|bĚ-9?H4=GVèh $91ewKL5Ą:no%GOr-D^)Gđ,W[w7⿰L<=bk5r[G381cퟳwi^?񕞉7,N<;%>lM)nf=NtS~'~ ⟌y 'g5 ]>/0Os{ kyF~ѱ8%_~Wh7M>1Yy^#3_N;YxYTI|$j¯; )?|?k6vcl7[/&uǗV͂~|!}jWw UwwnXy"I<#~̟NOxY|1 G}-8[GRױ l )QaXȽ'?Z[x=s7ŋڒi]A-5p##̱K(c"2~_M/ xK.znCawJ"jDLā~<]o5^?x^LJkBM.{[+wڗ}Ouyc_-<Jko5мI>|7Wr~Xh-ͭ EØ:(-b&?'/-w><\GOVe v6mK]HHc,jY7CxP D獾־ ռ5:ϴquyo,)Eg͖*Y7%\?JiO.ymmSlF2h==hu ?B?mn6jmSOe&(ι>Zjvʽ'=?l7Mx3U}ƩmCYkcj%ɨG",GHJȱ~?h_Ś_t^:~ؿԵkie'0y R;G`$[3*~xOÚ/W?zwwzo:\o 0&'XWdGYd ewKL5Ą:no%GOr-D^)Gđ,s>_ [?_lz1۟])-u!#mOȱf˖(yV%ysG$qS}y_nψ Z|9|s-AhW:&^e7.VY#%ոKB.^kGbe70'%n;hO/`Y?? XZg}{.͹?;[-Z7}@w/\O+=ok,*4fCNLQ?~4?< }#S^mEMcPIk ~y6Aw ɐc̟NOxY|1 G}-8[GRױ l )QaXȽ?`o_aai |`s_hZ:V.- ߻e+"I|'b|2^\|W_}6 B!-4 2poIo5ʄ|oΛ_xXPXXnP 濂tymo$T{9Xj?s>_ [?_lz1۟])-u!#mOȱf˖6?fO%47>\Ov>=zzcFO qlM+IE?@ִxoOZSI/gXkI&VqfQ $D0|=L7tn$ZmFې;ljI/kkO#+AK,7oog@W7y_^*4]HO Ms6Xzt"dIU$p,I]sGM4x'~0x?,n,-t>= ܃疭G )~ BK1hvJw-o49J aW__يYΥyaׇnm*{Sm٢kG]ly~I;#i~2oFYtYc6bXQ㵔;Al%ZW|yxBxRk7AԒ#ӧ"Jq#WbH^X~2:|}W |9FY+sT#ynƙ4%&:y+*|WWg_~¼oNyq^).0&Jxf8"i#. @?j|S տǫYCMbR6<lmcdQCx%=OoH>ק4ldл7mȎB_h|@ kL]e߅4Nufkiekg&`- ےI<Z~о?4+> tf/=jwmN`t2vHfT.~I;#i~2oFYtYc6bXQ㵔;Al{ Y~ n_fR‡TLמK!GPDYsiaru$cş_*ODYg7O3{߳?&>~xOÚ/W?zwwzo:\o 0&'XWdGYd K[]7?h k~hK:mCÖ:EqO ncجQd†;?g)s+?N? ѶYEM qɯ+?N,n$--"Gv,DpīH 8HQFKþ'\x{SԵ_О>1teLN[/-K+ʲ]!xkk=Gš6a 5 LX) +L4HFxacx T׏/5fk ^{bG _k?y$hB$L \^+gV.A >`yyMވ. t?o٣?S?dl`&qako`_6o'xڴ{{5o|VPn~iwؤԄ9>"ƥ.[`?Is?~µ{??e?[&~k(?0m>1j?W7>  Hz̗vӈ;]>pw@љ6R!CSG? ?GINyR4~}d/r>`p3@QEQ]$o@Q@Q@Q@Q@Q@Xmso{kjW>׶@|'J]kt;xF]wO?~gy$W*M6lw_1Xqq=,Ѕ~SEV<;lk{  cO$xCsO.Y)JgδQEyGޟLoG^$ Եb~e.k VʸX[uпG"|ry|j&aX O|;omh,C/~SY>%c:Vjwt<T,5籵Q#\#X\]I%dXχ%ZW|yxBxRk7AԒ#ӧ"Jq#WbHP6xO\eχh!kIu *g߭yjpam[| Tʒ?zh`/__]]x?A ɦd>WM*^6喞hmDf$v`cg^X@  iA>/7gcu[.M'nn44F: m[p <_mŧ 쯧.a7O"hQ̹ Q'5gOs_[πK>/jg@667e{eKuDXP@?~=/v$oioᥗLF3oKv%%;YJ9C?/!ՠx%?<1wsn5k-S6#e gʐOI8~ٺ/`M[ߴ>sm[:`eobk8DwAN_Z|xVs|/6=_Om.'XԳel>? k^!k ItRKN[[*R=Ď^%" Y@EuXj3]7lXY]mu?/pd`5938z5kN4wúީ o6]žyoYP_v>0 %捧Rg.纲Xh wO,#G2B~'~ ⟌y 'g5 ]>/0Os{ kyF~Ͽ5]|S#{'L#Y,j 9UO2ErbPTn 3Er|)σ!%5uq{8̰F+W[A7fث_zC $Ѵ LVKMIh5P#HQCpewKL5Ą:no%GOr-D^)Gđ,xO_'u?b?Wt M1欰/`OZ$W&% ;|e;]wxޑΩ ]ϗ;}ΉZ|ždࣟO<|Qu_M?$n,5y.#睭|"Qhڿ<AES fvAiSNW$\I?O<*'C4I./4m?“>w=ՒS@c|Ag8=Mm'RPUaOc=o!i\^h&}B{%qq4zO(ܤ(}'~:gֿeVXeY'ڭlry+=?_^I<56v,w(g!>kgw;̑\ S‘֣J?8ҵz%lLv67vVѿfO'RUC=? ^7&s_Cm6+ZF\m 'FԣgT \WVfBO<Ņ{G'|ېcCգwۿhƯ |eP4ϊ_i&gh̙'tGbn$σ?Ÿ6CBŻ?׿EĩfxN)cM%㶴=JlP,Gd_4/ߵ|iῆO~ѵ/iɨO$vl ec d,ev<x_ş_\֕H?Ox{zVAo4%ĖiY|IR%#aK] ~$Ew/.-5\MD\9C+h㗆>xDŽYGҼ-?z6vAXi Fc0@Toφ_oYxv7>d>2R߈5+%EY)=[lk/ X|=9~hZ=ϊ|=~}>+(c?ilRZBFgcR͗-l|VfBO<Ņ{G'|ېcCգwۿh?b d; ? OF)3sY,PE4;'sx@!E O|s>2.<\oHrT˝D->xO2PW^> ]uO?XUt3Sk_Agly,2,rVwpC<ɉ~oЏS/_c{F? xRagE'/1&rMfx<14!c#V6|I|s?{ NWwkw"4~^*~ ec-xC^5qaFbmuB m8eDv2 by_$ŏv~~1ǶЬ<:hPww bgњ6"*dPog?? |)|`=;OtE&ֿ;r)AΝ}&3Cc#Dc~ f^F$|Ks ]M-֢i-dU[)tY0P==hu ?B?mn6jmSOe&(ι>Zjvʾ#~6߶u?i.l.|+\<2|I:{Z~>r[@Q'"AV+t߉߳G~!xMfO=#pm1yjѻߴvW?AIqyi ("Ɠ 9ki< Gr'~fSǟCKkK"BIm.q`-CWh&7o+a k.GN᩵F YcՖEs9 [;!ܞdĽ'ÿ_~-x><(m ƷqrB apn nXb?|2?ix#ź'ċ't\xLu 5Nz5$Qw njt?VoiivOqo廝E+[PE2̨<פ-O|HQ: hg%:q7Yeiݣ54*y@=/쓩xؗuYkTewkO F'N^a,J |cɏ ~N'Cį⧀(MO׶S@3%S[ r2<͂?7^dCO0O`bhgTf?&>=~^c{^ɬh }f{'Cztif!4!yHПφf YsmxPdž'w,ZgX_B:g_!aMU?>=πNl|<#LJ) Kizl#x0G/4G`O*g=;E_xM_Yׯ6HIu:HXjyk"/M7Mms5O_okgVnnM&6o2[~|~'~ ⟌y 'g5 ]>/0Os{ kyF~~߷9n>rsHP[KfX i#P~+Ǜ3c/~ |:? k^!k ItRKN[[*R=Ď^%" Y@>o=CHE>xOn|[{MEc"-AMADApO6Α\V5WԊEa hфQDJf/@$ִ ?UMvisz~>dm̚ly7m~6~'|}n|)uG?}[F|mhܩL/ ʰHGd/ g/_~_/u_OxEÐGΚi7t+=%¸HD7G7q3^uygx_ km*[nLg6U`!FK{e*%ZW|yxBxRk7AԒ#ӧ"Jq#WbH_Hf~Ki׆Kſ |~>F.q$%YGkhY$2~%0ƞ 翂??O7 X~%q~[K\syޟrHom{<8Щ=S?~j??f+_~xP m.i.ýL>!(ׄ_k?[Oxķ75֠'fd0ͤPS.2px/<+W >Y#%ոKB.^kGbe70'%n;hO/`Y?? XZg}{.͹?;[-Z7}/|-# i> a jz6knM\$OAsL~> m7|:T1w0G"A3lfH7Oڂ|dv xu ƿጶxb;l52:KfH,dH E)jcIk lr}EK6\2(᡼bx$ik62h]dGUmpXJ(O=c\cq^f? Wrwڴ/;c}@v0l 7Pxb} >[X|k,nxrl!aٌol0HXWI;#i~2oFYtYc6bXQ㵔;Ano_{|.}=G]>E4Awj5Fu*初cP BZ~2YO?>3qW6V8u9!Sbo>|{W_|iV?Nw㵘A<6&\8c |ҕ((((((6P7HJN+h \ԋT|JzwÿQ҉Ҿi')|;we>_SW~aǟOC+E:9}'&Z-/<uCӼ 4ZpH?)S){Bש/ou#߅3+P.);xBt')b_Ϝ(Ͼ=?g9ka~.I.gwwK+h&OQ4Yy,#*D P^?vvY&|m=iw$1l>&.n H>oE{Ɲ4ߥHm˝CWm$4{Ww}@f- N??Vx?"_,'KwDwoٟmx?mi ޟo;y7𦓩_α֒Mum,l$A;rI7>~ i!&64:eQiA5:zL`/2aT* _=#su/c_4x6V9<%1o9Rߵ|wý G6oY:]Gh=̾Qʐv,|ފşӼ5N4eΡGgK\f?ggව4 xoaӴ?cM&gsx{w6>j٤fqbTm|S }慥zcKx'{$Zi"34r ®.|,, :vi,u}?.>X\40X?kX\40XO>/KshmDyu5'?PZ@ (4)mR, b.":?E{۳?oJ?~ Y'D]l{h,b8dD0|=LX\40X~!ξ߅} f4[}JG<^^cg乘f"9 G@?vvY&|m=iw$1l>&.n H=4ߥHm˝CWm$4{Ww}@f- O@[w7⿰L<=bk5r[G381cOğ|3mvNQ4xt[xK%nCmvuبڈtPCxP6ִyگ isKC#JHH$B&EFg#|,, :vi,u}?.>X\40X ?oo?xk~+i4;Cn˻ϼ&W%$3334~_fz|_yizޘ e{I%F{;H+=#_ߣ¾Nۻ?i_;o7w%\h|@ kL]e߅4Nufkiekg&`- ےI(<7{|YG#K1|Au2B,h+gx94*+@*2|-,|Ce/=gMBmZh,t8fki.tcNq,^e2T@?E{ sE׊gB]O@]2BW[KyD, o<7bOKZxSI ~7Lcu!\ButP|,, :vi,u}?.>X\40X~!ξ߅} f4[}JG<^^cg乘f"9 G@O.w_9?]˨Gyy#|[\yR=ŎoiߊçhoƚM2Pۣ%l|oI ŏ@[w7⿰L<=bk5r[G381cOgOknx'\=-n[GTgkylP[ (>~f i:?Wh~ 6PfY:>vlbPn0 )> ~x.z}šNqk:ƳZI5մ0$] oo?xKYPV 2(٠K=DXӦ0\Ke䰌-?ڿ|^ѵ=;D>4-lU!,c_'͸u bcj"@/-S~ ]MPUykپ鏘5ڊ)_Mj:__xll1XbEwWx8VxT,Lc>'E{g_> h(-.5;-tո*Vis}POdТJ$[w7⿰L<=bk5r[G381cP2~_M/ xK.znCawJ"jDLā|oΛ_xXPXXnP 濂tymo$T{9XjTh|@ kL]e߅4Nufkiekg&`- ےIoK4zeƧs}EJލ.obJ ,RIP^'E{?Vx?"_,'KwDwoٟmq=ueε [2OocMJ6Mmsm:<71ʌ[HF|־<#MB OW)uI`@Ψ&.;Bd>((((((((# RE\Z&fQ^GU+oU>B~|pq/ j( Y\OrLUD{ Nq\JxF_FXxWDGk}$i{uUF6:\* !>?Kl ƻ]w|Ȧ~ ?7hƇ-EhVHE}`Gag𾅦xOXI_?_ o?׃BTeL,$- +8\⼨G?hm/-?=UKeЮkwt7 W#y}lr?}IW#')ib7Z_z?_.7mȿs*_smc9$ ,QӼ$?>4I|fRԟo-u/=Ic!SM}?Z[_Dt+| ndb_O_ԿOx{%?Kd+GV Н=~d?hO.Կ_-u/=GW'_#R >(iX-o¾z_x E71Bwǩ\?bVZsԭv1/~1 W#Vd/3BԿ/X[xX2?R~/?ha5?ڟ?7Z_zC"\9/G ZoO Џ -7W{+{;CyǨ^~3m>_?ռOKIG{(¿#<KMgSho/?/CGIGy(¿#<KMgSho/??}?i??WIb㿴7[jzx E?ڟE|[TM/ {)_ >R+;CyǨ~ǯǏ[jzCx #m8G?SB 'Iib7Z_zx E7"A*_sw?E|>KLxG`Ib?7Z_z5BxǨ?_ V/GI!?FQKL|fRƿh_/Կ]/O}?` ?552g$1_o-u/=G + 5BxǨП]2k2ȿլOK|?χ?)ib[xgnp |R?~;?hO.Կo-u/=KE|ZT0x;#KM(?!~1h_/Կo-u/=Ga p#?H_xX -7R o%^~ko-u/=GZorx3jJ}+9C>3m?7Z_z!.TxkIibD<5BW$1__o-u/=G3k>_?՜OK;x2L3ேȧ􏆞7x?*f b ]KU_./ԿR˵|1r$~ % got3XZ/1 ~8SM'g/o-u/=QIy ]KU,|_\'/g잏 ˩2@=?z2ۡoRk/( Կh6z꟯C}h[o}?u[ox m??YxCo-1~ЇZ_z/Bvǩz_! #E><| rkWLY?x E/~Ѓk_-u/=I>WAr$~WOH%3_3k> ##?'|D7CxǨ^>3k> ##?'|D7CxǨ^>3k___+?Hq[O5|d9+?m?«w_O5O?eR?hO.Կ__?LW>4| rkcCXg&oq Ht2 $ 3Qw x E/o?u[n8`|er 2ASYDτ1\Iѧpr/WÅ䉼ĴP-/)2Gb$e=.VW액X&XlaV%HA$Z+ǭ/ʨРVsNUnit-2.6.0.12051/doc/img/testLoadSettings.jpg0000664000175000017500000021621611713252032020506 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?`'i1u{-/OKip^4fWyC+U"o‰#5PTDZZ do@$7l_Yů_|YxX}mK/h67mۋc72Eh#WJTYhݺ+kvH,UjTW-ݚ߱OͷNNt?EM|4> M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ(+俊g¯[ϊ> O|7ómhhڇ A<ٱ6F5l'dI6F4'%m{1ۯ>9 exOL߄tOOAּOM_/xW,NJ|R4χ Xk7suww;5US Fk&5yI0Ou+.$dS9F M5&ݵI-.?+ w^Ŧbu_xZH%w\sKM[7:cw+;Y|4:7ا\KⴢSpby-l \y#p򏙭:nJp_9V]u}-sU[^e'?]n}E~o _x^fs|VN'ĴwV~ L+aEݎ/}u:/*2:w,bUoWK/qu.»;EdiPIO6}G )b.sI'\RRiۧ[J4 M5qM_vQE`tQ@Q@Umd^v4hũ vM6qs@hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M=3Ot1-,$ Kgq` O#C+ F%!ӝH"Z _xGoIGP}Sջ/s*Qh+r+81guc=K ^VwQ&iĽHa?>ؗ 5})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[h|_|gw xT|5#S6 +M5X,dZu ,^FY䷛qHYc_ eְx$j:h't߇~";{k[=nMAwV(ZD$2M@~C-MxK.OKl̡'* H9,G"y>Ѽ1yqh/ou[RƩy7?mح̈́km)F!xT@aljd7̚.XݨK>ۻ٫kgnT| d/;xO[WJѦvhvŐa%Ȳ t&yP犕n֍j\ܺY}lgw^V=?NdX@yi.iu-.K\scyʓXꗗ1o@@wǿI[HY}_+|BI[V#>5wX–hvq^G/yv&f.TU$@I5M~)zio_ɶZQE# ( ( (<4b^3Vg~fK?jѠ(nj,:"E/تB0+O@ Ot[L4<;eZPCwg#[T0H@@;r+67Zi/G4W^ccw<3$QM,<ʠy$،;I_O4|<7t? ^%m[%ny<3 mX/SQӡMF3:$A\|G<=mOOmGˡ^FrI-mFcNLaIɯI5flw܎"ٛOx2^m v?O5bcWi,t&KPh*"(rg|/QHaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP͓HcL?GJrG?Q/g7q_ѭnH t`+9W9~|}و_(AUy?E㯽_&_$\Q}\z9"³b3O%C hwQ&iĽHaC:7oԟhNcT|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<ƏiރW4x_J-b? 鶚dz<ehHC2ҤAo_ோ }kxEЯtKᑣgVP\,AWO%]W+tkqkN!xG~դͫkv$"]=m[춍 (HI$'mW.|>xADK׭ob֠OfP'i㐾[9'5\(7nɧ4fjߧCu+W8_=Mw6gm?\aaKtxEwXI$]_ \o^5o7/ CWAY,euOX_B,,x_'!ԼEω%q?&tf6{V7%o194GxSe=.U;u"Aw|R$CJC\Hb1s9>6mm{)=қԒvN޾^;(N_+ƿgo[Xx^ oÞ隌(d/7Ui&P߄_R/|m}4=+Ŧ д[8bx4E6Dգټm %O+{-Jgd.O,%A]'iM:6% ً ?i?Kg[U<'DŽ^6VKA J!WFɉDQmg{kdkۤ}뵻mEtwRxK>\M˷}3EVFEPEP~fK?jѬ_LzZ4QEQEWw4x/~)M?)xE^=6!sXYLږ$&&8w`bmΐξl4 ݎC&ZӢA#wV1H˹Fy7s>&5W;Fc.] Ƨ9ec޾(?+qׇt恪u~5i4+Ԋ٢բq=EXLC Z-#d,bO$A jopj0×1iv6PM.|";o Tc]6ܥKn;tMwmEU>vn:y?iNךKi/.b{I٭jg8B m)vx{T+#U5UKPңulpD.amy@F O¾1 ~$pxNqxJn/51 mzȶ<|9ns@7_:gl_nn>ۿU{nOڥofrK(oI/_fKFWSO򾵫K[;\ԯZ}IzdeK\шby- \ףiT;Hre)4DE ᩺o]~ߥUvo]i7mſ >=YR`kDy$VX mn3"=ԮuKj^xwRŬ@#j+'.Sᮧymy+-#LY<&K-6rc%K\]-R1bމ~?8wZyP|5{^MKÇ\k̷Quo\ʻ#`xj3BkniyFϑnɷYќ}\w\+]k_~~дkYt jWP߶~\+p fEX#N._,-`X0&(F>*[PBu0~I/k tϖeWU;r{j{FO -Mx]Y(L`Y yrLXq̋Y{Qu! %ċ$eZ6He/\ggQjڭ$_~<;^_糗YS>_1ۃx;WǾ=Rk1A1[cvv=k?׳ڗKrѽVZA/rcO{z-zb/v _ h!u-y%D-Ė$W rn,ˏvGi_:ŻN6[izgP&-摐cc~85|74]on}w>[=QC\M 'FOi12}ƣsY|9dlݢǒ(ĮCo+*D%\?Ye/=m[ b(]>v[>)AMĿs7"/=goW#I .qO |C"}$Sяv:HNŸ >,hN;_;omO\Zau3WӒY1?-+'Y tf2]*@1~^$t o)~4Ӯ|.ڝ62+Ż;c%F|kXpvNTbR~NnOѩGK;SЄ.^d/T/ES]#>re9ɦX 4ވE`ub3.MTl/f^ ]\[ė渾4hnXVlm,eG}F,ڼzρ(b/ciKz$kkݵ_%n%}oT>Axy5FWV7zu^,P5F#yw,TL|}֥QF~a} ;xVM97J֗AYJ}c]2Qו%nW__vQEf0(((((((((((((xm_/s%uIuk W8:<{6%//xx⇈;-6k MW#Ԡm-!MF)vީv!BexB\Mr5QZ[u?]lsҋXso-Z[UIS)e}JZ] >Kkj.qm&}/͗c*3)^/(ڠ|8UƳ)mſ^7qy%hc!؅oܭKW!$'MxůZ݇d.m< ?TE, #ծ\%"۔2m~Zg/ |A׾!|Hz}>-Z kgeٻn$J*Z?˯yry'ot(((̿m3O%C5hw&ioĽcHf(((((((((((((((((((((((((((((( CP}<_4Zl/QC;<o|MpN|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5thNs0<24l+8#>1~:?QK?ޓom-ĺt2I$6o,;'E̘}#T6:SK(E^G=I,KybE "K&|#]]v?>'~+֯5$n,egxDP`f.оm4x,IxòZdI1A=ʀx$MHtTCk+)^Vݭyֲ6OM+o_~23KC2{u$iemmckk]$*%ُYGF;+B=#R'x[#Q,.h5^}S-C, >TC˯? +?K>+@vUVJK/[/;M9fZv$wb|tڳEik9.i.itm`Zik>XY)7xO c?|+NJoKMvk[qyhDD eR VRäh~ԿoMO Bĺ֍؋,|>ReR#(~-N[]懥|FM?: xk\r{9{/hmؑ{W?~^};_j[}$=̶4DI]|, T(Vn߯/{;+un]MKis+2((2>-ؗ գY߶ſ!h((-/S_*RnF:߈0<$VhU^Y|'V7(~i׆K:c]5.'yٷHKnv۵O[6hxZDHYl[J혌Lr_:|e#?~0j:?k>-2>>KntMNv˖V+$;FGmu#3?ݶlN0WM|3 ߉6{ |:gMo~-"|5=Chpywo)7ehuJmJ>hZ9sj*VW^_[?Cؾ-xbKO9Av{ױFݘDlSʹ?w~OX]s;Ц! 6~'xīyբ6o[T7ӵ=TQ^K6;J . HnPC- |67~}6f|uiu:Hk-A$4+2Hemܝ&֒mul/{7QO{\g|!jҼ&1jwڄ,pffG+"(qŋmkѴt{bQ($Ql_NeQky_eφ2mDÖ^ӵKN} E&&.OhF-գU%B_V?b:&wmZ=JYT"w $-, .$u0umT_%nץ|6䔼W}t}|gx[Ś6q%km4`"y"fUtRA\Yi7ß~ZK"_?5]Ul(%0;,q_ kVOO / C+4 meq" @:W_Ŀ+GZ\#46‘ lʿjy~$=|OSE{kC6w fpw 3O Ȓhq) {Ҋ\W*O(;=99UP3ߗHiu}.ϥlh_jo>[x?4qwuᘵg-*%{@r#;SXvĚ_˦6lEAȰ8lVP$5=_un@߁__I?/HMIw5w N;&|GA_:F |D_!b,gkSPI-`46]@gCߕ8yg'gh譣|HlKt)S\R{etJ揄[z}~?1kov۟kb7mdiBVaxAQ׬EWᶁyhZQ5BJ5 0y#U/ 3o+Ŀi/Ǐ$u SÚšV]o%ޝd'cXs$7,ֿwxwTcedy'oչEIJ6qWTɴʯvmmKW6)r-[Ixg*{xBwuquma^,61g;`I,g5b/ž&W^d xcON=^=N+˹&xVD7mp7x&H{k;xFQ($r~J9 Z[hM+6zi{^χ9} >]xf-fhJ ^?HaWa_+xoBQ[MI5 }5cA]mܤe4ZtFY!a) MD =_߼O>]+L(QEQEQEQEQEQEQEQEQEQEQEQEQEy';?_Ì1?9& +z|G+nD$|_7P}|V?!>~t|0sFN?G+~ъȡ,5+._[_PأL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157tA׍ycH SI?_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ ~#x˹׊~|?g}mΪ̖ܴJHUAbIVbz#F%HITOmh^K繛n] S[Q{=/| Œ麵'M&#Ѵ@3AfKf*5|)j |]tx%՗EӴ;N@6Mf7kv!V1!>#:^x UWEiee%Gu!JNHOw3McZ-;S񎟤Y}(Ү.o- Dn#/$m1ޯd[+Ikt_g~CO+[j:tx ڙ׼=Z67zT[& Td>cr6)I' +\_YO_ j/8$K?!n1;T ]%X2xEԺk^/..|_wD|]xk*P<6[ 5-Z71}Mԣmo"}V{k&,{Zڰ(Ȓ "I&yi ._k'-]]ۻl{iuzk(ڷQ?!;0i<Ŕv7WwDMngxVYb ,+_x^x% k5^N\/diP˧XI4l#i=S +xwǶ.i>4 G-tRyϟlOnsiW׿^nj)`񾯭iK}OVRtOOc[m>(j/fi6rzcwuA~?XOqjމ,lZou{cVXTEvAloh ~m7~v?-c8۽-Xe2?گ?x:6 WJx,ԭ%9H'1 6ːlRލ\߄>V5Ε&F$B\JtӽP7*(Ƞ(̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((τďe P_Zd ( G+p0ʼn_(3O R wG:Fk^?j;>QXb9gV*^?BxI_Wx/k|'k=Ot:;vO,;s5Ā\[Uc.E,ǥ{ yzy57Cռ'i[6nh4lk> ~:Q~<|i5|G7.MĺKꚒ5nX$P5uM?_>|9ĭCšxľ"ƨiWuJҦHCjW܏<_^,xΝMwFYm.ᤆ|Ыk,KrwWϝ9S~׺6h6x U|xSquH9F4**E}Sn,giL^!EKGwgGBܼA*j/?/&2ږaU%m`1TA#I  :]Oזj>.քz׉U泃U's4A#cŒ!|GRugQ*ihyIJɻYZj5ll2x?:~ޞ OþouVWOm>G+xeGq%^Cċ;_pOi>0xm{ ڛ,jNl͹'W;Rb (K|u_ hon>5-b! CI|Nx*o?6iiK+-z-R >K+EM2O0}Rv%N$Wk˭id#?o k~-\ Zvӵ֢[m [d.HK&ؤ2G'y}'3e/F Zhڦ,eO6Kd0LWh2^WsFMJ '&UʚM+٫y2n5jI-9lկ^׽:/Qt?'g|Q Sizu_ hqY_[K\ɧ,/$rűq$eL@^2K]:~3e-fR{۽hvBY@_|g?'k-z-ՌaOBV6~i%ky>x'⟋!uy}}}D[ WDRm=/΢*pS#'ֿ |o{ZΡ}7ҵk;*yHX+2/^&xź2ORi<xHѬn$o.+egy&51uY"_ HG@gTz沿-﷕O4Z5m~ҽugk_?jQAi* ȯ\(Ai(aE_PZ? ?p_?3?jQ|Tϵ7MaBݷn} g[-҃VWѥ, RJE4oQEuekɚ|[/XFm3O%C5hEPEP^;|TT%] /;tR+mvD»Y h-rFv–S$T*e~Ͽ _CZj:kDU'Ko@VU۔ jψ<g}mZs"is]w%YT4@6ȵ_Iž?o H|IM 荧fFϨ{07a;nvnwo,d}@$mU9R//? mxSM4-;HM.!mEt,{iPxS4۝|[nm4ݷڌ#+y[TEWtcZ]}k y d%|Y:e[MX_Vңm;FZ.Wi @]fln \u_ᖇx썷r1ko⦓rյI|鹿t\|H/tNn-NTK3A}SCuwV /b{k-L8)8ېH ki[lpw8' ǵ~ZMfZK EiiHE&til+pݧυZ>Ǟ- [x)/ú0ӴgA&[%^pRz]'rjhj:۫$~oE/E~^|F~|K'ëP(;hLJ)j\=jd,8S*Vܹc yc|Buc^Iqڔuo1|/ͱJVv+[_IMZ?Mv_>?tFSf_[yN<.Zt5 I9#;5k7]»k&iZkڟ<)a6iu=JN~s4Y$ ̶b$۷|i&~*lއ-nOuu y! iČE7w;*i2{Zmmzɫ6JMJ*J+=;j?'/Ci=ZzhAg,:nwٱk 7M+(꟰ĝLV~"_z?ğ+oY-!{U%v]B{krV^U,rIKm_kѿ +7OIYxC~;)>hx>[_Q&}(a(eY$Jh7 1OXj▷໽ZOv6,>KFM6+y^HAj,zE}?^"񧇼u_xKަt[k[g>H5e ݢBq3g*<2Ee=I`ULvPqQ #>ק熵k/6 ~,ڗn"K(u;` wa \^я<#w۫C x: 4M*YbQG_fS" B4U]}[Y^9;{S4kwV_OEEPEPEPEPEPEPEPEPEPEPEP.-߉ʼnO(3O⿡~.|M O(_xgǞQؗ 5Y߱GO!ΧM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=zy_W$K|cltX5+6eioR.+cLߜ?5wqch(T*V(yF8h(.b`@o=_'Dڕur8m m2F7Bj}eˤì7;) 2 IQR6XPxD2L6" *4wdդ,e7z%̢IGHݫ{ۜ~.CH[۸i ۙFiRKxmB ~%u DW.;%U6Dġe* zi_SB1%u8u?df@/ N¡6$0|ִ;eH-<+}Pvr/rcHg,gg$קK5\KGg;]5fms\[%t_]hZFY|ZAx^?jZr=]y$1|3,@41Nu]m]2M4ef6X/n^|#ecZj4-^/V/CqJ*'`6%G]`⣼~)|'!gīƾ[[kK<$;3VUv3c2&u-^hWY4i, qiwh?u^ڭ/G"~2R};YiJ [_M0frD @Tg%B%gMg&i4Mw\\훿)d6'1ȞdhC+riW Ņ7ڟ'cS VF0VVR3]mƵT?5)ÚϡM 3" 8^i*b)oUy-.Enf&ǂ˰XW-uWֻߕ|) GtR-5̈́2*i#QEM/ˠ7aeX6]+[)1VǵvBu>3Zd]f]N7 h-P"%D8 >5۵E\;(ԜjIkk5F-hF 6IcFVXYE%yZ]~fwm{S`p)ʄ۽+[$ʞpO.]AI[xmA;ޛ{pn<ϐ#H+m?#ׅ. ߌ%_iZ}[nMq־q0'D_$Ҵh{[;?j;,QMgc#; ]xo64JEk*)[W}v(ZP'_sR'?q_?|M?â|y9WW_#\o&~|,l;!|V*Ώ'~}~X+~y&/0أL'z?Z5ɚ|$/Gk>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I4^_jDZHYbB$q0\KX)0ZKƟnGu㏉ix<_YKA2\4j.D֓4<]ջ$wJI/OouK?}}FB ڒZ[\[\Y!G${~9i|ƚeZpЗH.o 6&$u%R(CmE4WLJ =[YS7:Ŏk 6+}{T_Z#Q5R[vdS+ K |û'6"_ xy5 J[QNْU$ț[5/_N&fؖԜѓ^nqd߱%͗c_u_ 5GY<- y[_s 60t|p~p?۳◉u;=G|+j4 GPiQ:Zv뚣 5Ht$âJbd~G̯di;$20._꺿{_GҺ?Ah?eڷgSxc*Ӵ+JN:>5ԗRG7X#܇a-|hT[l"(eG|34SݬUm.m/FjFRWJ7IEvBk x|-|1CoSFPK{g8#,l@|h Qt 隿A:d4on._%29gdeb2R#\ʻ_vMRkD;s9u*hm%e'ݨO_UϟE~>& ցG趱iWVVERP@LϐJ u5sχ6+Ȣ2IJY&9Tn V AIc^MtwtדZ.JOɫ]~)?'m(AEPEPE[Yݍ4.aqjny]aoͳv3g+&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bkOL4<-c4|K ,Dv<s `c$j(>\Gω6'tZx?ࣟϏ?Qѷ=nnxSɨ0qk%-w hd_4`z =;-ǁ..\Eq#xEY4rɈZ\*]\3$iV N.@ '@5] AwE{ -<]4F6- $,7|cln& u,֒fI.nE"1pYOlַM/qh݈^EsDFsȲM^ݵ-< ׺{yN[}%i>|czGpCg\\I%-Bh;WIp c/4 ;IѼQ/,f9 Yc,;Xdv5a'x_--u]gXߵV5Ε&F$B\Jt6~h>ku'-܇~km-N-QPQ_ſ!k;4b^3VQEd/x⇍<)'jڞmw}ۭ w**QX?c?t+?|*o=6 g6W]KMi>y`|I"Vӗ1;&pr~ &.&;HbD yࣶ@C>QXZ6wp1Y߱GO!k;(4Ib^0ך})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷwEhXg?٦x@axTfkH4I.U蛳rۉU*6p~n`i|SA'* ca!7H3"a@rS*'<+#>Ov|Oh7ZbY؋]M'IK\)xtwIYFݛnMmekmՓ[߭I;&@|Aio 2뺾>sfmebKYc{CcjSsl_[]t x3(<:-jfilo#cwaOaR&K#Y_<[=?6eYf);G$峷9U>l!k>&AF5Oc[VzP>?,&r\FwaJM{{^&M++]^jMʟv _xN -x 9KhZt ˋ'hת.%bӍ}#.WX~>xWzئjP˩>ʳ\iI=ݸ}V&E(ݡ*;k&މOs_>~|CmujgIm$x2]Sٵ$ŕl> y7' C%΢o2S M9"WHp}m/o|ZZy.M ߲oQk ýA߇ib=ܺrm`vI(th[1Iokǿf?gw>!G,42R$&keili29$5W[}06{-QEaEPEP~fK?jѬ_LzZ4QEQEWƅjx'K뉮jhɬ\xrKCf2;;NZL:욍[ ys!z[W#UUxxRD}o[tڎ2M{uddTRTJaGO>7`ZǑ|,H3~"\]O,~ >MmUIc$I'޼__`Nr6χ?,xzT $i.kYnqd ,U9ZzwZki˞Q浝٧nxCğ'ǁ`ݯ6-]A_F<ѕIXO~ݞ1ִ/],SgG~d\n^ےm` COz .E񖈗r4WH[j77vۖDup@J?V4_(_[_ aҵ7*]}:[ -H;߲{H*d'?KOANEzYxľ(񏉬/:XZLזOet`~ޱ ݛp_"!0kʶ+vstysmunmڽnoq|Ou{ "=ƛ z}-vVF2_$F6ߌW/|ye/x7Ś M^ix_JЯmV9Aw—242$,Zr0ʦ?Mz |bp>Iͮj2 i~orhbc@jJJ(ypgJuOt/:_b>o^rtC%OoQG;WM9Zlt;NIYM)FO?us\n4kcPJњ{|Hͳ?` ¿״=7~.nX ^٬u ;{;xdg܍QfQr0vl^"icn4.5M ĦghgXD.Sm%ST_"K;V勻ISq\6\m]ܤVMWۯCqᛨCB?4RDԡܫϞ];Ǟ;QЯg;-6.btx*iak}r`}߳O(?[٭_ծlMCFkHltŝd2PEx|t? GwXk6e^1_O4 f2Fy%n{z+4giovz+mmٻ;[?ॶz>hw>/'u^=&^uGY\^teۼ68f FUlh_i|<{ú_}bJtIjWmuYLOGod nmmtMn"l)`Ѭ2:nD>r|eSkNo\Iiej*w[Lu hZ/ĶV#mFx%P=I*34_ثºsèxH|kݳb!I!A 8aܹ[uk>[쓕N7̼:^F[wozv]?R~zo =VTkG%],v Ȍb_!>qt YAᏊ^'~uOOiEk-;2DlvpI*:^2{/m|3jQk#ѝ#24a%6mfhiT{/^-?=ׇ|9y.`2 mG;HamTZ(T|Nwi]Z'h<[ݟ7n67g{Iy-^f[~ϟ4o u_FP2Xs+]ۂC\Ŷ8;UyYςW,|QZCWƐnf[/WSfdxǘmgJ6ο  jԿ nldwgpKi7e.{UG>3~vnl ng31vAگ?d~:g/uh<sX[-x1KM - ᇆu5o Zᦛh~Xe_Dm$!4)$ڿ*'KK*wnKw]׽egfs{Ks_KjWt{u6߇u||!muwiCZGm"A5]ily#O25txx _< fV}zi3&ON_5,σ()<A_g<}wKAR^^5Ks֡YUK*N#Ϩi~0<]b12V}2GoI+KCm4[B^$6<#|es%Xd .Lx3Zĭz֟NnԺIy5Ac\Ln"H UGIUj/o3ws5S>ZN_%+Էi_x-=/k?X!i-B$ڶФDѮ#lS_GbxNU-[+n2\]#E;b#2b;}Cyq`ܗoCdvoWN좊)QEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢*lO0G?!xNwU?F~y(L\]cU-_? Ebj0ڟp1x/gMw~?Ck~#i"÷7\HŸUQf2(TRzWכg|AgZt=[z&A.m6[6IovIA[x*xwXsxbK$~,\V`RE#WTڱ< L^wßJ<)|K+ jo[q[D*nd=Ơ~i-_HxC5 x.zt8\E 5+Uia_0 7O4G'~xZ-_Dten/Hg l ,ސW}/ß7{hgqѵ]WzG.u;iLlTIc\4aBʛrWN?ۏ[?1mφ~?F?TX$y{}xdq Kn)]72~i2is-k6[VmDb8Đ*0ӡa|>}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ+GįsxJ?]|_ hzn5T;kw :~<q|?~&|Ifx._&`}bٚ2!8yaI!2O>\k7 xSx=SD˚kkHx;+L l!gćS?J">+мK'ei:Χ=KrvYMq[FbXk݇o%N}owl5y_xM-O[!|Nx__6럈O w% -7ʌJw $2jl|ugmww/: m.'kZef;7Hda0)>O'x7_ wzsF|Kq=)4[HPyR" ebUψuZ]Xa&mZEoif%51|F=Fml;7N5omov+\?IEx~%ZSӤ̽I$ndeiDA[*.U<o]OWk6>-mN]@]Kw˲3%$mbP~D~(At{[cM[8xΧj- 0ETIl^Eb߄KF5k_.t{[wͲhZ*kW㴆6!KM4P\FVzVxm׭=[oxSlSI9O{wo+OȚKwNWDʖدvI~}-_ k~.-5K=I,JţM2;:q;/!?_a?Cc? ?>ؗ 5Y߱GO!ΧM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|TS_ x#^4 sev09 M& >|#Og co>i_a &.ݣp$`z׷Ϟ.^)_|=Oi:W2[rI*!!V)畉%Yk؍\y!%Q?yWӫy/mt='YU "-#!Y/@GUoߛ=cT4o6=#:Fcii亝y{mo GEF8䝥io\ty-yʰHEqH"1VIyg? xv&.+aE{ V[][Omu_̒Gu ѝ2:Q[[ѴN:KWi4g6M`M ~/.L/,=1luDӞ$H1 (p#m/W W[^;<[0Ϭo[,6:uNn|f۴|3xwt'm&J/t㵞W)aj7DDyf&?>~Y>$StZXx[DGڕfOyWӭ/q,Ҙez9KRWQ5+-o {j 줣Y[շ-kEmM(m]K2i&_C~|U*llMI,v!R?c(F/ŷf>eU9& +#w%đ$ȣLQѾ)Le{im-x^⿆BVK}B:f4Aem%k%< f oaiLJJKVH1kSycpeYB*ʇD5ej<[/^dh+[i2zUQ_]5goJ}{?D"hN/-S-,u+D^i$o*vF"eʥDm[{oҰuA4P@8pmB(aEP~fK?jѬ_LzZ4QEQEW? :O/j: ߉mIo`{6> T[OW-<˽$HD,k LqjWCN7L4KYen#6؈fiIE|k|hT[l"(eG|35]ٝR$ٿψz'IŞ*t}kR-(Soq""Òc zSjxQVj]4oT5+C?"4^[^hQHխVs3FU'_C )h:'75=ipI%"yYيr0bS UO;xA=uرmve؈Kcj?:{?&f>[i叛p"_.s۞M*NsK߫n.9yRjL;EBVI8^kx&x:a1kRxk]1hB.g;#4A_T~ ߵjp|6<>I{ir^KjS`6YLsѕxMK~k CzU38y)̌6;ɫK59Ow?HllH4;Q@cXOudSib6NnGoZhN1ӭݭu2ozA~w'5 r5%[;&K(V$1| CW#a~տ"~^4W>|CwtK&-{I\ozZBad ?{|^fڷb <=[<Ŕ|#KTܷ]zTwkonlJP7vVlW$H>*tX/K Ժw n"hIB%>hO #Lg`/kF4h=g^Z{m{ Y՚Z_׀/~/ZBVc+ͬA_).yʛ]0& 'zVj:fe{N:BLQƁzI5kG[vI? _uFR$>mi__vu] zb7ۚw]w~H3B-NavכAOh_1Z|36Z0t+{m>4Si\ܭH ,aWN"9~9~|h>ŗ|Yq$Ǣpٵ >^7I!t!?-'Ꮑ.<'{ggi]rljZTEq"±͹CtkBQof/7|ֻ-D]HՌNZ)o8^/!M{J>?xt?KN`݄t:sG jKgn𢼐Dim:Jzl𥏍t22 ?mo_oiEoլԽhݤɖe?|%<|8M_w, K}"Iڤb' Np3Ut{C; >mEg;bT-`   FrI{F6ߕ7{tZR^NSvndmg52Mɟ1|G9xST|?uω#XI<%wlr״ks5vWm >-xEýƞ#O{w#[) e$1,y}}KbkK< +Ṛ[muxᑖd`^4EV<NfgO,tx7MK(t[hbK)K%ETEI&zOyWIvg8MJ+Wv$|BO%-?WI6qXh0X]L,6Uss'!|$6П[mxmm%[/"F2oN[ ï^oWѧtiyږ/e[j^x":2e!'9cq6GMOɢ>YM)戊 &"WcՕyR:()|2_ᕹWdr$ h8>,xX Kw<1w5nmshm$l,'dq&vπ_@WkZMZXgvp]V4a/ ߒ|9OGΒ1}>_۷c>~ Gi)k ߤ:?#K`FH3D_b$Ub&ޭ&e(F;}~WY%9j0 uy w6sM=OHn-ثo|<{ЏrwW> ^Ӽ#GXxILM!/:FQ )EWmy~xu>Dx~]֮^_/}LRBBFojը伹R_'3Qtҧ}`"o}ZR,xᬚ3^?ti89qoM%cp|讯I0\$+C^>!|nFC<[in4M5/~"o1/+\9 $2aGB>[z7φ?twUM{Jҭ|9g %/`c ’HpIO}OU\LP0$`Esd2Jk-&ͤJۯo^N[WwR}QP0(((((((((((((( *lO0G?!xNwUcbES 9) es^/F~wV??h;/!?_ƻ,ucU/YfS=&30_qiOzuMov6Y[vk ,] YJ ?}kZnxOD5h%4mݡfѴi< nك 8(8 ך}|t/EOxSk0o \tO5%kݬ*HjV0Ri>>|.s߉Z4W@O|EwQmKvҮ4hM̐Я%z"+(x~?xFO.k %{0Y5 PlJ|>%,I⟇:t> W5g{[ cBl.A7E_ >wM^:/D.mWU^ ND%%"XW hЪܩkOźg~x៏i1xO -yeHہ WrAMh Z~̚FjZMV𕵀yQ1$(J&Xg?`Ow>^XksIZ^'WO WTYҢ:h 0|I՞mF'y+&eek֯m:Dt_R =+Eau?XǪڜWrx}?ݏ,JB1L*ߣko?GVZ/ SIXT{`Yn <7]*?cxx"joh$&)~ Xw[xs7 Oԓ>9k>Ξ^^{8>0k[4k R]d[PB[#v>fLgwÿG_ GF%e dyW"I7ʬ ?]V/j*ѣ-xyso%ēۣ L6˴*+ۖ/R}y.OTMefԯ廎vOK=웲 d!|]20m/.ҙPxTնTnjn[d&W_5{m|Co/{-{¯?4-sR:-,EMmG}I%) 4jG~2@$<]mxP!vo7l$RI 7$$R$n ]GF@ǹk)N ڀ=Š|Q?t׋5),H cyI8t< 7]Uy[6.L&E($bע|Vڟ5#_ӒkFo#M o˜)j(((((((xZ_m յ+ . l IgAPbeEQ3$ a7erߊ~ GA$Uovp,,!4R V ywm.ERQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_6'tZu?ࣟϏ?Q<D+׭Ky/}W~s.xC?F+,j~?ɚ|$/GkFb3O%C yٞEP%{ⶀڝ:mj,)4wC j~! * ͗__g75q+8~|g{pc>jn)JƥD.' ic?Lju_ |]}h[G%Q`OmqZf;isI)R`FcxK];|[^vI;?i_D:jQj=h:爒Q(-)%uݱ)%'a V5&Io正^kK֭sHhW;g*-V#<)ZK|CxOz|ΥfW -8mc{խ`=(3 / -<xB[V7^zk7Vپk~ YoJM5R]V &b A2LPܡ$Rᯈo |D[xrJ4 Z_y=q81y]6H+ |?٧B>&|M*kG^Ʒ8i}~XMR˼•>'ΗK~5 nk 9m9k RZ?*V•;p P捶Vt_nʜi-$i[mkUV| P!Ns4N7S\\<o1VEp; G|;'S~%Pj^+tYt!+Zo]76J NG@'6Xhmψ<h!{}kEʞE-32DQ%%L3[BMcᏈt/ ֚T(Q.o 7 _ LL6W>Pm9ox۷^kK5'dUE4lڶӮ%]u/'Pj3j֍|5{8Ha_Cm1) O?fgc]/ǟ5 6 s-d]X[oo X9/d8jHIwhycmk _}Š((̿m3O%C5hw&ioĽcHf(((+eəxsZ/kY[iA;(#P0;=~~??8aþvs%žw;e܊F#>GZnj "GJ1‘;@S(i=$k.]55W_KҌ};g?|SU@i/?O4cōE;]ZXxOsjM+#4fB#WHN<[othEK&>^j#_hYStP̑)+!O>|* x&m^Isu}=Ē9Iwy]ٙؒI&* PTս/k]5Zu{]?*~|MKoV3ZW7d5xUm2B"բ<{_ujĄyv᧍4[EiZj6/ntsdEj& 3@MiY%]9N KU揘ߴnmvRqmZ5 V-We}j$d}b7gCoS#M|?xet CV%4|/e/ K>;+[inEXO&4I҅J6-ndžh[{#L?54$C]CmnedptRI*o(o.I#n֊?}Qk+?z'>+>aqt|?kx[MC})-5:u,γEΊ[ sU-2i>?uaj~!<7ŶYLږE-#2;75{Z>f薟iI?+?3C}_5ϸ/'=lׇO<\̲-:}dZ=.tSKdJ:+E(?4TI5"׫rrv饥Qju'hM:o$A/1mԿM?â|y9WO>+M?6'tZv?ࣟϏ?QX)~YC_1g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|׫VcbEg 9) esV7_sR'?q^oz^?:˟+cɟ? g#<6-8ƿ2>?aqWemOxE_VwQ&iĽHa?>ؗ 5hzmQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPzo6'tZvࣟϏ?Q-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5jş+O0G?!xNwk,gZE 7) er^/Ge7??aɍh_Dl?M+7ЏD*0ڟpqY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@/x]_7oR'?q_зJ?Ţx9\W[ޗr GgWᅴ#N*1߆Rt%$gqWemOG³b3O%C hwQ&iĽHa4Ch(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>XEsPftZzL??9Q?,?QkfO{R?E_Ua?C/bBb3O%C hי.Wş ;M7Ӽ3[i6\&("XXHP3ҼϢ(go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-{4b^3Vy|Y^Լq ;eΓu%oh& j #8=+(9t~S4qxvX||ʮnԲ U$sҀ7oF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ Mkj5ߊ;=ȦhRH\ݰV# iEK tJ~QxOǎ?xNW|K#Ƶ_ϯkR'?q^oRgo_ܴ_T)!cq~f"{sm _0|ȩ~VYQ^iEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP?n_$qtJ~L??99\WbAVa+!xD+׭KwjW(~<~X}?O:x˯v xrbe!cXՕ?C*U1vQEW}QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEecb`VS i?dOUuojX͓?Ə?ojq9[| 8еZ>-5k+$ms46i@7Xn}ҹfGl޷5z_Ǣu;O^6Ul%{ k[y&r3.<1ež#^k 95 ݒلY^Ԥ@щHDdm-݄߻}_D/?oh͓?ƫRLaSZgh5ܼ(df=,Ā$ ^)#`ck,lU pAV.3@l޷4fU~1~x_Wwb:]Gͨ]@c#YV݂mVa2_+軽Z͓?Ə?ok)x-5;el#I :8<G0kNhJwԱ'ٲzz=K/Ɵ {'" i"{c`ŋi&T0['@k'dxZg"׵ =;FѭVF$\1Af$ UO(_!EPȿ##ZD 5) er/āL:%?Q?a?89\W[ޗ¶;QL/CعcfS{H>%~fNQjc< (Š(((((((((((((((((((((((((((((( .3Uu⌺|3^_i,v c 3xU>,?{]yIXkׄ5w]CڜwYZ6wVo){"f@2$vK-s ' gfi5oi_Gl-Ǻxgw mn\t溱d1 [u`D}6K̖o>H֥ml)im2,^2<-?-s ' gfj6%Z몼͡rJNw]ɽRkD \³I@|YYڒC 3&GF^_-!G cL^6ܿV& Q0$sJ R5^w[>(ˬ=_Kj9F'`F20U~;Fƾq?/t>U]3ui8Y?+!eD \³I@|YYM7]OmOGǿ7~3?$S@N|3SHx6+STD,?D'OkzN[v?oSF+wkS{|8&}ahM.~QPʲH( 4xu3VҮ'O}OTV՝6qC 1][.ءXW;"i=D \³I@|YY3RK4[C)Pq~]uQ2? 6:?>,?pߴ~/|}oCCX&׭ w/}&U+TL :Ҥ(h26r|V`ƿ?W 9\Wǿ si~F<+Q"u_5/x+Dy^|X.o>$V:NEZ]MmdH)]]9QA%!^jiY[S<e_*b)N|rN*mO+}A9czxrPG$ |+٫~G=W~_xub{v~?W?W~__3NJ?eW¿]Eq~ό'eOE|)~\c??Kˉįe?._*Z kO.r\'@Gf/~I>* O.Ol#O?|H0|rgGWŸ롷T '?c?#S}j+Y5:|M+aO u T߲ <-QK*_-E~tk7쯟 [6xX?Gl~>1@u|{;,]4y%oo.d~U?9<eoo.|y=v/쳏 [2??xU?8ǟQ_kxzOg̏O?Fh?X-Յ5'o tfG~U?>`~CfO_`_2~5K6??xW~_i?eo_4+]٫~5??[ӎ5Ԇ]3NI[C'W|oU;}F1η,c~/gAg~и~b!KoV_;ڜ9'z47*o5d w%D(_ˇ[~__ Wƫ/iXs^[+,ȧokTjR?J(̻| l'qQ u'~ 3 W._?yk??R(x|H]xW[¿Yw60V[]'W~<ԌV#OXW ?AT:wo_o~?gOV?B[_%E~rtYϙO[o+֬?f?elW]R˗*O E~px_չ%[¿{1VU>?#-WOE~TjWXş?럸O$/eyzƸoa*}z+RodgO#3p-J #n~ 8_ W_]g;w$YW?]._?x..T_WYl,?]Kg_ tg/?%O?S?#FeV`_(֢??9Q M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ(.I񇃴SG ꓋#Ok67J}ߺ*  Ko:uzͳG9SlۊS^5G1G:S޽[=37K`RGGMhyw L[qڞueY-,3x:m 4whMt-xHϛgKki?WWd]-%Gn۶qIiisKxSMχ/ Yujvw:vUC0$1BN?t :φ6]Q6)i'E]'q׊CLg|S 6{f×~Ь!뚊tw燯E_,VRڥܭƝbЀ/"eupx[u'ߋO'_MZMO07UY=ĎHVl1+/+4-7/xzgB]$siE,&p!E#EuE&O浭~vvIS-{Nhzŧx὿u F<x}֚lmyJnRP8f? \o WDmi|Sb-t;sAu/ YPbfo}(\i>ڐ/mBtQs YaXaH6&IYYbtG^ijzJMI{lVHfn^#4Oo>U]Nۢj*9Z|>I' M}۪Ikmݵ\q!?>ǹ_jVwSr /M;{[%rS $bS"NR+~+@sgϥ|/'Ə }?ᖡ/^&ݟ~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I3;ᇅ<]|>ޑWv2ZD-l㺆{uY#,[D@,DX/߲X<_5{nM_oÿC}&h C-"\D r~?g O&Wx<'W-ƫhx;{;KN0nY [6(\/?~(jm{Ěrڦcy$m }JImwlJj+i II|B{?MVWz4KjnMM=!Wdy%GlS+<^So;&M?J[=K~𿆮u+4Ҽ1o}kFkA^xFH̑h(sJWkF5.n],㾶3oO[_]O?ZW,~ |<4 :xSTL{IluK˘Yl bo;U-N, >!$-+VJ jEKi4x f n#<޻}t\ȈbC $FzR{kvl&x~ݽ4Z[Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP͓HcL?GJrG?Q/g7q_ѭnH t`+9W9~|}و_(AUy?E㯽_&_$\Q}\z9"³b3O%C hwQ&iĽHaC:7oԟhNcT|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<ƏiރW4x_J-b? 鶚dz<ehHC2ҤAo_ோ }kxEЯtKᑣgVP\,AWO%]W+tkqkN!xG~դͫkv$"]=m[춍 (HI$'mW.|>xADK׭ob֠OfP'i㐾[9'5\(7nɧ4fjߧCu+W8_=Mw6gm?\aaKtxEwXI$]_ \o^5o7/ CWAY,euOX_B,,x_'!ԼEω%q?&tf6{V7%o194GxSe=.U;u"Aw|R$CJC\Hb1s9>6mm{)=қԒvN޾^;(N_+ƿgo[Xx^ oÞ隌(d/7Ui&P߄_R/|m}4=+Ŧ д[8bx4E6Dգټm %O+{-Jgd.O,%A]'iM:6% ً ?i?Kg[U<'DŽ^6VKA J!WFɉDQmg{kdkۤ}뵻mEtwRxK>\M˷}3EVFEPEP~fK?jѬ_LzZ4QEQEGC|67i&6j֡j<=NYbTPƋQ}rk|ݞKMO{{d|L† b,ğ<M𖛩K}ks?sd<$CdrBKj$ %_-@]I/P߶! |Y~&D<Mw%tX ۽BB3+z پ?~{go3Qt }kCMUCqñM:;w 3|`YԼKx~VF=׳FUv0bX0 o(GMƐ<7⯆l4 Vu;HĶv;.ekf)#>}W5sj $M%+ C{'fkZA|B]MEwwWYMI c"Of(^񅜖^-ŏDY&]?GkST7{w 0nom~VM5qk벵_49Z|I5zJ6/3{I0ڸV/O,j"Ǖ"񘔓^}; iυީM^zcǦwh- XgX {x_"BH~f6+Iմ85C3Id}pDoxnء-e,1M_ax൶kkOlaI 9eB"m,Gڵz~"k~[mZLĚe JuKym좼iUVIed#9'#A!F<'M_V+䰞6[Gq#~(ݟ E.k%>ᄑ|m:W|妺;_W쌏e0/G|%xx\񥰵mVnJ0VVA!CGc|^2^x>SEO<7cKhخėZBvc샣꿳f>(Ь;+;X{G紼o%,jxYJ1kп`[? [jvKổ}#Cm1qu#JڼVq.8o&vՄ"*#?%xǕ/I)Y>5*wn颾:/P/ :A~%}KkjlAsmIks IܩHL ϋFW|;spx]"iD<ۨi ,q2 `k/_O i֞6%-C^k} r4W0a[_ݹ'h߲W~#o5dIGö)U~\f2V\HIrO`N 'k^|mwѶ2d􋷛խz[svh $GO>(CHlC]>.6uuH\AL=KOBf 嵆hqAv1wk23 `#4:oiRծ̗LTxm #[iN(ˠrX>iҦӴXLIv:-*䞊+-߲Rm|QEEQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@;mW}<_4Zq(?E+Fa2R@'/L-7R/Hǿ(!ӝz~}ګa?H1?FckoƟ<:E15!i0أL'z?Z5ɚ|$/GkM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=z{O_<<#χռAn=w-WC>O'*8ytO|T⟈^"ԬW7ڶSJ4d a@NV+kFRZ TrG|_Mf{]#ƚ-}5\ : e`2?NK~&uwàk[KG. I IJ435줶Qs&%!O]׶J z}9xO,eƋύ<9DA/|KX]9Ʉ%|*w9*H%"s]Z6Z[v^RMmfzߺWF>(뛏~/7mgzF_=5n!h⸑'ȻFo-_G[բtxFOnN[[WmuۋhI4ls~l&(QJ_D4~~ ŷ쭮5Hn-=4"! .cC.-d~nZ_$<7:mf-xZ?$5)tkii,igA)r.ܡm3?}S G55l>l%f[<-e݋q&QRU]{˕']oߎ=|[{EQ@Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPxj7sg#||9W{;oţqkE>>F+v>6V~@? `ïT崕|?>p:i+*³[Ng~f ?KѬأL'z?X)Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[`I Ǟ?>$x޹:-Gn巳X]ByAg1_??OS ZVu iWF,R9_L7H)cmus*KD꟎_ோ }kxEЯtKᑣgVP\,AW))B_!=t u+{ih%ӡI![yff= .dĠ)I.gkk[\$pKә鷍|g<Ǿ%n#EF,lkᘯu8-a& M-4 &Bq^KxŞ1?~v__v7z6YB-m9If[̫R(UyX{ 3RS?C^}xLP%W7kqc-="$(4EYv/mA[~gM#ľu%O gT4S"nHPEeJY]o8Jhdkޖzo_e[_(ۭE?#K+kh[]"%8Q.zͺ84 ]Rep?_/O]zdzBO赐f2b(bYGo^7{{A;.uAlimȂ!`H]yIY^q_zT_|76yl5b[$@#K՟ߒ+KYϙsIvN+K7kדMdYծIS_-ؗ գ@Q@Q@-d~ǿ B/7^(准|k kmSZd6Z|p$MviD9VR8d&f!h$gƯ&}kJQ-i-̏/,H01h?aQ_ !'tOxWV4H.Ye KQx-[x_e5|dI.$(G|XCԾ,mq?LעyՒ{[EM,vm !{pÿ|_:M׊&qvkئ;BMm0xƬs^%Ki0I26Q{6\]k++.\RMԞ՜Q>Z|Mtڧ7kG6kvq'2FKJ1X*5 t/Cw{ݔ&I՟\^+il95Ւ&XoT!@- >!x.&բ+o,EшH'p ZL xK/ZkQ ,\. #57RZwﶿ+OWΦqk8W}Z/̚v\>e$?k5|{I0ڿ.UHʸ\)&lsF|cN֦pxlW J`fg|߈oy.m4%͔z}I }rFiYm#g{7_-oƩ}6-ҡff~f-pb'&f--]4l}+^Td,l .i[4y_)էkŻ=ߊceſ١HđC&`9 %rro5|>ͥi x$àAxVquI4F|n uMOjN5^iV_emXfݬ]$┃ VMIb3Z_x7į &g{]X"oikolmD;2I EPCYIOk+w_MUmW._E_?2A|#>/h/t<a}[1wwlWcK-a! y A_ٳKgchVZ͕杬Y=vs^Gy Ϸ݈5<,I5h_-];JI޾k6v~y^+ed7\[ǻjQ`|^1KJVO|6ʝ~h>#fPt_~'E}&Zڮ=w\jZA-*R9`#k 57.\c^-v[WZq`/'Ox_5޹|_`+`E-S4HYߎ?M?𝮷uEWص\'k' f:׃u]_{s^}j$i׵n{ߚK~)Mnqw4zj:JCf|alQ$d/+Ï_χ!xLoAq5׋ޣHgӦ ]6~pC*#F> 8fLDž>(O>.x_RP\g,zpUYfbujS׵׳Wuz%ZZen'ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|TS_ x#^4 sev09 M& >|#Og co>i_a &.ݣp$`z׷Ϟ.^)_|=Oi:W2[rI*!!V)畉%Yk؍\y!%Q?yWӫy/mt;)O]oD_ E6K~'4FӵE-;d M+4w%㼗V]NӮ,;=\5Ǩ- [e[xĆ?{LOy-Vm_OH9ɖPTAԄ*w9 KUqye?|5x{PKXk/ST0|ZP)tc˹\Rޡx~D}ޭv9}CCal,G|hƪe;km7RWh> io ڴYREj~j8l"H$(|Vws=/uwn岵ו맦أjRMG#hkQ^˦5IZrYe$(_gy|]oxO|C◾¸1im$_V9]Hʻ7o,W9zѮxI_OMeu=-m졳khܒ&Sq"Cuh"dҼ3A]K֙>}3E==Aq^C^Ax_72-=ZIK{uӵ=>5mEܾ捙XˍEq6a=Ɲz$i%a+}ZbIRyIe 0b=\9nV|chjg,!1^i)R#ƌ$۶o.@QJz5s_~i~[ZL׷:Wt][WxV$i r *3ҺZҷ';N}Bܫp+"(2>-ؗ գY߶ſ!h((((((((((((((((((((((((((((((>jv>/ g%CR}k. _sc.:'tZyࣟϏ?Qc@ִV𞉤jKioMCͣhxݳpPpA8#5l^#F#⧅.a7 .jK<'UX"-c(TB6`8~||]ÿ h:\i+J!q#_Kr>DWg~)x #{7^-4=7C03JAGWBâ>%,I⟇:t> W5g{[ cBl.A7E_ >wM^:/D.mWU^ ND%%"XW hЪܩkOźg~x៏i1xO -yeHہ WrAMh Z~̚FjZMV𕵀yQ1$(J&Xg?`Ow>^XksIZ^'WO WTYҢ:h 0|I՞mF'y+&eek֯mzxCö/?GžKsZi^{}=8}I %y.x ?|Y iUu\6jo`ũ9_6ܟ_IKՊc^"'x_wu-|5z d$2dR) &Cd;,<૟6hZ_,K@1K 6bTPS /O)4/M>HR{Jڽ\OO;0_.kU؏H5ڣO[^Ҽ/vW6P.7ofcXQcEwGh]oڸO |/,'ٔ?NCo$P#]2igsAP*_Oo Ǟ3<+oLiQjs^Lmla/XW^;&YxKmѺ7 CmTcɦK$bFVTvr %OɤҽM8%{e$ylޭ^׽b ?x'⟋!uy}}}D[ WDRm=/΢*pS#'ֿ |o{ZΡ}7ҵk;*yHX+2/x F_?txjI;QѬn$o.+kY{73lL]`VHC $FzRqe^Vq5iZ;kn޽wQE%Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPEP_4~?o߳voiơjΞ#핖-N+E hUw&_{OKMԥ也Ϲd\\Kq!_2W 9!BX vz-6m>g/2O# h%Hj>|G_~68 k<]s=쭢&;H6xPèj$ %_-@]I/WkgIϩxCݴi{Ifݽ`ı*` 8?N=l N 3RZ[*k|{pÿ|_:M׊&qvkئ;B(GmC>?x_ %M3Pm>YK%(< AGMƐ<7⯆l4 Vu;HĶv;.ekf)#>}ϥ/LV֐rSE< ;!1N$:gc}N@Xν65I!s!p}I)h Ơ@΅!V|.FQA;|ރƤMSݧn^{_FtڍX{MRzӶ{|ecDE5k⏅+(R(dP\M ,-,Pm.v>(=[{kZ‹=Oʹm*N,2 }@hJ`DhX.hf_47It}GLm!Z3kg[ Ŵ+ A$W~%7mKwo j~SNÚe4[\3f>N3NQVsj;jݒmx`(Rj}ޫ}z䷻fǟڷY3|g~_59Bej=.VZ;gS3=7y>(׬%QGO Hu+{5uCt,r. o'V)]7\W.n|zksYCxq2 EG_]DŽt[]:kO\lXyH"Y7lw_qf9]u\6$!mۥo(Lj|?|_xzߌ5$1 >k6?2Y$?Vz骯*C%ѺcYV{{+;dFRAq"g*Js xCGq{ n,uƢu[AKIKT WhО~o0 j>?ggRQ+vVe RrjC~Y[\һ앛m`'-z'u{&{(7&|?I/|y=_מmUmsxC(𯂥ixC ]?{<$} :-=#! *}aFҷvM5%WF~_V_1?qoQE@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQENj wabE ;) es{ sCbE 8Oj XL](+~WGGBcU/YS;xK³b3O%C hwQ&iĽHa43S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nnk ]@״xg)xMJ;94etdR/5kOWsu{>OA#PIqs xT" 1kO&ƻsQ˧7K_v'eEW5ݺua䷿(jI;#o:|7м5jG:ơ eG]fge!-R[I<#ZxT6yl, /-|QeDWZ" $bRD7_7Wt(ݷt>jMo3]DMN2mE+_zc/C^"4ưɪjz|nf{tHt"^Y ʜG3Lc5 ۿ+饺$ߢ"i+GK[ގ[^g?lv/6 :ۭOqxgjhxAY(d/+*}Q݇t]Y{(|NO_A滖//^<.m%FӍ&T F^(׏8=Ώaxk6W6k5ݕٙKWq%#dtyRHW"Hg_x^D;ˤi-koioxo%,[B΄nrWxߪI([U\i8VKS뾎mW^/oᆍ|WR'hu wfޡkwv@el$am?U Ūxu<%ЬKzKZ6QK$i4]UUy`1H129&FFoXh'eTa_>|'5_qxZ{>"Ҥ +H[EBUM:( ٘{߄>V5Ε&F$B\JtzJ &3i=SJ5/}uw֎&fBjQMN[ۮKEW)y&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@-xsibE 9) esW>&؟akC><D+֫ ~/7??j6>X+~WGC>Eؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfCj# [gGk\鶋+Kzp0y_8bepFu4yh3[F@YT·F[1#E$aDw;s~ޟ >!ĵGi>'M2&ԭt[mn8@Siw 20h<'mEsW{-6]&a/-GHIFJ"#!`aIQW(_3%$1f,<,U[?ɫ5o{ܹ-05ODJ2} sRզ.%ŬP)$NybP8o/يshzn-ߛ4ťA{rXuyvk(P/mNAxҵ |5:TYP;*:N?u >%]7O5ZX$!!@ 'p Nq0{e)j{F>N*ɣI`0SkKFIo'}8>׾U׵-?Qx\m*kVrbԎW1՛d:U2٬pmb)cp$y2HXq_>-XQ|4ms5^)ـN'!yKO7z][TaӒٍChmVU8{=8^"8ZOD杕\wREۻla=:4mw;+9lխ-m ?~ʓj~!M|>/4[=F{6ɧ4Qa+oreh 2(ach/<[KC[ Kn,o`\-QUs>f|U7??hzIZ@aZ[s4& x~wR&؟akC><D+uO_'4Jyࣤ>QXZ:~;t/!?_՞a?C ?>ؗ 5Y߱GO!쎧M/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=zz./z_"O_%ukxN?onMG iځ`f"̖UC2k 񦧮x[Xwnn xZ]h`Pɭ/.!HhWa+Wiiv{<ͫ4\2 #N$~ ;t|\sx7^\hIEsiamsnܢ(,fY#b ռ4+kx/)4^kYo.YrKZjmZi+dqoþ.~]gSRm6MdiPX_jV6wv%YSmhRHϘ+Gk|+9x_C-/7NY힫w$s6:\#F);>nx!=Ow/އ.nkIN , lu >]ļY2s~/!Yn|_jӭ4>}Rm=KZjvȶypj&7b$2mUES{忔_7'oDqy\;;Iko <W>/ŽiwhxTkK&# vwLE`1H129&FFoXh'eTaח|!|; |KxTubkOkO~>l%0ikqF1_~i~[ZL׷:Wt][WxV$i r *3҈׼זܜWr;htQEAG~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEĭDZ|e .&;HbD yࣶ@C>QXZ6wp1Y߱GO!k;(4Ib^0ך})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷwEhXg?٦x@axTfkH4I.U蛳rۉU*6p~n`i|SA'* ca!7H3"a@rS*'<+#>Ov|Oh7ZbY؋]M'IK\)xtwIYFݛnMmekmՓ[߭I;&@|Aio 2뺾>sfmebKYc{CcjSsl_[]t x3(<:-jfilo#cwaOaR&K#Y_<[=?6eYf);G$峷9U>l!k>&AF5Oc[VzP>?,&r\FwaJM{{^&M++]^jMʟv _xN -x 9KhZt ˋ'hת.%bӍ}#.WX~>xWzئjP˩>ʳ\iI=ݸ}V&E(ݡ*;k&މOs_>~|CmujgIm$x2]Sٵ$ŕl> y7' C%΢o2S M9"WHp}m/o|ZZy.M ߲oQk ýA߇ib=ܺrm`vI(th[1Iokǿf?gw>!G,42R$&keili29$5W[}06{-QEaEPEP~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_6'tZu?ࣟϏ?Q*xZMbዓq.ru["2I ]Sj*W1{'υ|;+P𦃪)/1-nUƝm:#DE}!x○<-x7_uKMsq7c8ԮT}|T+:/?[/_τ)sCh}]іwKi!4*Z ;8$zA]_ s~ߵZ/ë"=BFu_ A2\}]R)%Epц *mʑ_o8n=o[x᷋>ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F<7==+W eu~o &Ll~MP[۬b!6 T0SxƕU'M_|MĚefkt؄&k{$|>&gEqh>OMXM.iH]!Hאַa05䇍; OO*go B,)vO:rXI-MfC7mF%cTUv U;wwտݲd3~{t}m4=o:֭]|l^?~#xm<7_([sd,*1*!ޘb0=!՟߉ +-tx ?ei;[h!;y \L>| SG/q-:^l-m!CH'oM]WS>#~/|Y~&C}iuc㹆ƛEizb DnLRJr}_MW{<;l5KYjLs 'S{kֺjMNN2&$M9o/$eTEu>_xG qU:Nw{mAu-.X̖蒤 CS 4_~'_%lu5nu:^Ǩx0Sa%y ~.Hխ~&~1o^i6ɡh]_o֜^HOq,q4Aq,MZ/i[ק˷[Zh]Ͷ^4mίMҡM&-? V>ѿ}> "jF-; ;VDx]*[b%%:|5@/4$+E4"|@dgkQ|>v{&;ּAs`.n`OEɎ=BXV]I&K5 πjn*)<92;[@{'3~'4{U˫-i$sĒ5F.J<ѫ켗s6޺F|A~PWêoO]o Ʉ}K ʬ #I`Wook7Xvx#FҴ֊]NSP\ǣt`IrN ]~4W෈| \v:wmeXol$VY"YRhDȤҼN Oh|?D<;hVfӢ+y-HI#hؙUׇ(ɭn٧%I[^^OWOUZdžo? z|kEc}wZWi $J8WFP+ޅ+-ïG-ug|7O:'M7P{Wsm[PnwPxCE<;㿉:tV6ijDvq+diW"<Գ[I x?]~)?m,<-_IaKmJP3o*a6QIhWN;G`@ b#Rۏ xOW2~~igzHEYdQ\& {?SϨ^&|2i=Cw~"k)扬\j6Q㽻wh$,n]#.%1.B {C7l:څNJumI~w%sߙdL6-:[I/eE", t]XBWW췆KD)=ƴ[v ;#PlK/4m'])lnw:֢l ڴK{to7;#JPRWMmk"j6iX: (U8WEP0(̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((JL:-:QHgǟ( ӝEwU~'؟akC><D+׬qKџ? uW~t|.? G+~YG+Ǽ~5?Zk𵞧:S[MV@.-ª1yBcҽ=cu|T>#&]%MIgkEe (AՌTbO wVMUxΝMwFYm.ᤆ|Ыk,KrwWϝ9S~׺6h6x U|xSquH9F4**E}Sn,giL^!EKGwgGBܼA*j/?/&2ږaU%m`1TA#I  :]Oזj>.քz׉U泃U's4A#cŒ!|GRugQ*ihyIJɻYZj5ll?Q/Wn~'x3JGtO771꺅ܰ$nj)c#RLjS: t~7v/6Tm-.+X w[O&Me OÞ-A"/ƹ};x -ɇ_-=a|2lxSn$~ xxZOAs^&)Ȇ${f` YǻE}v-}B%h"HMv2O&|vZ4h ^2\q$D:t6Bcu 2 b( E)JKꔟ{8K$mY+nݭ{&W<:M}5= ^( 6}3;@bܒcDž,w><|7 '/~+mB kRy-0K5Էi1UVfT]%X&^l->g70KeZKk-1vL$< l.ha,Ջ)F/V]e=VpGf-šmw~ LJ%ԯ xš^Xiq\%7V /$*R?7ugG/rLĺ~nj1jhHx oboٛ_ tx4'^үWH^'h`ёivRŮ~)i?> 6P5I4 e>+2X^i.ڲEz9]A5Jjjskn-ߐ2?=/ |6u%8wKeuxBLو>ѕ*ևD.&O;"{G<^f~YګC&% ܈YM i~2X#T6!,6Xjn`:v\̷v{VvgzbŴ9<R=֎ w3ϤCCm+_-LrK˴T,)l=mU;ۥY e?hw8_b< ^{7@OM \Ԏmc}gd@[QjIjEC$G~? 4[h^":F $h>TC"6,2I2|iWOk7/|e?Ŭ_xb9/[6!l`Czu2RC28x~[K1[E Ed*>7)Z6rYYm.nU{uWK(aEP~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_6'tZu?ࣟϏ?Q<D+׭Ky/}W~s.xC?F+,j~?ɚ|$/GkFb3O%C yٞEP%{ⶀڝ:mj,)4wC j~! * ͗__g75q+8~|g{pc>jn)JƥD.' ic?Lju_ |]}h[G%Q`OmqZf;isI)R`FcxK];|[^vI;?i_D:jQj=h:爒Q(-)%uݱ)%'a V5&Io正^kK֭sHhW;g*-V#<)ZK|CxOz|ΥfW -8mc{խ`=(3 / -<xB[V7^zk7Vپk~ YoJM5R]V &b A2LPܡ$Rᯈo |D[xrJ4 Z_y=q81y]6H+ |?٧B>&|M*kG^Ʒ8i}~XMR˼•>'ΗK~5 nk 9m9k RZ?*V•;p P捶Vt_nʜi-$i[mkUV| P!Ns4N7S\\<o1VEp; G|;'S~%Pj^+tYt!+Zo]76J NG@'6Xhmψ<h!{}kEʞE-32DQ%%L3[BMcᏈt/ ֚T(Q.o 7 _ LL6W>Pm9ox۷^kK5'dUE4lڶӮ%]u/'Pj3j֍|5{8Ha_Cm1) O?fgc]/ǟ5 6 s-d]X[oo X9/d8jHIwhycmk _}Š((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((R;â|y9WQVcbE_ 9) es^/G6??h~׎>QXf9ז?+~YG+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h((((((((((((((((((((((((((((((KJL:-:QHgǟ( ӝD#SbEc 9) es^/G6??g?OM z|R*υwtT#WemO8E_VwQ&iĽHa?>ؗ 5hzmQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPzo6'tZvࣟϏ?Q-ؗ գY߶ſ!h((((((((((((((((((((((((((((((\$_>%` ZE 4%rޏŇƟkhuoxOǎOz]V?Gg/؋BQ(/| fd>!cUYfS=&/?+;(4Ib^0֍y|YKþ|q};:ek%ςoi"%ꪥ$9+>"O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ7m3O%C5hיQWş_ EMKӼM\7R[x&f)h+ R3ҽ2 ( ?Þ.OW.53Gn7̪K(9RG8(~g8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OCڛO]óڬf/E$Ub2*pzPQ@TK HZD 5xj'?q_gĿ,_?k_0F!??xNW/F~{(L]E uB<ܧ~Wo'?_Е emOg|QEhQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|FE@'ZD 4 ӕ@?-~$k(xOǎGOz~y(LMxD׊nnׇ߰&*_R<N1_=YS=SnQEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@_K6*e8 ̀֓6O[5_ \Vf?oh͓?ƫ㕷鳍 _^.:"۝CV(F3Cn!YY4 |Ŋ&w +l޷4f^z*xgSeh΍j>V]Nװ\Kwlw C2Cv_ ?i[;/ڵˆo#P.mmJeJJPd TKQm]VIMkMB͓?Ə?oj Pφ q=|N*.{xg6#ڻqK<څݤ :H5o-&f)%^zߞ?oh͓?Ʊ<☼oM?WSQf[}FK;2>~cڶ}Kٲz'WKi? M_zn]" +׺X6 X6n@p$InvٲzG|U|0^-{PӴm^Uaj2HU3Tb@_ɑEhѱtQE|,\_85tJ}_򐟏Q?Fk>+<*`OؗÀ?_uwpu>Z:B(,`((((((((((((((((((((((((((((((ƫ!Kzo.x|E-LDr:n;K( 2zoh?@+4;@^CRxw,?kVi?vɑEhѱ׵~/|}oCCX&׭ w/}&U+TL :ҾjWhO27iRڴay|QG#㴲+'{xe?~Ѿ&񯇾x↋/OkivFu ]ZG%0VftxYt>,?kVi?vM&ScS+I4&ӵ -CͼT5p"-0C3: x¾17׵o -o5&3*,-F\WӟkVi?vh?@+4;Q*I=^ӧ5y6?]|'$Ѭ!? 4Iq{Z(K_Gq2f%f4o{~-]r}Lլ{IS,on5g{i P­ WV˶(VȚEy?>,?kVi?vTM7VT"_߷W}tzy{]xgL/Gh?@+4;\7-~x4ɵCoIb`A+g<6>(+|p4?O(¾~'k¿'?e_>^6x+Ş]}}u6/"l[o"GJʌ zxp?4~ա SJڙ:^#Nsi]YCE~oA8F\W¿] g.sc?#??Hh;syHE|+m &b* 5K5\a??O{_ YWŸ]U KxY S]٫~G%_E~]^j_W<]ji'mxZ'BW': #Ɗ~_~x[6??x?:U6ĿebE<-Ԓifo[͏}O?D(αO٤O+x[?fV?c?co@u?G,X>=;xYo' -̏/ʧWIC/ txY?#?cS?ъ+_gǟo8?#?cS?Ѫ+y=%oo.g$oo.T:f9e[]X_?_~6Gd~\eS?j+?dk.C'_ tc?cq@u~GfV_XG /~|cS+ ~8Ŀ /Rxl__x_|eSz+Ѽ}8ljesqo t?2~6Gd~JW~Q_?2~6J<7'o tfG~ƕ?  =Gf$ao tnvWAo tfG~S?к+' ^XE,4#BzǓs]Hl5a<42x_E|̧Sj/ߚ+ቭC?7O9Rw_9] "yvo _쳑QwCr\B g'~TO"̸qW0G%`j"'>? @e_¿]r,vΨF*˽O~gYSxe= ʏ?#4WLJ?`]xX?ߏg7_?yr_?xS~Q_y'+9 $ż+_n@>=vVǟ&ğ-o.??}O?D[΋9; âOE :Fp{p$> 8q48ApaB { K` 2 '`w/%{l )x7{ltw:W5.kW9ytX}b;E J8/:rOH`k H:Jr ̅䨅Kct.,PNuɂ͑L` ?}عkC>Zo0[0H[&;un FxVL;j[+1 ?0?6p($%>4˃>RcgY\|V ŕ!g31+)95-#3ػ),-,+*S|%uD#^^:+DyE, s ݑ#AA6OᔙBSfcfSCFAFւ-f 'gYgYdY-R 0Oү2jJr2$$Ʌ4y瀄R2ǧ~ϔR>O(>L|8||K>AؤS1I'H<x<*DT{E&FcqG#D =¡X FEޠA;aġ[6o 6^9XH {Pc5k<\]^ 1WW-w]k<{ٶ3Z:N0nVîr❋x|):>b(*15$Ĺϙ+q@WFU`Q,/}`yw.|&3Y2}vMqQn;N,Ը4X8N㷸p@ nڍƘ*؍ )a6}fuqUWnt |0< [g1~|M ^yWH )qc4J\ h K7_`+!5Kz0#&>E.F]`u\X1'}z6F㮹ͨZuC oیa0V |v nfa;}=|I4`+o;psa0s!]xk _w`MXj';Sgq _KQ%7eY[yVY69]nCnS~KA[aGQWqoI_iYU`yu`yMpEmHemhemXUE*@-!ApW:HjU,oi(cQ\[TSTBw^(9PX xRz@ K Jg noAk>P 0p/r#p-r-dr ;ʷ2,3HoeVB9<"fzyz yuȾ.Ͼ.˺d_e_MϺ"#,ͺ,˺$ͼ$ɼ(ͼ(ɸ Q\HSOSHUMMLN E Q~tE>O%'x5NĥKǦr,&H4C#G$싈N +4nWh쮐`7zpA D -0rFq:^=qa9cXKQtjnuAW^xr.րK .*[o][/&beK|X}U eU^pjKU׬\jn;݈#o94e8'{8xN'l,<&{LSb"gN1m<qC㐑 Ȕsa2X _Qx4\1X9#ѷGva0=j=-Q0o}Y u5R68@׬_fu!@g2@ݴG[؏n;0pmE0vbbXkVJr W,VhwQpeŃVDVc9_Y9'X;Ovd2e I+m\&Xg0 tB'X>(~2D[I.)8I6'@uo>tIdG)NS9yM`Gn;pf8ko_suݙQ5vPwcݍTWESl yV9E6yŶy%vee΅Eŕ%Uޥվ5ڀʺКڦ؆Vm&ELy"ET]Ⱥ&* ߚ"!@TՅU $Bs լ`PN>!^eU@i%(*w)*w.K8:@%r-|Cy%6%$PlKp;2vN`]hM>ofR~gg_Ϡ(5 EUE.pY\\N%YEYl|2:/:'Մ$$cIifIQ|x?Y~:I~2)(;({Hx p Bڱ8@,TܢqڈKUz8&@Tވ] ClZ-X+hG,W4g߉c|! kaxH8Ta8@fCRlGZrf< 7 HNvAOaB߹BoN6Co;E  tf GɭFڸع1sx' ΀7&='xw8xe0s=p` *@={, t샻'1=g"LN;x&81 qIξH Ns`&/2Ld7g3+$=\<ɕ`i B`+7e0[#|F;q,?5`[D܃&*8wLv D?@je0Y0p(/ Ƌ1NcIǹ 0Ri5s8*n>m`:e0mmg|ۙdH@t8nO`ڝPi(y Cyt5{Xq~&'y'yOxs@`2'qXȓ uD#O8p7in`GYs<{.x. \0<B0-`>LDD5&p$ DJ#s=1@F<) fwS IA@4>3}f :7TL}axe !`wǷAc`w&Q;\~w"Չs]EsKl JAvEŠL{ygEOU^ Z;Z:Aw$wݲλ.HﺫD]ȳ;H"3 vf`rϖǸL0-Hࢹ="u$v&SxaAlKGlK{ A>H@S[Dc[xc[XcKhCKAsp}sP)ѿh`}% g꽫zzJ*R׸h,LJ liOPi_TiЩ@A9L4`UPΠ S ɁEn͜bk@Vլ+@f%0 P\"SKr2'FzEM\Pɽ(WA+<,4өǓGKƤJ.$~E`bq\!30(ߡ^xrpM 7,߸5r W7ްpz™LnuۮoYthk} uW HA fno[ vc;a}G:r05p{x#x"A$ 9sKu=x{&܂&a05pk8xx~Pp0a` =p{ǹjcH~P_i`!`kV z`@VTxʝi&@w$v7Zgp'ξ#]Fu8'hoTi*U-/x/tߠixM'yM xxn;8V)!G&r0#hgXpw|KBCD7dO,^ӼxO xe P0`Y;;d (+xwl`'dob%~KšD4̂<;;twd)oT~3#f#G 9_(G0Ft9Qj7hW)}0kS;az#-j',ҳne=ԦC=ڹƭSJx=5-*rsGbkɵ"h͒nnFW{"{w$ MQiZ4?RsE2W;wQD5UAl㎬ d0PUfSc-h#ab;AjN..NRǝ;IwUH踓N uƶ\$"dB(?59\\QNKpyv65466dQ[WӈOѻ x@PA& 5cF#ϠN%Ugc@CQC"x{ȇ30((,(_v +-n2HAEu _(,1dP{ qXC/y7_I@tH+OH~Z񔌣I1i;R6' _H9'lg( D2o@kov-?-pO 7Y8p&-[ov`[V[V)=߲P-\т*ʃIw@*^ u(?%`k O&z BNa0U_<=aV.& cB?‰B8L|Q¦PհJॄ2@Ġ6d V) xSF%߱Fv!M3wH(7<'3f 17 T#4\ 1'8|NPafMMNBN!Tf%1#j1e>:#H 83x) H?lE`ꠈ5A\_(2h!ИA$k'<&0'6'tѳZ%e+WF'kol&/DO&M L"##gG9;0jn`Qsa3ٻ4c-7;&5`wN^H3v]Nʳ0f^,|5Jw @ELVz6VEVPa-tE @9D_'F6.KnqA] a]*բALr==e86hhuHY@n!>C]*#A2=բ â )CHVԠV "tvKe]wew @vKEp.{iKC|nrD+fƵwƴu-){ɵr[[N_O\TXLPPu j (߳fjJn&d=Dޓ)}18Cndٟ~/FV9p{o_HQpQ6=CiΩwSf1i["ׇ% [=/rF`'X{iny?nQ3 c@ps7,@oZ( &>-uΙ ڡi(Pvwvq $4=d#tUL 88`>^^wcF>7b*_4p#&+ LƸ@gdn&?ʯk; l3l [Cщ3cSc '"MymKdM`G;>|4dⅲ^2- l&;,r^DȨEQы1Kbb8Y(2fQDaQ ¢F 9+(bf` 8l_4_BӼ!SO3L'A9+v >!`Y.d.8,0||bE|Ă0:u_nD z[}æ`PY1EL}?=jf=jv`zP ~lz<`Pn~SnWQ{Řrew6x7\zӅ\[ĭt,5?s~υ#SC\+ݰ >䖎+Es/]m*n{"Iü Uymjϻ0xV&4{s+\4E}(j;HբUA]ĐA*S$phb4yȝwɻ*1+sWA.y>dw>{ <H=wݽ tO鮸F :jؗ^Zy>=%{3`0=A-u-J4QorϪ~JO}_[EQ4='O-Dѯ ܿ9B[9/-v,##XY 5͟S^ggD3S>dz ܟ.Ͻ^rtĴ`p#z=xG43=fyB^<#fO{dbWSRk+xQ YÝ +ihjjZ8u opqsC&K& I?7(wgĪiڼwdX=ЉPɂ8ȧ V` ~, ϲ;:cS!.U{qӨ8I Kz@3Ex{An@Bձ]w}.zF*Oǝ ;ь 0(f :}-Eexg{Wz[W$";^}n)"Y+p7Kz)ۡ~15:ϗp?lu۠v,9enPܗD-j>\*ꖋ n~@4I탌&"юhgzOL&xF?Ѳӊ`ܖzUgٻfd-C6d vr**pN!?.p͓e d"њ2k୨*[j[zv07 SyeXۿQpAߞy$Y?1}Wt{lȔB⇍<冎q?I*jax: =v ` XZe*G*]ґt "UgwXڧ{M ;Qd Ӑ~v7S*>NwVq?1pݕ2Ȏ^`iL^@:YwNWZWU+E.^%Zq9%6~!1"shNJ[PwDUT8௢&GCub`x&QP^PHtKDS3p%˿*vTT@cu74“ ;VW0PCjݦ\~r1tHrVODђR]AseN   p]Am~ V;5 *B(J|eE3 +9.>?Y+1}[tS\蔕ICbe ~Pxr0PgPg?`ૄ#ѷ:Q sY9 s(%W&G*k\M<ݱfۋ켲n3gxrxx  =tgbϨ^1˼/IX書7qožq >sf1쎵uO¢<:=x9Χ>ϫ3v{NH 4sF__$2*>}ubmbƺ )S7)9듳qe]R暤Չ~(>,eAXJI@܀9qlqlY~1 ك#x%ޕ;twX桸c\Lǡvr(8dO ^BglT0;h"ǯJIZ/Kْ^SW8`q桒, Pu(@a}y{s3d+vf)vdoKnmIIْ%!is\؄M#GĮ Y&z16vc#xjy5=6av- ^L]ڟ`\Y]jؐF ]G:[|Bhʯ lSwSA6ڭ]>a<`څF4PdjdIڱF #z=~@~vbQN@Z( ͛oSk8Xϱyˋ;CMoY| @xݮd{~YM6#qы:m_YXSTWRXVR.3_"%ohj.Iy7H#|u7n&/_M=x${ܽͬOK6ߡhyK$AR/v*.mi9iM-iī}$))Y,mοB4׷P.oKDPCE^mmp2)vuI᠋aΎB0lĖDƕ~.!)*khٹP4ҏҫ!2qI_Iu0 \\ZWVqT(:sgU:8.!aKNʼnӋDm%%>>گ<u=EL,gSXEdT8--uwWՈ2B8ӫdnbW8㷄Yڃ\Hǝ-(Ď%NCwΟD;CŝZq㇋t\@1s-rJY/b|% /:}8BF KOH}Wu(-s_jY|{Rxشɋ" 5I17loX1`^A=cPF1\tp!g=/kڶz2jgc5In5{x{I>Ӝf:u =tG2^|W$MZ嗼/e_re~K}W8>AMgw>]^vX<;0n>^O7dmJ"ے^p|`$oSZuk ++bӗG/KDJ.R, MY$gǀxv>[U,DuKU@5؝1RkcϛЈ1H7SgK(8Tu,hyα\\)9\}(PaYeܕ%7Sv$ҶlKL%&^PܗiR;vhkAXE>K},c+ }<(f_;hN\N*vvdoqb_r ŕ ~vq+Wuڙ,3:3±Yf*7g|7ÛW߼AovSd=Zuh38'rA)?:qHsns.^bmM6:dffgD&^_,"OS7e6djw>輣܆n#ls;: _߹0|JϿ F'j:ID ^sGJEvewfv(ZnASS.%7Z$M@&‘PoNlp\SJCcJ=LOm3_ϗH[DGZ[[ |V,hU+ ZS[[SZSRS;HhےZ[[[,΍klm'퍭p'. L- J֞a/dReTwawaWaIK->7HWNxx\VND-!e%ޥX!-t:dO˫DA !驺ՎݡRFW++}3b"'RIji..%ںۺr7u7@8>^^ܻ Re+wm6yS hZ $ R7dkj&T55uu ) )MP $-`z5RR ZZZ$P4Ƿ4656646DEEEֆԄUUTVWBG;B|<-;a%pP ү@[^[~1sQ\YRUZs+.?(*qE_E_yoY徥>%ewIw1Wf%E9gm{99vYv699VxMNf3*Yp#)ؤ΢$#2.g]*ѳ#yE'J7=kǸ f=`1+ky<Ԏtp%Pa_']1-{<GFYVy*Wͯܗ_7jO^Ş܊9ffYe;2J+oloH] m>g-ĬՄ3W_XC((#`_.0zmMhMMHUuPxcVW]TY\s3s2YLy<@d3h87ՒO6S7uenxMyWe7J0}O%(ҧҧܻܻ̋ī("͠ȣ/ ,53\lLRf{ymV&ʬ2K6 M%7ex5yUyy.9^3eM8GN XK]P(8Yp6P{v9E0 )<]p8@fٛdY$+Sҗ/K.N,N`(.06eAL򂘤1Id cE1@¨Q X Nu!Dq箧;7v5awCo9,[8Vc[\Z̴vk{xKjе=b6z'lI蛲OQ,?mrqqyѳYqFǹ;]vWݵήa ^M8qX@7;(n2DJH_}}gVҽy *W*9T,9XTszABs+̲vfn(٦(ښ^9`cߐ t>~uIYkQtvǞ:LNM~(L/N)R'0᰸a.~ZZD,ۖ-U _y**zڼSujONV坬=Ys"Dy2JscG gؗ%߭I%SS$&mKX2;1#)=Y&qOMLMJMIKIe`=(,euM6E3Nys#]؞AMbKం;MѭD=l ,XLo[@ r k !>Ȋ / + (-+#/( ccjjk"jÀz>|6u5A5AՁUU~>^eEŮyy c*>&=J*$[jHi6V2xk,Q 䢥,":3y-o]^1y>WZRVZVnťnEŀkA_8`ι:e82pvgنBa'Wmd2:Mbv;%")fbҍĤ$$]ILr)Ir1Ev!Mwўū$Ip|I6NyӒl40q>朑|(@{&=yӊә Ne->[|<ݼŇ)4.ؖ%#w"g"{]zFFZJX&_Hiaete XTHH,OL[(:q~D<~f`w#' #;Ne_\yFyvbp ʆt^G7'YO8|kŶ|V;u Z#zWf;)6eR5i+)Kʼn @}g`=90X;#tȏY^k4O]Z;:=,4o=8>k oId9쐄ڀn'+`>!:qȁ6s5xj}!*>X jg|J rPlw@iJe=Y{.&TuI6Q}aMLšQpM9R;=m^u<׷0om/n O3q9j^W;..6; ) .*%,)KqqEJ@ii`iyPEEPYZUV] 9;7EAmhmMHMUP5A`uU@uMƿ !uqMoUOUweg̵Թ+ ms6 TWa.M&,v))Rbd rrڕTմik@O|%SeWRӯ+KdYY9, K "w e$S,LL+E\a)LB~K&#bn!HLMz39Fr9;56JL苑#΅ (=AXGD;p26D|q5Az,Qv4Q~$Qaqp0QB2"cє̣)ҲIIrޕ罛Y^vK-(9VTzpQف% Kvm+ܖSlߒ|9+oSf˳ `2e륊u% #F/fz6Y6yS/,uIsl8vxru 'nHs׭ǛLa;n-8h}Z'.\C6yDn'i_ftXA,'ԾH?/fb&C^AcU>XYvkOvrY|pw`#,W+؛_'|w^ٮ0}YvɎbߖQUQYA>%sME$ !L8vL`ff*jW2:9H+BuB2J9'9S٧2OVd,8Q8Y&?Q*?Q(Ŋ GffJvvHS$mHHXM=zq=a/̱t`b0S]Eŵ?Jv'!FUR`A(]]ubx'::bM0ԮT aǶ7 c` !O5WJkJ[xAq7+_~{/~5qnE69Yypڧ+dɩI)NIIɮIIID}H2Y"#8;7,0,*61%55%9j!a\mKkKlHjLnLifaI_ВڑԊV91! ثj+jU (c yVehXe7 S@ %"U UWUWTUxWVxUUxVUzVU5u5^u^u5LƳݫݪ]++*KJJ nd^Sd^).IϧH&}r&>c h}\K >Ĵ$%K>N},(YQWҏG)8\zyyŌKWf_ʽkme4OW\_JIW$WSS\Nt)Hp1>B\ظ11cEF<QX؇NO1/G}?$<r (|_h=#wE%N#:u{t48#V/v`ϺYlWB$ޔ}92`?JENJˏV)8TZq`i%{KwE%@%f v;vys  '[n2-+wkfΖ 5&ϏxOlǂyVx Jj{]tǺ9ƿ=x #>>#یf=VSͭg޴gaq*{u\7o+nOV-DqO N[?m?n/`}Ov5=d;awvUAuR;NG-نm]9%D_/>VYwT]Zɀ\9Uߌ''4߀GbNp@qՁ /۝W;eo6Is64 gM sðYIg+]j6ڳ=xuS5Y3OVf(K?Q*;Q"=Q"9QvHrP^<ɑ\});[S7$ƯHq m@ ?BxC7w҄J)W8Yr S(_Ƽy? 81³S9 0:VA[DM@ %xXm0Xjj4UIohRڕ6y7v5^PEeKރ>x{+ޫsgmWW]ww}wwݻ4=|q'O>i{i>O>ZV|>/ہϾl_0Jm/۾/Z?O>mƧ O?|=yZXOj?~!}ZӚOV|2CէV}iOʟ<-{8~{XK{NN'0;l0=A F>l:P?W;{뾟Oc.s3#hkomkrښ47+Ԝؘؔ44duuEu:ZVU%VVJՒIM>,o5-o" Hb  ޔ. MjROgI=֏Gpô{@xPGW\kGLs[TcKx}9R! UφZ TUA%@pIEHqEhqyXQYDqyTIyLiE\YE|yUbeMRemJu]jMCZMYR*kwH;% ]i ] ])ƮĆֈ AUZAMS(!KL Bkx8ydKtSޒ֕ѝzl~iO~繟}9%|j Dr>ϲ? f=))xT!#Gxy~'3/oE*I W jt@k4mqA !aMͭqmm]w$e*|z?w'ُd?~t<~O,Ό{w;dIlmoim;[+)' ALЂ -x!hn!nkd4UՇVTTWUZ%*zPVPn덄eA+ּj5ؼmŦm#7m-#7nlLq36[Go:fֱ[߶cvbf6u׮wػg־=s`܃~Cs}puÇ><pbQe|=|dóq};iמ ;wN3z ʿu8~Ӱu nv= ̕Mpkf%6lQCU qwÖ#6B2[Q7ڰiԆonFY3rꑫVXbˇ/[>l2K.!?Xh…,ޙ?мy}{Μg8k̙,̜֬o͙o_ւo-^֒o-[5`+ּr+Qbi$ oln [o6tˎF=v {Ow`CS~#GMűG՘y45$<4{߽wQ͆o1dӶZ%D9)GJlj[\ {{Zs^fC|FX5rŪQ+א骵cWzƭ`˸5[ǮF~k^nLjuۇ6tkvk6\-Z՛ YMJҔZ ^ce#AAbö}=쟴!wgs<ƻg7{HO;tt#Bcڱk֝C7oa6\˴*VPOU2Sht"G_2x֡[ؾcٸ=';isuHIc4V|3ݗM,E6E8Îf&/YǴ ʯC;[nʣ?S>9gk| S]hotpǃ}TL;^0ތ;ɰnz{{ub^bsV7[oѕ|M-M,XgȴaD w@&Cм9tPɆ Z l Ey| =j-}HD7wџ)C`N "6l|9[>E%[}(oF}]vђpC Vʼnϵbqg1WZ*S?Kófgj|uL!K3f.s0 J}tO}q]7->cOx\[Ƈ(&soW81bMuoU6纳*w *(=(yf>-o([~#Teʭ̎R J-7=9jKTڍ|, Nx洎սܜvBLLes=in^vDcC.^4s]ѬI_YZˠW,jNϱZR-^i=퐦g^7(?r ϠdcүQWiM絺(N0阹QսI 'a_UBeQ!|*n.:Frؒk`F!(Q;9~ٝވ+>N x}=WORޑdA: ̛ I M竈ބITgA6k UT"R4'yvRxܷn?=M~2 RL1*[)/+H:9oʜ1F 4P9VU!Mck,;tQ) g̤{}v#lՙjT8BH"GuG0#&.mG[U i68')Gj+•ɫT<\T& :˯*]yp4.GRTCsЮQk6{^H`8!MH@I;)Ӆ4-nݟH^T![h#ʴ5[ :҈^:Z)?ye!ïbDX5nhuNuytۂџ McL9ۯwr{ܩStz _Ȑ~*)njQm$C._h?e!r]&poWTBQɛ"R[LM'b]z%S~&rBRkyʹy;<~o>iKd_c@)35j EהnyWhzxEO3k|C^ke4KiU`z@4!:4P j)s uԒFo}L[}HT ghW駲e=đ3 <;_ݥ6zI4F]i$7}|?Je5!P{<{דoE BɐAsp}@/U&E~/&l۲\Q;X(é_iuQ{c*am`U)DV9):F?>G5(:}_clݎJF0nG0S_(lCfg⸷+[qة=IK_=ǜu%g]qTߴ\I!u1X~ndy+{QWtyQ-7`Jqm 9ID D%7;T#>,+1ýl* CC#jBZÀeB<Us﷑(<#)?5IK 􌳶B[M ~ȂGK003N$oЅA]w`{EQ}r@賐]a!q>}J&߯wƋU2ȘZ߬1ϯvQzJk0m#>a~,1Iy ~O D;0N 0I/c[ X gM cIVdB/`. $ H@ A^ R$ H@ AD)Y $ H@ F $ H@k#QZ A $H@  H@ A 6c$ H@ AV]V\]VO AJ~eӃMO;VVI?"HUJjo[ר(j,i H@ }.m+׵b.E}%v߷(BQiEv]BM}Fax^EGE};nc ^{9I@I zҿ ^ݒן|}kn+Zck/~ mb%'jcB4#%m/]_t۷W;Vd02pRgۈ޲P5"e iq)d9@]KwYMKvae,?4]VAWF?ӳs6cR}+▁i| E$+>5#:Q/ < ^j=`Reu2EnYVaufamf1D|<%ϯ(6EᱩacR]hgOwh>ow͹[:>'z'trGn<\vsf~x%z$<+8קݭޮfK%}TxxY3E*lF`|^b>eaITj7fllvCg' w 'S3Fum.I3.@7#7HC@ǽOںyoթmW6&I]BKkYtt._-4KYuz⑾D7zTG;~sGR}>iy 7j 7WO/&-no>z`i6,νKC|i/o|N1`1m/a}}gɸR $wfwN[u| ^O>x7FcR*[:T_߾'mPŠv,dCBYrꬰO;K?ZPRo7~}Z#EKu[y 韸J~Z|{e)BIތXjח,z<~ K Oos띏ק<}R;rily3:dcܝG_mؕgo$įXοj_h1ݤ=|s=[^K}GDe+{)7\3!jrho\Ǻ =sRcy11wJɊR U_aWD!y˵V| a`cP T0XO(p#&2Ot x3 r!(x/4 Ì1h ~n#]WACG!yWAJ Fļ!l[ANbP)So=D c/s'/%d.:y h0Ajo7k }[RȱW1ASx?ДoY7hH?w??CwO?m3ȃ# :kcJԦ_U4>^ח\6oݦ_:ͨגgq:xp^Q;0DΘ'T+YyĤjɢC3ew3\A\OB__Iqwt7e)=pߞ#mԿ'1 s2ezH>׉n.:>V;Or|Djf/١^Ǧ+v u ; k'h,тSrj4]FԎr5~< "x F~`#0L}Z&߶ԎJ;<눀Se#BSGEjB@[=XbIgAF^V󁶩}E.RREp E- O By>uޫ?̀D⤅"xoo|u%1oOˏ"9Xލ,# &d~_^ؼAw O:jfiS#PO5.4Ͼv_ꣳ0o0˛^2hqq\}}ys/ǝLuyݘ~le5H<y3V85 (yQ;3V9߁Թn"#o?7׿:TO\ob{@ƊԎ3G[-޽AYE/ϟ&\>QN}O] F L?[Y't&h/pbf/<ܴ3Raa\((CbBt C#DPM88Ա De(aM NCڨTm̜xWt 'vd5O($U cF$8 fP!|dD;PRGKUP0*?xN@J_FVX~MN؈Js꘿u,h1ƯM #P| cwޟWDWyS//M@߃|,~ˢ28SoN7o7^\qLcԿNY3?LCK󺾞zFy\g.4 j4Bo~o?oowv7i;d ‡z g?svS8C{]Ծ%(ם~A^Q~cO6GG;Œt?˗0CyctZ: I_1AX>Cʃaa #!|odi4.`>藠C%@tT qxuM2uGmx7eTZ0>)ԅ*fh/H dL~*H6W\lBAי%DFFk*\ &%N#&:2Ezn/2uF?OW'^Zjx}˽Ý:Ola ,A*7 W:^85s|T ϻ$jǒ~ KOX9BOdO[.՟,ISlӷKNע^ՊgU*ߑ #럱~5 ,5I:mit d>0 ]D/Qg'R(@=6 #(> ^`2: E R-Z;Z^ kӠ" v، $ks#^CH?u負v T!@OE q/8 !dPn7痃ԡjSes/JSxSMn>䀘hо HQ{jf{㥽G^Cq𬑂ђ^`t.n1Nzb#k#=6:*t1'j_ǮG?y^Y=>#2Cgv# ݇'HKjVl=֫n<ۡno>e|^kn[U;'#N+T_et6D{-wkZpewmUoUG]`ъs$vn~=Wj_̗_|#Ͼi O尶D|be>jr+7p$< uD-\"tNc}>-hz*u]Df丄hгɺrr&1aB6U0Y?jޤ2Xʐ=DHOi#sD)1OO=j4PR9YTslDCg\3f &S{F3ޚfchzi7ӥxԆ:QU `::GFrDh>3 q]}+ keY 懚ƎDlS u2&?#h {Yj;<>qy#xؒ;5k.6~k׾䱥d~Ē{O~ ·߷?kη} ϒ@T)c+ݼD5'ZƻKDA`h` B@*$@)j 7=uDfdJ+c>CCY(5YBMGumgo^Pz+iPL.`P!mvI#fJqfxTJϞTRQ;p۲ڮEA$7jTsۺ5zÆ5<.?:7cVAb/IXm\ToѾOOR6ʳrQ;yS}3ԕGܽGamtjΆ3׽KR[udJtSֽ85t́JkqӧJJIA'1סYzn/HތI>٠ <01`8G;@!!L𺑦xt0C'LïK]}{ϳw5k{~џ.Z)Ԯ^_e7i|gA;+ǍWݘZdPu; )i}qH rCI)9 #<֌)1q:XEzt SͻИ{}c18^Rתrzik=/}*˖#`EY#j-_6{; I4=]}~d#$"HI 415 =z`L{nyGy=}kY_ylD;> (XYEAU@`wWG - ֶ>2@E]aAD¯w?6"^QUXA uü^0)<"~DDA E $ H@ F2 $ H@k#9;3Ҁ }@Bxڧ N}@*G2 h}@B> څu }@Bxk|ʟ0t }@GM[~_]w !]O{~A!-W/^W 4z&^.]|a ^m,~yɎ+KwW]]ڊׁU{́{o}m=_>K^E Gr}1>צ컱f9}ynO $J@wͷ #H@YkNka $J@?Wo$DŽ.;N9^U# igc(p3~WcB9rРCY3Cw͛et\j's:U'@6DciX+{]+[75 R(BLSRvq%4>.|D?o?z%;ՓÉ׋^p> "OiϤߨДQMF"q1h݋0fo~Ӑ#f>n#{g*iy~XרXs 9F+n4ʦWzK9A1]Q jefvCr<@bkVs&^DhX+{]+[75 Ruc%2U;FՋx!1%+)a\uSAфEJx<ܘVYE+}S35~t"\^D=Yr~"<2!3 j=" VwjUZիJt_ky'} j߸q62T᫷7:t_]knMwinSR9wqK]n +uOQF(!Y:LR~?/)RGe(q;-v2e13WWо"S Rw`+%%;G3RUR{oN Fc"s'oGp8#JLw5[đx$"NBB_qQ7=z$ᒠm7 eg-{JwzV{jG15+W?+/^LXվ/=9T0+DoQ+Eܧ $HҙbHR-;}`FbD#cSU`B (IJ㮈@ִT$e.:BXR>VoǜOiq%;|Eeuu'mC~=uxLC[d\AL7J2]&d]eIT)KŦI~J}esN4WD(HKOʯU<-贞+ /Ǥ+Sz02GRE=XC%mݙxHV_5sl~ӞaҡSgmB*,r᮰4>N:%t{W8eJ:;!*QӋTzFe^fSR5pȪ_HݚSWh~a_x~j_p̙˂ڟF!;4ʽΆu샺)0WwTvft1;GLᨓ#7)R1"C<Ŗ몧H %Eh-t%\@J @ՔzEk'Lj @~3|8>·l;I_'{-.\*,|VL|ʘ$Ӈ$ΥE˹͎&e M.z1eMDYkeyPm!bA[ ΏՔޘ\klܰr b L`t+ċgrXV3$DY2>Vg~rwUPγHė7L8~Ą^r=J3N}I+ɛ!U2#7tK6ºd8m!=@$-^л}|0B^׮Xs]MHjexyV/ }vRC~aFC~(gx]H_XAVmweoyj%h4]nLUXre:hsFjfY)S2J *?"Ѩs9*pg"sn@s$*OL +jlsfp[J#MS@@#U~_^(v[Y\?g9vfDfԉ5/16 ԕosuquXC֖̕5} 4il'ɋԶ&Y͆G%S;vڵ}V4~w; .Qg Isut5UHjG41 *YNVJ%P{?8R+kvՁtٔԤhj7|WDԮɂhɛRiV!9\kk$t噩̀{K?3$Me7b:'P|}t_ː^!\I@KIZz?G5d'"[ptbJzORNbc`}ܵaMf \)M9Fm4/MPs-QI!I.̈oWg$4 U* <ޫRI{v0(HB:n.?+ۀ:˖Ǽi*uz_S]%Og)6SּyD S}Uֵr_rwKG|֔yTgU0&./ZrH|*W]g p:O#C}r]~}jGmPɓm/ UmHiP}feeOB~ݺuZԮ Ə&d(];7"o{gײ37Lj\ ^Ųtyf4`Թ+]QbPӾ=)% N"ƨ/cw}v5R _|xg57\#kWӰ4_N ɈE5g0"+&6 akQ]kڹ Ak=cSӑ-A-yD{~O])C5g޽ +h.m]HPWؽڍ,(!&=OֵMZwՙ/?enS j߶met}O4֭ۦhm60x\9kK{PӬu5{w287zhΐ /=#o˦CKfx=ω{1ϙ3wsL>7̳vQ3j$*K@?Wxr]$DŽ09rxAԎpfIA@ .r1! X/Y}^1]( H@? A"~vv'Ѓ WZg $ HK]JB ? 9 $пxfj]|5R$ H@.Ǘ7cs@4:] ?NN$/,Hڙng H@ WHnK'.{s/>4vV12ۼe`iI1Ay;qL{ {x sۆ&=}mFˢ[O86wCgo8S! }ϴW[$ HeFA~v,kNZ}7''_5/R{y`'?cG;,#L(j$n.p@%՟)cݗb /ï]( A Po} Sy}JYk4l.όMٿqI˿J]6[?"0 XoP^R+gHj*He@ҝWUZbY]\jTgn^6H <;ɥ?#k>GLiƒTUvxK_NB&'D8#L<6@i}\Wk3Qz>$7Ѫġ)Ǎ_`͈V%(-^2l $G%^jئg=fC"2>}ן|]ÿD$ P;w˟~C'P(LNߴ;WS?yAX+$xv59πȍ֚#٨3,dSFjScjMf-J$]A|JjgtCԎwӞ,Dž9Eچw^2^V2pLþvtw7z̜~d%G߷[ڟ؄i7f3/Ck/X;_C_܋d96yf菷&\>7xޣ@[B/ZZ}GDe+ڹ4$1vV_nXKR-pO"R S^ÿNxo]Ýoڿ]gVv(ݿO_S/{ʜTk[Wjg"Xfrͧ8fm_C?Ӎk,40h'0)!Q5JHglFZ?h{!eRr޻ddT*NYB^$Z*W&Z٨+z*&^4[zH$Ңmodo k_ _iܟD[3%B׋M_} jgٝF;x5GI]"7U)>dfDϲabIj{ R94Jȝh9 乵cg3.^ˠW]l$ҙr$%yRqVt5o-e!/ X:1r |%ѥv(VVkǾިH_;`' [7.^OλSdXk/eWE=pmoۊ֯_7Akm(1vR;w>;(k CP.MYw2W8K ALֺhKAӘ!?͟%0|K Wu66R`c`RF <>ݤn& p3v$]EYoy-ߤyɺ=X7SP)9unx渀b"BNSyw>na煰"#_c|wuq؝@T'fxK&Q;ڙOlxR]uƫaE]Z.*кOFƷkК HZ;;4~=&5k_v0zF 蓀v]vO@>^J5NIrėHoV=bkfG]6Td>5XTm s癦hYAi4OPz-1B"\>MS)(# ƷA܅˴޿S_oFQvN 0׮++䩾];^9fXkW-.3j3]P\lMkL#Տp(pEUIRGag]lMqQ)깅JJT*i!F&QYΞxţ_G^Je[_1]( H$_.zHBuM_$ $ H?%`X7bc]  HVWo~ew_H VR{ߘt|usz_@( ALv8Iq{:J TwA+-ڢL_QC A/Lv݃f:xA4Tk2K;'H@Gn9 o~o~>u5}e:$_($O#'Ohg|־qAt,@ A374=ߘtX}NNO^A~ɩHҴ3 $ Iש}h/!!?| o0?$%^G%>I;'했DGGkgL㾹pxxxqP$zIk|HsyFdth'WD=4%}i*i#v))4M!k-CeJ('>2?T ? : qGguv;wrvWgߜY '147:=@CFI9EXW? )pþj)\+V34[iCXwg`hM>Da8?8ĉ'Mr򤯦NzfLqgMu֌=ZZ1iJj5^(]j7zdMn17R;>>>0M$\$z??'/׿oσuț= ^~ވ>^TdX,?#<.H@@G8m6N___GO&//6!!GAWϺM޿R$% _ w .ʥ y-dQHPk7ItEwY ga|b|M߸ki#<-Hwk7p]t Oxn -por/ϭB‚^3zWsj / v>}^\* EZZ^B^E$D$"%Ы2y] y w ngڍ`7FJBA/L}8F3@/لX۷i31xg ީbBYZYڍ#%! &]j?]IN9^-6 VBF/Db|} '^_cwxQ|ϯBʂ^_{,P{&<"HI@@o8k_k'!&Q  x~Хv8Iq{:J{[!/ڟ_)x ve.M )^7q3XXƚ}79mt/y k7IA&K,HH7y}k / TB./F=\b("H@-^}oP^ob^{ kҐ"хBdzr`ҿ8^yRp`? πQ7ŲmLq$S64YhЈڷPgk $RH$_{~$v^=X5?7\jVV=s=VJ\jaOI|&K,H@K(g}0 d/C֔_K?z)3_Gᗯ[Zz@/a{劤՟U8hkDx죀CB?Dn6D~~п>&Hd_K58ӿ.L2ڃC*P+ x$`x|V9hi:K!:Y?8 P_{Y5џJC3~ J=8b豛-rwokiV}N?'9 $$` {eP{ =Tw=C_|ё&Net===󓲐+$,P+vBQ GG=_wT|ѯKSuکA^sO# C1ͱM'=3S1[xK4H]^lj՟j4PSAxm}E$9C>2,U_5 xj%^Qu/&t+]ߴצ!3 A/F.}uq#9C5:o}}Nuk7:6m8#.S,PkB ~g׉NS_^jgu?Nő5SY3p}x&u-.Kܕz_j hg CA~_ lP +䝶v[!wA(,P3Sx\ /}~|GByݐٍX$ok5r$`_I" $J_^B~g"> SIPB p% څ H@.XSk%kX ^Ruh큡5 Ri҉ޖ ׾*(P-TVk)g}=)] ɜCx-[NsVWa_s AI,Ǖ}?T|گ_j"$+H_$՟j $"%R]<]xb|\uT"IKǓf kWTw7\L/8rB^IE Zs AIz]!׍1?jKV, ;ڍ@atCW%Dn_FNH/MiLn.)="g wZ^jʢ<J*'|&66bKh>f!E( ̙gLZL& >e+xa#:Ӂu* jך [!p''eͽl~3=vn/؟9pѷhϋ{z+i/eLpp0}a<5!1$ Mj4ִEͫ!E(NLʊ4I1ys!asT^g|F}iP; x|aF":&ʪ)*?G&)qbQ[*5b+ bt9rW/S5+'zêJ851!`n C[Z)gեҹHTEߥivkgf0ڵvjzv騆A;^w_;ur7-ܙAkJ_%vp?q"9JzzzR#=' vksf vmi78N}ZϓܩFw6ռt[t%q먪6iQg_p߬mA:d-ҸI%hg]jRj cvŕps cuGRy:1ZŞ/y WO]9} pEZE)zCTNwZ.+wjZ;rWkWy%A/S?W + J8jP)C ^N"?Ş ;Έ!ߐ_kGSp}|OFS;oDE]:Ԯ/Mډ䵔rv⨤veqZsKٟ7BϪ\F'4I'w^2`ZsŘ.gɉqދL ̨W3%"4 |*):.#,]ZwHf_֜KZ-MRS.ޭnhiyg-FbK׮kg1j'H y 1zLxE)ЀQYkUZR'PVWD*/1#T4XMӰ&Yg̾l !WDZYMA^Fe*s}sHe%¾ HijyQ[M)$\Xϋo`K|N 0^}/ڟSUH@?W Z{oZpj/AQ;7ܮԮB#kXRgtJtKG{m?fڍ,P$JK@itoX$ yn$ K?}[_F*(H5/ yӪozfIӰ@_+ 5$zK4$A҆U7k)5B H@K%g}_{|/UВ {wI]"AȈsk./j}ފhbN/U47jgue#D$rIu8+lXw]w\wuEpLjt]sQ 1+&Aɒ$)0Hs af_:ܾ{V:USew?na)OKH}<'gKsNF\QJx 3O{~BQӍy_i~ut[b AҒ~)YA-hWzӜOͿWտ0rzNTj|=*]?3'Ϲ(yOϵ{Q#A=]z"aߦɎƢkv;/=ϟ]mw}ɖd>\8`z8>Zs'oyA@Rʩ\YgUSP;QQ^± vs3eΟh[bQP *ڑ?N::]Nv;ZJ|!o b~vW}ۘV&w7]Dy (TN7nJ Ӱ/䐇cC`N;ыfw }mfZI*P;C4 zɉK,V.bKDPwR7Y!`O*Ojo]{oF~u b};t݂s:ngUjQ"ԨE@5! :vƨ`B7޽q|I Ήի?M/Of9kKrȼ=6c hŪ-t2IQZM;N[YPO\vԮ=VLpQY+0>Ԟ^=RX@k]jjUkb#{Pn(]˱`piJ#jMF;_c \Sv9"Xb_MC1+II?4Az)w^4 gaՎL1@wLWTDc!4ޙ@N1SLB]+H Fr1WuR3E ֗R;W,nuWv)#nҪY:2^!jJÌ }j t4,~D99 <OtM-.0ig.wNt56)SjvU  *1d\|}+ Z-vp-v;0e=V;g2Ӈ4g@<Γ=3[!gXA<S7N=yxWtIn\ sV沔.`<;)ر̿G鴈WM&tk cfڥy$QfvX='G ;P;Yh}C9ujJXŏ21< JCф\;o|qN|ml(>XebctMbԓ?oc;ڐ&z [B7oý@g~Fgi.m?d0:eFZ|hBfP;P{VT> :֞2~H6SkX{j ϥA@pE XB %^1%jRjXB*@H!}x|:Q\9ƃcioıyg0a!Q;Q4jx EA,  bjwAE5@@k^r@*" ځSN=$~Ck q,uȰ|,Iݥ}!؞IhN~WXu_{|96@8x3S]$@2_>d1v;~.T@,D@ @;f]@$X{H:6bVˎފ=^0cK 9obgGҝ2я1Of!plo~3)6Qڑ ڻ\7klԞ Ik/Of!}׺fVSdQm#{:*ƸڧKψ$wU匪Ou_qV+{j3ڳhɎ/#ͳ2II\zgc^YsE.s3GO=X7:$=֞LvW =?9:&gyz֯~{J( ^|8IȻ9݋>q箁#L($^jEXըTWR_JP{zv_Q-b-65~DAOVAˬdXdÌ 2}X̾}j: _Bb{[]-0 ]g厨1%E|yjjOKi7m#r tstZ7@E8"~t9WŹo-q}T{h]GxZzcݡP@r.>iz * 14ڭԾh: 1)s&n\Lͧ7iy @j2uOBظg|ϼEإM|ß k3{;w\ٹ0ĖO?c5R:.XjwC]jc-*#XQ;#iL1Հq~"$yꁊ|P >|uf 7rYh3>WД5߾j7לL]7O!b\eW1{1Rn|S/ˤ)Mjfi!aEnOSj^sb§^(H$ =tvmP9$_fm&QU_\kiKO9 0˔[5;r~7μ&8vns;ZR8My׶ʴi '.wk$t ŵ/ 7rH>>ORjWuRK~mF؝ڵ/o,TO6뉹}pFb6:{؞cyW}}ϵ3j:S/$:ԞjϠ"}=n!$ǃ)o^oJ^ &"_,D{uA6 pDP{"쑙 ԎVGuLQj_YC-u47>F!>B@"BԞEOfGUw.HwrJd|4Pl_=9I! z!*[u"g] $:1'P@=~ }BdS9^U_߫7|c]Noו1I]8g/ds\b|7xDT>YUI@Lڒb'ۣvG݊?8pYl?[͔D剁;2`p;u"KS;',PJ 5GK pm维l\[Ztns+ӟVK^^saЖA9"g2e\VQ>_:t.͞m1D9bjwq;(A@ 24j^ve+oU[st[VwA}}&6'g2D9(] @ $DñשEKO5w+MϞ+Zxc|tMۇvs X>@,@HZ-?ye]ⴊ7U\MCmr~Dݽ@&W̱mѽ,DɘAW6IkK=K B)uo?'2Rj 7@H D{noF}Ǚi2$ПCb> C ic;z׮?4Y(al%cW=vo*)֟v`4t){`lbF?=NƜcfj8V;(,!?Bv~aշ*tɢ]nک<k@>@,@HZUdL9/kp2B.:m?_hU*o{^qFt6]ӆL"aA^vmnR(Յk{湭|ؓN4a67sk;  O`?n{fC hwZ#FG]2|!cjd@bJZ9׷7{y.wq_w}_|ށHR$3խ];w ]߸VЫ2+ڽڽc9D"X;ԩcGw,]0nݷv}ov^8q>h$S6wу]AeIX!W2FP@YOpAb@ H6u4zC)@Bϵ? Buj+|t:;z%'>/:N$:9@"kpKu|uU'80kŽ~m|\J]_#[7Ԝ:I$# ਂ@ډQ{ku5(}YUny_W6d;O]<]PHbjW!c8r{]mME]ݟy7O4~߹Gn&rKVW+ʄd@pıUQ"cCVԾ}zᓈſz~#L=ǍZ]Xz^cwh=y\Ţ*^>^@z^IO?y@ yBשݯXm{kשnړ"[5]W}O;ᦅsz0k*nQ5vj"B2Fwrg`sbksn'3K^֋׽Ad1/8V^}#ji6Hҋ+` !bS[GQժ]{[8Vun'\~_3dB^:Toy ڥ[ rx՗`~>KoHXjWԐ Rڍ_3ҍyv^LV;;Z^8E7gΑwM94g>|jċ␃X"P Rڏܺ!ú9yeOntNjV?̻ysU];jݜ4=kvDZ3X!`-g/n{}kC ivt^)c׾|^O}eR{znO#gZ>3/=*^,),$r>M jW0:"CdCݵQ  8I#\Y7ԻξgK׎s/:mg|p9ڶ*\L:RG6sOܮ:͑.;*s3]<~iŸe^O5LV5btklb& xC ivGW,70oOhqg=U|7[U45g|={PV6kJT' Y Q!@cm74r xeMB 0h]P*@~,G;!I[:~n HXjOB3@ ڱS{@V@ =H=${R:RwH $OTT(u,}w#jt#.R:$Ԟ ) @1?.ݨDEf\c 6fk3'33PhK$xm;<3i++i`2 Eڛ4iKY_ 7H@=[tKk9wzfh & POg!v.#E[ fDWI]f&ׅJB:HojDf]ջJZX{Z5(x cej?ݚ7,r&58d/50!0ojJi !蕐ԛS^P.!֞.-zF=H5:f[v9hqLtf= _u;q]9qfW>=Hh&P2: k5jfר]ѭvej߼ kfDM u*Q;uhruޠ2X{$X{k#v0)C/q!oX=/Ӷt.L-j7IksX&mEtFtXB㈆w]9}mt8ؗp!ӮtP譗Q(qޫmWe`WW:Y9X;#PFt @?àvF6݂'-C.tg=1=md>y p7&\N..P&Ko:b3{5MP3%S! v_Ԟ&}&ߺZmBP<4̊ԉ|4T ԞnPʐ6rFo"d+kT4hNLBꒅcݍE=PY@ ܵIj#=X{8:=AM3яԞ 2gpB v?A@H% ֞JkOF@ kd<gP#@H.$ :c!XO@S9{X\<=u<_DTϡ SڞA,GoN<\뾽ZS!ZC5BUujZ HQpB"]Zy) JjI m~nF{>Spg/ @hK*'CސUUPhS?A bh}W@ C)2%=Ȝ.W#zԮPZ) j*f**iNme ! cݡajNZB9v7)VG|;?y!RapJ?(ĥt((YΜV; k'r^num}̀c{r}f\ŗIA n8#Dy:IJc]-o ]%+wHDkGXk;Gst5tlGbJ)=-iCgMN7^OiA(F~vF |);\[.Lmz@<ޚȦF6b.F!=PSGMpX au{+UX<gk༛MLV.2I'tqs0x A`4JS 4AVc\ߴ^AcgK h[$h\N2tfJzӦF~i55:7J{輡Wr#D +@l@bZ9儞DIWQժ)cLtK YdS}}YZ'K4o LO͛(j#ɆM$E|ӼTC@ kwh#cB<%EnUv,J!OkO8乔XxSNFv3 \,FۗȐi4 4jd*Y65Z> ,ՆJ~FHJ4֮z(ש6S>'pB"vOBbԿaζD-lѥ))}/e M}:lKĔGv &17㩯ܤm}< ssv-ZxLISDuVL]UkoSq D /mtVT/մ$h={It|# Bvߺ`FKAA!CNn^0(#9*XF h{6$R 'qcD=h}BpQZ+U rı y@ zpz(*1/tDNy.Y7ݙK1jSә4/KW?0Hj'ZżLӯ:w#RXWt3_yD?0]40siLmb` >kh@T S̼"1})}_W,~,B=<H caTl9VɳC]\S=ekY(J\ @[FLf[)&4%Z4Xr6O'̤FtCa}S&y׉|m@ 0uG h2X!;; '&DcBksdڑ7(""))4O(ꐧqՎz{ Àk y6=GWr;4R44~O8ik\x,#XD9K{_cN @.Mx\vlZmąaSg;bBX(~5caLcYuj)7LX Jdw-iXJ쳊d$֎yCVv=u\ O|xyaps>էvOV8]prz_y48jN fgd.u#evxC; q'jNvzZڅNeOtH=ԯ'j"ߺ[FGi+mtH>ܮ:gi@#;؎XL[KLvm3=G`갍o6:v\7>ṡ~;#~P{9*'S :hNԩ[ j""ڴ{jwJ.P)jrSlџI*Stb;SPƆ@"u=CaLj̻qR7q P;P{*T Gv =wx3dH,kO, =҈lO^ g:`gz C<"VGprL @b D3kO@#[ձǗoEX>.ёǗYt5/wv/]@Rj@ԱvĬ#3z`Ɩyr߄#t祝Ƞ@ ADm#7dwn~aY7/:ԞbjԖzك@ԱvdOǞ\Q4tx䎖Q5nc[k_y;Xӧb̚虿p &H}'Cظ&4h+&HjG*)(>683Ƽ'5P\g,22 '=)BQܩxwLMh8 .6!gFN<ؓQڙy_#&Q Fpws}8>]Yb3'y=֛w)Q^#=Q TҸ3S/OriA"&}ySrAYNm]KIݲ0\ԓOCugySw¤xw:ߣێ5vY3'ﴈI,Uhg"+Kuby#pAimY_*LFzzleڥ˄U4Bqrksoz IT".\g2ԥ:InZαiȨc6hϹ!Jl˨]GU@vy+X9X07sq$gor'7/ؗ8fs.ɓ@pZ, c\%Ru=L'X]v 2)vCjkePʩjc +r{aH9{ZJH"c6:"@?G{-}Ԟ:M4= -2 u>֌żz5Ire1Ԯ5?fa)Dײ:sna=v*ZШݩ9Z @Lt%iA@2=ebscn'%/l2nj{,Qd_jQZd 7}vFH6:Ks2m dꚧ2 7qv"^@9 MJ6VЈ:֮$ړ<)W0Egtތy__7Hll K@CUÇΚ]*΂f6(o6ț19u@dםenZ FKWU &e;S"4o!T@ `2{BS)-V|8BII )WS4!bj8AAbY)QфPBͨPOS`Z^t$ތyڕ$jϞNxSD`&RYabPWFcx+R)SA@@X! XݾP;@ X{62k$DlP*y՞pnsˑqVՁ!J@] &s=CYd>ɴkwAow?:g?swM{ۑ1wTfiu1Wt@zTlIja4Į-/2P0q<˩qʅt8x\ReO*u{B,D:|Y-SM?!i jφSD`hHI]S}7雏6ۿj|GgTUVZX q >` &p:vjx`\d)WB),J xQ7wnsK^^snᤚbHq#4$Yl^W:pnjuj:GWt6yfIΌ!OkU>1w^vy -'d\MF.'D<-.U2X^~俷ԟ 0k/]Tk;5ӟV7q?}SXŸ[|UvQvSGKȇ՟&̻tWDCdAhHI]\}|sVLcIk;6?go?o|;uﯜx롑Mv mR'0ʉ%?`/{cQ13%0jNX8U4ZfNl'.Nܪ7J= xe!/u $+JX"P@>,@4$j9rŧou|6wm'co;ί:Z8]ڥ)Sn6HfaIŴe*bJy N9g<W/IųYYRf*OwĈҧ`bSQ@lF yxjiW}woEy?5E_vb"vyg[t`9/ {qs0 7(,,ZAXvXӟ!Ԟ$uOEf#0jKW;4涣_tpm>p߿S6}n쒝6 zҍs6;,ZY8o썰,/`g'۠Ǟg;şxQzo5ËfSq^)vgOl]Uox7myReY@}YnyzAO SRb'Ċ(@Zi3ЫJ~;luiG6O&Iɹ(SFǀFW3 Hf]QEHD<%P $x]M:^K6+\+DR$5R/^W4fGU̫ٻ|]eIgP#@H"ɵWoY%AEKoɭʾOȫ,-=#;=;j dɌו6DQú~_FrMy_ڿ>>kO6 @Yuu7|+wg?t/~_ӷo&+V'}nw:zy$VY)`COtG i}kMf7ʆǿf򿟛֚y/V[#ES*FOԞ,X{zh "Iy֕9遝o/pnlgr^;P; ڡ@#X;:j=yjViOOGoݵ7>{։:.^zȺWuU YC=I|+-ρeϏOt!֞&@ I_e?uy8d7w^A<[_u) hݧ|;d ;Iה,^ҁ׾絯=x~`IkjyM˖p{;un:LH%XmYR;99 K?̚.PrbtIbIoP"4ʕ=jf=ߒ>uZdݬG'~l{]]<[gP-$D킉N8 x}e,BVLsY> )WDzSr]QX4HkZ#nj|?l}fdKavYle14Xj<=/IJcF!.l$Zz{v=V<{c۫Q;g40F획n+S%\P_3%2mJ'|b=xSo%\d!P~4m{IH_ 7u2 P+{KBZ@ X&Qvf7ehX;N : _eږ5B'F턹 1:#L]j{9n]r{kxjjG4,륙ȩnW/F} 2JwL)c!—jUIrLCsB4`mJC5si=a_LqYB^va=3{laEj7md-xB:BgϹazo޳h!F&ivӎ1oj4{p(ff7mj+C(CS0C^T|8/@r@ c{j({D$w3L<6^4z mx=Cb,WNPXy"dzlДKnI@!֞@pAt:"VVszλ钦L]E3]XekϠƄ@d@2=C)X)( xBbę3@#V{0#[  v" b#?cqʙwjƽ`c]$V5o:ԭk7!pn 858^Jح*IN|k]":MT"ͮEb  hb{t'2cI ,NюŔRj{Zbz[YEH obc7ٮrdږ*{O#eZ){L HץFzJsٵ:%3>G鮡DX8w,*kSSt6[Zh˼&WqsM5: (jKHR)ZцVO"6iX&Ӟd~]$yEHȝOC'Tkϵ{h H @S+g/ۚoC }NEH*[Xv2V)ʗ.":"d١%NwV܆GHyH?XM =A휣g_-MIRڱ`yՎl[E7O0gs>VN/C@x2P٨"W7FL5I=V^5F6w+EjW\Xp߳ hbvO8-lCc;k2FϾt޴wF'.ˆ>6:yf6\s-.lmbrK1߾%*S'ReS̊ˌydx85l<'@%>BV{ͥpbjOlz@i@}ma EkW e -PxVliRՐZa>Hrg[@׋2F žW]HZjhRbd|{@6"llu`CtGbނ@=d@A D@n^YqxUInr30:!PSn9Ƌ+>A2 S͓{j%ջn'gFgKFCRt^Fu``eXDD*S@ @@ԱvC?QHt<nbVڵ4tyQ"/GCt܈z4aԮM"{g&/N2iʠfۜ[W A*Z^RXu> , @V@LLKT"#KR&-]F'HpWZ+Urj a7(dc79jص%"KlZ8K9Ȫ&Jԑ^?'GRiÌ~>`q;XTхrn:!WSpA5FY[ӦQA$%M8Zt,f͚܈88/ڂwTȠw py,@HX{j "[v ՞-X! @ r 9&P`V#n~< $j}ut@ưϬS /!1!\۽OvH>d\jܶق@ԱvĬ#3z`ƖyrN_jϖk !PA޼@V;2yc:AV{|sSv$՞^m0ӫQڑ={rc\F}gďS;ZrFEY\o _y;P{u a䔤vVI Q% fu^z٘8=f?j˜QFjX@%.Y~xxXZ6y՞-lTuLv@G?ShmKf[><+.@!u[97dRw^MsKVoEN9 s3g>Xi)*ړ?6EjGVn[ԋڹckXXjg %IoP jjjOKFdlFG@7ixzK_@QL`'9'4ȍ09s#gzr&*/>0Ws{v,)}Oz@b-@=--a~ɂ|4϶!g.@Ԯl~x Ffn}BN@ #՞PjFvF.@i@Ա4T. ֞]b;xSYOӯ@"V{B kd("X{: 2j~: ;kOCFb! @ rjr(0=w * WC؞PĀ@=tCv-ƽ{f#*򣻇]qE7\IЫ  ֮%|, TO]wx{o{i_jε =vA@ qDxɰۯ?;$ Cb>x}Y!V{UźWhR~e߳& $vɺp!M:PUILR" Q̳:\СDjRFk Iڕ`tTA.@ dk(vl=7=KW73fY{oqCuiL̈]0,<0۩XrBIɉ[75'wM-" s-ZpkNG8̝ yBJv@4$[ꩃΜ+y/59g| j,FQ;Z٠FZ%94j1@hHIV/sx+uo&[U?8Cm5 =R'8J@]Ҙ;7,POcBDd?qN{jKK?"h'QoѢ)/,eL;bT^%C[[ncV_PPl{BG8=%"jn@krxek|\&;:"tl5xRj*_s?ve١_~xziSy=8m'z Ӄއ` @J!X;:|ߐcڸ\}]t7سso3ylrЭj~f.;".Cb @$j+yǿo&K&hC kg贈G{;{ zڞV;4y;y8-K{@?CO6͍ܐv8' $[Ulx⢆jdfWV~df/jJvПhxKj'/׎ciR@;eko?wڏ<{z3=W絓6 vK|^-w;sY5xȹnҼC̝ *Ԏ2ϵ5@ҬꊭG=w"f3:>õ3yynX0LҲkFgw^;N@nEoV{ iBH&Ԏ$#ۙמ IEQKUSk yg y#k_Ak__o3kO6O1bg4j'NH^ ~׾_d;]bgĖzw_sƉ15mRlw=3byUĦ~8=Hޙ>jWE $I Z\t^]g~N?LБapg:-8]THXjwD0!ZKo2#8Z @яS`Au:tlІ7.ݨD8Ef\cujg>fPÌF@]{v=qqKf*";L.)!عmт]'uQKA&I ~gXæO/E댅 *c=j?ݚ7,r&58d/KKmX7S2mC>;fıvF\ $ID~,A5:f.:1[_2m]w[y4:j]'qjHq=,{IꃲwsF3 kԮVO!oK훗pA}ͬȴ)P}ڥpt^rѐHEı#v0)C/q!oX=/Ӷto=P{*XIڡc& CْmtO]/MGNuz6:pKߐiWC]˨8ն{Cc'V }0!vBMt i`sn<,Zoȷ9g߸'k..n/f{{YbYPq9k3ҜpzqP܍=jm?͑ dY3{lմ'N- ixe% j}I|_F@ αAEw>xlg0kH=l@  nn X{8:0AwԞ=52!Nmjc=k;THS ֞ j' c퉪 lEbPo"dp[c1>^o(L: DXl+dʐ=֍uEutTX:2+ ֎] ]Jj ӏڍKl|='x߽nSO[׌E$SxƮ@AX&O//T\@ c@햶P{*%-y$05zD4R0jQSkԎ:-dZ⹹Sa09v7)掝G|;?y!RaPeѴ"X򂸔%X9oM'md2z@؂J65sy, N+(Iݽd+iὨ#S^T KH@iٗқ.u|'iALy=SmFb>$̜Mm6ҽuo(.M)fz1m$+ qέV?H6"uJ6:F7٬^,sJ4ޖ~CN xız=W L.%mHtrcR'F=TB@t=Z =:/d;mwJxV&m"w  BcݡyS*a `. ϵ3R:2ա @ D 2@ qX{X:8]A2  =ء@!NmQ@c=V@ k@ ֞ U gYCuXBߵ`2Lƿi! jn^W~&bז|ڜ >Ӷ!}]A ]"+>3ѥymZ(<W5.ǨNC>24"=<+ lA X;#)?""JM<'ߤ eSۣS6gb UtKSXλ:L&`kʆ_<k = c̭Q9k4SDX>]1ТF?HzmcyЇɷvccAS~,۷êҥ@#ї" K)338=["!Ӧ!:gAtE鏋Mj:(ޮ];fs7@h!PZL!oaaym@ҟ1DP;PY$"@c뾩y' -rn}v z9,@:֞*HW;ڡ@#u=3g|CGbPAo@^R^FIEbI X{ LBbԚQ:`Fǀgǧկ&mM?a9S5oB~MD$ڻu_{|96PTqg)!\۽Ov. RfkO޼Ye8l|ͮeXג{00[,gԎi+_`}RڃCWXG__1eGoŌj/yކ7=A%c^Y}SΜL=B괆0 B6?F(Ȩ=3@di8ޭe-\3=17=f.Ixdʛy"9y|EL’xѢTʒWB\@,ƿDu?TcaWN ǩ8Q/ڢF ?Wa=6y==񇛝^KS \AL%џx}P-DOI!1 ލq*fTn3-xX{o(γcOb˨}OqJrGK_UΨT_1]qV+{j|vNűu[n^B]}Os9,37kQ t+h/5.ux"5kbޱ f穟*6Wfv}vD5>yvv:m:kFb^MΎ'Az@jrƎVd@JnZ@KdfOHjN̰%Tur*Qf[DEKlYzyMrnF%Ejkpc:~8 ӳ~SRGY ID^<8w Ԯ.L @ nt .0|ez>mtpC\QRu6 rt/BiFJ؋`qTXRS@qL[U LFѩ=bQ2 Wvj,(^J'|-azegJG!17\jMWt㼈%9g9WwjDuȋFFv;:ڬT.n#O ]tnzK!]G(bf_=xwzfұ(CשY[97dRw^MsKx5s] O,w ,OY9jrvNDP{ *"GD-ok]z3~I|\#N`Ko6~73!@p[vȉ٭r*m6F<;!`}vN]AF6jrgOhM:I˳*Zws%mzR<1M1 hN@ )YrS|i7S[){}ԩY>AGb ( pkΞnf-1c//E$رcFСCkPA@ 7k8$v`pP;ѐR{aa_|xYd<!I5x *kn9>P/|?ɞߞ5?)\Rj2d*5 hNb(q,J휦w֛Ԏ.Xj;yϚ5+g=> X{8:>S>U6>~ٝz.6eĒc{ ?~,Uj7;kϹ#>GՎ2իW/[,5 $9^||Ѝ>Xf#c`?\z^:ջ+mvé|]Ǐoݺ5g=> $3֎x}/z|2~!7}k.xvL~}M pG5.%z]}9=}﮳%<מ7TpF Eky'lm1ĩǎ-`|V0y"?˃8aAMNUI^%v9dcP2'-ɑZĮ-Z!OgxkVM3M:Ԟ^h $N(NK,d;cw r`v_V)m,^^y|ΙۼνvޡSem9˔a_v\Pl߀&lT2ߣ4EP;L ^.1E6 ~8>}gxeqsZ7q=/k%}U GεG/Wr>\뚅ʹ)YJKDxBy}D1iڬYwț$s67VnvGHrCms,z׽&dߧ{F]P2 ?8v85aڑΨ=>k׿iX3wM:X~`ڑl{v]ݒƯۈ\-jV&3[ PXb)T1|0[J)ڍ@ . `аN|LZΑD SBrg\]ĝu,NZb_Y 8N$m_Ou&>x}O+Izm_z*XQ6`J{/:%i!KMdF{R"I]0y%q}O-q C+͹Zjډon#!SJQ757<5?_Cd*3 Bò=Q]C~7oyW4׷;I_?unW>2GLcGN^q=em$඘QE\@XΩj]ij;, XjʕkL=j;9\BfH?<>nL I=Ϭ o|jO[xƞ/׍^XeCeaj0s'vlt6ҘZʉvͶZhsh3*&aI`%-{87e?7sylh^bf4Qvg^c=3ѨU@ @}/_+8Im]͊K:|7zC!wU._m5]m m/]COUT)K>.pn?7d6t82@Ns xBP4Nxk6Zٷ5{+^?5z/7?wE~/,. L>1 .X$ 3?%mt0c(p['F:֜8Uqx١#߲8lz = ǂ9ڃO H$3NSwgo-~|7DL pF ܵ3"'$w>h}_uz;N~ܵxqSy7R&Jl=4^3CvJy;ɨKã4$.[ _@p|Q'׊>gܥo=8g}m.x}iO> ;p^;~٪y7tPoy=<>_P]_O|2@ yhN~Ejמ7{d~v 0Q1 k|t^߮yvx^;U~e`[팼eԮxMoqĞnc5y yи}#v7~eɴou 4}CJ@|HVʵ"/q3/|NӶ>5gwmFW޿AϿ8]?yq\&Pvd-aN <] :yc._ڟ^_'^͖\?U/ `E5jZWOzǾjzE75F_Nkڍm:九C?R:j;ԞpMoFo|L.5V}%$Ϟ}UC>4{^rtOY|sЧCCלy_=7nwtvWj!s^yU.n놗7'[9څQŔvHr2k7nh1%oΥڷ}Ƽ$M.kM&w^(˂k@THZ݈m]\Mȹ/ycsK׏eUuZue0Mdx(s*$(Ǻ1%%}5vd_[?8Ϯ7y9Xp8[o(מ&\[nΛе.nFsW9{Olw^Dh;p\xs{kYFq,\gs\rJ=[Y4oan= \@ A F'2#g\WWǟ\ F>@ c:bjG|XH@k^rNe=Ns_znړL}q잣@pD?5;S{r@ $9־y,kUŸCmko?xq$c;Q #X;A'utcyy]>&絿=m<ːǺ@ HZɃ㶌]ґ1cvbC^+8߂k|~f-d 34kbg̰Su3+16iC$nyf䪻:4B iېm#^Gn-=.}:pt{זE@#r$.g,_@^ҷ_o]O6BBv[JK_.} o?_O}֔omks; zD G:fMEZ /j*y:}-+}?Eb1S;y86M-4/V?֧{F+t2)n/ ITgo8`@ Ш?˫S{kř>0oޞU5֏>{[~whx3:F|JMIiI2Cmqˑeb)T1fǝIFEG16D5k,:lbEܩ=[Bz vԤ|=dS96IAkhAvelm]-Y\בMv$wK-GZ9U;mV&,*=q絋 RzɁG/ $k^Dwx3W&y';Li5`-q=_絿k+8]rZڽ:= Gںw!BjOy"X3-EfJ"3 ovփ}֣nAut^-.x蛸iv=cj4֞-~ RH(I#Y[Өn|/nkWv%絿t]8o :?ƕQ8]4Myz];WxL!֞P{Bu$-֎xݪemӤ?ox?KOλs/y ZwK7N7ڎ=Dv%w4׎֛pq<hB=Ѽ E ivJw7.?5jv/:ݶx7ڝpںOIy!޻oϿ|wů_﷡jDL>+4F4cܧ/N"[RHsW7uIWv1ys=*fn Of " >3"9dZM[DkGQ8l]n48!X{B'hC@9֎ +ޘ?!Ț^z'lSfw}Yd4-#f?͋8TťE)=nSF/su~u-m{b?ͮŋSG?Kd#I|! 8<zA5RSGY^'r̎&FREEa d4a[[s1ρU7"z-1jgvWv\qZ02T)kO4 Y4$>-8 omut>F||V fO4;I{@|ӟ4M-(9pvd7hmt4?$/_{I!= RcuOvD3gC^H9CS"L#]u7 ڱSv͑~KjY@[kH=딚A@+t8cfݧsnAYpZ{y:;oX{7^|k glM}з{egC^|Of{p;5SGQoǃC>ˇ:XE=J\{I!= Rcj_q#"76q.w#bMK3kGwMo&i\]Z =[jxvkVnjN>ɶ`]VQTȐ>uJMӠ :S)?M H(bS͌q,H[WwNXE>J\lc!58[,jiNXN\=iXH+jW\$9G׀@@ c퉛A2 .>'PH@rX{rjcU 6kQJv1֞JJ ] sbSC"}!M_S焄'?B\&\Uv" v~yC^ БAߚ]EU>+c%/k.e1QIM]uL?fy% L 0PyTi eޫ|zZ4`:{*!I5x) H۩SaÆ1jJhD KN*̵9:N5Fָ{lfձcȔBus .S*.7袭 Gx}޼y˖-۲eE?5#>݆1)BRsCL&.g:gɹ3 RJҁjS4!֞!}'nKF<6|mRnܜ`5!%+V<r%ij-# H z8r Wxi|]Fj(YF!v tبdmd8wb,֮&vlt^-|X[mWEJV<@ϵ7qcj ~}?I|j%!-@#J)|d2>J^+6,{|gR^b]gJntIx*NԾ@[<6\(g fR~Dy\OH2D°5 ynm#FkޕM$~#ʵs'vm ;kZ|P=x,2E55`GhW%bS߹Ƴ;gJZ68~~/Y7X/տk_eOݼ?.?~f:`퀎gQgO|4ei$# . xKW?Sݪ=}չƟ5%>] @k^rK.2eFBUUGP/;1sci-w翽CRs/:C]Ўw~PaNZ cht:?߱aq{1igQK80ӯ_9swڈ~,  _x#ʵ{*Otqj?:~Rp9XPo築tNm{Lwj>z2sZ Rq8J]M>eƹػk0ݷb-)#^G/$Ss:Tv߸qs޽c!u C v5/EkU*g xӪC~>jwXi!稝:ѧۣC}nr?"G=snpw;J5l PmДLUUUG)++#/=hڵ+WYlŢK_o_)J] )Y3P [4j'FVmGī]aX{pj?Q3OuEǏf}+ WL5RΝ;j[o u:"vOȰMk彣caT|rҢ 'kѓoc>jy1ezgl,9uVW!K:\j߿_b~MM]%c=tՎT9_;\@7^Ԏ^)/=kMi2b~H)Ɍ&d2oAYfhAwSݝ=Cvn2;{9*ۑ!#qqӹ3^{O(` g}˺K.k^Wy~ѡm\7l>^oM:6=_ߐ/ZHN{* G ! i7DžZ}m QFP%`pB*U}Gkz.(3v",en>GvyQ6pܨ=:o{lTL_^[x2 ڃڭ!8sS-4nn>e69'Ǒ _&ؿ\JI1Q<_-l{Gm-Y>/K4zѺ2]y'^4V"8hx@ Ŀ,RQ^&TLK{8@Q',.R;Xd1GjoLE;J.^-,))Oj zl2XwT{'I(V#/דȗ댮ΊnЙXeFyW=e)qlzFykmeDjs) @0:=QXmrؚz]ԱvtdWgh:XxQ!dd+Ss R@@Uo f^ XFA6j[Z4i%gӼ%4A0>F&:[ =\ׁ vv\  aᵓ.dnSCWgQɤV|d`Ma{;驹`z5٬7 Q;ť}I^y–wN RrLVZ%l3$f!vZzn-jslSv )AbRՅ:$Bz-]]ϬK),v5  o=A 5$ b2 O0o?~ȑFrȯG˿C&X=@ mr:]jzfj馛Zh+|ǽz/W}EkI&G즞(ܘ՟_t$N']{38Q̎љHJhE;rtH7iԞh>}ӳM3-EEf?Z0j|.+_׃=@K r3mb-3}Ëm/z5SIa*5IRH8Z-k~5:iʖ`P{MihU:Y_&8 3z8.XVdI׸]5 R;ԑjvV zJб0ڑMg+滎O8Emj39|g i>ޤr+/2exXE>/P[y>>cIJ|MhZ0!9"djg:E6,NA2қkR{l"vK+)cY\O i&$N׹ nS vJ>%dZPh{1))$ONV΂]L{OX}Xϱ*:,#tNS7Q;CA9=ctX;BxjGZbKQ; xe@,D":tv][r՚eV@]u:lɌMvv4/u;+v*ՉuHZk,ά&Վ$`䴣vє 5^;2sU;;FL~XN?ԧ,HM[&ӑCɕrn"c՘tdlǙ?66A\F+>uZGZ9"$=WHr|CڎIN]-](Mڥ;hSs$'҃aY_0w,{nOF w64W ztX*X٘mGqQ,ҼRn*"t2yU]]eaWB63mdNpJ$kmt+Jm|ΗϔdLTOio les_!-vR@ )ѵpqjZvoy7Em AaC)QLQ*cɡv3Le[Z]i,1O횡Oc'O<~Ce}tǂk)BCשU9xht{ myr!y>&S@>{޽{}O4iΝ+Sz@"X;3٪^m7v%]; n`Lr Q޽{ٳcǎ"ۋQJqICa F X;×-Y#>~%ރg=čgm3zȁ'\8{9+9˿˖֒ HѼp*4.+ Q Kߏ9p@II vW "udIaJ^w↑+ZW7sd3uCީ5ꃖW`5w]j̊^ɞ^ohw߾`&D*ZGAk3dB X +v|7z!>g GmYY[n[Ė5?* R<vks+P{@<1jX{:64 <Q,oEF֖֖_gl%S>iͼ߮V;;M3g3׉/:GXz;4a‰؝zwGM\@@їEkʔΛj:Iƻ۶S{9pYlKزcC1Ʃx!1HҌё9ŏPZav^t+YPű\@Ш(v́7=sf t=vS{yىo]{iAvXwnfju8=7 #.[I\ԮgR;!-7&>@ AbW4@ YX{8:\R[n'^=WmYU1Ó b.8=u@Pj-ns,\vqOMe5]UM|%ԮZ;P{nEU / #@c*~bAݖע+~?|}O__|˯?|7H c}-o[& ݕQzg%EϼƦN.q78Ǣ!J!^p>ʅ, $cUW-Zjzgll[Ilm]i0}ГAq6yQx;ۈL@!kscu=Mۮ];dVl|P; @ U:֎w͝:'].9k?Xج O{>O?Ᲊ:o_ z3>b; `poW?H\ZY~|{}wKm {`iTAXP) :X;PVSYydϮ5+Ϝl'_`϶!5dYojBUB N*vw uvՃmruN++zw_;6|q6O!1 j @z!@b:rUx蟻7\:gE+$v: ^X{H:^\}FKg|ۤ.Ryy:t/^u}W2 酀^zO8%ם:yM? zAu )kb]o =8EQZ=6aW|ذK 9>tPcG[XiQSP@b8~pvh6h}K]2G<\v`g(-p&?1oLJ̺kFEE|IIIϞ=>a„RjV; ?@\+֦Ďc%n]?mp^ E!Vl vr=!DkG7N8!o >ʅ, $kר=kʐ(#EmkNr WᐇX{:֎Z!pGG-@(Dktҁ'߿?z3wf?B}(6z+ dQ+~U'8|p޽6w}Pktt뭠/ QDk_xR>hȒ\PSl%ktZC@ cg2cvPjO}@ C +o(;f|h[n."S k ]pesE:~  xm7K] di,鴙3.!p嗣YR] :p Ed dmA8H=k>h &M%//*ڑ1ߩS"j[1Ș:VK4#^_pǂ(Vܯ*K:m&LKdq#Gܶm;=zko&tY[eS9^}Æ ~- ͒ee׮-ȘI-[N/֬Y{Ӌ#jDS;Yf޽;\jDž(y%6z&%2ڴi3q5k֡ jE-Z@)iPujxv43-[neʔc?[NbŊ鴙3.!.fϞ=gW^y]D@X;7sLs%(֞6z&%2üf&]O#zK^VK4vԮkw-:mzU0kW%.y7@kN^] ci`2zdb߾Rho}v-bzVć>iӫ@!uu(OvT:@^CgF|h6;8HQٹs-[ Vlݺ5-jcNV2 cΏ^E)^;^*]iڦC(WM9-X{*騛i! w)g:v~;E $fKw"u&_VgEun#{m]]]P汬!r`95RnN7`U'.Y~<m7{Ʃ f/~Pr/:iIsMӑQCwGrmT0g?g=?;-mzJoO^nTkRJlkO|!{WIn{}綷wB_k^r].0zv[5aN&M.Ev݇|2`[Lv .w-KwOU՝8YDǮ酳c$ވNJ퍧]״uً{Qőuu,x?[HΥ9/S~RIpp)_ҒJYۡ!9tn}ͮ}SkWM{+_T'^XѮoEfb"8 W}5>fKPW>uڂ_J=uan!a\TanCSbӯ(U5HJW!$kQK> ߦx 7O֝Zwn|ߐP_M/ ՇL"5} +XZ&}ѼY4(1՗_ʸC2K(BU~΍cc_M^^g󩬮=~ౚ]$kwS{ r#gAn[{JOZ!?}K(wT.bcpx-װ9W:d:)uĹdR=dwXpeFxݡZr_@7+f4Ͽ6o]ϡ]zc+BFfʯ^PrP텍uҎy>|~gbރ]q׀3O|mX6y8})> s6Vetw6>xiWʎ,\clwA|?Qھb?CDʪG˫޵ѡb^g?4lo1m{ONv]ԱզiǼkW.vcƩm8|4dwt܁cf?7>fD+휷tagSٚT}rߋOͬu|3\YU{TъDxʪf.-~QMf2myd򬵣'/5;U9mtftwAu.>?&_dڍˆG;^~vs\}ڥZ46I=${ݎ Q1ڵ}eڶ䆝'Vo+=uJys?'b>lsB0պ"ق]VbAM17@2y?4CKآ'tφpsYY\zki?':?#]hc DCP>s`$+`ҮI8ieƗeq*H&e~Mk[;{c+/]89/}{h:2=DnYf 4V*'&u]j{ީM"+S;g=kv;Kv.,U)NMMcU[ p{PYl/K;z+ba F}x&/[cjtnĺhR2H0bNhm } ?>fCQ[:;FdS G/V,r|;QSv`==(~_hhSWV>o wZ0'[MF"F,h^&-Bhj8l#V0$vvLTBiJj\ѡK"B!xz%vA?9wlG &f5#rx-צ$#gJc1 ҈^8U챃Gż/7?Gg΄'Dg>Wc4ids@&C~`oCYOZ;46jksNբe+63`Y.i4_X }HUɡ*DM'mv#1 絿'jx)S`(QE+'jw,j޶o!v99s> ;[;S :R9H&YekP|(sąw*FGp箫^{nB&6"mZz 2oqP #Qڗ!nz}&kWMa`Nlq# m6b e⪛A-vtO.:QYm;]kvd7*ڔfƔ81z1}qdái!^\cw3n>$ӳ3>1jO]lz@(5g~,fcn/7ZdF^qƬT{/gf,19""oG4Ĝ(kR0{;98:sevsCW~^V=Tcߩ{B$ȉGy/[Mcr,N>[[j/yP3Ц)]9UDnC؉]Trrˮv8P;u)?ʸqz7Һ2o-W܆*??ʫBx/kBA^3//Vb63l$~/ڂNیXQc'MutM|#i/s$4&М{lQkW*VgF7=2~? MFLOI[mS4^'1SA3ҾCUT"Zc{p548^~7_TwXbEmݴsp{FG"WvIEHX3TEL # ւ'xE]ӥ]B껞FѲC)ز]mtឣ5\R̦1Iɾ0avbrpn9i#vd.fIIm/{3ł?4i% FDo5_c}^3;OVao"Qbݾ ZZ=$NZki.;ho߾m݆,QDY{r x9m lPv{zaJ\YX;.\4ƩѦFFަb՚H}#CwP1:b[ċ_[k]mм@U6s&ʜwEg$M2͇Ɍma-6ԛLˠ!IlG.j/9N@{YAc3+/ZыצAF@VK{ ? E{O6_5GvQZ:q(%|^zvSqsυk^^ }]} -2pPoOqukY1j#/7w]RNA8QuLvw8,C>4{}Hđi%z3<2 9gin{y<뜆>@bOp 8@>}t$֮S;\S(ҷ}m};  P;l@B=3cP@ P{F5%d@ځ@B=3cP@XЧ9]iդP^_ͤ&ɒR(@H:Oc^wvp^AF@@@{j" )=wY_؛,xfŽcCv$x;ޥ_*ݷ$K3&)~+8H =8ڙ7^qYEL;Gvp$wDMm 鍀s](go#xפ{5Wm}n+8O(&@Hsbbw L&bTv>i.9 "iޮw XP{>[y9!3%bwbKe*:-N{0d턁  8ڹ1SwJ}lLI`{$2i m'ûF?Td` t@@ jϨ7   d@՜V@ځ@B=֪ P;P;  Q_xVNDIENDB`NUnit-2.6.0.12051/doc/img/bulletOn.gif0000664000175000017500000000011111713252032016740 0ustar jtaylorjtaylorGIF89a95[!,(;A!]WV;NUnit-2.6.0.12051/doc/img/textOutputSettings.jpg0000664000175000017500000020565111713252032021135 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?8|+Ꮗ*Xtx6ivF\fɺkgI%EWDeEUu2|,Cb]b_y|5JA//|G(|:ھ<-}ZEˍܗP/]\A$[įnS{%f~d,MzqoWEK_Kvz!_='Oh/ޭºKLu=I-<2UxQ%Ih!gyxƟx+/ džl݉uJI.fHp,uG(kץhN{馴i?`- GKPqG#=#Z;A4Cm[J ]5.丁X\Sγ 'YeWd+׭>[;h׺5 *ѭKoBY,Co48R$K9/)-MaW'))&ծ;>4~ DY-#OHG/؅=zߊnkci |Hzo;c'atGF`u"qJ4`ݹW1)_Kg]~8?> b5^ =3:5N3Z f;gU&WI}F3GGzO31_kBSKJU,?e8e?˜|1V]AqkH:?#WE{АX V]V@@lFͱ_3oٳ?@ѿ7$Fj}JFsS[k&mq ֋ OWa,?e?)7|1Fj#>| dFjKyנu"SU#/ 5|8? 4F)p3\tFI@&-L: 6M5D<??9)|~ |:?#ST>?| ]bKW܉y;Oi~g_GjOe_?F 5v~p7 5D<?K7W@G2#?(/_r|w/8*!@Uneo߃ 4oFCS^eu#Fj~=Zz\3VAg:yCgOoF8+Ag }ޜ}괿}ȗ)8+Ag 8|*<]B)rA1OԿ}og:?f߅'Sѿ?fg 4oFo=F*E0h/_r'c?KgO?@hNO‚?|Fj=ZQtGi"lc)3(?G 5 ?|Fj~ }z,-/_r/9ofG 5 ?|Fj~=Z>=Z>K܃c?K[G?@hG3?#ѿ_֏_֏E R3gQD{7#Q 4oF##괿}?134oF~_ 38Fj#i괿}?1`>7|0@ѿC/|#aσ b;`]@q >K܁g? _s_Fjx>)@]Z^A5"]9"E"1?1>@]w}r;a",?KCW@N tF@wCRxZ_ʾZ1S?r?A?eM|? ]X#iyHKRU#H? ɯt~ |:?#T'|?> tF]ޞT5/_r-g? /l/> ؃=ui|:*TKSU7OQdOoAiS'\+_-#몊2 OWt6OM?csSB?_-G;ҬG|=ECWt5O+OAiHc_E> =wixsOHsPCWtG3?y/E> =0_•.1RF7~i(㚗Bʾh8/Bȿ5ݯ߄wv~.m-C5N":ۆVVP {[>Ay4c M'sr߳o||Q,>&Q/HE/PkJv}]Ԏrm>Hu:ogr/U||9{5x?) ot9#<׎h~"3:mW8Ep? &}W/KƒEcRM EpYuDPYT/_~=oEgxb_Y>J[/e+fblHII>]K $3$bd"3nx)֜Nǯɕ#MI*zR9n< |%Ezu{_$^->GQm#!,)^wv)W?^-k( CՍMrSF1_?LcR־}ZC-!ؠO:zRk @%?s0GGcVx|a$eO?afb1ß ҳK_⟍'|o$zn,J -$HF< cKم.־~kW,uD. _mdq^ >$Gk^UVk5ot>>lKRXh7'kueGT~/|StynѾݠc:\[\A,|^t,P7\7 Sx^/u/h|Gq٫iZ[E7#DaG!Lu >$oZ%?kJN)&׾}ޏt %)+j-?iY7Ool<Iq.5[wc6g C?xh{=vk^׃o-<]OhNGfwO$ Wi?ovW#0~|Iw-j(ƍ)sBIio|[K3*ғoZ'6ZRm5~߳ʞt}Qi^]/㴂[%,෵EȂ0i4I#$+*S⹳9S"鮁Z>N>CS]4ZC,5?O֪~l溫ٗӱ+z-/xq ??mZv<8n99[W`]a.oy-h:&K?2_UR^-mh|C-h:g6i~V}h>2SUR^-mh|C-hп՜W%Z?2_U?|[D-h#&Z?0΃YͿ_.<\ .tRXgںCŧ?kUx>|C-i‡Vsog/ qM8Lnf?LI_F?mUCmGB\141)/&[ ,u}?mO=Z-С f /q==k`~3O~ Z-G?'?pΉV3of:3zǍaψށjr̞3?> qށjatm@?_($Rn?fwy[R٧]|A-h:42 pn 'Կ~1w?kB0΄_7i~f#z?5_Q֪1_H@/3|AZ:425_Q εnjE$wZո~:8G-h:4 8ù^.>B-iFx/֏ ?\14*jƉ݅ZZ?|Bt?kK ;şM!atRY|h-oh?Ϳ_/0?|C-iIo@_:)pm@?g&RU_-QV?kNZ?Cx΋\7<5\5<~6^ n;4'?kN_>-^ ~":Hk@?̹?x՘jn ZM~"qMtZԉŨ1 )-j^6hd9y_3Z/#-V F7V<ڗ'RϏͺMsO_ h i/$FR5ۉ6IT9̴omnj< H}}GOkL|0|?jmi9IϥGiƎ1Z$OKQ#xNwh C+ڶ}_:Qh\L+Cs AW#6%!ӝzU>.ZzĶڽy~ R0|=lI ?jk*;|q| j+J?vÜ_QEyU[ĺ55 ;P.mnsdlʲCA\'Ep?'!Q !wwW !w1iѾ%QC bJ}4+; ׈? i xQ\4@?nATHh@HhG4@?nATQ\4@?nATHh@HhG4@?nATQ\4@?nATHh@HhG4@?nATQ\4@?nATHh@Wo hך|D>E HGv ,HMzEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|R+`s |`+E>>F+LGa%7R(|{8\#-<8/E㯽|9ĭCšxľ"ƨiWuJҦHCjW܏<_^,xΝMwFYm.ᤆ|Ыk,KrwWϝ9S~׺6h6x U|xSquH9F4**E}Sn,giL^!EKGwgGBܼA*j/?/&2ږaU%m`1TA#I  :]Oזj>.քz׉U泃U's4A#cŒ!|GRugQ*ihyIJɻYZj5ll߈??=wGxN>r)m˹^Z%y$+(75dZi=;Gk?gc[kmvxFM*+ޑ$7dfFmтc>55t_J_ŏ' sK@l`/_ܤIyndeI$;y\9?վ%|O7ILno >.څˢMq*#UTCJ뻻k6Fs;ݼٳy<Pzc: b$ 3׊uK" mŠ(PQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEWߴǏd%T^*G>T^*G>T^*G>T^*G>T^*G>T^*"#^խ닸_0}4ѻW,@<+(يU0<_%7R&# #qo⿣>uP|`+|{F+ӛ~|M k븗K?p[.|<8?*ÃV_zX]Cg~f ?KѬأL'z?\'ѝO›߷^O}nG~6j w>6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}/|6>'fF/]wwۿl\t7JƥD.' ic?Lju_ |]}N2 YaZ}* P^V$I'^(䢡NJ~]-{w,G|0𧋵O[5?j Ҵ]CUKHwPn5eKywE? Q]k xFs鶋}Mw(coDphbKC!YOߴiݴ=B*'/4$˨XxJ]Aqk<2PO#Br'_K[U.j]޳sk8/-Kfқ IDilDxI'|ɯH+YڻڋqoֶvLVOQ jtooaiqYY]܋ Bav>f' WQ5mxR[Tt}SA)C-CQu)m&a{wrgboVk@UA\1bD(^*S\m}̈́›kUuQR0(((̿m3O%C5hw&ioĽcHf(~(q-? ~?kVχ񶥠6^-5)cѳGU?)=֩9=,E2PZE>m&VC)ʻ@ð %I5nմqi$EQn]I.ֲzi+Yvnϊ>|-|c[j^'s{ho]v-c2(Z^ȮTUG;s߲'/i/e=;t-[ɶ!cڻ7CW~_ |EKQ>P $^-%Èv-dؘb㠥_wxZ: uh5Z}6ΡZ | JYHbqU}YZs9 +;:.i/jgc-o x':#}wi}}C2X︴IlY 3~|9;x#Mj*5CkBfS6\mu3DBYZ3ݗȼ!8|'qc*yb[APv+.|2c>F2in(O{&v;=sRw/;]liҲiٮ**0MyU+4Fﮩ=p:|C= ŝ/FХӮdCWދ$%fڹh╼WO Zz-bV[˛;W`{ +FB4T 62xQ[់2xMk ?R?=iBccmP+߆xzH'IK[;+8 {HQBqƀ*"* S"V)y(1JܻE_TIV)7VZ{۶QEdlQExw-_?~9i'xX/FOKkhYh5 -S"L+_ؾ%|~,Ѽ/]m_ky\-jj cm|<$-gY8nz6MײrV7,Iڵ]9]e>7?|um{6 :þ%Zm^vP[EdǹgZ2?/[1|D~:gΓvi{jzЪ5>[/aV)F\<7wG|~ Ĉ y5:;[8Rmn#% .=c6Yi_L=_Qt{NRҘ֞%\}EJ{Ŋ< F$,6׊vvvj*I{ܽU4zl&ᯌ~;|aj&LN3B$Zd6N]X'۰U>ދYEhj6W:U ș~Ӹc]YBoo?^mBMc:mxnbOe٭hŸ^B*K4 x_4]Z 25u{aNPG1hm`2 $tcX0./oȖs^Mu岍뫉3~|%_M *$ol5E*$ol4z >AG$ol^OF >A@?4OF*$ol4z >AG$olyoN_x>-ܾ^Xnd-XY7?{+od`<ZÿZ/1nCM6K"'WFFUBXGF%|OV:mޝ+'>sINp|*Ar`* ~V׮9$oikm\ 67(Y`Xַ^9of>hP:M&1xQ M9kg8R 54-2=;ėJ ;Πe.oekͷ  ?x)vx{Sc"}n ?-bU.A\}\엿g̹9)?dK}vKG?R]oĿ<mEֵ:_R+L4q=R~Wo({> ߷w}gkx\^Ư-AiqE"9W }gS@D!-NxZI5+ٴ՘YKvIL(M2ğr+糴fck{d.K*y$um"% yF1jW󔛖״QI9+S_%~&λaޟg Z͊K C 5O1w~8_$QH|o-^臩~|&~^Ҭi\}s4JM44K#+;bI5"/%zuy&41?dO4)i_Gzy&-+HC((i )q_W %F+5M>).L%9R?Q|C;/1?s?J1gu|+s "Qt}G$VVwQ&iĽHa?>ؗ 5{Si۬jGύ۷z۷ʷGW7i۬jGύ۷z۷ʷGP%{ⶀڝ:mj,)4wC j~! * ͗__g75q+8~|g{pc>jn5K/mn}o{vy6Ǜ mrb g2I&@~2?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^ A>& V>!ּeG6LQ{{G6a̷6 fWT4-@|5thNs0<24l+8#>)ľ{˽J^zn`.-g$&n72 #c`Wzvo=:>+gLu~Z˟D|,>"KŹuK)Ebi7J;b dc>Лcc7 kh AL+ OS;'H`"}ȩu/'bQ$?4ڴy-n[˧ }ѶAe[ $0~πgh1wvW[j\ B߻[{x.ej iF4P MS,>nh2$#` ?+ =׆ f%ajbh7+=،ޮu B5ԥeX1$:y7ľ1[n'dڝӯtW D1wg/H |l1|EџUJGn$Z.J@$i_a`Ӏy+yZF9g>]>gә&e'zSpNW^k'eiw¿x,-} k s[3Q w $ܰ*@ Eoxkqg SOƐ5yFȖ3z{7w~yoy_|CeY,ַ eԶSieH5+-"ɷ3Fġ]1~#g' ljG8]ZkFг!#bcD*Hܙ1(-ml-{tvm*O sr'޿IvRݏh((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ('MJ5 V~n?P[[@?n?nEXպhպjcV~n?V~n?P[[@?n?nEXպhպjcV~n?V~n?P[[@?n?nEXպhպj$r͖I6袀 (<'ß^*7^)L|O$ r(+3Z:$׵@)M@-s [hx&N5tPü~ \§V?? SM{]?տ&wokT^Ex;7*uoIZ:$׵@)M@-s [hx&N5tPü~ \§V?? SM{] i𞗡i6dҴ[Hly0ā#MK6@N9$֍PEPy*O _) xǾQ|C;L* Nj_R#7q^C/?z@7Fs&QZtguMczDrxu+;(4Ib^0֍g~f ?K=éS{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn<O|H_ýsuo[eǩog$rϓ9cʾ0N>35>%x+ >ү4>Y"c+ᏍxǞ^+n-N/KMB fD.]YN ?i ;&] J$\K,Rs{)-\ɉASUFN2i&MݮU, J<եdی}X~9o7M7·#JMɫ[X]E嵸"uK?+4k5"R˜~Zi2]?~,M8O< ܬp6h",lT1ܫ^sK'6?Z:f/$^ys jGg=ͬK/+D0/1>CI{R]ZC;ya0$]Ԍ;5 "F|~춴lKv^5RMVzߺWF>d뛏~/7mgzF_=5n!h⸑'ȻFo-_G[բtxFUn-[G-ߟ-33eJ5ck$պwut(4((2>-ؗ գY߶ſ!h(((((((ſo?E|qiڮ;[][L"?'8=G#ECe(2~E+??̿E?Qt?_"=Ox(/GƩy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?jj_ScGּ;_m>E&I-3|cjo z'-_lΕ:W 9r.|H^FO|D|_x[t;4kKtkPT`x# לxK|5˧Ch/STΡ*i,^H6+ FZO9ɱRQF24UI㒍Nv?L:y**ZW+^K~yp.|CmMѯ4˭:9n Y"ۻD 0uB0U71\_ |?m.G\ֺ|O \ ͕d$WBYBoWӵ?QCk/NI6O io,Bcu Fi7;`T\_V,'/5'VAAۣlDzTtnUElRJ+{4sӅ_#%M&jNM5Z(BTBZ9]I[MY3lmg|R=G։om6fgFkJ 49vܲI|=c-/͆qkܽٷhm̥f,Mi\ ږ2[%75Xo>O.G1%}Vgut|N$> NR-!T7}N;%Ry [_,s\e>E 匝86쒼:ݽݛm\顖'ї3W4RJwj[_]L{V>4>9d0ͺ;icɌ wxR1^!|3D>inƒot3he8FPNa7lu{.&φUFtQ!X7 gI$n57=WOz- tmbf)&iؤx3S+GZ { ]V]=֧nIaBڼgM_[[]ٟQE!aEPEP~fK?jѬ_LzZ4QE| M ݟ~|*[_"SԼO{.(pjZ%HdQ0W]v~~ JUnonMZ=,V0VB]"(vV`-|1-GPs;C(xb@o"mضNѓlb`DT gM𝔶Vc[Ms=Z@44ҐJǖgf$MvkJR7tۧDžS64uZݢ+ ( ( (>I+Nxᶷm.^//m|K᫭f-V;]"e3ofmٌdo>䟵շѥi?ƿ5(fK4`=mEl!$0B6#;o+|icq@/i6y^߳~8FsIb'|?U|h' u;:2ogmXҍԫLX;{7۶-]ljl%Ö'?lYKN#v,Nb{%_TN[bKVGw1GpK7-(;Y<3Wψ˝KNѴ&I_Mn5ݼi*o(E'kJo {ŝ"~6{J/4{#qְAGfs2rY5߈+/|ՕGYo,YZż<J+%t"SKAWw*嶶շu|+i]ZZ|ٯ_x_w>gOWzMiڜiHďbGtWc2 xT񍦗c;7]f}&=R7͑&sƲ0HB@0XO?OV4ZQƬ<]> {?]]=d=k&i lHD|^o4~-:Ë|)h^%u<ˣss pW (%dMg>er/m[d%.דW쓲I+W⏇犬|S~>)f:mIaa+\4BA*<|GEl/wUi‹i6Cc[Z}囹JYE\R,^7 Rx<=͢SS3}_Mw`"-ȴڭ*wWF:x[;67^%յ)[ϳNZQ<,9*˰y@fmFMmm7]9{t|((((((((((mrW#]w?\QExB[/س $3C"1VFFAr=ڛ;Vu>+~5>ĺ2Zjt Бh.Q*cܥn!g֟뱤3"Y1 @' 60d ~#xK?|][hlj"۱1D00-eF3dbYSmz:77qco0j:.@lU[{m(njSI^2Wז<|fSKi%meKaoľ4ƍ}l/CoŝP'Rꋹ%\D;WGx-M4Kiɤͦxf;ImyDs6It099?~,xG~4i wIմ[G2K{hRx${[hs>$-ri+ln Tx{q{$Jy+ GFR"ThUTZQPZoG}v"ּm_kGeviDE'@QEQEQE 3_(?s+|I |eEG Q*(H/9Wbz#QA 5{?rχ-io#Hq}g_ ûQ?_br(y&tչ%kɚ|$/GkFb3O%C qFu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7ܤp6h",lT1ܣ&?Rm__<}0.o亲vuygi=Fm`V2*$1Ogx']+jjz@,W6L )S).~ɬxRԼEj~1/\E4x 3GX]6艭OӒ,P%vYB>sxǟh<+>ƞ Oo"OʶEUٸygSfsŗZOmZxk+msoe \%D.x2(#lٸ?7-ؗ գ@Q@Q@Q@Q@Q@Q@Q@ 6:tj Y1$$ɩ1,_M%}l/&E>? IE."[ϭQ@ bh_c4P/X1,_M%}l/&E>? IE."[ϭQ@ bh_c4P/X1,_M%}l/&E>? IE."[ϭQ@ bh_c4P/X1,_M%X%WK{4t!0TiQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@9OΏௌmM[OӜNh3WC3_)Q+x G~SZY>.=?[~@Gþ=rNw Cs{#) :o ݠO?_? uW{8?7'_|a^=࿋a]🅬?߈m?HqnTY5>c@ִV𞉤jKioMCͣhxݳpPpA8#5l^#F#⧅.a7 .jK<'UX"-c(TB6`8~||]ÿ h:\i+J!q#_Kr>DWg~)x #{7^-4=7C03JAGWBâ>%,I⟇:t> W5g{[ cBl.A7E_ >wM^:/D.mWU^ ND%%"XW hЪܩkOźg~x៏i1xO -yeHہ WrAMh Z~̚FjZMV𕵀yQ1$(J&Xg?`Ow>^XksIZ^'WO WTYҢ:h 0|I՞mF'y+&eek֯mzxCö/?GžKsZi^{}=8}I %y.x ?|Y iUu\6jo`ũ9_6ܟ_IKՊc^"'x_wu-|5z d$2dR) &Cd;,<૟6hZ_,K@1K 6bTPS /O)4/M>HR{Jڽ\OO;0_.kU؏H5ڣO[^Ҽ/vW6P.7ofcXQcEwGh]oڸO |/,'ٔ?NCo$P#]2igsAP*_Oo Ǟ3<+oLiQjs^Lmla/XW^;&YxKmѺ7 CmTcɦK$bFVTvr %OɤҽM8%{e$ylޭ^׽b ?x'⟋!uy}}}D[ WDRm=/΢*pS#'ֿ |o{ZΡ}7ҵk;*yHX+2/x F_?txjI;QѬn$o.+kY{73lL]`VHC $FzRqe^Vq5iZ;kn޽wQE%Q@Q@Q@ekɚ|[/XFm3O%C5hEPE|_ms߅/?|)OQ)e[mM}-\=p!ȣa-oύ1z4ףfKmj&) K6w'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\mMs_PWVE3Gn"D̪킱`8=(N(/*Y-=[~@GoxoǞ?Nw`=܈z{A-~G|.3X ӝfsu:jq!GG?q;!?_пX+~׭mO>&/0أL'z?Z5ɚ|$/Gk>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I4^_jDZHYbB$q0\KX)0ZKƟnGu㏉ix<_YKA2\4j.D֓4<]ջ$wJI/OouK?}}FB ڒZ[\[\Y!G${~9i|ƚeZpЗH.o 6&$u%Nj66g^.Yڷ.^(PoVyY ʩjT|7a;Wo^=)u}9K׀O {QyA Fѳg3M=x>GԼ5esf]]nKFHEyF/ 8WW:m{>w#RU6 g(5&Y:A.|czGpCg\\I%-Bh;WIp c/4 ;IѼQ/,f9 Yc,;Xdv5a'x_--u]gXߵV5Ε&F$B\JtZ;m{Ϛym}uw!ߚk[i=ӶKETy&ioĽcHf>-ؗ գ@Q@_Ɵٷ#XE}eJCbxtpG)'xO1{\^hX ^UՕһ)Er5k$.އ-y;ZUǃ->$wT %3^!BJc($,Knɬm'ISxI^ t4NYyX,f%eѷ=nn%}kO}e/ơsG%g NZO <+giiB]"L.kG_V֦xF oi?I >"S\OxK״xg)xMJ;94et'dRo/js7wsu{>OA#$* ..dJ$A#8 )s7GחNo+DuUj]GWrI3Yu}CfoxkL5uK'S,u;BAv ʏdgtB[शxG6>2>mX{D_[Gl䵺E)(HŃo:7I M~7=7@Ok \پ#}OPԚg{ dO )bWq'Zc/C^"4VMSS5s4SۭۤLD83MÛDۿ{Y:tI7wDgU?{kymz{MG|㖷Ocׅ|5jmQQcK7K8ԱP_;A o~~Ϳ < kSxXָ̺]QM..KbYde7IF#?ljW~']cBo(!WAl]i4˷qpq! ve{Go .5LJ vlu@X4h[ LAs8.y9?.i5fk7-+w{˕F w??}O[Ya5 ;F!s+Z섐_/o^[o?h6_bk3j[#5ŔJUi#W,,aFuA60ԮexZK{tA7;+Jozui| ǡwAy XPboux6mQaߗM?{*wz[Zi4dڣߴ='H׼oz._{u?6=" PжcLF׏~_ ~3/~"|CXieH-M8>)fefsI9'kj76hgm\6[y_kP+22>-ؗ գY߶ſ!h(((l]aE幑󅀵i<ن-/= >$]_w/ ƐiԒ, |w6o캆oI Y!x[k}CHFF/zZir%2E8¦3i>d~w:mv4z6M5~kY[w[+6T)/x[ﴍ\"ӎZjx)' meބ5fP-[Wšǫ;m3ķ\Ϧc+hެ݋X~m0x У׼e&-ͳ\u5*yI;.0S-7;sְts7)ȒmG I4Ku$_-W&3u7&>/kI=9/ײ|o_WoѴi<#?WNJuO>ҽ宩-[#].ҁCnxSվ-־ އ_a{QN]3IJX 0pf~e޻Mm|6L |Qc tq%˓KXLvVV YTV2a7>~ZWόw-|mCNjQh>:6$ .]w"/H!Z]|tw{Y-ow}9#G㟈~.xݏuy4 G"[{xyyY OcLտ_Pm_lj]{ Wо/xÞk%6GI:6^Ia K =mwĖ^[ K`ZƷN" 1{cFŘʺ'MZ-zt&ZRwkp+Š((((~,| 9]xP/5/: i:;FYķqff FHsח8'[zo_xs蚍Q?cd$I42n4e0o$~#Kk]M/|=񎹩3Tjװ]MZE yJf(kN +<]GºNYi>ZjYA5}ĈB*@^oG~΋B\xWv[ .\ٲb$E'~~ﱭ)Essuqiw^U-ׅ<#}O6uVWENV[LG% veޣ"LJzc_>|YԧV|QoC5mllڀb5B@$7lUd!x~#D|=nKYd]6іFM?;?`#z?mx314j4X#_IĮ%8F/a|[k%Ե-?U9z]B2:iOO.y MpiZZZ$V盦?g<ܥk<[v gCV~M[]iA.t:Y[M+Y6M3HaRir寖~ 7xom 1j-k4$VF;[(agY;@Z?|Cɪ~/dO:3#5A462HDnћev-7[+ulJ-I=jz/푢hF% BM!vn| ̋uMw~j/U ዟ|-g~|SJ 0ԚTBu& d,qm.w'kxPik+1譩I"lZܘ|<]BQKx_BјK?wĆX^DWcݸ[Jז;U}v'oZs_tv?6ݪžֵvM3W:Eۈmfs6ǖ]Knd Z}{Z}֝w\[G<7MOf젘u'i( 3<7~;|Huk-zOэƝSYvvYC ԓdm\#2^.<5m7Nu v;yu.T)QqDqdL/f[[MkV絟oQE1Q@Q@Q@Q@Q@Q@Q@Q@&x@W0ʊ|XWOxgǞO⿡\/|MbD :G<3#J'?q^_Sg GggGnd>QXZ:~;t/!?_՞a?C ?>ؗ 5Y߱GO!쎧M/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=zz./z_"O_%ukxN?onMG iځ`f"̖UC2k 񦧮x[Xwnn xZ]h`Pɭ/.!HhWa+Wiiv{<ͫ4\2 #N$~ ;t|\sx7^\hIEsiamsnܢ(,fY#b ռ4+kx/)4^kYo.YrKZjmZi+dqoþ.~]gSRm6MdiPX_jV6wv%YSmhRHϘ+Gk|+9x_C-/7NY힫w$s6:\#F);>nx!=Ow/އ.nkIN , lu >]ļY2s~/!Yn|_jӭ4>}Rm=KZjvȶypj&7b$2mUES{忔_7'oDqy\;;Iko <W>/ŽiwhxTkK&# vwLE`1H129&FFoXh'eTaח|!|; |KxTubkOkO~>l%0ikqF1_~i~[ZL׷:Wt][WxV$i r *3҈׼זܜWr;htQEAG~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ\闳[\Ö6K(:`[  w/ *:+/X??w/ *:+/X??w/ *:+/X??w/ *:+/X??Km#\[2Vw者,BBgH ( ( ( (>BO''4J|ࣳ~<5s]_` ,O0_/v(gǓ|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSwIQMp/x)і94.~3?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^>xg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{_( 4ߏh 5/j>Qi%]v~Zq$dv# d>yw'ZݕKdvKgo/iMex >(GWڠbl#5{&@PIFdL:V; xO$~$xז~).⏝LK=RSqc4 KD){4e#On+(۳mɵtkuӽI'u{}z-4y(Ҧ{IkxQ.Xˈ)SPI}}k$i{]\u˫M_iSNXKiRxowů_g=tNyqdEľ}ZqODp9 x \mJu'tVk> '|WȰ\%Qؼ^gmq4|+⟀g՚=z_/mCI-[뵊{6D-q_G24-,^SnC\܍,% f4-mx ?'? E\_]=#l-c2fVg8$}so>/e (,((/_LzZ5kɚ|[/XF ( ( (>p?gcWOԯ(ZO$P(D''ڽqVQox]Ik \"Uˎ4Ts$ n+7Tk˙.#ybB7s]Ifv\~u % "@ Ie_g |n6*|=VM"5귺sŧ]^<<:ŲJJ&&K6zi?m躇4y<_ogS뺜0]Ȑ7I&ۈd0qP^_ ?a'ռ#oY{ Vlr<7h𗉟N& ;߶,Vjj!"7i2>]%noPM^xUo^_,Q` T2JMUGWik_'u}MjeQ)+Vz禮Ӷ|uC'_ uxNu֯xWzb/|pigE ~ z'>ϊdA6gkVPE4B4k uS!:e1$6%v wo_zt:vg? ﳻK΢YQ"ycj>}o'~< eFm]sOݽ.[QE(((((+~|R>-SntOx!I^u:Ȇ„]b2ğr(bk=XQ喓M[iݥ߹(ITT$ZO{6ӷ]U)__u[3S K4k Sni⟈6vz4<`qǔT]~%xB|o \j,0}&̍G &_M $5]`uGm84MRN'Kt eCN?g<\5Y-k}R[7Gu=ΏZI$ff$2kWyu[Z<ɾsM8)so\.F('o~7=nzi'(F%[JY"QJ8e8no۷~ ׋l 1[j6s(@B̠2(oc7|=Ǫhv*m:Lj-hxc.KU`! QT(?t/jzeuUէAer.ഹk=PN7ƈYД(=m&ֶn8>WgfqouenMe' :O ?rxNůRѦIbk::K9UY5]qqOGїI1 U0ZJC#&YE,F)c']}sƷ%\2jzާ-y=Yu$M"imV'abAb+k;'PLόN{-9''O,ńdePmmkSSܞ妏cּ7>uuK ZH- M"ѡ`*T7AOXv_Km@=׷Ay9yI$j\ (Gƾ _Ka{,2/5eg5ZM1w *Co34qISg}NxῈ>ӵxoYִl`Of&Mk-D[_/('tƥ|C&-FMӵ>EypCpG-!2O4K&?&x6/|Wl5`m?Nu{k( vZ(N@{+JﴒRkwgZ'iY}Wi٭6}~^OmISMsKj?ceNukkk!*AY| 8M 5^k4$EF9)rGWeS?&iŏoLX* 4/;D?j%?~HګXn2Pd{es~+ss |OppO4_~ؿh7MUe*Ysc6N03_n ~Ѵ/<)}[{ߦ<D+֫ ~/7QIƻ!T>QXZ:~;/!?_՞a?C/b _? ~-gNTGniEno渐 pePa7!X~7zM#V]CK}FmmFv0 yٜgB4TǏ<-&sɸ@ItSRY:kBFcy+>xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mWď_+~7P&km6?-w1yrI* |tyJLᯉ Wž ]Mv2ų5:eBp“5 Bd >П`}3^"4o|@'z4׍.$wW0rC'sEa37|WxO;V'uN{9,$n&!Xⶍ# ı*׻*b rJi;2k=>[ud|CbkV.㏈6m/Q?6/J-ṲZoUWtL1rI^eՐ_u\:O<o}{ןײa4vn͆`.&R|{Ѿj)ORn#8{/[LRiEѷA˿&Ů?,?!BMcM "=1tF"K7vkbHz)%9>/Ϧ+YvnkߥM,5gVi~OCJ=׊k]5t YIy?zIIo҈T]x"R_𯏼#ll|[X'Xѽ eu,fKtIRʡ)/?\Q/:ƚZqOV/c[<awԊʼC[ Vjֿ|]?z/4 dдT. i Nm/$B'8i|&ۭ-4.K[[_{gWPqs+KW >y}ّ5#fڝ+"< -_kxZ ]Zj{y[bXF"e>w23u(>;t xIN㏈~?ny^ 70EAg"Z[vk+I.$WgV MaK$Ӭkֶ'6A00P.坵|Է^^_$nKFKߥ䭧]u袊Ȱ(((̿m3O%C5hw&ioĽcHf(((((((((((((((((((((mm/BF:$զiO>UEf;T$qQ1 5YP$}}Cƨ~g@\ UEhAq?W?jO]Լ[5 > MŏdMĞXHU<D++;_ΧsR'?q^_Sgq? uW~t|.w_CE6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}8Gh hl`rAM? |GxWOw5k)ΪĖV7K+f8UI_kSxK_|Cw ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{? muW.d夒TBBR +Jױ4(BJ~kFW_=wz{]OC^-5=u7+/&E,.ZFC*^$0m%m]7x{ ©imczGuJZ+;u;k5MBAs-ҋ]$q;K1uC ?i_!6s!ZMaYdeeIDb"J8mVk+_]A_ Yjzb_ꉧ<"H$}\ sMWG#|"K"IeF sl,&)?g]O>a{|S[)̓ Xݸu* i2$JחK xͭ㿈T&&qͦ4b֦ʳ؅U7 jyV^^ѺVTӴd$h-]k8 7 xÚ&suZFO]ݠ7t3D z+o*N{ ŰSj)մ=&tޜw~e3gpشm$DA!ö~/hxO-ؗ գY߶ſ!h((hv^&o4JQӵ^% Jn AJMA_Ro*xs௃u鍤h~=hS p1#&]#G-L{^5h4it _<9#xяi!M.X_Yߕg/w^mw>c>1x-xO躏5φt.8߻O 26{Hem17'o ?$h▛ BT^kzZkc>! 8#H+ JrNIikߺzy[ɽvɡCxkY𦭤կ;O _]XE Q' \)y|}5d`ddvi w4o ]Ri/K_k\$M ԭ,-/i|ђQg$ve$?gOV:hW#ִɼ/cSz\V, pC]YBR{9wMeM{U(:8mI.mݣJ+1߂=/ j>%Z]xb=6_\]xJo2\, FJr >* 3|B𦑠'?|WKI->EKmoQ G`Ħ@*Nu!K4(ݛQmhҶv8b s^jQ}UW?Jhfů^%_S;Šyo5v MJQ}26}6d" 0 #Qm%u~gT]hQE_QW2C7bF208 oi7h>_xW]k\Vy۲]W%٬IB8C'Z&]i7n~-%$?Qt?_"x(/Nyfksሠƫ^|>&V֭<>5V!Vu@⾥V<9o>7咳,~E??̿E}OEHϖ??̿E?Qt?_">X2~E% kwZFjEmcmrI,(ffb@$+ɾ~?~5 _ž$ϱ:/t.6bƎh8Tbx[㟅>=׺u?Om9$pM̠ $ឲg9iF_F UUQ誠 ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?QxSAtW~Tm*NZT{A ["'ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F<GKU,۟ ҴQSz}w,7ڊ@mcԤ/ξ6| j>!K-% 4huK.`ɓxB8~x&q_jm,6Kra e|ow3q [I>㟈-^.\zEɴi!Yn1r+iIۣr׻vVRn+FJ4۷y7G+w O^ "++mYMf*!2yӍSqOV| R"NsF-llUKH5 d-7clQA~|;~!M^JtkOXO_k:|nPIgy$z̭ ob=oB׌6\I> 1t nXJjJRm'7uI9Dj6VmJ[kDɻ.s?UNxGAOBFoA l",$X1x  / P~Լ;^iKg u-jgLxUn0aIV> 7<3}Ʃ[ x)ϩgc 76yVml`}E b ,O/H4 4|iOZzo/-.9 `t-`֐K$&5bJQզFmm5e(٫tK}ohf|a%|qu+ 𦃪jWmƧW jե(Kķ{!#JTOd{|)Q7ŋw\".xĺl6۽Z=76@!i"2yؿe-f8𵷃 ?I״Œ"E#,#@X4dp<z]kwZO/o/56ͣ6Mm4Ri,&+ =BgOḒ'V"i׫*ZE˧vi$Wj8PMRۦKw? >%OD ]_|wƒ]^;hv6b OeGk C4 HE&jv76ɨuCn@"b$jhhZ_4,ͯl|K [4ί=ݤ3-ݞ՝ށxXm/NO44ԼOu}ŻFJu ܒ) 7n%O}[kNnff徖BikO{Z'?X/"׾M<*B5#X_Y$wڤ_ڸ}Amb#F},M#5kvy2O$ȍrK E,lF~>?wrǚ+ YxO1kK;Ma["ޝAf g1:z;heyVCoyev17|(MVvVu4K[^t}~(QE_ſ!k;4b^3VQEQEQEf"5eJc]zC6\ı12;QWa/| SP_ X(^l)my^vWۻz/w9|{_YWv$FmæCH,`8 " `3Y:_g߁~ ikiYu`QB]feYasESmU7m]Igi|G_PxŰ]Z뚤~[j+aohY7Cv dxfh6ims")ɷvoFkCGxg ׃-#={Aqy1EgS(Wnb ??| 5>Myg5'FKF adESwm.%K~Zz)|-ŧwoz]; %+*7cj1Ge/e~D]ԡu'jfb2x%F+wPo篮5mߖ~? |;xRQr{ZE?RUu5ʹv,%,rkDXUT*`KE$Qmw_}EP (cz |@_,WYEjs&+9[enfh V>Eiv{ki4,ݰgffc31$M4F4k_L # xg_ i/?nMKz֧(I..5Id1"ĪW BKx#]yג&nvFcbkh!N Co?@xtow:Lj>7]6چW3PG6UFO@+3_#(o7\MŵYX:JelC)Aֽ< _ tI xoCՅh4UI6Uxݷ8z נ(((((((((((((/N?â|y9WU~8#_ίsR'?q^oz^?;m&~|.xC?F+wCaU1YfS=&30أL'z?Z5ɚ|$/Gk>(9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSwILmVV5,B!v I>dH_'3~'4{U˫-i$sĒ5F.J<ѫ켗s6޺|~+j'jx+B@Hw0IP zYw+O>>nC%tuJNnm:*#Ia3283,vӆ]_6/ ]8޴mR7>L#q ܌N@*r>&G6sW‡>u uw_~dr(Æ8 O ;߉:?| /LR^Z˦hA \+z!V8Rp:9]RCo|@=k@ Z/Tz/Yon`",(a|?o; |Fx_NҠ|=eEgtxmZ$xmee,o{ݺ^fzY;%ʮj)ufշwi, éx':TUvִk2E$ ͮ *iI}E^97>~QXf6z<#Lg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@6_U&؟akC><D+'I&L:-;QHgǟ( ӝzz?/;Q?zhc}W~n|+y,?H,j~/³b3O%C hwQ&iĽHa4Ch(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>kտ|M?â|y9WMVcbEg 9) es^/Ge؟ 苞Uc_ JQ8޲6z<"y+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h(((((((((((((((((((((((((((((([JL:-;?QHgǟ( ӝDڷ6G(3Oz~u(Lc&;{|N*7̯#0oB#qWemO8CPأL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((vO_tZvࣟϏ?Q( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((R~.JZE 7) er[V%֟bkB~<D+׭K9s|w3+?~'~o)T~º3 FQ8ʲ6z\#Lg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@,x"(3OL:-=Q( ӕ~|l.,>4GH>+\C(~3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1kɚ|[/XF⏂,Zg/ j^8wm2I74qOD셵VP\JdQE`it| wtѩ8;u,q>eW7jYA9@V7#>'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3%bcZD 5) er^)z3ܷFGg/Z/_ê83= TI B"ucYfS;E_QEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Q|c |Va+0xj'?q_V]Nװ\Kwlw C2Cv_ ?i[;/ڵˆo#P.mmJeJJPd TKQm]VIMkMB͓?Ə?oj Pφ q=|N*.{xg6#ڻqK<څݤ :H5o-&f)%^zߞ?oh͓?Ʊ<☼oM?WSQf[}FK;2>~cڶ}Kٲz'WKi? M_zn]" +׺X6 X6n@p$InvٲzG|U|0^-{PӴm^Uaj2HU3Tb@_ɑEhѱtQE~u~V!/5oGxD+w3JZ_Q ӕzcj߯|_U<??d|*>Q8~ǁ|"%}nOE#OS)c-?_QEyۅQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5_ \Vf׎'uǴ )mZg0(#qYD@f֫@|YYړþ&| jƺ9@lSl2EoFe4dI*4ş ZO-s 'jߐ]QfZuS&+ ݕi> 7ucw,0c1.@"/m_,5|;𑍼Kw4ۥ˺Sp0dY]6 dyVZ4ş ZO-s 'm'WKUy-C4~%Y%mz׵^) gfhD \³I$gL/G[C{x:ƙ6hm2LX`H%q׌瞕%cUuojxB|QY{O"զs "97NXd`=hثwo/7|=4_z}ͷ]KH3g]B9-q3vVBˣ gfhD \³I㴚oga40ďof~\I6fܦjmWyhƘYN{7~myky=Յ1,Taogj2⾜D \³I@|YYډRNm^=McOާ?&e!WĦ\qMm~Gx]<;d1+4Qho/fe]x7Ncxkq;Hlhb]BvD,{y gfhD \³I㵴gʤiRS??d?lt@|YYio^#MZx_LV \u9I%Q@~^%]T'Lj¾?9i%Q%o&XG /F#?+Ɖfx3 ckZe~Mض-V8WY㑕X3u&?m.aVV NQөU՞ڟ}Q__?o~fex_?zO>M?f$mo.C'o tgq}O?AϏXW - jV?AT:w5+]?f?eox[=uO?AϏXW - jV?AT:w5+]QxVGz?S~_ٷq__6뜏6Gz?W~Q_߷eW=eoo.??8ǿo?6I C/ tg/_O?G￉eW>=3lje_¿]??#S?+yy?g?7KgI,_¿]~G§WTgQG+]X_y>$mo.zk*_E~zͽI+ao tl2~[]~ [_E~|dmo.XW -S}z+ݼ5lje`-.߳V^D:w6r26G' -_?y?_?DOg/?ex[O__?x5 ;Gg,O_NqW?O?D(%mo.M睾&1ao tg/O?F,¿]7_g_?x?"6_ǟ{xZkxo_7K=?§W'eo_.6x/췏 S=}O?KhN-Ÿ]I+#?C[OUE~uY|Ap"? xVݏ x[=}O?BfOoOrO⿂j$xUٟ CZfʧ7// +F4|~֒|7Me|_SҚ+_?[{V?ّp@u~E C uǍ?g'eq tfG~§W׌|D{k&dq?.T:w& <')ƿZ<'Oj_E~\kG?kWƿ;ZDŽW?W~_ZDŽrv9 t?cS?*+|m7e_]/&?cq?.\j_E~`k3?gG~ c]qO=㒆#L~F¾#~^# ^|CF\Ÿ)bbƝ:Q3c _cgMӍG)hNNUnit-2.6.0.12051/doc/img/bulletOff.gif0000664000175000017500000000011111713252032017076 0ustar jtaylorjtaylorGIF89a95[!,8+!]WV;NUnit-2.6.0.12051/doc/img/xmlView.jpg0000664000175000017500000055106611713252032016646 0ustar jtaylorjtaylorJFIF``C      C  b" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?F|5ᎁS⮃x^8]sNP4m:LifxiQY&tFTUZ9b6ğX9-k~,Z/|]=-R=B+D=~2LVeuu{W1k^Zܹ7688oxOx_Y隳YEz|AeVI>ǚ\&Psp[ۡןp/+T6擻ݵk> %~ | Hza/|œ.?A#TڕŚTV.=M{yΌq@IXUuC\LmoZmᶅkK;Y` /&[1)Bu&,l۶|koѣx Rsw̒pi4^7ͻ> @a!?~ go(_'xSMm+F&{si+{im-j$GʁXw߲O~-5_ xRhzmV 0D7eO04 Uz(E%Rv馞VQRu|Oy^N=^_؋r؁50_ 31`?ѿ#g}O~БğǷ_~4GC^@C[YCYR_̌=P/~|a}++"m"%b٨IB(I%1-ôRcC%֟*m-R{tw􌞗2،&WIm>W{^e{|% c ~ğ @~ |w_xľ&@OsTM,]Yⶎ n\ZJ'0MXe9go 'U'w]]Xd$y4ƈm+ uod}MRMԒ[}Kc!HS'r@\~_ r4FOs7- V֗_KuĥmagqO&g33\4Di DDQw]7x_(/:D H%eY>RJ 4K~3dygD:Hq^\[._m6ة`J&ԣ&޲Mtd=?br~ | hTD#3`cڸۚ)h?~x{ӵ4mX>$BݖKf FJk1Fm/ ~ߚxƕo(Op3–wsy4[@od' [˲ȓ"lݭ}/nK UVm{IX-ڛR ~ F_S| dFj~z20|>5kk`ڞ{ 6b')*̗ $ ̬W5;w(Q]N_e~ROўN>x;ՒϯC/g@;cԖ_[7/#Wj։TR!b@ -?_r>jsZ{YOa?g?g߃ooFO|әsMkߚai*,??9w>v?g ~G74ҩai"q3yXc7/#TO<|/H_?A}5u <_r!? YN3+"Oكy7"W^N#RxuG G܋s3͓`Y#? > "Uw߃LSw ӵTa"qOCG ZZFJ05uApԹ]Z֟/7t__eHsC&f8}%Sf?dQ|;5:dd°6B ݼb'ż?Y೑u 82L<TI/#??ƈ?O_FO٧p?`ջqldPG~-|kq4'fI~${5 Yo}5j'-W~pݐBO13|(gtFjҿeO3-o'h51jOJʦHq32M>~ |WŘE€hW2O^6sY^򯸺y:֟߁#r'?hQG1dDZ.t1O1U_ڸ_3uex>+ ;JSe__B:;:P +ε/K;0S^F; '/qGs?{QV_ nr?.S+J8>6%P_o\*F+[-5Ճ>QI[՜SJ~ ;A(-?N?E4iV?-GZ諅+WiΦT{9~|SaX߼>8ufLuY*T䖭>_|A#~j Gk $U#O{ >#| >0?HE*_|yAuKmZ4a! w7C풳M:3x:ϨĐ\+b%4v N , N`Ɲ۾ס -JR\nֲ7~W>7Ěދu(|=1k0=𕭶bW+u%lM);.:ÿ^#,u(> B;oHSkys~=-bw[['u.B'.,';(̑Uͺcww~!iy,m"(ֱL+3PnJtϖiF7'O߷37ouH<%x'XRAkѮr|?J kl eyL71jRIuƧ|#ڴ[8C@+tסٌXJjsV)e9W0ܪ\{]ג_u?$ψ| u/Cl7Vm{`iD>F(sMidB_~Wφk\'?do Zvt> ?'WKD{o$!q,#-=Fk?  BGN>Zۢt Y cxpT|Izn5{=W]O,6#,sFVm^-fTv8πց ^VJ\Ol)/MIҢs^{_o^.//'wtICAqYX`J Ĉ@ LJkP}JŸ$xܭoQԕZ)I$Il>L0W~V~(N-cP=;#/W1xJ?,HmSe_ú?y5|BxnZ#kioNX+skim큖. \8/Zj3o_q_XOď-kTp2jM?4{RZ6uYM۵m{#o7iZMΩDF͇a1\@l-vG2-c F`!O+^ ӵz{o_Ǫh&٬,nxa[eHbܲM"ELijOāoFگ+-kX*N||'DsC y#ENkE(tٻᦹ]:RN-_TXdRpP(U $VO#_xr? ìhs]jZj,a!Z0"’#4U[?ZY-|o1a։*䵷_iʒ̜GIoi?TOgEI¯iZt]GkKϨNrqߔsQ0 $}[߲ψzbk GwkCMJ䳞a$A⅔H CϻMO?A-i>@? "oگ|zJuiYkR9ӢVK]ϮOfό>>|C-SŸ1MtZF8Tm}~֖5̩ѓh=ld/moG/+>F;*n|E{jZY8yBj#Q)!~_crBj8-j 7oh:2|)χObiMtpM i֏R8mhG y͟,-]<p?mB|~|A-h:<|K3R@ *GrF@L)&Zd!]<=zi;$Bb׷uc<,]DCҺ㡀>BXY ? !鯇m]Yd'uɍ1ӦM*sa@~? >!o֪j|spG?ca|H1 rkiAbHৎ/8x@,mZh῝ l?3<,˹952>|C'mC0З fs3iS$xHs] Y j6\ xf~|C]_^9 a cx,vOsn%:€EUMXuI> ~! oګ|O?믇mGװ9/]  yO .>|@m~ AkM|?jKd[|K2mUMҕ&vM֏ia -~x9K鷇mRoF׭_3.;@<j+D #]0>|CON !{$oO ֋gxE |! 7-a?|Cc*voQm.3e G[^U/ZMD zpA?7e' "ڧ[@ψZqϏW>t5 c_qR5.뭋><W-xO?S@O_׾fxy_s_>U||E'[ח,'_{>i1ڤr~/{Hn9%/k[@O/_[ӓDC'|9zK ɖhی^e/<2?#XX w?~ {V.cu6=ZФ{rE|C"  Zi>F|I}xwkþ!}pfjZnBZx.ThZ\ ;ᢓ>{>smLm>-~Go"9|{?QC;(D~=F(QKso$?êy1W5ɿU_v_xQ^= 73AX~|caӢtqnoon/o 840qL+׿k+||w߅_%kC5N KHcxfVtḅa#DJnஷoM3*luryx :ťy,lmme_*A/XxƏGI |Ikwš?>}V/EQEөPEPOO)((((O)Ÿ@Q@9:iրEPEPӥ-"t(((uEQENZuQELJZ( ( ( (u#_?pQE|pQ|/?/)Go?_QC;*p?\gu~yL‹V: )|@<1f|A+>Au*48 "cXьKOO7NBs|[n?xwGuSZ7= çJ5 =Đ]Kv鑦HT7ŠyBAg%dH_ߚk>]zѸz# +^_ I:ϊ:3Wj?si #W^?կ~,MmT_ܖoK6@5_~|]GoewuSj2x^Kk)cFh*wsދ&7Mx&Y׊oŠxgZkj e Ke׭4``ZKwiU#(K{;(;}.m3>:3Wj?si #WWi6wlmm_^(5M2)@1)A77S}{G/=뻿 Yz~uE5tonB$x,:<*XYދgɻiu\ZuTK⮾N=|q }:0X\XZJRX`A|/%Kg0MH,?QU2ߥhO~Z(3 /ڣjsQ{4}?~@>CO[Ȁj{4}/~Q@CGbj{4}/~Q@CGbj2}h /͢4CJ (WJ(?ʢ5h҃(]58Otj[Ot=o=?GMc@ږ4j[Ot=o=?GMc@ږ4U:k׷ ?:±( {^z+MbdOS:°h ojz+ڶ rkvs/:¹(ܵ ?-:¹(ܵ ?-:¹(ܵ ?-:¹(ܵ ?-:¹(Gw?-ȍ/huc]~.|Wawe#縝_QH{F(RI'!ӝDsܛrO1bĒ>./%'8tZu',m1o{}[@˫9|{O|b{+ CFӐ]&o,L{yq(}bMb OP>)ywu#>/:M/nvo/mm$k 9dGq ^@q)ȷ:}8"RMQ.XmxKmOt ZҾ"ҠLy$tLW9't_^[[[ ? ?^[[[ ? Qu5_E艋i+OI~K^ƿc?Rk۟x/Oyk/Zkk9Ɩll-XЖg/dïg/<'_]uk[5h͡/;{y簛-rop_^[[[ ? ?^[[[ ? K{[E˫d%Ǔɯw>%Pl{LVyg3~/3{cо=Z7GoGԾ \Z^.lsb Io6q!sHBE>gO+ |E-SyWiZ<[ˋ[EEDxneWW 2:~zKkOIhyfwڦswĒo5;5Lɭ=]=E>89ww6~0楼6ϊGH#FA#~_*!;>GWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|N*WF?|U¯EWoD~j>_*![.}E|ۨn)j|,nnëًLCI| ab)9=/-nݭԚVF?_fwT<-7.,ӵK[).-u SdF01eC NuM8-춦"-5DclYX ]vc"~|uy?o.DKz͟RTXb(ɤA:,eAw^).}MN[kjhW׬q> 3;ngbpOw{!TZ߅._i{kG:5/xcDVkau}joV)dv(`۾ߣ ߌh u-7N^?dApS\7>kdeoZC'5(}̊ױw-FXVsiaܾXkFYm5~ćWtim>+[o&it?OâK(|{HmGeH.($M~omr׿o^׾_Q>F(E~>G(FREd.QS.]^e/[X?F6Gػw5ĬZoC6>qww<6M3QvcP$5mM_S~ثHEᧅO7G4Kcҷ#I3̱mJX)+_|rDžx\kMszẢ]k4r {vͭws>Bᯉ'?+Zx.M,nZ[_5Ŷow3]/ɴ9u;nͨZ^kwwY<%h1)5υu?"Iex]m/DP"FD0d|"L.]4+_f]vỲiNmqⷀt{ *+<-(I$K4rȭ=oI,>!QGl|]~%I4%ͦXEL?o3<1ȳ$ S߰ x0?oWV_ں3"Hom -$a_S׃|'? x_,|P_OXxM"XOk(hPVV$3uy[7ݲE*vS;uN6VצセW)۞]?SQk?l!Ҽ_Hf4D-ӵ 2쾆H۽]o_?i4KO\I/&5)$[ vv,|{ ?M{O~?&cw];Þ:$z5$B&1,ɱ!ie{MɼޓwH~xFŻbfCT:.]"ͷvTxJ12۾뫲dVmͯ~/OW}mbC?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]imkwO=|MKQi_[i_,2:K2PJ-Z0@z_~P5ߊm~"LCS|څ v[wpA #]bV?؋YAS/].6~K QaHW&"T*7)Z]}׷ٳ]s;/+/׻y&{k 꺶Roog=Q8p!++(BI"I9_ً qG<"IZք[pNJ}x_KIxym3X(4p$HF <Q#9f>Eak;أ,v90_,5`#E,6no]Z[EIZ\oM몳VK+__x7]} QWtӠ$ Jncر ɾEfC8ÏUϊ:? //cB I$U9f E#⯈|N>+zk6]>aYwZP\'U&U& X1fQԞ/O^6o-km][_v.Gj_~*Mu ~>+=b%x&F"Ph(t5ОGS/^񏅴~]GwW:==ĚMDIoFQ;T>~ڏ.:|]!Xtn+j 2EH-t&AJˌ3GcOWm̟koA4B-h//U@wb۵~*k%ZI7ky%R/.#'>FKgo', 7Rt#֯~͟5 W73IH;[Knmi,M븥[T>̆X]U6`@ued{*I5}$YuRm8ߵu|m#٧x[9|'x.е q\ii+cyI p\JO,oǂkx+ֱ$?ỻ%k/ooĩ&$5iQx`X;tdcfoSMx{_ S[麕|n^ qK,)R-хPME?~?~>7 &4Ao4">b^PuTyؔCJ5KiFK:Ai-We]Ӿa_1| ;I6aDPj?bG:y6:OL.; 2s·0/|[>˧xsW'DF$De ce 4F&lE^vz+~/Gk;dRk{[Ѳ{"7tow6WWLd䰹;! 3+~پ%%|Gw麆ӃKjѰe%e`%u _'%~,x[0^Y'Rм;ssO%4L%4\FdWIx'5? Mׇ5+fr_Ks1wr Gĭ&:nm?D[kZ6Zֽ՚5f[wiGy+~aZXţ'1qݽ&WT;4z"?X$Ȟ}đh7ImIE܁.2c|{ |4o.'+\/#  [#A4.n!{_^' ~,> ܎/.u M16޷);onV{|YB. |3xke5+]:/R$/?~>&cwu^ _Bg=.4.57қ,zeª2oY/;RWnxo[y5ŜqY)+4R0sE'YC2!:lRutekAp\VTT`śuO߰~㋿|c7V('[ڲC @ ]" F%$yRb 8EoʮY_o4엺=][#?^ i%|5;t{m#Yӭ{5$.wYі"+G|/>2x{>j~$vb w_&ﵻ_6kc}z]'ygCws<XSiB01ޯͧn+ul 6z/+s ?3|Pxj+jrޛ "C@/.P3D&5Ӿ ^8Sh?.oE=H]A0H`Фr@1?[S!P5O%r$Q5m:(D:7o'+_|^{eFCΒt}>;~ZX,D\,K%kXEyDʮsrje.RSɻ.ז߫},!0m ~zS)m{AMp8:h#P/Blc)3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k>Z魣|a/4o2;GhvYbYΝaraK( }=}[ٿ54#䯧W w 4}'Vox~RK^ssDYse!fM%K`epPO )S؎GW_u|UGOKֲA孄JGd2E#oe?{}{JRRvt}wO 3h~r_W`o$ &|&nN׭ji$16n!KW~%mÚ>+觹-ovAcziF5[{ݽKK>z_ݵw|6ऺό~@1xiPYcTՖ&ymku#fu[V `$!2~U?OG a ͮhZ] 9)AjW6eK } ۽]_ |~?8AAtcercxIkcou3(b;O*)?6~ xXnHgo. \=O!YMY*B#yi_ǫZS4~9E~~,ςn,;mCCԴK6eR7(ĭr?'}Qi`Gٴ/mݓ 漻o|[׈44(5+g閳%$;L|t4 iB!h[lf37cx*goOvߝ߳J W3^N6VTe GGQýNM#S8 :QX8Ut՚;ĝc>xwvhӍRMO^GsbHLp[V|~~h];6vtI?Z53δbčZ2C˅+V_-?h [ծ7"M =: JIk6:eu;K+D7GI|ї]/٤g%VmY:>^ۺ^in*68 _kO Ks{k^<;z%{Xsvֺvn$X!>G|:?f. ľ2uɯ=Q8:(J!Q$$g R5o?FGa{;ܫ,V9ӿ0_,5edOEo~<-_\d,3NNiǴyFᣅ"G6 xmg~{[~zY[[UJnriu1|CGxWWkN z:yvC$B$^Z %e:5|j7&>.[ %_jVzV6 yfp??^+ &Z>sBxsWֱ9CIY&i2"w:'qx_ᎯVoY|k=Vkf٭nhYcy+m}Uj^hW߮5OEv #xVuIt; i׺Gg$$2hw!i ?q7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI=ޝᇽ^O}3G,O5-R)58R[ ~-R/wvàMut1ivI"al9,X '}Vܾ~?~]ַ^/?<-!s[H6wN 8b%2dL9`(u"<_VyO?r_j>+UV[_kfMgY+׺{ukʢo5TɎVxlaD{mSHa58Ug*ݎƬ2Q >u`mGLu"sB|54RH(!ӝR?HDMUi^a#]`Goƙ4XOFһb85߻(Wϭ*GQᵴi$p $G{h{x_?m>,7|1x᎙ ƫiŢшI܍&:%K=]I"N?6-jwz'u+}cÚlBFC#NA?|or-}"6kIA8$Kf;ge'ŋxjFmZlx-"7dH.F1P[}M'?wEia5j+5٭oN饥ş/Ч?G\&_ RӡU"B/ R _[#pg^ M)>|X&ļ]W5siZ[_Op&+$, "m%phl>(~1ItW|8[h#ӒcoΑ g:~*Vvš֍ux Zdgb$*rX"7[{ZR_g;6û|*n>wNAwIDZc.Q| >~ڗştkz߃ρ,XI^ ȸ.)<-xt'0~|Ug[RWtMfë=6.]* ⷀ*ʤ ,۪|5o_]tBG:ݗWNՒdZL1)#ʕ 78+~UvydԞu\%^Z[~X|C&oJi|-KM.=#X&~g/uxcgFH,?,⶚XcgH!($]Cd@Aa? kjznd?_hx QmfDxDPpq: FK>fhxB $`:VR7)8q/uk$ֺ'o/[^oٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhNg_/ohz׍-gC?$$VYJK.Ԗ%vS|(Gϊz x#Дk_kWGc`Ȩm Y+g_K8yᓤt٧.O pc<A8|QV\a,Ts|^ѿGmKt]W/?I~|]𽧉ᱻMK^-,-u&M˾P_gTXy#0!L/]/_|jou[{ GE2\HvEIA`Pz.tOX|OwOo4جGplӂhndiei>Z魣|a/4o2;GhvYbYΝaraK( v]e{%t ]m.wץ~w|/>2x{>j~$vb JbTtaTQ~߰=_ŷ2|g 4IM[EX"(8WUC%RE~z&QNZ{Unt/[X}"4o[i iRc7ÿx/ * ? j-My.lNKs !C$&_u=" ˝:k^(6ՙH ] )9՗ eH?<~M?i|X |>&m#t,0\%S$HʇPiKUvmv򽯻Kڴui-cĿ:&xzZ[iwy4w22PH-0@uXq|r_1jV7Z:4vJ{V=FGI%bD̓4n asw]k/GEYjv^[K2nHѢ >iu"e_0HSWm h#xDg>km E8=#XV+n}Ͼ߮[YnIummWO[w~A/شd&)%\ `2 Zm-!o;i5Q{e*80śB_l$cz#=~ | c?ߏDx%kLJ!tKG+O9Kyn&b5Aٵ3ŇwG;ytxj}̤lr̡R&WH߼˙_Eo}SVյvwF0؞0>|Bq Ek%ŕܶ;=M%bWQ3.okM_?vk_[[4m?Þ"fYA%TѮ#XD&g)>+>#F-P,*P^}.Gj79YX/gI%ܰF<9q cGUeݬwhAut^;؉$g0,HZ9+h:v{SG'W3owOkO+~~)(ajyl%0RLdy&%`LG|Y%uxK.kڐcQ%*|=׊m"|KCS|څ;\O-㻸 GD&>'o>(|H7~iϫt3׺ݐu4fMF~ɕB#JKmvk+ܩo'W3m/=oiYοSM ςk}$an7sl0Ϋ4%KE`UЮ~MtZC%ĀAkMwdZF E I0_' oR>ikz׆tKFԲ<-hBFz R5o?FGa{;ܫ,V9ӿ0_,5edJu֗T--UuJ=]_D|d4}'Iv,QxNv$z iګƟ?x^^FqMKe/]ת IʆO>(aexSxz3jڦ`5Չt+'XKr<2Ue.Fr.ju;])mx&%uM7>#৿>>*4뷰/(㲺aN,hMEw┖ /RCo$nC|饩)۩$!fvREcσ?<i0}/: )i2azZ^:4`X5 eIFɶI4q!fgFogXHԾ|oZ|N:iLIK ! K $??W,>(,-.nxb#;$WÒŘ) nx+◆G7 /nO]CHg;XKi^%,syD;k~;keH_[^ ?OQ?4niB3kBe}iڅ͙RB_Cl%vWE?g/=>:|Uo/ &C4-"A5י"y`Pƭ|\&ůXnIio. ܝ=O!YMY*CG?}ɼݟ㮧;|_uκ"]_Kl2@M" D$,JbTtaT__A )ڜ!}^>!ZI.y=|4C&?_=ˣwwzn,4d)@ΰ\lׂ?mO7o#NᴰWV#oYXkF$8aGn_?Ӭ5SN:Ưx~e{-MFk+ @bVVW]~*Vvš֍ux Zdgb$*rX#w>w_&ﵻ_6kc}z]'ygCws<XǬ\zt[nWio̿=>[^׷boڻZw0Z}e@KQx$^ IɌLm0@ua|g߉<1c<67ikZeiwJ o$f$1RI/'O>)/4g B6bSK o,(DB]0v*"M.tOX|OwOo4جGplӂhndiei W|[K{]GIGzz_{n~[_|;ޢ#JnLJ[^o\6q}hZ kn)X34~7~Ԛׁ$WIŜ u *X}>Fզ%{yhu#};!j_W┾Ѽ<yqYەeg:w冽,4R̃if ٴx&Ϊ~!GHˋĉZ@(P91qw}/ӶNֺWW /%g:{vk}mcG{ƍmX}^Ե 3OЮ<62xod)*ȂK_/ohz׍-gC?$$VYJK.Ԗ%v?:ڽƟ7-چxz+9n({.]R$P`IRy_K8yᓤt٧.O pc<A8|QV\a.j'˝_fyۛO?6N5HZ|3Ğ xԵ-2Piۉ% u{E73)$ /H^^7[ḭ5⇴I0rI$1;6fICx s|<'úyg=KfCs%4{H (OqwBԾMm)|yx=F*t# ; zYDh%)%},[d2RvE/]g!ti^- KCRlwv^\j|q䙟ˉ\(xmW<-I$/-,bFwo}oCז{ƏO[owAuij#DtX+il6C,BŪ^?~->% ׄq"Kx|aaIim*Kk}mwm]|$TIm/վ&Z$֭[*^xN4yMaM{R4?3B|ὐ\S" S|ixS~7ƾ?j~Ӵ–vz_:kIfD#ʑ$hU;o[OOmBH<mm vŋKW2O6?{5G;GrRbeTI$I%φ>+Yא}jUѯuٴ C2.#&.wJŵo!DRCo>߈Z{kx-I&WfkH!y"G6# Ci~(]T%mRR3wswm}q2*rcT@6"*~[G~j^K{>^i[Uun+^k:?ľ>{x_|d擦wqkCmqynWryXZeF 㧏|s OOOG]_:~ E:`1vf1\¿اMY:^_[Ѵ)/fׅME3yhp9Di.9]WRDC' 뭏heƾ> @l4A-ixvo^#ӭ{r~gc3+/=&?ֿo hUǥnFT%fx,. '?hڏYAwJ!\е&s,SN.lʗRg9+z/_n࿍5ַ Göt\ț~%f KMn9l({ kg5ﴏv#Ѵ "5H4B M,r3"Hom -$aM=tw;~']฾[ =t<׶jj:|fEX -$2|'? x_,|P_OXxM"XOk(hPVV$3u>~¯^GwO-G-*i{vs- ng ]f+HwtW]ҷ_w໿>Lo xR-GZu+K W*kHdhaT{9$)$O81_?hO@Ҵ_#q[9uoiZw4yҮnbQ3ޖyyl}{}/eʵ_{b_).@|=os~5-^.T~5e[{h]B٢bC .@=3 f)IF@R$~ ~Z':u}/YXj RE4'A򥌱Q7+Kiӣ{+%e+;em:^˻ִ`G-W2wk ~ `yQeS:6^[izŤMD2"(̮b672 \Bx'BӵX-4/_f6h ;];xI%Pm-#5{&miyiourO0S$RF `PI `pRZ]_˿K꯮ֱI~׮;h|7K:/j1- ͮ_Yii7sjo{5,LSK4 o+D<e[ Okk?ZB߼vkUpa6َHu^Gz@Aſk%ɥKN5C'Ks&eVrM?$kg kg5ﴏv#Ѵ "5H4B M,r$xoB׀|Yz#OҼ7?y) o Rh2gu^SMuk~K(tM/PJ#[,,[XA#?Ï8\\;ش ѺLDE_[K`D߻^ZҺv _5ew|]3>p<=I5?];y?d?v!݆ ?G_h|7_^ Ʊe1Mm4Wv{͌nIDZ" *c.]AysMq ݺZ)D+e' : m'V},w+6omb׺wWӧK%?h |cƺJ3om^KA4SR°c' ӾZOtMG$ρ&K]'P9ah-eId[<`뜰?g&4>,|]񿅾6oacu {k.gdR)IC_S k 2^6|E}8-RS^+rEaK3*Eʚ~{|6km.owem r,E7Cm?hxzO_< x/FMogg+Ɋ$K4rȭIYL׾#Z c*Pm4[S$-ЊF K$~M<a'8g<;;-,|ArkcYG4A<|Wz?3H.|^^hEthKdY.#X2+$sm-wM]nvE+ku%$vVӮ|V׼qTjO |5 x+xy5b[]=$Aj<opE>1??~~Եo\p '4[h/_*@߼y_>OWƻ.=ZTum[FWkFF8٤X(e@);r+z$ɥEn^iy[vmM([F|! /|t=CiYFjʒlh㷔B΍?CbMǶHӯ.%m,%մrHu[apV'щ-9dVWÏ8\\;ش ѺLDE_[K`ex[ $x{63 _]xE{"+0c2~l1J+z?׿}T___O_o~^& ,xNb^.KQ-U-W]H VhZ6Fj~*M5O xx"+};T[)nPh1@m$c O#u+#KTeݬw;uv].ZbH[K!HE ]sW? $P+Ht *XˌV~=z.Q+?]?o-.?eC NuM8-춦"-5DclYX ]vxc~gMOsrjwݯ[P@gkwwYCws<Hx/ _<{M<xz?iм;HZ,ٌ71m4{?m,%M}>3>~>?~>&cwu^ _Bg=.4.57қ,zeª2oYovRp|ѣ͢kkږiٚǕO %B5\}5w/aϊ*^.ͯWO{XmV]ֺT oUII YK?:ڽƟ7-چxz+9n({.]R$P`IRy]F hk~ow|Vt2fY/'{_/ohz׍-gC?$$VYJK.Ԗ%v|g߉<1c<67ikZeiwJ o$f$1RI'qx6'IOӼ]h[x<qd%f3L #2$[^\-I:iYEٳ,o& <᥯Z&5ZV_rZs ?W kn+M÷x!s 6vI N YB'>m+^%Ծ!]Yséhr^ kkVN<3q7ːV?zkh~)K̎w5VXVsiaܾXk#E,6_Mo+2֭MJxb\k` + Ivu}Z{&mu{&_>ݵҶٻj|,5|< xI"KFG[,5孺G{ƍmX}^Ե 3OЮ<62xod)*Ȃ? ax×|Po x*W^ƎV|-+M$ql??gkzܿ~*x7SjFi䲖D?VT('RTpqᳵni~]15>˽i]埳oWVuo~;}+Ě,O jim6Ya4ʑF^M!eFpH> +F/eq-#P,v5]jIO&IdX#"6S'x/ _<{M<xz?iм;HZ,ٌ718NߡU-87}ɤ,8O[/.;?ý/M5]=gUΜ[V- 1+++W:?kJwDGݏ\ߦmy [Bд(!SR['u~3]'Ļ ]NZkhWץ|Aogw<%h1wBԾMm)|yx=F*t# ; zYDh̛yֶR/;z]}ֽ{i_97=^S+?oYPPȫK}KPOKj:? GTӎ2^jb"QJ6k~x(/~'&}5 X4 +v[wp7w31tZ8Le5%-5ݭ_UzKgmZn||>_Kgn|A֥m5w-6"-好V$7X /"%D$B(,I5_ ay< ?h,H-&y{vs- ng ]{1xKO/OqX'X]h ПRxm|8Q7+]-M;ɽ+Oࠞ"F|t2>$1xA;X˛{)m"h EFP=rs_RNn=I")dN^]y' j'^x_ |1χ.:>nOӠ6ZGa ͬq4 ̲~ ~:ŷZum/XXjk RE4&ABWyqt-]m/NLx|>jpP+}7R-)e%1*E0 D1k?>:~<\%f)a,1I d BBʖ2F (.YoUf꬛VQM^.nדwKmWiuψ m!LČF:⤖A-% ۬mzgr|bE欺^j-Mu iƙ`]qG`ARo6߯. IZ6GִO~?Ԧk}*P[LH` Y Ш}¼w졤|~x; ωQyZ-m(m,Z;H!YZ$y|}z[wm$3;uET((((o_1b:my_1b:myn#Mg3W|ߍ Ǎ-Ы}&ڏCh~38 dX9ttP73iR\J#_xN4RJ7g~$xwU#[_? p>1{wj' o_G_@X.QƮ_1G֔QEygC6>qww<6M3QvcP$5W_*?m i{9qq રXj\Ԓ!_OQ?4niB3kBe}iڅ͙RB_Cl%vWE] M<ƾWv oڤvɭg9ͅ~6m~ @&a{];Þ:$z6a$B&)(T G17&n-sF[_W~Z5eo{IZD׻+ouoN}um?<~⛟Au[Myu .yio&dU 5,)ட8~7t=붗:{g BMGOȫ5Zxŏ IIK<н\ t{73 ĆpU :.X CzŲhťM4n{]>yED 򂲱!+inފC^V<w߉/ EZΥis{jMi 6jsg$E$]B?GVⷄn<[kg=M+No4UP&gU e_$I_m.oEiqaxa!Ն>7|X'/tCIvi{ˑ$D|cxnX~3Oޖ7^[gvA,"i DT>V؋YAS/].6~K QaHW&"T*7iu_-:twOed%gx쭧[׵wwr֟?,/E{ fN9mr7/bL4 <̪}_Ԧ+m>VIh{U$E0F]rFQ>}|@k_濶Яdҭ/58-Z v$Hѡl7* !XN KKyw}U)/5;zmϝf)vGEF??|K+-6->FmY-fuIf-h4X |9?iom{H[MwA^YJN :~sqf[1ޮO_>3OwQy4 id]nd0R[{Xb6m~ @&a{];Þ:$z6a$B&)(T G17&j˙_Eo}SVյvwF0؞0>|Bq Ek%ŕܶ;=M%bWQ3.࢚ď V:4}BRizWCy71>- R9]X Ÿx3⾣;b b©eDvss%E{t]1cq?uX~^_]{Z7A1iHs abt~k]z^svW\ᾋ欮Oky/.#'>FKgo', 7Rt#֧hڋ/U_ ks156麍yr9h8DQAaEV,eh/.t!xXkVe HEt,V\# VJϥwNEf-]Z^t>Yऺό~@1xiPYcTՖ&ymku#fu[V `$!2wKX/⎉CĞ$֩kz]G,2:Mžs 1 gsܰf'ŏ7f<=;-,nArmcYEiu"e_0HSU]V{/uM쭣߯n[s_f(moYIǁ4%ڿLR{u1Y$``fYi:?R"ȎQkZ?2 {_UJuhu<ï8_ϊ:_ .cB۬yiHs aff g_2 Ztk` ԯ.moZK_6]J8O-`]q`AI}uoOɻjQ%7oz$MHGcN"DW[cCխimyw5nTo6m XIJ>8Z*@kMBNRyZ퍎m<]N#MSi|" ~-;Nkm3RC\L04[_,F0Pjzki{^=oMe^WimfUkw?Tφ~;'񍠵iv^t)ob(h["i=?|@p~4Ѭ~%X]Z }*{d岺^<`HI`;yo a?',$szL|Gwϖ.Yl`K1HH"2' oY'⟆|Iϋ5 wwKh0^yh1 v%kXEyDm鶗Kn(mn.uߧ*K]\Y_RK|?m߉RM/IsiǤkD>n w2,ُ?j_CIOAoEo&]Kk#h-G ܛH?ggÏ?Bz$&Tk{y}-A{BET!  "BeI6h?!ex/x "5{0|( BYRQmMvYѣg|lZxxu݄ IN z. Z1%3 q?uX~^_]{Z7A1iHs ab 6ďx?aoq6Ex&,O \<#UIU^UewoG/+]iKoPO+Wŏi,Kѵ[q76E bI*+Fu?h[_oxZo\Yoj+q)j|,nnëًLCI| ab)u?Ou^gᔰiN!!aKbyqjײOǿEӺ%uwk'cuu?~icW%ϡɩkv mB 'ygq #]"VI?}?kcǩ`ڮ dΝm}ϻ|3y6\i4\68~|Dm~|dOxH_ɤٶy E$@myij1wm ɾ=MvCƾo9oI$^~ic7Xh({:&WT;4w4ᗉ_:|7#B-LMpyZEsonʐ]7#)^?~->% ׄq"Kx|aaIimJ[{R|׿ן|Vt;CmV}K'،^.T*wًgp_a@i_7?״ o3kc\_Z9%ۄ*vV3}M⟎-kh-huVw_{&c?f-/ҾoQ~%7c-h7xgP-rJT픬gW?߇;[\vC{Eg 4jjzbC}ioIb\_d-KѾ0R7#4k;rZN0ù|ץFYm9 ay< ?h,H-&y{vs- ng ]ZKףF5yrV-׵;POKj:? GTӎ2^jb"QJ6kc }/)ZבhP؋}ﵴ}Z/i>]o{\[ȴIn'!2I#Kz9|A_} ܺtKCh4ss.&TYB4C⼻/KM%Si_粵otn[9|N⯃|oxGXOO\i7ZqmyI.ʆ5lJ?g/=>:|Uo/ &C4-"A5י"y`Pƭ|YbgMOswۭxDYe,55)"_D HXyRb'؋YAS/].6~K QaHW&"T*7mO}Y[﷗M4foSMx{_ S[麕|n^ qK,)R-хPM}E88 S8Cwf~}>EKZI.yM|M>"t+շí02h[Y gH.nSִO~?Ԧk}*P[LH` Y Ш{?>y.jZSlu]BfiE1X$qqQ%PVWCH7Ow gwA;x+ԵZPYvBH.z{|MhkIzmwWo>SԨB(((((((6%.jSל|o_lG%.jSל|o_lr?~6Q=ylH%Z=׮>u`mGLu_%֟h5? |K3/ 5) er('O;ݿ b:Gػw5|Q!__AX.Qƭ \V MPٙT˔D0K{8j=g ޗ (_msBԚY̱O ;P*]HKm辋~ɺ'7_Zߊ1_!|As"mTң1.Y53y&ͯ,>/|[>˧xsW'DF$De ce 4F&mŮhkkFi+Hem~3Ǐ_>`'(IhF0P^Ui^g|^Njq%Fke>4]I n SH ZsjzZQ峵*Y*u}k!ऺό~@1xiPYcTՖ&ymku#fu[V `$!27Gڿt}Αqs.qM":yr$<&m#t,0\%S$Hʇ1k?>:~<\%f)a,1I d BBʖ2F ܭ.zN쬕"$}z.W{ZG{y_w{ymI4V6xʤ2F .H2GϿw/?s '= Nb@м[w}V*/mKt$A'ZU5[A|X&ļ]W5siZ[_Op&+$, "m'Yg3^Yj^ZxOޗRy5 bK[=Aok*Rnmu bGTeݬw[utY/<63I~al9,XzF_ Nws֭Ikf ZY3,8˸8);Zz.7mV>d]-oD֩i9~6i~$ x^ -CFjm}J;x#Bc';[iqb^(<+uhz-O.9oʍ{ +B)T='K@]O_uhQjWO+]-KYZ$wV 8o55oZxoŻ?imxJHt 3ItKk啢]><շ ZO]m4o~kݧMW=l+-*;-n6j?g-}}u4f{e;|Kxj*ʲL^o%R}} >I~? ٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhN|]7@<- M8Rn'heK]B9Y+|8bVOv.)ͭUݗ69o;߇ s[|L:g\$%ȎO)hXC?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]r[xDžOo{埂u+ ÷7:In>bX,D\,K%kXEyD_?c|6~&M˩kvmB \O-㻸 x.+G կ%ONte_s5htֽ՚5fر>~;xg^ Zgv[PIYC%+<>*7uuƓuwIבK t̑< cV>Z_㦧;_mּ"][K,2@M" D$,khUKr;|՝eɵOك oK4~DzMk k7./ Amm;e+=r7V:PQYz%EXZ[Xz R5o?FGa{;ܫ,V9ӿ0_,5edNo^O|CLj_Kgn|A֥m5w-6"-好V$7X Ew^).}MN[kjhW׬q> 3;ngbp>x(/~'[H` H*Ğs_,h?PO|G>hOxSnռMczeՔڃ`smj6M4wA(/ |i)aA+dޱ A[XjP} oҼM|?w|i4υiƃw.~; 0\meh|ˉU%e.>k{I_Wn;[_{|t^Mևi$[^E,)k˯2D2[$kҏwuώ|}K:xB}:I;$kȥE:MyuHXT1d-zV_؇YCS/^.~K MaHW&"TX.2 c"~|uy?o.DKz͟RTXb(ɤA:,eAq[kVg%kM4ٛ}SiD}q{5iJbTtaT__AzNY}_OR֤RwK^Giuψ m!LČF:⤖A-% ۬m|;%)x~?)J.DS daR+E*3p''+^j˯څ֯k"WPay i eGq T;P> S]qww<6M3QvcP$5W_*?m i{9qq રXj\Ԓ!_OQ?4niB3kBe}iڅ͙RB_Cl%vWE] M<ƾWv oڤvɭg9ͅ~6m~ @&a{];Þ:$z6a$B&)(T G17&n-sF[_W~Z5eo{IZD׻+ouoN}um?<~⛟Au[Myu .yio&dU 5,)ட8~7t=붗:{g BMGOȫ5Zxŏ IIK<н\ t{73 ĆpU :.X CzŲhťM4n{]>yED 򂲱!+inފC^V<w߉/ EZΥis{jMi 6jsg$E$]B?GVⷄn<[kg=M+No4UP&gU e_$I_m.oEiqaxa!Ն>7|X'/tCIvi{ˑ$D|cxnX~3Oޖ7^[gvA,"i DT>V؋YAS/].6~K QaHW&"T*7iu_-:twOed%gx쭧[׵wwr֟?,/E{ fN9mr7/bL4 <̪}_Ԧ+m>VIh{U$E0F]rFQ>}|@k_濶Яdҭ/58-Z v$Hѡl7* !XN KKyw}U)/5;zmϝf)vGEF??|K+-6->FmY-fuIf-h4X |9?iom{H[MwA^YJN :~sqf[1ޮO_>3OwQy4 id]nd0R[{Xb6m~ @&a{];Þ:$z6a$B&)(T G17&j˙_Eo}SVյvwF0؞0>|Bq Ek%ŕܶ;=M%bWQ3.࢚ď V:4}BRizWCy71>- R9]X Ÿx3⾣;b b©eDvss%E{t]1cq?uX~^_]{Z7A1iHs abt~k]z^svW\ᾋ欮Oky/.#'>FKgo', 7Rt#֧hڋ/U_ ks156麍yr9h8DQAaEV,eh/.t!xXkVe HEt,V\# VJϥwNEf-]Z^t>Yऺό~@1xiPYcTՖ&ymku#fu[V `$!2wKX/⎉CĞ$֩kz]G,2:Mžs 1 gsܰf'ŏ7f<=;-,nArmcYEiu"e_0HSU]V{/uM쭣߯n[s_f(moYIǁ4%ڿLR{u1Y$``fYi:?R"ȎQkZ?2 {_UJuhu<ï8_ϊ:_ .cB۬yiHs aff g_2 Ztk` ԯ.moZK_6]J8O-`]q`AI}uoOɻjQ%7oz$MHGcN"DW[cCխimyw5nTo6m XIJ>8Z*@kMBNRyZ퍎m<]N#MSi|" ~-;Nkm3RC\L04[_,F0Pjzki{^=oMe^WimfUkw?Tφ~;'񍠵iv^t)ob(h["i=?|@p~4Ѭ~%X]Z }*{d岺^<`HI`;yo a?',$szL|Gwϖ.Yl`K1HH"2' oY'⟆|Iϋ5 wwKh0^yh1 v%kXEyDm鶗Kn(mn.uߧ*K]\Y_RK|?m߉RM/IsiǤkD>n w2,ُ?j_CIOAoEo&]Kk#h-G ܛH?ggÏ?Bz$&Tk{y}-A{BET!  "BeI6h?!ex/x "5{0|( BYRQmMvYѣg|lZxxu݄ IN z. Z1%3 q?uX~^_]{Z7A1iHs ab 6ďx?aoq6Ex&,O \<#UIU^UewoG/+]iKoPO+Wŏi,Kѵ[q76E bI*+Fu?h[_oxZo\Yoj+q)j|,nnëًLCI| ab)u?Ou^gᔰiN!!aKbyqjײOǿEӺ%uwk'cuu?~icW%|Po6Ia.ޙonyMI o%TERWioi.WotOݥsh(Y7im<y6Ju_o~^GVWҼIxD𝭶jK{mL#M,l bCź4-74lat>mW6𣲤wsBQq~2o~!h&[k5 o_IzFddE1<(*0e2*.*Qץw/K[g {=s[kZ驝c }/)ZבhP؋!c"c'xzŒiŤ4/n{]>yED 򂲱!+c~gMOsrjwݯ[P@gkwwYCws<HSQRߗ]ͭW?[6z}իy+w|?x]jV^GyCb, Z[ɨbC{ii%@ ->[H` H*Ğs^1|^A|<=a4bgk=ow7cxYIK٥srӹ^:|Uo/ &C4-"A5י"y`Pƭ|\<Өi /] :o%v`KpK,!igC![uV? $P+Hd *T,UwIrܽ{^-4dɛv}mMOwuώ|}K:xB}:I;$kȥE:MyuHXT1d-zWߴ/ڛNh'Ƨ Iu+kM ܼAYS[ O㮧;|_uκ"]_Kl2@M" D$,]÷[nQEH((((((6%.jSל|o_lG%.jSל|o_lr?~6Q=y>hg*ЫӾɺl6{:U7~_?lQ L|Ϗ?F!?xNwQ|y9QX?v>4<5d>Qx+b8ÿF/}a#]`G̾G~g֔QEyG݅C6>qww<6M3QvcP$5W_*?m i{9qq રXj\Ԓ!_OQ?4niB3kBe}iڅ͙RB_Cl%vWE] M<ƾWv oڤvɭg9ͅ~6m~ @&a{];Þ:$z6a$B&)(T G17&n-sF[_W~Z5eo{IZD׻+ouoN}um?<~⛟Au[Myu .yio&dU 5,)ட8~7t=붗:{g BMGOȫ5Zxŏ IIK<н\ t{73 ĆpU :.X CzŲhťM4n{]>yED 򂲱!+inފC^V<w߉/ EZΥis{jMi 6jsg$E$]B?GVⷄn<[kg=M+No4UP&gU e_$I_m.oEiqaxa!Ն>7|X'/tCIvi{ˑ$D|cxnX~3Oޖ7^[gvA,"i DT>V؋YAS/].6~K QaHW&"T*7iu_-:twOed%gx쭧[׵wwr֟?,/E{ fN9mr7/bL4 <̪}_Ԧ+m>VIh{U$E0F]rFQ>}|@k_濶Яdҭ/58-Z v$Hѡl7* !XN KKyw}U)/5;zmϝf)vGEF??|K+-6->FmY-fuIf-h4X |9?iom{H[MwA^YJN :~sqf[1ޮO_>3OwQy4 id]nd0R[{Xb6m~ @&a{];Þ:$z6a$B&)(T G17&j˙_Eo}SVյvwF0؞0>|Bq Ek%ŕܶ;=M%bWQ3.࢚ď V:4}BRizWCy71>- R9]X Ÿx3⾣;b b©eDvss%E{t]1cq?uX~^_]{Z7A1iHs abt~k]z^svW\ᾋ欮Oky/.#'>FKgo', 7Rt#֧hڋ/U_ ks156麍yr9h8DQAaEV,eh/.t!xXkVe HEt,V\# VJϥwNEf-]Z^t>Yऺό~@1xiPYcTՖ&ymku#fu[V `$!2wKX/⎉CĞ$֩kz]G,2:Mžs 1 gsܰf'ŏ7f<=;-,nArmcYEiu"e_0HSU]V{/uM쭣߯n[s_f(moYIǁ4%ڿLR{u1Y$``fYi:?R"ȎQkZ?2 {_UJuhu<ï8_ϊ:_ .cB۬yiHs aff g_2 Ztk` ԯ.moZK_6]J8O-`]q`AI}uoOɻjQ%7oz$MHGcN"DW[cCխimyw5nTo6m XIJ>8Z*@kMBNRyZ퍎m<]N#MSi|" ~-;Nkm3RC\L04[_,F0Pjzki{^=oMe^WimfUkw?Tφ~;'񍠵iv^t)ob(h["i=?|@p~4Ѭ~%X]Z }*{d岺^<`HI`;yo a?',$szL|Gwϖ.Yl`K1HH"2' oY'⟆|Iϋ5 wwKh0^yh1 v%kXEyDm鶗Kn(mn.uߧ*K]\Y_RK|?m߉RM/IsiǤkD>n w2,ُ?j_CIOAoEo&]Kk#h-G ܛH?ggÏ?Bz$&Tk{y}-A{BET!  "BeI6h?!ex/x "5{0|( BYRQmMvYѣg|lZxxu݄ IN z. Z1%3 q?uX~^_]{Z7A1iHs ab 6ďx?aoq6Ex&,O \<#UIU^UewoG/+]iKoPO+Wŏi,Kѵ[q76E bI*+Fu?h[_oxZo\Yoj+q)j|,nnëًLCI| ab)u?Ou^gᔰiN!!aKbyqjײOǿEӺ%uwkG?)jj>$|>ӴGTӛXOie䶦"-5DblYX ]B6O ?ȶ>-:ƌi#œbx?Sm\k-`,Y|Aogw<%h1QNMY8ۭޫ\)kz]M{< __O49PVf,ºgϾѿ|=7vS|,5|< xI"KFG[,5孺>*xTc>;|t.E.4qM fI*չ>Z_ ax×|Po x*W^ƎV|-+M$ql_b cMOw/x^.k6~M?TXb(ɤA2ą,eA%/ouKlcۢVŭ石a@i_7?״ o3kc\_Z9%ۄ*vV3vTiA!d@;!j_W┾Ѽ<yqYەeg:w冽,4R̃i|/=&?ֿ%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+;ȴIn'!2I#Kz9xW^O|CLjԠ?t3ye%/fmnKokN{okuSŴ('#џ4]')O7zpj&a1=2{mA965H;QQD'x\W7Լ#''Ӯ4CHYSח^deCIץr^o x N|,O4t7 i3k+C\M-©,,m_㦧;_mּ"][K,2@M" D$,:|Uo/ &C4-"A5י"y`Pƭ|^O3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k> ~Z':u}/YXj RE4'A򥌱Q>J qYz&ծSW[u}tDws/oxwB[|:#,Qx%r G{_B-?hu>s޸/>y.jZSlu]BfiE1X$qqQ%PTͽ?w˺ekVͻ|;%)x~?)J.DS daR+E*3p-(i_,>so^EqzË[x`K82VV_2E^V]o}IvmQE" ( ( ( ( (< عN^q عN^q>u`mGLur~(x?Gt*On? μ(x?Gt*2>?U/Xg|y9QKy9QX?u4<5d>Qx+b8fe__@X.Qƭs <^ _ZQEt}ZM48QFYُ@xTRwM_S~ثHEᧅO7G4Kcҷ#I3_Kgn|A֥m5w-6"-好V$7X |;\|?ˮ\p\_-s~kX5 5>3"J֐Xj>x(/~'Z}vD?/P>7ÿx/ * ? j-My.lNKs !C$&_F>(Wc6𞸾O.4}%)XgY.DIֹ a?>O|oo͠x{wz[Xyn y# )yPZ?b-g]OǓvtDe,5E)"_DHXyRX\d]|=D㲶o^kZܰxo#k|+;Y^dGI0< (2RGЯo-Z &բYTfWHñAwEFHnG~!|DׇiݬPhnJRMIu$6 _BJFkh')ؒJ#F ܨ$b0fm8)-.ߥWkXxDv>wO[w~A/شd&)%\ `2 Zm-!o;i5Q{e*80śB_l$cz#=~ | c?ߏDx%kLJ!tKG+O9Kyn&b5Aٵ3ŇwG;ytxj}̤lr̡R&WH߼ͫ.e}ѽO[+ZJvד[[nmVbxW! 6W:Wrڄx72U]D̻dnOVj<7Z>, =HG⑧^ 柼g)Ht{Hbrw/ ~)ϊ~&QG5? :&_okڭdy -Iw, ~®X.|QaYy}wkZ]hWŦFv"I"-%0R"JGv{Ri]s;/>m_ hF.ŝ~;Xs{]IZj/|>W|/XƲPG6+=7Q$ x-E[XS.ӦciY" вYrT6jIZ+>q;\wkz;g%߆>1w]oAgSVX巶% ))naXd1di-cĿ:&xzZ[iwy4w22PH-0@uXrr|>.@=3 f)IF@R$)5υu?"Iex]m/DP"FD0d|"MTw}v[޽567~ow~"ࡶW=e'¯ӼXj&nm3UKkdd%U9dV,&kk-KÞKO ;O"9F^"Ikg-%U*[xm?`s~_>(|, nn%畦v"I"-%+A~3iѮxRյi-~ڞu+K4&y<GwqU'k]OEս?&G̔ޫ_%蓺6M#?;ĝc>xwvhӍRMO^GsbHLp[V|d_k6<[X^oVե:~-Q/a%c(Y%*?h [ծ7"M =: JIk6:eu;K+D7GMTmg: Isi0L6xs[KKHvu[n̉ŸFawuk6-GEx E#%[g& x[3ޖW>[gvQ,#i DT>Rx+ g~$>/_ /o4O i-Xy}ƺz4L%ڲO,ac9ޖ].mhW|+i~\-urrfI,>!QGl|]~%I4%ͦXEL?o3<1ȳ$ Sf>+k85}'>EP<Ʊv-H@|rn78Q"a??kZ_8u _ Q[[h[E/ P o^:4`X5 eIFɶI4q!fgFGixmX~$iחv69$}:-0+hĖ2++~®X.|QaYy}wkZ]hWŦFv"I"-%0R2-ڇ<=?ﯮ?ƌ^Olgo?|6IpU%UyVIݽ侪Pu/7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI5o~&AiqgZحM qk]G4r u1t'|:Õ^\E;tɻf-1I$U -%Kc"~|uy?o.DKz͟RTXb(ɤA:,eA^m?N먕ߟᮟ緖D[U!I}Xj:u_T݁[S"V1@Ĭ]QO+i%6tIT1< O$k=׊m"|KCS|څ;\O-㻸 GD&>?ikWWN߲BgN>gݾoSRJinEԷe9w;[vg1α|5?Jeuqg{|tsn<7B+$BnHDj~-J{R*,uk[%XfnV{MB&Se F088_':뛝$t7~wg妞dY.#X2+$1k?>:~<\%f)a,1I d BBʖ2F 5zo}NWK~zZy)!|Ua{[_?=_J&K++=vڣ[M-eXq24s ~Z':u}/YXj RE4'A򥌱Q4pWoM/ߥIGn+OVI(~']BO_ğuiXOle1ir%cd JJf H  $ rxc~gMOsrjwݯ[P@gkwwYCws<Hx/ _<{M<xz?iм;HZ,ٌ71$Ҷ|۵4u |skkz_E8O[/.;?ý/M5]=gUΜ[V- 1+++W:?kJwDGݏ\ߦmy [Bд(!SR['u~3]'Ļ ]NZkhWץ|Aogw<%h1wBԾMm)|yx=F*t# ; zYDh̛yֶ¥_v{S~\sn> {þ,Χo-7-V`޳Iyi&V$7֖%-]cuu?~icW 3;ngbpj6J[>k[YP'+Oڵ{^:1n}χ Jk4[lEu[K{5>3"Hom -$a_Q^EKq< !ITP2Xk¾x(/~'qhzƒER"&$O,*ղO+|cǟ]u 3e|1ˡ@m6L71YZ2inIed-#lu?5?n^gᔰiL!!aJ .[k^_e3zy=|i9|N⯃|oxGXOO\i7ZqmyI.ʆ5lJٛ}SiD}q{5iJbTtaT^c"~|uy?o.DKz͟RTXb(ɤA:,eAP\ު[Y7u߮\:;& &Ӿ&k}CúC֘bu{I-Z?JioYCn~tYu{PdZcS4L"/!2#8*ndm+^]-_%m43h,K LUvZ'1'S ]H,Q0yoCH7Ow gwA;x+ԵZPYvBH.*~?H%ng˷vmŠ(QEQEQEQEQEQExc_Jt5xc_Jt5PGj?g;e F|PSő=W|>u`mGLu埵ٿi_c8Ы9\cQHoǟ( ӝQHgǟ( ӝ={v?O/F#|.]^ &Y1{͇wjpr3Ҋ(0puFG.6ipŠ2x $j+_G- \V MPٙT˔D0K{8j=g ޗ (_msBԚY̱O ;P*]HKm辋~ɺ'7_Zߊ1_!|As"mTң1.Y53y&ͯ,>/|[>˧xsW'DF$De ce 4F&mŮhkkFi+Hem~3Ǐ_>`'(IhF0P^Ui^g|^Njq%Fke>4]I n SH ZsjzZQ峵*Y*u}k!ऺό~@1xiPYcTՖ&ymku#fu[V `$!27Gڿt}Αqs.qM":yr$<&m#t,0\%S$Hʇ1k?>:~<\%f)a,1I d BBʖ2F ܭ.zN쬕"$}z.W{ZG{y_w{ymI4V6xʤ2F .H2GϿw/?s '= Nb@м[w}V*/mKt$A'ZU5[A|X&ļ]W5siZ[_Op&+$, "m'Yg3^Yj^ZxOޗRy5 bK[=Aok*Rnmu bGTeݬw[utY/<63I~al9,XzF_ Nws֭Ikf ZY3,8˸8);Zz.7mV>d]-oD֩i9~6i~$ x^ -CFjm}J;x#Bc';[iqb^(<+uhz-O.9oʍ{ +B)T='K@]O_uhQjWO+]-KYZ$wV 8o55oZxoŻ?imxJHt 3ItKk啢]><շ ZO]m4o~kݧMW=l+-*;-n6j?g-}}u4f{e;|Kxj*ʲL^o%R}} >I~? ٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhN|]7@<- M8Rn'heK]B9Y+|8bVOv.)ͭUݗ69učK1'U+;㦘4˛t䱺^I lRФr@6>~ڗştkz߃ρ,XI^ ȸ.)<-xt' m/=v~ oot/\'Gӡ?-4h $q9^Q&؃XESo.ׄKZ͟SOiL1!aKbyqa]=ݶ}$KVzY:mմ^u3n ՟߇c];?|5oʶZIWּ!V!AMw|6K[ t3Kh#W_Hm; >2&PoU9Ǡi4|(nW{6kt[5.M뵯w|E~I<"|o&f )]奫d5ݴ+&!>g?r~ ~ 6Եn |5|9{/'0mmufCiCf.dr؏gi-~+Zgei4?OXâk(<{HmGeH.F1Q>~ }Qއ|?W' *MQ-b2:*(ĊYQm/e_d;]wVeOs:Wk R_|%O[h"m A}-.L3M41.ge?lڮ/O:Q4j Wژf%e`%u?O'<gci iힵd:%KYYVr4Q~i!#X>w_&ﵻ_6kc}z]'ygCws<XǯZz3T޽ Z֖DhK_oqg[XH\ZjQYeF:{|YB. |3xke5+]:/R$/OfEOwm-`,K;,!yJc셩|^7R#F#=zƍgnU+UFw/K2 Ǚ7]m;R/;z]}ֽ{i_97=^S+?oYPPȫK}KPOKj:? GTӎ2^jb"QJ6k~x(/~'&}5 X4 +v[wp7w31tZ8Le5%-5ݭ_UzKgmZn||>_Kgn|A֥m5w-6"-好V$7X /"%D$B(,I5_ ay< ?h,H-&y{vs- ng ]{1xKO/OqX'X]h ПRxm|8Q7+]-M;ɽ+Oࠞ"F|t2>$1xA;X˛{)m"h EFP=rs_RNn=I")dN^]y' j'^x_ |1χ.:>nOӠ6ZGa ͬq4 ̲~ ~:ŷZum/XXjk RE4&ABWyqt-]m/NLx|>jpP+}7R-)e%1*E0 D1k?>:~<\%f)a,1I d BBʖ2F (.YoUf꬛VQM^.nדwKmWiuψ m!LČF:⤖A-% ۬mzgr|bE欺^j-Mu iƙ`]qG`ARo6߯. IZ6GִO~?Ԧk}*P[LH` Y Ш}¼w졤|~x; ωQyZ-m(m,Z;H!YZ$y|}z[wm$3;uET(((o_1b:my_1b:myn#Mg3׏~גi_$gF{Ba}&ڏ?l#$I^Sg?P~"xNWQ9w?PA++mQ!_G^a#]`G_CGػw5m|4p{3Kg֔QEyC6>qww<6M3QvcP$5W_*?m i{9qq રXj\Ԓ!_OQ?4niB3kBe}iڅ͙RB_Cl%vWE] M<ƾWv oڤvɭg9ͅ~6m~ @&a{];Þ:$z6a$B&)(T G17&n-sF[_W~Z5eo{IZD׻+ouoN}um?<~⛟Au[Myu .yio&dU 5,)ட8~7t=붗:{g BMGOȫ5Zxŏ IIK<н\ t{73 ĆpU :.X CzŲhťM4n{]>yED 򂲱!+inފC^V<w߉/ EZΥis{jMi 6jsg$E$]B?GVⷄn<[kg=M+No4UP&gU e_$I_m.oEiqaxa!Ն>7|X'/tCIvi{ˑ$D|cxnX~3Oޖ7^[gvA,"i DT>V؋YAS/].6~K QaHW&"T*7iu_-:twOed%gx쭧[׵wwr֟?,/E{ fN9mr7/bL4 <̪}_Ԧ+m>VIh{U$E0F]rFQ>}|@k_濶Яdҭ/58-Z v$Hѡl7* !XN KKyw}U)/5;zmϝf)vGEF??|K+-6->FmY-fuIf-h4X |9?iom{H[MwA^YJN :~sqf[1ޮO_>3OwQy4 id]nd0R[{Xb6m~ @&a{];Þ:$z6a$B&)(T G17&j˙_Eo}SVյvwF0؞0>|Bq Ek%ŕܶ;=M%bWQ3.࢚ď V:4}BRizWCy71>- R9]X Ÿx3⾣;b b©eDvss%E{t]1cq?uX~^_]{Z7A1iHs abt~k]z^svW\ᾋ欮Oky/.#'>FKgo', 7Rt#֧hڋ/U_ ks156麍yr9h8DQAaEV,eh/.t!xXkVe HEt,V\# VJϥwNEf-]Z^t>Yऺό~@1xiPYcTՖ&ymku#fu[V `$!2wKX/⎉CĞ$֩kz]G,2:Mžs 1 gsܰf'ŏ7f<=;-,nArmcYEiu"e_0HSU]V{/uM쭣߯n[s_f(moYIǁ4%ڿLR{u1Y$``fYi:?R"ȎQkZ?2 {_UJuhu<ï8_ϊ:_ .cB۬yiHs aff g_2 Ztk` ԯ.moZK_6]J8O-`]q`AI}uoOɻjQ%7oz$MHGcN"DW[cCխimyw5nTo6m XIJ>8Z*@kMBNRyZ퍎m<]N#MSi|" ~-;Nkm3RC\L04[_,F0Pjzki{^=oMe^WimfUkw?Tφ~;'񍠵iv^t)ob(h["i=?|@p~4Ѭ~%X]Z }*{d岺^<`HI`;yo a?',$szL|Gwϖ.Yl`K1HH"2' oY'⟆|Iϋ5 wwKh0^yh1 v%kXEyDm鶗Kn(mn.uߧ*K]\Y_RK|?m߉RM/IsiǤkD>n w2,ُ?j_CIOAoEo&]Kk#h-G ܛH?ggÏ?Bz$&Tk{y}-A{BET!  "BeI6h?!ex/x "5{0|( BYRQmMvYѣg|lZxxu݄ IN z. Z1%3 q?uX~^_]{Z7A1iHs ab 6ďx?aoq6Ex&,O \<#UIU^UewoG/+]iKoPO+Wŏi,Kѵ[q76E bI*+Fu?h[_oxZo\Yoj+q)j|,nnëًLCI| ab)u?Ou^gᔰiN!!aKbyqjײOǿEӺ%uwkG?)jj>$|>ӴGTӛXOie䶦"-5DblYX ]B|:|o xK>xNFM3;lDvlXi6>%ϡɩkv mB 'ygq #]"VM \Bȋ$r2PGqNmY8evmf|?)u ?CӾ|d/.<)IkEk053jX"hL ċ:2ʲ/učK1'U+;㦘4˛t䱺^I lRФr@>A?~?~>7 &4Ao4">b^PuTyko'+_0]'Qм=ssNY"\,K%kXEyD[kgI4ߥ֞UN=׿va+úu K૫8`խlya'eY5 9Le2[º1B2B.7'܁^ c"~|uy?o.DKz͟RTXb(ɤA:,eA|/=&?ֿ!c"c'xzŒiŤ4/n{]>yED 򂲱!+c~gMOsrjwݯ[P@gkwwYCws<HSQRߗ]ͭW?[6z}իy+w|?x]jV^GyCb, Z[ɨbC{ii%@ ->[H` H*Ğs^1|^A|<=a4bgk=ow7cxYIK٥srӹ^:|Uo/ &C4-"A5י"y`Pƭ|\<Өi /] :o%v`KpK,!igC![uV? $P+Hd *T,UwIrܽ{^-4dɛv}mMOwuώ|}K:xB}:I;$kȥE:MyuHXT1d-zWߴ/ڛNh'Ƨ Iu+kM ܼAYS[ O㮧;|_uκ"]_Kl2@M" D$,]÷[nQEH(((((((6%.jSל|o_lG%.jSל|o_lr?~6Q=x|3GJ>*OG*n? μ\jOG*>?W/XgcR?qEQHG(~ ӕv~eu6; q'P/F#y.]]Og_d}iEW}T:owskikM48HEgf<ISQI 5}OKb#?Ø|`. J܍&K*Ye]I"O%=T~?OK/C6jMt,X]\ٕ.%6rWnt_Eпdko~_yl/> 6KiQpisP<fk-i Ӽ9᫓GiD"k2i2H@Y^y#~o64owVZM{VW]c }/)ZבhP؋n/|]otm'Bl8@5Ȳl[B҈FQ)$BE-9^}ys-i({_^˕kWĿR]C{?k?[\4,1j<5亄E:-+ 0y }x_wŏz:]>Ht9kkagJXjJ'Z?g&4>,|]񿅾6oacu {k.gdR)ICju?Ou^gᔰiN!!aKbyqnV[=uӧGtVJVwu{[ww+i#r=[;ψ'df+sqzA&$H0ʧuJmBkH$+VgeRDQ]#m$ne#ٻ ^NkvAZh^-־+Kۗm6A%vvJ ZG-~km M*S 孠`bI*.#rऴ~_]b]]vKoi?t^c[o]ľ"bonՒkXThVysH%*ßi׺xtEç77l ) 꼏Ꮓ4~>uKK𖝯kO%.MS <-帚(wH.fk-i Ӽ9᫓GiD"k2i2H@Y^y#~o6Z+F=lUi)^Mmo[Wg{j߳n]^/^dZb\Y]j^2YV/,u2푹?[ )|HޅkG/!Fgxo7~sS@# eм)>+>#F-P,*P^}.Gj79YX/gI%ܰF<9q cGUeݬwhAut^;؉$g0,H+wKwGk'7iIujTg||/>2x{>j~$vb &m#t,0\%S$Hʇʿ>|eּl2q$ZeuC,V})](fU5Qozl[\=75Xo~^& ,xNb^.KQ-U-W]H VhZ6|G/x~-<'K)<x% HToYᶇS:Å^|\E;t-ɺV؉$g0f`=u#/υF JV3jzԭ,ӈ eGq Tw=VU2Sz|7NTM4~?4 xC?uyo<!1Qn [y|48^mc/Ez4=ZV'sXFlЕdw.o_V4(5+'%,;E7ƚ-R|X&ļ]W5siZ[_Op&+$, "m'S վ.UjEŜVvkb4R2%Ůuc,HОG9?WzGs▩˻Xav&:];Q$W0,B/؋YAS/].6~K QaHW&"T*7{-{];WW~Z]~?imWPS'aq5}Sv[+mLDZj3\Xwzp?uoﵻ_ke}z xjג y nuce3mU?Sm\k-`,Y|Aogw<%h1?zZZs+ߖ[]ogXHԾ|oZ|N:iLIK ! K $']>f@՟Fip 6#%W bAET|  ?7nt}z4DKidc ȯ(c_ujo?qi+~c5ԉ~~-.ueHQBBu%I9w=?t~JnWK/,?kJwDGݏ\ߦmy [Bд(!SRV?k~ @Mψ ԭEXY弴Q2*ĆKd-KѾ0R7#4k;rZN0ù|ץFYm9 ay< ?h,H-&y{vs- ng ]t~䮟V.^ޚOwC.ʍ#($"3{ 2}_:R]_wz^j{ZΫ8=䶭 MF[)11 @bVVWP߀~Ǿ9'# ÿdΝm}ϻ|3ykwo4)u;jZY_^kwwYCws<X1[k_@n[G{6I0m ~zS)m{AMp8:h#P/Blc:_97=^S+?oYPPȫK}KB;!j_W┾Ѽ<yqYەeg:w冽,4R̃iO ~/|X DdDi3 ۵OQo,s%ϡɩkv mB 'ygq #]"VG^O|CLj!c 5auh+kBJM7:W_ |1χ.:>nOӠ6ZGa ͬq4 ̲z]Owi+J={+u:wuώ|}K:xB}:I;$kȥE:MyuHXT1d-zQ9|N⯃|oxGXOO\i7ZqmyI.ʆ5lJ5?~:j~;k%մb)a1I d BBʕ ]A> ~Z':u}/YXj RE4'A򥌱Q.+mz_={~}iw3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k(9R7*ZԔ֊Nt^Km;n<;^>ix(GWT9=Dvuʹ:|D/|'3[Vh*`L*Eu#XZȰ^FvXstYu{PdZcS4L"/!2#8*~G~+<b\^" eG̑wF%ohF;ZMwk]ڻ|ETQEQEQEQEQEy@\g?gM%7y>|Nw-iv?-˲F0k|h/ uc:m|Co6iVȭ$<'֜wɺl6{:_w~ѿ+OG*n? μBoQ \|ϏK?|w9\QGkR'?qErÿF71{݇wj?meu; q1i#c?쏭*GQᵴi$p $)p%WiO x>o hUǥnFT%fx,. &=Wߴiw tf-ڎsodd6*-?hu:~4o|sυ`ksv@ԉ]Ki4n-e[6yߙh~οEu(IwZCn5ZY1ǖؑqQ%PQ4}^j1IꮶE}u Z6՚G| !k˯=jw}R<9|_\(Mh<0${|YB. |3xke5+]:/R$/7ŏ:߆ do xgR]9H付3BqYϛ).ܝE?od޺?ͳWWuf(moYIǁ4%ڿLR{u1Y$``fYi8ߵǏ߶x#Wuе}KwM: }mM=pVi=Ï8\\;ش ѺLDE_[K`^ j>*⿊WK&kUuyq[ReRbm~5'׍2Kk먛$o]۱ Ծ,U^| qgVzŵJM.EŦuIPo$káqww<6M3QvcP$5;CSW~ۖ|Xn>cP72WEMU>tJ{ D05!?'Zq/ 'Eq"mL֓G pIvͭw9π;O%ſOԌ'/!4o[EsonȐ]2cMo&O~.Dik}tiVkZVKK:o?^%ѡO4 xLFkCD8^5ݹGOٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhK_`^پ,|Q5#xc:详qͼ42G% "w$uV8ÏUϊ:? //cB I$U9f EŮo/?.v&G}, wgm?w^Uu-F}_CNs_[x|-)bǦ\*&A|/?~&:׆\YmbE# qi]G4Rye:[O#+/aϊ*^.ͯWO{XmV]ֺT oUII YT=j >78w3xbYu/ $0 bRG* o.2qMSV5N{=8Kk輵2$GMvM$[ė6\zFaM3 _s"Ό0YLE7RYim5ΐBPI9!*'|?~?~>7 &4Ao4">b^PuTyڍ}\g,Ѳ$2@HunR29qU;{4}U_d HtN_.67Ucwtm_\vzͦ~jm}=º올DJ3G,Ѵ_+ߊ_H˯xZSG׼7ygIHuId]-K`eu^P[W6G(־֮CQ%Pۘ$0Vφqx6'IOӼ]h[x<qd%f3L #2$Xm{4m~-f1 }_+O~=00{Ocve[XZM6q?}$.pFa2C$__h3BxIHd-u)Ah!V)&~\-I:iYEٳ,o& <|/+[FJ_hdvCѬʲj;H^Q)fA5)(+G˕^KKZ2ۤ]+KrgmO_D|d4}'Iv,QxNv$z> Ӗ~|9xƉ& 7Q%FZ)eGh$}L-e%Jd72:>f+?X;6omb׺wWӧ ϊz&> y_hZvPi5;Xho&c?%X~Wÿ "=OĦxz5oZօI@ /3AujWw:v|Dz$=Pa4"$cR!9__FE"=F(Nt#; xYDhP{sd׿ky7nV&[{z[nhO⧎O<#W Ot]Hkwkˡ$2[Jك oK4~DzMk k7./ Amm;e+?_㦧㻏]qWҵ? ,1I d bBʖ2F $5$]#9| ,XtI{;fFXR8j~T!#E,6iEmUܩ%%-?tK{8j=g ޗ (_msBԚY̱O ;P*]HKm蹿ட8~7t=붗:{g BMGOȫ5Z~6m~ @&a{];Þ:$z6a$B&)(T G17&v~¯^GwO-G-*i{vs- ng ]j+EGWѻ^ފlWzu_^/:?kJwDGݏ\ߦmy [Bд(!SRiO_ߵ6|>4O3[NoV֚Ax,%HFA5d-KѾ0R7#4k;rZN0ù|ץFYm>N=}[ٿ5[>hGMSO_OGV"HM>{k[kxbP%C sK%?h |cƺJ3om^KA4SR°c' mb]OHN;ufR$WBN@ueR2r|>.@=3 f)IF@R$Riݭkdݮv[zK^ݥmZ:S_Q<=sIRI-Xdt;}FRc($ :,8Q9\b/_5m+]Anۻ%c=+#َ`α[H"fI7}?ƹ.gW#",;/ b$[H4C2$\6~C}MFJDI"oI@Hd,DR}>MoKA$붶R'ڌ ~-;~?skVZlZ}ڲ[s [.iaVsB~-6O񖐷ಕbtF́e!/c1]W?>|1fo< pi~ӵMcÐ%ɣjaE  lMbŻ#᝼w<5rtHm>HMfR 69fPK+܏$boMe̯Z7etINkk~ -jڻ;ߣVlO~r>!|8V"5P[PFBʱy`lQMSG+_xŚ>gR4=+~!P)v,NVw]O<_Qߊ1hWgTD qt;U̒"{=źI.18ÏUϊ:? //cB I$U9f DI]]u5=/{Y9JM+goEVWz͵< #S%سOGkN~a:}`SE~*/5۹k[HFEwg9dOE("k2zEݴ:tQ۬m52$A"Rr.@ʑF|_I+_{g;~k.{Gu}:y,ĿR]C{?k?[\4,1j<5亄E:-+ 0y };o%|TGD|!O\kTu m=.#&QTJ CxnX~3Oޖ7^[gvA,"i DT>U?ƹ.gW#",;/ b$[H4C2$\+׽fݦvV-_67Ucwtm_\vzͦ~jm}=º올DJ3G,ѴUĿ|HOxsQ4!$"Ikg(HT7۬u bGTeݬw[utY/<63I~al9,Xz:_ [E֛YwwZv-BVk_-C0Xfqq%PRv=?&GQoUݯD֩G_O/>)>! 5z~#|iڧ^f;AbRRE\ta@i_7?״ o3kc\_Z9%ۄ*vV3th<Y׼]3^8GC-Ҫb2dK~1|R?;ܣ,V9P_,5edK۟['䯮[r5[vFw~('~l #{uȵ6U.iD^CeGwqU4IOշuM=|{GV[}YwM#'x\W7Լ#''Ӯ4CHYSח^deCIץ?>*jmUF-m}{NxdhjW s ʫ;G؇YCS/^.~K MaHW&"TX.2 ?3AgoMAj6^^Tn؃FաKP̋ rnZ{[}Pnϯ߿e-.O%߆>1w]oAgSVX巶% ))naXd1d~yW_wYIms<3u>2̦l, e[3yݰ|W |=&}þ#t,0\%sM$Hʇ> ~zM[f|F5Nl)kiiY[! EV4m;]%~K=dRI^?smVuenHOؗ K~~ߍt c5MYbg&P6hXaO!/| (蚏&m#t,0\%S$Hʇʿ>|eּl2q$ZeuC,V})](fU%G{o]nis{+h[|b/ٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhN_>$~ڧ<9goVmuo$[ZJQx|S:Å^|\E;t-ɺV؉$g0f`=y/-kMSur;Qlu+K5/,q88);Zlvޟvj(owNTVi#' M|A=^?nS/e3GƠjwȱLb)RM)C".:ك oK4~DzMk k7./ Amm;e+:4_g?Ԯt~t/Iy{iUee1 VEFIP]߲CZsh)I̋OEzƍenQ+TF(w/K2 ϭW^tݹXemmo[;?g:>7|X_x2]>KtK#eSH"Y.F#ʆ5nO+ʿf-/ҾoQ~%7c-h7xgP-rJT픬g ~/>;|^uƼ"]_Jl2~$P+Hd *Xˌ<> xt?.Ac{&cKP^oK( b)MK7}Wr,[m9/ |7z_4|R Rkg2>4B̩u!/sw|;\|?ˮ\p\_-s~kX5 5>3"J֐XjAٵ3ŇwG;ytxj}̤lr̡R&WH߼Q ~!xg_ߋ?hXxMXOk(hPVV$3u_F{z+[Ym^Vz`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}↹Լ?ݘ#Kˊ'mOWD;hgm R9_?eFE=E(t# ; zXK2 ?k {P`[c_M04=#8 i+/$[wZkQͮirjKwo+5np__:R]_wz^j{ZΫ8=䶭 MF[)11 @bVVWPu0m ~zS)m{AMp8:h#P/Blc>OfEOwm-`,K;,!yJc셩|^7R#F#=zƍgnU+UFw/K2 Ǚ7]m;_v{S~\sn> {þ,Χo-7-V`޳Iyi&V$7֖%-]cuu?~icW 3;ngbpj6J[>k[YP'+Oڵ{^:1n}χ Jk4[lEu[K{5>3"Hom -$a^Ϗ~5|E{;~E*<>:ܷP3,ǹU];%1|^A|<=a4bgk=ow$>"3]9g3Mo<3ZIiX;.Tѹ]%MmsIZ[UzOؗ K~~ߍt c5MYbg&P6hXaO!/| (蚏&m#t,0\%S$Hʇʿ>|eּl2q$ZeuC,V})](fU7Qozl[-.owem r,7gǻ/wS}?Cuk[GoZ<FF#WVe`M/5_p+EUŠ5 yH 6 /ʋ͖9/hc}&ڏi4D|P?6G^Mg3ן~ѩ,Q L|ώK?F!?xNWQ z|D(St8<69Ѷ; q߇GC#cuwj~~7/Ҋ(,uFG.6ipŠ2x $j+_G- \V MPٙT˔D0K{8j=g ޗ (_msBԚY̱O ;P*]HKm辋~ɺ'7_Zߊ1_!|As"mTң1.Y53y&ͯ,>/|[>˧xsW'DF$De ce 4F&mŮhkkFi+Hem~3Ǐ_>`'(IhF0P^Ui^g|^Njq%Fke>4]I n SH ZsjzZQ峵*Y*u}k!ऺό~@1xiPYcTՖ&ymku#fu[V `$!27Gڿt}Αqs.qM":yr$<&m#t,0\%S$Hʇ1k?>:~<\%f)a,1I d BBʖ2F ܭ.zN쬕"$}z.W{ZG{y_w{ymI4V6xʤ2F .H2GϿw/?s '= Nb@м[w}V*/mKt$A'ZU5[A|X&ļ]W5siZ[_Op&+$, "m'Uo/?jSÞb+oe6:7Z-%U(<>~/X.|Q"Yw}wk:dVK+MDE_[K30V<–n|Cֹ}KPbvP8ٜGq TvOEoOɻjQ[wk'um4 ϊz&> y_hZvPi5;Xho&c?%X~Wÿ "=OĦxz5oZօI@ /3AujWw:v|Dz$=Pa4"$cR!9__FE"=F(Nt#; xYDh+~nܬM{Vݷѭ쟳Oj,xGzX<.u%Ƒ)\,חBI#eC'^_a@i_7?״ o3kc\_Z9%ۄ*vV3b cMOw/x^.k6~M?TXb(ɤA2ą,eAIj/P) 慩5гbtvusfT9]s~]>pn>zm.u8./EO]?z5V%kH I,kj lMbŻ#᝼w<5rtHm>HMfR 69fPK+܏$boM(_?3ŏ ?<[&,ZT@p'[4@(++ºV^~vﭬ6+wV{v^u0m ~zS)m{AMp8:h#P/Blc>gC\Yj^n~sG"IkbڏHRnSG셩|V/2#F"{q۔eg:w冽,h~?5ouU^j-կfiD^CeGqU4~zhK4zo%ܕٷt8/[/.;?ý/M5]=gUΜ[V- 1+++W:?kJwDGݏ\ߦmy [Bд(!SR['u~3]'Ļ ]NZkhWץ|Aogw<%h1wBԾMm)|yx=F*t# ; zYDh̛yֶR/;z]}ֽ{i_97=^S+?oYPPȫK}KPOKj:? GTӎ2^jb"QJ6k~x(/~'&}5 X4 +v[wp7w31tZ8Le5%-5ݭ_UzKgmZn||>_Kgn|A֥m5w-6"-好V$7X I~fŸ t"(McXDOI$ FZ>A7?(N'Z_|Bψp\bKsf??W,>(,-.nxb#;$WÒŘ)^mC ^^Fm/HL'X̟$ygF!+z?׿}TWࡶW=e'¯ӼXj&nm3UKkdd%U9dV~~њߊt S N-lVxF[.9Le:Iº>~/H.|R"Yw}wk:d݇WKj$*ÒňR%1k?>:~<\%f)a,1I d BBʖ2F կe^uJOKOC?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]^;?Sm\k-`,Y|Aogw<%h1 OO_&꺿t/:uc>|8b[M?K.{kkz_O:{ߵǏ߶x#Wuе}KwM: }mM=pVi=?ݾ/|T4hhifqy{ IPd.&Dg] j>*⿊WK&kUuyq[ReRbmέ#q⯍Kq5k[c3pKWT'RTk:WQz߬_-̇Y_ᴵK#ky{Wuo Yw5 O X'Ry|;{NoVy#d6liK472[ɀG4ikV.y4|I}֢զܹV/{9?\C{ZŽ_({Hd -ݤChh.d>)|{|7J׉o5/WVp\ZcU5E%ӏ$\M셩|^7R#F#=zƍgnU+UFw/K2 [owAuij#DtX+il6C,Bũ]w_F]^9Iϭmtvnګ ?n?⇍|?f>%xs4H-b-nѬQvt1K,Myknwh~{7GDD׵-CL4++͇̞J>k!p!2 >j^?~->% ׄq"Kx|aaIimow޷/Ɵ7 څxy,"iՕ!E % ԕ$yl}ۼm{u6_uMOuZWq'ůyg)!|Ua{[_?=_J&K++=vڣ[M-eXq24s|8bgN)+kӥUK{j? Fi?K%mNV|KG_KKu WO}kY|?sգaip%&&$ JJοf-/ҾoQ~%7c-h7xgP-rJT픬g A~(.BS֭v[wp7w31uZ8Lq/+[FJ_hdvCѬʲj;H^Q)fA&~{뵭qTޗv_uw{jy+xwŗ"庆Ei/- $42*Ćtĸ?lڮ/O:Q4j Wژf%e`%u߄xŏ IIK<н\ t{73 Ćp6>%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+;ȴIn'!2I#Kz9xW^O|CLjԠ?t3ye%/fmnKokN{okuSŴ('#џ4]')O7zpj&a1=2{mA965H;QQD'x\W7Լ#''Ӯ4CHYSח^deCIץr^o x N|,O4t7 i3k+C\M-©,,m_㦧;_mּ"][K,2@M" D$,:|Uo/ &C4-"A5י"y`Pƭ|^O3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k> ~Z':u}/YXj RE4'A򥌱Q>J qYz&ծSW[u}tDws/oxwB[|:#,Qx%r G{_B-?hu>s޸/>y.jZSlu]BfiE1X$qqQ%PTͽ?w˺ekVͻ|;%)x~?)J.DS daR+E*3p-(i_,>so^EqzË[x`K82VV_2E^V]o}IvmQE"< عN^q عN^q>u`mGLu ͑=W}Mg3 @⏷#{BS)x_3ER=QHgǟ( ӝG?!xNwW)~|?o _6?_IX.QƯ9<3dFQx b8ј4o1_Q^YP:] m4L#eI'ME'{h4x^a~ \\}D*=+r4/3ĩg)u$a<SqDz >/P) 慩5гbtvusfT9]}BtOn񯆵b=}>CD-G5b]kwg3a@߄M_?< X|^}|3N熮NIA,!ie{Mɼۋ\Ѿ߯YkV5[Ӯ_]wGg+w|?x]jV^GyCb, Z[ɨbC{ii%@ o+ÿC<Χ0iY潵PQ2*ĭ}ii%q?/'>!c"c'xzŒiŤ4/n{]>yED 򂲱!+Bο?>('~lSZC%C $I"if.d=*Ejz5cxJӾG.ss:kybW&anE+u[Kx=Z\XiH|;ua$OQA5Ɠ%[} $ʍ[|`?Ҽ!2HwMѴ I]K"}im J"F@` {gkU޳{.U^dCIu{;7lbpҠƩ,LDגF02I2Beo⏏<k t"A]EuI*y`y+d-k?~ w|LGwז.Y`K1HH"2'c"~|uy?o.DKz͟RTXb(ɤA:,eAZ]lNY++DIY;+in]ܮ??l> x¿ٓo|?5\KAd /s*i)} Oծ- hmZ%IFet;t\df_4Ox{:ixZ4U/n^)AQI*h0iO+4kKN8$kK{y$4h[ʂHV#fӂ]_U}vKtN޽wGm/sٿ ]x;QoſxOmtMOVK{ٮabbRYKyZ! ,?hO{[E^2㶓]uRSY,%VrF7?> -]G.M/Zvixr0Hg?Gxm5k-E znoilcuN@'"PX}Uu=" ˝:k^(6ՙH ] )9՗ eH#i>fҳgӿQY{k~ֽף<ϖb_).@|=os~5-^.T~5e[{h]B٢bC *|Kj>'| 5Z:w Gqo*Lc%\!<7,?gc-xK{ -\Xs; bO4Dd"O**Ÿc\]Z+đjZE [-hC]vHW.TG{o]nis{+h[|b/ٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhN_>$~ڧ<9goVmuo$[ZJQx|S:Å^|\E;t-ɺV؉$g0f`=y/-kMSur;Qlu+K5/,q88);Zlvޟvj(owNTVi#' M|A=^?nS/e3GƠjwȱLb)RM)C".:ك oK4~DzMk k7./ Amm;e+:4_g?Ԯt~t/Iy{iUee1 VEFIP]߲CZsh)I̋OEzƍenQ+TF(w/K2 ϭW^tݹXemmo[;?g:>7|X_x2]>KtK#eSH"Y.F#ʆ5nO+ʿf-/ҾoQ~%7c-h7xgP-rJT픬g ~/>;|^uƼ"]_Jl2~$P+Hd *Xˌ<> xt?.Ac{&cKP^oK( b)MK7}Wr,[m9/ |7z_4|R Rkg2>4B̩u!/sw|;\|?ˮ\p\_-s~kX5 5>3"J֐XjAٵ3ŇwG;ytxj}̤lr̡R&WH߼Q ~!xg_ߋ?hXxMXOk(hPVV$3u_F{z+[Ym^Vz`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}↹Լ?ݘ#Kˊ'mOWD;hgm R9_?eFE=E(t# ; zXK2 ?k {P`[c_M04=#8 i+/$[wZkQͮirjKwo+5np__:R]_wz^j{ZΫ8=䶭 MF[)11 @bVVWPu0m ~zS)m{AMp8:h#P/Blc>OfEOwm-`,K;,!yJc셩|^7R#F#=zƍgnU+UFw/K2 Ǚ7]m;_v{S~\sn> {þ,Χo-7-V`޳Iyi&V$7֖%-]cuu?~icW 3;ngbpj6J[>k[YP'+Oڵ{^:1n}χ Jk4[lEu[K{5>3"Hom -$a^>+k85}'>EP<Ʊv-H@|rn78Q"Oxŏ?hM"XOi(hPVV$ |?_RW캧kSY[yo^YR)a0Xfc(֑Omm]~]6n[om<Z@>^:4`X5 eIFɶI4q!fgFGixmX~$iחv69$}:-0+hĖ2++~®X.|QaYy}wkZ]hWŦFv"I"-%0R2-ڇ<=?ﯮ?ƌ^Olgo?|6IpU%UyVBWv7fu/7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI5o~&AiqgZحM qk]G4r u1t'|:Õ^\E;tɻf-1I$U -%Kc"~|uy?o.DKz͟RTXb(ɤA:,eA^m?N먕ߟᮟ緖D[U!I}Xj:u_T݁[S"V1@Ĭ]ܰPI ׎;{|D>&}5 X4 +v[wp7w31tZ8L}'|s}jt/}:us>|8bir˹r^ޗ{<|E~I<"|o&f )]奫d5ݴ+&!6>~~;|J煼i$x[ťZ?cyXbX]Sx_^' ~,> ܎/.u M16Ӭ5SN:Ưx~e{-MFk+ @bVVW]+w|?x]jV^GyCb, Z[ɨbC{ii%@ _p?uoﵻ_ke}z x!c"c'xzŒiŤ4/n{]>yED 򂲱!+N.Q},]hS|ͧnvso/"%D$B(,I5ƃ3拤=< &Q [ &?Ǧ\YOm<0FFiGpJ*4> bƟ^2;ⱆO 4?ۦp+|/>_wƝCLY} h7roy- fV̸[RYfY H.濧m4M~ӿo;ǺO aqhzƒER"&$O,*ղO('x\W7Լ#''Ӯ4CHYSח^deCIץeu?5?n^gᔰiL!!aJ ?b-g]OǓvtDe,5E)"_DHXyRX\d?_=frV]o^N4O;iO_ߵ6|>4O3[NoV֚Ax,%HFA5{wN U-jJkE't/%y67\[ЯV"Y◇>R}BnO0bN",-dX/B;[,`9gr|bE欺^j-Mu iƙ`]qG`AY_e #ߋ?Ş?ޱ|MȮ/Rxqko CigV2A #HI7mc&߮]gdOR*I ( ( (< عN^q عN^q>u`mGLu~cd_hU|>u`mGLu||пM=W/s"z?(3O?ࣿϏ?Q+>*GQᵴi$p $m%WiO x>o hUǥnFT%fx,. '?hڏYAwJ!\е&s,SN.lʗRg9+z/_n࿍5ַ Göt\ț~%f KMn9l({ kg5ﴏv#Ѵ "5H4B M,r3"Hom -$aM=tw;~']฾[ =t<׶jj:|fEX -$2|'? x_,|P_OXxM"XOk(hPVV$3u>~¯^GwO-G-*i{vs- ng ]f+HwtW]ҷ_w໿>Lo xR-GZu+K W*kHdhaT{9$)$O81_?hO@Ҵ_#q[9uoiZw4yҮnbQ3ޖyyl}{}/eʵ_{b_).@|=os~5-^.T~5e[{h]B٢bC .@=3 f)IF@R$~ ~Z':u}/YXj RE4'A򥌱Q7+Kiӣ{+%e+;em:^˻ִ`G-W2wk ~ `yQeS:6^[izŤMD2"(̮b672 \Bx'BӵX-4/_f6h ;];xI%Pm-#5{&miyiourO0S$RF `PI `pRZ]_˿K꯮ֱI~׮;h|7K:/j1- ͮ_Yii7sjo{5,LSK4 o+D<e[ Okk?ZB߼vkUpa6َHu^Gz@Aſk%ɥKN5C'Ks&eVrM?$kg kg5ﴏv#Ѵ "5H4B M,r$xoB׀|Yz#OҼ7?y) o Rh2gu^SMuk~K(tM/PJ#[,,[XA#?Ï8\\;ش ѺLDE_[K`D߻^ZҺv _5ew|]3>p<=I5?];y?d?v!݆ ?G_h|7_^ Ʊe1Mm4Wv{͌nIDZ" *c.]AysMq ݺZ)D+e' : m'V},w+6omb׺wWӧK%?h |cƺJ3om^KA4SR°c' ӾZOtMG$ρ&K]'P9ah-eId[<`뜰?g&4>,|]񿅾6oacu {k.gdR)IC_S k 2^6|E}8-RS^+rEaK3*Eʚ~{|6km.owem r,E7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI[KďڻT5-JMN$y?2k_UJ3}y_9p /uH]]}Y7AՒc;$WÒ~?[iwwzGj-R.ifX36gqU'k]nnڭT|]-Ijj$|Bo➉ψ3^G=-֝xhMN)?,E*[ɾe(dXO0m ~zS)m{AMp8:h#P/Blc='F{L9u{Ν.=/4ya2M*!*Ȩ*+{AԾxNm)<iCѬ2j7H^Q)fA=~Jߵ+^쭽ս-m4kg{'SZޫVKiw.qliW 5ВH`PƭץyW%X~Wÿ "=OĦxz5oZօI@ ؃XESo.ׄKZ͟SOiL1!aKbyqt~~ǚX✾ҖH,|v$=#,vq5?*edLE4[iwfﶪnT}Z%=T~?OK/C6jMt,X]\ٕ.%6rWnt\߃WO?kyuKN n`O޳{k&dUZK-Z?6~ xXnHgo. \=O!YMY*B#y ?aW/ #cx'ɣ4=\ t{73 Ćpף߫ݯoEu{k6Mս:/^ݗ~[_|;ޢ#JnLJ[^o\6q}hZ kn)XϲYP> ~Z~QqDZ؇~c6T۬m=!j_U6⌾ѼȴǡhvbYΝaraK)fAGtU|AjZ clukiƙ`ǽqG`AM%e䟫n^-t9.^[n%fm4 V|KG_KKu WO}kY|?sգaip%&&$ JJοf-/ҾoQ~%7c-h7xgP-rJT픬g A~(.BS֭v[wp7w31uZ8Lq/+[FJ_hdvCѬʲj;H^Q)fA&~{뵭qTޗv_uw{jy+xwŗ"庆Ei/- $42*Ćtĸ?lڮ/O:Q4j Wژf%e`%u߄xŏ IIK<н\ t{73 Ćp6>%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+Gm{FzY] X.%IϐnM $S3|^}k,(6&;yD,ѳ>-wh6Wv^\.G{{6_~$^Νm2Vsl<";q>ؤ!Y`;FseC NuM8-춦"-5DclYX ]vx m=~ ԯ/t/'G=` pM,acu~kE6.}9 X4q> 3<Gĭ&2V=;=KբZVioMbDj~-J{R*,uk[%XfnV{MB&Se F0)_{|t^Mևi$[^E,)k˯2D2[$kҲ ~:ŷZum/XXjk RE4&ABWyqO㮧;|_uκ"]_Kl2@M" D$, 3;ngbpȭdiU-huVw_{&c?f-/ҾoQ~%7c-h7xgP-rJT픬gW?߇;[\vC{Eg 4jjzbC}ioIb\_d-KѾ0R7#4k;rZN0ù|ץFYm9 ay< ?h,H-&y{vs- ng ]ZKףF5yrV-׵;POKj:? GTӎ2^jb"QJ6kc }/)ZבhP؋}ﵴ}Z/i>]o{\[ȴIn'!2I#Kz9|A_} ܺtKCh4ss.&TYB4C⼻/KM%Si_粵otn[9|N⯃|oxGXOO\i7ZqmyI.ʆ5lJ?g/=>:|Uo/ &C4-"A5י"y`Pƭ|YbgMOswۭxDYe,55)"_D HXyRb'؋YAS/].6~K QaHW&"T*7mO}Y[﷗M4foSMx{_ S[麕|n^ qK,)R-хPM}E88 S8Cwf~}>EKZI.yM|M>"t+շí02h[Y gH.nSִO~?Ԧk}*P[LH` Y Ш{?>y.jZSlu]BfiE1X$qqQ%PVWCH7Ow gwA;x+ԵZPYvBH.z{|MhkIzmwWo>SԨB(((6%.jSל|o_lG%.jSל|o_lr?~6Q=q?)v~6Q=q?)zO?*3C~<E( =) esNS?Dl.]_8>pxgȍ; ql+>+>*GQᵴi$p $m%WiO x>o hUǥnFT%fx,. '?hڏYAwJ!\е&s,SN.lʗRg9+z/_n࿍5ַ Göt\ț~%f KMn9l({ kg5ﴏv#Ѵ "5H4B M,r3"Hom -$aM=tw;~']฾[ =t<׶jj:|fEX -$2|'? x_,|P_OXxM"XOk(hPVV$3u>~¯^GwO-G-*i{vs- ng ]f+HwtW]ҷ_w໿>Lo xR-GZu+K W*kHdhaT{9$)$O81_?hO@Ҵ_#q[9uoiZw4yҮnbQ3ޖyyl}{}/eʵ_{b_).@|=os~5-^.T~5e[{h]B٢bC .@=3 f)IF@R$~ ~Z':u}/YXj RE4'A򥌱Q7+Kiӣ{+%e+;em:^˻ִ`G-W2wk ~ `yQeS:6^[izŤMD2"(̮b672 \Bx'BӵX-4/_f6h ;];xI%Pm-#5{&miyiourO0S$RF `PI `pRZ]_˿K꯮ֱI~׮;h|7K:/j1- ͮ_Yii7sjo{5,LSK4 o+D<e[ Okk?ZB߼vkUpa6َHu^Gz@Aſk%ɥKN5C'Ks&eVrM?$kg kg5ﴏv#Ѵ "5H4B M,r$xoB׀|Yz#OҼ7?y) o Rh2gu^SMuk~K(tM/PJ#[,,[XA#?Ï8\\;ش ѺLDE_[K`D߻^ZҺv _5ew|]3>p<=I5?];y?d?v!݆ ?G_h|7_^ Ʊe1Mm4Wv{͌nIDZ" *c.]AysMq ݺZ)D+e' : m'V},w+6omb׺wWӧK%?h |cƺJ3om^KA4SR°c' ӾZOtMG$ρ&K]'P9ah-eId[<`뜰?g&4>,|]񿅾6oacu {k.gdR)IC_S k 2^6|E}8-RS^+rEaK3*Eʚ~{|6km.owem r,E7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI[KďڻT5-JMN$y?2k_UJ3}y_9p /uH]]}Y7AՒc;$WÒ~?[iwwzGj-R.ifX36gqU'k]nnڭT|]-Ijj$|Bo➉ψ3^G=-֝xhMN)?,E*[ɾe(dXO0m ~zS)m{AMp8:h#P/Blc='F{L9u{Ν.=/4ya2M*!*Ȩ*+{AԾxNm)<iCѬ2j7H^Q)fA=~Jߵ+^쭽ս-m4kg{'SZޫVKiw.qliW 5ВH`PƭץyW%X~Wÿ "=OĦxz5oZօI@ ؃XESo.ׄKZ͟SOiL1!aKbyqt~~ǚX✾ҖH,|v$=#,vq5?*edLE4[iwfﶪnT}Z%=T~?OK/C6jMt,X]\ٕ.%6rWnt\߃WO?kyuKN n`O޳{k&dUZK-Z?6~ xXnHgo. \=O!YMY*B#y ?aW/ #cx'ɣ4=\ t{73 Ćpף߫ݯoEu{k6Mս:/^ݗ~[_|;ޢ#JnLJ[^o\6q}hZ kn)XϲYP> ~Z~QqDZ؇~c6T۬m=!j_U6⌾ѼȴǡhvbYΝaraK)fAGtU|AjZ clukiƙ`ǽqG`AM%e䟫n^-t9.^[n%fm4 V|KG_KKu WO}kY|?sգaip%&&$ JJοf-/ҾoQ~%7c-h7xgP-rJT픬g A~(.BS֭v[wp7w31uZ8Lq/+[FJ_hdvCѬʲj;H^Q)fA&~{뵭qTޗv_uw{jy+xwŗ"庆Ei/- $42*Ćtĸ?lڮ/O:Q4j Wژf%e`%u߄xŏ IIK<н\ t{73 Ćp6>%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+Gm{FzY] X.%IϐnM $S3|^}k,(6&;yD,ѳ>-%ϡɩkv mB 'ygq #]"Ve |S(G7 K$ULyx<&x$I7*I"+v7촗+'˹}y6zGW}ouٞK ៏~$Ō? >.^ݦYiMOI(K*,qwLI'q'xW+7/ xXGO4b8{q4K,Myknwh?(l'|P ;d2\ hW!g,o&y[ žįxWr4vt3IoXl"AGmo.^Fcem-nd[o_%ͯ˗nnw~&xVZo^2x4?fK vז,g˖|{7 <:/ /|#|K߇G^$< eegxNT{Ki%̶&XTg6@߱!U[O|ቚ]S60Rt6+xQR !(8s?Z7ߎv-oc綠#RH2y2K"yy(g;ߗWVqt1n}χ Jk4[lEu[K{5>3"Hom -$a_R!eFpH> xŏ IIK<н\ t{73 Ćp߀~Ǿ9'# ÿdΝm}ϻ|3yJo[jek&yi~߶ohIuznk:t7ڴl-5nāYX ]B%X~Wÿ "=OĦxz5oZօI@ ߁?c<>%hRwշ_P@.3 xj{t<Ǐ_>*7uuƓuwIבK t̑< cV>ZKM|?w|i4υiƃw.~; 0\meh|ˉU%ek!~tw?-ׄKizşRSXb(ɤA2**ˌo^ッu{i}vd|;ǺO aqhzƒER"&$O,*ղO+foSMx{_ S[麕|n^ qK,)R-хPMz'؋YAS/].6~K QaHW&"T*7Ar3z5oUdߚ~jpt^OhN|EWoZ`$e7$Ahk(]gmNpp@=8|G/5eBW5jm]LM042#8 }ywWlm|Jٷt8χ|D/|'3[Vh*`L*Eu#XZȰ^FvXse #ߋ?Ş?ޱ|MȮ/Rxqko CigV2A #HԪ˿[m/ .ۭw (AEPEP|C5)k>7_ףC5)k>7_Cp9n? θ?plQ _n? θpmQ L|Ϗ?G!NwQy9QX?r~7|3dBQxb8FY/}a#]`G~~7#J(u}OXiG (;1(O Nix_i|4h@pUX,zVi5B_fgR.RIy/ |7z_4|R Rkg2>4B̩u!/sw.& _ k~+z?|;a|ẢR[JkĻMd3f?6~ xXnHgo. \=O!YMY*B#y}_-7"kݕ]ﶏLσV?k~ @Mψ ԭEXY弴Q2*ĆK߃WO?kyuKN n`O޳{k&dUZK-]^O|CLj1w]oAgSVX巶% ))naXd1d߳j,x?:EƃϤ[]4 =ȒTUV>Z1<7,?gc-xK{ -\Xs; bO4Dd"O*+WE ]sW? $P+Ht *Xˌr믖:;VWvVӭܻ]kOۖ ~"|@='}~k6[З1&A^U>ӯSh嶟w\ZA$XڴK=*"v#h.#s(> h/:t-;[ Bm޵iX^ܼSi .ӷU`%{x#w6\:@C˚A,X~UПMe-m&/x,X?Q`YHKoWU`' |[\<_~X2y.t2hZei)o-CBFv?6~ xXnHgo. \=O!YMY*B#ye̯Z7etINkk~ -jڻ;ߣVlO~r>!|8V"5P[PFBʱy`lQMSG+_xŚ>gR4=+~!P)v,NVw]O<_Qߊ1hWgTD qt;U̒"{=źI.18ÏUϊ:? //cB I$U9f DI]]u5=/{Y9JM+goEVWz͵< #S%سOGkN~a:}`SE~*/5۹k[HFEwg9dOE("k2zEݴ:tQ۬m52$A"Rr.@ʑF|_I+_{g;~k.{Gu}:y,ĿR]C{?k?[\4,1j<5亄E:-+ 0y };o%|TGD|!O\kTu m=.#&QTJ CxnX~3Oޖ7^[gvA,"i DT>U?ƹ.gW#",;/ b$[H4C2$\+׽fݦvV-_67Ucwtm_\vzͦ~jm}=º올DJ3G,ѴUĿ|HOxsQ4!$"Ikg(HT7۬u bGTeݬw[utY/<63I~al9,Xz:_ [E֛YwwZv-BVk_-C0Xfqq%PRv=?&GQoUݯD֩G_O/>)>! 5z~#|iڧ^f;AbRRE\ta@i_7?״ o3kc\_Z9%ۄ*vV3th<Y׼]3^8GC-Ҫb2dK~1|R?;ܣ,V9P_,5edK۟['䯮[r5[vFw~('~l K}M߲?Zsh~(̋O=zƋgnQ+UFw/dOY7 IW{u6Vay i {Gq TV^IM/˾\ռrVkfHeo7Ŀu7PtֵW:p{mZ6Rbb@Ĭ]`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}owo4)u;jZY_^kwwYCws<X R5o?FGa{;ܫ,V9ӿ0_,5edK2okm羻ZwK{weZw|?\||Y{+kN[ot[f BMCOC"Ho-I,KZ/C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]O ~/|X DdDi3 ۵OQo,s ǂ~lDi3۵OQo,sxEi&4gpE3HQ+4p?uoﵻ_ke}z xP<52O(AxvxbHZ EEΡc&ǎ8<-"7eH.q o^27<3.omC$zr]m!wq8GUa [[{T뭿ݹvz67Ucwtm_\vzͦ~jm}=º올DJ3G,Ѵ+ÿC<Χ0iY潵PQ2*ĭ}ii%q~®X.|QaYy}wkZ]hWŦFv"I"-%0R%[xz牾-V ;ϣ4=ZW}Y1`ֻ=6}Kmi}WgݧPįx[ƒI_ZXţ758Ά)e-m0SZޫVKiw.qliW 5ВH`PƭץR[ žĿx[R4vҴ#Io,6_L i#7S`ͽ]b5k:j~;{u}+Yi@M" F$, {þ,Χo-7-V`޳Iyi&V$7֖%-]cuu?~icW 3;ngbpj6J[>k[YP'+Oڵ{^:1n}χ Jk4[lEu[K{5>3"Hom -$a_Q^EKq< !ITP2Xk¾x(/~'qhzƒER"&$O,*ղO+|cǟ]u 3e|1ˡ@m6L71YZ2inIed-#lu?5?n^gᔰiL!!aJ .[k^_e3zy=|i9|N⯃|oxGXOO\i7ZqmyI.ʆ5lJٛ}SiD}q{5iJbTtaT^c"~|uy?o.DKz͟RTXb(ɤA:,eAP\ު[Y7u߮\:;& &Ӿ&k}CúC֘bu{I-Z?JioYCn~tYu{PdZcS4L"/!2#8*ndm+^]-_%m43h,K LUvZ'1'S ]H,Q0yoCH7Ow gwA;x+ԵZPYvBH.*~?H%ng˷vmŠ(QExc_Jt5xc_Jt5PGj?g/?//c{Bj?g3'3ؿЫ9Tc?{R/?qEQHoǟ( ӝ=/md|^:*Gػw5|ƶ|2Y/}a#]`G~~7#J(u}OXiG (;1(O Nix_i|4h@pUX,zVi5B_fgR.RIy/ |7z_4|R Rkg2>4B̩u!/sw.& _ k~+z?|;a|ẢR[JkĻMd3f?6~ xXnHgo. \=O!YMY*B#y}_-7"kݕ]ﶏLσV?k~ @Mψ ԭEXY弴Q2*ĆK߃WO?kyuKN n`O޳{k&dUZK-]^O|CLj1w]oAgSVX巶% ))naXd1d߳j,x?:EƃϤ[]4 =ȒTUV>Z1<7,?gc-xK{ -\Xs; bO4Dd"O*+WE ]sW? $P+Ht *Xˌr믖:;VWvVӭܻ]kOۖ ~"|@='}~k6[З1&A^U>ӯSh嶟w\ZA$XڴK=*"v#h.#s(> h/:t-;[ Bm޵iX^ܼSi .ӷU`%{x#w6\:@C˚A,X~UПMe-m&/x,X?Q`YHKoWU`' |[\<_~X2y.t2hZei)o-CBFv?6~ xXnHgo. \=O!YMY*B#ye̯Z7etINkk~ -jڻ;ߣVlO~r>!|8V"5P[PFBʱy`lQMSG+_xŚ>gR4=+~!P)v,NVw]O<_Qߊ1hWgTD qt;U̒"{=źI.18ÏUϊ:? //cB I$U9f DI]]u5=/{Y9JM+goEVWz͵< #S%سOGkN~a:}`SE~*/5۹k[HFEwg9dOE("k2zEݴ:tQ۬m52$A"Rr.@ʑF|_I+_{g;~k.{Gu}:y,ĿR]C{?k?[\4,1j<5亄E:-+ 0y };o%|TGD|!O\kTu m=.#&QTJ CxnX~3Oޖ7^[gvA,"i DT>U?ƹ.gW#",;/ b$[H4C2$\+׽fݦvV-_67Ucwtm_\vzͦ~jm}=º올DJ3G,ѴUĿ|HOxsQ4!$"Ikg(HT7۬u bGTeݬw[utY/<63I~al9,Xz:_ [E֛YwwZv-BVk_-C0Xfqq%PRv=?&GQoUݯD֩G_O/>)>! 5z~#|iڧ^f;AbRRE\ta@i_7?״ o3kc\_Z9%ۄ*vV3th<Y׼]3^8GC-Ҫb2dK~1|R?;ܣ,V9P_,5edK۟['䯮[r5[vFw~('~l K}M߲?Zsh~(̋O=zƋgnQ+UFw/dOY7 IW{u6Vay i {Gq TV^IM/˾\ռrVkfHeo7Ŀu7PtֵW:p{mZ6Rbb@Ĭ]`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}owo4)u;jZY_^kwwYCws<X R5o?FGa{;ܫ,V9ӿ0_,5edK2okm羻ZwK{weZw|?\||Y{+kN[ot[f BMCOC"Ho-I,KZ/C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]O ~/|X DdDi3 ۵OQo,s ǂ~lDi3۵OQo,s&}5 X4 +v[wp7w31tZ8L}'~Ǿ9'# ÿdΝm}ϻ|3y$~ݯ馋nskUwe͢wcc#Rk ~ i: 2$y,nWH'4),'oܐ ~0[[:U՜0XֶK<ܬM2-a] q~qx ⿅Ooݟu 7:In>M=e"%4\FdWIc"~|uy?o.DKz͟RTXb(ɤA:,eAkf%o麵ٷ SB{:ĿzMSVVz'mGR[Lm,eieHx`aFj~*M5O xx"+};T[)nPh1@m$c O#AѾ|rmuo o_IzFddE1<(*0e2n|u?Ou^gᔰiN!!aKbyqi$ޚ_KUWڒWԓPOKj:? GTӎ2^jb"QJ6k!eFpH> p?uoﵻ_ke}z xOfEOwm-`,K;,!yJc셩|^7R#F#=zƍgnU+UFw/K2 Ǚ7]m;K{weZw|?\||Y{+kN[ot[f BMCOC"Ho-I,KZ/C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]O ~/|X DdDi3 ۵OQo,s!c 5auh+kBJM7:VRRiFܯt6W&[|<[Ax?sE~žwmc.omK#o#Qi% @Owuώ|}K:xB}:I;$kȥE:MyuHXT1d-zW%&Ǐ>4gcAC}?Nhm.nc6>e*2ZF5?~:j~;k%մb)a1I d BBʕ ]A\/mw׺M;Y2f]{_[zvSrs_RNn=I")dN^]y' j'^7)KӼ=㯇kqBxJH>t/{|ĩ¨&E ]sW? $P+Ht *XˌtgUoZ]E5xuw^M/'MA^M|M>"t+շí02h[Y gH.nS'88 > #{uȵ6U.iD^CeGwqUJݾW~6[Kw%klۺigÿZ>"Y◇>R}BnO0bN",-dX/B;[,`9 ߁߲oAXw>&EWk8+h eh$]Uoe߭dJϗoۻQR ((;!~/k!~/j7_g\gsl_hU>u`mGLuxcl_hUe? |Ȫ^ =) es(7_g |^:Gػw5|ƴ2/}a#]`G~~8;#J(¡u}OXiG (;1(O Nix_i|4h@pUX,zVi5B_fgR.RIy/ |7z_4|R Rkg2>4B̩u!/sw.& _ k~+z?|;a|ẢR[JkĻMd3f?6~ xXnHgo. \=O!YMY*B#y}_-7"kݕ]ﶏLσV?k~ @Mψ ԭEXY弴Q2*ĆK߃WO?kyuKN n`O޳{k&dUZK-]^O|CLj1w]oAgSVX巶% ))naXd1d߳j,x?:EƃϤ[]4 =ȒTUV>Z1<7,?gc-xK{ -\Xs; bO4Dd"O*+WE ]sW? $P+Ht *Xˌr믖:;VWvVӭܻ]kOۖ ~"|@='}~k6[З1&A^U>ӯSh嶟w\ZA$XڴK=*"v#h.#s(> h/:t-;[ Bm޵iX^ܼSi .ӷU`%{x#w6\:@C˚A,X~UПMe-m&/x,X?Q`YHKoWU`' |[\<_~X2y.t2hZei)o-CBFv?6~ xXnHgo. \=O!YMY*B#ye̯Z7etINkk~ -jڻ;ߣVlO~r>!|8V"5P[PFBʱy`lQMSG+_xŚ>gR4=+~!P)v,NVw]O<_Qߊ1hWgTD qt;U̒"{=źI.18ÏUϊ:? //cB I$U9f DI]]u5=/{Y9JM+goEVWz͵< #S%سOGkN~a:}`SE~*/5۹k[HFEwg9dOE("k2zEݴ:tQ۬m52$A"Rr.@ʑF|_I+_{g;~k.{Gu}:y,ĿR]C{?k?[\4,1j<5亄E:-+ 0y };o%|TGD|!O\kTu m=.#&QTJ CxnX~3Oޖ7^[gvA,"i DT>U?ƹ.gW#",;/ b$[H4C2$\+׽fݦvV-_67Ucwtm_\vzͦ~jm}=º올DJ3G,ѴUĿ|HOxsQ4!$"Ikg(HT7۬u bGTeݬw[utY/<63I~al9,Xz:_ [E֛YwwZv-BVk_-C0Xfqq%PRv=?&GQoUݯD֩G_O/>)>! 5z~#|iڧ^f;AbRRE\ta@i_7?״ o3kc\_Z9%ۄ*vV3th<Y׼]3^8GC-Ҫb2dK~1|R?;ܣ,V9P_,5edK۟['䯮[r5[vFw~('~l K}M߲?Zsh~(̋O=zƋgnQ+UFw/dOY7 IW{u6Vay i {Gq TV^IM/˾\ռrVkfHeo7Ŀu7PtֵW:p{mZ6Rbb@Ĭ]`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}owo4)u;jZY_^kwwYCws<X R5o?FGa{;ܫ,V9ӿ0_,5edK2okm羻ZwK{weZw|?\||Y{+kN[ot[f BMCOC"Ho-I,KZ/C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]O ~/|X DdDi3 ۵OQo,s ǂ~lDi3۵OQo,s&}5 X4 +v[wp7w31tZ8L}'~Ǿ9'# ÿdΝm}ϻ|3y$~ݯ馋nskUwe͢wcc#Rk ~ i: 2$y,nWH'4),'oܐ _vgZ޷k8-RWhar.-5 O,Ky#^ qqx ⿅Ooݟu 7:In>M=e"%4\FdWIk >|twq5VgE)"_D HXyRX\dWj;=OumIկoum.~[gǽ7o#_ x2=h#U}UDg!?~;n~ (.1+8HWtBO [8~kv?~,A29Osi4nAiܦ!%Eb񂇄/~ޏ3׋./y.@nT#e3m)U7ەͭo6r˓{zk}k:~|Dm~|dOxH_ɤٶy E$@myij1wm ɾ=O\;xM-o[_ Gm^⇵I1[[jrYPٯ˵>#YK_ZMS0Zt6+xQR &QqOG>_G7~,|G|7:ytUI帷7JTKxFL1"TmK|W%nN|ջnj?g_)EZCTW xSǬAeaxB_Ks M vC˙İweC NuM8-춦"-5DclYX ]v ÏX.m+Z~gxnNtzU_HH/b'u>3]/ɴ9u;nͨZ^kwwY<%h1;~hl>o/V57/;RWnxo[y5ŜqY)+4R0sE'YC0~KB (ip|'JNKT p ks<1K$-}ol 5v5o_]tBG:ݗWNՒdZL1)#ʕ 7~|XkFdžu%_MymhdNK:D.'uH1Jwq7쬋yۿ*PO+Wŏi,Kѵ[q76E bI*+F} 4(]FPHEf d+~~*Vvš֍ux Zdgb$*rX#м/=&?ֿ\'fԗWޗֳ~Ncy-FQJLLH+~[_|;ޢ#JnLJ[^o\6q}hZ kn)Xϭ:?Qm]ƅ.}[x5 X4 +s> 3;ngbp;!j_W┾Ѽ<yqYەeg:w冽,4R̃iqqMmk[NTޗv_uw{jy+xwŗ"庆Ei/- $42*Ćtĸ?lڮ/O:Q4j Wژf%e`%u߄xŏ IIK<н\ t{73 Ćp6>%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+;ȴIn'!2I#Kz9xW^O|CLjԠ?t3ye%/fmnKokN{okuSŴ('#џ4]')O7zpj&a1=2{mA965H;QQD'x\W7Լ#''Ӯ4CHYSח^deCIץr^o x N|,O4t7 i3k+C\M-©,,m_㦧;_mּ"][K,2@M" D$,:|Uo/ &C4-"A5י"y`Pƭ|^O3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k> ~Z':u}/YXj RE4'A򥌱Q>J qYz&ծSW[u}tDws/oxwB[|:#,Qx%r G{_B-?hu>s޸/>y.jZSlu]BfiE1X$qqQ%PTͽ?w˺ekVͻ|;%)x~?)J.DS daR+E*3p-(i_,>so^EqzË[x`K82VV_2E^V]o}Ivmxc_Jt5xc_Jt4Cq7_g\_ǁ◷c{Bj?g3'3SlhUe? |Ȫ^ : ӝQHgǟ( ӝsfxd?c.]^Ʋ<2G/F#|.][? ?DyLg}Q^YP:] m4L#eI'ME'{h4x^a~ \\}D*=+r4/3ĩg)u$a<SqDz >/P) 慩5гbtvusfT9]}BtOn񯆵b=}>CD-G5b]kwg3a@߄M_?< X|^}|3N熮NIA,!ie{Mɼۋ\Ѿ߯YkV5[Ӯ_]wGg+w|?x]jV^GyCb, Z[ɨbC{ii%@ o+ÿC<Χ0iY潵PQ2*ĭ}ii%q?/'>!c"c'xzŒiŤ4/n{]>yED 򂲱!+Bο?>('~lSZC%C $I"if.d=*Ejz5cxJӾG.ss:kybW&anE+u[Kx=Z\XiH|;ua$OQA5Ɠ%[} $ʍ[|`?Ҽ!2HwMѴ I]K"}im J"F@` {gkU޳{.U^dCIu{;7lbpҠƩ,LDגF02I2Beo⏏<k t"A]EuI*y`y+d-k?~ w|LGwז.Y`K1HH"2'c"~|uy?o.DKz͟RTXb(ɤA:,eAZ]lNY++DIY;+in]ܮ??l> x¿ٓo|?5\KAd /s*i)} Oծ- hmZ%IFet;t\df_4Ox{:ixZ4U/n^)AQI*h0iO+4kKN8$kK{y$4h[ʂHV#fӂ]_U}vKtN޽wGm/sٿ ]x;QoſxOmtMOVK{ٮabbRYKyZ! ,?hO{[E^2㶓]uRSY,%VrF7?> -]G.M/Zvixr0Hg?Gxm5k-E znoilcuN@'"PX}Uu=" ˝:k^(6ՙH ] )9՗ eH#i>fҳgӿQY{k~ֽף<ϖb_).@|=os~5-^.T~5e[{h]B٢bC *|Kj>'| 5Z:w Gqo*Lc%\!<7,?gc-xK{ -\Xs; bO4Dd"O**Ÿc\]Z+đjZE [-hC]vHW.TG{o]nis{+h[|b/ٿ iExR|*M;ʼnx6k}.;=F?hT]vLVI"X%XEhN_>$~ڧ<9goVmuo$[ZJQx|S:Å^|\E;t-ɺV؉$g0f`=y/-kMSur;Qlu+K5/,q88);Zlvޟvj(owNTVi#' M|A=^?nS/e3GƠjwȱLb)RM)C".:ك oK4~DzMk k7./ Amm;e+:4_g?Ԯt~t/Iy{iUee1 VEFIP]߲CZsh)I̋OEzƍenQ+TF(w/K2 ϭW^tݹXemmo[;?g:>7|X_x2]>KtK#eSH"Y.F#ʆ5nO+ʿf-/ҾoQ~%7c-h7xgP-rJT픬g ~/>;|^uƼ"]_Jl2~$P+Hd *Xˌ<> xt?.Ac{&cKP^oK( b)MK7}Wr,[m9/ |7z_4|R Rkg2>4B̩u!/sw|;\|?ˮ\p\_-s~kX5 5>3"J֐XjAٵ3ŇwG;ytxj}̤lr̡R&WH߼Q ~!xg_ߋ?hXxMXOk(hPVV$3u_F{z+[Ym^Vz`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}↹Լ?ݘ#Kˊ'mOWD;hgm R9_?eFE=E(t# ; zXK2 ?k {P`[c_M04=#8 i+/$[wZkQͮirjKwo+5np__:R]_wz^j{ZΫ8=䶭 MF[)11 @bVVWPu0m ~zS)m{AMp8:h#P/Blc>OfEOwm-`,K;,!yJc셩|^7R#F#=zƍgnU+UFw/K2 Ǚ7]m;_v{S~\sn> {þ,Χo-7-V`޳Iyi&V$7֖%-]cuu?~icW 3;ngbpj6J[>k[YP'+Oڵ{^:1n}χ Jk4[lEu[K{5>3"Hom -$a^>+k85}'>EP<Ʊv-H@|rn78Q"Oxŏ?hM"XOi(hPVV$ |?_RW캧kSY[yo^YR)a0Xfc(֑Omm]~]6n[om<Z@>^:4`X5 eIFɶI4q!fgFGixmX~$iחv69$}:-0+hĖ2++~®X.|QaYy}wkZ]hWŦFv"I"-%0R2-ڇ<=?ﯮ?ƌ^Olgo?|6IpU%UyVBWv7fu/7Cm?hxzO_< x/FMogg+Ɋ$K4rȭI5o~&AiqgZحM qk]G4r u1t'|:Õ^\E;tɻf-1I$U -%Kc"~|uy?o.DKz͟RTXb(ɤA:,eA^m?N먕ߟᮟ緖Ce'E| NSNmcW&}5 X4 +v[wp7w31tZ8L~4)q ", ʰ=A9do?7y+s]o{ߥW~6N=[h% Lͨ `2Gs7, *c?5/V,o`.mGEy$}HCBv QoX{S[s'p3DjЋh 4Z%"{AP o=v_wgFBΒt}:;ϳOYfpM,ac%ou$~Z{TNGm:o^5~ϟFį׼%/VYhg.h1Po$c O#f H  $ rx7؋YAS/].6~K QaHW&"T*7_@:x?xZ4Uӡxw쐴Yӭoo1%ϡɩkv mB 'ygq #]"VMFK~_wkk6W^eoVkۡ_?<~⛟Au[Myu .yio&dU 5,+;ȴIn'!2I#Kz9xW^O|CLjԠ?t3ye%/fmnKokN{okuSŴ('#џ4]')O7zpj&a1=2{mA965H;QQD'x\W7Լ#''Ӯ4CHYSח^deCIץr^o x N|,O4t7 i3k+C\M-©,,m_㦧;_mּ"][K,2@M" D$,:|Uo/ &C4-"A5י"y`Pƭ|^O3~ҟjm;:}h/|f>-'Mԭ4KrYgLJn*k> ~Z':u}/YXj RE4'A򥌱Q>J qYz&ծSW[u}tDws/oxwB[|:#,Qx%r G{_B-?hu>s޸/>y.jZSlu]BfiE1X$qqQ%PTͽ?w˺ekVͻ|;%)x~?)J.DS daR+E*3p-(i_,>so^EqzË[x`K82VV_2E^V]o}IvmQE" ( ( (< عN^q+HxsVҝ6}hɋCp9_n? θl_hU|>9~5ڏ?!>)z^QgqzࣟϏ?Q<D(Sx?X?CGػw5x7ïFY1{͇wj~~8;#J(¡u}OXiG (;1(O Nix_i|4h@pUX,zVi5B_fgR.RIy/ |7z_4|R Rkg2>4B̩u!/sw.& _ k~+z?|;a|ẢR[JkĻMd3f?6~ xXnHgo. \=O!YMY*B#y}_-7"kݕ]ﶏLσV?k~ @Mψ ԭEXY弴Q2*ĆK߃WO?kyuKN n`O޳{k&dUZK-]^O|CLj1w]oAgSVX巶% ))naXd1d߳j,x?:EƃϤ[]4 =ȒTUV>Z1<7,?gc-xK{ -\Xs; bO4Dd"O*+WE ]sW? $P+Ht *Xˌr믖:;VWvVӭܻ]kOۖ ~"|@='}~k6[З1&A^U>ӯSh嶟w\ZA$XڴK=*"v#h.#s(> h/:t-;[ Bm޵iX^ܼSi .ӷU`%{x#w6\:@C˚A,X~UПMe-m&/x,X?Q`YHKoWU`' |[\<_~X2y.t2hZei)o-CBFv?6~ xXnHgo. \=O!YMY*B#ye̯Z7etINkk~ -jڻ;ߣVlO~r>!|8V"5P[PFBʱy`lQMSG+_xŚ>gR4=+~!P)v,NVw]O<_Qߊ1hWgTD qt;U̒"{=źI.18ÏUϊ:? //cB I$U9f DI]]u5=/{Y9JM+goEVWz͵< #S%سOGkN~a:}`SE~*/5۹k[HFEwg9dOE("k2zEݴ:tQ۬m52$A"Rr.@ʑF|_I+_{g;~k.{Gu}:y,ĿR]C{?k?[\4,1j<5亄E:-+ 0y };o%|TGD|!O\kTu m=.#&QTJ CxnX~3Oޖ7^[gvA,"i DT>U?ƹ.gW#",;/ b$[H4C2$\+׽fݦvV-_67Ucwtm_\vzͦ~jm}=º올DJ3G,ѴUĿ|HOxsQ4!$"Ikg(HT7۬u bGTeݬw[utY/<63I~al9,Xz:_ [E֛YwwZv-BVk_-C0Xfqq%PRv=?&GQoUݯD֩G_O/>)>! 5z~#|iڧ^f;AbRRE\ta@i_7?״ o3kc\_Z9%ۄ*vV3th<Y׼]3^8GC-Ҫb2dK~1|R?;ܣ,V9P_,5edK۟['䯮[r5[vFw~('~l K}M߲?Zsh~(̋O=zƋgnQ+UFw/dOY7 IW{u6Vay i {Gq TV^IM/˾\ռrVkfHeo7Ŀu7PtֵW:p{mZ6Rbb@Ĭ]`?h +߆Sv<=r~᷍p-lu BG$_[pNJ}owo4)u;jZY_^kwwYCws<X R5o?FGa{;ܫ,V9ӿ0_,5edK2okm羻ZwK{weZw|?\||Y{+kN[ot[f BMCOC"Ho-I,KZ/C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]O ~/|X DdDi3 ۵OQo,s ǂ~lDi3۵OQo,s3>~>?~>&cwu^ _Bg=.4.57қ,zeª2oY/3VWnx[q[ڥOHpsG)[i#WBy_c WG_~6|WU)u}WDm|:}jҠO.+xLL@bͺŸc\]Z+đjZE [-hC]vHW.TjPUw.o;/'U,JQzko{͘?:_:/K/,~#o!D7ՄWtBgS2'a0>+e? үukj:nm.&[rL'v`d #~s<Ѿ&Vq?ktR :ܱq쌪Ew^).}MN[kjhW׬q> 3;ngbpTg~[ytԊYr-9ih-|7~$j_ a>7ҭ>'Y]\Y4\ۤ%ЊIb%[S~.~3hmjϣxUԴ8izW+JN1p ޢ>qx ⿅Ooݟu 7:In>M=e"%4\FdWI~?Ǻ7Ɵ~8Fi䱚D??um:(D:pmM޺i?%e+^E˕ן7+ץm~[_|;ޢ#JnLJ[^o\6q}hZ kn)Xο+w|?x]jV^GyCb, Z[ɨbC{ii%@ ?zkh~)K̎w5VXVsiaܾXk#E,6߄xŏ IIK<н\ t{73 ĆpEFg{{uWOET/uoMo}{_!eFpH> [/.;?ý/M5]=gUΜ[V- 1+++W~?ikWWN߲BgN>gݾoW5OfEOwm-`,K;,!yJcdiT-YV]]$?kJwDGݏ\ߦmy [Bд(!SR_W/k~/|Emsu u7^ZAIidU %p W|/+[FJ_hdvCѬʲj;H^Q)fA'? x_,|P_OXxM"XOk(hPVV$3ui/w^WOC[[^C?-$>Ӭ5SN:Ưx~e{-MFk+ @bVVW]+w|?x]jV^GyCb, Z[ɨbC{ii%@ _p?uoﵻ_ke}z x!c"c'xzŒiŤ4/n{]>yED 򂲱!+N.Q},]hS|ͧnvso/"%D$B(,I5ƃ3拤=< &Q [ &?Ǧ\YOm<0FFiGpJ*4> bƟ^2;ⱆO 4?ۦp+|/>_wƝCLY} h7roy- fV̸[RYfY H.濧m4M~ӿo;ǺO aqhzƒER"&$O,*ղO('x\W7Լ#''Ӯ4CHYSח^deCIץeu?5?n^gᔰiL!!aJ ?b-g]OǓvtDe,5E)"_DHXyRX\d?_=frV]o^N4O;iO_ߵ6|>4O3[NoV֚Ax,%HFA5{wN U-jJkE't/%y67\[ЯV"Y◇>R}BnO0bN",-dX/B;[,`9gr|bE欺^j-Mu iƙ`]qG`AY_e #ߋ?Ş?ޱ|MȮ/Rxqko CigV2A #HI7mc&߮]gdOR*I (5}OKb#?Ø|`. J܍&K*Ye]I"MzioL>7Z8#R53m$U[6t9*hy k)%_> hh[˴mn3~ NQ[.]{V6kR3c-#.80Ji;=ֽխ{b]mVVm429_Cח_{MNDoxsM?6"/ (P:[Hѝy`I]gCH׋?jVt:_H^x]ۙY!k{dpn e'ŋxjFmZlx-"7dH.F1R8|?״6ou x@Τ+so- w1gHU7TSK[-]-={;;(iɽuKgm"PO+Wŏi,Kѵ[q76E bI*+Fqk?mh1;G¯믡j3tt{ěiM{=2U7Ȭ{߇9q cGUeݬwhAut^;؉$g0,H0~|Ug[RWtMfë=6.]* ⷀ*ʤ ,ۈjOe7Nd׵Q7Ium}߷cW|Y7Aּ7<8k)\MB9,HׇBy_ख?(x#ö_ .|Ji|-K].=Y& _s"Ό8YLza[GW>.oQ:Neӵd"$D JHB Ax3P^7GmfDxDPpq}: Aj}?+V5h7u;%)x~?)J.DS daR+E*3p-(i_,>so^EqzË[x`K82VV_2E^T]o}IvmQE" ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (9ܓe&=i[ Mk^#JX-W2WV Af{6^Hߪ\,ų[-%rhGmWh9 +[ #x7U _:xcdhU_t1 $膯><Q?G*r㯙u"z?(3O?򐿏Q_ Bґ^T"uD@yFDHwuE >"pU!vJګDпj?­}\k@Da{2'ːf !S$%CI=i80cljtaRg_!׏Կ~OG- KڗraxC]?{Kz?hj_Կ'.{E+ph=t6W-%豁C5ٱIp2BԿ~O\g? s]˨inJE׹Sd/ӭ.{ǁ|U'ī]R}⟎.ѵ[M1,xWoLcb9=wWK: sxKZΡV)iickGKzX\=wWK:?)^3}/ǿhj_Կ'Kz9BaRg_!J^= CR=5/j_=]?=wWK:Z/{RP?z>taRg_!׏Կ~OG- KڗraxC]?{Kz?hj_Կ'.{E+z>u5/j_ CR=s)^3}/'ź< ig{G36Vo{o.gʶG,7Q^i CR=UV5ě=N?"7޳AI? ? I|/Sv7އg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?Tg m?_oCQ@)'G޳AI? n?T$ߴ esE[蚽uh.-VPz2u,uG0e 'osZX]~he. *pfHI`v2Dp \@8i|OJ>7F Us[c,Q $7#{B['_ |oJ3B<D( 7) erNg_C=o|%._HZ[,RBA_'i~?o>4>|N״o@_xtoLɵtŪJHʬ z,_ه_[뺭(WVG`1<<7$⮬Oį#uoCį#uoC?b?25G,_ه_[W}9IS֠ԓaj?D~Й/7_*ek."~=Gel[]5~/OjOg"?L@_&x W-co[&3v7o tgG~/?W}g/G "q#ḿ G߲i8e_:?}\gW, _&x Q/G "q#ḿ .߳>~~"}K+]W/EBg_"3_n/Rf!3/o tX ????Ư_U#ḿ ?EBg_| aV??b?25I S}W/G "q#ḿ /'C/o tem.t~?JWg֟"3_n/D~Й/7_%em.X? /k*_"?L@_&x Wɋf__b~̿26K:?}* #/D~Й/7G"?L@3vX[]U dQo tgG~/_D~Й/7S/+/ ;#6ac}|h?g.&o.~ ~θ߲/o.r@uG/߉GjG,/ w_ڷ!G߲ -myooΏ_x.1@uG޿/߉GjG,/ w_ڷ! {oo}ooΏ_xW} vt~%| > Ϲ߲?/o.Y|ET/e?/o.W/ax_տX^Ŀ#oCm#F~W]O aV???_>K;V:?ax_տ,0+]feoc:?}: #?X^Ŀ#oC/[X |1 a?25Gtq@uG/߉GjG,/ w_ڷ!G'Ŀ?-.X 1\j_,/ w_ڷ! vuK|CʜxWgoxXz£ ._x.0@u?G',/ w_ڷ! vu0,.I-?WSƟZ<'fC~)}_/[K;V:5!C tmC?k̇'oX^Ŀ#oC/[lxwY?6C t,?x Wg',/ w_ڷ! vu eOk3?ge~ƯYC vt~%~oψeq t| Y??cW,K;V:?ax_տ8Gg8_M,]pq@u~~%/߉Gj_ψe_]|Y???cr@u~~%/߉Gj_|Y??6C te~ʯY7 vt~%~rm?g?  )?*Wg_FJ>#xdr`?&__|Y?Co?/?.ƯY><2;>$NI> I?/, sGZ!W?gJ7K.?xWg M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ(~(q$]eG><Y;B̐ƍt[e{89 T; %w#!O6>m3UnvM%cg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +3O]óڬf/E$Ub2*pzVQE|'?#Co⿤[ ~-|U OD FG~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I3;ᇅ<]|>ޑWv2ZD-l㺆{uY#,[D@,DX/߲X<_5{nM_oÿC}&h C-"\D r~?g O&Wx<'W-ƫhx;{;KN0nY [6(\/?~(jm{Ěrڦcy$m }JImwlJj+i II|B{?MVWz4KjnMM=!Wdy%GlS+<^So;&M?J[=K~𿆮u+4Ҽ1o}kFkA^xFH̑h(sJWkF5.n],㾶3oO[_]O?ZW,~ |<4 :xSTL{IluK˘Yl bo;U-N, >!$-+VJ jEKi4x f n#<޻}t\ȈbC $FzR{kvl&x~ݽ4Z[Q@Q@Q@ekɚ|[/XFm3O%C5hEPoYc\ҵ?|8-?ٷziOe%捚]𕅽e bHYI5j.9xFow>&_ ؽsyBb4覴w^_Q޿60ussAՖ/eFHYIq lf%pI5cǞ~)CPM#z}jqYGvI@VMn49?Cl|9? ~ 5e%ydm3GqBE:>ԼSiznKy̾ ZAc]JM;_VO"PMY黿q>5zxV:jb\6ؒ-AHA ik3E%]_vQ@(((((((((((((((((((((((&{|H_To⿣[s'W!!%?sNr=?+S;P!6_{¿LI?,J;GrEig~f ?KѬأL'z?\u? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?xi+w|?έ w촛9m8WPPt|9??Lyo5chckZ~m4'y#m6sj)eyHI鿴_YHy_Md1As#Fά¹*YX8#K/,ԯ5/|WxM"m&{ ]Ѱ['s 61F ew'nӭ6tw\黅mMG:n$[GTқD_N)(&C.T#!`F3 9?Z?hK?|gƺg[o[I;8^Hx 2'OLR|F-/U2CKIW IE{ڷmdQ%0IN쯧\|?*>waZA>q ż6O!.!|rNkE+PnݓNiwMm{;=,-O+gVp{ƚm3K Kd~u=ړ"H"1 p=xko_ka&rY}y P#[]JYX%|N/kCxǟ|KMm:O%{ kho!k$Jcvria_x{]]?ZvEH 88".Ťcsv}9m^R{k7 $u蝽}RvQ֜W|+'~!k߇0߇~ζx;:OÏ զl <!;&8Bɓ>B׷Hkvڊ9=7"}}io$ou+f(((2>-ؗ գY߶ſ!h((l]aE幑󅀵i<ن-/= >$]_w/ ƐiԒ, |w6o캆oI Y {0<5ghukb;9F "̰2 P]{-W G_G< x+:=v !}67RF$ &&n'[$+ӦЍ?VV-}"x~9|7z/,8 P9*ֺ16 ּe}O]='X`U{VͅF"LF]OFޗNRMYvsWܭSDﭓjI;#_1<uxcW *ɵ#V򌑗ӥ^^Z0&.\~UWy3Ok^#'_/Mw'VWiψ,Ҥ5o_ktgfh;Udca/enOx#ŭŨ諦O5[`G;$ţg >W@J>%4 ⦛[iťޚŏ f.\ڵQ*˝>nYkD鯭u$͕ḛ?3h%ht}o.Kq=#yٮ!I ~ټ9i~#g8k+:keeB f2ȣ`a=)בxτ::?/fHmjcK.N.'bYcT]m| ?xM.smH.bI|׻*.빟iNl\*i7o饭 k$M#77Ƿ]{Ƒ-xwM#I' Q7vLѼ[Kh$'"k߷^藞ujKCV։ǬվgHÈAM0d/J #GH?t X%$vkiL*l!ݽ>PԭJjS#||mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5thNs0<24l+8#>0:/QK?ڝޓom-ĺt2I$6o,;'E̘4iVPiR5kk OoffY$^ O[SkM3_ Œ麽'ǁ4FE-;rj%>$FԼW#L6y%ys jGg=͔K/+D0>/u.`!tXK&` whinmzI5^~_}ŸW  n>!mZoFou{Q|=DXC" 5oVAmD^,th,n-e? kd!VKu30l; u"쯩[ K-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@[jȂU( g] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5w/ *] 5t--+O ?)Ko⿥~-E_?R)7q]>^"3[^g-߅Y-I_YVu=+;(4Ib^0֍g~f ?KNM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=z{O_<<#χռAn=w-WC>O'*8ytO|T⟈^"ԬW7ڶSJ4d a@NV+kFRZ TrG|_Mf{]#ƚ-}5\ : e`2_NO~&uwàk[KG. I IJ435줶Qs&%!OIvo_K?[^D%\ߋZ\_Mk?=/ti/4`c_ {kI5bio 0I2hˌ_[ƞ,#𗋵rH#XE1SDm=9CwƙuTp?ao?/[xw.Em9" =F{h_"0ԙc3yߋ|#y_)SOZ:\x'yff|6$j<NAikje#I7s- 3@&W_8(2 [궿KJ%zۗgG\諸̠((̿m3O%C5hw&ioĽcHf(((ڏ"~|'|C.-fנҭm%WH7ۃ|X+&ĺMDVn/ KbO&8 )! -z?|9ck6xoVoWRX4{VO6/69!|$:H[.5#E_ƚ.k}mJ?2Nm6,6q+fv|=#Rm-?[&Z34/{(bug{R[ro j7>$ҭ>ڰͻXkI+)BTf$-}mD.P犓Kw}z/uc1|tcWq ׆.#-j22?4RDԡܫ_s~})[|).m+>3Xf>[!7D$S_~ KjKx5-Q|K=(JQAeomkbY 9?;۔_C,nŏam$-~ Ęv+P*vKvnWz_V'z\7O]sm7gmGTU=߆" Xh4yn,uI_GeI$S)9?s ~:ǯ>_gG|'ivoBE6nb(RA$p*]H꺯ş $#SkWˢ%^&lpiۭJ!YۖUnko# ,7X i~Maa0V@/2FU_WUIO+7%ݯY8'ծnk*m6_gNOը@(õφ>4{C.Ûۘu[!Q($0Va kؿ&iŏ9Me}[:F<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏK<oLX?&iŏKO!ӝMďnjEC P/"ӝv'>u*???υ9gÖփ78ҾΏ(Ebz1T<Ő&tչ%kɚ|$/GkFb3O%C qFu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7ܤp6h",lT1ܣ&?Rm__<}0.o亲vuygi=Fm`V2*$1Ogx']+jjz@,W6L )S).~ɬxRԼEj~1/\E4x 3GX]6艭OӒ,P%vYB>sxǟh<+>ƞ Oo"OʶEUٸygSfsŗZOmZxk+msoe \%D.x2(#lٸ?7-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@m+A@IaVVBb*ƿ Z?-M.Uj( h79U ?-M.Q?V,h79G Z?-M.Uj( h79U ?-M.Q?V,h79G Z?-M.Uj( h79U ?-M.Q?V,h79G Z?-M.Uj( h79U ?-M.Q?V,h79G Z?-M.Uj( h79U #P;љ2s3AU (<&ia#BT;')ֿ/)B /?E;<\?L#bE 9) esBTi]1ζ3׽گ?Nz|V*oxh?CFi׻OО -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'9o_΅?hߏ>*xZMbዓq.ru["2I ]Sj*W1{'υ|;+P𦃪)/1-nUƝm:#DE}!x○<-x7_uKMsq7c8ԮT}|T+:/?[/_τ)sCh}]іwKi!4*Z ;8$zA]_ s~ߵZ/ë"=BFu_ A2\}]R)%Epц *mʑ_o8n=o[x᷋>ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F8<;aBS|[ķ:UgOg@>2W1"ŚO/ln 5[o'^kv !*ZnmĔX1e/zG>5{wRWZ.ۆOMoKc,E*XkBd6A_^ fZZER^D sf!O0iJrLE+ݥdӳ 8?{ZvZY=dZ?h{%]+^e{e c&o67(h%9dY9 i:/|m2}A=6E5!&w9/y;c¾&dɩiٺu?] m>me_IKe&x26ѵM0XʞlkIJAo&+e`Y UGg.N]m.h,M+٫3WROǖ{/?਺ľ(ox)u= ĺ{ڮudӖ9bk82 JW/~ o Ěx6iCDXIm"[orh*,MtwP_ӤeivPj,j?,5;-J7oKic":w{Fdyˬl 7 |5m[~+v7W췥2kD`]}ܽsuߖŴ{^}$_g~)WTIetK+6I!)" qi e;2}k| esy+ZkFC?g@p "w-teGL'F4 ӵ;mRIV2i縘Cs<4d>1"H@g)gVWnVouQRPQEQEQE_ſ!k;4b^3VQEQEQEs>#i͎-oQ% q#T`D6U!=Ԡ4>5קqO+n+UY#Y]6cwS^G;N/S=r B6x ,r6deSga' | U Zx~xCCn|?cgyc7ZZIiiXV2*ۻCs Nk˚lSkn+D_kM]nVڣ}^@Eadq Ǡ/"/ >3Νڽ#+~c~Nۚ-c2Teo[Z7>v?mnlգԥҡ edFrFxdeROKWVRH {Q_l>.5=wΩxKcwGðZK cm+)}CW/x▿x  xsH χuokN[;!H۱-ĉ|2_Y3ԚVW~㽽뮎)8ǚ״uv?I(Š((Oo ;WëVMogkaDjWw!|K5ݹ3?m o_>$x ~)-lu;&Td}{Ych\A4dH]_$gHua[N7pZY >!7)IHWD>tD&3IBx$=[?iI/i'T73hM :z_~;efȯ+F<~OWt+-??5[o_QT7I)5XA!,%]SqJ$zN 6> cq cH`š["r,wY<{SAAoo/өI㗽[xx&}D$ǛeR?1T=s:9G[+w~_xM5__, i^i6zeΠKi3c$K;}M|_w5Ae[EuHn%FӠx4`XYİ3yȭI3i]tVZ]cmm4;z_{Rok{&}'E~8բ).?b1ΝO*+i>Ӫ=#BaOz/h? w[gS(.i Gwmv&wpkgPIOIy.EQʾ*;/Wz݌$1xKG%av"iv-6sBKR^M+K^nɫJ4nVi^{^jֶm/׀ψ{{k!j^DͲV3 HJ$)m~|[8|c\Wº_<&z ڥVDceSˊ~Ϻ߂;o=ׇiwZqE~d~l.[rw8qjַok}rߕv>m/Ŀ|OH-W𞛧sH-%, PlYgKOkMC{ Zމ8ER[I.l#pH|)O؟]}Q,V׼WigO%ך6a-L6VV*2$% O,]7ᯑJ)>Vm%\__Zoqi+h]k6P#J$oݶm;ľ!'hgk-KEmiokhVڇxgX8^se?f'_y4߅^ Fw/TK;}4^ecoSNPMMFR7I;R5ջ꒷t~|ͥzomd5-CKxWYFa9R9m/Ǐ<{o|}O#E Ox), **0$|S|>)hPɼ5}Rjb$#95=H^ x7'#s\H?o-& JXXq0Sa/Kߋ_kFbfO7~$՗W}M^-3OO`O wl,5 E'OiW@Tg*gokw5мaoiE/cv_x[uO(I-B@ؒ,[iGM%voV^a 9^Q7KWn}\__Zoqi+h]k6P#J$/'+M(ݿK}BM xjp{c仍X8n\ ? :E48>ټ#"Xtvi}&x 7/^M!G [tq&i KkxW..~c7ﳸI{I+ieG+}zn~kixJN֡3*L+2z1noxkú?S_R eKHc/ŅMDƠ9J/uσ< > ]kֱ wV6V() 3BbYcCy7O~ xz4 ~"{1;/d}6̍ek7tkդ룽mWVqF>axG-o[oU}#EJȖvDay݌7H+9;RQniɧ{jίRKMuhQ^=x? eO >&KO{ŋF!N7s5^Tw7PmBDJ=TdmPQEQ@Q@Q@Q@,x?~&O'tZy?ࣿϏ?Q|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwQoi>>j^",|=Y+MKd&6yUeʳD 1gxiߋS@/.<2zy{,&G ĒAp16W?Lx >(GWڠbl#5{&@PIFdL:V; x?śxZhw&tR|jL1MrZr $5#"HĤi%/M]mRtn$һ{ Gh*kmFQЬm|G<{66Ɩ40aHQ߆?~!f|G{.t%/-t˛BMyEɥkI!jgnI| F𮑫k/;5̈́G.t{@[(&{[dԣ㝃HHV^I{xjInu/B&w>w{77W1B@DD8cQ@Қ3}ytN7ZV5 zw$:0W<6oCWTqH=bS$`̨KlwD  Ki'|Sc+O&O-E/}=,ȊK[RE-SMid5=S[73E=A[nK!ySL849MӧDwzFuSַ׮wb>3iZ|ڍhv(TiBoZU xgNŗJ]w,4NkmuTm8yBe@ѴlL~=x^>+σ3G5/ j1\٬vWfe-@<$R+^Q" _> Fi5l$-mwm- qS5 s"hYF}ڿWo$o' Gnk+ZBhڇx/xVZޚ[XviZ]wm VFxyWQZ<wS[{ MפeRFK%PUW̓̂S/A %_i⏂#vźvFT5 Xs ,x3~R"&sǦ\ʥB=ijd'*2kf@3>$RƴwsxeEڂgo&}-t⋟x@MVlg/j̖!)g?Jxq-JMMMK.־,X'³̢O` _*5dX˗zevW ~ͿY)k ]L!]WBdN#:ݔ2!G I3[}.~ϺO|Gm{O:e*ҭlo,gn a cDڕ׉oS0C9mbq$Q#1 UjXTN4.goKE-Ri;jQN5ӯɷz'fYo~>Cuወ ČO*ԆQ6(w*sÏIf7.c7#i1FL`KvwR(e_GonǕH9 £3D3a+>(5v+|34x_΁[46JRYbOpd8=& A<)}X_< ^mo#.f EDZ_V>?hƯ>6x_ƺI>m$y  U1#KGUKKōW&Eiv- \70B#|7lG*Er cxoO6~)ăJ]RNT-4彲mVH]4pҒW~9ʾ_[mfZ:O\}Xeb3HlLJc9FAKퟳORt/ijNZi4.u5/S)yx_48;[wvֱE:ͿՠL2J!ՕBE<3hwnAin5HvN\"W хT4W|mC=ھdZ,VZ;;v͸e򫵐 9.|a\c7 Goou#6-Bbd;h ļDG̡NW~Jvݬފ̏7"r_=24Hv]e%w3JwV66m`P r #74.GX&$ ,:n%v(Ye# |P>9ޯRX!i~4dc橷M;@-lqgZG!GWM:T$5"b\4X Xl\j8m7w9_ʚP--=?7|Z~v;;i/d]VI :N<]/c#H|+Ğ*4^iWVZY{i x1"DA59c!2 K ѵmSǟn^[>ӧEcGK^e9Ve=myFѲ^w^"9ں~w}k7K__ǧU˵X׽_,);ɚ7PHȍ꿷֡{@Լ'H!-4>ysZ573x6dX$W-uIozoc} =ib;ixaheF\[ 1ҵ|D:}6WI\ijwnc,rF9JԪ2coETšޯo[N[:n~o5* {:> 6S<@R#]Ec]b0Lѳ}''?J|]ux{ĞDլDl 6p;.."&HHtC1|!Zx7ֺXΠneeQu-Dƨt߁kٖ<|Ǫ2$vbhqcQKۚ{Zio=_|7M[ۦaA4/BjFx^eٺ]P+-d y4WeDho A@=:ƳZb4{U7}l WQhD2.K藿~+j馛3{7c}fhL™oD$y[W1χ~1Ox&M7Su9|a mk"eU)J,Fm+ww>kKiiDyoﭹ<ǟZ߆? #%|IwGukzENșuV(J?`YZ߸XHo/Zx/|gc1G*MMKB.*- WCl3K? x'/xj?hwTґbg6@t(XXؿ[K_Nψi8vj7UFXy$wUFxߓ$ggf1ꉣcIK'wfS2U :kJMEwoGfnpRRw_EWh5 ( ( ( (>ZP'_sR'?q_?|M?â|y9WW_#\o&~|,l;!|V*Ώ'~}~X+~y&/0أL'z?Z5ɚ|$/Gk>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I4^_jDZHYbB$q0\KX)0ZKƟnGu㏉ix<_YKA2\4j.D֓4<]ջ$wJI/OouK?}}FB ڒZ[\[\Y!G${~9i|ƚeZpЗH.o 6&$u%&؟akC><D+uO_'4Jyࣤ>QXZ:~;t/!?_՞a?C ?>ؗ 5Y߱GO!쎧M/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=zz./z_"O_%ukxN?onMG iځ`f"̖UC2k 񦧮x[Xwnn xZ]h`Pɭ/.!HhWa+߆:xǺ|9dlf-5Ůagm9rW |Us[χh$ח?$mͥͺ{krL5dHGV⧕ڔѓR[WjmKZjvȶypj&7b$2tUUN[Nމ|k|U[NYkEY࿅A-HuGvڤW3Z\A5֡cb/fqa/X7^k?؋T=tsZԴGKۛk?mEx N䘣 +gM/@:??YxFQa%-Ym fC$L,ӾxjR^[lj.;YxmFY}EB{Y-L/ @ A ƛyXjnŷh׻edjgFB_O{lkDFW?ଞ \oைmntյizZ.f&nfTMkǔ[3F+d~Uu? #nn, k-:c<]eUi2A )ҵ?'ΝNϦ'ĚŖfmnCl%הhxF4) )ern5{Vxb]CUHݠh~yC2U5Λ޽kn[yyMRuo;yoDT->XzQu3NtT4_3 5$EZMGt.}Fᗇ|]474}Z#AQXZ:~;t/!?_՞a?C ?>ؗ 5Y߱GO!쎧M/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|TS_ x#^4 sev09 M& >|#Og co>i_a &.ݣp$`z׷Ϟ.^)_|=Oi:W2[rI*!!V)畉%Yk؍\y!%Q?yWӫy/mtkū^ڧtḛ?11P~ڤdPvWizٻ+u<|l95=4mM/ 4N`X,eeu2$ z>#𕹻L㴖K]J#H巉Ǖ=N716 K ??Z-ßmmuInzF%0#.82Oas]M h[/<4ֳ.%kQinmT,*x*OUJ^zI鵴Z# ,BX6ѫ:{]}Š(O((2>-ؗ գY߶ſ!h(;~x>6to/ծCP6mP(ՒH+ -7_^o$^Ҵ}osymo۷hg- G WTW$􏈟ofmmȦS[}㔝Ēզto'/.fSp[xCy_hZF;A|^[O$+4jM#wZ;^j}ޑn;GxAtMi4дrN`MK?/|/}q[Ӗ9Dou #(6l`]lk/]k^]u+JF6"M]i%ѱk+,T*C&TaQvo+~=N)z sC_R/{_xZu$KOx[FCwej,b4̣_x` +[Yծ_Qo4ZȒb }]| '7'eoax?H햌} Vj(=,#Ȍ gkoGź.%:Mg jj63_,&ݿqe#B8kNDm_#YԢ&+{m=6'?o->)| Xi'ý[IxOX]$]V"$k-)c0V$ / ??|)qxz.`ãj@ⷽh㶽0+*ZW c~|iۿ`kGyz]q3/3vn0|:< {?iz,.;]— w3h2ywPUwXu{˵ՉnԿ~}&E.&A4š`6mnȱHӴXQ;=#iR[2iwhΣ"fFf򂢒Wxo454Ʒ,.qvMOMJӮ,綎 &mU'2Y5ڿ:چWwO<6xPW:}[BXIgQ}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ+GįsxJ?]|_ hzn5T;kw :~<q|?~&|Ifx._&`}bٚ2!8yaI!2O>\k7 xSx=SD˚kkHx;+L l!gćS?J">+мK'ei:Χ=KrvYMq[FbXk݇o%N}owl5y_xM-O[!|Nx__6럈O w% -7ʌJw $2jl|ugmww/: m.'kZef;7Hda0)>O'x7_ wzsF|Kq=)4[HPyR" ebUψuZ]Xa&mZEoif%51|F=Fml;7N5omov+\?IEx~%ZSӤ̽I$ndeiDA[*.U<o]OWk6>-mN]@]Kw˲3%$mbP~D~(At{[cM[8xΧj- 0ETIl^Eb߄KF5k_.t{[wͲhZ*kW㴆6!KM4P\FVzVxm׭=[oxSlSI9O{wo+OȚKwNWDʖدvI~}-_ k~.-5K=I,JţM2;:q6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷw~џu߄>03S[~"a1;_DRd2%CX6wp*ƚV<9B(QE (/_LzZ5kɚ|[/XF ( (9] 5_ xF>jjTLlC;wl']Ҽs 15*hLj>]5-cϾ4[׈t,UU<rkEoh~hndҬ"IHL#Ug a@Q_(~۞h<]P|3x{UwkP6*Љ]N|7*#DbƕAfdV1,y!TWՏ,[m{'}kI=^[Z_Z+?w$_UόR :> ƛ[^)<0p$m3/y¿ff2ծKhG{duש>o$pCv1N"]凔e8Kxծ^%kFGJw#:ig࿆5΢?nOOĺ)|7BH]fmWkZ qn"1| ~^|'ӴO ZKo%2²m"h"iX2.O9)Fj >Uޚ>秈ӔuWVͮ"s?ӭn<k'|1[x#RfbJyvTphsI6DzRc'r_8޻Zͻdڟ[Q_/%~1]xAK.ڌVIj$=U2ǹhSꟴ!T?KiUu[EׯS[uyc%r5m Xu%릏m'ٴSXlj}wE|;{_ſh^ 9As{}ǂ : xJt:4-$WP )8UJBW}E|iN?hf Ě<3_h=ݫ-jWMoK `lCcOy7?+E-:6i] ?`YWAdbN+_:ogtT=9k_w=Ɠ?N7ƈ#Ɠ ^xmjɖ-I.3 64>KUƴx᾵o x':֑X۴Ul-l_tTe)&#*oiOj4׼oevࢾH7 4y="m(Ѕ%xf\7F̌9RA II촟l2| (Š(((((((((((((/N?â|y9WW%WwO(3Oz^[(L](пX+~Gб}WemOxG¼{_Ŧ? Y~ӡ5۴~eoۛ$*w*)f=+k|3> _i=HՠPQv-FѤ7ݻf $^ig-kмG<;GO I\91rn%]?TԖyNvDZP"mXqJ/dχ~%ju]>%߆5E-JӭV72BPGB4}舯I:}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ3K<'w4}A#s}c_jq] F{v<5) ƥ3wG~'iZRIhCl5M&-bR guX$d!vP$<9߄>})kڛKwܘ|(amG/&Dž>RO|?| :{z{,m"@]RNQ6ڍR:=,n˜sSoiSмQi>+"o73! -!~9x^x#q{~2&-߆/WR]Kv[Lo%fk@Ue |GxV; hvqs ͤ^U=Ķ[Qko+$K: 6oSֲ^0[)KK{X> b--,C+ɍXRbiѧ[keg noAJ-zj/[Z~'x gxr]J<)ꚕ军oqZuih -Ha(Ҫ/ sY>_ l|Mb]/tȼK. 6q&l$獐`H+ ^vv/nF5@w<-m>Ou*({qdH{yx <_&e,ZG▓:KC hu [M{i OPYSQ2s+IՈuʖmݫ+tZkkI'ڎTƦo;6/+ω~3S"mWW{_`#8qWW+jk/͘?QhMoC't}ci~ͪ2j2]lۡ-ȅ$ھam(u??K3ko- wi5wggiy7x,[K > //h~ wqn(vI4$P[DX2HѪD|Hu/ C,iݼpAFI$2#lܒ,K$+g&tܾ7 rw^Z#Eh:|V7PY%$;,Y)|g/o,m.nnn$cP^Y]A q* "{╯m.g+hM&VW]%th߿*QEy&ioĽcHf>-ؗ գ@Q@Q@ | <ڕ`IdtBQ?/ P[ *I[%=Bg|Zq[[vɿVV$d$쏜t&??#ķOiм;xb-sSҞ\)t Tna9bMo^h%]rQ決>ko8{lYGav+%7)s~œbb6v0SDN7~"}hd°k_8c6}>Xj\oƕj-Ķfh^{i !{yKDEKrV^n9dZ/m<1kowkIDyI 1ClC O_ icះ3xRƚhguCģI% (7&(J60H#?AQD7Ů|^[Mu[~G ZZ˽;6I{`똉]PA}S-q|T7:&'uҦy vr,D &m\w^!ޥh]̈%Xb 0 F}P/X?s|~cZEEl܊OyXxhCcNs-xr"a|="ԵI{W&KˉgVGGd1تyo `/X?[Пg4Z;f |1< xuFNޏi2ia{ZZ,7PNȏ~d *nExFD_jZi7j^$5}Jx/[^gie623]VPH> 7_T_ UTdԹӳ^Ժ+i(>0kkwh%4=E$Ko6ẄЀGڥ= Ҿx3IchVqi#$ kps 7_T_ UDRj:]v(_o `/X?`uW/ 7_T_ UuW/ 7_T_ UuW/ 7_T_ UuW/ 7_T_ UuW/ 7_T_ UuW/ 7_T_ UuW/ 7_T_ UuUxLvzNcZ#5QXb9ؗ 5Y߱GO!M(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157tˉ %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7<#a]ӍF\E#}Nɒ9ˀ0#o/_4~-Gik'-JIŴxu[Y0#1L~}m魯k[Y֝4w}Pu?V5(MG4NIq:ؔV@roS+ $mvV/5bVEٹWԤo4 +H^j%!SԼ'{> jRM+YjZ6jְDgdX|mO Gs[j!1wIp:7;,`a5K/nR ^Kk۲}-ӫE=5+l[5??k%Smouk.]@֓{nϱ&_(nP)~Ko_O^>"x9i_maD/JJDYE$U>l!k>&AF5Oc[VzP>?,&r\FwaJ`gK7_ӵYC)-{+aJ8[IsF+~ZjFeNR_ⴭ6E|o+>|( s}'Yx^|u)m?Ag+a"8`ch`ࣾsG_ t5/:ufA-ri%kki' #ILmoE,46ִ eOzkwՖ"(ʋ& |&ñoM* WZV~(N ɅG&[KxXB+(6mۯ5mg\梚Q\o[{v?n:| 5Kk[mkFS$RN\\ 򯡶x'U㟳mg3걮ψ׆|9Rh.-㷷I,qG\i$Q$|v׵m/VzY|aETQE_ſ!k;4b^3VQEQEQE|1ԅ.Nk<6w7|P5xDէ-XEek !p?>WíkT. |Cy_x~3 iɮXi4^-şt_^u[/^xKQm[I͑>tֳڙ0t7#+x'OV:drqkچq-|YB^R9E,nI?fI'w/4SWJE}o2m4_?nOOĺ)|7BH]fmWkZ qn"1| ~^|'ӴO ZKo%2²m"h"iX2.O K>h#Uŭݮ&IGy&4q,!Qd(o?=|1|~\KiAQ.u'LbD|7WlX+o"RK Y־0i+ 7W7Z6OWPr!HVU,((Gdo+ |1g[iq^YYcLbmc ?#΀VQ#ߥ${:Z;yz-^zQREPEPw  q7ȁK'Oc07 q#x(w~__./e0ocBۥuSH瞜St(d4vшƩ`@r+rcRtU[Iʚjҋ\R֟\eVg(B5j5;8wo"E1362]N3R, qf?f^7t}W̒D+$pG~G E 3ocXdIRNW'r9ھ|Gƫ諽ytu4OFk{#O ʒdtqTkT奮Ϟm+#IG`YpC's񌞵qt81,vsg['U={.D$źK+]]m.E;nxaѴ:]/k"㞜Փhl>f6`(8p+eMqyx:fqyi _Qi%6CKmspJ#8FNP<'mSIsu=eK!8ٶ*ZY|noƖc{}?N+gNXy+r?:|i,[M*+b)mI~\@>z$*~;Ykl;^DP+,NVmzf}~R=:"/ͨW i"*>;\٠4(Nf`X}@8ShJDF |h`xh8a-^碝NWqԣUXI]Eri飿"j#}3G"g??¾dp#+i~cgeq?#EX:t i~vO??8O*_\O>k5?}3G"g??¾dp#+i~o WϚ O>x_LuQ@O??HƟdp#+caS??a/:+vO????HƟ?eq?#EX:t i~vO??8O*_\O>k5?}3G"g??¾dp#+i~o WϚ O>pZexF(bP"Ql5k?fm~$ִۛϴ[_6e9GS=q"*tbiըk5kikmm,Tp**Fjj.~U{[{p+=((((KJ#_οsR'?q_F%[w(3Oz~w(L\^:Ebњ^^ZcU3YfS=&30أL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((( R#GNvu>|.?exZf7F-ql4 ԹL=v< giPq-)ԧ{xZYVQC2y"#HV?o[C\}iZ4e8pk)_+){Mu/~TǕ~-'>>=c}gxZ!ko-Gy t@%`*,c M?f GtZSҵoˤiw=v0 [I`k'ZIZED(+`:w|Y ΅<iQX*OWw"D-\n ~t/UK>kHrBcm91VrTjֻzz䞻ٔ]mߣm+|m'[o ΡivVw^9Zt;ŞA8j|nugI~ ԣV]7Z3PDO6l[HV atȖ[`iwI y9uok7ռ7W@ [H-$兡ixn˸pr _Z[<Ŀ<)joj/Yɤ,W+խaT8Ha7aYĽOĿZդ6:h}1*,n**LY%pv>#hggcO7m?[ZE4&;!4(Fn cخ$~ <C xf @RKO)6ă|o!w@;MkOȒvQ{_7?/K[J"khWfb!BÕV%rs%h|?}J+Ĭ$s#ixrAfQ@Q@Q@Q@Q@Q@Q@Q@Q@?OCu_'DYQEQEQEQEQEn%_o(3O⿢}T_i?â|y9W[ޗcɟ X'=>)~»:*gBQH6z"y+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h(((((((((ʼ:JFAe}[:ug]kzK#B[y4ߓ]O>wn\tLg_HI^]kѵԥ&T ~ \x:^toD6ŚG`bFAy*O'g4xּu[xnMwa3z-Eծ&,\>!VII-"4˭~;]N.nomh]$`Ol#e[*#j(ZI$biַ>i]+:=}OVk6\in[r-ۺ%vhц*Qgih[EvU)io6p~QR0((((((((0}hx?k> ( ( ( ( (>kտ|M?â|y9WMVcbEg 9) es^/Ge؟ 苞Uc_ JQ8޲6z<"y+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h(((((((((ʼ9)-_ξ9)-_ξ((((((((((((((Ou_'DYa(((((V7_sR'?q_6%_oEg 9) es^/Ge7??`Ɏ^?M+Ј%aUkYfS=&3?+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h(((((((((kXx-=%HIGL&uT,r@@ۖAq?W?j H.?Q _PϢ4? 5G$}}Cƫ>~\(C TAq?W?j H.?Q _PϢ4? 5G$}}Cƫ>~\(C TAq?W?j H.?Q _PϢ4? 5G$}}Cƫ>~\(C TAq?W?j H.?Q _PϢ4? 5G$}}Cƫ>\I2;Kª ;TQ@Q@Q@Q@Q@Q@5jş+O0G?!xNwk,gZE 7) er^/Ge7??aɍh_Dl?M+7ЏD*0ڟpqY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@/x]_7oR'?q_зJ?Ţx9\W[ޗr GgWᅴ#N*1߆Rt%$gqWemOG³b3O%C hwQ&iĽHa4Ch(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>XEsPftZzL??9Q?,?QkfO{R?E_Ua?C/bBb3O%C hי.Wş ;M7Ӽ3[i6\&("XXHP3ҼϢ(go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-go>}z>O?Cހ=O|ftc=-{4b^3Vy|Y^Լq ;eΓu%oh& j #8=+(9t~S4qxvX||ʮnԲ U$sҀ7oF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ M&.66hoF|OC??bhfg8x_ Mkj5ߊ;=ȦhRH\ݰV# iEK tJ~QxOǎ?xNW|K#Ƶ_ϯkR'?q^oRgo_ܴ_T)!cq~f"{sm _0|ȩ~VYQ^iEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP?n_$qtJ~L??99\WbAVa+!xD+׭KwjW(~<~X}?O:x˯v xrbe!cXՕ?C*U1vQEW}QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEecb`VS i?dOUuojX͓?Ə?ojq9[| 8еZ>-5k+$ms46i@7Xn}ҹfGl޷5z_Ǣu;O^6Ul%{ k[y&r3.<1ež#^k 95 ݒلY^Ԥ@щHDdm-݄߻}_D/?oh͓?ƫRLaSZgh5ܼ(df=,Ā$ ^)#`ck,lU pAV.3@l޷4fU~1~x_Wwb:]Gͨ]@c#YV݂mVa2_+軽Z͓?Ə?ok)x-5;el#I :8<G0kNhJwԱ'ٲzz=K/Ɵ {'" i"{c`ŋi&T0['@k'dxZg"׵ =;FѭVF$\1Af$ UO(_!EPȿ##ZD 5) er/āL:%?Q?a?89\W[ޗ¶;QL/CعcfSпA$ncUQ;GoS婌/(Ϸ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (,jWhO27iRڴay|QG#㴲+'VD \³Iu?'|Ma^ߍujs=ށgwmk{[=d΍9,hȒ ۊU/h?@+4;G4ş ZO}!9~;MW߂4(4+}rM|@o/Xawpc\4mՁ8E_.2Xj Mw#xZ)iKtᥴ`Ȳmx h?@+4;G4ş ZON+Dk[69i);vKJ;&IkS-s ' gfjI(_{]|Kx߁&t?52mzr'eX2%DJ=+J*ƫ!Kzo.x|E-LDr:n;K( 2zW_o{Lj(h=[o_iVwdgPκդr[fgG쬅G-s ' gfi4iu>a?e?h "MMm;YM!<ȯMQW(э1c; 9í>1.n+]/?x={Y {RX{ Y"c1X2e}9 gfhD \³I=:zWooʟaOM|BWZC^/<+'J'?q_|01+_0h_QWǎQEsٶW$xV)_*R?Bc?#o@>$k.C'o tf:woN8/o u?3W鬶??xT:wo~_\[]'' -ҧUW' -ҏI+]ّqO?BQٿ?e|[]$?$[]ّ*.⿂ז,4~ !8ОbR wXd;?%m 2_3)T #xbkP:챏 TeeWB?a.>[C4WjpF,ov/ܩ?e߁ȣ.wUoE~I|'_;X#e`9τ%z,~;_o?\"~U|{6v/o uߏ?gg?el[]~!?9l|w:,쭷V?X@?elW]R˗*_ E~vj2."?~OE|-^sQ >~]s&I~G*<]70?G ;p~ %|_,+*x6Ge?+.r['@?Ge7Y-a_ut?e?+.r*/֊+un `Y,?-./ugg/*/֊+YMGeGp\TY,?+/.r S~Q_ ?v$~#sX~8?g@?GN. (%+/.༜/e?+/./?%O_O$4#k 5xOǏ( Q+b'¯ |a-~ v<;+;PkZ8 (q$9~'~><|Juk~3uB8iLq]Jʫ0 aZb\cSRNկ77)+=NUnit-2.6.0.12051/doc/img/configEditor.jpg0000664000175000017500000004553711713252032017630 0ustar jtaylorjtaylorJFIF``C      C  19" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?C /|*о$xzguZ&cgt#NIgv-$O+[4R$K"DP+?ar`?#V;f[+(}>Er2<W~#Ҵa^i:rMs) xדd+|*2QI+|m|-yVVru_eӹq #c@F _? hmt/(O|IiSbto-wOu đ=ͼ1ȱ|K>2S??x3v_>N-VɗoV1zH7)J2paR3Ҝn%ͥhgmoEsG)(Nm_}~ftC> #B3 %\Gk L hO-jz$XmlҬ>-in`F݃d)G\x'W7|- hڶTVe[^KC#$Ofa&Jt*BNn{Jzuz]]_].]|HzC|%\tGۋM?? tGd/m~3X>"Ěm)|9sk:VXj:O$A8f}Ř P|1G4k_F5Q&Ikuni/8'_#|QR:G#ϾxΓx#<]s=m,5ӉA Dj#2g>(eg1Z\xTtm< ijW&x-9 ]Ԃ9Vi-k&f`0**n6O[յ}4};z%~ GjO%~ b ?i;h7[ү5-F s;%G"ʗ V׉-P`WEN#Q%i$ף?1M)8Y];|OeH g ?g> 5z.d`xeOr2y R_q6/{/ Ŀt;`?ѿ?? ;d'7#WhC?3Ra*ig/ 1|'nO߃5YZJg@ѿuAn$S #v@4򯸸fؿ/ 5`܁5YNBHsrE"r3VPPCWtC5OM?d2~ |Gj?dOf> 5vq|®rcta:#gp~ |? R$ Fs,O|WGj_cE~ 4FEI^)z'(vF0}9" qh+\܃5z(F,eȥ}8"?co?E> =z>2GdRy~ +[> W:?#W)EGd5}_c_?E~ 5Ig`:G#ףP3GqN; c_{>yWBw՛A []&^+{mDqM wC$k!(G?!>o~6O4ɻ⿓ W*ys JN?b{շ~>xoMOBl|X>wTqbtmB'3Zwn&pH!ػm$f_[x? Q$:vBn0hvU#`qvMY[}'-kGkRzvNEcKm~qm/&n O{'he$)[ᄃ-?+>g.]èj[ZIb򢤦fDd vX?N2:߉'0>Ew?iTYox0 #pTJޏWOmjpy.ʯ^-LxP$|xm.L5KGx&&xE~tV= ?c|.fk^'7GBeW=G j̋@ǐWģm[T~o@{x{\{rYv\_1${gZ;J>(Ҵ h:nk-jeMm5ťMF>)dkzo%|Mm&gimMa*C|2 s.RetkƖ-N?羁Z'+4e(vFrZ?;r1 TV~96Z[,w$LlZ2~|D7. 6?k]4jЄc%hI$IX19VgRPz߫woهjj1Ȭ+Q7C׌#E5?kY7o;~!.馁jX?̏2|7r)h)U;Ij෎!lÿ֯/okV?|?g[!zT4-DrXW[|~@ARxv?ZCayZ~(eP H$չIHu֝'ʛ[#֣t0=hm%L p ugT _P~|B$։g!>D@DTԲ{f|Sc5e>(D|fp~F $_ڦ犟.M?Z_YƱɱKzLiFqNJ: NMg?0>|G]Oi0<>mpEk̹;Yn #o֤_ŧo֓Sa,>_xC$o9o>XOh^*o-F^?d (CE,vp՚gS?F쯅|Qᣃ.Q ^=N~#o<^ !VHf4,RH&VFS ڙ#ECe+?`(4c~kK?};)<ZM{U{[:]Yۛe{?͵Y}.Xث2?ZV5_ \Vf0͓?Ə?ojc6O[?dOP?oh͓?ƫ@?dO6O[EX͓?Ə?ojCǾ*>x/TY6lww/*5$*噏@ 1 I׊F"4߀Qqc$xj5MMQs ?$kX=Ezu~%[7H?I 6?Z0|OH:;n:Še+ ӯ'~_ߏw [ŚB|;4Ma]6ȵG?eUeo6+s>~/9_"&B4f4YëK1,ұ9Ƿ2̼9a-oOUosj!Bcӕ%I/yYW0eKaF{/4dZD)mDA9BVk}}vovzhL8 -}Oee%}O~ 80|K}]*h嶺QI iNb(U&9Bw%kkG{|K5a=kismjkm4PM,ֲX $|nQZOҍqF.(뾖]^^U_3ە]?`1ա-Sw5/&.dy$$1LH$S5NעEeq7᷊R{{YHܘroSseov&˥կk=~n>ew)N6{$|%=~1gQ:L/uIuWUP,o%Y,j"mF|s%}{^,5-jV35&uU #^rV ]WޗY9QkkhݷwOr*s-uj[ۺjAm#QjAm#Wu?8d? ?毉5毉5~QGF^$h?d? ?毉5毉5~QGF^$h?d? ?毉5毉5~QGF^$h?d? ?毉5毉5~QGF^$h?d? ~L~Ͽ|3kV֙\:++SH Ҿ?|F+8bcǴ++&`|<$\i/ .3Uƫ!KϞ^(?7;ium{džF/zƯ蚴%[r8?lcMeZxO7u?xK׃Yk>'<3 ^GS*<"1v;s?i5x'Qgj3IO k{Y-c!kX2&V󔀍'to]Kψ (5kfV,㽇P^x o"4ʮ _J/Mkڳeu[oG]욳ќAi{aR-> mC&ksjRAoeq`@ wf1~>?߆tԮS?KbSizt%ӇVH䷷A*aK֋4mRID%Kk)Ef݉id?/Ws\.Ε-OI7"1q Z\DK^ɁjLdi^޵#>f$msR1Smne>/Q/xZ&InʴV]_^]L CB3~_xRxzotZizv6SIV1-Fk%do"b+^ >"x~ qt4́$ӖO1m|P 8 ??cχ߳Vqw#Q[UflRiRD<"bmuuv=WV&J~6~^TݷK{v6(5,?kVi?v6O[?dO D \³I@|YY??oh͓?ƀ>SC{x:ƙ6hm2LX`H%q׌瞕%Pφ m,m=FOn™VI1۟68Imuݦ*p==}i}E|L|[jA.VxfH_\yv3iY7.NV?zg>ŎkHֵ]R=bKMyZh֖6m.r#+p -&鿋]=79XrsM5n>բNO(w}b0ց7ċ_ ip6ZBt-r'% l'#o=oo07}'Q-lQҬb[KD(.{dɮeWt]WSyoF(3??d?luuQ2? 6:_N੟!G%r5x<#V5_ \Vf׎'uǴ )mZg0(#qYD@fր=Oh?@+4;G4ş ZOPgÝ:ׇ5VW[VddO]5L+6eH>%?-_jWCꚤ:ܚFo}[{ISj vO5Iu[Ԯ 4 ḁmњ߇0@,IFcUEY~_ bN &e kxzeəxsZ/kޫ>(((((((((mrW#]w?\ecb`VS jX)s][?dO6O[EX͓?Ə?ojc6O[?dOP?oh͓?ƫ@?dO6O[EPφ 6G\ڈ@! ;6kֽZ݇9LC /c,'ue~vxZE’?Y,'Yc~o _p?L3/K[{x//Lß{^^y!EPEPEPEPEPEPEPEPEPDŽoCͿJh.3Uƫ!Kz(  UCxwᦕjt,Qֵ?G, #fy# [ nĐAR¾?Vx~fi8t['5/\K&&Y$c"d,F1:8[j{oظI+k{Y׃\i&t IkK[#x.Ө_@MP[LOYw@ePL;?4ֿ._Ú>V$:MͿ&EG5݀Uyb+q9!Τ.uH/xM i7x|+w^;K2H̸8f~G>x& +6Z֣nxP`s<#DE5')=kt^_O>mq+}nWkXkO]h_t5m:ey_F(w+rv) (ɑEhѱ׵׊F"4柂OI5 ]k:UڎjW!~u1_ '\luS_Yo8R*(1S=^/Lß{^^ 2<^׽W}QEQEQEQEQEQEQEQEQEG?|FDŽo+u⌺|3^_i,v c 3x^V_K6*e8 ̀ր,?kVi?v6O[?dO D \³I@|YY??oh͓?ƀ<3-s ' gfkdO6O[Ox/TY6lww/*5$*噏@ 1 II/z/?|"|xz\ԓPWO#y?^N1cu?_l?'ց!:QH6z%L_|g2<^׽W2̼9a-oOUdQEQEQEQEQEQEQEQEQEQxG_69+?|F R5^jWou]&G)-LD%:H8nRnö;Ey>XoH`Q RmALqg`J61C9D>>'%>#tXn&gD[[VG !%weܡM~v\_wQhJ6z!L_|2̼9a-oOUL3/K[{yQ@Q@Q@Q@Q@Q@Q@Q@Q@|CͿJkxG_69+jWhO27iRڴay|QG#㴲+'{szu;~P1 uR޸3,?w!ԠMv HOi{9a)K21)¯,?kVi?vcҢQ,eM>eYL_?іƐt A-IkX̒0s#_%~y:q'D \³I@|YYw <6&K֘\3y 0PS) ;!ayc^S-s ' gfi.gL/G[C{x:ƙ6hm2LX`H%q׌瞕%|V~4$+GV_:kjW)8]M&wxr FerfGk#2GhloN*7s T/Lß{^^ 2<^׽W}QEQEQEQEQEQEQEQEQEG?|FDŽo((((((([AKW_ӯt%+cS?7q_~X H~Wy"9*,?Pj~+SeəxsZ/kޫf^O ( ( ( ( ( ( ( ( ((<#]mrW#@Q@Q@Q@Q@Q@Q@Q@*|,MoR]B>WCMoRMB1_?C|?%I xuF7/Dӊ}jl1UXS=N_/Lß{^^ 2<^׽W}QEQEQEQEQEQEQEQEQEG?|FDŽo(((((((GiKW_ӇMoR]B1_?C G ]~lx?L?DlIjG/Lß{^\i 8㲉R5@ Rb/XO;+_c4b/XϭшbhLE>? F"[1,_M}l/&;+_c4b/XϭшbhLE>? F"[1,_M}l/&;+_c4b/X|CͿJiHJhC+-`;z('1g |pִMj+?P+;KyP'4{]r-B(o ̛.UL4}w^kIǦnYK՚]%_~>2W,axYq"^egk.ᤸbleҿڦ_:4;WukZ=M藺v:uOOou2eWO~ ]j6zڞ {\4{[imuiWh ?Pßٟwٟw}E|9 gѡY[ gѡY[tPßٟwٟw}E|9 gѡY[ gѡY[tPßٟwٟw}E~YAl?۷Og[[U]-g@coΪ'sל`E|SC9jW#SC9jW)d8߂uT?O FV3_a|J--uC]_ג#_ikhI0#gxG7eA?E+d|Q MZ*bi)ɹMdއؔWzÏSc{U-<# *3msf{}OgWó3L1Ve'PGo?4h͟/}E|L|-q|V'et?M6̾\iSha\'`M^'{W"GdFl?&?_xk_/&fOf }ME| X/WxiTk?C mٓexϩ,gN>_/&ӗ>?bw62xϩ,me? mC?½qFRyĿGd}\oSYUc|3 +qQ_ 60/om ܞt/K:_̃r>r_c`IXRi8Ӈ$p7h?6xhΗ!4?:+|Hhm$> $Gg62Ƈϱ(?~*YM#'??,?u z3 &_}C/W:m{×sO.++̪u0Bfٛ<?g c2 [c*F* jՕ|BQC+W@,ᥱBȺ(n_%P0((((Gފ(xS袃6QE`( (QEدqW(QEQE6NGފ(QE{%Fogz(j='NUnit-2.6.0.12051/doc/img/miniGui.jpg0000664000175000017500000077225111713252032016615 0ustar jtaylorjtaylorJFIF``C      C  U" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?`O[~=7i.u6ubkXb51xdy$Y$uVU^@~3Ο sYbًj˰>xXt,<]z@T~5Ksmo4iKkuMp.Ah^9 4[M.kr^]/eWSx/\ԩ k (&ծIJjB~_ Ai-rO©ehm~2xNB];7~/ELQ_ , +e f+㖃)Լu+ kP4;i`,{#]]kA'BUrYf4qPsmktk~pe֣C))we$$㽮ypf> ѿ/'stFj(5_UwG—zom|/u}:;O y?`+!ܛL~tfae&΍DYkkkךulF [ĖOq-#v×ll]xR}^]ÿ D~ m~  |'#ξ8~ݗ?5x'7QoM6d.s A #Cl\"x3Vx{Z֩x''e]Xӡ3\HXFm*iNkumHFԕMN;֖k]N]`K?A?_>~'-#~\>Rtm_vRje/ڧԮ, >qa؄5zկX3^῏kJ֤2i0c'q#_( <[6yoTRi_}K]tk:z(N-ջ꟰Obc%\t?#>OoF/]4_퇄|9yĒHfWf;k[nm_e`ܒ*v6S 5=#V]׾t l:=ڃ@Zt8^KHe5F`VhO;~i߲MkIqPn2minp9)\?K0A1/㻈u?"v/$ N,X$soq ai01_P[[Ú׎cu#Cik]JF,x2y;Uy#SUݺkz_F0h r7N)9EvBG?Ga ckx ͩh'|koz[rw,qsqpG H`M'&ȟilhl% o4_sĺo]֮-uVUǟ *`GkN88KIB7kKN jԟMipTbbIh\z6fN> | Q7Kg 5zį=hZ_k ~(5[ϫM˷I]Zg$cjr:^!37Â%iOagffe-]BHшFb1N*roK+7hb%VId^}Wkl 7c؁5IM1c? h^qg]~1o^ |q6H-`h/I/$P7|qxw?"k i.C=DžB]@ ፣/ohǙ% PBQNOf[6_%D_Gjw|"c hTom;_sa|KOiwi O= ܍;3G,/ovj}>3#ּWYW6dy`I l-hB[ vQu9b[n-=Һ4e_ѭ>-' 91_ /{6G<7<>ac a -%^)$F\E{.bѹ WkIcȒ-nsN{6WaZeRM_3<|Hz_c GxMV 7fF]1,>vC(kK]_a3JݏF9| Hzww HSII v˱My^k\ľ"DMxj#u*++~n A*}wOH?k|9ƍ{{_V܉mdz[i5!6Yx[I!i׺w'W m ϔܰHEq πIkAv>*| |Ex} o%Msi,)1[0H$~"l h |hX}.is1$I'o7KHz]κW;5η=ӫU[O1%Id`q#ξ%~מ%O{_05#bP#)g;m?11 )F<.Oq%tmks _ 1r劋ޏGk.6N؇ତŒ-j?GഃHo Gك5.t۫4y.# [o<?|!>'U\%H4互kXȹ7 ;9&$,Ȳ~J1m+;]Y&iK}[Ij|*9in$oDl|#_-# -DGZG#_?I 6Ein)Z% D_õ%_2 .d #~}:Ivk\ei.#K+hwA'IӜa8Y˷^~O)5mݝVQruVowIfU}ͣ|> |HzO`D =Xio In4_k,?ju sl.H5RbbVDA_.yxƾΝ;Ӆ bwUnPN['F:lE9J2{1?4KHzGoO?fF,|FiZŋ-ZX zŮYh2 #heek|V\|m|6Ʊ{izr:usi8GjmxsB^2]ȕv8^⟆ |/1ZqYj7L'@uE;{W\y >bTѦ2ZߧRw$%gk;V.HUw?(u;O03Rg?#T>+?bσu ?zEWr[O֘K5LcBX8W |Gjb5g v__H5+NmSxBSM=SRcdB*3a-">@όP|Ǎu{Ub&dHԯah`#*7T¥)R+{ۧFU9F'±7#To|,>|OoFf|+_j5(5A# T 1zyCމ^*]9.âxJ6{It)׸'QujS8{/{Mk54-tvIзq5Fji> 7#Uޗj>-x9D6s[-I eILI)~QQ=k᷅w^ZxrU׭,,&G=w>ʖ'q7 J!T;Y:j\{lXIk4r.3:~wWrFwS~ǟ #ž5S:UaksdFj}[i~4 77-<=ik*gH~ /MaFO9R3zaDiuEg ȵh6AMWBY?S~Ͽ /8}-" /8}-vgL4æ6>G܊Y?O?–S~+_sGը"qg*?fυ'ooFjUD{d)H, }^/ g? _p_ |5 |5w_ٲt'M'E,?K~? H=c Կ 5w ȿpi`Sz?Ⱦ?|w>1Fj?>1Fj硧gz?ʾ5)ٛAwᙾ1FjF㢚_MWCY;Op ?5 ?5w`CGz?Ⱦ?lw?ᙾ1Fj?ᙾ1Fj?}? 3|(;c ԇfQ#>E!kc'g4|)>|5C'G 7#W* 4짚>G܅g9|-^~ /#Uig |"3EZI9MUKq)WAgK /"|hO\=SK|z?ʾ/ /j3CᲐS|kL~~SW}5h_r|w/9?wp$Ge}-o~ gKC[z38 `z?Ⱦ/ _e٫AG 7#Tr~͟ 8?d?ѿ{FsFvG*,?K:qZ:|!21TFj7z|"2?h^6ϥ??)4}^/;Ku/k'tEZ5>|kJ~~STg EG܁f? _q'_l|%5'/"3#2ȵKH Iś4G܆|w̭~ .pZ $œ.F7WOHrM/U"o~ooF5\?ѿ$  AI*so63gGj?WcH?#W^pEM9xz_ʾm?e?9~w1\܁5MlO@h]pON1__3O#,A_,?AXa10G5?_q 'gR G+'O_ X.C*UDeA"c{!G=#/icxASi5?~,N>u,}ĖH8`.ߘ낮9T>.̪*mr?>|=#ϣ#=#?e|7?W?h"bs'Mz#M#]>mA#u&;>n[[.A*} <ܶGV=='߱7d%-bD\HxJu?60aW|v=I߳Wx\?tN xZ( `$!_UGl!;$]S!P$O|#{ŚՅ~+W/|Kj <d1}Ѓht-XLbYM+mt3n?fc'W> ܭ>Q"_@8__/px>f:/}%VT6(W_#FȧזxgWGNO}wӴ>BE:XFNs4#_-yϒG? "ᅝTo+uGT(a/u=z?߶ȵv?d!''"ZgoČ,GzWAg;#F ~/&,h=?0j|Q/DD{~eXSob=^u?<Ңta(M7GX~5MI ỖKm]X+Քqcϟ ]'S5O7$2x~OmļfI`VȀȏCx2[ZHm/b.&hHۜ2@pg\;{=aѭNMɵt~[{ 1L."#8qSkOGÿjfO>5zM0-vg]'6ZDH-qJP+°SnPanL 8_LcQ@5=bNm_s?O d،M(+G_7=g owl׼5=ǟv|y3?+.bV?3Glij1%s?s4L?m/6wըO>9Qm'g*&]xkMk?Ïx^-k)f–Qm~&e_+**yb% 5BI!Ӵ_vaCBMsvWŇOڰ,3fDMZI)i8fj/fyRѦӳYyۋkE4ZWtN\X];k"_$"?VE W7'RӵMR"M_A{˫ [t 1*Ha3_^Y~!H*oz-| вk}Ed}+3\}hWJ |-jn۷&ɹ6l5ޡtoުOTf#6 ۘ]=x2[&Ѽ=2ۺ@Ey y3 @?`G=x{ "WkMΓ#eIvSӺ+]/n)Ÿ L񷎾->Tm|T4 l7Ime[(٧EAwSv(< Ğ8{˭K[u+$ d8al*95?J># ׇkUмy ?j#_^MGFe 5-߿R-.I[V쭲ݕ)~1SR wqk;gom_-̨hdfR>`@59ieH,w9$JZGrX ! XDx[Ҿ ڐz-CyM?[SR{k{뮩}|wRg ˗KK%emV[%m߰ែ6GSkh:d֌Ɩ `Q>1 ï_8Qb>F=Zu}DսeK0. Ǫ?"kz/gi]Fɴ{=^y{Roq!V&"+t/k_ލ2[뺖jĖo,_"X&rSn,~ LN>|E֠:/?E}x{F8x2gVN饬։GV.r$JOmҿKɽ<xk)_u-NPunٮ6{հYxk{c ^/lcϊHcnO {`O~Jl`2Fy>u|C(?[W5|[U |KTi'oշ՜5k1^I$I'D\<WUuwy৻8D2<,4{G?LJoUŰ? >!<;ˊMᚴ8e_Ɖi}_ź-Ǎ|[ox.moy<3]c'CIPTu{ڷmʶ.)thfPg xwVW_dxC_]! /ŸyZqO'֗&g>?Tyď٧-4^ U엪Wepu˻ʽ@ 6F1O?_>!֖?x2O=Z8 .z˙{vJ袏>~?;S ǧ~yKׇmR$XG#_~X#~89DvB\k2ޤGfZ5zk'!I:]4-=ą EAU0ŃVxA|?iT:.OSQQMU%biwqA|v8G9s}zԨѧN0n|3׭[ۛ_TQKϧ+Zͪ@BFF8"4?N~ݫO wqy{m ۯ kTѼ!4V׷i#E{BĄ+bAŘu?BA "h?/?ᬫ:R+++%%%k5oy^ϻ=<<<_9BG$m'˫ڳٻ^IGoKYd yRK!ns3@ ~6CkŠS <$K 4!k)6lvJVSο[6Ǎy 9]ҫ\/>|E-* VJѭ.r}:Rivs5ڤw$[4{O'O~h(_ xZImDD7w,Mh*$_""_3bzG %E|`3#JG5ĥ.I-g$2xbJ436J6-(xL3V&ZKՐ\+}[MI6vIxQx/ፇ5{UjYڛ9u ^;UVaNߒ%_ `|)/vM^+;FQ散ĭ005Pٵi/Ҙ_iҺe/zԗN?e({5A۶^xuixҮi6WCiyba-Q`^%R*έKLx ~(w>'osOTId9"$&(=3sh_im4/Zp4mmM+Su>^ە}Emce#*WXxKIj6q%O R$n)W/ٓM>2-oX:Fմ`h-B"..e19//P^7<¹փï#h?n]_-PΜ]7\iZ7&'▏4 Oi\ɡܘ3#<[o xU+x-kI7:|iֺtqm,[I%)x7SWI%дOUy.n5 KSe.%igQlh¢"*cҢ¾3|> iҮ.$^ËgUJ/??7T%c)+Doi֓?74ZW\qtR3/ERtV ~0oh??74ZU}r~dfyKZҏ@aDiG(7m>%aS SZM &J>G0U3o/̿)*X~xJ$iG(7 3o/Ŷe8fS>2k]a<+? kҗ(7R\|K1x f寠 xr>A-)x/ғom>d~Z w׋2tZRxte ??VͿ?oGuem/ҥ(7R||?yk(أ7&?J?/_A/Q`U_F)RtR ²tZR=&?iG7_<=&?Z?_A[_51RtQ/E?1Z?B-i}n~aD(ꠃLx8!mZ 1֚Qo?||?2/PګMj1Zo7/Y-hχ5U9TOOGkPï>@??||?fke(<(u2|.-֢5lŷ4kG(7k>g(haEtOwƭ4MS>6#Ϗ?馃Z>GW?̓GVYA`e¯Z?<~@-kZ4@oN=&kG(0Inghڦ+PS'?iQ|bI!mZ?k>fTU+U/#$kG[O#?A]frڨ*:(IƯ|5?ZO6~ ~?Z>GW?UH8^|nN\xh?Ew0#ǏZ>Gj "H?|ok~@a]tZ1Ov?kI(0 f9U{z:E4xOci#mZӇgD?kI7Z|?Q22Txcci?֞/ZԼU5f\˱8b9мf?|C?@H?iw3mZԼU6\<[OxKPodQES=-$Ic& $rƎ7 #"ĩOx:uQ2-;-Z8#A袺tdK>"o֦K?D?ְJ-ߚyap*-4/_c##k]S?lj5.D*HSZn/{;U |~l~NRsL5;zN-5v춌󓸷8 ?O&U0? ~"OF?FS}hS`q 7sf?|Fң"iW^_^:N^͕ցǗw!H;zi( O_#@eZ4*r~lT0c^.Y-*>}5H#Ɵj?aqS^׺$1\ŪjK`)5nCgi^+MNR3xiRND9l>`¹ӾE7im߶TNUWYޟc#wwc(?F~*9@bbfz ?ιJϣZCM~ '%x;n/o\|A5Ver [}?X9&0Dv!Q6u?ڼv8 ~&$-dPJ :Pc"L.(I8{z{=uekO)Aך,i>~6ZUwe{OoFJ.:KD,Dg8@U2H Σ,. rѫQ(v] yWwѼ*uRѮu<1XR3aW"xgE!k U~0_> wqcFOАuOođmxLX#Ïكľ6{|t4Mg]bN5ŽܯZu{뻹rJ~`?ok&Y­\j:}$յ9m"'MOf0GpyTcI7nNM'fӵY86Ms[M>gn;{Sὴ&M%,~\L̙Q7zO-e??ƾ7_OZw_7.jDOh:ND"[7M̟7yrg%~ M^o-'׺ћӵﶾ{?e-'g7W:w?t[[{c>Եbg{{Y%eTub H<׌6k5 ZxcI5-+xW)Q8%!B'BQ{SO+/t]oS]qZhdqc,kysknRe*XX>-hA DR|K6&JOl.Z3ojsHg-UPĪ#U>UKoK+;m5ӄ[E%n#. l|ia\!or5υH-tUZ\$m126fD G_UE+]MkdkO ›(- @ʰĨcJ:דƏkUo \j̈́6A1edf>hѤO/ȼ=ok߆e֭QbFxOLuy.7tMov#Eo1$<,B¥}_/˳ך鴾kJJN[Tz5-w\OٿOx^.BϦkVIabWwx.ڶ% ""kN6S[WH`$tZ\Vh]5R ׭",,1q+UjQufvtWWi4{>T+mSt7ַ ^=#R4NTR8bp.82nwFh+_xZX֠ԡYP'ӮHIopz;_)2H/M{Z?Dqxӯ whL=d/"HԜ_u xgVOEKkbyyɚIeN̖W $la٩-].Kt^U&Qc?\#vxSZ4o p[]sw=иwaB˝A}k= |:|')Sc ~%x?7-ٸW$_~ӷ;ٟ8֡~U_xK:0m+ߺ.S(ǃgn5Sm] #kKy C4# "Ÿ17y,߁BX6/x7O~cQӭ.|ko"$Ey}|c-x# ~і"[/VTJIy$ztzӡRqOE*umS\wz+cmFd|u_[٘TGBU]rB\Ry/ 3Z|>,>ɢ7Y֢X!{;YaFF8Q<{g u/ wguOIm]{(yjOm3e&3?*|lR7eʈsgq$m>; 6=oӕi-Ck뛵WߴW澁_1n=KƓ\= IO xtKdgFhue@qZCrK }7ྷ7/j>*jpx{;n oYX ƕ.x{]IppϟKs$ߕRnreX9mzگ&IRSkGq31¨ɥkY@;S^r9N+TWg~wڳV[kj6gTY}[. T .]2Fϯ+߅05Lx_x~މ~7uiu2#1%GEle|<ƫ߼-K'1󾝱ub4QeQir76wh/}%KW՛veȮkZ1y,Yũ6p s\Z#I(0**\&P^2F~oK;LI(t#Ↄc{ YfҴ𝌲KM*Q,H|~嗍YNx"/ ٧_x{:P[[wQ-rդxdDݝM%y;Þ=e-"<[z_{# IƏڵ3Kgr7HM $ #YO*A+BWZ#!{:?5ۙn[Y;l$ŝ12澨x]_ޓG5i+hIy&sJxKf{kh!GmC,(`f>T9!0k#?錄X嵚xFXeeIa9QxEttee_=St}ZK-iDP<[chW,qkiG8aGx\M̞5KΧysj6Z^i]Ɨr; ) -CSZnKoizɻ%}jEuw(իCt|Guriнf_ +Xu$pȬŢ Dec㏊Í_6خcbIseʹ͹ʯɌ?O>5OS.~]j.mMW D ~uMW3γycuQnKB7_w,:PI'=]>u+h%H 1QKLJ¹P)jd%??? iiWio|Ie&}W@6i%TVVcndڬpt>ot}g &V5f$0($|;ŏǂ<U=|-z &Ht1i y ~FG)E4xWt>3ƯxW^!|Ni&庻5 &ċ;*iQCl#U6Jkqļtީ4i-5+uMɫ?4KdsLj|kNf ⵵6՗OO5WjF/ҪV22l|W>> Қu ]nYx]b,ǖbv'D`a:0sV[Kڭk_NDIoU>襯 dYඳGU5Wmp1Yl9sԝ:6838~ g_O^$,%jzN$FwViyȁV&bB׫hz嗉K=OLtFf'P":AW&K/ #j?jS-NA#E4,PG":UV~bi u߳ύ4GXjr{ORM> #E+,bKЫ}x1\=:xxfuh5ΌK,-ɪR烗>|v4UrUpZQҹo/,<5!Ū%_ÿ6ڄ heˊG1UiDzW~~ռOKytGQ>$ F[kg,-J#̖4A;E.'ݿ qKm[Kk|ou(*HnIgU7ѰyVF*wpY[eŨ|rƧ:t+jVFy?(-j7E| zg«_7_=_|DxWo fIrdM.HgM˾s{-9qmOo>[GVoŸZ]r8ew 7/ťzOŝF?hUͷ +Mq}u4*4{o74f86fdGkvRwWiMEQ?i^Η/ /=)߰ǭPhnbKج1U!73K2r+ʿme^I-{C^mFhmQqZhx!k EsKd~k.^w{z}4u/L$7¹J%I5W.Bh_m8|gރ cㆍ 5iy.iu"F-˽Y4hʻ2#')F7ל$ݮ4g%65ʹK^sW]í{Ş#4WSF&՝ڪXj麌:owlek4O7+Ad]-76G~*~Ck ڰįmy çؾMI|_!|SoaT4 B[k~"N ռ~>Տ(@3qZP]wpXm{7ի%[F\h>ԣexGOxnbru%zw Qk ѴuY,VP#K;I&>~:<޶IME>MO}[ٮw<;xƯ>\RՐK K_48ģ/I(m8Ƥ9+oٗ*ZPM{ 濱m?e?Akh6W|% +NF #哏cSQEADQEfEPEPJ:JQP袊(()GQIJ:}QYQEQER>(3moJ ӆ^^G~~ Cp+l?"yy_C'erm/mQL?:ӾE*߫<?GgPxpY1}'<<6 dՙRx rFq:sYg+hU_u. X\͏8ٸ v77/ʪdž[FO\h ?G^+V k;j<3oa̐7zmcA6J}TLp,O"/%zrW+oi#awhawk/3X} ϖZ뚷4]'I-CS}:$#HNvє(u[<+J].;/7[ʖ7wRimr$\>Tx6CÿKG6CÿK] wį<{u{yo*Irn[k?i!xV 6kOCS ۾J䭎TowwwkDz,&^oʛRjS,_vsgs %gs % |Kĺg[6~s,1dMnbH"iO>3ޕ/_5%0eQNdIQD"p3jTRUպ%MY3x=p|sMhTKHgs %gs %O m+P|/moMl vERI[J,# "#p|z푭u(,tɅභf.t"HJ" ~&eE_vvӛ\]$wM$>6 KʾҍQߣMg?~Z?g?~Zӿ`oga=<dKxAӡ[hh a}Y]UlC~>IP^Kw4VV3gBy{w%e,at2ͬmm)7D$[O(U^%gc7gs %gs %3 REh57T#b],WMdX@$Ngߌÿr>Ci^-4o3OpY&0ߑ>kOeB8s9J?oxv%fR>['v|zzwG? ?Y-? ?Y-|%+ ǧź дm-͎{k9cO2(29>|Ai „B%/ KhKrxӒk;[%nڢ`XPC qԛm$ފGF륷4~"Rx:FmE-ZJͽSmYj} 9 9^ G/u/x> kƝ ̐4J !6gb_ 'S<п\EcĊā&Ip#-)7ig]X|oukuumu[6CÿKG6CÿK_ |=kiG/< 6o,]&m>D%!t7ʬ<mWvx& ŶHOldd{a) G,y)hk *Lf+wTcgFݥ.)$>nYK `^Vawhawk_~~S'֋Wg+ma3dlmy"O--W4' xsS!g,49̂`PYi0&4ۏB_wyY]jߣLjs+hRniXgs %gs %'qi6Wv~ƝF.QLҡӥKQUQ#B&9 xr/h:cӮ#hM&T ' .#\fN(iήUJ}5>awhawk <[x5u8ẴQ Ek C"4L- UgK]Ώ2k+%cN[f/&8k:2}rC_U*bM{mfi跳MS:xjqIi葉>awhawko~? N Vi:rGke#[&ceBM=@vDjW_%m➣3}+ լOE?gF P!X!# Y~xRUҌr_g>~!cae'fNz>awk_ߊ0?k֫(I䙰OIP $MzXxr;JOx-[iHa3 ,Ƌ՝@$WE#^CǞ]yQٮ?t#ß{Xll O};rj(%_OxtsZ# obҽ:(dߎ ?#?N0[ ۥ Q韲?g{FZ+G~&x?]|3SS=)4]\l!U*8%s C~? x -^$<ϱ74 _26]7Fe]^X <3ޙ :"SK~UO2o+ៃtL R :{5 WS\VѭS:s:(&ڧ\ ϭ֫_"x'_Ɵx_xĚWY}uƱ43d*(+jέ54B[vuy$n o2<M'Y\[q^0)~gzޡ&2:ea A#КyZ%)I=Sӽש\,Nz''JZZo1i7F3&h&x&exDe`d Os^+&*)8? |14oS٤:|W7^\*yʬDG"/4&uj3_{Z] IH2I(g_4[6i\2{]ddl=m-Kˡg ztZB %.FuPp3U.[k7 +Bz*oAkN4kkFcY6o%mfoMg}i6W:-24ƪK@q8JTT _ԔMTԴMoMt]f[ t I *3++ u &oo&}VѼ!_ZOJ7t;Hʻ"^X:1` TG 㯊gß jڭVH7;8\^3)g<Yu[ab5M<މ-r>aOWSK7ZW-5a/$onuVV.\*-ϱF* *}I⥟OF:4mR.,,) 0Vz񟂴}`SXyy݁g: u'([K|K~ޭޥJ*{Zg4,Wzv0),9$V:s/&G3)F!d$p)* {Y($yZcKfs?؞o$7gy񿗿ˏvn91?ξD} xEk<=[v\2"4d)jX3+u >)$FHHk8J$:Ms_\ Ox wi!ITw(i܉>襭sY'c 8e[D1$6K+fک1ڬNRz Υ~D=nC>sKD gEmeK[yPF̬`H \n/RUnmpn["6뛔-$ /4L|ѵ+ iV78xD4r#TAWT;7^54'h%mێ6NwBond8ث8 22{dWb_d˹\ٟߴց⹼^4VXDvIT+8TcdeNz'Zb7d) g뿵ϭ)եVw9 xgN_G*;;+;X-!Bq@~ϭS|kk2[ْ xYVrwjF)%EJ_7~7? %o5?/횶 >ˍbO2iag} N ݡ|@.^ đJw$"xWͷCMM9$2-8 7,+)R5MMka'ԹE'1ͬUh(fPr_~𽾇 >ktxG-aTtY9d $ 3skZ>,FX wx eOdV۝CV"eR@V!>}kR|)t&|H"!Eٽ7m7qS:ܸcR?_ҭo.-lobI IWFRC+ Ci~_3movͧL$Ȥݢ9ÆiP(]]3 Oh _?~+|U|uf[CP>qu}q+idx I#331%$M}+3Gby~'{ x3z|5yct]> O2FbUD#eL> Wvw<5cy鷞|k{k#o6>R2ϰ>OhXimV^/3GW`g)EtVAm$2QKu=cn/UrmRfKۄ@|qTZ_t sڮe闚΄!mJ ĒO)hLцUpRFqYʵWO3Gb/nٜ/#kO>Om~kf?,˼Yv,msY?l߂4j>:sxO ;*0'^.OoEug.K{YDc{I_52F_nD]]3?>Oi{u~(1tf=(1tf i$ [(U QTۋ<ǿƳ!1mFKk 1k[/ I0xN{9 踾c!]2ͅ]브޶S<3x:zƋs4pI "Y$Uu!# zsT Z+?3⦑4tvf,SG$qxַ^l "+)>M%_ؓE}~TѬGi5 \KN;۝6kYaCŕ&e(%I#MCԩe>$,OYZiIu܉H 1ҙ~SA?6>K3-@Yhe|ˁ $ 3.J{"캳zA^=FPo.٢[l5"3}aq[_6<6ޛ_m|y\]@m㽼ӝL\{kmɉ9x$:gl+Nkt$fx7,hOxNxORkzu։⻈x9 iM5L)pH.I,S կ ԬgYt'Ky&Pr+wUʹ z6V8!.,iMfvoBC7/C_/?:'1a}MvGռQ SJ֢⼇MY ;{[D+v#^o-^臮yI)ﭯ{_[hG(Qn;ZxK؇?6x{+Mo!}71Lmqq`rrqb0&Zi{lugհB3SMZk+*vZ#د~>3xw'5?|A|a7wwqdSD N|45=x>tF24Eե8FIb@i9jҍOkȔ[_+.YFzY#p|pJ˙vRINT6GTvv_|Xj)l]Y..-&).YOb*ܫ[H ʾyu|(foN| njmeʴ `hRnA]OS kM~?]u|,|?t>\wWwS4i8ðhdk~5t= NsIJZx)ߵ[iiW.~T7^msk>ee$Ҕ/Y5m9h^#VNKύ"(Lګ0Kr2fa><^KJ}{ 薆)=f/G >(;c_~:iΉW>8y$ӏ\YĻLUwafs,o|3}|-ka^XpbT#w/ # (Ζ]ֳIB9hE{[S,G4qtbI8QWj:zSY#e7jk_RI ǖOˉ.NYXxiWħSiriz!]lI!:*LB đ|1WsaCZZ^+!Vek<-i"w\:(Xo2cO^*Ma)'ng}yd prMꮭMnKkꕿ|Q ƯؼCjK41FGlTqe6Xm}ߴڶOH敼Go$hy}uQx;f,A,jyo:)RgJ+SSRikSDun{5=WJ)ΔUgnm!Khz*x6~%:=g^Qu/\"U^9e61]m[ /LsMkf[[I 3=RS~J޹Ww Yʥa7Ee?I$앾*_]u58K8iTTo7VkQ/~t 9o]|Kok+F[I,#e`ld|2KUѬя&Z|4i`22FWJHEymh'RVS㼵oKݧk];; ibZZɫTcῌ -VŖPeI3eXdk2* ɺ爿mG Q]S@д-3]60KM~ %\NaX]<|^CR ܟ xWjNK{km:Hbqr˨n9RED-J+W'ت ME5$+554wmۻm ڼLܹ\uTj+쬕Gw(w~%xFOu_ Y^ \nBbyWcr|˥;3 ^s#ƺy-!o2eo0h%TemnQUCŬMRSK^fUP7Ht~)^[z;> \h5MG-Cu-ԑ$kZyo.l]_ ִ꺦Yݦ%nn\y. gyV~Fu VX5v$o0a>~证S/DŽ{[ip| :x¹o+q/+ӫӏI܃ӧ+ >:|/N)Wh|Kiui$~-Nce>^HR 1<'1{\5w]Zkڶݛx;։#mrw`dl$r*Xzj5>KIJUwhmk֛>x 'cj_DwZC\) #KycF}_YG>>$jy|%mt$l":& t{=nk kjSEIYL4 /?k7pnIa@HJ(EInJǑxGARVzzoaYH0."c+p-?U>z?]&8.E]=4eլ2ɍA8o淟oHOORlTV.g͢}vly)Ӕ/vPvK6l/7őj_og'Qo\z~9]<}S?J[tYs\US,Yܪ,@C?i-V5%hcҮRvyG&8sF*?rӕZn׶\ehNFE;A,[_㟏DŽ.2? ?Ҹiz?fkZ$mFefHJ/ gNh|:VlזLIDmH] Ve%Xd33ܾ3.õ[6MۢgF )W4ݷS-[v;oڏk6YlNSZApɱ./ET6Ā 6[&_ @h~ ]U|A{_Uhef uد a#"7kx~[|I 5|n@6F9*[-3|3>9nsBLMm4 kHXkXYw9Md*qĿiQ]WwvO#6*'JQ>ȇ u6{񬏍zwD6h<^j((ӟ¹;]zH<]}Pugonv$bQt7oQsY{cZ4:t#}P\O;:"2AV@ 5E^>5A*#xS˅UMi7ܕ+_ |GOY|4kI<)Y翙3ǂKI'~<1RpW~?7o ަJP-ݦh4})<[U|3F˸/?3;Nz_z]IuZQ#UbH8ڼO%naHqm6'jZ*Ijmk#>3i< hˋYΣlShh ;HNVM IUڇ-t9.&q$rIS^_ E5K)mR9RF2=EBN_k\ h.ϹG\D5nF]m]l݉mL|?ߌU, `K y .RKQ%[/`c> S!I:'c7kﴬWvsl1;*Ȼ|Y,(GvHtbQ3*_<7Ach--c&d$`Ef#OT~ A30 8uM?F5K[[[^u(U"WYqƀBUMkrʬܜI9y+^qÂ{RNMɿ%w{.2KH)$0Z㟌_|A?V֯u 7JΩ_ GGmdk9oy-+<)Z6eq[R[ZɨA-MV_]1!91'/\Yr者i_SJ|o3KkOÍ"H1>N$e\+H#d`!0<?EiiLSpC{IW?w_xC/|;exZ>u_GmOx٨,a[_|S<7AwA%cE (}9++;dz'u/VHvhKٷK~ݵK8wG|[_5!|ake{&K4dɹK!4.d¢cy?ko x>{x+^;iIl-us!3([4*~%S hw^#YѬ{ i@+ qw>|uxW@&8#hg"v]3Y$IFUim)^j*촶h-'vgI[dns3_}W5vxѧ :Pр̺͛3a _8L 7tYWl RU8muflje>s#vѴGe˦iq/f+r|ȝRHip[YQԴqdщ7yrFTԩYWAO~xYe>sj:cعθ f J\r}bwEMAcrxk^Zm[0oxA]~j7u$ZIXԹHe%n>6 _5GJ>]+U5[SV6PgV(ٔJƸHs@־+))Ԫ$SQ涶O[_cU*tPK>)xe*7 xMH5]WPK! &;H#qp'hnY?3}Okеx5;[iD&F *Lxr3~x3[+ kt*/rmt B^7"|Qi_~'[#{oXkk>ic"&,meI[{CEV֖I_S<1_|Voo~P@wE#i>;O>|Iu]NZԼ1ŭXF^n30#yHd~9&K{5Kdm2( N <⟂_t]j-{he%KkܓY[2ed>/)+i&tWxL>x{?^4S-dފݾ&h!x3kSb ׭ L7aA2v83 -5c Ԛ; y1(l*+ɋ|G?rG+o񭖫|~K ]nr21{{d(W*{/E_`K?Qt?_"xYk#-2H-HLa+|-.jV^v"zNK[nRD+ ג|a|o:<5[ l[HwETF"&~}|W'eؘiEJ^.]]^Uٟ?F&o';߇>!躞gpQ<b ĻdsGe`Q?/}|B|>5oo7Co,|ۇ݆ϗv>$ď_MCDtR94n]N彈)2Z۔ek&89" n#4| s7]|:{闳xGl3ݩeKyk `ر#,5/}oM_vLڧ wbmEjJKe7?Svkm }_E7~N]6=6X mэa/|?l?|Ga[ϧ/OxL1o O$o@[3;H(pgKJx]෈c)5K A%`mb#?uG tBLqw2[;EQ isKH%ro^yBUyndUPE}E,j Gggk o_: ERQEQEQEQEQEQEWG=DӥwOlb?k@/t?>^wSWbKOk˾w:uZDq# :¿J>KѾ68Pӯ+Z}U ~Ѿ6s7? pPo~/oF_3=W½+Ͽe|S'{FYEC{hQ  ?(dc½({hV\,WQ|?@- آ<>G:Q;߇_MkJZwhG+ F(آY?@-hwh[QvF?+ F(?]Z7E] ѿ /&W~Q5Ee߇_M?@-kb.ʌW~Q4»o(Tc»o߇_MlQEr%~x{hQ4=@ka>襨raʌoW^Q4ºto)s0F7+F(?]x{:7Es0F7+F(7<[o^t{]:̨_72Yw)>x<@0 ֵ̨ݞ4%|[d@ ,'U'?`^x]&m3KP=4iG[-xu=_OqK@Hˆ==sRx;KԌOx}R˸ݟq;Lq&7#{o߈:tzFAo1NH[nA85~ Ӥ$^@YV=8HH©rRy-b*?Oԟu[7ßsj dsIrr\ʬp=*ѿ:+֤-t=Im4Y"ܤ2:dsW?XxK+t:p֩k;[j+ȲUܒDhѱ \f){NOs[KuvRD4+ D f>/GT>h04 3ƽ}x28e+m⻘a/4_O%i=S^5]W¶U [1Z1n!Lz|[G[H\ 4,I礈a_%2UiНMSW\?\?j/+^g{'8Hlw ԢyHTfݮ򜢵hYxK ?YxK ωt;+Jmuf pk+oA98ux 6HdxFRd$J6  Mv Q&Dl {-BOVPFAOԼ*eZc CyͺGTRU,mU1 k,/q yhY`8 +|ohNzsRZwE;+;JW <ɔO² /² /WZmexb>i,+o23:ᐺ}r×Xkxl08G%cd1pҋDڱj53^aǦ X#]HpnrUPl³ '/j×w:ųk{' AwI\Us/Yx=& "{f5?_u D 2$y|~mjsd۔o& nN}D[۸%?mgn +? й\Amƍ{?NC4PӬnk'MXJJ EuZ(i+JvDZ³ '³ '"ka59_Ix+OhBE`|Q@Ur^>SȨ& {u 4 Xv^"-f;znnrFEr~ ivg޽jXƞHq ,GVeӻA#~ |Z]ִoBJӴêrs"4`ĸ @\`_ľ^Nd7'm-f4LI$ƼY.o. g}}lzυZWV||ϳO?mv1(tkR]Z}U3ݎYsh-7 pAQ\_ ēgWtHbBv)'ֱfi"u,n%ĶTIxFft HnFÙ^Gµ zGKMπ+=/r) 0Hg?:r;jEi*/#,̥UG,@rIWKޡX\6aI$EwojJɈ 7+A݃z+_ зU/'Ge|7i6[C$u?yIA]]MFܼ-:=il!2c(@$ 0l MQWMt?eo$x@TĪI$zɄ|28%#51y$;hg5{F il}IF/3!TS8Hi3Vak&vMGN\"ŶEѭD e}t,d}gY췷{^LƄjm3VoC²K%x:x97\ĿKTu=CEi{(Yؖgf$$I&KOZxv[kR$MbiZ>c">yp *1z_b!NkOOct']E嬹4ppAQV?[xOb g߇wI5.noD5-ٹh#Ym8#:}?6709g?\u Bnn--/-ò |=5.UH$qNkz:\Z& KP[;%B:2 F28 wXžwVӼD2n˱*VSlm6vG|\>2{3Hl-e(g 1^H܈Appt{\n#zw)-^M*ޔmHxsY,oz =ݼs2R>\at/^ ]G#\2"gal[[A CjGJ0MIDD'Nɕc7XvPҴv,+8qN=V_?п/&S jO_UwBt_ <7$~ІV[R:v(p" /W~_UU`C@+j/8Oأ8h ?iοܪzrG'Vx?:ƯEEo^#r)Kpg&Q?_-|)+ 5~Y.]|^e?vN@:3/ |׉4]>"o qzLZt-eK(aK;x=_nIIt)sPkۏJ<˟}4McHn"ԵJc%mD_lƦEUSdW7zj]-oinu_&wHaK4؛ 5tQE))'ڍ޽ů j:^ i~8tV7Rd\$/XǨYG:5}Ex'#i}C?I1K6dH"k+hUYQ$ۏ?O?_x֒_ˍ59\3&_2mK{υ^:[kږZ^5/-h*)EV1"68R梥58oNER=~M]56Zo |5O6! ? S72߷ny,/\t~Ԛ%M3t-i#ǔw !J8y׎~ X||O].M?RMsnsYiPvΔP4]Oۻ>'m|Gּ񅖇8u;Auocxd24Gb.q]r*mwZqW1po`+~9:o~4[lm,M\yeXYpsnlitybc9,WEuz/>x'T/u ?/q +sZ[.yQ$rD!?͠GĒi ]k_G/ʭsppr#c08<_{<-x-m^Et6T@I" ,{. )(KmUZIS^Gi+Jex6?%|sM;A_>4?kBƍw-WV4/mI6g&k;+sgg -,H!'ߵ[[ "F$j3I^m7J{[7DŤ Mےl?R_z|M]TžjܢgUt$+ a[b Edgg#*K>V_*I4oiJ6rmKVўEx4SPZ&!קv:ؑCrI'JH"6kA6HۛWh֣a?uJan=ɵgK3O23G2+"mE-][^z&Oc+R.?_kqR Rm4;Qmsp-IUG{Jz7WWL&k6ZT-uq[|$ 5וh,JHž[kͷKKߣi5mn{ l_2uۿhv.}kiv-'Kk] ^}y),T%GM>h~O (Q@Q@Q@pwO:Zy\$-NbKOk˾w:uz/t?>^wSUH8_*r@}8 ?i/`d :¸[=wǪ_WyLi?io| kO uS[z6E5zxX/;KO#P:`? 'PS0q3+Kcxؓ [ieZWEq-En/ol|ciggO':1XfĔ(* <W+᭟}6Jӣ ԵUhGIwb87U ?g3L}S8Hj7Vxllf I($G1 |եu_xXQ)>2!˯FI8~U灎L}|?+p9 29 h :Nm(cկvĸas6A9Ȍ2r+9p xZϚgu7G3A]oQ|7DW`m[#,J {^C%>% HU)mV2`b$>%Oly?+:guTgOh埂!iyi" ]X&U9W_ l<??jg3Ru݂Cl?gh$Vqy{΋Č8U˴k~e~þWu#~ mUզEJUeIH@y?+:guu%M8I'=*1C^Dڬڐ HFUwǷTCiy|⺹kh˪HW$aHt:gu_KlU88#õ'Ěqu.-̍+~&kp ET^ɧ6f9`7Sw% t<Mt_uK!Uړ9O|@խlkM:G{|H$@'<`#^ dt5^ W\?᝴ 5D_Mkь^ !iKA}t5{qOQDv+_u!]EE٢eM;(>%kcC&vǹ AC!7mNeӼ=%Om:\C绘ƅYAr>_K$]sCƩZWuF9"0pF+G#˩9)8ݯ7g7x bKk%\eI @ A^r -5}Z.R'<Ѧed9bm!Jr@g-+Q W]Uh =CHGOmK{dʒTq*[G$P9J!U}X.c3oe30u2N);DEy<#[ 4n|qBeV*pC!k/ svG |OBd t4/7o L\iq$PsSzք[jH7 v"ʦ\RQ[*rf O{zν[Ok{e@ԞAZ|u{n YK ) ^yG?1e+?:} }W[^閸3][傍b)Jk_5/Zj:La,9rP;`8@x=7ׇ41„t#1'}DMO@6VdK>NIg:G$6 9MөmWbX}Eڛ}oC֛×Wɬ`lL`i") I#E<| _OUcXSEibt8QZft QByk+e\oIKŽFC+,0#8?(ŗ Zmwq[&ڦkH :F4v5-O_ lue[[h8i\%aaxr’:a!Au;4ϵ[3=9 GͻWI5 Y?;~#M]o~ЖZhR@5E1ѧ ^ځKPStGy#s]@As\MgS RV̸-Gܷ%r}O=TMUFUi]$#W-b7OM} i}J+_?>O+_>?Wq5[V[&?_GxYmTq)n##8I-#:+]/񶷦]x25 ӧ)UՅH 8 ~?Uq5O_g2~j' B+<!8h4?\My+C다MF$f|C$+>xŒi,ok6K+Rtn+ HFWjt/7|Aớ˝&D ŅOk{heITWVR);ЏVOGiEYZ_]/ӽ؛ 5u柱t!.((c&.gi:j/mm7ص+[ƍHdܰ2 1]a>$ oxMii+KikjrAM1~bN/I*u7?~,g䖚Ew,-aov~i#5`{':ro?O]ϻvl"I2'fo? 5 ,w8\K{a@ K Q~cυbg[h^)hFd+FborJ8ɏm|sƍ>2j*LwdʛLB(#z|5]GLu-GKkR[+ݒV"`LjpqaU"w/N||A_BqTӖ3ɾ55_o~w: ò~֑q/;\M4l^Q\f ũxuϊ֯ KjUwJqũ\$P3pU!|?O. 5OQ[MV_ ,U5Ʊ}PʱF6Xd @OO4~=OŷTnttk?k~#IxQD;Kn< HF_wC_}_~j}QE|2K M\ѬlQZdž}3}I]SQwgD"b~X|'7_uG5yjZ2کu{J,u/%t1cMClnn+}oK{-m/SYтnW,Hv2FLKS[i-,w0R#! l.nsVO^=]֣4.oug4],ۘgF /A)}/VOT>'҆]jMI&oz =髧{=m|N?eOYHDW ܋k9d|/ Jv -SLԵOzw $vmբKiFmi?prd6w(פxC[ķzcmldԅdl.ܻU^G79J[$}_-,0\oGM˽qUUx>1~߲DŽ5/&:gGImZ?jCpP"EE_73wy^O! y^kO-+ě$`yIg׾^[NjmH{[ݨiG"b)Bm%l+՛1?m_+<{g7EYic,Vr}w<BCZ <~xM&ʹ v̖Dmȑقrd' O=OYμo6YXnL[ ċ+`@8b0Nq4JjNfkQr;y)/4riq_ExÞ4t-B<xc?5" 46ff`{;j||2wyS[#'EΫhך$W-VIr%Q,4u+4,Jݓ9!OhC(-brTw.y8}Y K?x'#c׵{oq SM}wl;o+&YJ`wAH/uŖ~ dEE{=7˽&-Ӵ\Ae;,0H2>|1~𝇅o#j)xld-n (XKyHؖmsSw{yk+iEKZ~Wӕi/_1|KN<Ժvuè^#kX ʼ!BX@k~8"_3\$Jz{V3_X9%n3w,#!?z6iζeaٌp0"Q|O}\ޟ}.Oƍ^;8 BF9p#UW+=`Q X?31w|ǖK-_]NJxgEw^ߋֿ4Mj= ǶmºSAm<3")F]kU%o;JŞU .]+?eY͑0e6 X?3¾?W֡win+/-&Y%fT}}Yo|Ao;/ŷf],[K;Ѝ)%1őT22ϋ/|gߋK3Muetޘ6X:?G+=`PPQ7 ;Yi8dvtσgh<'K=J7:m?@Qn6\[WL$oiuUeh>ZIKoࡎ5n6V2B\ X?3|5,~Z}ܳŨ귺2up(ڋ$2IXKG.qiZİZ^Z-7珂& -Ct}axv얳,eWh+ۯlRc1|H@>,k7o469[M;m>[%L"i3 hU >| ?_®X'ͽW->X|\՗_t|ž-|7= YWYZ`b[5qc;y߉^$&72noե0T̎ {+=`Q X?3kM$i$ψ?i/AϏ|M.amNB[줯"3y.ꬨURm4ߍ~XKkN5gRN/o((!ʦ`6"_{¾??YLo-:--rmF/ [_xJy _Q ,-,Bɱw1yJeY(l%\dMj~;cp 횉XŲ37=ee | ?_œqPRR٧߯[xY8uoJ+%q>|->>I4ydd\L6gbT]9῏7!ֱiAoxPX-D!Ûh"B+=`Q X?3G.g+~qVῦ~yx㿈?|N]76$t 类OKYk{`-L3*??'xcw0ũjI蚂Q5'#,Be$(J`1kWz~g)SF15^iO 𶵣xQm4qM:y/$΃,6b6 8 _W_fNԴxA'ɮ4a⺵Gۭk*B| ?_ªx;ZVϩ , _/,/QO k7Q&-/i/.:0PTp9>M`Yx/`| Mr÷ww:tvP{x`B'\P7+=`T7 mHWIesJTޡу`G""Dݓ՟ JhcF|𖗮7ivuͭbXˆI%~lx-Zu|6d~!?q%oMn~_/wz~g(| UwrM$%}^]QhZv_WګN0oN>ogwͺŚh wm6| N}iew;s iҢXJ0{[ﻻc0$ee_ͷ5z*_9|t'~#:|3k:xjqZi`AIlFֈ)wv&qGY?g2*;k#|Og$=nOtjݽ7b3&C z]y_&wHaKAEPEPEP7k/r}Ny~"/3ݾ6ȃo_eG?b97ٮD^gۻ}6mWoI@%Ҽ^xz+Ejiߋ.uo/"m"see/ݞ <#k_^]BQmCȩq܊qH*(Xm_,k_ uko>'<)I_bY$DQfYz||7!L߱oe7c[B]|/Ac H]vV R.@ hKMݚ Yf }?#gq _o߳ϧwwmʼn卯~{?ikr_mk[C'+ Vu/졦xG߳o~瓷r6nۻ8lm?>k?HC^+Ǝl)5.Vr*mVkuDUy৿oAk7Ytl4.paQIrTqM \1Wcϻڻ1H2Z~_;++f]=H%6-$W]ۜiLֵĖ#Xnw7aRIڻlVc%:$vKv+'w~zգ?][ou}N[Y[[^Rh_|g+ hSA1, :d1L ᶯ_atey;ڵȏFiv\soۚuHVđ0y"Lc3LqE :gj7<֫ioU,Y .8 rq+'}}~/糺*:wӦH|SoN-=Qe|-د5-"iMKsvmuW1\Z5!>$x]w񞛤Aӌw{sf_؅V)D Xڢέ -<"Ii$F xx&3@Āx9ȱxXbfx `,WgNJUettGtյF)z'qTy]>bm^MW4V1dC:-躶MYLMQbPIiPco?<1/>+],U#-uK\岒Ui'ye2&~ץFK*5ӣװLP|Q=:Aw}.[&;в(8#Q?ZU)M%e*I[Vk.|׵;wn]w9YV U鶮V׹Es;IĆ{e[CfEF*} p8& rPI+BRq[_ {ccKZ+Ţ֠1%5ҝ:G[C^]NL;)Ӫ$y֛ T/*|?l_K>ӧk$?>=Obҭ>'Pl#%Bs>7Q5/1iT?s{ z_E 0K~ɕdi8eU @E>9S8oLPxoķ^ҡW }>x˪e@hm0wEfEpJ%XRjnX7[~"⥵+?]jBM{ɳ~v7c8_*%qh];M tI`Ӷ`Wg]xv ckOk w} 3ʀ Hgg|JS,yz{9k&Qׯ΋ǟG7? (.? ?zJw5KoڶiqH X#s@OxKW)eq S W\2ҩdƘgG&I]E&M7WYRq]5o}=txG Bǟ]泥Jᶝkt[Mbeg b UQ2 7Ě6 8%,`6֌*'V2F$\{_ڕk+=o, Vny@OAqTcx‚!}ŷ:z$׬"Vm+ȑNcwUW#kJ3_=KHtoi 6\v˩\S *d&Nݱ$%E<ӵvoo?P\<'*_>Sxw+.%ZKi6yݜ,'#Uo%O>I]FO7? (.? o?P\z(НoQ 7?'x[0j!KGcx‚<#!Wk xwH5 6ӭ$R#( II? >C4 /R5(O ]C$WFR`H (Y]tZywۯT>^ho?P\<'*Q ;)oN `(ի}C*? 727|?M?L 1JO*DCs+?x4iyb:`T2y!c&A9/Z-<ɩ7dG›|bm&_[^|+m_{tb{ ^$# &7h@RDauF' "*/f<+ޣD+h727|‰>!?WLx+O]]Qofui B0BdRMK34 )qxbL{u]CI`Ya|i!@'Em?QG[[[[G oQeo›|bm{(НoVt?\@C$Wj-y) 7nJmcISf{/7 oQeo›|bmjSyZmXX5Σ5’G24B`{(НoRYW$[MŷuG›|bm&_[^⏆ GZ6m%퍭y%GP3p_ >0ټ⟁^/[@i0Rҵ=3nyc0Z%wӿpy=:++ oQeo›|bm{(НoQ 7?'x[0j!G?Sz/_ޣD+ko -NOavkGdӴ߆ԴW÷3\|52i>ťz卭)id@c ˑi0kzL)*Q}m3\6(q,WÞY oQeo›|bmw閑yco6˦ ;e,֫|WQHBcWMfԼqʐvdrFq#r3_Rioj^񖧯>)t5ۋ{\- ve":H{>?O<{ Dz]!a`bM7B@yǟZxo Nc=i??>.~/|R𷇼7n{ Ħ…J 0Nӧxƞnn"mIo8Ȋ1p6|XF%#`sswZg~-kr|}#O_k'E_kN{M/][z`y5":_gРv67ͥ;HPj8oh-K^}_-s?ٷ-C'd"LJOΌA&“Qou E,Vo _:. fg pd72>& :Ư៉^͟E&-pׯ2̉` EyhBx\EYJ҄OTuڛJi/yvMN -Gv}~;|G Qa}hͫnq j_?f{o˩OckHi$faM+1 dO> ?ƟKqxgL񎷢]i5{\%{Mmm {v˰MTvUN..,yUN}kō;S.MOĞGowYD2ondX(Z|1i>.mm-=-ݽ(*6\,6>g ʹ\[ )cp"A:-JWce+&;tCZPi)J]k_~;oc֏cָL#gW;c֏cָL#g=k~k~a?GGAX{X{;?:=hv?߭߭qGG&{C?k} sWcG^~k0>߯ӏ(,\i/s~Wq>ZWS>/ËO;W,߼>"~|2Ö6?B-?J|_j^֧kfCu,)q"FBC2<^ ?J>8iW|e<Tӡ񆸺-O渵RG܂UCN۰sd>%9A%5 ӷ}Y?t~'ៈ 񞝨zi "DqAR[lDRėr4|j>9*z8;~ Sgwi85.wnu,;n9_?k_xHwR[ )D/( ?BmYZ[t[yьZQM^w}t!./;Obn0ץԖQEQEQEs~/w">1o|:J e_xO?i#?}E}ݻcf5vtQEW&M#lwI"*JkreiBTAD Yf }?#gq _o߳ 'ig;A'.N+X/anH#yVqod_?gO⽵. h"=kkpGs.QL{-7~!||-x]p垵 !KbQF]|~ӟ|se߇w%qǯw<$"U#®WyJtjWwvsdM5R MKߒE%uk}?gkش;QܴB#u+1ye FvۓZt{{M[O U-{[J?aO/{Y񾳦7z$[Ԭ-.i!.W9ڨQ?#Pxjo{z\,6j"̍ 2 ৿ $]xMMvMkX:un]:]Ib2]A}ҙB%՜TgvW$T#u%+i_姰j5⹹`k? bH.f.rĝTpx"XM`XH=ijaV9=-c'<1nxWյo*<^6}:HkRh7E6,ԠW5ͥ'gǾixwhpxXnᶲ5{ ZIQFX$ s)1b'e6zYݸnӵvҦͻwK&ߒWmC G/f2c%z Vt_.,ڔ/o"EnhQ,8N" 8^S*iE!\Kx)N֭%Ķ{ڱ  ԣ́[i Պ=ܞH`x8֜Zi T%^|2B7Ȳ@̲#d`S]pH'j(ue$:T!MWG=DӥwOlb?kY/t?>^wSWbKOk˾w:uZD‰`|x~:}z?U<[^muy~ 3J;N,O^a|EOO87)xLZUx:dtxZv`S"c!xIYROA }l\glťWxcߊx+ hWQ[x(,q  *;2 g/[߱#ʗ_7_7س_[$xڟn:_fg7yfǙwx[/Y=OW+JHEs|Vm%Yũ|O,ѹ?24?~ Y?>yuGHΆEP+O߉??0紟O&tӦt7 ^k]R3VgI;7neum-S/4?g$?_xngK)Ytf㳎Mf8ZrMftg;16xf__PȃE7Eȍmc+[Α } =4ai?ğMk^r7Q׷zѳ{jE%])}j?Y~mi?W;/&KԼCy_ w_xŲ=݂Zj->dODܧ!!t?fGƏX:߃CloYMOf􈮼E5s?iO'G&I44%ovVyJ֖KEi!W&'!ZxnXKKm-}97"UE{N~~"e[/?gY㛈.tgVừ[6J{}Kp J7ǧоVK?0紟O&L4'83õ-M*I+ߺ{k/nCoō?Þ7>!xNKCK[6"kt6ɬ_s!*҉Cm1]ý#LOFnu k7u]"}VuEm%,IO40L4' ?{I~$jd׻I~[a'Z~}7>!&:+,u>%OiiiG}I u/ؚCl-|?K-#io7R"u%XxP]$$4(?c0紟O&L4',z=d媺5dU,DiU`RN7+_>|iݣ-2𷌴ź/#/|+'u{MUDŽ俗MM:E\ 7b?ݖHdh-'4{{k}ᗊ|;rIyObn$Ϻ8u ?{I~$hO߉?S5_V8qv/RF?)sOo%m[WZ RRKŏgbAn+Ӯ?O |& ̒hdOEl t-$ai?ğMiO'D;l(}Rռ$ʞ:壏)H%1<-kxs޾+'"|Mo|UmuӾ$ѻMf[nSvȯ:~fҿf]{]v:n-3]Li/%(g&I =4I6_KIvHI7u i *4M{qĖ&ì $mUoj[E f(Te09WwtCf%N&qG˨47H(J!^oFH*vL4'v압{/5JMQ9Ӌo-%}}:~2swDziz|5k{xBkj0_v}[EwT69,F V7~~ڼ GoV +,&y)#&1#rh?MYjv6Cj[7Nzq;?_EeMacNU:we0oO%&x/ıS:ae6]~l+ s7GO~/:4&]Wzs5Rɱ"`DvV8&x/>[{t7a>"kj" `  |>~hgvpP}IMś e'k|mA{ i͵;.Rd1De7|EwfH|>?mAcĞ]|P]gҬcy(lo$/6p,8Ӓm+u{}Ҧqi&ޞס>8!a~TI %ٴ똘2[f +Ec'či} -i{xnĖ:~ZQW}54*N6±"P>O{oI#}'ÚO|1xOjZvIj1ZUQD a. Av*$k{kv_Kmn^uj;ռx_>kn,B5am,k,7ưxZHDH_[[<-y7?_g(ƴK[OKaSΒRSȜ>(>I(Mm}imİ1vVo; 6=WֱyjwV!rI8's?g&}O~ݖC~xr{[W~$n|kx}#KG'W7DW]̪"AWMbfz'ӣ#KJK)$[C$@JpAV:VMG}M!ծt6G?u_|b|_ GΙI43R}\Ot?/23Rs?Imے hSL8mv\㽳TfSqo *C+I X lxoS飦~_NbڋG.6K^ߚ??Dn/{O;TuooNڵ 5F/%? J"We ӎ.%}=_ 9/<5A(!q"}1t5\\?,T Fܒ >9.?_Aq`K+Sc/;Obn0ץך~g M((( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j ((?Mc῅.&:N2-~w]R{ ms⫿'‰c 4Axkea-MΟ4ee95ؿXKy5vRE{I *4f E5`#W4EMk]nˑ| h'?1ht?;IZ'-ibKOk˾w:uz/t?>^wSUH<|_|ռP~e +K$?U-n<*pO7J$oHrG;ףsӋ9c+Qp,9JenG4ł0W>ҫ\hDŽ=gS9kj6^#ʱ*618=2Bk&u?#_i]KFׯ?^'“QRj?~+sֲ9?׉QG<_?$Q }O+yw ?3dž)?H_?$WqE8g x O)|7=(£S裙 G3φ秊?"g OQEvQ#TjG3φ秊?"z(} *5?Hc(£S裙 G3׆篊?"g _QEvQ#TjG3׆篊?"z(} *5?HTj]s>czG$Q *5?Hފ9p>xsz O(|O$WmEϸX<9=|SF>xsz O+g,q?Ϟ)£S?<9=|SFQG38g_QEϞ%HT O3緊?"goSEvQ'ÿ?TG3緊?"j(} *uOHÿ?T]s>c}O:$UM{. W^,h޾(ԉP*fr3z~1_ K [izqj2[3,W .W;AW}׊~ޓ| +a_Zu}sO7' *w] 1տhWO@gWSzڟ ^Z+ 55;+lc*X %y fg,z '-y75:]W~Wb}kg'sXӥzgb|c^.վ"Q_~6ֵbӼ2q[Ht녒w]B$!!iA2}+kVq%̚׉1&jIhvѼ =˲We]khAPd͗ڼQ>}XMg|w/o|OWRE`mu0&n~x1 2i*"]&\^? xlfseۭ$v#$Xϴ(%*7vo/LUaO4c x/c6w c :+}hʀ̓)cib*8I3bA)hxZ'q}/Ze]j5;p+Y̘/e0,c݅ym5=5il6]kq^,aAK(&ޖSa{3~ 5ѼK iڽֳ[&5[-V4uʈͲKď?j:|AVEaʏUNm)nѣ$7>WGekڇŭKUi6ݏ(f|¾Y%1a$Tb%y]i&]NjMR]kd[jմi7j߰Oj[ZfCg iG%R-ikK+W}?,t߆A o4-^'I6"[HD3XI)-万dWoku$ѳk]6(DH=&)⩻s|k|* ^5_j^46i߆|J[p/4KH4g !vg8EA=,r/;]+wot^njktNzNޝ+Vx⏂lM/xƺAio07:ƾjE= ml{2?v)ikh*B[zJmQH((((6$@^=~c]q>1ײ3@kook[:G;Mkz:m(Xw">1o|:J e_xO?i#?}E}ݻcf5vtQEW&M#lwI"*JkreiBTAD Yf }?#gq _o߳ojz~kZ ^Xom7a!$)[N#\2~x ;ֵ]_NH~y|m3};Ok?'k/ʹt]c\lʳ+5b7!Yq0}b ߲MrEğM%F`ҵfm[) YƣN׽[ɶ:c78ut蜯|ўR>+k?*XB.S*lɤxYk +m7S.&2jI1,QtMSK[D/t=b[Ȣ%lf 4E;RTx S ]o^5si:9+nt)t}J=F4bo30Vǀs۔)zY;g;?{n8GmVVﶝ[O|MOŭ+,k|Eq8j<jlFPiNPDLk#(U/ CI(iw?$ռ̰OjE[5iv9O*6TS [7x;F浬9o3:Ͷ.UO\y9 &PahߵxGu1jZH,-SCNeḮNm&iU XFRԜlyIh+iesm.VוkQ)53WsElCv":~eդXԁLKk\F-Md8o2KQ[k8/x +9>%xĚ xv]GXt{OH.n5(֠$ZxnO7;ڌ0Cg?NԴRq-_D4@{ccKZ+Ţ֐O[C^]NL;)ӫ~1%5ҝ:|"Gg `ҭ>Tԓ:x°Y)Rb UCƣ_a/џBi?tN_SQxTDz^U24$&W`0^>mS<^9$l 0#$k5KOGzRhM`ikQFjE[6[Iguc2E"uܶAU k]whU5/B? 0dU+QE| %?SUQ~?Z((((((j"^k\ToEڽχPFu` h\qS+>%k'N|% @Fe6now0@@-7'h9.g[oQ$jtA笪 8كL na߈Fx/K ZޞnWM]E!5ܠw1-(Ԡ;B^IEo}񘚔 u~ =+R8ˠ !|) |j_555z·y-dmumXB_Hp$ĖoB!^.^_f};%u)wg'ffկ6I Ms? 5x7焇< AiAZc8xYz 5t/6z$GĘ5K 5-YMi`\S;kEh'O!ROi\uhb%E;$mwR]qN5I(Ҽ%-\}(;(((((((((((((((_"\VgxE}C7?kHCOj^*6Zþ?[ D6Z[cR#&Y0KcFs,Z8A OZ-{/$oktײO&K/#&kLZxϢ|6'm㿉v2#_[FLk5]*]lolbh.-I*rH$x {W=φxpG&gw8*wūnC&6r.g4Fkz8\(KQg|.L\)՞ctHB*bay߂]:W>'x~ \5=jkKMIآH[*#ghc_QJO{:o>[kٷݻMI-+[oފޟCߋzƴO:,.4 x^)X[]Š[';FͣTO(x烾2wwmZ^<h#:I>eJRb&dGo&DQLVt'#_e6ڒ[&J]H7-VӦzO{r@OC jv'ƺ!5/A6}j2-ْg?~ xW>x㴟u A}xIL%]FU$mђb?[h&5+{]M=mRݬ^+{ѩ;|Eo˿<<}cG[ԯУXGgIQ$x㴟u A}xIL%]FU$mђb?[hI2z׿[imoۊԵTivi xb^t{)u4h!}B*n'wi4;bI5EJMRIYQHaEPEP\Ot?m\Ot? ҾB9]NS|a[:Ӿ]zȮY0u(?~:Oz'e?4eu|Q!_G_yјO(à >9.?_Aq`K+>؛ 5u柱t!. ( ( (9Y}3Ou+Ɵfyywnٷ]D%s~/w">1o|:J(+|&o{ qR;ɤ ʑY%MFV!*m ^R"zs~xRd>i8/ȷٌcoیyQb|/fx[nhAcV](`9( Xߍr.?/Co_sFmwW=k:HaY#!U Sb?T( i^F=*S-;*0Km޽(%ʲF?C^]|/-ӳ i~#ƕD䟢OkĞ>[υ+y.aXӯ5.i9 b6S$aFC?~"?<oz5/[oa)uYowެuFk ̧ԴMSK[D/t=b[Ȣ%lf 4E;RTx S ]o^5si:9+nt)t}J=F4bo30Vǀs۔i'S禮{wmݴqKkX_|^[Mٟw&"&Ԣ{[xDXV9fFT2;HV?Ɲ_ 5[YE Hns#-ͬάgxV_>&GW75gF}e Qmr|$b2]UF;7KoGim/E[MBG[XuKɒ;x]gB#Nx? /tg}oپu\yn۷`snͿo/> ؃ixlCď!/џ7q?n?&i^^S1{oMyR oi^^M-#@Ы|?e+tgO( jLzwFb.5]G¿"/7Ԭ5+8mh yXHxcՁKIJ7wݓvWɾɗ9IEu7|#;?y/h>4oTFN$$)8u53]?Su_jbzp𽽼Vex>ɩ%ąA6G¿h%_kGQѮem5h`+ ]fR۴4$\[3%aғ*{|2irr)ri*8ug;Kk}%i?Z4[Y>?=?u?XgZ1B{CKcxZSk޿gݥE~0x_h6=W\ֱGoKmi_ lce)ָq»|t_N-'yFQiv5T9Qf~}@`AW3ස~HxςK:\mCʅU72OZ[3|5.ѣxw>3|A棬=#h4IbU,[~_~ p-tOڦ/Ph:LJ-.U.CCFLKHk~M!3C&r&;.*K;*o>"n%o5/K~"oR]3G=Rݢ,m.4ݕ#H\.C>CI361\izot-KE0XArDKK:Z Q/=LE:Ї#I9'iZ-ZRnڳi˖>J+7}4_oKE|9:FKo>o _k&~Ѡ,^{sK%.OŸa&!9-~>N_\ﵝkK$Eީ-zDv|^(!c߼^_*krVo.xE&IIS%V^V]]_+هZ'O~[yy>^]zMVỒ׋_\=Xvk>ksZQ[W~byMJ FdrWUXVJRv}MZj<t׬c~O?|\_?@:b4e.{Ù^ªؚg}<'O B4MaߨlbJy!rA骟-ֶݕb_tmtʴ4Wm:h=+A| xº[Rjf@ɪYJ **b͊?Vv_:Wɾ!T2m Y^LG,l͝] eBsJսq_ѹū_O '/ AWl?i_RxmW\=QWZm!!XȖXI` |~}3xg.xQh Ƴ/%d4BH8lVme OMYk]Mv=I.AQ^ nz4wW:7_ x~FV ZIX`V%U-h5uU9+JQ}_4-4 ((((((_"\VgxE}C72="wW=H? wZ\O">05jg+>h쿳ɿ9kw¿ᅱ^?<Ú.xᗄ Ѭ.Yiii*&ITy%M* ] R*Ww~b7&ɧ/"33|SnMTkI: ޽ƚ-HвjsX±%yȚP jZUSFjȅI*mR2xM^ώY{1bx$q tm\]F?RmY3VNW^_>Oo~?cF籙nEµe*st1<'?^|[k=i_\UH.u^46'dQ}{< _K|Zu+k85cu 5d͋_G)Lͽ7~x?HMsiZnqM&}>˒/>7lw/ <}Ny)7vRN^?FYXJ)mw?3~ x/ףiG~ u`mWHBY̑Ƭ"8mCU'Og8 Hog Fۘ\[4}|ߔq_W5kVqPOkeIlug 34qFI 1U 137|:W|SVx^DDpD7J4F=uoƦc}̹%4e{)YY8yRSg'ΩY_X؈| PM K$3* VH̏l9#yZ?~,X\xOnէBKŚ]F LKv&Q?D<#> |9>>t:F'eZkXA!Y HA e Uiu$߂vr.Uye f(oh#讜{6썩b#-]wIͿVӂ˲Whg|/ v#}:'Ӵtk+:|A39:sßk><-% V:Vc,V8bUDI=n5:ٶ?MӥIݤ܂((((((ڸ|a[:Ӿ_^Jm]N=O W_,z?~:Ozp5'PX11_yOGGwÿF71}_|:l2<6=>1}K1ڟQ__|r\!]=sW}ɝ'7Gk?b3&C z]QEQEQEs~/w">1o|:J e_xO?i#?}E}ݻcf5vtQEW&M#lwI"*JkreiBTAD Yf }?#gq _o߳ _.x3N4 I-f;X PPr,P@D\2~_3f߈1捩x{Jufa8²F%u2B,A9*UP + \4QzU [k6vUi`۽{0PKeBwtShw⇆ _[Cf4FxHW+WlDž -K *YNK3f ׉/ĺ.Q[EWwK4۷K5^ P`NSIǾ.~3mX#[!}rXG\c(_jnؿ-@|Gw\|u'2|/<7Ie{uxiA9X4YcƬBlWj.?}+{5?Euk#%"6EV+m@x/ j_n4 R419ys:Y(IOi›߉ڧ<:]^z){8ķEK 5ibw!|6ߎ gjLu-NsW? RzilfgaX)*N;rMm+ۻh{6{ֱX/x߳?G kAtMUEME,MıڬřdvaE#$&<9&⭼ ;_g־Xk(tZF[+wK[}ћYXI ȭ_H|L௅#|okZ΍a㟆>iQ`Hǘ#e ƍ^x᧌t_kFvⵃZKm{-; I⏁|7;wo xXJӼ ^wnԏao~1ߓ%v=?C/_o__jW)K?.6VnmZh7-qId|+o_} x:im:xWZK;yl.-m#F4+$Oj 5/tmC_M3 ?evYqokfT "(ssF+_(55t}^z+= ( h'?1ht?;IZ'-h ח|?Jt_ o yw8}3N_.|@*??H<_\*?AJ7'O<#O׹?3^'?tOY=7KOGzjًCdGV{{?*_A^M-#@Ыkɼ_]m zZ(`N3w<{ .~*ӷfkn^ɶ8E5ayH>Oi |3Eq 28Mw+44#I#,嫘%?SU ( ( ( ( ( +.Ѿ6|8|%(мAlwY7:|ByG*2H= (ԍj2qZif4֩kamQƙogVSծkany0I{F@_⯈u3ꚜ'@8abYd(M7DЭR]Ar]grYbI$QESwՀQE(((((+;+hwW?*,?/s?%H|t#]薠+w¿ᅱ^?<Ú.ƿg+>h쿳ɿ9|ɿ18_d5xM<3KGH>ݫȳڔRN-@*1$hxo]F=>;˻s :αy=ג=]-O$a;P 0QS#wcԋס֍2Cg3aRJ9IlE!?>sg+ c=i9AT ItR.:φoFdړ}ou[< y)l2i \ܐF_/+1ˢܕۻI'T;/kx;֭|Q|=4Z}_[{+-ѼWUTbSxHdE[7} τdZ%-+ߤ+#whOx^ZVytћK>\V.윫GOb O=~iK-WTԠwItյ'ݖɃ#˼JCNd ]6V>XUVU ]|_<x)]MY@%LGcDMZY,>o=Ɵ+mC_:F[#'P{7ʥ 3eR|&_ٯ_ <jOԭ/6[Y涉R ׂ8K{nKnI^ַwI%y˕.\:7eu%{^I]kvwvC ßZRRXϪc[!{9/#&gHs-&|T蟳JGs_ֻ[/[{UH#إ)m-O(<(|׬$_I򣦌o_k~]Z*c⏎C_ceᏆZv=6[_id~\ߣF$3D%xeU5_)iV6׿ ,[xű(,iMA.64~l mfGvȥBlWs¾+x:VؤzVXS2D,-N$ٌgt Wx/^ƿMdiG:[[CnXn@4&}*~i87ss#S+?NnGeߗ{ǻFV*XdGREd (QEQEQEW{/5W{/4tlXMgikwvq|APEP^7 \x_CPMM&(fT̩*m2 Si+5e–g'{H6y~Ec~cʏo)3߶u;@-$e b,@#@ȱAmFp_~"k6k+Y՚EG h BT~4 <ŧ2mGbҴ-KVMg5D! G(Kn(v7OƟdMg?iO|J񆥩ǿ[bP-B"GV6g8qu\eV˕_TvVN5uV3 ܔ%e$wlѷeo_ ? Y09ABKI&ѝ'|$|gf_u /:];u֯i-nkD6)sq<ς~5(мUgY C= ]Ysg|; ߲MrEğM%F`ҵfm[) _WF׏vCҌ9aʖ;r%r}w {?'|5O-•MCɬiךq]4ڋ\Iֆ1k)0J#!ψM~՟~?Ľ šۭM7E:Nw\ηVa:#FRfSZov|O%GvwE^1-Qj¶3MnXG)u_*MC.4KS_O7:v>j1[7ٙ}cV9mJ\[J(ͥ5|>{km&ZuUobjQizK<"vSq,v#*XQq?IxɿoucNY-,$]7VtfgV3RB+GW#+o|EÚֳhrXxᾲϨ6hT{>X1q䀙Bq~מiūAi ԵM:⻹9䛻[V$cb*?}ޒSkϚѿfݩ`ֽ7[^Nj|Rxo Nx^%#Ҵۭiu#[߭:w{i.Ff{'?e?iMN? Z]4Jd.;8Cmjiom[⿋!!]x[M-O Vgo-Ŷ{-sw(ݑfedB:/_>sg3K>օ$kgqSm8mqnD7qr [nnͫZyT{4mND}ET(+Ţֻh'?1htO[C^]NL;)ӫ~1%5ҝ:|"GR?OäƇxR?Op4'?t{/C_?%ֿf#{iQZ`-?ܟʗPWxe H4*oi[a!^=(=џ?'1xV~5 go̓c>ܰQ‚O$q?'1k;]8IEdT,[]#I?<A(Sy^ODx;)?G4G1}Bw|;#hc%'(w?R"`S}zd}?  EJOWQ }T쏧<A#I>OAꝑ4G1Dx;)?_0QG)>S=~&]ľ)մK;_K5"$nȋTsnbZhc%'+ (X vJDJmZ/ Ke74G1Dx;)?_0U̖$]*(g!{@(ެQ|ÎATJ)ɷ㌨I/#I?<A/P.%xG>mԣ/5SDHԻ 3d_\{]uӥ@Xږ>z~Dx;)?G4G1RԮ5M A]cnfX` y 띏'>%m +X58l%pBwanRBYHPT904(7]mtw1iXj,2[@ h[/#0^OM&v_aeGdv?H?<A#I7W=22ڍ_[]#(쭤e)sZ yuvc:%vBHmܣwdeԵP7d?^_>w?R"hc%'+wV/u}r+˸wV2#q CŚ|xkE>̗NI\.J(|Ԟ*m*_&早KR4_4_W#I?<AE.]|}JKEV!I&2! ITOtj~&ռa7o.,uO@ #i-ÐXg DT~fMDۭ^MUvI-Z_6?4Ͽ<A#Ic_|SP𞓤784F *ry. ǓylnG4񆃡[X_mJ{ٮ@佼~Y $2jY}8z_};(c+(I>w?R"hc%'+?Qi-׀7JSySF$O)( ?#;Hڇ'QƱB5ָIT<p^<`rXm7_WiV]hc%'(w?R""|A~ΡCwjtb{=7a^GGɯ_70@-s:5&qAWXgu ʇ ώzi~3:kjUqnau i^gTWzkݢߢ*iO.hc%'(w?R" #@_a=Q.9{od\GXݙ2ً`9Zz_lmb^G.,"xc*Aq7B n{7d_x[ۯT䏶?<A#Irf)n $Ǝ3A=HSCҼS{E:Zͽ̑`ӡV&\~AjKROV.8d?C<A#I7W=22ڍ_[]#(쭤e)sZ yuvc:%vBHmܣwdeԵ?Ce}i~lO{ujDx;)?G4G1|_|k=+|1^Cm&=qFG"O̱VΓ3V jRMP'ب.UW `WN;_oGО6]?~4ϳ<A~3xkz}֟_hO.?ʛ,<^$Au&GdӤЎRqݶXc_=[ ' I_PMElH|t#]薮="wW=H? wZ8A OZ-{/$oktײO&K/#&Sf[koZfQ:[]ڸT]Y67$L C/XxAS%k9H 99UѕєAR,x+ڷ_ =7ֱ,Zw^!R;ipND;D-!&Ua|j$Z7$Ե V-7g^9v\ۼ0˵ m*̒)1RNtR2mխ F]As5$XH\F$cGoEcx]gaΥFl @Z;oG$ Wqk3Fi~&n~x1 2i*"]&\^? xlfseۭ$v#$Xϴ(%*7vo~3 O 7-OVN5$ݿ3Լ=Otk6חI!4N1tMݙ!yOԿgؼh|Fn./-o+I+FU,z]; xO//`PۆIZd{)fS.;h/}'~'&/>|Oӵ>ϬszvykC:ʱnA!РݦGpj2$٭]rzteotz_~>⯇ e 5?گo"I y/vG@+=ѣ6[axO?jz(-֦Es>m6U"EiGF+n_-૽Rs~ |/k{w7756‘ms-Y+y}W)W_4oO>-J±hys3̭3+mgǗ\ldUvN_>)r;VKn;+r%o`g_i/ |'^^5Qm:,kqes jIpƑlY.T+Z߶ß x3W9º;xFғ7şt*[/#ކlЎAHMgy)jvOe^FܧiY'~^oѻ[g:U H}F6ZǕJ[4Vʚ6'd|ZtY<[kxZ_0ڡX3q-qns.2?&{c]t ?ĺVv WDYE9ϼ1ܹe{c_?oqmc_j_yAjȖj1{`H%]+}{6%8{}"oU}z\;7h^OO6O %F3qs 2!/RK~?|7j^sፆZ]_6>){ kiy p̏*:2 >.:$Xk~ 69.?0c/;Obn0ץך~g M((( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j ((?Mc῅."ǿ:o|cw@5JZ b* s&|@|Gw\|u'2|/<7Ie{uxiA9X4YcƬBlWRkh&JJ3WR^q9~hzǓ>'Jkhd4f mE$xc}Cy%O&߈jEmh[^MK&JFf';.g[0eZb)3)-7S{;T|'V#k"E/g(Ia[B,QND#&T[ׁl \N|J/ᛝ;J]RQ5 >ձ+6%ZI{T魥wm3]Zc綺o~}5]5V/6ij'e7j22E/?l0_4UZmax(bEukl-mFmfuc;$/"z!2?w^Ѽ9k:6%~/LmG#`H *w7y1|@LZ =KTYxn+kynIUhAq{9"ѩ9_%6 ޚ^mڛ k/Ex%>|@߈tkĶzVVҴ[u-.{ }Am.b&KHg6{7+Ҿ4<8Ұ|A{Kk} GMޭdqt.$XsKPͼa" xCC&ζ[N֭[;ˋmF2[n,kGHQ"*c_h*5xNLCaxv?ޑwwfî]]V(ѦK8Jm('iJ˖wkz^ӫן3_T}uETQEWG=DӥwOlb?k@/t?>^wSWbKOk˾w:uZDwC0V]qBğQ?AJe?ʧ+?C_?%b_9ۢzs|L>$GW'NuK?Gz>'r/B? fu(ZGVye+tgO( jLzhwnu:Wy;"2ؙ O\+']z閾*λKx!ݢꊻQe'@kW-V%50`{6;@ FH )sdؙǚ.=ϗ[x _&%{#¶5 M}sEQsoV#24¶5hB]1| _&V#25hK}F=ϑ[x _& vǹ7+o[?[x4Q.>Fm?k/G+o[Og>.^*<1u?xHb{@ik$M; 0]0z$%kѤbm|iZw>Fm?k/Y>8FxwĒi~U[դ&A+DU8H9}<]`R3-o6O\ݽ.QdJȒ/Y2rU lec[' ?bh|5vԯO}cWx<&fI% Y,I?+M:rGukZ dͲ_bUă0(c-/3o-nt} bk:zR-!WO0>7cZ/_-s!htH[3j%JYM}E5I[O us߅~ 4}c lc'2B# İoMm-t&w6\s$RBD!87{j5Z{M~gÞtV3V4c5q;Z9$ds>vRxշn,vfR^_Eon9X1 =İ1Z'c3-]#MDlKyufXV4yȈ0 @$tV3V4c5q;Z9$ds>vRx>W< v/v>kgO𧊠K!#\j=rZ96N,ex?0/ -b9"QuMFHvx% P ݌_xQIc7[=|őiW&f|wjR//,Іڹ򊓱s Ie x[K R`!G'~PW{İK?}˱^CnS}f|sI30I(A2TbM-nt} bk:zR-!WO0>7c_tMcQ0x>!H#ho<2 y)+Q<5[?VX.5 CT-YXGq+31.1,yRxk4>;_Wmw>\< d3 c,J$x&tOq^9#by2f/1*AWPWoW?ce}u.5Dn]B{4w!@ߍ8$U? 6^ԞOǎ!{Mj f2,I$E vjW?ǁ?dfscyixssY_Mm^jZ+,w2Hn/siz/G~ΰ^jzI@HgLmP@`+:)K< {"_`GJ@?LV__w4$W_ٲFnf];wHB WRV> K.]ox$]\Og#_\JۤV7Hǩ=ῂ5Űp\okY0HI$ƾȯTn*84~8\O">05jl?/s?%8A OZ-{/$oktײO&K/#&͗ڼQ>}XMg|w/o|OW^{o a4.uj kzκ*atȱ,aXݠ('Ծk_ d'mMb;($u KiD$J$\vKzWm_&a=̫3GoH(i$* ,ǎA$5f Y=QkZŧ$xy$_03'?@f#ך]mƹw 6+ .I|CdˊWعmc H~,We#tחq^ig XrZ˕O2#":)eG|?g_X|L|nuc˽p]YMokT2cK(,I6K"cpSZr+SrM2E/V>wl4;WMX'DH'sfhʙ= @Ѩ|~/*|aVt*>]ӢҘJtxŬVȒB4'ewzS햕c~5n~٧=ݵeϗv-F! 4q9!+򷳏3򺕕ݕI%uv_ m9BIݚQOڊO Cq:no#Q:Nxx}6=3#:j;Zrc|?+YÕWg2(((((((⏎,<5"x;͚Hcno!ʂU'N/r$G(ԨOz-D) jC'=+?~~a1G(rΞ k>7VQE|L4'$;^Ԣ޻p +~_¿s Cbo iwu+Yz2?? Z:'w}-~f;S 97/+$Bz>9.?0c/;Obn0ץך~g M((( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j ((?Mc῅.&ÿѾ"K[_ExIW{UDGͅ\8-^6>8yU&5vi+kﺵ޺ks xJ-Ua99&TM)ŻT ms⫿'‰7tDkzA">U%ղ*;U <$- zg!;Cz\2ܧp72vJױI8F%oZ?뾇V*u/gIRv5:Y+Qk#z-ce2FIDd9 /ڳ[oxSRu h_ى˙}'YDhְLnJ*𦊷WBzbRK,_L5 hm<؝1w~xz{toVehO?nlƳ yS\;,$E:QuM[˯vwˤGgm^;;K[Mٟw&"&Ԣ{[xDXV9fFT2;HV?Ɲ_ 5[YE Hns#-ͬάgxV _Z}kB_ #OVW*?AJҸm'OoB#?WF~O+/=Wmگģ>#G["v Qvϻܩy7PBY&]whUg%3hJ/]p?'1EPEPEPEPEPEP:> SY5O:]iNSs1t8ZYV8i|ETV$I/I˫mV{aES(((((((((((((((((ȯU\zo fnEaH>a+$G-TKG:l`|s 5%櫪jZ}{>`a2h@䑂iw¿ᅱ^?<Ú.ƿg+>h쿳ɿ9lɿ1,k?|=VQOoﮜ5Əo,1̄&- @YZikXVbI*Z]͍Mż"6YNC)ⴟ;w~mvξQ|\A0/#eN7 +N= KLB}4Oa hҜ0 !T5CmGҵj>m.+ S-a$l-A[S%cr+IǟN:-=w¿ 3]_P4?Z5Eo5nnnϘ蠾noo&rx_'lք}Ww"c>bzWŮ-"<:OIdPp>WGUWčNo;[n.4xooY۟ĉ2&쟛uXOQvͪNMr7>9qt]Wi{pE}-,wP4+[z_1~_/t_kU86S[8uIer0#89z xw^"ޯǶ[S[+&e -hbNaR:uʿ 6oˢ_{C}'pGLou+ ţ b;I#T,J=II*P Z~ߴ<]~i~+xV:6uy6&jӲF/Mh{ل նMɤݒm Z.OMt;_K%v>7m>UQ| sVcCz^\hr>ivso`.VZLBGc$ ?M_tQC-_Ŷf }&}k\KۻG,JάZvu`S?%ZI>Kdкioxnnӵ~^o.\~;Pm҆g)cɂVv!sά"%۹Y)[D{?52ɵ;]y=tQE!Q@yv'(ԫk˵8ؽF@S?n~"a0wRz{~?_-SmJ6݁<=OW_,K~џ ~Eb Oa=f^<Ə##?DlCkƺ<2DlB3Lg}|r\!]=sW}ɝ'7Gk?b3&C z]QEQEQEs~/w">1o|:J e_xO?i#?}E}ݻcf5vtQEW&M#lwI"*JkreiBTAD Yf }?#gq _o߳co߅=6x2AxLK{;/ XƬ V(!'P$BP~u?g^Aw.5˅IDX$AS{7~!||-x]p垵 !KbQF]|~ӟ|se߇w%qǯw<$"U#®Wy>,~o06DIS(:|o!މ+ Ako{x˚E|Kd(Uv.yVo㟇kcſ Ot;/3cBև=[M;Jy, +Il5MMPV&em!2BJye[Q>o׈KQm^t.N52~;lhnL>qɨȼtx vih4R4c4Ad1<*ssq w[ -u.󺼛m}uSsү,èCx$kbRkB$e2;Vy{OC/%!Vw~+hF,{h#=vjW(6c3ii)e?I_;:GB_6 o>op=ǙّǨ2|2_|301^j>{c*Y ԢGk'K6-\IjC OdM{ˮVnU.n[yV^G /῁4~5/A0mb|dkMI#ڬ4i3*c3h/[ գ|{{ޫe{mgoGK-6K+weKđext)w [zQ4k.ϳifבH!I؊B^Q~ X}h孵dEkTRmJiIɰAv(%i'Sg=ߕ޾#֗$ARTf,?k6ЭΊwqjmIlkiD(~jj^%=lj5]gK=)nmm%0\1U%Q"¬[ x^^<B=ONբ$Vmln|渄liVg *]3Mk>.>hu荌%ͦGdװ4Fݙe2I_䴿KkOɔ5[6z}\$-Nx;gz{kv_sxSrwO:ZӔ\[dMjbKOk˾w:uz/t?>^wSS_#$x}5 ];Y.m"H*8H lZӣ9[M?]jغt3~|7kmfz5ׅ>) x{be0}v'kc8Tt_~$mHi6tx[kKRFYyѨN/Mإjk]Z{wQ\> ?Wq,c};Tԧ8>YQNyIIwN *Ftk!`bB)rn`2y s^sw{OLteE(#\c"6߉B|@tg4?tM-~K}-{Esjh)}si(n%v9U7񚩧~>ZBNxuwNW`,Щv^_/A,]SZ_MN#sž?|OnJ8QK31"69ҢƯOԮ/gZѓ̿T;Ҳ1#8Si:5m}FVwZ{w^MEr| 63ȎW{wf rpBOzK}Qмk}NOméBMϙ:KjM7XöZ}ގ֊RG&ss(J-B'SWsĮɐ5aG>&x¶Pjէciݵݮ,nV0%<BxVx?_ƭ]%`$nXX$nHG&q756ws? >*j1_?Iw0K!TiXbDk""ڏ/ kzށ^O.mt;DKR{^ߧBڕ)+Y?uދWwTW]A>jCx}k/w6淒hlsyrs)|!?ko ⯅)Zڤ(xuӴcdd !Bqm_'3YeȦM^Vj7tZ5k}.z?e ޷|E&j?;WK])6o$+F9rư<;n6\GO|HOcW<9YϩG R6Ztڌ,]_秮QEA w7oM)D ');$yQ]I ]7E~iR3֐$icrӈ!V2bV*@$߃?Ca7ï~Kسuk'-Y.UěRmj1*3 4envb2]8և+Iﮍ7kӨ;ҿk?~^i~uK;=ɫT'Fvڪf ~8|a~Mk^D.4B[{A=cyghJd#qP=x\_'K8]Ub3C0RW5#+Y^T\%jn|~{]i鮦C(@UH* ȯ"ʓ Ȧ !\}}k# 𣻌6nI>䬯 //>/|7iwk݁5 apFPz?=,s?؟}Z_I?u^5;?_EeMacNUf_?͞FMIE|O5m;T/XtK&)}?9M"0)r#o\+_[yϨ,HɖTUtQF6rK-zms~xRd>i8/ȷٌcoیyQbte &Kuxx3Z0WfZ_[{kS!!NX p?1{QhZuƠiDQ4A= א?u@χ%. Xŝ)4Ed_ii'[[QL;0Lcũ~|:Saw9eٰc+n iя/ƭfAuebM-2R:ɻd0}'Kx}2{-N[*?˶$C+9FqjO{4UOs|Q7|:ŝ׀|xJkqi. .d`?x9?~j:|+>Նom5YD耥pD `3_Ek l={uhzgu#5+H-uk Ag{}VmַSŞhp96[^jU+vFDc1THr[]?I=*r(%h^וӷy +ž'}BbuSB4YB$`,A@F:ooCOla_3ux_OOQo:L? o|Bxuh5ImJk?,jgN?ThX6[;ÿgD?|㯈w'M"+ _FekeRɄ?< i){w|m} o&.[oyY-Niގw|5>Wkmxf5qu(Ibai%tVbXU?hٰOxN K40&Ve)O)󢅤vqڏ#~k;&SktfoO.`&eF7_#ө?Wn GiWV̒) &cxTxNiU{3YNPMYFN%n'xZ^Ea趑XY[F0D#}T('9JNRwlQU ((.|Ubzyv'(Ԩ~8A/*'?wpbԟQo]] /'Y 1@|-O#Ek,_y9SbHG}w'}/~Wpd^:1ڟQ_esWO\/ 8%pl~g MOؿL??^@Q@Q@Q@߁':ro?O]ϻvl"Y}3Ou+Ɵfyywnٷ]D%QE xl|7Dž8)bhHʒܣ+YZ`y6~/)=V_ٿ<)m}G?@g[1m<@?>?/G'wo?M3 k#:l1,(Ub- > ?<_{D🀾O/;Wui$;KrRQ+!IFTRW%{i6+ N@l0-z`*ʅ xwĿN+qi[7 񪐮Wُ s5ᣊ wݸE+o6tk=wW֟(S\ꢳIKYs)9Gn)hWOx ;dd_bfedYV{)9!.о,W 5GybXu c˜A%mW;Ok?'k/ʹt]c\lʳ+5b7!Yq0}b΃o㟇kcſ qɨȼtx vih4%fA43dV$FW>sak'_+^+ϣ}lm^9$G.0P2q^>Y+s۬d͢'ݶtnK봒kTM~վl-|CmWšH y_P濖[&@JAo2?xK Qk4&x[G<h>$G=>-\5=mkwzXHDj0ޖY#,ʒ'> ˯>Ʃ[h%|+_CukڽROyiU3~R ||u>Vֵm:} J5N+8+Mj c{.N65Q_VI^K&͊׵N[UW7K b'Mm[|%$u:Djn^2 {2[(on#%?x>. i|4kIկbҭ| Shmiq*;_ նe :3[/^XunM'PM6i [$.%9f1pTiRRyig=7iZ/ό_ o yw8}3N[1Xzg#^O^Ke&ťf_/!Q7:A]}:wʫ"iHV$I?t [0VZW_%xGN~0U~ `ҭ>&#GW _F~O/q_Q=oO1?ׯW~c=z[ݟw*_A^M-#@Ыkɼ_]m zZ(`F|dƩǪ^! vxh~*҉e}?np/+2RzYxBU5=?X.y7v7 qXmt%NX# ( ( ( ( ( (>;/ϢxTaj!HEʓB/>Z:4>0h.4mb{!R2k| ݓ]?4_[}֏}-ƒ.pB! z]88jj1擌 oE+%igʭ^{Rs;Zs>u{FÚ jWUϏ5z "&lP;Ƭ$fPFkhAdooCf@eǗ%H $1%z:ƂM,r[hwwU.I Ǧ3s_;oֱuMT/k[—Kkb@`FkNJ܍Z2oɻ7yY>i'pT^:E]F[;Z?|9_66"~m-wJƶE%3> N?ƅ[^ lm&tǔĸvyn# WR>xF[._Xk1d|H^>7R6vWӲZ4BN->J]n:\.pm"kcCn;C0V* $+9^93zI7,Y9vX6.J-Al& }״E,D B?jߥ͑[NXUO{kz+5c|׿V5ǩڄ=KI n_{3`eρO]ׇ|'/Z8b8"S}^# V3tL~j/#&np RM뾗ӿUvG4rBMmI-nڶxGï?z%l|/wZK5&-5ͭ/V2~W.u#VGNz֬%F"[x]V%ZFM~*$H\&ӮE֑M2ygiIb Q*1PŽ?=g(4 ss{4Sʉ>H`GF$4f$ZyTfWm{w] p(*iiB=m uiv3z^h\\ {86<| |tׇi i\^8I3v1(>?5 #|#{Gqxf&& .Vj%$(I&[5wӶ[c?sN._gѻ6̐K:oquMMLVS![f8@ă# ;xVqQzl5Ӽii/&hIem%]1s{~&>KF>y;X[PtlsK2wF#]NnVMrm7&ti$۾tVvQV%|8J߇t;$h-ؼhJRrȾ|&co~C k)5P5giō 4x8?J([пl-Ɩ~$kO[TPd'!h x&t @]A=om}ܖROts۝pkm7G乿d}V{s:IFWwnW[;Žw_#lgW>ҭo~(k%ky$z1#LQ+i`6.g?xm gZڔhyK RcFݥTrgox?&Q𭎜ufѭ&7h8+)X~.~^ R]FFy$)'تE ͵UQqoHsKlBy&Ne'餣kɤ>mi?~^? U [x%+ bݤ][PӤ#Vb : $s Q?|,"G#/Na–+LBjSw5/DĚ$V}ݽƛ7r\EAM4΂F`D)}.mlnS)-;؜Oά'J%EJN˖)j抋VV؟X,6gޓ!Yd"y>Nj0!ow;@<3&vkzot xc7οa_jzF$Fu+b8mک r 7ڕ]ms*w;")b#%i$|Efc$ z|wVimZBq*nT[m4fT5υ^"c8Z0[c̓dchwh>H~N\IFɻY=/vn/؃?>,hZ?E ˛m'LyOءKgg0|*s=ETthVz}g隌+qkwi2L,J (86j1ge/HȾlg?,OݷOYk]~gݗ#>'LJtAh} r }9$o>& Gb}f-펷upVcd ".7]@345Ӫi=l.s(=dmݽ-kgki̝Y)k~,|xiw%[X;׶9ң0 [HV9CZ0g%oWesiE֮il Ȳ I$2[U2F";_ [^wA+ !,vnso6LkzG;|ڥʣF#(:02*@X(IY.nݯĘP:1T[q6N^_46 x@?j#⟈|aqoXUKR(ȖL,A&X30繗[cM[ikW_(ga[v#b$ǖ|RYnwmot\NsSۭ.rv'fީ%vJ) IQĺ-\~Pyb?;+M<4a(M=`W[_szW<:ui(EFė7t]bOH|t#]薮="wW=H? wZOg+>h쿳ɿ9kw¿ᅱ^?<Ú.' 1m<q*jxb~}I~9hcO{[1Ggdqv?L?ػO߈ڟ$pH-<3\l,$Zn! 6q8^1ߴoïpg+kiQWαZ,w{Xң )$~,8ueOI&.q-^mY<6*]ReGwd,^K £ugRq^j_I<#c9uu _0GpE 4S̎I}!;Lq Io6/O-1ƱNq;O] RSe%*X|eJoR-hɍĶ\7IOw_ oÿx\ZӴ7vwwVc ((q֓ߵ_0~(:,*Ėsᤈd&P c.л8Rqi--9_r]ȋn+Tf8g?aˏ$T WE ٦wi7]ڵ=1K u.O^d_Du=ao5Kj +inifeookX`IggvᏍ{ÿ</"H5mDh 3ǒHJ>x?Ϡ|G?~>OCv" r\kAqk 0g 1kbkٴm~ךM9YfVTW߶=_~>)8}j/1clvv&I3x߶Ox ;ë}Ie+WsNm᷺ !0K$ĩ&g@-??I_z-~ PͦfwI6^+]&*Z*JLqSOǯ>Z7]״ W+~dTٟ! %wLIE%k_i]KoǸ^50~em} AqkƷ ᅸKK X4R~ H|-|+IWee=Cm{ >k5SpPmDeHi88Ӗ4zqi^m[zIחj?p>*{HҍJ_(wSyZ֣=^ZEy3;;(㑮)y XD -W? k^-?V|{YgH-4R+!S{ oTwZ Zo)-|Or_?J`?O(|{7|Qy^n;Vrr[lnIھ}/wRz+~]{Fhy)_5C.O"ޱEk'+r(G|nd^:5ᓏ?_4f;S 2c?Pc $B ؿL??^^iɝ'7Gk((7GUeMi]YAfrUi#c hρ':ro?O]ϻvl"r?lEi:7⑧t}8CimŚg8$X>ω~_k:o|ae4]N][8 Xe`˜nW\Mʌ\U=fdvM¾$nuK]J$8#MDIt +}}q;>$]S\G5;e]hҋxqskHRI1 JE# b:;vZ.6I5WiL ~߲׃4@іh,c EG" AnE'7omhڞWgViC+$bW]$* lS5= >\p'O֫qisyso}&$rG"Ea㏌_ KU̴dt1S4^I]>Om%V_ ? Y09ABKI&ѝ'yاGߊTB?_[D"$I`YS ) a yٓ ]Ooƺcg N<5Jb8|!c ZмA}]jKY/šZںucso 1 <$i#WjQJ VN;mWWЛqVۧ,_t/?KImZG|Ӵ ;HQdy[}BbHM:>[}Q$c^iIiZM]=;{#u`嘶~=xgƱውU{]WFѵ UWwCsx #R"8ʺj&/]4mmhAl>o]rxB_ dA5jֶFΥRCߛeej߳lj'$kA~aZ/[|/I㡎@N!2>5d֏'?)!8Y륵죾$gS^i>,ѥjri)2ig}m&Eu,sZI%3|.63w\C_=姆qVBז&嘈<}}Ecȹ\:4Jm-UI))MI?$G?oSod'/>(Y'ԯ5)&iBj^DWH0/bd _áj_e`knHHxamYG=Dӥ4I.ڶ;+ ɷwץ޽wgwcV/92 ,nPos#hc'$Mzo/t?>^wSU%#/S0VZr ^2%xGN0U> `ҭ>?J|%vwூG1xGڮi_dHO6k+5KCwN]JgC׋sCu*gH~R#k,7oA{e_o.7_aGz%umCĶKjRM?lL+1JU&%*+Vm(Y_rVIG q"ݢԺjyuӳ~zﵾ?Ÿ ~.|>|,KZ3[C :]E*_,'~_Lz_Wfqck:RFbnQ6f3iU~/18ۯ{UV_=h= jRrW,ȟ?|E<)3?O _Zo7ǷgK˲7pFW/wa]wo^#oV'V+1l4#=EjWZ ̊}TEzոWԥ 9r?zUg 9E_3j}ep\ -m--mtV[l^^ :h[57Ie+DnUZwfd\jFu%<[My,1N@E.ʡn`2y sSQ^zѯ^*2ytsi6IMIX5m$|?~$~|'{o|'5-zÚӲ6yFuH`̄Oo?~54_;\.ʹ}Fށ^G4\5` *bY1D0QvPPF!7"uOxk¿d>|5>jZnXܬ=B fO#*/EDZOE+rs%n(KNN1M~Qovy6I%_4_ocK XM S״y|9cR3 &[2SYȆHbod|] e7>7Dt_ɧj~}S^yFuՖK\];K;m2U'Di'eQF/Q)Ǖ/{|1ń|څ< 8 ~/]_Nm-hn(7kK^i2Þ-+aċ=|hеm6Iod 2*OpH|Y%/7ʭ5QJ/gԗͮgfMݽV_Iz2~ekek|)4^[*x_ O BJ_K=:̧,Ls_ iv?'mɤ|9=ntٵ$hbVYA7唊:+j^u?ENqG4)EEwF1VngJMjڶN3 ~/h?|Ax?xoiέe \ŧf4SŲRPwloo | ͮ>,+u*G;[i֓麕ֶp/ۄd)?QV9Mվ{3o[tW>1kr~?g-kv>&"icAQa}tN]^I:4m~ϖ> E| h>~z9 {y]M,7Iq1.P(yE)Qi[~KMS)MoȻֱf_o_-6SuΛxwTgiH2 h_eklq\jƂ)Y/0uN_k~ewT}aq}{Ut۩Xh-xV8D#/vLi]-w7Qϭ/^~{['꿲{~4'ƙ kNyn#;iO! ɩfD mVs_G> xr L\xjK(m-*H&Y7@cPw**+9.g&\jWV嫾Vd咚Jw碷o*տdX~|vs໫6zEzWApׅ7p9f$_i.fgY m->_ط2w/w {Emg5I?yWriܿ{Ͽ4OX-g\|Sc$ihv1yTHl8 aƍ*VqXYg{*VT~Jߏ~撗2}==;QRHVwW?*ѬȯTXǤ_J:KWCa+$G-@W '-y75:]W~Wb}kg'sXӥzgbvQEyAKo=~G<"f1gn1GW7j7-Og?l}6 Ǖ6(I\N[s⎶&e2MΤ ٺ,DmuMD?ڻj//s}nGo{v6ϕl)k%Ԟ&.`ISi$VbR$FJhpeiSxIdVIW.t&Gԯ M3-Ŵ$i"Y<1=*MA4LQiJy2pE&ъI5f~C|9;ϊ:O>47nG|2e\6꺬 a`P;*'_KgOSF;(.olG?@]5-x<Ego|/~_ |I{dmfeOjcgtv$m-1.]LRyO#G C'x+{:|Gkz5Ks5TkkfYVD>df,I柴}{o]Xi9~1|9u+Շb)bi'eu)A)6ޞiXƢ,Z٦g։4GݾU'mSŞ?](~/<?ovRVM;BMe鼂| &ۯ'~~ܟe9xS$a)z̧v6"%}y\ůj/èoVv>Dʳe gtņ̐RwY)&oqE"+^//iz0+ ϮB-ƿFɤCjQDB?Bj61wy~1|5W^ e-cL.3j6Zޡ٧|`[,B唰y@KEaʹ7I}_t[]wm"j$VG?1O[]+oKpT/k%-nR!*ܠ*ſN׾ ]YEu8^&^oyou`@"$1Ns޷r[tg+Yg4aRя)GIkFg <x^5/V'|O vd4%3D`[7.7x_+]oFvRh:T#>'x_]4{O&Яde1.#_߉t_ A^fwuƭ]2M[X"iedjQXU,q |BᏅS`o.,<؊7U峿]׻fG͟?犵WYu3ytS8VrtɗMϷ#¿};]ϋ^!s.|YlIl!Kr.\"Zj|Z]H>׫x7[Ȗ?\Kk i+ _(X $0 d}/*qO׺WΧ7(8=|> -,\+O־(𶱩[ZEM3JGZ,wEYcGX3?}~?|C[m7TYG5+Kr=hK%eYpXHh(@XRǠ93_'~$ż;]QV~%N4{6YIc6KYJ?#7699j~VVZ')}⼷)>HS=Z|=b"|"7kOtlmVY7-/ 7+0GR0Ogf_OFh0Orlj-¶j%FE${Yy7-x{.fjkռ}Kخ%4/,9GN_/iQUԩ)OROhU%Ӓm?#i>UqxKkj~5itM&0|l9n:oǧJ-韎wE|>=|Qo]8&] h߅_{(K`?b{?WNWGQg o__?GkW'po1\/ 8%1H?? qyt!./;Obn0ץEPEP\O }ceMV4Z ZF$r2nXCڹ/>xvmjjZvmkqxpY<ZpĈH?kE?Ś |w躞i%,EOӂh۬͊cnr"z'ScŞ7ÒZhZ>ܳ028V%8sW?xc GߊF;үxU [3iCyb(ke<'/ ζAE|ғI2'f?o|$'3xKs[W[-6U$B'80 A,6Gw8|b>S[º|AomxycE5* 0KC&>woL|nW˰[k=0bɶ@I ߡLV Ci NzBcV \l#6KFYBNR-g}v]4E#3F2,=H* ׊[;߻ov̿w ߋu|I5cv^>x2]^vj䲺A+ǩLmpȌUT^;xXG4J]}F?wjv7vkgq /_Ͷ[ 슫,~e|O-="(MeR=zB[>W o.U@%r\*2Kݾ/{=ӥ62S{4(=OMls *x{]I|b{i.VV}P?kO&?ď˯3t6:qnl+;]3(T]սo0i#[$#K *WrIy楼g`W|3"L7&6D$}̌5SRI+=_6{+k?u}܈hҒ-nj>"o^ >*񎟨= oEղjfh6ʋ42KJGxI]Ye𲮙kjZo-2ţO~=7 )7'w_ htNP\yV"+\B  ۖNBG%ԣ75hZZ6j[[׾m؇C>j<nQK|kOh18!gFv|:#?gMǖZ/2[Kx0nU@B)[d+?t{x/_?'?e CHQvRğ*ʗPWxe H4*oi[a!^=(=3nO=O6TMAIuMۢIbf. 0{YkT=OGon&ǵp$r[;@0I>2EOcTck((((((?`mj/|b=2/ג(y[yE<[F-$o(+mpc igC_е]UfQi,"߽Cy!Y w QʹiiFiX>EM(rSTgH*{ϧOy*(((((((((((((((((+;+hwW?*,?/s?%H|t#]薠+w¿ᅱ^?<Ú.ƿg+>h쿳ɿ9|ɿ1;Z( Yf }?#gq _o߳+5e–g'{H6y~Ec~cʏ'TMb⎷w:m=loM RtZL8}sz]]>7GӣϷ=y nDwʃ~ 6w$}a#t83+,,[vۨ,Um ] {74M7>\\X6lZs< K4eAE*/|]ki[97v\U_~=uOz]lbnnoωD. k~;_^Ծ% ;2o2haiq.u6J; ]p%G(Z~ɯ4$ӻrnRn6ο[[$,߄g,u|W]tb}J/HVO`x3a$߀|g?&[w侶ݖo^=ڜ6ױ+mqWOP$~yst%N4䗧kt_ RN1Vom.Is~>ǃ-x@} gյbt˹J7OmbBcϙ?8my7|1mZz?OšNcJt-RmBXcϖ5+[|Jڅ~~?Cßt;ÖڄqwjW:w_\fY!w qDUeeIJz}߼KMRWvH'>([|hO.l>4ͬi_|C뚃h!ž64b{P'`I\E$qDh+?~5 WZ5뿂t6w>hmI,fMcVԪ("r勍$}ui:Nonn?xiv]]þ4Z_l=Ԣյ44|"&a啓Rj?p>*{HҍJFQWGjURWeݮ˲)W͞+5i;^Ԣ޾W$7i{Rz+~\#o+z|;Oz89v? GSQZ?WNWGQQ"__~GkC'tf;S 2c?Pc $B ؿL??^^iɝ'7Gk(('> ˫YNZ[M-Ji97, mÌWm\ u];L5 -;Kk8^[,ўUR8bDlp|C O |;]OUԴvoI4[mrf1Lc7s9`>&x?{V6ia 喙 c*.U~f6d@Eہu㟈?5x!4KOT\۽Zb:T>vݱ/T8EM> ƺi{|ɖlp@XXsM)$ʭ+fg+QmfOVAU {yPGNTjx%oKF(Jv(}e#1PRG౾3mCh5}'ZEFr;"uU.ՙ[H a9|xĿ/5?jZ>"ZðDda>Y\仙O+Q1lIs[vWW]ISQۚ˛Dۊz]^4ݚN}#_G m7.AdL}]_Kk/ 0b'R_7þpko< r~YChxJZe2[2x*-bU o;opxC/ď,߇c,~tb{>p, RFF%[븫ۧ\wwҽJ iyl ^o./ΜrFTmI9b}U5᰷}Q `m@r"bqq ԒJ嬿l?^ פ/lt_O/VGKG !YQ_[grBiG U:vz4VP_xp8B˷mm̖b ]Tv^ZN[}{{%.tƖ9M{AILXRsJ>/ZM,x͑PwϹ[n~\c=kQ|&={du{Y#°ik7cU;2n>^?wQ|D|+MBּ9?ccЬ5kZ{x4{۹9DW`4,ZU$yYR:"KK5+芩"_.ZQ7ËэZ WO͓1hpR[A' Rj? "g[_Y JX| c5_W'F5焮o \|+Itb^2KolKlK1 ) o^>}{y ZC_8l=^I>^]A![xfECHNZ_>,-bvw}{}]iˤivTaX0p:P}Wx }_^ 5OxNn|ũiak\[ė6*0pnPqwBIi./x{Sltkica-<4GlڔZ#x1Oٟe>-zC3\k~g5}&(3k<:Xdˬ#wE ?Q~(N/73]ژQGa/JXݢiYHi.ouv}UK_>ߥoS߂uxzupksn-KH \dւ$w(U.areB,j G7k؛^?-QHa\$-NWG=DӥrpgyN^A-]?.'םk2EOcTck(((((((((((((((((((((((((_"\VgxE}C72="wW=H? wZ\O">05jg+>h쿳ɿ9kw¿ᅱ^?<Ú.' 1m<q* ~>3 < >$N=GH%eeFt/3NH_-_ᏆAj55tmJ{PS)[I i'3f>xC_ޫ 2 2r6"'5r9o/7&ܣ}-%F%g[,sk[džu !M3 կ4fėk^cOa~<'+_|y i9ß w>,n͌j~ AAv҉Z+{v1`_ m>K/_bm1̞Oٮdو$> ךr +֟c{ iZk{Cb3(U8fktޜ9]E;蒶|LcU4(|VX$KkgdS`9g:hۯ0f?\l)K#m> i7qx¿\%uCluk%  ?c:g|C[n-k_ZIVgu,fPNHRMrQsO|c[ ѵ+95FV4yzkFH#$Q0~6 KѼ-//im7kx^ġfDV0 M}!է6iu:OKռ3e{u$04˺+1,~' T<'qj$Ӣޱ%+Y['yB;yNQI.mͻQnJ/;j5(Ζ2KFIy6+_Ko|5/↤oxO^! 'O5e0yn ?h_î|0"W:4OI3L4E֪|#x|> xV/-dtmoOY2ĭo oHAS91_o `vMG]05cQfO33*gT{mJMS\՟6QwKGm7+FmyovPwM WK$jDF%X$ =kN8(UQFJZҤqV_ק(-nڏ^?RQ.|UbAgpۿG+sO&[?^?|3[v<.&]>pXed=kVOgQ~<hxkȅu7&o}Y1}Fc?. ~\/ 8%1H?? qyt!./;Obn0ץEPEP\O }ceMV4Z ZF$r2nXCڊ _΋7<|&ִu Dlol59 o |1@'|Lݾ(> [:Eϧ%Ů @PP-mb^.ޏ_eG?b97ٮD^gۻ}6mWoIJQMY('g7w/M׭|5<״ ѤK]dHF,X#T?ha?يoozO\ KUp1]IPX(vG?xEj^:<7axnu[}b9Uud8Fd>aO`!⯀>w6y Ke}=J]Y, N83 ѣYW攚\^^owoa2:1 )J13,o{-5oKy;oc_o.sꯒ5e1/ HPz'ž%k CXңƒ9'2&!@VN[Fi${iGErWi ?DždoyxGWvyW-%1'OwW7t/x}UӓOGjm&Ή"3#8D 5OÞ2cg⹚?w-Vv|*]ك|/|I|EM}_|BֆOis i8egXH?6 T?v'xcUHgW_^JfVӦЭ<ٕ'- +n9m,(%vKUe4d|޿8֜MN_>ڗ^I>O''Un@PFؗMմ t#}%ιx_PzM}qm ,ȭJ#"Aڏ#%?KuKr-[ѿ9n#B_,V?Ě~MSM^PhliQ7!%gi&_&`P Snԣoɷu%{t6n-tE-ie[CixK_~M.iz5˾lv'ӣ[9֗$ARTf,?k6ЭΊwqjmIlkiD(~벷6vp;D ^L nl2zRQM͵ok~Iʮk. (a\$-NWG=DӥrpgyN^A-]?.'םk<_ J?xW VW߇_2W _F~O3ן'~ʿF;?Gz_`cV?cGZ{*_A^M-#@Ыkɼ_]m zZ(`F|dƩǪ\O( jLzwQEQEQEQEQEQEw"knOyxDY:ť 4h,2>Z4fX? :>h~=[w'%W22ȡa Kqo?`O/ڼiw5. 7,Lߔ.Nz_|§o WÞkzd6f.vwcsc=2}k _Mg1RO]o{0~TS+ܜRVuu–_$\z}u}g6v:mj7H3mm~)x ΃{{Mi&,I}QIO5w{izmP7{wx#eޥsZhu2G#* 8 ~=x_¾_'K!7s]3PnMAjmݺ][ll⥗U[wmZo޲oni$ٳ~%)|] ֶv:[i.,IH :d `M:o {fuk6>kwno%vEglsp08] xS?hz-'saaׯm(26Y[<=s_mfx2s,p[;{xƠp9$\u*FXJY-\֋RWizXj)JNM=m(M6VӷO;]QXaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPY/_P F_"\Pa+$G-] zE{Dq_؟}Z_I?u^5;?_EeMacNU_?͞FMIE|@-4=HuMCU&R{bцbZ06nz~^&o?׌weY3luHW #-Z~[tm xO+krMg21DNNA^x?G^8e<7gBX_j7L|^G-[6;HBVSmB6IW ik 4FK;6;m-ne`u[}k]It{gEej pG@ QF=4Q€>rB o^ ?8N}"X KqZ`ʲ^JEqϕBNrJI+6iV~>>j +hծ |}_<5 <+|ŕ|f7kijB&|cL]HoschVii~&MH,6-Ic@K0N9$׊~:xŷogេt,tk; i,7s_TɵFFPy|G'|> ݵ}>g`e(n ąyQiSNVQQJ)'F)ݵ}K/ !ka1^QIZ)Fۯu+ۻW𭎽x/⏊4)||O5 'Jx4=T\.P3gSRp>%:9Z1T%M>=tV'ʒ0o27;#T~>P>3N7+o7SM{)퓫hM`vn?u~G̽Kuю1̓n~3WwFu'_|Zdžo~^mBuݖs-sm"^<nq—+ׁ?heo xߍnqZ׆N[-\lQ Ou G9@;O/i5=SvwtOua{i-OiQ]OeR)?<x?/.soi_!I7DYy$!M"g 6I_Em7/gŧ⮼]ދR߇R_ Bo| /N.[x/^ֱ语XKrZ-rVAk#G8$m"ͺ%| _[/eX? ,/}nQ]Ɨ2D2"!,2e'naMc_HgO=$/}jSVw浝"'i7)*]$.q/6G4{> i7/ulEw,,4LrWMW5}(TRi_k)g}?io+gcxNoUxůZֽ{ 놹WM8ؒ3g?Y*M#Y)WՆe2AJJ M 7M̡\ajm Kmg{hk+Oc=_t݁6bEhG#Mi~_ugO+6x@ ]y"MXR)/fTzGg(Zj^f߃:sxijMc[5w~y($ls e⯄~7JKj7~\lcK GpaΏ[U ^x'NheݼVCwoi&8Cp6B~/m?ʯ潺iVM[{st{|nW uu o>#յ?NCo zk fiN{8lBeFt Yv  # xW<-mV6Xk1=ޑ0I+$Oj9 iOş_t'2Im,z}݇e۴ѴW3KH^4>`?ahmbԼHu_6!>fh>"أ6Gl6爊]6Rү_7~YoPo:uW:M+Z$v(M$lP^!4_1߶h6i^$'%v\qޛ B _? n !~`<_~x+Qvj+}bMf pݵe<,QϰٞR5 SQh@m4_.vWspX~<ʏ#37_C~WO/F#vc~\/ 8%1H?? qyܛt!./;Obn0ץEPEPEP7k/r}Ny~"/3ݾ6ȃo_eG?b97ٮD^gۻ}6mWoI@|omh>#xOS//=kSҵ-^caO`!⯀>w6y Ke}=J]Y, N8ɿ/7ߴċ X<_uEf"A/<#]ʲ ) 2{ Ӽk |6AcoqK^>cN-1i]6C&;boO~x7[v˸<:䫄*Ac$@ C~?:=7~ZP/t񤪆6Ga ̉HC"U1jv;vV|UEFE;B\*~Ѵss][M5?xKTMoúɱ[謮9!eܲy4rb$G$KxVW|='4=S\x>#Ԡeyn Nf%@Oٳb??A|^u}+L5v *9#`e!NH` 0~s- ޭssQE kX8ieU\!iN?RWQnq)I[Yy.[y-;|=U?!3~#ޖ_.BD=HDd 'Gi !oL]X5OU7>2bfrLd9nx+y1eh,7|!k ҵ[O/|T.5 Zd:=ޖ-5 {X^I\$'aY^ IO :}.Ŵ<Gt$6OkAw{%X`KWoV^\yY;zoͿKmk9{g>5|Cм=]gUvYu1l.4i^+YQ.o2NP#Fx fn [\.}&kILKyWȪpW+|>=4zC^!Эm)jp#->nӢB4Nok2yQ?|*Iekxzvk8|-qzL~R!ٖ?vctRRakv\QiJKviDי;4tҲo{G?+}}YO ]V_ ,U5ƳPʱF6Xd ޹Ծ @:ߌWLUek汒[IY zG H"~'fZkk3a^jqȖַ1".b©#Ν}Vk?GJX9ã]6$MBH͜f\FURⰪjo(~w坿v6i|JKMŮ/#mվ~|Hkkqc]5=SUl ﵕo$ o3$ :zյω:G|/W^ mVo-%77Qms#?ਚƨtO~9[WI7%Z j<5M6Ri8DHasu"ԯt}CZPâ'[a9O_jTZhv\F`78Ի~vmI/eÕ5khIy{6{{|4-2ǧǣ:q,1Zl+y*4VL$,őM~ ׺-{T{+?7IK T3H[HMDp}|N=T2m65|;2kRwVArW76b!kEay$"g hTZiqxĚt){,W~ 4n{1=Q%մ%q tw[u+EOiBWG=Dӥ/O߆WhL-u]D4syS^ D4R.dr '$-N8=W޵&2M]3 ח|?Jt_ o yw8}3N_#|{)Gbi  VW@~2'_u{x/_?&b?e KQf\Y1-?j̣ʗPWxe H4*oi[a!^=(=џ?'1J/]QEQEQEQEQEQEx_쭫3ߎ5F^ѴӢ "gGiIcs,Qn3>-#'|SOL}ݲ\iɈa){hY;ym?tkCg&uiuˮ4~K4hu>Z1'9/GAV6kéP vhf RTc8p! M7̔y[j{PSI*|ܫhֱvv]:xM֕xW0hWH)X$X(pȓs|)UJ!e#G\j.𭷇_ĶaiN|R%`$D$1Kuv]׮m0Gmw@ φVZksYmkfgwSHX*m9gS gzhӿN?^jJzۗGk_|Y>YlZpʭ ^XmV1 `|˴Lj>0|}ߧ+k?fǟ6F5 h (>͌?4/zt|Ha:[Q<*[;Ęڀ`*>ߎ>;uau}$hM]孴v2l۲VaRRTS\ZN]KVC-*/)M>[O%+ny_o]ZaS-t#muU-ʨ2G%t ?hGF ;ڞZ~ʶec 9!>{ܽVm+]ipT扖HpA^s6î.-K_[Y.@2mT A]:O$RrROg+dJ_aĹQTyb$nmߺo]~; oH>xGO-q╒qirl5\J?L{ʴGV:&A%uN5 q\$sc|{Sŷ.U2{eK1US& rGi_^ CĚs 42=1aI8cQJ8)IhR/:}mX,dӅ֞TH7nj]tM>ٞ o~>*RCe[83DA%d>|KQckF+!oܓ^'ilH)[ dxj-a''RӤZQ񮵩]YIzZqu$!-nѶb(;>vkkv\ß/7?jz&qzM>lQ^%N"pᙺ غoW[? ZXxL'_ٹsA2  $"]z巼/ ?~+]W>?LT odͰ2mnWvdڽYm75+Yhe{bì#Hp2 E9/)FInzRӾ19;MɵMFj+-9ړ;[>/χ|2Emm ?Ųj%-(r`;QTQ=cķeѭ,ohv{KyI%HhԜ7 sWZF6ii> IZP+mQ\dGTϤﶞ󷖑eX44M_IIku__>|Y;< ֕xc[}RLmmy`B˅-p>b2pu㋈tx/I{ȵ(%%"Vr{|6i:Ei&$2>v-aĄG @gtVݼa妀Qctv$chJ[ЉUa *97IZR{jN_ʧMɸ[8sO;$m-ݫ~]>SQL[Jo9ܘ`͌0'o\_iū keRuqA j:#.m:u=vh VBP ,eCB\U(VN;E)yE+2LCNNRQWJwӰ-ƥktkKZ8]-.y@RIR9Z5'n_i^ď x_Kҭ<)xc[.o3ȟf$j[qo'߅sSNڕmZYHۤY@8R#@V5~GGkkٜx*8є10M^OWI]leѮ'hMZ,7TOR䫪5Mih[]J" 9.ym|tε[xgTZzڞ|ԍ-/i ~{hb( 3HcxWF4/4wJD?kZ%Pp\]'hگ$V_٫Ÿ5{CEOj6gsĺ4+n{뉌([2!`v."GZYtu}#th;Zjww׽zb~ȟ"|fW^6zΠ 4Âk8DQ4Hqizo'񞕡6O>>lQE.`b`d?^#;^-u{Etbc[Y̲-`n#qOw/|$:|;Լ)Xot=b16Ο$ɐJmPe T ,]mmo_UAdlk''4 YjzOXOHa@%,櫧,ͥ>~6ݬz-KͮږqycJKCGxe%Ё 7V?c߇zjGLծnau F$KIDI;G*I h+$3?ែ^h7>4$}-?keHX26 *PBt\\]̕џGkn+]~+ڏv-aĄG @:o};Wk=vP&k6 OpLXuDiXQ uԜ%kJw N]V2i4/ך׼ynnj|4P?<h2[bmjo\E7/?~/S>$+Wzάfauu*[8FUjBWI.+muv3*T(S|M/uk|3ꭲVKt"cobL)8[oe4TCtWh1D= *%$3"SZLZwa;G/ms%ʬIIce6у) y}_MmMu_iϊmnḏHT3lNOWӷ~LN9'>T~d2oMT^ύ&a|kZqh c5+k 1-6Q5j[ xraso:jd+fȐ$1)jWE$ZtK\>5ֵ+;i6KY.бD%6Qf pE/za5VwWg ɍ i)Jdȍ>~wQuW<6!'Wvkr + ^."i;|xw~bݭn{)6eYt2808$fq4xOpN_jhmڝ+fxfx||$XSQ4;d|jTC ƗI^oUg݇zE{Dt6ҹD|a`kչW '-y75:]W~Wb}kg'sXӥzgbvQEys5|?[RPI$ 2P2enT,@u'|?Xt65ΟH(0--ctFt5Q~kd*:zue$:tfurk?a(xkSΌ}ΥZ>dVp]ڦ]dʶ2meXvF7vոdmŦWOԌ^jUcO.kY1S`'J:uK35ỻ͢"k)t{яO|6!/5vkmS>"`XZ_iyb,0Ev5sk^p?KW.>iia[-c?ָ/ ğ em3FvqŌ\Knz[ $hvg #yUj(EIɭmR56&+ {O3Y6S?K^ >' Km߈hBLYbHĸb#JqNI;.k_}/v[ݧ+d??תIݻ}ۗu h~j~4[Ce 5"m+<oOz. h>Ƿp>res=HŻ;}_NWa3׈~+._˯2>r=Go"܋%!eH+mS|y.Kh䭭HM/[w,ߺ_<'B'KþЭ5z[T[¥#S*C`^ʬAyr ~u|.|Ck_x[WԼ-"&Lo#-D yT,pV,Z鬠)SyoDoMl"zTq]-۾sM4Š(DQEQEGC^vGC^@+?ۜ|<Ӿ_f'J<Ӿ]zȮYs' 𴞧_{(zT?>k4VOgQ~|<dk}O/F#vc~\/ 8%1H?? qyܛt!./;Obn0ץEPEPE|oyUӴmcPRӴk[Ƴ彾X(ӆ$F @Y}3Ou+Ɵfyywnٷ]D%x׎~ X||O].M?RMsnsYiPvΔP4^M7|3O1xn%&XQ†vbc)6>ZҾ8x@|kW+YִG[FլgNI{ֱY,EJA gxx.$]PH-݃47p |IUqHUɓLM_^+]OE xSᵪ {^jywiJ11ǿڻZ|{yC#{]Wm>{ȵMN{x.|ul"#A#,8}+  _ú&D޳ga4k^S0t0 ,3FQB^RvRQeI^l17&'5Z]uʤe{۶> vK(i#7AyܸRtִȵx%U5Sq1VVֿdeefU+_~ xjYmWO{(X&D uɵ%xðWPgË opM=I)]Ic-h!khiɘ7 o^? <5Ojv}_B}Iuq:-RXXf}䧔Tu!Y56kMYmսmK-_Jm{hR|EƇ˽KSmY澾{Kyڕꄓ+2~ /ZWe^KW71^K +4z}m@HN=8/v\k%0~GLjGV>χVN\/fD>hT{=IlMht2\)C4v ?+4>6.(~x+ VJOc\^K9lߛtϏ]~7C\^[ZvByV-v%<##"?mԝV̤Ť֍7 EG~k5tvo׾h YƏ:fcI.ZK3de]6O#>Ե xPV+J^ MsAGԭ^k9P\<:bN%}O۴TNWߗr>|}zLj!q=O A Ѭ>ZiL:Ɲ\궳e7̺h9%$ ?Cc ;mXYu{Úsig;vԆ4V (4]/ZӸ.*BaJM&iɧJhIfVg~~!|0 CzV5 H[hz<.Ӵn1 Q"K!H ;IZ'-k{ccKZs43UbKOk˾w:uz/t?>^wSS_>=|A J|$3C xR VWE񟏾3$KN0ogO#2EOcTck((((((Q@xT\xb¾n} Jtu-an互9* o)|x\Kҵf%ρVyL)"$[Z|W|o)𯉾1h/|'uxYln9{X_ ~yXk34:m-m5 xchbih[>b2|>_^.}\h5˝2MOGđYգB>u6ƍtSģ vJG |u㏈{q.4[\~l,폘T_r>Rv2^ x ǦFtrM)YYng0 KRrq/v&]o]m5wl*FN6'7Gy[wXi>iZ<:5.u%ןj|>BCu2Z/?uǯjxEԯ9jVR\*䰅f'ˑ2IɯH5W3mR{pp=kd7~gwmkR5I_KwrSe.4"yTjW_$va"JvղJ67%)xOek Z5,ܨ k׫EgOʹk;sN|+ZAERQEQEQEQEQEQEQEQEQEVwW?*ѬȯTXǤ_J:KWCa+$G-@W '-y75:]W~Wb}kG CZ|sZ毇3m-Jǽzgb{ßC&0?8:NiZfФp(r!ݙo5AKo=~G<"f1gn1G;ѼA7]o<~Z?> .#jngvYjwvEStbd~.~:oşj|%ZNͶ99CWR2#U5kQ4}&KԼ#3x‹o|mxSGwm[ǚ| 9Inz " %e{BF\[{{4zr7<[9VBUI9*z/Xd}# ¸g_l,`m1>{-Ϩ-Gr42謈щtOu,[-ROe*s4ӢM4(FXYD- k׃m7,a~&BFuHn7XM+O4"Gv- Q"{./h |QU%^;Q[Ʒ{x7E8ФI0Cwg_rKNNQiO]|}wZ~e\\iH2B")f?i~>er+I'7𷰍5k", y;?[ :$_jVnX -Ee $6k{yRE~]o+d@_S\ ~ Я)LO5 ' šh(1>n x7hķ$l@*߄7\ºfZEw* p=?f_.?•~%_1iqcW⨙hΠa-Ou *tNGToԯp eIG- IFY>'|^.Q T>QxﺜjG?_esWO\/ 8%rl~g MOؿL??^@Q@Q@q?/? @M6]ZXuh".^ojVHɹ`e #lbj(/~:/|H߳ZWU<1Q25c0%0_v,7?½o:>d*cE@@vS xz?Y}3Ou+Ɵfyywnٷ]D%)E5fLZџg߈o7^C^t+F}-u#\G)`%R(f+ٿkC/>"mk-Gc\.Rv/ڠK[Ho$bQ7;cú7 sekkj_]vVjvq3o2Yۗȝњvh^Ex?k_(ğ Dn?pyuWWTǂH2Y Jm(t= zoO^QMIU mkAkd EYC7a9Znޭn+71e.% eJ7ƯNK-BP ..{Wdn[F$KΞj`1^F7^-˛|6Ƌhژӕgaqq4<ωcc~0ᾛ]v,6 FYIdtOw|OƫLգ̭M[O-y8)3*NZVݝ֗4^?{O7;^ו;/ecy[Emv߲w>xLҾ' f5-j/-=M4jOr񽠺eH"m *cO=>"Zom#ק讍qmۆ7<]r G GL%:xCZmI-@Ghַn/F+KQCM?Z&H/f֨4f6ppwWƒ4/0( RrJ٫>֯}9utm;!HȓUY.on" `"$x׼c'j1>$(_t; Jdt(.d$+F׫U>{2WH-y1_x;xI7'H' |$dj[%=}uzMbMo4{[;{ki w d!p7%x:?KZ7d֩qr^{/m5ZikόhMߌ<}֚֟v}Ft8I/%_~mvz=Oo|$]{>0iܥ΃#;iSj2\st2tq!?oON-oYTutc:}$e5m{heXdwvQ S;2gJQ붶 Y7WO3试_cc𶛧iixkU[K=6 ⳵\\aɑ\:O" ΝMk zgXYkWz|7[nۤ1%5ҝ:G[C^]NL;)ӫe'VWE3 R++I|a^ G/Tן'_c%=zyO!2Z?׫UYG/&]whU53aM}ݶ|AKB3U?H_'G$zw=ӘĽkG+x5]3*>v:TIw[jZlJxqq L}C(~(xA5xl5 /.[K+Ϸ[iUx$U/cy{=gW?A'.UDҨ+J!Vo?oRr>jJa#nn6 2`@$`fi?ϗi?ϗ;+x -Wx -Wi?ϗi?ϗ;+x -W?<6:x@[z$s@i4Z k&eEʺ#t7 +QѾ 8|[)oм?lח:¿y+p 7Gߗ ?hO|om:85U1Ȱ,DUP ח„TmSrNFm4.NII~|)jV;M;H;xCXcNMj %@#HcGn|7g?+xG,ޙs΋}gjkb_2ZY7,d`njH7/ ZWŧ&aHR{n.|ɾPLF~ PWlT8cV- -[ÏpxGs:ҕ2Tal<OHsFXJ~k̹ەmmSI| m+Iu;Q-RGfP¶RpD? n~!W@յîjvt:uM*=V2%;ᾏOW>"MWmWzkv6:uƣp,R ti85^>x^!ԼGi/=/n5 uqd Er'taEct77 'NMV+/t0}MᔬspUʂTĬF zy,?D/+Vi%>/s+rxڧ=%[7v~Z@ έu]"MJ0Ssd.7тb49#͏t?jO|XiI:^-6ѬIwkk-*6VFE\#qx?>=|g'> t=Oi~nn|W;\{pCJ4|߀._<=㟉4nލ BhRőĹPQ ڧ&"䶵$'Σ&lӒi|FJU}7=W[dݺiu~9~x vxZĆYӵMUO*(e w̛AMǯ>4_x{V^0ռ%IG]jJPXi#eY2]|![>o :&6|=hnʲɩܲL%$B"y?h?ž j^(}8jz>R|c,bjY\*ӎS+ǑsY^4ӻzAG[+a&/]~8Hψ<)7EӬ=y໯[dV2B!t{a&@q.HS|!~mԭ_ZdISQ@{gm[dܛ b,$M#xŰ){x{\ÿntjouXQ ijʳCrIr(~Ƥ>$xc3cSŔ^E߆=EbWQ¡,h%_(¨ɥd3MɭaoEvvRn׊I :x){Vzsz~gö[VkB>n&\JR^ҴCS[v>& Rm&+ּ, oNI3XːkmoGgwƟ YiivWÉ4n.(R2_=";GF2KcywOyu '¿<5q]sORЛQ"+b+nJBdˈc, Gt^Ud|-mtVzcR]|A_S:4"ƙdD)Uv m蛗>osSltG_o?^[__UĶ kc{tbOkp~ YŏW^>=h $:^)7"TӸ˸mf/zٓP%7]_S։xιi<C_GWT׿ 4-!tkż 'YMޡ[+?w ^jI"/x֍J-B+jsK=^N" 1x~V^}z˾}U5wkvi߯M/׭k?i:/k];RsvL%7HƦ6{I $/F[`xKL|?SK\nZSa;i-$i7U &7L#~i}/'֚WZ|KxR6$5Ȇ&hљ"HUK7b?n=/7O_U.V[]ի6oXt7n=/oXt7n=/E`Y?P 7Gߗ ?fo@V,{~_(yoXt7n=/E`Y?PgxE}C7CVq9/=cEd B#ԌP~W4One<wMKiwwsnGl`GRK;~˞&7߈Fkgi`8@3r'!Lh¹o^Z(:5zBҀ8A OZ-t E`JwU n+ǀ,].6藶'\|59aq8lx=|ɿ1)kB+u[y-5+hZO]6!?mm?٢d`a,4+Hf|5?E T7Ok !7 "}д H[]fB$1B$u TW\/4Mo_ʪ?|[$'{צ&x aUɾ-+XUFl?ymc&x aUdx}h/yn n\G@vƏ^r[~^oCm9x7 Vt?ymy":w^ º#+[E _Koh/59x7 VCm@z?.首$ؗW~ )Y脯O ?SGA#M_4.Q]]6;Xw-*)7V-L /_A_XFCVr?Hg _ƟaO XM3J+{?iң+99*n W?hi"9]GWG_s|.$N9.?0c/;Obn0ץך~g M((( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j (/Mo ~9%c%_jzVgT}j=?QJYfa*_NxÞ5ORկq. y}ζiTQEO8$l(Gx1MKZdž,5-ΫcoG*]"Z2̇̇1I>#|Uu2G!Ե.!IlvIZ841G7wC"Kȷv dV[%Ǚ$r+V]e!W&OsV15zwu=1O֨,m# yi22-+c¨`_M Ǧ+Xj4Pֱ$96ݖIrUr ?MNЗ6Pn[]3(ӨhK]O6Znnkrɣ#uz<&|' jwY6+}$,ۖO>XfcY#vV,R>hioj*χ=Z=g|5K=zTL-d#T Hڛ|ooZtiM7Nam=s#̱[LIGʞg<#x<}c ji Z;Lt'#;2塅mꢓN׺qˮ7nJJjIiݤ1*?oK_^ iizD}RgEEvU"f2L#Gzus^|.,|\*[jN &2MkSɩ υʆY}"/?ϝ/${ :s|Uk:< U@|IԼWg P+όZE sGl $uniV1v2H_V>';֍M֮7Sӭck\!I"'ixT ^|85'ƚf.j,e"͛,2bbd*󺓻Mm{=uS.e=4vMy-VEZY&{xEዿ |QҟHũy} Ntc.:$lH?>/~/5;|0Tv ҅U_32쁞{׾(|z灆'wBK |Q,_`K߷5[c%J,k`ۗH~)'ͫ턶\_ٳE(2. ]Y$9NR[Y/;${TWHUzI^k.z7ͪIe+-gugG٬?[4X La$IpEP,|5x#4Wj-u rb1d--1H%QYVVQ ?ࢿ> M>x {m7 *mnGdAoO|l{Xsg&JGOYxඁ ;V 8I?leZ "~QxB"%ꈠ`(<{~Gލ߇--  N޵s|#u+n-]]Be q$2GB2gh RTW0_z>g?G.{?Y{CG.h >S_t}|=ú--. bmHWجǗM60 $vγsKzx&,DyɆ(o%"`!@v%'oH` K\^1F629ҟ8ľ&QXi%WN:dZ>S_t}s=gWk[/ ACG.hOsu\~+4ɾ1˱sqpu{| {Eÿ}4|ab9?(1p hOsu)O K.+W|>x;:7m+O,6G#1]C:Sz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʏ-yw6??~οqQz[GkWl.gw wEWa?ξz_ʍ:*U? g_((QnwEWa?ξ`~[H]𷊬5%DIT[-c$ϟFi $~r$Mx6s{\O9BV1 pJ.z 'EGvI6WGd>GޏV_oD=r? k`S>xᏉ4/=smd_2GW&0I$G+}n߳؟}Z<x%A CR|Di<(uw!U2Dr޹?A OZ->/~(;P,|y+3-w?\Czb勎r$:5Y:_ A][xco-u}>8 ,/mUmL'ܤ1? )W O?)-?VH QcZ.p io}?٧z_<)x\ӭMSP))uY>`m]?a=|Bw|A蚟<91?VP.?hG.ob8,N9gU*e FFb$m{F9BSpn/G-׶m+x1߉ݟui:'5Fkt.n <$ =U+mY-dL7JJ{XY̭3>6A_fuSNM .KPVZ 0V6f?B2׼'k7֗Z 鸎aY@nBD-IxIO}[/|M>%%ӥQ>˩we2\`YF"ROzVQnIRrK}/ >(5ԼOᏈ?|Z4xS֝,>YKo3k{X'_/b‘aW϶.చ 'ɗPypEFXSkx?<h <Ǧ_X+E2mKGhE&l\ G3ĭ!m,k'OΟym\> Z D__]KZäz fKn-,4Pi,0ڦ=}5 E=%Ӫ/ԡrOujW7/~?Ko 6n3Z^"n]?ͼ_W: 3okϙߍn.,rN* [ӷ~~)x <qhf&,emRltWW 6e yT䲕qw/Ԯ(-LX扜̙tts8H?pwd5B[Y5ۉabn{ qx <x{O=6äkv \kiVmF */0I9Mۮv?9wkM/jek} x?T[BKR7\[3'+P?)˟d/lmGQt~OŸ &;,˟˂);Xm6s~-c5P m2 )~7]Hl֚QZ|~ |=|)-|z>)qtS?W ?1`?bw1J1NޱEVҾ8x@|kW+YִG[FլgNI{ֱY,EJA gxx%դ1j+,#i2̪nPB/Rtpvz4do}۹|-J_7C{E,/"3Cw Yn dȮYw]\= YWDž>Z%w1x͏ ԟm+>1;i>J]/FյNQS⵴I!,U!*e]1<~#C ۴׌5ڮm}A>ź$f\:'Rjڌ}9޾I^ڷmOa^59Z2Qovޗ=#uz<&|' jwY6+}$,ۖO>XfcY#vV,R>hioj*χ=Z=g|5K=zTL-d#T H|Q$3xHռW{a'o|?EB[ح[#Ioo, Lk7Siz kZ+4텕R.H,1Gq$o2Fg%myמkחkUssjdZ/{\J?>&x:~WchZ^(T綱QaݩH`S$H!{ VS}nIZ-QEo0U#pѣv^6O-g?~%{=2N(eș.:*H|?iqb<_wM#[2Ý+="X籀u]"o][ȳXNSk'N϶[ i['%:M{g>5|Cм=]gUvYu1l.4i^+YQ.o2NP#Fi|W5OxOH֝ b2|< ? _ >'|t7N>,G'hfQg a3_KwzꢹU?>k:< U\KM?Jj>2}{AFl^]Ziַ +Y>^iϑ"+?cb\_Fx.;.;}ZX,>l fX%ij:4J*Ziww8m]KhEkZGs獬~ ifx'IOztڶf>%d&; siAԼ;[\g{(zpwO:ZAruwҳzk$پyoMbKOk˾w:uz/t?>^wSU1 + 1RG \3O?AJ3 ARG _F~S?n?&i^^S1{ogeT‚_:֋{ZJQswa-m08d&8VT%9j7KH?Z֊nZ;ojm#NWGx^ ,hcO/c_]K/>8<V}%/v\.<;hb^5ds6؞m@]qeb֭[ȱ/ڟ ,g8`Ouz/M6yQ]5̫lOCR|)౥8>jJof6m;96}U\_nڒoסNJ%^Ɯ<+O?~zg>.u Vŧ CG&XD,[{?6էǀ>8|H5 i@bC,k5i|fUĨs1TcQ^׷۳A.gM-%^ƏE|WA/5w!1Eo}%^ƏE|WA/5w!1Eo}%^ƏE|WA/5w!1EWO/cG"+A{"Bc)|?:A/{3E|WA/4+ x' x(&?ȣ>[Ϸ>WO/cG"+A{"Bc)|?:A/{3%O#GO? x(&?ȤG[Ϸ>GOO?Oƾ,&?ȣ"G[Ϸ>GOO?Oƾ,&?ȣ"G[Ϸ>GOO?Oƾ,&?ȣ"G[Ϸ>GO_?_|WL?G!1E_>o}o)'cG!+|UL?G!1E_>o}o)'cG!+|UL?G!1E_>o}o)'cG!+|UL?G!1E_>o}o)'cG!+|UL?G!1E_>o}W)'cG!^+|QL?G!1E_>o}W)'cG!^+|QL?G!1E_>o}W)'cG!^+|QL?G!1E_>o}W)'cJ[g& ~5?!1EOoW?Oƾ&&?ȣ"G_w} +x ~57!1E?!QBu|wfSܶ71Z]Ce]m, ,l̟,İQ?7c(Yl~!wpYs?c|D?_V\?oߪoߪ2];Bu(̡se+ÿ6 X?6 X?%ÿ{,O(x' ˟WQ '  ²xS9c(̗o>?"С+.]\ 0ĽSZ NeGoh%y`6 vbI@ON|uC~V?bN|uC~V?bMtD \ѿ_/:T+1G'>:T+1I;/^ݞ [ѿ~E x'>:T+1K ߎp? QS?WQaZ7 [ѿ:eשg¯oAO_jڞy^뫫 @X"`.sIx_'~;T+1\ړ[=o |OsC5l6(B$qog!:2*c!'ew>=EǨ|1ž3ޟi6.tV;Y͊E =(~3xFt:ζ6CG5E$0eʯvY}T+I}O_0~3?S 1?aK-'NWgnwc9.?5yhnf#&D>Ru1WC R!)ms D'Wߕ?pr~?bpX^0h??N65dBQx?φOQ /E jG7_esWO\/ 8%rl~g MOؿL??^@Q@Q@q?/? @M6]ZXuh".^ojVHɹ`e #lbj7GUeMi]YAfrUi#c hMoj~%c|_zL`K}M?N n6)bc Ŀ?cxnDt!iaՖ =D ;1 xy{A?}>+ ĺ]?폝)|,hߌogĞ5cN݋KLc  T| ˕s>wU D?koCM{vUڎ7imZyXyմĸX5IcR Ժ1~#|@m4jΗiHc&S͉֯y2;Ղ)q"BB0!?ۓ )?4_|9'|'7<|.O-kLu)&iwyuy'\ҥK[vZ-ۤ1&ydfX*#c)v{9U}}:^=նqGgo)־%zn&YA2/ #P`Kw3z°@̌<#ktUӵfMsὖxM;Wy#2}Y }K֏eptfWi]/Ki$=̈́vѴ$|&쟇U_uD>s.%X7[YRb@caUhԨQRﮚ>];{їgv_K[^O%Nj _g\j>j +omֵҬ.˞s|y mBN}'jr')7x;Ė+5ƳXw3,GfavJUgr:{ᇁt{yh|c[wMҢǨjIa/Yuxe@n"-x 7|I~#մjWG&5}V{x%ef@.k_[5Q7tҌZ=6Dmz?>Ii^Ӽ95ޖդ̫"FIkXy‰H ?W6"_|a)hExq(-RHcn%hq &$no*o ׈e?,|+kwk?Z}n4ŖHRᡑ6YXDἾETψ/]BAl3%M53O i+I s&ܣʓjזQNMy[aSvqtV%nZ^[Ųx[$ᴴe;/Z4VBNq=ôYq \1#Ie|' zO]CPx.8|AƍmkUO[X9#8ߙX> Gd"/5;/x3Now,k;rNUvYxO*6EiVrjSkd外!EGH-^V۩E.'7]sFF'O hrkm%uO1Eݜ>QbM~ ^ .u{,aMb-wwv[dxm]Q亱TX4nekM]~]J{|—dž.5Vo-u]Fl'UV1\YE Qp$K$*DZM=(0{ccKZ+Ţր9?_ o yw8}3NQ ח|?JtC⡟*oZ}t> `ҭ>-cӧO?Sן'~_c%=zyO!2Z?׫UuR ڿ2s OZ'C𗃾/xSїYϨK-k0r.ݴ9+JSQRMi25kkk?^*ˏ<1Eq {CԦo?Rr$<$^O-En C,мQɔr4⶷FJ$YHKec?y&_ ԿYG!,e KT;kw*g7;(~!h~1 U}uM+N4iSMqrH]FLa?O5'WluzG ,]$Hlm#Z32m?g/__T"*Y>$'{._{]?=%֞_k$t;⻽18Ki29G4&)#p͵Uߌ>|ck2hZu4`+ߵçZYKy>Z٤1w?|6Rexo//VQOK+_6I$/$&I vRoO|ݵw<_3&}2m?=׼K>Ӯ5;{414MU @9kxc'Nb)Y/<3&}W໹>Y-\E2ԬйUpv8`zRS&⫏r3ƫ~?|j?>_YS&;/MQKecU>ML5FNK)TS&ݥ??_&&}DϣW_|%@?NK)TnY~{>G"gѫ/SJDU|%@?i,jGɿF3) %?"o*SJDU۴_5^#DϣQj>.K-WOkQe!u)b(z[ y`YUUg_w_(&}DϣWԺGaz}o~s w_ O,vq/=T>ML5FNK)TS&nY~?jGɿF3) %?"o*SJDU۴_5^#DϣQj7G) %?"o*_/uo"gѨL5}e w_ O7G/aW73&};/MQ w_ Ov0ƫ~?|j?>_YS&;/MQKecU>ML5FNK)TS&ݥ??_&&}DϣW_|%@?NK)TnY~{>G"gѫ/SJDU|%@?i,jGɿF3) %?"o*SJDU۴_5^#DϣQj7G) %?"o*_/uo"gѨL5}e w_ O7G/aW73&};/MQ w_ Ov0ƫ~?|j?>_YS&;/MQKecU?5o؇ߵ7)| Ɵ q+KZ>{ag;( #|m2Fpˑ7d2i?aOƞ3z{5GD:,hpoNK)TS&*y ^[kݚO,(FJ_:_!mt~wm&:aYy cOdυ?M/|GZ$c2yI5;8f(} w_ O7NFWqK*(5soڣG_#MέA%Ox!PVkCec&ocP_%IrڜPqxehC!UNYXNK)TS&c_m.nmk[}VWpwV{OM6n0'K24;k㿃o|Q5VӬ/$6[E&(@_O|/<aukZH/ou)y7\JLbH#gZVtby^_~'v]sRJw^ͯӢKT#|/_I爼?qcpך7z% ]wgW˙V%`qWۿ<:s_X+Okڍِ[y{eeX!Y o,D>dCBRQQ^/^{_C>?om~tK,/wkzSGwiioo˲Hd_Ϲ?vC5Qcs!?o?#^QKRco?#G"dCG.}J}9]Fȇҏ}(ХO?vC5Qa)<vC5?V᭶%aeq%nyT=ЖyF@Fq_bdCGD>U)n{Yv5ho߭χa%3Cz<=5ԟ$}0F!0nPs͇cmP?o_ddC_)~6md* bª.:q{4Sp]^Mo^[pA;OZp?'pXq?Ɵr*?ӏ ^:y( /E㯿[S 1cPc $BMؿL??^^iɝ'7Gk(('> ˫YNZ[M-Ji97, mÌWmE|/gExx>_kZJ"67Z6FSFLox_& eGW^BѢӒLZ v((Jd/oGk/r}Ny~"/3ݾ6ȃ(ɔTZ3־~hwrnhO$w #HE,DUW}77mrhe'.DC%|w$\,;ax߲[<3q߿۴m݅*o.sꯒ5e1/ HPz'ž%k CXңƒ9'2&!@uEcqVi(.UwvMmx`%u;(/v1wdgF&Q KF拭s|?:NJ4eӾϛ 3Vkōn][g>eno7 ?Lh<371iz7to삞zjKjlONZ6\xI|kh\׋-FԭfE%#f~geF[=6%ֵjK6>Ķimp1CMH[gw Q}ZR^qVQ l og|6w"H5YTTq3A-I$Ixos~<>i~1\U_W>1բN'-rNPLaܴh/&uE_xHK|->"q+̅ %݌+VSXG7u.ooqjWEEthM][Ol\yrCmvW+_}V릝F=_K~2?|mOOO4[˽'^ Z. , ԭ5B_o䒙3p߉/.H?ϭ{g$x]w񞛤Aӌw{sf_؅V)D Xڢέ)a?Z?|3K;MbTi'UD[[1J|n2oeiT&խo~ \}^CLΈ[gݦQGqy>RRujMy TQI6D]lv&cm^MW4V1dC:-躶MYLMQbPIiPco?<1/>+],U#-uK\岒Ui'ye2&>?L_Z5|O_͏-|;:-{nmk)(YD:S]C^5_΍_G*i^PI4,657­5W],ࠒ]UlrEMwi|8մx-k0#֞`cq*Cg !b qq2xƟ gM\ڶY@)5+GFTSeҿM\d/I7- [C^]NL;)ӫ~1%5ҝ:_#H3U?AJN?h2GG)Vb UExď`~g?tOT=7KOGzjًCdGVgeT‚}ыzӜ6޽|u|'mv{EVx޽?#|s_e~4_k]GW"yyZ4A<Al(|u躗R׋%aݵŖgg*Z3\ eC8bw`wu_WZ|%Yxrb4UĊ3VR `Ο~_Cg5TܺYȊtplʊxg?ԍ nH~pTbB1E47~G˦I#iǟ u|p5mGMxR9`34VH˝@AY&ſK<N,ywM}m@$4r[ـ@Q7zq-'5M"HVF8ҵ [Pu鮤1 d˚'9p:*euQ-{{+wחWuT/zڽmowNVWM:η"_.5>Κ, 6soo !1 \fݧ(Z1%y?k?k_+4 x)ˤjZeB}*rT9U@Ey>xs߉3k~$|7g۝B 'էAL[deDXU{| !xGx]uܢ2##gv ueUUX:]/mͭjkЕ *o[_kwG*֣?Nk5v4WzxuvP=^6y7_rҹ_~rxGZW^e̱Oa\@a`G2,<<+b>έiT$䞺'k$}\*$K]ZK.y/cKP_ _x^.I\݉/KK@~2([}k S h>"OCmVMon {jYˀ9000_+|N{:j~o5j0CV[׻K7o1GA~9|&SM׼kOZaӕ[{Agr!*'_xk| ͱҧq9І)^IєTj|iM5$=, n~u.x]TMh?mgLԾ&x_wÍwEޣy+Eu B;YѵiVKŵsyknD|'eOڟeڮrgmIJd jzu$5 ~Q'c |i"ҵ1CPDdTYU0]m^DOcFExjē갧|Ai+7#Mn[26%FxN7_3J v$ɹJ 4.w;ihmײRk{׋j xS:ZY[^m6x쭗k2nnM.׍@ U wS_^Mj>1Fot=Ry5_QMvڔ{DFAu;&*(|Fyq㶑oVm%6TMϝH# Ouxcĺv~,<[QզY."dґ;kXaHEr(Pk9IJ+E~{˗CE'rRth/*Yx]<#FռM*v)ͬk3ڦۧK99LKcaq hׇ?>mP}iiOk_ٺJXh r%ż&d64FCf(+ҿe i}buާu'~:'\?gڣ6Ǘl6owTctBuZjos+{nGIk,~&फ़c=CO_|BG/Vvj:mj[rG8^YNhOYiZr0%w5gf~ci1a~k˽kh/G'٣F"7<1.de'dҳNOjJTՒ[qOڶ̵?hM?%KMBu.%[ݦ9uxykg4*fRT< %j>MKÂA)Ek^SIO[>Shȶve\UUET3קE齟H#d$뺾W C ~{ dմiTm=Y-"}A-g6g޻D {Dᢼ<+}3Νn v%K1p sLWG|+(W!l|B7viRjiCJnn&UJ=Ɍ2 5?cS⥏YE{Fu)mW?2H{B}aFHJMvm4dכG]b֔u*{jvvM%ו e.|-x_|Al?{Iauzp"n7G+]]Xr]C4Mk$T$b#H|wQK~9XFGS/w4b&IYѦ {k_ xsOlLeGin#HhAf%I$(ZiuoKk鯭iY$傜mzzhwn?3G9֏Mi{_9gޏ3^s Ps}>? 9gޏ3^s Ps}>? 9gޏ3^s Ps}>? 9gޏ3^s Ps}>? 9gޏ3^s Ps}>? 9gޏ3^s Ps}>? 9]szi~"j?0p:fKyZXz/"&c q7wQEqQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@fxKm97xTzӬ.?? [Ls {{?dOu?]]}Z;kI䰳"9 ݫDea()M,V'½Սv`?!x\M"g9'G?z(?jOcz(?Ɵ'+r(6y( /E㯿/5BQxyŒx3/+$Bz>9.?,c/;Obn0ץך~g M((( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j (/Mo ~9%c%_jzVgT}j=?QJYfa*_NxÞ5ORկq. y}ζiTQEO8$l(Gx1MKZdž,5-ΫcoG*]"Z2̇̇1I>#|Uu2G!Ե.!IlvIZ841G7wC"Kȷv dV[%Ǚ$r+V]e!W&OsV15zwu=1O֨,m# yi22-+c¨`_M Ǧ+Xj4Pֱ$96ݖIrUr ?MNЗ6Pn[]3(ӨhK]O6ZnnkrɣO- N=o7?PǙlݓv60|d~>&w5?lUD .na2:(?_eNjtw~揥˭x4m Jk[RR8gxTe 3i?]k^񦪟ͣi>0So\Kn s:yIwy[Ipa:sOmMZ_uNV^仾X,iͧÈk}ym5+Z1_+eZe4P[S:H~?H5$u-Q1Fm;sȶRa{yKlɝS WQԢѯsGo%ܾ}AllfB [c_#:P~+}{H"U&y.X.2_=?Śxԭl.K]cEZnn^FSqԹfiBGC)a?Z?|3K;MbTi'UD[[1J|n2oeiT&խo~ \}^CLΈ[gݦQGqy>RRu+MvZ{6ȃj>vK{]s^h |9m[D[,}{Kk[;yO Y0ʣyc5ؚf.K=RkMVEk#֒ -6t DXnv/S?x#WF_&3c_zmg^۠ixm;e9Vm6P׼m;Gx@sh:dJW/fF ͍dyMy)Y==n}tCI+t_swW>+53Vu+]k2^ɭWwvz2{+X"1cTu>,V~Xi?l<-YM}wfYdңP&eg \|-o OUi6{֙ͷr6җKi1%5ҝ:G[C^]NL;)ӪOU ؃ihq5#?t}s#|@*ѿkbG?‡c?tOT=7KOGzjًCdGVʗPW>5P7-ב^I }::.”p79OS]Go;m'_N6¹5gM)N3f;'V6]kE43VU ?WP5 z?SyQ??q` #vNz-ۙ-WòuoaַQտ獇Z^eן;h t4"LKmCRF`Dk.HBɮ{;~ #uo-}֞/yk|a#3sv2N&b47# ?|:{}7Oj?ĿM'UӼG`$Ҽq&)[u*{c=+w{v>xhR f'kikmZjNe^jo6[X#IpNѢ5rV$!dSW_7|+]7 }.ݥ_-E<#lnU,m[9_E~R}5iiO(*N^Э \-O"רY~<9C95=?պkpo!xYҠw*c9JXvoE&)%(I/f'hhR ҃Juc_O" \-}CG [Aa/I6Z?>"ԟkEh҃u=;94|E??G3G_msȵo P4}nc/f'iͿ-yx@)cV<?j SQ2"st>"ԟkE/I6Zoo?OoxwPoI?}mݵ&4< 06qx-5]dOMp#O%q9k,wߓA$ߛ%IMz</I6Z?>"ԟkEPg^|(կj:W~% źiY[ʡTْ7VVW`i/_.u:+o[Apм3ъN0E5e۾t`k}O hR f'k(??i}nc/f'hhR ҃J 0|'7H26[Bڟ \-}wg!<7 hJ/UnOjxoC-Tx,,0 3M,1Hr#]{-AƄMKVy3G_msȴ4|E??]·G_1[x_>i3ɨOb) l׷v&9 aG.Y6!sVS\x:'Kt`)!t.fUPBO+K[?\$˸B2K^3G_msȴ4|E??^ͯ/-W^%dᅢsoi#au1Flj\r>xPզ~w96~)MvHdj)37=Oo=}(=_>"ԟkE/I6Z-Uϊ-m+W?]zmQV ^ɶW29cZ6SJdᅭڶ/I6Z`~"0"ԟkE/I6Zࡾ*>.Hоh^,oZxZϋ%5tno,Vɶ[pC{%TtԴ1V[JHnbw I UU2H.:zktoG2eֺ~*-|(Wf'hhR D|'Iv?5Wɤ&m⨚H'0yr "5~c^m>/DMboNJ#׭ne<#mɗ>nyOӁ${y-U*[Ktռ-hR f'jW>Ѿ):ě;۽Jwep'M$$j͵1}JWRGf'J| \-O"ѿP4iAnc/f'hhR ҃J 0| \-O"ѿP4iA>"ԟkE/I6Z7J(?>[ñß>"y=|i+7rN8ݻ|Q3zwX$lsxѸnRûpԏL͏WS6]Gº-~/ֵ+ +K캼AIU'18+ $3ط7⡅VVVXqI8_8 -O>n^{DO[56gVOE?:nͦ|YҮ/+V5J>`ъN0Ek<i'-E%˪zc֊ѻ;_v{6wXqI8\_ïxDӧοu'5{4?TW K>bH6 _^yao ivtX=k7Q 5+OwCKL䷂Ynb1`qߨ5ym~STعXqI8UOc(m?ȱ 5({_ʹko?6} =?&Xq«m~QϵGs"$?ok7U6} A̋XqI8UOc(m?9ck7Q 5*i>m[߱{92,Mc= vG++}o6} |odmni(5ku¨?65ՁU_% ?ڗw(;OZ'eT%?~!eu|ƴ2}~Y/}UmO(ǃ?W1H?? qt|r\!^Y&_&wHaK4؛ 5tQEQEQEr_#|*t2X&Դ.yooFyV9J*4g_eG?b97ٮD^gۻ}6mWoI^%u㟈?5x!4KOT\۽Zb:T>vݱ/T8EM> ƺi{|ɖlp@XXsM)$ϖ01t<5 )u?QѮ5k+y"ӯRm൬GVy .sR~;=s:Z%!X/M417Ƞčɟڋ ?ʖߴ6ZWu^$k,#)URYUOKBSFAqcm"+?E;FHlK\#FNd5i^]^5{5{>]Qԕ5AMM٤^o!i>$x|w` &Ee_,yG"eAvRrd?%gWx S_mj0|Ɲ#(Zbһ6>l* L~^~>5WGi>[kZmy  F[!m";xCwFlV3mEGQ^i `4ɮzծkybww*X$`ѷY6*ԅvJmNe׽ӻJ6ݕ_ üDjrjQnn/T vieeG? qqy7dݻ ,`mE5#(Mr-Uo`2;;K|̌ړ _GRφ5EMτ<;wXKw-@RKC&H7SR3 stM]Vy:]4^#$6ښi4yda]S nr^VK]=Jqw?= 6,|8ƾז]ҵ`?UZ]CK[ؾ keE3to]mHRu!iٞ#4\"foeY/aW˼Q6q5>xw%B=7 op42,rFʊkU~)sE#OLپi\~͞wxOr  5-AnlQTAou|/{giodUiGr`lK7߾>@ӿZnt} t-:1-&6+d$1d*cG=DӥwOlb?kU}RI$$$roնO[C^]NL;)ӫ~1%5ҝ:|"GxR?OFӧ[0V]qFԑ:x/?*f/|MQZa9~&-?G>'rG4=gדMz~h7w5dirx+z֧kL_I_B v<5+ $ -zҼc^VXH]\n=G%7_z?\?UR*d"E#Z +<;ooAĐz&g{5{;Iwz[2Xx E|@ּY}/|B4 hΠNmIo&6sq 15xL}VA=?VA=?ҍ̼$HIYmTi=,G)x9|%'~{K}Zo?}0Mb(˪Ri;[LQgzOEk /wo⫽#7::D7Kb[ ta,BT}sVA=?VA=?+Jk8I)SԔ}|ݤӽI)7쳫x߉|D-%}7_ZWJ6^.Y&GKȐ` 8(ΫO2 tms]~hi6G8M-,yvPv<? '? '5ܞqc;+nQ=r*Jr$R?Ll)h9&.<fw藗,n-5{;˘dM̂ #)V,Zh t?5oxB*iVq_q؈&Xm(#m#JorN>+WOh+WOjRI4y_ᷞkN8u|['<#hx}?JucE_#d.l-l )4P)XTF*/B vB vu[O ~I+g4iZ-.QQOO'OO'<_>*/B vB v`di}T_j j ~(H '? '9TZ˼㆏B vn;b~ Y|~~(xFX񟅵M[xXci g3O|zÏ 2mu5ѵ*閅&!e7Ww,u=89'㴟j KjIrn*=iF_^>Omi ~O7MsPW&VM?m)fKm<fgf+O?ƁxgK5V;fImuv rYm.岠 '? 'm69J&*mI yYhH"+WOh+WOk>ar_>*/B vB v`ceD^UX]º߂u+NýlxC]XJtBOOk5ыH淹br忨OUmJ.WOqz`B v{4fݯ=kAOѫ?t¿_Q/ƿ |b#<2)ѵhwbmIP/ZXihYe~x5MSZ,&-?\Kiү|O=hφ&_2Y-+0DaH+WOh+WOi5m_)EF_zI5zӫ8NOX4ɯ_~~8~/~K]sDF4 nYD NdOFi]į'C=ޘ|!gwWIZo4qs"#MCqq~*)Ʀ ,峩-~ S,,{!`}߇\,dNDR\џ2Iw=):ԒnBgz|}~>!L|7'6kLl =W5u$%ͻ${ yW2s^-*-A-u=Q_CW▽+xAKGaDy6AEgd_ǦCsb5x!i/]"$]|9 |׺i{Ď%o(\_ޠ_p_ (>k50rm"QXſ6+rU.ŊӌO½ׅ7I ej7kfG(M#~o]4!S!O-Z?7o+Q?BZMh֏b9?HS^] W`=G yk˿7oZ=BZ?!O-yw&oG]HSG$).֏Mh+s yh? vs!O-Z?7oخz$)寔j[}gX b½sZ_Zim.wmxVӏM*k 6[4uk=cIՠP{kiũZ4m"G#&偔0Xq  o~kMkI]W\F[K]FShiw}߈ àZ4Zr\Z鐫[!e)LV%" e_xO?i#?}E}ݻcf5vtՙ2qkF=w~"zW]{MЭI@Dpiȥ0hJfM $%HdP䑐 l/~^#<[c~U#X.p-wZLfCfC>*jmZskoxאWٻ$E՚#0M5~iIʮevF#C<ҔX;VwgZ~˟?iK-_4MᯍxDԵmpm]@-'o7DtPF=sv~.hZ0:HRoyLvFߵboO~x7[v˸<:䫄*Ac$@ C~?:=7~ZP/t񤪆6Ga ̉HC"wIb%VM%ev+[{ z>(Z5QWwoiVxޡtS?uz޷R6e[ff84GX6 o^ռW*ng]Wu׌mhn_krNd9!+y,1گO><oM{EWi5w W"#48؃St~?~|w4gbh ,^++aH4ȍw)| > :21vw*WVZnG[Wi?%{W]5'U U7e#Z;IĀF +OO'"~#7O<kz.4۫ oflxC9)p0Pn-SJɷxQk%mVD%mV+.jwz_gٷN Kė*Ӥn#!,*qqs4VЫKLqƋz=xU֟]^CgY& qvQ{Qq4) >l{Pxkt:zM-ޫM槩i"駳Oj%F&bVarڒWr[l=omgTWi?%Z.g!q<8x%-TP&.UMI o)˭_–)mP\x{3v2Oy%jmy hWiE7ײ뺺m&ڲJ.]s}SX- {Zږk[$'8u uv@fyclD$BޡERѸER({ccKZ+Ţր9?_ o yw8}3NQ ח|?JtI?J`ҭ> 'N3ƿ$xGN/o Z}tOgH<_^ Pq?q?n꿳>&i^^Q0soݟqR 7uc K_0'l+/S֥5Gާ#?]c֧5/_=Q@Q@Q@AǺX5 K=OEPEPEPEPEPEPPj MOPj MOEPEPEPEPi]O=AySEPEPEPPG!Iz? M\o@EQEQEQEQEQEQE>ڗWf:!-歺 VF>]3r',y'oxsKJl+Sy75:]Vr &9/c=+V?G1CgFbgǎ_6xj?ZҾ8x@|kW+YִG[FլgNI{ֱY,EJA gxx.$]PH-݃47p |IUqHUɓLM_^+]OE xSᵪ {^jywiJ11_㧀>6|6</W~#n85j"iZxuTXP%n~x_]<9_Kk',k䶿7H9hCd!MvNj-uo3ө'&7yNֽW:[|;ͤki7VM{Z-Z},,&fO:X' cY"vg,R|_~8x◍s%upZtP麍kn3qqp,I ʡ"w)π7Ӻ_ xWҵ+ۻ k:L-͛Y03nde 3F601e KO|JnM"eƗ]jkjS(LbY.F-˦hsn)[Ntڿ[4ݾ7:t++).g+}}YO ]V_ ,U5ƳPʱF6Xd TxzA`5 f-5 <"cN۰!dنt)}oR𽥷uGoj[:G-|Ptdkd42F! }VR&kk)aZ]gkMq4Fdؑ LchvVi/=$պ_Kh[GQJOM{0^qCO}!t=u%^_ڭ|Ck]yIg8`Dps I:뻘5}*VCRVmek-434i$[CSj? Zokj|~WN"Դ[+ik/1 ™2[`.Q1ն'-Q{MY9Om}?EvWύ{|F e[~o HcFMKLT@ BYڸr9oh~Ä|,s.4;aXԞJYle&k;Ř▅^SjFw-ݬ j]TH#2ɹw#.IRAYѵ/], Y꼚w]>K?!WHriZL.Dի 5mXI, ƻ#c1}iErI߮QEHQ@qksGjaMc}FSb 1= vU#EIfZMxZX6Gg=ǏQ?s]-oV]*VHogigbĴ1z_t}H?!;?*@J48ؑ:xU ؁i3ƞ <_^ Pq?q_Q=[`-??e|LQ^{r*_ANe Ϋ㦒a('A41¡_m~9?5]G0E$|8⸱=j[k>TQMDh@09 Jbֻn_|/;Wt'}=:jʵk* 6 R)2F8@: JekzտxF}=ڿ?km |/(?km |/(?km |/(MH L+.sZ0h^uo3сOj_b_bc|/( J_b_bc|/+cŸ}I>M|Y%ϓ;wl;s>Vo~Vo~qxAs4q|= ok>Qk>W ǏM?G'>7P\ vVo~Vo~qxAs4q|= ok>Qk>W ǏM?G'>7P\ vVo~Ai +,lAz'/yndvn۾n:dz%kYbG821>_Vo~Vo~x56_rQ wMsܔVo~Vo~x56_rQ wMsܔVo~Vo~x56_rQ wMsܔVo~Vo~x56_rQ wMsܔZml4s5Ok>WZDh^<#_]o\%{?U[߱GU[߱^1 wMsܔ]o\%{?U[߱GU[߱^1 wMsܔ]o\%{?U[߱GU[߱^1 wMsܔ]o\%{?U[߱PGFU6`¼|/)Zy~U\qjʵk(ʵk+?.km gʵk(ʵk+?.km gʵk(ʵk+?.km gʵk(ʵk+?.km gʵk(ʵk+?.km gʵk(ʵk+?.km gʵk(ʵk+?.km |~F¨>l+_y75:]Wo>.Y?mi.ϤS5o+ǵ<I?uZ;Z((((((((((((((+oۋNgs*R*?n-;lSo ??/:oNֱEq7O'pX~<ʏ#C_C~4<5d>QxyŒ8//+$Bz>9.?,c/;Obn0ץך~g M((+||Al:izƓAr}RhDFM(a`Q@%GҼY\x+z^KiSj߄-l""OUܨߊ?σ~#+/hjsqkBl;tP gh2[X(ɔTZ3־~hwrnhO$w #HE,DUW}77mrhe'.DC%|w$\,;axn۷ܿ0[;|dwt]RQ? tC0j X3͢Ku3d,0D$_k`x_~!h 7:* cXIP" 9_|AM)V5*;i*cH"s"mp,5xady}*mGgK}oꒌV\% 59%wf?@~1w[ӯwI]>P׬G⥍̾Wባ֠uo {iHoe 6ƪAcC}E"׺[Z/ֶZ][T< q-cfIdf~?g<^ӵ? SQҡѬ];`&mFl-1 M|OQ |Pe.v|wOY>^R,N$ddg>͵kwi>&j|=?k5+uZq?׉tωZ~xcT{ jfUUeo!f ,$.2swzw oKǚ6cwzꚇDVzObE\]{:ſ~<_G'oxwLuFK R'kE EX4N'P7dS?k2j>5/ ]* ]yh -Oˉm9݈+%=溾OI]z]=֍4ԕVOmIIz5+5dtzW|7PDX%MJniI[ZF5_g߈-}x{o"ῇ3|d_`} |'o;wg v_hIG*i^2<웫 u1,2+&ĂS߲xVTm+G8i+[y|LnYQs/_ƱixOڒuM\I,]oFˌai]k8ENNoU姙 ~?>1懪\khiTa|MW!>wUt;^^iPZjKnLHs}aSo?c=GKT^(<+mMCih/p hbD̪K+2{/?^iZ_o1Oc "5.HXYJEoߝSk]~oÛk8/~;jTR!i,lQgxy-̀|)|#Noj~/IaԵM#I҂ YE6,-ɹ&AR/r0@Qu6[;o,`>~s#̼e hB+jxV{tJ=gNӮLl 2D)Ь!V卷 {ka_[3'($1}}5fװiWsXABJDag2\>Zͯ4ySIYx$(-/dm#ݐT1u؆O^jҴMc@Dޅ.n̶n%7rC/܇J([ gc9'Nkk v?w3'ziXך\K%YxV[=BbHxsK5}/S+7Oӵ-ek9XX xK6n>]xG6dS"rTV ߳5_|?jڿ4ֺ\ռ٢i H :s芍\|#1 ]Rm,\}mѻuܻq9X*ݛwyI]&|4?M)CUJncgxcH,>?e{(Ƒ)Vi+0Ҫ7Q |cOϤ.|^taQZɁ>޼7_Cv?g/i_E>)|Gmm[j`EEf Mja"+#"#I4' ;G[o,ؗ|1`ʜ68)kJ[9(rvM|̜k->tjY|w Sź>'^_j~:}ccxIM4+/Z(!~Y6kӟػI3_xVqVRޥll/r\D{Y[EnJS7CRx7Nox: K5 43A`$8!%kQ! (տhoKgyyxqϦ][jCZhYͧ[[ȟhh G2c4N*Q)A7$6ʚZ^/4mWkGm~mjo-6ĺᱶgQ6ɧ\iŦg u(" "BD~2P_kߵo|៉b1pjɒO,LPb*wŗWZցj&^5ƏhoУS{7O&6;FcZܯbˑG=sƃ/ ԵF{G!O]`$m ([~$gTRS'Vo;$ukE;3pVZ5udk_aM;H $<ڍ@ߛ7oּg>-JY*I b $pڲڽ~4뺫Z_&xZTɋXS0K!+翊<;⏈2Rrj1+meY?0&\?5}MRoa-5j<|f5ɛG_qìx+_myt4YȢ+|GJ2>c`<r&Ҧggu*E ܴ[#wBVerޗ >,5OmO{ci7Zd[7l%oQ|5qYXQ^k{Y ̒[@U7d5i2yX)^_i%ço/?--s*;}!T]OOo mvV±oNtO՞ nX,t? Sy\$Pj"1;PN$}/|)b֯!ñ_kiRHk:KMF͔bw xeA|sxr[#C[OxS+NَfvkvY>܃媉$0YpIBk:RI s$ 'Niťv3z+_>xAk[Xχ5JJ-<=(bS7ucoH[%<:zͱR %H;\o" &T4DmdFn4zm?6[^hD }RYt[M>=BeJdD= }a/>#XkVyiatX}=챺e#U X(+ռ[j֯cKm[4WRD7wyȝUp0 XWo257_< O]Ei⹷.gBTHw)ĥ_].W~N{/ᛝKÐܪ&mݒ?ygg|#wݾm:"X0ou$#fXjҾ~zW:fmcMih؈*6ou1D/dXѿPfxZ>gkzS.hAN0Is<̧}|@6U,N@/+=,m,/ѷk+*6ST`w|(:>t}`ETQEQE>xS(g'sXӥK^E்4-Wz{s\7~spG^.m_w_Rw_RrExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@ExW4]aG4]a@_~۟|Zw;K,Ho ;~"m }b>cNTťrHaT0bSZ'G-]?~o*y5ՍY6ẹw}Wm%LRkMɨF3k_Gvn_ <i⇃txG yB 'o|*|wQ5?|^o4:uo j(;@S .je~͚>yar#ѾivsW(\wr-վnaxb1$`&;:D.zs~U+[JT/j?a> x+KM}eR\ݽ}]fUk$FG.~֟6`|H 8<=7Icg޶5͛E[e1cj#:䟕`y'W99$٧u1!+^Un/[F|D^ZOn|?΋z.VS4SATXZT>XǶV>!32xl_ "FIs*Z4ڼ|PAr}3~T}䟕)>eʒVk+[m5%׾9?؇uyV_iuj\;EQĩ /,3=31Q?&ZOl$??*s_r&1Ko&ZOl-'6W ~T},cB ^eik.d#b'h`IIi[# &h~ դnY^M{@N kWP l}{ Ѐ[9/:E0m֚f^؅m$};m,?i_0Š&m+XSKtu+!rۉU.o.%{1^s'>;W蚋JJ ̩,2*qE׉t -Zop=lY#H @!$ _T_TtQӭ<Z5>aaAYN-|KlH5_~1 Wߌ@*k?_p{6y$ _TҍSyQ^E'y?1S+ʊ(W͞cE _TWQG?lO@*(n :>go7|cQGCw? WQ=? _TV|2>%"ƾ36y=3|4=`㺐GQI/P{3g\{]M1W66Jd z i/{]xM{ Iqs$`Gͤ;; qJ\گG;i1TK N9jQo[?8j7_Mz)Wg8j7_Mz)h~?᫼eDalSRWx_5vQE7E?z>ӦYiojSG-܅k m ēEzejPڏ ?_TQEze}c=ڏ ?_TQEze}c=ڏ ?_TRwQEz]}c= K)mUfp| m$IgwýGs|AŹ6s?i#F|?nX9(P{3|Z:ݶc⎃0X ᵶ{G %Min7dQ^EXcyCO Wn7dQ^EXcyCO Wn7dQ^EXcy_TQ}C_ W4Q>gn_Eۗ8|eQ^EXcq^nO =-"j,77?Ry'˴DyT01[t[vd/`_t[MΕ#oF(xAs@54x[j_Z` MWտ\oo~յEZ` MWտ\oo~յEZ` tA:Wտ LWտRw2?q #Q LWտRw2?q #WW׃/dwVWP{o yR5# X|׭YԮQnLDTLDUV|~gLDTLDUQi_^_*i_^_*"9o 37KQ 37KWQG0{?3fc y?fc y(gy4L~///G4L~///^E7%%(=31U31UzEs<fo&?fo&?H`~gLDTLDUQi_^_*i_^_*"9o 37KQ 37KWQG0{?3fc y?fc y(gy4L~///^ ŗ^<,i|5[_ZF/;; %L@5xc?_D=O!l?/:oNֱEq7O'pX1?Ɵ*r(ZjxcbNkoྚ|qL5:nn2B9F~N ֿ)D5-+19Ɨ"?q|=\dkE\/ 8%)D5-+rR,.exD×7;P(_|ŷ|[ogm?~4tٳae6 yѢUYN 2MtnE ˗DVY p#bXO߿]eɔ~ҟJ!u&QJo?kG}F BC-dN^F~;o R?\'7)DWYe߿]eɔwIo R?\7)D?WYeߴ]eɔ}ZyIo R?\7)D?WYeWYeV??y-j_h[?Կ$_º)??]eɔ}V??yvex,] 3% L 8Xn.t IBW=_Kx@eɔ~~ҭ_O_Gի+wxZ?/c5}~ҿJ#u&Q J*_Gի+w_xZ?/c5}ң¯2W+2WVX-).{x 9kM$WQL؝^}Gǟ]eɔߴ]eɔ؟oZ>k?~c2I,_Kꕿk?cb~#h}G??Ko??࿴/Lꕿ~>}G_~x? /L~K}&QJk?cd}~#h^c|m ; /Lѣ_eɔ}RNi⻍u#]^>kLo~C!-p1.k,VN;ZF0w_R'[o>[Xm`~+o[&,&ÀxtUsu&Rz~J<%u&QJk?cƋau> fZ[|YRӯku>) i:FYL.]J2<%S^o^/!g %S*mX͕FhIFsa(P3n!SΔ'_x@Q(oo^~x[TWn>"νX[\PVO2=^H-,Es0e"( \\`-t%cTNhѺ^"C*CHy~|=Zq8Zi?;RB7w4Z.|?4_ 'k/ďxǺχ%b]ko<3ë,Z wm {$RK~fխgM5vѸ +7w<٭ͧgws+'$Osǿ>)%g4/p:5$bI= `j<_c~}n[`Ew4:My$`aTE@ !>#|^Cڤb)K݅Yx GRFA$a .nGgeiosԊ"F5\U* ֳ[EyJNݭuUjym~;IzoGͮͥWO?Z?i=>@֣w/PrO'?3ÿrO'?3ÿ_?Ey4N> gkG4N> gkGj+ܿG=>i?|@֏i?|@֏V?ܿG=>i?|@֏i?|@֏V۹z}Ӓ8Ӓ8U_۹z}Dx{auoU?r+1ߏwÿ}-h_a^U RO<}iDZZw/Uձ|}=x{}V~ը)7u{ -h_a^Pk_=օ"nz_?EyZ >xkOU?r+᧟ -h㞟~ gkGj+ܿG=Bi?|@֏i?|@֏V۹z}Ӓ84 :9U?r+gkG5SgkG++]?Eyo5SgkG5SgkG++G=Jj3DZ Dx<=Z>[X*+ᨏgkLoڥS|<֏Vzu{o'5#okGj+ܿG=bokH?|=Zmn:ǃ|=Z>WXn?y4W\Ё -i?ᮭA{}V~$Zүsl>;$kGj+ܿG=jj>x{Zԃss-h_aQ^a 9'Z 9'ZZw/OrO'?3ÿrO'?3ÿ_?Eyy\us<=Z?᧟ -h_aQ^_ <N~ gkHߵ N~?_?EyCDpz~{kq?7_?Ey/5Ź}-iGmǟZZw/Y'<֏kHO<֏V۹zp?{YBz|>{}V~((GǿZWFz|={}V~ը)3?'>֏V۹z#{ -i7_?EyW5Z={UokGj+G=Vj{ -hO'>֏Vz_iDZ Xi7_?EyO5tO|}=x{}V~ը)dg}-jke{?xp=Z{Q^/a1??[Tɴ##;ß:C@%8c2$@wTUzڋP: HZh>($2  q[7w࿉P#dw 9 9*W G$]jK5j֮$2isƑ%HPKrG^ V5&oVNm\{?j;O:8fT~G,Z|>uCW\+IGF Vʡ/QGIG_ޚFС߀ytּ:nI;4 Pҙ$1i[kD>TQZCV 2ia`+Vu*RMݷ?B8?B8*_DC!zUGDC!zUE}v0Wr"!w_"!w_>_oAg^/UQg^/UQE]]>PD>T/^Á*f]>P^TUI xcfUQE]?|1sfURBTQGk3{.(U|0>kp!UHqS{_>_wC"  Eʪ?"  Eʪ(ϔ'T_B8(cW"$w_?qI(w_>_.˿ 0TkB8(a /D3_Á*X(a ?pnUS UE}v0W?p?=~ ?>_wC ? USC^ #?_\?2/]?_qu/UE\DCcY=Vm?X+Χ ,X(?{xgHmsTMOvFHlXkol#"Ȧ3ۊ+$rN3)$uؖ3Vs;S >;Hg%TUIf q֥?qV_u'ϔ <E__ʺ9 A*袟3ϔZX#c]?"^?j_(uϔDU?VQ/hA_/eQ_˿0AO/eDT?VQE[?|t_ ڧE }+(`Y_>PL:/mS YGDâ?QG֪02"aj_G?&6>W/H?&6"aj_G(b0Aϔ!C4T?VSY}W YE[wCS9sS0*袏f]>P'A*GI(\*袏f/{.(C"''W?UHzc WE}n0W"A3Q: c WE}n0W8c W@|>Ek?_ʺ(uϔKNG_9cD^?C*袏f]>P.c6rGmW YE}n1wBL:/mS YGDâ?QI0,.(?&61 +(.(}XgWI)Ao/]SodOC}*? (oaeDտt[C}+(?ܷ|? 򲣗Ne?aOʺ(uϔBWL?q߇_:(oc\=ϔ5o7Эd]4~=~k?_ʺ(uϔ7".h*Ws /[/UE[]>PßB/]*^^?tQG3.(k!6 +Y z?U0}TS_[?|DT?VQ0AO/eSoaDâ?L:/mS YE}n0W?sz?DU?VQE[?|O گ'?^~QG3.(q!~jx?Uf<:'^?tQG3.(Att*3/Z/UE[_]>Pk?_ʺks /Y/UE[?|LJk?_ʺu*袏f]>P|t*Gu/]Q^"C?_ʺ?$=N>[ܷ|G'X?UH_ WE}n1A}*!:(obWr"F_Gʺ?$mN>[oA#h?Bu/]6D'W?UE[?ܷ|D'X?U!Bu/]Qw-(Q"h#c WXSAI/\wCqtQBVf5wF}1xUU4V/UQEZf7uqoOZUPp펱dibV:g 4Ecȣ4dxQE7p2eq?WP񿌯_.'c@#H4S(8y!Pd%V )ϭTRtHNUnit-2.6.0.12051/doc/img/gui-screenshot.jpg0000664000175000017500000031635311713252032020150 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?kD1ᯇ~)Txu>\u+EӮ̴;97[lK$#ȲJ謨r?<.?MtEL һ~޿<cR;\e[jA"r\>˨1caZ?78.cf{r^]ݫ+Ĝe':ٵZgJ)}UKWW#}|:~k-VH7OGo^/fOK~=(`I;k?Qߑr,6 ]E~cQψl'KH]6qd"Iԕ\ S3X9;[ut[\?L)F"RSer5IZI{];\Se?؅==?bςd.OZG#))5T}C·zom|/u}>-\Ciqu:W/!HdCkֵi [3emXӡ+\HXfVݴwmv7V%~ѵ%tԝwVk?bςh Ga> ’- ~(xifվGg&Yzy`}Q+$.$]!}CWY~C?~ϏlgJ֤/-FrQ$ylb1NI8fDNpBU$wWwm/.㏂_ HzG䏂:G#הx /O/ۍR^ZIe}jjuƲωbaVsܒ*vPN|<9MwW񭷂t?^y6?eԤkhR+/W>ᩪI%u\=b)IIEϬݵ{/M]b_a?~ >ѿڏ%>{Iy")+덠Ȯ:?Z"{ :.XC=غDžB]@ OB_b_{y$ߡ\>*uEK{7%mn&Sw-Qo'"KSJ}#ĖZq`_XZyFTo5w܁?GSe/>zNJt;MJ>S#6hGBU~ҩyoOgtv8N[=o+ۀ_Gj>"2?h]y/[5V|a>|}5W~O@>i/UO5E5G?;OsI7OT}-ZըrOj\ аԿ}o7R1Ao ? hZ 3&`;_ ҵ&F+dh/_r;O3/o#ѿf_G~ 5uByڟը*k'g#  4oF7߂@h]vFKԿ}?3eMDw7#Q  4oFyyԿ}_? _q2|'<3bZgV?d'7#WsS%˃ K܃[??|O_F70q k5;M %e)Z/ ? _r7#4/4k}5_r:ǟ/9yGkO_F_ |}5t;ϵ9%=)V/ _?Kw$J>uEd>0HLа}ogԫ!~ϟ !1EjY$qLf >G܃c?K?gy?`?ѿE7(|g7#Vs?Jkt8K}ȥ)?f;c >3FjcpC G܆|/9!3';g 1o>o><5_r)f? _rK3'߃ ̿ Fjꄄx K܊OIf_|? hO_ُ!7g r1OgVE,??910$?F 4F5\܁5ubf&Ϡ4K܊Y;Or."<š/>@h]BG\n3RU#X/ '|.?@O[?> [RtG*s|gP8z.AO/Yo릊"Gy:!b'g(?dX)o ,G:?#WbGCR-ECUqO^qGG7D[:?#?߲;dº@Ҍ1%:]U яBט|LFῌl ح5\,;OwxSǍK0ih -L`S#i6;zѳ}nukSUUDѻ3!|7~ |ЯX|G,N2 A"&̟/ \#]t[\\<(Q#ڧ<KuxZ7?oj񏊼E/=R7K%@K Y7(x }wDثoL>~x[xkXӵ7S.\nY7`Ϳ_gC/񯗾MGޫ:~,svp!Qz⿌COŤxZ{:Kigv\(̣;22':t\Mtn筎 4'K^;_z+-I=ÿ YǤNtWVmLܮ>-+xƓ[ t-VAo{6i HaT "?jLZN?Y _Gơ[-uq&oI rΫ9'g'ד' TvNv沽{|vMq$KG_>~ 77?ZvYȉ/e}KVLc%KT7oχoV=#?|ׇm]Ԩ`+7}wN>.:+Ru%hXŭ[mvܛz7&m(|Pz4Ѽuz ֮,FWnm;Y緈\\#R+/{u|I-1_^2=#jo޼9zΓrVeKeT%}5g:)?>Ŀރ-Q5M6CJcqdPI U2]q4Q8s]o|_$'m6Su+$ d8al*9&F~oq_^ZX#G#9zU*I5-߿RsuMrekjݕWw۲x gx[?uiÒ #Iw+\ʎfFe#SN_Y|2$?#IF眖Kw3HCCiq<&~O[BXI'9zɻ}|ۗԙC0{[dVVY%[c_ƵѾ(Oj:<4:l(<1 î,xWuȟǯ> %2A$Vc8GϻvGMj6HׇoS$s6UШwovz9^|;?:h6'񕧅&k癮W˵Kyl> We^c/~4oj:GZټi|c[hbT A9O}' g-Gaz-߆~"N "ׇmNéFJIY敓練DMYf>}mJ/&w<[7MxS}GR-jݮ6kŰYmxk{s cY%.r,,#cn`<7{%?I# AßYYg<=j͟Y?"_tѯFQ-SMVm7yPѮ;)y$$v:Gd}j|x/|Hۃڔ8_3~h8]U^?Wohn-y<5C[,N2:D)巖4ه@ФW?B?c]-k_/ ֍ַOo-?%#C?\|K3qz[Dx{Ÿ߈?[Qtk>%o޺so!o}Dx{Կ0ΉUso9)Xk7%#.>pG*C?[U,?\|?1lc{?gOI oڠjD7g{zl´/3w. <?jctm>%ŬdG4-9B_~?#h῝ m>%ƉHxsv?Ο@( V~?8oBU3o/=e=:R><|Ag=A-h῝ SͿĿ83֝] [Sq G ?<|K3==[Q [QtK<|K3==D-D-:O7?wz7z 2?j? 2?j?p΃SĿ9E!$5?@e?@-:<|K3AҤ+?s -+/G k3o/ k.឵_1c-o[U @Lgo/7fh=1%#Ǐ|Bڏ7ͿĿ9ޜzS>] <=jx{Ԟct?W6?=VN[}Dx{›_[Tkso/֜?%#AڟK_/!.:fz? ~ GmK BڗK_/e[ְAw/-G?_E.Ŀ3ɩ||&[ <=jpSg/-V< |UZjz5K[O0OGxDFGd#͐:qǣiW? -ǀ`*>cS݅3j2 u?8t|AC'wǃiWO -|=j֡G D|{ԽKT3/|C~0&MߴR?a;KMW\_eG[|gtpx/ǐO[V@/R?*SՓHޯV}>N41I$KEk`c῿4ĺ8_@_3H#_mHWi -M>u.7//G8 _oj~zޤ&/ׂAU/:gak|pI>#;j?K[U#c/"|eVI?"i ̖:m"kqw,Oq^iwդ3dХ,1!#L"eQV=+-tۑW+<?~Yxğ]_^o xZ_CoKMfyKy"9ueF?:>MKR#%д wQ.,J{Qp։q>ԉ!3MD*z)߂ ~^x GoW+GMk>\O.I o]Tx) <.O!6<9m Y5.Nȓ J0R~7^^O]jZJPi-6.n϶4k}c#]^ēWhC+Au7ōDxoQ:DhF$"mޡԲ@e$gֹx(xSFc":e64?Yq Ɉc{m\ 2ϠxkQү˫+i'NxR ,!#L"s .h;jJ2Cj%Ujo G1ԴkF }Xn#ȼi@;Hb=+Z|=úOr]XkQd{$3]Eq$[^;ie8 H|`/>9x^i,u 2YӼ kqow+#֦^a0w\;%iWΟ} 7ømz{[H uAu٣L$c)Õ>}yRndۓSIٻtN0n젓oϙۢqom%7f|;kyde2pA߽/&ToMޓ _O|&<(e}֠˦چ='ȖMs'}\_GBWuIEf4{kvIN;]]X5-f+ؙIcYUXd35? =kƺo owVt i5 xv%%{6N'HuIД@wJ/FuzV:=\f\۷J{6*|?,h+~x!Դͩɦf=?R ZK`cT$*ƄGw[fe4+{I[HK*7Xh:lcs}R ].kVx62#ovLL Q7{xSkƙ>futpuplBE5r<*%yRw4~cxzWusa yv7LYb,-C,癏"ti/2[wjzo5xXѾ$?"5^KƝ4[݈㶑[I",rFK_h泺m/ZҦⒻ~ӣV+^}{GxK{Qu)|/ZYA4P.㑕 Of BuY<}FEfX(MCvx|W"xKK>+;{)Ak,!/̗ʶP4VA,W;|dm<z -es?kiy=[}v)c  匩R Jd֊]\dql=G yHtۭkV^o@[5_y?e  dZ9cp<1+_z5-Kzti5Jqd#c4HѤ*<)w+z΍m/RƱxDz 淸cىey/@DF^O'׋~kuzkyyuϧrlRyg $EVu#_vG{T)(--2k>ihʱj~4tV@,l/>VKxc]-e??Ƽ:ٛA-TW{/=΋hJMgV`${?dC]/KM;1S_1χ>G=;|DK}wڝpgXIA6~R$vۃkR|>m׍xdn<=~t{+ە_"Y-lุ4 nzφ _f{gr~^6)|\UBO;F[b᧌Ogkv^W[hRK G[Z\%hi™pг0Vrk=RmY{Zԕ ^iYiR:ʼn|grk{q3WW#5Ҵ ZZ3:O}[X漸#KXR+8GoZS| k/hw HӼ7sa;hQoqx,,ֳ`̎D(PV^ZV|M7Y%~_7weV}5ml} _O|&mˏg| ǧ:5ưvYZ]j3; f& *=H5߷_m+Uܞ#ѯLkR@ B/-Մnr ˬouN~Ϗ <7 U]w^(4vPD/a伒C9Hbd,d^|A[7*|4T'xs[^Դk[gu . pkYJ|v| |.=;O魫M_XjȒGDbfh]+k)5'CGφ|-t/EE%vh|\?&@Xm+>aH5,-8ֺn[[fߢΤQz- {?k)5= #^byLG _O|OhmS#hLG'H4dCGvyw6k)4S#k$z?G<?k)5= #z]]ͿZh..-e??ƏZbdCGH4}^`so2G-e??Ʊ?G$z>Ks˹ _O|2X#= W9LG _O|OhmS#hLG'H4dCGvyw6k)4S#k$z?G<?k)5= #z]]ͿZh..-e??ƏZbdCGH4}^`so2G-e??Ʊ?G$z>Ks˹ _O|2X#= W9LG _O|OhmS#hLG'H4dCGvyw6k)4S#k$z?G<?k)5= #z]]ͿZh..-e??ƏZbdCGH4}^`so2G-e??Ʊ?G$z>Ks˹ _O|2X#= W9LG _O|OhmS#hLG'H4dCGvyw6k)4S#k$z?G<?k)5= #z]]ͿZh..-e??ƏZbdCGH4}^`s>KR90Fx?5I5+uɈZG _~y$' WÎ?EY/}'<<6 dՙRx rFq:sI+J V_h|j.υ4<=V:`45"Y® Nk }NHBWCx_/ʸߌ03ASgKi.4++ T 888k>4|KFK燷xSP.Kw y;4\20}D _y3W,$1i쿭tr? ?Y-? ?Y-{ty?J#KRKTMńaz|([\ % > L> -Et=[z3ŧoMdYݪ1PA.r_m,m,jY'g/Z$){L3\\́JK,Ir&lc|Mm}𥿎|]5Ω^jw= i]~F9gP0!xq~_MIIAlzwmD,*RPu#MJPI֖_~6~ 9 9ߴčk-gh6^]ʑ<8HUf!T@+YO?^?|?‰xtO*sewsnΑ$', Ԫۻe)$m.g?~Z?g?~Z۲?A.㋭sEnmti4X&ᶕ!;6椮P-/ ؓ .Òj؛GiM=+YaWtPʎ@N*2&ٴ%ֿLg?~Z?g?~ZC_% ~i"֞ڶ *cYZ"~ҮNJu^Iiu%_3t™` d9M;;7/Q{ 9 9}o߉I}_+ŚCUXYx|# $`G/Z> we:ݣ^,K+[xSi++xD#!]5&I[MPJڿUkq? ?Y-? ?Y-I)/ > Zx]#_5 G+=lR&.̠(%U~! A}V+-In}jLVWP0WS.I;?")8-v<gs %gs %kkxomወ;{ sO}u@mOoϳ8m,m,sJ>"xF+Ήӯ|Sn"܃ng3AI^%Dy%O(h߶Ï|@soܷ>-t]Z_үnn0\E9Jlb-ٿ EׇkV:hŦOˇUI/i*[͑n*RR+^{mw EFV[?g?~Z?g?~Z{k HhxF 5 8 r)^cjwwwE_E #Laa 1h %%F*6vh?<0c|E}a+䳲4ItbcẌ%\~ VMA ^#ׄ)5 $q'I4UHѝ95P1o_O޽3O4o9pF.|#BfE#QЙ}QG<*8\G[F>3V"ywTp F|#BfE#WuEs5o"/G[F99Q?&jD_5 ]s˸rτLտj35o"/(pG Й}g?&jD_5wTQ.ʎ>3V"τLտj]Õ.|#BfE#QЙ}QG<*8\G[F>3V"ywTp F|#BfE#WuEs5o"/G[F99Q?&jD_5 ]s˸rτLտj35o"/(pG Й}g?&jD_5wTQ.ʎ>3V"τLտj]Õ.|#BfE#QЙ}QG<*8\G[F>3V"ywTp F|#BfE#WuEs5o"/G[F99Q?&jD_5 ]s˸rτLտj35o"/(pG Й}g?&jD_5wTQ.ʎ>3V"τLտj]Õ.|#BfE#QЙ}QG<*8\G[F>3V"ywTp F|#BfE#WuEs5o"/G[F99Q?&jD_5 ]s˸rτLտj35o"/(pG Й}x'H绻kkkK42#e`(O 7/C.ʏ"td8i4V0%@PW_g[䋞OH?ԫN@JʿRH?#;G3W?1I$qu b4NNԥI$v[)+#"HbCWɾ XRy{OE/>cI;ucjka$rnycRRUAH̵??oZ{Kޏk|Eau>R=7Q?G ޣ&^:#X׆)QBG|Z%⼷ i%߇>7|Ǫ(uyhw$_^2#4\h(kO7{{ON=kYzr3OUgO[SG 'PKik'~YG.tkb yQ]6x[mwR]Rm JT^YhVU3Aɥ"q sTVF3K㗇-~;Hn|%gkx$Co"[DDc!L(6gh*//xCe_z_kkaؘj"o-ݾR`br%)B뒵V߻?sL>] a*ptQ#{;-jvjYm哪IsXpYIPXd6W%ύ>&xOėG[[> }#OHVUi9/'{#܊:B `rnq>UHVԮ49?azVoBuwW%\AI5ʖF 6hQF<ڡϊ_L_|[k׾}ac#LKM\iD@4$p߼{?V_O<+e-|GK $I\Z{|,92$.Mjᦫk?^<xƻkZ֐ S*TQ7T ure]O=RKii6]vWnbi@3pFp; kN/I4xRR񍧆mk502YUs|al [hŧt]BA$S]XpTV(QpvJ>i$o$ԯ%rmG:V+ŭłIޡkkw03 mlYWMskr_ca0 |\s˦1Vw?{K=Z,308-Dd"ȋ.z-3:񗌼Z% 6$B6 y%⡆kye_8*!Eo*uVԓO6’3qNZi餬Zϐ4؂,𦫤ì #H6k[IlnvMDa`hx{z-_k:׃/M׆*(#jʫ,-+J TCw^[nmY~ }*lvߵG> <L<} E5 z*Z)1娬? =O\&k+ɫ[GklKaOrG, 2D&F颊~zGݽn)ߛ_{޵[|h} K[g *%NyRw.+>%)"%j=ݐ׬m/tRMHZIYfIfL:ԫ{?fy6{o5B[JQ_rK iOX~nޯjNg'Fda ַq odX$$ Mo_1w Ozd+DEӴ/V<;w-/5{F,7!?hQz]/I^V*NզV^i~LhjW6d6)Z uAI5W l}-7doU@wWrf׺M"q,3;i6O}i^g*G>U|>V Yj%Y̪kKءtuI*)b#K>[oUz) 󏌟5O vI=mmtZjXG<,N61*,$/bXI* ަ#a-kM3׹_?hdoG#KI$3*N64?l}-7do\Jם!oHFU 2dZ٠W,}?ϥUW3"#^խ닸_0>ݝnu 'SY^Z\0a{V'hnmGp H>eF̮9y]UQiv{5ïi[OuvG}O@cma-[epbQoi<2dC3N'?M+S櫨"i]L֚nzФFh11y!%;ya*nD ْTeo)6ouI7䝬߯2)%KͫޖgִW˿O>$]~О ߂/2w桨'"fG[X[d|-\r \o_~&x-#UjYMh swdΛ^K\1cA:rRpW5hkbrR{ۖM}W/KE|~>+x>u_SXԄHѾv)ͥı*׋RO!xK^ydbHg8vHd%prg;o7um:2RQ>۴WϚǟx[ŒGėgV^+K$Io%ẘ Y70rz㋭SN fGڛWH)ld~-m9N$N5ڵSW}fI}߉>3=m_-;/W=;y^Hn,$W?{yQu:mv65k3+n5c4n̦]SkuҼ]'5SNYrnYuz4F^BPם]~^wt>Mj/vz/[ji{MKLJ}Nك-԰XP0\%zμGSI\!]:I 4X' d@Ln (诉+nֳN4fSU[[{糧=(ak)ԴM/w]ji-zYjX"C;8H΢LRm 1νg?s7ĺG\Nd3Ċ]fddmQMi#ιjvN={wӺ59h'&^ҊKD~&XY@aJ6:}7C@T)[vmqov`Ok!OXE1GCx)"Hg^l> wp qWdTM_^ݟVҚnK[6~nv+~ٿ5V:)a6MHjۼqKeU.Or~;vMGU,.ة%;FXQuvu*ݫ[O^^gSES((((((+$[]Erx!~ )>%O'upG?G'O?M{ğ0hsڧV&νO4o9 4o'^dW73Eomoo4+HcbY$_ Uu?P X)YGJdo/5UHfCm%,@TȥN/X??w/ *F4⁽{M4|YKּ]~MTT kZG49w5M%i8`idym`OGl [<&,k}CYh]ͧALc-ŷ"'b8W_ UCkUMJSOYF1o;{TSZE|YY#] 5o ` N4^(>.xEe#XojZϝ;i7wl'zW⟆<7= "Xʳ2<"58 .pNi?t/X??w/ *WVv|9~Mh# -e7BZc y^BcR?ymCf9!kgBCqz~vP{K1]W.Q 7_UIg>eѮП>yo",0<EW\.Q 7_T7wq%>7/C'&-+H~0GSIkorH(ԡwT$j&-+H3GX P/}CkhQaǗ!H6: /iXxoAI]>7•i \Xg95E4*hV:͕֞K Q1RQ1HkK L߇>xA^iwZQ0LC{\IJ8H$*_luur~Myߎd_i|7/t+]Эu(a7y+q] |o5On6:΅vଊt`p+ɶ|gMB:z:P5]y+$,0BʤpJW9^j> W-}-NPQ6e]"Cg&$?1R/6u'?i#߇^b4?T|7ei{ahh[I#G7 \hz'9&m+Fa0jv)2m"CfF?sQT=}D/gw^eϏ>gitKg-"vSD$X ;ֳ|-74dN,/Gy*Zo7yb߃xc_ eѴG7V:@lnHA37Lj~'^Wr:kuc,F+BPG"UE]ӳmuw[}բׁЍ1v1E>Ztcvio?ȗ]W[Oj^ 𦡨ջ\6F!vBf(A:Ɓk#Gך7υzM߄f{ {? A&+ْ `fy^ELW+Mim&7}k9ojz~|5doln5Sy{I vu!IyxbOh2]j.]|FKWGVvۖ!㍁9E=@(ItwZ_|W48ޭj7%մ[mY[30(B$kީ>]E5}^DUGgKD ,$rX$]Iog/v՞7o~k>nq)J$75|1M_LONլt;ko Xqof/eٓ&F0q^EC[_o/篮|L<  KEl~Ռ}Ww{Vlž[{Sl4&)Rh]q]%wKD[eMsZX@sqqWb?t|:x׶W?nu=e^ y..|xaQ!)TR|iE tV^NޗI=f68-V_OkZf⛥ֵ _Cu,"q*i!][hmv,0A b8@ P=[Z˙QEQEQEQEQEQEo-^臮E_`K|A6{/)5] jfR}JJj=#|S2l?_-|#O?m%}Ymwm{[mgUgIIbe7ѕ"z\gS=kT_TxsH-FϨ6ԣX8 77͸yEݻT_[|bZ]|:3ӿ~ VmO.mJe{K$E3K,aOgoֿ{\wMKI=u{]{hVNQE ( my|?o^WA4x`" x!1@o4}gCO%󮭠C*{ VV`cM~?N-[h!hݖ6}ͼp!o,b8*5^I) X]|TM/GkGk[=J{]}A>(3!x=Z<[y'P1/-n]RmbF@ˈ# 2f_?XUoi[M&mZ1OʇaK%Ψc]L<`*IA[FЎ%,NQ TZuܧ䝥{{A:ωeuR+2Irč_Q=9f Q6F^G'_I{71u}i'G)oa24s^@&¯i&WaGr/=ƑB?wRX~|auۈXO"c,C:2@rski}iST.wZ=r;Oaۻ_ |v,a(̸e z*|ܽokyM[nzQHaEPEPxG_1E>'^~$O0\7SūOg^'@_7khDbէz }/ Nv/O4 ']kJ[%ͼX:V*z>/wo0j~-5}*)bڍ*AZc߅=L6S>{ە'{3>V?rs{YN7{r;۫_[~"|'_ ?7G2'%u]5A {qdGH|>gg9GBHn>EP>umFp't-Tv\일<"U+8ʥku[VbRm&??g?m ~ u[ME厉mmq(dD Ve8/w?NYٞ>?n?x;>9얟OL<2H8k~'C:_<<6]mt?}x9ʰپTR*SR*II*-&Wj7 ÿ',ȟ ;rOfx.#$w߲jo5D*['Oy? _q_BjeҊ]dD^0pa8eԭMN|jΌ^TێqiDODn#Hk60k6TEP0g38?ho>ĻGHO}Pm>[n2<ׂ~1oDE~?B ki}+YE v')a*rҥY8ڋOIZ7 Q_LO3ߴ?xLJ5"\bH8$W~1oDD/'i9Ei*-+|‡*浲pҕ:UVUӣ.kqwiBW5A {qdGH|>gg9Gz4F2Mݺi+d~1oD^Aٞ>?9BHn>EP>umFp't-Tv\일<"U+8ʥku[VbRm&~1oD^<}C~wn|/xsX?-+O>x$ 3EN?ᇄ&ڊݕ/dV'7bpΞIFu\iɨE&Ni_v?fhk~'C:?7"t?CgG=7'[Х;<}<~~8w|/sG-?.<7Oymd,q x'</Nuы^xym(<~"sa|.' )¤TUIFTTZM&fosh?3?gw>$ۻGHP&؏Wvr<ׂ~1oDF+P'v-vT#"k+(ƥjouSVtdruM)E~3~ϟgq~1.|/u?7wb^$7"}:epyc߅҅92;sJ:V N/ KRTTyճJquV+T2oghۏυko]":Ei3'đqHc߅q_8Nr7T[_V/Ukeὥ*t7WƬF)?c{F\I$f(k~'C:)ǃs}Ú?>iq}ls$yc`(,B#{IW",֎Q,NUV|yTiJd7udJWj?ٚ+c߅<}sys{_ODto5آlwg-8/ 'h.gvt|08&' 剨ӫe%Jfz*˖gk6~1oD^>~ٞ>9CxT׈ %":B}z|lƠ|q/NJZ?;yyE V#qJ4,Z(EhQ9kuM?ٚ+c߅ fx_X#[Vs2|[+Ig90+M9u]+?D^0ɲNo<=9Ԓ8ӋQNMҾn~__</Nt~1oD\2S${%\oAXO(?J+ wfxxq\_GZ#\y>nm33#X8 Oy? _~ۃqvQӳx=E *f\NSSHNH%$M^ͫ)E~3~g~>1|/k?Iwm&6#[M"yc߅W&8NFZ((/٫GE ,VQJ4FEMwI/Rf?lxc\^~o!>BHn>EP>um^ 5A / s'ievug1؜^' g'Jdj.떬V>e%k$)E~31?l~ >ODt;fO+eq#C  ^ 5A 4#pox D^0#{JTTo+YVR~NIݥ Q__</NuS3߳x:?4}"tiٜIQ?BX .1zF_k E YX7NDҕ7ovGɦՒ4W5A {fx.#$w߲jo5D*['(q_V'N\Hw\3?/`q8L-\NQӍVJZU-)-|*mٚ7/CAo%4mSZ\m>͆2w|ܟx!rʖ? ]e{^ѵѾ8%pZ< xFjQI;k}֧~I_R}Jj?g O6~(ԟR䎽=c]?χq xQn?_-~cxW?^zhfv >NS_҈dG`RXRlj%$ eR\tΪeU-{|s+>xO4t[om [FeyQ;/8>rlC/=ou5_mz-oO_hڦ{[iZ{÷J]xHu $(1rw_:k 4oO/Kݭ+ןuKE ( ( )[|KWIt$mewa&|Nd1j P 9u.__%FVy4X?fKxF:"U_ 'i>ohz-ݙ͡4#2V($MsGx͛M7Z?R45Ε}om"]mLăG럴ň|׼U$鴘D;q!=~5.-V)9+RwIwV|c;n}WJjt)5{&~ZO$Aӿ\ZAÚ;ԵiŬd,}eH)2h5~&[ho·]^i⓫]D"Qkܞ%ydUmC;7x~,|[ws'M6u.x]deߖBs zgOԿm/ ''< s Joa\1Q±S L-lh(8Ih].ViYɻZoѾw3F!% 7 5etV۷+żI7W>mbko}}ycyXgKMCm#=t z?xBе %Y\>{-a6[hmČ,rK>/%yCM$j#n1ׅ,.4M3P55}gYư$GaT"Uom0YCf'дs /kNZ__7Ws V] ᳼ Hr@,EïxEY|3_> }H˯?4 O0 7{?B|'E6|cD> _ h~>ctkj`%ݭ쫸0䝠V w_MVh'V=~Ӿ[[xboٛӢxZғPR'`Vt>LQ>`!k z~?7fX5/jQ:[Y|;] .%v*&rWUߒ1wJ+ʼMv|UƥV.uie%l-{kXe($w[EFekU  Aqky'uc_k>'u~GQO$# Cp9?Q=صil޾$KFӝx/(?Z6u_֠e*ZoIӕ24|^RzO|Nol??;o I)/p5Yu'R_+jϨȲ|?/-}IW4?d?|_R~7:F]kN2Easa}I(4?k/-|_R~?:FK/WML~ǎU6_ȥQ 1k~%Ϗ|B `:n~WΔ}Ol>.iN?ot-=7n?,W?/i<%VҴ-&MBDd#; xWDž4v?Ƶi3 A'Uxj()MO[3ʒ2i6;n}UN |Z=W]!%)^4s:K}w<7[sA}#$7theM6V~oDz.O1qᗽ+$ޗz.ɷ<JYW_o'~ Wv^3uosuE(*d[xis,rh'Hs1>ይg&|Ҭ5{ψcg}ezΖ%ͭt+$rFEx#E<𦳮FH.;ݕe2HkB9 qep,)JN>yjYh5+t <4šU*8&FSkKQK~gU-=?I=)ťհSݶ=Oϵ2r>-sw"þ<4}j%𼗓\iڈDl#\+b'Tn&Ok }:SpYApAmVyȑ l/{> ]SWZvO=Ԗ $ P~'N\8mrٯ5%$M'{4-zfxOSN^񯍴mcp#Ѵ;kn-5H 4LqMT蟱}nž5R>-嶚4B[/*we.b$H!q*Z]4دu[w.S}!%>hr9PE[=ߴ?f~9ѭ^[SR;(C)*N@a"$ʂ^^wUht&E+x]8V'^GW8KU;I'47 Fqo-o6wmώ1)>!|9tZ.k3jP^lm:kySJմ2-PA~ }Sp7s_g4}:/+ 1͒I1|rnԓ>Ui4Ym{zI~$O0z߇uc_k>'tCrOj-Z:?`ѿk^ G'O?M{ğ0hsx~Q[]1][±x&Id0Z5FpA|_Or|w/(x?ON;Y\xKYou_4Oa=Y:ebXq LF_0N3jN*Ov}m'yjK')۝ҩ:|ܪMsr^ɫ윭/˿K??u?h|cczǕ;ʉ!O)U# 3M{β\EP\nv}b^&,EJ*^ޯ2\=ғ\vn1oeo)O?]O?q^<qu}z>D:Ƞqθ>9k ?ƾ-5ON,kK ("m ja22C%ˣxF6厩{[Z+ &YBl'ME[ps[ 6㴚~)_O|'~-v_xv߲JfRF'eݜ6G~?C-#>0ԡ4;I٤ծ8 0vU+pUy)࠿mi:-aNMhoy?dD&o0K%˔N.{YI&=w ga^+6)vz'sBZ׌QwZq?w}#3L񏃼qG~w}q<9r\*+oq %XI^Җ KG4Fx\^m:qe^$M9Qj馚j1 Ʊ=c]DƃNI&orD }S׵2<#ž4м7ij5UqVOKnAG5??t5 + Q1CeY6Y -U<.59Ps[u o0alL)\1V1c*JiEE+[DmWşL~8g/j灾i|b\keP~vmq\9]_q>>1|]/^"u SOTo|g-H^I<|('`kUOo Z;h-[.J4j$  rrA؋i%ek+/%;0䡛ba)JʽT')&')=ܤ՜žqknzIL;J]6HorD }SӔQ,/JT {]-4շ >&ԩK6U4U9IF1RS1V#> 2>4;7?7O$#T9 )O?_NW~?C-#>0ԡ4;I٤ծ8 0vU+pUy{Q!kc[wd cG6ĪRi$wMݣ&vyg9]_q>CLck#<o_[TI |J1h8Qdk.RIm¥2OOsj۞M>}iЋ#FO2$FeLQ/pXxZ_[7v;%^fؗR*Q^e8E>{'9$b/rD }SS&G?|3𗃵O]xslĴ޾O}Q5β}(?;6ap8s|SQ܎鮩?TV7+NJ&RzN2[R՟,m1×e%S~ 2>់|Þ9ݧ쒙vlwg {qhY/_C]so}sotT0ȍ \2| ЎGg{>ۨbN D19&qJUEN/t⤬/˿K??u?gg|z?K'͉YYc*q z׎wc@qln!٥zdX6& >ݨg*XlO%%R&B7MkkFBx\Vm9Qz2MI9MY|_O?)O?_NHW?H񥿃?}VKf)%TdKDΠs!d9cm,==/Xㄮ^xM|id|&j~1n5W*$>HT4(2rI5×e%S~ş<?uM_/ݽևaY٢=y4ز!Č]]L/Iܮwww{ks wah ͱ0M(1UF1I(EM$I%khxg?q^<qu}z>D:ȠqorD }S׳~?OexZ7⼵v7g-Eo1ydEHp2k;Q ø=GVѮ+_6=OA,//nV .) لQHظX: ,.BU/[%d0ӡba6z^R;)e')J]dۻl'~-v_xv߲JfRF'eݜ6G×e%S~K~^uz5yk]ꗗӈVH"wnUURX]_Ÿ~AK}o^'R/ #0#)ce _-+mݼ ^'q <U|jTҌ9y5wiF1Gd|>&i1wn4o.<6'Ied9Gr0@5×e%S~M<l[xc]֦eڅ ob+L1xxr$m%ӪK^A8cbUF%/oW9Z-ݨJS_+$>c/˿K??u?h|cczǕ;ʉ!O)U# 3M{qh|ibZeA?f//'X-; r K(5Bmi^Kjiupa*6ĺ˖SJ\Q|rW ×e%S~2>ោxÞg%}r>u;Aٶ {7|I7Ú[^o%+xcR#UA$ >|{ABV'XZN6ڛWhD0 D2L)(agdzuqU~wU:lLn2qrsŵ,M?/˿K??u>d|??;K ů-<|LlO s9S`kO%%8PkT"kf71T'fؙӚqe^՜diMY9]_q>/˿K??{_?n|A_kH4ig,.'{{̈dkc*H  MW᷅Zڗs|[6}mmplK{ou,+ot`DIHPqDr,MF8zmuGUkiwgy-$+o{[/?L?O>1 Ʊ=c]DƃNI&orD }Sקԟ?c/Q:_cSYEۗ{+y|b$W Ҿh>:QhMw:ց4ckBv)/g)ʄ%+ݾXwoMa7pt)&8%F5*1QSI$Z-82>ោxÞg%}r>u;Aٶ rw})71[I4$P¥܅TP2I'\.R;%edd oalLr^NS'wm'~-v_xv߲JfRF'eݜ6G×e%S~sKg_ֿx8ƜTbTJjT%& $*gg|z?K'͉YYc*q rw} *k/]Ŝ.^4Tk!ko%[+;Z ?R_lf}/A-BR[:_-0O46ջ"+*7e{'#vM^yv&>'kX{#?rD }SS&G?|3𗃵O]xslĴ޾O}Q5β}(?;6ap8sr\)ЂOGGUtTLuM ӧRmh^q唣ug)-G߱“xuF-VO DsoD=uo-^臮zT`QV$>_5ͱٞ*XʴU99$)6ݒI][# Fy>>*ԫ/Z3 ~9;'RT<9BT|RfGf'BJ<;dv|4W,Ik+>1~O袊((+O(/QoUh?t^9w|!o\ȺV_ :1_$Zy2"y@V݃]x's@^x4_?O,_b54qc+h>[?ou}bPgDzt xmM.R8fVTCI6Qbټ9υj~S&r{%QfIegI~|Q'$x(j&ɥrpEw-AIܣ+Y1 qC?<4̱,G8 #%FVy4X?fKxF:"U?| K3C^s$Q[ 5Ef/6:Ayo ]bOF[Ws (@V mߧBӵoxեIV䁢Td\~ER)Ss^JڵmxR8R&!MZ)ݴzo-Yg_#~xRe$z~ۄP.--Auo67hU ߅6 m(WOסƥ_<)%亣,!hK #\fŭMI_ 4o%/gx}#c0[-u!G"d~?%5gOީmJ}GNKc>A{{q.By*#cc--{u>7ui+/¯&ς?go:~? }1ti2#+w#;cb|+c E~ _.O ..t;TExf7F[pcqhBЬIg|4Ӵ\x^d.M?C ;^@y/7P,>\2DZvof3;Aӥ$MGP}>զ+N ieSu۔*+wmGDQ+4Ҝ_·\Wfp "[|HӼOv5fM M4R*e$iq"b C0|Go?^mi W&%[[F R6D9n?_<;|&յexXfEH,VGȨN8l)¿? ֽigm%qq=LQMm4{TVP/r{?6vM_2TaZ+՗n^ckǀoa~.|0fӴ֮66k`n(+eHpF  xMl5PմV;+9{kdP,r!*A  -W2?o_z]((c;Z|E* tv^%׼n%'~&қQҾ$aefĄ*%n.>vm7nZl׺z4PӼo|>4xs\u .{h-0^Yieōqev_|}q:j[(pczk+ [3ɿ2i>nwNͭmhߗC9Fuouݯ#W-S Q_vb[Wӵ7]It8Δ,Ѡm{e%JEh9?,_?gZׇr n}^ˤ$< ":QQA{.^_k|^z7vNTO旦ɴ 5,gW5Mrɩ,P Ȧ8ܙ#`  (|/-\Xzñȵh%4:w_>FV jf >OW%RJ]OB?+u&Q)]W/I.p=i^ 59'Eԭ 5)'ɂ̿xyOS _߅<3Xiƣ&h%YkMn+D30I"$nRR*oi;?VSU:e~>O!h:Uω{x >WoYZ@ )614He~jc!oG2oKu:Ys >kKY=.4 #v!&p^g"g| ឳm+FxOj6{ Ϭ_Cuis54QyL~б$/!hW}_+kPwjҽI+?3NodQ_'CvMt? KirY-%vMGV^4eH>ilP}gUmN˩ƚ$->mI / \)u7Pۉ0> }~'E3]o4-FEog|F׷ڶZ&[&%P20y@V,r{i=䔌*n٫|*[Fm~1|C_ sH>xi^>hWe1DNwoSCǞ׾]Y|ZЯ4kZƧi5ΛRഋ.)˶UЙK֊.E+Rn]Em??i}iwu7?~/%u[ƴ4;=HB0\xL@—ψ>C+xsƺ]f͵ťŞd^G4 ;f7LIg>hqٙF$߁f.4#@e?Tε1E:kǗ컮m[][nj.~~ooK|A=4_ _";ބkᦥ V,s4kƭn hl-I YvmyIiyb]Uä_%b2_mUwu(M//#/گ g7iĺp2%1ޓcxHk +NY"C"6dhG ?uWP ߎm)/+Ky|f\E AڼO<H SJ¥~ K5U}W+7;NӵoQE߇-G\zEVo`4y-b7M]OzLJ<;wrG\ѭ4na1"b޳ R^Q='NqޚV>l:4ƿ4}{ XF>uKiv3].x t, ?i_'WW88x-r][-t[Ymͻ ^ie1E斯_4٧%vmZlN*?G/="NٿE'1>? |+toWM+K}6h[Mm6m%K6paD- ?h/|eHjcw4K]>]:yCpghxba(Wz&wO]M7'W~嵽UMt+r,~_>1 T6YO=ΟYE =$`y9QZΤg'-m3N0V$_$^H(¹E_`KW/H {>O?m=??*ԫ럏VUW;^-~J1_~/F#k࿇?\b:ҹ Lg|W|bZ]zy'/=ou5ך}Q@Q@Q@|-j_x+>O-u+VݺF4ċRo&DO1]H ۰~h ofqkI}cVeV&Zz.J$F` h_~'F?%]3^YzyLRV?iuh);;N3_>|xon |o ZݕfHq@&!6#旤~٦w/xmP ֢d3ؐG+~ MC*>xᧄu+K[sŚ೼Cڬ # oGS <=_h_| {Io`?#-II,{{>m.jvҴP蝽kǏjN_R r={M}I&=mo4KTbɗ;[z,fO2m<}ww]爼ZpjzeM@ުRH&UdFc>[ǂ/4mkt{vLb-mPMpddE8AǏVjno$߆u+M[ON[dX 3xw*=۾ZU•%a~|#ύ< m|?hږj(!k[˔d,׉7hEMv?=}/⏃mѴ|eImB{iQLOkvI F/(7?p=?/ Zai_h:o.W&0"Y[Ioǔ@,p+3R_um'>+Ѵ9Da hY`*_ٴ?j;;o]V8n*2*TR$C]Y5Wh_oú&CޥxL:օak;9XB>la?)ïSG~^?ˏ^]xo[aho*G# b4]ߞ UᯡxG_1E>'^~$O0T7ڧV&νO4o9ׂSūOg_JU\6:{kh%(r7 @5%OW_|]q6l[\xqCu !H u??f_M(+OlOٗ Ԯd][v//-I c[Y9I^NO^W}nen Ɗohn߁ >^g>7ҦȎ{ح'tCLXyW) #4=Mˣi~*,I<$#nQDEmŠAB$^ڰ\:瀾!;p,y6&?M>]y7}HnpoU~Dl˶\ ~m+zA +Kč;mXHdcK"{˖YK7\")y_H)5ú3˯iW骬ĺur˧_,w7vͺ fXcDӼWy{wᅝL4x8;v񌸶V@b@w._+%zGn5jB҇<c 2i޲o/~o4ʨEͧkYzvcI?nwðj.5OAݟ-|>+4z(Hs3+I Brjn&Ok }:SpYApAmVyȑ l/{> ]SWZvO=Ԗ $ P\SӋ}[NJӓђrK{dH y~i?x_נY^kYSJt'T Dw\q_z&_.V6@XwW6:ŕĉ1KX.e*pd>G-U:=ƻ}mi^떶]ܦkxC2K2|Ѣrŵ .uQ;Iz_lw. L誤#6׳}5fN3ܿn.TW/Da=fsiSEnVdL֓(^|d6(H?9Z|# >Րc_Y^ b&dpXeIڛd¬\M{%!IE:Ifݽm%u/%'uPg?G'O?M}7._7jOj-Z:o]om?ƞ0SV1fk˫ȵ 縶]*w7nXǗu$~i,J~5 ;]5wY׵,j2,k)Ao.먫'F/*\_[%XO_|#Rhj:yM{y?i[fY@_-}⏉oH}o[[]24kh6˴ML GHi=tfݞgkTZI]Gmlmju{Y ࣞ񗆾Jo+?x{O.mM/m ks%C!y!_@j* GQэm{6jZ-ݴfYg9#xP< 3biGzGim;Nu/ %ΊQik4+q#ځvd;hY4ݭKm֮IqJQwVWo{}hRZ6Kmo3 |1[x?kMkԳ؏G(w+%z4fl=ឧu[9|{}xY"O} 5TlFm5wH5B[x%r/a XOtOz<'xKY;.Ku3r;b֯m}{(5kO9jw׍76TdqkIPN`C((1b_.sU?y$>-]_Nl-}wE-˪Q{[#rfpd<e*\h}^Xs+z}-I(C ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?gI?/L3蛪~~|?7/+ݯ Q|_&;u⿇O$x?xÖcw>Y'uo_N ݐ`ec1\x 4b?goֿ{^^IO[vkMwd}/EPEPEP_:~տ=?kzω~|*4]5$ςi׾l-AJ'.?E7KhqgGl6}Ǖ&v0~6]_X>(총DlK=Ԃ&/9uYM~_{SLO]OI.e-q5cT I9Ɵ<%7 7zOH\2Qա< ![D*Ft>ơ+k[t;A,{K9}[Vn( `n)⯊M.Z|FY/,4bYdE7eTwDoOt~׷vKxT v|pȍ0J2Q IU$/ XJMI$Uɛ{0fqo &^6Z-ӮWo$~)O?4=ZE뷗}Z߽fC*;Hʞ eÉ=vR.=GQkciu-ϗjGxd|]h~$|Fѭa𽥔z wQuu22G+Is8T\ 7>\Ю~""SY4jQ崎GX@޹Ezb-vW֏]4o{ߒ~M_OKf3UGGB=O.6 7FDsn<ۤgrbp,ZOL}_o]KPeI!Γuj",n n-@"77i̶^XAذR$@ g/G?΃k#w4)-a"N}uSߛ̼eMl((]rKRIO_NOZ\-Ϗ$i'hG3&])C\_4ɸH WjUX#vc~"%F.Z7:;# JIn߷%*A'NԼ>$Nn;y&R-r`Q HZjMCƞ糺^1A왕^asl ҝZVM4wO{E]FuJVkdE)g{sqo.tg!Q|1 g7O~Ѽ/kᗉ5Z}X~(myckh㕚hY UmKJg髷AYIExWo ia/|e5z_EmF+ko/l0*p#(lۓ/oZ59xTuyuH&X'#3-+< &$Gh|w֫U-5~zn[&G<7kĶ-'Ckvl&Ҡ%VHKA.ʨ>g3rkۙbZUdQyqu'ֽwǾo-Yƥ[ u]V5X!W,x veR<&_ouiq]r\\Fc`E9F3ӡUSw@N̋Oj-Z:o]o'(?Z6u]״)Dy'W_lVxğo|]Uÿ?[ZBk$ Ḻ!crKpBm>;7*|I-Ix[uj?"|9uy<KN3} %)@:/ٻ]k6F]%'TԠV?dُůj&^{eanKT2hxءa}>[}M,^j^Onggo&8gDP8gV:ߝziz_Am>l#eG'3f&f὚]..6Fϒ'𧂵:^E=#d< t R7n6_4\oiO>n.]:56}NmZQ1]J WF&QMdhrV+LuϺ$W9<'pnFzlmLdC}Ƀf ǃ/i֜Ğ!mt!r|TncL~rzb ,~iJ-ꔗk4oXIQOV^W&]5E%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@y3$DWW?Io` M~~>W? >Kɿy_DO>| ɿy_{?=?1__9?Q?k=>qIE\x;A_ey'/=ou5׭ג|bZ]yKEQEQEW7KhqgGl6}Ǖ&v7I\[//+?ѣ}v`q.78ygT%q?/? @M6]ZXuh".^ojVHɹ`e #lbj7GUeMi]YAfrUi#c hMoj~%c|_zL`K}M?N n6)bc wOهB=cBkU"ӯm$}ĹEGfඈch3fǂ.M֏?w s_[ĪH[mof,9Ć1 Q/mᦧG]\ZⷅUyeHbRGc$v1.lm Klm'3uuw 0JMuxz{CFI-wGp (_!- Mk,Xdm.ec2V` 9~*xzWhe^M,FDPA#{HFU@gtF'G{{H^-wi^K`o8ɗ ۳%RHh྾763MYn/_,a^-Ms9Y4ՖN]~'ltl]6]]A%̌E\1,"M?kO(4+u"Zt;&Dqqym#3eP7q_{EnS~-O->ּ=*+U~=Wk(ӼrBӾNulu9ecK4o{Fw܍UO'&t]>7MN[n-V&5Y=4m,T-z^j|4YZewi[/ ,d HlXKFTeqV  C ~#ğAsM5; Ro U0@R ʤ5NS/l KԛYK|vkd NMX:mr$j0_Je㧂P3]G@tZ5k˦ h}=w*+wey

qQ|9Fw|mOÞ!V8'FxxrY7RmOGxWe%˝f'9f9Y  [M9?}Wkt*54-\W[W_6ugO؋|)<37u52Zu׋>9ln嵁>ktr]8|HHA ^)V5AqkRLS ia/17CKұ5/'u{L5 Mᳩ&! Ie4rZF]"+Ymm#⟁E7 VVfIbf2Ph"B\USuFo4ٻit8^ɭWkFÚZGZF|eM'NPN8yO}#WRxX}7SћVm/ ɣ́, ^o?F_cC5N*UVkzT'&޷s{TjDu^覯?hDbէMA'̿{_+B+{H\ՇP*UEdRB|{SWPn[xV+ӫusot,g6Fmw00exGTeb 5ͽKIk,W2qxhN wn=y ~~{~.R-tPu lɐ̱ys4dFp .Wӳ[5\eh%x_|fKї~W-N}vk}BK>owyytY'xdYocxT|!/okk \x=~I-JMhc!l #ӲA?m ]%ٻ]kYFL 2ܴQr)XM)MSv}6uf֑^2_-m=F(,((((((((((((((((((((((((((+i$7&2OKn $~Mu(|$?_zq_ç~}bпycs~ Q:QX~í*)?>cbC+~o?c?P$';εO_z߳|_k +?gHm>8~$_e1.QA١-hlw/_ |YC\]{آjE0mB~$(و$(ɯ/8*ҭKN;)B5 Nqi꙾a/f4dK_G3Of/``JR&-oB[B+Ď)#Q[ᏉC[@Yt"]#)*e-5$6xOlz}<,\ls^)aqo)>껿.0y,=u]RZ| aw6:G|k6v&eDm[Cydwn\ɝ.on]#Ou%oͨxzI++ۗ;Y#_K40,Lč~?~jz~/.o*M嶂uyAYG T oco>^7 BeJXl[)'Rޒ]ogi+eH!h? #ͬYaf-W؏5yC(҃O+4tgK5n Nfss%7+)An"eȳ,?ڻoÍr-/?sZj>!Dͽ`HxyHQkiK|aoAoEftkn±F128 i8*GQNQSJVWiuu%k]twG]ϗ|+ƅEởcKҬ+x|,7ZƛյLu[x #h-$;Ha.7Oxf=j?ۆWMAkzURVy }EUOēIzmEnnq[M^{<2Ӭ ^%|;jZVr:xJk{ifo>(A7HQ$QP_ClN3O{`Jym G2+*ZJ-[ni6RKVC>麮|agVηiCjbt}8K2Aw =762|'^~$O0i s{TjDu^覯?hDbէMP3f_=ώ c??IW -Xa,BY]V2$Ʒ ^2|vo?UG+~ |1tԼuxoP6r.[,q|F6-tk뺄zM朶~lkOyMvmM.uO 0J` 8ɇ"4̌Gy/_ t]xVZ]Sg^}^[MB[H,ž_Mi }G(-wKYwOQ[Vn \ɹ`ai#9_ M++an׶[Mz+=,KƱErpBT Х()+yhr7,emkW_=7T~kx4qj6u$k#&Ό W*H;c /ω4сmi˝V >ⴺmz4ZVdwlGTE6]SvqnI''>RZi{~Qt WzLzKm.Z8qozα0i~[˟2 Icp mD'TݓmۚgW׶Q^uwGǟ:7iF3Cz+DYu q.5K,osbM]EP0(((((((((((((((((((((((3蛪?gI?/'O7+5>|ɿy_{jtrgъBd נD2T|R3_8b no8V:9as+|]Wh4 ۝/:՛ZGln.)E *}2~/뿳Oϊa--dZKku2,4J$\i|?ѼEz4+kkog77cIJ!BI% #0Uf4c_|ZoKHݴs+XעAɒg-|'\?burԧw=ewm}ԣʖG(.R;o]G>|?͵[ Oh[7M^aw(6M rOoxv@5hZ%}g2j|֑ibXJ"d4 #W_S^ht={{A麟MWB,xQ0y]E#yb6v*>xyuύ 4h}~niꗘnU%#Hj|!Q_W՟|kM9cWkEy'gut_|, |DԴ+ Vy5c{Y4k -?u]6f)j\e4MSV:??1yMSMDŽgQwmJAqn/y6nounLTMZ׋,!k4Bӛ؃J{kMJk;S46a5nClu7n/qh_|}{x@۷VӶfDRm!@(cH>^6]EZfu]&=3Wp\:[;FѰ`@g)]=MU]I{vi7ꚳ}M_ƾ }~"è38//-C [ĖK8{T]p$ecjOاd]xU׭M: k $X3WSԮ+"&:u/74ek,m3Khe$r )"0'>w3Zxtu65_-\r.KQI/_Ryh+՗Ys_mWJ^{E95E>Gwλsc3J#uDJfy_ )vV|1i]ޝw:jOktm'FAg7},IW^ϰ{zwWCcE|O;$U\]j|qw=fhL}B?Cz;?uLO#(קג|O?#ď^^I?F_cC9?Q=صilviSW̟{TjDu^覨?/ocE_ך|`b_5+?SZ~ߣ\jWE^=kX] _'WMyO^;>,XfK'u B(㸒(o.-Bxl_vό"iZơSm#^+/5-RĖWmҭ٠eu8DvMK_WYԥ+i;+N%(}WC{[Ph|?w9vAn!WLF)W?L^&|_xǗ~4/4{SMicq-ya+O2!gj H@x%}EkRN\&ZMh+eN T|4w_>Jg hnj|/aɠh>Ѣ4+U$Kh\4[/C-x;Xc7*wmK+ʒI9cPQ{_v_=[$|M=~H>#OQ]_MmOS⿵$hx1ځk(d ;t C7^8(o:}?zqj/Ur>{K./>= Gx;+D]AsFq{^>MxqEk?%hl3-孄:—˫TQJ*ьV^z˫w~ES(((((((((((((((((((((((3蛪?gI?/'O7+ۯ $~MvM~hz^N3_7y7‘R1_UōOGo_ey'/=ou5׭ג|bZ]pn}/EPEPEP_:~տ=?kzω~|*4]5$ςi׾l-AJ'.?E7KhqgGl6}Ǖ&v0~6]_X>(총DlK=Ԃ&/9uYM~_{SLO]OI.e-q5cT +/I^"LY;6/0~Mޟzw7Vr :4&6_f?tvEYVK;j;f7j (1̭"?;⯊M.Z|FY/,4bYdE7eTwDoOt~׷vKxT v|pȍ0J2Q IU$ 9&6ݶ-h֩PQ~VnÞԼ]o q&.o$^Elu d' ?nu oCx^P4(.EW)⽛bmk3mPvE>>4%:wnb ~h3+EWowd*YA8)rbݷ^y"QἝ/>GcGG ߉ڝ43M, ;MF]: K}z;cVכF`QXFş'ώ|I}#þm'FK /Mx6V=@󭾧fFm2J"̅OV>j:'; |*A+] n%nȠHT Զ߷?+ k?ˢxR[Ŗ kzr% \S9@lfIIMɽבmԍO*vVQD=s,$Iu+[Ceҵ!5-5ḻoy1߽ßK_xŖ+O?W֮^Q&Σsg7ooysxXi; յO۫ྃsS:t:\/hCLX9n jL/5=CL^q15=:97۸D=kGȼv[=z[um&Ů?7ew^zg'Gv[/hSx_]~‹z,WcrAnшBDA$0Pk|1[#_< OI3D&أu S]!0Hm>]5k ~(E~!xA|S,Wg R&/4 tas|B *1iz&nW/w2?#ď^^I?F_cC[?bMz}y'O}hDbէM_2~SūOg_M˵{Mg̿{_D߳/ocE_4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW?Io` Mzey3$DPO'>7+گ $}vkM~ x^>B‘N3_ii?i /E#o\8nODvj3 O_z߳|_k[$';ε>^(((__tZ{m$%("?4 C|/Ex07<po i#k*G%PEk}c1f$1"~3Co 5=r8G,J*C;$\atgKkb\=gKkߴω?i ë_nUk+ J} 2Im ;f'OGeo>&l|WkYeċ#iv/$(e8W]s&K|mj#C,Vn`,2"AEb2;7:?kGJoMWZ%żO[X;yľLdFݘ%(E|>CGU9yjtz'd jkGZu런w_~[x{nïdȲ[]J$ld8ٰFIy/&/+Y~/\uk B+=ZY`Rk-uopDxvA'7XЦk:7Im3BUyb+ٶ,Nֳ6mn)_COSx&+/Fo%c(+E]u_~xb?蚦e \k>e-ڔJ9H^0#*4lɧFgc.mNYw2l҉ XeBw0)QcZ}z4{ Gcq[[%fyRDM,C\ĬշI--֚oo;۵FRoG~i>[H4Z4iI|p%P2Ci_Ls $߇b&({=Nvd!0vկw`|+L_K5HX-IrDnanC 5heS{j$ՓlCemxvOԵ{T.,ipHyfxcgV6B]|'^~$O0T7SūOg_M˵{MdڧV&ξkE5@1>;7*f_=ώ h(((((((((((((((((((((((((((((3蛪?gI?/H~|f_'cvM~h ]9 ~Y'~WVGq^N7_%~5|c?B_:k>1~>(((o-}h>;08m<*LnSxׇ|1RnPյg/"@t- 0 \O }ceMV4Z ZF$r2nXC (+5bE[uɎFRTZyY2z_zs?7DԢ]zM%tvwwoqm}4Xehv Ɲ"2_H!m mqa.# \qQmy905G x9JQ\;+[Komvw[rZ4kBwVnɿMvw)런w_~[x{nïdȲ[]J$ld8ٰFIy/&/+Y~/\uk B+=ZY`Rk-uopDxvA_WhzZZMKXX4r.!˯?o/zWŏI-vLWzڶir-n,է&(c O\jS 揫xNRҧ:RKGVݟc>/|Onj[nocNԬາf,6TojV{8; J6m_ky+,7Pcnn/o/g?M v eqGx\[3if < gY|Ek-Ն]wg{ K(GFRAN*V|r[ETw9I5?%īmkMJ{_A":yvԚFpۼ;A gصƗqү-R[̷ܫ,eewH *o&wDmnkz[{ -C^2ԟzW%c(+E]u_~xb?蚦e \k>e-ڔJ9H^0#*4leQBr_I%m`-˺ջv|o'ׅ?>|oi~ }:i/-EIgA<&JeuRҿz x_t /?υ^R(Aq5͘i%d u%p\BmIoWܤwk\Zy6geOVڭaotK[WMB. dg6}cid*܍>'u~GQO$# p9?Q=صilviSW̟{TjDu^覨?/ocE_5'WMQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_u^^gL'%7T">^W_7Ţ@?o>^W^3tβ_WCCԞO 'qCJq+θqܞc?P$';εO_z߳|_k#ϥ袊((+OڷgmoY/υ_&|`]݄Z :͐Ũ2)@$2i| ]?#h_q9߳ϻ8F| ?=chZmugDV.2Ixා|i~i˩1w^%̥&Lq1ʄ'I  7GUeMi]YAfrUi#c k&6kfl^8n^ktT~=xyjO~+\ Ɖxr>TT\-ǟ9UFViaXe+\ +.G Gx͛M7Z?R45Ε}om"]mLăG!¿ uqj#%VY!I.qڼ%尫WRrRo[/K~/uoV޻j| oĞ"5|?R 7χS3%η_h_$(y@y_گ5ޅq~~-B;!4-K6RM47Z֚PvI!Y|U$W]s&K|mj#C,Vn`,2"AEb2;7:?kGJoMWZ%żO[X;yľLdFݘ%(EN:9J.1K>U;4_ӯZRog^|DD|C=u%I&~kv05;{{#"[3L5&Mۄtc,T_H.וOGɫ稨(kͭk;-o?9-Wz?]/U;ȗQoݠF.eN ѥdYbF{/Z?>ε-[\ٸr@fiHQYsC-ς'|aß%{]Ğ|7w]$wRn&mtw,cB/oK<[yg᝝L#bX/˶S", Q۷[}wNsMKvҷ[i}t}nzu'|",o@vj-7M,4_ C^qjSq |Ѳ2,q%x:? j_Oqz,#izPq]erJJq#uC4W[>KlgQ^sk>յo&G%O2V&W2: 1&ooTVk=WF+c3#vu%uuoOboލ($?bMz}y'O}o:H/5a??:n#ڧV&ξkE5|G'O?M}7._7jc2|vo?U}_;~̿{_DEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^gL'%7U_u@O$o>^W_'I'O׷?Cb~,~hh:Ds>//HY)ƫrz# O_z߳|_k[$';ε>^(((__/Oa^džKc{BV͞Կ{phv>j;( zq?/? @M6]ZXuh".^ojVHɹ`e #lb.OHQD4M7O#KḊ[؂%FVc㑂+~:ueЗZO `P7]-rkSdrqRug@?/:'7FmxmmfxD8;xHYc$Df }?VHu -vLxem4$pADLd iG qkMWn&ORq֩~~.ω?i ë_nUk+ J} 2Im ;f'OGeo>&l|WkYeċ#iv/$(e8?Q jN24.!>'ԯ+-?GU5"{`9I,Q2[EV'E+?QɮN7\M|nKi<'O_|9Yj-:}yuq,mY_~qQQzۖvETxn|_Ykr6G{n֚=o-"hbp`xƚe|L χu$nx+][FOE:>vڣH^໱-捁 vAAW_u^覯ɋ|J2vu^覤̿{_D߳/ocE_4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW?Io` Mzey3$DPO$o=W_/gs򿝪1ܧ~u:/(/E#Ӻ𾄗O? 1~+zŮODwpr3 O_z߳|_k[$';ε>^(((}?e$;Q׾|!MGKM/]L@+(Fdm7o|3Qci:?<6ulV{Mem^r+*!$q xڦ,Q"\Zk 3n. A2yĐ`~K{υ^:[kږZ^5/-h*)EV1"68R18bi:Sm_Ѧhc͵MuG׌>~џƨ4w Ωaέh',SHY@%y>x_=tMIHHU xh3fǂ.M֏?w s_[ĪH[mof,9Ć1 Q/mᦧG]\ZⷅUyeHbRGc$v3-djrrROCQFnfշ/6#H<uoD6A|km4:ֲ/Nac ?66M ¾#]焭tmGc[Hmu+cH\UC\a⮹K>6ֵ_K}zK 7GXgaA "U#xݦx'-,z_&\2#nB@RUI"=^^V4MذY/چa&bK|jMiK4~g䁻%CB|cxGl=i:i}]D/!Yw7l)#CG_mMuú9=^ UK\r(2Wjy#V˙r{)sv-ڄZ]e|wѾ^q_YXxs/, fR4cq+4\$mn>+0~|+/Y,P*/u[3JY|3_> }H˯?4 O0 7{?B|'E6|cD> _ h~>ctkj`%ݭ쫸0䝠V svoM>dg QJ7:i/T{|?(b]7D&&O4|i| C~? +j-fo ̰j_fԢtfX6viR]JUɴw䶿T]nz=~ݟ<qCdUKZYj { v&C<&VQAU` #jZ4au{#n"QTeM> 5kXhm%ur;L"ḍ$xkGTj? +xF 2Y-Mco,dD䲇6l1a\dM^%\dM@c2|vo?U}_;~̿{_DEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^gL'%7U_u@>|y_DO$o=W^1{βUӊ@ cfK 9;!cbE~/+28OWv,Bsrx \ a[ڧ 8ܭs:O~}/+=*}Z5o3^-u V4 ƤG)=ih h}/+毅&—|%{_hwWZ}+IbI$~?? E=#jzG} _W? P? ?\5C+)zT_?QЯs_<_"_jzG} ?h_~-LE]bԭo6#rF,8|BtτWZM# k3 iֱ i7y BXkK஫ϊ-O~AXDSiH64X9;gh@`ghy> 33$uCە)9ngR~`П?fxwOY-:(~$_e1.QA١-h+ ]G+(xvEEZq -Rg l՟|[J]xe]60JMux~{CVI-wGp 27!Ec⿈Z.%YKY|e%L)!C(AǦ¹kBWkQ ]^_t0rJ˙˲<IK_M++_OڏǺƯ}kU&(EհSݶ=Oϵ2r>-x"ÿ4E4m2\iڈDl#\+b'T~Сɾ7l؀ 閠 }J;ͮW릚G"=S^#Y EC>h=NӼ2V,QT3I{qj NJz$_ioR>-嶜}֡i-;1AdY]Tqg:-C.' ,Hr]I>Km\ќ4<2hV!.!?瘣 yɷ)=\qJ:Z<miq'_< tK/ A }>ht&U+x]8V'^k7!|9tShޙͩAz?,m:kySJմ2-PA~ }S¶ ö[}@m輣 MılI/vWc>9@//x/|;kO߲Z?mm3bDOf:v Euḣ;]s RefVV;:|oʹc-?Ɣck-oyS K BF$`,Ǿi H$0pIYa*e`ڪ2yڢmŸPhx<@ $##o^?jͦ}[_]̥#%gbYaFY$yOOL_G{7jҚG4}~9I,mm}vڥH bX>m%xDO>2ỽ㕵R|jr KKKȾ?dَ%cyod8y/)g]WĺKkB[Wo#ٴMkm6F JZ&PqKk7ݗ>W//xDO>2ỽ y O E~BRl+UFak ?b[HdBw ̭F%_ï^#д^!Kg-yl+?1bgArF+$l+TO]OI$ﺿ˿_7wrxDO>2ỽn/_ Y7~*<1aq\x;Y+Z=e))m$)!KWnsP.ZJ>֭n/#eWaR||D޲qRvz[<Q_7wrsSe NL?ZtܛS0%B*.s] oOb:ց4Q\YxzLJҲ<ڽݒIWtKDF1{]TZ''?mv4<Q_7wrv&5;6e5iw[Gqq0Ȓ).Ng(GėTKOvnfRfQ=$"H YN+N[S*sSvz|+t'|QQxŜV=28@mD$Z@U ?q~)4 wH%ɍb<=ނg4`09~|=Z?j1Z^u'-y6 jZ]Nmk{ٗ*>u>~ #h~ #k?l_OA=Ͷ/hiw,j]ǻQ\9PuM[PndxwEik: -4ws:-buw6uuS#9 F|w7wvGUs?Us?z xo~ j~y3}ߘ7[TߜҼ~.>~?4닻|9Mx:waյUZs "WM[2%Kiz߻o7W ?[ŷּ ݮ~ #h~ #kogᆽ߷|8>}37;3Kc tx_Z& ; ͛yf2R 麖TE;e}OG+šK+F) I7$VCF֏xDO>2ỽ~toVFCW6:ƭ.e?Nn.bxA,"7Pgk▉Tgxv}SVZtRQM6m66&l8Gc{[k3^oCAD/9G<"'C_L&n -2KΣ=ޗ5ަ4Ȗ?$wF˶V6tG̟?isNxŇl|CP U^Dӣ4uuDVy-!HG99Ȫ_wצ]fب\߷]_7wrxDO>2ỽ㕙ῄxjCk[UV։w*Ɗ,!22N`Kay2Gc{ V{PGu-pҠYۣ-WO=H)vo_-?|ew{*Gu2.5-1b{Hv,fD@X`7m8 lXվվ;,F{j6hH:}i[Gq#o%[nwoE^ԭcuזhc_όn?|ew{+(+AD/9G<"'J(<Q_7wrRxDO>2ỽ y T<όn?|ew{+(+AD/9G<"'J(<Q_7wrRxDO>2ỽ y T<όn?|ew{+(+AD/9G<"'J(<Q_7wrRxDO>2ỽ y T<όn?|ew{+(+AD/9G<"'J(<Q_7wrRxDO>2ỽ y T<όns_l?ÿXӤwD*b fNp:t:S67:ͽ͵m&zVR J_Ž8ggoRFç~wWuibzz0 Q>QH~W_*'rvC}ъ,ziyW_ s:¼/oksP񍵝jUf2:DKnTGЀ||0Ѿ(hQ항^[3cͳ@vMuGdpUH*̧t^yhs^S W Q W PgwѴѵIӭ HVS Rlk ׿KkF}(F}*5%4lk ׿KkF}(F}('^-:':':td`jl,|&_*Ѽ_C?>*Ѽ_C{/?/?Q?1ڽ]jaq=VUsWT_l^?x2kOk47K),Ƴlu#u U<=‰-,|C湖[ I-d >YvJ70`9ە>5[]5Voy}[\MB. 6UFOVw2'%u3eFJ?B'izA6|+ִi => ŬiN֮,!m/nOHN ( >^mwkvs/Ӵ+[ >WJ1'ޑ"79R/2'%t"|'_ ?7Zsw;~W竷+gU hʿæ|/7W?h|K׌.%DЕTB#XOOj5/ I[u}a:Zi"I"%L +?>/w?NY%WU?{^gw_NUO{ŐBmGV6:}o;Fhw&Mı 0sO/,Ĥ}\֮.%絲{- ,[dOK9gDODnPZڋz36s[F @[[{i""2HѱL(~ßo~>x>BωHh x{A]ƺlj-QVXI%IotV1pPbڭ24쫡|KϏo/oK}SR-Sėv]\I핿~U70m[O%Z~6+8Gɯ{kgm2}nomf_a9hWt,?iZޡ~l6k{oj5)`1XvJ?k~ ԼnuQŗ"uXowlh6e76G19J*Ta-KlE?s+?/>Q~x;Þ%o٧oiZ-nc}%lk'!/ɯl#"ɧ\BOe?>7O \~:fcbLvK[i8f2i?DO%lkmrt|g&Ѿ-GXAqCnʳ2##|Wg Q񇇍*Dӯ/-5MygR9n3dX$%оc|'VQSλm%%ZI.ĒI$?NY"%%i$ףhoX=I/w%ʡt鵾j+=,$ܓ}oxdτ&ּFKEmMkHM3CX5f1Bie%Pe8?=^6ǛZ[FմXcfN:dI>߈;]i#_>/w?NY񺨶/OϥehqVQ\;[g6|Fu?k:Ckyqj1:jok$aSdbBvɷ3ZԣQ抿>4i~k_j5׻?C? qfJk rvFY+S<;wZ>2|&?:F nM%z.tJ D'>uRoNWj~ GiB+ MSROṦB,|N2q)I{8z]ٮWfWw^zE䠺uo;EV?G(_cĸԴ+jP*]+{K`F[m(?Uj/Mm{.$ϵ((((((((((((((((((((_oD=<BUG"/%zOaƯ x2\~ ӯ[^+Ӫu.sȴ>ئy3 RXg5-oOqOť>!5V R{˿$ >C̋džUo"7n|MjZ\jMng650 KqvO)%$NB"ޒvKi-.)СA C(x_P5 ㋟_\_>0|/g:/m>TchͲAqG3-t~Ba@~3N^:RK;O:F^-\m̑3FꗦIH2$su]<|ںQ~ܣٟn_ TM<BU_h uφ_k?[LV֩eB=߂~}I!Esy/.I_L7VWwKwqg/eeulqHWy4jgߛ%v4gltOmמ X-# _Y+n@6Tr9sP j78:q :W7-Þ]ό, N=N)`u%$;fo,:LғRZ޻}nM7V} C(x_P4_ TM|__|kSaZZ-vJvXZV-:9e)I 7z^BjĬrU.c DoK֟o-caA Ï$3 RĘI|ͤ ܹ.~Nk˴TN^m_ TM<BU_|luGE7ýJz$>M7OHt5" -XC!oP kKŸ <1m/t 6/=RǘNTH5~ʾЯ-5[)im:jy6Zbew+]fI${MR Ck)jyÿ&^>o&_2{>)eŒ)'`+{P kO۫m3x3P<o֖(YEYgo;k9ȬwHuRר[nԼi%׆W;EL4 |1Xiqiz(#O70]ݰVo5v Ӥ꾊NI%WS\WYGZdOHx/ &R C*x/tX{]Eou-{? mZI".'ZjH!Yi;`6?߈^5Z2y[|9%2Y*fH"k;,ʋ4:.i)?T{HWol>!5+A7 =K%(p^* +3”׽͢\7&/n-˻ܬ} C(x_P4_ TM|gcվxkZ׆R.<6SGW]Bt6pI,[ڐDXF4|o#'%mMu JzOyyMy%ƱϤ"Z\y9`7ÄoIg̊(oO5,p/5YghJiO<BUZ^Y i{xoA)| ͗5MJUͶi-y)6+n. g@Es/moVV?B7Qoj}&7N]cNZ6sgek12$aO)tH7-w6w<BUG)СA׏W-xkĞ'=Ro 0hzdtE"MwXmr񏑘|߇^e3>@52Z#ŨnImfd-HM,!淪Mw_t9Ky4vNܟ<BUG)СA¿]|_?CP'sTF_eKidfϳ$v >| g!~ontw ~YnΕ=AXE%D_)`EJr_>ok8Ihu_$b]W)СA C(x_P5Oٿx?o~=hz~ah̷4;˨p/6}VdTv[?@Mݧѵ;_cUuojX)s][_f^Yj6sj)Zxnپү6-#Hۀg˾ӥQS_ǁwm,xZԣQ枽W_8-C?> .5/m O4#Eg`p z[B{BP& d5mG6a$g-rƌ\$4f8G@lpfџ|fԵιڣZr3Bܯ̖W?QE80|B? 뿵oh~xR˞ƽ43/YĆW[oٲf+(#3t-ܣMZg,~"mox N B? ,%rN 3t-wت@2ԳΗps@_~o xB{Boۋ)/#? +fK:g, ,pFttY\?g/ ?n_|A{B?o|AUG[j,i~͑oStYX\?/ ߶?G px C 'W=m64J 17Ze_4ZR~~khlJ2^gN":!D\O,2ԱҤ_. şQrƛJU"Ocx.?k?П/$"S >H0JiܥZ՜3#`ܥU gտQ_LdX|C# { !~lC3;ʏwy7'tYQL7pog  M ]OtWxS|>!~lC3;ʏwy7'tYR~?G_~WxS|>!@k_?@oN" 3T}W ?G_~WxS|>!@k_?@oN" 3T}W ?G_~WxS|>!'5?!D;<?g,I?qr*T G_~XxS|>!>_@_ ~-gwLFp?]?eG0#?Kᬼ%>?׿kO ϗ uCg :ig|fsMT G_~ZxK| ֞/?@_Gƕ 7t_o'4YL7p,=8k_k_ϟ uC?{'=/7o,?s 7t}S ?/<8kk_ϟ uC#ru_39Κ?ޛ:>_~[xDB~~=, uCAioMM=ܹΏag m aOtXxS|>!~i H:Gcr:?9wLT(a  {᫼)>׿57<NC3;ʏa#?I᫼)>׿j χ? 5C͟wy7'tYQ?*_U{<Hk߈o|a wH7qg|F$lDN; ~h?3<7?wLFp#H?]?gT_g0qԾ~:A_oC5_:? gG0̟>8k_j_? K7!g|fwM@N_5_~R?y j_? `g#1wM@NL7p_~ڟêx܁A!ɛ %|fsMVo/_ar:> ?J<IO_,ꖗ/ ռ8'qX12@kU3@xk྿g%zo,77zo,~?? ?Q?<:A8?_' =M/GOwQr֛:>Ig? YOACQr֛:idGZo,~??Mg? ӇO:? xk?Mi__-ԷL7p$5g5Hw?R[^ws_n/䒤>2gܻΟ?*>#?DAx_Z 16}x6xDi@lG'koC5?*?!?eG0$5go5?痎h ~iC3;ʐß:7'tYQL7pog  ] I7!?wg4Z`j?gv5g2~edlv>I*@ckO~v*_ȫ}<>2-ҩ`o>??3W?5oq'ZI Ui@lG'k  ~H{G_%ZS{>G_%ZQ<sy@^xh's__}2/ҏ}>iB?og   Ox l/{?oE5*[O{e_M;y=Ͽo%ZQ<s#?Z?᰼  Ox &|f_M}3/ҏ ?Y᰼  Ox &|f_M}3/ҏ_~D:<82.طw|@ge$K"RH,p 7MwvlY`>ר.7Qglߟ}3/ҏ~>iG? >vd⷇u1[m8 W2]C E4~|Nx{ƁxC{;zK+{QCa6#[Ao4d=%i x1?]XKU_eؘIAԕ{NUnit-2.6.0.12051/doc/img/generalSettings.jpg0000664000175000017500000020421311713252032020336 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?`'5>1u{-/OKip^4fWyC+U"o™#5TTDZZy7f#$7l_Yů_|Yx\}mK/h67mۋc72Eh#WJTYhݺ+kvHYszJ+vinkاfs_':"&>HO7:"W a=>0$¢+S} +'ûbAIS?MDjw[O EmmiRM 2cssFre$q\ldluSM8//v'g'/!~|o%jiE'tCkZY\Jq GWyX/e?)?  +DZ?X|+^?O|y-YLr5^]9RsQ?ʾy7~C/_$|+Sk>? c>w-h=8<3)T}<fχ;OWΆr: >|Mu{rO5;9G5N!O̫ 12m|iCdj͑I/wl|vkg[Y_?Nt/D6KgA<Ҥrx;+G4/ ؙ|Y_ ΅Ȕ{+,_\s>342nƚ0ʾa.''geEkwuoo v]Y_=?;Ih432gS''qaMYՓ}+ìm`3!SF?{~_ 8+>q[QGx.*^k(çW{k] ÛN{kx 9-r]/E#Y3?? _2þtkZx.8~|'MCHtUgӦlk'a}q>eo_ ?ι=3GSu#O̊k/-'ٟ/8 ſ7SVL|;Uk> , Xm&A*ȾC\RӸ?cB KL_l|;U/ko?ῑ}ȇYOxJZQ<cB& !V\w>b+ig}?<'KG8h GqWP|㚻g?Ka~Tx3o̔0k  i9{h2!T i:\ 62+apޚO:&Oz1xwUѴC>5TÿZͬvnsU"|jܿȉ癜]"}4{߃l;U=ρt ~eB}QHHɫڞÌrʅ;{5#ҧc>g/8tdbyL;TѴ^ !V̻rZl\pT7kGS3$O+\2!U_i*{l SҺj9YWЊtƣg7qmܝ~ TÿQ D? ^*/i R+=В2D)\wCh{k# /J,WvcB7W AzSç/K>d6"ܐ~ ?wqi=^cBvMҞyv6wkq3KLEO_koH-6>*"uIoNw-wz<:ڜ~tQ3[D9kR~ dVWX?h&5*O >C܊X? _Q^qSOXO_OO^V3I("?ׅ͋tVaiG30xA.1T`xȾl0"]kCP(ku_\5?}j7P4}o?R?p*7u -*?e?99MP7 omD]u7Y#7s{~v 0[E-Spu$ܚ6¿koJOko=EMKUnMyI`do*lx+{\^|!j67>$y-!.$:RUpkUƺƛS\ioJ -&ypqٙC6]^7._5ڼWW35*gLwK#+899icq98a)V~ǭK K5)-~ X#o+¬fTkb"@XXFc:qr?_;m0tX3_W>"u?_繭L6&tލGp/ a&䯲F}?Ύד|*"/+BcRKnFyQfUM7u'|6/k1];bW+u%lM);.ߎOo;{R(m]aIDDYcݑA$Fb“~LG_x7Ou-2]?_O\Y$Oy6?_'?_ڤTgPMY^:aj"ſ/&J\CY_ i%OT_-סbZ|?&h-O i5摝CpUVIɑZ&yb>W/^ $> o;SCk[Vcm#c$bde_S>x}ZC-nkÇu&_򑟏R9?K>&ަS)&kvṾnJRVYY-KErn4=?Ol7Xxsw-11NAWS.pwxOCtfY}rτw0?SNyx'g'Oÿ/p_χuUyK3lPA5x<kS 9@.ſCt-A> {xwTla'J?_i'dVU5N߉0.'20~Cw407dnD潶?'9?>!˚?>!\K] s6MaHr??|C=ˊ_`<{04>{:jzW<.o'[ψno'?Cw4la4>}Y!d_j*+s½.jӂc?./BRg W7>fk G 蒾3\LJr/.YVq@?2K.zҥ{d'ÿ%'ıÿ'K3ێUךB|@O%oĵ]SFq@?=E5rU >|wU".>$?p pVr_:CxX5"0$3??uR'@??uYWgKl4>uYyXJ_ƾ_&gp0|o?Bxw4ka /ϝb՝rjG 5J4"_|A?sNMod?sGD59?j9=M> @=˚_vNxw4;9Y~|i˨t&l|C\?Axw4m{CKl,>rg#X[3uXp#XpvnoK3Ŗ3r߰9澂 ];/sSL//Ql՘F^O ?枿'i3.ik78i~xbjlyHk w.iu?_|/EK3ã1ך=aM{b=~|C;˚?ao!ÿ|/E.K3ŢXw5ju Cs >=?b_?=;ˊaGu0?k}}o@ɯOOاNj4'\T~:Q/߇qRa 9ˊ4?P˭ }ǝjHx K[y`ME,gj8tmmK;By m,y#$ץ4N맇?qNh1 G.+/'~}|a2ք\#Ef<7SxX/}Hto ?}^f`ů<9ˊOfgIwğ\VoC~~'o3_Q!xqs':|tc[v&]$`&{OQ[0Lj<2Or?7?I!sZ9ß&[VT{Ϩq7a)F1I%ov À|0?A\OH/H7WyoT?0ku? >%s#4_.*d`͑.3I|U$G C=Kw&sw< G EiƋ"v ۝?{k珉"ӥ@@jڮhM4I-ͤ)6O +Au e"69~8/}Xc_C^=࿋a]𧅭5?߈m?HqnTY5>cAִV𞉤jKioMCͣhxݳpPpAݤx:_|4u),|E/v"ԯt.R'Oqd L^wß|J<)|K+ jo[q[D*nd=Ơ~i-_HxC5 x.zt8\E 5+Uia_0 7O4G'~xh}]іwKi!4*Z ;8$ ;stm~A^]ڮ#:&KKE$Ȯ0ѡUeMR+'ǭt6g?#Lb,Z<><28% yVQ~}?@t=Ե+k61bHPMаϾ~~|>Qv#ּO5'4MAÔNko]jЇO,$]DQ$I?^{;[khxFM*+ޑ$7dfFmтc>55toJO<%/5ο-QL{rKi%幑${pH_ϸ|DRSV>?\k^K&-3I!H$ػj.5Ĩ UP} ;8F/ }ڋmkvK'fϪmGA'T|0?(-?t KޓYE)4I Pq =k*~*yҔWw)ceJd&EWQEQEQEy&ioĽcHf>-ؗ գ@Q@+l;7ևe> Ǎv>#5] R).W<2%(yoin=#4- A MmQKXP2fuZmĩ墁_Og>~5 nmm|EjJT::$n*?d^=ѴM7]eZ3s%k;tmKnXf@ `6:ٯ-+;Xk\UFQSw_vk +tU&+?FO? n:|C:nv7vm/JQ-lüj⇏cx_[Ƕ~643FnM$i2^G2I>\ņpq_s)|.񧆼I/o/EaQ=hot+hഘǾ3mHʪ8&oO?4ǥ·6&}YIkyy-ܰ]̰yJID$d:4yMM/6עjRiBJ)e}l{Im5-T{k~KhtTNIv蹺)*0KHNJOhJm;KGխ|~"uy/K(#C0 uW>"Kg,x1xvbU2XoN*?wX_jzWZ^G۵{۩ig#-x4EPZ]ܛnW|F˵Qޗu)QEQE[Yݍ8.aqjny]aoͳv3g՚(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢34kj5ߊ;=ȦhRH\ݰV# iEQE|'?pQ)x(!ӝH*Z|HlK?QC;&߲B%O_VK1?*Ãguc=K ^VwQ&iĽHa?>ؗ 5})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-ma Λy M+5‡c$CJ%#e }h?"Ǟ-g|9t?]ͭ\KyU G*$I㱎x$o.l/;}A0RJew>ðYeΫfXT3ʻ̙p~%I jORkEPsQMK⍵^/L FY)b)IiSh?z^M7%q^MYͯ_oj-kyr6b\}FPrrΧC]?Ov-!{p7[Hܤu៍Z喠>]?La·pBݛ!JM@P889->0\˜u8gSڋ]M5#%cb ƌ,T39qTw|J>fe;F"|F§@축ණ.gkcc7ufhe6Q mRR5b$ G]޻i=Vo-ؗ գ@Q@Q@W7n< 'O~8'7~Ѵo w6V ksjPjWF [?&P$0/ [h~#NXQIn7 JB (1޾J˯x*|uЭ<97M4/ |D>]a}}h^,b>vggmڌhڂfy|f+evTh-2m(Nj1W?Tn~=>া.]ŧbwu3,LnR8^T@ F\~?lo&X<Ǻ֯_xlll9敮!b{|beQӛIܛo$"O|i%MQWΚw"Ohh,>(mnmlV[BYD],> *#-f-$j~Dg{;G"\Nҫs.Dm('-I4یԚQwm%4һM/h_X1Z|UxozDΥsu6Iq} W3Kp!L>X|/񥯂xRzn6d =HǨ'3:(IA-t_i&ѫis_O]ij_^Q^!o_k|#t/]mMV)tfkqp=wM[#`ZGRV,Kx_sڕƣZ}?j"+ca D pȰ;l@ryFKi+5:PM>N'ׂ~"E𮷡[mZ흶V hKKN{o"`N¢n~%#[Uot̡ sqG"!7p2%Cjg' mmh+^hυ _J/LaK~(F~q6ݷsƏxs^񝦅z{ }~ 9;o,8) 3V)r)E-MFBRo5+kmj}=Exw¿~#xDoA='g\o4 ;#ʡb’^Iq>jzu|7c \%OΘ"갭g7{u{z 2]Oޏcsxݼ=h-¦3oGWIQo5)Nێ@C׏*?:֋yѷ=nn|#Og do>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[`I Ǟ?>$x޹:-Gn巳X]ByAg134L:ŏUukgM#d䍴s-ͫDBB" $K|rG|_Mf{m#ƚ-}5\ : e`2⸏/.Rס^X YI4/wFnb̂H1ޯ읺N϶'s_m7<_pgKg\:"qMlA4utҥQձ 1hM̱1B\|I?54?߅|EZOuE$0Ny>zdT1iz/\ׄxZLڼiOb-Mվh -āLv?e{4χ^4c'5[د'!"I2@x/IiJdӚ][^OK3=o-O+gVp{ƚm3K Kd~u=ړ"H"1 p=xoo_ka&rY}y P#[]JYX%|N/Cxǟ|KMm:O%{ kho!k$Jcvria_x{]]?ZvEH 88".Ťc ϗOI{kkIョޔ.UעvIGZr]=5K?~xk~V3LaC&!«I7, P"xo#i^-7~'ZYq b-Gv%ޭm`]*|!^[xjVK=&u-~a- Fj4wwPKG9Hª?.3w3sh]UZ?7ݫeovkN7=?NR\x-oGӥ&/4Y{te Cqu,j U1x {6mxMރvv:'tt|߳lY\2'1 ̧)eo_[$6kz-5zǟߴg4]'&[hZŦnmeX䁎b|XH\ $xG G5*muI^k7H[y9XJ, ]-&}nWؚZy[7$| 4|W}5#DОQnHȵ<3%4ߺF!x+|A4 +š/e$*@RME2ͬ9#*Y[J.jOGʹ\VMk4mXz7wú-?YNuKKKKi,̱:m;8e}+G)^5G:w{GeWj)l|mcZ疮w*.ϲ$A6E,^c}EMHz~j-7RRI'tA(YZ4mvxg0/ÍwA\Uxf]R M4`IQrW g[/Zf %Kp"?=/mkND`+GRN\}?$twM% -mѶ՛gi%GԼ_]g[O@%ƛ]\Y[LֿoDx6"!0-:Wڿ.q7NF>"ŃiˤxY9K7@M̪E[)E-_$]-ޝ[{|,<9Xm;Q6׺viݤEaEJ%6.3NFNwM{Gǿ6>skZׇ.BUӵ}%m^Meh؂İ0V6I$4{tvFZϾvxs6xVմG5Y5n.+mi K"#AF'މ|M/|C4 b/CHlԒڛͩˣ3p>%v: w~BfOY"=ӷWiRO'šq_>5ꗲj7,͠xZM9ӥ< XL WQJqRN2WOGWZ=jKuw_~+پtoxM@i[l ̒p7'>D,<4O5𞷢xŖY5֬rAǬ^Gp04 q2TT--n_$lJwR[W_>w\K䱟OKX"xđG2;XrE-"[}mVTm (Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@;mW}<_4Zq)J/q_6 SNj_R#7q^C/?zA$o6_j >xu?FckC'+Ng~f ?KѬأL'z?\u? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XCsF=“Jzt1p*FҪa2,|ewk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqN-VV5,B!v I>d/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{̞4-]2M2 \,7!۴yZπZ-ȹ~|=i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5ﭴhNs0<24l+8#>0:/QL?ڝޓom-ĺt2I$6o,;'E̘h >ƷKdխ.r?:ޥ5d{)?moL? 4|F-Y.xq\xIXm?P, DYيcW&AQgOmKw>+tʳh^i>Ʃk4vsK4Hr$C{Ϗ>ioQ}o>mo-ۈZ8$E2.kћ WQh,O gF]3N2[ȖKrnd[C3>&cE7Mg^3u o^[T8l!g}6q5tx8l/J_|^%(vZlGAc,[is^Cyq SIjRC$4pNkT6~F{uV6kѥZ :xWԭ|!ݳZiMhv^fd~t$((((/_LzZ5kɚ|[/XF ( ( (?g5O~!\կFѓX嵽̖(ͫei vw`;TVw )m>M:YbmGW&p22*)*%0z߶7ҳgØ B-;TуA#MuH:/<o:d0jq=3ZJL#U_g~gƟZ.^:Ƶqk2xwTMh,\Ko$+N_x$\&\?xEݮo*m_[$Ӛ7*1撶3߮vpUX>qvK?-Kw-ݴr%(˳ӿm [Quơa;}J=^FX S,`3rѫ( f麽,JzmuO_-%?f_85w]=} d|So|Mxsr^KEe $|ƭ HF@#8>cו OxeׇmƋwwt// {[ԼNdQ j&%ݥXDhöM˕z'%ʞ^wNi&ޖ๟GktzE|>~^3ޭŚK &ue_G2,`4';;1<7F'=b\dԤtԠ%uX׺Ḛ^8Y?d >Z[r-R:wSQ0٭m-q'rHUXJt{_^[}M=W__}ևQE ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (<3P>+O ?)Ko⿥~-N_%}eXVz#ˣi0أL'z?Z5ɚ|$/Gk:7oԟhNcT|mݻfݾU">7oԟhNcT|mݻfݾU">9/x!o#TaI{:FPd#SyiUDwl2CR?Wỏ^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'I++!x$`2ic?Lju_ |]}N2 YaZ}* P^V$I'^(䢡NJ~]-{)t1yx#G3x{-&=N[{9%+,|)OU q +?EXomwQyi#tV6W8AM> G4[ k'D 6ueRdpb?(MxNI@_·]:$keh fkImpLJB<4޾vΉJ z}9x+y #_ <{_(4_iƾSxUgcwia%"/#$k%ʱE"W%׿>.;?Wjtu^_}asv2۳ټ"(B3DUh_b6|t (_¿xJlP|:]^Z>m=9CwƙuTp?ao?/[x—.Em9" =F{h_"0ԙc3yߋ|#y_)WOZ:\x'yff|6$j<NAikje#I7s- 3@&W_8(2 [궿KJ%zۗgG\諸̠((̿m3O%C5hw&ioĽcHf((*t ;j ZfZMFɽ[-*U$߁Ic$I'޼~ Qյ[C+su9麌Z\:Zf]՟{FxGU[xe#snI vy#3 I| #oƹ?MHt] Jx"S-%DueѴRZ'{}v=wn]]<߀ڷ4}{zMu_&g|j^ʈ杶+#)U  #|_GuCv~-}k.\鍦HYZ[6g@qn2r[gtKNL~&?F 8\ B>tTჟE<}~Z-Ú~#MſmmB;k絇D/,59m[oO1Q[ے[sjӲ(b/5vxoسD._I}C;&ؗ 5})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-ma Λy M+5‡c$CJ%#e }xOUqye?|5x{PKXk/ST0|ZP)tc˹\Rޡx~D}ޭv9}CCal,G|hƪe;km7RWh> io ڴYREj~j8l"H$kQro{_^_]y9m] ekK+OMK_Gwվ#G '!L,M"ks<:8Ia]P=Ͽ*Ɵ--<+>ƞ Oo"OʶEUٸygSfsŗZOmZxk+msoe \%D.x2(#l]tWKuݫ3oW? W?5i~ӯt xK.ng}?\zXae,$I@xA;]R[[n\ZlWu{#K)z<϶F{hG4n+kH/ xf_0xWִ񥾧])sonvƱYH[ѳ49q_uh ?F,gӵ]oD]6-7ĺ1o],VI*\";i v Vzg?;_˟1 {=ZWW#i8#kyR;JXc;s0nټF*|Y Coi3^~mtk9n^HmX*ʠ$pJkJܜ=;9W6EVEQ@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP|$,>$|_70(Jp?%(\E?r⿡q_/sR'?q^ӄ(lf#kr5{ݟ_ cU1_ X+~47_|a^=࿋a]𧅭5?߈m?HqnTY5>cAִV𞉤jKioMCͣhxݳpPpA8#5l~#F'⧅.a7 .jK<'UX"-c(TB6`8~||] h:\i+J!q#_Kr>DWg~)x %{x7^-4=7C03JAGWBâ>%,I⟇:t^ Z-_Dten/Hg l 迫A~k@_P|l."z6/HΧm" I,r+4hUYSnT q3? Y4C<} $m+x ^U__O-?f]#Oe-cxJc G%Fzt,3'߀,5|]ꫧgO,iQBF Džw>D6 TF򓼕wkWr6|dt$K ,|a{e}sqy: UbԜ/snOv$j1/||Q;u=2}k}B[f2)RXB! >Uχߌ4m-/–VZ [1 })OVeޅ#J+jirY=>+Nu~־lݭVOb?#ֿj#>o xWJ𾗭^pCpgXɽ͍ aFEYgHN'uj<1IJG fPt:-M@w|ɧaK@)=3xX𷉼Y2ZGn]GGavqy3Cel7a__OoxǗ|Rg?F - mSu2&,[ XFCN'XI.4Z~M&mROǖ{/?਺'ľ(o_x)u= ĺ{ڮudӖ9bk82 JW/~ o xĚx6iCDXIm"[orh*,MtwP_ӤeivPj,j?,5;-J7oKic":w{Fdyˬl W |5o[~+v7W췥2kD`]}ܽsuߖĦMm{_[ۿ wo^O ]^___x:-Q%U.Ԯy'OK󨤊\*Ť0;CE5xc_utiʬex@u 0G &gxwĶ-ч:g=^+;D0jM²Yk2A.+9,.ZS]4AJ3ܯh-T B͍7<_Ꮗ΍/x^$:q5Aob=LVVl1*;U1~gO|W>(l?f5}+j,Ψ$p6>QP|5>t<7,tu+}AH2\FF%x@fBT+:Jɩ_4~eQIտM}6|hsG>oD-ox]ܕ0)%~>u-Zx3[7&uN0#P'|f7^񅯈t[MtâvL[|hX ?63li|?\XXizuoolE4#*Gwb2NI&jnWZK4.^З1qkv~sC}7P|?|o~]:VqpOyi8Hkw1* ]W_' [_þ fbjw~=]:XOx)gӴ~MդjN_߀o-hsh}lַ+rSkw &obZ|-|$esWÖRZ?#gm31%Ve[{MYY|5Up]:P$եg+ݵmzUSC=Eb쯸QEQE[Yݍ8.aqjny]aoͳv3g՚(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢34kj5ߊ;=ȦhRH\ݰV# iEQE|}<D+H؟ak esZ)30qOQݠV*Ώ'vd:QX^6v1g~f ?KѬأL'z?^iGSi۬jGύ۷z۷ʷGW7i۬jGύ۷z۷ʷGP%{ⶀڝ7:mj,)4wC j~! * ͗_j_g?7q+8~|g{pc>jn5K/mn}o{vy6Ǜ %`cR"bdM0?~ |GxWOw5k)ΪĖV7K+f8UI_kSxK_|C ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~HlBlxឭ֞ Aw6su,:OT$ Ē $k؅|T)TOv륵}%}kO}e/ơsG%g NZO <+HT\\("HG p*(nf(}蝔n ]k(jI;#t?+;[a񎯨xl4/ iczŎqH.QrٽlAtOV'm_7J7V֓~QO磷FrC  4mCwڗ |Ku_9x*/sc_cۨۻß:^?|<<+Ut_ŧZk6 Y\ txI d{WW S; =?þӵOƱ7nQe͝.ynXB4I̹m too3G.|Q#EDe+5=";kԸ%[3PC-rx#֬4dFWI?QtO_"n|+ ?񖟬kZhy&lIP $M}!T|CͿJQ@W1&O)}WMk:NhDž^PІK%(xR dͩ3r )#{xO!׵O(Tt4NO000z{8]\,TwW:%/wvG%_ۛj Nl<%|:^lX7hX.`D +5d$G(Q:g?A|ëjZlM:jڵ휟ihKt @i$NmdKMK}r7M'w^[Q_7_^;E?7-cǿ%lX,n4#T9 i]G$1>5|-o_s7.mV 7ZPDlIul1A]X(*ZRO]TT]ך;/#)E-c{4~Z4uO)?xHu+D2v—ZVDvzki#lunY#2h=SBo?Yx=/NT4+ۭ(XdG92FHD*٦JmI߻uve rQpK;CߒZ}oEd|?_MRcKJ V0B+<D+Gω6'tZx?ࣿϏ?Q/7??j6>X+~WGC>Eؗ 5du? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XCsF=“Jzt1p*FҪa2,|ewk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqN-VV5,B!v I>d/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{̞4-]2M2 \,7!۴yZπZ-ȹ~|=i:dzkW7RìUB@ʠI O&QEBDm[W|3mwQo/i>>j^",|=Y+MKd&6yUeʳD 1oxiߋS@/.<2zy{,&G ĒAp16W?Lx >(GWڠbl#5{&@PIFdL:V; x?śxZw&tR|jL1MrZr $5#"Hŧu+KfKN_ܛZF/ڥ.iI;w$ ?7?>XymmIlm-fi-`,= k|C4G> M6-8]^K^Z7֛mhJ֒CܒA2' 9m#W_w^>k ]wQCoL%/ɩGw3;nլ^-MZ}S8nng5IH$cA%́R$$ppQvo⏯.WݾFPۦ;_᲏V䓲IXww-ݝO=Im$l|ei}S尰66 E_ktS'P(toZշozv8|Gl5-u5;ɶ1RĮoßO^'D_|4Z;ɪjz|nf{t;u)Bqishwk7N&w航wϣ['1|E>ֵKq(]][% qjX/dž෿f߄yEx\Mf]K@.ͨwVVO%,Zmb5?fEߍcBo(!WAl]i4˷qpq! veG .5LJ vlu@X4h[ LAs8.y9?.i5fi7-+w{˕F w??}O[Ya5 ;F!s+Z섐_/o^[o [@K_;QTZѮ,V®CIk gHi6}W_gΥu+ƒH[ۤW ZW5%W? ZNrެ"dGwT|CͿJX,_M:) U 4t!0TjJEP^%_QԼ;jё́Rgԗe$I$ve$=Ow 7xZF.ec~Wy$9#*;( I$﨧w禾/˷Y_tW-> ]-g4z%k3DcO9b"-+ƿMoA.^Yn4eWfvRIFgً. &;Z6 ^V1~x~6MkrK.dQ5s+K]<`Kῇ}EkB-ZSc{ȣHfۖ#4Y̫@PK~eoDKwYt%u(uI<=ilڅ2c̞9Iuİ N)q?f_˪j~췒d̍LAi'QI?}˲YCmop[۠(P0RQESm%edQE ( ( ( ( ( ( ( ( ( ( ( ( ( (>\Gω6'tZx?ࣟϏ?Q<5sZ)3\o&~|.v_CEwBcU-YS;OPأL'z?Z5ɚ|$/Gk>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdY Kg_>y^oټol} gMƩ{_Эѷxைu=֝k QX^;+ʰF谄#x e"?=ey>3?<O瀵Y}= tX[+&YARYwRT/'n⯋ߎ|??xkˍ#hm,-m;Xey$lRD:mo%&+׳Wm}6.[k_^WM%}=,3M{}o@_gSRm6MdiPX_jV6wv%YSmhRHϘ+Gk|+9x_C-/7NY힫w$s6:\#F);>nx!=Ow/އ.nkIN , lu >]ļY2s~/!Yn|_jӭ4>}Rm=KZjvȶypj&7b$2mWS{忔_7'oDqy\;;Iko <W^/ͽiwhxTkK&# vwLE.\Eq#xEY4rɈZ\*]\3$iV N.@5 '@5] AwE{ -<]4F6- $,7|cln& u,֒fI.nE"1pYOtַM/qh݈^EsDFsȲuΛ޽kn[yyA)G߷{t"_*>czGpCg\\I%-Bh;WIp c/4 ;IѼQ/,f9 Yc,;Xdv5a'x_--u]gXߵV5Η&F$B\Jt6~h>ku'-܇~km-N-QPQ_ſ!k;4b^3VQEQEQ\.PQEfxkƺ7v}3VD9;vq}+N ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>BO''4J|ࣳ~<E+!wW1ے6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv鷑Oxҽޝ @#\(v2J<4XL;6_|!}+#;7 om}8Gh hl`rAM? |GxWOw5k)ΪĖV7K+f8UI_kSxK_|C ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{YDfosus%-$bnyXUҥGUZ5}:fۻCߴ,_s~<}|0ԼEX{OF5V$StM9hm˕f8??J]4)uxƞ5S+wFq[ 43ukvU--7}߄6^4^_jDZHYbB$q0\KX)_?^X|E?>t~'41,KyNlEŌDi.Hє4HeXk{I*2O'|Ac/>#KoO @KE%[Jey%򧻖s"D+mhkmJ6+~ɿGh{Nx/4m~4?ťr~m{ E$ѡlƙ%dg_D(ˋK[Xq }RrO\omoߥڹl׾EVeQ@Q@ekɚ|[/XFm3O%C5hEPEP_>#|c߳uďG5OZxZE [< ;[Gq K83# xU{ %OӞkoOi^.n{"wtoq" #={|1G-,x{~ψ[Zl7hv6,mfs^3jxSĺtxEҮ4;^*4޵ٖi`UQn$fVJJ*W+tI62݀|ט|jY5|Gei=:|OxoP6t%7n jfm/VZGogg:K> ߇<yx]؋Jٮmxn.\F@~ʬ&df/,ω/?toȴn/ #IaKAXB&LO?cukk{[K]VL.`NI* ,o[o'K뚓V[ 2WѭNfr$7s,sw{?E}fGx/Ck?{Ŀ!q5N凄G.k 'k{V(Tid<)_b>.|Ow;xGZд xS?NzItأmEa'h+UN߄aOLͨ-5G][)l\Oq{<f%Vx\U<ֹ-x3~M1mE' Sk2Mn~x 0 qhP~;|ҷg{{Ԅ^u%}m6|88yT>..[]z;6jE 8'ljxZ +χzM ܚl ^ϲm7u=_TVI]{ؿᮧ??WVXiYd+W &1#cl|g>k+.wP^ ck=$_gfFprXnk|Q|S0xQ}Eu6:6-/mz4!KyhdIieh Q[:JtӭE}k 4/R¬q$ !!#L*~52Y~٫K<l<.[/'|G)_2mWƏ65Ə]SHۨ\9s=В| ~i[mU-IYӵ߈PFÿ-KP ςZg-%U2WPG3}q䵹dM>6xڋ\h| ФW0x{S21ikmz]ۂ7wsȥw?i|9}-ƛi7:mNgn٤ˉ'i6f(XN2ygDZi:R_[__HKsm%zkNlcxYѧH$,K82t/,{>~ KIƩQ˥^]3!z3~ پ$WdiuYG-[bt*ʋ$(Qğ+/ E[x"5oNƷtKi&AqkjH"2}<Կg]/T^$> 'ӡ_ɨX=[R*afFNOxwHӤѼC]Y7ktQ1]-s4qiQbcө7hIvN0IyYjV.ݳ)7қzy-wVw| &~Ş#|=?KӠ86Ga2;m.o*f=d_U;ϲxYы<1ZSКt;8m8t2c,lr#JoMBI5}_RIp<ֶbYgmv~A0x;vi?$.yxPu+T(\YGlMT)f'>S|=}ejn5_YAy`.gHҏ6)GY]SSP^7?̭۫&f6{Qwŏ(/u ~)D֣ᧉ~?q+--byTO' r">AYM6jk4v?ea !M/ h惬ͦ:Ojl^H.D4Jtҿ>j꯿fOJžnGLmlI$uMJXVE[ģ vo*R[ Fɻ+݅k*|אQE%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@8_UcbES 9) esJL:-:QHgǟ( ӝzOџ`?k&~|.?V*Ο }WgmOxK¼{_ŦO Zj~ӡ5۴~eoۛ$*w*)f=+k|3> _i&=HՠPQv-FѤ7ݻf $^iG-kG<;OO ɬ\91rn%]?TԖyNvDZP"mXqJ/dχ%ju]>%߆5E-JӭV72BPGB4}舯^XksIZ^'WO WTYҢ:h 0|I՞mF'y+&eek֯m#|_+%xw_j}m}".]i0C9/7>i__t5=! I?_XfLNXRfAL!GoxW0>5T?$[.Hxñ!O|Ȭ~&|F׊/|gjDγg%ܭ݄d<ykVѤa"X5EZ[A>ISm'w}[]&Ms?zWG6Kn/|_/Sjqͥ3z7zE76BM.C +̿cڲ+Y[]KBKIǀ/xZ>VcY&#yOz7E> ^ $|B]ާџOcvM21Tz6H>Ywضu3=GŝGd7֗V>;hIi[A{V[Ǧ.`٨Ift_)Fml=];l5KYjLs 'S{kֺjMNN2&$M9o/$eTEu>_xK qU:Nw{mAu-.X̖蒤 CS ?~ ĺ=֜nbSյ ]"l$r"Po%գix:Eޭ;‚4-5BCzӛK%&_(.#eEm+zvM y-Y੶zT)|ŧAv7O_AvdMH٥av}ȏ+eKzWZd^>/hVؤ%bшDO Cp8χNž5|Sx[Gp׈.liYȶ1Ǩ]+KI$wf5XxR4+hZaʹDDq01T˹gm_"u-ח%.oohomVӮ[vQEdXQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢*lO0G?!xNwU?F~y7QGQߡV*Ώ uWgmO8K³b3O%C hwQ&iĽHa43S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N65IWӡkIR5?gTK Gqf/5/~_yzyfmmۏ157tA׍ycH SI?_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?='|'qeeo{& @YCthh~+_":wށQ}gzߙd!ӯtu };6ݥ%g{%<4]3;'Hi<#i6V{GgOvK UxḊ"#ȍK15 q'➻x%Vyr *P8P((̿m3O%C5hw&ioĽcHf((+do:=׺5u >eXV]72X/$ z7{ǿ~&$ uyw{}v [xHʂ=B9F%:EU{m1ۯWŚV2Xxc_4<5y}bN=[[o ifbx2CK??\kZ< &O5?xmMCiӬu뵒SS$1V}ݮv硗:/~{/?|9a<)u xD{%~ߨ%I S,p݅R%3w|7tğ>I/tP mWQio'XlXdy #« [tKh_4me&O-/o3W$'UGo?ӛߋ|q_Z:7dw?OCs44(}y|drGw"|b_/[\)ѵ +]q=v.eBmJb!5ͯMz6O7οyGӔWz|?&mĿ$ Tk+_o-/:.>!˟ ]Yv=lF6KUeXcsbQ ;.XrwشWŶW>g 5櫫i'ZIu&GP|8>8|OßoO~Q]i4 m;YM>M4&uI})1jO[&vKkVz\_4-O@|IBbX\; 1(esym`sc~_sxB}W扮?To`lE{)P./eӭa0%7[;-1o=?$j:.E|!^j!y}7Z|1]K#­iq\hS!ϓ0}C[T(;K_8ůםVEx}*KOgEVfEPEPEPEPEPEPEPEPEPEPEPEPEPEPU~'؟akC><D++;_ΧsR'?q^oRg{lw3wBcU/_ kBcU/YfS=&30_qiS֚uMov6Y[vk ,] YJ ?}ZnxOD5h%4mݡfѴi< nك 8(8 ך}|t?EOxSk0o \tO5%kݬ*HjV0Ri>>|.sZ4W@O|EwQmKvҮ4hM̐Я%z"+(x~?xJZv_,&n™d'Bݳ`FI(G54G'~xh}]іwKi!4*Z ;8$ ;stm~A^]ڮ#:&KKE$Ȯ0ѡUeMR+'ǭt6g?#Lb,Z<><28% yVQ~}?@t=Ե+k61bHPMаϾ~~|>Qv#ּO5à~U/8#vQH YcRU;FG)}ue^!mnvQZԳ,y2o(U~ox>UD5MݻInL>RAln#c¿ u'|sź^.\zEɴi!Yn1r+iIۣr׻vVRn+FJ4۷y7G/w O~ "++mYMf*!2yӍSqOV| R"NsF-llUKH5 d-7clQA~|;!M^JtkOXO_k:|nPIgy$z̭ ob=oB׌6\I> 1t nXJj )JKꔟ{8K$mY+nݭ{&W<:M}5= ^( 6}3;@bܒcDž,w><|7 )/~+mB kRy-0K5Էi1UVfT]%X&^l->g70KeZKk-1vL$< l.|mk%қT05"قZB$>ha,U)F/V]e=VpGf-šmw~ LJeԯ xš^Xiq\%7V /$*R?7ugG/rLĺ~nj1jhHx oboٛ_ tx4'^үWH^'h`ёivRŮ~)i_> 6P5I4 e>+28^i.ڲEz9]A5Jjjskn-ߐ2?=/ 7u%8wKeuxBLو>ѕ*ևD.&O;"{G<^f~YګC&% ܈YM i~2X#T6!,6Xjn`:v\̷v{VvgzbŴ9<R=֐ w3ϤCCm+_-LrK˴T,)l=mU;ۥYW_5{m|Co/{-{¯?4-sR:-,EMmG}I%) 4jG~2@$<]oqj!vo7l$RI 7$$R$n ]-;]vC#uNw^[z%~ /I{c" ң*P܋_+m%|H+ӾxGG񽯉<+_X#Aa!N$I0]n0|姦|c9=x |%sr׳hmu;LӴnc2,W%ضrI5?ه᮵xKTykO1>A" NSuP6A]'gu=&V}}=e?x55#CyA_/|񝉕;Wjg|s[~ukkP}I 춻Vt%g~X:]M]6>{GGğ h"Ȳӯ]2]Y% [{+<?߈gw< wW7-{6hZl;L3!Br]g$쨡Zyf/N<D+*l|V EW 9) es^/G6??hؗ 5fzmQ@Ogjv鷑Oxҽޝ @#\(v2J<4XL;6_|!}+#;7 om}\N-VV5,B!v I>d/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{̞4-]2M2 \,7!۴yZ?Qe? 5Oi:W2[rI*!!V)畉%Yk؍*\y!%Q?yWӫy/mt=_W&OT&W7ZyQ+masA)'V|}]^K]r=x5>ju6TFfdpfX Bؿk_'l4_k6qhK(oZ|2G pPT|M?+#?#4TX5\Ee٤\<:JT&RuN>׵ݭ֝4w} |Pu?v5(MG4NIq:ؔV@roS+ $mvV/5bVEٹWԤo4 +H^j%!SԼ'{> jRM+YjZ6jְDgdX|mO Gs[j!1wIp:7;,`a5K/nR ׷e_Wu{]+>[^7^zk7Vپk~ YoJM5R]V &b A2LPܡ$Rᯈo |D[xrJ4 Z_y=q81y]6H+ |?٧B>&|M*kG^Ʒ8i}~XMR˼•>'ΗK~5 nk 9m9k RZ?*V•;p P捶Vt_nΜi-$i[mkUV| P!Ns4N7S\\<o1VEp; G|='S𗁾%7Pj^+tYt!+Zo]76J NG@'6Xhmψ<h!{}kEʞE-32DQ%%L3[CMcៈt/ ֚T(Q.o 7 _ LL6W>qm9ox۷^kK5'dUME4lڶӮ%]u/+Pj3j֍|5{8Ha_Cm1) O?fgc]3ǟ5 6 s-d]X[oo X9/d8jHIw[卷{ֽ{h)|r ((2>-ؗ գY߶ſ!h((((((((((((((((((((((((((((((KJ#_οsR'?q_F%[w(3Oz~w(L\^:Ebњ^^ZcU3YfS=&30أL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((u/*lO0G?!xNwꤏOM(3Oz~w(LZzhc}W~n|+y,?H,j~O³b3O%C hwQ&iĽHa43h(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>kտ|M?â|y9WMVcbEg 9) es^/G؟ 苞lZqW~d|0$~ú+Dz0ڟ30أL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((o*lO0G?!xNwjU&tZvࣟϏ?Q-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@/x]_7oR'?q_зJ?Ţx9\W[ޗβ GgWᅴ#FQ8ƿ3~J+)<‘N*2 _VwQ&iĽHa?>ؗ 5fzmQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP2X.|J 'i(~ݿHX%~VYG ?>ؗ 5^g_~34|;OΙmsƚHbFrb !@pJO>Ste=-go>}z+>O_Cޏ|fkSte=-go>}z+>O_Cޏ|fkSte=-go>}z+>O_Cޏ|fkSte=-go>}z+>O_Cޏ|fkSte=-go>}z+>O_Cޏ|f _LzZ5|g?xSRøti:MԖ Yx'd- T L+O狥kFL۩c*R@%TJߢ?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.69Ũ@~+"÷I"gUsvXJEP,RĂ((((((((((((((((((((((((((((((\V0S i?d?ƍWB?տc6OAh͓\GoV|?ZoLmΡ\yY#k@,MbUv膕6OAh͓/ѓ:Lj|'/xDtmQުvV䵭[g|sbWLxNկtO\5x}nsklS,nRWK hč$r_+jO_6o{^>߯odzlރ'5^(xZo"׵ M;GѭVF$\1Af$ UO(_{]ecba jR4f?ٲzU~1~x_Wwb:]Gͨ]@c#YV݂mV`$WoA]=w_ٲzGlރ'?Fk>,<؇ä?GruQ;GwC3άP+>((((((((((((((((((((((((((((((R5^w[>(ˬ=oKj9F'`F20[-s 'אԞ5OxSW~5< zݵgulg+:6h ,"H7n)T>,?kVi?vWu/h텠_<oAͭ[떚ny|V7r ; n/ uْWXuÿ ԷqMM\7 -EkfGe@|YY?>,?ZIuu^Kf9M%'{;߮}I[gdީ5tW@|YY?>,?I!#`ckio^#ͯZx_LV \u9}I@X)s][^;Пeo7iHGMieV#OZ*?~|M_9 Ǻ^ksm*R.PKyc`ݕ@|YY?>,?&0ďof~\I6fܦjmWyhƘYN{7~myky=Յ1,Taogj2⾜D \³I@|YYډSNm^=[v?oSF,wkS{|8&}ahM.~QPʲH( 4xu3V'O}OTV՝6qC 1][.ءXW;"i=D \³I@|YY3RK4[C)Qq~]uQ2? 6:?>,?pߴ~/|}oCGXf׭ w/}&U+TL :Ҥ(h #T'x~ F?a_9?Q7F+!ӏ<+_( ӕ{5=/GeK7;(LeՅ~Ǟn}Eֺ?i x+ÿx6t yItxYl[o"GJʌο8`ЅxAemIuF"L46ӊS~ؽ׿gy ` W}$XSŸ]sg/O*/Ӫ+UQBX?x~bdGWŸ_?xN__E~pIexW_??gOż+͏/Ƨ_W%? O-¿]+x}ljexW:??x5?'4gI[q#?췟 xS:??x5?/5-Y?K-¿]jYxtA/~YI-]ّr@uor?f$m.T:5?e_5+]/\j_E~~٧8>$k.C'o tg/:woN?em.fx/E/͏'U?=߳?2??d?mo.?  <?d?mo.xpOc̏?ҧU_tWğ -Kٿilj?eGl~\_E~Qd_k?exDO_1x}k ,2fQ诙ުv_E<15coY߁?KYoZ߁t,b!G3E "cr~Dq}G0u>-x}1;o xTg%>%mo.C[%O)E~z'f|$ao tKٷg$-o./:w.ޓ_Ǟ+ֽfՍwWx[~|_QOE~wj4"?~+ojW&?4CTxo|%E~Q_?l g쭑QO U?r-_~G+l_W北_bPſ>گYEkC/ S~_V? ̤?exC?G_?xO*/֚+> Z'¾ꤍsy#ſ?+.z*/֊+P?E%f|(z?5œ S~Q_w V0dO쳻֍|!M,/gOg@>GE*jgxo uR}{d??O9O=gWG6+_0h__Q er/~)B=|y7 bGtZHnHq&jDzsRXle-̭<@ ݱJ(Ɲ:JW6Cbq8KGwNUnit-2.6.0.12051/doc/img/treeDisplaySettings.jpg0000664000175000017500000022145611713252032021216 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?8|+Ꮗ*Xtx6ivF\fɺkgI%EWDeEUu2|,Cb]b_y|5JA//|G(|:ھ<-}ZEˍܗP/]\A$[įnS{%f~d,MzqoWEK_Kvz!_='Oh/ޭºKLu=I-<2UxQ%Ih!gyxƟx+/ džl݉uJI.fHp,uG(kץhN{馴i?`- GKPqG#=#Z;A4Cm[J ]5.丁X\Sγ 'YeWd+׭>[;h׺5 *ѭKoBY,Co48R$K9/)-MaW'))&ծ;>4~ DY-#OHG/؅=zߊnkci |Hzo;c'atGF`u"qJ4`ݹW1)_Kg]~8?> b5^ =3:5N3Z f;gU&WI}F3GGzO31_kBSKJU,?e8e?˜|1V]AqkH:?#WE{АX V]V@@lFͱ_3oٳ?@ѿ7$Fj}JFsS[k&mq ֋ OWa,?e?)7|1Fj#>| dFjKyנu"SU#/ 5|8? 4F)p3\tFI@&-L: 6M5D<??9)|~ |:?#ST>?| ]bKW܉y;Oi~g_GjOe_?F 5v~p7 5D<?K7W@G2#?(/_r|w/8*!@Uneo߃ 4oFCS^eu#Fj~=Zz\3VAg:yCgOoFڟ_?uiz9<-/_r<) WȾu m+kIGdTEZ& ?WUa([u$("ˋαW/0z_Ch?_qO_FȭAG -V}Ye?g_H~ 3 r\\a5+j(Mah"/;̿99|-Ag 9|-Ag պKBWIN7S_r%Y/9g/H> ѿg/H> ѿ8~Gh"/<"qX|5/3$];ݤgo}Z/.r3pYDpYDԌ _r??_s 8-_qdFjA9-?> R>걎QZ?Ⱦ/'(?gO 7#Uf9;`թ*宷0}k<̿9 77#Q #95u)Fè&5(_r_ᘾѿ'Ry9`4oF0Aa*HdYM/RE#Hy/9t~~ 5H4gGj#ҍI;0G;?)'t/"~_?XX2j5_* ?Ki?d] |d ~ tG=f>cf*gX? ˧\)_#E 6)O-#뫋YLV#oOWuC8O?8)_? I q[qrۮ,2)SCс?_q ?e?87> ~ =0_?!i]aHG&Їe3O?dw ;? k6ҡX'tm++(`A { _>K#Hr q\+V_ٻjI> 0;W#ϊ%ڒGzB%ԡr\';Et>+ RM'վg:5;߳ x+=GUKDӮiD2!76s gkFO>,7v[\B^8J8IC*_8|N/XxP<>_XK cMחwmY3eH$a%WŐ缚[뫙-WK*w+.p8XfՏf0XsJ_M㱡O_ՖDboB:vTkr"#PI1k?OtOE~(|[y5,IC"3|C쿕xg)+EWmS 8Fp7 a&}G-O:  KI[G?$h(3Hꈠ2$_! 3zދu) WŇ ߀<)kmܷؕR^Vؐͽ y2_>ͨİ2+Ob%4v N , N};., ZǑi|OiWR. $3$bd"3nx)֜NǯɚqC,R F.nUnfl7VG_x3ৈ?c[-w1tDU0 f<ƒ؉xy-| c$Qג bk$t?/QXz8_֔o/1-R)~^> |y~!I/j)X4sZ|:5摻$[eHK#mW݊nb)xZGA/ocj7v4yd{WC[Ե:ե2ޟC_çu&=>"Nw|ZU:)fy/ q]rlKRXh7'kueGT~/|StynѾݠc:\[\A,|^t,P7\7 Sx^/u/h|Gq٫iZ[E7#DaG!Lu >$oZ%?kJN)&׾}ޏt %)+j-?iY7Ool<Iq.5[wc6g C?xh{=vk^׃o-<]OhNGfwO$ Wi?ovW#0~|Iw-j(ƍ)sBIio|[K3*ғoZ'6ZRm5~߳ʞt}Qi^]/㴂[%,෵EȂ0i4I#$+*S⹳9S"鮁Z>N>CS]4ZC,5?O֪~l溫ٗӱ+z-/xq ??mZv<8n99[W`]a.oy-h:&K?2_UR^-mh|C-h:g6i~V}h>2SUR^-mh|C-hп՜W%Z?2_U?|[D-h#&Z?0΃YͿ_.<\ .tRXgںCŧ?kUx>|C-i‡Vsog/ qM8Lnf?LI_F?mUCmGB\141GST9b|>8?oN8?󣚷 <_U_Qlz; |A _O'Zq]Ppy-%oK3zm!5ڮ}鶿'{Y/> ?/溭 6Q/-޲*pk{435:Njw _ y#,'? ՏΌ e:PfVq??JГ[χA{@UWnj|>[֋0rKK3w!X'Aڵr )_K3:`q!Ȩ& 9/Ɗr jKٯ3ÿ ZG:2\',8*:|޺_f_y?mI u<|~|B'hI; xo M}z /_ G 9Ast Cohd $?Ί\+42' &|X `1k1?N>!jjzGÏMԾCKOeH|F[9[ĥ.:E hSҩ1m4ZxΊ f /[D?@]'?kI(:5 faȼDF>jvi?U-i2~|E#x?΍ùy~Oy 䟭WZ"MtZ xe]G 2[\yi%5Lx?l>#o֤Oxz0|?jGω}ė6yc{]YjchCp8>֯Zmm "OJ[y[v\B'k> ~r>F0/9sm?ju7~c3*)4]us>׏̾6F_ }c37-i$ۧo֣SX||Ks?h i/$FR5{(l00si![?t//M?ZiG:m^e|.':6>'-(ùF1%$'x}|}ڶR/k#!|?鷇mZW7¯$ڹ2e?%/)#_3]?ZdyL~%>5 |SWφv%.cu5_M @/P( V8P3;vzl?_y9W[ n=INմ{\Zx.&iehnapRC8 sजD>O!ӝzU t>-Zz͵{}#^*[&9_Vg-X~Wo2n?>toVc-X~V88s (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((Ŀ +E>>F+IK8G_(dz?C;*GT?L,//$?| ^:}p݇9gB{_Ŧ? Y~ӡ5۴~eoۛ$*w*)f=+k|3> _i=HՠPQv-FѤ7ݻf $\ۻGt94/ JKK+'5KI~eY#a/~||]ÿ h:\i+J!q#_Kr>DWg~)x #{7^-4=7C03JAGWBâ>%,I⟇:t> W5g{[ cBl.A7E_ >wM^:/D.mWU^ ND%%"XW hЪܩkOźg~x៏i1xO -yeHہ WrAMh Z~̚FjZMV𕵀yQ1$(J&Xg?`Ow>^XksIZ^'WO WTYҢ:h 0|I՞mF'y+&eek֯m~ '_ߍ?u;&{xC.{hC_KYXH(ՒEiQ =m} I4zDZ, wٓUF ,P~2-*?<#/5ο-QL{rKi%幑${pH_ϸ|DROV>/\k^K&-3I!H$ػj.5Ĩ UP} +8F/ }ڋmkvK'fϪmGAl1bD(^),'ʹ (AEPEPEPEPEP~fK?jѬ_LzZ4QE| MGWzi5+2h&kJLqƄ*:-|oSrZ[}Jt]j6z3k =DM./ᶕ #N5=w6F[t և1GdFx4Xv\[ |&m,&:H!d$1H-"1F[쵏~h^>|5🅧7Z6q)t"RX-#.K1܊Xѵ}:UKi,lo IJM&Z&x(dRW"1Ǻ1-rю?O> ~wo xvF=]4+AK; q ) `Qdow]JZu[MK'c?h~znjh6Z6_T<FCjP:K /g!Kl4n[[tgV/, ;ǖ'$W\ڵg_Q+0*J ( ( ( 9t~S4qxvX||ʮnԲ U$sҷ oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h oF|OC??bkfg8x_ M&.6h ?ÚZ wj)8;q&~eW7lyZtQ@Q@?imXD DD~=89W}αY>/L%8?R7/|(!ӝzsoCM}w~ëv_%χUWUWxpc*QxZ+z@0أL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn9"R[A]HRv.PO@?,/oi-Pܷzji Tqe2>`,6>SOҴmK~𿆮|c&, {-`c{խ`=(3C&sJnѿMԹtW߶{{=?i, -4=;ºék.lo RkR"#Vmi#Ki2O+ៈ_Z-CQu)m?G^0]{qc7]:2"4تj?Ĉ>$x F|Ai?J1ܑm}o~'`QTݽWmV?jQAi* ڸ/ QPiZ_X^ijA )`]d2ApAϔZvkS2M]QHaEP~fK?jѬ_LzZ4QEQEQE|mMcG? @}{Zxz`{8zݤE$nV`T"%i/V_)*5+7e?Kku>ɢ==5xIy| B߀xƺŌn?^ \3B p$$g~ҿ߲|F6?h~ .&4ǩJa4Ionbwb2UG%?M=ls&o._\%HoC.Z^m|+eDiOx' MɎy2!>&|[mfocJMMV )eɘy|/k:ppKF2i YQ*1yl˙_[Rl9]|Wlth&ƥ뺟dz8Nqhzf &O02-_H|Eyioe'Ifcv SpK,BxQUGKSV}]zgnR7Q_ xM=]oWm_BI֚eb]^z+ekyANOKOCh"又4"[ +gMN]FLNѧ%gQOwlUmo$ 1mv}E|?;ƾ񶱮Is^^4u3H\ȌFrQj\*Ï(7FÞ!|/j&M_Hž{- PHF8W"͕ƜG \K*Q]ZJWdJe)ʛ~I7>)'d[ފ .'/}]!o[),n%KF1$X+4X0q_@S.jpь([{lMNpfR&@*((((~0~~ ma7uMM-G++ UHgt5~EkO7{{m&񏀵?x{š[ާoX⵺+IteP5!ɆIb:Anwwݡ?od~E??̿EzW~UYxfk»q,RI9Zݡy]I'_'oDk^ѵkb΂+vhtR.Sk_z%o} 2~EC>X2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/G Πq+ qG3!p## 9O/'߉ wZڵtRutF݄aK]FrFpjfqq,>$1g9,Iy$QEQEQEQEd/|S >/Q)K9Wkr.|R8]4Js >=?Nw_Eb=W~x ~cD&QxzW ;E_uW>'hH:0أL'z?Z5ɚ|$/GkΧM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=zygR4K yhׇtȷ]%3`/ ~^_~o|=i/ -ƓeIO5۪K4X\72#!T ޭm|,^>owh76 ЩFA6σ4N=)-~xǥ_wB( bhہ.9VRVsIS{-ySSw62BR7u Z{JU?y/gh;Xm"IY\I#Ʃu7Jۣ;U32~|1O rռ? |=gsa=g>>!}_ ׉5uV{Yd |m~`iͱ1\Mw꒖I Jr:ME[ݒz$լ:i6&}3I"ٳJпg_[\Y^xsNxr"ƬXAEvI|5Լ% 7]xbm9'Qnä+mơ J+.U=WWj֏C' [Þ++}5#Ҵl-mFQylOc` < 7n6\XpC^ESw|rRVG}.8< oM]x 5`h^YҢ5UUI-|)u'<'^/i/ww3E?[],3E?[]Ί?[]E3E?[]Ί?[]E3E?[]Ί?[]EǾ)zņo~b4ZH` Jpࣂ_AEkZWMbQ~xP5 HYev,;K31$$I4_65? /}R]SR"̒4;vC(Iڻ,:t_krdI¾Ѽm6l #.w1T I2I=M^((((xm_/s%uIuk W8:<{6%//xx⇈;-6k MW#Ԡm-!MF)vީv!BexB\Mr5QZ[u?]lsҋXso-Z[UIS)e}JZ] >Kkj.qm&}/͗c*3)^/(ڠ|8UƳ)mſ^7qy%hc!؅oܭKW!$'MxůZ݇d.m< ?TE, #ծ\%"۔2m~Zg/ |A׾!|Hz}>-Z kgeٻn$J*Z?˯yry'ot(((̿m3O%C5hw&ioĽcHf(((/*oSoi3m3Lվ ^+:YOy'ot[iYerĮUA8W.KFEyߵ?ý]߈twr^'o[8]o(B JNqU7h^/>+5g66q{(^PXQ ڌNTvt_{ZwG2ܷzU__<ӥx] ZBr*CXەǙw˵oۣ-_ .Xt("e60&+5 )-pp 5.kUצ+z~>|BW4-ýs\sMindL1$Xc PYoCYe'«IcC 4+eI#n\#0'p棙Zݓ[[|i_Z+oڟ^?|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5thNs0<24l+8#>1~:?QK?ޓom-ĺt2I$6o,;'E̘}#T6:SK(E^G=I,KybE "K&|#]]v?>'~+֯5$n,egxDP`f.оm4x,IxòZdI1A=ʀx$MHtTCk+)^Vݭyֲ6OM+o_~23KC2{u$iemmckk]$*%ُYGF;+B=#R'x[#Q,.h5^}S-C, >TC˯? +?K>+@vUVJK/[/;M9fZv$wb|tڳEik9.i.itm`Zik>XY)7xO c?|+NJoKMvk[qyhDD eR VRäh~ԿoMO Bĺ֍؋,|>ReR#(~-N[]懥|FM?: xk\r{9{/hmؑ{W?~^};_j[}$=̶4DI]|, T(Vn߯/{;+un]MKis+2((2>-ؗ գY߶ſ!h((½Gk6sYEkzTYIbKU r*69SNk| _ocij^)@5o㴳Ӡ%KGsg&٠ DBd.ֿ:>{kXj?ּlڒϚS_tѴ ty|clP{K㽶;ũ-LԠA /?R?᰾Rs-qܾnin#D~CѨ9GEK_rl/TKe*J=l/TKe(GEK_r=l/TKe(GEK_r=l/TKe(GEK_r=l/TKe(GEK_r=l/TKe(GEK_r='ğQ%<1#co%Η})(Ucx؀YN ⶨ(>6;ׄL6׾+w-/%/. j/笠~Z΃lnMwIn+ܳ]Fʷk($KmcHq:31P4kX#L~j ia]ZU^7H"IaquL")}+7k=l4z4Vx}_W3|"uK&>FJ./%͕ϛ$OQ O$yG桮KF|E >6uM'W[WIng@`.G.l?#*ëKszYɪiqy,abg|x? d߈:O6:kngB[ڦi{'$i%k&wFqI6m䯧K'w{ۥ'nOw x>:]V,F3As^cYj۵3\@[Y {趺ty[k$vnf3hьdT#(=Fԕ;{zXݥm}EVeQ@Q@Q@Q@Q@Q@r~ ?&+0}Q@Q@Q@Q@Ip8_I}C;>ğWPZd~"ӝv'>ywgW,rAy[4Wu;A8cU/F*"99jWM[\Y߱GO!k;(4Ib^0gSi۬jGύ۷z۷ʷGW7i۬jGύ۷z۷ʷGP%{ⶀڝ:mj,)4wC j~! * ͗__g75q+8~|g{pc>jn*)<92;[@{'3~'4{U˫-i$sĒ5F.J<ѫ켗s6޺./z_"O_%ukxN?onMG iځ`f"̖UC2kS& vK.iWw.mfokxC-2bC?=|Gu6esd(*K B; ;g៌nj+KZv?H]Qˣͥ]\]ZGqp_H@c+_NkkkWu6N+itƟWO2u_">ӵ3x{^ӡlo kMj|ǁ]mR) O#W |%*¾<=_X%pI5̗eBcv-rJ.dƋuoPּ?s^\\VPU;xl!k>ZncU{|2 5ͶG44ۋZD) McYt"?ea6Q$@DL\+;ח^N[{BwZRQ]o)&CIw`4y5(nml$N9,XWiu/w<.7y¾!Kh\i6/t mn]]~e=?h,|;Eux*{*x)NP3%ąJ݉?Uvq{%̒wM ! /훏|S}_ZƖwͽڞƶ|Qe"n_sF,l~ բ8WTNuYtش0tY$r[ޱd_3~wtmv4 YsZK sGt\NcFm7 (@Y? 4|-&k۝+:Mg-۫I +4UTTU]-i[?{ynU͸QEAEP~fK?jѬ_LzZ4QEQEQEQEW?/H?ѫ_/?PQP:Fqwu*AmkK,Ɗ2}li:\Νmj5h& 2$pƱ9,@\ʆ'Yps8Tߢ>_Yc{ %ޛqo4[w8I&UFHʸ܄ {EtaU)taRaE|Kkmw0\\,T f87i_7ǂ~#i}X%;U*J]kg*EyT|>ԦNgC-1i Gt9!Gzs:9~7~Jim[DKi/J5;+_C?j/%5kXEmUmڞ!\4{T D|8#ks>m? +.YFQn2e''M^M_PQ_*@^!-m{Ě+EZ6deH(ſ +U-ed6*x'FdR#'\Ix&*v|]Gn;)8ҕX+}RoϷS*(no(%"~PQnj5MBBӭM'̲g2F-`:1Ua| ľ|wI,/֕uaS:1E-_/~|P/{e/ xr ^N4g]LK[˝=8JH nU!b h+-);io+dܣ;oKD;=6KX+~ -oi%xԹ*}AYxk2ǡ~(xwǮO_nrce4BoM?}>;>QXb9gV*g~$y+Ǽ~5?Zk𵞧:S[MV@.-ª1yBcҽ=cu|T>#&]%MIgkEe (AՌTbO wVMU hU@w`pH9f迫A~k@_VWw)[WK]fp~[ej{T~)+xKºWn[=MloPK 42,rȳu ]|T.*h4t^c@~k γ:rsm[Zi)Tu~wMSu,IPӖ(Ŵ e*$~5'|k//N{/ x)D3A|e-%w$5.76bTu+pr"&@}pv g֑VhV=p/qSrV֪-Nz_SߗG*\9/},i[wv-'sǷu_j^-HӪmn@)"5pAoe |Ck=YE0TG~|MǍ lߌ<==wPы%1(Q[jO즕 oVxW kI-]46mR袉`QP: Y4k]q hQz( {෌-W?g>H~ۏ3w98G|8WDC֗׾"I=kM>wOgd{x~aSo _0>W MCXoյ7šŭI$"h#-򐒎ƿe>147J ivW*ݕ?qa͡=7N3jiRK2/Eg_|JڝAzݮE|i+C$k{D"VFXE}k7_#ԾkjWi?Rx/JlDy ŏY}Gᮉk:9{[SXM,2iH$\E=&2d?L5kþ !Zݖw+xxq+3J׷[("`B+iANDKJ]iI|{'rS\ͪpnӖ$w9OC󵯁~(֓:s{|]۫AmO,yee.0FMXAOe?EȬ< gQzK/=!|]x~hv^_JӣZ|ьǜ/%YH^jL%汭|0ƚ7Viwo,uiW՚akn\"/ra {Oέ+F)[~^[[\_G>\__GB_&8J>\_G>\__GB_&8J>\_G>\__GB_&8J>\_G>\__GB_&8J>\__E| {M_7~L>^1s:?tɗKu)znr|'-7QEifiIs/ x7s:|}nx*nIrj{)ߑ4QE?Q@Q@Q@_U+n?j!`|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[h~аMRc?֑Zh]N%7g塷ʫ.U l+>#w@M]⟈yqᗰIa4?ͼwpN$ VYQcſl|iG>* ca!7H3"a@rS,xC5xPdh#糐\'i'iyxF%$ԭ-O-9~wrmjjp|woI$ܓ/_.8xGVk[h4ck9 ٵ%4B,H1sH53?4شu{.yk\Zm/M+_ZIS<#rKy7$t^_~)xl'jMo3]DMN2mE+-|!/jlK&)t"^Y ʜFbf͢m߽ޝ:$ߢ3wϣ_iJEwt|kWVlm']SFo\QBHOSzվn:v ~,zR'qa s]lۯ6î*gϏfz_|=ΏaxkQf3)h]ĖI"\# _x^DaH5 I<[ga&koioxo%,[Bh3~$}mumi8oz;tm+Y_?ZF>+}ov:׆Պ]HPhH2v06¿*O\%<[{gZα55k6yRDN58TCىj? 4|-&k۝+:Mg-۫I +4UTTUU{?{v5ۓC5~Ӗ{m((/_LzZ5kɚ|[/XF ( ( ( ( 1.|E7VLzZSse41[E@?[Go{·/++8V4eiE7 =#?|FYG+hz(oO-_VQ ƟZ>#ފ?[Go{·/++8V4eiE7 =#?|FYG+hz(oO-_VQ ƟZ>#ފ3oO\\k߉u/CT&UU m 1 s]EPEP[U͔%|ϲeRv!@݌ heD?+J+?B8O Ҋ?1?_? #heD?+f_N<봢/>8O :(c?K+>c8f_N<heD?+J(R0Ϙ+/:?>8O Ҋ?1?_? #heD?+f_N<봢/>8O :(c?K+>c8f_N<heD?+J(R0Ϙ+/:|=/V6lZDX xIVk5ZmٵS_t(C(((`P7zC?ֿࣚ>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I4^_jDZHYbB$q0\KX)0ZKƟnGu㏉ix<_YKA2\4j.D֓4<]ջ$wJI/OouK?}}FB ڒZ[\[\Y!G${~9i|ƚeZpЗH.o 6&$u%u> 3]>_(FcXΕ7̌*5/uupֿ04Q/ha4?xwڃ T&DtYaEk3ֿ xa]*ܬZ9ԚK[&]B(ZM=0l]DPZĒŶ%OyO V^hL$ 7Vlh@JJDωF㏄>>-Hn4럃VxkL yiq_¶wqXDۈRSIz'ӎ_GOO~Ӟ #Ğ֣jگZ8YcWNe^BILW+>!.>+4fo/[QI(bi/J֫*9r[_/ ggf-_?d?viV>_}ۏq񟊿J+_ ~k~#>1L^#nT[{9#/動,w8lgM]Rmȣ)Zڿ^7S,o?ڗ=kz׉/ it7WHH߅ٹ_s>̞% O\5 +OErIT&HGX]xc'~SN[ yvou.c}\ۭpͲK/r];cxz↓&5cm'[+ךm4V;F$DUgwI OSML\i8}Yiy%JƏlCUK\uSo'>sĞ)_ikĖ'Ӵ|TM)+'{_?qF^,R<]+ᮗQy , ip߼MV/K~|Y/>ϻ8?~] Wk6is>e^-X?s٫RKǕr Z.?-&'˨Gkcyu}B (f-X-],QXZ6wp1Y߱GO!k;(4Ib^0ך})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[BeEK_i+dno }mIHm;P, DYيcFMb<4 k"ֳxCѵk;Mlq5Z) >ey>3?<O瀵Y}= tX[+&YARYwRT/'n⯋ߎ|??xkˍ#hm,-m;Xey$lRD:mo%&+׳Wm}6.[k_^WM%}=,3Mw}o ,z MIm* KJĺK#Jo- Ir94eswq_>4Լa z?8nnf~wKdh%1wy!M|8$<gE% ri0iۡe dg˸k&T.o?%>k> ԏ}-CuϪM{[KMV9o. Zdf ,YMuU7{#+gu}>I-vۍg?M"C׮MOj\iqZv!鈽Ǔacߵyb-S_kR5G/nm շao;[218b$r_&-4(χABtkZś>17\kI $7^S[8V,Xx6k[YɸYZMu VW/i"ڇv9k9Y UTMsnۖ~^os}kJ={ۧ-Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:Q{?{v5ۓC5~Ӗ{m((/_LzZ5kɚ|[/XF ( ( (+ v*~"5F{mrб9P^Y|n~M&׼MJ|=֝vW6wΑGmeUxDDH? >!I/Ŭjሴ-J/.!\Br|{kyk7]^* .nmU0F<UvdI~6ԼUZj^I{5Dჺ.fK6<+O@}xWmdCG<5O4XMbjP Zv/%{$NOe~.;z( +m/Ŀ|OH-W𞛧sH-%, Plpo_i~&\xF-ZC5}xfSw-$Ijn*)<92;[@{'3~'4{U˫-i$sĒ5F.J<ѫ켗s6޺afᆥ-R5"$VKnCn'V\4@W_OíĞ4z_웽'3:]NW1[l.l)!T,^=rFrsH i#̉U]aOďx/?Q>ig[wb.,f$Iu6%/}pFiV%evm6VMnw~I$wtOo]U/KˮBg͛iif{-e ReMͳ>n>mu%kxg]y݆=JRH6FU.}gƟO?>)|Hn|ڋݖf񘦚 fAn;`lWLO|LT֏i>o[Y6q@"Xyq݅*j 5;/mzM4kkuzIm6*i )~m:O .,.i28o.,]^ϳUN7W(#' ?_a]bͩC.*q$vOX {v;?z&}=υ~#S _GKe ֣u}i%}vOf(TeN? h_|FS+A:JKOw,)4D]"1n+mhmhmJ6+~ɿGh{Nx/]~4?ťr~m{ E$ѡlƙ%dg_D(ˋK[Xq }RrO\omoߥڹl׾EVeQ@Q@ekɚ|[/XFm3O%C5hEPEP_i "/:G4\Յ/ mjzFXY2e#jkyCEa!ٛ?~|-eozmGܓ'$dW,I#;3m7O>$חGo<Ʃgv6}c3Z$%H1VdÛ4'~j̥+&~!E7V7 h4X!ӭQb(qC)O7.O:emB ;oگ9k>f֍JtVʣUc[p~WN/kRft*/i)/ӽv{oo㵶C8߈VfК:5Vtyh&a&hp4d%;|@׿lo%N8mn0=Α 7e0Ȼ6qU*JTI [ۿ}-o~e%V߇O_Ln{4- .lTqh bKq*s"A⯎Wi~0mykxZɽnm!o3suynBxZY4O x}w-qc#bk&[=|soaxܑE]GQ{'.߾5IEE-=ߗ-oצ/ڟ OþS^iSba厠m, xDHbj4`ؒGg+V| ꑋkb+ipŽi1+8vuEZ5zȘSQ[r/^Vw?x[K*_L`\w::φ'ԯ&f h+DAW?ࣟ ?'T3qw1c:E^IU< aOQ5=J U⌣'^OU0,b|Qv5Gy@u RxXnq~"fޟ$OR&ԙ=[xv^}cρouZ?ٍŵ{KCۿej+nvzvKM/ks3/GGR]gխ\wۖG'[-گ˫ld/#t3D؞ᤐB=+'п'OڣQ+ :NVQHey!#{p ~yy/EƊQRקP* B(((((((((((((((/N?â|y9WW%WwO(3Oj2ɟ kBCEwBcU-YS=&/0_qiOzuMov6Y[vk ,] YJ ?}kZnxOD5h%4mݡfѴi< nك 8(8 ך}|t/EOxSk0o \tO5%kݬ*HjV0Ri>>|.s߉Z4W@O|EwQmKvҮ4hM̐Я%z"+x3ƿYox_Ζ_kƥt#+\F~i~Ɵh|$OÝ: EՅ]I 1W6Yޗ ;stm~[l"z6/HΧm" I,r+4hUYSnT q3? Y4C<} $m+x ^U__O-?fM#Ne-cxJc G%Fzt,3'߀,5|]ꫧgO,iQBF Džw>B6 TF򓼕wkWr6/Ho_G[+xa5 Mfczj>gs w.bOڛǟ4ω:l|[k$l/[3XC^',)3[ &@} 7V>#xgzdL3m"}gY糒InVk2 +h0,K{b w$ﶓ.&o+ۣiVIx>/)ֵo8f=siND!eQUUwA!_Y -NW^mäV׼-y}{+L,Gf !xShωn'`t&ki *DY=x$,lZ꺙{Σ2K4$4ح+HM0lo$wff/ǢSmff_VzekV:O?x]WO՚jwt4$m̌(+yy%E/*-+ >[vźuh nvWRdD m\/ŸHC=2<.kciumB=E}H -Ȭ@T5 uhFk7#wxN𠹶M EMb|мv޴D"{c bj|[J޽>]BmKmu*m i7>1ionⴱ}ݾp]R6in]r#R޷nֿi//׏Eoy)%Xb)Qz#8GP\23@t87. ssZ}r->Lqn ƲI0z_>ٯo|i M:ZmkhXbsmac # UrYWȝKuIK$d^mJu[nފ( ( ( (<4b^3Vg~fK?jѠ((?BiHXidnHX#mte;IR;WW2<^o'Α}z!C><唝9Ao )'-Hx"p&T2:H. O_n?띿~#x_k~;(4k |Iо٤x).;O,eH {bhE 7]ɿ&Tct]oW>|URӵ+ {_mpZIyrF[k&~q0Լ7H? M67-mғE,qĞTankC߷'=|]eLJ/Y;-tf%D ,kM7ʷJ7r=I龉|nkuյmm)\6O4>1Y;k/f}z-f2R UfS߰ům;if :T%vJ&Tl. #vυu5 KRuxSQHu~]M絾gw[IpEmkok}wIkkt뮚[i~3XjBimgp#E,{$GFUU?'W_vx"]XVM:v-ps {$ $"M֣k> ]gZ a&.a#K:FJݖI"rK7ez=oiy]_էjVl1\]pskRI;\ R@ 3k|M}xKy퇈ukF̲ZT12H]Wh(^~N d^vxMNi_K\5U[kYr}.Տ+Jt4$V}0ZlWbI?O}+cOIڝ[|1aDDiZuz& Rvu^mcMJBUіI=f32+ϴ^A/6$e>%wW?QEQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@8_UcbES 9) esJL:-:QHgǟ( ӝzOџe5??h;/!?_QߡV* _VwQ&iĽHa?>ؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7'|'qeeo{& @YCthh~+_":wށQ}gzߙd!ӯtu };6ݥ%g{%<4]3þ;x'Hi<#i6V{GgOvK UxḊ"#ȍK15 q'➻%;۱wvH8S )譿:;LUՍޔ.|aouu~xdtBkE`1e αn.maFuyo6mags]j&H$HhyS4 .U-uw-&n*ݿ {}Ϧ  AP({jQE (<4b^3Vg~fK?jѠ((ggkEooa#8T@P8SbdHX"8R<D++;_ΧsR'?q^e^/&~.w_CEqwX >QX^6z<#Lg|a^=࿋a]🅬?߈m?HqnTY5>c@ִV𞉤jKioMCͣhxݳpPpA435l^#F#⧅.a7 .jK<'UX"-c(TB6`8~||]ÿ h:\i+J!q#_Kr>DWQ$W0-J]R;]/\J7vaLjnٰ#$#_ e|KY?t|@<-k2wViw $3ƅ_KXdz\6oH+|ڛѴ Euo^]ڮ#:&KKE$Ȯ0ѡUeMR+'ǭt6g?#Lb,Z<><28% yVQ~}?@49Ե+k61bHPMаϾ~~|>Qv#ּO5à~U/8#vQH YcRU;FG)}ue^!mnvQZԳ,y2o(U~ox>U|D5MݻInL>RAln#cŸ u'|sž׾|? =Hpy6M D1#K4R=.Qr\);tnPnj]ybTJRvvMz(^]v&_U~Ak~S?_T^օe{y K)WleV2Ä&O6qjn)*σ~!jVw?$]6}SI|`ֶh͊vr lF|͊7U?>~? ԾZiK gSo70,A2DoSY>7 ^&ֺd^%OMwQUGF0M$WPP;};e~cx~a:zDHr=`4?D RZ5.HoЈBDm_06M K:Ɵ⥙ aP sty维eڳ<eIxBՖB4n8o #FInIaHHѕ߳Ox_^?|?|;/ -bgv>A +cBӨ,ђ_f?CX367Wm w7W\1(m/, 8QiJ׶qNZΦit+rۮ]oE (<4b^3Vg~fK?jѠ(w|pZܺEޕ8tۯ2&4ɻ|f 3+7?~ v^Pr5um5m=.Qy̐XJӭ_/VÒקO]M쏩hCaßj(hV[ F-S{C*~3,caT9=xO_\zVG¾KA־&.C(^[K wS:pxSq{qW]5R%n}6}/߫]/S+Lo{{ih -CH7 Kjڍ̈́p`̎4q"@I)|ǷjxcLnn7_WO*xZ/R؝>~#G38k:3|C.5ݒvMoYGә7Fqv]Z\]mzl_Z~i~ |LokZií隍VP mV&x _^ mIdbmi;4Y YO;3NIrVI$nMn0HJ1wm]z^WtZ4{,'S𧉵H-nu=3S׼;oyeh3u?6Rte]*7K[M7d'{QH((MOO/.H#YPK. 0 t[U @4EclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEfi! _9Tyӌpp]]3N'O@Q@8_UcbES 9) es[p?6G_(3Oz~w(L](+~W?Gd>QXb6z<#Lg|aY߱GO!k;(4Ib^0ך}QEr^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3q:A$jXB@ }ɦ>|#Og co>i_a &.ݣp$`z׷Ϟ.^)_|=Oi:W2[rI*!!V)畉%Yk؍\y!%Q?yWӫy/mt=_W&OT&W7ZyQ+masA)'V|}^K]r=x5>ju6TFfdpfX Bؿk_'l4_kqhK(oZ|2G pPT|M=+ xź{2U dYEAi#1Ot+&f7oӷϭ5wkk4ӳ~oNO/j^&x.5}>9"R[A]HRv.P eacQa1mj=洺,P]jh7:jZesrѼk?M]š~?z/w \Vixb -B X#7Z޽Œ#>z׈t+mS:.I.'e,&qV6=~MqxY>u.e5koo $ E/m~+GO/#K͵1蚥iWZ[(k8 g-sg߈>(Ҧ{IkxQ.Xˈ)S~ W]cP Ӗcv+(e%el)SPi5heo_MU̩V22KVֺh]|mo?n|/7>O|=e5͵^3,l$Q q wÿu=._!u&'NLP"VCsm$mm~5/v>WBiAzQAsy0ZH[$iqoY#ey3u潾ͬRvK]SJ;Y߾o}:YROu&mc6`hWdI닛\a>U6/sof}V5yZޓ`O<1_ EՅv8E(K6$֏6;Z_OK/( (<4b^3Vg~fK?jѠ(k xױ]x+RTX]V9eі@T]ːz|5OĽ BuWšV {V&_X$lCwYbz)8NzO'L6[6|ץ3[M/œ^|HxŲrMWY5ɸŧ%.GVBPSi/ψuM:'{Oa4w9RR[]BаeR%XVUDIfd}nc{&DŽ,Ex[X-Շ,WuY5Xosq%o*F;5`>2=ϋ~%|Yi4=CY_Ad] P"_{qk p{2k.ݺ]W]c6|{%~I%%}gϑ>\\f?o-L:kHc^D^{䓓O%߆( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((}_Y]sTI|.~xgw>$Ohߏ)-[N_Լ?GÒ]k7(HXu`%sw$,~m%ZnveݣMd'g`4Io|Ȇ5,3aA8PI kYNUE~vO~'|eI?~ _ɧh?Wze\MuGmH@vXr*`EײOy";Rx{Ůao um"C]=eQ%5Ib|;,͌9'/wkY|}tOpuwMv:+ә+K]Dm%_"Գ ͅA'57/.v^ 2]*T6fX[csxߪ`o\IQ+\8ĿCs>,-+:oCu4&ЍRxS&Ir'R[Uwߧp\Iog٦~ZƠiWtvw>Lܼ yh|B9yfLJF&Ҭ܏5Fh_xX9Em#ep.V`m6?)4BZ'xs|*wФk'ejMcMsguI8A͌?^Ѽ$4+/:?-, LM/ y{#n9/(E;]ӿ27iK4++M+iZnύZ?.j [ N g=בCbٱT.֌!z |C0n/i5iwx[G[蚥U]Z[ذK;sv (XY&|a96Yt_x:guWi.鬺mTwKUD%X :ܑY([ߗmoZ 59`oQN]Sw-GS5_P|!@(lk>$m6H&6R3%[c|4(z>w_uo!յ Qk~"|5YwMYn"kd/bb~ѧHDHM55QWr[koTsmǚi"->~̚Y:]mW4[o0OåFTeME Cj5W ?|5m| _ZNOZnu}&;u-[˙ۉGܚ?ٯeկ^7wmE~m|]{)K>m4=w|8 iP,ԭ@-iV`-`Կ=x߆Wy6siwK $_Im}jbhv3pUӚMz%K?UރmE?&Mm^>й'KЀ@$ =sx^Dho4XiZ]6;0d&x[̤E,K|ό:χ~ZZz&g_'lx6/tx*3Mnћ;8K|fT÷f" 1*IF$gε\W'{X}QPXQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEn%_o(3O⿢}T_i?â|y9W[ޗcɟ X'=>)~»:*gBQH6z"y+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h((~>׋/-/LwmZIf\Qn @ˍA&x)JIv愣o|?ƅʒ{Y/~>|]Zυ {M֝I a@!g5ynEvSn!x]Mާ.?Cowj:+ @fqՄjJ*];}EqܔW7_v.?n^]pG>]oiz%նAGi~"hzmo]Ь4M%e75+ks<#=##WI%9۫=V"׭K6χfk=鶴Y]jOL!1+n"*U>RX=C EA?I[~l~Zoo >|XߊtKϊvڵϊuұ=!ɭ9>ev`'?.Ǐgߵ~F/`]ƍ; hZ} =rMPKƓ_X唽!H9K}EDF~wW=ͭ%)s[mqĖ 'MA~ ~5ߤOk@ݵńzBۛS+= {R 'jVKӚ|^|x-%u 隔w6jP{WC,a%).XFrݵhoM[&%g%dՒI{%l~acew6 K k&_eyÆOBFw}wyl/r#ƕosx_OkKҵK1"^gEZZH 4r@DGSKVz?4֟.JY$[ (Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5U&؟akC><D+&տM?0G?!xNwwCFGg1 qW~e|1zD?Mk,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|ի~&z?â|y9WAHıgi(/Oz~u(La&5N*4߆C0cB>l?L,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+wWL:-ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((cW ωA|Vak0xD+fqa:DZ~F[%r^/F~yC ;"J*Eٙ?a0?HX%~VYC ?>ؗ 5^g_~34|;NΙmsƚHbFrb !@pJO>Stc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|f _LzZ5|g?xSRø4i:MԖ Yx'd- T L+O狥kF L۩c*R@%TJߢ?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.69Ũ@~+"÷I"gUsvXJEP,RĂQHOǏ( ӕzKџ6??a|r~P?)_bOR?_#0ڟ/P+>(((((((((((((((((((((((((((((((((((((((((ĀN3_i<'?Q+_0h_?Q ^/GeڸLP 9|ȟu_ Эd?,yJq_5=YSG RJ (삊(((((((((((((((((((((((((((((( /cf@GI'.3Ul޷4fUoƅZoLmΡ\yY#k@,MbUv膕6O[?dO n=<3x~2w4MgFѵ a.huklKZMm%6w;!q!/ό-ZDX7Α^6%2%(DHG*%$Uin&g&GfGl޷5^(xZg"׵ =;FѭVF$\1Af$ UO(_{]ecb`VS jX)s][?dO6O[^[8'xlRӼ3]8mB$ ҷj W]noEzl޷4fX L^7𦟫iŨ-e%rHd?1Zum[BS?oh͓?ƫ%_~4[ߦ=7O.[I,K,XI7 ɂ8$;_?ok#Ǿ*>x/TY6lww/*5$*噏@ 1 I׊F"4 (?:l+khFGO7~i?bF1_foݥojcm֬P+>((((((((((((((((((((((((((((((R5^w[>(ˬ=_Kj9F'`F20[-s 'אԞ5OxOW~5< zݵgulg+:6h ,"H7n)T>,?kVi?vW4x|{7_w~РfM7IkaCApVHcoa,m6߄m}j[٦.]қу"h3#ʲ>,?kVi?v3i8=_ul)g{/+l&Oh?@+4;G4ş ZO$??d?luu-~x4ɵCoIb`A+g<(.3Uu⌺|3^_i,v c 3x@^~ߴok#Knm=}ZZEݑC:Vo,s3]h?@+4;G4ş ZO{; $|{|'3M54 g0x>4Po"5DM\F4Ō2pt xMhf-K[a-g)`ʦ 3;Q4ş ZO-s 'JptoW ^jo k*|s? 4k/|¿v%7Ío^k;l% $Y߳G~x\_5k-*tKk[YCg0Cղs&c{h?@+4;G4ş ZO>U$M2]>^z^)#`c-s ' Kx߁&t?52mzr'eX2%DJ=*M(?~7 ZBj# ӕ~~_?~"̀+^Ї(֖?>_ ӕz[~ySͱOyGg8|N:4'ׄ>4Oxzɯiy%ضE)"GxeFVz xx쯏 Sxb!%emN\1e8M9>y'ug6G#3a tM,Ÿ]se~=oƧW;x>HX#?6C tWO?NhFxYa$qa t,??x5?>/dğ<'5C te~ƧW q?k?Mo|=??cW~Q_eqqo t~16Gd~0@u~M C to=+Ÿ]ّp@u~E7V?_MgeoW2??x?&67co_.MgeoW2??x?&67co_.MgeoW2??xS~Q_??17G&  +? S~Q_??17H|o=c??#?cp@u~=71?_?Qg#oO.T:wo|#}oOY_!E._UWŏ?ټD#3 x_C ef xT7_?ykj??G(ʔUov+EYO<([_xʫv__E~i>!Dž?,~ ;|A*㕟WGDxJwo|#F<%*Ϗ!5_?+~!*@>/? MW CV+!<%$?ڋa*}Ժ+_Y\ xKT *0u\g?rzeO?Vhʶg?rV2^9?ڟ S~Q_zğ,xGUAH*e;rG~"֪ S~_^-~/e ‡яR_7U~*+y%߳7쵒8?%5?._i_knxDŽƿ@~yDŽ/?S*}Ԋ+xb%<'ըoIT?.-@> ~3eE+WWϠvGĿ?-_'f߲?Me~G"\aQOu'?G-Oge[~W~Q_?2_7J<=w/쵟 [9:wVyZF ?NOE c7[z'"[_߈Ҽ]rCu%hӝљXczGcy_}~(|Ggig=y)AGH~VkxK>;Fpv]t;3exZsIZ˵6,~ ?O4Q .T5_'ȵm[2X/7 |<̾*"uA[o*і0pn! ,713+1>9w+hzc[&m-BUy0<N2;r;|koѣΖ]''z+O}CN?}- )ot_Ei-JG-|6c!/n4-o5}:-kho*ss"NP1VHxFOV~;ufb!Hh2$i8WJ.nJ7MEԝi*ucgQnǙutأA ?OoF |$ooF~؞$?];~-Wmwz%U+kk("Kx_ =c Gs^.cm^([/EQE/I";E+,&52Pij;)=/e=|"WIm>W!J?|5"KDc5q&|/ >!uK>ea{ػjsEo2\$A8!Dzjo*7~8xOI<_T'wYGf$xoƚу= IDtRpu &ь՛WզB߱a4chL?7a)5Zi|s߁5_iע4Bw)sXYlɼӴDh%>cNw~;F-֧=Ƒ/? iMdԣ҃M:'-͑%Ղi\KytbīrmJ1oW$ڷKYwjz?‘ g_3?\/msS״/ ?Z\,}EV]۶6WܛXъ3kxG49: VN{M&kt _<\$!KcvYeRXOٻ[]'urKwt}yЯyETo״}w{+7{jh_~ m=c/"5|1',7/"ևoVM_3xQmlSRM 6b')*̗ $X2sUq{zW]5 t_T3GzOݟ^|c Udy-u:TʖU*iN_3O ;|$1DZO i/7'"]4ƛ<5~Ÿy/~bKo dCZwDO?]3Kp7OSU\g[!*Cևȕ 2 g7Z"Vb95ZV z"֒t? OJt"^Ɵ?_33ÿ$G)I )ʾOS?w-~'3CZߢcOWx/ g?n?Eÿ$[Qi*O?e?91Ogz"{%~N?E*dG Z"Tg¿_n?Dl{ʾO+J Z"T- w%\Y9 MƟژ/ Ꮒ/]<߄_?O4Ak - ?ѿ<t|K)H ʾ㖦oOJMK]fIf6Qy7󵯛kSNA?5vu7Ʃ_9Q_"|G&IyMzXL-bryR3~|#ɗ ,s~:_Q"s޶,5^5SPk_r9? _w֞|neT3!օ? > 4!gkZVh/ ?Kήþ |gwCt@:|'_]뜲zO5ig5a,_r;!__xO~|D^6}8gI^ǏQ:iֱ)Yw -,:{F{U\/+E+}+_ O[|6yd,DlYI9$֗dO|D /&kp}x'-ݼ$PN3ȯ~2Oa ĞъzWԚ[quxUǀo j o%JX)UP7Lvd,c8F.7X lkʪwV\־c"> i~/?f,lg?->}i^Y/tyMԖ/x2"@6ʭ@ߍă^EB|V=ŽIUu}y hYcsnw_g׹=߃Rl5> oGk~ DD߇!]Hi%H@ < 3 tXu?[GT.]aYDDB"I'kVх{O^gVX~^kY_eEd^|Oh_wk=_ÿ%rR^ؐͽ y2|O_Ь~ | +5គ*#ׄ|g*| ǎ|!ikyR.ŒDe1 U%HoFu Tŕz׭f_TP3ުWۥu>_r*tTl>[k;Z=5qk7]+||xKfUo^i47XtY&O"Ehv*WZ_KʺƧ|( [kÇu&ng(MrU E{w[?~+?>)x:)VC|7EivҊ.R|EK+5,p_w@?*bN?\x[LT(|1wZdJiy.x5C>N,#'<fJ½cPozy"Fdt Y 7'? ~$ڼYFPul]OK0挬ڼ[.]>yi nDKu:tZwǏ<{]W,sgruaWFgʮ}!-\®6-#?$މ*NK𔗚m=mܜ&ۻۻM)?TC/|~(_DWKkI%guD^2nw<&DOxb>&xÉukEMFᑤb&SQ"7>A_ ®=zC?oVMg-[%}:iۻeEO/¯V? )xV:)u铛fkȭbeh`|+ƬKRG麏wx$σg]*S~'4vK~eGկ~>|H$ex{~NZvmzhֲ1W-Y5٥}<4 ^ӏ?߇oK 'ޏaYgw `MgțIme+_߇oU|)'O~]VO<)[FF?]A?zA!|B<»}}vϗ L0s^cyw-ClŻ~].?Fu5|@?zk~Ɵ|@ޏaHTOj8 ]1O'??z$,+[??s3/3s ?k9[5@? ~!]<=z>C\?~~?<µ<=z_fM~!ޏ`W3?8+iD-iD-s3/31]3O&燿o@> 燿oGh0y4[&;rGZ~ ix{ ~!sM<=z>Gfx'ڣVb!Lď?F-"W9o?|*VOT_6?@??ޜ?coc-|*x9S6D[үqO߇oGh1?g>_gӣbO/߇oJ?c {}vϗ- 5n~~.AK7qM<>?/]\H/+էR֪8kpvxޘi~|mkJV>j ?d_mE3?-Y~ai~x]sֵunM{<Jϋ'=5ʻ8ï^VR?pLogs[]g4ڭegh B+6:#qxtg;h+j|\o A3;c Gar5O#ňƫ ?+Tu 8+8:vp?>,F? ~$i]ո?`¯qM<3˺XY.y "4h7#Kӣ_]yG) 3mB*3Jцj~Y^33a6.'__ŝWۻR&bqr'smil`oܴqy.HCdwd>iJ?9K8o Pu̻6G.R䕭uxHx ]u@$><we()K;xcu"?O&yC-\Scs%n) @OQ/ >z~'?QO?/<~O?W#׎9kZW3'53x¼uw?0k[? M{MBxRon$+x"D;w.OE<]#h:_LԴMmՕ٭m<:v%oTe zf_Щ|*\6|Grf}RZs \sğO)os/:\\ cݖ0tHgfF+S9eh' G_uʼnzG>:3h+u] V׶tZn-pG&#ɒTP2sse{[7 hz{>qsib_/NAyL$hMÍɦx^B/5ouXXo% ̫H%?I<<ω-.SOgZiKF8y6D7lVLd_()-4WIWp:7dM.ߺ&YB$XaI8#8>f>[6Ro~(}n z2Xv>k>[]j=.^HZ'o(ۚ/v۶6pS-b{ 7Mߥj;}Dkc9hZ=ݼhy=@dH|Jk_ aϊ=hz[9B3I $TUN@_?4} }F+ZIq,354%XA` w ?v a<y|hQ-GNO|%+:R[2Y|@V3̶Y/#Ɂh\<4jgXmS@_Cqjt)}Zy!(AH]")>DZmͮͭLɵgkAET()S JT€EPEPNޝ@Q@=>SZ( ( ( (> }QEM'ZuQ@Q@NҖ ( ( ( QRREPEP:iQESӥ2(h(((QWLvOY+~m?Y*:6K@5*|bӆs_?V?7x _z>SúEOt%\E0{vEh?R!j:l+\mgHa!e1N: FD_<꯿u3fe(7{4ާ.=7>:7Wj?q #V?#WTkٺ^^WWmZwXNIQy^8$G"# _Ķgźcjwokz%ճXՌ0#`ŵgֿ0Ie;'oz7.=7>:7Wj?q #V5[:qIoS}W^u_;NOU/"-̈<$$_i^(Q5}>k}&M*[!k".EHf >[?]~uWNtX%K_ح6-;XȱF$ꋹT enW֏5}k5 ]D0YŝZ[kV`pyO@lO5}iVej *@GߥV,QU ir9o?E\R{4}?E\R{4 ~Q@CGcj{4}?~Q@CGcj{4}?~Q@ }#/wk6|_ o(K4B/̢5h҇(WJ(ʢ5SdM/5EljA=?G5EljA=?G5EljA=?G5EljA=?J5X2?yƢ6:{J(o^z(׷ Ģ7X?o({jz(ڶ 7:œݨ~-:_z-:_z-:_z-:_z膻kt~m+sKZ2Y[Ƒ<;_UGQ׭g"$~K?#_xN4Q,xN4U 燎A'/E#M:o_ gu_ޥgFmߍu[Z[PزwMǖ2Mqb~'+Β1_kτmټBڿ7ճ3|O|Mnsgmou d>+tڻYY45Lr1'ˣ og\I[Yy?pԂj 'TB.Kvx_%*C4'}:."ճqY(,I2S*}4}w׆/|]Onx<%Vp4"zM$3hXOQFa?,ѼXi?r%VNrz7wdŴ5Z-6՞QL|a c/|w.q}/& G|2LDzdڀxtoK,L% ^߄L) ~=EޟkdzO [TH4-ޜp`.k cɖ$Uzk?o:Oι*#'(h߭z+ɻg[ܛ?L-oDpzn/>"u}!~iˏXQwW^/MrmA#WI,$)}tVlo1VaMi[  =|VPٵ/Fz'z]tk?ַݟ1_KKb4/iUmKTM>}qjΟ X0#[i"÷?OZ["u7,o_xě&8ႂ00*&#@bXg }fx{ #cۃH:Ͷ߭ZH+Y9+Z+/]+tn>iW_" Ư*Q/EW>iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->O8g4OF|;_Eχ8յeցwضQ[颉&k# ŝO$~6ImM]1Ʊg?,xpW&_ 3xEK?/)go/:\GR9@H.h5Zc_vM_u_ "N6}izj5h%Ff J?65歠|T/h">.T{{;=6\Kd* VYX-~?G_h/]GR֡_YjV7*c-Ե8{ QH#O);L 0ڗZ}eor_ߨ|fF|o2Wx/9h$$wjmHAۂ;zo/KFC|?zfT.=xP$6G>/oDxoxz^~ Mӭj`&igwl#U 7t_ag7t};XT hKq1a]I5#6vۗ,ݫAϢNvWK9?d4\nJ7յ mK??fccJfW|m&xrF+)4hnb úv1k_wo {)=׹vՒI#kDr_mí[[E5;!Qi<}ݫֽWxkh>xh~ So!|]:ox}VTQ a4fe16;$(?8D%_ڟý#>ռ{%6bkH٣ɎX \Pa?z?%4|f𞵧\^hwE{iyu5wOo 7W У2vAe:]iZO]:uy(i%kg(ͷnIy]ۋ|`]G$PRWUSo$@ήFܰe#9o(j&ޓsImX^MIѼeoA_? g~֟ |i? ^|F׎ݭԽؔHQLB]*+"|F?ghV>"{XI(2G#(ˎt YHV{?(2rV止_k9{4m?m~&׾x[ĞK?y& %#wB2UkI? 8ifZ56^3_Ě^-rwƱLi#|Sx#|-9Qm_P;!yeE 2FK9"<io&Ox᷋'xG_Yo kvkO>ZkYu`ojIʵ[9/ '7]/XoSDnk_|F<9y2]4J\YHi(hZVZrٴew{zoG~mϡ~ A/?iΕ[ŖJ!sl.|(ʹn'<++O<{\woV-:&që.[]󷭹Xgo#'5hZoS.<-}6ݭΝTMF'㱉1䨯 5GV?]c^4GR6V[n =f TmaGZFlI[nh)q~W{&?Zۋ࿆1g|\e_xP-o|ScսmkdiA$o=&2)^h^$}#_xºW,Z>o_2Y@IH&DكWeiOoB+닯ismES͌m cb c|qߍ<;^=5]dҮ`͉31 . rh|Y4IڒJ-KWW2aͫ|t.]JIri/O-'־% ED%l], OuKSO{tXCѴ+RY#GuF!Qkx#ў{X- fIO#4ّ&0$N$?_e|5ƿx[6v. vP]ż6 ZCaT2RZZWUi[E$hi%mek_7WnkT/߳W[|M_#>(2ő$R+hKJ$$b1\.4Rx mjKau$p馓lb`-`?&!u]x࿊<֏w hܔӢI@lW#?"]/xWƞ񮁧M NC E֘UR8h\^MM&٧Q8J-gIss+(Qq\Iߧ4mMjwZ-xO]~~о?M4> O 0eApGb?\{[x@yDj!x N`HT}O$*}}wj+G3[_t/z'M/nR6]6#x&yYԀp ״o~MNk°h[GE(i>QrvsssJɹ4i*I>6-/RQc(AۑIzr=9-]S ~ þjz犵ŧYxxY,ryםP1<pŀN~ xjX8.u=Ba%rNЩaQ'p&P#3''5s^ _x~JYjW^Kyws,t/ohV8U';nE_^mOޑj {{5\$ql,k.A(ΓWQ9+4q却zݴӿ=>eNRFPt^풳Vn9| %Ϋxīi,*#8`hG.QK7? x6^.Iȸk+(*eR9&&[|e%ƯW>_^KIԮnl"hIm%J1`>$\~ΟgPog5CcZ~[j|BX)Fð`*ʣJ>}vZhWi^וgگ'!Go t' ߋt-Gk#JpB`y?gǝ⎫/ i?Q'uk}#9/'} 24rS_ |HUᮍm ~$OPK'R֬%ѮmlHvW?fo/;;[Z<̤q˴iqU^R5!*^x-ߖ)=W%I˖OTUq9' ǚW|-x-foZj+o6ctbcm]0ktVLoRmSƺliд 3,FY#@̀ZE\?9~6|#axe 5{V#Ӯu~tt;{YafI%5I#I#!Pk77 =v ßBUfWe&I+"9SZ* ^F:hܴzN0vmӔj~Q>էofMe L̳H rm$a630l'*|oዛM^~nsh.D)nn]cIJe򑃟~>?_O.x?:k,Cj}-ܩitU;>Vn75_ 3[ F/^}ߋ'[yռ04Kƶ7-^LH~CYZ\ͽjm,br:U6o& [}߲%|ĿxNP$/5;D$GRr w_?~?wx=$\lf*‡o]\iƴI)z_O)qu>+kQEsQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@!Oտ[jƱ/#߈_'NkN7y8_rlz?~/W?/wOsESHe'_tz-/*[ /7P[?Ecu7.Q^)1%^׫o5]Ƹ݉e*ӫgQErQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|q [I|7O8?r$7k]~3{xE;^V}|TO c)N4Q3_RGK*2ݟbGiWjw.}s QtQ7.Q\5S-VO_:ԿfOiz߃3p5#LYMϤi]6\"[+?32-ט^M"7mV6M6Sɒmf&ޖk|=-oŴ뵖/ |hd^V_IkZ/,a]6Q[Gh^ieʁ9Jࡿ Kv.Zݦw%com.[EYsx XA9HW>/;|g⎃cQxKWt 2Úfš׷7/y,dA$X!ɷ Gu^-o:xGm/k #дQ[I8nzC{pؑBGGov}e仮m'Kom/X?oӿ 8[y[ U{ٻ 967]3xֺ^ns k6쐈%I"8ٮ]|Mx?iv=mǾ5|q2ΝCoi4dqU'9?g/k7\B>ikjW~44Dk״ˋ71ZbGOAm^x@ț AFԆOe,$Ǝ+ML%:Z$M5U$yO .;y+K=⿈g<%Zv-aykq[ߵtwvۿj;:qݶ{i5Z|]|G_|'E7xovvj֑ &iY"91BC2 @4x3}W4{=w\|;/iZ\r7sg!@Ug`1!ކiҼ-x+kv :,P:cki h8˼%t]ĺC>4ռQ ãV5IhO%Vͽ`TR3*LSsT/T՝۪w[6($wy=ZK^Z} GK״_x?RHn1*E;:2#Y|7׀/M#CJҌr_=jݤT(QY$r$~ӞSh~,џV:O ;X/l]d.pdGş>'z_n< wK&yp gcXo'747dݖۚJv{禮M{'fA? g\:K4 wӷYP3 Ǘw([_ 6|K$?4Fτ~ .յIn.k249o/S/ #hut9״xtZZ]inIVl*8rCWNwOMXZvk.'Wc >x>)cYC={" 'IL?"l33mAuVO~x _'wo46?=iq}{,TLPD9ig(A,+ۋ 1XfzҬM5xK!=s)nf1I~||5bIM3ᓧmLk=J{hCm:!D>bGe{ztd%{Mo֍٨ݚQ{+w IkJu~|CӾ 5Mcz /oI1}CZ.VܵIE^\w1m$īiw-{}kh]&-??F+ ">K]֮*KAO(|Syo#B{,Ed495So~1e#K |FSmNgu#`Up)'oJ֪(rʥeҿx};[m}No?Ğ4Ҭ<q]hhWqZM9\]c,V|BS_4q?MxLxt?Hmmhm+Kx"ѫ_C{mp!y-df[FztM(ջi~ v}mfF+ "Q ?)[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h[oO `(-?h#_ Jnld\^]iTد2 @ ¿p3]?QU_RFag}s4v>&HRZwv'O@ xS~$V#w +)'e' pt/rR?|mxVCm,Ki3w7 i=1WYcdHJFEz-|߉|[]xn`^t5JN!X! n%8 b~niWQ .j d>5fN?L/7G&~Y֤uxKEak[NA(dG(XL/7G&~,YE/6rk/RCg(X?L/7G&~,YE/6rk/RCg(X?L/7G&~,YE/6rk/RCg(X?L/7G&~,YE/6rk/RCg(X?L/7G&~/_s2ğI#*- 1Iw\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMW/hxZҴ+D.u a.A!w$qkYE/6rS?TaNk/RCg(YE/6rS?TaNk/RCg(YE/6rS?TaNk/RCg(YE/6rS?TaNk/RCg*އJ96o?Vy kmrirpQ\$4\,zG&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEƟ&~ tMVe\,iaN?0OUfQEŝ[[m4+uv I-+U!w$hC9??7.QXc~z"8a_鿴_{ƃIu&J~/ono.O &L%@N{T_>=:?Gs5]6m}\yܠfux. Ls8Ā0eCP XxcORU^^giWPֳR,N#L`W~пK;+ c;]&q^Yx]0^s{,oqڰku2mk̈́Iyr2OE}_4VIjRv6{Y]Rb=^@g—[c਻⧶ln. WX/M|N/54߆Z>;o{s9Vm-dkFAk*EnN(_K\mi(mvݮ7\O> KKծx፤dH\Σ$d~xx SGkO ?je}f(n1&7Yk#b8?@x#hS? 6Z5 \Ҽ?lZ+q-Z.(.&%aT!.j\׳k-|M*=W3_%?f㿂Ϩt.um?+M Atzg*JO0G{}| S B?jW֭ :}Ώm+0jkF<017U`:wCŠ߳ZxSkZ-֯T]h$Kk;no)vt35Ɲ&ۋi7H%jm>_-S,u2WV?/m-4ߍ \ҡS4h'e{5fL9S*HS4ߍ \ҡS4h'e{5fL9S*HS?0u_%MgCw/MԠ3wܺxIwݵ5͎.4a%_caHE}"ԾWL7C⻨k)\!2FK$)|XҊqY+zlvto[^w?gM['únOjxӴ!jwuK u s4wI*D++.z ~5?Z?ĉu k{|9kޛcKƺݾרE2C< иheE~~Oniߊ|+h˯[xoU$䗖8H ӄX19-b46ᩧx>[MkkQWQoys]y+?3~O/k_xgC kJ-煂]$iK4NbNpl)U-___>|+'K𖝩hGpX\[iq@^nKc7igDoO.gh$%\}2}Ah#a7dm;#δ`Qs.K);e[F&ZN{itկ?缿٣~O/k2+ȣ?f?缿ٯ#~< }|վ|Iմ-HI^ij"O`+::nW]I-N/=̊dnYOq\+O.|6wbىm"fS=|Sx;^xxW"S>\qƬėOd5*iGcx> Ht>iךvHZ[Zm+7֋Dry8Wm➑t9n$XhXXG;W~Rxaox{Ꮛ$>tKؼ=}YOqwM :7֊k(l2s_1K}QOv^97//3V"yS]I]E$6A@K:6nVY'vkMJKWtWv?Gj<+^wI{--j6~ $wΙi/B2OOFˮd G 8Y]5wk7f_s^}OCA[r>=;j׼__ús3" g{bTmیf, & ${s/ïA]'L~?Muٵ9[).$i&qlUkRW-x?xӼ:o6qcuL/T M#l6M;vZvAGX˾-ݵzo>Ώ &Y.b%EFe!YszS_rQ1[DÍ^"~ ӯ?v`'XKK#fMe|/پ=𦵬I#.AvOVl<)d y"21޷"]uk˗龶Wi-uoE}/?^#xž_< ei&ZWPpKo=Gw iVUxHҵ=|n/"{EV>ZQV $oXpmjtvw9+:uO qSx*igƻsn΁G\mHw+QkOx ğ V7^~[ڄ7YMw'H{hbV/ͧ||쌾S! :φ%|(|1c OJL?ɫm[P!P%EWzꮼFo}5NtϺ>VK^-ݞiiF&Ԯ/>X ̃t"(3(]cyaAuk$ 2BHV*̹FGkw_u_jT* D,XP+KEͲ7ʷ)cq6?_ď_+7:63[+rºn鷐iۉsdfEYD8$y=J*6{ɷmw5iZ=^߮k~~?߆fK=ŷzu ;%IUOTCk 5v,Tm$zxEa<0~G~?c>'k:]W5={|E6/'٪ϸ̿|1W}H𕵶PgȌ豨[]/LDo`q/m/5lZoө?yG_בeq?SG&W?5'5矵kĈn. jW1xX%9z29_,L^|}$1 o|=te2 6dUR HK?W ߆44  3\K+.NKyu ͞MUUDEH@>Ԣ(:1Myi6ŵ/`H"7;\Auf|YFҡYfGҦu{+b(d'X٣^VHԻFrH5O'Oo>Ə|Wo鉥z΋j]Z,6,w2<\9o134&KkYR^[]ջ2'Dmbm"\MI47ge{@A8(<0k?_yMkU| )[|;[?7& k]]>9+i DcҾ"Q[6çcVjxY6x}Iڻl'J2&SvZ]]_V쬜sJWZ;+[e{W|2`27zKM#ͧZKjNqW/}ɲ( D#'-?cGrӼsׁtoexJe&CgHP2}iZ,53%4U>h X|/? [ } H-nD2˨ȷ&9m XLDˏurit{U{5gfKMw{Z>9i];F@^uiYzad6`)B9#3H^("I'Nu IsMikwZh4=^QyfKn! 7ك~0~.>3փKxutJ=69/_^X躮?OEhZ#z֫nTdEX26<࿍>8k]mO>%R0 oІ,ף7{օǟ 9|,|/Vu{Q6KWXmK0(]ۨG^*W)vmZ;kF㽖OvwV π0|.>|;VhJDoX۸r8Qŏge// o xKY/4[a9\PѾiFΒ~\w:yS[/JKQ0QE QEQEQEQEQErB?Vs_Xy/ _o7_B?Vs_?Yyu }~}kG7gl O ӝF!?xNWW!ꟵR?b 9}WZc_EL: uL1ƥڣ$3VQEQEQEQEQE[I{Ft}fHt.ݭHX0WITC( MGPŒ mG( MGPŒ mG( MGPŒ mG( MGPŒ mU5ٯ^0omK^ҵP:_aAh}Bt2ɼ84PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP-Ho/o'5?8|~=|W׆߈_'Nkw 3'Z} GG'Ȋ~>F!?xNWQx9\Q\~x#Z:B*gWk`G|Eu)DD"u ƿ x&+3z(D41LgT"ʱq0H#?/>y͜VN|6/xTEW:ZڰfVќLb R{+?>|1ie߅fBԵ#Z-ޱi ]ƞ%[¶Al]!c6h._H +puriy]u$SE磵{VlO xC_\=e}Ư2!v7`:,U _/X{u'qK ~^#g/bM9"2 5eVߎ?=n-l|KS] %Cu9ŶkFԤ2J42}jUN?Hmzk+rqKg/{/J+Abh CUI<FHo#yaJaech{5xL־=iŷ~o3kK0$z1hVR]Iķed d j*𡳓Kw{tM2uV$oeޞG1^|Ii厉AR|i&e Dd1\_#{?%<߈%7t4 ;ZHnF k+6bC9EKYwϥϢ~# ~@Ӽ%|-`D6;;BJ8PK"]w0 dWW~x>1x;Gw5/|=h<5>]q/`Q $dm)V~<ޛgx~xOĚm54iauiL2]X-JM9Q Fkmnމ]b/I+ݫbit|JW[8?M_xwN/ 6ݮ'KS{v[=ecڔpV|h/Gk[ZLjkMsF MsYsuuYg%mӝbn'f3?R {k%"WԔf@`6.b;;pz=`(((_to!ҬwDjIo ']I'n(v--Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ uzOMuzOTS$7xƿּ7__B?Vs_Y?>;DS3 7) er(/O=cctU'BP_C57n ~z|7.QXcz"8[ϡH?RөH?Rן?ů|>ccCuOvOw=D8-"##_20K[R/GB?փjWRc]xšƩk+,ˤڤyDEd#yB'5|#X-V)ad|fkyahE'+!+"0VW?5KCg@J[o2_Ki ig̣cL$e+%[Q;^-dnx asÚ[$^(.4_ jڭrmմ&Kq%SaC&THù \6 #şommgJҵhtz>-gMsrUm$=IrO~?M< x4QZMsb%-& *r(]0 po?a~Ͼ_ͮ~Ҽ74Q6TVI` FDIb-HF2wӣWvJ4yǚQIlk[|^o~xoHβot-BMY٤]eC0NTn\F~5Id붚5]އĺŬw0K,3&7ErB#rM~&5mG>.cC|sxEGn5MV3f;Y5YEi/c GmI;_KI'|6怾"xQkxAmZ[Ep6kݏ7BqO:DtdҖ|5x'ouh=3@ѼD:zZj4#W8S2aaM_)xe#AIk-"9,ȐK8FfRxC 6_-? @!qMdQ;py=+Ce }56{G!~(}nnlJD/wp1}RyQ(mR0Rq(vE+}jRM]n$޷O/?7EuOk7I^,?fa6%-J \(|6<6O<Լ9V]B~t-I-MD1ϖws$Wkধ/@F]ԴԵV_LxeS ʢBMe%kO?BRֵ3GѴQ_^__-IG!Q.K1ֱ\IۚQZMDdޝl] )㷃a ޑukbO\[E)uG^UsXӏs @% X{C<kgY\štW,L9ܞo8|up͏<KI[;~,KGk> d&oly0t>jͫ[=Dn'~ɭSJ[~ym~ym|%/*/}O SHjd֦ӣ0&HȂ#L0ރ.~'|Ua~)u<3XZjwV1Z{YYHLHeJ˕ ~ymA1.tmW^S[/ xm45]:i/&.m 8g ;o,1gݶQXl!!$a%ě"^i/46^H]c3N+m_XPȚ3@E[׿ϊ^֯o7ֱiflh%87AՃN1q{Y-:|JNI.[^z4}=c7VڏmQeXr + A|[ѧ&"R=N~('t@̒mXGr#'weU,>/׎t n#@Q%o5@-\iM$3 ƭ_¾׭n_^Af.ek i`ȅD1̉&%Qmdwii}5STq{ڭmo~x[jV OLԠKKOzQ:I#u*A E[s {kⷎ|4<|}.kM utdr_E}.`|+?_q[7~066Ok #j2&$Qw3<̑y,[}_g? ߎ׿62Ҥ?ƟxjTH}+XT%%mB Q'cq0WvKc?bs|-3~[mpKpvG\:'MN:'MN{ |q [I~Nf<c_^/?C~!؟9,'kku<1Gx")?x9\QGoR'?qErXH<‘W:c_:(0(((ž+u֩KGWEΛ$P]OzD Fk)ِ(>O'=}ğO!~z-+z׷׈jDhn/+p]'kۨ=lC>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cw_5?5K'+K(ĭ1-<GAǠ@-~~*~ci*ΕZy<5s5v$j$M%$(ȫ#_w#g>'S]<671_IQ@C 31?SQ4it?22 Nں:1ӊFx?Jj?^t@?ំMo?Kz,2\:-( yeBF%z? \k5t N&P`e)+Pg۵J+aC?V?߭#(\hRo<|F$`3Gu$\w#iW<7z 7J5ki;@ hm#_k g*H"W EyG[RhG8a5*OPdլ#49DEa~Z^xYzE{|*Qq{-X-tK ^F"m.+togTW ~M߰ϴ}df7hyf6y^l>y/}տc&otVg>23y<3my?5}ϼN~B<D( 7) erXR"s-?P}_C5_ܿ쟡|U!w}\_&􅫴:gԼyh 2^]=iXr3aa (QG#p׹_M'x [EI WsN[K(#[k/vX|3X~1w>>Z|QöN08u{Kh BYo'ˆBL} !_kwiw)x bqsZ 7o]Gk;ݴ}eVwu{}-ޗn_[\s߶_|#ߊ.~.CេIb|7ca{Qy*qsyBw%99?RO:7or[ $r_XjCLMψ?k?.9-%[‰ 7oT燁{{ݽv`R[+[} |yGҼk[zޏjZ'5#MA2cZKu=q]l I- yOM%/,sAGxxKiSX]/ow b# d䄢rwOOKE^Qkx;ݯ}gz-O-R)o-6[Qhd%e[~D?>9| ]"7n|oȮ42k hMӵ+i-RR źha]^k^<%?{Kbnm.$Inme堺EO7Qjw1cXESӾ|Z~::yzr1ygL%߭kg~Ti[ɥ^׷Vi7>5o/7>] |lݭm:8.ۼwwZ]NɆnVD>e;|I_g7->?Rh=bݍ3ȍ=Ք~tKq9E2C[F}ONkǗe?/?ˏ7wl/e '/;׏/7ϱ_~3ӗo7ُk͞^?iUE5/{ia)4}~K~yCkrK;~7ͅk.kst[JZp敼 AE~ }x.v/m"%%v6@.fT"'/;׏/7ϱ_~3ӗo7ُk͞^?O=;^wů_ocض.ur6ei:}szdyn.;YD|7M}R5m[h?w{smigmK<fv$P9${1Qx:dݴi3\]\6[Vr)Y馫]S_z< 1^GxD4n^=_HuMꛜ W'H-Oh^up Om56mw|5cY–r躎5힟okIwg vmm2Ji &^읮Twѵ{ɸw?WS^99=5o[{N|Bմ{ij<ݺo׍1k=ӴQLR$RhRّF3qH[絚\!YRcyq&]M|OMV@eDRH:$ x׌9jz_SUn5+KUocid6RZK|䧐i=儁Gk\Pj5p*mŨNiw*>d*[v]n\_V5,ci2{Fnmed{jC|A<4ˇwE.Db] T?ZO:MZ?5 x$ Wյ5s\έ 7%"v^郣`UCc3cfV1/l ff{!zN TMG^T;ii;>W1&YAu&I-*4(|`$mȧru3[ ? amlEs}>%ś2ƦSrLA޲pwg$+×^  4PMxY6BvLH*URa;4ZwZ.QUxiҩ)c(-);|:kux/-u(k^"A_%dgDKGH`)*Aj>G5Sw /#\;ۏEݛ f^ȑ!P @Wj^<uŧ|=ĐZ]k h"cvmtBlDb |tm-*UJ&rڻM]Js:ofZ6Mlһw(̵??uySSUȼAƚa5-rAm2hլͱYݔnrܣ7 0x;Tѯ--nm`褰 Ir8%lMÄi-I=mk-nRn ̢jmn]؟eաm ߆.i7O76K*Ѯ}")@ m 7JѵH_EfL(ʼnyȷr3zmWO'd5z|O6Z%isnU̻S,e d<7oeە~M[{wJ ?Uξ vSK]'k'15ǫiYP;|rxԊ2|֏j>Oy7⭽RXҥnt wk$l314 񀾡S̚n#G|F:dos%8;LJe5+8fG[8՞1}fi[d4c!icާ HhoDU땤k=E@G@[: 22|֏jW=yqkfc}iԷV,V&mxx@Ң5HQy֥xjoځZ1*lӒYcFHΒ|JƯN8^\`-hj*=e9'v;^^38J:c)_w~WV˯i_׏ Ŭi^G5|E}B_&xJ?G5|E [zKO )'-Ohe*oa/?'$ȟS̵??uySSWQ'ɇD$"}O2|֏j?ZO:M_,QGB_&J?G5|E [zKO )'-Ohe*oa/?'$ȟS̵??uySSWQ'ɇD$"}O2|֏j?ZO:M_,QGB_&J?G5|E [zKO )'-Ohe*oa/?'$ȟS̵??uySSWQ'ɇD$"}O2|֏j?ZO:M_,QGB_&J?G5|E [zKO )'-Ohe*oa/?'$ȟc|+?7ῴ RMG/=k_X/ɯuC{!nNeWfmLW'=ƍ3J⯽A(Ͼc'~ e6*,"[zi? 0Ͱժf9d*Hi-7%(KuZ&7<#;K1$w2&?Ux[kw.w\>[G$7M^MдHn6Uac6W2HS I4Wz/^˻?PM˶}W? ?9fQ ß&l~lU&Us> ok_A5}Va-Տ^l#5!Tto5jW ]?gӮ^Jm{ƺ18r'Qf[~Thvt~ڙN1Z5/{k[}1s͏g?Ls?Z(/WÝG3?xc[ӼK Ccm-fR3ȥ*wtb$[Clj<8ݟtQEW9WEK?t=XG\_,a?cU3׾\n[56ouޡ.-Ho/o'53$~>u 7!OտO5}ϼNB~<D( 5) erXLed=y!a|Uf!w_/~s>*Wk`Gaaob>k_J_  ֽxI}?߁:ALj)|5G?FS6iH\i>%FIHHdH1#7}ĿoŝZ Z*_k\ Z2Hv}i Kj.# Oӏ;/u}oǿ4k6JP&E`NaoZ)M4^LYZ[oCm,wXExf3kM'__w{E]G+ߚTݖI7h~mݿtIfߏ|>NkH./mՅ֣,6tyl/&XLMȆw}sY~ea`4^=Q[75=Jk-!|i֒$1Aw (6 *j>xJ?5odӯBJGh<СYӘ,|w[ O<]ɪ] aՎlm^Q-M2Hb^2**gVROy4"}W3,դf"N)kd_3-z|Ǩs;|)7? <]jVsu][\G,iwg{y!d\!df}x^'!>imtðESjv+81oDB{n|q~|Qt J]+-uoIK}bQ<1[I*&ВcxH1tJ7ݽ쵽Om۳j˰)ToVtݫEl9O߲/u2nL>^ŤėVOsw$.qetq3$K.~> _O>|!tw> [m+BD6JHWp,fEy ڏ~[V~-zFm:m!}CXyu!d 2%a~i ^.n[mGJzjmp]/=cT) گ)]f%+5SMN-ʖWiъZ[]_eSQ+/ z}ޓ-ͭƥwY-@=乊(g.TM@?$_xz A|%b]jQ6T 5H崖/+Mm8^IM"Jj?u ╵KMYxY^jK_SHnn4K8aFd`|h~"DxMᴏ awcojvP1}Vi&Y[j"fKw{bShz/ݢ|G৉fךˋ[wϥj l'yؑ yß{rW8U$]Kk:iSյ;IinZ I( ^O0`?5 C| Ӯt@W(ޡuIPEo!Rbeih(hi\Ś5^I_z=ދ粗PO6+_.9!=6cyuݴe8f(Z{nW}-kj'%f ?xSھakx}?WhEh2ڋ+qiVZfo|`|;of8ͽë8wK͜-_Ej6?m ZE^f+M'U G l֖j9Ke5hx*xWE텥|[|ᗽ&áɧgӥEw4˺@<y_/;~WMQ|g;?xo:M_o6=B.o%v8#m&l>]~*kN|G:l~ I}8Yk;-g[|$wXb述y [ßK%G>dzFo&w}Ǜa3r_m^wv{kfZ7dx.xtae4_ ǀt+0q?'?wTlc)_? #WaDO?8n(R0Ϙ+_?iWaDO(c?K/>c8?eN<_?i뼢/8neN<?1?_? #WaDO?8n(R0Ϙ+_?iWaDO(c?K/>c8?eN<_?i뼢/8neN<?1?_? #WaDO?8n(R0Ϙ+_?iWaDO(c?K/>c8?eN<_?i뼢/8neN<?1?_? #WaDO?8n(R0Ϙ+_?iWaDO(c?K/>c8?eN<_?i뼢/8neN<?1?_? #ҿfχZm}eYJA,) `@ AM?Nwf Nxf7oع,u_^voG F`~/uXuNOmm3C;gNYDn{H[+lwMf%p6kv2@,DqHBM}\?g[SR0G0U聆Tpy(+":ks0zV7_-^qoPS$7ƿּ7_B?Vs_Zǣxn?c#E?G? ?_򐟏Q1~zƩ^+][zF"OzQJX,3G$wvj u^'^(дPwI!缵eYjAJJaFIY-O<;\Ko^ te9 I K.[uF/x_Qun|9km˧4QEYJR]"~U *;.]mw]B=7O[ݶVD>N|K⟆⫟|:5)YM_yR!t1Rv)w GAW7cS֣SMֹm,%zeן,MMLE>2]:-kzUkd|ƹө)E/VI6ͧ'nSy[GzE}~&lܟ C%Ҵy<=c.REw#ݸX4h;tY`LR1^0(xW_8ΡjYKb l4E7֦KVf.&Us'pٗn ٶ-G>c?[=OSѡem4"X1LUe PYH9<Q&/LѾx+LR} ^uİAiW2FX' 0 )M5i>}95%w|Nr]-}ךi.x4HZ}Kedr\$.cbD¿oS㛏kڅ%斶ַ^t^y.,+ewW:i3|<o>C4G 5[EdhY0.V6"Ѿ@P>|o5^/;}oC"KgwYVT`'F@dr,sUi9Q^ݦʽK54/K'湔[}3 3ŚWş-ÿr^ZlIlAG>K.z&??kk^"}Oжj2̾" n.oP]-HH0"To349_|?:N؍2Mm.H<['me|K+{.n#D#M7 :_ZZ;KIuiI#dB"wHHG___k)C"[mWW¶/,-o,sb%G&W$21S$V-|2>9%uɣMioZE2CZ2,aL mJ[ĤEUU[Qq__}r27^m h?g߅|#k/~9w~#\CcZ[C+v8(y"TiG/UN>7xG4o,u -uI<9$QjF)"e7[fS?o~/>|?l>*SxON֗OQD\4ҧ%;~ <_K >#:߇l罸] ob4eّL$*K_ã[TW>:罭tg׆ ~ۧGw wòv:d6BP&k$g"y+Ě֑ixD>(x3@/A\MwދnpAo1 '5KdÞK [i:<|6ܬ#m-fA ox*tob|?&iqN ;C$hְ6 źnQS9|{oi)^ti-6ro4/-})4sɳk!^x&{ZnfOt,i5͋:E1L lkԯKӮ. mJFX{]8Ld$XQ׸wdW̿Q_՞5|=P_YkxXVH*Ls969p_*' E'%ԓQP0(((((((((((((((e֮7mFk;?)$&]Xr0"A(Ͼc'>{~  [|x_źP/6-^M ;/M+;zG_~ 'ޅ<1%Fӡ1jD xVFʝ+>)}g."chӽ+2(ϊ*Yàƺ:>*ȩgcNouޡ→ au9o?C~!؟9-/kkuHo/o'5/xncMB~<D( 5) erOTLcz|>*Wk`G|7?Ꮄ/_Q_rjw1 = _=sZtkP~[pW>Uuokjo?o3ɬ -6.ѯ.%:GV2@̡sF3^R5_cï];MN-堚&]FҬLNW )mmM9*qWwVqş' Gτ~ɩ趓v}Yܶ%ԷtEiIB~5?? sw4n6BkM>+)gX^4u^·GkvbBkm#|{̾<;h7][]Ee:uʮx^}K$\=!/AesrN N0.դ_wt>.;%m0Efڴvgu{kxgC_|IOxi:ai7SjvW-&ZO?ßr][巇[K?KvS\YͮK Oŵ_,ny3>%ѯ3:!4=3Fn.g6m=3A[[["D]o?^߄ρ5A>%GojZS[kԮ:h@KHSwrFktTz8IF%hkikoxO'1V߀:g~u}QgK35$0Zj [kO tk}[Ae}WxĚ*wptm Ym5Ӯ^iy Xd!z|F?~AŸ_@n+:|^׷6Z|rZ(cix#G?:?{KA//;>FSL&{2Em#YI0ػN2j߼My QZEs[_u QWW-iM[O'߆/otOVqu ך?OZFe1I[ g^D RöGyp\Nd ~:11f~A4|_<KsxE״4V|E] K{UY4˗Yg1""IU=K?[{j_Kw9+v.f z!3Y⛟%|.se:m B=/N[3` MCov}i/x[Ƿ ս.g \y_g{)L3F/jITy# 6:wMF%ōϘYav9!"Ec/FKn%}{(WLrr˚ZWdުGğ¯Z{ggjN%X7+ea<2D"j2?qC:]<_EV PVe4)5wե&a J̮ei~خj8Rj6?^^?c^b=F}6cs ޙn iitA,2H? Mxs@_燯t=[_ ^;..%Nb£u50çCI5IxnE ]jf?oox^}<=KK·7Z4W6okEuRE/-KM68]{s?'O_|C4/'l"LOFٮkbhYIhRݤb*_D4~x;*e#M؋Ԇ8/$ d Mi~J*sŴ$Vn,9jW7wJG0bo/tɥK ԭnDwH𕸏{_.c }_$߷]_^?|70$i/om 2ri2#)eJ| kZΓS} m?4{FQyFUGDj ImM[6:ZƋPokm=h4 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( >_>᧹6i/A4<c߷#v7gQ_GWͿnsOX߉6xFCÿ/5_-+K6}":ҥP}ɫo5]ư|0Dp1C5AKao_K\ֿ%/\ c^u_ \Vf|Xxg¾ VriɬҫGE%R2Az.3_47Nj{-]bgqPA u &z~:~gFIՂV:o))CDk7>!g࿒|V-,aXRJsPg|^'mi,?aL٬b2an/k絀}"IR_>ظ<= R[ XWX[gjm_7 :>_<3O5'4ft:hu]U8#emeq$ 7ڢvnzY/=}u9irkiߪQ6J&j~xƺmu i-Փ%[Yo=ݹkI:dLC_'<''Լ/|?aV𗇯l]^[xCnױ7 ;dYcZQ''|@񏄴 Sᗆ=#Լ^>Ѯl;$wI?>x~}ׇ h'>"k0Muztz뤲^Dnmx8g҄7ߤիmRRrrzY'nZ;[K٤ޛ-]W?;X~.M厛wGs}M7mm/e{[7Kee!;1`E%_(cx^"}Ğ.Ӵ-D՝Zx|5c=4۩I?x| ~zß||G6 Aµk-[9,./,Ķ (xd#|y_F??K]RG͠ey5MmE}oqdVYn2Rȡkq\]ZR?4TZ+zs8׸vQ>-?_xP?CH\[Z-KmG1%J'k\qA~.|N>78,5 m,E­w?whR 2t_6x/:ƶ!}wW»oꚹh]ƎK$ #,@|MSx=t|E&H5Fҭ ;!m kxfd"iI̐F*jv|UzViw{RDy}]tU{n\~_&G<ľ9#Kzՙ%ԯ$ vJ?̠ 6/{A-k+_"SZjEKarjڒd[,,rjQYf6]J@-h{}B@_hVFMi8aKtDV f ŏC_s4: FgC68"2y#LY2^]=۶ֹsKj{\[Txx[|Ckw|=$ڍπ"ԭU)xd,cAek]YlWhW?Oq@*]݇|/qm__AZYk䍶@ROuw,Pe;(?h }Wi-~!x~c=gW7pjMy3CcؖyIdiEz+wJEi&?G{jNv Z̴$QJLS#^[߽obfܡ*_~A~ɥ}l}}W -柡|Ok͡x[HZ9%QpbQcƑm ID;KX?<- gZsN{&WWTb}:Xd{I)nvm~~*L|ڭ}jJDÏP5P-m$hc:]_@n7o$rCo?x#Jm>O/'iNWV(隕wEEߚ w޶^mٿ6[͸}[_MNw|$,VD:6x즞4I5 ;eY.\igH$L}ؓÞ1Q8bt5/4nӾڥ,v,MO9r_o~0M6d7>tw0nI"6Ḗ4wɂEkJ1sʼV^*6gZVwVѺgwt׽+>7k~>|:q\ZNi6i1XxU|t[>PaKK{kj[W}Nhm6NL`e9vr0U +8IICE-.$Hs_aER(((((((((((((((ݼb׸WͿnsOX(C ( ( ( ( >*ȩgc":ju:տz׾\n[4=8 b~%JO+kuHo/o'5?_@=qּ7_A?g&Ȏ~<F!??xNWQx9\Q\=S@hDuaU!wkW:??7.QXcz#>&/3z(? -+k%l}sn!KהC /Ə;ciڿ~y~fٻn7mlgV)s][?֭D7'SZk=ŵVuNiWagj2k%R*Z+~ܟ |M-kCox~mJJ4Xhr^L(D c" h߇4f^̢8-|DG⿋):/|5ZeEPMKp5GV[z췶[^\a'ʜKt^{ѿnBmEe:][a,b+5m,t[|On<=~dTMAH}XG2\\L ^+RLj65 ϯھhZm$ev)^薋mneeCG_ūcKh&梫{Xd'W~+idWу̾w!a'iMٷ_]){;|m.`G~|;|Ruk]PIf!? 7~;ÚfI6\[}SHԧ'N ʫX+͒\Kwa6>)[h5t>j:ŻKCׯF.)k6jPFu3 VkhL*QמI%.f὞Rm9Goo[OQ/ď5Y-.5HC!*H° W+AQ'_Z/urN(^6ylFAa3C*Js|+5χ),FďT6"u1v(o B߀6>2|WwMR Yܷz^|I41t>}J4)df̯}{~.p^sF'']v&Ϧi~м;ku+h<`\؛IeB&;>y$xnִ\^.odh_u&gk>Ӧ^h:m*@JK59EN@4?d_2Iwy?j_M};IA^gV_77~ٿG?i)|)_ m[Awzv->O=tRěf _ljfo?ֵ JV,&I#滨~*Wk`GaaWϡ%륮k_tu.3_>מ,| gִKFX~]\\{&C24RR 0a־)s][OV>-7ZLR.~xC\)m=EͿsqS+G{]&mER.JK ?7V5o >?[ӟC/m[:6ITQyl!q<ѳF_:Fm/z;YмDbd;j-_kEeMḼo_Mւh^14BRr}ş_>3$6b+ rC>ʹNef$ʄ/je+zMdQКS뮷z+|*G|w?4O>G|w\hZ~-T!4˫G}kmJueq{G>xރOsR_ˢOiJe` XX" ?jl[OOAӗG<]^]idmݒi^]5֘"[̋jxal ?^)uđu+[Ru gMR7 k$r4RP JNSj^efr識ݭruwQ}綮ֽڼCɩX𧎴] -ſi6haVXZadtI'U8ǣmUիjz՞))/g|W^ _t2}NYc:=;GDHVYEۙ&hȢ {M? KÒ`Wڗ-)/k)#B ٲxZ} RyO\^Xۭ"ε0"-ͻ43 ;_&[c@W\x~$vxSXpR^#jqYnwLvc% UPJONi} (9Aw߻v秇 GgK|?.'xwB|U&-%֡/Ltv2 q%0obo)U ~+SᏇ,n))jVobH宺sO ^+ĺWͲjrܬ3^#$cGX*%ec YͧM7DWk |J'k_J_  =|fx{TgkLt_VjWRւGJdP$_Djr:ۏkWC˻+{ XH$$\[Cq' GTIsEǺ5>Ivg.?N~ ~ӿ0ӥ^$Oֺ.50/$h]/Wğ>]OOmYu-S0cT[ƙ`X-VJ-TFPxo@?PhZOU~>ˢ]X8$KGg~1aSC>gD>Y^=ں6K[vkpZhDݕw0h?Mcž<<)gI4GĚއ{çG 8j(6'l?PhG"~*_ѿyw+_oӽM٬gʚ~ }ik;ݕ |UM<_& 8ht뫜yị% ?Ph\؟?*{ocD26}V?cLfM *!NL:O/cǿn5"[O>>Z}ݍƿqo!6>drR,,\Fר?C?W'*5-*9REъ_uwѷ1Sܖ^_Jˮ5J]]_/IjV簞D-}JN.qyiq$"ēfxߴM7zI,.U[4kQO)4EmZf_`-w"fĒxvn5{ktmVxZc"~*_ѿDUECƿ);f޾]Ҳw.TvK{Y=tVVڴu~wx?^W?ྰ񖙯MviuP׾^,MܱIb!\ǿW'*5-*.\<0=^H~-Tnޟy4W'*5-(O_T*ȩgc":ju:տz׾\n[4=8 b~.?w?mnQ8 b~.ୃ?Pmxn_l}|$?QHoǟ( ӝG!NwW) P?d?,?7.Q_*2NO6_xjw1 = _=sZtkP~[pW>UuojX)s][յ[} J-,y$U,O`&sQNRvHvE+߂?Q>|Ao R.bۤSJTBn_B_cֵ *hZzViwmi:B,~ryjk]^ϳ-mmomo)M;˝W6sx0iw^$6O{!w,O ,FDX`8XŮx_ އkjm-n4B}6KzKgdteIIQ}-+^å_ݿ}[E| ?>BF_N:{i˨X%-52*SIT4~?t#\Դ{{O{++F黎s+HfXmNJZմm_>k/&ZιQ~!i!HҼ[ַbM E$3-`r?zlU-?c.m'mӣ5į*yp-1& 'R~J\g-7ߚɟa\Ţ躏ol{iѯmL Ǜ%m.bc>T{ M5'}PQE((((((((((((((((((((((((((+":ks0zV7_-^qoPS$7E3E$7E3}3D3 =) es(7_=C_r4!FP_C5Wu W޺c_gOOFM7K{3f Nΐ#F>u@XjS4|]kៅ..m4 x{>3>1|,}΢>OQ(7_?ߏ?Q|A;+-/~M_C5ߢ?|>|6*7.Q\߆8a_=sZtkP~[pW¶>Uuokj"#Y|)a][^XmcKm4ѧVC4ApXC&#5隯.3QZap4 $pAUJ%85CMY k_K~.A»N$״ mFP jAo,+ Qqeķ:օ'|G\Jח-ki Qwk%˰kl8AA?&H5N^ SK^ kb嫖zI?/QZ| Otg 7 wPM XLot?rk {:>iskR6i[&5+UW9$H0vA?&H5:Ү޲ROeVnWj1-5?/oߍz4)] -<=xҴ[S4DM8)_xd%ES'[ZCģPvK < Vӭ\I7=f}?fA?&H5k񮉩ak~4 .mR/^ijPjKq Q$'0@H Cdq4A?&U$g⬟[4N嶜vᄋ]Zj/1+cþ Ojv|Z$w@,$.m3Ayt 0X ?߸? ?OZJm^~( _%ﮎ?)6wwkio?e&Ŀ)^#{u2FK8 uP lϕ1‡H5 ?߸RgcEqj' Cdq56*cEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEcEqj' Cdq4[.v4W ?߸? ?OEc\jC ?߸3uvJM",8 t%x|3 |HlxW[״jPz=́h-m$h-`lՐ"\@*Fxdž|[K/KOJMgM.tൂ w>OQ(7_?ߏ?Q|A;+m A2~^} 7.Q_x]T= D" ƿ xυ%zϡ%륮_ƐVگ[O/5ޥյ>uoMı!Fp#aR5^>!$;bO?=yhEEb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`Eb{yD_0:Oo?x'Q`\_,a?cV?=yhY^.5_iu!z5K$7}'Z} Gx"I?y9QI|y9Q\~sU1ȚyBP~ j~KsM'-h[r2YGo9m\;N__i<[]2 ~ht3Ua5mD)"HeFVv~7w$߲?/.Jq5$'Bt'.i'ugw, sGZ!T49 a==Irz·O_]T#X/%zLZ ?\4U$DO QOYJddo7/.q7¦rW߲ 5?/_ S?Y4U$DO QOYJ[1 7쳟 ;&goe;k~/?։-Oo¿TM<+UG =g+Fo\+Io`QuA?iO<)MDa*'w&Ȕi_?I?_k?=E,],爁?_q?>*'_&Ȕi_?I?_ |~37e-._y<~i_?I?G&ȕ#r $+cV/a0|Q,gu/xWz"Q '%~F< X-'żEZ '%xWz"W ;'OoM<+UG =g(¿T!oҒ(?/.|6~G u/xWz"Q '%~GsȩĿ/. #7/./Y@?O QOYJ?4U$DL._;=uV&)`?er/.>( S?N4U$DO QOYJ ? #ӗş/._x։%O1¿TM<+UG =g+;ς?07G%ao.Z'@?O QOYJ?4U$DK>+?]*~7Kk~/?։%O0¿TM<+UG =g+Cρ07K oeoG~/o@>O QOYJ?4U$DK~+?]VS_}Z'@?O QOYJ?4U$DK>+?]'%ao./Z'@?O QOYJ?4U$D⿂#fX_?]1YO t}M?xWz"Q '%~d uo8Ok~/?։%O:¿TM<+UG =g+Uoc⯃C, S~i_?I?G&ȕy WexCS?{xY@B #O QOYJ?4U$DULuc~J~;/?.?z?4U$DO QOYJi9[w_9J=_~`C!WտG/&Ȕi_?I?_sI?eT&[ q,RCWG&Ȕi_?I?_m%7-r?aA~B #xZe/d9!8##=Z_#W-7-v2 i<}oFszvaUռ?C'uTI, 6-e<*lsxnui-k k x"M񧌾ˡi$7u]#QsIv\c )2,u^UODױq6p/KRM;6Jϫ|O|x9\QX~8|R/uk^0nl\\IyvYf" 8'nsNUnit-2.6.0.12051/doc/img/testOutputSettings.jpg0000664000175000017500000011335011713252032021122 0ustar jtaylorjtaylorJFIFxxExifII*C    $.' ",#(7),01444'9=82<.342C  2!!222222222222222222222222222222222222222222222222223" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|]s]FYwk'=p;I\s'1Vbxg" NT?LTm.5دa+,9`#&ˈe(kn[Ok56f=7v<z[ߡL:_m~{N];RgYHBA%Il^rq/WWs:[͈yf!pgzVsO9lGWѧVwkԭߡG_m~5t-I oOWe_-7'dt{TmޚmB3sn1 ۣ|n{*t۲j $,iE>vQߡU-6Gf]C${նCA#Nnklbne8I4umugJ/B( -6km~vӳv3wLU/IoVN{{ܓ AdOߡG_m~Kx[[G&`vWR}2}c Sh4אMWLҋ|УJ/BAA"C6|W|Tuc{s7r x^ւvgJ/B( ̢*)ߡG_m~fQG*SON/B8 )ߡG_m~eQʃӋ|УN/BF(Aji>vQߡYxr5?;o(Ӌ|ЬQ9Prqϝi>vV^(9MO8 ?;o+/bT_k~Qϥz1G*>SOJ/B( ǽvSOJ/B( ǽvSOJ/B( ǽvSOJ/B( ǽvSOJ/Bt"}Fo zu, +qFN9Ҹ{ס i( J&lTNJ3VOlHwELB3HoN#R־9iЧ([Y^; Ox#Z6cV#Q`C7|3G×Zn5 Z["$#rP֒ GJJ$Lck`1՘u-Fo9ຒ5[VIiw[Xu#4ޫg{\ZYk?uy4BkY]$EgDO [iRLb%մhfxCƎ#etOy ^hV +`y[K[*8hTaMLrKuT5paNN=oӽ- n' qX۰]QRY .a=# Rx*ۯxIf40Bhß4)*q#sHG`l#,+4 +be0: X$ey!~쑹V_S'_qc#$VΡl5-NZqunӍISʂq#mݼWk'>ϴ"IB+`0$Ns+/Y/onLkRZ^"5[˛"Dh~DUGs-ӂWm^ᷫ~FQPiwp< dcm&6 =$L5c|o-guqnllM1R\n^}$im{'/VՈ#p^<㹩R;oPn@^´[;5 [IɯqӚ7۷DцF{4,`y\s=yVit=r_uĴ!(dT}3oߴ21;߽GAo (f 8qUVnz7i|,u'tSbimcmkr&0E֒VQCX.rN9#i+D7R@XaQyk]JEBnˈ[MM\ҏ-+BFWևTׁm4EXĸ:(}c[^-wsjkng|AkI!@n{|(KSKE9iG]|cMx|5Ҍ©!?Th_O]꣰ʫ)|?&1}OS?SI?&*Oɧ>Dp?O?EO?EwTG'>Dp?O?EO?EwTHcu(zKW?}OS?SDn!P)|?&7~0§?T§?TyR7MTG7~0§?T§?TyR7MTG7~0§?TO?EwTG'>DpO?EO?EwTGG!?ޣW?}O?S?S,T,T\oa?O"(?DpO§?UWyEڸt?*}_EOQG7~0G DW'G*}_EwQ>C§?UQ DW']jDpO§?UWyEڸt?*}_EOQG7~0G DWI C?+\oa:ʎ&?ڧO"A=oOEwQ>CQ/xRN Rɿ1Eoy]ӭ;͜a7/ȧ7}(뺮GҎ|ׄ I%$mʹIOZڥޟ_@"h;$u덨wWp _];:gٵMNٴ8ʳ2&Y"hv7Wn)ฎ;yXePWR2#RdmF*^7Gx~mGegqr>֙x5u]~aB1"2.Y #',F4d/ѦRfԴ)F[Ǹ?kѼ=^m^km4}=#wfrFC(NXKdu=M5OV͎;Xæ8aCW!i_a4kSRq5ͬClI6Α49X3Iܩi,YbC$mu]O{:Y$UA >ևnWVaE4p-"uePI,Kq7Ym݆a=~AklIc@P*e ~v أΫ_s] \_[tl$ܨӻ͌:=U{uM!5;hyhb]@X/hv_xwFY}"̶4Qؙ˙dqڍ2e!ybiZVUB%U4$t海.<ǮN,ΟJgW#Q" #p ?sҎؿ'¾w4}ta?3g}I)%p]i4u?QEy| <GE`I)&ha6dx %]!O4u?QEy| <GE`I(OS]'?OTtQvi_JQE ( ( ( (#y8  *:(y| <GE;y| <GE`I(OS]'?OTtQvi4u?QEy| <GE`I(OS]'?OTtQvi4u?QEj[hO!y{̱/=]`,sҙ$ȧ7}(뽋r+O"/?jzOĬi.D8OrKhvl[qoZX 1aϹ)_E+8O<;]W6:}RX896< pQmcU7:0Gԝl"45|*"Ӗ۰EYEc5#ZҼIYLY:UKo vvbΉ]KupTYL1 sӒ<7iqoM*m$i~SĎkembX`;{VƲ0#áѕOO^ pG+Ua2Ra v\r%k\-nP|40%Ywr8$PH9Bz]\[0h%ԲEF?w1H.>|UZwkOxrM Bvnc 4 OBXSMUO&@ԧf ƪ8%l~;6-<剠1O#Dz4G%cC ( B1v%qk%]4 b~P@r]m}KDz`cKh>B`,wUl][.#<M2m$p.Y>0"s鶺]CjyeidYܖcI8 ˸tyw.yw..~cԴP^]E˸u-q?Q1?/?]KEE_ <R@yw..~cԴP^]E˸u-q?Q1?/?]KEE_ <R@yw..~cԴP^]E˸u-q?Q1?/?]KEE_ <R@yw..~cԴP^]E˸u-q?Q1?/?]KEE_ <R@@Q#+fUvmS'ǽKQA4h`x7/=]`_+{E}YO3ΫI]'NoQ{xWE9iG]__9:09*J?ȿ%p3dҬ0+U\YqKn`zqȫOpŽKOiEYI~dd-ccq, H :l~;yg^xu_kex qFFT?iEn4P%m!*p]C>( YgnݥA3:XneR: .Om֤Ll Sg-GrًD"7qpzh]N Xh"F2>WX wSOT *vbG= ܐ*Juyo-no濎 &H@dWjyJGlͪoƭ >&mPo݈Kd|H  UK[t+SSs"ߌg2?1XVa9}6UyvoUT>LmO$񮌺mխץ٦ReUЃsа~q­dP#8#z\ޯ. h6KAqq c'k|I ͸5jVyЕŽF̶QL7f nH )`;j+ouo[Ǭ^hױu;ͻ#PAI!}9ͽQuOE^74m#lF Bl䴀cqutV45ԸI4xn\i`{nkY[tKyLo!z-FgnݥA3:XneR: .Omֹ _T5ǓPАYD9`43;aWLiY}EƓw Y%0ی-Tl;xs~OE,-I[}KXeޱܤlW$d Vm5DL `G\jR˽ƙg}۬clc%ޮn|5S\l#HNHMvg9nIܭ yU2?`TzSםIZmL&TkYf;"quW^"]M2At1l)Xzf\,BimNM>a]o ON  uKidHՠmJK1rL2:`Ed$T`7w=͝WSIqm9E%"Q\+C ( ( ( ( ( ( ( ( ("wiRPuM*Zl"QKE{(?y/;)__J:b\ ȧ7}(뽋r+3OڞF1 Or/%IQ~󒤮t@`CATtRvpy7ow}iW2c|Fb2x~Tou?McHY EZ0D p!d*7*=@%W#YSgO]-t6M^[ݲ[+4R'*"0T{sr!¢dVQ4 CigY[Vc 6}cp*(s}%Əw*y-u+d.=8ZTPnKkq=\ ,Q"f rXX󍪲jZ&y_ښe/V.83 EQ4:4L9LȰ[m%sj8"xDy|v\SQ@jʹaosog.ˈDYaax>4?V[}Jm+"<պ(-C٥Gx}f)ab;GؗhFK[^Ahe2B.3e#5yG编Y*rFvGA!`Sdg: ;{x(bPTP0Cϼ ؛D'_Y6N 98rTҚ?f+m4q*('X?E9 FY6v,1&Iڊ'k6 6wKxcl8Lr]K$Pdcq JaIQHeiZpY=*($7H\0.Iyῆo4}>[WGI'GS-XWǧ+ޗavL,1u,AR<)*6%F".`Ubc'S拁k3Zx?o+G/˶ +dnv/#|Z\^X\^[[ZccIʣ~JM u#P%A6se3Q2sF8xkHv&<,i}() (nwq E,fކb[opၰTtJM常y wFXf rszŠ(((((((((s]TnJ)ȯ{|R_F+:?)u_K?sҎؿ'¸/)__J:b\ ф H?n܋RTi_E+ERQEs嵮R'4$ѸU$k@dISJ::+u> j?ٰogiT.UAَN*եt /fRbd#g`xçZn-͚+Bos} RͷmЀ M'V8t8w8i̳F/ޑYdJs Eszu{o,&9͊NBȪ]AޛqF5u{2O2kHI %L!# %(ivooq,ǝ$v䊥#qRjM_PM}:@Yo `IEpʄ`2bNC4+_}/mDdoȓ=0X..g|%#y2ƬS|aO͌iGIEdo;>(-yE!!d6eN_H3E_g>XIMi`%|, r'̻?(ѨJ&}6eEK5Հ;8Ceuo an,2ڣ|Hcn(d^!;FxdȲyf-pd-#3nR d!ho[nE mNlTtbUEd⸷ HN Vqz ( ( ( ( ( ( ( ( ( ( ("wiRPuM*Zl"QKE{(?y/;)__J:b\ ȧ7}(뽋r+3OڞF1 Or/%IQ~󒤮tQHaY.gPXfֲ[H͗ #FA ҢvW:- Ibg$˹~ ; GH؈Z;kY(NX+gkQCacm|A:wcZ}h"+&QW $O Oz,>dRLa(>Ǩ9=F\>M=<e֞VS<v"`#m-W@{:|Sd Vf'J COy~n.x:T]#IuF )UX0Ea7r[v܀Tմ6a 0WR3VrP𝮛q2-ٞIZ6"=b܄n&:ݑ^YֺoeuXmc}H6v.=ˡ\"41i6ZzY.+;@φ:zhlH;Kro$**g_m(^+$z\vM܈T.x%ׇ=kp7L%X1vϻG)\m?v|/wyeac]4Spn7 8<ޡ۽*Ltil4;)!P#kw|E;\A m3Lci[qvD9&R1RQEQEQEQEQEQEQEQEQEQEQEnJwiR`x7/=]`_+{E}YO3ΫI]'NoQ{xWE9iG]__9:09*J?ȿ%p3(%-!lgf:ݴW0x~gT#}!# ෥ 6^t/4Eo$((@* F s2͗Pkf 7ٴۉ2qX *-<tsfXh>^wy#88ŠM p8fQSENzFg+ g% 9<hZگxSYMo秘lz *33}'w`p6P(RW}o dB7|p "T _tNɪ"Eq̛~XeLʂ=HpxeSsEfnuGh7vsz%fc ) &5ĐũKO9m~p' <'XPYϨKqiᗖMa8{ͺ[hʴ'Vy Eb@V@Z^6 _ MZYwqto!$aTg`e,IO1HZK%{8/*B7NcưVY-Vj8U0>P y#p督hpJGs? jo%a}ov=J %r$uWݯo ıI2 3C"i!%xX㶢\89|[ f+$\UH8c 0s}>fm'Q5L} :?6_9cP$>QERҮclwBW}|n -t>+K 7'SmO %r3CWIEzݣ=]_h[=`h7y$° [4C1bѬl!޹'CA۾;8og{up9 ?yp(Š(((((((((((s]TnJ)ȯ{E|R_F+:?)u_K?sҎؿ'¸/)__J:b\ ф H?n܋RT-ΰ4t ~ _2EZ*/2EO>rȿ,KEEO>rȿ<_EQyϜ/.2EfT^d/̟|tY-?"'9_]`KEEO>rȿ<_EQyϜ/.2EfT^d/̟|tY-?"'9_]`KEEO>rȿ<_EQyϜ/.2EfT^d/̟|tY-?"'9_]`KEEO>rȿ<_EQyϜ/.2EfT^d/̟|tY-?"'9_]`KEEO>rȿ<_EQyϜ/.2EfT^d/̟|tY-?"'9_]`KEEO>rȿ<_EnJdUB,;|R_F("WetS<ėwOp_ Su?OS ?xi)O?ZJΐ((((((((((((((((((((((()ȯ{E|R_F+:?)u_K?sҎؿ'¸/)__J:b\ ф F~OPdӮܶD cyO0-* ld?J",Pzh?\ : ]sk o,-q;G}+>9!Կ-JYuO|ce'Tk I-Qn)K]7ilHLLΥXyf.XA%ԦF ʌyTznH$7 d$"@9$bBG g^ Ė)k:bM EsTd NO,zuḚ8 2J2p aI`gL%>@11%T73HB5{ _H{+{ԋOk仳`,ATHY<S PZ|Os7B/_?j^}SDT Hrwl-$-bY|#:u> tYG;VVU{`(̫d+J8ƶh:՝ k Qsۧ]ʏ6;N{tŤ<Ѧ(ȟNy<nՓ|)ba7wMonYv=YROEIEEK_ }| 얿k~(%߄ 4Z*/ZϝO얿k~( hk>v?ZϝO@%%߄ >k>v?얿k~(%߄ 4Z*/ZϝO얿k~( hk>v?ZϝO@%%߄ >k>v?얿k~(%߄ 4Z*/ZϝO얿k~( hk>v?ZϝO@%%߄ >k>v?얿k~(%߄ 4Z*/ZϝO얿k~( hk>v?ZϝO@%%߄ >k>v?`;SwFտ4o_+{EWwѢ<ΟJgW#O"/ ?sҎؿ'¾s4}ta?ۯ"rT9*Jg@QUu\˯/I^{kiG.Ն*څ\\Ɗɰ(bW9**X U%䴴.ıM *Ablb;p?M摩뫤 x$gHYAb k!3XD\c KQ\ݧa/L}tB3UA[#3sVծ52M_ YS[bKV4,  }n{kKy'x٧`Wqe` 8,#vQ%m>cg4Weldb?ǝ$~mXiҮ[ZJ h+̛.sNXKi4aP0K[imfɵZFHyFۑ6piukog%3Oyd^h±\#3nIcmڊ.6yuF/%ȗ1F#Uq,`?5K;}R=<ɞU@ˉ@) O QE笴&wQe*'G"F-9 \A}crڅqK,FX9RIr3@.rx6dom; UmV%]D)ٚ*f*6 M9LH%$R5 A[RvCfba&Ռʼn)d*[ ?}Mէblym~1[Som%#WG[k/ XpQ5 A[RvCfba&Ռʼn)d*[QEO o FX^7e%  8A[j2_}{r!>TqP Grp@%,uqGHլtmJY^s ݓRGbϵTK X 6S ݲ#KyeY%fUd×@,hq汛AfkK*\M6B  77 |3VJZ2ipFۈ9WX (<.YKuQp9{ KG&a-mk:^\89Peyv]7Elv"rIxM@r@E+QE ((((((Oޥ_-Z}o_+{EWwѢ,ΟJgW#O"/ ?sҎؿ'¾s4}ta?ۯ"rT9*Jg@QEuu>hr >37g761X3 ``$qWbe.=Jܼ&堆IQ`T 0$ggizl+<NdXze}ֳq-Q!S?wlc pUTpti) }u1 J$nMGPLKx`'t,jy=2>\ChwvVV1]2/%*"<6`TcH5iW:|E as$w`ϱR8B6ƈ8'gdMGPLKx`'t,jy=2>\-֜eGtDz[sI ;$$ 0 $`2JlnmmtY4ZG;-^NӴ֥sc}H7w^ٌu$N힇8h:Ij,\]Xy\KXj&e.Q,9#2@q8h,2N(./-fi6u)w8Fr8}>Iּ^;)V {- K(#HMPTHRFdn_CAc3`(e|@)5uEy$`$A!p  ypַ7Z}_1me@@.6e ere& ~ |'P'=:MJZBb%Tr`r@87[]ӯMYBjy!u &#*jm.N"֭,Wm.x-_I)9 Q *nE,W %Ɵu'-bM>=LdM7 oU󊍃 4XH=$ ʲBfu:;uФPLC͎Dvǯ<~G.bvF$ƥp3E֢) (((((((((((Oޥ_-Z}o_+{EWwѢ,ΟJgW#O"/ ?sҎؿ'¾s4}ta?ۯ"rT9*Jg@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEE'}ZFoRRկto->x7/=]h_+{E}YO3ΫI]'NoQ{xWE9iG]__9:09*J?ȿ%p3(nݢD8eB`}x<6m`%&7Y>wa;BMKER. @ VY @ y<:ƷsjVn Ksmnq`:cT9mn KB^HSawg ]K1JɋZ5ĺpmm+ϛrpe`lfޒ߮dl hbl#EQ쿳 8u:ޓea ާe|ncpF;P+4kIv&k#*09nM7[u7/S}%ٜ;Ip#@+_VޟK+"$x4 Q9*R]vOӦnT0\uBF]8,qiQTN%vBHbySpHъ I<=(Cwg\[ V47Mq,0 Uiز { lQ`Ԭ,]0b#a\|zN{ O ۅ+xc Xѷj(`)5U)uxQy@&0 qnL4Qp9 ?O#LjT8 DLbR;ֶmue=ᶂkgdem\$Bh6GD\(rIjz./|5tQHom_Zyg43PIdVmZ$53wZ2xҖikڄ^5*գBRgUi_|r8S4Rzhh/%12`As9F5(daL]+#>W 0wJW7qCY}U ӦiHVI3y1!A0%KtdVS@R *xqQxHw{#&LZSgr2* Aa 7zEΟ'eVmȁԎDGt~l*|uqFbmVs!Ab8 OŒj[WM+9'h.lFYePqמ`^h6Z RYIp3bxOVΫ۲,vsAHHP΅A8'Ҡ&.gmp$3db.]v[x@K&qkK hϑ$2fXrܦtJTi]F,M#pA Ѓ\5k "Nl|ODZD+۴K5~Fߎ .[Qиx`ȑb(9U-lݎq;ERQEQEQEQEQEQEQEQEQEQEQEk]EKQIVѿ[ԴWwт>)ȯ{EYg?:%tGE9iG]_\wO|iS$ _E*4ۯ"rT΀) ((+hyXAf<T"-e41]D0HfX'b0szӢx丸"%/$0UE$xOci&z yzSk4b _ߴ$.C*cljڢ|kg"9q#cq]͐-ΉwYOy*[ti#r6$j8"xDy|v\SQ@j.!]oKЯuQ HA |.9nזjfIs0n<ϲۤ[ghOh׈ukKn滑aC>RF, ;*8CcxUԵ= Ymx/4V0GTIZ \%DdVEܪ\G2++H<&v^(\_:ƷC][,f\Id($$`5 [dwz!5 Ln<x=+٭alI ;]́d>"$$qơU ;Qp3f'l?f7c^ GuFƧ5|I#Ei' Q'98#4+4(/'En$N'$sދmIL}mVI`2r@'=5 g/g}iQ'q&md2m],Tl*B׏ZjWwO5g IRƪKۼ'w^%] nVmZ±걀!•\\YZt$FN\9'hgkl֣ ށNZ" D )As[5,P ihAiH\(T05ZxwDxnep",˂0 0<SR\M7zem%F=#kIE_wZ?whgvxۻnݬ?ú&pnL˱HخA*@ڀ0W^"]M2At1l)Xzfl&4m2=uw/d"K|gE Я]hK~eopm}J屓GQ*;Oe-Є6.١h \ +mWRX${[6O4h\|T(!BM yzďm"+e$9#{JؚOWWeo}x7/=]`_+{E}YO3ΫI]'NoQ{xWE9iG]__9:09*J?ȿ%p3,.I "b<\uƹi~TY,qAhO3͖!"")\s$mlvw1fHШ'cE? oizŜSj}B`(Iq=jۨ3KE#xVibm̪y\9kw:k:|ΰ4:(UdI Sup nxf)_<RvZ0A";)ddx +0lRZkzM- t &qP_z4Оw3N5wj֣5.I#˷kdn:f~gu幏S<oD>r\2Ź2Qdt/m Wbm6*a ŀ둎M_V,.M6%2޼2| &0KOn>}IQ~gۈ`lQjGzEƣ-j?2xbL6d9#jwv&fh́͒nj*<uCN$a*&k/ysF*LNMaYڦ=52HrwڪU#5&jmFD8#nLG6uQE!Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@IVѿ[Եk]EKO KE{(4Q_eL_Dw Su?|'NoQ{xWf=N'b@u_JOr/%I\ (Š(yⶁE$fcB-rYcCI3i`eR~V#=G :*9KR(bRI#TP2I'RPEG<[[qq*E J^I$`I$ꮛ:Ǜ_yX>pq8? QEQEQEVn-I[}KXeޱܤlW$d Riޓyz3 .N3EG$D$<Ͳ5f`±Ǡ'I@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@IVѿ[Եk]EKO KE{("WetS<ėwOp_ Su?OS '~󒤨?n܋RW:(0(;Y32O,#Zapx9OBмOaojzyX?烎_;@J]X:j&/| BXɫT5nC3=A6E1YYB~Vo{)K{XeRG"WR0AL{+I#ahheBP WⷛH qsoc 2L'Ce2dpO+aj˭B}VGz"'+Iy a!X3W6[D*92<GjNeV>n<ϲۤ[ghOheޯ.WiSU6&E k~cr2Ashd1(63WT*Y3 /9'i).zuApP$LTx$88^ ; [y}Ш6Iː2$}M@p4 }V=BΉ{{o)99am~$0|tݭqeX5w$"UT1)DcP>\>rGoi'X#P+/ ~Wu3^[ak{ C`}f6xC/\Cg[K{70EKl’FJ *O kzj o(yYgq;`>qnFGgŽB&]#&Je_iYAy>6+tY$rw09 \ 6 _ MG.ⶱo/*#y8z`gzW6[D*92<Gje啦hְ[Itl(ͦYj6"INs4.|ݫܫ V{yUVImW G 83tHżz>(#[d c%h9geiZ%6d0F'' 8=QHaEPEPEPEPEPEPEPEPEPEPEPRկto-E'}ZFoRR_F("WetS<ėwOp_ Su?OS '~󒤨?n܋RW:(0(jSZ٨.g ʇsONxԏTS/V}8[Vw/Ѽ7,m=Ӣ%K"2=#^Zo' .k" t V2r7uVM4 `cΒ;Yd ERHc) p4?tWeě|mE*rH + ֢W\\={y^;y-!Ba" 1ᱝvSkx>wfP@%D$dr,FMf/og_Yd/NsnqGR$DufH]pUdXu-7l-+9o1 Z5RFK`@k^AַpZo25RS8^>#9Οso#{kX$1G|Jʄ~$YK&I-e)3BIrxFlnT]JmHqT+86@}t8w8i̳F/ޑYdJs Z[Gv+2YXMw7s[T7 "^xK{{f <#H$U);NkQTuK+N7"/6F("BCI$n88]2@$ C-޷n5K>Iex$FE ̠8$a/W7owϗ=;M.4k[yCI"3*,g wm6[s:#A(2[#u;=^MH[cB!#!HS,Q@Q@Q@Q@Q@Q@Q@Q@IVѿ[Եk]EKO KE{(0Q_eL_Dw Su?|'NoQ{xWf=N'b@u_JOr/%I\ (Š(nmaG0%CkA>k0IUm6[Ngi Ш$N2}+ Xt[H&A ՜pIh\(fks(NSUt'4MVbRDTa!mrn<;-凊#MiG"5kXr 1zcN.:޽ 7:%=4s;*H1shVzH] xS:ʹ p n9]n./x:-Y7k58p% H˫縏Gm֜隍ۦX-ܑ0q $$mkeav֩r!OZcB$g@8 A[xnO-!$}qV39#igIŸ#tA@ʃstVMlCǕq\(yXc]#ݮG&6Y!;8pyU|'a ݄a xٜmY)0-DAOgEt=oyg3i7z}Ct>gc cgq`<u}jɪ[CH"0d-n@mEjKH__EoFK/l."` b8&QEQEQEQEQEQEQEQEE'}ZFoRRկto->x7/=]h_+{E}YO3ΫI]'NoQ{xWE9iG]__9:09*JdD3++@>UtQ}T}T v_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_ he>ev_v_OޥYii]GBt&"QKE{(?y/;)__J:b\ ȧ7}(Xz ф E?xi+ "OKu_yIEdAu_kYG@W(?@VG$7U' ? ?P   H#nOEdAu_kYG@W(?@VG$7U' ? ?P   H#nOEdAu_kYG@W(?@VG$7U' ? ?P   H#nOEdAu_kYG@W(?@VG$7U' ? ?P   H#nOEdAu_kYG@W(?@VG$7U' ? ?P   H#nOEdAu_kYG@W(?@VG$7U' ? ?PR_F )c/ ueo:J =,sҙU$~ȧ7}(뺮?sҎӄ B(((((xLʣ84l_ꟑ xJe1ؿ?#l_ꟑ e?bTQ~G)>'$Oѵ N8ڴ pp !b w+nl_ꟑ 6/Oe[Wwv&nՁ+d`pF*}?PSkusn[Lp>t% 8ʕb{bTQ~G)R=S?FQ@YE}oI$c;X?N*zb׭z)2*)Jz=S?L~G(ؿ?#Q|gd3{6Ϛi~bTS(1z=S?L^YjV <ǮN,ΟJgW#O"_)__J:3OʞN1 (((((J2_j؈6ד1~ݜR;*$7U' l z+#G@W)\GȮ4BP2˛{%R4`ʞ c   H#nOs ያ:][A4ӈ_>)R) Wc74ۛs=e99#>s=e99#>s=e4QG<${.缟ѣ?O(p`e?OElT}{}QElT}{}QElT}{}(]Ò=?Oꏶ\y?(]Ò=?Oꏶ\y?(]Ò=?O˟'hywH\y?G.缟Q.˟'he99#>s=e99#>s=e99#>s=e99#>s=e99#>s=e99#>s=e99#>s=e99#>s=e4QG<${.缟lTQG<${.缟lTQG<${.缟lTQG<${ ybIQIIlNUnit-2.6.0.12051/doc/img/gui-verify.jpg0000664000175000017500000032363711713252032017302 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?kD1ᯇ~)Txu>\u+EӮ̴;97[lK$#ȲJ謨r?=|/?MtEL һ~޿<cXwR˶4ե D&}QLb ~wq]Ô)VIFI7eW[8Nuj! Sn]$y4vGvg鮗ȵZ*9"> g{߀m.KS$KZF/g? =pr~ZRɠ_fNK44{hwI)9Օ2+_~(uM7oui4mVA][],\No$bLrB\E8s^7勓[E+Mo|j!N5]({y.h==~şO/AiR|%_-#ɾ*vOğx/MT5ݍiZ.ż?1cG+6ͅā)Ce}$)-!`|jr}S}&{"7°/c ]b_?~ qTFj?mco= VKខ+?k }prm[\e:Np!19oW^ƞvP G۶EUďjTۊSb\U%XřV]Ihoi(u%v |5Ic|( 3c8joP?3Yֵ;9 hZM iKSQmp e;WW$#$Ϳoix;Rn#$y0Z&Q@6$汎"GYrw%{knLBB.N^jQ寣a'M/~ _u04žя.¾Sǿ|iN >ԭ5o3Om2,rs&22_Qd\ika]{vkiibi]V;V?9]9SK>a$o?4fk4 މȵR ??<shU>|4^ > i/UO5h/_r#_??9ק*_|>Z `XoGdըrMJWj_Ⱦ7R1Ao ? hZ 3&`)߃@hF20Ic} ɣ}_? _s̿ Fj?~1 ֍ը*k'g# 4oF?߃@h]vFKԿ}?3eODw7#Q 4oFyy}?dNy=c? hUfh߄A5w;2\>}^/;y |#5Ej~|3> S 5sF4G܄l/9qIk Go ȵo4sWB[g:>|2? >|1Gk 44G܅g; ??o_F_ z¢4h]ZQ&=h_r?Q|}5?yEg Ь%ǭV@|/9gυH ?gg7/#WGҬ_r#c?Ksw?o_Fw?o_FyV^G܃c?Kcw?o_Fw?o_FVAg/ 7/#Q 7/#WQEVAg/ 7/#Q 7/#WQEVAg*߳4/?o_FE1>G܇f< 2W"3{SR9^ך_VCY?ciQ#ѿ?_ooF9R$}Z/g$?fG~ 5/3?#?ѿ懆CY; 3wFj3/#?ѿ!JHMCRE"3_ٗ7O7#ScH|FjꄄGթ"K7OL~? Oσ@hOOهCoGj=li}Z/|w]Fy7_ .|!'_ԋqxj_ʾh|oY@|Gj?eo/4Fn KF_3OCcGj?de tG+V#m c tGG7D_GjRR-t)*渧/e?8#/_Q Z] xiF]ISڮ *XDhǡ ^a32ji^o h*b@-g?^<;|4GM <)[0hn"`VC8 o#dkQ7z ?ݰF\Cmf'x/1i>"֭^NYz]?:,7(̌ \Mtn竎 4'K^;_ݻOp̹(TͪwdE axÚ+{vV>[{χ~H-̮ڙŹ]|[V>*_&ѼAǦZm g!¨+E˯~A+Ҵ3~>>̿I KB/ XZlMWrN>O#(ǬN֩9)&e{o8x!_BPj.RT/+]}Mg>?xY/o4OE(CT$j{R7'bkqi>ѧ/DſZ eu %!0[f t- x6_? C}n?~9/nu>ܿI,GAyӗtםGڲ2<2fDMZI)]l۫3l߇eUSZqV5tVjoG>#-t/V#ew]^FO\Iơ!?ZO?W^/mo'y-`\GpV/Bq|AM[ջ|@O?[Wm:QpD}~;ęHU$ |m۶ۓoW&mQg7^ BW<'{OOH.~a2#)([pTS[%6.iKuɈ7ɿ>$[#>& &ßtp2դ~i$a.[BZmݯe{oe{'|/I|H&+5NوS%a•,A@tT%R?-Vdح6m$"&XՐEoe23|%^ZX#I#9zG.fdԤ$3ע2OAҤӋZl⒋]I+fGW|=/Aß{HmKíHdq 7֗Vlt܎"WB`ֿcƟ-O/t #NK[ܔTC8qh1ms~H9z[|KI>$W?oT_MmI%Iek[_+$%m >kw7QᏅw6W>[hARs5:lwqI 5=7dHko7>!DŽ.5B;g5ôYTܺ)9PpIن9??oׇoS$s6Zjŗ7Q}ێZpխdIY+%z.:|%}?|D=\,MԵ#m9crF.7$A?dizOSS Gk4-qƠ'u+>0dyfn_ISz-߆~"N "O^oESVwoo%KDbF*+-&͞k[x.~"E;>{yd-sOW0oB:U[?n'?[Vl>"_?[ҭFMSWmmgfwt$ދI.K#:uxZKV^ov[XR [Ǣn9-h m;?>$xW\s[xNu++{ys2O!dRI|/^O_60KxW:~Viјʎoۧ|S@|^>n|mCvpȕ&y晝L\-2HX1`G 'ß _¶Z`-Ú5k/4wF9P%C9F&}P V3/&?Ko7|D`ZxԿ0·f_y9ZԴ ~@lڭ?gwt?[5?}h}k|AڏS?]<=j?0΃VĿ07Z '5 K GmG).Af_>'?!GmG)./ ?\|?j|=kT@5›_[T{8#!x-ctm>g61MYvq:xbHggx3W/&??7Uso/+֏3]͟V??n᧏mGп\|K3YsjA&@5؏ٿk[SsM<~mGП _hxsv?Ο|@( V~?8oBU3o/=e=)wZ?> 3?jp gp΅f_zHGN}k{D-~8eo[Qtm>%ѿ]w3 ڏgL ڏ7_ _?@e?@eh῝ω~r;o] [Q [Qto>%OS]3&_?mG3&_?mG f_f^$7Nk?s -+?G S6?ݏZZ|?|A8Y~|A?[R:S6?ֺ/S>_ <=j?Lx/-:+UͿĿ9ZrI׭t<}Dx{>>?!GmI8oCUo/ZUMo›_[Q oK!GmStm>%ӃOw-?%#t_ω~a qO[z)w]<=j_S>x{Կ0ΊU_/e[ְA4x{ԣYڏ ?՜|K31n;jh||&[ <=jpSo/-\ŭH !OmPF|2`Z妭i#T Y_$yQ'K I$dxB<z?Cڞ|x¯[V518y+9\6.h^ *O }˺OW> B4'{ԿWCo>bPzQ$;xZ'og5["$lWv68#=ij>Os7<\Hҹ$'{x ªuh^Z%G ^ω<5.;xC__9ڏ@N41I$KEk`c῿4ĺ8@_3I>#_mHWi' -M>ue?e/>| QOOT[Ԓ_j$H9L=}/i/|ׇmQpI~#WmW)lZU$K_ a뗶eui çY4)s~ Fy#HS$aeէJ~]=lwdm>J?z߀^5'ƿWש^SYR4B;EFYQ>*xRԼ~/`G @R}+Q-]K" ĻRAXx]P:{W|Cm^;x?hrwmk]g%KIQ(1&Jn=ƞ2mwZmmv]ݟli?-*F'"ѲWR  CoޢtQi>na2B&|K.dRFykWv؎e 6Vi\CbcWqL(3otrIӬtBFy#HS$2h˚0N>-kuh৚~x;Z =G1ԴkF }Xn#ȼi@;Hb=+Z|=úOr]XkQd{$3]Eq$[^;ie8 H|`/>9x^,u 2YӼ kqow+#֦^a0w\;%Wչ&wYki:n.{4xD"gLv:އO{2Ʒ6,Rq區%f?? /!tHu-'ijjriOԮF6V4y/U ,J>jGw[fe4+{I[HK*7Xh:m5cs}R ].kVx62#ovLL Q7{xSkƙ>futpuplBE5r<*%yRw5~cxzWusa yv7LYb,-C,癏"ti/2[wjzouxXѾ$?"5^KƝ4[݈㶑[I",rFK쯴zkvzY6­i[qI]_?vWj֯F;h_|d񍆭D/<\j6!iZ9d^ވP!~ǾdkߊzǍk_ GMVZ~W>6b8ʬnXʕ+RU#&W r&Ӌg?Sφ:GCkZK}|٭n-X`K$ȥ3~CᏈxKԵj^ 4IU+$)gF!T6>YO$ÿ^;t{5ğĿ #5dԌ5ƣK,x"2>[\{f8v_hZl~-)'!pbKUgP ~~3&ሼQ&ƧCGKdȢe`Do5s#k?c;WY"ѵH{? DX{yuf HAX'Oֺ] Zi ] i~.|<7>']5y}-PM 2]_!x#:x,5O_WȆVK[)f,8..M,|hoxᾩtW'7 ?';K¯|x?ߋ |g{={_:͂BX_M8,- G=NˆE򵣗^Yjj֤f_4wNK|9׾,K=_S][ۍ.)DJ沇Qh1|ҩPT/#&O_ > }Qo Xk++M71)XmR3)`y~Zׄi9oxQ񮕠b"od}C,5ĉZ'i]QĘ ?z{Y@Oaizwl5Gm-/PZŞ@epH *+]Jϙ;[VIVIs7{_|՟M[[+`s#kɿmrY.kiV΍iwqVZDٲ pł(, }>;m_~c\–7jQylmD$ά#p^6]cKКs6|W~09|Ee "Fkڄ {%C%c"ٿP᥿d?Ú>"ޥ_>_$vK{XQe)+_k'ō.ş0|=烼IBA zVϾXY EU3Υ"2|)~iRx?İx3O mj,{ T.Q)9~?_6ק%+r{V'=O- ׵ R}OMm_OmTFDg8 O"$3B@^ _|??|7׈!k3#K|4|9.}u>$,h}Ͻdb}aFv7TSj/E~o3G-g??Ʊ?~dj}.˹ _|3X?Z?~{ ]]ͿZRms#hLG'O֏쟭—`so3G-g??Ʊ?~dh<?k95'G9LG _|O쟭?Z=..-g??ƏZbdh)vyw6k94s#k'GO֏aKs˹ _|3X?Z?~{ ]]ͿZRms#hLG'O֏쟭—`so3G-g??Ʊ?~dh<?k95'G9LG _|O쟭?Z=..-g??ƏZbdh)vyw6k94s#k'GO֏aKs˹ _|3X?Z?~{ ]]ͿZRms#hLG'O֏쟭—`so3G-g??Ʊ?~dh<?k95'G9LG _|O쟭?Z=..-g??ƏZbdh)vyw6k94s#k'GO֏aKs˹ _|3X?Z?~{ ]]ͿZRms#hLG'O֏쟭—`so3G-g??Ʊ?~dh<?k95'G9LG _|O쟭?Z=..| rs-QvOA_K\| C<guğ|?ƞdh&͵3qӞ_]#U_gj.υ4<=V:`45"Y® Nk}GB]9׏y Bo.쫍+k ctu6tKrXeIÃ󎆹OGĿ =ύth<0^x{w5 8GpI3A (ڄNК_#>*|Ųh:ƠQĖM 9l+gJ.svI][RZ{[? ??Y-? ??Y-y7'᝷_|1>jzoG$r;n(\yS9¤ΦXVB{oq[|:ڞ.Jӌs$oKiZn8ᾳF!V5IݴIWq᲌OժєݓyzDMk'e?ayh?aykk Iɮ/SkVO&V)$wlLr.2842Y?g"q上6YT=ʻ) rz۽&6/I[[_FWkۭ"ǚ8ZӕuJMSJ~lΟ0<dlΟ0<dlz؇UܫÖ+&y{W=Kh4[37*V?ayh?aykgƟx[OӭZvQІ34;nFK˖*yau1H'S8oƱ ɤǢ]vV)e;ؼ%/ L282=]9_n^ymkv.]jTݩaF#߼۳Z37gt %gt %~pi73S`/t9$),=j y7r[t'д|:t-wpLﻝ\ɾ~cݭY^tUtK_o V]F+{5~lΟ0<dlΟ0<d& xa 죒s\Dwy#wD"1~Zg-o4z캥bRS)1gr]n<1##ԏ<1򵚺w49*;Z7tkK : :}k:&m%.֡ATȓ%(,3;5?7!:A]7EVt)sEnyD¨Ki7.҂{e  QVRi;Y۶o9 : :gcGCדRa'Cyat-eY {fbH ĄfxE^4!- b@B", isN8-7kIv;4bIXZ료S[-mgt %gt %H~ x:h 9:hYB zF1ڻ/]5 kK;"m/e00U4Rlc  ѫ*2[Z=4vFHէ['<# ~XxJ,M?R]3" ~W(_UrA-z׈5? iM{{k@E wER4gfguNMy?L[WqCL }/ Nv{ jֶM//R8FY $@_oD=G~ϺrAn$)mOı .8t⿕> $\|wA>_w+ҭc|f ѯc?6O,Jf?:Df4n,Zfi:$Ke47duTdIV(rGs_J? 嬕OĿ+ sPmt[ 'spwe GfJ)ooǧz0߷5I{n=gZǦ:=Bb[9u+Yk[*4H__> |>zi\w ϝThbWB Ex_a4Fە4JVjDn~s9 R9rPiYuӶ{%w5?ZvIώmtMNج⅁]2MBW դLu]CJtk4[\J.VVQΡl66@C/ .{)z&Ѝ4q Gh1RчN{Hq77oV6w:Vv`hoZ5#!X¬c 1VTwNiIJ-RWIZ‡J#R5[j6mwnϥ~]xrō~4ծ7NטD #]l @;A\Ï(wx@466W {ou,d2kuĉ DH~R5Bn-5O=md%T0\ksin:'`5ETi&7o_ j:7o xjvZUWGէW6i-ʹJbV DjS.$,,%ԵqIZJ.-m /i81qBiIx6M;yfK F]Hҭ]r qȣ[|F amn|ui{i)-eg4ݱL݆?-P/3ƭl:$4Ŀ߱;?[~qi3|q_Yx K/ |eZi$IIF d@,G"-I%uhZ.U_eiR?/o).G۴xO4q$ el'*a>.1t-۟ߍ5+6oG儖Wִq4Z@D6R+4neȒ<~x#ĚƍO ?xzKKŖ:l2Ii$(h$  /ߵ=x/izው'WԵ 59{˓ K:SNWN][6gJx٪}eC C۹nR&:LE+Zr-2yI%\m!79]3GLΛi_z1wk$C wjUv/G_iK=J:%u=C:ma6|O642Oyw7Ɵ]Xio1׼?>Se;ix)˴Y֫g[mJu5r]4Դn_tHO+u= kZW|2A+}$M *e;F ؀`] R?m_ᆇ9Moqwqk##rf/HGȟj?WZįxVSɨh~3GjYӘ\3%½-捶|Smk_7.%'ڛi7osN[?6~MI寊,g"XJ'{OCko&Y>hcPRtmࠟ ; a{*ChUOk-aVyd,&fC_ZZg>#6; OvjR7m] $ þ,ZiiZ;If"2I{qmj1弢Vccf ,VTQ+'wfWVlΚ~ST㊩ʠʞ^om~PEtOWլY3Ϧ..Ĥv;l ބڵ-iޝ{iV6:zr$-u k>Yot xϏM>OpEGi 9fDEyPx #n^8ay߇ŗ6,6WPC$ q*yFhQd0ȍW^+⹜ekԺWu燆nXmi 3grmvk?Pp5M"=[]֬Ev9-UbV$ن晱qn;| Ӵ[9= T"KXbaZ`5+D'<g[?{W6:;XŤviDxe2αFߊ j /Hfw ŝ"߼ٝ|, fiK]o{?uok#UjG>h-)%4ڽ?#>~~߄.Cˠ"lXN.14hZ9Cy g_Q?mk7R6RZn-`IZYb;#!ԝ*ZltK.fk֊^ҧER.|6 _=bZo?+S Q;ZEwO{.OGcq'6Z`H) ۹Xg6=IKidkxghPtpP~O_ xs>1߄kpx{G\,d%I7IpVI%BQ)'kï^|IxH3jZ孥1y1ªq[NT^ި|~y &mw[޿H%ukt<~/|е/nO7Xdth*YY R+?a_~Ț}$yKS7k3Ӻs#wߜ;}b?ψ5ƷC@76wZYVQܤ EqqdmvOxVi1CŠG_דYJֻnݵ]t?L(ݥ2(į'o^'@_7kkO/&OUb("Zc$׵|I>c;Zijd!8Tv$$tl}`MR U#X?7dUWS?ƭ^$}\is^4Qkg6S ~|ދcdUl}`+yXXm.ZW/t]BeU}Z^ DrHVk ر>U|dxgOX km?z#/$*F |͌Jƣ!K;#tOF%䒠k?h;/_ֿ={ \G>~oQI$$gv 2I8z?l}`ϬUhtya Y>ݝnu 'SY^Z\0a{V'hnmGp H>e_܌]zr/-S]캫ԕOsߥϡ>||3L:~>#ztk nxr{+xE+Iy"oOv>~wiGG}#?oƒd+alS?4)IE&kbbm%z/LkWӬOOkyu3ZiBHw䄔GWgƚt|,Я<-7K[ۘ4o%ɸQ3fIQ1W$ߒv~NΚm/6{zYZ_.>0uBx'~k_hwnmcIn UrIʜ-so|lWūgu6a47ߛ:nuz,svmpŏ?)8oqZ/\O{rIj%htcog6Bkv 7Nb#=\W>=ݞ6b:bV־V2i"O k, I G@ĮuoڷZ2RQ>۴WϚǟx[ŒGķgV^+K$Io%ẘ Y70rz㋭SV,~jm]#ԥ_#S$qZfh8'\Vr8jc?M_W75Z3+|gz᷍[aktςm4kfWkRj"iIvݙL0`uӤi.Wk.FKڨJN4WɺE.Ekx95RZ5 YC {#QX yp3wOG&$? tXܛ{en(M$S(T dRHqv{?TջUt[Tt=՚o+O|;KK O׬F_[\9l^a1HeA\?_<|H_xw<Fa=R]ǙiSLF>l)'" }V%k?֛&3MOou򾗻G״WP^ >xő>K _1jw.gM EMÕPFOۛg4GMsMEf~\iV֯:hc`TťW pLB WPn]hľҴ4}Ac(Sj-OŢ#3G)đ:⾀k|IxLӵ{F/t.- XUbDGdܠzMHJvM/45`j*ovEQEQEQEQEQEQEQEo-^臮E_`Ks3?(ԫQ{I)5 #?a-?JK/?^3/ܮFrYk q.C#$"* c'$>+hG^5FkNm-/5{kXn"}^7F2 xgٚ_^]{IojMp zu+$\9oNͧ8lgkGͥݝ֩_H4ͤ\[|;$A 0N2I<)-=VfF|ci^,]R-$VwI{v%ñO/_Ο υ{)'R "[DҬ+"g7xO|MCPxa2-ƎΌQ#cF?K97V|F<|&4}_Eco~-ė0\x_Ԧ׵tk<[E JXpX620N?uۿS1o˭UτƥZܕn,E7R1VPȱz_>xSdGվfI|]wvќg|CRx#-n5eY4mFO.+K$Wd` 0U*qz.TO:k+Ѕ]t^׿FֺgԟEQM_]-eSdo -ܱYٱ 6k'}Kxg 7e6=M JK:K%|ŒOy/Zߵ3}usO+9D7Sx_f| o⑩@md P`yv׃Г%" .z_~ZtW|p{>%O>MVvZ-,e|+0/!&!pЮs^dG<Yڎ`VK{dFn\I.08-܄d?kRXQO \x~N'8 ҽdb}+10ދoKc_umO70Ykv.q5WI6d$2̄V)VQ|3vk{t8AF{3N_{kwGwM:lXÚ֥Mja8PX_4ace701.em߇ڵmO<]NG5׈-32]lkRBL+*IS)E^=TJr弓OٿMWM)G_Ge}_Ϧ:U]ZJUy}Qm]Ju[]Hȇ`N.Ƴx_i[?#ִ4ycMXη.ZO >W|f/(qwvlWWS|{y]۷?a}B;{im*CҎK EE*~?e 77vv}eV_r~~lAwSմ }?O{FH%Z_9LJ'?έ_x^hJ+%:OOs3GZ3-Z噈 lINJQR֒k-ϨEIoev/Z-nmmL[Miidi('ԇ4{ۿww^*I4nln_7AF4}U4 5vk$Wq6*+y[vtGzm6ܛ*EN5#-$KKmw? (u-X:麭`eH0Q^q*9&ٖʥ%}+s~1Υq{CnDNmeU~Xx/a-MF F*Jrsg~J(5U`C/A`׼I>c;Z(-v_oha"gHE zğ0hs 4o'^:dW73Eoooo4+HcbY$_ Uu?P X)YGJdo/5UHfCm%,@TȥN/X??w/ *+ž?iz8M|i ᮗxKIFyhs]iw)jsjK$pm=?KxM|Yq4iлӛO;F[o4DN8qg/X??w/ *6)M=eſ(*SQMi{KEedw/ *] 53?h;/_ֿ={ \x_cKվͩk>wݤmݰg^⿊~޶Z b̂P)cJ* ؊֪f9>\.pNi?t/X??w/ *mN7Þ- Y{ йv}V;EX*GWXԾ[F1`HAvP^TnWU 7_T_ U;g>eѮП>o",0<EW\.Q 7_T7wpE_`K"ɧ/KJ8>x>.((]vUI$Z"ɧ/KJ8~|E{Nx>!5n4[iu(ˊ̋$UčK~4Ȭn9$Go. \J4G.G,]ޢ=]VBln.gXUfBQʒTGC_?o\$f/g<;-rL烼:֚фe:%aǟG8 WTT إ9Ggof&ź^CcV pE<8xJM>KFZhxN UgBpVED:0U8QTmK!%鷑TVGYQ6vPK%|䅙XYT P{ "!c/Y~^̏[R}Gx-;Ѝ1v1E>Ztcvw}-&dAAծM";AdKfY6oeyqssW1GouO _j |bO \]zi|8hœ4d1TDWiE0+m˥o+^bj? 7Gr.WfA<7vȪJ*-/|+Lχ莧6N|ŌxUrZ_$AE/o܃{<߱_1 𖗡iRiuo,[D YA CoĽwJ@Iyr80̤rNvtU6 =}u%$-i顄 |2!SD,e/y7^jς| |4𥆃K!ӴH--#;#0$kRKEd7Š((((((((E_`KW/H {-2H-HLa+|m7v f~?w٤uմheYajp i/#Kcc>|Y˭CմM]Z]5JK,B%y-.g 2e6$'u oT>/5mlK>)vGcC2E'7gfpcⒼZ٭W ID|xZ+4V.gi"Aff\ k}<,5ϲ]͠X.$| n]wxG|/h&i~^. Wr-m2\o[.j MOXH䕢ٸBn(\0\+09N/?hw^ORMz+7Sa8/k ;3(lΘq#i)ԍ x/i|?ѼE{mxmmfxD8;xHYc$Df }}o,Q=p\C4 2Bv0y e)BiYYI{oeyqS~]kE񯄯+)ż;w-Ǘ'FDnf[ߎN9/^yw:cOx]L_ٛ^Dm7 f&D@N~So~ ~'4?xKQeNҵ˫Ǹ[;!~mˀ kVߋOkZjzQH((((VS}N6)P1o_O޽3O4o9יCž%?;zω?`ѿk@W 'ǚƓzvﭒmwFaXdp@=Eqȟ |<rַu?ms WJTmF`x A~{珅?|GxWhө/mnEnN[ߚQek_$pOտi՟q'-8Zֿ[ۯȟ |<r ',| _>cLzOڷ_ ~>&^L?#|7[D<%Y{WS灩TkrS ,/yV嬕9_[ݫ'wesHN\z()^;;}_ ',ȟ |<r5&4GD]nOZ?>7#{yMʤ)RG{у4k֧FT`+iO[+'왗'x[C%+u)ҴmUTɻ_ ',ȟ |<r5&4GDoĭnOڟ7#zu$(+nP;`іңJd*OX֧ T1it2 fU凡'U)ԩά^0j=m+?g?m ѵ[ME厉mmq(dD Ve8@5?e<߶W_! 0ʧҌǾ1phS87Y95{Tnz7n'x[5p^S8S)䢛jvɻl2'&?t"|'a ?7_珅?_g#ן_O_M6'ˏ>0y?NYC_,&;| cf<5&4GC6ulj5NPmFn-֗IۡgIʳFWNt m7 8Nۤ} ',ȟ |<r<}u|kiSsOo?ɹT0]H@|_g#љѣVf)H֩Ԏ2I3 e㇯7(R)i¬VV3J]M72'&?uE]>b4PUUW¿ }uS_&sO_#ιdml_g#эhVFUFINtoK5}'x[C 5BU*RUYS;~Q_^>@5?e<߶W_! 0ʧҼƿ<|/ƙUၧtkrT,/x*rwH[;IR%rTJirSƔUck6tmE~d珅?_,&;| cfcLzO>>|54 ũS9ܪGJ$|gM?Fjtk%F ravOOo4zəw18X|BXx*)ݧR+F]5HlTWO/x_ 3>_+[/6쿰M枾Gr'! ۔4e=:ңY5 0U%GZ]/k ;ٕyaa jk v*s%WFJ}E~d珅?Rį/~CҺaU<ޔe>=aFY ɨڣvɻt ;ٮc|Byœ\M$%U[޶Mdϼ̟_g# _>cLzcxk|WiqmE|VDt i_gasOfhg3OJ_g#סx~:t(6 7zK3Ϥ eY#+at':rq6[MNZ]'m?M~$x@[/Ora*T55&4G35F͸SR-Td{ٵgIk_nPSHSӅXjTf'tVoڊ7῏_?j~iy,|@08^w _>cLz1= (jh)Ξߚ uf3 `apu#hSJJV>jrz]Y{/j+K_>&^LG#|{J$!T{zW珅?=04nJNNk{t[;YJM.Jw8Ҕ^jmfԮM̟_g#ע~վ>k_4]?Zeٺ'o,rǓҊ~=51nJs5RJ߼+{dK;2깤pJsMJwHՔZ^Jvlݾ2|kLi^#Z/ݦx?j}oG4HS Uڤ ɣh׭NdNW.Ӝ)VO[3/N2'KKRW;Shګwʊ 1=z']k%kwz? Y$D![r>`qǾVTk&Rz8JqKv}'x[2,= >!8­MaN֥NudqQݓi]̟_g#ע~^>@5?e<߶W_! 0ʧҌǾ1phS87Y95{Tnz7n'x[5p^S8S)䢛jvɻl _>cLz?|kLi^Lo ϊ ?Zy6|!@؟.?Mj]|5.{-2L?ilm9fc^w _>cLz3o/VVYΔaf]Q;]ityl1ex>!΄NN0piKGoď]hvAnU#L%Wj>P3&ƿ<|/ƙf~=hգY s0B5#E}/{6 ;mx i vZpUҗDjQ_7ֿ Vw^mO`=|:OB(k|kLiF7ǾQZVm]%9A.ַFal 6""m wITJҽUgNOK4{mE|)xWD 闿hsO~i]~d0*oJ_g#WǾ=ѭRs\U#mot+}'xZ]K4Ru)NRkUۺҲ _>cLzOڷ_ ~>&^L?#|7[D<%Y{QOǾ=QNp\I[T}ov)}'xZ]W4NtNKRӻTWO/x_ 3>$x@[/Ora*T4`{MѬ)s=?y4{&eIP)a aJvJtUw|"nyW/H {+ UdѢSh֖\hcC9_E_`K >)f84sYI%/vN.9-85F^k)g(;KxY-C?g_2{#~'ԟRڿͲ|tߊ?'ԫ#ب}7[>=;_Fl>(,<; c?l۰nm_}_J!j'Ajmj5Z*wKI u.V4XX1ߌ_z߳|_kxOݽ=chZmugDV.2Ixා|i~˩1w^%̥&Lq1ʄ'I  7GUeMi]YAfrUi#c k&6kfl^8n^ktT~=xyjO+\ Ɖxr>TT\-ǟ|8Sk~ko4hX\(8y׎~ X||O].M?RMsnsYiPvΔP4_E 4ān-Dq[Ī<1)#E;W0}:ӔrrzggK.SݷS>3I/#Þ ~^hW޳^NLc+v<399/|Onj[nocNԬາf,6TojV{8x⮹K^6ֵ_K}zK 7GXgaA "U#xݮx'-,z_&\2#nB@RUI"qԦ3tKȬB3,F:t>9h}o^^&\ڸ~stZku1&џl_/_3[Bu^ũkhtZ۴8VZ,"6?j ďXxRƋ[%$n.o-%e0DKL\^!ONNmII-vVۗ{/jO<5iz#Gò\\Pmn1قȞi+/ o^{oxWEѼ4=XiI cWWdĐm-4ACtz'56i;Ko ]#7mì#eBN*D?~IwYFu/X44zEв۲젨]wr}e.g{Mmggj?ݏ*OnWNQ^X?mH|`>%|?oOg%xxNeI\y8(X`-Wo:3Fm#CKw}u[Aa#ewq gB^_O]_b旫Y^?w|5^"5S.㻳VHt#) ֭ 44QE((uou?An#n"Q@'\d>$KFӝy?L[WqCL }/ Nv_m_{EKO ?rWL̷#2!^sx? Z۟N?pW8O&GI w?0Zk?5^K^Mgƿ( GRp¿,*#gCK <1K峠8I$P]Yxot[9u.{iVXƛ| 5P#_o?_wNnrܵ}CET(+||Al: izƓAr}RhDFM(a`Q@!x Ѽ#@?g֒ል$ѭ!/(wOهC=cBoU"ӯm$}ĹEGfඈc_':ro?O]ϻvl"8ԃYȩ٫?L:e(%X&Ҽ==ԡ[У$л# fb~xVco Mk,Xdm.ec2V` 9׊?h eςmRֱ Cw sʬHlo !b3! R{|5]GL5u-GKkR[+ݒV"`Ljpx8}oSV\]py%,=s94^GS~!K{T_/+ Gčobe>\f[[˄ o ۿ^ͨjVx[:j7gn {X#ixfпU/WZ|0/<9oZg*{m;"U-مɕ;! v'ZOue7ԭ<]{IcyAw $EawU[M^[mg~wOowGQ^Co(^~ÿOkgza|Ak%Τ-&ecfgy^OѠo[[S8[FOE:>۩GRb댟zgğ0hs3ɋ|J2vր4x+k8+{ܸV/2 F F<:EB.*T;a?:꺯!esy-fI-|=Zg$aYb]Ā|"s9B4+8ߕNWvN|_g\7汌|-*]HF|WvNQc 9]u[į]kz߆/u;ݞtsǿj*/ʌaUGwW3'E`(6^m&kͥ)$In.>ph&iٸ(lTz)%<s 78[XѴK Mx?s8y>`s~bq?>$6_Lu=;/٭.TO42 @ʧ?MJ< άҥ̓R\g}.>jPyn1QJK-){uәE|"F_]kh}ºΉiỈyoNv/XbOF{W-V@~ķ:T|+75f-J{M.fOӮ5D"+{ty|4gcX5ʧBϯni5g5OaK;eoUu~vyi*0QU޵ 9]uoxB֫=;{zm>]6{hѦX*1 l0*,|q<#7J]je̼`lH7껈 2klGpj|NnPnNNmɻvߙ'8WV&[)IѦwnNMŶw&*k}º6wỉ`Nu<'3n`N;`VO0/n?qum7Vo޻jv7<5c6O.$/$ITI.^?eğȮ(gѓ,$%vqm5M ?-BNt2<[RiIJ;J-KfOF-EB./ᯊuwZ&o9ٹv*rÑ֭|w<#3x.oϴk􋻈d(*.q$ ~ 5#^eԕi5tյZ>_R J2jIQi٭5G|"F_]ßQ]χ->xFZ]Ϗ5|5gڄ#cFcsM6ʝn UQV(?)(Ǖ%6KK'5,F[bo++Xߖ*ߚ7ӞN*I.]m%WB`ti%D&նnVoVދị-N7l܌9VaY?ßQ]?W$p]2C Q<Ȉ31aMBCgkͬh7WY,粞`HDY$E`GN?:JhEoe '%ݹlJ)Q' :1-&4$\"Z}>Уq.u+|7⫭o[{ΛNxEEQ*v^|#Con'Û[_}x乀\@I"1]5>:+G\kBͤen[;)>WN6FXxu 4};9G&-oU$g|"F_]kk}º6wỉ`Nu<'3n`N;`Wy\ύ~^2Կ-[)5R}gW;"S0c%i~N)Z^8YtC*9f*FIQ2J:hI;hG+ 9]u  :%"'ӵ+2=kP[/jzZ=cXiIpѩ8Oߋ_ ocM[TOvo >nEJP/R5*QiPM5+&RMj akB jQN2^i2kUkßQG0/n?quשQY5B&"cׄ?UWow:o9ߵF 0ֲ>Уq._~1ƚ5-W檺' ,g4""*cmі_ pQ/w)o_H.^?eğȬaτ_(RN *`(hJ %w+/wE۲oZa nJ )ѦUܭ攥eeo |Uk3i&+Sf 9]ug };_fs>(ͭޝ;[&[ic;oH.1(2yA@$u~E62~Ru++%Pf",mOe|ҡ< M^i{*|9/v)oD9x}po,øN4$]%%E_D 9]u[į]kz߆/u;ݞtsǿj*/ʌaUGy4W7U':~HS-Yy+* |uxxƫn;M"O^$5dI\-kטH%v6@h Nҕ䮽-]rۚeFXxe~I8Qfҗ,j2++;6zG0/n?quֶ+|7+h~L_#p|6xuXK|\MiRZ?k}.d-jҭ|@m"7&_iGn5.ϹH+ !?O<̭$A]]J\hg{M.ZTYn1ej4ҒMNѴqIB)-Po hi*gma8ǘ1ڢ$[]%:76GqopHFC)A#sx!0*+ pF*dJݶ}[`h2QJ7"v۴bWmem>QgwRJ<.ZUW?_G)W<[?;ö1EcR3_;WᏊVÚbGi,,F Q"W?w">1o|:JkFz~ Zj-/ZOC;lҖaF.pʣw{Ӽ<5焵 wSԵkKB^_j3hcy!n";A1<'?h eςmRֱ Cw sʬHlo !b3! R{|5]GL5u-GKkR[+ݒV"`Ljp|Y`x{_S<7*Q+ $3C7 Pg /h(🆼)+Ki^C(()UGP0%W M,!R>Ҵ˻ ++eqmR$ڮa.OZ~מ,h_zo-whMu YZFxϒ;X :,yg77EuI4WsإM8Zkm}?j~ |{//5K[y4-o;8$ ݼKh^d|Kyk"(S <k\>O |ZNw}jiWmJY9VPɂDE i >k(.Eَ?w H]=N8ytx_QAˣxO-y vǨi76nܠUHc*q{Nv5}U%/;^<7z4xPm#LuK?xQN^7XEյVBiw▇wMWYBa0}bZ\ٕ|oa~? ՗MռW_StkWQZ9ZP,X 'Vړ`\e0xnC QK7v0E:W&.g/y_r^jR){?M|H5/T*mCRSQ=wv\C2K7+[O~+X:55-4^WI$NscZA,_'ʽhV?o/h~7‘xi-5t|]|E,rdݷV"9 pN+';LԵெJwxjE-dݦn<@6L!#2Z8F';hV캤Þ2o_vo6?tzN;m"EIVƦ#FHHh$P' |04uImKH_Ӯ j7d%P<308`@?#zw_ᵶ95NIw:\7E:u!:4^ORzVMT碍M!<}[B4&V4wj+FgCž%?;zω?`ѿk^g\d>$KFӝtҾx^ǟ|G_sJmF[JTgFX ehٸٴݻ?ujW6ˢwk^~CX<CNsWO.rúY4ye]7aG‘|W2|QJ?.<RmBk{3eޠ. cBMerZ!{tfy7ࢵ~QZ)4]7mu];fֶoˡW~VD}OͿ!jRd޸i:Nt`֍h3/Ͷ-*T.G y d*{=xX8tX[u4]$1%QXTaʊ r[Wѻ*%4o鲲m?3+3Q_j%ݎwAhoStK<#%0V /(>RZէ5L3kbnoX[aGT-!*)Aro5wfݍooo+^ AG|féT5|8iqaqw$w]4QpFc`b˾/ek÷ީio%;gqw$=ܰ5ʯ.$ًn#{} ET_*q+*iD.g׳_Vm+| ?mύKj9>xvCalκ2ipX*N  t|~9xƏ\/|_[WbIKmh$4Dqu)|$+7M8=\SiurR~NKwGKOck/ {g{=cB iAivүIey"gpݾ ↯wV6<ao7Z]Vk{ c[ tM,Wk)QEjESeyߍgftq~R;Oh~5|,_GMZ;I)k[9Pmny+Ne"|?&ֵJX.k$~?Lj>#j>/]? ^\-{r%G+p;"f-ܥNK(M2Mw|K?#Kh>&..R%XUbH`7A7'_z]€ȵo/"|ch_,`(SL{Z0z*bmn?JݞK\'| U\+|aWKNj|+>=໽^9u=.I{ GjB!Ou:gZg/uGvwBk ң/OZZMh9$NFIp-đ`٤ff\oQm_i5x?G𿇦_\i^D.]vu,%LrbQE\ͷi7VFZ+蕕[NWnWψ:xYtEuM Omcv]7)e f1@ubTƑX2i/xV|O SV8u떷wq.bY)u 9`O(DBZFER:5tkᾛ7&fR kv6߯E|C^|3K9d(ZQdSnLP@r(nAo=m1b63]Jӻ˨#qrύ Eus|_xHlm@]BY> aw&;߸4UN2Sޚvd*Pto#Oڧ$_[~~8G|AxKy)XjQ͎&Jaicc'o~#kZ_.[ߋ8iNPqo:"QmhOD_+ڽ|!k\)[o_~+~LM08u既C׌|m~ ëGm᫭4=;J&E6H1|c!iz|G Z} kLLJnL~mԊ%X9'Q~QYӂg )/*OڳIr%|CwğmG|iCYhS+Mj[iyQ129cY,n,^ U|߇u==_\hnb52Vv;mJȋon n:*~{ߏSQu;ڽuԚ-I_N?<Wc LJy쯮dBj7dZ۷4e!G-? !xtŏG1~64 {-2Lǧxo ߡ94{+1bMeҮt,N mLU͸u+h 1V]6.g=>&}>+Z*tӃ’ޫ?&G_߱_k~ eK6KNkBeAd$Ҡ.dvk*OIo~_~&C4xLe -.]AuJ4r6w2G(`G Be?ZC7UwV}wԘFWw>Zmje~-판E{hךubI&RB$qˏ#3umw HūƯa%V2+%('Vt҅Oj_ ir˱GM{5%-~:|C]{@Òk3js?6mmuXIl|A 5O&H&'1~>Ii+_ıkZ 5ehz\p$Q+ _YNVJr}~o_KKP㻿9m]>ixZok$1i``H}=,~zh;%NnﵩĆmX^Yo;g% +?fg|oˢ-M|\_7}?ߕm]̯+?h[bW.t߄YԬQdK͎ m^&y6w?v#F~o:76_h"]ʽhi!2IE]DNOML-*+_wo{ߣiOxI|aq>5u_:1 k2Ӥ#XCs(AZMktjW 7P[&s1iyea|lR7EUKNsJRnV :rZ%e3Mr?>oxnnm1~袊(( e_xO?i#?}E}ݻcf5vt(g~ӬG&^~45߻ȋwo;j (/Mo ~9'g%_jzVgT}j=?QJYfa*_NxÞ5ORկq. y}ζiTQEO8$lZ 5~ }7%-d*jmjZskoxאWٻ$E՚#ƿ[⧈5xoUUs.VI g %o2*+x' |_k-Ǟ>*__%EvoE$?*k͔ع2Q2i-~%-6G*qҏlQEHŠ(VS}N6)P1o_O޽3O4o9יCž%?;z}CJִ}FS0myF%OW_|]q:6l[\xqCu !H u??foM(+OlOٛW,@<+ίs:~/+?Vr1/uq_5 (/J,tnw M:y'/=ou5׭ג|bZ]pf}/EPEPEP7k/r}Ny~"/3ݾ6ȃo_eG?b97ٮD^gۻ}6mWoI@!xѼ]B9?g7z֬VxVZѮ>}Q/1C{_NxÞ5ORկq. y}ζiTQEO8$l9W<'kIo>w%oۼJ<=V w|o\˨uatIh̆ʨ@`3J ~_h@珴xO^b׈/!MiJ̪# {o՗o [}g#>' 1m<q*.0?+g⇓6*b&_g/]l1qx I3Tt&VMoǩ+<[ʬdr̻$kuMdz5{[GQ^[og/|3: H"_uk7#^s]ҿ$Ky-ݺD&I7M$jT*7~m-{[W-_ezm^ _k>*__%EvoE;7*|I-Ix[uj?"|9uy<KN3} %)@:/ٻ]k6F]%'TԠV?'ǞKu{~ƻWM1CPoqJʬbjK~ M GS/5 u'73]Ku3q3"(W뿰,kį'C!?SB#/(ɳv^rYZ7x*m;/6ZDmYcMRkվ9;MYY w7bb_-BVa#× >2όK6u_kĖ w>㵵4* crmUTɬmvkEm'{u_዇+e活WcZ~;W\sz~{x+r؞?d+i_.O[x_Yͨ[z&5}D[ Ew[Zݥ$i'_1?'>Zi9KO`SWћL#6[2Y\@Vd B<}6_]uW"_Oh>7EKԛM:2S~NY) /Wz~$'쩻{itg+kv۴V͇F? jZd~Ӭ֖h ;b',2`PkES?Z%M!d`"0SjxgJ@1iַ~Y4ۍ>&܋q-Ѱ99*k{֍﶑|ݵmڦiIGyoE碵֫iߕ7r }wU|&31\ׁm8>!Dvmσ|u .H8a$bKD%7 LlkB4eJ kio.n}qʗ­oKikjY]y>_\_jxT3ci|WWn2 x%4x/@[}?? ڬڵτC W azb hwwEY ] OEZ[NKЊyX+y{a>!*{-a6[hmČ,rK2i o<5YEٛua';IVXy yf&]dbB>izGo>,4t)$~y KvJdV@%*\b:xtOFwVTi5~Wu]?vzs~-'fυ6^? GW^"16L^vdn.Z0,%hNX? Ni^֛DաG޻s oDX $"x AE0;S߈e/m4jZum\2\h<.g(?PO|K|0w5;~0ִn{.~%1s$wOPmdŲE8JRkNJR8kfQ\|}4N{oizL a/<( jm-r**G07dTzqFHdIYNUAqRGVPQQJ;t.rnMsb댟{o]״)Ŀb댟{o]״)И&3vcnl%zqYT_=5ҾzFQJ]Szw+&_5H~' ~_]ӭQ|%zmtEȐaeG2*boſQkkeA^^_Gao0Ӟa n;Ae~=HEoFSMGbXe$mES#/ď>56fo˷lڨL̡Jqud]?ǥzdDrMRORw^Kw4Tq5MHOռGei>;uY---.51b3j:em AvuO._B?k_R|ix7?|#=_Liþԣ.4/övv3FIatx!e : x;H6%i=3=[+|bOdk_'eu[_ Жo'/'#WrfS;IxP$';εO_z߳|_k8#z( ( (9Y}3Ou+Ɵfyywnٷ]D%s~/w">1o|:Jsex2Of$#:}K~5y^(dgͬI&Ft߻ȗwokn'(?MÃ῅.M&ukMɤX4-gwHE0<3hiiZo|U Ciz."K!jvkriʤyY[O#p7</+<_ "qj'H}o;9/B+Sqyb`݆"ySxLş~*Mo^m&Ghg чȑ1˞ʬ$&ᄋU]ޱJikt<q_MK_{kZzvegzfhzvesxDI. RE'dO~+fћH̗Okxps ~*|%ݾq`\-:Kgn0(  ,29{oi'-]N74z7{$~' pPiؕx!׫ OŭPx>2i o<5YEٛua';IVXy yf&]dbB>izGo>,4t)$~y KvJdV@%+7ZvWzkܮ}nݽTVt/KoPhe<;_E?xS5;Ԓ;W͸./*yq2}(Jx];/o4hZu@eNӭ5a$!<U#s{G [38-[}"Af]^jڥYC-pOM_Yĺ7xS,' kN羂[Cw2GtnI [ kNRsrMi}:OtZ;Qi)ʗgmz]'nWz^&3XK6 ڛK\JʄQ| :12xQ7YFFVS`P`TTR g&ܷ-lhY%kJ>g{kݵviIFt]B~wE_"+e {trr&ߥ켺w-[H_ߛ{w(xa}6{, $EFNF7KY~ԩ7|VDXm/V*mQK(PhζoM[JI|Nc}EL]]&ݖv宩k_kYYtLӜ_/7*F<[}?¢;\+KkO iȖ"Z& YQHKOx"O~Ѵ붏>_c iZdv$P&"K*~QWNj#Q-ys+luvH^^.5_FW# sr)/;>LPI߲߱χ~9 x^4Ӭm xB -R%`5)%&wB))Eꕯ7uNQVۙsMhtO[5ɤ{&>>yߎ 4k]֚ތZG7N[K)dM敱ЪZ1eLٓ$'' |y+>`5?&Os{ƢױZ]5خ ĖRd%[Zs'VK)[l][ӕEw쿦/xz >#_.\i_e6ٹ*s\s w021<7?>-ſƭg\\z߀oKi-$Pη0Ļg)3E"Y fݫѷoFݟNTv=Z/k_򖷶ω_?j~׵մ*mRYE=I&an`wZz($Sw+u9)?D[#ADkwaEVfEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^gL'%7U_u@O$o=W_GI'Ow׻?C?(/E㯿41d:Qx6u1^IO[vkMwugoֿ{^iQEQEQEs~/w">1o|:J e_xO?i#?}E}ݻcf5vt^(dgͬI&Ft߻ȗwokn'+͗ڼQ>}XMg|w/o|OP^7 \x_DMB=6Gy49R+2(VD%MDCxsG/hޡ麆$. VDTn 5<\'@^x 4 !<1i:Ӗ&{WӬNcPJiˬ]|<e IGalLTKZZG# +㾗L~؞?tgWYa-sxnmHGqr$攴f8"?ڏ}7Ml'#R4KuC4w˻2Fq=|x6j~.ukm#åj-$쯭/Eyep7Nd^Y~?߲~ރm!3%͕睸 psRl_I| 8`2Y6%Ԑ<N#HYZG_/GloC*1dxfeRy%qvx}{T־|;>Kid%u76' lWRQ˧n[/>OM*PtvmmWr^{;׆IX[6&#&c$ S'mQ Ydb8LjiW-.,IɧO*3em<ZwgO xFQ*axW,&&㘖D2Rk -Đ߅ohmMuWW,,m[i vNDO.M5$Լ?`>gkVwm>FGk6W8WDXHJU$^MvAd/"{m|t|OF_? ]ۗ-t47MOȎkR ,ogp$7 8/)g_"Ҵ?z[!/:W(-cȳL%W` 6dUZrW[)IݮC4Z2ROugNዏC6Wx[&%ٞ I50,-q&9CJRZJ@k>-]N74z7{$~' pPiؕx!׮|9YֳL>iVݽMSEgKy:9I#FH W-ciƞ'ݤw߇u:X-K,W6pq .`Y=XHPލzg}twiD~=맶X/KoPhe<;_E?xS5;Ԓ;W͸./*yq2}(Jx];/o4hZu@eNӭ5a$!<U#s{mx{޵6ZmA\]ZXD.}, y%w0T.^ߊ?"-Y曭Z(#I|*98qNMwt|/+wdz^&3XK6 ڛK\JʄQ| :1^]FXo.'G43B+ ApA5OCY97-ɋ|J2vu^覯ɋ|J2vu^親$ٗOs|1e` & ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?gI?/L3蛪|$?_|z??I>{n[:~3h?_6/E㯿ki>Qx&sLg}W|bZ]zy'/=ou5ך}Q@Q@Q@߁':ro?O]ϻvl"Y}3Ou+Ɵfyywnٷ]D%s~9W<'kIo>w%oۼJsex2Of$#:}K~5yߵG7hu2>l.2 f9|4]c4`3s#Iy/ #~kDKImS_gSb}2}TO$΂S(C =xsG/hޡ麆$. VDTn 5<\'@^x 4 !<1i:Ӗ&{WӬNcPJiˬ]|<e IGalLTKZZG# +㾗L~؞?tgWYa-sxnmHGqr$攴f8"?ڏ}7Ml'#R4KuC4w˻2Fq=|x6j~.ukm#åj-$쯭/Eyep7Nd^Y~?߲~ރm!3%͕睸 y~x|i?|VM3Qn)-DPLwQHDJ$.?d߳dž|qپ <Œ)KyIh'y+)!^ oM&xRe$z~ۄP.--Auo67hgK ߂>ƛ^Ro좚${{u7khYdBΗrGc1i (}Z-f'!P6tV7R/u4;o4Ə2ͧFA\|A|,ij$ȉ]faX/SݹJQ3]n]mncQMFsm?W~,G|Booo%#hkɭbkyKٞXqoM\&O~5 mߎ,u'խuK@[/=4WӦ/_ˆum&ߋ --<|g61۷ĖeŴ"kRrlPx^o~!xUY ]M㍤´0mƝ(֎+G%iowջռ*sיݮVYh6>x.῅t)e=[}od8aÕ-sm7fHlF1ڟQy'/=ou5׭ג|bZ]yKEQEQE(g~ӬG&^~45߻ȋwo;j +5|Q9>XMgikwvq|AP7/x}6$~"_/mݾ;ȟo6_jG$?mbI73.D_ۻ}w[w?I@-T~3|q&^ w)NVϻ.l˓O a09ZO??g? |<4<'fD5AFx=F',G۱DL%2;P>(Q'>$x{ޛjIkri-EA3^ C~ߴ玼7OG"0*Ɠ/l!M9bg}:[_DV5 k̺/YQYi 𛴑dqؽ&x˵D$|*0:>;7F~;[7Ѵi$}/+@iKM,vc(S1\|7t6"}b;)JNT3J7|$j p7ھQǏi:& V<:S5r{(&V?%(GŪx–^_5,&C.ĭ%|<3eYF,O [̪O;D>31\cJJ|!=VAg]@iڜW?fdYe^owWOn]?eմ}u/gcoOסgW KZN|9P5OI/5V[@ݴw& F˾ dan^C>i~6}>Sė8v-$oHc7A 󣀮}ߵOa?/M]2R׭-%oՑZ@d4 J 1ȬO7/Z;AHQ1 yQeEfQ.[iUXʣnWݥuת:$ڻowONv>i;{_]ocxEuYAmYJ&k C?%Do|]kZ~|7K[ߵZR#\YkYcP4s [|D-lj|].i1k֏}X2ݴ"MUBp yD5};myGs6=h ?i5bђ`G4>Hog]6ܖٷO$C'φeI>oYxnEtCi2j\h^$h2B<#IyW?KU&m3R_j~svTi4~f?+^(3n<u h kߊ1o|:Jsex2Of$#:}K~5y?h eςmRֱ Cw sʬHlo !b3! R{|5]GL5u-GKkR[+ݒV"`LjppG7hu2>l.2 f9|4]c=?V?o i_iexR2h=RngcI@OykiZeՅ^ٶL)mW 0'p_?k~ߴ?/R[7זEoմ&Gk,E-#=A6W\X-[!maΈO!ʾ@[&> =RO|UkC@[i: -4`V)8eRx (&%ԕ)]I5-.V]lkgg|Ho?o!)BY:]*FLMS*x[PѴ|?=Ϳ'mhk}uM6Ea8e&%exOR¸JbY`DDd\\ʄDX`H| | 7Ěfh6R 'ђDaF/o,G|~si][KrAPe蝽^{->@kMO}E Fۻ'xn#n"QXSa$FӜ');P1o_O޽]o_P1o_O޽]odc2|vo?U}_;~̿{_DEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^gL'%7U_u@>? y_DO?o>^W^/t2oWC/DlF+?OO {|Z:|jGo__goֿ{^^IO[vkMwl}/EPEPEP7k/r}Ny~"/3ݾ6ȃo_eG?b97ٮD^gۻ}6mWoI@|omh>#xOS??/=kSҵ-^caO`!⯀Fw6y Ke}=J]Y, N8?l|k*x]__W21a`]|2 ~_gr3 ]':|]< 21?:~]h9akO6=waxlAM?H,Fd]ޟ='Ozh^$RlLp]DU-k7?'7 j`Ul,& I-6beav\Ե["N`ݿğاx>5CRIu KZ_XMohmX>$h V>!Bt>0ψO>.;d]jEg;U1C ?{?>'q-wR8uaL{Z9$I\m5ۙGV.jJQM'}-:̎oM}/]XK\-kmvH\\HS 9:`>#ϊoS>| G5ri^Mؒ\;.R9#u/o=Z<7{/Ge.i?O$k I"+ pN⬬GP<~/|94(φâRKH[sM;͵>5Q9FZ(ZvveMFN:$&޽TYi^X4CL$f4S<#Wɾmdog? NYkqj>&5'Ӟɭ [ɺi|׍|(_ݩ9E]K;䟫wzp:t}E7VS}NP1o_O޽]o_P1o_O޽]o?/ocE_5'WMQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE_u^^gL'%7Tg]vk&|_=vkMDy`Z:<|1dBQhNLg}W|bZ]zy'/=ou5ט}Q@Q@Q@߁':ro?O]ϻvl"Y}3Ou+Ɵfyywnٷ]D%|E |`=O? DOJԵyꖗ\G![qiK0#p[bQ;=sZZ%!X/M417ȠčWA2g6xX߅;omV \ ]ֶ7Y1)={ϊ[i:5)-n+Guf&58`>,<=V w|o\˨uatIh̆ʨ@`3J ~_h@珴xO^b׈/!MiJ̪# +OykiZeՅ^ٶL)mW 0'p_?k~ߴ?/R[7זEoմ&Gk,E-#k(.Eَ?w H]=N8yn߇:^ρ$sWLvwj6pVS*Ʋ[b%Wm'ʔkjSɫ_m~KYy<朞mSF`$Q#kpJcGd7-m {.wៈEψ4x|EaXkvkiļKVcp+Z?mx34kI%grle[ts N"5jFZ/zדK>3]7AU}M/秞w<K_k)'ZUX(uh }>yBe_-bb*u,Ѽs:R֟Gm zkghْR=dYcȻ%C׸?-=z]O kԮ5-z.fuGH:'vp4&mS爴~|@[z~㩯 X4vs$$ԖDAahygF4Aim5ZK[$3Ii³:G]5gO2Dž<mZ/+__C?ēZxF}WUn.˩Bq#+GzxwZ{~|_xfKKC##ʺjI\˕Ku!%u ѯحduai@ :gVkX|`oVZ_Zx[-=[ҎaTʻ8z#DעiMy$ rOs-zmi u[c X%K9uk)^WVq[-5;A,Vw% So㯅Ϫ|T x;7*(((((((((((((((((((((((((((((OKn+i$7&??_H|nO'O7/+ۯo:~y3h??=HY-~燁vx`Z:|jGw__goֿ{^^IO[vkMwl}/EPEPEP7k/r}Ny~"/3ݾ6ȃo_eG?b97ٮD^gۻ}6mWoI@|omh>#xOS??/=kSҵ-^caO`!⯀Fw6y Ke}=J]Y, N8?l|k*x]__W21a`]|2 ~_$}+`xU4[{I %Ԑ:IBrВ[O^kkJwQ%-+I8O K ,^R56TCm6>]Ějk:Fd,^nKXy FlSxCQrÿ<?CU :oxrοoGKWW=qxL1جqk P+#?ؓ!P x֣?h?işkyZz+k91+oG_t_Tӭ,-I,zV{BHĨ6FNJNJIk[٫;2`F1Zu;{'VeQΗ ^\> w5+5y-*`7@XSpsNi~,.*h#4_Ѯfnx)gku;أ%LxFz7zc&{uqc{ON"CzdfIgUZ|,lWc}3Y2@ߺ&RBⳒJM=khrɭ.2I+vVa?_|=CßɼC{^$5<:A^koșY59p&J0Ož-I5v:xo<(b ܰn6,r44㶱|!)?-yk]h6%l֬_Or G..2EKڥa) |@]j!I% 7-,HXU\j-#RoT%$䞽[}KM#E #Et v6&A{}5Ɠiyʪ5迱tϊZeNu[9D ]?bѤIvV-w +nB[  gQKzdѼs趺D+[.>5 4jKi_PZ |`o5׆[]X Ƒ{ut- (kvr mUJU*FVԻnߖYe5Q*u?0m~|?jjzeln j3Coo9DK~yidl#)t}ECe'\dM^%\dMH1>;7*f_=ώ h(((((((((((((((((((((((((((((3蛪?gI?/?I>{j_'?o=W^5β_WC' ? ___>!eu\َŽ&3+>1~n_:k>^(((o_eG?b97ٮD^gۻ}6mWoI\߁':ro?O]ϻvl">"Ѿ0|F㟂~"_{֧jZyuKK֮#-8Ff-1rEO|9-C]-ZGWڌn&EHuPDbF +~ |3uԼuxoP6r.[,q|C=_ WQ-BKQmm{7d@X0q@~+|T 7𿊮ecI:y ᤴPCr|eT 0%oa?ex<' k1xv_&4`%bfUw b}BK'uT5χ2\j/ln&y6B ָ/?g~^-k7]]H#c"3䴎7&ŸΧK/c2_RoM7v_)c|1{7cۇ['|&u[ SW$Ѯr76h}ǚ8<6:Ga>?%Ӵ? Y5/Okn<1,dwqBvMmRuY ?KY by(--$t4w^&|s|W=5i\R,m$K 7SXDsu~AMTRN޴W]ݹ};kwUa殚魮޿+x(3SZO ?+Pisr||,ʾZnipFxNH@kZ1Iia4jR0/,ݶ/}Y~?Sx]Us^ % Wv2N:\|)|C"o}[it+)]?:׉]^>wiCOx. FV5uӵxoHAsfW|m9no(/xvÿ~kNjz4^!UlO0+YdYBK( [wYmWKg-s1OkxDgfo*&IwA#D՜ZK4Y-,T"Jܿ_}ջ߮[N ß l,- mEenbl4gO \`0YK^ѿ^>H4]4gH,?6aC v!)vIENƟR ~(Ii>#}fH8fs۟5"؅1\sK<[ygᥝL#bX/˶S", W%Wfe%&k]nT3w-u]շѧ45ou?AÛǖ>'|Q᧏f`-ռB a6<iV3Ip0g֏oVd[xOXV;eJmِb  &-+׶˵{MK &-+׶˵{M;7*(((((((((((((((((((((((((((((OKn+i$7&>}$?_s򿝪I>{jgO%y?.??CB ^:ljGw__'; srx \ a[ڧ 8ܭs:폫~OQBJjOҧաV/o?<5Ikw_.o`Nj@x֛A|~jz'(T?^_m=&'x]L+(xvE|`ieo |KU̺qXigX6O!4nO ?ĭWIoxD'5Mf/]]x[KbDFMX]uX__~С O]_7>D&oxo NF'wg)>7=O[!:xȝt!DEE ]NӓK00,5m@=} PkFF_I>Y{ԣ5m6Jko|1oᡨ^ Ku8gd' IFYv;|9_GbmKřZh3od*쪬G>m<¶t&RozIWO媺eK侼 [>3\xOS_j>{ZhVk6乺DUhv0/ Ç[Yj^E h亵Ćwh[qs awK?VΦQN׎K:Ou |؉{KY'|ͭvsVI^OYDZky*A ğ5R[kޖlKHF?\:Fꚤޣ֚}ΤEӝBHmq5{6fN~ydlވZA$I+,%LWs9;UFO8P;TVm`pŸCcl?(y-$ⷯXMVU@- fR,p0,T< '&/#WP#?Ǎ<_~9I,mm}vڥH bX>m%xD?O~2ỽ㕵R|jr KKKȾ?dَ%cyod8y/)g]WĺKkB[Wo#ٴMkm6F JZ&PqKk7ݗ;=,~g!{ ߌnbx[ +6a_ڭݭ5 XQO=Ek$hheh5q,e2>bx{׈m{ kkx<[%X\eѣu56;|GKI;h!{ ߌnA_ۋoxF ߊK X\jw7m#Jַj-DJ[I+q v9?_RiPx\5ҏ[6Kd:=}1{ԅ_)#+޲pv9!{ ߌnyOuas&MQn. #O7n `JT\ ۏWޟGuh}dy#W{%[/(d2Tc_u~ 98Ik_7wrxD?O~2ỽ /|36iЛ) O;aVD0Irp+<B>$\j~(Ȱ7u4|B5M-Q$]QF de.p]wڙBjqRO7no4*/XS'ݽGYMQxyW[JG;=3&a$1Z燯Qַ:fG5><'ໍV;m&,tDDpB,@8ѝ$ {B;GS~!#h~!#kgڻ?SF sms.ceY$㍵ XȒ,{lp{{^yꗶvB7WwS,0[DYwbUTXm5'wdt_\?\?cnPA<:>EwR_];P˺-^զY$Re$9p+)*Yn쿭R^ o7z%W?;G%W?;\ UE4J#yLqr#Gڹ;ccIUO۳DŽ)_xCP|:_4;)U6'%L Ⅻ[=J?vJ?v+?QmY_Eį𦥤xъHMvߌnq_]"PͥKOK^<&1>PK @a>'Zx#Tgxv}SVZtRQM6m66&l8Gyuo} igwއu_7wrxD?O~2ỽ 1Eo0~5ĝ{D/ÛNS5Aȫ*mGiʉZB ?ssǑTM޻ZkQ#ncsߌnew{+3߷ |07ZVnquyw]ʱ eS`1~ my?:D{^z34Kl,sr47A%' jc5R. iݯr<"'ʥe-nLgŋKLX?] c8V*X N3[?oow/sQ&D:E[O;(u{y*?0%s>67*km%t)^Gew{(CD/9^Ey_<"'?=WQ@W_7wrxD?O~2ỽP!{ ߌnzew{(CD/9^Ey_<"'?=WQ@W_7wrxD?O~2ỽP!{ ߌnzew{(CD/9^Ey_<"'?=WQ@W_7wrxD?O~2ỽP!{ ߌnzew{(CD/9^Ey_<"'?=WQ@W_7wrxD?O~2ỽP!{ ߌnzew{+fA߇""ytQ3(U,AsA׼@w_ tBQDoUՀ*AAWoN[ԣQj_d8[Neu_>pxc}5rf;S ;x;PԿa?_Au?>)x~;Xm[Uҭ1%_0'(rZ>clnᆍCBNlKflywɢn3 )Y,sn?0hoPrhoPr=B㨾|EjvvWǧ_Y9yfuƬ" W Q W Qp8o: ou>*Ѽ_C?>*Ѽ_Cʮ`8o: oPtd`jl,|&_ZKG{Pb4kW6r'$'OL~˟ o~6;;{[iN-+cH^GM}?NY?>0y9;rykݕ*Q_OW>z/W%IkVVwq?h"WYhJ!]u,QEUE^gn{ѭ:밉-gMΑ$_H ȟ |<r ',L\ӪvMͯ3ꯧgԇF'~ȼk+>7 \e;u&X9? 'xR\x.nW  Cqv`eb̄-O2'&?t"|'a ?7S(EIQJmE=Ugͭˣ\Iiu Xi-m$Kh؉&xՋD EP׿aρ׿<_HxgĞ4{-/s%B)K2{2 `K<VdOL>9gDODn~ɫ5kzY[ehQVϭw?b ?eG|'=SyREI,+]: kH$[f%gvf 7A/EoXt~4@kiQ$*W7oB~#5wKK.T;DԕsA$ɪܝ$<nx.toď_\YEay}y=[U. V̰gdɍ ]/UdžW}SYuSZ;xfoA}2F_ %,W_Z~6(76Ye !G!6qyh(+76G19JΟ*1U=WYdKoS(x_@4 KĚZ$P)cݪݑfdFGB+l&U^^[xkZ,riX$g1jHK͍}:Oce s䢧w\KK*9]ٙ$I5/2'&?t-$M?_m.f~=Ocᕼz|r:/l}bwF]GRԣuբYGj"m31D|bO⷏AcX4 J%9gӕCk|ՒVzY%)NI'[}w/ɟ 0yMǗeg˲4mv}{}'߇ m|iA =Ʃh뭩%MZBq\C)[o/oZӦPmt HoKm,AtD.T,PrD$ =o2'&?uxSO }'CKY%;mU31z/ h%vCvzfQH((((((((((((((((>ɷ34U,x KZԣQ枽Wd8a?F=/~W߀/EB<;wZ>2|'?>F c}s²h%H}4Sy*.%Kſ?i;_kIA3Ò,5MJ;ۛa?jM:[H;$qХ%Qwf]O[Y]{ĔNyhjZG\K~=pjZUzV[G5(.΋m=0P J-*W&JQTu˽Ҏ}bX_{z|O͔QEIAEPEPEPEPEPEPEPEPEPEPEPEPEP/H {R C*oD=|MaWĸ_"WUX]B i;=鷒6}Lfx j)[$ߞr%eK}Y C(x_P4_ TM|%ׇ>I}N}nk{ 3ZZ!ח~ HA }&/,7'u x?ljG/ǖ:oLJԴSRռ:mmaX"k3faq"Aq2 6Ӳ}ݼM)&DvzoNw|%]5>!]v]]r7f} C(x_P4_ TM|%ׇ>I}N}nk{ 3ZZ!ח~ HA }&/,7'v侧(CxR)K[D7@ɍ쁱UKƛ$_M J\߈R C*P ko.~-|$ţxvFMwwݴIvW[px#k-탯jx ^7\'' ,!- muO丽ᠷV{̓oڣvrWvWMjvɹSߍvOV)СA C(x_P5_OZ3V^7.OyT:d:D5&s 7Imy_+߯U}ze1m?c!I5AG;YhڅmoU'Y1\(2pHx/ &r>~ |(ּS:i_j 8E:E4FmXYim+⭮x×VJt2 Oln :e˸KQ{+jm{g)СA C(x_P5*gҼ'kCtkVo]j}u AovR-t1bKU|_~߳c:>,Qa ]#PQ5ǥ6xmH@2JV_ ڽߺWD)F>vRo)СA C(x_P5¯|C i wRV|)+ɼ=c|=,3%%4"Y<"iQ{'Hu\~*~ -OC ۴H-ȸyBi]5Rkݻku8.2n_h.T}:g7SL6cnٿmqmY8ۓ};F} C(x_P4_ TM~o3hPxGӾz2 /-$-Z !16j{A(v}~V{׳fy8Vg9R C*P ko#K֗<WמsP k;A$M-G)fv:frI<`W?W_ _7cWw٨Wo ޳զꥲ,'$ /Y9>ߵʯR{՗?)СA C(x_P5uF?u=bQl,e}exM ̲# 7L#@!|H]o2bu_ϩhv~ HKɷdHVTB&yaCoiYNMKR C*P ju[/z/gZ8X-wHslX;#7IMOi^RFiQej%XٗQ'6! ;~9/Iݵ+j~/+$}[I=P kKŸ <1m/th6/=RǘNTH5V4o'?xcĚ6{sA[|tLj 2̤=R C*hQz%&\ؑGUd!(&di+E 4[.m¶gkBoOkHhbuE?}+3[_*KVOI5i_ TM<BU_+i_%|.h>?;I`u֝ M-[.YR$J15?i?i:-[׾<+=42|6G8mݼbmFA㕙HE$%Vw],zY9V/DZT} C(x_P4_ TM|M_gQ',uGÒ[_~ϓ%Ҧi&R̨NCA|W'vU_x QƪۡI4Q:ehT$/bqHSnڻY'k_ti?MJ_ TM<BU]E%_h #KҾӤ}8<ݶݰ 'W?Hx/ &|k_4ط~*q+G 5_[}7 C(x_P4_ TM|nhu+jO|IٵC-$[-iO%d˛*G<)_,sW4 i(e+XZoBR(LdnOvwnjoWVO_s?R C*P k)Ow?dtR?5O}p,kZ\ w40ViCf0Wkm?灼kZ>ݪZ1I-"Tek]0* en/[VMTn<2O󿝟go?Hx/ &R C*L>?|D6ៈ-߉~mX]tm{{Ko8$l`ojI]o{=῍^𖷪\|?O1GNIi94BV"Gk27'ph?i('5iJ?;-nمgIkk[SoekcP h!-Jɬi=]/u.-)oL5jAyI:q+v{k8ɴS\_ٿܺv?FHx/ &R C*?5>`߄ń:].|Q\f\NF- IrcH]rtՊupj[W;K/ C(x_P4_ TMuVe5_ \VfՍWB?տ;kiZ]坦in:re*I Cn218ֿ(kw:~/|&.MVaz_N^yH5j~orA׿+-C4O.mSOGUf9cF.A4f8G@~Q(Ocr:~¼ +4l^8z g7+%<&l!Q׿ixGMys]|:&e#Y؊ܻ?g쯌?.iruV//t'3upr2i2ʨ7qyBt?g_BtS2~WZs"zg-k*q~G_~ZB }e| '!WG?߳lLB4#bR^p?g g\:8j k?g}p_~nxu4>b_3l?fPoQtY6ͭ)cM_ps@_~6|A?OATp : *Ͷ@Ӿ2Գ΢ͷMecLU?_3in?H  *xN<!WYoٶ.3bƛJx ,iw9E?Xs[|Ao:g__W#xHetZV__5Ӿ3Y\7q/=kӹ?l?>!!'"SU~7g<>3?Y*-? uoU?Sk"V𣌋g { !~lC3;ʏwy?'tYQ\7pog  M ]_t_@k__@N8oy'??eOo<<Hkk Ϗ/ 5CŸ {UoNa?eGp??3{|A^:o8+za Ni8z_o'4Y\7p<<Hk/kO ϗ uC_{(? 7t_o'4Y\7pIxct{Eqq<hF dNO8㱮!~ :Of|foMU5g5O }xu~$ u5pcgg,7g9:|A_~ 𿆴WI >" ,sL{d9;_Ծ玿k+" 7tA~3;Ώa?}@qԾ玿h39Ώ`?38?G5_}3tY!?eGp$5go5痎jKګaTwD;<?g,ggwLU{<Hk?~^փ5x6}x6xDi@lG'k~;A/wy?'tYR8sy#G*>#?K3;ʏ$5g5'Xw?M?O ~hI ~2. 3UF <4:>#?O?<S>!?<S>!/W?Gzo,|?gGp$5goO~*c xZŜ; "81B8<ԓ\ c ~]/o27Ω]ٓ?WpOx\7p,<넏B$*GS/ǎIy?@_grdE-5,*{7s"?-W&Q,<?3?+R9?O|El/?oE5hgggJhܭi{>G_%ZS~#?[᰼  _x %??J??J>b??3  ^xkU_ڟJo-)}3/ҏh/s_G67"~ }7?gJ>bX3f/s_G67"~ }7?gJ>ag ЯPb=lN?,>lUI *h4a>/`󴿶W[f@q"<3`~ }7?gJ>ag ó$?pP^Cռӈn|A{q i'׬䲺׼E6iʬ5OLc߲V?)`@ljx#ՄaIEZ=b%RWo?NUnit-2.6.0.12051/doc/img/addinsDialog.jpg0000664000175000017500000006771411713252032017577 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?` G|xƚ\Zq_hfݠ}ݭYcy2*Y` t~dJ*oG?Q:kTi(&6I$j;'Gsg/cI*ȳ~]tASƇȕm~:?_#_]koS-i֭.nՊŌ9h^?S/@ x&uj^M:}[ie83A:ƶr4KBEdJ/m9薻jy _n[wvIF3dc!~|ֈֱnca~ dB?i[uKoZOo k zkmf00V6űfKſ?$4/'5}bM2W0g2, Am┙rA1N_cQZWiZ2-0 I++W%n3~CX&"Uc?=T':"VO+'tMھjzft]FQiRФC"2m "lmU?Ǥyyq&x]ƌi-w{2LoHd]?Q+vuOW_mwIl߱c4s%1c?˜|*qTCJ4~־Ѭ|1/ x'> sYD!T)0 |@ߵ _Kjv6ko_1}.@kB3ݷO Fs] ?hU,n]#ӭl9gfyiK]?Pkk![BģFݞMt=xVJ'הY]B[kd I 7!p#ރS+ijlL1jޏ"OYoi\6[1UYXcu_ %p-~@k k#3 0-+qs_߅MƁ4>M|ɧmqpmq2c'r?_r9%ٟOG6~*ݼ3 k`->8#'5.˰}q>iAc[[]~|?MC^ 3u߄ف85&*Ϲ11 ?͐Za.""3h/:_l !]9t@YT X Ⱦa#?'cu-7¯MD?#7ŸN4/DrpEQ1 z_GW܎\Go G_6 J|?~ hW+rNZKy5huC>ƿ}/ bYuo.f' 74IcSmS4HU@s^7C4SOk/x>/!Ѯʹ3jv.G?0=nox6[6|9Er.S m o|}SEEԷܼҰyZՖNVOsWa?u5fV sX~}oG?h궑mt!<3|Do| Ww}ï.n#%2@ K* 5"GcEk?xZXM'I&yVa"-w b2PIۀJYn5_o>۷_Rpӳٕbባ''~k|Iie ~K4> iwVZ}ݝýiqmq%1BVXe A'?|-q{i߂ *$u{C=!UUW8UP\^ķ~0M}qxW0e63Jύ|uo ,/kl?7;KRXJwk0, [U߱ß2c?6.W w{+?k1-+j,* Vw ۶#3Inr>0Ҿ+|DlgPsuᇊDѠ xz5 u]?L}BH]^1jmw p#*UŒܬ޺{d~pN UӍ>hsuz}Gs|8ig#`Zͬ:M[:SeeyP++dx##'ԭÏW?_E}K&ē6d%g=2lIO,WU|[ɡ}V8~U;>].k]_ٲb #%kkW_x^muk)&Ú|s[_"I1udU<+Y?cڞ;[i?¯jWfF Z+*Y#ax^'OI?p鯆s_C9FgJ3ZjiEvRgtnׇu(U#yŧei]4wN۫5q|4{]r?Ι Ҽ=7t'S"7WN}Ho5 x?IWs[Njꒆx@ + A8')`5.jDQ?hva(Qi)o--C3Ê3:^ʣm[wɹ6rnM9߉W>$~'o5+-nCNmFʍ$riVU7#(z_ڳ৉E>8z.;Gռ5G[4--Eo,fm#ypg?YH߉_ oq`0#i]6u)ВݒZ}]ox/GӼ7ctMwTnZLn`KK _Z\DVcy0H~֑Zj%]o=iLH$y#6on1F#|,\r|)m|7˚޽L5jRiWwM;vѵemNkF[vv[Hi>&ik6:ޟ.4淖жicOd枑 LEi=񭗅Ys NC-%Ly +S+`o`nKs⌝>|L~*H %M<7˪5u5=Ɍ3h4$[-,Vg'fݷ9? MsgkiM"Ӗ-+bYⴎ팑^7fl$a=S20~|G=ˊs7x>"߇oZRV9?R~p4[4IZlx ˼)?xG%Ԏ@bIdgw=ˊκks83ׇq^ poY?R[e?+Ugn`_\\UY?7n> \Wbΰ<#9i~|_rXl_?Z'o߈' \Tm|=Yf9 /ϔkm[`Ib:pO ˊpwt}-\P/DK3)u+5!M}@^:$qQMԣ 'qKg ?KgʑL8=5 M1$xϷqPK8x{4sK3|B^?a@ db|@nϷsKg ?ksg׌?6H\d+9__$x\y?v\9K3myAxͭ1_Es@|;˪+&G~ >/|/C\4!I!e /8-w-.!.cܴ1$1nea qe(Y@˸Zq9u ?]?[g\78o⸥꥾g瑊۫lc\`k>!5|;nזYE;6`|H#uOi9M5? +!?}RG =|6?Fw&BN?X|I8oSU?%sCah"3Vn?nozi~{_]Q%Å;B䓒}?e 4W.jd~1?駆s\x JQ.dz^cytT]?V? ]U%qM<7˚g?ωGxo5K _{=-/?yB|0-3$ qH*?@z~>=P?Kxo52|ځß\?-sW3/JN~>:-ƭsoNӌVme,RN>xO%-0 $.I$'u 4^?믇?q^eZj߲_SO4_Wu+9Z3ILJn扙O*$\pr2zקS¤wyqwҚZv܏zc86lZ1 ~fx"lhjqPG-(ι3=_D> \ txfI d{S??̿EO4 Z*?k8uĿ EbfY5c< Z.w%WyI]nvwl#ECe(2)xgᬾWW0R1}5BYyPȆ>BX(8o)g//%|\|xZazWֺ &-#4!€MոR@+NWtUjCvM-N+~E??̿Ev^=|+8QmMtHT׭l4m3C+"a=JM?Fhx!n5r8U+{%6˶6KhZV3F}2<^׽W('{쮶v>3kfWv{1>(j7m;&/I)amgm=d`i4 !\#㷄W5?|Yq6Mܾ `OUrNcX`D/X?J*-}~w/ *] 5d7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@7 7_T_ U{%CkG.WQ@ S'~&Կ#}B/#56ۿo;ss^CmYtݦe~_<-qyB~ eK[r/Fer*'MMZ[_[M\&6˭|)ּ!|T,״mV{Y|ao]As{go-֚jewUs~ɾ.]FNǩi+֣ͧ o}!3,Xgufީ⒋תy(GB%k|i614"K?uJwKošZ^iM6%f Dy?|i<kaR’IjɨƬ@!w'TTZ $J vJͦmǦˢWw] 5o `(CkG.WQ@7 7_US@Ƌ//>fnG?Lۻa83ҽ<#׎_%_oUW-|W1'U]?C帒L5M~ eIxrRO1 v/u"!|6GCBzd &e kxzeəxsZ/kޫ0((((((((((((((((((((((((((>!G%^>!G%r5o# S3?E^.|3 IFprJ#;LI_ݴ|>+%}_GII i Z)6ɗ[_p?L3/K[{x//Lß{^\gQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEG?|G?|F'l?oo?zb)3V/CΣy4F>5H+?_"-*kO7g2<^׽W2̼9a-oOUzEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPT|CͿJT|CͿJkIOk^ϯ#[s/nzgFm7ç'%m}U_ xwz*ȟdЮќ #ujTo\'Br'\f^_&_?%Op((((((((((((((((((((((((((*?W?@| C|Bc?[O_[W'&tyM8Eua鹩[t'G_v^o,$ ieu)_.?L G/E y\'+/Lß{^^ 2<^׽W}QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEUDŽoUDŽo9oF Ed ƽL?D/ҧ[+T 6.p>)69 '}0ڟϋ8&_?% &e kxz80((((((((((((((((((((((((((>!G%^>!G%r5~4FQY+6tģ)EdK/ڧ\^y5>/'c'h}њO BQHO8&_?%꼇Y 7H曪Oa5̗!kc$3l qn.vA_cO7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7h/KV?/畏Kƨv_c?.yXDj7j?T?.yXDj j n,A4r3,1]Xyc'Zů_WU~jHHq#}eT>+F88G+~槂_' SefJ6>_QEhQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE?`8?oI+  >QY+|W_W挏i/9#}q 3߇7?~) Ec*3 !L_|_?ٳWǿ-x'io6y44mCiEl؍X#APGx )C 7tOSAּQNmJ\Iu}XKd g{Kѕo~+~_ (k h xzna슉'NmY[xoitx{JG < 5Coi4.+ea;"%G?'<3 šxFKүK+2k۸nXdRLGw_J^ ^0)u-S('{c2A,)-IF$.[JQO~VڗӗOD87=~Ӷbw}Ug >1S@Ou[([xWЧoYXC׬އ6YZPaAw%h7RxQ߆u}[z4Q*\]m9fu"D U%,|0z!8G}Ry]Ͳ1N|+eվ`A-;ῇt}}5kMEܕ$_r\sI!l'ȿħ߼# KV6qZoETQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@~j %}o$Ҫlx(>r,iS/U0wGKkV_UL`K#cBJ6.~D> \ txfI d{S??̿EuL3/K[{yڟ,~E??̿E}OE|#ECe(2=|PxN5VQ S<6 l $(&"X-c8":@YWACW?%{ĕ|&71%zyv?ψ`8Vma/ Ǟ?IX'Ӫ&%1 ?W,jEpz_2̼9a-oOUL3/K[{yڅQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@a|HRo+v$ȩ7tB??f楦M^k='|s" Gɷ/&Ӵ$(-.-x{H: fnE(&}1$AR1@|Ʊ^1%}_|EauWmS,1.wO'1#cuE_q qT6?_t?z_2̼9a-oOUL3/K[{yQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@a|HRo+v$ȩ7tBEGT?,? Tq} CW~%{ĕ|Q_!׿I^]O8?4p|>vrbK+czxn2qFQH~јO(|ߴ~2<^׽W>uI&7$-sw5@ dm7m݅?K<"_5^a t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/nX_K<"_5G%+P t%T]/ne/iT $`b畏KƪKXyXDC3J`q(zPq} :y^x~6Xod Gea2@ ~Mދiڅƫw"[4yx*t<m/Hզ8'I[g[ J(/F$k?bJ?|o%FQ89~?^~?_T?{3 (킊(((((((((((((((((((((((((((s/F$k3B>Q+˶|G_W[@NE#5c_oҰ; ?W},jEpnjO^^Y`+M$g=62d{3ZE/о"U̎ȴk=IS$cQhW*; ۂ闈<3OKMWOca'fTB N.1uZgegoo~xzӼ{yFw|CY3.k⹧G$c/:1$ J࠾;>&;tz[7ZXuH2wn:i %ŻIa/| SP_ X(^l)my^vWۻnjMw[}׾*Yz n3$( nlMiۚ/R_=-'+z_{>Ws=k M[~:5k>ۿSv=ylnbZY.eFemʤ) R|G><|2֡>"\x-M|5ᔴ/e$[ C-BUuϔP[[˪x[<Qvm%uk*Ld<$G?yZM~jo3xZ7~!ތWQ,,c #˷RXgfcN7^vWN$hRo{GnWv;/OO>2|% ;$VR~OM_ 8]E>Ib)goC.y ;URIɵFPQI%y ((((((((((((((((((((((((ϯg FQy+:})OocJQi+˶|G_W{}:6њ̏qW8lM^‡/{([+! бI#tYALjgX2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/GX2~Ec3G.|Q#ECe+z(x(/GQh6jCg}p?L3/K[{x//Lß{^^aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPX_?TG ݬ/*M]#Ѕs} C_t}H?!wOcJQi+N;!/kħWmS,1h<|:R3_= xvR &1zS %ό2̼9a-oOU?πngG/4R{ .d \tP$!`cwasz%+W}Ea]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@V%+Q t%TEa]/K<"_5@KZU$ؤ_c񪧯kV@ҰXc~|Bx/Ɨ%BXg PƓwEqudf9*==O'D}tK)R9i4 V°=Ҁ#@ûJ}~-%~.GEO.ڧYd{χWgD+GR?Ƞ|R:.1zS /c?P+>((((((((((*rXjR4fGl޷5^'ٲz+wv_ᆽV;K{,6b"IsU$e חx+E΅WkM /{feӬ ѴL^\ҽ+wCkK_{'ٲz߳qTEmWRд{3ͫ:ZD^%Q-^^XA!+,M mRf֟w'ٲzz+1~CZ/L5wy77 Ec1_> ȳ~X)3_eQ^aEPEPEPEPEPEPEPEPEPEPV5_ \Vf׎ {m|i]kSBąfHU\TW}O?jGh|R~ xMzd턖ވg632+m$ۂpkʼ7o~*h<-:X_ xY[d "i+oOڟ#7?m=D}},z5^߱oPl>/,,>&Y-y;Xx'2Qw@6ѿ 'mOirm~mI"rrkSo~ Sz>F' ?G~e"Hke_>(a@|M>Om omgt.qWs^@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@RAfc4"Afc5k^!|\XM;KZԚdQiyWnӉ,,!*Ih"Oط^)>QEz8 zũ:KO_x%W2yƈ?[?C {촃W]e.b9Ky%[9mh4b$Y1Dz?-tYDxEVi[cȠl^(*ܯ̖W?M>K yS)_XƓRޙ:D<)?sLeL7qg fkr_:c~^ NM1t_*pGsL$_@A2R:>5gr~^ ~/oC~Αp43t~0ԹΏa`? kkϗ?7!lc-g '!?vG_'4Y=O ;tKzaܝT g/ k }~ ?OAU"~ rI~O=?iR. o-(pT_KO?@kA<:|A k_^_ f+r;y?g\L\7q۹G_~?OC?A~U\sgcR)H\?͏LرQ\7ps_3[G㭿7!ix} *|dcM!~ο 7}W ?۹/ ?mOG}~TvBKo-*[veabΚ?'Gp"_~ OoB/_ U^ /7Zg,_Zg,~?k=οklϧ?7!Q  9+7zg,Gs4Moοklϧ?7!Q _*Ο ޙ:?37Ώw:E?O?|>kG6O:Wqrޙ:?߳37Ώw:E?N|>kG6O:+7zg,~Ο ޙ:>u@_~d/}>! lϧ?7!W/?tWo&Y? 3t}W ?۹ u _*?|>k__?gI? 3t}W ?/<W|C}~ _oB¾35Θ^?Y\7pn_5g6gO|B}~]wt_G5߄??goL8/?-okkϗ?7! w_:?g|gsLG@Nion5g5߄?y~e8x#J:O/'3YX\7p{G_~_x;|!'6}?gOK>3sRޛ:OzZo,~??O᰼>\ƟLh'-<%5jGkn2OOoZǝ*o?w__&Y 3t}S ? >? kϲ,5}#YMroGmX-eO#~AXi(GVClIϊ^G K$> jVwP84~7F*Ac ;쿌MioM;{ᾓh^^ֵo˃S$kHy#ޞZ$B$+]ٞ"kT 7̞INUnit-2.6.0.12051/doc/img/runtimeSelectionSettings.jpg0000664000175000017500000015614111713252032022260 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?`'i1u{-/OKip^4fWyC+U"o‰#5PTDZZ do@$7l_Yů_|YxX}mK/h67mۋc72Eh#WJTYhݺ+kvH,UjTW-ݚ߱OͷNNt?EM|4> M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ()QM[<+:Sr0kk'i%}F1QX>jYZւk4^8.n$ DRId'цY|j%熼Amw}Hkx[ .$GK{W-cR7^?>xH~0/Pc鐽^_55n42]J[p9bskɩysZ+{&N-C➫}N]}urvM+m.xw?]YWLtbE;mN+gQed@X@px+ Ϩ/5/tOxFn#k DIKuǙǑ'=½+z(<3Ӿ隖qq {귲㴸'DLTgK̑SM-q]4̓ԓ8%ZJE'ni$˕(z4o #*G,x S_!b¿ /cM^8񾒺=hWZVdZKn##t/>u/ٟ~6>-]C>-`|􄬒-R9M&̺&讟FuvݝN3Qq˭>￑_?lonڵOپ@:HfI ذ;q|6Ǟ>ԧXlfTn w>g7?[SS߄u)&Ѭ}2-а*vZ?u? IO k;6rJ^ǧvlQZw#<7:Ĩ 9JѓQ~nWkdOiI|޺]s2K^Mkg:UֱcY*-ơ9&hՃBK*g~s~q px^D7|=_6 ?ot]n4k @ѭM JO3SiI6[xV.摧&K?{i-\#%4Z*HJpNQm?G+.%ԕKzwGҒ@$Ocڊw?+Yci^5jӗ:E} sN5ܫ,gH ysH ~ɭu_-N33Q׭ˉb3*6=eESwNQL((((8x9Zgi.&Miݙ9fr?xNwMeO>*5K%>cV_G_^W ]G?E㯽kdzY³b3O%C hwQ&iĽHaΧM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=z{G;x?xSڧiZmic%B;gYe2%߻DD"Km(.;1ZLrh" 1B%A!,opmox~Ytxr[e,Ve <%.P(hDܑȡe9%֍ˍsDG{j^5K.Ymnl%[iM4Q ¢ `Fw"KFOHԤyvĦ˔'iojz|]}gxHmĺnyGTqe2>`,6j%!SԼ'{> jRM+YjZ6jְDgdX+N+;(4Ib^0֍g~f ?K=S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn<O|H_ýsuo[eǩog$rϓ9c|g|h&?uG^2#ΛiG=i[VH3+*DHM> ֺG4[ k'D 6ueRdqb_ |]eޥyA{7FĒii7S_Zq?0c+_;um}mѳN CM-{oeo>yԿπ t%:"qMlA4utҥQձ 1hM̱1B\|I?~54 ?߅|EZOuE$0Ny>zdT1iz\ׄxZLڼiOb-Mվh -āLv?e}? 3W4I z+j n-iRy !v9 峒sZ._u^҃vsKkkff}Io-y_K=<_؏߈~4|}i\~(O_x~]f{&˩fdGWxԙAkF_3x\5{[ 14F[oWTϺ!Rβǁ,oqx{\K^<_̷mNNni׺|Q+[[ElCp X"VK$}>6Z"Ϫ%^#]-wͥ D40i<t-#3. ̓jײ{])]I'nD5ꓲ{_-ؗ գ@Q@Q@W|O ?W7>M tE eVL A@X>(h_| __ghhO6Q QF$I#q;"01&Th? |[I{G5+]4{ƍqqHҺ"b/*Ce:j~#ǰYk9YQC*C Ox,R9АGҧR:sA],R{I+^'(5kז2$;]+Xпh9"xBR?ŝ D_ -MM OsmZXۗ]H^9ؙ}b>=U*MzaU'6Ɏk &ߜc(O*QY^׻Ш}ZYE[@_>5X~ܺ?-5mi&|Y &76Ĺc~&|2~j?^rچ.|[ysxX̑\j6w.2Ȥ[ 4#y](dVRZyr{.KU=ѥk+.O~}Ėޥ ]&763#f&fk",._(7~->4_H: š?oߟ\~|d5#VauKV7I˰7r$*1 o_|sZ.?/4/ɫk7riRhtk)n[LnApK'71'& ?c}`5;R[O}d%bGU%$ÿh}wm?FwTn;/b޽Ef+s}7[JԖ2khB>Rzz]{,o/KQYQEQEQEQEQE| _|`k|{%?sIKx?0hH"?xNwI>JjS#||mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5thNs0<24l+8#>0:/QK?ڝޓom-ĺt2I$6o,;'E̘4iVPiR5kk OoffY$^ O[SkM3_ Œ麽'ǁ4FE-;rj%>$FԼW#L6y%ys jGg=͔K/+D0>/u.`!tXK&` whinmzI5^~_}ŸW  n>!mZoFou{Q|=DXC" 5oVAmD^,th,n-e? kd!VKu30l; u"쯩[ K-ؗ գ@Q@Q@|l~úv={žӵ/-:ݾaŴfklp%9tP̿L&T_wŽߎwwe(ٚ~[UUX"2R8ⷷ_߃ ko2+Ţhpe3\8+ 2:z)u85缵h!adk[%um"N@*7+{QJ]{Q't=QռOSiey5(EGIz 9  ߍ^MST_HitB-"I\Io 'HIv'iQQ?-Be÷mޯq1ʟo<;-Z<ȹ." 'UqMڋX׊t+Oj?[HCs MSRHuX|Ɩid|\vd.U}wwO}ّJKG~GCT[Fn!ɫ}qol|ojPY%#4MGƏ*߀>;]x>uHu jusm<2`KhdKSWo|CNK]C~{Ikuo>`Sg{|S$_g3f$N^_5/xٯa}bmz{|y_7$켬~/sf_45o(x<0iZ{xWƫt0藚IQ\3QU.#܏k xĐi:.}s5)33M.,n@’<_[O&OF+X=78_I?"?xNw߻Cb+???gfJMYE8~4aYO-S³b3O%C hwQ&iĽHaT~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$IO!ӝMďnjEC P/"ӝv'>u*???υ9gÖփ78ҾΏ(Ebz1T<Ő&tչ%kɚ|$/GkFb3O%C qFu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7ܤp6h",lT1ܣ&?Rm__<}0.o亲vuygi=Fm`V2*$1Ogx']+jjz@,W6L )S).~ɬxRԼEj~1/\E4x 3GX]6艭OӒ,P%vYB>sxǟh<+>ƞ Oo"OʶEUٸygSfsŗZOmZxk+msoe \%D.x2(#lٸ?7-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@YS|\?*“_̗sA"ӝC.w~&x?â|y9W*\.[܍kgW'v=>+~W7ü4!?_4ݧO ?b _? ~-gNTGniEno渐 pePa7!X~7zM#V]CK}FmmFv0 ygB4TǏ<-&sɸ@ItSRY:kBFcy+>xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mWOGO~)w>-[*Jho N d+ppsxk 'W7x[OxzᵻS{V-I͂6jbJ]S=#=㻩oSm'&%c",\5!H`i2  a/\MF--")eeZX"Xaڧڂ`|hIY}iFVz|Wiل}tuZ,G~G|= }/[ᲆqu{74 ,4ÿ>OKB~6xcd>̠tZy"N;WR{xg<Ʊ_xdԴSNLSwohgoc n ¿62ߏ/2_n׉Zhڦ,eO6M5Y 2,'XI.4Z~M&m+)'gvjcT] Y_|7t]WZ=VWW:i l{IS%wy+cxׅ|yMa{Դ],$6\^I-鷹_Z\&:[;td/2˻(5 ߊ5a㛷ѥִ[;=Xo2ZL^t] w;{[{GIn5[I e y^ubbIkkowᾎVm 3?] E$j%ڕޛo$v~uV Whp>[{߈u N5^U8B\|;Lź2AxţTOڍcw$yu[_L!kebE b$ 3׊׳++v[J_[t7k(((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>XvnL>,O0G!xNwxsnlO0G><9WW^Wɟ EbъZwh_CEؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?ߴ,?s~<}|0ԼEX{OF5V$StM9hm˕f8>c; ψ"ux>i^\xe/lRXM8+sso%-Ucl~o|Q/A?G$kg,1MĀv8ȘuP.%ܬv-|%O7^#ĴMo/ .by"IkIGEy0I5+KfKN_ܛZF/ڥ.iI;w$ ?7?U>>XymmIlm-fi-`,= kC4G> M2-8]^K^Z7֛mhJ֒CܒA2' 9]#W_w^>k ]wQCoL%/ɩGw3;nլ^-MZ}S8nng5IH$cA%́R$$p5nf(}蝔n ]k(jI;#t?+;[a񎯨xl / iczŎqH.QrٽlAtOV'Ν_/eXi>r%'ͽĨq ʁh3왦zE|Wkfsj^cYZ7Wq%#dtyRHW"HExÞ4|A4BkIZ[ nk 2E.гE07G)~xߪI([][ZNE?mW+օ-0ѵj_$55bn4-n( Č68 {yḵOx7_Ķiq{Ic ]&;icԤ&K1ʪ7'(^K¾2='?xIz+u+JQ6=ޟ;‘ͩ^*fHV,w13=ƯwI𼺆idRZ97y$P)N˕_k7IE>]<-tVݥ Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:UFn徺u߭忞C* <4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((T 4x?â|y9W?+lO0G!xNwU?F~ɟ_ ?NwF+b ߡ_?_a?C+;(4Ib^0֍g~f ?KO:7oԟhNcT|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwQoi>>j^",|=Y+MKd&6yUeʳD 1gxiߋS@/.<2zy{,&G ĒAp16W>S oDt}gB[n!= '4WmԄ| ?|YMo<]A2\4 g NZO <+90V:V'4+rd]nus̰q([^I(m*tFZ?ZGѧo+_0m^ͩ-5ŵEybG-ßzFGi^ŧ t]2PmQiZHwZ_3&Qȟ^_fu湰Hߊ4 {@[(&{R[dԣ㝃HHV^I=.Inu/VA7W12%H  lk5Q.stovQUs\ ۧV;^K{V䓲9m |c7} ZfX8}$zcj fT{%ܶovv[;r?%>)񕧉Oh~'">[dE%)LY@F,y/dOx_u}7@Ok x@z;ڵHd&x\QK|%W><>/>E-SMk kwhDm-Jb%吼~S4F9sPMޚ[I]"*?{t륵m6}oZ߁?i^/_xsYֵ]ÏGFM,GG(U.'ˈRA|<5}6$5O-cWZk2ZvmF 7Sy.'eOx$Cm7G;o|}'hEw=3.Y|H#sRx]vkFmfQJ<=-\ƷN,e&QJ ''-8MYO5>gwQ'/* #k=nZg$~ ,lH')k#A~_W i{oZ^x~%ɯgͪBlQ+aW!_ֿeR70YwѴ{xMfYWZi!yR$d*vV"oQO}PTڮ/zz7zJ%u/P#iV^OrBwK\Cuڷ勵Odڣߴ='H׼oz._{u?6=" PжcLF_Vw|G{E(ˋxDi 7[+{dL $GO LW#~$|Ah!>wlv]eIԕ)F+_{j/0V\\D+^[QEyy_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+lO0G?!xNw xE{h'L%jn5K/mn}o{vy6Ǜ mrb g2I&@~2?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^ A>[gkO2 שuy ou |7{߶HWoGWV^X+1Jǐk-1iFF7F23;Y&09%KnW}լ{x ~n_ [[ﶛnn_vZ#%[˓:ֹ]Db)]N&S"eT Xu xM7Mx;BkϳH;{ !!!ikmyɇQLǧ]?mWz^P+#\nRU a\{_V?z &#3Gl'(D)ÇRI5cT0QW7u$ܵ[p/~W7&^RV[)=3_uj6$ּ;.R]USI@y%\,J@ gşTPj-gkv-&K/dK{Mw;6tJщX;v$?n/讖Ozi22Ѫ27,qQ! KvImk5IS; +㝟!̗AEr;yxC/&ӡ>VٛZIn+5cr *MV:mZ Y pƶ|4JA\o_Y)w_`/bHroU{<'ž:"%&G%sQdh*ov S;ؖ`~1ŝw>5yk+K:{8r J2B^'s 8oա+Y)E*SûuJ}:2\mI+TR79oQ_y_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+Q~%O>,O0hGgyj/?q_8;t/!?_QۡV* %L_|VwQ&iĽHa?>ؗ 5du? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7>j^",|=Y+MKd&6yUeʳD %[_:|IOG~ɻ|#8usO*r^қo|Q/A?G$kg,1MĀv8ȘuP.%ܬv/I H,>"S]:? ֘zy"i"A4SnRhF-%iVQfۓk[YZ[y5d{dNwI=/5_Zx~4LO,6qٶkngXX!چT[L=ľTr“NdH#&[Kֆk䯾˓o{BTx$mE|73C}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ+GįsxJ?]|_ hzn5T;kw :~<q|?~&|Ifx._&`}bٚ2!8yaI!2O>\k7 xSx=SD˚kkHx;+L l!gćS?J">+мK'ei:Χ=KrvYMq[FbXk݇o%N}owl5y_xM-O[!|Nx__6럈O w% -7ʌJw $2jl|ugmww/: m.'kZef;7Hda0)>O'x7_ wzsF|Kq=)4[HPyR" ebUψuZ]Xa&mZEoif%51|F=Fml;7N5omov+\?IEx~%ZSӤ̽I$ndeiDA[*.U<o]OWk6>-mN]@]Kw˲3%$mbP~D~(At{[cM[8xΧj- 0ETIl^Eb߄KF5k_.t{[wͲhZ*kW㴆6!KM4P\FVzVxm׭=[oxSlSI9O{wo+OȚKwNWDʖدvI~}-_ k~.-5K=I,JţM2;:q6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷw~џu߄>03S[~"a1;_DRd2%CX6wp*ƚV<9B(QE (/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?QxSAtW~Tm*NZT{A ["'ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F<GKU,۟ ҴQSz}w,7ڊ@mcԤ/ξ6| j>!K-% 4huK.`ɓxB8~x&q_jm,6Kra e|ow3q [I>㟈-^.\zEɴi!Yn1r+iIۣr׻vVRn+FJ4۷y7G+w O^ "++mYMf*!2yӍSqOV| R"NsF-llUKH5 d-7clQA~|;~!M^JtkOXO_k:|nPIgy$z̭ ob=oB׌6\I> 1t nXJjJRm'7uI9Dj6VmJ[kDɻ.s?UNxGAOBFoA l",$X1x  / P~Լ;^iKg u-jgLxUn0aIV> 7<3}Ʃ[ x)ϩgc 76yVml`}E b ,O/H4 4|iOZzo/-.9 `t-`֐K$&5bJQզFmm5e(٫tK}ohf|a%|qu+ 𦃪jWmƧW jե(Kķ{!#JTOd{|)Q7ŋw\".xĺl6۽Z=76@!i"2yؿe-f8𵷃 ?I״Œ"E#,#@X4dp<z]kwZO/o/56ͣ6Mm4Ri,&+ =BgOḒ'V"i׫*ZE˧vi$Wj8PMRۦKw? >%OD ]_|wƒ]^;hv6b OeGk C4 HE&jv76ɨuCn@"b$jhhZ_4,ͯl|K [4ί=ݤ3-ݞ՝ށxXm/NO44ԼOu}ŻFJu ܒ) 7n%O}[kNnff徖BikO{Z'?X/"׾M<*B5#X_Y$wڤ_ڸ}Amb#F},M#5kvy2O$ȍrK E,lF~>?wrǚ+ YxO1kK;Ma["ޝAf g1:z;heyVCoyev17|(MVvVu4K[^t}~(QE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢otZuࣟϏ?Qxg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{A_&Q>]STvq\jV}DͶBJ ֿচ̟WÿZ|!wy-u㣬֚TvsmFaQK c4 b?d ~؞|O}Zm.hק]idneuBrS7į?ā?~#4TX5\Ee٤\<:JT&RuN>׵ݭkNW;o?~(jm{Ěrڦcy$m }JImwlJj+i II|Bz7?)ōGI|[ŶyhAuijR7ʋF$U5t iV)^ޟ?5sY, {-`X5kX"z3 2G,~d6vx '‹O^#ЭO$mnJȝ0|Ǘk)X͆I/cr^JϖբמꕶvoV}A}5ƒ|MdԺDծIC؂PL/7(Igkk%ǯq[įiiß?uE𾓬M ڭ_ ^))'Xlo.mpeWLDFJH*ٿ6XKMkzMi>Ʃl4 YV$8K.f4ڒ(]Z>^X{k|k+m}=,{{0*(/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>mԿ|N?0G?!xNwj_U'؟akC><D+׭Ky5V*o5?_5a?Cc? ?>ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((R7_οsR'?q_>H4؟akC><D+׭KyCFs]`3!aUGYfS=ɚ|$/GkFb3O%C yEPEPEPEPEPEPEPEPEPEP~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE^%[o(3O⿢m[JL:-;?QHgǟ( ӝzz?.&~-WD\~`Ht?V_a?Cg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5U&؟akC><D+&տM?0G?!xNwwCFGg1 qW~e|1zD?Mk,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|ի~&z?â|y9WAHıgi(/Oz~u(La&5N*4߆C0cB>l?L,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+wWL:-ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((cW ωA|Vak0xD+fqa:DZ~F[%r^/F~yC ;"J*Eٙ?a0?HX%~VYC ?>ؗ 5^g_~34|;NΙmsƚHbFrb !@pJO>Stc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|f _LzZ5|g?xSRø4i:MԖ Yx'd- T L+O狥kF L۩c*R@%TJߢ?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.69Ũ@~+"÷I"gUsvXJEP,RĂQHOǏ( ӕzKџ6??a|r~P?)_%|B"ueYfS;E_QEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Q|c |Va+0xj'?q_ŋs7_vZD 4%r^/Ge6??S|!^'A!a>#.۷5Ɋ=SW-cVTG)TۥGQ^qAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP半YN3 #͓?ƍWB?տc6O[?dO|vm7lBWk˦hPծ <۠HbVy1bɻ]CJ'ٲzׅ%~TfNQjc<(Ϸ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (,jWhO27iRڴay|QG#㴲+'VD \³Iu?'|Ma^ߍujs=ށgwmk{[=d΍9,hȒ ۊU/h?@+4;G4ş ZO}!9~;MW߂4(4+}rM|@o/Xawpc\4mՁ8E_.2Xj Mw#xZ)iKtᥴ`Ȳmx h?@+4;G4ş ZON+Dk[69i);vKJ;&IkS-s ' gfjI(_{]|Kx߁&t?52mzr'eX2%DJ=+J*ƫ!Kzo.x|E-LDr:n;K( 2zW_o{Lj(h=[o_iVwdgPκդr[fgG쬅G-s ' gfi4iu>a?e?h "MMm;YM!<ȯMQW(э1c; 9í>1.n+]/?x={Y {RX{ Y"c1X2e}9 gfhD \³I=:zWooʟaOM|BWZC^/<+'J'?q_|01oLWj6O⽊~wkc3t 8B/_u+-~>_/5~-m6Ec:m^Eu6-#Hu9QKğ?WVk M++jgXE:iϚmug\W¿]'5/ +bMwvc#G챁Q_ tí㧊?eS¿]٫~GW~Q_^{xXig~?5Gjq_W|Q-Ÿ]5)NJ?e+O.?#p@uGwj'?W]%&0wZ'¾g/U_WS-ZZv?F$w<)~J #ڊҳg,)<)>1V%V7Hk-_?y/&;YVf_[_?x W~_Qi\ĿE|-I٥xV[O?C٤u7+o*|[4Ieox[6??x?=_BK+[~2eaq_ ?#S}К+O~!?<+TjUV<-}O?E(٤+]E7f#oeqqO tfK*_/E~vGٵPo[# |G7;dxW¾͏O?F/W¿]*sC` W6??x:vݟĿ}֞3ղ|M+c¾xlQ_X[]/?? =?ŒxV-k0$-o.??9l|w:,쭷V?X@?elW]R˗'?9wp߲|-^{te`M|%TNjT_#B/Y?Y w[?]~G-OE~N$Z'¾O,a_tg/*/֚+Q>1d xG-g8xYW?]~GųJ #?J,|#RBY8k._?x%OE~N0kkk_{س`9c ?h\ॿ <]{?M'=Xǧi.ڤ[ &Q8!D)WL|ZM߀|)xT'w]]YGf$y`my!=BRQ]s8[U}MT+76m[k?#hLo9c է2$uj|EiڄYF'y3R#D<@(t]wߋ~"ď5=u4|RMoRM,4Ӣs-͑%Ԃ`.%󿼺mÖڔcdMtc?g~ 7/"Zޥ _~he-.,4YuS$.`e݃(RƄ6?oN?VK|)|k}?=K4Kn5O"1e%Utg[7kkNZ%[sʅ~iEUo״}{%|3Ÿ3SkQ~?Pȵ{^tU[-7;zo MUmN, Ԥ24xe`ʽϊp'(>^6X::_7^|i #1SjK |NZTIfz*b̚/)$DEZ*#MYVp?r!3]kI?~ !T<1&>*"sɣo_ٗTfմ|?SGyc  9[>q gٗTf4lcBhhN !Ve9x 7ܿȿ*r3GCFwc  /C4/gR}_5_?_hEwc  hN !U(}_WeAehN !Q6^*EQϸD9{/l;T}Ewc  Gp?r ̿"̶0yc  Syc  ##ڏ~D2r2ww'4}g  H9Z>qs//-t4F%?o !U Uy88ow1r3[0>3ÿN_Yᇇ bi\uRG>">oy`1!V揭xrr 1> #ef<%p_?L?u0+^yx kw(9PtC=R3@sc? 4!Ո1wSt@:ÃRuXKC܎g? [s SMTXskgCsV5t}s_3Ҿ|WO:_TGÂ&hŨFdb gƽg?ǯ_nt?E_{N`]?Ibn1T7t+_x^<< RGE4g)|z}.iGD#ҬFս7{꨿g@?>to{m|YUHu 䁏|m8ƿ~/RW#oQ6i6)ez奇U/hnǯJo+|*4NY'K,;;3[ffbI'$$|g?^xcZ'd7RXȊ(*~7 y[ 緿o?EWorimg|0>+;>ikϯs;d~ |m%G/|ގג*"/+BcRKnFyQf_~"./".T{Xe{!$Q#ȠB#1I?hwion璘C3A RT,[/5ߢ}{9xWM>]~  W#kkXI{([3b@ N6˷#FO=B!-68K_z Hdye@#?Vm}n>G[㾓kxO-/ ]WEygA<"cdI<fبf-_>j_"b _JƧ)[kÇu&~g(MxrU E{w[?>+?>)x:)VC|7EivҊ [)?xN4WK;Y{2̾hd~ s4f/{KxlK]%\5C?s,#-$f^1WR& ;DUjW" HUG`dq^s:~Ls4$$l]OO0 k2joX5t|tk^&])l>4,oMGs+3KP kҾ(|?~8|<֯s{ocy=0h.#@ + A8r?bi7.*[}74lHO7oюVUjY9Z$-pԢ}zlwÿL5x5 _Pu=?#3V1xJ?,HmSe~Z7&MkǞ>xrš)fxsNXx͵&Wq2yb oڌ|DE&:omZMI=].i}|޶} >*1'm:vJ*ݚKM/ X^jsXkڎIq"4.u= UpB>~:LO𿏼-[$]j:r*;IܫFdXUљ2}#s>IRž?^W߂i~M.KoI cb}/ =XxoBuz.%ef76yTL& 6S?ú_ko wk-DMF呤c$A≔H CϻoB'Io[O_o47-dV[6Љ|-}uRo0ӾTol6,Ioi(ϒXa?d x(բ_;~*DmX_ڴ䶉!)X2|ﻯ?ćN~"ޡ_?n!ޚT4\?_-f [hllm-h<;2xo%|Cs?ZLj/5Nk_Rg= (U#$ģRC1r*s|9~t,] >(A|[< /)?W/#=i~|<?ZoO?φyM?Gdȉ/)n?4>X=Eh͑־O$ of$Ÿ!Ag /ϙT 9iF>!/<7_ۘ\4>cLC E`/)?_C?M_Ԝ"x=iT|YyotuOş'?ۘ+<i~|ʭ)k_|Dkugş'?K?g /ϙQzugş'?9O~"dص_x\4>fVY{-^QD'[_o?PԼ-:߈muoş'?xK_20y-^QD'[_o?PyK35}+SZo9k(~-7߈mD> ?_(̇>Zd_Yk>/*H|[x /ϒ%B3U_\#̃ /*?]|/(?/<i~|G_Ż/)?dO?yG~!K3+Vh\s]nE{>0 ? #Ȃ|b/*^sp~y@?mG\P7;o%T!#_)W? Yy~x|15n Gn>#^T4-m k g+|<d Buл t-b5 ?}]%/^؃ Q5.V8no[xcuUo3*8Ӑr5/_ [zxëͭt-te#] oeݒF` ~?i~'gxcu*O|T2D=i.gbxWa)rJֺGx _1 ?Z4.ᕾ'#1˺%2QOϤqr_oV1xc_S_p t~?#?wG24.mr/Y #yu u:6g=2tɨ\ C-đs|oH€oA*/ kEX_hLԴMmՕ٭m<:v%oTe"L_ 7͟;9pܙ馷Ik$G?h)"ӥK#[?ydhOi+:<7k#ACMqbvْ;οi _?{GF|C톝s{{q{yfkd \Y^ර*=+Zjp^Ϣ\\EcŮ2FeS "Swu~i&W#cÐ[0xe]a-/.gdkms*R r>`+~4|jOO'KoA{|Dֵ;}-lRM)MOOZK-6VhOj>xc>;QӼ xξԖL_=Ռ-6e`{/t< |?/t_|dЮGUӤ|Qko[KX\%[O*A9WRL2ez]E[ܠ6'Q'U%~m+[wGOσڷ=TkZ]'uq{,ֺxh^HA&PRhc$lȊOQ%kz/iuukkSmz=QE# ( T’>EQEөPEPOO)((((O)Ÿ@Q@9:iրEPEPӥ-"t(((uEQENZuQELJZ( ( ( (uSxrJGQ_W#cÕd&|ȹϧR9@H.h [)?xN4S[ [ &ƀ*QH/㮋i׶V>3gx<#I -e _7# R:wrl9yo|[|;|6zhi丙 0!6JW$B^&SrbmhY\:w|unԩNΓ#uF~z_,(k~Cc h!)&umQ]iaX$cS%v_Ex/q])m-k kk[yYk{ۋ=6]v0YTrsG2}U=}ӌw[f\zo|un#uF+_T-ލsHנT Xӣ.ʾKae apex;W+sc~1u]7R B.|/sqhy[J]%Ki-SkI-!^;ۉMBV|kv]v~__Ǧ'_F^UcD 5iJ?Mo|q nEN/i]FQ!#?yR/g< x_fT>(ү]lBse-iַ-n45܎fw}gRjIٿ?vKl6+[m[ v ebZI-s,@ <-xL?Q.ߧKsl=ǖy',pv8b|Q}7xU2[klk}`-||%qZ1.:ƙyk7z\dO6FRttY@h YvWlZ=_Z<>џ~*|]g*8;^5j毭y߅ 5ћy ~B@I$K3T`EwSIw?gi_ 4X N=߄meQqIDraut܁Z7tݗfISW~7q~j毭qЇY>)#g|3exGºfk="xYmt@* BI 毭*̠MAEH~п(B{P/J>п*m.Pg-_'CT jO~'CT jO~o (chl P/?~ (chl P/?~ (AoeCN|_ f@_o5Ei}/5ACYP? P5EjiCCYTPjp̟ԃz㦱 H?:hԃz㦱 H?:hԃz㦱 H?:hԃz㦱 H?:iFG?XPOQo=?EmkOt?XPk':m=Eom[_tV?X4PշOS[@OQk=Q@OQk=Q@OQk=Q@OQk=Q@mr?{ڒu-I,Hq<;_5EW5o>W'?# YxH.h [)?xN4S[ [\6>s4*QHJgүų? |#ųΦ_46y?=3?OVG_L^>|1ߊ"k}%#&m"po}g]3g0x%״mɩk|VQ7!!vi"ki 4bOյ {n?{W?<3vwڦsww}߱?QjGn7[TߜҼ~. SM^/?#蔚/nHs|!$𾣬co * F֚>|jٸ,Dma$B)^>GK_xŚm.|7<kiMMt+8nG =K &V4Qq&]mwe/}|='ھ7;3Kյ {n?{W?<3vwڦswJ5n]ɋi%kk|Zm1>2_+aoGoOXx[i)ץ&Vjv6.۲vEڧP_ĿZφ4O<-weJ Piai홄11W/3WyԵ^Uuu&85tBڌEnFN1o&#7o,<-*-Rk~gjm%FS-mk|O-?O-cAFVԵM4sWۅ 5 j V,;}c;x{T/Š-W]|A"Ζmo.JIi(#aMi[  = |Mt ~|V!ep?/߆hǿ6:9mER󒻿ҷFsj+M5ЅW -|j Zysj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easj+M5ЅW -|j Z->iW_" Ư*Q/Easjw\ǍQf65mi*_ᗎ4 eGwi\=_aI. %+,S l?ڣ SLZ.XP쯬5+{2o'PXIqk ɡx4i>yyo\vkYICo $~Y*C/ƞƙjhP`Ve~~)w?N B·716Ũ7%r[*݉#7Kz4nfQ'M)$uBM-M(|5?؇_X3v6ֳ DwΖ-Z0,D#:{ !WQ(O7%qZ`'-n&ݤ@ 7p.C<˛%mK>_/Mo_R{Y>3|MsCо~i+]_JhuAm3m[\6Vռ9#^cݔuf71fVE;ݯ^ڷo tڞ*mCNrfKF!Ts&l` ?+MCFÞ*:Kk[&6uV,ߚnnI$7UTީ{8jɷG?n xKƣ|4 cRxvw–/Ŗ0fYE dP%?m-we'w _|CcNᵶ[;8nY.A$3Ty/4j_O_A ?v:Ԓh-Ἱ y&k6YQR"ҼdE1g.|O?R_||y[è0Myi 3 {GmpG~E_^mOޑj {{5\$ql,k.A(ϰLOP>3[OZӮ`n;";'qphQę;VײVԴ-'˝jX[nf۷^IrߤWćo0|.#([CWag+ʪ)Q gWBnX27[|WMYoIt9Ԭ/|ii$h`ѲU yʟ?MڳokO4~Bw>#kSj^lJ_$(UX >#h+xVAj]=,mU[#L:,T_+rZڔSu9Y+YYsV|]oG6ÿk-OxM{{ayXvܑ G;uEÿs5߆( پ #67KOlQ%e/ @no?Ï"Wo^_G֜ZEcclҲvU#%_?Kc^ #,755'ԟS̭5G$ZrIG u𮗬x7~)|oxO`ӵ>#ͼ{Q W.vA%.,Ybe$i4wmw- J}+-Ul2ٽy^7cw6?W´DJ-Ix>of ya`W'Ş=_t;w7mT՗M[[inKy۬j\3w-)CljMnN*\z]O&ĘrTWA~߂#ūxͮ^~+{Uo7Y[q O3*6RhM#g~v}TٴTmڏ8KEFO[z_w>.|2үkgmh)}j54Β7ʍ`^Ih\~/4/|>GSHW]+ƖK-NBq/, i$_$r"lH|hWX2?|7kkzׁn49Ӷb"d6̱Uq?ǀ8oe/.2^W0C C}ęz Æ94YfMmI%Ko%+٫F0վTNr].xi9]4vw֖_hm.J|un6eMf럷_ hdU=:uϋ,!hX`P,̨5A_h|=sxÖck3Hmu['EԑΚl֍\Kv'LPk~C/߲>xX___ |k|I _w©'X>ﻵz?I#~n/ƽP_)J `߈?W ⫟Mki^W76w_q4R$e{%0r[b.?gOO?xlU!f?\[UY-}>!}m,{p0 eQZj t[;-ttzm4duv׳nmW#j_:f]ź|#v 8W!I @< 3ΉGU^(º>Ww쓾I 9\$~*Ff?x{r_ORϨ%qHu[kVh6׶Q $ Pǻ+C7—ֿjZޭhfR84}*/)eHPUJo<og}+$'{^\ڸsw +><_75kyw1W1yi6.5h?Q:f{|w7Y6wk]6hZTeb#C,f-"r ?>0U2oO::l:ٳIku[hmɐ  x;C}Ff{ ުXܫDzm$|S[?W/^V4nZ=M's;6~piZh?G(ٟxo_ [k~&&afYR960ǘ|j|?KOZ>7ͦru? xA_MS["K7$ZD2Hǿ_kۧGTd*K睈UW+7k#NË/xœ-༈jL%[R/&$?!,-e.fҵK۶~qt9HZ7qiIGos>xK_nׇ|+Jygϰ_ycrvnۻ8l`aDUծmtk^ 5,$Z1i1| T_$KYoK5>V➖riSQ?4}2]/Zk+IGtW×0sY/ @%wkv?P߅w ΥUmmyn\16-],9H +3GA]ouĺm3Gbk xRkۛ}ZW2 ,VdM/mk<}65Z(m}7iy EH!h|do]6UI~߄iߏ(Ouۈ|5jڍfY.U[@Z)K̆5ky@c -;o|sV%\ӥSo<O*P]N]=g㏆ox. M]/W_ 9յjrTHDl.>&8Q[[NMXR7Lqd Ig ]H8ѓ[_^xV5o_z? 45ص+hw"ymkeW1\Y n' f/< dMM AjC_'cf jcG&ԝ-x@M<ׅ^%}Gò/tnLϨYIu{8%sgFnn%6ʕ4S׾x\M$zϱZ-+.y1L"h }n!;{OQ{=<գM/St kw4{)VhRPby$E.!|Ə/ͪ6{OÚ=jt)mt[.Q㹽[A3(w`t3PҬX CmdicY_0dH#l% E>%|!s _ 3ƞ;T}N bHo;mߵCi8vtn=~CXo.j_c/xG"Լ7{;[ ZIkHk4Rq Yx?<>?z?[Ú=j-.dDf Iko3*C~zwoCk^<[kj(_14kF L[ ~:|.]P!j(ѫiփkhizoup'+Yy0O*G)S u)9Noj]-q켞]Fmuv>w߆|#/<hݤW7pp`"X>wk&|˥iF9/Gcgn*Kr(,Dq ~_S iOxq4?h+'uS\^O²K OFK2w_b؟\a=L/V7 b;@k@qM,7ݓWnVnvm%~Q;FwvV[Y&wgHwGᆳ.se΍x۬M(IrW?<<;ImCXhzm,p%<_nX[k;x5%'f3ۋR 5 ?W /OM^𮭦4EEum%ս>ș:u  0ya97gfuOH.ck޷ݻoE}#Z_ _G4[{m;\|?"h֩#O_a;ۻ!$I IQxO xG𕌳x*kv)I)k nVt-`2(uxK>/|6ѵo×qeuqrZCuRO|%.Qcx4*e3Oiwɏ-)I^5)-4t]k՟w`)CXiߕ/N>_ uxCAU;G(ПoWŸ>%uw #N?jVwSqjڤַVYKVpԂX]7)gR4m:x<:^g4^$+t69ʡ^Kv;-gm{;wݗU}۫ oq_EѬ vC$@6˺'  <կ“;{MW ("AHuMxCa =WFiVki?>!3Wn\w [FV3G?}=~m;$5@R%Xbt:?!| ŦOG\Kxt>!_-[+nZݯk.UݒO~bUڍ5].ՓwqvVIW LE|BS_~%z\WV_ wUԥ '[h>)ߊŷi`"2dq E~ux>#G'PLё@e_*8m dݓٷ%gkkU}yTYrR_[i>w>q|7OiVa.4+ѭU&nIO.1 w+ `zQ ?)8M|BSG(ПoWSEMG- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv- 7_'[0W LEu4Qv//thZ}Cka2.eP~ePyUE9+ހr|mK}[ZjWZ]wR2@./.ᴉ* lWY NE_ǀ*?C|0;{kxzy` iXUPI')c+ ;l|L@D8:9?۩ܟ>6+c K!|U{6%Ӵ,Zʤe%O#"ai>-牮e7St0xTlLshIgbTç@,b7rB?Vs_7HiY8 b~Ŷj~7N?z|RyyhI?hA+t q)&?N4Vc[7%iw@|s QF7.Q^oO`,?G3?!:H7.Q\oʏ_ӜO袊=0(((}TLOj r2bl~hpf&~ tMVer^,ORi%0d-@@ w 2#A\,z&~ tMWY|, ?9G5)\,z&~ tMWY|, ?9G5)\,z&~ tMWY|, ?9G5)\,z&~ tMWY|, ?9G5)\,z&~ tMWU/cOW$.40OU_ӧo*(cO tMQ :ߦ2.40OU_ӧo*(cO tMQ :ߦ2.40OU_ӧo*(cO tMQ :ߦ⫗4?Z@|W5k]FMq][X"=H FHǚď)~1K5 O͝QX4b+M2n Gv-p~G;$~/l/j:cx~XV[]Okm!ItP\5LJĩB\Թf{Z=UzfKmZS|; Q\!~VHT a.:)j~*ԯ|1Z5}Y<7uC't]xV`d$yaXcnpt؇UAӿf¦ִ[_਺I4wRrfk:Mfn+J}- [۱z~Xd}tz_s^[y{~.i|.C}oii%.O6k9[ 6 r9*T ~.i|.C}oii%.O6k9[ 6 r9*T ~`KO·aw^igA_ fËuF&Qk$k{\hKr?E|)ao ;xSwQkS%BeWAlHSn~VW7ge|=ҼOc.~ΚOu<4hB5 Vė6h!- U ׌WW?]3j~'ԴVVQZxa\ ;q1PHsY?)蜢M]}lI|4yx)/xMS0OX^)Ѷ:i(nh{6Wot wQbkutxᐼ3K)N7&a\_x+tˍO| sP56MHu}Pdy$Apʋ65߆ $Y|2ﵿWH-^ޫIb5[/,pA 6b( r[žhmSNr}4{Oūf{^WV~g_ם#ώ3ך;q<2[ H hK.9bRZ6de-j}kNWNw-;Smbdస⁧ܖn;߁]φI}gKeD Gi o,gۃvF%V9 hJv\~Rwi_ⶍNMAn韫_yG_בeq?SG&W?5Go=y^G O yO0x|8ɫhZ[̒.XEyk!ʞ=͆VVtuxр>["_Y_"{yǙ2 JV\l-$E|z Lwwzʹ&|Et|#(Y/#,Kɿk T*S| }#"ӯ5h7.)WoBp7=#O4rIe-ŴM ʏYv :I,|+藱xzGLuoQ d c% soZ^_g[ԬEz[ԦG)(IIm82tm%/)۲NTKYwM+dk~/xW@[{ZyRkˆU"8aWFDEf' o)-wCF>hW,մ_ܭY5ֳsփ;Hs4v+#]ŏߴC|,lAI52^ej]ɦ Ď$pkRoͤ]mew4߮ꂶ}F rzw=3Sկx t; ~fDĨ۷XXLI /.?_^4NH뱽jsh=R\2InMbX6([ZxE|'xu;.m*P%_کAG#VmCv{6}-[ktߏ|) m'Mg "\ K*,+B 1%cⶉs/EáAy_x~ყO$,7F:{_}{MkYG ]x_/Ǘ<3o;ud8y RapEe9wcQnE9rF/g}lӒZ8tߞ_'~Q_ GG.?|=75 PxI2?M'+ Ρ{C3Jr-b6ojzϤ^DGj)E}-ʢH|0dѦպ]]rWuM^n%Tavݝ%^$r9ð\W?֞0RA{/>׈n-cIo$!-N#6,"+t_Nᩕ|%B|u KæQy?b>'ŷڞ.%~#WEܷmU黟u|}g$u[=:LҌM{]]Eko^|D$DQfP 4IQ]@dUr: %ֿ}&tU}Yqk%Ρ V{yeo;SnR;$mbhkzWntmggĶWZ啟tQo Ѯ ۷H.BSlqpI{|Tmo~+jҴz4o}{Y[]^Fk ~̖z-n+];Yy-ԮcYFZK$r euVrY> B -oK.<5Hbz dmA4Ȫ"=?aOſ ihfWy](@<-"}EP^uc>9>muk?R^C Dn-v/Bv;-MV3Oe,PɨNGvC;*2kN|%>,%K OoSVXm^Xexrc{fiMonֳIh}]m-Dիwk?eOszE޹s{q=“i n#Uq+nPy`Ŀ Ě֫RwxoIMGAw6?g6|sW;K0&ǥ|E!mÇOǃ-cՅLnfm')2 veiv7ENOeM촻WY9Y5쮵vWI_$ej[d:o̖GNDԝ8^˓eͤP61,FO Z~:x)+!פwL'ÖZe$LҵXk fK>~8h|j:&^ AĶE ZڈeQCnLr@/fg{$kKo{O߲M=V}^sҺvFL R.l4ys-RsqGf,Q$E%*O ׬OSZx[oI4AYdX$m~,Z?o /5+Pмk-6UbI$Rq%b(e6}7ᗈ7K/YmI>NW(E۔bY\ 7o¿ h{[uP|4u]NNеF+׭V ?Tܩ ɶ;΋emu2x |q׆<;%j?Ɵ}KK[.aߡ .YqGo"ǭ _>sXY+_':mmk$e48aQK|{Q4TZ.Rڴv9{-;?eWzFaq|>+[|`]s㕾}0v/>.Е{|5J)p q^_7_f_?5=s)k~1'廲L_Gi6r'Dgg( }~ҍ%;.bmw(۬u}_ʣ/.`*@(((((8 b~)?౒2~0Xg}Z~q [I~Pd> rY?9y>Q-_C5;ᇢ'S_=Q^qEPEPEPEP^E?='RԗE7F{jP[j{7&f4fi%u |n8z?mßiANi48cXԱTd{ ֢ ( ( ( ( (8_ /whΏՑy0[*(x9o)ڽzQ6-o)ڽzQ6-o)ڽzQ6-o)ڽzQ6-5 x¶VYjK7Z6rONY7(((((((((((((((8 b~)?O׆o߈_'Nk lGŃQ p}|$?QH_Ǐ( ӕF!?xNWW)韵?!aUޯ!w?<<3) D"u ƿ x˄)# SȲgv mO}gӟ 5~ ?dλkvg8!rƻ t|5wY&k?-FVwxiuC6{ocmĥq4p%[9OCzE~5 sDCҥM]xOHXF W4~J!\^Wi;|E!9Qmy?DS?^k~"}WiY__oq̈]4Ψ @H8nWwǭKǖ?*g⇉\~zuzWzؓNH̷"4Yl;wx[A<We/x,tId,4N}>mѵ) e iکi)S)^m{&ܢRKҊ3ĿP~ؚ'n>emn4>;Xn!Yd:7~^^$5px'GEmߛo 灒L  Z:TlAq-Y-(ʼ(l]L%UI?z)E~f?7|jm>d<9ci)}PxT-Ic,LW,3Ć'뿉5w>~< M42 29"[Q…͘0NQR;~/Va9(.{3蟈Ÿ4 xw xX5xP3Ȳ8wWj#U߁1?lό^] xKğ|=x; OWvkqK#FdI!gUğw<755&[MjM'ZX]i:n V2{2GNlTBb>nsQ徿rZ[Wi=y/>X}4Jj8~~UV-OlvW^ӿKMk:Ixݵ5u{0fX6%pno $Vu+\ѴB\~]krh4hX.5١H!hҔky4&~%vg2s{$E~Lo㧍?g:|ikh;յMf=";Ltn'Och\"+$Q~zqkGex{Qgp B}Ztk6vma,V8kM)=._[u˔Zm>_[Zw, ks,j$;FyԩdZ?_>d㨦 g/E!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S~h3ma!S%H _iY>c%T8>csq':hw9o?C~!؟9,o!x5R$7&'^?I?G??ࣟϏ?Q<D(S?`?eC5 o5]ƿ> e C o5]ƹ =<-oigoYפ)ioYפ)kqQE!ydxs3O5/ n'񖱪i\%{[--IFdj;"F*}. ( ( (1<%F.*~+F?$jۉ0B~ڀ/ɜdv袋k//QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE۟^פ)۟^פ)Oau9o?C~!؟9o+"Nj^ԟ?C~!؟9ˏ+w_^?I?G?ࣼC~A qHX!}o5]ƾ&c/X#}o5]ư|0F\'L_|goYפ)ioYפ)k}{׈YxOAtz1w:Rͧmhxaґ /%-~ڗmkA5+ MjTy`[RJy2oE|͡h_žS[ui,E+Oo354R"++Ě凋 I{@3A]omb/L%a4׳QlwR]I֌M}(mnZ/m7N7źմ h"muR-BRm+وLTD_0&կ߇<2jvd n$bUfxHY%#3)ɼ!L{æP2(oT| x'Oj^g.{i:\&W"g;+ SSEEZCZtwC?ߋo|_$[y?Z[kSik$dA`]v oA֗?*I<;:g\:e LD'Q\׷DwoRfwץ[ۡg3^kG3^kPş~Gh?`Ԍ/5M/5Mb?#4ş~Ghog? ߎ׿6g? ߎ׿6?`  -?~;^?-?~;^ڇ,݃?G,Yƀ&s {hs {jXvg/5M/5Mb?#4ş~Ghog? ߎ׿6g? ߎ׿6?`  -?~;^?-?~;^ڇ,݃?G,Yƀ&s {hs {jXvg/5M/5Mb?#4ş~Ghog? ߎ׿6g? ߎ׿6?`  -?~;^?-?~;^ڇ,݃?G,Yƀ&s {hs {jXvg/5M/5Mb?#4ş~Ghog? ߎ׿6g? ߎ׿6?`  -?~;^?-?~;^ڇ,݃?G,Yƀ&s {hs {jXvg/5M/5Mb?#4ş~Ghog? ߎ׿6g? ߎ׿6?`Ԭ-5;[xu+{= ,$&D$2ct%Feʐ Og? ߎ׿6:6˩z@|\o.cy4͗lRY 7ڇ2}뗳֛xkH>,GhVkT>!$sjnvok>fet@(gM;?o x:ώ5-s={4~.lbnaI#(cLUU9[~wɵ|_f*KGmS u_n2>6h? gx:4nm_SOq2A Q[Z\K<Ȋ[Ҫ#oz}!q+rrBo,A$Ys+?ࣞ& r2+#]|wh׌k?x %>|)j6M#Mn$ӿhD΂gǔ)JI/61kݶɻ$sUݓ{] ;M5V|F۴VokvLjYnzGwOϢx?/65 qZK,60MHڌG_O x?Wƚś?M$]|6D/,(dMCQ爀LѠ_hkgO |CWt^XRM6O4ZHڜ l‰ uק}ԬZMuL'$ܗo-֯^~=>RmG6(,^?^9QU >- ~YhVo Egj:I EI6qK#P\Rw:k(@Қ ik~֮4ݦus OYV_ _Z׷~/ׯ ]3\[2PH40dBcVD 储}컴gZmV6ӷt쏿OW?>>|BS5` : 2 9/XixPYQf0>]M^8-ύWuYL'ӵ g)4,3OK񥲤WOf׫\n+GVћhuյӺϷ-?~;^?-?~;^t=gSsvnmfatDqrfHRg-?^eƯ3^kT~iRxO<5mkw$Z>ZCjq618+m%nS}c-ö h8;P#Ӯ{^覧Sn{^覧U=8 b~-")׆+߈_'Nk yo/?{xnc#|K$tC~<E(C><_ ӝzg(z|F:GWk`G|ec؇F:7Wk`Gaa_b>: KN: K^C㨢C ( ( ( |)]jd zΥ{i\AunnI4l6 A<$} iGIDҽ>׼O_i>JE«Rc-Yd<O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZQ>{<$} iGIDҽO/Cg'_J(>O'=}ğO!~z-+??|B?ZWu>cYѭ|QZkhY[,${X"Jѓ!yn$z 6:6 Z< eSW3^Gk rIHT"RB 31?SQz؁_^ugY5]^ [ ,agiknfh6W,dV,\p1uE6A׿?ju6A׿?juS]N[߈_'Nk[ A)Fּ7_?B?Vs_ZpOּ7_A_>%Ȓ~BF_TO??򐟎Q$5~xJKvkw$VTY(p 3օg{twgvkh.KE{OigjHf쫅X 2&-.x]{).4KRx$hY$Ddu'*A(k[\WwW- R5/(~8ZG Qo1h#TYSUޱ;[XA;h{*q)GUrB-/STڶ W7VH3\[E)qܪ)B1oEr5/(~8ZG V^m_WOO?X0<61A QREPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPn{^覧Sn{^覧U=8 b~%പOZ~|q [I~Lh?/M_xnc#|K$B~<D( 5) erOLoeAc87.Q_x>uKa|Wc_ɟh?| S_޻[{ Nd($j6>)K/ PtSgis%|vK'#tt ){ {[kCnlBծ˸u °@b2:£<< @5m=잽k7]hMr٭oVv^UݚCN>1CxZji]Pp݋5+wa}i-LHƩxnkqM? :g6u->ӣa%& !Ӷh*??= ?QA UTNj}9wR颳WoD?:|CaxT?[6zWz.SŽMmdͼjnZF-?l/pS񕆝gG}* iccF a8m&FLʘM- 7oT燁{{U:"zyio먢z$sѥt<(Ũ~W]马ij*=Xyׯ=O-kI) YxMͳ>,_dG/]$S洼4M QgwI%HY$K"p uQA T:5ZOGCg.g1r+{nm,o}kX~ZEr>u>ugbuTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]Go)?]EUEr>u>u Uhx^šhx^šX.uTW+x kWQx kWQ`Q\o)?]U/xßa/ JOAs4 mC=jZe$\y.v7?ISSڜfR;k1FC]N[߈_'Nks 4lO׆߈_'Nk &l?+ku5G_'(gkR'?qE/k(WǁrOLu엡<ŽW޺c_? i[I9$ն :( +@xt徳 &wp- oM1Va;V;Apj¯^|Gxs^T(u)]k 2 k{tS(wt#jzhjM ]%IXBBy]Fr$@tV}Nj?hSj|Z{ܢ\AF̑F%f2$У(((-=yZ,cm&[V+9m<= 2AqS?[xOoL?d&}V, (m<= 2E3?d&?[xOoLLm<= 2Z-u]'Ps}6KWS>_AE(Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@sT@Սtu|UROV5Q:{ECSkV7_-rB?Vs_X`A_^կ?C~!؟9ʯ,">!{xu p}|$QH_Ǐ( ӕFxU_V?|;Vx Wm_+Yx_Nas5XOkyqpUAlV%_j9kf_(I=NcnkxYVFZ$r;%\XʎJ)We/Og#H_Ze3KV`%/nml4[o}f^}+R 1GXHR6%Xv#k/m/^>VOit-1u&u[:rr)*y_b?b~Si%}ݭ~'m?;{,;I4÷^! >?§Nwӿ!?S?(_a/y|Dt("b| hT+h׊_ǎi?'O" k3j]hꗖOLm'6FQwӿaR|'vºΩhW^zͶy}ssm$0;3I"$PQE|xi+վ(zׇ?o>}kQjEujJ'\  je_oZw߈^ 'oGgfR$/&Jd; OZ*m$xI+tWHduݟt] ?ho?g@:zyo1eg!ƊUD+~/U~ C|-CVꘋJD&(BcEkRIө+s_;M}wK~],"ħtoYf6?j˼,G!Rk?k߶_M/~,u1|A,)fmxmVl#t袴5Q%e'uok'"\$~myXUO?Wťi~φψVGVV& eYe2i*cfIjύ)?^w|?7]iְMk yjo\3h-"m-u,E;ъӚ*[d-=.ɽW+MYmvz]j6crԵ_UMOCu}Hӧym,d6.ZXyii_Ư'i |om,Zx{ID[n8/nֲo{iai+-4/=EW:vyikz_[hԎ+~)+K٥tm!7=]A8ҟE-SI'NX;/^wk_]DxUudFSi|IJnlĦÉ6 {2G18-5*`88?¯G:v;u<֖)-5Hv9x!e,dqW"i/k2F]i$ټ<9&"r,I\m~2I(uvՖ2M=(ߪrY[ZSW&#×GF vMVE|?N^&.mv85~9S~o^k4ݯ c1X%fU+ ] i&Z6hzU67LskhR 8HrX`;|gh 7c '~r[vmjۛvcwe9$?Eխ|w~ɿ ?i?|E׋kE Yjd[S΍MFۣ&P0H__Vxτu[k~߈/Mn'MomFX%.̩#j&Ú Ƒ`dwKuU#]],1]Dӵ]Kil kiik(R8pUH,?/NWd譯0Ow~輖>S=~ߴ</Pˢ|OL45Im=H9$I"X>u[vmvOӵ|-,/۹8xyWF2Q :OH,?/'u[k#xu.DlhNHfMQR0((((((((((((s0zϊ*Yàƪ;gS}[跨jm{ECC]N[߈_'Nk k6F7_?B?Vs__We_D Q p}|$QHgǟ( ӝG?!xNwW)韴1@\"?E_qjw(|>=~!}ѫo5]ư?vυ?J_  Z(? -+[\G[R5^jq?~;O7|%xXM;Ui$ d7eʖE+B]@w+OT|މ|ވ}KVKVuQ\Ŀ~6IVeŭ5nZY2JFȕ`ʸLg$ ([rA kŚ_.-NU"{'0ar9 @ݵbZ_x6-l]*S5(e'P$n)0$AWↇKឿ7þ5;khPƬRv8'~m,8&UߢׄhÒ7:/_’1KmB&0`;rMh*IQE!M4e [M쑽Ϋ,2>A%V 'Jv 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>G#6Oy?"Q`noOȔ?o[% 誟>H"a5Rm-| ,.Q\qXt}[ӴZ(By;$p"R^A"xʿ-.kDds8P2H-AsȤs0z_ x~ӵ2qujZLM R":ju:տz׾\n[4=8 b~-k׆+߈_'Nk ܹ~#zX?} G"I?|y9QKy9Q\~Xd_6?E_tw<+0?_<6E_uw1 = _=sZtkP~[pW>Uuok7ŏsߊ| siG_zՙnR#UMbME۔t?gWwR[>ֽz7[4ѫkۣL㗎> ~* WѼ`;kͯZ:FSς4]=yG2KDu-^5?v=.Km쵦νܶRVia ,mEmTA FOEc#{;Mm*P: ߝ/[Kzk˾w6V˴}ݏU>oh>1k 'L|iKottx%0Yn- ு|q}B>^_u֟z|7HK '[Pa/o/gM9%Y͆HY̟4Vtv+)jh3sf)ZV2dٶX ĺŚYZz7E–kt|K+d~Q[:I|MKQy.:Sp'//ϖJW˴t7OkLQk$Wt/i-+ڍM%"4]MIHLqf4u|_YζSh$,mWn{g c- y%/R!Kzy+=ަ\'T~[ﲺMMhx*L>,SS?ٷ<}B|;kNo0C<ۿnэ݌w9NV[췲I\k'./^^?.E]%ѯZ fCX)#]u"? OIq\ET?X_f;S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-iIZX_OGNp\6#qM&&w7~ >0O%כu y_<ݛf/ş/a:xi춺\EO͊&Z΃hքM k_J_  =W.3UJ ( ( ( ( ( ( (6ֲ N%Ph>5nF@gM>NrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrS'<( 'J,-U?|-Gm@ DrsT@ՍkFhdԤ`K`A&>*ȩgckt&Χ^qoPտzu9o?C~!؟9˿+G_G^O?C~!؟9˿+G_G^?I?G?ߏ?Q|A;(C~<E(S?Z&vd57o5]ƿ=c^qlUo5]ƹ =]_=sZtkP~[pW¶>UuokOoǝSf]f7v^kI V }g;m8ۜ>l&!KןN>|mNx]mĚFhV֖A,ުB9PzQozMz^ڥKnlӚӮT&F>$3&=>:tImetKKb[-3-At_[g៏u?ZxwGkvZ۲Kem:VKKo( ~ٸ^%쎛jڵjUTLS|mD$,EV j*^sB2a#4RTQ(;UNPV~]W_6ݝevr]6hu{voğ1m>Ю|[DOVֵYuk}6In}EZc⺒FB[?|=?-ſ zZ\iesyhVE8*b7>%߈$jS_b|?g%.Mp$VG _KgCQE5;ŕ:\ d" '9CHxճApsSϙܞW5wJ/{>h^ aR{R,xZuxO/A=7SҮMia:5K6_.9w?߈Z|2^ ?du4sNb2HB6 2 co>%Eu/_  PW>+ ƊV ۿtk^)ihjyo.ޭhGy-|WMv+LJe.ulLQ A.qYD'uh~cn~!-||C6g"?n+>^[/9r"./a򼛧GCC_&<q~o #$-䳂Cs 24,ܨl Ʒ4$O4m-9Zn^u[>|q⯉{5/QAE}+"Hh]D@*%пGڧ4k SxS:Nge{i<>mmd ] 7K@.hM#2?Cdm kZ.@WЭfItx ˋoJeohoCcz|)ݟg|ߗfݸmJ3SיKm߽jV5!Ov.>'?js㯆=/C֥׭ kBdhMͩY7g~$5C'м]ey?мMMìNj ã\ElYkZꌆO]~PW$𿈾ۦɣ\iP^y2:)#4g%H/? \h]=6i++q_&Fʏvv:R/KչJJ^&dEF+TRkӲs俈߷ Dz|4|5k:O^eia݄VUiD_Z b?xRMO?luMl䜭ouĸğ] KÿxLSW4[./R:K+L\b#'K4:TOdKm240q6RN҂+?Mvd?:*xDVaT?M`-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ0-U? OG$ih S 4Aa?֟Ƌ02 Ǯ_JJ*YàƻGNp\6#q\7_,a?cTBS}[跨jm{ECIN[߈_'Nk '׆߈_'Nk '׆8k>>ĿOQ(7_?ߏ?Q|A;+_ib?;@|>!_xw񯇼*?<{B*Wk`GaaU_=sZtkP~[pW>UuojX)s][_Cax֟hu? o[uRRO+U:UѳFBwjW6ZGM4# +z],+Zjw.`ޝ?Xnj>j[Z$e2E_~]g^Լ;]h:/r,/!e˪vk2!mfe()Mov$嶷zo>*ѿ^оx/ЯxOq>gđ^i6ڂf[F8!cIdO-Am\/(?[ԆŠ(((((((((((((((((((((((((((ϊ*Yàƺ:>*ȩgcNouޡ→ au9o?C~!؟9˿+G_G^O?C~!؟9˿+G_G^?I?G?ߏ?Q|A;(C~<E(S?i*?<}>X!}o5]ƾέ,7B#_tw1݇#Ub>k_J_  ֽq'=7A=j%,4RDȡC&]ı*` :.3U\пah eYԭӼGMkw4O 样cD y)O@?>~izi+_Rx7Oes <+ʑ$ʬ}.Ӽ`:[G#/$A!v'jpSĝ#ŷik=WȞa@."䏘 r=EKqiuI)Msxy$Ҵ/GnOAM.[ _Xq&٤ewʝ.VxN19-4|?iz|AosZŽѸe DdjEoxNo}bJҴy.oo'X-!Kn4[)a/y$u!W$!(]+А\)vwz) (2H,@I(nco|G6Kk7,1Ϧw!tbheA#MŠ(EPEKI66:Ƒq;%{)ʔ)%˒7;dS0$U-o-"5 -6 !KyX yQTrI .EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW9WEK?t=XG\_,a?cU3׾\n[56ouޡ.-Ho/o'5whchkuHo/o'5whchku5G_'(g{R/?qEQHoǟ( ӝzgV>"dU9o5]ƾ~>~PWZc_ѿ=z/#x-+T'rRH\ F ZᏆG~Ӻ HiScYaz,77o65^}_(~kv 柣VXizUvvv(H$jEU ZT\mi+5vmniGlSM?4 |m|e^Os|5m+׾+NtCukwYZ&M ^yWGڧ᭿>xw7ic~/isy&=&V8L>&fx|*yD+;.vZŮ_'w[+Yu xQį,\7)ֵ_ԳGZǧKy;M O]ςbǞ/ċ\^aR`pEg:yQqĒ~_4~|/? r_yUzuʒ2؊QvRWezm﮲i$rNK&ۯwo?&x/ O ˬhz?)5 Nqu4:+Xi{!g#5[_Ymy??Ӓ]* /_X V˲{ʍ8IhUZD"(EMIQm#m%Ȓ~0G!NwQy9Q\~x_V?c_D\ncWk`G~v17Š>&kKWk`Gs_D1T}\ֿ%/]-sZp{)s][V5_ \VfԔA-W0Z[B7I4AX֩cƺ7^}W5xc;^K+E> w ]=Stſb'nmno%P[x0?<:ÿߵ'~5O/<,iXm\ҍ"-I5{kSfK}$fuP>hP;wK2"J^/]?ғ>͢@oI~mm<N-~#]h֒hݽ]4SwW|M?Q~? }_VWCI%..%KkKYkZA2֍VKnߛs>ov2ko]C٨7ZDgg$1#TpR*Yc触 +_Un ^";πU_|d|kxk^&<;èz-xۻ8mU xR- u쿳ODM"!"@?2׍x[Z6N%6zږtG 2WW@W7s>~Nߋ:2Ӯ[-vTѴ {'Ll w2tٻMYO}k8m;9-Ri6]}ko#?xNT}%xtJXY~$kiNj3igN4HѬd1E+O$H hz$O?;4.]馍߷߳:xNT}%xtJğ%ſrWFCƾ71YkpM{]Os ̫8KK?vxNT}%xtJWV |;:ӭu8mO,ndR|$2(%R|g~& c~-xD|'}SKam|Q&me d[$RFIJ/MRKݪmэվz>Vn ^";w?J_ &SMgm:ߊ45++&N1b_ῌ~;|aj&LN3B$Zd6N]X;}JR~}]8ˑtn^w?ۼABW'N>E:w%WT x_ ]>&^׮4 ťGx~Y[gYoTi> u ?߶o|#s9𷆴k7Isـ˨縅ZC ,!(uBlQ+SNVէd~X뷼Kz7_kw}TzۼABW'N>E:w%W~~I>ƫmmnd%URs`m͹?ڿaؒ};o 3P|4Džx+&֦UܷWڍݏ>q EZyq3\ 7y?VZ"]z=4ɓdϡE:w%QЕ/ ӿ*5?O<'gy'/'lI^).-Kv|p;?mmu@ukioewXj=M4XNDѽE7.Dq[u%Vdr.~k{_ۼABW'N>E:w%W3el'x]w<;/ qOIg4W6%]#$_iGUO<_?n6X%.l >Nb<5W&hD1)_.thɨVݒ}tLo +_Un ^";W Gkahz65l,XMrjHјfl#|^g|.h^8Z_mV8}z?Ma{{o~xżF9eF0i-$'6mLܒWCw?JGۼABW'NU xGBֵ#NQ+iQZYve,!,ѡ*3D>$|:ÞKK6Y[[ĺ(7 wrEld_&Wa)8>U۷8ٵ'k&ߕ]VϷxNT}%xtJyW(<? ׅx?6Oi-%8Xx ͗ž)l/1fLlm;tx_`dR1:WNqGV=mgtw^wٞЕ/ ӿ*xNUt>/? x.;oU&ZgqAVc=z:[%FgP W~Yi>4:XXέzٟm$2]*DQO+I i>y˾YoOfov߷xNT}%xtJ#?V ä{?ÏkQ]xG}KFOV٤'!iΝ4ur?y'K1>5[tMvi|FV9cB1rWKݳvvA7˿tun ^";w?J^EMxNT}%xtJN?n ^";w?J^E~E:w%QЕ/ ӿ*:.%xtJ +_Uzu\1w?JGۼABW'N(cЕ/ ӿ*xNUQp< +_Un ^";ӨyۼABW'N>E:w%WQExNT}%xtJN斺.ھ-ĖS9WEK?t=Xנ|@]?T@ՍR Nouޡ→ 'u9o?C~!؟9˟+Y?mxnQ8 b~-୤!5}-$cC~<E( =) esOL~ž~XrB7.Q_xF)yuG1Wںc_7Kwkk-fpa$SHg?Ou{\؇sgaq[J8-v 9먧p+Et?PmInY[!Ax 4Ěͮ VMc:ΩuNammDmq/ޡd/tx<12ZIm,ʚp1#do^Ӯ!O?675;tumż 1OIosb%aOI$_?QHȨktm|gwqoYZǏY)#uo!OR_ީw5u%GĨ - M3N?~ xĞ*.ọ (լ;ujPE'b]]}/)=߃m.'{{m<, iW}_s%~Ɨ>&xᾁ|em2Iy/ewP 5q6۝ ?O7^._>hwy \ķ7$kw‰P'"Q"E<E7Qwm߿q8%mK]{7~/mfQ׵)MIl%ӎͩ^["F,D{6# 7qw0}K7:zBZމC[XCy2q3q\ʊ4q/"Q"E<ECQ6}S=VI{RoCyu94XWϠŕ,1’Lۢo/b׈d*jq.㺎^m&Kyrecɘ.:_E<EdyG|;ǖN|^_+$bmҶ6ez^rZx3^~0|nҴ+;$Ӽ+aaA{x"(TJ KDr̲c|;Rxk[OWo KiQY^hZ^^E\i*b?wro-%^Hȣ(S7utTtml c7о$x/eצK"5]Z D16ywoȷl cbՋ/%[ĺO5o>)Ԇ}_-ιv/Ֆ!eKxA۽dyG|>.I)CFד֌Vэ~喿zu}ٛ>3j:qSO,&=B]:M !&mcy|>$T(xG?DtеiRؤ kU7}/($_?R-$Va_ݞU&7oxA_tO=YYY:mާyy -dv{73lLdXH۳۬]Z{ Fǒb f-bF`ނ͙9b'}/($_?RZ%I}hɷ}޻|{C*#I#ŷv&IZEkjW 7'5FZ|tUGWj' _iu6 ?<-a$Dȉ--…2BҝOE<EdyG|˖;o)}I4)+Fi#[ѵK 9'/ohS޼辿eFfH2DĠI}|k /Wu~m^YS!X*mP9%udyG|>\I+?5{wmNMKy&[Yτ |O贯OjpXMUbC JA:۪HgŸM/xM,ּaz5H@IkX 1mk?dyG|>r3擻i%z$З{r[SO%߄<;sDO ZjWF XVڌzu7ݥF{.Uy'u x['OoW.iWZ׭_-;m/C$,&R%}/(RI=kի7%5wrZmwNZGQ^Hȣ(S@(G"Q" +}/(.@(G"Q" +}/(.@(G"Q" +}/(.@(G"Q" +}/(.@(G"Q"> 8iXnk@$G\_,a?c][mDw 0zOT#׾\n[56ouޡ-Ho/o'5ooc`kuHo/o'5mo8~"_F7_C?&Ȏ~2G!NwQy9Q\~O d ;OW:c_Ow}Gm#^?hbDxbLт-E$xPc,3 y?VڗnY 4MkPU=iچbPyMu*M$c8V;4?xG'Ioy2y^߷vv\㨯ً}H׆I8-Mpkګ! ,9_6( #eT[Ueg.]+8+nw˛FGKs/?m cŗۼƹY@̲§˙$BaDm@OkZh:΍^SQl^#3̒?c|O|^ii_֚Cm:y=-q30iPd^s&[]ឯ6_ ,_Ku[Zi,-K8 D`д;t[v-Ys/Qiەhvۗ[?kxO[~m%O&a"௙>NV_+XW_ 6? i7Q=ٺwohX`qFW Dngkkys+]ޖ׺>oMl=W<I7mz4CQ+M[Sz˂iw,LQzo{/izJmbGG")fxZ8]̊ wnj:gu? XϥQj*(Cu.k/w{*ZcN*c,ҤM)@ ^jzψ]rOjcL]mKIdujVV)_\ukjZ;5Dֶib.? ie)vBomoL7'_j%x'گt /z\j0^$I -IoxmQJ35:mJΦ/}k9STt>1|=e]Ljo\立|=k>!.byk{K&u1h@XGGV2$zh}A<cQúvн}$Qo:%]r'/Rx_$$jQggm7-h3vpnF8ٗ<CDj~-GtI ͬ٧T2IΏSUeW :1u>+Bwܢ֎Nҗ&l_:=~>vִSR֮5KXYg]& $',ݞ# '?<9/ubM5E𶭪,][Bn\E<2nD;?5KCg@J[o2_Ki ig̣cDz?^*M2x\؉fIJ-ܬ$iL3!D^vVO>g$՚SYj=,M<_Hgě[}GYҴZ?CϩKxYŦ<\ܕ[I6ny0C|x|-O YMX=ݻ4+7hc ʍ˟ }Mmwƾ;>HO颌zW6ڵKj2'KlE ?_&ſ~ϚͶ x_9"ڣ·}huAʚ"#$U=4mT{5lid}q` 'hwwz?,H˒ʱ @˞s?|[[@&[",+Q_ҽdʙDH% rr|Nm|E=f-T8)6pڵݬnQyjl$oˑ$ g||D%V6ZFyH#Q210e? G-}WZ'dZWTxKT>Om? PK'Vwq%ptC3"B/HkKM3]YޮGUmb(-RPIX$) x?㿈z__KmFMJ.k|Tc_PR@/3]RVXDʗ<d-&VfO :qi׺ ln.`yؑ rRwx_.? Oi?Bj^~5vdiWFǟ6 .ؓ/JD$>YhͳKuA$_\*EZHE#nh?Gwkw 5-}UEVeQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@sT@Սtu|UROV5Q:{ECSkV7_-rB?Vs_W/<6F7__B?Vs_W#?} Gx"9?y9QG{R/?qEr9[P%?3tB7.Q_yYѲN:F_:c_k_C[jm?HƃzwVֳC7Uվ7ćO QOYJ?4U$D⿂V#O cF[?G_x։%O1¿TM<+UG =g+)WS_⿂?P7Ok~/?։%O8¿TM<+UG =g+ UgxXDŽUs'*`c?rZ'@?&Ȕi_?I?_⯃ݼC,r)>asa>*''&Ȕi_?I?_?aO)IC>iTOԿM<+UG =g(¿T,NJ~_8g q9G_x3J '%xWz"W,>-1GF<#+SGŔC+a Gk~/*'7&Ȕi_?I?_~<V:¿;8ai?XɎ?mOK_yٯ?@4U$DO QOYJw|9k!?/N|I^o\ec*zJQo9j5G&Ȕi_?I?_o[saʥq&sW߁n(?a>=xWz"Q '%~ yoeQ?w_9Ug /޿M<+UG =g(¿TgeS_eq?!Auo '%xWz"WI??w_9Ns߁}uo '%xWz"W˥8e|or%k߁/D>_[~i_?I?G&ȕe#7_9M,7-vD>_о¿TM<+UG =g+$k _;/-7-vD>_[~i_?I?G&ȕZoZ߁7̷7O9G ?"xڿ/?~4U$DO QOYJ[g[wO;Vta?߁/(D>_[~i_?I?G&ȕOmwe\krO5*r?"x_[~i_?I?G&ȕ[ kUׁie_xQ___xWz"Q '%~_u9G|5AW^aC!WG&Ȕi_?I?_ie_xQkUׁ?(D>_*о¿TM<+UG =g+<8A쫟 xUK4R~ׁP}_*о¿TM<+UG =g+6wۮ~'T^eeCWG&Ȕi_?I?_eeZoZ߁0}}o '%xWz"WJiZy_;KYoZ߁0} /_M<+UG =g(¿T11k~59eorD>_[~i_?I?G&ȕoY߁meQ___xWz"Q '%~sη,rXoY߁!C /M<+UG =g(¿T< ;/Ͱ}U}o '%xWz"WaAc~y?w_9G?"x_[~i_?I?G&ȕ!oX߁meQ__xWz"Q '%~y?w_9IXoY߁'C!WG: _r7CXpcfFGP{?, sGZ!W#KbeRdor}_/_YʴZI螺>{^ ]%g> C><D(_>)ƺ5jZޠ M}fM{xWEqNNUnit-2.6.0.12051/doc/img/logo.gif0000664000175000017500000000267311713252032016133 0ustar jtaylorjtaylorGIF89aG,+.IHL:9>LKQWV\fekPOVtsz֮""-ff33CwwooDDYUUo<|B88sڵ_!bh `呐8b,7dSuo}7rfeـۙ$)}qtPBl v ׁ"='XT!F) cDFwƑf2uxUX ] ya vbJvu4qwnѠ^Hi{ ќiryi_ a<8D_`&m:1FDb 9˙9"%Dai䳹Vo\6SةER~!(clBfґ:go[qv/,WHgu+FRy%.V/%U"QZغ1v_`r:~P#ځuJ$*GrdS7Di!8Si膰B rWˋЍ#fDt>*%$ ƺ> R--vP~ AX`uJ}_#%nȍyĔ6( /'AzjvmꬿKth;;_H'[2/^n(' ̀YR2Л^Bl؉ߛsLp3$AH. 2ȓhE?Ph p! Mzd by7Q4 ŧ@pDBJ&Hw@ B!THL&:PH*:1B;NUnit-2.6.0.12051/doc/img/testResultSettings.jpg0000664000175000017500000017317411713252032021112 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?[sx4?է5[.i57FP=q]4x>fV6kg|=lKiwl.@ LbYQWaRW=w~Jm}n?+OmVI^v?߿GjOw> 5x{\վOQ? WÐcX`54̖ZŽp,RLG44KoW6x> |5agi\݉u>!k2ұKeċ0+Qm說tgי54֍3?Oσ= | hQK8WGjRkuZ& >fci&ܗ2u@a8̋*JI|?zſ{}[Nh᥷k,Ky|7P7fF&1n%%ukϮz6OG.?` qRN_؇yooFX;>O l|M' CTnP$}ջG"*VRHƪNх(7⡬jt Fjj6pkzʾy3~g7]xg,atFjc~?яooFRgT^x`z>OPu__{3~qg5QFN> OoFXUPWg&ai*d;\'7#UYe/)qtEj˛GVXV}2^y߲>}5Td^>Ot_EOG3dTr_9X:ʾ|C9~_8{-F߳?L|#3DZ sLUHXJ_ʾ\EZ_3o٣Si~_ 7 > dDZSRY:I%F$*|A/}? Z~˿ ?~ /"Ց)|-~~ 1Z ]']9#."̿'g/ ¡0?hMo3k4`z` S%c??Ot_E-|4^ jLU ) =?̿T dDZtTR(qBE"%ęJg~>;ƒ8? gއȵڝe$X7HQ_r!.g?K)~J ;~ ~ N*C \c*Ⱦ/3gUh;_?dCZ졗'`sGԨ*Ws|z(5'"ҷk[0 $T,_r͙R3txJ> '"?+ȵ[a8Oqt<OE}"&d޵KO?hSQk?O4?ER0Ÿij,8DV_r:)gG"̮oÆI ȵ~~|ȵZԗ'!=2E%K>̢a|qc(21TDZikěTy-nѥ%d>g7|<5+ G|3{O(g_S"SjWæ~ȵ-Xi*Z,W܏:|C-=)?ØTdDZþ1R>   0)tE?kZ΢YT¾::? _-d"1Sj_Y?|{-u:*(ȭ p5R_e}74'g/Џ$?k/\XDY~|IȵUېkK2LF_qׇ 'Z_3 >T} ks(2ב[]\En rTHL..wR_{;?_ |Q`׽|,>" 'ZU_Y"`y0QFxq>J RWC!Eɿy=|& ?|-;VU$zq\%&pJ!& ɄU~ / %/576CKi䷸@QMIV wmi^ A/5fm\{.0ڳ(f˫ 7|-uy{hU..'{*Gm3Տj: :'ucOQh}H+xGxQWʍnUYQ5v 9q:i*Iatl4Uf> Ԣ Xe{,1#0VwXwdPI!pW?io Vkoæ>INKp $3$bd"?7}??L0XRi4;_Kzp2M*X:0o+Rr\m+>[]>+= Q8ῂ;_"H_GcOع_Gӽk~*|D$7F]CkXֳ5?8Xcb+uܚ}/`'t_-קCOƽ7&?  ?Zyg@1l$k,KJ ;ū7/~><x_jz'kHmb6 CVυ>.Uz|^ؠC"LJ@rk K)e?sѰuJ0x|B-Z2]~#'#` 9-*b V8w=׵O8ajjA_7V6g$H"t>QqЍG*ω,?ZJ)&]v{niBܔ[l_wux@t뛭zJŁ!梺[#ƣ8U\m26eEC_|q7hsxY楩i{Ftv ulV;3}A%c$ 2--Zo|\gď֦hR4$yEMm*Owխu])6ޚ~?*UmGTզu{wT o'KY9Av #I$~UJac dG?S*?k~#oֺቤy-K%d.1NaU{]ޝ[/IeNjNJwȪRxkO4??kP|T]hG/O$5*T^OVNWG@E/W'O?kDqtWFs˥ 5j<__? ~"k֫_?]1G5^^y_2TFH#q/â.>DMՋ>.`[Vaog[@nn t6~9D<ⷛLqr OZ-TfէэNi~sp~ndj?xVOkƯG @Skt jx;ZM fXi~q?1uIֺ[DŽ> }[V|CR }?ˊ49_adK3]gß\ΥZЏ ._t#YV. O_1]4[U{?\|Co@5a /6 djK vbWZ-2gOG @5a ^q@?r1_WE 'ԣQ9}?hKYK3_#rhof5}h+x@5 Nq@?cZ椛ha]l:|=}h^> jgm <-~/2o$g"h1$Ww N jz3O> jF;aYkl285hxĎ3]O3|B[S.!gԿ0Ί|#g{xj;[`pcڻB/ޣso)c^5ak([?̧a2Q~lGxp2H4?ُp( եk=??mZ< oDG8CJVSGFxI7g_鷺b ^ Eې_^4m2?_Էpԥ1o^]()PťIA^sR{{d l]WO_'w)U6tf^rʌ8A8VnxGe,>"|\Yo{(BG4?k]T1t">_9ufͷ,9>Ukᯋ?tk5_/L'g5[S2\WvA ï/]G__?kR?LJ3K_+!s!jΧҽѾL_´89 "2=ZVkoa#--.㹳Y6D8#皭 +x|W Yy <٭;h|c.!Bǒ2MzH{(E'ÿ7OmYʵ1هԓJiW<</oyLa[^W~,gn?鯇mLϋ|. KKT"nW;kKV飌[IvFq7# 5tٚh//0>|G{_e*WVHߛ>|S4#mf#|S/{S-߹G7bw;|ŭM=jԴ𧋢?Ÿ ?뷇m\w.vÎOCQc.}|{چ6՛ž u?e>F+/cMi5(Mt{ hZX_ίe?sNIAhxy~3Zi[纽~Ko<3fA33|=0UR1_5BULO/(D-]RtB6Va2HeYYH! OHi x; ׈? ;+; ׈? LJvh̨rHt%N>Қ@z HhG4@?nAT郞CC7^ *?4?NuB4?NuBCC7^ *郞CC7^ *?4?NuB4?NuBCC7^ *郞CC7^ *?4?NuB4?NuBCC7^ *郞CC7^ *?4?NuB}o𷆴kKRӾ"iv ]\?ע$R#YUU$&" ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>m?f+||j7q_D?_+K_!ӝwʟ|4~oî<8q4.Qx'7Êeu8n1>sWx/k|'k=Ot:;vO,;s5Ā\[Uc.E,ǥ{ yzy57Cռ'i[6nh4lk_wh<&ᓩIc)|#^}r:{ !l5TbO wVMU hU@w`pH9f迫A~k@_Vg_QQ_>5e;/4)7y>XtMQ|[e/o>).x Yc/X1"*>|!}y  fF9G %A#7-oo q|  #(dM_E!F-/@ 3ZD5dׁsΜ"F}YmJO4DUݴ#OKoċ ᯀ5oQzQQhFEQǖ/ioԴ>ui]wg'QxwEx7~,u}cHM.slηiP_6zWXD?`i&H5j| fm!{)t{e.Jĺ"!|C?ź旫Xzf [Z]³s 2:0*A "_/N6?| c!_ؙ6񿗻bgn3sVU#;5IZ]livkX4}5{uWIѻꮟ??/@|agKѮ)45ǸD7aT3Bm\qJjpp:g_i;/%GkHuv7Kݍw9ǒ1$br(Nq'{[ߖYio&EVFEPEPEPT5MZmcot9ٹ[X? n9p<Ec3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3'L\m 1sɵEc3/L%8?R7/|(!ӝzsB%O?VK1/Eʫ#U޵2WP=,{aY߱GO!k;(4Ib^0 gSi۬jGύ۷z۷ʷGW7i۬jGύ۷z۷ʷGP%{ⶀڝ:mj,)4wC j~! * ͗__g75q+8~|g{pc>jn5K/mn}o{vy6Ǜ mrb g2I&@~2?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^ A>8n&GLL"Q)cW2BEx/3@ox|[WXΥuwz4gGդFfK+LO<={t +D--4}+E~e<̛l!76YE7 OR|6GW_þCͮ/%Ҭ4xnuek[Xo!s{t$!{0~ſQ[? 'Mw\ּUj#}"LKha᧾OI8HhLA)J.4rW3oenڭ{u.Iwz+EQ_K>xoůx^BOzͬR@$Z]bEPU3D#MrQҾ4x=7>)agtykW:U3%ݤ2ɝKK{s|d#iŸ>9V[^>_Z }4].{$]GRiїo]w0+JRJN ٫$o'ylRoD][W??n|h7<hZϧ!}>[ -wÙ#Âh`\?\o>9xBYZ=y{R]Hۮkp8bs[׿,e{ofi)Z1R~|zk^]GؔW=x7IzYӼI}K+xvY/OeKRUay,V=C{gڧPK;YǀЖ-Enɯa7^@0Rȱ(T~rm%vzգKJhZkџYQ^@|5ir}bMGP;4[M* {ۉ&FU"*,"?/'Aij(IourO殨`]SEMA93I5枉[;wk/vNѧg]_u(A#.ƿ o3ZlhVd%H<2#Yw߳+|A⽞d~ %Y.>THؠSAz*Q#+-# (x_'|o}+;;Po,q([K9vgٞf izrVi‚xe@ؗ 5Y߱GO!|~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$Iii7S_Z +$Q]ʱ=:3jVwQoO--٭fU3< p8'%s;hGj_pgKgnoRJm|_8{Xi iR؅Yϴ&Xk.>$ ¿moi"-m'Sy" '`<ȟi=2+Ծ1bQV\ׄxMkv$"[7ao6,"Kq a$<T>im=}.^nA>q ż6.Ry !v9 峒s[,Pݣ-Niikkfb\ [קCl_#5hfYɴr{Y-m9c&DDc,u|'sѾ!x{G$,5 ^LMg?a}FK)K+~$:h=Gľ1[n'd2Ҵf6{V[$_x^Z.J@$ia`Ӏy+yZF0|ϗKv|2M^ײ{]-}ԕX۪W蝵5ꓲW|+'~!k߇0߇ZWGy'\/"~-ܴ$ܻ{^]ͽK= "6цC)GEf=5tQE!Q@ekɚ|[/XFm3O%C5hEPEP^K~ оCO57~"𮭬i -֑]I,̗zn [I̶JE[5|dI.$+~/SM}M#χƉiRßFkm5ܱn{ ybl2C(aRi=ٯ'JM'4k [_G_Ϥ-HZ,Iq nI'GN=yo^ ;^OǥCkwm}0dm9`.-6hAqMNrnqwM}[hzii4֏uwk]=Ɖoxgns>Nְ>C[[2񼡁"@ Z }q''Ԍ׈ ET3;#]!>&=Zٽ_ʵo!F1pw[jۥ<7ƯV xJ-OUgӮPMJ{Kk;9ܰQ%:\8%AJ?<%)F=$׿c^^ajtǥ=4ͨiOyfE[K HPBx ڇ|y[V5Tf[n!1, dj>HR\IKI'˲E+Mz?sm;>=nxkx Gsc.>mM][ArZOKG=jWH,&E 9k%*MwKI.$HQVN+f)s^m[<O/Ŀ/,V-ξ(vKͩ5iFk;…D6NmJ/4O hZYIy`K$Q m> ̍pd(! hx%%mENJsWi5nMz SWៈNwΟiڄҍUuk{Ǚa%PH] ]ixk ΋cKCmi368)Q?&URVA,$I$mz6-i99=[wwGe}~+||n4>{+x[h4A¢s'4Mwemx_k6f]CLQP"[ym,!\ET{?wMvW]{{{/->3dbYSmz:77qco0j:.@l<#M;~=",++t$D#@I$UOE`DIy+z+-ݷd7QvvW}l (AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPy*O _) xǾQ|C;L* Nj_R#7q^C/?z@7Fs&QZtguMczDrxu+;(4Ib^0֍g~f ?K=éS{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn/6:i-q5Imh&{Wx_ci9oo wHgvt-n\ˑs4`E0z$_ xݾ{_YA\\<\2Bk^]>޷A|ڝZu SOe F\0XG06*y.Mr-L&"1MGowa1TT%(ڼ塀Zz_o[|.#+±Zá|4;[Kx "I)fc4ܵ+- aϋI}cA-kjqgMg6q83$\|28kG4}bUx(q\҂}]Vz_g܊v*^M ۢZmm~l??W?*+4 u ŕ헇4.-,-jpUyWk_Vkny~lX:),$QEypQE_ſ!k;4b^3VQEQEQEQ_-d~ǿ B/7^(准|k kmSZd6Z|p$MviD9VR8d_&f!h$gƯ&}kJQ-i-̏/,H01h?j֍ijǏx{NfZZ7o WStC &%lH@b}R.4ۄ7&f/eĽU4mf?NNq<~|SE"壴XBP:|ICuወ ČO*ԆQ6(w*s2{m+iYX}S[vw诈6C=fůj|gAyNo6ܱ^#feA3x#Ӵ{J\gjk[AEՅWuD",_Srו66{mTO~n_i[_6~ο50xsZb:xS[׮൷EX_-5VEGg]۞W >xsK hgY4 xkn䶖R2e<&:3z^6kҍXm%u_>z +i1s m5} =& ^ܛ{GQ"FI 濳ǯ| k~(&vŝ6QӴHl?iz$k[sZuvg-s)nQٙQŧ5-9ZO޽kqq}tW· [ b<-cCVmkfex|A%IDx;YUxٯ6s|C76-m_Ų# 6ıڕE*ʤƬXn)ky(۲]h%R/Ko_졨E [xfۮ NVx|ΒTg *Dx  >?//|0ɫ2YLam@}S0LkZ"'* y]dMW9-:v>;#8>TQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE\x/0hH"_?xNw,xhx/GZiटOQC;oݏ3j?m%}}_&,"χm?JʰGөaY߱GO!k;(4Ib^0u? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?xi+w|?έ w촛9m8WPPt|9??LyW)&fxįBb!յGšU摧'`W rX]\6ʒ=7+k3Z4o4+鬝(.`xdhՔ8W%K+qG|bt6㯈u;&] Z?tdHm%Y1vOe%‹1(! xKzY:'(G\-jm_Gh40|[xH|Qf+N XDICKy-IG$\dת4g~>]|;FmW:uާ P[D{tY/,*^D>;^LGT~ |OW_Ak#%=}EVeQ@Q@ekɚ|[/XFm3O%C5hEPEPEP^K~ оCO57~"𮭬i -֑]I,̗zn [I̶JE[5|dI.$++ȷ>wZXԴk= /WװZu4 ˨ly8l2 eN=zOx3u5Mkljfqy5r^.FvXHvbW<ztE/O/oE[G6$ G1eP2:4RTdiigŮEY5nSM;tۓZrw}ݯ>yMOjj/ k^'SuN/5WY/aaZMn$b!z_? tIuo&:ygE)T(,b,K$G'wڛ{)x{?k%+d+M6JoVJ}/_/k!|7zxbðj HabbL~SJhe(Tx.q[4Fk[a"=WݻS+Y;}T] T]-'>ta{Wz_j^Ouo Mw~݆kox$ImCrVi&I#fn&/&?u.t,T3DY D+Y#UP !_hn)Feg舘Km깝[Q¶h6`*E68QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEy';?_Ì1?9& +z|G+nD$|_7P}|V?!>~t|0sFN?G+~ъȡ,5+._[_PأL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157tA׍ycH SI?_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ ~#x˹׊~|?g}mΪ̖ܴJHUAbIVbz#F%HITOmh^K繛n] S[Q{=/| Œ麵'M&#Ѵ@3AfKf*5|)j |]tx%՗EӴ;N@6Mf7kv!V1!>#:^x UWEiee%Gu!JNHOw3McZ-;S񎟤Y}(Ү.o- Dn#/$m1ޯd[+Ikt_g~CO+[j:tx ڙ׼=Z67zT[& Td>cr6)I' +\_YO_ j/8$K?!n1;T ]%X2xEԺk^/..|_wD|]xk*P<6[ 5-Z71}Mԣmo"}V{k&,{Zڰ(Ȓ "I&yi ._k'-]]ۻl{iuzk(ڷQ?!;0i<Ŕv7WwDMngxVYb ,+_x^x% k5^N\/diP˧XI4l#i=S +xwǶ.i>4 G-tRyϟlOnsiW׿^nj)`񾯭iK}OVRtOOc[m>(j/fi6rzcwuA~?XOqjމ,lZou{cVXTEvAloh ~m7~v?-c8۽-Xe2?گ?x:6 WJx,ԭ%9H'1 6ːlRލ\߄>V5Ε&F$B\JtӽP7*(Ƞ(̿m3O%C5hw&ioĽcHf((((.[e߆_nQi ^ 5(_ԴlH510Drq\5L[BѼIυ|o^Mb:֣w[=[_8X V3͘`b/~u|%?#Vo?/uXƇ?%@LJؐ1 \i ORo%ͯM?n*__zh~emeq6+x&EGh$+|u~$/Sx>,՞ZouFh&p$2\6UAuU!N.M%oZoZEJ)]w2j3+]W G_G< x+:=v !}67RF$ &&n'[$qw wǃᖭ'K@jjz&&s=5ȗOV Cn;RU妺)J)7VnpeUnIG^NUF} E|gውWÓ&!OZ7JP,_B3'o3+C>/8GJQm{ۊ~.-e2j]쓿+}AE| mq~ )>oFXtAw곬bf=nkš[↽cயwȺ-ӵ ,2˧.ʇcZLP?jڥT,rZ_OI%)(I$u7W9jzW¿ xQHtk_]vfC5ȑi2QXb9gV*^?BxI_Wx/k|'k=Ot:;vO,;s5Ā\[Uc.E,ǥ{ yzy57Cռ'i[6nh4lk> ~:Q~<|i5|G7.MĺKꚒ5nX$P5uM?_>|9ĭCšxľ"ƨiWuJҦHCjW܏<_^,xΝMwFYm.ᤆ|Ыk,KrwWϝ9S~׺6h6x U|xSquH9F4**E}Sn,giL^!EKGwgGBܼA*j/?/&2ږaU%m`1TA#I  :]Oזj>.քz׉U泃U's4A#cŒ!|GRugQ*ihyIJɻYZj5ll2x?:~ޞ OþouVWOm>G+xeGq%^Cċ;_pOi>0xm{ ڛ,jNl͹'W;Rb (K|u_ hon>5-b! CI|Nx*o?6iiK+-z-R >K+EM2O0}Rv%N$Wk˭id#?o k a&IoM䨱7C!N ]A^V@+ݾ.| fwg.`jH/ 6շoZdZ{H[_ޖ8O{w݂NK(_ur~[Mm{_[ۿ wo^O ]^___x:-Q%U.Ԯy'OK󨤊\*Ť0;CE5x__mtiʬex@u 0G &gxwĶ-ї3-x7NlkI%[˨Vwa [,X//cĈ !QToY_ׯ㷕MZVۧgk]QEIAEPEPEP~fK?jѬ_LzZ4QEQEQEW(/ú'u߈+kBKujRK,D%ިۂs-RQ@ @$A$yk %J-4ÿ%|65-BöŵM2:m+^N3( Fkh&Gޟ-i aB SZF.hY^Mm׋ǧ0aF5RU?_%^6m/>1`lKtyfť$ 7YT M)FjY ]Kc'1ymTE~4YK23Cx_/G;~[5'Մa&ݬrykr 2FXopt՚c$Lѿ5jYhN 1=#_|m =ub$F駴a7,$RI;~h>x2SNZš K#! #/*Arr{SrOnZ}#V^K^-<{7M?Z.ukvxR+9 HΞ 3,,Vŋ&X-Ӿ4|Eד?𥦲4h(Ҿůg\'k' f>E+h_Nn*WܒӶ-doGS'Exo4w_մ-u|=u7&62̨d&m쿯"QE"((((((((((((((((((<][L:-QXb:>?Ebz0ڟ_ɚ|$/GkFb3O%C yٝO›߷^O}nG~6j w>6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}/|6>'fF/]wwۿl\t7JƥD.' ic?Lju_ |]}N2 YaZ}* P^V$I'^(䢡NJ~]-{( 4ߏh 5/j>Qi%]v~Zq5&K9-^{9Ȓvxf^G$iRMJٴӗw&֮ыg˺ZzvN]=#izOV6#ap`R[ycKYk{k0$(ďoZ?3Q>#LNWeuZ<dҵ37$gL{INxWH׏}#Ɨw:]ƽ-wPē=K-n2jQ$+/[=5k$:~!xVA}NR}R !PIqs xT" 1iMEۙ>sy_v'eBWn~=ZN |c7} ZfX8}$zcj fT{%ܶovv[;r?%>)񕧉Oh~'">[dE%)LY@F,yѽNxZokV){_xnKz;صHd&x\QK?bkx8 "j m-Jb%吼f&in&ӢI]#:܏k[Kk{l;e۱~ƟOWwGV umFl{4k;VE* 4@!yYU7[*<3jG.wz5ܶy} soq*6om_7J7V֓~QO磷FrC ~ 4mCwڗXzQu3NtT4_3 5$EZMGt.}Fᗇ|]474}Z#A-ؗ գY߶ſ!h((((((((((((((((((((((((((((((~.|M>,O0G?!xNwJL:-<QHgǟ( ӝzOџ5gWBEbъXwguWgmO/b ?>ؗ 5Y߱GO!ΧM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=z{G[snoǏKi(fDuY.?g- UYrCg~_?ZnG-5Kˏ 힞^K nnm㻂q$P\%jb-CcO>U'X{l! .GĻž!%ifw^8]?%SA=I;Mi<3Hȯ#4)&il~ikWh[T-=[rI't|BtFZ?ZGѧo+_0m^ͩ-5ŵEybG-ßzFGi^ŧ t]2PmQiZHwZ_3&Q'<+jNsa>K.^;mIĥp5(x`[KſI]Ϡz F>|$1Mᾅ3P,t|>=OX5 3*=[7;-9n{I?a`mm|Ao{OK-"O,Q# '<-7_q=<7msf=CRkyZ$2jwQm<.b(]߇?h?OvxTg}ZY5MOTOnGnۥ1^T34 7mnf$ޮTG祵m6}oZ߁?i^/_xsYֵ]ÏGFM,GG(U.'ˈRA|<5}6$5O-cWZk2ZvmF 7Sy.'eOx$Cm5_/u EР]w=3.Y|H# w"|S,׃[,mYnu`ҽo 32IktORh(B]ﳎ$՛_3ܯ.Wu?/* #k=nZg$~ ,lH')k#A~_W i{oZ^x~%ɯgͪBlQ+aW!^nn`MI׾t+/RMIjI-+T+D(! U53 ޱ7҉c]A=ADU~]7}ī]ߺ۶[oitj~ĝ#^_=h~'Kې7#l+ICBٍ2K}^=5~);ľ#?6Gi$+RXa{x>o)okKᨐ(DcmB("m+HMF.=b:]E1V6znUWj_|Dbe+7~,R4۝Liѷ'ՙn2I8_21ɜ;r~ x3Őp.KHM@0b,=Ï{->? [m",bKxXQG1"\8h|3åiuۡ+;h+x*(\ӕ4?+yyjJn3S}?7~Y"?~x+~"mޝ_:ibY:ʠ3\]*W_n ?]? xCg՝dkkHy;ƃ yO٧zw(=vu qF #2Ui|_>|1]u6zVCeo#,V2K]*םN[+~Kv{ߡ*/(Eꕻk{tW(7 ( ( ( Zj׫k{ifֲܪűHt,ˀq (&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.69Ũ@~+"÷I"gUsvXJEQE|+lO0G?!xNw xE{h'L%jn5K/mn}o{vy6Ǜ mrb g2I&@~2?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^ A>/i֚N>6m-5[;x[{HU5ipȀf6T߽/_8]ם$Wn7_[ X+b4^4yt} H,Qa%Kw[}B$,h0=#zw[\xqKm_i{"G,‰ j4bQUk}nv$*rV׾-\ɞx_Gak~.Bܯ}ipxs| ]+PGO648$hTfHҭ#Ν?> ]/~Nk(jW\=Zy*i̍|m[s*ys5{YG]Wzg%8`:=;a-컋ƷL]G?OE^2Ql._QcuK`&{ 5"PB9]6v[F˚6VoV E+.{KeMex ύ φ FM}[[O kRn vk[HּyE4k"FNW/ZS=_aiVc61[Ⱥs%PUVs$}+Sz;Y\4Zi|IYkoMpY$6̒\yO7n DcHX a٭o_g&Wek7%5[M\j 8扮d3!UQ5Λ޽kn[yyAu([nDKB5|=ǩS:EMCEk#0RK 4ZѴwN0_ $ixwKxMլ^Xr4IJYO*vk˾>O\%<[{gZα55k6yRDN58TCىj? 4|-&k۝+:Mg-۫I +4UTTUDmk|nN[뫹[]N[:Z(̿m3O%C5hw&ioĽcHf(((.[e߆_nQi ^ 5(_ԴlH510Drq\5L[BѼIυ|o^Mb:֣w[=[_8X V3͘`b.Oĭ33>9$u!2)(KOwQ\ͽijtwm%}E|{i.e?<|WAhw0j Ƌ^B^}VWyG@۵~_GS<x.m4 8TY<'h(<6U5-[s!Hgէ JisUPʚJ۹8ݤu+巯F}WE|*>|j+Ě֡SeJӯ1K P2:/-1V h?hWᅟ]iz8WYK&KEP[_Mwo,}W?O?,Ck2T|tInmB%6KIM6Xc*Q\׬k6|G$Zm5cPk7 ,|->mC?\8ԕ;J ofwQEdjQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+Q~%O>,O0hGgyj/?q_8;t/!?_QۡV* %L_|VwQ&iĽHa?>ؗ 5du? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7>j^",|=Y+MKd&6yUeʳD %[_:|IOG~ɻ|#8usO*r^қo|Q/A?G$kg,1MĀv8ȘuP.%ܬv/I H,>"S]:? ֘zy"i"A4SnRhF-%iVQfۓk[YZ[y5d{dNwI=/5_Zx~4LO,6qٶkngXX!چT[L=ľTr“NdH#&[Kֆk䯾˓o{BTx$mE|73C$]_w/ ƐiԒ, |w6oTPCP7I$I,ZjmIҼ7u?ߌW4>*|L}}h-|9jV]绰)o&)2E&ѫOɭzqOM}&>+~5o:G$i1ռu*ïͧ].ZA FҜ,QǗ@/~!~|&Ӽ}>[5Rܺ5+$UU'=WUEEHFzIw_'0])4Oh>3KjIٛ7Iټȏ, %w<8I&&w^ѥIk_Zq,lYQ'f]N0ARnnm]b"m-o~ETQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢*lO0G?!xNwU?F~y(L\]cU-_? Ebj0ڟp1x/gMw~?Ck~#i"÷7\HŸUQf2(TRzWכg|AgZt=[z&A.m6[6IovIA[x*xwXsxbK$~,\V`RE#WTڱ< L^wßJ<)|K+ jo[q[D*nd=Ơ~i-_HxC5 x.zt8\E 5+Uia_0 7O4G'~xZ-_Dten/Hg l ,ސW}/ß7{hgqѵ]WzG.u;iLlTIc\4aBʛrWN?ۏ[?1mφ~?F?TX$y{}xdq Kn)]72~i2is-k6[VmDb8Đ*0ӡa|>}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ+GįsxJ?]|_ hzn5T;kw :~<q|?~&|Ifx._&`}bٚ2!8yaI!2O>\k7 xSx=SD˚kkHx;+L l!gćS?J">+мK'ei:Χ=KrvYMq[FbXk݇o%N}owl5y_xM-O[!|Nx__6럈O w% -7ʌJw $2jl|ugmww/: m.'kZef;7Hda0)>O'x7_ wzsF|Kq=)4[HPyR" ebUψuZ]Xa&mZEoif%51|F=Fml;7N5omov+\?IEx~%ZSӤ̽I$ndeiDA[*.U<o]OWk6>-mN]@]Kw˲3%$mbP~D~(At{[cM[8xΧj- 0ETIl^Eb߄KF5k_.t{[wͲhZ*kW㴆6!KM4P\FVzVxm׭=[oxSlSI9O{wo+OȚKwNWDʖدvI~}-_ k~.-5K=I,JţM2;:q6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷw~џu߄>03S[~"a1;_DRd2%CX6wp*ƚV<9B(QE (/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?QxSAtW~Tm*NZT{A ["'ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F<GKU,۟ ҴQSz}w,7ڊ@mcԤ/ξ6| j>!K-% 4huK.`ɓxB8~x&q_jm,6Kra e|ow3q [I>㟈-^.\zEɴi!Yn1r+iIۣr׻vVRn+FJ4۷y7G+w O^ "++mYMf*!2yӍSqOV| R"NsF-llUKH5 d-7clQA~|;~!M^JtkOXO_k:|nPIgy$z̭ ob=oB׌6\I> 1t nXJjJRm'7uI9Dj6VmJ[kDɻ.s?UNxGAOBFoA l",$X1x  / P~Լ;^iKg u-jgLxUn0aIV> 7<3}Ʃ[ x)ϩgc 76yVml`}E b ,O/H4 4|iOZzo/-.9 `t-`֐K$&5bJQզFmm5e(٫tK}ohf|a%|qu+ 𦃪jWmƧW jե(Kķ{!#JTOd{|)Q7ŋw\".xĺl6۽Z=76@!i"2yؿe-f8𵷃 ?I״Œ"E#,#@X4dp<z]kwZO/o/56ͣ6Mm4Ri,&+ =BgOḒ'V"i׫*ZE˧vi$Wj8PMRۦKw? >%OD ]_|wƒ]^;hv6b OeGk C4 HE&jv76ɨuCn@"b$jhhZ_4,ͯl|K [4ί=ݤ3-ݞ՝ށxXm/NO44ԼOu}ŻFJu ܒ) 7n%O}[kNnff徖BikO{Z'?X/"׾M<*B5#X_Y$wڤ_ڸ}Amb#F},M#5kvy2O$ȍrK E,lF~>?wrǚ+ YxO1kK;Ma["ޝAf g1:z;heyVCoyev17|(MVvVu4K[^t}~(QE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢otZuࣟϏ?Qxg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{A_&Q>]STvq\jV}DͶBJ ֿচ̟WÿZ|!wy-u㣬֚TvsmFaQK c4 b?d ~؞|O}Zm.hק]idneuBrS7į?ā?~#4TX5\Ee٤\<:JT&RuN>׵ݭkNW;o?~(jm{Ěrڦcy$m }JImwlJj+i II|Bz7?)ōGI|[ŶyhAuijR7ʋF$U5t iV)^ޟ?5sY, {-`X5kX"z3 2G,~d6vx '‹O^#ЭO$mnJȝ0|Ǘk)X͆I/cr^JϖբמꕶvoV}A}5ƒ|MdԺDծIC؂PL/7(Igkk%ǯq[įiiß?uE𾓬M ڭ_ ^))'Xlo.mpeWLDFJH*ٿ6XKMkzMi>Ʃl4 YV$8K.f4ڒ(]Z>^X{k|k+m}=,{{0*(/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>mԿ|N?0G?!xNwj_U'؟akC><D+׭Ky5V*o5?_5a?Cc? ?>ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((R7_οsR'?q_>H4؟akC><D+׭KyCFs]`3!aUGYfS=ɚ|$/GkFb3O%C yEPEPEPEPEPEPEPEPEPEP~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE^%[o(3O⿢m[JL:-;?QHgǟ( ӝzz?.&~-WD\~`Ht?V_a?Cg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5U&؟akC><D+&տM?0G?!xNwwCFGg1 qW~e|1zD?Mk,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|ի~&z?â|y9WAHıgi(/Oz~u(La&5N*4߆C0cB>l?L,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+wWL:-ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((cW ωA|Vak0xD+fqa:DZ~F[%r^/F~yC ;"J*Eٙ?a0?HX%~VYC ?>ؗ 5^g_~34|;NΙmsƚHbFrb !@pJO>Stc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|f _LzZ5|g?xSRø4i:MԖ Yx'd- T L+O狥kF L۩c*R@%TJߢ?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.69Ũ@~+"÷I"gUsvXJEP,RĂQHOǏ( ӕzKџ6??a|r~P?)_%|B"ueYfS;E_QEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Q|c |Va+0xj'?q_ŋs7_vZD 4%r^/Ge6??S|!^'A!a>#.۷5Ɋ=SW-cVTG)TۥGQ^qAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP半YN3 #͓?ƍWB?տc6O[?dO|vm7lBWk˦hPծ <۠HbVy1bɻ]CJ'ٲzׅ((((((((((((((((((((((((((((((R5^w[>(ˬ=_Kj9F'`F20[-s 'אԞ5OxOW~5< zݵgulg+:6h ,"H7n)T>,?kVi?vW4x|{7_w~РfM7IkaCApVHcoa,m6߄m}j[٦.]қу"h3#ʲ>,?kVi?v3i8=_ul)g{/+l&Oh?@+4;G4ş ZO$??d?luu-~x4ɵCoIb`A+g<(.3Uu⌺|3^_i,v c 3x@^~ߴok#Knm=}ZZEݑC:Vo,s3]h?@+4;G4ş ZO{; $|{|'3M54 g0x>4Po"5DM\F4Ō2pt xMhf-K[a-g)`ʦ 3;Q4ş ZO-s 'JptoW ^jo k*|s? 4k/|¿v%7Ío^k;l% $Y߳G~x\_5k-*tKk[YCg0Cղs&c{h?@+4;G4ş ZO>U$M2]>^z^)#`c-s ' Kx߁&t?52mzr'eX2%DJ=*M(o _>##g'k kS 5x( ӕ~|{>7Fk +? 5`_89\W_ޗ/ls&~R;c}n?PZ+wQ|%h~#/Y-+'Ym-.Ŷ$qI;#*25C?xW9#^jiY[S,g_*b)N|rN*mO +,W\kFBxWW¿]a~\c??H)u-9#_WU[mc}-6 7O tf~_W[xjcIe|SU?34Gl~\*_)E~ufo\~8bxW?c?cO?C(FĿ -ot/G-_O?Cӷe[{:,]?\_)E~t2?7M>`~CfO_`_2~5K6??xW~_i?eo_4+]٫~5??[ӎ7ğ?oX1,.IoA1/9Meˌj%4W>jyOl xS=h| $/_.l~.2'2|u)ğF<)'|ܟ~E1?9I`}J+C#Qs/\ xW=\ǿ?X[]/??:?cż+xo?{ğ -TWğy'쭟 x[=/TW-gE#[¿]jk'쭟 _YrO?Ah_t؋oE+^X3wvʄou//_}|%E~_š@ xX?MW?U2xZ?? S~Q_w_ş?UJY¾g/Kg@?Ge1 Q>,IM-u'ſE|#_?xJ #@V~$G" dY~G S~_ڝ4Om+PD3xY[?, S~_e?eC%1/cq??'kRcOK[k kC 3p??:D+Cğ/:Mv#x{Wnq11Zqh2?,H3?6+B M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ+/(kN +<]ʺ{@##Y4qrM KoC_e׵m ĶwEl<+2L]h#Hr#\{k[{iq<J L3+F4J̢I-^i9.׿]~S+oڿ㮵~ZӼj֖ =]87䵷 [#kh~;<9|G|Qo{*++LkfI\x)p3X*OKQm^VmmR7_/ees+oRIXψ|9s xt|Qjcx8RAP[ag"+y[~?jo:4zj7V[Xk>b`>j-Ȓ@lt:RIo^Vn'줯ʫÑToF׭Vݩ%~Wo|+3`(MOO/.H#YPK. 0 t[U @4EclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEclxVtlxVtEV`MC@%Sgl&}4QES[4+08G_W/Q)/(!ӝzoCM}w~/ëv_%χUWUWxpc*QxZ+z@0أL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn;[x^_]#Ğu BO K.-gT )7$r(YbD}+ uxb\>+|_ 귚׍RKn~mg[ lSai(-B5o5]%k=WrQn-}wWܩ _7w _Mx".5;k; KdL6ynأup:jQj=h:爒Q(-)%uݱ)%'a Zo7Zu__Y(<[q.[54^yiL9yO 4+Io/ ^OԬJZG oq{#?2F}+_Թt=n}t{u<i^C\Ӽ+Z\:MR 1&/.b"5f=V4; $Vĭ[SG(|%j:-/u.⽸_zMӪs"#H]>1 HJk=ٰQSv߂mjn*FQEQEQEy&ioĽcHf>-ؗ գ@rOZ{n| >`:*M;Xؕ2SʼJʇ8OSE4wCRj5gp.|?㯋/տ/,Llleo1v-dPC 9/o|WuEk/qN9Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?xi+w|?έ w촛9m8WPPt|9??Lyo5chckZ~m4'y#m6sj)eyHI鿴_YHy_Md1As#Fά¹*YX8#K/,ԯ5/|WxM"m&{ ]Ѱ['s 61F ew'nӭ6tw\黅mMG:n$[GTқD_N)(&C.T#!`F3 9?Z?hK?|gƺg[o[I;8^Hx 2'OLR|F-/U2CKIW IE{ڷmdQ%0IN쯧\|?*>waZA>q ż6O!.!|rNkE+PnݓNiwMm{;=,-O+gVp{ƚm3K Kd~u=ړ"H"1 p=xko_ka&rY}y P#[]JYX%|N/kCxǟ|KMm:O%{ kho!k$Jcvria_x{]]?ZvEH 88".Ťcsv}9m^R{k7 $u蝽}RvQ֜W|+'~!k߇0߇~ζx;:OÏ զl <!;&8Bɓ>B׷Hkvڊ9=7"}}io$ou+f(((2>-ؗ գY߶ſ!h(ڳL~8[j{xuow%;EnZZՀAqpŷ FU? Eizٶc+vvN3J 5}犾#x/ٷWy IiVs$\E,HBjek.Yktʗwۚ߂mΉy^)nJJm-yFF`r P4i}+T#%hh?Sſhx'm=֩Eqrb\D4,ѹ9[ot&O ;OxĚmޭg_:emhHy$y-Ž:`LUKk_o7 4$9[F񿍼Cw|5/[Ү}9%ڵwAAr+ԏ>SHj=iZΉgWml,5jk'^ FBRqb64Ti^=7?ɾ]/+[ڟ hxkZ'/t+}gĒZn^d>hdH'̙g?oWmI7U]i\mfh $&W!ZwN+y[s+Voe_캟pQ_"jzC@ÿekėZïnhn4TyƳ́LA"3.G߳u  ѢQnmC|?Έ ^'/湼s7zh\g춦𕰹nE.U s >#˜l wjK(/5 ;wD"W]!FJ~"M?Ť~]ٗ/;_>9|`տkx_^t]Ki ͵݌p\H,戬)b'@z>'SV:/ -O_|=@&3E%׬ifi.63#eӃ+%>GvCTI蟡5O nW "ϋҼ}ye,{ൌYoXguW zc|SO~%nk&kKZEcg{rד#L[qy9WNZ;ivDkMڊicMׇ4iNhwk;nu FKb ƛ03<ЂI(>e*FjQEIaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPy*O _) xǾQ|C;L* Nj_R#7q^C/?z@7Fs&QZtguMczDrxu+;(4Ib^0֍g~f ?K=éS{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn<O|H_ýsuo[eǩog$rϓ9cʾ0N>35>%x+ >ү4>Y+tʳh^i>Ʃk4vsK4Hr$C{Ϗ>ioQ}o>mo-ۈZ8$E2.kћ WQh,ѴO gF]3N2[ȖKrnd[C3>&cD7Mg^3u o^[T8l!g}6q5tx8l/J_^%(vZlGAc,[is^Cyq SIjRC$4pNkT6~F{u\M]^Z4T_R/S>}kS5[i]v=M_.lj Tg,RW_Q _@?|qm;+kfR4ۋM=HnKB Y4߹[C_I NY/^7ֵ5MJ]x ~`Y@ G\&2KE(enL_~|B Cn j}:[( o1٤4{YawbfIT^I3wO_5'tQEAaEPEP~fK?jѬ_LzZ4QETs[\=a3DyNUrk0w( 2pw@fe\$G| KYGO vC++ CF2qcMtxݿ~7jƫy-f{swVA…JG SS@ѵH4_XxWfKɼoK fKdYdUw TU=~v姦Z+-sZ j# =1x^~r IdqRh0**r2M}G~!oji:tEO}ż-(gx!92H[(Mɷ-oii?T ;%׵)}<G~ᱦqMR[u 羸kkZ ^=!  lM jz2~V-'{{QDӮd1\C: <8'W;@z96Ԟo+Zu܈T~cᶋA>F+v>6V~@? `ïT崕|?>p:i+*³[Ng~f ?KѬأL'z?X)Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[`I Ǟ?>$x޹:-Gn巳X]ByAg1_??OS ZVu iWF,R9_L7H)cmus*KDi|1 }#T6:SK(E^G=I,KybE "Kk߲-RS=z;?h2$n-egxDP`f.оVMh7&_J]Fe@cIgT4S"nHPE({JrnїXRZ=ُm Z[뾻zo_+[ſ||=S4Z.Y㉕ǬۣH!VX C uJ RZ+|gG-Yc."/5x,(ˉ6۽ bGhK.BDe%itm`iw|߻]{?)a+Ҽ[ ï /5mm7p\iQH7[JJwAR7<'{ oZ4Vӛb. gU.n;cI9J7-~7V?^};6ikj ҈Mk@3@&W_8(2 vw[i}V{ؙf=ڍ˳=Q\σ>476%[z(oj]JTbB3,=k zeV./M?^XҒQEbjQEy&ioĽcHf>-ؗ գ@Q@yϊ߂&χ!iz|i}Jg{{EHsm-l<[>_|͸mpOR^ƊB*0}{W%v`g>[J|'G=NPӵ?lm%ՅG+&YcymY1Plm-IFQi]]/6b䔶2<]Yxkŏ~04/xs^sDZW': ,NMRm56T 6I;BRnFk[۞'S׺n2勌m՞~ן YG,C;9-= %J^H$n JTګhXx~NPl[hs[xXcmGl):7Q7Fa? xĚ/~/ix-ZdV }$ ŶIn+|}|[l^:#լӥյ[+y xe11oG|FY<6IO[*7v^z֕d%ڳn+6ڛi=c߼+s׃h>Fc =1ϖ'%)}9qU  Gxxm+ \\Iu+^񜚜f]F(w v"W)FW}GHt%wi>*$Miwu=RL@ebD!{kVII]tJ]ן{޷kݲզ䤝h"+) 29z2<^z)` f^ږzERQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE˵{C{O7?KSǽr?⯏/-[񯄴mkFeUoouc$ԥ4vӰQ_׉D񯄵kYbUoqu}#Ԣ쪳1 $⯀^׉-o[WkYeoqu}eд11$$_^/oDWmkFbooucb4vꬰ)P)ҽRR37ӝ{]QEy';?_Ì1?9& +z|G+nD$|_7P}|V?!>~t|0sFN?G+~ъȡ,5+._[_PأL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157tA׍ycH SI?_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ ~#x˹׊~|?g}mΪ̖ܴJHUAbIVbz#F%HITOmh^K繛n];|aۗ$z>i:.wg6d%1a<a$|Hp+U2xZ[^c}0go=2cJXRnP|F>&xZUeabז5L$k0y]eEkkœ[跗wb97zvPǷ ?wR^Tb4欭J;+/}[NZwF1SQ(һ].]R?dkjڅi/GZL MD>-uҷ]#}_JҼCm=ռZ692p Ч87VWď>'iL|A`:2RN`yJ>݈ 5>Jk6| mi.kh8eycN$r5L}OgID\mexߖp->Kc5R (/qRJVo^cxF-<ͶWqkq@*jw7O**m>g{Oykvi^+>Ľj[B @v>]?</4;k[-<3䕮m.Y̑/gŏHkKimgZ"OjsZ\a.̦3JdD90:ӚtݕW~v~V80%e5}Wnk_ݹ_L?o>qh34vlFc9M˂9@?_RTA\E>? F"[ϭшbi(_c4b/XJ(q,_M}l/&\E>? F"[ϭшbi(_c4b/XJ(q,_M}l/&\E>? F"[ϭшbi(_c4b/XJ(q,_M}l/&\E>? F"[ϭшbi(_c4b/XJ(q,_M}l/&\E>? F"[ϭшbi(K)!FPB➫Qx7If*˭jw3H vFP}O?jGhtP|-[.~;֐xfAvvufY@8$1u5Q@Q@YS|\?*“_̗sA"ӝC.w~&x?â|y9W*\.[܍kgW'v=>+~W7ü4!?_4ݧO ?b _? ~-gNTGniEno渐 pePa7!X~7zM#V]CK}FmmFv0 ygB4TǏ<-&sɸ@ItSRY:kBFcy+>xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mWOGO~)w>-[*Jho N d+ppsxk 'W7x[OxzᵻS{V-I͂6jbJ]S=#=㻩oSm'&%c",\5!H`i2  a/\MF--")eeZX"Xaڧڂ`|hIY}iFVz|Wiل}tuZ,G~G|= }/[ᲆqu{74 ,4ÿ>OKB~6xcd>̠tZy"N;WR{xg<Ʊ_xdԴSNLSwohgoc n ¿62ߏ/2_n׉Zhڦ,eO6M5Y 2,'XI.4Z~M&m+)'gvjcT] Y_|7t]WZ=VWW:i l{IS%wy+cxׅ|yMa{Դ],$6\^I-鷹_Z\&:[;td/2˻(5 ߊ5a㛷ѥִ[;=Xo2ZL^t] w;{[{GIn5[I e y^ubbIkkowᾎVm 3?] E$j%ڕޛo$v~uV Whp>[{߈u N5^U8B\|;Lź2AxţTOڍcw$yu[_L!kebE b$ 3׊׳++v[J_[t7k(((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>XvnL>,O0G!xNwxsnlO0G><9WW^Wɟ EbъZwh_CEؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?ߴ,?s~<}|0ԼEX{OF5V$StM9hm˕f8>c; ψ"ux>i^\xe/lRXM8+sso%-Ucl~o|Q/A?G$kg,1MĀv8ȘuP.%ܬv-|%O7^#ĴMo/ .by"IkIGEy0I5+KfKN_ܛZF/ڥ.iI;w$ ?7?U>>XymmIlm-fi-`,= kC4G> M2-8]^K^Z7֛mhJ֒CܒA2' 9]#W_w^>k ]wQCoL%/ɩGw3;nլ^-MZ}S8nng5IH$cA%́R$$p5nf(}蝔n ]k(jI;#t?+;[a񎯨xl / iczŎqH.QrٽlAtOV'Ν_/eXi>r%'ͽĨq ʁh3왦zE|Wkfsj^cYZ7Wq%#dtyRHW"HExÞ4|A4BkIZ[ nk 2E.гE07G)~xߪI([][ZNE?mW+օ-0ѵj_$55bn4-n( Č68 {yḵOx7_Ķiq{Ic ]&;icԤ&K1ʪ7'(^K¾2='?xIz+u+JQ6=ޟ;‘ͩ^*fHV,w13=ƯwI𼺆idRZ97y$P)N˕_k7IE>]<-tVݥ Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:UFn徺u߭忞C* <4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((T 4x?â|y9W?+lO0G!xNwU?F~ɟ_ ?NwF+b ߡ_?_a?C+;(4Ib^0֍g~f ?KO:7oԟhNcT|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwQoi>>j^",|=Y+MKd&6yUeʳD 1gxiߋS@/.<2zy{,&G ĒAp16W?Lx >(GWڠbl#5{&@PIFdL:V; x?śxZhw&tR|jL1MrZr $5#"HĤi%/M]mRtn$һ{ Gh*kmFQЬm|G<{66Ɩ40aHQ߆?~!f|G{.t%/-t˛BMyEɥkI!jgnI| F𮑫k/;5̈́G.t{@[(&{[dԣ㝃HHV^I{xjInu/B&w>w{77W1B@DD8cQ@Қ3}ytN7ZV5 zw$:0W<6oCWTqH=bS$`̨KlwD  Ki'|Sc+O&O-E/}=,ȊK[RE-SMid5=S[73E=A[nK!ySL849MӧDwzFuSַ׮w9k~>x^|gZ֩v<˫{68DSxT.#K8ֿYt lR3Ƨ{L~7>{4-BtH̻w gR o&_^O^ lxPmfQJ50{{i$1Ӂ?I wK;lVnƳq|r{']np 0x_sCGkhP<$bW;m"IO]2*i{{-k+[&w 6 ;\YD\5{4m'^d)l, ;JQ6W%ʑ$Hk$ySkJxw6x*mW\֗\z7zJ%u/P#iVtKw~nڹo祿OOM<]@~t{~6w>-,^SnC\܍,% f4-mx ?'? E\_]=#l-c2fVg8$}so>/pe (,/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>\Gω6'tZx?ࣟϏ?Qѷ=nnxSɨ0qk%-w hd_4`z =;-ǁ..\Eq#xEY4rɈZ\*]\3$iV N.@ '@5] AwE{ -<]4F6- $,7|cln& u,֒fI.nE"1pYOlַM/qh݈^EsDFsȲM^ݵ-< ׺{yN[}%i>|czGpCg\\I%-Bh;WIp c/4 ;IѼQ/,f9 Yc,;Xdv5a'x_--u]gXߵV5Ε&F$B\Jt6~h>ku'-܇~km-N-QPQ_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+Q~%O>,O0hGgyj/?q_8;t/!?_QۡV* %L_|VwQ&iĽHa?>ؗ 5du? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3(<_s/ S,s i7\g1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ|o~w>:Ocx3M_\X{IQ H7>j^",|=Y+MKd&6yUeʳD %[_:|IOG~ɻ|#8usO*r^қo|Q/A?G$kg,1MĀv8ȘuP.%ܬv/I H,>"S]:? ֘zy"i"A4SnRhF-%iVQfۓk[YZ[y5d{dNwI=/5_Zx~4LO,6qٶkngXX!چT[L=ľTr“NdH#&[Kֆk䯾˓o{BTx$mE|73C}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑ+GįsxJ?]|_ hzn5T;kw :~<q|?~&|Ifx._&`}bٚ2!8yaI!2O>\k7 xSx=SD˚kkHx;+L l!gćS?J">+мK'ei:Χ=KrvYMq[FbXk݇o%N}owl5y_xM-O[!|Nx__6럈O w% -7ʌJw $2jl|ugmww/: m.'kZef;7Hda0)>O'x7_ wzsF|Kq=)4[HPyR" ebUψuZ]Xa&mZEoif%51|F=Fml;7N5omov+\?IEx~%ZSӤ̽I$ndeiDA[*.U<o]OWk6>-mN]@]Kw˲3%$mbP~D~(At{[cM[8xΧj- 0ETIl^Eb߄KF5k_.t{[wͲhZ*kW㴆6!KM4P\FVzVxm׭=[oxSlSI9O{wo+OȚKwNWDʖدvI~}-_ k~.-5K=I,JţM2;:q6U}rK}aZI%D$* $1=M{K$$'6ju{/%ͷw~џu߄>03S[~"a1;_DRd2%CX6wp*ƚV<9B(QE (/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?QxSAtW~Tm*NZT{A ["'ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F<GKU,۟ ҴQSz}w,7ڊ@mcԤ/ξ6| j>!K-% 4huK.`ɓxB8~x&q_jm,6Kra e|ow3q [I>㟈-^.\zEɴi!Yn1r+iIۣr׻vVRn+FJ4۷y7G+w O^ "++mYMf*!2yӍSqOV| R"NsF-llUKH5 d-7clQA~|;~!M^JtkOXO_k:|nPIgy$z̭ ob=oB׌6\I> 1t nXJjJRm'7uI9Dj6VmJ[kDɻ.s?UNxGAOBFoA l",$X1x  / P~Լ;^iKg u-jgLxUn0aIV> 7<3}Ʃ[ x)ϩgc 76yVml`}E b ,O/H4 4|iOZzo/-.9 `t-`֐K$&5bJQզFmm5e(٫tK}ohf|a%|qu+ 𦃪jWmƧW jե(Kķ{!#JTOd{|)Q7ŋw\".xĺl6۽Z=76@!i"2yؿe-f8𵷃 ?I״Œ"E#,#@X4dp<z]kwZO/o/56ͣ6Mm4Ri,&+ =BgOḒ'V"i׫*ZE˧vi$Wj8PMRۦKw? >%OD ]_|wƒ]^;hv6b OeGk C4 HE&jv76ɨuCn@"b$jhhZ_4,ͯl|K [4ί=ݤ3-ݞ՝ށxXm/NO44ԼOu}ŻFJu ܒ) 7n%O}[kNnff徖BikO{Z'?X/"׾M<*B5#X_Y$wڤ_ڸ}Amb#F},M#5kvy2O$ȍrK E,lF~>?wrǚ+ YxO1kK;Ma["ޝAf g1:z;heyVCoyev17|(MVvVu4K[^t}~(QE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|%WwO(3O⿢otZuࣟϏ?Qxg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{A_&Q>]STvq\jV}DͶBJ ֿচ̟WÿZ|!wy-u㣬֚TvsmFaQK c4 b?d ~؞|O}Zm.hק]idneuBrS7į?ā?~#4TX5\Ee٤\<:JT&RuN>׵ݭkNW;o?~(jm{Ěrڦcy$m }JImwlJj+i II|Bz7?)ōGI|[ŶyhAuijR7ʋF$U5t iV)^ޟ?5sY, {-`X5kX"z3 2G,~d6vx '‹O^#ЭO$mnJȝ0|Ǘk)X͆I/cr^JϖբמꕶvoV}A}5ƒ|MdԺDծIC؂PL/7(Igkk%ǯq[įiiß?uE𾓬M ڭ_ ^))'Xlo.mpeWLDFJH*ٿ6XKMkzMi>Ʃl4 YV$8K.f4ڒ(]Z>^X{k|k+m}=,{{0*(/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>mԿ|N?0G?!xNwj_U'؟akC><D+׭Ky5V*o5?_5a?Cc? ?>ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((R7_οsR'?q_>H4؟akC><D+׭KyCFs]`3!aUGYfS=ɚ|$/GkFb3O%C yEPEPEPEPEPEPEPEPEPEP~fK?jѬ_LzZ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE^%[o(3O⿢m[JL:-;?QHgǟ( ӝzz?.&~-WD\~`Ht?V_a?Cg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5U&؟akC><D+&տM?0G?!xNwwCFGg1 qW~e|1zD?Mk,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|ի~&z?â|y9WAHıgi(/Oz~u(La&5N*4߆C0cB>l?L,j~g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+wWL:-ؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((cW ωA|Vak0xD+fqa:DZ~F[%r^/F~yC ;"J*Eٙ?a0?HX%~VYC ?>ؗ 5^g_~34|;NΙmsƚHbFrb !@pJO>Stc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|fkStc=-go>}z+>O?Cޏ|f _LzZ5|g?xSRø4i:MԖ Yx'd- T L+O狥kF L۩c*R@%TJߢ?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.6F|OC٢?bhg8x_ M +&.69Ũ@~+"÷I"gUsvXJEP,RĂQHOǏ( ӕzKџ6??a|r~P?)_%|B"ueYfS;E_QEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Q|c |Va+0xj'?q_ŋs7_vZD 4%r^/Ge6??S|!^'A!a>#.۷5Ɋ=SW-cVTG)TۥGQ^qAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP半YN3 #͓?ƍWB?տc6O[?dO|vm7lBWk˦hPծ <۠HbVy1bɻ]CJ'ٲzׅǏS ;:-LgY~EW}QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEcUuojxB|QY{O"զs "97NXd`=j4ş ZOk!<;k w:🆮kxS ;k[F6s$VtlYcFDnR@|YY?>,?&[ 5/h텠_<oAͭ[떚ny|V7r ; n/ uْWXmÿ ԷqMM\7 -EkfGe@|YY?>,?\fq]u~z$]uWٴ9SII_uV7M{]kVi?vh?@+4;RHF"4[?>7!ikֆ;>**&Wxy_RPV5_ \Vf׎'uǴ )mZg0(#qYD@fր=v2hxT h^|Jouχ$-w}#JVI3E?=f>jZU׃|=7ַ(aV+e+ dM"ǼkVi?vh?@+4;[F|I}+he*n/o۫|<=S 3&GFG4ş ZO|G״O [ϯV:NEZHSb8WY㑕XC/Ƿ?esq_ uuhB Ҳ`J^#Nsi]YAE~orlO+W1 GE|+٫~G=3: #> FG%uly>)|)^k'@uGc|~'=?kO*jfǗd O~0U_WhϊeE|'#T&W쵀+?.?#??R(K_|W?쵸 [Ÿ]5U#ٱ\j_[E~iC[ĿZ6>0~ğ>?c?cS?+]68S~W] g:V?Gl~\*_%E~w_25R'fTE|-в?#p@um7H>$|-uLj?f_#3AO tf~G?:"֪xW'žUWԿ3~S]ٱp@u>G7fK~h~4Gl~[O#E~vo٥VAO٠+]ٱJ #N_Ju7)o.|U5I߲?Cc?cp@uGxY?#?cS?њ+~#3ao ua~ }I+]ّqO?AϿXPW_X?W |/͏?ƧtWAsO[`~2~6GjO?@h46QIٳ?/e~-.c?cO?AF%ż-8+]ّ]*_E~y8+](ğ -T* #.?W-KٻiO_-O?B?+-ybGq /Ou!eLV/}2NQ?~h& s߁?KYoY߁t.}G3E%a u,):UԪ?Ҋ+._!<|1mZx Z{ M.o8-ŧuǗ,H3أ^o%0}sU1dw24l\pca(Ɯ){_c#U%QZ=NUnit-2.6.0.12051/doc/img/visualStudioSettings.jpg0000664000175000017500000021320711713252032021417 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?2|/ᖁWⶃx^8MsNӵP4]: ifxYQY%tFTUZxa./HzO#o-dus4ZW|39CĝogÍjc—^/%;q܃s1IeF^݇J\J+;_D۲GN&iͷd饯ݥ=9`ςp?C`|Iz_{ sVQMG&5_q cS,gX&Y`i"q.#|<|nZ ؗQZ̭ytdd ɉaW2v/뵷.;{Wo履[Ѧz0GCzO#%~ 8#\RW _-sa#D'ռ+Ԭm!URIՅɸe1Y0qȲIJx; Qkw -~UKtF -3] dP[ shHJ$K9/)-McW'))&ծ;>=74~ DY-#WR R~*K᭏85EZꗚmܳ;OhVJI8ͽ_5QC_cVVyZƟ.B?c_#h|؅=wRO5Hʾ?_{36%DOzG#Y/A]Mִ67sҦH*T_pKKd08)\܅=RC.p?B?Uc 3YU ʾ)f8/%8dσ |.1R^OO1`܃5vSqV.(˸Y+~s~83c U.ftF_E|̪ORl9b>|Gjy8(!~ 7sY冦WblcvUe?9/#?ѿgeo?OoFgπ*H%r5io_rLwV_2=? dFjsC |Gj -PZ,-/_r0OOr hR2|%sH7#WMubϖ\LkG*WJ]"K+Os^L:10|&9c SaH,H%,?Kr_ٟ,c'r՝~ mД=dTFjfԍ'Ò*X ? _#T??M/.O?Y5w25]YHk E"1=$£5SH~|."3EjֵD#$fM$;Ozk G܄w/+o? TEjh78?~ H qgD0UBy;v>N8Cg?O_F'O_F+[ 0'VI/ g?Kl|,|?O~ ~|5SO]ĐMu(m "a)/%c)Ώ GSq=-*?d(+pXIxJK/1vZG ѿvU?] &թ"og<d34oFU?g Ri 1U 4/ f? _CO hJBH?g PFy5K܊Y9R1zHSyFj8> 4oF5K\/E"iegH> 59?gO|Fj`5IkG܅,dwG|$ԁ5Y/-œ3RvwMi{('5_VD?K%>? 5Q~Zd8Gj<5+0/QZ?Ⱦ\s|sǟ/1?gh 4oF~9`܁5/cGꔟ_r5Y;ODrիc2 PO? hYڐ_Z|?x5KU y;OacBG /:,{຅OSׯnHC i28Mx8B+%=<3NvY?y~2o %( =?? '"'5z׋ ?yusN~V?!/,'"oo^0XGEj!ޙ}A] -#U~ SZG#eX#M^jkч9'~pq|-GඕfdÕ=z Ȑ b|C'Dlх4Kg4τ45QB')vڿ=F!9ODEji+F\ڢY;YWAԕ>g9}k׏|uoqm]& N92@5>.ϖ#H Z9 _9nw<|I> uT>'b񝷎cKقp<ԧ-тN44GG7Gk_;j־*4=KUnNy`do*t<#C<" h\\_\xDKi䷸@QMIVF_ |YX<k",Лsoˏufe ux4aH񧅼*ǫsqsss}upMdvڠ=WMyy=;¿~McvhN;ŽvTkr"#PI 1WJ?8;HcW7 i7i׸vxOS"\۬_M~q5pB.Z>wpVRUAĕ^L:_ h{/2AG|=$h(3#"A5}?oSgcOb-mt[/efblHIWGFԣyZ"3iYZtuohZ> qKDI]Cny௃oȵ_ZG!1V+k'XF׬_M|8WLOy|b-R69t}k~ -K ^ #@M<#âh49Am#!,)^grSs߉_S~#x ׼\hzM+~š|,\[K;lYIƯ)37q_`1RI7~(j(,6a^-e&Gm Z_Q~kMO߱g>*k8G&mf嶸)"KĂe."g7.jkZ,uD. Qb68^׋ >$`־P*{kM{?5[*%|zֽ_ |<ok&tۭdn&.- OΕf&\+`|g<׵O8b\jjrA_7Vg$H"t>QqҍCigČ֜5+?Z:R<߾_]z7V[VVKmdbx}M.-+ƺ .!梷qnfTq2_" {XK\ ;K$>$FfL|U( ,7?kT4O龁Z"Z$J/$^G~Z%lj$Yڏ!>@[ghxu]xSjHO }RI=sVQ' T_'OZ>)`0Zҧ^VD)[Vǒp OkKs޴Ey'PO5?kLxnoy-kX?|74irs\a@5e~ x !*|z? !C.^i~c⠖7O?kLo/8o@5Qt_fE$䃚n#/pka~ 1i֕ @?f /JTi d r/?֡ ۀG+C?@WB\34<}vKv 9Jef&cJ;k@V?ǍA=}h΅f /7xD+ rx-،?kƿO~ g,‡>Ϳ_bCsP]Ü]~4??mH߲O?,ʇV3ogA|Dի]h?|A[S20~A?-:'XͿ_~|DkSKKD~c]Xe;O-U|d?|A=<K3 /F7ds]3?ONmG37I?mIf@c7i~rw^ A85kO p`3] d8w[P?f:- /̖dlȨ1$[2u?mAgDڗЗ f /tpQAh~2ڔ~1~|A?=haX_!#C '_6űC ?Ռ2=~|A-ha pm@?̧ŀpEr>+ Mw2c?kUf,[SYp?i~yCkW[ߝ*w]݇^'bGïC?xʾ;u-atno5y~pvzȐe،?v&`[3-gLik~!ڥDφocnbʾ3\i2O*kG0~C'hgAlȟ>!A? jݚ;24;/oڂknI MNAV~LS|A@k"`O!?韆y^ g+WI#>O*Sj*&{O/zDvv3S\?fv4F9>?k3&G4?k]x*ґx̏3BO3n io^>xik֧<\:4ZxΌ!/Y񂴧9kRӌyg|+(cMau(u]F:ur6M+Cs 7 +BOxNw tx\~"ZWWOܟ`bx~_Vg-X~W_|0gezgf?ՌWvc_Aڏ;B+Oگ%Ѭ-7Niڄ)skum^C$fU >+; ׈? i xi xLx}h,ʊ|<($HBT})\4@?nATHhH4?NuBCC7^ *郞CC7^ *?4?NuB4?NuBCC7^ *郞CC7^ *?4?NuB4?NuBCC7^ *郞CC7^ *?4?NuB4?NuBCC7^ *隷7j xkFԵ-;&iz(mE,;UUPIb@k(((((((((((((((((((((((((((((((AIXxI"?xNw"\?GJpख',oTRshTO]O v_}n#%Fa.QxzƻW Ö'o _? ~-gNTGniEno渐 pePa7!X~7zM#V]CK}FmmFv0 pPs nǞ1о:|2u),|E/v"ԯt.R'Oqd L^wßJ<)|K+ jo[q[D*nd=Ơ~i-_HxC5 x.zt8\E 5+Uia_0 7O4G'~xZ-_Dten/Hg l ,ސW}/ß7{hgqѵ]WzG.u;iLlTIc\4aBʛrWN?ۏ[?1mφ~?F?TX$y{}xdq Kn)]72~i2is-k6[VmDb8Đ*0ӡa|>}ya&hGxU]>k85]Ryg3J0V<(8ru'VyR7䬛cZˑC|c~4xׄ|Oh>)L5qY-gIb#xVIӾ4F3v>5`4k $Ң]j/<@.fOVdf&K K?=[Ws}_x].4&X kb\$<*UA4.j-g;smM.>΁;S!B=xT *(EQ@Q@Q@Q@Q@ekɚ|[/XFm3O%C5h_/~0'xY+6z:`*],mq<ڎGek7_n˭.}WJu9Ki][$ar#x Iz8b *VRJh\&vɵgs7ύfk S^#Myak>mFmt]/\ ldm J$pFEfa[_GھvjŤYM=ޭO;h:mvQ#Ѥg_~%~~9hOohamoM-0ԥKh/6 "oAdhӼ!mugZ,QO/l 23$P0 ⳣ~ C_'MxVirLy^Qu,1\N:ӪӦ민{գv^YY9'M,颿o}EumzU+4uu{H9JgYе:-"NĶ%[YbٱO6M*c ;7l<9] FχVZfe,V8cUD8PI4R\izF+[:㕶(fEPEPEPUz=M&w%v67c;yqY1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢1?bhg8x_ M(&.6F|OC٢!4?O M#2K80],wɚ((=X3H|{j7q_:gld?0hH_QCwP#ľ_ݗ s9eu|9U| ^:ֲJ/~+;(4Ib^0֍g~f ?K>~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gMƩ{_ЭѷdH_'3h?"Ǟ-e|9t?]ͭ\KyU G*$I3;ᇅ<]|>ޑWv2ZD-l㺆{uY#,[D@,DX/߲X<_5{nM_oÿC}&h C-"\D r~?g O&Wx<'W-ƫhx;{;KN0nY [6(\/?~(jm{Ěrڦcy$m }JImwlJj+i II|B{?MVWz4KjnMM=!Wdy%GlS+<^So;&M?J[=K~𿆮u+4Ҽ1o}kFkA^xFH̑h(sJWkF5.n],㾶3oO[_]O?ZW,~ |<4 :xSTL{IluK˘Yl bo;U-N, >!$-+VJ jEKi4x f n#<޻}t\ȈbC $FzR{kvl&x~ݽ4Z[Q@Q@Q@ekɚ|[/XFm3O%C5hEPEPE|_ 7~GMkjO:xSVX;c8,qT}\gifo>Y(;pX 1 TWߵ]kF_ O?ǁ=x3Hխ-~7ņ{V)qokn$ 1 GCҥ| _YWb'ϊ2h\vHY[k[JV>YvN5VwvGTW~:|IM)4N(I']+N*Qz>m|9=7Vj7[Jըo*Zӛ]㪽pxc Wú4Zˤ< mV]>LX#Hx#wcGj ֛S=}QM63gsg ^F,Qm.I@>GtעW}R+<ޚVe浶_ A-Sſ B5}R]6{[9~.&۫Zo#T& `*]7M ?^XOS%ơ{mk|ʸ+;78J;5Ԛ~lwחwmyZo[o4/ޟ$uZ 9n *0HH %u>xfOO Om[msͫMZ;in-$Syr*y y#hڃtI{]Z?JV5Mv4Wow2o<5hVxtR6ʻ5 $r e~,~<C¾>ÓJּXYж5*0%8)0'Z1I)I7s&nzs/W4Vw}]E|( }G4A#\LE͵*hZWL"XA0rQ3w%Gj|-+:~ZՍڈ~ i{!5gWHw<)b[mWYwz+:#U)EW[_[#+υ?W/<}'t"^WQ.bc$5+t xZ>(З\[-bOx${ogw?|PcTݓk~^ۊX kgo(Q4qkY5^J5-i.уFc*$(XC?| 6+^zoPdҋuG:Hyln&A192NQr DfMJ*KQE ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>lCdg?W"9|{?QC;nSwϊGK_oxǾ_9p#GOB/}_ ?2'|:ˆ]+C__ɚ|$/GkFb3O%C r)Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[`I Ǟ?>$x޹:-Gn巳X]ByAg134L:ŏUukgM#d䍴s-ͫDBB" $K|rG|_Mf{]#ƚ-}5\ : e`2⸏/.Rנ^X YI4/wFnb̂H1ޯ읺N϶'s_m7<_pgKgnoRJm|_8{Xi iR؅Yϴ&Xk.>$ ¿moi"-m'Sy" '`<ȟi=2*]K uT|fM.kѴ.?'/?e.=i [+rjL X5O |BuᯃIXj ae#-7gBmu)gYc7u8=I/|M/V[Y6kk7>(-H!xp+y]>Ÿ-|E_tgtkۮ Ґ "WB4xFckϗOI{kkIョޔ.UעvIGZr]=5K?~xk~V3LaC&!«I7, P"xo#^-7~'ZYq b-Gv%ޭm`]*|^[xjVK=&u-~a- F^j5^;Z sXbHC ɭzkz̥N-ܾæ쮖/,_.ȆMGij4R( ,jmU3_ kXj+d4v@V <9igr~]EϛR'Mcuo[D? |@[]~/]/u,n4ɬckGۆ|qGDh?ou-.K?ɣn ikųٝK<32F1+ZrVIih˓qzڻ[7M)Ѿx xvkϨkX/{oyq$kmaKhhXc$~+B %|6P'dTP]CdUhD{[k_[m⛔wov>j??H [_;mNmv9NHm.Hd`.1-oix5I5VHQmfmCsffgIKWVnZ]t97jh_7׻wmS KEѴJ宇xw]62ӣ-=J傎r[}ʨ6|Ծ+jzv|KSݮ<7=^BXݩ`ʤJ2@އEk9OVۿ[]tVfTB [yw߯CW {-"mK{{>⩬勵Ymk,)&>Z-W SeuO]hx[M?Z]^x+y|nZP(A }EOӶZ^n|O[Gd2o]%>=?Z x4.YFƳ$B|G[/>/ MK / mVb53DGڤPكF\#UOQM/]}[.<5m7Nu v;yu.T)QqDqdhQEmTbIQHaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPy*O _) xǾQ|C;L* Nj_R#7q^C/?z@7Fs&QZtguMczDrxu+;(4Ib^0֍g~f ?K=éS{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157BF7Gd>ѷ=nn<O|H_ýsuo[eǩog$rϓ9cʾ0N>35>%x+ >ү4>Y+tʳh^i>Ʃk4vsK4Hr$C{Ϗ>ioQ}o>mo-ۈZ8$E2.kћ WQh,ѴO gF]3N2[ȖKrnd[C3>&cD7Mg^3u o^[T8l!g}6q5tx8l/J_^%(vZlGAc,[is^Cyq SIjRC$4pNkT6~F{u\M]^Z4T_R/S>}kS5[i]v=M_.lj Tg,RW_Q _@?|qm;+kfR4ۋM=HnKB Y4߹[C_I NY/^7ֵ5MJ]x ~`Y@ G\&2KE(enL_~|B Cn j}:[( o1٤4{YawbfIT^I3wO_5'tQEAaEPEP~fK?jѬ_LzZ4QEQEQEQ^e@~GFѼ#w _[Z[ٰh! -\2Ma[~lm~ QN [~ZpYHQ]EfڌBb=z%4YN@K6IQɫë`ws DZDdW$D8?7ր,EQEU5]b[Ķ$~WSj6o ѷ40M*yUA*I Vh(ζUq@ZI;)XiByjv`~eѢ(k密{B_"3,m-GS ?$AQEQETj_p1w\Ơ9|m$`(ZͶ%\Hѵ#0i$@ig<}vnfk\JBV5b|;TchlTZxŮ,䑒9)Hau<:0yhIV[.#݌q:l`dݰ9ڍCZ ,(ƍ,Ί@b.,=ijVRCpA" ( ( ( ( ( ( ( ( ( ( (<3P>+O ?)Ko⿥~-E_?R)7q]>^"3[^g-߅Y-I_YVu=+;(4Ib^0֍g~f ?KNM/u'>ӷX#?5 ٻϟqnٷooȏoM/u'>ӷX#?5 ٻϟqnٷooȏK^'mo;k.t'XRi^N ;%HBUQ,&Aś/Ծoj~Wp?ۆn>|j_ |QF3l#mߏ6 .: %`cR"bdM4e1 c?:_>.ގמ$Cq:KYX,UW%TA%} M/4ӭ~!x*+geV(o6ё7]?^gǿ i73vs#ֽ _.|y߆Zßx'CNެ԰->Pr/+H$ɯbiQP%Q?yG_=z{O_<<#χռAn=w-WC>O'*8ytO|T⟈^"ԬW7ڶSJ4d a@NV+kFRZ TrG|_Mf{]#ƚ-}5\ : e`2_NO~&uwàk[KG. I IJ435줶Qs&%!OIvo_K?[^D%\ߋZ\_Mk?=/ti/4`c_ {kI5bio 0I2hˌ_[ƞ,#𗋵rH#XE1SDm=9CwƙuTp?ao?/[xw.Em9" =F{h_"0ԙc3yߋ|#y_)SOZ:\x'yff|6$j<NAikje#I7s- 3@&W_8(2 [궿KJ%zۗgG\諸̠((̿m3O%C5hw&ioĽcHf(((ڋ*~ n>MiR³R6$I_d+O]R%>>-/* lK9B[apI[ 2 {,rgʖHug?nM? xOPַ6 de:<]{y+KM. wlnJ ijMnB’ym+ۊF,ij1'i)[5y#n,|G',Q+-(j$󵦫quq nlw+CGӣ'2K<>|ɦ׆?7Cq ,n[wtSzO+0jhzg:}a[4g bm`^zC벽YYpff]8U'AzUӵoK-ylkhmo_zhUO9#C*:$^k`IK`Z7[Ac͘^#x_9>Mw^E%?JZ[WGFuVke񅾕mj7\Osyo1a%%یVSU#zޑٮlmCUi FVRĢ;sTz}6hRDY#ea`z;V\|ߑI6_$wW+qmi?mi{5:ycV .V4KU#[x9gh4p67l1czMZ_$t+If"Xl% `أq֮7֖wo~7m>"ݮ^i1B cu18lt/w]+5)jw #o:\G")0TRiZ}|3ʬ|3&_sao'-ٮ&K@f{VvbqF Ib,jL-EFOLgwvڊRWn?7wF쪤Vm&dF;AH-f8]zטO+thk/5!Vls-]\B 221ɬբz͆+?BІՃ@2BN.R_6<[o(LudHOlzhAԏ}{ D1eơ1[Beg̠Ɠ$ɐ@dfr[+~;=D?e6gXbRV_7P}|V?!>~t|0sFN?G+~ъȡ,5+._[_PأL'z?Z5ɚ|$/Gk3S{ I5HBvnm۽vm[#+S{ I5HBvnm۽vm[#(W=[@[N 65IWӡkIR5?gTK Gqf//~_yzyfmmۏ157tA׍ycH SI?_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ ~#x˹׊~|?g}mΪ̖ܴJHUAbIVbz#F%HITOmh^K繛n] S[Q{=/| Œ麵'M&#Ѵ@3AfKf*5|)j |]tx%՗EӴ;N@6Mf7kv!V1!>#:^x UWEiee%Gu!JNHOw3McZ-;S񎟤Y}(Ү.o- Dn#/$m1ޯd[+Ikt_g~CO+[j:tx ڙ׼=Z67zT[& Td>cr6)I' +\_YO_ j/8$K?!n1;T ]%X2xEԺk^/..|_wD|]xk*P<6[ 5-Z71}Mԣmo"}V{k&,{Zڰ(Ȓ "I&yi ._k'-]]ۻl{iuzk(ڷQ?!;0i<Ŕv7WwDMngxVYb ,+_x^x% k5^N\/diP˧XI4l#i=S +xwǶ.i>4 G-tRyϟlOnsiW׿^nj)`񾯭iK}OVRtOOc[m>(j/fi6rzcwuA~?XOqjމ,lZou{cVXTEvAloh ~m7~v?-c8۽-Xe2?گ?x:6 WJx,ԭ%9H'1 6ːlRލ\߄>V5Ε&F$B\JtӽP7*(Ƞ(̿m3O%C5hw&ioĽcHf((((ϟw_|5} ̗'!ڴkf^`Kn" ƽĿ'4WUG>}/\_nx#Ar/ؾ,PwEIrӌ*V[˧oGj.}}wZr]W+-|/E>k7,5?h:akccIh}$w3YG"< ԊJ91'%^n[zI7TzU~7=-{}>_</xk~%ցr='Ӌ;=+\;GCFwfy}Mm' <%/>7tEޛƚfF -$I I3{Ko w[z+νջu}7E|>%/:wkczVO iid"6rC᱑w2׈?nxgm~ ᷊5oD*~,]Ak7'P&XKhcf}&5!}^})o=rMEI+]%mݬh k>ᅶZ%=tlћQ4B m!dPyuOC\ZMgTDj`uhem1Vb@XZӋHS_nqi𩈄!9REf~aQ_)?|}qr9Z!nmQ5-9p¬[@(N^*<Z<W "y5).&O[M1kpW*+b!f۲W׶Tt8;7}"֚OQ_! EFmS6ncH/-/Kڄ`cy#.8I\ gmPxgOC[7RX?[mO>S+j]Q7{-9$ݻ*z'?NI/DմW#j<!{jn?,s=DH~u+;V5m _#j>wM??kI~*UÞ &_:XX@Y$q>t.W=.^eo>* zoĞn^6]ԛI{#ɵHQT\G'+aAQkz'Þ>֮<7'RZof`FLlޑ!b3jOw}|E9nig}vS+R &=ֵsrK𦜍Oobn5;m;IY"t8дbcnjEwٛ-ok]5} [J$k{[7\b%hk2\G̊N\;>m]'Nuj'kM_n_(J?h/|'l<c8?xO-֟k`-^qK*+&aYױ4wDŽ KV@B=x[#Kq#![J#3 w"#Sv^ҏxٽoI_݌%%vt^E|= E+k/:qMsV 7uȴn%vi%Gms<$+;FߴCIt?O=1,u{u$[k:_:ՖHx-n;3OY9i{iϵvΠ}=wWC+ O> g;kp'i66mhi} w$ /{b? v>,Ե6C fX1ۢ"y6t_ZïZY]xYſɴاkE&v{ENJpU#m}-]5MZMB-6K___$|P|AUR<%ѵt@[xT4)>4G2Z hK܅RW'Ln5M>OӮu巿km5 .!v-` mN)_D~e}ص6^_*k<7mkFg5˨jЭt{{iouCws+t C8b)n FK "MGJnv6Y.#y\8uVgc9U[OM=}~W>)Q@Q@Q@YS|\?*“_̗sA"ӝC.w~&x?â|y9W*\.[܍kgW'v=>+~W7ü4!?_4ݧO ?b _? ~-gNTGniEno渐 pePa7!X~7zM#V]CK}FmmFv0 ygB4TǏ<-&sɸ@ItSRY:kBFcy+>xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mWOGO~)w>-[*Jho N d+ppsxk 'W7x[OxzᵻS{V-I͂6jbJ]S=#=㻩oSm'&%c",\5!H`i2  a/\MF--")eeZX"Xaڧڂ`|hIY}iFVz|Wiل}tuZ,G~G|= }/[ᲆqu{74 ,4ÿ>OKB~6xcd>̠tZy"N;WR{xg<Ʊ_xdԴSNLSwohgoc n ¿62ߏ/2_n׉Zhڦ,eO6M5Y 2,'XI.4Z~M&m+)'gvjcT] Y_|7t]WZ=VWW:i l{IS%wy+cxׅ|yMa{Դ],$6\^I-鷹_Z\&:[;td/2˻(5 ߊ5a㛷ѥִ[;=Xo2ZL^t] w;{[{GIn5[I e y^ubbIkkowᾎVm 3?] E$j%ڕޛo$v~uV Whp>[{߈u N5^U8B\|;Lź2AxţTOڍcw$yu[_L!kebE b$ 3׊׳++v[J_[t7k(((((/_LzZ5kɚ|[/XF ( ( (9pàxp'!l讣m 4q#"~X幞nYZWfe@BFH*"*ET'̖ܞ߆uݽB(QEV_kΫ=>JgHbn( wN~"|M|g}?[姍5? E|M{i]Qalš[+",e#x1)ʼ+鷖Znӿj)tP|W쵵/ǿ?'}~S 7#MgTl+VV-mKI9c#n%Z_r_hvZ]mB}N=}1mD|h|AZX2;˕G.I7ȸJY +3by7Ak;kx 5MFӏi4jEy) oG.N9N:{8I%{AQSPwg }}W"uY^ͪiݭ2\\K`kX$smTc(9ߴI?j> nu{yk:O!%kcgiwVry)x[E;JMwq\)3,| Fi;]kfɬtM6ır+[q7Z{FoXۺRi>Z藼yjkҒMFﵯoHbY~~O}V;K{r.--${W dRd ašMph۝Z{MFuM,$2 y-6qjŸ,9׆r?xoH5]2!2X,D&Dl xksuּ=lk۟U)W c9Ȩ#%~W5F뫧~k[͸[fQ[n[M_{P|D~ | >,k}g;QSIۈEZJ] . ϵW/};G&-mISOv0Bnnd08ޖw0ن`~Tx{ˢ^Y~Z W^"׭q);%ZϗJS1 yoi_-So>,R*:vo=]l D쁢%n?7?%}wunTm٦+ٯ]5]&o#FѵKQ"y['k[_>EWȉ7 ry9qm5[MKŷ:HkjT#[f`_)nZa~zo<1jd7$\Kխ)Jxgs ŽS᷂><4i>O}N7_ ӴQ]R[a{K"YUpy;&z4t/u%+;(۲jITq{6~i5f_O ]^X,/-E=@ia[H-KXUe˃Pc [?|7mAtW1ߨs f՞?-g;W oh ž%MO 5O @סR,dx8VAP'?Mb%s7^kqeķ18 eu-jRb_J.;Isr5=Y{N?~(,nѼKj/o)ciV]l07 ! UT?ğ|?]Fo=oC֣mًWYmxĈ[44pZH 'ƭ3_|5'=oZ5kTZMԢZ[jR]iw7?fkouClB(%߂O|w%ǂl>22ҼKq.uutޭ ԏ&?"3IdG漂.װI}yוjoҮthCo_|/+~ڕhe:;_JS}Kq^-@_I&v4oiGGw{,pF\mtw1|z oh_+Hxj??lH/|#_;se[֋u շ٭Rk4߻eG%euI6ֈ'ŸT,+k^jū_\:Le{$*F` d|<|14GNҵ_DW5zΤnZK=]^\K4ʶG+FU<|^}g}B_O.`G->أ'D6&>k]G WieycCn^8~6mIkvN܌տ%$j]lںEߵ[{su_'=_Rnd6_ԭm5KXey baIe+̫Sw 8nuq贛[wWIIMyRXi!Ydg8/G>?y_DReOc1f/y*|'kl] VҮ^y,yi!zAWcURHu=(++_Omҵ]qZp=;$^h})~_ 32j~#"ԢTsLJ-:|qoΝ<3$oLYO]p| #MF(aznZc;yKĎs1? xXߏo?hm?gtzLc\@t7LRHBKń<^I3񭮳'ōoKU/IiVMcQ_uܷӘ[mhD.:ChYҳӢj%=J%QOVR>8x/=ωo)/N<>f|b7V q]+.Nw<FVf׺c&ynI IQdDl2A?o~$z Tҡ> k mƺ{&C#j ̒(>`gυ<3#m-ѢzSSgqW$VM/U]RO=JGyY/kF>[o)OEOUѺPiIoRNUWg_}yi+[Ti&IV>n&y[ZЮlmR[.XdԬ BO(HMU'~ il14izm,-9ἷ;ݒҤG|A7#x\Yo?!a٭, nfKɰ+9 O>O1]TW/leKkq*5[3>SQ tܤ]>mN7NQӞ5yhE/ur.2}?~ tm~ =]~+ wW+s{̙.de|3` ^?=:5ՉuM+m,(ֵ1eki]6jhys=y6ǒPo|ն?jwl.V[YMaė/gf9%{Xw.ʼn,q񗅮? 7t蚅'-ZU/o5QCw#~iVqEW-GW,|[]h,˧jdq,11Vp[`$jI)fܔ^[KVm))̛.-w$٧w?wόƧiswj'uMQI%͕3"4 +Febᦣ |ԭ2kdo˛8 +[Z+myۭƺiHMk#y /3$?x$fǧ2xZ>sEA:nmڭԅſΣ@"0%SUȒ򒜝fL+FW~i'뻾J.-( ( ( (>XvnL>,O0G!xNwxsnlO0G><9WW^Wɟ EbъZwh_CEؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?ߴ,?s~<}|0ԼEX{OF5V$StM9hm˕f8>c; ψ"ux>i^\xe/lRXM8+sso%-Ucl~o|Q/A?G$kg,1MĀv8ȘuP.%ܬv-|%O7^#ĴMo/ .by"IkIGEy0I5+KfKN_ܛZF/ڥ.iI;w$ ?7?U>>XymmIlm-fi-`,= kC4G> M2-8]^K^Z7֛mhJ֒CܒA2' 9]#W_w^>k ]wQCoL%/ɩGw3;nլ^-MZ}S8nng5IH$cA%́R$$p5nf(}蝔n ]k(jI;#t?+;[a񎯨xl / iczŎqH.QrٽlAtOV'Ν_/eXi>r%'ͽĨq ʁh3왦zE|Wkfsj^cYZ7Wq%#dtyRHW"HExÞ4|A4BkIZ[ nk 2E.гE07G)~xߪI([][ZNE?mW+օ-0ѵj_$55bn4-n( Č68 {yḵOx7_Ķiq{Ic ]&;icԤ&K1ʪ7'(^K¾2='?xIz+u+JQ6=ޟ;‘ͩ^*fHV,w13=ƯwI𼺆idRZ97y$P)N˕_k7IE>]<-tVݥ Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:UFn徺u߭忞C* <4b^3Vg~fK?jѠ(((((((YGA|HImT+ewd,e+b.87 o+¯ٷ$"5^]5wERiswweo$I*yqG Is$jcv0.gƚ$ni [k_|0ؓw-fx.@_ ~/k׌gz,zçM]5NmJ]=#Ӧ{I˖;XAWbGVZ{koyFkv[m}9v5\tK֡t 7nQJGkh.RЇKJjf0 dyU=Q)p֞{jj(-he'zct<3iھ㏉nFyDbm3Qw< $wUFxߓ$]ggf/ҭ?f/ |1ž2Oi4H)i2ھIPjШXDR%Yw9jV~n+Kt},ͯ0W\ލ߭5-խ~vV/ŸW)Q<3Y[H#w-f(Op|Z6RW/Oipj [k֑i麎&mk/bx&RFbW8H-Zea:VgnS^ijẐIm'Il*ovvOgE=]{Ƕ:XZM;Qkc QA}-- ͝)$yUԭ앶Nʛ/:|׏*dx-޻A{i~uE 8߱W]!j|==7:ikm QH7.t5Z<+k>o~|H_ SOri5լNaeK8ZqPܟex_^|dмk*Vg4"S4Țm\$G *$?;'Gc=?|_sŚf-M/\٧:f2ԁD2eHQM(ROHޥ6}MZ%t5uvl}G^ֺ?kwޥGhz4vՊjP`dg%H+ Wo5|UtW4iwb;|;ʃ,`&@{3lχX?ּ5s/ ዘ5u]&>,${hDdwRw3im;_[}Mx_sMk7ϗ[Eh̶2G"Ϧ^^Y`z(#]?Pxc◉߆SēiQG%ⴸ qL7l, Ξ :|CɟRŚ B20Y[D%Hϵ?a2ټoy?)hs'lmvј4Ɗѵ)_/_w_]9~V'E@5fߊ-@n5㋍:C.l#AfX_c^[ 'E |u;C_`K7 DS ѠWĵ/,/-|-:f^vj&g(G#DB3|MyxFXM?ɥEe5O}D0I:y+au9bko)w֪>m请ZV_5#̵+ e~A-/RI.b"(&c|RHXX- ݠ|J|)𷌼kMf P>6(7?dWU6 ԷGÚ^}U}jZMm$tDvxhĮH<_|=tSIߏCĿx[FPbb_ilD. igƥ9K*0o_y&]URJ){7ucXMƴjJּ/E4ݷϹ"tkZ"O֍oKs{"y# [X>Ypbm}+X^7j: l:v˸mghUqA G5K? !_ ŧ\ç.wn[}h#o2iLHze Ϥ^k7'^]%;BLr>30+N3) UrSXB0iz Gা=_k m&9 IG3n=D-HTt) צ[]>jFVY/aҖu!;Yc6/x1%B2: |QMI5iq[\b6WwpcG!'m3Jfq%~oo><~[u[ jpGڤao"+ԳI7AR׻nrm7[4e#.jnݒQV^r7ז3⏆_PKP74y4A[SՠisgCyhlF_?b|U/$ԯUs`"Ur~˞ojzl+-Ǖv$sᅯ"+YVm GGĿ xb:\diHc7vSwmC&f|0ju;zIKITI󨯉BN>ϚⴗDޭ͞ki#<,|wn^1x[D4e'72KzM#vA&Bm'gԼ}tOnAǦ=Ι%3bwYpZa/[62kzmh`FFI#"3&RY@Ӗ2|<4?5𞷡ŖY5֬rAǬ^Gp0,SF>(!G6]Rem@F? *[<5վ8E's }3VfZgmÛ1xn#ݤ䅊XtC񷏼q ѪhXcHD~tn-&`ySvjwnluZ_ ri+_;xU/ ~x[K:VEдRC-ĚM%ve5M+UgO V߭>٦k=8t7cZ_<)}i=cGv"xm5 |v2"HUB' ?k["u-+\?g[n+܇]>A`cC=j>uY4-F B+!(ca׵$2;}8"~!//~?fm.fѮ< PP?mNvWWm-z[eZKY΃px ľcD־iZ}n"`0MhYdFVɆgڃI~ 5 /L岹I`XQs ͍ͥYm~t&ޝ[otK}^J.ڌ &zƱ]GY}f{xi"\ jvB,坙<]NIm˥_Vͥek(.g6[-niv޶I_&؟akC><D+֫ ~/7??j6>X+~WGC>Eؗ 5fu? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?ߴ,?s~<}|0ԼEX{OF5V$StM9hm˕f8>c; ψ"ux>i^\xe/lRXM8+sso%-Ucl~o|Q/A?G$kg,1MĀv8ȘuP.%ܬv-|%O7^#ĴMo/ .by"IkIGEy0I5+KfKN_ܛZF/ڥ.iI;w$ ?7?U>>XymmIlm-fi-`,= kC4G> M2-8]^K^Z7֛mhJ֒CܒA2' 9]#W_w^>k ]wQCoL%/ɩGw3;nլ^-MZ}S8nng5IH$cA%́R$$p5nf(}蝔n ]k(jI;#t?+;[a񎯨xl / iczŎqH.QrٽlAtOV'Bq>\G* h>q-ٷ'~*xok YR4j70iեՓq=K,}"hؤgOo|}$hZ-*- &v. 03A.Lh#Լ-⟁efcn͕Σs kxaɖH.c[2EB''6}v&ݍf.OyrP`._6w"4 =?>#cguxxH6vEq9KY 2/eM |U m[4 ,VM|=FmRkdwF[ $j%u#s>"hN#e{_x_F.5x;7$m^oVV+֗6mYea!K/d_|I|K_#ȴ/{ei$ַpA,X\ʐ>뢢Rn_IZ%$u5{;>KOE?sVWZ5Oß ?m/힉:ƣu."פB#$hb/>"SY|TVko0]\j[pu/I'W0Tq2̐9b!rvy)E_[nIkK5k9M?~ ֳRօ ;;x׏K[yKp褛3PEY6a?u rMkU5 H%F2o]E"رwEỽJNl,'.~%Di)P nl8 nb:nmkVQͻjڷ|S_4%ۦx?~$:Oh?%W^\_'M |R]hQϧRU{e05TyΑ-;IJ*ii.7Z+"//[Y(s>%#_Qo ŸdLh5|}_:ďO|G[i:> zl[a繲.A-ԐTPLP=UDetӺѧgku{7wZ'ߞK'm?dwQXZ6wp1Y߱GO!k;(4Ib^0ך})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[BeEK_i+dno }mIHm;P, DYيcFMb<4 k"ֳxCѵk;Mlq5Z) >ey>3?<O瀵Y}= tX[+&YARYwRT/'n⯋ߎ|??xkˍ#hm,-m;Xey$lRD:mo%&+׳Wm}6.[k_^WM%}=,3Mw}o ,z MIm* KJĺK#Jo- Ir94eswq_>4Լa z?8nnf~wKdh%1wy!M|8$<gE% ri0iۡe dg˸k&T.o?%>k> ԏ}-CuϪM{[KMV9o. Zdf ,YMuU7{#+gu}>I-vۍg?M"C׮MOj\iqZv!鈽Ǔacߵyb-S_kR5G/nm շao;[218b$r_&-4(χABtkZś>17\kI $7^S[8V,Xx6k[YɸYZMu VW/i"ڇv9k9Y UTMsnۖ~^os}kJ={ۧ-Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:Q{?{v5ۓC5~Ӗ{m((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>BO''4J|ࣳ~<5s]_` ,O0_/v(gǓ|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSwIQMp/x)і94.~3?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^>xg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{_( 4ߏh 5/j>Qi%]v~Zq$dv# d>yw'ZݕKdvKgo/iMex >(GWڠbl#5{&@PIFdL:V; xO$~$xז~).⏝LK=RSqc4 KD){4e#On+(۳mɵtkuӽI'u{}z-4y(Ҧ{IkxQ.Xˈ)SPI}}k$i{]\u˫M_iSNXKiRxowů_g=tNyqdEľ}ZqODp9 x \mJu'tVk> '|WȰ\%Qؼ^gmq4|+⟀g՚=z_/mCI-[뵊{6D-q_G24-,^SnC\܍,% f4-mx ?'? E\_]=#l-c2fVg8$}so>/e (,((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?Q _i=HՠPQv-FѤ7ݻf $^ig-kмG<;GO I\91rn%]?TԖyNvDZP"mXqJ/dχ~%ju]>%߆5E-JӭV72BPGB4}舯<28% yVQ~}?@49Ե+k61bHPMаϾ~~|>Qv#ּO5$xk{xCUo<i] la{:;_z[_^}2k`XM2Go0a 'o|+ï~uMv9#Zu'CCFPY@U9 ۿ ]LQuGd7֗V>;^klV^V.`٨Ift_)ӧc$Hћmhצd{?:yEӕX'-;]t5+OO^G~'zQUZ髧j5;:KԚHM6F[xDS|}-ƻccV:ގn Է{+c2[J6.US1_C=3$|b ic}J'/2&l㰻SdG2o+ݭ~__ïxAZߋ MROo+lRKhSL'Fpe xINoIuxE70EAg"Aozۂ$L^7xO7>Ϡ–IY_Zֶ'6DGX@\vZeJ\7w_m2Y޴4o+iU{ot?jQAi+/|//W?/;+'?~#ir_x{[5(0=ƝyI B@`N:ᇭkW JS' OFvSN 4PQEQ@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPU~'؟akC><D++;_ΧsR'?q^_Sgq? uW~t|.w_CE6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}8Gh hl`rAM? |GxWOw5k)ΪĖV7K+f8UI_kSxK_|Cw ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{? muW.d夒TBBR +Jױ4(BJ~kFW_=wzy??; mMj 2R2{+W0h< 1'?PjVVSriwV> H _m#ϖʁ?l߇__ ]r[)-EQcrF0!kt&\Dڍ Σ]$2hebqum5u/dnVҲi=9m]\bpԞe 6]As^7{̵vGޭxN]GBk6U駷 Fu\1oP2FN; ~F!MӵY,w,2j @g/m!5m&Tӝ4}OEintY\dSIh9Mǁ~ G}Ž cʓ*j~ԕued1I9B+/ k\{k+sR!C=6H!xCbt tu#flNV-I/. tq4eՓPQ+64>~ʦ':}[P jxah"%]b5fs@sQR;}KC*ie %U81݈T_1skmwZMՌZ<[n6pƧT~5o,5۝4˥O?uDEl L(2ѩ:W3UWV煔_ӝw'\r n߼{*^\OScՁ -ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@8_UcbES 9) esJL:-:QHgǟ( ӝz)z3¶;QGQߡV*Ώ5ߡc(Ebz0ڟ1x/gMw~?Ck~#i"÷7\HŸUQf2(TRzWכg|AgZt=[z&A.m6[6IovIA[x*xwXsxbK$~,\V`RE#WTڱ< L^wßJ<)|K+ jo[q[D*nd=Ơ~i-_QGǞ#u_x7)uHt \XMq+م2ɨNfP k-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mg #*xOiZ(F=WP⻖čE 61ydjRɍJg_T[N>?ՖxjMZźEkRpIɼBWIxsſ<}WSW/6gvA%0KQþ7ǿ;_M |-֤Q~/ ^I.t="X E4yďq,lK7hGs4ѹB^ݻMKvQQQ)I7%ytK mۼAU;O[]CL}Rm{Z6,]_UYX Yh wM'GZAX\jW6*%$Q6(V `w? w?&/Roj:5,'/NPxe7oX$RINUfVi7xTUk[˛y.$HNULndA,^]P)]ܶ}RguR|m+6-u{zYdݗ9*W#ƧxUӠ|W Eofg{ CT[B,sGǏᗄerM[O j^ԯ4 f53<*v0J [ocT𭅼vg1IlT{me0>׆1VIu'$m>4dY`Sjq:|[[0[kHYd %Wr(KO_2[պ_%3m0N>8井xSA5+ 6S+}FєA%[ĐQT_*A|=?(_ZxO<]6Xm F-VMI 4]@VB_ݖ3xkᎁxZ}UQ" ,28xM=.X;-'tf]X&)4Ӗbآe`V4Օ-"ӻVV֒OG+(&SMZwmm{_WgEoڮľ;|GqI V_4; 1'25Z! uOuNjLO5K;Uhdd!B [ 1I|44-/Pf6>%[ @-AWkjLo@<,X''|_Yj^']Aytm%a ynIyvʅ7mʧ{t3VrK!4է[n ,G|{k~&} Ikm|Qb/h j;RI/\>HdUb>&m ^VYӵxἃd'ʒHdFٹ%Y"6I#wFV?~ϟM?㻹|o{,'㘵 G%ڋ{t0oNFJHvY~gR=c^X\_Ksw2\Is<+hlTEG٦+^]V;Yk+:MʯnJwWѿET (/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_UclL:-:QHgǟ( ӝzz?/;QEQV*}WemOxG³b3O%C hwQ&iĽHa43hU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gM%2uIX9XԱ؀3$M ?~ |GxWOw5k)ΪĖV7K+f8UI_kSxK_|Cw ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{? muW.d夒TBBR +Jױ4(BJ~kFW_=wzzWO \M M;K 8n +]SWDk!%B_SMfO+߀>AzkM*};Q#0l%̱Nv?~lOh'l-tzѶ4QHkӮ2dA7r2 :9 {W@t?d,"RGqm.bV%*VLo)ckߧo[zkki5g+7_?5]GOնMJ9mSGMS\j6|rE$λ%5$>\=ƣ >-b]մ{ itXմvnt)lEy*ׄ4+Io/ ^OԬJZG oq{#?2F}_;<E{VڧuG]Ē\6 N>XMR۵yfn$_kkgtu{FMoJ;7y+>b|m{>IT[i&}[]ZˢjPuۡA(&I$_58-W4+o_ZFớkXc5K:Ү'Q/+pIu84χ4Zω|QMhAg-?O \wR>$)xơq qA-4ay`VPKG^RzVjѶߖљS>ed+}ͭtj4 ρ_ :~"_In|&)׵z~kkf2YH'{?(~$z\/ĿB2MKzNk.>7Es \밆IZxIHS|[uK 9'/ohS޼辿eFfH2DĠI}=kh_ |1⮅}:JUe%ӭᶂakᶶI)F g-v{}Yf*v}-VuݤcO+۟MRmVZѯg6762|m"^#%$ xYk&&xcT? {xpQ%3GmII.c/,mݾvu{AK㕶_=xQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@6_U'tZuࣟϏ?Qؗ 5Y߱GO!M((((((((((̿m3O%C5hw&ioĽcHf((((((((((((((((((((((((((((((V7_sR'?q_6%[o(3Oz~u?V??b~G+.x?lZqW~d|0$~ú+Dz0ڟ30أL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((o*lO0G?!xNwjU&tZvࣟϏ?Qj?A=|VakC><D+ פ oX3_oR'?q^oz^?:˿o&~|0п'~Wo!1O6_Ua?C?Bb3O%C hwQ&iĽHa4Sh(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>^K+io(+O⿡o[cZE 5) er^/Gد hG#aUc_ Q JH)D*0ڟp1g~f ?KѬأL'z?^iEQEQEQEQEQEQEQEQEQE_ſ!k;4b^3VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|+Ġ>+O0F~ϧxgLmdMM$PD#9]UTTg8yٟDQ^)ό:|1}7 {]lC!oG>3{[^)ό:|1}7 {]lC!oG>3{[^)ό:|1}7 {]lC!oG>3{[^)ό:|1}7 {]lC!oG>3{[^)ό:|1}7 {]lC!oG>3{[&ioĽcHf?> kៈ)xw˝&Ko,'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3'L\mlX 1sɴ3+_0F~ S×%~XSWcVTGSnQEyQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@_K6*e8 ̀֓6O[5_ \Vf?oh͓?ƫ㕷鳍 _^.:"۝CV(F3Cn!YY4 |Ŋ&w +l޷4f^z*xgSeh΍j>V]Nװ\Kwlw C2Cv_ ?i[;/ڵˆo#P.mmJeJJPd TKQm]VIMkMB͓?Ə?oj Pφ q=|N*.{xg6#ڻqK<څݤ :H5o-&f)%^zߞ?oh͓?Ʊ<☼oM?WSQf[}FK;2>~cڶ}Kٲz'WKi? M_zn]" +׺X6 X6n@p$InvٲzG|U|0^-{PӴm^Uaj2HU3Tb@_ɑEhѱtQE|/ĎâWx9\WMl3|HRqtJJ??:D\WY[%_ޏدʿ"$|N3_u_~#>QH~YҟQJ2EW}QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEcUuojxB|QY{O"զs "97NXd`=j4ş ZOk!<;k w:🆮kxS ;k[F6s$VtlYcFDnR@|YY?>,?&[ 5/h텠_<oAͭ[떚ny|V7r ; n/ uْWXmÿ ԷqMM\7 -EkfGe@|YY?>,?\fq]u~z$]uWٴ9SII_uV7M{]kVi?vh?@+4;RHF"4[?>7!ikֆ;>**&Wxy_RPV5_ \Vf׎'uǴ )mZg0(#qYD@fր=v2hxT h^|Jouχ$-w}#JVI3E?=f>jZU׃|=7ַ(aV+e+ dM"ǼkVi?vh?@+4;[F|I}+he*n/o۫|<=S 3&GFG4ş ZO]ɟbVge|b:1c¿~h >&k7v/쵟 W=}O?J(͘|}ğW> gexW=}O?E1ٸ~[]/'o -tW'g ???dmo.?S~_kO[`~_2~6Gz:w5+]?f?eox[=uO?AϏXW - jV?AT:w5+]?f?eox[=uO?AϏXW -|5ljeaqo tgn@u>=?sljel[]F>?Ŀ?-o.?W~Q_g%mo.o~ι/o tgo@u=xX_g_S+{=v/o t2?7GrT: #z>YC$ao tOge[9T:B\__=O̿ +v/ tC\*_QE~iw_ogx??A:? )Ԑx"/?h W=?TWUK/\ x[Oٰlj?em?A:w./~Ho~$+)Ge]?ksrN`14oHO=i/g9 tY?)57coO.MgeoS? W~Q_17P\x`BxXGd~\*__E~_]xh'/G?.gOOȍO?RhoL -r1n5L[Zi.8]+\_,iӥs892 5V6t8qDNUnit-2.6.0.12051/doc/img/langFilter.gif0000664000175000017500000000153711713252032017260 0ustar jtaylorjtaylorGIF87a@ ` @ @@@`@@@@@` `@``````` @` @` @` @`@ @@@`@@@@@ @ @@ @` @ @ @ @ @@@ @@@@@`@@@@@@@@@@`@ `@@`@``@`@`@`@`@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@@ @` @ ` @ @@@`@@@@@` `@``````` @` @`ࠀ @` @` @` @ ` @ @@@`@@@@@` `@``````` @` @` @`𠠤,DH`aB&Ar,"97&Q"Ǒ!BR$J+#><)sf͍s ;NUnit-2.6.0.12051/doc/img/internalTraceSettings.jpg0000664000175000017500000015673411713252032021532 0ustar jtaylorjtaylorJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?`'i1u{-/OKip^4fWyC+U"o‰#5PTDZZ do@$7l_Yů_|YxX}mK/h67mۋc72Eh#WJTYhݺ+kvH,UjTW-ݚ߱OͷNNt?EM|4> M{ ߈? WIM TWhմH}RR,GX%IeDYW1_<xCWb4;.=km2ʱK,, &e U(]-Co~^}nkFub߆Ph_Tco)+S +k)Ѯ|)EUQF}ONK'X\LV:!N6YCƵ@N ϊ:{E閦4Cmq5ȑ,K sahaRQNt✒ݤںG=l:3t9)+]v}uz=N RْQ|o%c]|ulH? dAJxվ.|= oW:ڍ֟u$а ,7704n*VRHxVFSM8//v'g'/~|} +SM?, >oZZ֊1Ҝ`ɭ?^S ~;S ȴ°V)DZ&.9X?ʾ?e!>|y-gyw-h=8  ;JuO]|,*ɶκ}[OtIWYAm _r9q7~e\_i :>#o駇xCC6FI&/swl|fMtr@ dBJd|d*A!'o.ÿsˉqji|,-':"RCss%qlNjɻ4YU# q>c??;-b/? ~ #{|7ObG>gC[H'f^Fk:= ?}n jά͜^fm\3!SFgB|6cgY چUB;}qvaUV_D<1dSZ^7|70AgB.<,] tGfe|" 41@:\q3.N?hI&>R@6G"yn܍c? _bWc|60ɧzDLwdTÿ]eƈ~bj&Ga_rl\ q SMhc -ge + $#RȾC\Rx?8jZg|L|;U/k3̾6a}gAd?3ÿR֒O>2w("'Oo_rǙD9%OwD<¿3ÿYqՈpzig}gAfGž2sTÿSe8+G鏇 G88R"x/%:~?|eBfz|<2xwHHyOz鴝.Xf" 鯹oLD9ˮ~ ɗ ]D8߃Y?L;UlNTAU/338{TYWЊtƣg7qmܝ~ 2!TCA߃g闇 uBTVz7y%w#*kZG_W?wtE]:|08fS=̔Tf1cBm-'Tw`Tÿ\l8滿,W=|mN?r:(g-"ڵvo? eBQ+ìyqc a**T8+E"f?̣4'SOX_O^[g/1fl_,x? ~ :O stZ q⥎*^/Lj? R/n ~ :_]C("8ִ'eH~%񟅿]< g_St@:oqWWUΤ[ߢ=cU~eM;Oխ:*M5-VK+DM6E$Mq Otqy\X_O@K+i䷸[pIVy6atAJ9*D$7ң:*mbk TgusqxjIS/u{ğ؃ǭ#Ŗ%7 mSEyg@<"cGUi$dVGb~@|O|K|I>t=PAǛrvy'?{Wυ Vz|[b?ZIǟ)Wg\5!R d$gJrαjMSKDum';$v_w ʗZ5;x^2񦀑 gW}3Ik$x;tv'Di; /m~4vڍ䈆G Z!Uy#`q^u|,M;zꟲPVk=CSU OU׾9heGgot:u֮Gt9IX,"YbɻCp`?^Q&?m=!ok{"IĎC,;ziOOҿÿ9sJI=uݕ(ےVVKmlO.=3:,\ |f jPU˜=>/㵮5{~/5o:ՠ|v-snV;CkyL2/:¬oL^:u#_鷇?oSK [KoEQv]Ni4Iխu])6ޚOpn.\k:vyw62_&-$*C asiݲcY{]yA$զ ]~5 $]<;ˊk͞7lām<;ˊҡeMEP"סK1x?XHK)\ų?~R̰ΌeJ<*JϽr'z\߲8~S1o;ˊXoFl퇑׊QqzD9.ag~"w5{tN>Cغ3Z4¯Yn_0zHxW_Ms\)_;|\֫7:9y~x bG ׼ǀ ÿrG> uBͰ> K3jé*A{:vr| |;˪r.'|wUK8f+8i~x͗#B m2dfE?~ g[4>'BǷuG~"W /42pG"䑃KO'oĘc\աFψn07dnD;.j?c<\'9K3Fs6MaWǟN!~/0??|C=ˊ__g? /ϞQ\ sw =ϬrEP _K'H#1.jӂc?.慜a+8i~|U#_YgtIO|A.k&%_ĹIǁ> `]P* /ϓ$bz_:Y$ |;˪pR|K| |;˪/B|4>XxwU*2~$xwUͰz<-?]e9bM*jE}_F38>ǷsOh|F!|A;˚mO_:ū:jG 5J4"_A?sNMod?sGD59?j9=M=5w;_'\ö>"wÿ3Bi˨t$W폈 A;˚??OA;˚O6½" /Ϝ$P#J/?sK?G\гl*ڢ /ϝΦB8$dkn|E*@<;˚?5 x>?l/F?8O\4>-q/ +R)ycO|MBG ?wW`X|K|uC<¥DEN ե~\o{.A_%ĀA o4&k |=qb.DiOsu}Z_,Ti~WQ>~ "~|B˿ÿ> <.jVqpfqi~xz`py1j ^O ?枿'i3.ikቩ$u7 ?`__??`_.hRy5xus.jDzºGÿ|/EG0?hZ]ls{z?C?qOO؇ǫ3oF4<_bA o@zz~><_?⧏3M"^fL7+/gA7ަ?q?.*xd?w̰Ύpk/yzuT|t?_ك+4Ash::ayZ;Ԑ$\[wiyo5 h#sGm|Gc|(Q>//٠m\@$dp?It.)8?W|Hsϯ=\WЋh=lg&u b%/?<-/ӏ?qI .??qYE ?J׵kXb$@N@Ysp|#_t(mB};U5 麆%[܅&ieh.pRVW(,O$i4o2׫T67{[ E"m12>Y'flhlZq&s|cS (7?j xFԴ;&jͭշzXnbu #VVR`H +(CC7^ *?4?NuB4?NuB/17ij*(vA_ܠ#] SEp?'!Q !w ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i xi x; ׈? ;+; ׈? i x[-RԴ~7WW?衶aUUA%IH((((((((((((((((((((((((((((((9W{p@?XG__oiS#pW~xُ ìB+K_]5=.-LO -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'>?xSAtW~Tm*NZT{A ["¾`*n-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#m;:7]Ǯhï T4}S:w=kB>dZ$weFF+M'|hxg|kmm5hIEx "^yd]þ&̟bͺ0LybƯ&iQKAyu he۔[I/-̌$Go+2B}'~>7zįx:X\i1iMޱ rA'>PtI%DyU iY1{]wwwf[hvs]۷]y;6}So'?]LvSaC $FzNdA>U͸QE ( ( ( ( (<4b^3Vg~fK?jѠ([Y=im_ĚF[L!)Uض寡*BJ/ #F){ 2/)3,PB(%lr@?5IfoбmX@6o^D*]mnB2O9/cOG}AҼm.I<=%LJX)P6JS3`WTjjO$۽K}╛v^-k{+^khOKࡣ?|X˩j>3 KCii FY5G[R]id6O h'4^ޅ_[l=#iF|Y~xmޫSSVwc ,PCox^A|ImwIH[ַɗ FpNh{NɍJmOE5h| ;CO VBINKY/,9i,=cמ_#п㿎?sÿ xWվ,lu4uA}kW-jao;H21l.i{m[gLfZe_ )Q@Q@Q@O^4j6m8-7Y0n]ʤH4V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf[H??V/?&6hoU $oCG hf}s<0b94(O#C+ F%!ӝH"Z _xGoIGP}Sջ/s*Qh+r+81guc=K ^VwQ&iĽHa?>ؗ 5})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[h|_|gw xT|5#S6 +M5X,dZu ,^FY䷛qHYc_ eְx$j:h't߇~";{k[=nMAwV(ZD$2M@~C-MxK.OKl̡'* H9,G"y>Ѽ1yqh/ou[RƩy7?mح̈́km)F!xT@aljd7̚.XݨK>ۻ٫kgnT| d/;xO[WJѦvhvŐa%Ȳ t&yP犕n֍j\ܺY}lgw^V=?NdX@yi.iu-.K\scyʓXꗗ1o@@wǿI[HY}_+|BI[V#>5wX–hvq^G/yv&f.TU$@I5M~)zio_ɶZQE# ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((&{|H_To⿣[s'W!!%?sNr=?+S;P!6_{¿LI?,J;GrEig~f ?KѬأL'z?\u? o~{>Ʃy٨\.|ۍwͻ|}D}%s o~{>Ʃy٨\.|ۍwͻ|}D}%r^*=+h }XAsF=“Jzt1p*FҪa2,|e~xWk/S7^7Ϳ{q3T/VhG6g=wmߍgnyoqNI++!x$`2i/_!~ )uv&e/YZXer9* +Jo |K>xைu=֝k QX^;+ʰF谄#x e"?=i[φdd?ĹXnCI˷h/ Zs2վv:t.f֮nYi#AyXA$M{O9*=tfC?xi+w|?έ w촛9m8WPPt|9??Lyo5chckZ~m4'y#m6sj)eyHI鿴_YHy_Md1As#Fά¹*YX8#K/,ԯ5/|WxM"m&{ ]Ѱ['s 61F ew'nӭ6tw\黅mMG:n$[GTқD_N)(&C.T#!`F3 9?Z?hK?|gƺg[o[I;8^Hx 2'OLR|F-/U2CKIW IE{ڷmdQ%0IN쯧\|?*>waZA>q ż6O!.!|rNkE+PnݓNiwMm{;=,-O+gVp{ƚm3K Kd~u=ړ"H"1 p=xko_ka&rY}y P#[]JYX%|N/kCxǟ|KMm:O%{ kho!k$Jcvria_x{]]?ZvEH 88".Ťcsv}9m^R{k7 $u蝽}RvQ֜W|+'~!k߇0߇~ζx;:OÏ զl <!;&8Bɓ>B׷Hkvڊ9=7"}}io$ou+f(((2>-ؗ գY߶ſ!h(0cx9rV *ˡxoQ'qi_f$dTj*vb۲GSEp?1_ړ_7Y𮫠HXxH"H'=k%i+ (O?_:{ 촴ɒ]7QZ[DŽV?$Ѣyg!P^՝ _}EoY+篆^ZO&a\;Q֝55ghyX@Rh(((((((((((((((xm_/s%uIuk W8:<{6%//xx⇈;-6k MW#Ԡm-!MF)vީv!BexB\Mr5QZ[u?]lsҋXso-Z[UIS)e}JZ] >Kkj.qm&}/͗c*3)^/(ڠ|8UƳ)mſ^7qy%hc!؅oܭKW!$'MxůZ݇d.m< ?TE, #ծ\%"۔2m~Zg/ |A׾!|Hz}>-Z kgeٻn$J*Z?˯yry'ot(((̿m3O%C5hw&ioĽcHf(*y?~*%Nrε?i AM}B|R|}|%_> ~"h:]VE4Yܔ[WX(̡ ;[ߎ)ǒ-,__օu{=!㻄@muMfmHn4x#Rrѯ?tV%SkTeNT{r俯gMVHh_ ) V=k[}F;?CrH)A!MyŖMowC-_0k6v#iN[i$BeĻ}uE(MG~h]u-4rG']]6???n߉9I=G:7M>ᇎT}q$IJ]w-`̲v> |fORkj=/[Zxh]X Mkxh50Z 7}uEdfŵ{Vԭf!MEQۧMuV)K|aYt&~=7W?tJv[I]V9V4I4rOw>shg}_7gڿy'^]m]I.g-|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwRgVZMzrKW+Y](: >S<3Q< SW~!xR_jM*HG0+E9XmqeIh}S@|5thNs0<24l+8#>1~:?QK?ޓom-ĺt2I$6o,;'E̘}#T6:SK(E^G=I,KybE "K&|#]]v?>'~+֯5$n,egxDP`f.оm4x,IxòZdI1A=ʀx$MHtTCk+)^Vݭyֲ6OM+o_~23KC2{u$iemmckk]$*%ُYGF;+B=#R'x[#Q,.h5^}S-C, >TC˯? +?K>+@vUVJK/[/;M9fZv$wb|tڳEik9.i.itm`Zik>XY)7xO c?|+NJoKMvk[qyhDD eR VRäh~ԿoMO Bĺ֍؋,|>ReR#(~-N[]懥|FM?: xk\r{9{/hmؑ{W?~^};_j[}$=̶4DI]|, T(Vn߯/{;+un]MKis+2((2>-ؗ գY߶ſ!h((((((((((((((((((((((((((((((>.g1Q)7Q_?q_w$#Fq(k0~j?q]菝qJ3fgY屺#5i1ჟwv2q >QX^U.E5qd8物]5nIrg~f ?KѬأL'z?\gѝO›߷^O}nG~6j w>6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}8Gh hl`rAM? |GxWOw5k)ΪĖV7K+f8UI_kSxK_|Cw ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{? muW.d夒TBBR +Jױ4(BJ~kFW_=wzwRˆ~3m?~,Mկ 8Oi7)6j2[1U w(ɮ#OWWh4x## kT}`$2^a whصʠR*Ǘs?.uCZΉyqsZ#Cs_W6ᰆYgjѹUw,6nƯ|@n.i\)5eLՄpFD I3KQro{_^_]y9m] ekK+OMK_Gwվ#G '!L,M"ks<:8Ia]P=Ͽ*Ɵ.;O /}qbH2rwvn.Ys٣\e֓k.{-~-@[\Cf p %;xLyF0<[;h3|d}֥vs/m_ :@twA{%Mg]>I gAH$IQ]þ=u/|EN|EɥxgW9m3|dg{t{L⼆𿏿n_^__%Ly%G!QAff 'PIrom+iJQ{W1|_!Ү<#ExWN}se躵d&f)S[x+hx߃mxKGiaKL-&y5ő-aXLќKrrP %U7%7{i2YQi>"]JZfDgpay8@vj՛]( 5]VBom쬬i.'G,p@xT_'QƗ=#QEvsE%" S8wLkWi]+& 7k7n^oe5O;o4>]]wZ ho-uWAH8 ޙ @tlmz=28o#DB̑/]rΏ'\giOs|Y>x÷67m{4 Kn^y_08 J>"kn#x:<ž Xu{˭P-m6)0- kH8.mMvN1kpwYMM[+PIm'I'VhR@xGGSʲ2"ګ?? :/ěOsZ׌_iE.o\\X }NɠDM}WY [g^_]񧂼1euմf N-)t9o&w]&q,f9%}~J~WoggR*3j.񾏺ѤUWGl|Eh}-Io*ʋ,R4RJ$YH8 b|O1: NoYvil;oz|j@|het%W]W}6?F]KukoKǏ~\? Dlςxk30?i+ !|;_/D4OI=þeFNu3Sh-[SNޜ@|-&tz 56ӭvN?0<9_kQ[D~2YB[IIwy\FE쮊oXU~G xź'|!˭:eՌumggo>aQ,vBy5 Jn/K]+47{=Zt;_M<.:ȊC+ A/(|sCoDiw]u!vIio,+sgjnBKo,ƘDa|FHtZ-cQy$rI$T&uZOhQɣ 2/|Faɑ?,h?O_>&&tkxeeH\:Ex:^ݳ!]8fC~ mu &NbxF &ўDvRPw mkf׷K=Ψtގ*Mov-^ke]tg:Ơ4}/?bfwwo5{J6cyu\- XG2*Lnb) Y0'_5:O /ukM?C?E)P-hsx扳 贿:ĿR|1>ύ!Կ,RC=(D)y $r2Ӽ6t]x•גqӪQ׷Sk_iW"m2o,)K0w"@qWI~L״k۝j|P^$` JL,@ȹ\Ȝ?i|]?;eυ4O ַ]Y6u On٠5xTgF}_+RgR?-St;i<XB5'h$4ZO5;ݴӚ`n_9ME/w.TW紿=ܦ>g:Io˸k _IeΎ5 Ja-4fI5ό G];@PåY$HfIid//g Pf.cG]_^ɡ|u7;~/;~QE ( ( ( ( ( ( (<&ia#BT;')ֿ/)B /?E;<\?L#bE 9) esBTi]1ζ3׽گ?Nz|V*oxh?CFi׻OО -5 ZSݦ+q UE˼QK1^^oCឱ:o kMo F۴9l6'0a'9o_΅?hߏ>*xZMbዓq.ru["2I ]Sj*W1{'υ|;+P𦃪)/1-nUƝm:#DE}!x○<-x7_uKMsq7c8ԮT}|T+:/?[/_τ)sCh}]іwKi!4*Z ;8$zA]_ s~ߵZ/ë"=BFu_ A2\}]R)%Epц *mʑ_o8n=o[x᷋>ftQ`YĀy-w/kʴڋɤi̶t|Uo [X qABoN}{冷4}UtuI*#PvXn_ԝYaJZ(RwnVVj.F8<;aBS|[ķ:UgOg@>2W1"ŚO/ln 5[o'^kv !*ZnmĔX1e/zG>5{wRWZ.ۆOMoKc,E*XkBd6A_^ fZZER^D sf!O0iJrLE+ݥdӳ 8?{ZvZY=dZ?h{%]+^e{e c&o67(h%9dY9 i:/|m2}A=6E5!&w9/y;c¾&dɩiٺu?] m>me_IKe&x26ѵM0XʞlkIJAo&+e`Y UGg.N]m.h,M+٫3WROǖ{/?਺ľ(ox)u= ĺ{ڮudӖ9bk82 JW/~ o Ěx6iCDXIm"[orh*,MtwP_ӤeivPj,j?,5;-J7oKic":w{Fdyˬl 7 |5m[~+v7W췥2kD`]}ܽsuߖŴ{^}$_g~)WTIetK+6I!)" qi e;2}k| esy+ZkFC?g@p "w-teGL'F4 ӵ;mRIV2i縘Cs<4d>1"H@g)gVWnVouQRPQEQEQE_ſ!k;4b^3VQEQEQ<}9n3\ {&cͷfk$(xVol--2`((d|-Oothn&.eդYdHmC-#fGb#@5ӳMojmz0@)QEQEQEQEQEQEQEW / k_Dσ|Bo}qujiavhiD* Z(pJ (QEQEQEQEhzm4vV0YLg;[s3m+NI;2<𖙠QiFmy HUFrNI'$֝-/nQ@Q@Q@Q@Q@Q@Q@Q@,x?~&O'tZy?ࣿϏ?Q|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSq^+omt}FO#|ͳ؍_ɷ~<7n'[h$K]<O4/~ g~z;^xW Ʋ,,IectVc^P %7%<_W:Nਬo/ eXbhktXBf۲FG߀t{~4-]2M2 \,7!۴yZπZ-ȹ~j|;i:dzkW7RìUB@ʠI O&QEBDm[W|3mwQoi>>j^",|=Y+MKd&6yUeʳD 1gxiߋS@/.<2zy{,&G ĒAp16W?Lx >(GWڠbl#5{&@PIFdL:V; x?śxZhw&tR|jL1MrZr $5#"HĤi%/M]mRtn$һ{ Gh*kmFQЬm|G<{66Ɩ40aHQ߆?~!f|G{.t%/-t˛BMyEɥkI!jgnI| F𮑫k/;5̈́G.t{@[(&{[dԣ㝃HHV^I{xjInu/B&w>w{77W1B@DD8cQ@Қ3}ytN7ZV5 zw$:0W<6oCWTqH=bS$`̨KlwD  Ki'|Sc+O&O-E/}=,ȊK[RE-SMid5=S[73E=A[nK!ySL849MӧDwzFuSַ׮wb>3iZ|ڍhv(TiBoZU xgNŗJ]w,4NkmuTm8yBe@ѴlL~=x^>+σ3G5/ j1\٬vWfe-@<$R+^Q" _> Fi5l$-mwm- qS5 s"hYF}ڿWo$o' Gnk+ZBhڇx/xVZޚ[XviZ]wm VFxyWQZ<wS[{ MפeRFK%PUW̓̂S/A %_i⏂<D+Gω6'tZx?ࣿϏ?Q6nn*oI\›߷^O}nG~6j w>6nn*oI@Ogjv\鷑Oxҽޝ @#\(v2J<4XL;6_|}+#;7 om}/|6>'fF/]wwۿl\t7JƥD.' ic?Lju_ |]}N2 YaZ}* P^V$I'^(䢡NJ~]-{( 4ߏh 5/j>Qi%]v~Zq5&K9-^{9Ȓvxf^G$iRMJٴӗw&֮ыg˺ZzvN]=#izOV6#ap`R[ycKYk{k0$(ďoZ?3Q>#LNWeuZ<dҵ37$gL{INxWH׏}#Ɨw:]ƽ-wPē=K-n2jQ$+/[=5k$:~!xVA}NR}R !PIqs xT" 1iMEۙ>sy_v'eBWn~=ZN |c7} ZfX8}$zcj fT{%ܶovv[;r?%>)񕧉Oh~'">[dE%)LY@F,yѽNxZokV){_xnKz;صHd&x\QK?bkx8 "j m-Jb%吼f&in&ӢI]#:܏k[Kk{l;~/_kToڍսΛ"XP\Oƥxk {mIk_'ZLj,eԴ "<ڍnuiqud\Ok%k,H6)cS=j_I=}A g{If]) G/?/ |DYuٯ[Uq~C8sj_^QYy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@.xJL:-<QHgǟ( ӝC^.|^ _/txgǞGOj XL](п+~WOGnd>QXZ6wp1Y߱GO!k;(4Ib^0ך})Gv{fp7yn6޻6)Gv{fp7yn6޻6x~-maΛy M+5‡c$CJ%#e \}|#Og co>i_a &.ݣp$`z׶|~!kEϏ<[VsO~ ՛ZeUbIy5B>J*';hھK繛o[BeEK_i+dno }mIHm;P, DYيcFMb<4 k"ֳxCѵk;Mlq5Z) >ey>3?<O瀵Y}= tX[+&YARYwRT/'n⯋ߎ|??xkˍ#hm,-m;Xey$lRD:mo%&+׳Wm}6.[k_^WM%}=,3Mw}o ,z MIm* KJĺK#Jo- Ir94eswq_>4Լa z?8nnf~wKdh%1wy!M|8$<gE% ri0iۡe dg˸k&T.o?%>k> ԏ}-CuϪM{[KMV9o. Zdf ,YMuU7{#+gu}>I-vۍg?M"C׮MOj\iqZv!鈽Ǔacߵyb-S_kR5G/nm շao;[218b$r_&-4(χABtkZś>17\kI $7^S[8V,Xx6k[YɸYZMu VW/i"ڇv9k9Y UTMsnۖ~^os}kJ={ۧ-Pbi1~=EΣ8!SP..$Ԓ i4mӫ1¿_?^v$(mk3,Sʝ2;?~W/|cꖺMii͞d#ӭ"`(6bZ+?o x+IJkYvCo č!UU.U%UFs:Q{?{v5ۓC5~Ӗ{m((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>BO''4J|ࣳ~<5s]_` ,O0_/v(gǓ|mݻfݾU">7oԟhNcT|mݻfݾU">9/x o#TaI{:FPd#SyiUDwl2?R?ټW᫏^Gwo/n=kSwIQMp/x)і94.~3?WŸ_xGkj!RU,nW*q+Ò Ŀ[ S]iֿᳲ @MmnL7ۛv[h[./|3{ُƞ%kIAKE4v9^>xg7?lx~~<꯮]\o=I$XV$f'b4irQ䄕D֍_Ne{_( 4ߏh 5/j>Qi%]v~Zq$dv# d>yw'ZݕKdvKgo/iMex >(GWڠbl#5{&@PIFdL:V; xO$~$xז~).⏝LK=RSqc4 KD){4e#On+(۳mɵtkuӽI'u{}z-4y(Ҧ{IkxQ.Xˈ)SPI}}k$i{]\u˫M_iSNXKiRxowů_g=tNyqdEľ}ZqODp9 x \mJu'tVk> '|WȰ\%Qؼ^gmq4|+⟀g՚=z_/mCI-[뵊{6D-q_G24-,^SnC\܍,% f4-mx ?'? E\_]=#l-c2fVg8$}so>/e (,((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?Q _i=HՠPQv-FѤ7ݻf $^ig-kмG<;GO I\91rn%]?TԖyNvDZP"mXqJ/dχ~%ju]>%߆5E-JӭV72BPGB4}舯<28% yVQ~}?@49Ե+k61bHPMаϾ~~|>Qv#ּO5$xk{xCUo<i] la{:;_z[_^}2k`XM2Go0a 'oZ|ԼH⻽N9>%Ke(c<dm| kgz:o.|w0ГXb"L]4QȒݚ阾R#INOK鶶~Vogm~K7MY镮Z|~"<?SuvM]?Vi^O^Di224 lઞԮ+An5'I.stomH.]KTrx "F?~ ĺ=֜nbSյ ]"l$r"Po%գix:=ޭ;‚4-5BCzӛK%&_(.#eEm+zvM y-Y੶zT)|ŧAv7O_AvdMH٥av}ȏ+eKzWZd^>/hVؤ%bшDO Cp8χNž5|Sx[Gp׈.liYȶ1Ǩ]+KI$wf5XxR4+hZaʹDDq01T˹gm_"u-ח%.oohj7{y+i]oz(,(((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_]_6'tZu?ࣟϏ?Q~R};uR=hP]v]vV|JR};uR=hP]v]vV|JU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gM%E5Py?5@^@8;FXkco`c?Lju_ |]}{$7Zݝ&)-ݴh(,_=j_[qOi_[OÞ/m,ҼR?W{_IH,0Kda1Og: φWM'l+d*d-.éPVhIQ&VHXSmmFxy44Enm477U,r\xOVXv5Nҵ'_y%-Ej}_ ~Tѿgs.oMs>5FJ66|wbōˤp%Ħ8%S[Rt?hwx_-BPN6v~Ӡ仼{,;ŠgKi%" $G_~{E}⫫(\`'֋n'db c e@\&:mݒxRM{V"Iondi_*\Z魾[_oMFU~;yM+PAAE QP (QEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@8_UcbES 9) esJL:-:QHgǟ( ӝz)z3¶;QGQߡV*Ώ5ߡc(Ebz0ڟ1x/gMw~?Ck~#i"÷7\HŸUQf2(TRzWכg|AgZt=[z&A.m6[6IovIA[x*xwXsxbK$~,\V`RE#WTڱ< L^wßJ<)|K+ jo[q[D*nd=Ơ~i-_QGǞ#u_x7)uHt \XMq+م2ɨNfP k-i/gO9ӡZ;X_ͥ4σ}-cepY /_?joF-տx!wj\v .>."hFU6H_~-*8ʈ q!BTa7B>| [MGЏZ>|pjf(;D`xQp7s/Nj0M-o);Y7{++_M^Ƶ}#mg #*xOiZ(F=WP⻖čE 61ydjRɍJg_T[N>?ՖxjMZźEkRpIɼBWIxsſ<}WSW/6gvA%0KQþ7ǿ;_M |-֤Q~/ ^I.t="X E4yďq,lK7hGs4ѹB^ݻMKvQQQ)I7%ytK mۼAU;O[]CL}Rm{Z6,]_UYX Yh wM'GZAX\jW6*%$Q6(\׈?c_ </i|Ağ -eu_[MҴ(giw*ʮ>||v_=oB׌)$}":tbT@drP q)J>+)=7OTW3ub]s-W=-ɻ-W<:M}5= ^( 6}3;@bܒcDž,w><|7 '/~+mB kRy-0K5Էi1UVfT]%Xg?- ~ީ[ x)=";?naʁ[YmCa%wiS~-OZz|]/-.9 ht-`֐K$$Us RcFwi-{l#`XhK0N>8井xSA5+ 6S+}FєA%[ĐQT_*A|=?(_ZxO<]6Xm F-VMI 4]@VB1?=f^~a:>=^Y"$R9p ,28v)btcV~'I{yy|A]X&),NXLVz2bZNFUuʕ }ի+[Ez9]C4TR[˳kn-= _H-U:o1i/ ښa3f!FTwZ=@?]Xz~igcsj [$7D r!f"I6pgZ_4;W6!,6Euy湙n4&ŋi<;44h~ w1ytm%P/A %S*1PdkN[[YoinQk'x ^Z߉_BhZt[kX;$ڎTKW-,R$hX>eIxBՖB4n8o #FInIaHHѕ_p;& rw^K;Mia["ޝAf 1:z;heyVCoyev17|+ ^"̬~^W+hv駋ZrT&MYmWs_e~(3(/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>p;_ΧsR'?q_UclL:-:QHgǟ( ӝzz?/;QEQV*}WemOxG³b3O%C hwQ&iĽHa43hU{?|VSMR{Ņ&bCTO!UdYKf_>y^oټol} gM%2uIX9XԱ؀3$M ?~ |GxWOw5k)ΪĖV7K+f8UI_kSxK_|Cw ._^ _U &6E&amͻ-d|- O=O|5$ %ϢrM]G~Ho<3]ώSX{? muW.d夒TBBR +Jױ4(BJ~kFW_=wzye/?7ŭ-c:My^8%:]vv62y.ٯk>//`Ҭ% #Eqk>a r2Br=>'3#-_Fܮwum/#8+`7#ȼ1/>o_i݉LJ"jգ)GmxxUOǒн8{gukiŜ(<){J7Zﮛ4;kyӴY\Kwo}oRKG / uJO;ي¶w|%cgiM ^graܝ6x@9ȮPys} _SY-OT_ j-w4[XD+3ಶ=Eݠx]bᗊO ^ƖOj}m"ݜ0au*nix+euֶyU%a]V쭣*֪>Rd&Lmu tɊp@;ヹx!{xj u8.uݴ!Cu 3cj'{o|\|{/z+?#5!ii9g|Z𖟮[[|4ǯO^M 6Td`35W 811sMZN?++npb ZJnkM;N|iuAj1k#IuAy9cV-' GF>fu٧SìѵXN'ErM}7d(K&9uo\Oy5^M)ndy$ϔȯ$rHJ@C5ƢO+G{ۛI]7ʯo-ʛnԯ;o]-fU{COE6Z[\"T/4)uhUr2N"#x9 nT.uVmU+MbY@~1.jU[K>]^>aRO۽Nkk]+gkQ_Q@ekɚ|[/XFm3O%C5hEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPͺo6G(3O⿢KJL:-:QHgǟ( ӝzz?/;QCƼt??_5Ƽ!T>QXf6z<#Lg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@6_U&؟akC><D+'I&L:-;QHgǟ( ӝzz?/;Q?zhc}W~n|+y,?H,j~/³b3O%C hwQ&iĽHa4Ch(((((((((/_LzZ5kɚ|[/XF ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>kտ|M?â|y9WMVcbEg 9) es^/Ge؟ 苞Uc_ JQ8޲6z<"y+;(4Ib^0֍g~f ?KO=6((((((((((2>-ؗ գY߶ſ!h(((((((((((((((((((((((((((((([JL:-;?QHgǟ( ӝDڷ6G(3Oz~u(Lc&;{|N*7̯#0oB#qWemO8CPأL'z?Z5ɚ|$/Gk>( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((vO_tZvࣟϏ?Q( ( ( ( ( ( ( ( ( (<4b^3Vg~fK?jѠ((((((((((((((((((((((((((((((R~.JZE 7) er[V%֟bkB~<D+׭K9s|w3+?~'~o)T~º3 FQ8ʲ6z\#Lg|aY߱GO!k;(4Ib^0ך}QEQEQEQEQEQEQEQEQEQEy&ioĽcHf>-ؗ գ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@,x"(3OL:-=Q( ӕ~|l.,>4GH>+\C(~3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1tW}7 lC!o@Ex>3{[ό:|1kɚ|[/XF⏂,Zg/ j^8wm2I74qOD셵VP\JdQE`it| wtѩ8;u,q>eW7jYA9@V7#>'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3'L\m 1sɴEc3%bcZD 5) er^)z3ܷFGg/Z/_ê83|=6>XTL,j~wc?B(4@(((((((((((((((((((((((((((((((((((((((((7/8ϊL:%??QD+nf +_0F~'~W׃tv91U2qEqʟE*tP+>((((((((((((((((((((((((((((((\V0+)d~ٲzѪR5^,fGl޷5^MhZvtAG6t R4ѠX,UY7o뾈i\dO6O[/S:Lj|'/xDtmQުvV䵭[g|sbWLxNկtO\5x}nsklS,nRWK hč$rZjO_6o{^>߯odzl޷4fU|U|0^-{PӴm^Uaj2HU3Tb@_ɑEhѱ׵V_K6*e8 ̀֫UWB?տ6O[?dOim㈼/xwVu+;?ٱ.ݣY. _1@+yn60I/}vv]އfGl޷5 iZ 26RY$@#5Vմ%;X͓?Ə?ojr^ͥO jtRi^ıbŁp*ܘ- rKs͓?Ʋ<{3ᇂOkڅhwwrQBY *xgL/Gk(_`âWx9\W{o@k(ԟ񰟏D+׭Kyt[(Lv!\|J3_w.<91#ycbQ*3'?𣷃SneQ^YEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPWB?տ F]f>[V//4tvQ;b1,?I!#`ckio^#MZx_LV \u9}I@X)s][^;Пeo/iHGMieV#OZ*?~|M_|8 Ǻ^ksm*R.PKyc`ݕ@|YY?>,?&M.?#?W?iMk>)߅|+c"oGk0Ao}Zkuak=Lf1KU0X[ڌ?>,?kVi?vT~zWO@jS}-m~XS7OIYxC~;)>hx>[_Q&}(a(eY$Jh<[ ƺYiW^ X+Zj8ZlP+4@|YY?>,?m%o䭡EnO(_kVi?vo[?>7!ikֆ;>**&WxyRl}IEPWJ9>+_0h_Q|xD+߅4+_0h_Q O⽚~wkc3׷ƾCyC}E~KxG >|G״_ [ϯySb8WWwFTe`kпg?esq_ uUhF Ҳx<ξUSU՞ڟ4WX hW].| )xO=~G W~_xĿ#巋gB_cfƧWjl>&xkIec[5: #:~m37?+o.K?feo[5T: #FO~ o[dЙV??#S?К+U|M+aO uF={n|Q+`S¿] -_?xT: #rO~ VžO?fqX͏}O?DhΓٻq#?)o.>-Y>&Bc?#}O?CΣO٨M+sQO TĿH34Gl~?;,xV/?f9'?Gl~\*_5E~q`xW߳͏/Ƨ_W<~5"xX'AY-Yl~>2@u|{;,]4y%oo.\_1E~sy<,]4z_gGd~\_5E~q?gĿ -ğ -?*W~_6g/챟 x[ kO_̏ _ E~}̟ |/dk.l~5??WӜ~5K hV?Wj_E~~٧xVO͙|K+Qo t[O_E~z7gx/-o.O_̏OS?+O_Gf$mo.ҧU_tWğ?-o._N~?-o.\_E~Qd_k?exDO_1x}k ,2gfO诙ުv_E<15coX *_2 +pC0UNP?+w8#[r?7O;]nhnTkAJQ;$W_ҰA?/췟 WYeN?y2W~Q_w: Ol8ɓ/h?9P~H}G0u>-àA.|E,T'|y6,N?-. W_]??#l\&ԄKe?+.–3g?B˗? S~_Xug@?qa"?yrql#ߌ@[k kS 5{ e%q_,~%-Zx [|;+7P-8pQO8??a~)x-V\aW34}VN:rLx{_ZRN^'NUnit-2.6.0.12051/doc/projectEditor.html0000664000175000017500000002305411720512704017432 0ustar jtaylorjtaylor NUnit - ProjectEditor

Project Editor

Beginning with NUnit 2.6, the Project Editor is a separate program, which may be executed directly or run through the Project | Edit dropdown menu of the NUnit GUI. The editor now provides two main views of the project: a property-oriented view based on the Project Editor that was built into earlier versions of the NUnit GUI and an xml view, which allows direct editing of the .nunit file.

Property View

This view consists of a common area and two tabs, as seen in the image below.

Common Area

The common area of the Project Editor contains information pertaining to the project as a whole. Information that applies to a particular configuration is displayed in the General and Assemblies tabs.

Project Path

This label shows the full path to the project file. In the case of a wrapper project, the path is set to the same directory as the assembly that was initially opened.

Application Base

This TextBox allows the user to change the project AppBase, which defaults to the directory of the project file. The button to the right of the TextBox allows the user to browse and select a directory.

Process Model

This dropdown list allows you to specify how operating system processes are used in loading and running the tests in this project. Four settings are defined:

  • The Default setting refers to the option selected by the user on the Assembly Isolation page of the NUnit Settings Dialog.
  • Single means that tests are run in a test domain in the same process as NUnit. This is the way previous versions of NUnit ran tests.
  • Separate means that all the tests are run in a separate process that NUnit creates.
  • Multiple means that NUnit will create a separate process for each test assembly in the project and run its tests there.

Domain Usage

This dropdown list allows you to specify how tests are loaded into AppDomains by NUnit. Three settings are defined:

  • The Default setting refers to the option selected by the user on the Assembly Isolation page of the NUnit Settings Dialog.
  • Single means that all tests will run in a single test domain created by NUnit. This was the way versions of NUnit prior to 2.4 ran tests.
  • Multiple means that each test assembly is loaded into a separate AppDomain. This setting is not available when Multiple processes are selected in the Process Model dropown.

Configuration

This dropdown list allows you to select the particular configuration within a project that is displayed in the bottom part of the dialog.

Edit Configs...

This button opens the Configuration Editor, which allows you to add, delete or rename configs and set the active configuration.

General Tab

The General tab allows setting a number of options pertaining to the selected configuration, all of which will be stored in the NUnit project file as attributes of the xml node.

Runtime

This dropdown allows you to select a particular runtime framework to be used for loading and running tests under the current configuration. Currently, only Microsoft .NET and Mono are supported. If Any is selected, the tests will be run under the same runtime that NUnit itself is currently using.

Version

This ComboBox allows you to select the particular version of the runtime framework to be used for loading and running tests under the current configuration. The dropdown list contains entries for

  • Default
  • 1.0
  • 1.1
  • 2.0
  • 4.0

If you select "Default" the assemblies in the project are examined to determine the version that is required. See Runtime Selection for more information on how NUnit selects the version to be used.

In special cases, you may wish to enter a version number that is not listed in the list box. You may specify the version using two, three or four components. The version you provide will be saved as you enter it. Leaving the text box blank is equivalent to selecting "Default."

Note: Running tests under a different runtime or version from the one that NUnit is currently using will force them to run in a separate process.

Note: To conform with normal usage, specifying Mono as the runtime with "1.0" as the version results in use of the Mono 1.0 profile, equating to version 1.1.4322.

ApplicationBase

The ApplicationBase defaults to the directory containing the project file. Beginning with NUnit 2.2.3, it may be set to any location that is desired.

Configuration File Name

The configuration file defaults to the name of the test project with the extension changed from .nunit to .config. The user may substitute another name.

PrivateBinPath

By default, the PrivateBinPath is generated from the assembly locations specified on the Assemblies Tab. For those applications requiring a different level of control, it may be specified manually or using this editor or placed in the configuration file.

Assemblies Tab

The assemblies tab contains the list of assemblies that form part of this test project.

Note: Although the dialog shows the location of assemblies as absolute paths, they are always persisted in the NUnit project file as paths relative to the application base. This allows moving projects as a whole to a different directory location.

Add...

Opens a dialog allowing adding an assembly to this configuration. If Visual Stuio support is enabled, you may also select and add a VS project.

Remove

After confirmation, removes the selected assembly from this configuration.

Assembly Path

This text box displays the full path to the selected assembly. You may edit the contents to change the path to the assembly.

XML View

This view simply displays the XML from the project file, as seen here. You may edit the XML directly.

Note: In this version of NUnit, the XML editor is somewhat primitive. Errors in XML formatting are caught and an error message displayed. However, the values of attributes are not validated as they are in the property-based view and it is possible to create a project file, which NUnit is unable to load. Improvements, including intellisense and better error handling, are planned in future versions of the Project Editor.

NUnit-2.6.0.12051/doc/testcaseProviders.html0000664000175000017500000001174411720512704020331 0ustar jtaylorjtaylor NUnit - TestcaseProviders

TestCaseProviders (NUnit 2.5)

Purpose

TestCaseProviders are used with parameterized tests to provide the specific test cases that will be used in calling the test.

Extension Point

Addins use the host to access this extension point by name:

	IExtensionPoint listeners = host.GetExtensionPoint( "ParameterProviders" );

Interface

The extension object passed to Install must implement either the ITestCaseProvider or the ITestCaseProvider2 interface:

	public interface ITestCaseProvider
	{
		bool HasTestCasesFor( MethodInfo method );
		IEnumerable GetTestCasesFor( MethodInfo method );
	}
	
	public interface ITestCaseProvider2 : ITestCaseProvider
	{
		bool HasTestCasesFor( MethodInfo method, Test suite );
		IEnumerable GetTestCasesFor( MethodInfo method, Test suite );
	}

NUnit will call ITestCaseProvider2 if it is available. Otherwise ITestCaseProvider will be used.

HasTestCasesFor should return true if the provider is able to supply test cases for the specified method. If a provider only wants to be used on certain types of tests, it can examine the provided MethodInfo and the suite for which the test is being constructed and return true or false based on what it finds.

The GetParametersFor method should return a list of individual test cases. Each test case may be expressed as a ParameterSet, as an array of arguments or as a custom object containing one or more of the following properties:

  • Arguments
  • RunState
  • NotRunReason
  • ExpectedExceptionType
  • ExpectedExceptionName
  • ExpectedExceptionMessage
  • Result
  • Description
  • TestName

The ParameterSet class provides all these properties and may be used to avoid the overhead of reflecting on the properties.

Notes:

  1. Most providers will delegate one of the interface implementations to the other if they implement both.
  2. TestCaseProviders that use data from the fixture class should use ITestCaseProvider2 interface so that they are able to access any arguments supplied for constructing the fixture object.
  3. Providers that acquire data from outside the fixture will usually be able to work with ITestCaseProvider alone.
  4. The ITestCaseProvider2 interface was added in the NUnit 2.5.1 release.
NUnit-2.6.0.12051/doc/identityAsserts.html0000664000175000017500000000770111720512704020014 0ustar jtaylorjtaylor NUnit - IdentityAsserts

Identity Asserts

Assert.AreSame and Assert.AreNotSame test whether the same objects are referenced by the two arguments.

Assert.AreSame( object expected, object actual );
Assert.AreSame( object expected, object actual, string message );
Assert.AreSame( object expected, object actual, string message, 
                params object[] parms );

Assert.AreNotSame( object expected, object actual );
Assert.AreNotSame( object expected, object actual, string message );
Assert.AreNotSame( object expected, object actual, string message, 
                params object[] parms );

Assert.Contains is used to test whether an object is contained in an array or list.

Assert.Contains( object anObject, IList collection );
Assert.Contains( object anObject, IList collection, 
                string message );
Assert.Contains( object anObject, IList collection,
                string message, params object[] parms );
NUnit-2.6.0.12051/doc/eventListeners.html0000664000175000017500000000725011720512704017627 0ustar jtaylorjtaylor NUnit - EventListeners

EventListeners (NUnit 2.4.4)

Purpose

EventListeners are able to respond to events that occur in the course of a test run, usually by recording information of some kind. Note that EventListeners called asynchronously with respect to test execution and are not able to affect the actual execution of the test.

Extension Point

Addins use the host to access this extension point by name:

	IExtensionPoint listeners = host.GetExtensionPoint( "EventListeners" );

Interface

The extension object passed to Install must implement the EventListener interface:

	public interface EventListener
	{
		void RunStarted( string name, int testCount );
		void RunFinished( TestResult result );
		void RunFinished( Exception exception );
		void TestStarted(TestName testName);
		void TestFinished(TestResult result);
		void SuiteStarted(TestName testName);
		void SuiteFinished(TestResult result);
		void UnhandledException( Exception exception );
		void TestOutput(TestOutput testOutput);
	}

You must provide all the methods, but the body may be empty for any that you have no need of.

NUnit-2.6.0.12051/doc/requiresMTA.html0000664000175000017500000001261511720512704017017 0ustar jtaylorjtaylor NUnit - RequiresMTA

RequiresMTAAttribute (NUnit 2.5)

The RequiresMTAAttribute is used on a test method, class or assembly to specify that the tests should be run in the multi-threaded apartment. It causes creation of a new thread if the parent test is not already running in the MTA.

Note: On test methods, you may also use the MTAThreadAttribute. Although the runtime only recognizes this attribute on the entrypoint of an executable assembly, many users have expected it to work on tests, so we treat it as a synonym.

Examples


// An MTA thread will be created and used to run
// all the tests in the assembly
[assembly:RequiresMTA]

...

// TestFixture requiring a separate thread
[TestFixture, RequiresMTA]
public class FixtureRequiringMTA
{
  // An MTA thread will be created and all
  // tests in the fixture will run on it
  // unless the containing assembly is
  // already running on an MTA Thread
}

[TestFixture]
public class AnotherFixture
{
  [Test, RequiresMTA]
  public void TestRequiringMTA()
  {
    // A separate thread will be created for this test
	// unless the containing fixture is already running 
	// in the MTA.
  }
}

See also...

NUnit-2.6.0.12051/doc/runtimeSelection.html0000664000175000017500000001206411720512704020145 0ustar jtaylorjtaylor NUnit - RuntimeSelection

Runtime Selection

Before loading an assembly, NUnit must determine what runtime to use. By default (see below for exceptions) the following rules are used:

  1. If the assembly was built for the same runtime under which NUnit is currently running, then that runtime is used.

  2. If the assembly was built for a different runtime version and that version is available, NUnit uses it, running out of process if necessary.

  3. If the assembly was built for a different runtime version, which is not available, then the result depends on whether the build version is earlier or later than the current version. If earlier, the test will be run using the same runtime version under which NUnit is running. If later, then it is not possible to load the test and NUnit gives an error message.

  4. If multiple assemblies are being run at the same time, NUnit first determines the runtime under which each assembly was built. The highest version is then selected for the entire group, and rules 1 through 3 are applied.

Note: For versions 2.5.4 and 2.5.5, automatic runtime selection only works in the Gui runner. Use the /framework option to select the appropriate runtime under the Console runner.

Overriding the Defaults

The default runtime framework may be overridden using command line arguments, menu items in the Gui or settings in an NUnit project file. Provided that the requested framework is available, it will be used. If it isn't available, NUnit will issue an error message.

Note: To use version 1.x runtimes, you must have NUnit's support for those runtimes installed, in addition to the runtime itself. This support is an option of the NUnit installation.

Command Line Options

The /framework option of console runner allows you to specify the framework type and version to be used for a test run. See NUnit-Console Command Line Options for more information.

Gui Menu Selection

The main menu provides File | Select Runtime sub-items allowing you to reload the tests under a specific runtime. See Main Menu for more info.

Project Settings

The NUnit project format supports specification of a specific runtime to be used with a project at the configuration level. See Project Editor for more information.

NUnit-2.6.0.12051/doc/ignore.html0000664000175000017500000002005411720512704016075 0ustar jtaylorjtaylor NUnit - Ignore

IgnoreAttribute (NUnit 2.0)

The ignore attribute is an attribute to not run a test or test fixture for a period of time. The person marks either a Test or a TestFixture with the Ignore Attribute. The running program sees the attribute and does not run the test or tests. The progress bar will turn yellow if a test is not run and the test will be mentioned in the reports that it was not run.

This feature should be used to temporarily not run a test or fixture. This is a better mechanism than commenting out the test or renaming methods, since the tests will be compiled with the rest of the code and there is an indication at run time that a test is not being run. This insures that tests will not be forgotten.

Test Fixture Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [Ignore("Ignore a fixture")]
  public class SuccessTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Ignore("Ignore a fixture")>
  Public Class SuccessTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [Ignore("Ignore a fixture")]
  public __gc class SuccessTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Ignore("Ignore a fixture") */
public class SuccessTests
{
  // ...
}

Test Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [Ignore("Ignore a test")]
    public void IgnoredTest()
    { /* ... */ }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()>
  Public Class SuccessTests
    <Test(), Ignore("Ignore a test")> Public Sub Ignored()
      ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test][Ignore("Ignore a test")] void IgnoredTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Ignore("ignored test") */
  public void IgnoredTest()
  { /* ... */ }
}
NUnit-2.6.0.12051/doc/parameterizedTests.html0000664000175000017500000001552411720512704020477 0ustar jtaylorjtaylor NUnit - ParameterizedTests

Parameterized Tests

NUnit 2.5 supports parameterized tests. Test methods may have parameters and various attributes are available to indicate what arguments should be supplied by NUnit.

Multiple sets of arguments cause the creation of multiple tests. All arguments are created at the point of loading the tests, so the individual test cases are available for display and selection in the Gui, if desired.

Some attributes allow you to specify arguments inline - directly on the attribute - while others use a separate method, property or field to hold the arguments. In addition, some attributes identify complete test cases, including all the necessary arguments, while others only provide data for a single argument. This gives rise to four groups of attributes, as shown in the following table.
Complete Test CasesData for One Argument
Inline TestCaseAttribute RandomAttribute
RangeAttribute
ValuesAttribute
Separate TestCaseSourceAttribute ValueSourceAttribute

In addition, when data is specified for individual arguments, special attributes may be added to the test method itself in order to tell NUnit how to go about combining the arguments. Currently, the following attributes are provided:

Order of Execution

In NUnit 2.5, individual test cases are sorted alphabetically and executed in that order. With NUnit 2.5.1, the individual cases are not sorted, but are executed in the order in which NUnit discovers them. This order does not follow the lexical order of the attributes and will often vary between different compilers or different versions of the CLR.

The following specific rules for ordering apply:

  1. If all arguments are specified in a single TestCaseSource attribute, the ordering of the cases provided will be maintained.
  2. If each parameter has a single Values, ValueSource or Range attribute and the Sequential combining strategy is used - or there is only one argument - the ordering will be maintained.
  3. In all other cases, including using multiple TestCase attributes or a combination of different types of attributes, the ordering of the test cases is undefined.
NUnit-2.6.0.12051/doc/setUICulture.html0000664000175000017500000001474011720512704017214 0ustar jtaylorjtaylor NUnit - SetUICulture

SetUICultureAttribute (NUnit 2.5.2)

The SetUICulture attribute is used to set the current UI Culture for the duration of a test. It may be specified at the level of a test or a fixture. The UI culture remains set until the test or fixture completes and is then reset to its original value. If you wish to use the current culture setting to decide whether to run a test, use the Culture attribute instead of this one.

Only one culture may be specified. Running a test under multiple cultures is a planned future enhancement. At this time, you can achieve the same result by factoring out your test code into a private method that is called by each individual test method.

Examples:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [SetUICulture("fr-FR")]
  public class FrenchCultureTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), SetUICulture("fr-FR")>
  Public Class FrenchCultureTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [SetUICulture("fr-FR")]
  public __gc class FrenchCultureTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.SetUICulture("fr-FR") */
public class FrenchCultureTests
{
  // ...
}

See also...

NUnit-2.6.0.12051/doc/license.html0000664000175000017500000000746711720512704016251 0ustar jtaylorjtaylor NUnit - License

NUnit License

Copyright © 2002-2012 Charlie Poole
Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
Copyright © 2000-2002 Philip A. Craig

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required.

    Portions Copyright © 2002-2009 Charlie Poole or Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig

  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

  3. This notice may not be removed or altered from any source distribution.

License Note

This license is based on the open source zlib/libpng license. The idea was to keep the license as simple as possible to encourage use of NUnit in free and commercial applications and libraries, but to keep the source code together and to give credit to the NUnit contributors for their efforts. While this license allows shipping NUnit in source and binary form, if shipping a NUnit variant is the sole purpose of your product, please let us know.

NUnit-2.6.0.12051/doc/constraintModel.html0000664000175000017500000001617311720512704017766 0ustar jtaylorjtaylor NUnit - ConstraintModel

Constraint-Based Assert Model (NUnit 2.4)

The constraint-based Assert model uses a single method of the Assert class for all assertions. The logic necessary to carry out each assertion is embedded in the constraint object passed as the second parameter to that method.

Here's a very simple assert using the constraint model:

      Assert.That( myString, Is.EqualTo("Hello") );

The second argument in this assertion uses one of NUnit's syntax helpers to create an EqualConstraint. The same assertion could also be made in this form:

      Assert.That( myString, new EqualConstraint("Hello") );

Using this model, all assertions are made using one of the forms of the Assert.That() method, which has a number of overloads...

Assert.That( object actual, IResolveConstraint constraint )
Assert.That( object actual, IResolveConstraint constraint, 
             string message )
Assert.That( object actual, IResolveConstraint constraint,
             string message, object[] parms )
			 
Assert.That( ActualValueDelegate del, IResolveConstraint constraint )
Assert.That( ActualValueDelegate del, IResolveConstraint constraint, 
             string message )
Assert.That( ActualValueDelegate del, IResolveConstraint constraint,
             string message, object[] parms )
			 
Assert.That( ref T actual, IResolveConstraint constraint )
Assert.That( ref T actual, IResolveConstraint constraint, 
             string message )
Assert.That( ref T actual, IResolveConstraint constraint,
             string message, object[] parms )
			 
Assert.That( bool condition );
Assert.That( bool condition, string message );
Assert.That( bool condition, string message, object[] parms );

Assert.That( TestDelegate del, IResolveConstraint constraint );

If you derive your test fixture class from AssertionHelper, the Expect() method may be used in place of Assert.That()...

Expect( object actual, IResolveConstraint constraint )
Expect( object actual, IResolveConstraint constraint, 
             string message )
Expect( object actual, IResolveConstraint constraint, 
             string message, object[] parms )
			 
Expect( ActualValueDelegate del, IResolveConstraint constraint )
Expect( ActualValueDelegate del, IResolveConstraint constraint, 
             string message )
Expect( ActualValueDelegate del, IResolveConstraint constraint,
             string message, object[] parms )
			 
Expect( ref T actual, IResolveConstraint constraint )
Expect( ref T actual, IResolveConstraint constraint, 
             string message )
Expect( ref T actual, IResolveConstraint constraint,
             string message, object[] parms )
			 
Expect( bool condition );
Expect( bool condition, string message );
Expect( bool condition, string message, object[] parms );

Expect( TestDelegate del, IResolveConstraint constraint );

The overloads that take a bool work exactly like Assert.IsTrue.

For overloads taking a constraint, the argument must be a object implementing the IConstraint interface, which supports performing a test on an actual value and generating appropriate messages. This interface is described in more detail under Custom Constraints.

NUnit provides a number of constraint classes similar to the EqualConstraint used in the example above. Generally, these classes may be used directly or through a syntax helper. Test fixture classes inheriting from AssertionHelper are able to use shorter forms. The valid forms are described on the pages related to each constraint. Note that the menu items listed to the right generally reflect the names of the syntax helpers.

See also: the classic model of assertions.

NUnit-2.6.0.12051/doc/setup.html0000664000175000017500000001754411720512704015764 0ustar jtaylorjtaylor NUnit - Setup

SetUpAttribute (NUnit 2.0 / 2.5)

This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.

Before NUnit 2.5, a TestFixture could have only one SetUp method and it was required to be an instance method.

Beginning with NUnit 2.5, SetUp methods may be either static or instance methods and you may define more than one of them in a fixture. Normally, multiple SetUp methods are only defined at different levels of an inheritance hierarchy, as explained below.

If a SetUp method fails or throws an exception, the test is not executed and a failure or error is reported.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [SetUp] public void Init()
    { /* ... */ }

    [TearDown] public void Cleanup()
    { /* ... */ }

    [Test] public void Add()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <SetUp()> Public Sub Init()
    ' ...
    End Sub

    <TearDown()> Public Sub Cleanup()
    ' ...
    End Sub

    <Test()> Public Sub Add()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [SetUp] void Init();
    [TearDown] void Cleanup();

    [Test] void Add();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.SetUp() */
  public void Init()
  { /* ... */ }

  /** @attribute NUnit.Framework.TearDown() */
  public void Cleanup()
  { /* ... */ }

  /** @attribute NUnit.Framework.Test() */
  public void Add()
  { /* ... */ }
}

Inheritance

The SetUp attribute is inherited from any base class. Therefore, if a base class has defined a SetUp method, that method will be called before each test method in the derived class.

Before NUnit 2.5, you were permitted only one SetUp method. If you wanted to have some SetUp functionality in the base class and add more in the derived class you needed to call the base class method yourself.

With NUnit 2.5, you can achieve the same result by defining a SetUp method in the base class and another in the derived class. NUnit will call base class SetUp methods before those in the derived classes.

Note: Although it is possible to define multiple SetUp methods in the same class, you should rarely do so. Unlike methods defined in separate classes in the inheritance hierarchy, the order in which they are executed is not guaranteed.

See also...

NUnit-2.6.0.12051/doc/nunit-agent.html0000664000175000017500000000744311720512704017052 0ustar jtaylorjtaylor NUnit - Nunit-agent

NUnit-Agent

The nunit-agent.exe program is used by other runners when the tests are being run in a separate process. It is not intended for direct execution by users.

NUnit runs tests in a separate process in several situations:

  1. When the program needs to be run under a different framework or version from the one being used by NUnit itself.
  2. When the user requests process-level isolation through the command line or the NUnit settings.

Debugging

When debugging tests that are run in a separate process, it is not possible to do so by simply running the console or gui runner under the debugger. Rather, it is necessary to attach the debugger to the nunit-agent process after the tests have been loaded.

When running under the Gui, NUnit will continue to use the same process to reload tests so that it is not normally necessary to re-attach to a new process. However, if the settings are changed in a way that requires a differnt process - for example, by changing the version of the runtime that is being used - the old process will be terminated and a new one created. In that case, it's necessary to re-attach to the new process.

NUnit-2.6.0.12051/doc/values.html0000664000175000017500000001227411720512704016116 0ustar jtaylorjtaylor NUnit - Values

ValuesAttribute (NUnit 2.5)

The ValuesAttribute is used to specify a set of values to be provided for an individual parameter of a parameterized test method. Since NUnit combines the data provided for each parameter into a set of test cases, data must be provided for all parameters if it is provided for any of them.

By default, NUnit creates test cases from all possible combinations of the datapoints provided on parameters - the combinatorial approach. This default may be modified by use of specific attributes on the test method itself.

Example

The following test will be executed six times, as follows:

	MyTest(1, "A")
	MyTest(1, "B")
	MyTest(2, "A")
	MyTest(2, "B")
	MyTest(3, "A")
	MyTest(3, "B")
[Test]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    ...
}

See also...

NUnit-2.6.0.12051/doc/conditionConstraints.html0000664000175000017500000001401111720512704021024 0ustar jtaylorjtaylor NUnit - ConditionConstraints

Condition Constraints (NUnit 2.4)

ConditionConstraints test a specific condition and are named for the condition they test. They verify that the actual value satisfies the condition. The following condition helpers are provided.

NullConstraint

Action

Tests that a value is Null.

Constructor

NullConstraint()

Syntax

Is.Null

Examples of Use

Assert.That( anObject, Is.Null );
Assert.That( anObject, Is.Not.Null );

TrueConstraint

Action

Tests that a value is true.

Constructor

TrueConstraint()

Syntax

Is.True

Example of Use

Assert.That( condition, Is.True );

FalseConstraint

Action

Tests that a value is false.

Constructor

FalseConstraint()

Syntax

Is.False

Example of Use

Assert.That( condition, Is.False );

NaNConstraint

Action

Tests that a value is floating-point NaN.

Constructor

NaNConstraint()

Syntax

Is.NaN

Examples of Use

Assert.That( aDouble, Is.NaN );
Assert.That( aDouble, Is.Not.NaN );

EmptyConstraint

Action

Tests that an object is an empty string, directory or collection.

Constructor

EmptyConstraint()

Syntax

Is.Empty

Examples of Use

Assert.That( aString, Is.Empty );
Assert.Thst( dirInfo, Is.Empty );
Assert.That( collection, Is.Empty );

Notes

  1. EmptyConstraint creates and uses either an EmptyStringConstraint, EmptyDirectoryConstraint or EmptyCollectionConstraint depending on the argument tested.
  2. A DirectoryInfo argument is required in order to test for an empty directory. To test whether a string represents a directory path, you must first construct a DirectoryInfo.

UniqueItemsConstraint

Action

Tests that an array, collection or other IEnumerable is composed of unique items with no duplicates.

Constructor

UniqueItemsConstraint()

Syntax

Is.Unique

Example of Use

Assert.That( collection, Is.Unique );
NUnit-2.6.0.12051/doc/fileAssert.html0000664000175000017500000001127311720512704016716 0ustar jtaylorjtaylor NUnit - FileAssert

FileAssert (NUnit 2.4)

The FileAssert class provides methods for comparing two files, which may be provided as Streams, as FileInfos or as strings giving the path to each file.

FileAssert.AreEqual( Stream expected, Stream actual );
FileAssert.AreEqual( Stream expected, Stream actual, 
                string message );
FileAssert.AreEqual( Stream expected, Stream actual,
                string message, params object[] args );

FileAssert.AreEqual( FileInfo expected, FileInfo actual );
FileAssert.AreEqual( FileInfo expected, FileInfo actual, 
                string message );
FileAssert.AreEqual( FileInfo expected, FileInfo actual,
                string message, params object[] args );

FileAssert.AreEqual( string expected, string actual );
FileAssert.AreEqual( string expected, string actual, 
                string message );
FileAssert.AreEqual( string expected, string actual,
                string message, params object[] args );

FileAssert.AreNotEqual( Stream expected, Stream actual );
FileAssert.AreNotEqual( Stream expected, Stream actual, 
                string message );
FileAssert.AreNotEqual( Stream expected, Stream actual,
                string message, params object[] args );

FileAssert.AreNotEqual( FileInfo expected, FileInfo actual );
FileAssert.AreNotEqual( FileInfo expected, FileInfo actual, 
                string message );
FileAssert.AreNotEqual( FileInfo expected, FileInfo actual,
                string message, params object[] args );

FileAssert.AreNotEqual( string expected, string actual );
FileAssert.AreNotEqual( string expected, string actual, 
                string message );
FileAssert.AreNotEqual( string expected, string actual,
                string message, params object[] args );
NUnit-2.6.0.12051/doc/stringConstraints.html0000664000175000017500000001711611720512704020355 0ustar jtaylorjtaylor NUnit - StringConstraints

String Constraints (NUnit 2.4)

String constraints perform tests that are specific to strings. Attempting to test a non-string value with a string constraint is an error and gives an exception.

The Text prefix is deprecated beginning with NUnit 2.5.1 and will be removed in NUnit 3.0.

SubstringConstraint

Action

Tests for a substring.

Constructor

SubstringConstraint(string expected)

Syntax

Is.StringContaining(string expected)
Contains.Substring(string expected)
ContainsSubstring(string expected)
Contains(string expected)
[Obsolete] Text.Contains(string expected)
[Obsolete] Text.DoesNotContain(string expected)

Modifiers

...IgnoreCase

Examples of Use

string phrase = "Make your tests fail before passing!"

Assert.That( phrase, Is.StringContaining( "tests fail" ) );
Assert.That( phrase, Contains.Substring( "tests fail" ) );
Assert.That( phrase, Is.Not.StringContaining( "tests pass" ) );
Assert.That( phrase, Is.StringContaining( "make" ).IgnoreCase );
Expect (phrase, Contains.Substring( "make" ).IgnoreCase );

Notes

  1. ContainsSubstring and Contains may appear only in the body of a constraint expression or when the inherited syntax is used.
  2. Contains is not actually a string constraint but is converted to one when a string is being tested.

StartsWithConstraint

Action

Tests for an initial string.

Constructor

StartsWithConstraint(string expected)

Syntax

Is.StringStarting(string expected)
StartsWith(string expected)
[Obsolete] Text.StartsWith(string expected)
[Obsolete] Text.DoesNotStartWith(string expected)

Modifiers

...IgnoreCase

Examples of Use

string phrase = "Make your tests fail before passing!"

Assert.That( phrase, Is.StringStarting( "Make" ) );
Assert.That( phrase, Is.Not.StringStarting( "Break" ) );
Assert.That( phrase, Has.Length.GreaterThan(10)
                .And.Not.StartsWith( "Break" ) );
Expect( phrase, StartsWith( "Make" ) );

Notes

  1. StartsWith may appear only in the body of a constraint expression or when the inherited syntax is used.

EndsWithConstraint

Action

Tests for an ending string.

Constructor

EndsWithConstraint(string expected)

Syntax

Is.StringEnding(string expected)
EndsWith(string expected)
[Obsolete] Text.EndsWith(string expected)
[Obsolete] Text.DoesNotEndWith(string expected)

Modifiers

...IgnoreCase

Examples of Use

string phrase = "Make your tests fail before passing!"

Assert.That( phrase, Is.StringEnding( "!" ) );
Assert.That( phrase, Is.StringEnding( "PASSING!" ).IgnoreCase );
Expect( phrase, EndsWith( "!" ) );

Notes

  1. EndsWith may appear only in the body of a constraint expression or when the inherited syntax is used.

RegexConstraint

Action

Tests that a pattern is matched.

Constructor

RegexConstraint(string pattern)

Syntax

Is.StringMatching(string pattern)
Matches(string pattern)
[Obsolete] Text.Matches(string pattern)
[Obsolete] Text.DoesNotMatch(string pattern)

Modifiers

...IgnoreCase

Examples of Use

string phrase = "Make your tests fail before passing!"

Assert.That( phrase, Is.StringMatching( "Make.*tests.*pass" ) );
Assert.That( phrase, Is.Not.StringMatching( "your.*passing.*tests" ) );
Assert.That( phrase, Has.Length.GreaterThan(10)
                .And.Not.Matches( "your.*passing.*tests" ) );
Expect( phrase, Matches( "Make.*pass" ) );

Notes

  1. Matches may appear only in the body of a constraint expression or when the inherited syntax is used.
NUnit-2.6.0.12051/doc/testProperties.html0000664000175000017500000000673511720512704017660 0ustar jtaylorjtaylor NUnit - TestProperties

Test Properties Dialog

The test properties dialog is displayed using either the View | Properties menu item on the main menu or the Properties item on the context menu. It shows information about the test and if it has been run about the results. The dialog contains a pin button in the upper right corner, which causes it to remain open as the user clicks on different tests.

NUnit-2.6.0.12051/doc/compoundConstraints.html0000664000175000017500000001050011720512704020661 0ustar jtaylorjtaylor NUnit - CompoundConstraints

Compound Constraints (NUnit 2.4)

Compound constraints are used to combine other constraints in various ways.
Syntax HelperConstructorOperation
Is.Not...NotConstraint( Constraint )Negates or reverses the effect of a constraint
Is.All...AllItemsConstraint( Constraint )Tests that all members of a collection match the constraint
Constraint & ConstraintAndConstraint( Constraint, Constraint )Tests that both of the constraints are met
Constraint | ConstraintOrConstraint( Constraint, Constraint )Tests that at least one of the constraints is met

Examples of Use

Assert.That( 2 + 2, Is.Not.EqualTo( 5 );
Assert.That( new int[] { 1, 2, 3 }, Is.All.GreaterThan( 0 ) );
Assert.That( 2.3, Is.GreaterThan( 2.0 ) & Is.LessThan( 3.0 ) );
Assert.That( 3, Is.LessThan( 5 ) | Is.GreaterThan( 10 ) ); 

// Using inheritance
Expect( 2 + 2, Not.EqualTo( 5 ) );
Expect( 2.3, GreaterThan( 2.0 ) & LessThan( 3.0 ) );
NUnit-2.6.0.12051/doc/nunit-console.html0000664000175000017500000000774011720512704017416 0ustar jtaylorjtaylor NUnit - Nunit-console

NUnit-Console

The nunit-console.exe program is a text-based runner and can be used when you want to run all your tests and don’t need a red/yellow/green indication of success or failure.

It is useful for automation of tests and integration into other systems. It automatically saves its results in XML format, allowing you to produce reports or otherwise process the results. The following is a screenshot of the console program.

In this example, nunit-console has just run the tests in the mock-assembly.dll that is part of the NUnit distribution. This assembly contains a number of tests, some of which are either ignored or marked explicit. The summary line shows the result of the test run. Click here to see the XML produced for this test run.

The .NET 2.0 version of the nunit-console program is built using /platform:anycpu, which causes it to be jit-compiled to 32-bit code on a 32-bit system and 64-bit code on a 64 bit system. This causes an exception when NUnit is used to test a 32-bit application on a 64-bit system. To avoid this problem, use the nunit-console-x86 program, which is built using /platform:x86, when testing 32-bit code on a 64-bit system.

NUnit-2.6.0.12051/doc/requiredAddin.html0000664000175000017500000001236111720512704017374 0ustar jtaylorjtaylor NUnit - RequiredAddin

RequiredAddinAttribute (NUnit 2.5)

The RequiredAddin attribute is used to indicate that an assembly requires a particular addin in order to function correctly. If that addin is not installed, the entire assembly is marked as non-runnable.

Note: In the Alpha-3 release, this attribute may be applied to classes or methods as well. This is of limited utility, for two reasons:

  1. If the method or class is not recognized as a test, due to the addin being missing, then NUnit will never process it.
  2. If the method or class is handled by some a different addin, that addin may not recognize the attribute.

The attribute will be limited to assemblies only in the next release.

Example

[assembly: RequiredAddin("MyTestFixtureAddin")]
[assembly: RequiredAddin("MyTestAddin")]
[assembly: RequiredAddin("MyDecoratorAddin")]

...

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [MyTestFixture]
  public class MyTests
  {
    [MyTest]
	public void SomeTest()
	{
	  ...
	}
  }
  
  [TestFixture, MyDecorator]
  public class MoreTests
  {
    [Test, MyDecorator]
	public void AnotherTest()
	{
	  ...
	}
  }
}
NUnit-2.6.0.12051/doc/favicon.ico0000664000175000017500000000137611713252032016050 0ustar jtaylorjtaylor ( @wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxwwwwwwwwwwDDGwwHwwwwwwHwwwtHwwwwwwwHwwwHwwwwwwwHwwwDHwwwwwwwHwwxDHwwwwwwwHwwDHwwwwwwwHwwDDHwwwwwwwHwxDOHwwwwwwwHwDHwwwwwwwHwDHHwwwwwwwHxDGHwwwwwwwHDHwwwwwwwHDHwHwwwwwwwDDGwHwwwwwwwxDDwwxHwwwwwwDDGwwDDGwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwpNUnit-2.6.0.12051/doc/testContext.html0000664000175000017500000001077411720512704017146 0ustar jtaylorjtaylor NUnit - TestContext

TestContext (NUnit 2.5.7 / 2.6)

Each NUnit test runs in an execution context, which includes information about the environment as well as the test itself. The TestContext class allows tests to access certain information about the execution context.

This class has been present in NUnit since 2.5.7, but was undocumented until the 2.6 release. Those earlier versions of TestContext are not covered here.

CurrentContext

The context of the currently executing test may be accessed by use of the static property CurrentContext, which gets a reference to the current TestContext. This context is created separately for each test before it begins execution.

All other properties apply to the TestContext instance returned by CurrentContext. Note that the context may not be changed - all properties are read-only.

Test

Gets a representation of the current test, with the following properties:

  • Name - The name of the test
  • FullName - The fully qualified name of the test
  • Properties - An IDictionary of the test properties

Result

Gets a representation of the test result, with the following properties:

  • Status - A TestStatus with possible values
    • Inconclusive
    • Skipped
    • Passed
    • Failed
  • State - A TestState with possible values
    • Inconclusive
    • NotRunnable
    • Skipped
    • Ignored
    • Success
    • Failure
    • Error
    • Cancelled

Notes:

  1. The result of the test may be accessed during setup or test execution, but it only has a useful value at in the TearDown method.
  2. The Status value should be used in preference to State wherever possible, since the latter will not be available in future releases.

TestDirectory

Gets the full path of the directory containing the current test assembly.

WorkDirectory

Gets the full path of the directory to be used for output from this test run. The XML result file and any redirected output files are located under this directory. This is normally the directory that was current when execution of NUnit began but may be changed by use of the /work option of nunit-console.

NUnit-2.6.0.12051/doc/testCaseSource.html0000664000175000017500000003150411720512704017550 0ustar jtaylorjtaylor NUnit - TestCaseSource

TestCaseSourceAttribute (NUnit 2.5)

TestCaseSourceAttribute is used on a parameterized test method to identify the property, method or field that will provide the required arguments. The attribute has two public constructors.

TestCaseSourceAttribute(Type sourceType, string sourceName);
TestCaseSourceAttribute(string sourceName);

If sourceType is specified, it represents the class that provides the test cases. It must have a default constructor.

If sourceType is not specified, the class containing the test method is used. NUnit will construct it using either the default constructor or - if arguments are provided - the appropriate constructor for those arguments.

The sourceName argument represents the name of the source used to provide test cases. It has the following characteristics:

  • It may be a field, property or method.
  • It may be either an instance or a static member.
  • It must return an IEnumerable or a type that implements IEnumerable.
  • The individual items returned by the enumerator must be compatible with the signature of the method on which the attribute appears. The rules for this are described in the next section.

TestCaseSourceAttribute supports one named parameter:

Category
Used to assign one or more categories to every test case returned from this source.

Constructing Test Cases

In constructing tests, NUnit uses each item returned by the enumerator as follows:

  1. If it is an object implementing NUnit.Framework.ITestCaseData, its properties are used to provide the test case. In NUnit 2.5, this is done using reflection to allow compatibility with earlier versions that did not implement ITestCaseData.

    The following public fields or properties are used:

    Arguments
    An object[] representing the arguments to the method
    Categories
    An IList of categories to be applied to the test case.
    Description
    Sets the description property of the test
    ExpectedException
    Specifies a the Type of an exception that should be thrown by this invocation
    ExpectedExceptionName
    Specifies a the FullName of an exception that should be thrown by this invocation
    Ignored
    If true, the test case is ignored.
    IgnoreReason
    Specifies the reason for ignoring this test case. If set to a non-empty string, then the test is ignored.
    Properties
    An IDictionary of properties to be applied to the test case. Note that the values provided must be compatible with PropertiesAttribute. In particular, use of custom types or enums will cause problems.
    Result
    The expected result to be returned from the method, which must have a compatible return type.
    TestName
    Provides a name for the test. If not specified, a name is generated based on the method name and the arguments provided

  2. If the test has a single argument and the returned value matches the type of that argument it is used directly.

  3. If it is an object[], its members are used to provide the arguments for the method, as in this example, which returns arguments from a named static field.

    [Test, TestCaseSource("DivideCases")]
    public void DivideTest(int n, int d, int q)
    {
        Assert.AreEqual( q, n / d );
    }
    
    static object[] DivideCases =
    {
        new object[] { 12, 3, 4 },
        new object[] { 12, 2, 6 },
        new object[] { 12, 4, 3 } 
    };
    
  4. If it is an array of some other type, NUnit can use it provided that the arguments to the method are all of that type. For example, the above code could be modified to make the three nested arrays of type int[].

  5. If anything else is returned, it is used directly as the sole argument to the method. This allows NUnit to give an error message in cases where the method requires a different number arguments or an argument of a different type. This can also eliminate a bit of extra typing by the programmer, as in this example:

    static int[] EvenNumbers = new int[] { 2, 4, 6, 8 };
    
    [Test, TestCaseSource("EvenNumbers")]
    public void TestMethod(int num)
    {
        Assert.IsTrue( num % 2 == 0 );
    }
    

TestCaseData Class

Although any object implementing ITestCaseData may be used to provide extended test case information, NUnit provides the TestCaseData class for this purpose. The following example returns TestCaseData instances from a data source in a separately defined class.

[TestFixture]
public class MyTests
{
  [Test,TestCaseSource(typeof(MyFactoryClass),"TestCases")]
  public int DivideTest(int n, int d)
  {
    return n/d;
  }
	
  ...
}

public class MyFactoryClass
{
  public static IEnumerable TestCases
  {
    get
    {
      yield return new TestCaseData( 12, 3 ).Returns( 4 );
      yield return new TestCaseData( 12, 2 ).Returns( 6 );
      yield return new TestCaseData( 12, 4 ).Returns( 3 );
      yield return new TestCaseData( 0, 0 )
        .Throws(typeof(DivideByZeroException))
        .SetName("DivideByZero")
        .SetDescription("An exception is expected");
    }
  }  
}

This example uses the fluent interface supported by TestCaseData to make the program more readable. The last yield statement above is equivalent to

      TestCaseData data = new TestCaseData(0,0);
      data.ExpectedException = typeof(DivideByZeroException;
      data.TestName = "DivideByZero";
      data.Description = "An exception is expected";
      yield return data;

TestCaseData supports the following properties and methods, which may be appended to an instance in any order.

.Ignore()
Causes the test case to be ignored.
.Ignore(string)
Causes the test case to be ignored with a reason specified.
.MakeExplicit()
Causes the test case to be marked explicit.
.MakeExplicit(string)
Causes the test case to be marked explicit and specifies the reason for doing so.
.Returns
The expected result to be returned from the method, which must have a compatible return type.
.SetCategory(string)
Applies a category to the test
.SetDescription(string)
Sets the description property of the test
.SetName(string)
Provides a name for the test. If not specified, a name is generated based on the method name and the arguments provided
.SetProperty(string, string)
.SetProperty(string, int)
.SetProperty(string, double)
Applies a named property and value to the test
.Throws(Type)
.Throws(string)
Specifies a the Type or FullName of an exception that should be thrown by this invocation

Order of Execution

In NUnit 2.5, individual test cases are sorted alphabetically and executed in that order. With NUnit 2.5.1, the individual cases are not sorted, but are executed in the order in which NUnit discovers them. This order does not follow the lexical order of the attributes and will often vary between different compilers or different versions of the CLR.

As a result, when TestCaseSourceAttribute appears multiple times on a method or when other data-providing attributes are used in combination with TestCaseSourceAttribute, the order of the test cases is undefined.

However, when a single TestCaseSourceAttribute is used by itself, the order of the tests follows exactly the order in which the test cases are returned from the source.

Note on Object Construction

NUnit locates the test cases at the time the tests are loaded, creates instances of each class with non-static sources and builds a list of tests to be executed. Each source object is only created once at this time and is destroyed after all tests are loaded.

If the data source is in the test fixture itself, the object is created using the appropriate constructor for the fixture parameters provided on the TestFixtureAttribute or the default constructor if no parameters were specified. Since this object is destroyed before the tests are run, no communication is possible between these two phases - or between different runs - except through the parameters themselves.

NUnit-2.6.0.12051/doc/customConstraints.html0000664000175000017500000001153011720512704020353 0ustar jtaylorjtaylor NUnit - CustomConstraints

Custom Constraints (NUnit 2.4 / 2.5)

You can implement your own custom constraints by creating a class that inherits from the Constraint abstract class, which supports performing a test on an actual value and generating appropriate messages. The class includes two abstract methods, which you must override and four virtual methods with default implementation that may be overridden as needed:

public abstract class Constraint
{
 	...
    public abstract bool Matches( object actual );
    public virtual bool Matches( ActualValueDelegate del );
    public virtual bool Matches<T>( ref T actual );
    public abstract void WriteDescriptionTo( MessageWriter writer );
    public virtual void WriteMessageTo( MessageWriter writer );
    public virtual void WriteActualValueTo( MessageWriter writer );
	...
}

Your derived class should save the actual argument to Matches in the protected field actual for later use.

The MessageWriter abstract class is implemented in the framework by TextMessageWriter. Examining the source for some of the builtin constraints should give you a good idea of how to use it if you have special formatting requirements for error messages.

Custom Constraint Syntax

Having written a custom constraint class, you can use it directly through its constructor:

Assert.That(myObject, new CustomConstraint());

You may also use it in expressions through NUnit's Matches syntax element:

Assert.That(myObject, Is.Not.Null.And.Matches(new CustomConstraint());

The direct construction approach is not very convenient or easy to read. For its built-in constraints, NUnit includes classes that implement a special constraint syntax, allowing you to write things like...

Assert.That( myArray, Is.All.InRange(1,100) );

Ideally, that's what you would like to do with the custom constraint as well. To accomplish this, two separate steps are required:

  1. Provide a static class patterned after NUnit's Is class, with properties or methods that constuct your custom constructor. If you like, you can even call it Is, provided you place it in your own namespace and avoid any conflicts. This allows you to write things like:
    Assert.That( myObject, Is.Custom(x,y) );
  2. Provide an extension method for NUnit's ConstraintExpression, allowing you to write things like:
    Assert.That( myList, Is.Not.All.Custom(x,y) );
NUnit-2.6.0.12051/doc/directoryAssert.html0000664000175000017500000001617711720512704020013 0ustar jtaylorjtaylor NUnit - DirectoryAssert

DirectoryAssert (NUnit 2.5)

The DirectoryAssert class provides methods for making asserts about file system directories, which may be provided as DirectoryInfos or as strings giving the path to each directory.

DirectoryAssert.AreEqual() and DirectoryAssert.AreNotEqual() compare two directories for equality. Directories are considered equal if they have the same FullName, Attributes, CreationTime and LastAccessTime.

Note: Two different directories containing the same files are not considered to be equal.


DirectoryAssert.AreEqual( DirectoryInfo expected, DirectoryInfo actual );
DirectoryAssert.AreEqual( DirectoryInfo expected, DirectoryInfo actual, 
                string message );
DirectoryAssert.AreEqual( DirectoryInfo expected, DirectoryInfo actual,
                string message, params object[] args );

DirectoryAssert.AreEqual( string expected, string actual );
DirectoryAssert.AreEqual( string expected, string actual, 
                string message );
DirectoryAssert.AreEqual( string expected, string actual,
                string message, params object[] args );

DirectoryAssert.AreNotEqual( DirectoryInfo expected, DirectoryInfo actual );
DirectoryAssert.AreNotEqual( DirectoryInfo expected, DirectoryInfo actual, 
                string message );
DirectoryAssert.AreNotEqual( DirectoryInfo expected, DirectoryInfo actual,
                string message, params object[] args );

DirectoryAssert.AreNotEqual( string expected, string actual );
DirectoryAssert.AreNotEqual( string expected, string actual, 
                string message );
DirectoryAssert.AreNotEqual( string expected, string actual,
                string message, params object[] args );

DirectoryAssert.IsEmpty() and DirectoryAssert.IsNotEmpty() test whether the specified directory is empty.


DirectoryAssert.IsEmpty( DirectoryInfo directory );
DirectoryAssert.IsEmpty( DirectoryInfo directory, string message );
DirectoryAssert.IsEmpty( DirectoryInfo directory,
                string message, params object[] args );

DirectoryAssert.IsEmpty( string directory );
DirectoryAssert.IsEmpty( string directory, string message );
DirectoryAssert.IsEmpty( string directory,
                string message, params object[] args );

DirectoryAssert.IsNotEmpty( DirectoryInfo directory );
DirectoryAssert.IsNotEmpty( DirectoryInfo directory, string message );
DirectoryAssert.IsNotEmpty( DirectoryInfo directory,
                string message, params object[] args );

DirectoryAssert.IsNotEmpty( string directory );
DirectoryAssert.IsNotEmpty( string directory, string message );
DirectoryAssert.IsNotEmpty( string directory,
                string message, params object[] args );

DirectoryAssert.IsWithin() and DirectoryAssert.IsNotWithin() test whether the second directory is a direct or indirect subdirectory of the first directory.


DirectoryAssert.IsWithin( DirectoryInfo expected, DirectoryInfo actual );
DirectoryAssert.IsWithin( DirectoryInfo expected, DirectoryInfo actual,
                string message );
DirectoryAssert.IsWithin( DirectoryInfo expected, DirectoryInfo actual,
                string message, params object[] args );

DirectoryAssert.IsWithin( string expected, string actual );
DirectoryAssert.IsWithin( string expected, string actual,
                string message );
DirectoryAssert.IsWithin( string expected, string actual,
                string message, params object[] args );

DirectoryAssert.IsNotWithin( DirectoryInfo expected, DirectoryInfo actual );
DirectoryAssert.IsNotWithin( DirectoryInfo expected, DirectoryInfo actual,
                string message );
DirectoryAssert.IsNotWithin( DirectoryInfo expected, DirectoryInfo actual,
                string message, params object[] args );

DirectoryAssert.IsNotWithin( string expected, string actual );
DirectoryAssert.IsNotWithin( string expected, string actual,
                string message );
DirectoryAssert.IsNotWithin( string expected, string actual,
                string message, params object[] args );

NUnit-2.6.0.12051/doc/vsTestAdapterLicense.html0000664000175000017500000000637311720512704020716 0ustar jtaylorjtaylor NUnit - VsTestAdapterLicense

License - NUnit Test Adapter for Visual Studio 11

Copyright © 2012 Charlie Poole

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Notice

NUnit 2.6 assemblies distributed with this adapter are subject to the NUnit license.

NUnit-2.6.0.12051/doc/theory.html0000664000175000017500000002047111720512704016127 0ustar jtaylorjtaylor NUnit - Theory

TheoryAttribute (NUnit 2.5)

A Theory is a special type of test, used to verify a general statement about the system under development. Normal tests are example-based. That is, the developer supplies one or more examples of inputs and expected outputs either within the code of the test or - in the case of Parameterized Tests - as arguments to the test method. A theory, on the other hand, makes a general statement that all of its assertions will pass for all arguments satisfying certain assumptions.

Theories are implemented in NUnit as methods within a TestFixture, which are annotated with the TheoryAttribute. Theory methods must always have arguments and therefore appears quite similar to Parameterized Tests at first glance. However, a Theory incorporates additional data sources for its arguments and allows special processing for assumptions about that data. The key difference, though, is that theories make general statements and are more than just a set of examples.

Data for Theories

The primary source of data for a Theory is the Datapoint or Datapoints attribute. NUnit will use any fields of the required types, which are annotated with one of these attributes, to provide data for each parameter of the Theory. NUnit assembles the values for individual arguments combinatorially to provide test cases for the theory.

In addition to the Datapoint and Datapoints attributes, it is possible to use any of the approaches for supplying data that are recognized on normal parameterized tests. We suggest that this capability not be overused, since it runs counter to the distinction between a test based on examples and a theory. However, it may be useful in order to guarantee that a specific test case is included.

For boolean and enum arguments, NUnit can supply the data without any action by the user. All possible values are supplied to the argument. This feature is disabled if the user supplies any values for the argument.

Assumptions

The theory itself is responsible for ensuring that all data supplied meets its assumptions. It does this by use of the Assume.That(...) construct, which works just like Assert.That(...) but does not cause a failure. If the assumption is not satisfied for a particular test case, that case returns an Inconclusive result, rather than a Success or Failure.

The overall result of executing a Theory over a set of test cases is determined as follows:

  • If the assumptions are violated for all test cases, then the Theory itself is marked as a failure.
  • If any Assertion fails, the Theory itself fails.
  • If at least some cases pass the stated assumptions, and there are no assertion failures or exceptions, then the Theory passes.

Since the user does not generally care about inconclusive cases under a theory, they are not normally displayed in the Gui. For situations where they are needed - such as debugging - the context menu for the theory provides an option to display them.

Example:

In the following example, the theory SquareRootDefinition verifies that the implementation of square root satisies the following definition:

"Given a non-negative number, the square root of that number is always non-negative and, when multiplied by itself, gives the original number."

public class SqrtTests
{
    [Datapoints]
    public double[] values = new double[] { 0.0, 1.0, -1.0, 42.0 };

    [Theory]
    public void SquareRootDefinition(double num)
    {
        Assume.That(num >= 0.0);

        double sqrt = Math.Sqrt(num);

        Assert.That(sqrt >= 0.0);
        Assert.That(sqrt * sqrt, Is.EqualTo(num).Within(0.000001));
    }
}

See also...

NUnit-2.6.0.12051/doc/collectionAssert.html0000664000175000017500000001764611720512704020144 0ustar jtaylorjtaylor NUnit - CollectionAssert

CollectionAssert (NUnit 2.4 / 2.5)

The CollectionAssert class provides a number of methods that are useful when examining collections and their contents or for comparing two collections.

The AreEqual overloads succeed if the corresponding elements of the two collections are equal. AreEquivalent tests whether the collection contents are equal, but without regard to order. In both cases, elements are compared using NUnit's default equality comparison.

Beginning with NUnit 2.4.6, these methods may be used on any object that implements IEnumerable. Prior to 2.4.6, only true collections were supported.

CollectionAssert.AllItemsAreInstancesOfType( IEnumerable collection,
          Type expectedType );
CollectionAssert.AllItemsAreInstancesOfType( IEnumerable collection,
          Type expectedType, string message );
CollectionAssert.AllItemsAreInstancesOfType( IEnumerable collection,
          Type expectedType, string message, params object[] args );

CollectionAssert.AllItemsAreNotNull( IEnumerable collection );
CollectionAssert.AllItemsAreNotNull( IEnumerable collection,
          string message );
CollectionAssert.AllItemsAreNotNull( IEnumerable collection,
          string message, params object[] args );

CollectionAssert.AllItemsAreUnique( IEnumerable collection );
CollectionAssert.AllItemsAreUnique( IEnumerable collection,
          string message );
CollectionAssert.AllItemsAreUnique( IEnumerable collection,
          string message, params object[] args );

CollectionAssert.AreEqual( IEnumerable expected, IEnumerable actual );
CollectionAssert.AreEqual( IEnumerable expected, IEnumerable actual,
          string message );
CollectionAssert.AreEqual( IEnumerable expected, IEnumerable actual
          string message, params object[] args );

CollectionAssert.AreEquivalent( IEnumerable expected, IEnumerable actual);
CollectionAssert.AreEquivalent( IEnumerable expected, IEnumerable actual,
          string message );
CollectionAssert.AreEquivalent( IEnumerable expected, IEnumerable actual
          string message, params object[] args );

CollectionAssert.AreNotEqual( IEnumerable expected, IEnumerable actual );
CollectionAssert.AreNotEqual( IEnumerable expected, IEnumerable actual,
          string message );
CollectionAssert.AreNotEqual( IEnumerableon expected, IEnumerable actual
          string message, params object[] args );

CollectionAssert.AreNotEquivalent( IEnumerable expected,
          IEnumerable actual );
CollectionAssert.AreNotEquivalent( IEnumerable expected,
          IEnumerable actual, string message );
CollectionAssert.AreNotEquivalent( IEnumerable expected,
          IEnumerable actual, string message, params object[] args );

CollectionAssert.Contains( IEnumerable expected, object actual );
CollectionAssert.Contains( IEnumerable expected, object actual,
          string message );
CollectionAssert.Contains( IEnumerable expected, object actual
          string message, params object[] args );

CollectionAssert.DoesNotContain( IEnumerable expected, object actual );
CollectionAssert.DoesNotContain( IEnumerable expected, object actual,
          string message );
CollectionAssert.DoesNotContain( IEnumerable expected, object actual
          string message, params object[] args );

CollectionAssert.IsSubsetOf( IEnumerable subset, IEnumerable superset );
CollectionAssert.IsSubsetOf( IEnumerable subset, IEnumerable superset,
          string message );
CollectionAssert.IsSubsetOf( IEnumerable subset, IEnumerable superset,
          string message, params object[] args );

CollectionAssert.IsNotSubsetOf( IEnumerable subset, IEnumerable superset);
CollectionAssert.IsNotSubsetOf( IEnumerable subset, IEnumerable superset,
          string message );
CollectionAssert.IsNotSubsetOf( IEnumerable subset, IEnumerable superset,
          string message, params object[] args );

CollectionAssert.IsEmpty( IEnumerable collection );
CollectionAssert.IsEmpty( IEnumerable collection, string message );
CollectionAssert.IsEmpty( IEnumerable collection, string message,
          params object[] args );

CollectionAssert.IsNotEmpty( IEnumerable collection );
CollectionAssert.IsNotEmpty( IEnumerable collection, string message );
CollectionAssert.IsNotEmpty( IEnumerable collection, string message,
          params object[] args );

The following methods are available beginning with NUnit 2.5

CollectionAssert.IsOrdered( IEnumerable collection );
CollectionAssert.IsOrdered( IEnumerable collection, string message );
CollectionAssert.IsOrdered( IEnumerable collection, string message,
          params object[] args );
		  
CollectionAssert.IsOrdered( IEnumerable collection, IComparer comparer );
CollectionAssert.IsOrdered( IEnumerable collection, IComparer comparer,
          string message );
CollectionAssert.IsOrdered( IEnumerable collection, IComparer comparer,
          string message, params object[] args );
NUnit-2.6.0.12051/doc/settingsDialog.html0000664000175000017500000003567211720512704017606 0ustar jtaylorjtaylor NUnit - SettingsDialog

Settings Dialog

The Settings Dialog is displayed using the Tools | Settings menu item and allows the user to control some aspects of NUnits operation. Beginning with NUnit 2.4.4, a tree-based dialog replaced the older tabbed format.


Gui Settings - General


Gui Display

Full Gui

Displays the complete gui - as in prior versions of NUnit. This includes the test result tabs and the progress bar.

Mini Gui

Switches the display to the mini-gui, which consists of the tree display only.

Recent Files

The Display ... files in list TextBox allows the user to choose the number of entries to display in the recent files list.

Normally, NUnit checks that project files still exist before displaying them in the recent files list. This can cause long delays if the file is on a network connection that is no longer available. Unchecking Check that files exist before listing will avoid this delay, so long as the missing file is not actually selected.

If Load most recent project at startup is checked, the GUI will load the last file opened unless it is run with a specific filename or with the /noload parameter.


Gui Settings - Tree Display


Tree View

The Initial Display list box allows selecting the degree of expansion of the tree when tests are loaded:

Auto selects a setting based on the space available for the tree display.

Expand expands all tests

Collapse collapses all tests

Hide Tests expands all suites except for the fixtures themselves.

NUnit provides four sets of Tree Images, which are used to mark tests in the gui as passing, failing, etc. Use the list box to select the preferred set. A preview of the selected set is displayed.

If Clear results when reloading is checked, an automatic or manual reload will reinitialize all test nodes in the tree (grey display) if it is not checked, result information for tests that do not seem to have changed will be retained.

If Save visual state of each project is checked, NUnit saves the state of the tree and restores it when the project is next opened. The information saved includes which branches of the tree are expanded, the selected node, any checked nodes and any category selection.

If Show Checkboxes is checked, the tree includes checkboxes, which may be used to select multiple tests for running. This setting is also available in the View | Tree menu.

Test Structure

If Automatic Namespace suites is selected, tests will be shown in a hierarchical listing based on namespaces. This is the standard display as used in versions prior to NUnit 2.4.

If Flat list of TestFixtures is selected, tests will be shown as a sequential list of fixtures.


Gui Settings - Test Results


Errors Tab

Check Display Errors and Failures Tab to display the Errors and Failures tab, which shows information about failing tests.

Check Enable Failure ToolTips to display the tip window over the Errors and Failures display and the stack trace. Clear it if you prefer not to see the tip window.

Check Enable Word Wrap to turn on word wrapping in the Errors and Failures display. While you can select this item and the preceding one at the same time, they do not interact well, so you will normally choose one or the other.

Not Run Tab

Check Display Tests Not Run Tab to display the Tests Not Run tab, which shows information about tests that were skipped or ignored.


Gui Settings - Text Output


Select Tab

The Select Tab dropdown list is used to select one of the output tabs, for which settings are to be viewed or changed. It also contains entries that allow you to add a new tab or edit the list of tabs.

The Restore Defaults button is used to restore the default setting, which is a single tab labeled "Text Output." The default tab displays all types of output and includes a label for each test that displays text.

The Title text box is used to modify the title displayed for the selected output tab.

Enabled is checked by default. If you uncheck it, the selected tab will be removed from the tab control. This allows you to temporarily suppress output to a tab without actually removing its definition.

Content

The check boxes and combo boxes enable or disable a particular type of output on the selected output window. For each type, the display captures output produced while your test is running - either by the test itself or by the program you are testing.

Standard Output

When checked, NUnit captures all output written to Console.Out.

Error Output

When checked, NUnit captures all output written to Console.Error.

Trace Output

When checked, NUnit captures all output written to Trace or Debug.

Log Output

Use the combobox to select the output level. When set to any level other than Off, NUnit captures log4net output at or above that level.

Test Case Labels

Select On to precede text in the output window with the name of the test that produced it. Select All to display a label for every test case, even those that produce no output.


Gui Settings - Project Editor


This page determines what editor is opened when you use the Edit... item on the Project menu.

If you select Use NUnit Project Editor, the NUnit project editor is used.

If you select Use Program and supply a valid executable path, the program you specify will be executed with the full path to the NUnit settings file as it's single argument.


Test Loader Settings - Assembly Isolation


Default Process Model

These settings determine NUnit's default use of operating system processes and may be overridden by settings in the NUnit project.

If Run tests directly in the NUnit process is selected, all tests are run in a test domain in the same process as NUnit. This is the way previous versions of NUnit ran tests and is the default setting.

If Run tests in a single separate process is selected, a separate process is used for all tests.

If Run tests in a separate process per Assembly is selected, a separate process is used for each test assembly.

Default Domain Usage

If Use a separate AppDomain per Assembly is selected, each assembly in a multiple-assembly test run will be loaded in a separate AppDomain. This setting is not available when Run tests in a separate process per Assembly is selected above.

If Use a single AppDomain for all tests is selected, all assemblies in a multiple-assembly test run will use the same AppDomain. This was the standard behavior of NUnit prior to version 2.4 and is the default setting.

If Merge tests across assemblies is checked, the display of tests will not be divided across assemblies. If automatic namespace suites are used, they will be merged across all assemblies. This option is only available when tests are run in the same appdomain.


Test Loader Settings - Assembly Reload


Assembly Reload

If Reload before each test run is checked, a reload will occur whenever the run button is pressed whether the assemblies appear to have changed or not.

If Reload when test assembly changes is checked, assemblies are watched for any change and an automatic reload is initiated. This item is disabled on Windows 98 or ME.

If Re-run last tests run is checked, tests are re-run whenever a Reload takes place.


Test Loader Settings - Runtime Selection


This page determines which runtime is used to load tests by default, when no runtime has been specified by the user.

If Select default runtime... is checked, NUnit will examine each test assembly and try to use the runtime for which it was built to load it. If left unchecked, NUnit will use the current runtime to load the assembly.


Test Loader Settings - Advanced


Shadow Copy

NUnit normally uses .Net shadow-copying in order to allow you to edit and recompile assemblies while it is running. Uncheck this box to disable shadow-copy only if you have a particular problem that requires it.

Note: If you are tempted to disable shadow copy in order to access files in the same directory as your assembly, you should be aware that there are alternatives. Consider using the Assembly.Codebase property rather than Assembly.Location.

Principal Policy

Because NUnit access current thread's Principal before running tests, it is not possible to effectively call SetPrincipalPolicy() in a test or in the system being tested.

To remedy this problem, NUnit can callSetPrincipalPolicy() on your behalf. If Set Principal Policy... is checked, NUnit will call it using the PrincipalPolicy type selected in the list when it sets up each test AppDomain


IDE Support Settings - Visual Studio


Visual Studio

If Enable Visual Studio Support is checked, the user will be able to open Visual Studio projects and solutions and add Visual Studio projects to existing test projects.

If Use solution configs... is checked, NUnit will make use of solution configs when loading Visual Studio solutions. If it is unchecked, solution configs are ignored and all project configs are included.

This setting is checked by default. Uncheck it if you want NUnit to load solution files compatibly with version 2.5.


Advanced Settings - Internal Trace


Internal Trace

The Trace Level dropdown controls the level of internal trace output.

Log Directory displays the path of the directory to which all internal trace log files are saved.

NUnit-2.6.0.12051/doc/random.html0000664000175000017500000001261611720512704016077 0ustar jtaylorjtaylor NUnit - Random

RandomAttribute (NUnit 2.5)

The RandomAttribute is used to specify a set of random values to be provided for an individual parameter of a parameterized test method. Since NUnit combines the data provided for each parameter into a set of test cases, data must be provided for all parameters if it is provided for any of them.

By default, NUnit creates test cases from all possible combinations of the datapoints provided on parameters - the combinatorial approach. This default may be modified by use of specific attributes on the test method itself.

RandomAttribute supports the following constructors:

public Random( int count );
public Random( double min, double max, int count );
public Random( int min, int max, int count );

Example

The following test will be executed fifteen times, three times for each value of x, each combined with 5 random doubles from -1.0 to +1.0.

[Test]
public void MyTest(
    [Values(1,2,3)] int x,
    [Random(-1.0, 1.0, 5)] double d)
{
    ...
}

See also...

NUnit-2.6.0.12051/doc/pairwise.html0000664000175000017500000001121111720512704016430 0ustar jtaylorjtaylor NUnit - Pairwise

PairwiseAttribute (NUnit 2.5)

The PairwiseAttribute is used on a test to specify that NUnit should generate test cases in such a way that all possible pairs of values are used. This is a well-known approach for combatting the combinatorial explosion of test cases when more than two features (parameters) are involved.

Note: In the current Alpha release, this attribute is accepted but ignored and data items are combined usin the default combinatorial approach.

See also...

NUnit-2.6.0.12051/doc/writingTests.html0000664000175000017500000000534511720512704017326 0ustar jtaylorjtaylor NUnit - WritingTests

Writing Tests

NUnit tests may be written using any .NET language that supports attributes.

Attributes are used to indicate test classes and methods and to modify their behavior in various ways.

Assertions test an actual value against one or more Constraints and result in either a successful test or a failure.

User code may acquire information about the test and it's environment by use of the Test Context.

NUnit-2.6.0.12051/doc/releaseNotes.html0000664000175000017500000004605311720512704017252 0ustar jtaylorjtaylor NUnit - ReleaseNotes

Release Notes

NUnit 2.6 Final Release - Version 2.6.0.12051 - February 20, 2012

General

  • Support for .NET 1.0 / 1.1 is no longer included in the main distribution for NUnit but is provided as a separate package.
  • NUnit's executables now use config files that allow smoother running of mixed assemblies built for .NET 2.0 under .NET 4.0.
  • When opening Visual Studio formatted solutions, NUnit now uses the solution configuration by default, resulting in changed behavior from previous releases. The Settings Dialog may be used to revert NUnit to the earlier behavior, which ignored solution configurations.
  • NUnit Mocks is now deprecated. All classes are now marked as obsolete. NUnit now uses the NSubstitute mock framework its own tests. A copy of the NSubstitute dll is included in the distribution.
  • NUnit no longer stores settings in the test configuration file, as it did in earlier versions. Specifically, we no longer recognize or support
    • OldStyleTestCases
    • ApartmentState
    • ThreadPriority
    • DefaultLogThreshold
  • Changing the URL to be used for NUnit help through NUnit's config file is no longer supported.

Development

  • NUnit is now built using .NET 3.5 or higher. All NUnit assemblies and most tests target .NET 2.0 but the full set of tests requires 3.5 or greater to execute. The build script selects either .NET 3.5 or .NET 4.0 to perform the build, depending on what is available. A Visual Studio 2008 solution is also provided.
  • NAnt 0.91 release is now used for building.
  • The Windows installer is now built using WiX 3.5, upgraded from 2.0.
  • The TestRunner interface has been modified. Applications using this interface will need to be modified but general users are not effected.

Framework

  • NUnit now supports composable Action Attributes, which allow the test developer to put reusable test actions into attributes and attach these actions to suites, tests, and test cases. The actions can run arbitrary code before and after suites, tests, and test cases execute. It enables the test developer to build smaller reusable actions and to compose them in unique ways for each suite, test, or test case.
  • The following Attributes have changes in NUnit 2.6:
    • TestCaseAttribute now accepts Explicit and Reason named parameters.
    • TestCaseSourceAttribute now accepts a Category named parameter.
    • TestCaseData now supports marking individual test cases as Explicit.
    • EqualConstraint now recognizes and uses IEquatable<T> if it is implemented on either the actual or the expected value. The interface is used in preference to any override of Object.Equals(), so long as the other argument is of Type T. Note that this applies to all equality tests performed by NUnit.
    • PlatformAttribute accepts "Windows8", "Windows2012Server", "Net-3.0", "Net-3.5", "Mono-3.0" and "Mono-3.5" as arguments.
      Note: Since the 3.0 and 3.5 frameworks all use the 2.0 runtime, the semantics of their use is slightly different from other key words. The "3.5" arguments also include "3.0" and "2.0" and the "3.0" arguments include "2.0" in their interpretation.
    • TestFixtureAttribute now accepts a Category named parameter, allowing individual fixture instances to be included in or excluded from a test run.
  • The following additions have been made to the Constraint syntax:
    • User-defined equality comparers specified with the Using syntax element may now be used with collections, arrays and dictionaries. The Using(...) syntactic element may be repeated multiple times in an expression, so long as each comparer applies to a different Type. NUnit will use the appropriate comparer, depending on the Type of the arguments. Among other things, this allows overriding the default NUnit comparison of collections, arrays and dictionaries.
    • Is.Positive may be used as a synonym for Is.GreaterThan(0).
    • Is.Negative may be used as a synonym for Is.LessThan(0).
    • Has.Exactly(n)... may be used in place of Has.Some... in order to allow tests over collections that must be satisfied a specific number of times.
  • When Assert.Throws() fails due to an exception of the wrong Type being thrown, the error message now includes the Message and Stack Trace from the exception.
  • Visual Basic users may now use Assert.ByVal rather than Assert.That() to avoid errors when the first argument is a property with a non-public setter.
  • Documentation is provided for the previously undocumented TestContext. A new property TestContext.WorkDirectory allows tests to access the name of a directory to be used for file output. This directory may be specified by use of the /work option of nunit-console.
  • So-called "old-style" tests, identified by having a name beginning with "Test" are no longer supported in NUnit 2.6.
  • Setting a ThreadPriority for the test runner thread is no longer supported under NUnit 2.6.

Console

  • The following new command-line options are provided:
    • -result is a synonym for -xml, specifying the file to be used for output of the test results in XML form. The -xml option is still recognized but will be removed in a future release.
    • -noresult allows supressing the xml result output entirely.
    • -work is used to specify the directory to be used for output files. Any relative paths specified with the -output, -err or -result options are resolved using this directory as a base.
    • -runlist allows the user to specify a file that contains the names of the tests to be executed rather than listing them directly on the command line.
    • -stoponerror causes execution of the test run to terminate immediately on the first test failure or error.
    • -apartment is used to specify the ApartmentState (STA or MTA) of the test runner thread. Since the default is MTA, the option is only needed to force execution in the Single Threaded Apartment.
  • The .NET 1.1 build of nunit-console no longer supports the -process or -framework option. There is no automatic runtime detection and tests execute under same runtime as the console runner itself. If this functionality is needed when running tests under .NET 1.1, use the standard console runner to execute the tests in a separate process.

Gui

  • The Project Editor is now a separate program, which may be executed directly or run through the Project | Edit dropdown menu of the NUnit GUI. The editor now provides two main views of the project: a property-oriented view based on the Project Editor that was built into earlier versions of the NUnit GUI and an xml view, which allows simple editing of the .nunit file.
  • The Gui now displays invalid tests in red immediately upon load, without waiting for the user to run them. Tests marked with the IgnoreAttribute are displayed in yellow immediately as well.
  • The test reload functionality in the Gui has been rewritten and simplified so that the same logic is used for all cases where the visual state of the tree is to be recovered. Test results are now found even if changes to the assembly have resulted in the assignment of new ids to the tests.
  • A number of new settings are available using the Settings Dialog:
    • The Tree Display page allows the user to select alternate image sets for use in the test tree. Additional user-provided image sets may be added if desired.
    • The Text Output page allows setting the threshold for capture and display of log4net output (previously controlled by the test config file).
    • The Project Editor page allows the user to select whether the NUnit Project Editor or another external program will be used when editing the settings file.
    • The Runtime Selection page allows enabling or disabling automatic detection of the target runtime for each test assembly.
    • The Advanced Loader Settings page now allows specifying the argument to use in calling SetPrincipalPolicy for each test AppDomain.
    • The Visual Studio page now includes a setting that enables or disables the use of solution configs when loading Visual Studio solution files.
    • The Internal Trace page now shows the directory path to which log files will be saved.
  • The location of the settings dialog under the Windows AppData directory has been changed from Roaming to Local. Users will need to reset their preferences in some cases.
  • By default, test Cases under a Theory that fail an assumption are no longer shown in the tree. A context menu item has been added to allow the user to view them.
  • The properties dialog has been redesigned to be more compact and readable.
  • The context menu for the test tree has been simplified.
  • The directory containing the log files may be opened directly from the Gui by use of a new item on the Tools menu.
  • Test summary results are truncated when the window size is too small. The full summary is displayed when hovering over the field.

PNUnit

  • The PNUnit code has been updated using the latest build from the developers at Codice Software and additional examples are provided in the source.

Bug Fixes

  • 498659 Registry entries and shortcuts remain after install
  • 498690 Assert.That() doesn't like properties with scoped setters
  • 602761 nunit-agent hangs after tests complete
  • 605034 Log4net not working with NUnit
  • 625672 NUnit GUI bounces to background on reload
  • 638289 Install uses CURRENT_USER instead of LOCAL_MACHINE for AssemblyFoldersEx
  • 657801 Help URL should not be in config file
  • 676560 Assert.AreEqual does not support IEquatable<T>
  • 691129 Add Category parameter to TestFixture
  • 692180 Script should allow building for net-2.0 under 3.5 or 4.0
  • 697069 Feature request: dynamic location for TestResult.xml
  • 697329 NUnit tries to test disabled projects
  • 701331 TestFixture attributes on base classes are not ignored
  • 702734 Separate packaging of NUnit for .NET 1.1 and 2.0
  • 708173 NUnit's logic for comparing arrays - use Comparer<T[]> if it is provided
  • 709062 "System.ArgumentException : Cannot compare" when the element is a list
  • 711330 Test-free assembly given failure icon in tree display
  • 712156 Tests cannot use AppDomain.SetPrincipalPolicy
  • 712444 nunit-console /run don't execute parameterized test-cases (with commas in test-case name)
  • 719184 Platformdependency in src/ClientUtilities/util/Services/DomainManager.cs:40
  • 726313 Failure in Assembly level Action attribute causes crash
  • 728500 TestDomain should unload the test AppDomain
  • 735851 Add detection of 3.0, 3.5 and 4.0 frameworks to PlatformAttribute
  • 736062 Deadlock when EventListener performs a Trace call + EventPump synchronisation
  • 739039 Add noxml option to console runner
  • 741402 Error running .NET 1.1 console tests
  • 746247 Add AllowPartiallyTrustedCallersAttribute to nunit.framework assembly
  • 747581 Failure in TestFixtureTearDown not reported in console runner
  • 756843 Failing assertion does not show non-linear tolerance mode
  • 761579 Tests using log4net run very slowly
  • 766749 net-2.0\nunit-console-x86.exe.config should have a startup element and also enable loadFromRemoteSources
  • 770471 Assert.IsEmpty does not support IEnumerable
  • 785460 Add Category parameter to TestCaseSourceAttribute
  • 787106 EqualConstraint provides inadequate failure information for IEnumerables
  • 794115 HashSet incorrectly reported
  • 800089 Assert.Throws() hides details of inner AssertionException
  • 806198 nunit console crashes when opening certain projects with common output path
  • 816863 System.NullReferenceException 2.6.0.11089
  • 828739 Run NUnit tests listed in a file
  • 836080 Log Directory shown incorrectly in settings dialog
  • 836360 When size of the Gui window is reduced, test result info may not fit in the field provided
  • 841894 UI won't run tests marked Explicit from the context menu
  • 848713 Feature request: Add switch for console to break on any test case error
  • 878376 Add 'Exactly(n)' to the NUnit constraint syntax
  • 878899 Changing logging level has no effect until NUnit is restarted
  • 878955 ParameterizedTest not in their parent test-suite when FixtureSetup fails in .xml result file
  • 881617 Tests with invalid category attributes should be more visible
  • 881715 Frequent socketexception in nUnit GUI
  • 881958 nunit-console-x86 crashes with socketexception
  • 882137 When no tests are run, higher level suites display as Inconclusive
  • 882192 Ignored test icon should be more prominent
  • 882517 NUnit 2.5.10 doesn't recognize TestFixture if there are only TestCaseSource inside
  • 883271 Reload Tests sometimes "loses" tests
  • 885173 Tests are still executed after cancellation by user
  • 885277 Exception when project calls for a runtime using only 2 digits
  • 885604 Feature request: Explicit named parameter to TestCaseAttribute
  • 887005 NUnit.exe ignores categories when using /run option
  • 890129 DelayedConstraint doesn't appear to poll properties of objects
  • 890384 When font is enlarged, layout of settings pages is incorrect
  • 891237 When font is enlarged, gui Test Result disappears and suite name is truncated
  • 891265 Add /cleanup to nunit-console.exe
  • 891326 Non-runnable and statically ignored tests should disable the Run item on the context menu
  • 892844 Not using Mono 4.0 profile under Windows
  • 892845 "Mono" is not clearly shown in About box or Test Assemblies dialog
  • 892847 Gui offers to load assemblies under a lower CLR version
  • 893919 DelayedConstraint fails polling properties on references which are initially null
  • 893991 When working directory contains # sign, it is truncated
  • 896615 Tests can't be run in existing AppDomain
  • 897289 Is.Empty constraint has unclear failure message
  • 898192 Feature Request: Is.Negative, Is.Positive
  • 898256 IEnumerable for Datapoints doesn't work
  • 898850 NUnit 2.6 beta 2 crashes on assemblies without tests
  • 899178 Wrong failure message for parameterized tests that expect exceptions
  • 902305 Gui should not normally display Inconclusive test cases for a Theory
  • 902343 Gui 'Hide Tests' function no longer works
  • 903078 DomainUsage.None setting crashes nunit-gui
  • 903080 Test tree context menu needs to be simplified
  • 904841 After exiting for timeout the teardown method is not executed
  • 907270 Gui enables run when the assembly specified on the command line is not found
  • 908829 TestCase attribute does not play well with variadic test functions
  • 910189 Eliminate NUnit Configuration Section in config file
  • 910218 NUnit should add a trailing separator to the ApplicationBase
  • 912955 Project files missing in source code package
  • 919876 NUnit.Util.Transform.resources missing from nunit.util.dll
  • 920472 CollectionAssert.IsNotEmpty must dispose Enumerator
  • 922455 Add Support for Windows 8 and Windows 2012 Server to PlatformAttribute
  • 924504 NUnit project files should have an Edit command association with the project editor
  • 928018 Issue with test time print out
  • 930774 Adding or Removing a category in the Gui causes an exception
  • 933800 NUnit will crash when started and dll from previous project doesn't compile

Earlier Releases

NUnit-2.6.0.12051/doc/configEditor.html0000664000175000017500000000731511720512704017233 0ustar jtaylorjtaylor NUnit - ConfigEditor

Configuration Editor

The Configuration Editor is displayed using the Project | Configuration | Edit menu item and supports the following operations:

Remove

Remove the selected configuration. If it was the active config, then the next one in the list is made active.

Rename

Rename the selected configuration.

Add

Add a new configuration. The Add Configuration dialog allows specifying an existing configuration to use as a template.

Make Active

Makes the selected configuration active.

Close

Exits the configuration editor

NUnit-2.6.0.12051/doc/range.html0000664000175000017500000001315611720512704015713 0ustar jtaylorjtaylor NUnit - Range

RangeAttribute (NUnit 2.5)

The RangeAttribute is used to specify a range of values to be provided for an individual parameter of a parameterized test method. Since NUnit combines the data provided for each parameter into a set of test cases, data must be provided for all parameters if it is provided for any of them.

By default, NUnit creates test cases from all possible combinations of the datapoints provided on parameters - the combinatorial approach. This default may be modified by use of specific attributes on the test method itself.

RangeAttribute supports the following constructors:

public RangeAttribute( int from, int to );
public RangeAttribute( int from, int to, int step );
public RangeAttribute( long from, long to, long step );
public RangeAttribute( float from, float to, float step );
public RangeAttribute( double from, double to, double step );

Example

The following test will be executed nine times, as follows:

	MyTest(1, 0.2)
	MyTest(1, 0.4)
	MyTest(1, 0.6)
	MyTest(2, 0.2)
	MyTest(2, 0.4)
	MyTest(2, 0.6)
	MyTest(3, 0.2)
	MyTest(3, 0.4)
	MyTest(3, 0.6)
[Test]
public void MyTest(
    [Values(1,2,3) int x,
    [Range(0.2,0.6,0.2] double d)
{
    ...
}

See also...

NUnit-2.6.0.12051/doc/contextMenu.html0000664000175000017500000000777711720512704017144 0ustar jtaylorjtaylor NUnit - ContextMenu

Context Menu

The context menu is displayed when one of the tree nodes is right-clicked.

Run

Runs the selected test - disabled if a test is running.

Show Failed Assumptions

Turns on and off the display of cases under a Theory that have failed an assumption (Inconclusive results). This menu item is only displayed for nodes that are part of a Theory.

Show Checkboxes

Turns the display of checkboxes in the tree on or off. The checkboxes may be used to select multiple tests for running.

Load Fixture

Reloads only the currently selected fixture or namespace. The fixture, once loaded, remains in effect through any subsequent reloads. This generally results in substantial reduction in load time.

Clear Fixture

Reloads all the tests, clearing the currently loaded fixture.

Properties

Displays the Test Properties for the selected test node.

NUnit-2.6.0.12051/doc/codeFuncs.js0000664000175000017500000000317311713252032016173 0ustar jtaylorjtaylorwindow.onload = init; var langElements = new Array(); function init() { var els = document.getElementsByTagName( 'pre' ); var elsLen = els.length; var pattern = new RegExp('(^|\\s)(cs|vb|mc|js)(\\s|$)'); for (i = 0, j = 0; i < elsLen; i++) { if ( pattern.test(els[i].className) ) { //els[i].style.background = "#fcc"; langElements[j] = els[i]; j++; } } var lang = getCookie( "lang" ); if ( lang == null ) lang = "cs"; showLang(lang); } function getCookie(name) { var cname = name + "="; var dc = document.cookie; if ( dc.length > 0 ) { begin = dc.indexOf(cname); if ( begin != -1 ) { begin += cname.length; end = dc.indexOf(";",begin); if (end == -1) end = dc.length; return unescape(dc.substring(begin, end) ); } } } function setCookie(name,value,expires) { document.cookie = name + "=" + escape(value) + "; path=/" + ((expires == null) ? "" : "; expires=" + expires.toGMTString()); } function showLang(lang) { var pattern = new RegExp('(^|\\s)'+lang+'(\\s|$)'); var elsLen = langElements.length; for (i = 0; i < elsLen; i++ ) { var el = langElements[i]; if ( pattern.test( el.className ) ) el.style.display = ""; else el.style.display = "none"; } setCookie("lang",lang); } function Show( id ) { document.getElementById(id).style.display = ""; } function Hide( id ) { document.getElementById(id).style.display = "none"; } function ShowCS() { showLang('cs'); } function ShowVB() { showLang('vb'); } function ShowMC() { showLang('mc'); } function ShowJS() { showLang('js'); } NUnit-2.6.0.12051/doc/testFixture.html0000664000175000017500000003371311720512704017146 0ustar jtaylorjtaylor NUnit - TestFixture

TestFixtureAttribute (NUnit 2.0 / 2.5)

This is the attribute that marks a class that contains tests and, optionally, setup or teardown methods. NUnit 2.5 introduces parameterized and generic test fixtures - see below.

Most restrictions on a class that is used as a test fixture have now been eliminated. As of NUnit 2.5.3, a test fixture class:

  • May be public, protected, private or internal.
  • May be a static class in .NET 2.0 or later.
  • May be generic, so long as any type parameters are provided or can be inferred from the actual arguments.
  • May not be abstract - although the attribute may be applied to an abstract class intended to serve as a base class for test fixtures.
  • If no arguments are provided with the TestFixtureAttribute, the class must have a default constructor.
  • If arguments are provided, they must match one of the constructors.

If any of these restrictions are violated, the class is not runnable as a test and will display as an error.

It is advisable that the constructor not have any side effects, since NUnit may construct the object multiple times in the course of a session.

Beginning with NUnit 2.5, the TestFixture attribute is optional for non-parameterized, non-generic fixtures. So long as the class contains at least one method marked with the Test, TestCase or TestCaseSource attribute, it will be treated as a test fixture.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  // ...
}

Inheritance

The TestFixtureAttribute may be applied to a base class and is inherited by any derived classes. This includes any abstract base class, so the well-known Abstract Fixture pattern may be implemented if desired.

In order to facilitate use of generic and/or parameterized classes, where the derived class may require a different number of arguments (or type arguments) from the base class, superfluous TestFixture attributes are ignored, using the following rules:

  1. If all TestFixture attributes provide constructor or type arguments, then all of them are used.
  2. If some of the attributes provide arguments and others do not, then only those with arguments are used and those without arguments are ignored.
  3. If none of the attributes provide arguments, one of them is selected for use by NUnit. It is not possible to predict which will be used, so this situation should generally be avoided.
This permits code like the following, which would cause an error if the attribute on the base class were not ignored.
[TestFixture]
public class AbstractFixtureBase
{
    ...
}

[TestFixture(typeof(string))]
public class DerivedFixture<T> : AbstractFixtureBase
{
    ...
}

Parameterized Test Fixtures (NUnit 2.5)

Beginning with NUnit 2.5, test fixtures may take constructor arguments. Argument values are specified as arguments to the TestFixture attribute. NUnit will construct a separate instance of the fixture for each set of arguments.

Individual fixture instances in a set of parameterized fixtures may be ignored. Set the Ignore named parameter of the attribute to true or set IgnoreReason to a non-empty string.

Individual fixture instances may be given categories as well. Set the Category named parameter of the attribute to the name of the category or to a comma-separated list of categories.

Example

The following test fixture would be instantiated by NUnit three times, passing in each set of arguments to the appropriate constructor. Note that there are three different constructors, matching the data types provided as arguments.

[TestFixture("hello", "hello", "goodbye")]
[TestFixture("zip", "zip")]
[TestFixture(42, 42, 99)]
public class ParameterizedTestFixture
{
    private string eq1;
    private string eq2;
    private string neq;
    
    public ParameterizedTestFixture(string eq1, string eq2, string neq)
    {
        this.eq1 = eq1;
        this.eq2 = eq2;
        this.neq = neq;
    }

    public ParameterizedTestFixture(string eq1, string eq2)
        : this(eq1, eq2, null) { }

    public ParameterizedTestFixture(int eq1, int eq2, int neq)
    {
        this.eq1 = eq1.ToString();
        this.eq2 = eq2.ToString();
        this.neq = neq.ToString();
    }

    [Test]
    public void TestEquality()
    {
        Assert.AreEqual(eq1, eq2);
        if (eq1 != null && eq2 != null)
            Assert.AreEqual(eq1.GetHashCode(), eq2.GetHashCode());
    }

    [Test]
    public void TestInequality()
    {
        Assert.AreNotEqual(eq1, neq);
        if (eq1 != null && neq != null)
            Assert.AreNotEqual(eq1.GetHashCode(), neq.GetHashCode());
    }
}

Generic Test Fixtures (NUnit 2.5)

Beginning with NUnit 2.5, you may also use a generic class as a test fixture. In order for NUnit to instantiate the fixture, you must either specify the types to be used as arguments to TestFixtureAttribute or use the named parameter TypeArgs= to specify them. NUnit will construct a separate instance of the fixture for each TestFixtureAttribute you provide.

Example

The following test fixture would be instantiated by NUnit twice, once using an ArrayList and once using a List<int>.

[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
  private IList list;

  [SetUp]
  public void CreateList()
  {
    this.list = new TList();
  }

  [Test]
  public void CanAddToList()
  {
    list.Add(1); list.Add(2); list.Add(3);
    Assert.AreEqual(3, list.Count);
  }
}

Generic Test Fixtures with Parameters (NUnit 2.5)

If a Generic fixture, uses constructor arguments, there are three approaches to telling NUnit which arguments are type parameters and which are normal constructor parameters.

  1. Specify both sets of parameters as arguments to the TestFixtureAttribute. Leading System.Type arguments are used as type parameters, while any remaining arguments are used to construct the instance. In the following example, this leads to some obvious duplication...
    [TestFixture(typeof(double), typeof(int), 100.0, 42)]
    [TestFixture(typeof(int) typeof(double), 42, 100.0)]
    public class SpecifyBothSetsOfArgs<T1, T2>
    {
        T1 t1;
        T2 t2;
    
        public SpecifyBothSetsOfArgs(T1 t1, T2 t2)
        {
            this.t1 = t1;
            this.t2 = t2;
        }
    
        [TestCase(5, 7)]
        public void TestMyArgTypes(T1 t1, T2 t2)
        {
            Assert.That(t1, Is.TypeOf<T1>());
            Assert.That(t2, Is.TypeOf<T2>());
        }
    }
  2. Specify normal parameters as arguments to TestFixtureAttribute and use the named parameter TypeArgs= to specify the type arguments. Again, for this example, the type info is duplicated, but it is at least more cleanly separated from the normal arguments...
    [TestFixture(100.0, 42, TypeArgs=new Type[] {typeof(double), typeof(int) } )]
    [TestFixture(42, 100.0, TypeArgs=new Type[] {typeof(int), typeof(double) } )]
    public class SpecifyTypeArgsSeparately<T1, T2>
    {
        T1 t1;
        T2 t2;
    
        public SpecifyTypeArgsSeparately(T1 t1, T2 t2)
        {
            this.t1 = t1;
            this.t2 = t2;
        }
    
        [TestCase(5, 7)]
        public void TestMyArgTypes(T1 t1, T2 t2)
        {
            Assert.That(t1, Is.TypeOf<T1>());
            Assert.That(t2, Is.TypeOf<T2>());
        }
    }
  3. In some cases, when the constructor makes use of all the type parameters NUnit may simply be able to deduce them from the arguments provided. That's the case here and the following is the preferred way to write this example...
    [TestFixture(100.0, 42)]
    [TestFixture(42, 100.0)]
    public class DeduceTypeArgsFromArgs<T1, T2>
    {
        T1 t1;
        T2 t2;
    
        public DeduceTypeArgsFromArgs(T1 t1, T2 t2)
        {
            this.t1 = t1;
            this.t2 = t2;
        }
    
        [TestCase(5, 7)]
        public void TestMyArgTypes(T1 t1, T2 t2)
        {
            Assert.That(t1, Is.TypeOf<T1>());
            Assert.That(t2, Is.TypeOf<T2>());
        }
    }
NUnit-2.6.0.12051/doc/exceptionAsserts.html0000664000175000017500000002072711720512704020164 0ustar jtaylorjtaylor NUnit - ExceptionAsserts

Exception Asserts (NUnit 2.5)

The Assert.Throws method is pretty much in a class by itself. Rather than comparing values, it attempts to invoke a code snippet, represented as a delegate, in order to verify that it throws a particular exception.

It's also in a class by itself in that it returns an Exception, rather than void, if the Assert is successful. See the example below for a few ways to use this.

Assert.Throws may be used with a constraint argument, which is applied to the actual exception thrown, or with the Type of exception expected. The Type format is available in both both a non-generic and (in the .NET 2.0 version) generic form.

Assert.DoesNotThrow simply verifies that the delegate does not throw an exception.

Assert.Catch is similar to Assert.Throws but will pass for an exception that is derived from the one specified.

Exception Assert.Throws( Type expectedExceptionType, TestDelegate code );
Exception Assert.Throws( Type expectedExceptionType, TestDelegate code, 
		string message );
Exception Assert.Throws( Type expectedExceptionType, TestDelegate code, 
		string message, params object[] parms);

Exception Assert.Throws( IResolveConstraint constraint, TestDelegate code );
Exception Assert.Throws( IResolveConstraint constraint, TestDelegate code, 
		string message );
Exception Assert.Throws( IResolveConstraint constraint, TestDelegate code, 
		string message, params object[] parms);

T Assert.Throws<T>( TestDelegate code );
T Assert.Throws<T>( TestDelegate code, string message );
T Assert.Throws<T>( TestDelegate code, string message, 
		params object[] parms);
		
void Assert.DoesNotThrow( TestDelegate code );
void Assert.DoesNotThrow( TestDelegate code, string message );
void Assert.DoesNotThrow( TestDelegate code, string message, 
        params object[] parms);

Exception Assert.Catch( TestDelegate code );
Exception Assert.Catch( TestDelegate code, string message );
Exception Assert.Catch( TestDelegate code, string message, 
        params object[] parms);

Exception Assert.Catch( Type expectedExceptionType, TestDelegate code );
Exception Assert.Catch( Type expectedExceptionType, TestDelegate code, 
		string message );
Exception Assert.Catch( Type expectedExceptionType, TestDelegate code, 
		string message, params object[] parms);

T Assert.Catch<T>( TestDelegate code );
T Assert.Catch<T>( TestDelegate code, string message );
T Assert.Catch<T>( TestDelegate code, string message, 
		params object[] parms);

In the above code TestDelegate is a delegate of the form void TestDelegate(), which is used to execute the code in question. Under .NET 2.0, this may be an anonymous delegate. If compiling under C# 3.0, it may be a lambda expression.

The following example shows different ways of writing the same test.

[TestFixture]
public class AssertThrowsTests
{
  [Test]
  public void Tests()
  {
    // .NET 1.x
    Assert.Throws( typeof(ArgumentException),
      new TestDelegate(MethodThatThrows) );
	  
    // .NET 2.0
    Assert.Throws<ArgumentException>( MethodThatThrows() );

    Assert.Throws<ArgumentException>(
	  delegate { throw new ArgumentException(); } );

    // Using C# 3.0	  
    Assert.Throws<ArgumentException>(
      () => throw new ArgumentException(); } );
  }
  
  void MethodThatThrows()
  {
    throw new ArgumentException();
  }

This example shows use of the return value to perform additional verification of the exception.

[TestFixture]
public class UsingReturnValue
{
  [Test]
  public void TestException()
  {
    MyException ex = Assert.Throws<MyException>(
      delegate { throw new MyException( "message", 42 ); } );
    Assert.That( ex.Message, Is.EqualTo( "message" ) );
    Assert.That( ex.MyParam, Is.EqualTo( 42 ) ); 
  }

This example does the same thing using the overload that includes a constraint.

[TestFixture]
public class UsingConstraint
{
  [Test]
  public void TestException()
  {
    Assert.Throws( Is.Typeof<MyException>()
                 .And.Message.EqualTo( "message" )
                 .And.Property( "MyParam" ).EqualTo( 42 ),
      delegate { throw new MyException( "message", 42 ); } );
  }

Use the form that matches your style of coding.

Exact Versus Derived Types

When used with a Type argument, Assert.Throws requires that exact type to be thrown. If you want to test for any derived Type, use one of the forms that allows specifying a constraint. Alternatively, you may use Assert.Catch, which differs from Assert.Throws in allowing derived types. See the following code for examples:

// Require an ApplicationException - derived types fail!
Assert.Throws( typeof(ApplicationException), code );
Assert.Throws<ApplicationException>()( code );

// Allow both ApplicationException and any derived type
Assert.Throws( Is.InstanceOf( typeof(ApplicationException), code );
Assert.Throws( Is.InstanceOf<ApplicationException>(), code );

// Allow both ApplicationException and any derived type
Assert.Catch<ApplicationException>( code );

// Allow any kind of exception
Assert.Catch( code );

See also...

NUnit-2.6.0.12051/doc/delayedConstraint.html0000664000175000017500000001057611720512704020276 0ustar jtaylorjtaylor NUnit - DelayedConstraint

Delayed Constraint (NUnit 2.5)

DelayedConstraint delays the application of another constraint until a certain amount of time has passed. In it's simplest form, it replaces use of a Sleep in the code but it also supports polling, which may allow use of a longer maximum time while still keeping the tests as fast as possible.

The After modifier is permitted on any constraint, and the delay applies to the entire expression up to the point where After appears.

Use of a DelayedConstraint with a value argument makes no sense, since the value will be extracted at the point of call. It's intended use is with delegates and references. If a delegate is used with polling, it may be called multiple times so only methods without side effects should be used in this way.
Syntax HelperConstructorOperation
After(int)DelayedConstraint(Constraint, int)tests that a constraint is satisfied after a delay.
After(int, int)DelayedConstraint(Constraint, int, int)tests that a constraint is satisfied after a delay using polling.

NUnit-2.6.0.12051/doc/culture.html0000664000175000017500000002015611720512704016300 0ustar jtaylorjtaylor NUnit - Culture

CultureAttribute (NUnit 2.4.2)

The Culture attribute is used to specify cultures for which a test or fixture should be run. It does not affect the culture setting, but merely uses it to determine whether to run the test. If you wish to change the culture when running a test, use the SetCulture attribute instead.

If the specified culture requirements for a test are not met it is skipped. In the gui, the tree node for the test remains gray and the status bar color is not affected.

One use of the Culture attribute is to provide alternative tests under different cultures. You may specify either specific cultures, like "en-GB" or neutral cultures like "de".

Test Fixture Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [Culture("fr-FR")]
  public class FrenchCultureTests
  {
    // ...
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture(), Culture("fr-FR")>
  Public Class FrenchCultureTests
    ' ...
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  [Culture("fr-FR")]
  public __gc class FrenchCultureTests
  {
    // ...
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
/** @attribute NUnit.Framework.Culture("fr-FR") */
public class FrenchCultureTests
{
  // ...
}

Test Syntax

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [Culture(Exclude="en,de")]
    public void SomeTest()
    { /* ... */ }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()>
  Public Class SuccessTests
    <Test(), Culture(Exclude="en,de")> Public Sub SomeTest()
      ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [Test][Culture(Exclude="en,de")] void SomeTest();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.Test() */
  /** @attribute NUnit.Framework.Culture(Exclude=en,de") */
  public void SomeTest()
  { /* ... */ }
}

See also...

NUnit-2.6.0.12051/doc/runningTests.html0000664000175000017500000001060311720512704017314 0ustar jtaylorjtaylor NUnit - RunningTests

Running Tests

Nunit provides three different runners, which may be used to load and run your tests.

  • The console runner, nunit-console.exe, is used for batch execution.
  • The gui runner, nunit.exe, provides interactive loading and running of tests.
  • The pNUnit runner, pnunit-launcher.exe, is used to run parallel, distributed tests under the control of pNUnit.

NUnit Agent

When running tests in a separate process, the console and gui runners make use of the nunit-agent program, nunit-agent.exe. Although not directly run by users, nunit-agent does load and execute tests and users need to be aware of it, especially when debugging is involved.

Third-Party Runners

Various third-party applications are available for loading and running NUnit tests. Some of these actually use NUnit to load the tests, while others provide their own emulation and may not work in the same way that NUnit does.

Because the status of such projects may change from time to time, we don't discuss them individually here. For the latest information, consult the manufacturer of any third-party software or ask other users on our discussion list.

Additional Information

For additional general information on how tests are loaded and run, see

NUnit-2.6.0.12051/doc/propertyConstraint.html0000664000175000017500000001113611720512704020544 0ustar jtaylorjtaylor NUnit - PropertyConstraint

Property Constraints (NUnit 2.4.2)

Property constraints are used to test for the existence of a named property and optionally to test its value. It may also be used as a prefix for other constraints to be applied to the property.

PropertyExistsConstraint

Action

Tests for the existence of a named property on an object.

Constructor

PropertyExistsConstraint(string name)

Syntax

Has.Property( string )

Examples of Use

Assert.That( someObject, Has.Property( "Version" ) );

PropertyConstraint

Action

Tests for the existence of a named property on an object and causes subsequent allows tests to be made on the property value.

Constructor

PropertyConstraint(string name)

Syntax

Has.Property(string)...

Examples of Use

Assert.That(someObject, Has.Property("Version").EqualTo("2.0"));
Assert.That(collection, Has.Property("Count").GreaterThan(10));

Special Properties

Certain common properties are known to NUnit and may be tested using the following syntax...

Has.Length...
Has.Count...
Has.Message...
Has.InnerException...
NUnit-2.6.0.12051/doc/files/0000775000175000017500000000000011742560362015034 5ustar jtaylorjtaylorNUnit-2.6.0.12051/doc/files/QuickStart.doc0000664000175000017500000011100011713252032017574 0ustar jtaylorjtaylorࡱ> DFC7 'bjbjUU "@7|7|#l*"D*rrrrrrrr`bbbbbb "brrrrrbNrrwNNNrrr`Nr`NN``rf tO*TZ``0`c#c#`N**Lets start with a simple example. Suppose we are writing a bank application and we have a basic domain class Account. Account supports operations to deposit, withdraw, and transfer funds. The Account class may look like this: namespace bank { public class Account { private float balance; public void Deposit(float amount) { balance+=amount; } public void Withdraw(float amount) { balance-=amount; } public void TransferFunds(Account destination, float amount) { } public float Balance { get{ return balance;} } } } Now lets write a test for this class AccountTest. The first method we will test is TransferFunds. namespace bank { using NUnit.Framework; [TestFixture] public class AccountTest { [Test] public void TransferFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 100.00F); Assert.AreEqual(250.00F, destination.Balance); Assert.AreEqual(100.00F, source.Balance); } } } The first thing to notice about this class is that it has a [TestFixture] attribute associated with it this is the way to indicate that the class contains test code (this attribute can be inherited). The class has to be public and there are no restrictions on its superclass. The class also has to have a default constructor. The only method in the class TransferFunds, has a [Test] attribute associated with it this is an indication that it is a test method. Test methods have to return void and take no parameters. In our test method we do the usual initialization of the required test objects, execute the tested business method and check the state of the business objects. The Assert class defines a collection of methods used to check the post-conditions and in our example we use the AreEqual method to make sure that after the transfer both accounts have the correct balances (there are several overloadings of this method, the version that was used in this example has the following parameters : the first parameter is an expected value and the second parameter is the actual value). Compile and run this example. Assume that you have compiled your test code into a bank.dll. Start the NUnit Gui (the installer will have created a shortcut on your desktop and in the Program Files folder), after the GUI starts, select the File->Open menu item, navigate to the location of your bank.dll and select it in the Open dialog box. When the bank.dll is loaded you will see a test tree structure in the left panel and a collection of status panels on the right. Click the Run button, the status bar and the TransferFunds node in the test tree turn red our test has failed. The Errors and Failures panel displayed the following message TransferFunds : expected <250> but was <150> and the stack trace panel right below it reported where in the test code the failure has occurred "at bank.AccountTest.TransferFunds() in C:\nunit\BankSampleTests\AccountTest.cs:line 17 That is expected behavior; the test has failed because we have not implemented the TransferFunds method yet. Now lets get it to work. Dont close the GUI and go back to your IDE and fix the code, make your TransferFunds method look like this: public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); Withdraw(amount); } Now recompile your code and click the run button in GUI again the status bar and the test tree turn green. (Note how the GUI has reloaded the assembly automatically for you; we will keep the GUI open all the time and continue working with our code in IDE and write more tests). Lets add some error checking to our Account code. We are adding the minimum balance requirement for the account to make sure that banks continue to make their money by charging your minimal overdraft protection fee. Lets add the minimum balance property to our Account class: private float minimumBalance = 10.00F; public float MinimumBalance { get{ return minimumBalance;} } We will use an exception to indicate an overdraft: namespace bank { using System; public class InsufficientFundsException : ApplicationException { } } Add a new test method to our AccountTest class: [Test] [ExpectedException(typeof(InsufficientFundsException))] public void TransferWithInsufficientFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 300.00F); } This test method in addition to [Test] attribute has an [ExpectedException] attribute associated with it this is the way to indicate that the test code is expecting an exception of a certain type; if such an exception is not thrown during the execution the test will fail. Compile your code and go back to the GUI. As you compiled your test code, the GUI has grayed out and collapsed the test tree as if the tests were not run yet (GUI watches for the changes made to the test assemblies and updates itself when the structure of the test tree has changed e.g. new test is added). Click the Run button we have a red status bar again. We got the following Failure : TransferWithInsufficentFunds : InsufficientFundsException was expected. Lets fix our Account code again, modify the TransferFunds method this way: public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); if(balance-amount&l&q&v&w&&&&&&&' 1h/ =!"#$% i8`8 NormalCJ_HaJmH sH tH <A@< Default Paragraph Fonthoh Code9$ 8p @ x7$8$H$^CJOJQJ^JaJ#@ )MQeij '+.01;W/3679: 2 4 R e g h i 23BDS 8:[u"#`b"$E_  :ikl-/S{LNU/2D[\f{ # ' V +!/!^!_!c!d!!!!" "9">"l"q"v"w"""""""#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 '.93/D#%'' 2 2 4 4 R R e e ST"#MN"#+1T[lr08>Lt|tu , # 5 H S \ 3<EJTZ PX\j#)cv:BFTz!;K02SX|V]F~hn * > Y i !2!F!m!t!!!"" "!"A"F"z""""#33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 2 2 4 4 R R e e ST  88::[[uu"#``bb""$$EE__    ::ii--//ST||MNUU k!m!""""""""""""""#Raven James Newkirk Charlie PooleeE:\Documents and Settings\Charlie\Application Data\Microsoft\Word\AutoRecovery save of QuickStart.asd Charlie Poole.H:\Dev\VS.Net\NUnit\nunit20\doc\QuickStart.doc Charlie Poole.H:\Dev\VS.Net\NUnit\nunit20\doc\QuickStart.doc Charlie Poole2H:\Dev\VS.Net\NUnit\new-nunit20\doc\QuickStart.doc Charlie Poole2H:\Dev\VS.Net\NUnit\new-nunit20\doc\QuickStart.doc@#@@UnknownGz Times New Roman5Symbol3& z Arial?5 z Courier New"1h3:gw$O>gA!20#4$3QH!Let s start with a simple exampleRaven Charlie PooleOh+'0  $0 L X dpx"Lets start with a simple exampleosetRavenstaveave Normal.dot Charlie Pooleth7arMicrosoft Word 9.0s@b@ %@IkO$O՜.+,0 hp|   ># "Lets start with a simple example Title  "#$%&'()*+,-./012456789:<=>?@ABERoot Entry FwtOG1Table!c#WordDocument"@SummaryInformation(3DocumentSummaryInformation8;CompObjjObjectPoolwtOwtO  FMicrosoft Word Document MSWordDocWord.Document.89qNUnit-2.6.0.12051/doc/files/Results.xsd0000664000175000017500000001217711713252032017213 0ustar jtaylorjtaylor NUnit-2.6.0.12051/doc/files/Summary.xslt0000664000175000017500000000256211713252032017400 0ustar jtaylorjtaylor Tests run: , Failures: , Not run: , Time: seconds Failures: Tests not run: ) : NUnit-2.6.0.12051/doc/files/TestResult.xml0000664000175000017500000003224311713252032017666 0ustar jtaylorjtaylor NUnit-2.6.0.12051/doc/files/QuickStart.Spanish.doc0000664000175000017500000011600011713252032021205 0ustar jtaylorjtaylorࡱ> IKH7 *bjbjUU "F7|7|&lJJJJJJJ^BBBB ND^"2x"z"z"z"z"z"z"$ '&z"Jz"FJJ"FFFJJx"Fx"F&Fl"JJl"  ]O^Bl"x""0"l"&F&x"F^^JJJJEmpecemos con un ejemplo simple. Supongamos que hemos escrito una aplicacin bancaria y que tenemos una clase de dominio bsica de Cuenta bancaria (Account). Account soporta operaciones para depsito (deposit), retiro (withdraw) y transferencia (transfer) de fondos. La clase sera algo similar a esto: namespace bank { public class Account { private float balance; public void Deposit(float amount) { balance+=amount; } public void Withdraw(float amount) { balance-=amount; } public void TransferFunds(Account destination, float amount) { } public float Balance { get{ return balance;} } } } Ahora vamos a escribir una prueba para esta clase - AccountTest. El primer mtodo que probaremos ser transferencia de fondos (TransferFunds). namespace bank { using NUnit.Framework; [TestFixture] public class AccountTest { [Test] public void TransferFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 100.00F); Assertion.AssertEquals(250.00F, destination.Balance); Assertion.AssertEquals(100.00F, source.Balance); } } } Lo primero que se nota en esta clase es que posee un atributo asociado a ella llamado [TestFixture] este es la forma de indicar que la clase contiene cdigo de prueba (este atributo puede ser heredado). Esta clase debe ser pblica (public) y no existen restricciones en su superclase. La clase adems debe tener un constructor. El nico mtodo en la clase TransferFunds (Transferencia de fondos), posee un atributo asociado a l [Test], esto indica que el mtodo es de prueba. Los mtodos de prueba deben retornar siempre void y no recibir parmetros. En nuestro mtodo de prueba hacemos las inicializaciones usuales de los objetos de prueba necesarios, ejecutamos el mtodo de negocio a ser probado y comprobamos el estado del objeto de negocio. La clase Assertion define una coleccin de mtodos usados para comprobar las condiciones posteriores a la ejecucin y en nuestro ejemplo usamos el mtodo AssertEquals para asegurarnos que luego de la transferencia, ambas cuentas posean los saldos correctos (existen varias sobrecargas a este mtodo, la versin que fue usada en este ejemplo posee los siguientes parmetros: el primer parmetro es un valor esperadoy el segundo es el valor almacenado en el objeto). Compila y ejecuta este ejemplo. Asumamos que compilaste tu clase de prueba como bank.dll. Ejecuta la GUI de NUnit (el instalador habr creado un acceso directo en tu escritorio y en la carpeta Archivos de Programa), luego de haber iniciado el GUI, selecciona File(Open ,menu item, desplzate hacia la ubicacin de tu archivo bank.dll y seleccinalo en el cuadro de dilogo Open. Cuando la librera bank.dll se haya cargado, vers una estructura de rbol para la prueba en el panel izquierdo y una coleccin de paneles de estado a la derecha. Haz click en el botn Run, la barra de estado y el nodo TransferFunds en el rbol de prueba se tornarn rojos nuestra prueba ha fallado. El panel Errors and Failures mostrar el siguiente mensaje TransferFunds : expected <250> but was <150> y el panel de stack trace justo abajo reportar en que lugar en el cdigo de prueba ocurri el error- at bank.AccountTest.TransferFunds() in C:\nunit\BankSampleTests\AccountTest.cs:line 17 Ese es un comportamiento esperado, la prueba ha fallado debido a que no hemos implementado el mtodo TransferFunds an. Ahora hagmoslo funcionar. No cierres el GUI, vuelve a tu IDE y corrige el cdigo, cmbialo as: public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); Withdraw(amount); } Ahora recompila tu cdigo y haz click en el botn run en la GUI nuevamente la barra de estado y el rbol de pruebas se tornarn verdes. (Nota como el GUI ha recargado el assembly automticamente); mantendremos el GUI abierto todo el tiempo y continuaremos trabajando con nuestro cdigo en el IDE y escribiremos ms pruebas. Ahora aadiremos algo de control de errores al cdigo de Account. Estamos agregando el requerimiento de saldo mnimo a la cuenta para estar seguros de que los bancos continen haciendo su dinero obligando a mantener un saldo mnimo. Aadiremos la propiedad de saldo mnimo a nuestra clase Account. private float minimumBalance = 10.00F; public float MinimumBalance { get{ return minimumBalance;} } Ahora usaremos una excepcin para indicar la falta de fondos: namespace bank { using System; public class InsufficientFundsException : ApplicationException { } } Agrega ahora un nuevo mtodo de prueba a la clase AccountTest: [Test] [ExpectedException(typeof(InsufficientFundsException))] public void TransferWithInsufficientFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 300.00F); } Este mtodo de prueba adems del atributo [Test] posee otro llamado [ExpectedException] - esta es la forma de indicar que el cdigo de prueba est esperando una excepcin de cierto tipo; si tal excepcin no ocurre durante la ejecucin la prueba fallar. Compila tu cdigo y regresa a la GUI. Mientras compilabas tu cdigo de prueba, la GUI se debi tornar de color gris y habr colapsado el rbol como si las pruebas no hubiesen sido ejecutadas an (la GUI espera por cambios hechos en los assemblies de prueba y se actualiza a si misma cuando la estructura del rbol de prueba cambia ej: cuando se ha agregado una nueva prueba). Haz click en el botn Run ahora tenemos una barra de estado roja nuevamente. Tenemos la misma falla: TransferWithInsufficentFunds : InsufficientFundsException was expected. Corrijamos nuestro cdigo de Account nuevamente, modifiquemos el mtodo TransferFunds de la siguiente forma: public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); if(balance-amount?ABVXZ\ru368:<?SVX[psuvz{  36CE]_acilCG|z | S U -/klno<=XY[\xy{| $%cekl 24QT[\^_{}+-34hikl!#%&PRTUWY46GHJKtu !!!!!!!! """ "8":"<">"M"P"d"h"o"r"""""""""""######,#/#1#4#_#c#########$$B$E$G$J$u$y${$~$$$$$%%% %#%'%)%-%X%\%^%a%%%%%%%%%&&&& & &&&Carlos Vinueza"D:\NUnit\doc\QuickStartSpanish.docCarlos VinuezayC:\Documents and Settings\Carlos\Datos de programa\Microsoft\Word\Guardado con Autorrecuperacin de QuickStartSpanish.asdCarlos Vinueza"D:\NUnit\doc\QuickStartSpanish.docCarlos Vinueza"D:\NUnit\doc\QuickStartSpanish.docCarlos VinuezayC:\Documents and Settings\Carlos\Datos de programa\Microsoft\Word\Guardado con Autorrecuperacin de QuickStartSpanish.asdCarlos Vinueza"D:\NUnit\doc\QuickStartSpanish.docCarlos VinuezayC:\Documents and Settings\Carlos\Datos de programa\Microsoft\Word\Guardado con Autorrecuperacin de QuickStartSpanish.asdCarlos Vinueza"D:\NUnit\doc\QuickStartSpanish.docCarlos Vinueza"D:\NUnit\doc\QuickStartSpanish.doc Charlie Poole:H:\Dev\VS.Net\NUnit\new-nunit20\doc\QuickStart.Spanish.doc  @&@@UnknownGz Times New Roman5Symbol3& z Arial;Wingdings?5 z Courier New"194jw D!r0dV'2QQuickStartSpanishNUnitCarlos Vinueza Charlie PooleOh+'0 , H T `lt|QuickStartSpanishdNUnittaCarlos Vinuezasarlarl Normal.doteCharlie Pooles28rMicrosoft Word 9.0@VP@Zm@nAO ՜.+,0  hp  VIMEWorks Ca. Ltda.sDV' QuickStartSpanish Title  !"#%&'()*+,-./012345679:;<=>?ABCDEFGJRoot Entry F]OL1Table$&WordDocument"FSummaryInformation(8DocumentSummaryInformation8@CompObjjObjectPool]O]O  FMicrosoft Word Document MSWordDocWord.Document.89qNUnit-2.6.0.12051/doc/assertions.html0000664000175000017500000001041711720512704017006 0ustar jtaylorjtaylor NUnit - Assertions

Assertions

Assertions are central to unit testing in any of the xUnit frameworks, and NUnit is no exception. NUnit provides a rich set of assertions as static methods of the Assert class.

If an assertion fails, the method call does not return and an error is reported. If a test contains multiple assertions, any that follow the one that failed will not be executed. For this reason, it's usually best to try for one assertion per test.

Each method may be called without a message, with a simple text message or with a message and arguments. In the last case the message is formatted using the provided text and arguments.

Two Models

Before NUnit 2.4, a separate method of the Assert class was used for each different assertion. We call this the "Classic Model." It continues to be supported in NUnit, since many people prefer it.

Beginning with NUnit 2.4, a new "Constraint-based" model was introduced. This approach uses a single method of the Assert class for all assertions, passing a Constraint object that specifies the test to be performed.

This constraint-based model is now used internally by NUnit for all assertions. The methods of the classic approach have been re-implemented on top of this new model.

NUnit-2.6.0.12051/doc/upgrade.html0000664000175000017500000000634411720512704016247 0ustar jtaylorjtaylor NUnit - Upgrade

From NUnit 2.x

In general, there are two approaches to running tests built against earlier versions of the NUnit framework from 2.0 through 2.5.10:

  1. Run the tests without recompilation. This is the best approach when no further changes are to be made to a project. Ensure that the framework assembly against which the tests were built continues to be avaialble in the test directory.
  2. Recompile the tests referencing the latest version of the framework assembly. This is usually the best option when a project is still under development.

Note: NUnit 2.6 no longer recognizes "old style" test cases - those identified by a name beginning with "Test". If you have such tests, you will need to convert them to use the TestAttribute and recompile your tests. In such cases, it makes sense to recompile against the latest framework.

From NUnit 1.x

Tests originally compiled against a version of NUnit prior to 2.0 will need to be rewritten and recompiled in order to run under NUnit 2.6.

NUnit-2.6.0.12051/doc/addinsDialog.html0000664000175000017500000000742711720512704017205 0ustar jtaylorjtaylor NUnit - AddinsDialog

Addins Dialog

The Addins Dialog is displayed using the Tools | Addins menu item on the main menu. It lists all addins that have been found and loaded by NUnit.

Addin

This column lists the name of the addin, as defined by its author.

Status

This column shows the status of each addin. Possible values are

  • Unknown
  • Enabled
  • Disabled
  • Loaded
  • Error

Description

If the author of an addin has provided a description, it is shown here when the addin is selected.

Message

If the addin failed to load, its status will be shown as Error and any error message displayed here when that addin is selected.

NUnit-2.6.0.12051/doc/actionAttributes.html0000664000175000017500000004647211720512704020152 0ustar jtaylorjtaylor NUnit - ActionAttributes

Action Attributes (NUnit 2.6)

Action Attributes are a feature of NUnit designed to better enable composability of test logic. Often when writing unit tests we have logic that we want to run upon certain events in the test cycle (e.g. SetUp, TearDown, FixtureSetUp, FixtureTearDown, etc.). NUnit has had the ability to execute code upon these events by decorating fixture classes and methods with the appropriate NUnit- provided attributes. Action Attributes allow the user to create custom attributes to encapsulate specific actions for use before or after any test is run.

The Problem of Composability

Suppose we have some tests in multiple fixtures that need the same in-memory test database to be created and destroyed on each test run. We could create a base fixture class and derive each fixture that depends on the test from that class. Alternatively, we could create a SetUpFixture class at the level of a common namespace shared by each fixture.

This works fine, until we need some other reusable functionality, say the ability to configure or reset a ServiceLocator. We could put that functionality in the base fixture class or setup fixture, but now we're mixing two different responsibilities into the base class. In the case of a setup fixture, this only works if all classes requiring both features are located in a common namespace. In some cases we may *not* want the test database, but we do want ServiceLocator configuration; and sometimes we want the opposite. Still other times we'll want both - so we'd have to make the base class configurable.

If we now discover a third piece of functionality we need to reuse, like configuring the Thread's CurrentPrincipal in arbitrary ways, the complexity of the solution very quickly. We've violated the Single Responsibility Principle and are suffering for it. What we really want is the ability to separate the different pieces of resuable test logic and compose them together as our tests need them.

Resolving the Problem

Action Attributes get us out of our bind. Consider this example:

[TestFixture, ResetServiceLocator]
public class MyTests
{
 [Test, CreateTestDatabase]
 public void Test1() { /* ... */ }

 [Test, CreateTestDatabase, AsAdministratorPrincipal]
 public void Test2() { /* ... */ }

 [Test, CreateTestDatabase, AsNamedPrincipal("charlie.poole")]
 public void Test3() { /* ... */ }

 [Test, AsGuestPrincipal]
 public void Test4() { /* ... */ }
}

Here we have used user-defined attributes to identify five different actions that we want to compose together in different ways for different tests:

  • ResetServiceLocator
  • CreateTestDatabase
  • AsAdministratorPrincipal
  • AsNamedPrincipal
  • AsGuestPrincipal
We can reuse these actions in other test fixtures, simply by decorating them with the appropriate attributes.without having to inherit from a base class. We can even develop and distribute a library of common test actions.

Implementing an Action Attribute

Action attributes are defined by the programmer. They implement the ITestAction interface, which is defined as follows:

    public interface ITestAction
    {
        void BeforeTest(TestDetails details);

        void AfterTest(TestDetails details);

        ActionTargets Targets { get; }
    }

For convenience, you may derive your own action attribute from NUnit's TestActionAttribute, an abstract class with virtual implementations of each member of the interface. Alternatively, you may derive from System.Attribute and implement the interface directly.

    [Flags]
    public enum ActionTargets
    {
        Default = 0,

        Test = 1,

        Suite = 2
    }

Action Targets

The value returned from the Targets property determines when the BeforeTest and AfterTest methods will be called. The ActionTargets enum is defined as follows:

When an attribute that returns ActionTargets.Suite is applied to either a class or a parameterized method, NUnit will execute the attribute's BeforeTest method prior to executing the test suite and then execute the AfterTest method after the test suite has finished executing. This is similar to how the TestFixtureSetUp and TestFixtureTearDown attributes work.

On the other hand, when an attribute that returns ActionTargets.Test is used in the same situations, NUnit will execute the attribute's BeforeTest method prior to each contained test case and the AfterTest method after each test case. This is similar to how the SetUp and TearDown attributes work.

Action attributes that return ActionTargets.Default target the particular code item to which they are attached. When attached to a method, they behave as if ActionTargets.Test had been specified. When attached to a class or assembly, they behave as if ActionTargets.Suite was returned.

Test Details

The BeforeTest and AfterTest methods are provided with certain information about the test that is about to run (before) or has just run (after). The TestDetails class provides the following private properties, which may be used by the before or after method to decide what actions to take:
  • Fixture - an object representing the user fixture, if available, or null
  • Method - the MethodInfo that implements the test, if available, or null
  • FullName - a string giving the full name of the test
  • Type - a string representing the type of the test, e.g. "Test Case"
  • IsSuite - true if the test is a suite, otherwise false

Examples

The examples that follow all use the following sample Action Attribute:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class |
                AttributeTargets.Interface | AttributeTargets.Assembly,
                AllowMultiple = true)]
public class ConsoleActionAttribute : Attribute, ITestAction
{
    private string _Message;

    public ConsoleActionAttribute(string message) { _Message = message; }

    public void BeforeTest(TestDetails details)
    {
        WriteToConsole("Before", details);
    }

    public void AfterTest(TestDetails details)
    {
        WriteToConsole("After", details);
    }

    public ActionTargets Targets
    {
        get { return ActionTargets.Test | ActionTargets.Suite; }
    }

    private void WriteToConsole(string eventMessage, TestDetails details)
    {
        Console.WriteLine("{0} {1}: {2}, from {3}.{4}.",
            eventMessage,
            details.IsSuite ? "Suite" : "Case",
            _Message,
            fixture != null ? fixture.GetType().Name : "{no fixture}",
            method != null ? method.Name : "{no method}");
    }
}

Note that the above Action Attribute returns the union of ActionTargets.Test and ActionTargets.Suite. This is permitted, but will probably not be the normal case. It is done here so we can reuse the attribute in multiple examples. The attribute takes a single constructor argument, a message, that will be used to write output to the console. All of the Before and After methods write output via the WriteToConsole method.

Method Attached Actions

Example 1 (applied to simple test method):

[TestFixture]
public class ActionAttributeSampleTests
{
    [Test][ConsoleAction("Hello")]
    public void SimpleTest()
    {
        Console.WriteLine("Test ran.");
    }
}
Console Output:
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test ran.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.

Example 2 (applied action twice to test method):

[TestFixture]
public class ActionAttributeSampleTests
{
    [Test] [ConsoleAction("Hello")]
    [ConsoleAction("Greetings")]
    public void SimpleTest()
    {
        Console.WriteLine("Test run.");
    }
}
Console Output:
  Before Case: Greetings, from ActionAttributeSampleTests.SimpleTest.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test run.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  After Case: Greetings, from ActionAttributeSampleTests.SimpleTest.
Remarks
You are permitted to apply the same attribute multiple times. Note that the order in which attributes are applied is indeterminate, although it will generally be stable for a single release of .NET.

Example 3 (applied to a test method with test cases):

[TestFixture]
public class ActionAttributeSampleTests
{
    [Test] [ConsoleAction("Hello")]
    [TestCase("02")]
    [TestCase("01")]
    public void SimpleTest(string number)
    {
        Console.WriteLine("Test run {0}.", number);
    }
}
Console Output:
  Before Suite: Hello, from ActionAttributeSampleTests.SimpleTest.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test run 01.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test run 02.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  After Suite: Hello, from ActionAttributeSampleTests.SimpleTest.
Remarks
When one or more [TestCase] attributes are applied to a method, NUnit treats the method as a test suite. You'll notice that BeforeTest was run once before the suite and AfterTest was run once after it. In addition, BeforeTest and AfterTest are run again for each individual test case. Note that the order in which test cases are executed is indeterminate.

Type Attached Actions

Example 1:

[TestFixture] [ConsoleAction("Hello")]
public class ActionAttributeSampleTests
{
    [Test]
    public void SimpleTestOne()
    {
        Console.WriteLine("Test One.");
    }
    
    [Test]
    public void SimpleTestTwo()
    {
        Console.WriteLine("Test Two.");
    }
}
Console Output:
  Before Suite: Hello, from ActionAttributeSampleTests.{no method}.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTestOne.
  Test ran.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTestOne.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTestTwo.
  Test ran.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTestTwo.
  After Suite: Hello, from ActionAttributeSampleTests.{no method}.
Remarks
In this case, the class is the test suite. BeforeTest and AfterTest are run once each for this class and then again for each test.

Example 2 (attached to interface):

[ConsoleAction("Hello")]
public interface IHaveAnAction
{
}

[TestFixture]
public class ActionAttributeSampleTests : IHaveAnAction
{
    [Test] 
    public void SimpleTest()
    {
        Console.WriteLine("Test run.");
    }
}
Console Output:
  Before Suite: Hello, from ActionAttributeSampleTests.{no method}.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test run.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  After Suite: Hello, from ActionAttributeSampleTests.{no method}.
Remarks
Action attributes can be applied to an interface. If a class marked with [TestFixture] implements an interface that has an action attribute applied to the interface, the class inherits the action attribute from the interface. It behaves as if you applied the action attribute to the class itself.

Example 3 (action attribute is applied to interface and attribute uses interface to provide data to tests):

[AttributeUsage(AttributeTargets.Interface)]
public class InterfaceAwareActionAttribute : TestActionAttribute
{
    private readonly string _Message;

    public InterfaceAwareActionAttribute(string message) { _Message = message; }

    public override void BeforeTest(TestDetails details)
    {
        IHaveAnAction obj = details.Fixture as IHaveAnAction;
        if(obj != null)
            obj.Message = _Message;
    }

    public override ActionTargets Target
    {
        get { return ActionTargets.Test; }
    }
}

[InterfaceAwareAction("Hello")]
public interface IHaveAnAction { string Message { get; set; } }

[TestFixture]
public class ActionAttributeSampleTests : IHaveAnAction
{
    [Test] 
    public void SimpleTest()
    {
        Console.WriteLine("{0}, World!", Message);
    }

    public string Message { get; set; }
}
Console Output:
  Hello, World!
Remarks

Here we see a new action attribute, [InterfaceAwareAction]. This attribute uses the Fixture property of the TestDetails passed into BeforeTest and casts it to an interface, IHaveAnAction. If the fixture implements the IHaveAnAction interface, the attribute sets the Message property to the string passed into the constructor of the attribute. Since the attribute is applied to the interface, any class that implements this interface gets it's Message property set to the string provided to the constructor of the attribute. This is useful when the action attribute provides some data or service to the tests.

Note that this attribute inherits from TestActionAttribute. It uses the default (do-nothing) implementation of AfterTest and overrides both BeforeTest and Target.

Assembly Attached Action

Example 1:

[assembly: ConsoleAction("Hello")]

[TestFixture]
public class ActionAttributeSampleTests
{
    [Test] 
    public void SimpleTest()
    {
        Console.WriteLine("Test run.");
    }
}
Console Output:
  Before Suite: Hello, from {no fixture}.{no method}.
  Before Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  Test run.
  After Case: Hello, from ActionAttributeSampleTests.SimpleTest.
  After Suite: Hello, from {no fixture}.{no method}.
Remarks
The [ConsoleAction] attribute in this example is applied to the entire assembly. NUnit treats an assembly as a test suite (in fact, a suite of suites). Since the [ConsoleAction] attribute implements both ITestSuiteAction and ITestCaseAction, NUnit will run BeforeTest once before any tests are run in the assembly, and AfterTest after all tests are run in the assembly. Additionally, BeforeTest and AfterTest will be run for every test case in the assembly. It is unlikely that action attributes are applied to assemblies often. However, it is useful to build action attributes that ensure state gets cleaned up before and after each tests to prevent individual tests from affecting the outcome of other test. For example, if you have any static or cached data or services, an action attribute can be used to clean them up for each test.
NUnit-2.6.0.12051/doc/teardown.html0000664000175000017500000001764711720512704016453 0ustar jtaylorjtaylor NUnit - Teardown

TearDownAttribute (NUnit 2.0 / 2.5)

This attribute is used inside a TestFixture to provide a common set of functions that are performed after each test method is run.

Before NUnit 2.5, a TestFixture could have only one TearDown method and it was required to be an instance method.

Beginning with NUnit 2.5, TearDown methods may be either static or instance methods and you may define more than one of them in a fixture. Normally, multiple TearDown methods are only defined at different levels of an inheritance hierarchy, as explained below.

So long as any SetUp method runs without error, the TearDown method is guaranteed to run. It will not run if a SetUp method fails or throws an exception.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [SetUp] public void Init()
    { /* ... */ }

    [TearDown] public void Cleanup()
    { /* ... */ }

    [Test] public void Add()
    { /* ... */ }
  }
}
Imports System
Imports Nunit.Framework

Namespace Nunit.Tests

  <TestFixture()> Public Class SuccessTests
    <SetUp()> Public Sub Init()
    ' ...
    End Sub

    <TearDown()> Public Sub Cleanup()
    ' ...
    End Sub

    <Test()> Public Sub Add()
    ' ...
    End Sub
  End Class
End Namespace
#using <Nunit.Framework.dll>
using namespace System;
using namespace NUnit::Framework;

namespace NUnitTests
{
  [TestFixture]
  public __gc class SuccessTests
  {
    [SetUp] void Init();
    [TearDown] void Cleanup();

    [Test] void Add();
  };
}

#include "cppsample.h"

namespace NUnitTests {
  // ...
}
package NUnit.Tests;

import System.*;
import NUnit.Framework.TestFixture;


/** @attribute NUnit.Framework.TestFixture() */
public class SuccessTests
{
  /** @attribute NUnit.Framework.SetUp() */
  public void Init()
  { /* ... */ }

  /** @attribute NUnit.Framework.TearDown() */
  public void Cleanup()
  { /* ... */ }

  /** @attribute NUnit.Framework.Test() */
  public void Add()
  { /* ... */ }
}

Inheritance

The TearDown attribute is inherited from any base class. Therefore, if a base class has defined a TearDown method, that method will be called after each test method in the derived class.

Before NUnit 2.5, you were permitted only one TearDown method. If you wanted to have some TearDown functionality in the base class and add more in the derived class you needed to call the base class method yourself.

With NUnit 2.5, you can achieve the same result by defining a TearDown method in the base class and another in the derived class. NUnit will call base class TearDown methods after those in the derived classes.

Note: Although it is possible to define multiple TearDown methods in the same class, you should rarely do so. Unlike methods defined in separate classes in the inheritance hierarchy, the order in which they are executed is not guaranteed.

See also...

NUnit-2.6.0.12051/doc/suite.html0000664000175000017500000002036111720512704015744 0ustar jtaylorjtaylor NUnit - Suite
Update: August 22, 2007

SuiteAttribute (NUnit 2.0/2.4.4)

The Suite Attribute is used to define subsets of test to be run from the command-line, using the /fixture option. It was introduced in NUnit 2.0 to replace the older approach of inheriting from the TestSuite class.

Originally, the NUnit developers believed that the need for the Suite mechanism would diminish because of the dynamic creation of suites based on namespaces. It was provided for backwards compatibility.

That has not proven to be true. Suites are still used today by many people, so we are making an effort to revive them in terms of usability.

The Suite mechanism depends on a static property marked with the SuiteAttribute. In the clasic implementation, supported by all releases since 2.0, that property returns a TestSuite, populated with the tests that are to be executed.

Old Approach

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;
  using NUnit.Core;

  public class AllTests
  {
    [Suite]
    public static TestSuite Suite
    {
      get
      {
        TestSuite suite = new TestSuite("All Tests");
        suite.Add(new OneTestCase());
        suite.Add(new Assemblies.AssemblyTests());
        suite.Add(new AssertionTest());
        return suite;
      }
    }
  }
}

This approach has a serious problem: it requires a reference to the nunit.core assembly, which is not normally referenced by user tests. This means that the tests cannot be ported across versions of NUnit without recompilation. In some cases, introducing more than one version of the core assembly can prevent NUnit from running correctly.

Beginning with NUnit 2.4.4, a new approach is available. The property marked with the SuiteAttribute may simply return a collection containing test fixture objects or Types. If a Type is provided, NUnit creates an object of that type for use as a fixture. Any other object is assumed to be a pre-created fixture object. This allows objects with parameterized constructors or settable properties to be used as fixtures.

Test suites created through use of the SuiteAttribute may contain TestFixtureSetUp and TestFixtureTearDown methods, to perform one-time setup and teardown for the tests included in the suite.

New Approach - Fixture Objects

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  private class AllTests
  {
    [Suite]
    public static IEnumerable Suite
    {
      get
      {
        ArrayList suite = new ArrayList();
        suite.Add(new OneTestCase());
        suite.Add(new AssemblyTests());
        suite.Add(new NoNamespaceTestFixture());
        return suite;
      }
    }
  }
}

New Approach - Fixture Types

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  private class AllTests
  {
    [Suite]
    public static IEnumerable Suite
    {
      get
      {
        ArrayList suite = new ArrayList();
        suite.Add(typeof(OneTestCase));
        suite.Add(typeof(AssemblyTests));
        suite.Add(typeof(NoNamespaceTestFixture));
        return suite;
      }
    }
  }
}

Limitations

NUnit support for user-defined Suites currently has two limitations:
  1. It is not possible to include individual test cases directly in a Suite using the new approach. Anyone wanting to do so will need to use the old approach and create an object derive from NUnit.Core.TestCase. This is not recommended, since it requires a reference to the core assembly.
  2. Suites are currently not displayed in the Gui or run automatically by either runner when they are encountered. The historical purpose of the Suite mechanism was to provide a way of aggregating tests at the top level of each run. Hence, they are only supported when used with the /fixture option on the console or gui command line.
Approaches to removing these limitations are being investigated as part of the planning for future NUnit releases.
NUnit-2.6.0.12051/doc/suiteBuilders.html0000664000175000017500000000675511720512704017451 0ustar jtaylorjtaylor NUnit - SuiteBuilders

SuiteBuilders (NUnit 2.4)

Purpose

A SuiteBuilder is an addin used to build a test fixture from a type. NUnit itself uses a SuiteBuilder to recognize and build TestFixtures.

Extension Point

An addin may use the host to access this extension point by name:

	IExtensionPoint suiteBuilders = host.GetExtensionPoint( "SuiteBuilders" );

Interface

The extension object passed to Install must implement the ISuiteBuilder interface:

	public interface ISuiteBuilder
	{
		bool CanBuildFrom( Type type );
		Test BuildFrom( Type type );
	}

CanBuildFrom should return true if the specified Type is one from which the builder is able to create a fixture. This usually involve examining the Type and its attriutes.

The BuildFrom method should return a test fixture completely populated with its contained test cases. Return null if it is not possible to build a fixture using the provided Type.

NUnit-2.6.0.12051/doc/mainMenu.html0000664000175000017500000002250711720512704016370 0ustar jtaylorjtaylor NUnit - MainMenu

Main Menu


File Menu


New Project

Closes any open project, prompting the user to save it if it has been changed and then opens a FileSave dialog to allow selecting the name and location of the new project.

Open Project

Closes any open project, prompting the user to save it if it has been changed and then opens a FileOpen dialog to allow selecting the name and location of an assembly, a test project or (if Visual Studio support is enabled) a Visual Studio project.

Close

Closes any open project, prompting the user to save it if it has been changed.

Save

Saves the currently open project. Opens the Save As dialog if this is the first time the project is being saved.

Save As

Opens a FileSave dialog to allow specifying the name and location to which the project should be saved.

Reload Project

Completely reloads the current project by closing and re-opening it.

Reload Tests

Reloads the tests, merging any changes into the tree.

Select Runtime

Displays a list of runtime versions you may select in order to reload the tests using that runtime. This submenu is only present if you have more than one runtime version available. Any framework versions not supported by your NUnit installation will be disabled until you install the necessary NUnit components.

Recent Projects

Displays a list of recently opened projects and assemblies from which the user is able to select one for opening.

Exit

Closes and exits the application. If a test is running, the user is given the opportunity to cancel it and or to allow it to continue. If the open project has any pending changes, the user is given the opportunity to save it.


View Menu


Full Gui

Displays the complete gui - as in prior versions of NUnit. This includes the errors and failures and other tabs and the progress bar.

Mini Gui

Switches the display to the mini-gui, which consists of the tree display only.

Result Tabs

Displays a submenu that allows showing or hiding the tabs on the right hand side of the display.

Errors & Failures, Tests Not Run, etc.

Selects the individual tabs to display.

Tree

Displays the Tree submenu.

Show Checkboxes

Turns the display of checkboxes in the tree on or off. The checkboxes may be used to select multiple tests for running.

Expand

Expands the currently selected tree node.

Collapse

Collapses the currently selected tree node.

Expand All

Expands all nodes of the tree.

Collapse All

Collapses all nodes in the tree to the root.

Hide Tests

Collapses all fixture nodes, hiding the test cases.

Properties

Displays the Properties Dialog for the currently selected test.

GUI Font

Displays a submenu that allows changing the general font used by NUnit.

Increase

Increases the size of the font.

Decrease

Decreases the size of the font.

Change...

Displays the Font Change dialog.

Restore

Restores the default font.

Fixed Font

Displays a submenu that allows changing the fixed font used to display console output from the tests.

Increase

Increases the size of the fixed font.

Decrease

Decreases the size of the fixed font.

Restore

Restores the default fixed font.

Assembly Details...

Displays information about loaded test assemblies.

Status Bar

Displays or hides the status bar.


Project Menu


Configurations

Displays a submenu allowing selecting, adding or editing a configuration.

Debug, Release, etc.

Loads the specified configuration for testing.

Add

Opens the Add Configuration Dialog, which allows entry of the name of the new configuration and specifying an existing configuration to use as a template.

Edit

Opens the Configuration Editor.

Add Assembly

Displays a FileOpen dialog to allow selecting an assembly to be added to the active configuration of the currently open project.

Add VS Project

Only available if Visual Studio Support is enabled. Displays a FileOpen dialog to allows selecting a Visual Studio project to be added to the currently open project. Entries are added for each configuration specified in the VS project, creating new configurations in the test project if necessary.

Edit

Opens the Project Editor.


Test Menu


Run All

Runs all the tests.

Run Selected

Runs the test or tests that are selected in the tree. If checkboxes are visible, any checked tests are run by preference. This is the same function provided by the Run button.

Run Failed

Runs only the tests that failed on the previous run.

Stop Run

Stops the test run. This is the same function provided by the Stop button.


Tools Menu


Test Assemblies...

Displays information about loaded test assemblies.

Save Results as XML

Opens a FileSave Dialog for saving the test results as an XML file.

Exception Details

Displays detailed information about the last exception.

Open Log Directory...

Opens the directory containing logs.

Settings...

Displays the Settings Dialog.

Addins...

Displays the Addins Dialog.


Help Menu


NUnit Help

Displays the NUnit documentation, if installed. Otherwise, attempts to connect to the NUnit web site.

About NUnit

Displays info about your version of NUnit and a link to the nunit.org site.

NUnit-2.6.0.12051/doc/maxtime.html0000664000175000017500000001134111720512704016255 0ustar jtaylorjtaylor NUnit - Maxtime

MaxtimeAttribute (NUnit 2.5)

The MaxtimeAttribute is used on test methods to specify a maximum time in milliseconds for a test case. If the test case takes longer than the specified time to complete, it is reported as a failure.

Example

[Test, Maxtime(2000)]
public void TimedTest()
{
    ...
}

Notes:

  1. Any assertion failures take precedence over the elapsed time check.
  2. This attribute does not cancel the test if the time is exceeded. It merely waits for the test to complete and then compares the elapsed time to the specified maximum. If you want to cancel long-running tests, see TimeoutAttribute.
NUnit-2.6.0.12051/doc/guiCommandLine.html0000664000175000017500000002153211720512704017507 0ustar jtaylorjtaylor NUnit - GuiCommandLine

NUnit Command Line Options

The forms interface may be run with or without the name of a file containing tests on the command line. If the program is started without any file specified, it automatically loads the most recently loaded assembly.

Note: Options that take values may use an equal sign, a colon or a space to separate the option from its value.

Note: Under the Windows operating system, options may be prefixed by either a forward slash or a hyphen. Under Linux, a hyphen must be used. Options that take values may use an equal sign, a colon or a space to separate the option from its value.

Run without loading an Assembly

To suppress loading of the most recent assembly, use the /noload switch:

        nunit /noload

Specifying an Assembly

The other option is to specify an assembly or project file name on the command line. The following will start the forms interface with the assembly nunit.tests.dll:

        nunit nunit.tests.dll

The following will start the forms interface loading the same assembly through its Visual Studio project definition:

        nunit nunit.tests.csproj

Assuming an NUnit test project has been created containing the assembly, the following will again load nunit.tests.dll:

        nunit nunit.tests.nunit

Specifying an Assembly and a Fixture

When specifying a a fixture, you must give the full name of the test fixture along with the containing assembly. For example, to load only the NUnit.Tests.AssertionTests in the nunit.tests.dll assembly use the following command:

        nunit /fixture:NUnit.Tests.AssertionTests nunit.tests.dll

The name specified after the /fixture option may be that of a TestFixture class, or a namespace. If a namespace is given, then all fixtures under that namespace are loaded. This option may be used with Visual Studio or NUnit projects as well.

Specifying Test Categories to Include or Exclude

NUnit provides CategoryAttribute for use in marking tests as belonging to one or more categories. Categories may be included or excluded in a test run using the /include or /exclude options. The following command starts the gui with only the tests in the BaseLine category selected:

        nunit myassembly.dll /include:BaseLine

The following command selects all tests except those in the Database category:

        nunit myassembly.dll /exclude:Database

Multiple categories may be specified on either option, by using commas to separate them.

Note: At this time, the /include and /exclude options may not be combined on the command line.

Load and Run All Tests

Normally, nunit only loads an assembly and then waits for the user to click on the Run button. If you wish to have the tests run immediately, use the /run option:
        nunit nunit.tests.dll /run

Load and Run Selected Tests

To load and immediately rerun the last selected tests, use the /runselected option:
        nunit nunit.tests.dll /runselected

Note: If no selection has been saved, this option works just like /run.

Specifying which Configuration to Load

When loading a Visual Studio project or an NUnit project, the first configuration found will be loaded by default. Usually this is Debug. The configuration loaded may be controlled using the /config switch. The following will load the Release configuration of the nunit.tests.dll:

        nunit nunit.tests.csproj /config:Release

Note: This option has no effect when loading an assembly directly.

Specifying Multiple Assemblies

The forms interface does not currently provide for specifying more than one assembly on the command line. Multiple-assembly projects must be loaded by specifying the name of a Visual Studio solution file or an NUnit test project.

Clearing the ShadowCopy Cache

The /cleanup option erases the shadow copy cache and exits.

Displaying Help

The /help or /? option displays a message box containing a brief help message.

NUnit-2.6.0.12051/doc/equalityAsserts.html0000664000175000017500000002030311720512704020011 0ustar jtaylorjtaylor NUnit - EqualityAsserts

Equality Asserts

These methods test whether the two arguments are equal. Overloaded methods are provided for common value types so that languages that don't automatically box values can use them directly.

Assert.AreEqual( int expected, int actual );
Assert.AreEqual( int expected, int actual, string message );
Assert.AreEqual( int expected, int actual, string message, 
                 params object[] parms );
				 
Assert.AreEqual( uint expected, uint actual );
Assert.AreEqual( uint expected, uint actual, string message );
Assert.AreEqual( uint expected, uint actual, string message, 
                 params object[] parms );

Assert.AreEqual( decimal expected, decimal actual );
Assert.AreEqual( decimal expected, decimal actual, string message );
Assert.AreEqual( decimal expected, decimal actual, string message, 
                 params object[] parms );

Assert.AreEqual( float expected, float actual, float tolerance );
Assert.AreEqual( float expected, float actual, float tolerance,
                 string message );
Assert.AreEqual( float expected, float actual, float tolerance,
                 string message, params object[] parms );

Assert.AreEqual( double expected, double actual, double tolerance );
Assert.AreEqual( double expected, double actual, double tolerance,
                 string message );
Assert.AreEqual( double expected, double actual, double tolerance,
                 string message, params object[] parms );

Assert.AreEqual( object expected, object actual );
Assert.AreEqual( object expected, object actual, string message );
Assert.AreEqual( object expected, object actual, string message, 
                 params object[] parms );

Assert.AreNotEqual( int expected, int actual );
Assert.AreNotEqual( int expected, int actual, string message );
Assert.AreNotEqual( int expected, int actual, string message,
                 params object[] parms );

Assert.AreNotEqual( long expected, long actual );
Assert.AreNotEqual( long expected, long actual, string message );
Assert.AreNotEqual( long expected, long actual, string message,
                 params object[] parms );

Assert.AreNotEqual( uint expected, uint actual );
Assert.AreNotEqual( uint expected, uint actual, string message );
Assert.AreNotEqual( uint expected, uint actual, string message,
                 params object[] parms );

Assert.AreNotEqual( ulong expected, ulong actual );
Assert.AreNotEqual( ulong expected, ulong actual, string message );
Assert.AreNotEqual( ulong expected, ulong actual, string message,
                 params object[] parms );

Assert.AreNotEqual( decimal expected, decimal actual );
Assert.AreNotEqual( decimal expected, decimal actual, string message );
Assert.AreNotEqual( decimal expected, decimal actual, string message,
                 params object[] parms );

Assert.AreNotEqual( float expected, float actual );
Assert.AreNotEqual( float expected, float actual, string message );
Assert.AreNotEqual( float expected, float actual, string message,
                 params object[] parms );

Assert.AreNotEqual( double expected, double actual );
Assert.AreNotEqual( double expected, double actual, string message );
Assert.AreNotEqual( double expected, double actual, string message,
                 params object[] parms );

Assert.AreNotEqual( object expected, object actual );
Assert.AreNotEqual( object expected, object actual, string message );
Assert.AreNotEqual( object expected, object actual, string message,
                 params object[] parms );

Comparing Numerics of Different Types

The method overloads that compare two objects make special provision so that numeric values of different types compare as expected. This assert succeeds:

        Assert.AreEqual( 5, 5.0 );

Comparing Floating Point Values

Values of type float and double are normally compared using an additional argument that indicates a tolerance within which they will be considered as equal. Beginning with NUnit 2.4.4, the value of GlobalSettings.DefaultFloatingPointTolerance is used if a third argument is not provided. In earlier versions, or if the default has not been set, values are tested for exact equality.

Special values are handled so that the following Asserts succeed:

        Assert.AreEqual( double.PositiveInfinity, double.PositiveInfinity );
        Assert.AreEqual( double.NegativeInfinity, double.NegativeInfinity );
        Assert.AreEqual( double.NaN, double.NaN );
Note: The last example above represents a change with NUnit 2.2.3. In earlier releases, the test would fail. We have made this change because the new behavior seems to be more useful in tests. To avoid confusion, we suggest using the new Assert.IsNaN method where appropriate.

Comparing Arrays and Collections

Since version 2.2, NUnit has been able to compare two single-dimensioned arrays. Beginning with version 2.4, multi-dimensioned arrays, nested arrays (arrays of arrays) and collections may be compared. Two arrays or collections will be treated as equal by Assert.AreEqual if they have the same dimensions and if each of the corresponding elements is equal.

NUnit-2.6.0.12051/doc/sequential.html0000664000175000017500000001166211720512704016771 0ustar jtaylorjtaylor NUnit - Sequential

SequentialAttribute (NUnit 2.5)

The SequentialAttribute is used on a test to specify that NUnit should generate test cases by selecting individual data items provided for the parameters of the test, without generating additional combinations.

Note: If parameter data is provided by multiple attributes, the order in which NUnit uses the data items is not guaranteed. However, it can be expected to remain constant for a given runtime and operating system.

Example

The following test will be executed three times, as follows:

	MyTest(1, "A")
	MyTest(2, "B")
	MyTest(3, null)
[Test, Sequential]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    ...
}

See also...

NUnit-2.6.0.12051/doc/extensibility.html0000664000175000017500000000555411720512704017516 0ustar jtaylorjtaylor NUnit - Extensibility

NUnit Extensibility

NUnit is designed to be extended in a number of ways.

Extensions to the NUnit framework - the part of NUnit that is referenced by tests - usually take the form of Custom Constraints, written by users to encapsulate tests that pertain to their specific projects.

Extending the features found within NUnit itself depends on the use of NUnit Addins. Currently, The Addin mechanism only supports extensions to the NUnit core - the part of NUnit that builds and executes test suites. However, the API that is used provides for the future ability to extend the client side of NUnit, including the GUI.

NUnit-2.6.0.12051/NUnitTests.nunit0000664000175000017500000000300011676064722016322 0ustar jtaylorjtaylor NUnit-2.6.0.12051/nunit.snk0000664000175000017500000000075211504175260015036 0ustar jtaylorjtaylor$RSA2J 5Km 9@ j2v>-ri ^V<㓬=֢ gn&FhIaR_uF+J|1 ВQmR3GKOF c! 7:#1Vdz6!ͧ3 IbexL:k|+W]n-_9"nE;ν+Z) i0{,58Zsr2GHZYDgsb,1烵?ϤL#W;aY#P箎ixA?ʕAYq%X[3OCj*Mx!Geto7[!1\4DH(9pK fTqQJBq[i~=UHGZG/b/3/\>eNojQ/G\[@Mţč0Ԏ}MrG_KՌux!K.r"w_1/N NUnit-2.6.0.12051/install/nunit-gui.wxs0000664000175000017500000002166111713304232017311 0ustar jtaylorjtaylor FRAMEWORK20 MONODIRECTORY NUnit-2.6.0.12051/install/tests.wxs0000664000175000017500000000256111711735612016542 0ustar jtaylorjtaylor NUnit-2.6.0.12051/install/NUnit.wxs0000664000175000017500000002713011713315336016433 0ustar jtaylorjtaylor FRAMEWORK20 OR FRAMEWORK40 OR MONODIRECTORY NUnit-2.6.0.12051/install/samples.wxs0000664000175000017500000002714111713267050017043 0ustar jtaylorjtaylor NUnit-2.6.0.12051/license.rtf0000664000175000017500000000263311712221132015312 0ustar jtaylorjtaylor{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\froman\fprq2\fcharset0 Times New Roman;}} {\*\generator Msftedit 5.41.21.2509;}\viewkind4\uc1\pard\f0\fs20 Copyright \'a9 2002-2012 Charlie Poole\par Copyright \'a9 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov\par Copyright \'a9 2000-2002 Philip A. Craig\par \par This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.\par \par Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:\par \par 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required.\par \par Portions Copyright \'a9 2002-2012 Charlie Poole or Copyright \'a9 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright \'a9 2000-2002 Philip A. Craig\par \par 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\par \par 3. This notice may not be removed or altered from any source distribution.\f1\par } NUnit-2.6.0.12051/lib/0000775000175000017500000000000011742560362013733 5ustar jtaylorjtaylorNUnit-2.6.0.12051/lib/Rhino.Mocks.xml0000664000175000017500000101540011544330406016602 0ustar jtaylorjtaylor Rhino.Mocks Defines constraints and return values for arguments of a mock. Only use Arg inside a method call on a mock that is recording. Example: ExpectCall( mock.foo( Arg<int>.Is.GreaterThan(2), Arg<string>.Is.Anything )); Use Arg.Text for string specific constraints Use Arg<ListClass>.List for list specific constraints Register the predicate as a constraint for the current call. The predicate. default(T) Allow you to use code to create constraints demo.AssertWasCalled(x => x.Bar(Arg{string}.Matches(a => a.StartsWith("b") && a.Contains("ba")))); Define a complex constraint for this argument by passing several constraints combined with operators. (Use Is in simple cases.) Example: Arg<string>.Matches(Is.Equal("Hello") || Text.EndsWith("u")); Constraints using Is, Text and List Dummy to satisfy the compiler Define a Ref argument. Constraints for this argument value returned by the mock Define a out parameter. Use it together with the keyword out and use the Dummy field available by the return value. Example: mock.foo( out Arg<string>.Out("hello").Dummy ); Define a simple constraint for this argument. (Use Matches in simple cases.) Example: Arg<int>.Is.Anthing Arg<string>.Is.Equal("hello") Define Constraints on list arguments. Use the Arg class (without generic) to define Text constraints Evaluate an equal constraint for . The object the parameter should equal to Define constraints on text arguments. Used to manage the static state of the Arg<T> class"/> Resets the static state Returns return values for the out and ref parameters Note: the array returned has the size of the number of out and ref argument definitions Returns the constraints for all arguments. Out arguments have an Is.Anything constraint and are also in the list. What should BackToRecord clear Retain all expectations and behaviors and return to mock All expectations Event subscribers for this instance Methods that should be forwarded to the base class implementation Properties that should behave like properties Remove all the behavior of the object Interface for constraints Determines if the object pass the constraints And operator for constraints Not operator for constraints Or operator for constraints Allow overriding of || or && Allow overriding of || or && Gets the message for this constraint Constrain that the public field has a specified value Constrain that the public field matches another constraint. Creates a new instance. Name of the public field. Constraint to place on the public field value. Creates a new instance, specifying a disambiguating for the public field. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Constraint to place on the public field value. Determines if the object passes the constraint. Gets the message for this constraint Creates a new instance. Name of the public field. Expected value. Creates a new instance, specifying a disambiguating for the public field. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Expected value. Constrain that the property has a specified value Constrain that the property matches another constraint. Creates a new instance. Name of the property. Constraint to place on the property value. Creates a new instance, specifying a disambiguating for the property. The type that declares the property, used to disambiguate between properties. Name of the property. Constraint to place on the property value. Determines if the object passes the constraint. Gets the message for this constraint Creates a new instance. Name of the property. Expected value. Creates a new instance, specifying a disambiguating for the property. The type that declares the property, used to disambiguate between properties. Name of the property. Expected value. Constrain that the parameter must be of the specified type Creates a new instance. Type. Determines if the object pass the constraints Gets the message for this constraint Constraint that determines whether an object is the same object as another. Creates a new instance. Obj. Determines if the object passes the constraints. Gets the message for this constraint. Evaluate a parameter using constraints Create new instance Determines if the object pass the constraints Gets the message for this constraint A constraint based on lambda expression, we are using Expression{T} because we want to be able to get good error reporting on that. Initializes a new instance of the class. The expr. Determines if the object pass the constraints Gets the message for this constraint Constrain that the list contains the same items as the parameter list Creates a new instance. In list. Determines if the object pass the constraints Gets the message for this constraint Constrain that the parameter is one of the items in the list Creates a new instance. In list. Determines if the object pass the constraints Gets the message for this constraint Constrain that the object is inside the parameter list Creates a new instance. In list. Determines if the object pass the constraints Gets the message for this constraint Applies another AbstractConstraint to the collection count. Creates a new instance. The constraint that should be applied to the collection count. Determines if the parameter conforms to this constraint. Gets the message for this constraint. Applies another AbstractConstraint to a specific list element. Creates a new instance. The zero-based index of the list element. The constraint that should be applied to the list element. Determines if the parameter conforms to this constraint. Gets the message for this constraint Applies another AbstractConstraint to a specific generic keyed list element. Creates a new instance. The key of the list element. The constraint that should be applied to the list element. Determines if the parameter conforms to this constraint. Gets the message for this constraint Constrains that all elements are in the parameter list Initializes a new instance of the class. The these. Determines if the object pass the constraints Gets the message for this constraint Combines two constraints, constraint pass if either is fine. Creates a new instance. C1. C2. Determines if the object pass the constraints Gets the message for this constraint Negate a constraint Creates a new instance. C1. Determines if the object pass the constraints Gets the message for this constraint Combines two constraints Creates a new instance. C1. C2. Determines if the object pass the constraints Gets the message for this constraint Constrain the argument to validate according to regex pattern Creates a new instance. Pattern. Determines if the object pass the constraints Gets the message for this constraint Constraint that evaluate whatever an argument contains the specified string. Creates a new instance. Inner string. Determines if the object pass the constraints Gets the message for this constraint Constraint that evaluate whatever an argument ends with the specified string Creates a new instance. End. Determines if the object pass the constraints Gets the message for this constraint Constraint that evaluate whatever an argument start with the specified string Creates a new instance. Start. Determines if the object pass the constraints Gets the message for this constraint Constraint that evaluate whatever an object equals another Creates a new instance. Obj. Determines if the object pass the constraints Gets the message for this constraint Constraint that always returns true Determines if the object pass the constraints Gets the message for this constraint Constraint that evaluate whatever a comparable is greater than another Creates a new instance. Determines if the object pass the constraints Gets the message for this constraint Initializes a new constraint object. The expected object, The actual object is passed in as a parameter to the method Evaluate this constraint. The actual object that was passed in the method call to the mock. True when the constraint is met, else false. Checks if the properties of the object are the same as the properies of the object. The expected object The actual object True when both objects have the same values, else False. This is the real heart of the beast. Used by CheckReferenceType to check all properties of the reference type. The expected object The actual object True when both objects have the same values, else False. Used by CheckReferenceType to check all fields of the reference type. The expected object The actual object True when both objects have the same values, else False. Checks the items of both collections The expected collection True if both collections contain the same items in the same order. Builds a propertyname from the Stack _properties like 'Order.Product.Price' to be used in the error message. A nested property name. Rhino.Mocks uses this property to generate an error message. A message telling the tester why the constraint failed. Provides access to the constraintes defined in the class to be used in context with the syntax. The type of the argument Evaluate a greater than constraint for . The object the parameter should be greater than Evaluate a less than constraint for . The object the parameter should be less than Evaluate a less than or equal constraint for . The object the parameter should be less than or equal to Evaluate a greater than or equal constraint for . The object the parameter should be greater than or equal to Evaluate an equal constraint for . The object the parameter should equal to Evaluate a not equal constraint for . The object the parameter should not equal to Evaluate a same as constraint. The object the parameter should the same as. Evaluate a not same as constraint. The object the parameter should not be the same as. Throws NotSupportedException. Don't use Equals to define constraints. Use Equal instead. Serves as a hash function for a particular type. A hash code for the current . A constraints that accept anything A constraint that accept only nulls A constraint that accept only non null values A constraint that accept only value of the specified type. The check is performed on the type that has been defined as the argument type. Provides access to the constraints defined in the class to be used in context with the syntax. Determines whether the specified object is in the parameter. The parameter must be IEnumerable. Obj. Determines whatever the parameter is in the collection. Determines that the parameter collection is identical to the specified collection Determines that the parameter collection has the specified number of elements. The constraint that should be applied to the collection count. Determines that an element of the parameter collections conforms to another AbstractConstraint. The zero-based index of the list element. The constraint which should be applied to the list element. Determines that all elements of the specified collection are in the the parameter collection The collection to compare against The constraint which should be applied to the list parameter. Throws NotSupportedException. Don't use Equals to define constraints. Use Equal instead. Serves as a hash function for a particular type. A hash code for the current . Provides a dummy field to pass as out or ref argument. Dummy field to satisfy the compiler. Used for out and ref arguments. Central location for constraints for object's public fields Constrains the parameter to have a public field with the specified value Name of the public field. Expected value. Constrains the parameter to have a public field with the specified value. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Expected value. Constrains the parameter to have a public field satisfying a specified constraint. Name of the public field. Constraint for the public field. Constrains the parameter to have a public field satisfying a specified constraint. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Constraint for the public field. Determines whether the parameter has the specified public field and that it is null. Name of the public field. Determines whether the parameter has the specified public field and that it is null. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Determines whether the parameter has the specified public field and that it is not null. Name of the public field. Determines whether the parameter has the specified public field and that it is not null. The type that declares the public field, used to disambiguate between public fields. Name of the public field. Central location for constraints Evaluate a greater than constraint for . The object the parameter should be greater than Evaluate a less than constraint for . The object the parameter should be less than Evaluate a less than or equal constraint for . The object the parameter should be less than or equal to Evaluate a greater than or equal constraint for . The object the parameter should be greater than or equal to Evaluate an equal constraint for . The object the parameter should equal to Evaluate a not equal constraint for . The object the parameter should not equal to Evaluate a same as constraint. The object the parameter should the same as. Evaluate a not same as constraint. The object the parameter should not be the same as. A constraints that accept anything A constraint that accept only nulls A constraint that accept only non null values A constraint that accept only value of the specified type A constraint that accept only value of the specified type Evaluate a parameter using a predicate The predicate to use Central location for constraints about lists and collections Determines whether the specified obj is in the parameter. The parameter must be IEnumerable. Obj. Determines whatever the parameter is in the collection. Determines that the parameter collection is identical to the specified collection Determines that the parameter collection has the specified number of elements. The constraint that should be applied to the collection count. Determines that an element of the parameter collections conforms to another AbstractConstraint. The zero-based index of the list element. The constraint which should be applied to the list element. Determines that an element of the parameter collections conforms to another AbstractConstraint. The key of the element. The constraint which should be applied to the element. Determines that all elements of the specified collection are in the the parameter collection The collection to compare against The constraint which should be applied to the list parameter. Central location for constraints for object's properties Constrains the parameter to have property with the specified value Name of the property. Expected value. Constrains the parameter to have property with the specified value. The type that declares the property, used to disambiguate between properties. Name of the property. Expected value. Constrains the parameter to have a property satisfying a specified constraint. Name of the property. Constraint for the property. Constrains the parameter to have a property satisfying a specified constraint. The type that declares the property, used to disambiguate between properties. Name of the property. Constraint for the property. Determines whether the parameter has the specified property and that it is null. Name of the property. Determines whether the parameter has the specified property and that it is null. The type that declares the property, used to disambiguate between properties. Name of the property. Determines whether the parameter has the specified property and that it is not null. Name of the property. Determines whether the parameter has the specified property and that it is not null. The type that declares the property, used to disambiguate between properties. Name of the property. constraints the parameter to have the exact same property values as the expected object. An object, of the same type as the parameter, whose properties are set with the expected values. An instance of the constraint that will do the actual check. The parameter's public property values and public field values will be matched against the expected object's public property values and public field values. The first mismatch will be reported and no further matching is done. The matching is recursive for any property or field that has properties or fields of it's own. Collections are supported through IEnumerable, which means the constraint will check if the actual and expected collection contain the same values in the same order, where the values contained by the collection can have properties and fields of their own that will be checked as well because of the recursive nature of this constraint. Central location for all text related constraints Constrain the argument to starts with the specified string Constrain the argument to end with the specified string Constrain the argument to contain the specified string Constrain the argument to validate according to regex pattern Provides access to the constraintes defined in the class to be used in context with the syntax. Constrain the argument to starts with the specified string Constrain the argument to end with the specified string Constrain the argument to contain the specified string Constrain the argument to validate according to regex pattern Throws NotSupportedException. Don't use Equals to define constraints. Use Equal instead. Serves as a hash function for a particular type. A hash code for the current . This class defines a lot of method signatures, which we will use to allow compatability on net-2.0 dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy Allows expectations to be set on methods that should never be called. For methods with void return value, you need to use LastCall or DoNotExpect.Call() with a delegate. Sets LastCall.Repeat.Never() on /any/ proxy on /any/ repository on the current thread. This method if not safe for multi threading scenarios. Accepts a delegate that will execute inside the method which LastCall.Repeat.Never() will be applied to. It is expected to be used with anonymous delegates / lambda expressions and only one method should be called. IService mockSrv = mocks.CreateMock(typeof(IService)) as IService; DoNotExpect.Call(delegate{ mockSrv.Stop(); }); ... An expectaton violation was detected. Creates a new instance. Message. Serialization constructor Signals that an object was call on a mock repository which doesn't belong to this mock repository or not a mock Creates a new instance. Message. Serialization constructor Allows to set expectation on methods that has return values. For methods with void return value, you need to use LastCall The method options for the last call on /any/ proxy on /any/ repository on the current thread. This method if not safe for multi threading scenarios, use . Accepts a delegate that will execute inside the method, and then return the resulting instance. It is expected to be used with anonymous delegates / lambda expressions and only one method should be called. IService mockSrv = mocks.CreateMock(typeof(IService)) as IService; Expect.Call(delegate{ mockSrv.Start(); }).Throw(new NetworkException()); ... Get the method options for the last method call on the mockInstance. A delegate that can be used to get better syntax on Expect.Call(delegate { foo.DoSomething(); }); Abstract class that holds common information for expectations. Interface to validate that a method call is correct. Validate the arguments for the method. This method can be called numerous times, so be careful about side effects The arguments with which the method was called Add an actual method call to this expectation Returns the return value or throw the exception and setup any output / ref parameters that has been set. Builds the verification failure message. Gets the error message. Range of expected calls Number of call actually made for this method If this expectation is still waiting for calls. The return value for a method matching this expectation Gets or sets the exception to throw on a method matching this expectation. Gets a value indicating whether this instance's action is staisfied. A staisfied instance means that there are no more requirements from this method. A method with non void return value must register either a return value or an exception to throw. Gets the method this expectation is for. Gets or sets what special condtions there are for this method repeating. Gets a value indicating whether this expectation was satisfied Specify whatever this expectation has a return value set You can't check ReturnValue for this because a valid return value include null. An action to execute when the method is matched. Set the out / ref parameters for the method call. The indexing is zero based and ignores any non out/ref parameter. It is possible not to pass all the parameters. This method can be called only once. Documentation Message Gets the invocation for this expectation The invocation. Occurs when the exceptation is match on a method call Allow to set the return value in the future, if it was already set. Number of actuall calls made that passed this expectation Range of expected calls that should pass this expectation. The return value for a method matching this expectation The exception to throw on a method matching this expectation. The method this expectation is for. The return value for this method was set Whether this method will repeat unlimited number of times. A delegate that will be run when the expectation is matched. The arguments that matched this expectation. Documentation message The method originalInvocation Get the hash code Add an actual actualMethodCall call to this expectation Builds the verification failure message. Returns the return value or throw the exception and setup output / ref parameters Validate the arguments for the method on the child methods The arguments with which the method was called Creates a new instance. The originalInvocation for this method, required because it contains the generic type infromation Number of method calls for this expectations Creates a new instance. Expectation. Validate the arguments for the method on the child methods The arguments with which the method was called Determines if this object equal to obj The error message for these arguments Asserts that the delegate has the same parameters as the expectation's method call Setter for the outpur / ref parameters for this expecataion. Can only be set once. Specify whether this expectation has a return value set You can't check ReturnValue for this because a valid return value include null. Gets the method this expectation is for. Gets the originalInvocation for this expectation The originalInvocation. Gets or sets what special condtions there are for this method Range of expected calls Number of call actually made for this method If this expectation is still waiting for calls. Gets a value indicating whether this expectation was satisfied The return value for a method matching this expectation An action to execute when the method is matched. Gets or sets the exception to throw on a method matching this expectation. Gets a value indicating whether this instance's action is staisfied. A staisfied instance means that there are no more requirements from this method. A method with non void return value must register either a return value or an exception to throw or an action to execute. Documentation message Occurs when the exceptation is match on a method call Allow to set the return value in the future, if it was already set. Gets the error message. Expectation that matches any arguments for the method. Creates a new instance. Invocation for this expectation Number of method calls for this expectations Creates a new instance. Expectation. Validate the arguments for the method. The arguments with which the method was called Determines if the object equal to expectation Get the hash code Gets the error message. Summary description for ArgsEqualExpectation. Creates a new instance. Expected args. The invocation for this expectation Number of method calls for this expectations Validate the arguments for the method. The arguments with which the method was called Determines if the object equal to expectation Get the hash code Gets the error message. Get the expected args. Call a specified callback to verify the expectation Creates a new instance. Expectation. Callback. Creates a new instance. Invocation for this expectation Callback. Number of method calls for this expectations Validate the arguments for the method on the child methods The arguments with which the method was called Determines if the object equal to expectation Get the hash code Gets the error message. Expect the method's arguments to match the contraints Creates a new instance. Invocation for this expectation Constraints. Number of method calls for this expectations Creates a new instance. Expectation. Constraints. Validate the arguments for the method. The arguments with which the method was called Determines if the object equal to expectation Get the hash code Gets the error message. Doesn't log anything, just makes happy noises Log expectations - allows to see what is going on inside Rhino Mocks Logs the expectation as is was recorded The invocation. The expectation. Logs the expectation as it was recorded The invocation. The expectation. Logs the unexpected method call. The invocation. The message. Logs the expectation as is was recorded The invocation. The expectation. Logs the expectation as it was recorded The invocation. The expectation. Logs the unexpected method call. The invocation. The message. Operation on a remoting proxy It is not possible to directly communicate to a real proxy via transparent proxy. Transparent proxy impersonates a user type and only methods of that user type are callable. The only methods that are guaranteed to exist on any transparent proxy are methods defined in Object: namely ToString(), GetHashCode(), and Equals()). These three methods are the only way to tell the real proxy to do something. Equals() is the most suitable of all, since it accepts an arbitrary object parameter. The RemotingProxy code is built so that if it is compared to an IRemotingProxyOperation, transparentProxy.Equals(operation) will call operation.Process(realProxy). This way we can retrieve a real proxy from transparent proxy and perform arbitrary operation on it. Generates remoting proxies and provides utility functions Create the proxy using remoting Check whether an object is a transparent proxy with a RemotingProxy behind it Object to check true if the object is a transparent proxy with a RemotingProxy instance behind it, false otherwise We use Equals() method to communicate with the real proxy behind the object. See IRemotingProxyOperation for more details Retrieve a mocked object from a transparent proxy Transparent proxy with a RemotingProxy instance behind it Mocked object associated with the proxy We use Equals() method to communicate with the real proxy behind the object. See IRemotingProxyOperation for more details Implementation of IInvocation based on remoting proxy Some methods are marked NotSupported since they either don't make sense for remoting proxies, or they are never called by Rhino Mocks Rudimetry implementation that simply logs methods calls as text. Initializes a new instance of the class. The writer. Logs the expectation as it was recorded The invocation. The expectation. Logs the expectation as it was recorded The invocation. The expectation. Logs the unexpected method call. The invocation. The message. Behave like a stub, all properties and events acts normally, methods calls return default values by default (but can use expectations to set them up), etc. Records all the expectations for a mock Different actions on this mock Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Verify that this mock expectations have passed. Verify that we can move to replay state and move to the reply state. Gets a mock state that match the original mock state of the object. Get the options for the last method call Set the exception to throw when Verify is called. This is used to report exception that may have happened but where caught in the code. This way, they are reported anyway when Verify() is called. This method is called to indicate that a property behavior call. This is done so we generate good error message in the common case of people using Stubbed properties with Return(). Gets the matching verify state for this state Get the options for the last method call Get the options for the last method call Set the exception to throw when Verify is called. This is used to report exception that may have happened but where caught in the code. This way, they are reported anyway when Verify() is called. This method is called to indicate that a property behavior call. This is done so we generate good error message in the common case of people using Stubbed properties with Return(). Creates a new instance. Repository. The proxy that generates the method calls Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Verify that we can move to replay state and move to the reply state. Verify that we can move to replay state and move to the reply state. Verify that this mock expectations have passed. Gets a mock state that match the original mock state of the object. Asserts the previous method is closed (had an expectation set on it so we can replay it correctly) Get the default call count range expectation Gets the last expectation. Gets the total method calls count. Get the options for the last method call Gets the matching verify state for this state Initializes a new instance of the class. The proxy that generates the method calls Repository. We don't care much about expectations here, so we will remove the expectation if it is not closed. Verify that we can move to replay state and move to the reply state. Get the default call count range expectation Validate expectations on recorded methods, but in general completely ignoring them. Similar to except that it would return a when BackToRecord is called. Validate all expectations on a mock The repository for this state The proxy object for this state Get the options for the last method call Creates a new instance. The previous state for this method Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Add a method call for this state' mock. This allows derived method to cleanly get a the setupresult behavior while adding their own. The invocation for this method The method that was called The arguments this method was called with Set the exception to throw when Verify is called. This is used to report exception that may have happened but where caught in the code. This way, they are reported anyway when Verify() is called. not relevant Verify that this mock expectations have passed. Verify that we can move to replay state and move to the reply state. Gets a mock state that match the original mock state of the object. Get the options for the last method call Gets the matching verify state for this state Initializes a new instance of the class. The previous state for this method Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Gets a mock state that matches the original mock state of the object. Write rhino mocks log info to the trace Initializes a new instance of the class. Initializes a new instance of the class. if set to true [log recorded]. if set to true [log replayed]. if set to true [log unexpected]. Logs the expectation as is was recorded The invocation. The expectation. Logs the expectation as it was recorded The invocation. The expectation. Logs the unexpected method call. The invocation. The message. Writes log information as stack traces about rhino mocks activity Allows to redirect output to a different location. Logs the expectation as is was recorded The invocation. The expectation. Logs the expectation as it was recorded The invocation. The expectation. Logs the unexpected method call. The invocation. The message. Marker interface used to indicate that this is a partial mock. Options for CallOriginalMethod No expectation is created, the method will be called directly Normal expectation is created, but when the method is later called, it will also call the original method This is a data structure that is used by to pass the current method to the relevant delegate Initializes a new instance of the class. The invocation. Gets the args for this method invocation Get the method that was caused this invocation Gets or sets the return value for this method invocation The return value. Adds optional new usage: using(mockRepository.Record()) { Expect.Call(mock.Method()).Return(retVal); } using(mockRepository.Playback()) { // Execute code } N.B. mockRepository.ReplayAll() and mockRepository.VerifyAll() calls are taken care of by Record/Playback Creates proxied instances of types. Generates a stub without needing a Arguments for 's constructor The of stub to create. The stub Generates a stub without needing a The of stub. Arguments for the 's constructor. The stub Generate a mock object without needing a type of mock object to create. Arguments for 's constructor the mock object Generate a multi-mock object without needing a The typeof object to generate a mock for. A second interface to generate a multi-mock for. Arguments for 's constructor the multi-mock object Generate a multi-mock object without without needing a The typeof object to generate a mock for. An interface to generate a multi-mock for. A second interface to generate a multi-mock for. Arguments for 's constructor the multi-mock object Creates a multi-mock without without needing a The type of mock to create, this can be a class Any extra interfaces to add to the multi-mock, these can only be interfaces. Arguments for 's constructor the multi-mock object Creates a strict mock without without needing a Any arguments required for the 's constructor The type of mock object to create. The mock object with strict replay semantics Creates a strict multi-mock without needing a Any arguments required for the 's constructor The type of mock object to create, this can be a class. An interface to generate a multi-mock for, this must be an interface! The multi-mock object with strict replay semantics Creates a strict multi-mock without needing a Any arguments required for the 's constructor The type of mock object to create, this can be a class. An interface to generate a multi-mock for, this must be an interface! A second interface to generate a multi-mock for, this must be an interface! The multi-mock object with strict replay semantics Creates a strict multi-mock without needing a The type of mock object to create, this can be a class Any extra interfaces to generate a multi-mock for, these must be interaces! Any arguments for the 's constructor The strict multi-mock object Generate a mock object with dynamic replay semantics and remoting without needing the mock repository Generate a mock object with strict replay semantics and remoting without needing the mock repository Helper method to create a mock object without a repository instance and put the object back into replay mode. The type of mock object to create A delegate that uses a mock repository instance to create the underlying mock The mock object in the replay mode. This is a map of types to ProxyGenerators. This is used to record the last repository that has a method called on it. this is used to get to the last proxy on this repository. For mock delegates, maps the proxy instance from intercepted invocations back to the delegate that was originally returned to client code, if any. All the proxies in the mock repositories This is here because we can't put it in any of the recorders, since repeatable methods have no orderring, and if we try to handle them using the usual manner, we would get into wierd situations where repeatable method that was defined in an orderring block doesn't exists until we enter this block. Creates a new instance. Move the repository to ordered mode Move the repository to un-ordered mode Creates a mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a strict mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a remoting mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a strict remoting mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a remoting mock for the specified type. Arguments for the class' constructor, if mocking a concrete class Creates a strict remoting mock for the specified type. Arguments for the class' constructor, if mocking a concrete class Creates a mock from several types, with strict semantics. Only may be a class. Creates a strict mock from several types, with strict semantics. Only may be a class. Creates a mock from several types, with strict semantics. Only may be a class. The main type to mock. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class. Creates a strict mock from several types, with strict semantics. Only may be a class. The main type to mock. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class. Creates a mock from several types, with dynamic semantics. Only may be a class. The main type to mock. Extra interface types to mock. Creates a mock from several types, with dynamic semantics. Only may be a class. The main type to mock. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class. Creates a dynamic mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a dynamic mock for the specified type. Type. Arguments for the class' constructor, if mocking a concrete class Creates a dynamic mock for the specified type. Arguments for the class' constructor, if mocking a concrete class Creates a mock object that defaults to calling the class methods if no expectation is set on the method. Type. Arguments for the class' constructor. Creates a mock object that defaults to calling the class methods. Type. Extra interface types to mock. Creates a mock object that defaults to calling the class methods. Type. Extra interface types to mock. Arguments for the class' constructor. Creates a mock object using remoting proxies Type to mock - must be MarshalByRefObject Mock object Proxy mock can mock non-virtual methods, but not static methods Creates the mock state for this proxy Cause the mock state to change to replay, any further call is compared to the ones that were called in the record state. This method *cannot* be called from inside an ordering. the object to move to replay state Cause the mock state to change to replay, any further call is compared to the ones that were called in the record state. the object to move to replay state Move the mocked object back to record state.You can (and it's recommended) to run {Verify()} before you use this method. Will delete all current expectations! Move the mocked object back to record state. Optionally, can delete all current expectations, but allows more granularity about how it would behave with regard to the object state. Verify that all the expectations for this object were fulfilled. the object to verify the expectations for Get the method options for the last call on mockedInstance. The mock object Method options for the last call Maps an invocation proxy back to the mock object instance that was originally returned to client code which might have been a delegate to this proxy. The mock object proxy from the intercepted invocation The mock object This is provided to allow advance extention functionality, where Rhino Mocks standard functionality is not enough. The type to mock Delegate that create the first state of the mocked object (usualy the record state). Additional types to be implemented, this can be only interfaces optional arguments for the constructor Method: GetMockedObject Get an IProxy from a mocked object instance, or throws if the object is not a mock object. Method: GetMockedObjectOrNull Get an IProxy from a mocked object instance, or null if the object is not a mock object. Pops the recorder. Pushes the recorder. New recorder. All the mock objects in this repository will be moved to record state. All the mock objects in this repository will be moved to record state. Replay all the mocks from this repository Verify all the mocks from this repository Gets the proxy generator for a specific type. Having a single ProxyGenerator with multiple types linearly degrades the performance so this implementation keeps one ProxyGenerator per type. Set the exception to be thrown when verified is called. Creates a mock for the spesified type with strict mocking semantics. Strict semantics means that any call that wasn't explicitly recorded is considered an error and would cause an exception to be thrown. Arguments for the class' constructor, if mocking a concrete class Creates a mock for the spesified type with strict mocking semantics. Strict semantics means that any call that wasn't explicitly recorded is considered an error and would cause an exception to be thrown. Arguments for the class' constructor, if mocking a concrete class Creates a dynamic mock for the specified type. Arguments for the class' constructor, if mocking a concrete class Creates a mock object from several types. Creates a strict mock object from several types. Create a mock object from several types with dynamic semantics. Create a mock object from several types with partial semantics. Create a mock object from several types with strict semantics. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class Create a strict mock object from several types with strict semantics. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class Create a mock object from several types with dynamic semantics. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class Create a mock object from several types with partial semantics. Extra interface types to mock. Arguments for the class' constructor, if mocking a concrete class Create a mock object with from a class that defaults to calling the class methods Arguments for the class' constructor, if mocking a concrete class Create a stub object, one that has properties and events ready for use, and can have methods called on it. It requires an explicit step in order to create an expectation for a stub. The arguments for constructor. Create a stub object, one that has properties and events ready for use, and can have methods called on it. It requires an explicit step in order to create an expectation for a stub. The type. The arguments for constructor. The stub Returns true if the passed mock is currently in replay mode. The mock to test. True if the mock is in replay mode, false otherwise. Determines whether the specified proxy is a stub. The proxy. Register a call on a prperty behavior Gets the recorder. Gets the replayer for this repository. Gets the last proxy which had a method call. Delegate: CreateMockState This is used internally to cleanly handle the creation of different RecordMockStates. A set of extension methods that adds Arrange Act Assert mode to Rhino Mocks Create an expectation on this mock for this action to occur The mock. The action. Reset all expectations on this mock object The mock. Reset the selected expectation on this mock object The mock. The options to reset the expectations on this mock. Cause the mock state to change to replay, any further call is compared to the ones that were called in the record state. the mocked object to move to replay state Gets the mock repository for this specificied mock object The mock. Create an expectation on this mock for this action to occur The mock. The action. Tell the mock object to perform a certain action when a matching method is called. Does not create an expectation for this method. The mock. The action. Tell the mock object to perform a certain action when a matching method is called. Does not create an expectation for this method. The mock. The action. Gets the arguments for calls made on this mock object and the method that was called in the action. The mock. The action. Here we will get all the arguments for all the calls made to DoSomething(int) var argsForCalls = foo54.GetArgumentsForCallsMadeOn(x => x.DoSomething(0)) Gets the arguments for calls made on this mock object and the method that was called in the action and matches the given constraints The mock. The action. The setup constraints. Here we will get all the arguments for all the calls made to DoSomething(int) var argsForCalls = foo54.GetArgumentsForCallsMadeOn(x => x.DoSomething(0)) Asserts that a particular method was called on this mock object The mock. The action. Asserts that a particular method was called on this mock object that match a particular constraint set. The mock. The action. The setup constraints. Asserts that a particular method was called on this mock object that match a particular constraint set. The mock. The action. Asserts that a particular method was called on this mock object that match a particular constraint set. The mock. The action. The setup constraints. Asserts that a particular method was NOT called on this mock object The mock. The action. Asserts that a particular method was NOT called on this mock object that match a particular constraint set. The mock. The action. The setup constraints. Asserts that a particular method was NOT called on this mock object The mock. The action. Asserts that a particular method was NOT called on this mock object The mock. The action. The setup constraints. Finds the approprite implementation type of this item. This is the class or an interface outside of the rhino mocks. The mocked obj. Verifies all expectations on this mock object The mock object. Gets the event raiser for the event that was called in the action passed The type of the event source. The mock object. The event subscription. Raise the specified event using the passed arguments. The even is extracted from the passed labmda The type of the event source. The mock object. The event subscription. The sender. The instance containing the event data. Raise the specified event using the passed arguments. The even is extracted from the passed labmda The type of the event source. The mock object. The event subscription. The args. TODO: Make this better! It currently breaks down when mocking classes or ABC's that call other virtual methods which are getting intercepted too. I wish we could just walk Expression{Action{Action{T}} to assert only a single method is being made. The workaround is to not call foo.AssertWasCalled .. rather foo.VerifyAllExpectations() The type of mock object The mock repository The actual mock object to assert expectations on. Fake type that disallow creating it. Should have been System.Type, but we can't use it. Utility class for dealing with messing generics scenarios. There are issues with trying to get this to work correctly with open generic types, since this is an edge case, I am letting the runtime handle it. Gets the real type, including de-constructing and constructing the type of generic methods parameters. The type. The invocation. Because we need to support complex types here (simple generics were handled above) we need to be aware of the following scenarios: List[T] and List[Foo[T]] ExpectationsList Dictionary Dictionary class Create a new instance of ProxyStateDictionary Allows to call a method and immediately get it's options. Interface to allow calling a method and immediately get it's options. Get the method options for the call The method call should go here, the return value is ignored Creates a new instance. Get the method options for the call The method call should go here, the return value is ignored Allows to call a method and immediately get it's options. Set the expected number for the call to Any() Creates a new instance. Proxy. Mocked instance. Get the method options for the call The method call should go here, the return value is ignored This class is reponsible for taking a delegate and creating a wrapper interface around it, so it can be mocked. The scope for all the delegate interfaces create by this mock repository. Gets a type with an "Invoke" method suitable for use as a target of the specified delegate type. Raise events for all subscribers for an event Raise events for all subscribers for an event Raise the event The most common form for the event handler signature Create an event raiser for the specified event on this instance. Creates a new instance of EventRaiser Raise the event The most common signature for events Here to allow intellisense to make better guesses about how it should suggest parameters. Allows to define what would happen when a method is called. Allows to define what would happen when a method is called. Set the return value for the method. The object the method will return IRepeat that defines how many times the method will return this value Allow to override this return value in the future IRepeat that defines how many times the method will return this value Throws the specified exception when the method is called. Exception to throw Ignores the arguments for this method. Any argument will be matched againt this method. Add constraints for the method's arguments. Set a callback method for the last call Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched and allow to optionally modify the invocation as needed Call the original method on the class, bypassing the mocking layers. Call the original method on the class, optionally bypassing the mocking layers. Use the property as a simple property, getting/setting the values without causing mock expectations. Expect last (property) call as property setting, ignore the argument given Expect last (property) call as property setting with a given argument. Get an event raiser for the last subscribed event. Set the parameter values for out and ref parameters. This is done using zero based indexing, and _ignoring_ any non out/ref parameter. Documentation message for the expectation Message Better syntax to define repeats. Allows to specify the number of time for method calls Repeat the method twice. Repeat the method once. Repeat the method at least once, then repeat as many time as it would like. Repeat the method any number of times. This has special affects in that this method would now ignore orderring. Set the range to repeat an action. Min. Max. Set the amount of times to repeat an action. This method must not appear in the replay state. This has special affects in that this method would now ignore orderring. Creates a new instance. the repository for this expectation the recorder for this proxy the proxy for this expectation Expectation. Add constraints for the method's arguments. Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Set the return value for the method. The object the method will return IRepeat that defines how many times the method will return this value Set the return value for the method, but allow to override this return value in the future IRepeat that defines how many times the method will return this value Throws the specified exception when the method is called. Exception to throw Ignores the arguments for this method. Any argument will be matched againt this method. Call the original method on the class, bypassing the mocking layers. Call the original method on the class, optionally bypassing the mocking layers Use the property as a simple property, getting/setting the values without causing mock expectations. Expect last (property) call as property setting, ignore the argument given Expect last (property) call as property setting with a given argument. Gets the event raiser for the last event Set the parameter values for out and ref parameters. This is done using zero based indexing, and _ignoring_ any non out/ref parameter. Repeat the method twice. Repeat the method once. Repeat the method at least once, then repeat as many time as it would like. This method must not appear in the replay state. Documentation message for the expectation Message Repeat the method any number of times. Set the range to repeat an action. Min. Max. Set the amount of times to repeat an action. Better syntax to define repeats. This class will provide hash code for hashtables without needing to call the GetHashCode() on the object, which may very well be mocked. This class has no state so it is a singelton to avoid creating a lot of objects that does the exact same thing. See flyweight patterns. Get the hash code for a proxy object without calling GetHashCode() on the object. Compares two instances of mocked objects Compare two mocked objects The next hash code value for a mock object. This is safe for multi threading. The sole instance of This is a dummy type that is used merely to give DynamicProxy the proxy instance that it needs to create IProxy's types. Interface to find the repository of a mocked object Return true if it should call the original method on the object instead of pass it to the message chain. The method to call Register a method to be called on the object directly Register a property on the object that will behave as a simple property Check if the method was registered as a property method. Do get/set on the property, according to need. Do add/remove on the event Get the subscribers of a spesific event Gets the declaring type of the method, taking into acccount the possible generic parameters that it was created with. Clears the state of the object, remove original calls, property behavior, subscribed events, etc. Get all the method calls arguments that were made against this object with the specificed method. Only method calls in replay mode are counted Records the method call Mocks that are tied to this mock lifestyle The unique hash code of this mock, which is not related to the value of the GetHashCode() call on the object. Gets the repository. Gets the implemented types by this mocked object The implemented. Gets or sets the constructor arguments. The constructor arguments. The mocked instance that this is representing Create a new instance of Return true if it should call the original method on the object instead of pass it to the message chain. The method to call Register a method to be called on the object directly Register a property on the object that will behave as a simple property Return true if there is already a value for the property Check if the method was registered as a property method. Do get/set on the property, according to need. Do add/remove on the event Get the subscribers of a spesific event Gets the declaring type of the method, taking into acccount the possible generic parameters that it was created with. Get all the method calls arguments that were made against this object with the specificed method. Only method calls in replay mode are counted Records the method call Clears the state of the object, remove original calls, property behavior, subscribed events, etc. Mocks that are tied to this mock lifestyle The unique hash code of this proxy, which is not related to the value of the GetHashCode() call on the object. Gets the repository. Gets or sets the constructor arguments. The constructor arguments. The mocked instance that this is representing Gets the implemented types by this mocked object The implemented. Range for expected method calls Creates a new instance. Min. Max. Return the string representation of this range. Gets or sets the min. Gets or sets the max. Records all the expectations for a mock and return a ReplayDynamicMockState when Replay() is called. Creates a new instance. Repository. The proxy that generates the method calls Verify that we can move to replay state and move to the reply state. Get the default call count range expectation Gets a mock state that match the original mock state of the object. Records all the expectations for a mock and return a ReplayPartialMockState when Replay() is called. Creates a new instance. Repository. The proxy that generates the method calls Verify that we can move to replay state and move to the reply state. Gets a mock state that matches the original mock state of the object. Options for special repeat option This method can be called only as many times as the IMethodOptions.Expect allows. This method should never be called This method can be call any number of times This method will call the original method This method will call the original method, bypassing the mocking layer This method will simulate simple property behavior Validate all expectations on a mock and ignores calls to any method that was not setup properly. Creates a new instance. The previous state for this method Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Gets a mock state that match the original mock state of the object. Validate all expectations on a mock and ignores calls to any method that was not setup properly. Creates a new instance. The previous state for this method Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Gets a mock state that match the original mock state of the object. Summary description for RhinoInterceptor. Creates a new instance. Intercept a method call and direct it to the repository. Validate arguments for methods Validate that the passed argument is not null. The object to validate The name of the argument If the obj is null, an ArgumentNullException with the passed name is thrown. Validate that the arguments are equal. Expected args. Actual Args. Validate that the two arguments are equals, including validation for when the arguments are collections, in which case it will validate their values. This method is safe for use even if any of the objects is a mocked object that override equals. Throw an object already verified when accessed Create a new instance of VerifiedMockState The previous mock state, used to get the initial record state Add a method call for this state' mock. The invocation for this method The method that was called The arguments this method was called with Verify that this mock expectations have passed. Verify that we can move to replay state and move to the reply state. Gets a mock state that match the original mock state of the object. Get the options for the last method call Set the exception to throw when Verify is called. This is used to report exception that may have happened but where caught in the code. This way, they are reported anyway when Verify() is called. not relevant Gets the matching verify state for this state Get the options for the last method call Records the actions on all the mocks created by a repository. Records the specified call with the specified args on the mocked object. Get the expectation for this method on this object with this arguments This check the methods that were setup using the SetupResult.For() or LastCall.Repeat.Any() and that bypass the whole expectation model. Gets the all expectations for a mocked object and method combination, regardless of the expected arguments / callbacks / contraints. Mocked object. Method. List of all relevant expectation Gets the all expectations for proxy. Mocked object. List of all relevant expectation Removes all the repeatable expectations for proxy. Mocked object. Replaces the old expectation with the new expectation for the specified proxy/method pair. This replace ALL expectations that equal to old expectations. Proxy. Method. Old expectation. New expectation. Adds the recorder and turn it into the active recorder. Recorder. Moves to previous recorder. Gets the recorded expectation or null. Gets the next expected calls string. Moves to parent recorder. Set the expectation so it can repeat any number of times. Removes the expectation from the recorder Clear the replayer to call (and all its chain of replayers) This also removes it from the list of expectations, so it will never be considered again Get the expectation for this method on this object with this arguments Gets a value indicating whether this instance has expectations that weren't satisfied yet. true if this instance has expectations; otherwise, false. Allows to set various options for the last method call on a specified object. If the method has a return value, it's recommended to use Expect Allows to get an interface to work on the last call. The mocked object Interface that allows to set options for the last method call on this object Set the return value for the method. The object the method will return IRepeat that defines how many times the method will return this value Set the return value for the method. This overload is needed for LastCall.Return(null) The object the method will return IRepeat that defines how many times the method will return this value Throws the specified exception when the method is called. Exception to throw Ignores the arguments for this method. Any argument will be matched againt this method. Add constraints for the method's arguments. Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Set a callback method for the last call Call the original method on the class, bypassing the mocking layers, for the last call. Call the original method on the class, optionally bypassing the mocking layers, for the last call. Set a delegate to be called when the expectation is matched. The delegate return value will be returned from the expectation. Gets an interface that will raise the last event when called. Set the parameter values for out and ref parameters. This is done using zero based indexing, and _ignoring_ any non out/ref parameter. Documentation message for the expectation Message Use the property as a simple property, getting/setting the values without causing mock expectations. Better syntax to define repeats. Base class for method recorders, handle delegating to inner recorder if needed. List of the expected actions on for this recorder The legal values are: * Expectations * Method Recorders The current recorder. The current replayer; The parent recorder of this one, may be null. This contains a list of all the replayers that should be ignored for a spesific method call. A replayer gets into this list by calling ClearReplayerToCall() on its parent. This list is Clear()ed on each new invocation. All the repeatable methods calls. Counts the recursion depth of the current expectation search stack Creates a new instance. Creates a new instance. Parent recorder. Repeatable methods Records the specified call with the specified args on the mocked object. Get the expectation for this method on this object with this arguments Gets the all expectations for a mocked object and method combination, regardless of the expected arguments / callbacks / contraints. Mocked object. Method. List of all relevant expectation Gets the all expectations for proxy. Mocked object. List of all relevant expectation Replaces the old expectation with the new expectation for the specified proxy/method pair. This replace ALL expectations that equal to old expectations. Proxy. Method. Old expectation. New expectation. Remove the all repeatable expectations for proxy. Mocked object. Set the expectation so it can repeat any number of times. Removes the expectation from the recorder Adds the recorder and turn it into the active recorder. Recorder. Moves to previous recorder. Moves to parent recorder. Gets the recorded expectation or null. Clear the replayer to call (and all its chain of replayers). This also removes it from the list of expectations, so it will never be considered again Get the expectation for this method on this object with this arguments Gets the next expected calls string. Handles the real getting of the recorded expectation or null. Handle the real execution of this method for the derived class Handle the real execution of this method for the derived class Handle the real execution of this method for the derived class Handle the real execution of this method for the derived class Handle the real execution of this method for the derived class Handle the real execution of this method for the derived class Should this replayer be considered valid for this call? This check the methods that were setup using the SetupResult.For() or LastCall.Repeat.Any() and that bypass the whole expectation model. Gets a value indicating whether this instance has expectations that weren't satisfied yet. true if this instance has expectations; otherwise, false. Handle the real execution of this method for the derived class Ordered collection of methods, methods must arrive in specified order in order to pass. Unordered collection of method records, any expectation that exist will be matched. The parent recorder we have redirected to. Useful for certain edge cases in orderring. See: FieldProblem_Entropy for the details. Creates a new instance. Parent recorder. Repeatable methods Creates a new instance. Records the specified call with the specified args on the mocked object. Mocked object. Method. Expectation. Get the expectation for this method on this object with this arguments Invocation for this method Mocked object. Method. Args. True is the call was recorded, false otherwise Gets the all expectations for a mocked object and method combination, regardless of the expected arguments / callbacks / contraints. Mocked object. Method. List of all relevant expectation Gets the all expectations for proxy. Mocked object. List of all relevant expectation Replaces the old expectation with the new expectation for the specified proxy/method pair. This replace ALL expectations that equal to old expectations. Proxy. Method. Old expectation. New expectation. Handle the real execution of this method for the derived class Handles the real getting of the recorded expectation or null. Handle the real execution of this method for the derived class Gets the next expected calls string. Create an exception for an unexpected method call. Gets a value indicating whether this instance has expectations that weren't satisfied yet. true if this instance has expectations; otherwise, false. Creates a new instance. Parent recorder. Repetable methods Creates a new instance. Handles the real getting of the recorded expectation or null. Get the expectation for this method on this object with this arguments Gets the next expected calls string. Hold an expectation for a method call on an object Creates a new instance. Proxy. Method. Expectation. Determines if the object equal to this instance Obj. Gets the hash code. Gets the proxy. Gets the method. Gets the expectation. Holds a pair of mocked object and a method and allows to compare them against each other. This allows us to have a distinction between mockOne.MyMethod() and mockTwo.MyMethod()... Creates a new instance. Proxy. Method. Determines whatever obj equals to this instance. ProxyMethodPairs are equal when they point to the same /instance/ of an object, and to the same method. Obj. Gets the hash code. Gets the proxy. Gets the method. Change the recorder from ordered to unordered and vice versa Creates a new instance. Disposes this instance. Accessor for the current mocker The current mocker Used for [assembly: InternalsVisibleTo(RhinoMocks.StrongName)] Used for [assembly: InternalsVisibleTo(RhinoMocks.NormalName)] Strong name for the Dynamic Proxy assemblies. Used for InternalsVisibleTo specification. Normal name for dynamic proxy assemblies. Used for InternalsVisibleTo specification. Logs all method calls for methods Setup method calls to repeat any number of times. Get the method options and set the last method call to repeat any number of times. This also means that the method would transcend ordering Get the method options for the last method call on the mockInstance and set it to repeat any number of times. This also means that the method would transcend ordering Utility class for working with method calls. Return the string representation of a method call and its arguments. The method The method arguments Invocation of the method, used to get the generics arguments Delegate to format the parameter The string representation of this method call Return the string representation of a method call and its arguments. The invocation of the method, used to get the generic parameters The method The method arguments The string representation of this method call Delegate to format the argument for the string representation of the method call. Utility to get the default value for a type The default value for a type. Null for reference types and void 0 for value types. First element for enums Note that we need to get the value even for opened generic types, such as those from generic methods. Type. The invocation. the default value Allows easier access to MockRepository, works closely with Mocker.Current to allow access to a context where the mock repository is automatially verified at the end of the code block. Initialize a code block where Mocker.Current is initialized. At the end of the code block, all the expectation will be verified. This overload will create a new MockRepository. The code that will be executed under the mock context Initialize a code block where Mocker.Current is initialized. At the end of the code block, all the expectation will be verified. This overload will create a new MockRepository. The mock repository to use, at the end of the code block, VerifyAll() will be called on the repository. The code that will be executed under the mock context Create a FluentMocker The mock repository to use. A method with no arguments and no return value that will be called under the mock context. FluentMocker implements some kind of fluent interface attempt for saying "With the Mocks [mocks], Expecting (in same order) [things] verify [that]." Interface to verify previously defined expectations Verifies if a piece of code Defines unordered expectations A delegate describing the expectations an IMockVerifier Defines ordered expectations A delegate describing the expectations an IMockVerifier Verifies previously defined expectations This delegate is compatible with the System.Func{T,R} signature We have to define our own to get compatability with 2.0 This attribute is here so we can get better Pex integration Using this means that Pex will not try to inspect the work of the actual proxies being generated by Rhino Mocks NUnit-2.6.0.12051/lib/3.5/0000775000175000017500000000000011742560362014240 5ustar jtaylorjtaylorNUnit-2.6.0.12051/lib/3.5/NSubstitute.xml0000664000175000017500000001320611544330406017247 0ustar jtaylorjtaylor NSubstitute Raise an event for an EventHandler<TEventArgs> event with the provided and . Raise an event for an EventHandler<TEventArgs> event with the substitute as the sender and the provided . Raise an event for an EventHandler<EventArgsT> event with the substitute as the sender and with a default instance of . Raise an event for an EventHandler or EventHandler<EventArgs> event with the substitute as the sender and with empty EventArgs. Raise an event of type with the provided arguments. If no arguments are provided NSubstitute will try and provide reasonble defaults. Create a substitute for one or more types. For example: Substitute.For<ISomeType>() Substitute for an interface or class. Be careful when specifying a class, as all non-virtual members will actually be executed. Only virtual members can be recorded or have return values specified. The type of interface or class to substitute. Arguments required to construct a class being substituted. Not required for interfaces or classes with default constructors. A substitute for the interface or class. Substitute for multiple interfaces or a class that implements an interface. At most one class can be specified. Be careful when specifying a class, as all non-virtual members will actually be executed. Only virtual members can be recorded or have return values specified. The type of interface or class to substitute. An additional interface or class (maximum of one class) the substitute should implement. Arguments required to construct a class being substituted. Not required for interfaces or classes with default constructors. A substitute of type T1, that also implements T2. Substitute for multiple interfaces or a class that implements multiple interfaces. At most one class can be specified. If additional interfaces are required use the overload. Be careful when specifying a class, as all non-virtual members will actually be executed. Only virtual members can be recorded or have return values specified. The type of interface or class to substitute. An additional interface or class (maximum of one class) the substitute should implement. An additional interface or class (maximum of one class) the substitute should implement. Arguments required to construct a class being substituted. Not required for interfaces or classes with default constructors. A substitute of type T1, that also implements T2 and T3. Substitute for multiple interfaces or a class that implements multiple interfaces. At most one class can be specified. Be careful when specifying a class, as all non-virtual members will actually be executed. Only virtual members can be recorded or have return values specified. The types of interfaces or a type of class and multiple interfaces the substitute should implement. Arguments required to construct a class being substituted. Not required for interfaces or classes with default constructors. A substitute implementing the specified types. NUnit-2.6.0.12051/NUnitTests.v2.nunit0000664000175000017500000000121711574622212016647 0ustar jtaylorjtaylor NUnit-2.6.0.12051/NUnitTests.config0000664000175000017500000000361311700664754016443 0ustar jtaylorjtaylor NUnit-2.6.0.12051/NUnitFitTests.html0000664000175000017500000001423111504175260016572 0ustar jtaylorjtaylor

NUnit Acceptance Tests

Developers love self-referential programs! Hence, NUnit has always run all it's own tests, even those that are not really unit tests.

Now, beginning with NUnit 2.4, NUnit has top-level tests using Ward Cunningham's FIT framework. At this time, the tests are pretty rudimentary, but it's a start and it's a framework for doing more.

Running the Tests

Open a console or shell window and navigate to the NUnit bin directory, which contains this file. To run the test under Microsoft .Net, enter the command

    runFile NUnitFitTests.html TestResults.html .
To run it under Mono, enter
    mono runFile.exe NUnitFitTests.html TestResults.html .
Note the space and dot at the end of each command. The results of your test will be in TestResults.html in the same directory.

Platform and CLR Version

NUnit.Fixtures.PlatformInfo

Verify Unit Tests

Load and run the NUnit unit tests, verifying that the results are as expected. When these tests are run on different platforms, different numbers of tests may be skipped, so the values for Skipped and Run tests are informational only.

The number of tests in each assembly should be constant across all platforms - any discrepancy usually means that one of the test source files was not compiled on the platform. There should be no failures and no tests ignored.

Note: At the moment, the nunit.extensions.tests assembly is failing because the fixture doesn't initialize addins in the test domain.

NUnit.Fixtures.AssemblyRunner
Assembly Tests() Run() Skipped() Ignored() Failures()
nunit.framework.tests.dll 397     0 0
nunit.core.tests.dll 355     0 0
nunit.util.tests.dll 238     0 0
nunit.mocks.tests.dll 43     0 0
nunit.extensions.tests.dll 5     0 0
nunit-console.tests.dll 40     0 0
nunit.uikit.tests.dll 34     0 0
nunit-gui.tests.dll 15     0 0
nunit.fixtures.tests.dll 6     0 0

Code Snippet Tests

These tests create a test assembly from a snippet of code and then load and run the tests that it contains, verifying that the structure of the loaded tests is as expected and that the number of tests run, skipped, ignored or failed is correct.

NUnit.Fixtures.SnippetRunner
Code Tree() Run() Skipped() Ignored() Failures()
public class TestClass
{
}
EMPTY 0 0 0 0
using NUnit.Framework;

[TestFixture]
public class TestClass
{
}
TestClass 0 0 0 0
using NUnit.Framework;

[TestFixture]
public class TestClass
{
    [Test]
    public void T1() { }
    [Test]
    public void T2() { }
    [Test]
    public void T3() { }
}
TestClass
>T1
>T2
>T3
3 0 0 0
using NUnit.Framework;

[TestFixture]
public class TestClass1
{
    [Test]
    public void T1() { }
}

[TestFixture]
public class TestClass2
{
    [Test]
    public void T2() { }
    [Test]
    public void T3() { }
}
TestClass1
>T1
TestClass2
>T2
>T3
3 0 0 0
using NUnit.Framework;

[TestFixture]
public class TestClass
{
    [Test]
    public void T1() { }
    [Test, Ignore]
    public void T2() { }
    [Test]
    public void T3() { }
}
TestClass
>T1
>T2
>T3
2 0 1 0
using NUnit.Framework;

[TestFixture]
public class TestClass
{
    [Test]
    public void T1() { }
    [Test, Explicit]
    public void T2() { }
    [Test]
    public void T3() { }
}
TestClass
>T1
>T2
>T3
2 1 0 0

Summary Information

fit.Summary
NUnit-2.6.0.12051/nunit.sln0000664000175000017500000005045711712475522015053 0ustar jtaylorjtaylor Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A65042E1-D8BC-48DD-8DE1-F0991F07EA77}" ProjectSection(SolutionItems) = preProject src\nunit.snk = src\nunit.snk NUnitTests.config = NUnitTests.config NUnitTests.nunit = NUnitTests.nunit EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{A785FC02-6044-4864-BE24-4593CAD23A97}" ProjectSection(SolutionItems) = preProject scripts\nunit.build.targets = scripts\nunit.build.targets scripts\nunit.common.targets = scripts\nunit.common.targets EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NUnitFramework", "NUnitFramework", "{A2FF9F1B-1854-479A-859C-6ECEBF045E4C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.framework.tests", "src\NUnitFramework\tests\nunit.framework.tests.csproj", "{8C326431-AE57-4645-ACC1-A90A0B425129}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.framework.dll", "src\NUnitFramework\framework\nunit.framework.dll.csproj", "{83DD7E12-A705-4DBA-9D71-09C8973D9382}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClientUtilities", "ClientUtilities", "{D448BA20-BA70-4F70-AF53-4C0E6C1E97E7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.util.tests", "src\ClientUtilities\tests\nunit.util.tests.csproj", "{74EF7165-117E-48ED-98EA-068EAE438E53}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.util.dll", "src\ClientUtilities\util\nunit.util.dll.csproj", "{61CE9CE5-943E-44D4-A381-814DC1406767}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConsoleRunner", "ConsoleRunner", "{1DBAF726-8009-41CC-B82A-4EFE94CBEEFC}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-console.tests", "src\ConsoleRunner\tests\nunit-console.tests.csproj", "{8597D2C6-804D-48CB-BFC7-ED2404D389B0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-console", "src\ConsoleRunner\nunit-console\nunit-console.csproj", "{9367EC89-6A38-42BA-9607-0DC288E4BC3A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-console.exe", "src\ConsoleRunner\nunit-console-exe\nunit-console.exe.csproj", "{53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GuiRunner", "GuiRunner", "{77D10207-CB02-4C3A-8734-5A5173E3C506}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-gui", "src\GuiRunner\nunit-gui\nunit-gui.csproj", "{3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-gui.tests", "src\GuiRunner\tests\nunit-gui.tests.csproj", "{AAD27267-DE1F-4F61-A1FB-D1680A5B8001}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-gui.exe", "src\GuiRunner\nunit-gui-exe\nunit-gui.exe.csproj", "{AAB186A4-FA3D-404D-AD78-7EB5BB861655}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NUnitCore", "NUnitCore", "{AEAED2BD-F22D-42C8-9047-F293BEF70EAB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.core.tests", "src\NUnitCore\tests\nunit.core.tests.csproj", "{DD758D21-E5D5-4D40-9450-5F65A32F359C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.core.interfaces.dll", "src\NUnitCore\interfaces\nunit.core.interfaces.dll.csproj", "{435428F8-5995-4CE4-8022-93D595A8CC0F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.core.dll", "src\NUnitCore\core\nunit.core.dll.csproj", "{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GuiComponents", "GuiComponents", "{168F8C38-129C-454A-B112-F456BC7F4FE4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.uikit.tests", "src\GuiComponents\tests\nunit.uikit.tests.csproj", "{63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.uikit.dll", "src\GuiComponents\UiKit\nunit.uikit.dll.csproj", "{27531BBF-183D-4C3A-935B-D840B9F1A3A4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GuiException", "GuiException", "{35A92AA3-A1E6-426E-8D96-322F3EBF1C8D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.uiexception.tests", "src\GuiException\tests\nunit.uiexception.tests.csproj", "{092486D0-6AB9-4134-932F-0FDA10704455}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.uiexception.dll", "src\GuiException\UiException\nunit.uiexception.dll.csproj", "{3E87A106-EB20-4147-84C8-95B0BB43A1D4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6142B985-EA14-4DE0-884F-E62D89949E1D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mock-assembly", "src\tests\mock-assembly\mock-assembly.csproj", "{2E368281-3BA8-4050-B05E-0E0E43F8F446}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nonamespace-assembly", "src\tests\nonamespace-assembly\nonamespace-assembly.csproj", "{5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-utilities", "src\tests\test-utilities\test-utilities.csproj", "{3E63AD0F-24D4-46BE-BEE4-5A3299847D86}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-assembly", "src\tests\test-assembly\test-assembly.csproj", "{1960CAC4-9A82-47C5-A9B3-55BC37572C3C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NUnitMocks", "NUnitMocks", "{7740410A-54B5-4334-8DE3-6D6F616BD6A5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.mocks.tests", "src\NUnitMocks\tests\nunit.mocks.tests.csproj", "{8667C588-1A05-4773-A9E8-272EB302B8AB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.mocks", "src\NUnitMocks\mocks\nunit.mocks.csproj", "{EEE7C98B-23E6-472D-9036-C2D53B0DFE7C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PNUnit", "PNUnit", "{979724B8-6FAA-400F-B40D-EB653A815C87}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit-agent", "src\PNUnit\agent\pnunit-agent.csproj", "{621C27DA-CC29-4663-9FE4-BF5A67970C18}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit-launcher", "src\PNUnit\launcher\pnunit-launcher.csproj", "{91FC5C92-E801-4446-B4D6-EAC5B56A4DB2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit.tests", "src\PNUnit\tests\pnunit.tests.csproj", "{319B9238-76BE-4335-9B4D-F8E43C4B124F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit.framework", "src\PNUnit\pnunit.framework\pnunit.framework.csproj", "{5261ABA1-98E6-4603-A4F0-59CAC307AC68}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NUnitTestServer", "NUnitTestServer", "{D029F8FD-84E3-4AD3-8F1B-CCA0C856E659}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-agent.exe", "src\NUnitTestServer\nunit-agent-exe\nunit-agent.exe.csproj", "{3E469CD9-FED2-4955-AE4C-669A74CA6767}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProjectEditor", "ProjectEditor", "{992367F7-9154-4424-B55E-3EF8673A2A36}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-editor", "src\ProjectEditor\editor\nunit-editor.csproj", "{ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit-editor.tests", "src\ProjectEditor\tests\nunit-editor.tests.csproj", "{A9E1C1E9-AE97-4510-AD94-EAFADE425FBE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8C326431-AE57-4645-ACC1-A90A0B425129}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8C326431-AE57-4645-ACC1-A90A0B425129}.Debug|Any CPU.Build.0 = Debug|Any CPU {8C326431-AE57-4645-ACC1-A90A0B425129}.Release|Any CPU.ActiveCfg = Release|Any CPU {8C326431-AE57-4645-ACC1-A90A0B425129}.Release|Any CPU.Build.0 = Release|Any CPU {83DD7E12-A705-4DBA-9D71-09C8973D9382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83DD7E12-A705-4DBA-9D71-09C8973D9382}.Debug|Any CPU.Build.0 = Debug|Any CPU {83DD7E12-A705-4DBA-9D71-09C8973D9382}.Release|Any CPU.ActiveCfg = Release|Any CPU {83DD7E12-A705-4DBA-9D71-09C8973D9382}.Release|Any CPU.Build.0 = Release|Any CPU {74EF7165-117E-48ED-98EA-068EAE438E53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {74EF7165-117E-48ED-98EA-068EAE438E53}.Debug|Any CPU.Build.0 = Debug|Any CPU {74EF7165-117E-48ED-98EA-068EAE438E53}.Release|Any CPU.ActiveCfg = Release|Any CPU {74EF7165-117E-48ED-98EA-068EAE438E53}.Release|Any CPU.Build.0 = Release|Any CPU {61CE9CE5-943E-44D4-A381-814DC1406767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {61CE9CE5-943E-44D4-A381-814DC1406767}.Debug|Any CPU.Build.0 = Debug|Any CPU {61CE9CE5-943E-44D4-A381-814DC1406767}.Release|Any CPU.ActiveCfg = Release|Any CPU {61CE9CE5-943E-44D4-A381-814DC1406767}.Release|Any CPU.Build.0 = Release|Any CPU {8597D2C6-804D-48CB-BFC7-ED2404D389B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8597D2C6-804D-48CB-BFC7-ED2404D389B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {8597D2C6-804D-48CB-BFC7-ED2404D389B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {8597D2C6-804D-48CB-BFC7-ED2404D389B0}.Release|Any CPU.Build.0 = Release|Any CPU {9367EC89-6A38-42BA-9607-0DC288E4BC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9367EC89-6A38-42BA-9607-0DC288E4BC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU {9367EC89-6A38-42BA-9607-0DC288E4BC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU {9367EC89-6A38-42BA-9607-0DC288E4BC3A}.Release|Any CPU.Build.0 = Release|Any CPU {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E}.Release|Any CPU.Build.0 = Release|Any CPU {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148}.Debug|Any CPU.Build.0 = Debug|Any CPU {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148}.Release|Any CPU.ActiveCfg = Release|Any CPU {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148}.Release|Any CPU.Build.0 = Release|Any CPU {AAD27267-DE1F-4F61-A1FB-D1680A5B8001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AAD27267-DE1F-4F61-A1FB-D1680A5B8001}.Debug|Any CPU.Build.0 = Debug|Any CPU {AAD27267-DE1F-4F61-A1FB-D1680A5B8001}.Release|Any CPU.ActiveCfg = Release|Any CPU {AAD27267-DE1F-4F61-A1FB-D1680A5B8001}.Release|Any CPU.Build.0 = Release|Any CPU {AAB186A4-FA3D-404D-AD78-7EB5BB861655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AAB186A4-FA3D-404D-AD78-7EB5BB861655}.Debug|Any CPU.Build.0 = Debug|Any CPU {AAB186A4-FA3D-404D-AD78-7EB5BB861655}.Release|Any CPU.ActiveCfg = Release|Any CPU {AAB186A4-FA3D-404D-AD78-7EB5BB861655}.Release|Any CPU.Build.0 = Release|Any CPU {DD758D21-E5D5-4D40-9450-5F65A32F359C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DD758D21-E5D5-4D40-9450-5F65A32F359C}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD758D21-E5D5-4D40-9450-5F65A32F359C}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD758D21-E5D5-4D40-9450-5F65A32F359C}.Release|Any CPU.Build.0 = Release|Any CPU {435428F8-5995-4CE4-8022-93D595A8CC0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {435428F8-5995-4CE4-8022-93D595A8CC0F}.Debug|Any CPU.Build.0 = Debug|Any CPU {435428F8-5995-4CE4-8022-93D595A8CC0F}.Release|Any CPU.ActiveCfg = Release|Any CPU {435428F8-5995-4CE4-8022-93D595A8CC0F}.Release|Any CPU.Build.0 = Release|Any CPU {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}.Debug|Any CPU.Build.0 = Debug|Any CPU {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}.Release|Any CPU.ActiveCfg = Release|Any CPU {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}.Release|Any CPU.Build.0 = Release|Any CPU {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B}.Debug|Any CPU.Build.0 = Debug|Any CPU {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B}.Release|Any CPU.ActiveCfg = Release|Any CPU {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B}.Release|Any CPU.Build.0 = Release|Any CPU {27531BBF-183D-4C3A-935B-D840B9F1A3A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27531BBF-183D-4C3A-935B-D840B9F1A3A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {27531BBF-183D-4C3A-935B-D840B9F1A3A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {27531BBF-183D-4C3A-935B-D840B9F1A3A4}.Release|Any CPU.Build.0 = Release|Any CPU {092486D0-6AB9-4134-932F-0FDA10704455}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {092486D0-6AB9-4134-932F-0FDA10704455}.Debug|Any CPU.Build.0 = Debug|Any CPU {092486D0-6AB9-4134-932F-0FDA10704455}.Release|Any CPU.ActiveCfg = Release|Any CPU {092486D0-6AB9-4134-932F-0FDA10704455}.Release|Any CPU.Build.0 = Release|Any CPU {3E87A106-EB20-4147-84C8-95B0BB43A1D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3E87A106-EB20-4147-84C8-95B0BB43A1D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E87A106-EB20-4147-84C8-95B0BB43A1D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E87A106-EB20-4147-84C8-95B0BB43A1D4}.Release|Any CPU.Build.0 = Release|Any CPU {2E368281-3BA8-4050-B05E-0E0E43F8F446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E368281-3BA8-4050-B05E-0E0E43F8F446}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E368281-3BA8-4050-B05E-0E0E43F8F446}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E368281-3BA8-4050-B05E-0E0E43F8F446}.Release|Any CPU.Build.0 = Release|Any CPU {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D}.Debug|Any CPU.Build.0 = Debug|Any CPU {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D}.Release|Any CPU.ActiveCfg = Release|Any CPU {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D}.Release|Any CPU.Build.0 = Release|Any CPU {3E63AD0F-24D4-46BE-BEE4-5A3299847D86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3E63AD0F-24D4-46BE-BEE4-5A3299847D86}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E63AD0F-24D4-46BE-BEE4-5A3299847D86}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E63AD0F-24D4-46BE-BEE4-5A3299847D86}.Release|Any CPU.Build.0 = Release|Any CPU {1960CAC4-9A82-47C5-A9B3-55BC37572C3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1960CAC4-9A82-47C5-A9B3-55BC37572C3C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1960CAC4-9A82-47C5-A9B3-55BC37572C3C}.Release|Any CPU.ActiveCfg = Release|Any CPU {1960CAC4-9A82-47C5-A9B3-55BC37572C3C}.Release|Any CPU.Build.0 = Release|Any CPU {8667C588-1A05-4773-A9E8-272EB302B8AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8667C588-1A05-4773-A9E8-272EB302B8AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {8667C588-1A05-4773-A9E8-272EB302B8AB}.Release|Any CPU.ActiveCfg = Release|Any CPU {8667C588-1A05-4773-A9E8-272EB302B8AB}.Release|Any CPU.Build.0 = Release|Any CPU {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C}.Debug|Any CPU.Build.0 = Debug|Any CPU {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C}.Release|Any CPU.ActiveCfg = Release|Any CPU {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C}.Release|Any CPU.Build.0 = Release|Any CPU {621C27DA-CC29-4663-9FE4-BF5A67970C18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {621C27DA-CC29-4663-9FE4-BF5A67970C18}.Debug|Any CPU.Build.0 = Debug|Any CPU {621C27DA-CC29-4663-9FE4-BF5A67970C18}.Release|Any CPU.ActiveCfg = Release|Any CPU {621C27DA-CC29-4663-9FE4-BF5A67970C18}.Release|Any CPU.Build.0 = Release|Any CPU {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2}.Debug|Any CPU.Build.0 = Debug|Any CPU {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2}.Release|Any CPU.ActiveCfg = Release|Any CPU {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2}.Release|Any CPU.Build.0 = Release|Any CPU {319B9238-76BE-4335-9B4D-F8E43C4B124F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {319B9238-76BE-4335-9B4D-F8E43C4B124F}.Debug|Any CPU.Build.0 = Debug|Any CPU {319B9238-76BE-4335-9B4D-F8E43C4B124F}.Release|Any CPU.ActiveCfg = Release|Any CPU {319B9238-76BE-4335-9B4D-F8E43C4B124F}.Release|Any CPU.Build.0 = Release|Any CPU {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.Build.0 = Debug|Any CPU {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.ActiveCfg = Release|Any CPU {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.Build.0 = Release|Any CPU {3E469CD9-FED2-4955-AE4C-669A74CA6767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3E469CD9-FED2-4955-AE4C-669A74CA6767}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E469CD9-FED2-4955-AE4C-669A74CA6767}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E469CD9-FED2-4955-AE4C-669A74CA6767}.Release|Any CPU.Build.0 = Release|Any CPU {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB}.Release|Any CPU.Build.0 = Release|Any CPU {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE}.Debug|Any CPU.Build.0 = Debug|Any CPU {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE}.Release|Any CPU.ActiveCfg = Release|Any CPU {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {A785FC02-6044-4864-BE24-4593CAD23A97} = {A65042E1-D8BC-48DD-8DE1-F0991F07EA77} {8C326431-AE57-4645-ACC1-A90A0B425129} = {A2FF9F1B-1854-479A-859C-6ECEBF045E4C} {83DD7E12-A705-4DBA-9D71-09C8973D9382} = {A2FF9F1B-1854-479A-859C-6ECEBF045E4C} {74EF7165-117E-48ED-98EA-068EAE438E53} = {D448BA20-BA70-4F70-AF53-4C0E6C1E97E7} {61CE9CE5-943E-44D4-A381-814DC1406767} = {D448BA20-BA70-4F70-AF53-4C0E6C1E97E7} {8597D2C6-804D-48CB-BFC7-ED2404D389B0} = {1DBAF726-8009-41CC-B82A-4EFE94CBEEFC} {9367EC89-6A38-42BA-9607-0DC288E4BC3A} = {1DBAF726-8009-41CC-B82A-4EFE94CBEEFC} {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E} = {1DBAF726-8009-41CC-B82A-4EFE94CBEEFC} {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148} = {77D10207-CB02-4C3A-8734-5A5173E3C506} {AAD27267-DE1F-4F61-A1FB-D1680A5B8001} = {77D10207-CB02-4C3A-8734-5A5173E3C506} {AAB186A4-FA3D-404D-AD78-7EB5BB861655} = {77D10207-CB02-4C3A-8734-5A5173E3C506} {DD758D21-E5D5-4D40-9450-5F65A32F359C} = {AEAED2BD-F22D-42C8-9047-F293BEF70EAB} {435428F8-5995-4CE4-8022-93D595A8CC0F} = {AEAED2BD-F22D-42C8-9047-F293BEF70EAB} {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} = {AEAED2BD-F22D-42C8-9047-F293BEF70EAB} {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B} = {168F8C38-129C-454A-B112-F456BC7F4FE4} {27531BBF-183D-4C3A-935B-D840B9F1A3A4} = {168F8C38-129C-454A-B112-F456BC7F4FE4} {092486D0-6AB9-4134-932F-0FDA10704455} = {35A92AA3-A1E6-426E-8D96-322F3EBF1C8D} {3E87A106-EB20-4147-84C8-95B0BB43A1D4} = {35A92AA3-A1E6-426E-8D96-322F3EBF1C8D} {2E368281-3BA8-4050-B05E-0E0E43F8F446} = {6142B985-EA14-4DE0-884F-E62D89949E1D} {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} = {6142B985-EA14-4DE0-884F-E62D89949E1D} {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} = {6142B985-EA14-4DE0-884F-E62D89949E1D} {1960CAC4-9A82-47C5-A9B3-55BC37572C3C} = {6142B985-EA14-4DE0-884F-E62D89949E1D} {8667C588-1A05-4773-A9E8-272EB302B8AB} = {7740410A-54B5-4334-8DE3-6D6F616BD6A5} {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C} = {7740410A-54B5-4334-8DE3-6D6F616BD6A5} {621C27DA-CC29-4663-9FE4-BF5A67970C18} = {979724B8-6FAA-400F-B40D-EB653A815C87} {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2} = {979724B8-6FAA-400F-B40D-EB653A815C87} {319B9238-76BE-4335-9B4D-F8E43C4B124F} = {979724B8-6FAA-400F-B40D-EB653A815C87} {5261ABA1-98E6-4603-A4F0-59CAC307AC68} = {979724B8-6FAA-400F-B40D-EB653A815C87} {3E469CD9-FED2-4955-AE4C-669A74CA6767} = {D029F8FD-84E3-4AD3-8F1B-CCA0C856E659} {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB} = {992367F7-9154-4424-B55E-3EF8673A2A36} {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE} = {992367F7-9154-4424-B55E-3EF8673A2A36} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = src\ConsoleRunner\nunit-console-exe\nunit-console.exe.csproj EndGlobalSection EndGlobal NUnit-2.6.0.12051/license.txt0000664000175000017500000000215311712221104015332 0ustar jtaylorjtaylorCopyright 2002-2012 Charlie Poole Copyright 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov Copyright 2000-2002 Philip A. Craig This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required. Portions Copyright 2002-2012 Charlie Poole or Copyright 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright 2000-2002 Philip A. Craig 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. NUnit-2.6.0.12051/src/0000775000175000017500000000000011742560362013754 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/0000775000175000017500000000000011742560362016546 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/tests/0000775000175000017500000000000011742560362017710 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/tests/TestTreeTests.cs0000664000175000017500000000335211504175260023017 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Framework; namespace NUnit.UiKit.Tests { [TestFixture] public class TestTreeTests { [Test] public void SameCategoryShouldNotBeSelectedMoreThanOnce() { // arrange TestTree target = new TestTree(); // we need to populate the available categories // this can be done via TestLoader but this way the test is isolated FieldInfo fieldInfo = typeof (TestTree).GetField("availableCategories", BindingFlags.NonPublic | BindingFlags.Instance); Assert.IsNotNull(fieldInfo, "The field 'availableCategories' should be found."); object fieldValue = fieldInfo.GetValue(target); Assert.IsNotNull(fieldValue, "The value of 'availableCategories' should not be null."); IList availableCategories = fieldValue as IList; Assert.IsNotNull(availableCategories, "'availableCategories' field should be of type IList."); string[] expectedSelectedCategories = new string[] { "Foo", "MockCategory" }; foreach (string availableCategory in expectedSelectedCategories) { availableCategories.Add(availableCategory); } // act target.SelectCategories(expectedSelectedCategories, true); target.SelectCategories(expectedSelectedCategories, true); string[] actualSelectedCategories = target.SelectedCategories; // assert CollectionAssert.AreEquivalent(expectedSelectedCategories, actualSelectedCategories); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/nunit.uikit.tests.build0000664000175000017500000000377311504175260024360 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiComponents/tests/StatusBarTests.cs0000664000175000017500000001071211504175260023166 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; using NUnit.TestUtilities; namespace NUnit.UiKit.Tests { /// /// Summary description for StatusBarTests. /// [TestFixture] public class StatusBarTests { private StatusBar statusBar; private MockTestEventSource mockEvents; private static string testsDll = MockAssembly.AssemblyPath; TestSuite suite; int testCount = 0; [SetUp] public void Setup() { statusBar = new StatusBar(); TestSuiteBuilder builder = new TestSuiteBuilder(); suite = builder.Build( new TestPackage( testsDll ) ); mockEvents = new MockTestEventSource( suite ); } [Test] public void TestConstruction() { Assert.AreEqual( "Status", statusBar.Panels[0].Text ); Assert.AreEqual( "Test Cases : 0", statusBar.Panels[1].Text ); Assert.AreEqual( "", statusBar.Panels[2].Text ); Assert.AreEqual( "", statusBar.Panels[3].Text ); Assert.AreEqual( "", statusBar.Panels[4].Text ); } [Test] public void TestInitialization() { statusBar.Initialize( 0 ); Assert.AreEqual( "", statusBar.Panels[0].Text ); Assert.AreEqual( "Test Cases : 0", statusBar.Panels[1].Text ); Assert.AreEqual( "", statusBar.Panels[2].Text ); Assert.AreEqual( "", statusBar.Panels[3].Text ); Assert.AreEqual( "", statusBar.Panels[4].Text ); statusBar.Initialize( 50 ); Assert.AreEqual( "Ready", statusBar.Panels[0].Text ); Assert.AreEqual( "Test Cases : 50", statusBar.Panels[1].Text ); Assert.AreEqual( "", statusBar.Panels[2].Text ); Assert.AreEqual( "", statusBar.Panels[3].Text ); Assert.AreEqual( "", statusBar.Panels[4].Text ); } [Test] public void TestFinalDisplay() { Assert.AreEqual( false, statusBar.DisplayTestProgress ); statusBar.Subscribe( mockEvents ); mockEvents.SimulateTestRun(); Assert.AreEqual( "Completed", statusBar.Panels[0].Text ); Assert.AreEqual( PanelMessage( "Test Cases", MockAssembly.Tests ), statusBar.Panels[1].Text ); Assert.AreEqual( PanelMessage( "Tests Run", MockAssembly.TestsRun ), statusBar.Panels[2].Text ); Assert.AreEqual( PanelMessage( "Errors", MockAssembly.Errors ), statusBar.Panels[3].Text ); Assert.AreEqual( PanelMessage( "Failures", MockAssembly.Failures ), statusBar.Panels[4].Text ); } // .NET 1.0 sometimes throws: // ExternalException : A generic error occurred in GDI+. [Test, Platform(Exclude = "Net-1.0")] public void TestProgressDisplay() { statusBar.DisplayTestProgress = true; statusBar.Subscribe( mockEvents ); testCount = 0; testCount = 0; mockEvents.TestFinished += new TestEventHandler( OnTestFinished ); mockEvents.SimulateTestRun(); Assert.AreEqual( "Completed", statusBar.Panels[0].Text ); Assert.AreEqual( PanelMessage( "Test Cases", MockAssembly.Tests ), statusBar.Panels[1].Text ); Assert.AreEqual( PanelMessage( "Tests Run", MockAssembly.TestsRun ), statusBar.Panels[2].Text ); Assert.AreEqual( PanelMessage( "Errors", MockAssembly.Errors ), statusBar.Panels[3].Text ); Assert.AreEqual( PanelMessage( "Failures", MockAssembly.Failures ), statusBar.Panels[4].Text ); } private void OnTestFinished( object sender, TestEventArgs e ) { Assert.AreEqual( PanelMessage( "Test Cases", MockAssembly.Tests ), statusBar.Panels[1].Text ); StringAssert.EndsWith( e.Result.Test.TestName.Name, statusBar.Panels[0].Text ); string runPanel = statusBar.Panels[2].Text; int testsRun = 0; if (runPanel != "") { StringAssert.StartsWith( "Tests Run : ", runPanel ); testsRun = int.Parse(runPanel.Substring(12)); } Assert.GreaterOrEqual( testsRun, testCount); Assert.LessOrEqual( testsRun, testCount + 1); testCount = testsRun; } private static string PanelMessage( string text, int count ) { return string.Format( "{0} : {1}", text, count ); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/nunit.uikit.tests.csproj0000664000175000017500000001333511574577562024576 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {63EC3999-FA6B-4C5B-8805-5A88AF4CBD7B} Debug AnyCPU nunit.uikit.tests JScript Grid IE50 false Library NUnit.UiKit.Tests OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.Drawing System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} mock-assembly {2E368281-3BA8-4050-B05E-0E0E43F8F446} test-utilities {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} nunit.uikit.dll {27531BBF-183D-4C3A-935B-D840B9F1A3A4} False {3E87A106-EB20-4147-84C8-95B0BB43A1D4} nunit.uiexception.dll False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/GuiComponents/tests/TestSuiteTreeViewFixture.cs0000664000175000017500000003514011655011770025212 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.UiKit.Tests { using System; using System.Reflection; using System.Windows.Forms; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; /// /// Summary description for TestSuiteFixture. /// /// public class TestSuiteTreeViewFixture { protected string testsDll = MockAssembly.AssemblyPath; protected Test suite; protected TestSuiteTreeView treeView; [SetUp] public void SetUp() { TestSuiteBuilder builder = new TestSuiteBuilder(); suite = builder.Build( new TestPackage( testsDll ) ); treeView = new TestSuiteTreeView(); treeView.Load(new TestNode(suite)); } } [TestFixture] public class TestSuiteTreeViewTests : TestSuiteTreeViewFixture { private bool AllExpanded( TreeNode node) { if ( node.Nodes.Count == 0 ) return true; if ( !node.IsExpanded ) return false; return AllExpanded( node.Nodes ); } private bool AllExpanded( TreeNodeCollection nodes ) { foreach( TestSuiteTreeNode node in nodes ) if ( !AllExpanded( node ) ) return false; return true; } [Test] public void BuildTreeView() { Assert.IsNotNull( treeView.Nodes[0] ); Assert.AreEqual( MockAssembly.Nodes, treeView.GetNodeCount( true ) ); Assert.AreEqual( testsDll, treeView.Nodes[0].Text ); Assert.AreEqual( "NUnit", treeView.Nodes[0].Nodes[0].Text ); Assert.AreEqual( "Tests", treeView.Nodes[0].Nodes[0].Nodes[0].Text ); } [Test] public void BuildFromResult() { TestResult result = suite.Run(new NullListener(), TestFilter.Empty); treeView.Load( result ); Assert.AreEqual( MockAssembly.Nodes - MockAssembly.Explicit - MockAssembly.ExplicitFixtures, treeView.GetNodeCount( true ) ); TestSuiteTreeNode node = treeView.Nodes[0] as TestSuiteTreeNode; Assert.AreEqual( testsDll, node.Text ); Assert.IsNotNull( node.Result, "No Result on top-level Node" ); node = node.Nodes[0].Nodes[0] as TestSuiteTreeNode; Assert.AreEqual( "Tests", node.Text ); Assert.IsNotNull( node.Result, "No Result on TestSuite" ); foreach( TestSuiteTreeNode child in node.Nodes ) { if ( child.Text == "Assemblies" ) { node = child.Nodes[0] as TestSuiteTreeNode; Assert.AreEqual( "MockTestFixture", node.Text ); Assert.IsNotNull( node.Result, "No Result on TestFixture" ); Assert.AreEqual( true, node.Result.Executed, "MockTestFixture: Executed" ); TestSuiteTreeNode test1 = node.Nodes[2] as TestSuiteTreeNode; Assert.AreEqual( "MockTest1", test1.Text ); Assert.IsNotNull( test1.Result, "No Result on TestCase" ); Assert.AreEqual( true, test1.Result.Executed, "MockTest1: Executed" ); Assert.AreEqual( false, test1.Result.IsFailure, "MockTest1: IsFailure"); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, test1.ImageIndex ); TestSuiteTreeNode test4 = node.Nodes[5] as TestSuiteTreeNode; Assert.AreEqual( false, test4.Result.Executed, "MockTest4: Executed" ); Assert.AreEqual( TestSuiteTreeNode.IgnoredIndex, test4.ImageIndex ); return; } } Assert.Fail( "Cannot locate NUnit.Tests.Assemblies node" ); } /// /// Return the MockTestFixture node from a tree built /// from the mock-assembly dll. /// private TestSuiteTreeNode FixtureNode( TestSuiteTreeView treeView ) { return (TestSuiteTreeNode)treeView.Nodes[0].Nodes[0].Nodes[0].Nodes[0].Nodes[0]; } /// /// The tree view CollapseAll method doesn't seem to work in /// this test environment. This replaces it. /// private void CollapseAll( TreeNode node ) { node.Collapse(); CollapseAll( node.Nodes ); } private void CollapseAll( TreeNodeCollection nodes ) { foreach( TreeNode node in nodes ) CollapseAll( node ); } [Test] public void ClearTree() { //treeView.Load( new TestNode( suite ) ); treeView.Clear(); Assert.AreEqual( 0, treeView.Nodes.Count ); } [Test] public void SetTestResult() { TestSuite fixture = (TestSuite)findTest( "MockTestFixture", suite ); TestResult result = new TestResult( new TestInfo( fixture ) ); treeView.SetTestResult( result ); TestSuiteTreeNode fixtureNode = FixtureNode( treeView ); Assert.IsNotNull(fixtureNode.Result, "Result not set" ); Assert.AreEqual( fixture.TestName.Name, fixtureNode.Result.Name ); Assert.AreEqual( fixtureNode.Test.TestName.FullName, fixtureNode.Result.Test.TestName.FullName ); } private Test findTest(string name, Test test) { Test result = null; if (test.TestName.Name == name) result = test; else if (test.Tests != null) { foreach(Test t in test.Tests) { result = findTest(name, t); if (result != null) break; } } return result; } [Test] public void ProcessChecks() { Assert.AreEqual(0, treeView.CheckedTests.Length); Assert.IsFalse(Checked(treeView.Nodes)); treeView.Nodes[0].Checked = true; treeView.Nodes[0].Nodes[0].Checked = true; Assert.AreEqual(2, treeView.CheckedTests.Length); Assert.AreEqual(1, treeView.SelectedTests.Length); Assert.IsTrue(Checked(treeView.Nodes)); treeView.ClearCheckedNodes(); Assert.AreEqual(0, treeView.CheckedTests.Length); Assert.IsFalse(Checked(treeView.Nodes)); } // TODO: Unused Tests // [Test] // public void CheckCategory() // { // treeView.Load(suite); // // Assert.AreEqual(0, treeView.CheckedTests.Length); // // CheckCategoryVisitor visitor = new CheckCategoryVisitor("MockCategory"); // treeView.Accept(visitor); // // Assert.AreEqual(2, treeView.CheckedTests.Length); // } // // [Test] // public void UnCheckCategory() // { // treeView.Load(suite); // // Assert.AreEqual(0, treeView.CheckedTests.Length); // // CheckCategoryVisitor visitor = new CheckCategoryVisitor("MockCategory"); // treeView.Accept(visitor); // // Assert.AreEqual(2, treeView.CheckedTests.Length); // // UnCheckCategoryVisitor unvisitor = new UnCheckCategoryVisitor("MockCategory"); // treeView.Accept(unvisitor); // // Assert.AreEqual(0, treeView.CheckedTests.Length); // } private bool Checked(TreeNodeCollection nodes) { bool result = false; foreach (TreeNode node in nodes) { result |= node.Checked; if (node.Nodes != null) result |= Checked(node.Nodes); } return result; } } [TestFixture] public class TestSuiteTreeViewReloadTests : TestSuiteTreeViewFixture { private TestSuite nunitNamespaceSuite; private TestSuite testsNamespaceSuite; private TestSuite assembliesNamespaceSuite; private TestSuite mockTestFixture; private int originalTestCount; [SetUp] public void Initialize() { nunitNamespaceSuite = suite.Tests[0] as TestSuite; testsNamespaceSuite = nunitNamespaceSuite.Tests[0] as TestSuite; assembliesNamespaceSuite = testsNamespaceSuite.Tests[0] as TestSuite; mockTestFixture = assembliesNamespaceSuite.Tests[0] as TestSuite; originalTestCount = suite.TestCount; } [Test] public void VerifyCheckTreeWorks() { CheckTreeAgainstSuite(suite, "initially"); } [Test] public void CanReloadWithoutChange() { treeView.Reload(new TestNode(suite)); CheckTreeAgainstSuite(suite, "unchanged"); } [Test] public void CanReloadAfterDeletingOneTestCase() { mockTestFixture.Tests.RemoveAt(0); Assert.AreEqual(originalTestCount - 1, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after removing test case"); } [Test] public void CanReloadAfterDeletingThreeTestCases() { mockTestFixture.Tests.RemoveAt(4); mockTestFixture.Tests.RemoveAt(2); mockTestFixture.Tests.RemoveAt(0); Assert.AreEqual(originalTestCount - 3, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after removing test case"); } [Test] public void CanReloadAfterDeletingBranch() { int removeCount = ((Test)testsNamespaceSuite.Tests[0]).TestCount; testsNamespaceSuite.Tests.RemoveAt(0); Assert.AreEqual(originalTestCount-removeCount, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after removing branch"); } [Test] public void CanReloadAfterInsertingTestCase() { mockTestFixture.Tests.Add(new NUnitTestMethod((MethodInfo)MethodInfo.GetCurrentMethod())); Assert.AreEqual(originalTestCount + 1, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after inserting test case"); } [Test] public void CanReloadAfterInsertingTestFixture() { Test fixture = new TestSuite(this.GetType()); testsNamespaceSuite.Tests.Add(fixture); Assert.AreEqual(originalTestCount + fixture.TestCount, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after inserting test case"); } [Test] public void ReloadTreeWithWrongTest() { TestSuite suite2 = new TestSuite("WrongSuite"); treeView.Reload(new TestNode(suite2)); } [Test] public void CanReloadAfterChangingOrder() { // Just swap the first and second test object first = mockTestFixture.Tests[0]; mockTestFixture.Tests.RemoveAt(0); mockTestFixture.Tests.Insert(1, first); Assert.AreEqual(originalTestCount, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after reordering"); } [Test] public void CanReloadAfterMultipleChanges() { // Add a fixture Test fixture = new TestSuite(this.GetType()); testsNamespaceSuite.Tests.Add(fixture); // Remove two tests mockTestFixture.Tests.RemoveAt(4); mockTestFixture.Tests.RemoveAt(2); // Interchange two tests object first = mockTestFixture.Tests[0]; mockTestFixture.Tests.RemoveAt(0); mockTestFixture.Tests.Insert(2, first); // Add an new test case mockTestFixture.Tests.Add(new NUnitTestMethod((MethodInfo)MethodInfo.GetCurrentMethod())); int expectedCount = fixture.TestCount - 1; Assert.AreEqual(originalTestCount + expectedCount, suite.TestCount); ReassignTestIDsAndReload(suite); CheckTreeAgainstSuite(suite, "after multiple changes"); } [Test] public void CanReloadAfterTurningOffAutoNamespaces() { TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage(testsDll); package.Settings["AutoNamespaceSuites"] = false; TestSuite suite2 = builder.Build(package); Assert.AreEqual(originalTestCount, suite2.TestCount); Assert.AreEqual(MockAssembly.Classes, suite2.Tests.Count); ReassignTestIDsAndReload(suite2); CheckTreeAgainstSuite(suite2, "after turning automatic namespaces OFF"); // TODO: This currently doesn't work //ReassignTestIDsAndReload(suite); //CheckTreeAgainstSuite(suite, "after turning automatic namespaces ON"); } private void CheckTreeAgainstSuite(Test suite, string msg) { CheckThatTreeMatchesTests(treeView, suite, "Tree out of order " + msg); CheckTreeMap(treeView, suite, "Map incorrect " + msg); } private void CheckThatTreeMatchesTests(TestSuiteTreeView treeView, Test suite, string msg) { CheckThatNodeMatchesTest((TestSuiteTreeNode)treeView.Nodes[0], suite, msg); } private void CheckThatNodeMatchesTest(TestSuiteTreeNode node, Test test, string msg) { Assert.AreEqual(test.TestName, node.Test.TestName, "{0}: Names do not match for {1}", msg, test.TestName.FullName); if (test.IsSuite) { //if ( test.TestName.FullName == "NUnit.Tests.Assemblies.MockTestFixture" ) // foreach( TestSuiteTreeNode n in node.Nodes ) // Console.WriteLine( n.Test.TestName ); Assert.AreEqual(test.Tests.Count, node.Nodes.Count, "{0}: Incorrect count for {1}", msg, test.TestName.FullName); for (int index = 0; index < test.Tests.Count; index++) { CheckThatNodeMatchesTest((TestSuiteTreeNode)node.Nodes[index], (Test)test.Tests[index], msg); } } } private void CheckTreeMap(TestSuiteTreeView treeView, Test test, string msg) { TestSuiteTreeNode node = treeView[test.TestName.UniqueName]; Assert.IsNotNull(node, "{0}: {1} not in map", msg, test.TestName.UniqueName); Assert.AreEqual(test.TestName, treeView[test.TestName.UniqueName].Test.TestName, msg); if (test.IsSuite) foreach (Test child in test.Tests) CheckTreeMap(treeView, child, msg); } // Reload re-assigns the test IDs, so we simulate it private void ReassignTestIDs(Test test) { test.TestName.TestID = new TestID(); if (test.IsSuite) foreach (Test child in test.Tests) ReassignTestIDs(child); } private void ReassignTestIDsAndReload(Test test) { ReassignTestIDs(test); treeView.Reload(new TestNode(test)); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/LongRunningOperationDisplayTests.cs0000664000175000017500000000301611504175260026724 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Framework; namespace NUnit.UiKit.Tests { [TestFixture] public class LongRunningOperationDisplayTests : AssertionHelper { // This test was intermittently throwing the following exception under .NET 1.0. // System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+. // at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x, Int32 y, Int32 width, Int32 height) // at System.Drawing.Graphics.DrawRectangle(Pen pen, Rectangle rect) // at NUnit.UiKit.LongRunningOperationDisplay.OnPaint(PaintEventArgs e) in .\src\GuiComponents\UiKit\LongRunningOperationDisplay.cs:line 117 [Test, Platform(Exclude = "NET-1.0")] public void CreateDisplay() { Form form = new Form(); LongRunningOperationDisplay display = new LongRunningOperationDisplay( form, "Loading..." ); Expect( display.Owner, EqualTo( form ) ); Expect( GetOperationText( display ), EqualTo( "Loading..." ) ); } private string GetOperationText( Control display ) { foreach( Control control in display.Controls ) if ( control.Name == "operation" ) return control.Text; return null; } } } NUnit-2.6.0.12051/src/GuiComponents/tests/ErrorDisplayTests.cs0000664000175000017500000000213611504175260023676 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.UiKit.Tests { [TestFixture] public class ErrorDisplayTests : ControlTester { [TestFixtureSetUp] public void CreateForm() { this.Control = new ErrorDisplay(); } [TestFixtureTearDown] public void CloseForm() { this.Control.Dispose(); } [Test] public void ControlsExist() { AssertControlExists( "detailList", typeof( ListBox ) ); AssertControlExists( "tabSplitter", typeof( Splitter ) ); AssertControlExists( "errorBrowser", typeof( NUnit.UiException.Controls.ErrorBrowser ) ); } [Test] public void ControlsArePositionedCorrectly() { AssertControlsAreStackedVertically( "detailList", "tabSplitter", "errorBrowser" ); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/ProgressBarTests.cs0000664000175000017500000000362511504175260023514 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.UiKit.Tests { using System; using System.Drawing; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; using NUnit.TestUtilities; /// /// Summary description for ProgressBarTests. /// [TestFixture] public class ProgressBarTests { private TestProgressBar progressBar; private MockTestEventSource mockEvents; private string testsDll = MockAssembly.AssemblyPath; private TestSuite suite; int testCount; [SetUp] public void Setup() { progressBar = new TestProgressBar(); TestSuiteBuilder builder = new TestSuiteBuilder(); suite = builder.Build( new TestPackage( testsDll ) ); mockEvents = new MockTestEventSource( suite ); } // .NET 1.0 sometimes throws: // ExternalException : A generic error occurred in GDI+. [Test, Platform(Exclude = "Net-1.0")] public void TestProgressDisplay() { progressBar.Subscribe( mockEvents ); mockEvents.TestFinished += new TestEventHandler( OnTestFinished ); testCount = 0; mockEvents.SimulateTestRun(); Assert.AreEqual( 0, progressBar.Minimum ); Assert.AreEqual( MockAssembly.Tests, progressBar.Maximum ); Assert.AreEqual( 1, progressBar.Step ); Assert.AreEqual( MockAssembly.ResultCount, progressBar.Value ); Assert.AreEqual( Color.Red, progressBar.ForeColor ); } private void OnTestFinished( object sender, TestEventArgs e ) { ++testCount; // Assumes delegates are called in order of adding Assert.AreEqual( testCount, progressBar.Value ); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/TestSuiteTreeNodeTests.cs0000664000175000017500000001407611504175260024644 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.UiKit.Tests { using System; using NUnit.Core; using NUnit.Core.Builders; using NUnit.Framework; using NUnit.Util; using NUnit.Tests.Assemblies; /// /// Summary description for TestSuiteTreeNodeTests. /// [TestFixture] public class TestSuiteTreeNodeTests { TestSuite testSuite; Test testFixture; Test testCase; TestInfo suiteInfo; TestInfo fixtureInfo; TestInfo testCaseInfo; [SetUp] public void SetUp() { testSuite = new TestSuite("MyTestSuite"); testFixture = TestFixtureBuilder.BuildFrom( typeof( MockTestFixture ) ); testSuite.Add( testFixture ); suiteInfo = new TestInfo( testSuite ); fixtureInfo = new TestInfo( testFixture ); testCase = (NUnit.Core.Test)testFixture.Tests[0]; testCaseInfo = new TestInfo( testCase ); } [Test] public void ConstructFromTestInfo() { TestSuiteTreeNode node; node = new TestSuiteTreeNode( suiteInfo ); Assert.AreEqual( "MyTestSuite", node.Text ); Assert.AreEqual( "TestSuite", node.TestType ); node = new TestSuiteTreeNode( fixtureInfo ); Assert.AreEqual( "MockTestFixture", node.Text ); Assert.AreEqual( "TestFixture", node.TestType ); node = new TestSuiteTreeNode( testCaseInfo ); Assert.AreEqual( "MockTest1", node.Text ); Assert.AreEqual( "TestMethod", node.TestType ); } [Test] public void ResultNotSet() { TestSuiteTreeNode node = new TestSuiteTreeNode(testCaseInfo); Assert.AreEqual(TestSuiteTreeNode.InitIndex, node.ImageIndex); Assert.AreEqual(TestSuiteTreeNode.InitIndex, node.SelectedImageIndex); } [Test] public void SetResult_Inconclusive() { TestSuiteTreeNode node = new TestSuiteTreeNode(testCaseInfo); TestResult result = new TestResult(testCaseInfo); result.SetResult(ResultState.Inconclusive, null, null); node.Result = result; Assert.AreEqual("MockTest1", node.Result.Name); Assert.AreEqual(TestSuiteTreeNode.InconclusiveIndex, node.ImageIndex); Assert.AreEqual(TestSuiteTreeNode.InconclusiveIndex, node.SelectedImageIndex); Assert.AreEqual(result.ResultState.ToString(), node.StatusText); } [Test] public void SetResult_Ignore() { TestSuiteTreeNode node = new TestSuiteTreeNode( testCaseInfo ); TestResult result = new TestResult( testCaseInfo ); result.Ignore( "reason" ); node.Result = result; Assert.AreEqual( "MockTest1", node.Result.Name ); Assert.AreEqual( TestSuiteTreeNode.IgnoredIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.IgnoredIndex, node.SelectedImageIndex ); Assert.AreEqual( "Ignored", node.StatusText ); } [Test] public void SetResult_Success() { TestSuiteTreeNode node = new TestSuiteTreeNode( testCaseInfo ); TestResult result = new TestResult( testCaseInfo ); result.Success(); node.Result = result; Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node.SelectedImageIndex ); Assert.AreEqual( "Success", node.StatusText ); } [Test] public void SetResult_Failure() { TestSuiteTreeNode node = new TestSuiteTreeNode( testCaseInfo ); TestResult result = new TestResult( testCaseInfo ); result.Failure("message", "stacktrace"); node.Result = result; Assert.AreEqual( TestSuiteTreeNode.FailureIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.FailureIndex, node.SelectedImageIndex ); Assert.AreEqual( "Failure", node.StatusText ); } [Test] public void SetResult_Skipped() { TestSuiteTreeNode node = new TestSuiteTreeNode( testCaseInfo ); TestResult result = new TestResult( testCaseInfo ); result.Skip(""); node.Result = result; Assert.AreEqual( TestSuiteTreeNode.SkippedIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.SkippedIndex, node.SelectedImageIndex ); Assert.AreEqual( "Skipped", node.StatusText ); } [Test] public void ClearResult() { TestResult result = new TestResult( testCaseInfo ); result.Failure("message", "stacktrace"); TestSuiteTreeNode node = new TestSuiteTreeNode( result ); Assert.AreEqual( TestSuiteTreeNode.FailureIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.FailureIndex, node.SelectedImageIndex ); node.ClearResults(); Assert.AreEqual( null, node.Result ); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node.SelectedImageIndex ); } [Test] public void ClearNestedResults() { TestResult testCaseResult = new TestResult( testCaseInfo ); testCaseResult.Success(); TestResult testSuiteResult = new TestResult( fixtureInfo ); testSuiteResult.AddResult( testCaseResult ); testSuiteResult.Success(); TestSuiteTreeNode node1 = new TestSuiteTreeNode( testSuiteResult ); TestSuiteTreeNode node2 = new TestSuiteTreeNode( testCaseResult ); node1.Nodes.Add( node2 ); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node1.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node1.SelectedImageIndex ); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node2.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.SuccessIndex, node2.SelectedImageIndex ); node1.ClearResults(); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node1.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node1.SelectedImageIndex ); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node2.ImageIndex ); Assert.AreEqual( TestSuiteTreeNode.InitIndex, node2.SelectedImageIndex ); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/VisualStateTests.cs0000664000175000017500000000275711504175260023534 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.UiKit.Tests { /// /// Summary description for VisualStateTests. /// [TestFixture] public class VisualStateTests { [Test] public void SaveAndRestoreVisualState() { VisualState state = new VisualState(); state.ShowCheckBoxes = true; state.TopNode = "ABC.Test.dll"; state.SelectedNode = "NUnit.Tests.MyFixture.MyTest"; state.SelectedCategories = "A,B,C"; state.ExcludeCategories = true; StringWriter writer = new StringWriter(); state.Save( writer ); string output = writer.GetStringBuilder().ToString(); StringReader reader = new StringReader( output ); VisualState newState = VisualState.LoadFrom( reader ); Assert.AreEqual( state.ShowCheckBoxes, newState.ShowCheckBoxes, "ShowCheckBoxes" ); Assert.AreEqual( state.TopNode, newState.TopNode, "TopNode" ); Assert.AreEqual( state.SelectedNode, newState.SelectedNode, "SelectedNode" ); Assert.AreEqual( state.SelectedCategories, newState.SelectedCategories, "SelectedCategories" ); Assert.AreEqual( state.ExcludeCategories, newState.ExcludeCategories, "ExcludeCategories" ); } } } NUnit-2.6.0.12051/src/GuiComponents/tests/AddConfigurationDialogTests.cs0000664000175000017500000000476311504175260025627 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Framework; using NUnit.Util; using NUnit.TestUtilities; namespace NUnit.UiKit.Tests { [TestFixture] public class AddConfigurationDialogTests : FormTester { private NUnitProject project; private AddConfigurationDialog dlg; [SetUp] public void SetUp() { project = new NUnitProject( "path" ); project.Configs.Add( "Debug" ); project.Configs.Add( "Release" ); dlg = new AddConfigurationDialog( project ); this.Form = dlg; } [TearDown] public void TearDown() { dlg.Close(); } [Test] public void CheckForControls() { AssertControlExists( "configurationNameTextBox", typeof( TextBox ) ); AssertControlExists( "configurationComboBox", typeof( ComboBox ) ); AssertControlExists( "okButton", typeof( Button ) ); AssertControlExists( "cancelButton", typeof( Button ) ); } [Test] public void CheckTextBox() { TextBox configBox = TextBoxes["configurationNameTextBox"]; Assert.AreEqual( "", configBox.Text ); } [Test] public void CheckComboBox() { ComboBox combo = Combos["configurationComboBox"]; dlg.Show(); Assert.AreEqual( 3, combo.Items.Count ); Assert.AreEqual( "", combo.Items[0] ); Assert.AreEqual( "Debug", combo.Items[1] ); Assert.AreEqual( "Release", combo.Items[2] ); Assert.AreEqual( "Debug", combo.SelectedItem ); } [Test] public void TestSimpleEntry() { dlg.Show(); TextBox config = TextBoxes["configurationNameTextBox"]; Button okButton = Buttons["okButton"]; config.Text = "Super"; okButton.PerformClick(); Assert.AreEqual( "Super", dlg.ConfigurationName ); Assert.AreEqual( "Debug", dlg.CopyConfigurationName ); } [Test] public void TestComplexEntry() { dlg.Show(); TextBox config = TextBoxes["configurationNameTextBox"]; Button okButton = Buttons["okButton"]; ComboBox combo = Combos["configurationComboBox"]; config.Text = "Super"; combo.SelectedIndex = combo.FindStringExact( "" ); okButton.PerformClick(); Assert.AreEqual( "Super", dlg.ConfigurationName ); Assert.IsNull( dlg.CopyConfigurationName ); } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/0000775000175000017500000000000011742560362017573 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/UiKit/GuiAttachedConsole.cs0000664000175000017500000000136711504175260023631 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Runtime.InteropServices; namespace NUnit.UiKit { /// /// Summary description for GuiAttachedConsole. /// public class GuiAttachedConsole { public GuiAttachedConsole() { AllocConsole(); } public void Close() { FreeConsole(); } [DllImport("Kernel32.dll")] static extern bool AllocConsole(); [DllImport("Kernel32.dll")] static extern bool FreeConsole(); } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestTree.cs0000664000175000017500000006703511715463050021670 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { public delegate void SelectedTestsChangedEventHandler(object sender, SelectedTestsChangedEventArgs e); /// /// Summary description for TestTree. /// public class TestTree : System.Windows.Forms.UserControl { #region Instance Variables // Contains all available categories, whether // selected or not. Unselected members of this // list are displayed in selectedList private IList availableCategories = new List(); // Our test loader private TestLoader loader; private System.Windows.Forms.TabControl tabs; private System.Windows.Forms.TabPage testPage; private System.Windows.Forms.TabPage categoryPage; private System.Windows.Forms.Panel testPanel; private System.Windows.Forms.Panel categoryPanel; private System.Windows.Forms.Panel treePanel; private System.Windows.Forms.Panel buttonPanel; private NUnit.UiKit.TestSuiteTreeView tests; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.ListBox availableList; private System.Windows.Forms.GroupBox selectedCategories; private System.Windows.Forms.ListBox selectedList; private System.Windows.Forms.Panel categoryButtonPanel; private System.Windows.Forms.Button addCategory; private System.Windows.Forms.Button removeCategory; private System.Windows.Forms.Button clearAllButton; private System.Windows.Forms.Button checkFailedButton; private System.Windows.Forms.MenuItem treeMenu; private System.Windows.Forms.MenuItem checkBoxesMenuItem; private System.Windows.Forms.MenuItem treeMenuSeparatorItem1; private System.Windows.Forms.MenuItem expandMenuItem; private System.Windows.Forms.MenuItem collapseMenuItem; private System.Windows.Forms.MenuItem treeMenuSeparatorItem2; private System.Windows.Forms.MenuItem expandAllMenuItem; private System.Windows.Forms.MenuItem collapseAllMenuItem; private System.Windows.Forms.MenuItem hideTestsMenuItem; private System.Windows.Forms.MenuItem treeMenuSeparatorItem3; private System.Windows.Forms.MenuItem propertiesMenuItem; private System.Windows.Forms.CheckBox excludeCheckbox; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; #endregion #region Properties public MenuItem TreeMenu { get { return treeMenu; } } public string[] SelectedCategories { get { int n = this.selectedList.Items.Count; string[] categories = new string[n]; for( int i = 0; i < n; i++ ) categories[i] = this.selectedList.Items[i].ToString(); return categories; } } [Browsable(false)] public bool ShowCheckBoxes { get { return tests.CheckBoxes; } set { tests.CheckBoxes = value; buttonPanel.Visible = value; clearAllButton.Visible = value; checkFailedButton.Visible = value; checkBoxesMenuItem.Checked = value; } } #endregion #region Construction and Initialization public TestTree() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); treeMenu = new MenuItem(); this.checkBoxesMenuItem = new System.Windows.Forms.MenuItem(); this.treeMenuSeparatorItem1 = new System.Windows.Forms.MenuItem(); this.expandMenuItem = new System.Windows.Forms.MenuItem(); this.collapseMenuItem = new System.Windows.Forms.MenuItem(); this.treeMenuSeparatorItem2 = new System.Windows.Forms.MenuItem(); this.expandAllMenuItem = new System.Windows.Forms.MenuItem(); this.collapseAllMenuItem = new System.Windows.Forms.MenuItem(); this.hideTestsMenuItem = new System.Windows.Forms.MenuItem(); this.treeMenuSeparatorItem3 = new System.Windows.Forms.MenuItem(); this.propertiesMenuItem = new System.Windows.Forms.MenuItem(); // // treeMenu // this.treeMenu.MergeType = MenuMerge.Add; this.treeMenu.MergeOrder = 1; this.treeMenu.MenuItems.AddRange( new System.Windows.Forms.MenuItem[] { this.checkBoxesMenuItem, this.treeMenuSeparatorItem1, this.expandMenuItem, this.collapseMenuItem, this.treeMenuSeparatorItem2, this.expandAllMenuItem, this.collapseAllMenuItem, this.hideTestsMenuItem, this.treeMenuSeparatorItem3, this.propertiesMenuItem } ); this.treeMenu.Text = "&Tree"; this.treeMenu.Visible = false; this.treeMenu.Popup += new System.EventHandler(this.treeMenu_Popup); // // checkBoxesMenuItem // this.checkBoxesMenuItem.Index = 0; this.checkBoxesMenuItem.Text = "Show Check&Boxes"; this.checkBoxesMenuItem.Click += new System.EventHandler(this.checkBoxesMenuItem_Click); // // treeMenuSeparatorItem1 // this.treeMenuSeparatorItem1.Index = 1; this.treeMenuSeparatorItem1.Text = "-"; // // expandMenuItem // this.expandMenuItem.Index = 2; this.expandMenuItem.Text = "&Expand"; this.expandMenuItem.Click += new System.EventHandler(this.expandMenuItem_Click); // // collapseMenuItem // this.collapseMenuItem.Index = 3; this.collapseMenuItem.Text = "&Collapse"; this.collapseMenuItem.Click += new System.EventHandler(this.collapseMenuItem_Click); // // treeMenuSeparatorItem2 // this.treeMenuSeparatorItem2.Index = 4; this.treeMenuSeparatorItem2.Text = "-"; // // expandAllMenuItem // this.expandAllMenuItem.Index = 5; this.expandAllMenuItem.Text = "Expand All"; this.expandAllMenuItem.Click += new System.EventHandler(this.expandAllMenuItem_Click); // // collapseAllMenuItem // this.collapseAllMenuItem.Index = 6; this.collapseAllMenuItem.Text = "Collapse All"; this.collapseAllMenuItem.Click += new System.EventHandler(this.collapseAllMenuItem_Click); // // hideTestsMenuItem // this.hideTestsMenuItem.Index = 7; this.hideTestsMenuItem.Text = "Hide Tests"; this.hideTestsMenuItem.Click += new System.EventHandler(this.hideTestsMenuItem_Click); // // treeMenuSeparatorItem3 // this.treeMenuSeparatorItem3.Index = 8; this.treeMenuSeparatorItem3.Text = "-"; // // propertiesMenuItem // this.propertiesMenuItem.Index = 9; this.propertiesMenuItem.Text = "&Properties"; this.propertiesMenuItem.Click += new System.EventHandler(this.propertiesMenuItem_Click); tests.SelectedTestChanged += new SelectedTestChangedHandler(tests_SelectedTestChanged); tests.CheckedTestChanged += new CheckedTestChangedHandler(tests_CheckedTestChanged); this.excludeCheckbox.Enabled = false; } protected override void OnLoad(EventArgs e) { if ( !this.DesignMode ) { this.ShowCheckBoxes = Services.UserSettings.GetSetting( "Options.ShowCheckBoxes", false ); Initialize( Services.TestLoader ); Services.UserSettings.Changed += new SettingsEventHandler(UserSettings_Changed); } base.OnLoad (e); } public void Initialize(TestLoader loader) { this.tests.Initialize(loader, loader.Events); this.loader = loader; loader.Events.TestLoaded += new NUnit.Util.TestEventHandler(events_TestLoaded); loader.Events.TestReloaded += new NUnit.Util.TestEventHandler(events_TestReloaded); loader.Events.TestUnloaded += new NUnit.Util.TestEventHandler(events_TestUnloaded); } public void SelectCategories( string[] categories, bool exclude ) { foreach( string category in categories ) { if ( availableCategories.Contains( category ) ) { if (!selectedList.Items.Contains(category)) { selectedList.Items.Add(category); } availableList.Items.Remove( category ); this.excludeCheckbox.Checked = exclude; } } UpdateCategoryFilter(); if (this.SelectedCategories.Length > 0) this.excludeCheckbox.Enabled = true; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region View Menu Handlers private void treeMenu_Popup(object sender, System.EventArgs e) { TreeNode selectedNode = tests.SelectedNode; if ( selectedNode != null && selectedNode.Nodes.Count > 0 ) { bool isExpanded = selectedNode.IsExpanded; collapseMenuItem.Enabled = isExpanded; expandMenuItem.Enabled = !isExpanded; } else { collapseMenuItem.Enabled = expandMenuItem.Enabled = false; } } private void collapseMenuItem_Click(object sender, System.EventArgs e) { tests.SelectedNode.Collapse(); } private void expandMenuItem_Click(object sender, System.EventArgs e) { tests.SelectedNode.Expand(); } private void collapseAllMenuItem_Click(object sender, System.EventArgs e) { tests.BeginUpdate(); tests.CollapseAll(); tests.EndUpdate(); // Compensate for a bug in the underlying control if ( tests.Nodes.Count > 0 ) tests.SelectedNode = tests.Nodes[0]; } private void hideTestsMenuItem_Click(object sender, System.EventArgs e) { tests.HideTests(); } private void expandAllMenuItem_Click(object sender, System.EventArgs e) { tests.BeginUpdate(); tests.ExpandAll(); tests.EndUpdate(); } private void propertiesMenuItem_Click(object sender, System.EventArgs e) { if ( tests.SelectedTest != null ) tests.ShowPropertiesDialog( tests.SelectedTest ); } #endregion #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.tabs = new System.Windows.Forms.TabControl(); this.testPage = new System.Windows.Forms.TabPage(); this.testPanel = new System.Windows.Forms.Panel(); this.treePanel = new System.Windows.Forms.Panel(); this.tests = new NUnit.UiKit.TestSuiteTreeView(); this.buttonPanel = new System.Windows.Forms.Panel(); this.checkFailedButton = new System.Windows.Forms.Button(); this.clearAllButton = new System.Windows.Forms.Button(); this.categoryPage = new System.Windows.Forms.TabPage(); this.categoryPanel = new System.Windows.Forms.Panel(); this.categoryButtonPanel = new System.Windows.Forms.Panel(); this.removeCategory = new System.Windows.Forms.Button(); this.addCategory = new System.Windows.Forms.Button(); this.selectedCategories = new System.Windows.Forms.GroupBox(); this.selectedList = new System.Windows.Forms.ListBox(); this.excludeCheckbox = new System.Windows.Forms.CheckBox(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.availableList = new System.Windows.Forms.ListBox(); this.tabs.SuspendLayout(); this.testPage.SuspendLayout(); this.testPanel.SuspendLayout(); this.treePanel.SuspendLayout(); this.buttonPanel.SuspendLayout(); this.categoryPage.SuspendLayout(); this.categoryPanel.SuspendLayout(); this.categoryButtonPanel.SuspendLayout(); this.selectedCategories.SuspendLayout(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // tabs // this.tabs.Alignment = System.Windows.Forms.TabAlignment.Left; this.tabs.Controls.Add(this.testPage); this.tabs.Controls.Add(this.categoryPage); this.tabs.Dock = System.Windows.Forms.DockStyle.Fill; this.tabs.Location = new System.Drawing.Point(0, 0); this.tabs.Multiline = true; this.tabs.Name = "tabs"; this.tabs.SelectedIndex = 0; this.tabs.Size = new System.Drawing.Size(248, 496); this.tabs.TabIndex = 0; // // testPage // this.testPage.Controls.Add(this.testPanel); this.testPage.Location = new System.Drawing.Point(25, 4); this.testPage.Name = "testPage"; this.testPage.Size = new System.Drawing.Size(219, 488); this.testPage.TabIndex = 0; this.testPage.Text = "Tests"; // // testPanel // this.testPanel.Controls.Add(this.treePanel); this.testPanel.Controls.Add(this.buttonPanel); this.testPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.testPanel.Location = new System.Drawing.Point(0, 0); this.testPanel.Name = "testPanel"; this.testPanel.Size = new System.Drawing.Size(219, 488); this.testPanel.TabIndex = 0; // // treePanel // this.treePanel.Controls.Add(this.tests); this.treePanel.Dock = System.Windows.Forms.DockStyle.Fill; this.treePanel.Location = new System.Drawing.Point(0, 0); this.treePanel.Name = "treePanel"; this.treePanel.Size = new System.Drawing.Size(219, 448); this.treePanel.TabIndex = 0; // // tests // this.tests.AllowDrop = true; this.tests.Dock = System.Windows.Forms.DockStyle.Fill; this.tests.HideSelection = false; this.tests.Location = new System.Drawing.Point(0, 0); this.tests.Name = "tests"; this.tests.Size = new System.Drawing.Size(219, 448); this.tests.TabIndex = 0; this.tests.CheckBoxesChanged += new System.EventHandler(this.tests_CheckBoxesChanged); // // buttonPanel // this.buttonPanel.Controls.Add(this.checkFailedButton); this.buttonPanel.Controls.Add(this.clearAllButton); this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom; this.buttonPanel.Location = new System.Drawing.Point(0, 448); this.buttonPanel.Name = "buttonPanel"; this.buttonPanel.Size = new System.Drawing.Size(219, 40); this.buttonPanel.TabIndex = 1; // // checkFailedButton // this.checkFailedButton.Anchor = System.Windows.Forms.AnchorStyles.Top; this.checkFailedButton.Location = new System.Drawing.Point(117, 8); this.checkFailedButton.Name = "checkFailedButton"; this.checkFailedButton.Size = new System.Drawing.Size(96, 23); this.checkFailedButton.TabIndex = 1; this.checkFailedButton.Text = "Check Failed"; this.checkFailedButton.Click += new System.EventHandler(this.checkFailedButton_Click); // // clearAllButton // this.clearAllButton.Anchor = System.Windows.Forms.AnchorStyles.Top; this.clearAllButton.Location = new System.Drawing.Point(13, 8); this.clearAllButton.Name = "clearAllButton"; this.clearAllButton.Size = new System.Drawing.Size(96, 23); this.clearAllButton.TabIndex = 0; this.clearAllButton.Text = "Clear All"; this.clearAllButton.Click += new System.EventHandler(this.clearAllButton_Click); // // categoryPage // this.categoryPage.Controls.Add(this.categoryPanel); this.categoryPage.Location = new System.Drawing.Point(25, 4); this.categoryPage.Name = "categoryPage"; this.categoryPage.Size = new System.Drawing.Size(219, 488); this.categoryPage.TabIndex = 1; this.categoryPage.Text = "Categories"; // // categoryPanel // this.categoryPanel.Controls.Add(this.categoryButtonPanel); this.categoryPanel.Controls.Add(this.selectedCategories); this.categoryPanel.Controls.Add(this.groupBox1); this.categoryPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.categoryPanel.Location = new System.Drawing.Point(0, 0); this.categoryPanel.Name = "categoryPanel"; this.categoryPanel.Size = new System.Drawing.Size(219, 488); this.categoryPanel.TabIndex = 0; // // categoryButtonPanel // this.categoryButtonPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.categoryButtonPanel.Controls.Add(this.removeCategory); this.categoryButtonPanel.Controls.Add(this.addCategory); this.categoryButtonPanel.Location = new System.Drawing.Point(8, 280); this.categoryButtonPanel.Name = "categoryButtonPanel"; this.categoryButtonPanel.Size = new System.Drawing.Size(203, 40); this.categoryButtonPanel.TabIndex = 1; // // removeCategory // this.removeCategory.Anchor = System.Windows.Forms.AnchorStyles.Top; this.removeCategory.Location = new System.Drawing.Point(109, 8); this.removeCategory.Name = "removeCategory"; this.removeCategory.TabIndex = 1; this.removeCategory.Text = "Remove"; this.removeCategory.Click += new System.EventHandler(this.removeCategory_Click); // // addCategory // this.addCategory.Anchor = System.Windows.Forms.AnchorStyles.Top; this.addCategory.Location = new System.Drawing.Point(21, 8); this.addCategory.Name = "addCategory"; this.addCategory.TabIndex = 0; this.addCategory.Text = "Add"; this.addCategory.Click += new System.EventHandler(this.addCategory_Click); // // selectedCategories // this.selectedCategories.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.selectedCategories.Controls.Add(this.selectedList); this.selectedCategories.Controls.Add(this.excludeCheckbox); this.selectedCategories.Location = new System.Drawing.Point(8, 328); this.selectedCategories.Name = "selectedCategories"; this.selectedCategories.Size = new System.Drawing.Size(203, 144); this.selectedCategories.TabIndex = 2; this.selectedCategories.TabStop = false; this.selectedCategories.Text = "Selected Categories"; // // selectedList // this.selectedList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.selectedList.ItemHeight = 16; this.selectedList.Location = new System.Drawing.Point(8, 16); this.selectedList.Name = "selectedList"; this.selectedList.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; this.selectedList.Size = new System.Drawing.Size(187, 84); this.selectedList.TabIndex = 0; this.selectedList.DoubleClick += new System.EventHandler(this.removeCategory_Click); // // excludeCheckbox // this.excludeCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.excludeCheckbox.Location = new System.Drawing.Point(8, 120); this.excludeCheckbox.Name = "excludeCheckbox"; this.excludeCheckbox.Size = new System.Drawing.Size(179, 16); this.excludeCheckbox.TabIndex = 1; this.excludeCheckbox.Text = "Exclude these categories"; this.excludeCheckbox.CheckedChanged += new System.EventHandler(this.excludeCheckbox_CheckedChanged); // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.availableList); this.groupBox1.Location = new System.Drawing.Point(8, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(203, 272); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = "Available Categories"; // // availableList // this.availableList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.availableList.ItemHeight = 16; this.availableList.Location = new System.Drawing.Point(8, 24); this.availableList.Name = "availableList"; this.availableList.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; this.availableList.Size = new System.Drawing.Size(187, 244); this.availableList.TabIndex = 0; this.availableList.DoubleClick += new System.EventHandler(this.addCategory_Click); // // TestTree // this.Controls.Add(this.tabs); this.Name = "TestTree"; this.Size = new System.Drawing.Size(248, 496); this.tabs.ResumeLayout(false); this.testPage.ResumeLayout(false); this.testPanel.ResumeLayout(false); this.treePanel.ResumeLayout(false); this.buttonPanel.ResumeLayout(false); this.categoryPage.ResumeLayout(false); this.categoryPanel.ResumeLayout(false); this.categoryButtonPanel.ResumeLayout(false); this.selectedCategories.ResumeLayout(false); this.groupBox1.ResumeLayout(false); this.ResumeLayout(false); } #endregion #region SelectedTestsChanged Event public event SelectedTestsChangedEventHandler SelectedTestsChanged; #endregion public void RunAllTests() { RunAllTests(true); } public void RunAllTests(bool ignoreTests) { tests.RunAllTests(ignoreTests); } public void RunSelectedTests() { tests.RunSelectedTests(); } public void RunFailedTests() { tests.RunFailedTests(); } private void addCategory_Click(object sender, System.EventArgs e) { if (availableList.SelectedItems.Count > 0) { // Create a separate list to avoid exception // when using the list box directly. List categories = new List(); foreach ( string category in availableList.SelectedItems ) categories.Add(category); foreach ( string category in categories) { selectedList.Items.Add(category); availableList.Items.Remove(category); } UpdateCategoryFilter(); if (this.SelectedCategories.Length > 0) this.excludeCheckbox.Enabled = true; } } private void removeCategory_Click(object sender, System.EventArgs e) { if (selectedList.SelectedItems.Count > 0) { // Create a separate list to avoid exception // when using the list box directly. List categories = new List(); foreach (string category in selectedList.SelectedItems) categories.Add(category); foreach ( string category in categories ) { selectedList.Items.Remove(category); availableList.Items.Add(category); } UpdateCategoryFilter(); if (this.SelectedCategories.Length == 0) { this.excludeCheckbox.Checked = false; this.excludeCheckbox.Enabled = false; } } } private void clearAllButton_Click(object sender, System.EventArgs e) { tests.ClearCheckedNodes(); } private void checkFailedButton_Click(object sender, System.EventArgs e) { tests.CheckFailedNodes(); } private void tests_SelectedTestChanged(ITest test) { if (SelectedTestsChanged != null) { SelectedTestsChangedEventArgs args = new SelectedTestsChangedEventArgs(test.TestName.Name, test.TestCount); SelectedTestsChanged(tests, args); } } private void events_TestLoaded(object sender, NUnit.Util.TestEventArgs args) { treeMenu.Visible = true; availableCategories = this.loader.GetCategories(); availableList.Items.Clear(); selectedList.Items.Clear(); availableList.SuspendLayout(); foreach (string category in availableCategories) availableList.Items.Add(category); // tree may have restored visual state if( !tests.CategoryFilter.IsEmpty ) { ITestFilter filter = tests.CategoryFilter; if ( filter is NUnit.Core.Filters.NotFilter ) { filter = ((NUnit.Core.Filters.NotFilter)filter).BaseFilter; this.excludeCheckbox.Checked = true; } foreach( string cat in ((NUnit.Core.Filters.CategoryFilter)filter).Categories ) if ( this.availableCategories.Contains( cat ) ) { this.availableList.Items.Remove( cat ); this.selectedList.Items.Add( cat ); this.excludeCheckbox.Enabled = true; } UpdateCategoryFilter(); } availableList.ResumeLayout(); } private void events_TestReloaded(object sender, NUnit.Util.TestEventArgs args) { // Get new list of available categories availableCategories = this.loader.GetCategories(); // Remove any selected items that are no longer available int index = selectedList.Items.Count; selectedList.SuspendLayout(); while( --index >= 0 ) { string category = selectedList.Items[index].ToString(); if ( !availableCategories.Contains( category ) ) selectedList.Items.RemoveAt( index ); } selectedList.ResumeLayout(); // Put any unselected available items availableList availableList.Items.Clear(); availableList.SuspendLayout(); foreach( string category in availableCategories ) if( selectedList.FindStringExact( category ) < 0 ) availableList.Items.Add( category ); availableList.ResumeLayout(); // Tell the tree what is selected UpdateCategoryFilter(); } private void excludeCheckbox_CheckedChanged(object sender, System.EventArgs e) { UpdateCategoryFilter(); } private void events_TestUnloaded(object sender, NUnit.Util.TestEventArgs args) { availableCategories.Clear(); availableList.Items.Clear(); selectedList.Items.Clear(); excludeCheckbox.Checked = false; excludeCheckbox.Enabled = false; treeMenu.Visible = false; } private void tests_CheckedTestChanged(ITest[] tests) { if (SelectedTestsChanged != null) { SelectedTestsChangedEventArgs args = new SelectedTestsChangedEventArgs("", tests.Length); SelectedTestsChanged(tests, args); } if (tests.Length > 0) { } } private void checkBoxesMenuItem_Click(object sender, System.EventArgs e) { Services.UserSettings.SaveSetting( "Options.ShowCheckBoxes", ShowCheckBoxes = !checkBoxesMenuItem.Checked ); // Temporary till we can save tree state and restore //this.SetInitialExpansion(); } private void UpdateCategoryFilter() { TestFilter catFilter; if ( SelectedCategories == null || SelectedCategories.Length == 0 ) catFilter = TestFilter.Empty; else catFilter = new NUnit.Core.Filters.CategoryFilter( SelectedCategories ); if ( excludeCheckbox.Checked ) catFilter = new NUnit.Core.Filters.NotFilter( catFilter ); tests.CategoryFilter = catFilter; } private void tests_CheckBoxesChanged(object sender, System.EventArgs e) { ShowCheckBoxes = tests.CheckBoxes; } private void UserSettings_Changed(object sender, SettingsEventArgs args) { if ( args.SettingName == "Options.ShowCheckBoxes" ) this.ShowCheckBoxes = Services.UserSettings.GetSetting( args.SettingName, false ); } } public class SelectedTestsChangedEventArgs : EventArgs { private string testName; private int count; public SelectedTestsChangedEventArgs(string testName, int count) { this.testName = testName; this.count = count; } public string TestName { get { return testName; } } public int TestCount { get { return count; } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestPropertiesDialog.Designer.cs0000664000175000017500000004523211672151200025770 0ustar jtaylorjtaylornamespace NUnit.UiKit { partial class TestPropertiesDialog { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.testResult = new System.Windows.Forms.Label(); this.pinButton = new System.Windows.Forms.CheckBox(); this.testName = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.hiddenProperties = new System.Windows.Forms.CheckBox(); this.categories = new System.Windows.Forms.Label(); this.properties = new System.Windows.Forms.ListBox(); this.propertiesLabel = new System.Windows.Forms.Label(); this.testCaseCount = new System.Windows.Forms.Label(); this.ignoreReasonLabel = new System.Windows.Forms.Label(); this.testCaseCountLabel = new System.Windows.Forms.Label(); this.shouldRun = new System.Windows.Forms.Label(); this.shouldRunLabel = new System.Windows.Forms.Label(); this.testType = new System.Windows.Forms.Label(); this.testTypeLabel = new System.Windows.Forms.Label(); this.categoriesLabel = new System.Windows.Forms.Label(); this.descriptionLabel = new System.Windows.Forms.Label(); this.fullNameLabel = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.assertCount = new System.Windows.Forms.Label(); this.messageLabel = new System.Windows.Forms.Label(); this.elapsedTime = new System.Windows.Forms.Label(); this.stackTraceLabel = new System.Windows.Forms.Label(); this.message = new CP.Windows.Forms.ExpandingLabel(); this.stackTrace = new CP.Windows.Forms.ExpandingLabel(); this.description = new CP.Windows.Forms.ExpandingLabel(); this.ignoreReason = new CP.Windows.Forms.ExpandingLabel(); this.fullName = new CP.Windows.Forms.ExpandingLabel(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.SuspendLayout(); // // testResult // this.testResult.Location = new System.Drawing.Point(9, 11); this.testResult.Name = "testResult"; this.testResult.Size = new System.Drawing.Size(120, 16); this.testResult.TabIndex = 0; this.testResult.Text = "Inconclusive"; // // pinButton // this.pinButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.pinButton.Appearance = System.Windows.Forms.Appearance.Button; this.pinButton.Location = new System.Drawing.Point(416, 10); this.pinButton.Name = "pinButton"; this.pinButton.Size = new System.Drawing.Size(20, 20); this.pinButton.TabIndex = 2; this.pinButton.Click += new System.EventHandler(this.pinButton_Click); // // testName // this.testName.Location = new System.Drawing.Point(135, 12); this.testName.Name = "testName"; this.testName.Size = new System.Drawing.Size(280, 14); this.testName.TabIndex = 1; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.hiddenProperties); this.groupBox1.Controls.Add(this.description); this.groupBox1.Controls.Add(this.categories); this.groupBox1.Controls.Add(this.properties); this.groupBox1.Controls.Add(this.propertiesLabel); this.groupBox1.Controls.Add(this.testCaseCount); this.groupBox1.Controls.Add(this.ignoreReason); this.groupBox1.Controls.Add(this.ignoreReasonLabel); this.groupBox1.Controls.Add(this.testCaseCountLabel); this.groupBox1.Controls.Add(this.shouldRun); this.groupBox1.Controls.Add(this.shouldRunLabel); this.groupBox1.Controls.Add(this.testType); this.groupBox1.Controls.Add(this.testTypeLabel); this.groupBox1.Controls.Add(this.categoriesLabel); this.groupBox1.Controls.Add(this.descriptionLabel); this.groupBox1.Controls.Add(this.fullName); this.groupBox1.Controls.Add(this.fullNameLabel); this.groupBox1.Location = new System.Drawing.Point(12, 39); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(424, 218); this.groupBox1.TabIndex = 3; this.groupBox1.TabStop = false; this.groupBox1.Text = "Test Details"; // // hiddenProperties // this.hiddenProperties.AutoSize = true; this.hiddenProperties.Location = new System.Drawing.Point(139, 192); this.hiddenProperties.Name = "hiddenProperties"; this.hiddenProperties.Size = new System.Drawing.Size(144, 17); this.hiddenProperties.TabIndex = 16; this.hiddenProperties.Text = "Display hidden properties"; this.hiddenProperties.UseVisualStyleBackColor = true; this.hiddenProperties.CheckedChanged += new System.EventHandler(this.hiddenProperties_CheckedChanged); // // categories // this.categories.Location = new System.Drawing.Point(101, 86); this.categories.Name = "categories"; this.categories.Size = new System.Drawing.Size(309, 16); this.categories.TabIndex = 7; // // properties // this.properties.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.properties.Location = new System.Drawing.Point(104, 143); this.properties.Name = "properties"; this.properties.Size = new System.Drawing.Size(308, 43); this.properties.TabIndex = 15; // // propertiesLabel // this.propertiesLabel.Location = new System.Drawing.Point(13, 143); this.propertiesLabel.Name = "propertiesLabel"; this.propertiesLabel.Size = new System.Drawing.Size(80, 16); this.propertiesLabel.TabIndex = 14; this.propertiesLabel.Text = "Properties:"; // // testCaseCount // this.testCaseCount.Location = new System.Drawing.Point(101, 108); this.testCaseCount.Name = "testCaseCount"; this.testCaseCount.Size = new System.Drawing.Size(48, 15); this.testCaseCount.TabIndex = 9; // // ignoreReasonLabel // this.ignoreReasonLabel.Location = new System.Drawing.Point(13, 125); this.ignoreReasonLabel.Name = "ignoreReasonLabel"; this.ignoreReasonLabel.RightToLeft = System.Windows.Forms.RightToLeft.No; this.ignoreReasonLabel.Size = new System.Drawing.Size(80, 16); this.ignoreReasonLabel.TabIndex = 12; this.ignoreReasonLabel.Text = "Reason:"; // // testCaseCountLabel // this.testCaseCountLabel.Location = new System.Drawing.Point(13, 108); this.testCaseCountLabel.Name = "testCaseCountLabel"; this.testCaseCountLabel.Size = new System.Drawing.Size(80, 15); this.testCaseCountLabel.TabIndex = 8; this.testCaseCountLabel.Text = "Test Count:"; // // shouldRun // this.shouldRun.Location = new System.Drawing.Point(299, 108); this.shouldRun.Name = "shouldRun"; this.shouldRun.Size = new System.Drawing.Size(88, 15); this.shouldRun.TabIndex = 11; this.shouldRun.Text = "Yes"; // // shouldRunLabel // this.shouldRunLabel.Location = new System.Drawing.Point(183, 108); this.shouldRunLabel.Name = "shouldRunLabel"; this.shouldRunLabel.Size = new System.Drawing.Size(84, 15); this.shouldRunLabel.TabIndex = 10; this.shouldRunLabel.Text = "Should Run?"; // // testType // this.testType.Location = new System.Drawing.Point(101, 24); this.testType.Name = "testType"; this.testType.Size = new System.Drawing.Size(311, 16); this.testType.TabIndex = 1; // // testTypeLabel // this.testTypeLabel.Location = new System.Drawing.Point(13, 24); this.testTypeLabel.Name = "testTypeLabel"; this.testTypeLabel.Size = new System.Drawing.Size(80, 16); this.testTypeLabel.TabIndex = 0; this.testTypeLabel.Text = "Test Type:"; // // categoriesLabel // this.categoriesLabel.Location = new System.Drawing.Point(13, 86); this.categoriesLabel.Name = "categoriesLabel"; this.categoriesLabel.Size = new System.Drawing.Size(80, 16); this.categoriesLabel.TabIndex = 6; this.categoriesLabel.Text = "Categories:"; // // descriptionLabel // this.descriptionLabel.Location = new System.Drawing.Point(13, 64); this.descriptionLabel.Name = "descriptionLabel"; this.descriptionLabel.Size = new System.Drawing.Size(80, 17); this.descriptionLabel.TabIndex = 4; this.descriptionLabel.Text = "Description:"; // // fullNameLabel // this.fullNameLabel.Location = new System.Drawing.Point(13, 43); this.fullNameLabel.Name = "fullNameLabel"; this.fullNameLabel.Size = new System.Drawing.Size(80, 17); this.fullNameLabel.TabIndex = 2; this.fullNameLabel.Text = "Full Name:"; // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Controls.Add(this.assertCount); this.groupBox2.Controls.Add(this.messageLabel); this.groupBox2.Controls.Add(this.elapsedTime); this.groupBox2.Controls.Add(this.stackTraceLabel); this.groupBox2.Controls.Add(this.message); this.groupBox2.Controls.Add(this.stackTrace); this.groupBox2.Location = new System.Drawing.Point(12, 263); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(424, 136); this.groupBox2.TabIndex = 4; this.groupBox2.TabStop = false; this.groupBox2.Text = "Result"; // // assertCount // this.assertCount.Location = new System.Drawing.Point(234, 26); this.assertCount.Name = "assertCount"; this.assertCount.Size = new System.Drawing.Size(178, 16); this.assertCount.TabIndex = 1; this.assertCount.Text = "Assert Count:"; // // messageLabel // this.messageLabel.Location = new System.Drawing.Point(18, 47); this.messageLabel.Name = "messageLabel"; this.messageLabel.Size = new System.Drawing.Size(80, 17); this.messageLabel.TabIndex = 2; this.messageLabel.Text = "Message:"; // // elapsedTime // this.elapsedTime.Location = new System.Drawing.Point(18, 26); this.elapsedTime.Name = "elapsedTime"; this.elapsedTime.Size = new System.Drawing.Size(192, 16); this.elapsedTime.TabIndex = 0; this.elapsedTime.Text = "Execution Time:"; // // stackTraceLabel // this.stackTraceLabel.Location = new System.Drawing.Point(18, 70); this.stackTraceLabel.Name = "stackTraceLabel"; this.stackTraceLabel.Size = new System.Drawing.Size(80, 15); this.stackTraceLabel.TabIndex = 4; this.stackTraceLabel.Text = "Stack:"; // // message // this.message.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.message.CopySupported = true; this.message.Expansion = CP.Windows.Forms.TipWindow.ExpansionStyle.Both; this.message.Location = new System.Drawing.Point(106, 47); this.message.Name = "message"; this.message.Size = new System.Drawing.Size(306, 17); this.message.TabIndex = 3; // // stackTrace // this.stackTrace.CopySupported = true; this.stackTrace.Expansion = CP.Windows.Forms.TipWindow.ExpansionStyle.Both; this.stackTrace.Location = new System.Drawing.Point(106, 70); this.stackTrace.Name = "stackTrace"; this.stackTrace.Size = new System.Drawing.Size(306, 50); this.stackTrace.TabIndex = 5; // // description // this.description.CopySupported = true; this.description.Expansion = CP.Windows.Forms.TipWindow.ExpansionStyle.Both; this.description.Location = new System.Drawing.Point(101, 64); this.description.Name = "description"; this.description.Size = new System.Drawing.Size(311, 17); this.description.TabIndex = 5; // // ignoreReason // this.ignoreReason.CopySupported = true; this.ignoreReason.Expansion = CP.Windows.Forms.TipWindow.ExpansionStyle.Vertical; this.ignoreReason.Location = new System.Drawing.Point(101, 125); this.ignoreReason.Name = "ignoreReason"; this.ignoreReason.RightToLeft = System.Windows.Forms.RightToLeft.No; this.ignoreReason.Size = new System.Drawing.Size(311, 16); this.ignoreReason.TabIndex = 13; // // fullName // this.fullName.CopySupported = true; this.fullName.Location = new System.Drawing.Point(101, 43); this.fullName.Name = "fullName"; this.fullName.Size = new System.Drawing.Size(309, 15); this.fullName.TabIndex = 3; // // TestPropertiesDialog // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(448, 410); this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox1); this.Controls.Add(this.testName); this.Controls.Add(this.pinButton); this.Controls.Add(this.testResult); this.Name = "TestPropertiesDialog"; this.Text = "Test Properties"; this.Load += new System.EventHandler(this.TestPropertiesDialog_Load); this.SizeChanged += new System.EventHandler(this.TestPropertiesDialog_SizeChanged); this.ResizeEnd += new System.EventHandler(this.TestPropertiesDialog_ResizeEnd); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.groupBox2.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Label testResult; private System.Windows.Forms.CheckBox pinButton; private System.Windows.Forms.Label testName; private System.Windows.Forms.GroupBox groupBox1; private CP.Windows.Forms.ExpandingLabel description; private System.Windows.Forms.Label categories; private System.Windows.Forms.ListBox properties; private System.Windows.Forms.Label propertiesLabel; private System.Windows.Forms.Label testCaseCount; private CP.Windows.Forms.ExpandingLabel ignoreReason; private System.Windows.Forms.Label ignoreReasonLabel; private System.Windows.Forms.Label testCaseCountLabel; private System.Windows.Forms.Label shouldRun; private System.Windows.Forms.Label shouldRunLabel; private System.Windows.Forms.Label testType; private System.Windows.Forms.Label testTypeLabel; private System.Windows.Forms.Label categoriesLabel; private System.Windows.Forms.Label descriptionLabel; private CP.Windows.Forms.ExpandingLabel fullName; private System.Windows.Forms.Label fullNameLabel; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.Label assertCount; private System.Windows.Forms.Label messageLabel; private System.Windows.Forms.Label elapsedTime; private System.Windows.Forms.Label stackTraceLabel; private CP.Windows.Forms.ExpandingLabel message; private CP.Windows.Forms.ExpandingLabel stackTrace; private System.Windows.Forms.CheckBox hiddenProperties; } }NUnit-2.6.0.12051/src/GuiComponents/UiKit/NotRunTree.cs0000664000175000017500000000345211504175260022166 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { /// /// Summary description for NotRunTree. /// public class NotRunTree : TreeView, TestObserver { #region TestObserver Members and TestEventHandlers public void Subscribe(ITestEvents events) { events.TestLoaded += new TestEventHandler(ClearTreeNodes); events.TestUnloaded += new TestEventHandler(ClearTreeNodes); events.TestReloaded += new TestEventHandler(OnTestReloaded); events.RunStarting += new TestEventHandler(ClearTreeNodes); events.TestFinished += new TestEventHandler(OnTestFinished); events.SuiteFinished += new TestEventHandler(OnTestFinished); } private void OnTestFinished( object sender, TestEventArgs args ) { TestResult result = args.Result; if ( result.ResultState == ResultState.Skipped || result.ResultState == ResultState.Ignored) this.AddNode( args.Result ); } private void ClearTreeNodes(object sender, TestEventArgs args) { this.Nodes.Clear(); } private void OnTestReloaded(object sender, TestEventArgs args) { if ( Services.UserSettings.GetSetting( "Options.TestLoader.ClearResultsOnReload", false ) ) this.Nodes.Clear(); } private void AddNode( TestResult result ) { TreeNode node = new TreeNode(result.Name); TreeNode reasonNode = new TreeNode("Reason: " + result.Message); node.Nodes.Add(reasonNode); Nodes.Add( node ); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ExpandingTextBox.resx0000664000175000017500000001213611504175260023727 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False ExpandingLabel NUnit-2.6.0.12051/src/GuiComponents/UiKit/WaitCursor.cs0000664000175000017500000000232011504175260022214 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace CP.Windows.Forms { /// /// Utility class used to display a wait cursor /// while a long operation takes place and /// guarantee that it will be removed on exit. /// /// Use as follows: /// /// using ( new WaitCursor() ) /// { /// // Long running operation goes here /// } /// /// public class WaitCursor : IDisposable { private Cursor cursor; private Control control; public WaitCursor() { this.control = null; this.cursor = Cursor.Current; Cursor.Current = Cursors.WaitCursor; } public WaitCursor( Control control ) { this.control = control; this.cursor = control.Cursor; control.Cursor = Cursors.WaitCursor; } public void Dispose() { if ( control != null ) control.Cursor = this.cursor; else Cursor.Current = this.cursor; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/SettingsDialogBase.cs0000664000175000017500000001267211544330406023637 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { /// /// Summary description for OptionsDialogBase. /// public class SettingsDialogBase : NUnitFormBase { #region Instance Fields protected System.Windows.Forms.Button cancelButton; protected System.Windows.Forms.Button okButton; private SettingsPageCollection pageList; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private bool reloadProjectOnClose; #endregion #region Construction and Disposal public SettingsDialogBase() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // pageList = new SettingsPageCollection( ); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.cancelButton = new System.Windows.Forms.Button(); this.okButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // cancelButton // this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cancelButton.CausesValidation = false; this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(256, 424); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(72, 24); this.cancelButton.TabIndex = 18; this.cancelButton.Text = "Cancel"; // // okButton // this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.Location = new System.Drawing.Point(168, 424); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(72, 24); this.okButton.TabIndex = 17; this.okButton.Text = "OK"; this.okButton.Click += new System.EventHandler(this.okButton_Click); // // SettingsDialogBase // this.ClientSize = new System.Drawing.Size(336, 458); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.HelpButton = true; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "SettingsDialogBase"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Settings"; this.Closed += new System.EventHandler(this.SettingsDialogBase_Closed); this.ResumeLayout(false); } #endregion #region Properties public SettingsPageCollection SettingsPages { get { return pageList; } } #endregion #region Public Methods public void ApplySettings() { foreach( SettingsPage page in pageList ) if ( page.SettingsLoaded ) page.ApplySettings(); } #endregion #region Event Handlers private void SettingsDialogBase_Closed(object sender, System.EventArgs e) { if (this.reloadProjectOnClose) Services.TestLoader.ReloadTest(); } private void okButton_Click(object sender, System.EventArgs e) { if ( Services.TestLoader.IsTestLoaded && this.HasChangesRequiringReload ) { DialogResult answer = MessageDisplay.Ask( "Some changes will only take effect when you reload the test project. Do you want to reload now?"); if ( answer == DialogResult.Yes ) this.reloadProjectOnClose = true; } ApplySettings(); DialogResult = DialogResult.OK; Close(); } #endregion #region Helper Methods private bool HasChangesRequiringReload { get { foreach( SettingsPage page in pageList ) if ( page.SettingsLoaded && page.HasChangesRequiringReload ) return true; return false; } } #endregion #region Nested SettingsPageCollection Class public class SettingsPageCollection : CollectionBase { public void Add( SettingsPage page ) { this.InnerList.Add( page ); } public void AddRange( params SettingsPage[] pages ) { this.InnerList.AddRange( pages ); } public SettingsPage this[int index] { get { return (SettingsPage)InnerList[index]; } } public SettingsPage this[string key] { get { foreach( SettingsPage page in InnerList ) if ( page.Key == key ) return page; return null; } } } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextDisplayContent.cs0000664000175000017500000000722011702534234023723 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using System.Text; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { public class TextDisplayContent { private char[] content = new char[] { '0', '0', '0', '0', '0' }; public TextDisplayContent() { } public bool Out { get { return content[0] == '1'; } set { content[0] = value ? '1' : '0'; } } public bool Error { get { return content[1] == '1'; } set { content[1] = value ? '1' : '0'; } } public bool Trace { get { return content[2] == '1'; } set { content[2] = value ? '1' : '0'; } } public LoggingThreshold LogLevel { get { return (LoggingThreshold)(content[3] - '0'); } set { content[3] = (char)((int)value + '0'); } } public TestLabelLevel Labels { get { return (TestLabelLevel)(content[4] - '0'); } set { content[4] = (char)((int)value + '0'); } } public static TextDisplayContent FromSettings(string name) { TextDisplayContent content = new TextDisplayContent(); content.LoadSettings(name); return content; } public void LoadSettings(string name) { ISettings settings = Services.UserSettings; string prefix = "Gui.TextOutput." + name; string rep = settings.GetSetting(prefix + ".Content", "00000"); // Assume new format but if it isn't try the old one if (!LoadUsingNewFormat(rep)) LoadUsingOldFormat(rep); } private bool LoadUsingNewFormat(string rep) { if (rep.Length != 5) return false; foreach (char c in rep) if (!char.IsDigit(c)) return false; this.content = rep.ToCharArray(); return true; } private void LoadUsingOldFormat(string content) { ContentType contentType = (ContentType)System.Enum.Parse(typeof(ContentType), content, false); this.Out = (contentType & ContentType.Out) != 0; this.Error = (contentType & ContentType.Error) != 0; this.Trace = (contentType & ContentType.Trace) != 0; this.LogLevel = (contentType & ContentType.Log) != 0 ? LoggingThreshold.All : LoggingThreshold.Off; this.Labels = (contentType & ContentType.Labels) != 0 ? (contentType & ContentType.LabelOnlyOnOutput) != 0 ? TestLabelLevel.All : TestLabelLevel.On : TestLabelLevel.Off; } [Flags] private enum ContentType { Empty = 0, Out = 1, Error = 2, Trace = 4, Log = 8, Labels = 64, LabelOnlyOnOutput = 128 } public void SaveSettings(string name) { ISettings settings = Services.UserSettings; string prefix = "Gui.TextOutput." + name; settings.SaveSetting(prefix + ".Content", new string(content)); } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/AddConfigurationDialog.cs0000664000175000017500000001666611544330406024473 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { /// /// Displays a dialog for creation of a new configuration. /// The dialog collects and validates the name and the /// name of a configuration to be copied and then adds the /// new configuration to the project. /// /// A DialogResult of DialogResult.OK indicates that the /// configuration was added successfully. /// public class AddConfigurationDialog : NUnitFormBase { #region Instance variables private NUnitProject project; private string configurationName; private string copyConfigurationName; private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.TextBox configurationNameTextBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox configurationComboBox; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; #endregion #region Construction and Disposal public AddConfigurationDialog( NUnitProject project ) { InitializeComponent(); this.project = project; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.configurationNameTextBox = new System.Windows.Forms.TextBox(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.configurationComboBox = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // configurationNameTextBox // this.configurationNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configurationNameTextBox.Location = new System.Drawing.Point(16, 24); this.configurationNameTextBox.Name = "configurationNameTextBox"; this.configurationNameTextBox.Size = new System.Drawing.Size(254, 22); this.configurationNameTextBox.TabIndex = 0; this.configurationNameTextBox.Text = ""; // // okButton // this.okButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.okButton.Location = new System.Drawing.Point(50, 120); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(76, 23); this.okButton.TabIndex = 1; this.okButton.Text = "OK"; this.okButton.Click += new System.EventHandler(this.okButton_Click); // // cancelButton // this.cancelButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(155, 120); this.cancelButton.Name = "cancelButton"; this.cancelButton.TabIndex = 2; this.cancelButton.Text = "Cancel"; // // configurationComboBox // this.configurationComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configurationComboBox.ItemHeight = 16; this.configurationComboBox.Location = new System.Drawing.Point(16, 80); this.configurationComboBox.Name = "configurationComboBox"; this.configurationComboBox.Size = new System.Drawing.Size(256, 24); this.configurationComboBox.TabIndex = 3; // // label1 // this.label1.Location = new System.Drawing.Point(16, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(248, 16); this.label1.TabIndex = 4; this.label1.Text = "Configuration Name:"; // // label2 // this.label2.Location = new System.Drawing.Point(16, 63); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(240, 17); this.label2.TabIndex = 5; this.label2.Text = "Copy Settings From:"; // // AddConfigurationDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; this.ClientSize = new System.Drawing.Size(280, 149); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.configurationComboBox); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.Controls.Add(this.configurationNameTextBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "AddConfigurationDialog"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "New Configuration"; this.Load += new System.EventHandler(this.ConfigurationNameDialog_Load); this.ResumeLayout(false); } #endregion #region Properties public string ConfigurationName { get { return configurationName; } } public string CopyConfigurationName { get { return copyConfigurationName; } } #endregion #region Methods private void ConfigurationNameDialog_Load(object sender, System.EventArgs e) { configurationComboBox.Items.Add( "" ); configurationComboBox.SelectedIndex = 0; foreach( ProjectConfig config in project.Configs ) { int index = configurationComboBox.Items.Add( config.Name ); if ( config.Name == project.ActiveConfigName ) configurationComboBox.SelectedIndex = index; } } private void okButton_Click(object sender, System.EventArgs e) { configurationName = configurationNameTextBox.Text; if ( configurationName == string.Empty ) { MessageDisplay.Error("No configuration name provided"); return; } if ( project.Configs.Contains( configurationName ) ) { MessageDisplay.Error("A configuration with that name already exists"); return; } // ToDo: Move more of this to project ProjectConfig newConfig = new ProjectConfig( configurationName ); copyConfigurationName = null; if ( configurationComboBox.SelectedIndex > 0 ) { copyConfigurationName = (string)configurationComboBox.SelectedItem; ProjectConfig copyConfig = project.Configs[copyConfigurationName]; if ( copyConfig != null ) foreach( string assembly in copyConfig.Assemblies ) newConfig.Assemblies.Add( assembly ); } project.Configs.Add( newConfig ); DialogResult = DialogResult.OK; Close(); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TipWindow.resx0000664000175000017500000001444411504175260022424 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False (Default) False False 8, 8 TipWindow True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/GuiTestEventDispatcher.cs0000664000175000017500000000324211504175260024513 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Util; namespace NUnit.UiKit { [Serializable] public class TestEventInvocationException : Exception { public TestEventInvocationException( Exception inner ) : base( "Exception invoking TestEvent handler", inner ) { } } /// /// Summary description for GuiTestEventDispatcher. /// public class GuiTestEventDispatcher : TestEventDispatcher { protected override void Fire(TestEventHandler handler, TestEventArgs e) { if ( handler != null ) InvokeHandler( handler, e ); } private void InvokeHandler( MulticastDelegate handlerList, EventArgs e ) { object[] args = new object[] { this, e }; foreach( Delegate handler in handlerList.GetInvocationList() ) { object target = handler.Target; System.Windows.Forms.Control control = target as System.Windows.Forms.Control; try { if ( control != null && control.InvokeRequired ) control.Invoke( handler, args ); else handler.Method.Invoke( target, args ); } catch( Exception ex ) { // TODO: Stop rethrowing this since it goes back to the // Test domain which may not know how to handle it!!! Console.WriteLine( "Exception:" ); Console.WriteLine( ex ); //throw new TestEventInvocationException( ex ); //throw; } } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/LongRunningOperationDisplay.cs0000664000175000017500000000710111504175260025563 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace NUnit.UiKit { /// /// LongRunningOperationDisplay shows an overlay message block /// that describes the operation in progress. /// public class LongRunningOperationDisplay : System.Windows.Forms.Form { private System.Windows.Forms.Label operation; private Cursor ownerCursor; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public LongRunningOperationDisplay( Form owner, string text ) { // // Required for Windows Form Designer support // InitializeComponent(); // Save the arguments this.Owner = owner; this.operation.Text = text; // Save owner's current cursor and set it to the WaitCursor this.ownerCursor = owner.Cursor; owner.Cursor = Cursors.WaitCursor; // Force immediate display upon construction this.Show(); this.Invalidate(); this.Update(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } Owner.Cursor = this.ownerCursor; } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.operation = new System.Windows.Forms.Label(); this.SuspendLayout(); // // operation // this.operation.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.operation.Dock = System.Windows.Forms.DockStyle.Fill; this.operation.Font = new System.Drawing.Font(FontFamily.GenericSansSerif, 10.2F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.operation.Location = new System.Drawing.Point(0, 0); this.operation.Name = "operation"; this.operation.Size = new System.Drawing.Size(320, 40); this.operation.TabIndex = 0; this.operation.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // LongRunningOperationDisplay // this.BackColor = System.Drawing.Color.LightYellow; this.ClientSize = new System.Drawing.Size(320, 40); this.ControlBox = false; this.Controls.Add(this.operation); this.Cursor = System.Windows.Forms.Cursors.WaitCursor; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "LongRunningOperationDisplay"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.ResumeLayout(false); } #endregion protected override void OnLoad(EventArgs e) { base.OnLoad (e); // Set this again, see Mono Bug #82769 this.ClientSize = new System.Drawing.Size(320, 40); Point origin = this.Owner.Location; origin.Offset( (this.Owner.Size.Width - this.Size.Width) / 2, (this.Owner.Size.Height - this.Size.Height) / 2 ); this.Location = origin; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/SimpleSettingsDialog.resx0000664000175000017500000002304711504175260024571 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Family False Private Family False True Private 8, 8 True Private Private 8, 8 True False True Private False (Default) False False 8, 8 True 80 True SimpleSettingsDialog Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextDisplayWriter.cs0000664000175000017500000000344411504175260023571 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Text; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { /// /// Summary description for TextDisplayWriter. /// public class TextDisplayWriter : TextWriter, TestObserver { private TextDisplay textDisplay; public TextDisplayWriter( TextDisplay textDisplay ) { this.textDisplay = textDisplay; } public void Clear() { textDisplay.Clear(); } #region TextWriter Overrides /// /// Write a single char /// /// The char to write public override void Write(char c) { Write( c.ToString() ); } /// /// Write a string /// /// The string to write public override void Write(String s) { textDisplay.Write( s ); } /// /// Write a string followed by a newline. /// /// The string to write public override void WriteLine(string s) { Write( s + Environment.NewLine ); } /// /// The encoding in use for this TextWriter. /// public override Encoding Encoding { get { return Encoding.Default; } } #endregion #region TestObserver Members public void Subscribe(ITestEvents events) { events.TestOutput += new TestEventHandler(OnTestOutput); } #endregion private void OnTestOutput(object sender, TestEventArgs args) { } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ResultTabs.resx0000664000175000017500000002603711504175260022571 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True False True Private Private 8, 8 False True True Private Private 8, 8 False Private Private False True True Private Private 8, 8 Private Private False Private Private False False True True 80 (Default) False ResultTabs Private 8, 8 NUnit-2.6.0.12051/src/GuiComponents/UiKit/IMessageDisplay.cs0000664000175000017500000000215111544330406023136 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.UiKit { public interface IMessageDisplay { DialogResult Display(string message); DialogResult Display(string message, MessageBoxButtons buttons); DialogResult Error(string message); DialogResult Error(string message, MessageBoxButtons buttons); DialogResult Error(string message, Exception exception); DialogResult Error(string message, Exception exception, MessageBoxButtons buttons); DialogResult FatalError(string message, Exception exception); DialogResult Info(string message); DialogResult Info(string message, MessageBoxButtons buttons); DialogResult Ask(string message); DialogResult Ask(string message, MessageBoxButtons buttons); } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TreeBasedSettingsDialog.cs0000664000175000017500000001760511660212302024615 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { public class TreeBasedSettingsDialog : NUnit.UiKit.SettingsDialogBase { private System.Windows.Forms.TreeView treeView1; private System.Windows.Forms.Panel panel1; private System.ComponentModel.IContainer components = null; private System.Windows.Forms.ImageList imageList1; private System.Windows.Forms.GroupBox groupBox1; private SettingsPage current; public static void Display( Form owner, params SettingsPage[] pages ) { using( TreeBasedSettingsDialog dialog = new TreeBasedSettingsDialog() ) { owner.Site.Container.Add( dialog ); dialog.Font = owner.Font; dialog.SettingsPages.AddRange( pages ); dialog.ShowDialog(); } } public TreeBasedSettingsDialog() { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(TreeBasedSettingsDialog)); this.treeView1 = new System.Windows.Forms.TreeView(); this.imageList1 = new System.Windows.Forms.ImageList(this.components); this.panel1 = new System.Windows.Forms.Panel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.SuspendLayout(); // // cancelButton // this.cancelButton.Location = new System.Drawing.Point(592, 392); this.cancelButton.Name = "cancelButton"; // // okButton // this.okButton.Location = new System.Drawing.Point(504, 392); this.okButton.Name = "okButton"; // // treeView1 // this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.treeView1.HideSelection = false; this.treeView1.ImageList = this.imageList1; this.treeView1.Location = new System.Drawing.Point(16, 16); this.treeView1.Name = "treeView1"; this.treeView1.PathSeparator = "."; this.treeView1.Size = new System.Drawing.Size(176, 350); this.treeView1.TabIndex = 19; this.treeView1.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterExpand); this.treeView1.AfterCollapse += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCollapse); this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect); // // imageList1 // this.imageList1.ImageSize = new System.Drawing.Size(16, 16); this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); this.imageList1.TransparentColor = System.Drawing.Color.Transparent; // // panel1 // this.panel1.Location = new System.Drawing.Point(208, 16); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(456, 336); this.panel1.TabIndex = 20; // // groupBox1 // this.groupBox1.Location = new System.Drawing.Point(208, 360); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(456, 8); this.groupBox1.TabIndex = 21; this.groupBox1.TabStop = false; // // TreeBasedSettingsDialog // this.ClientSize = new System.Drawing.Size(682, 426); this.Controls.Add(this.groupBox1); this.Controls.Add(this.panel1); this.Controls.Add(this.treeView1); this.Name = "TreeBasedSettingsDialog"; this.Load += new System.EventHandler(this.TreeBasedSettingsDialog_Load); this.Controls.SetChildIndex(this.treeView1, 0); this.Controls.SetChildIndex(this.okButton, 0); this.Controls.SetChildIndex(this.cancelButton, 0); this.Controls.SetChildIndex(this.panel1, 0); this.Controls.SetChildIndex(this.groupBox1, 0); this.ResumeLayout(false); } #endregion private void TreeBasedSettingsDialog_Load(object sender, System.EventArgs e) { foreach( SettingsPage page in SettingsPages ) AddBranchToTree( treeView1.Nodes, page.Key ); if ( treeView1.VisibleCount >= treeView1.GetNodeCount( true ) ) treeView1.ExpandAll(); SelectInitialPage(); treeView1.Select(); } private void SelectInitialPage() { string initialPage = Services.UserSettings.GetSetting("Gui.Settings.InitialPage") as string; if (initialPage != null) SelectPage(initialPage); else if (treeView1.Nodes.Count > 0) SelectFirstPage(treeView1.Nodes); } private void SelectPage(string initialPage) { TreeNode node = FindNode(treeView1.Nodes, initialPage); if (node != null) treeView1.SelectedNode = node; else SelectFirstPage(treeView1.Nodes); } private TreeNode FindNode(TreeNodeCollection nodes, string key) { int dot = key.IndexOf('.'); string tail = null; if (dot >= 0) { tail = key.Substring(dot + 1); key = key.Substring(0, dot); } foreach (TreeNode node in nodes) if (node.Text == key) return tail == null ? node : FindNode(node.Nodes, tail); return null; } private void SelectFirstPage(TreeNodeCollection nodes) { if ( nodes[0].Nodes.Count == 0 ) treeView1.SelectedNode = nodes[0]; else { nodes[0].Expand(); SelectFirstPage(nodes[0].Nodes); } } private void AddBranchToTree( TreeNodeCollection nodes, string key ) { int dot = key.IndexOf( '.' ); if ( dot < 0 ) { nodes.Add( new TreeNode( key, 2, 2 ) ); return; } string name = key.Substring( 0, dot ); key = key.Substring(dot+1); TreeNode node = FindOrAddNode( nodes, name ); if ( key != null ) AddBranchToTree( node.Nodes, key ); } private TreeNode FindOrAddNode( TreeNodeCollection nodes, string name ) { foreach( TreeNode node in nodes ) if ( node.Text == name ) return node; TreeNode newNode = new TreeNode(name, 0, 0); nodes.Add( newNode ); return newNode; } private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) { string key = e.Node.FullPath; SettingsPage page = SettingsPages[key]; Services.UserSettings.SaveSetting("Gui.Settings.InitialPage", key); if ( page != null && page != current ) { panel1.Controls.Clear(); panel1.Controls.Add( page ); page.Dock = DockStyle.Fill; current = page; return; } } private void treeView1_AfterExpand(object sender, System.Windows.Forms.TreeViewEventArgs e) { e.Node.ImageIndex = e.Node.SelectedImageIndex = 1; } private void treeView1_AfterCollapse(object sender, System.Windows.Forms.TreeViewEventArgs e) { e.Node.ImageIndex = e.Node.SelectedImageIndex = 0; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/AssemblyInfo.cs0000664000175000017500000000072211504175260022511 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/GuiComponents/UiKit/VisualState.cs0000664000175000017500000001216011655437510022367 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections.Generic; using System.Windows.Forms; using System.Xml.Serialization; using NUnit.Core; using NUnit.Core.Filters; namespace NUnit.UiKit { /// /// The VisualState class holds the latest visual state for a project. /// [Serializable] public class VisualState { #region Fields [XmlAttribute] public bool ShowCheckBoxes; public string TopNode; public string SelectedNode; public string SelectedCategories; public bool ExcludeCategories; [XmlArrayItem("Node")] public List Nodes; #endregion #region Static Methods public static string GetVisualStateFileName( string testFileName ) { if ( testFileName == null ) return "VisualState.xml"; string baseName = testFileName; if ( baseName.EndsWith( ".nunit" ) ) baseName = baseName.Substring( 0, baseName.Length - 6 ); return baseName + ".VisualState.xml"; } public static VisualState LoadFrom( string fileName ) { using ( StreamReader reader = new StreamReader( fileName ) ) { return LoadFrom( reader ); } } public static VisualState LoadFrom( TextReader reader ) { XmlSerializer serializer = new XmlSerializer( typeof( VisualState) ); return (VisualState)serializer.Deserialize( reader ); } #endregion #region Constructors public VisualState() { } public VisualState( TestSuiteTreeView treeView ) { this.ShowCheckBoxes = treeView.CheckBoxes; this.TopNode = ((TestSuiteTreeNode)treeView.TopNode).Test.TestName.UniqueName; this.SelectedNode = ((TestSuiteTreeNode)treeView.SelectedNode).Test.TestName.UniqueName; this.Nodes = new List(); ProcessTreeNodes( (TestSuiteTreeNode)treeView.Nodes[0] ); if ( !treeView.CategoryFilter.IsEmpty ) { ITestFilter filter = treeView.CategoryFilter; if ( filter is NotFilter ) { filter = ((NotFilter)filter).BaseFilter; this.ExcludeCategories = true; } this.SelectedCategories = filter.ToString(); } } private void ProcessTreeNodes(TestSuiteTreeNode node) { if (IsInteresting(node)) this.Nodes.Add(new VisualTreeNode(node)); foreach (TestSuiteTreeNode childNode in node.Nodes) ProcessTreeNodes(childNode); } private bool IsInteresting(TestSuiteTreeNode node) { return node.IsExpanded || node.Checked; } #endregion #region Instance Methods public void Save( string fileName ) { using ( StreamWriter writer = new StreamWriter( fileName ) ) { Save( writer ); } } public void Save( TextWriter writer ) { XmlSerializer serializer = new XmlSerializer( GetType() ); serializer.Serialize( writer, this ); } public void Restore(TestSuiteTreeView treeView) { treeView.CheckBoxes = this.ShowCheckBoxes; foreach (VisualTreeNode visualNode in this.Nodes) { TestSuiteTreeNode treeNode = treeView[visualNode.UniqueName]; if (treeNode != null) { if (treeNode.IsExpanded != visualNode.Expanded) treeNode.Toggle(); treeNode.Checked = visualNode.Checked; } } if (this.SelectedNode != null) { TestSuiteTreeNode treeNode = treeView[this.SelectedNode]; if (treeNode != null) treeView.SelectedNode = treeNode; } if (this.TopNode != null) { TestSuiteTreeNode treeNode = treeView[this.TopNode]; if (treeNode != null) treeView.TopNode = treeNode; } if (this.SelectedCategories != null) { TestFilter filter = new CategoryFilter(this.SelectedCategories.Split(new char[] { ',' })); if (this.ExcludeCategories) filter = new NotFilter(filter); treeView.CategoryFilter = filter; } treeView.Select(); } #endregion } [Serializable] public class VisualTreeNode { [XmlAttribute] public string UniqueName; [XmlAttribute,System.ComponentModel.DefaultValue(false)] public bool Expanded; [XmlAttribute,System.ComponentModel.DefaultValue(false)] public bool Checked; [XmlArrayItem("Node")] public VisualTreeNode[] Nodes; public VisualTreeNode() { } public VisualTreeNode( TestSuiteTreeNode treeNode ) { this.UniqueName = treeNode.Test.TestName.UniqueName; this.Expanded = treeNode.IsExpanded; this.Checked = treeNode.Checked; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/StatusBar.cs0000664000175000017500000001615611504175260022036 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Drawing; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { public class StatusBar : System.Windows.Forms.StatusBar, TestObserver { private StatusBarPanel statusPanel = new StatusBarPanel(); private StatusBarPanel testCountPanel = new StatusBarPanel(); private StatusBarPanel testsRunPanel = new StatusBarPanel(); private StatusBarPanel errorsPanel = new StatusBarPanel(); private StatusBarPanel failuresPanel = new StatusBarPanel(); private StatusBarPanel timePanel = new StatusBarPanel(); private int testCount = 0; private int testsRun = 0; private int errors = 0; private int failures = 0; private double time = 0.0; private bool displayProgress = false; public bool DisplayTestProgress { get { return displayProgress; } set { displayProgress = value; } } public StatusBar() { Panels.Add( statusPanel ); Panels.Add( testCountPanel ); Panels.Add( testsRunPanel ); Panels.Add( errorsPanel ); Panels.Add( failuresPanel ); Panels.Add( timePanel ); statusPanel.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring; statusPanel.BorderStyle = StatusBarPanelBorderStyle.None; statusPanel.Text = "Status"; testCountPanel.AutoSize = StatusBarPanelAutoSize.Contents; testsRunPanel.AutoSize = StatusBarPanelAutoSize.Contents; errorsPanel.AutoSize = StatusBarPanelAutoSize.Contents; failuresPanel.AutoSize = StatusBarPanelAutoSize.Contents; timePanel.AutoSize = StatusBarPanelAutoSize.Contents; ShowPanels = true; InitPanels(); } // Kluge to keep VS from generating code that sets the Panels for // the statusbar. Really, our status bar should be a user control // to avoid this and shouldn't allow the panels to be set except // according to specific protocols. [System.ComponentModel.DesignerSerializationVisibility( System.ComponentModel.DesignerSerializationVisibility.Hidden )] public new System.Windows.Forms.StatusBar.StatusBarPanelCollection Panels { get { return base.Panels; } } public override string Text { get { return statusPanel.Text; } set { statusPanel.Text = value; } } public void Initialize( int testCount ) { Initialize( testCount, testCount > 0 ? "Ready" : "" ); } public void Initialize( int testCount, string text ) { this.statusPanel.Text = text; this.testCount = testCount; this.testsRun = 0; this.errors = 0; this.failures = 0; this.time = 0.0; InitPanels(); } private void InitPanels() { this.testCountPanel.MinWidth = 50; DisplayTestCount(); this.testsRunPanel.MinWidth = 50; this.testsRunPanel.Text = ""; this.errorsPanel.MinWidth = 50; this.errorsPanel.Text = ""; this.failuresPanel.MinWidth = 50; this.failuresPanel.Text = ""; this.timePanel.MinWidth = 50; this.timePanel.Text = ""; } private void DisplayTestCount() { testCountPanel.Text = "Test Cases : " + testCount.ToString(); } private void DisplayTestsRun() { testsRunPanel.Text = "Tests Run : " + testsRun.ToString(); } private void DisplayErrors() { errorsPanel.Text = "Errors : " + errors.ToString(); } private void DisplayFailures() { failuresPanel.Text = "Failures : " + failures.ToString(); } private void DisplayTime() { timePanel.Text = "Time : " + time.ToString(); } private void DisplayResult(TestResult result) { ResultSummarizer summarizer = new ResultSummarizer(result); //this.testCount = summarizer.ResultCount; this.testsRun = summarizer.TestsRun; this.errors = summarizer.Errors; this.failures = summarizer.Failures; this.time = summarizer.Time; DisplayTestCount(); DisplayTestsRun(); DisplayErrors(); DisplayFailures(); DisplayTime(); } public void OnTestLoaded( object sender, TestEventArgs e ) { Initialize( e.TestCount ); } public void OnTestReloaded( object sender, TestEventArgs e ) { Initialize( e.TestCount, "Reloaded" ); } public void OnTestUnloaded( object sender, TestEventArgs e ) { Initialize( 0, "Unloaded" ); } private void OnRunStarting( object sender, TestEventArgs e ) { Initialize( e.TestCount, "Running :" + e.Name ); DisplayTestCount(); DisplayTestsRun(); DisplayErrors(); DisplayFailures(); DisplayTime(); } private void OnRunFinished(object sender, TestEventArgs e ) { if ( e.Exception != null ) statusPanel.Text = "Failed"; else { statusPanel.Text = "Completed"; DisplayResult( e.Result ); } } public void OnTestStarting( object sender, TestEventArgs e ) { string fullText = "Running : " + e.TestName.FullName; string shortText = "Running : " + e.TestName.Name; Graphics g = Graphics.FromHwnd( Handle ); SizeF sizeNeeded = g.MeasureString( fullText, Font ); if ( statusPanel.Width >= (int)sizeNeeded.Width ) { statusPanel.Text = fullText; statusPanel.ToolTipText = ""; } else { sizeNeeded = g.MeasureString( shortText, Font ); statusPanel.Text = statusPanel.Width >= (int)sizeNeeded.Width ? shortText : e.TestName.Name; statusPanel.ToolTipText = e.TestName.FullName; } } private void OnTestFinished( object sender, TestEventArgs e ) { if ( DisplayTestProgress && e.Result.Executed ) { ++testsRun; DisplayTestsRun(); switch ( e.Result.ResultState ) { case ResultState.Error: case ResultState.Cancelled: ++errors; DisplayErrors(); break; case ResultState.Failure: ++failures; DisplayFailures(); break; } } } // protected override void OnFontChanged(EventArgs e) // { // base.OnFontChanged(e); // // this.Height = (int)(this.Font.Height * 1.6); // } #region TestObserver Members public void Subscribe(ITestEvents events) { events.TestLoaded += new TestEventHandler( OnTestLoaded ); events.TestReloaded += new TestEventHandler( OnTestReloaded ); events.TestUnloaded += new TestEventHandler( OnTestUnloaded ); events.TestStarting += new TestEventHandler( OnTestStarting ); events.TestFinished += new TestEventHandler( OnTestFinished ); events.RunStarting += new TestEventHandler( OnRunStarting ); events.RunFinished += new TestEventHandler( OnRunFinished ); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextDisplayTabSettings.cs0000664000175000017500000001004711701402420024527 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Util; namespace NUnit.UiKit { public class TextDisplayTabSettings { private TabInfoCollection tabInfo; private NUnit.Util.ISettings settings; public static readonly string Prefix = "Gui.TextOutput."; public void LoadSettings() { LoadSettings( NUnit.Util.Services.UserSettings ); } public void LoadSettings(NUnit.Util.ISettings settings) { this.settings = settings; TabInfoCollection info = new TabInfoCollection(); string tabList = (string)settings.GetSetting( Prefix + "TabList" ); if ( tabList != null ) { string[] tabNames = tabList.Split( new char[] { ',' } ); foreach( string name in tabNames ) { string prefix = Prefix + name; string text = (string)settings.GetSetting(prefix + ".Title"); if ( text == null ) break; TabInfo tab = new TabInfo( name, text ); tab.Content = TextDisplayContent.FromSettings(name); tab.Enabled = settings.GetSetting( prefix + ".Enabled", true ); info.Add( tab ); } } if ( info.Count > 0 ) tabInfo = info; else LoadDefaults(); } public void LoadDefaults() { tabInfo = new TabInfoCollection(); TabInfo tab = tabInfo.AddNewTab("Text Output"); tab.Content = new TextDisplayContent(); tab.Content.Out = true; tab.Content.Error = true; tab.Content.Labels = TestLabelLevel.On; tab.Enabled = true; } public void ApplySettings() { System.Text.StringBuilder tabNames = new System.Text.StringBuilder(); foreach( TabInfo tab in tabInfo ) { if ( tabNames.Length > 0 ) tabNames.Append(","); tabNames.Append( tab.Name ); string prefix = Prefix + tab.Name; settings.SaveSetting( prefix + ".Title", tab.Title ); settings.SaveSetting( prefix + ".Enabled", tab.Enabled ); tab.Content.SaveSettings(tab.Name); } string oldNames = settings.GetSetting( Prefix + "TabList", string.Empty ); settings.SaveSetting( Prefix + "TabList", tabNames.ToString() ); if (oldNames != string.Empty ) { string[] oldTabs = oldNames.Split( new char[] { ',' } ); foreach( string tabName in oldTabs ) if ( tabInfo[tabName] == null ) settings.RemoveGroup( Prefix + tabName ); } } public TabInfoCollection Tabs { get { return tabInfo; } } #region Nested TabInfo Class public class TabInfo { public TabInfo( string name, string title ) { this.Name = name; this.Title = title; this.Enabled = true; this.Content = new TextDisplayContent(); } public string Name { get; set; } public string Title { get; set; } public TextDisplayContent Content { get; set; } public bool Enabled { get; set; } } #endregion #region Nested TabInfoCollectionClass public class TabInfoCollection : System.Collections.Generic.List { public TabInfo AddNewTab( string title ) { TabInfo tabInfo = new TabInfo( GetNextName(), title ); this.Add(tabInfo); return tabInfo; } private string GetNextName() { for( int i = 0;;i++ ) { string name = string.Format( "Tab{0}", i ); if ( this[name] == null ) return name; } } public TabInfo this[string name] { get { foreach ( TabInfo info in this ) if ( info.Name == name ) return info; return null; } } public bool Contains( string name ) { return this[name] != null; } } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/SettingsPage.cs0000664000175000017500000000601111544330406022507 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { /// /// NUnitSettingsPage is the base class for all pages used /// in a tabbed or tree-structured SettingsDialog. /// public class SettingsPage : System.Windows.Forms.UserControl { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Settings are available to derived classes /// protected ISettings settings; private string key; private string title; private MessageDisplay messageDisplay; // Constructor used by the Windows.Forms Designer public SettingsPage() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } // Constructor we use in creating page for a Tabbed // or TreeBased dialog. public SettingsPage( string key) : this() { this.key = key; this.title = key; int dot = key.LastIndexOf( '.' ); if ( dot >= 0 ) title = key.Substring(dot+1); this.messageDisplay = new MessageDisplay("NUnit Settings"); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Properties public string Key { get { return key; } } public string Title { get { return title; } } public bool SettingsLoaded { get { return settings != null; } } public virtual bool HasChangesRequiringReload { get { return false; } } public IMessageDisplay MessageDisplay { get { return messageDisplay; } } #endregion #region Public Methods public virtual void LoadSettings() { } public virtual void ApplySettings() { } #endregion #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { // // SettingsPage // this.Name = "SettingsPage"; this.Size = new System.Drawing.Size(456, 336); } #endregion protected override void OnLoad(EventArgs e) { base.OnLoad (e); if ( !DesignMode ) { this.settings = Services.UserSettings; this.LoadSettings(); } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/MessageDisplay.cs0000664000175000017500000000742211717420154023035 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.Windows.Forms; namespace NUnit.UiKit { /// /// Summary description for MessageDisplay. /// public class MessageDisplay : IMessageDisplay { private static readonly string DEFAULT_CAPTION = "NUnit"; private readonly string caption; public MessageDisplay() : this(DEFAULT_CAPTION) { } public MessageDisplay(string caption) { this.caption = caption; } #region Public Methods #region Display public DialogResult Display(string message) { return Display(message, MessageBoxButtons.OK); } public DialogResult Display(string message, MessageBoxButtons buttons) { return MessageBox.Show(message, caption, buttons, MessageBoxIcon.None); } #endregion #region Error public DialogResult Error( string message ) { return Error(message, MessageBoxButtons.OK); } public DialogResult Error(string message, MessageBoxButtons buttons) { return MessageBox.Show(message, caption, buttons, MessageBoxIcon.Stop); } public DialogResult Error(string message, Exception exception) { return Error(message, exception, MessageBoxButtons.OK); } public DialogResult Error(string message, Exception exception, MessageBoxButtons buttons) { return Error( BuildMessage(message, exception, false), buttons); } public DialogResult FatalError(string message, Exception exception) { return Error( BuildMessage(message, exception, true), MessageBoxButtons.OK); } #endregion #region Info public DialogResult Info(string message) { return Info(message, MessageBoxButtons.OK); } public DialogResult Info(string message, MessageBoxButtons buttons) { return MessageBox.Show(message, caption, buttons, MessageBoxIcon.Information); } #endregion #region Ask public DialogResult Ask(string message) { return Ask(message, MessageBoxButtons.YesNo); } public DialogResult Ask(string message, MessageBoxButtons buttons) { return MessageBox.Show(message, caption, buttons, MessageBoxIcon.Question); } #endregion #endregion #region Helper Methods private static string BuildMessage(Exception exception) { Exception ex = exception; StringBuilder sb = new StringBuilder(); sb.AppendFormat("{0} : {1}", ex.GetType().ToString(), ex.Message); while (ex.InnerException != null) { ex = ex.InnerException; sb.AppendFormat("\r----> {0} : {1}", ex.GetType().ToString(), ex.Message); } return sb.ToString(); } private static string BuildMessage(string message, Exception exception, bool isFatal) { string msg = message + Environment.NewLine + Environment.NewLine + BuildMessage(exception); return isFatal ? msg : msg + Environment.NewLine + Environment.NewLine + "For further information, use the Exception Details menu item."; } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/SettingsPage.resx0000664000175000017500000001444711504175260023100 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False False True True 80 (Default) False Private SettingsPage 8, 8 NUnit-2.6.0.12051/src/GuiComponents/UiKit/nunit.uikit.build0000664000175000017500000001217311703367456023107 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestSuiteTreeNode.cs0000664000175000017500000001754611715541224023512 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.UiKit { using System; using System.Windows.Forms; using System.Drawing; using NUnit.Core; using NUnit.Util; /// /// Type safe TreeNode for use in the TestSuiteTreeView. /// NOTE: Hides some methods and properties of base class. /// public class TestSuiteTreeNode : TreeNode { #region Instance variables and constant definitions /// /// The testcase or testsuite represented by this node /// private ITest test; /// /// The result from the last run of the test /// private TestResult result; /// /// Private field used for inclusion by category /// private bool included = true; private bool showFailedAssumptions = false; /// /// Image indices for various test states - the values /// must match the indices of the image list used /// public static readonly int InitIndex = 0; public static readonly int SkippedIndex = 0; public static readonly int FailureIndex = 1; public static readonly int SuccessIndex = 2; public static readonly int IgnoredIndex = 3; public static readonly int InconclusiveIndex = 4; #endregion #region Constructors /// /// Construct a TestNode given a test /// public TestSuiteTreeNode( TestInfo test ) : base(test.TestName.Name) { this.test = test; UpdateImageIndex(); } /// /// Construct a TestNode given a TestResult /// public TestSuiteTreeNode( TestResult result ) : base( result.Test.TestName.Name ) { this.test = result.Test; this.result = result; UpdateImageIndex(); } #endregion #region Properties /// /// Test represented by this node /// public ITest Test { get { return this.test; } set { this.test = value; } } /// /// Test result for this node /// public TestResult Result { get { return this.result; } set { this.result = value; UpdateImageIndex(); } } /// /// Return true if the node has a result, otherwise false. /// public bool HasResult { get { return this.result != null; } } public string TestType { get { return test.TestType; } } public string StatusText { get { if ( result == null ) return test.RunState.ToString(); return result.ResultState.ToString(); } } public bool Included { get { return included; } set { included = value; this.ForeColor = included ? SystemColors.WindowText : Color.LightBlue; } } public bool ShowFailedAssumptions { get { return showFailedAssumptions; } set { if (value != showFailedAssumptions) { showFailedAssumptions = value; if (HasInconclusiveResults) RepopulateTheoryNode(); } } } public bool HasInconclusiveResults { get { bool hasInconclusiveResults = false; if (Result != null) { foreach (TestResult result in Result.Results) { hasInconclusiveResults |= result.ResultState == ResultState.Inconclusive; if (hasInconclusiveResults) break; } } return hasInconclusiveResults; } } #endregion #region Methods /// /// UPdate the image index based on the result field /// public void UpdateImageIndex() { ImageIndex = SelectedImageIndex = CalcImageIndex(); } /// /// Clear the result of this node and all its children /// public void ClearResults() { this.result = null; ImageIndex = SelectedImageIndex = CalcImageIndex(); foreach(TestSuiteTreeNode node in Nodes) node.ClearResults(); } /// /// Gets the Theory node associated with the current /// node. If the current node is a Theory, then the /// current node is returned. Otherwise, if the current /// node is a test case under a theory node, then that /// node is returned. Otherwise, null is returned. /// /// public TestSuiteTreeNode GetTheoryNode() { if (this.Test.TestType == "Theory") return this; TestSuiteTreeNode parent = this.Parent as TestSuiteTreeNode; if (parent != null && parent.Test.TestType == "Theory") return parent; return null; } /// /// Regenerate the test cases under a theory, respecting /// the current setting for ShowFailedAssumptions /// public void RepopulateTheoryNode() { // Ignore if it's not a theory or if it has not been run yet if (this.Test.TestType == "Theory" && this.HasResult) { Nodes.Clear(); foreach (TestResult result in Result.Results) if (showFailedAssumptions || result.ResultState != ResultState.Inconclusive) Nodes.Add(new TestSuiteTreeNode(result)); } } /// /// Calculate the image index based on the node contents /// /// Image index for this node private int CalcImageIndex() { if (this.result == null) { switch (this.test.RunState) { case RunState.Ignored: return IgnoredIndex; case RunState.NotRunnable: return FailureIndex; default: return InitIndex; } } else { switch (this.result.ResultState) { case ResultState.Inconclusive: return InconclusiveIndex; case ResultState.Skipped: return SkippedIndex; case ResultState.NotRunnable: case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: return FailureIndex; case ResultState.Ignored: return IgnoredIndex; case ResultState.Success: foreach (TestSuiteTreeNode node in this.Nodes) if (node.ImageIndex == IgnoredIndex) return IgnoredIndex; return SuccessIndex; default: return InitIndex; } } } internal void Accept(TestSuiteTreeNodeVisitor visitor) { visitor.Visit(this); foreach (TestSuiteTreeNode node in this.Nodes) { node.Accept(visitor); } } #endregion } public abstract class TestSuiteTreeNodeVisitor { public abstract void Visit(TestSuiteTreeNode node); } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ExpandingTextBox.cs0000664000175000017500000002055111504175260023353 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace CP.Windows.Forms { /// /// A special type of textbox which can display a tooltip-like /// window to show the full extent of any text which doesn't /// fit. The window may be placed directly over the label /// or immediately beneath it and will expand to fit in /// a horizontal, vertical or both directions as needed. /// /// TODO: This control is virtually identical to ExpandingLabel. /// We need to have an extension provider that works like a /// ToolTip in order to eliminate the duplication. /// public class ExpandingTextBox : System.Windows.Forms.TextBox { #region Instance Variables /// /// Our window for displaying expanded text /// private TipWindow tipWindow; /// /// Direction of expansion /// private TipWindow.ExpansionStyle expansion = TipWindow.ExpansionStyle.Horizontal; /// /// Time in milliseconds that the mouse must /// be stationary over an item before the /// tip window will display. /// private int mouseHoverDelay = 300; /// /// True if tipWindow may overlay the label /// private bool overlay = true; /// /// Time in milliseconds that the tip window /// will remain displayed. /// private int autoCloseDelay = 0; /// /// Time in milliseconds that the window stays /// open after the mouse leaves the control. /// private int mouseLeaveDelay = 300; /// /// If true, a context menu with Copy is displayed which /// allows copying contents to the clipboard. /// private bool copySupported = false; /// /// Timer used to control display behavior on hover. /// private System.Windows.Forms.Timer hoverTimer; /// /// True if control should expand automatically on hover. /// private bool autoExpand = true; #endregion #region Properties [Browsable( false )] public bool Expanded { get { return tipWindow != null && tipWindow.Visible; } } [Category ( "Behavior" ), DefaultValue( TipWindow.ExpansionStyle.Horizontal )] public TipWindow.ExpansionStyle Expansion { get { return expansion; } set { expansion = value; } } [Category ( "Behavior" ), DefaultValue( true )] public bool AutoExpand { get { return autoExpand; } set { autoExpand = value; } } [Category( "Behavior" ), DefaultValue( true )] [Description("Indicates whether the tip window should overlay the label")] public bool Overlay { get { return overlay; } set { overlay = value; } } /// /// Time in milliseconds that the mouse must /// be stationary over an item before the /// tip window will display. /// [Category( "Behavior" ), DefaultValue( 300 )] [Description("Time in milliseconds that mouse must be stationary over an item before the tip is displayed.")] public int MouseHoverDelay { get { return mouseHoverDelay; } set { mouseHoverDelay = value; } } /// /// Time in milliseconds that the tip window /// will remain displayed. /// [Category( "Behavior" ), DefaultValue( 0 )] [Description("Time in milliseconds that the tip is displayed. Zero indicates no automatic timeout.")] public int AutoCloseDelay { get { return autoCloseDelay; } set { autoCloseDelay = value; } } /// /// Time in milliseconds that the window stays /// open after the mouse leaves the control. /// Reentering the control resets this. /// [Category( "Behavior" ), DefaultValue( 300 )] [Description("Time in milliseconds that the tip is displayed after the mouse levaes the control")] public int MouseLeaveDelay { get { return mouseLeaveDelay; } set { mouseLeaveDelay = value; } } [Category( "Behavior"), DefaultValue( false )] [Description("If true, displays a context menu with Copy")] public bool CopySupported { get { return copySupported; } set { copySupported = value; if ( copySupported ) base.ContextMenu = null; } } /// /// Override Text property to set up copy menu if /// the value is non-empty. /// public override string Text { get { return base.Text; } set { base.Text = value; if ( copySupported ) { if ( value == null || value == string.Empty ) { if ( this.ContextMenu != null ) { this.ContextMenu.Dispose(); this.ContextMenu = null; } } else { this.ContextMenu = new System.Windows.Forms.ContextMenu(); MenuItem copyMenuItem = new MenuItem( "Copy", new EventHandler( CopyToClipboard ) ); this.ContextMenu.MenuItems.Add( copyMenuItem ); } } } } #endregion #region Public Methods public void Expand() { if ( !Expanded ) { tipWindow = new TipWindow( this ); tipWindow.Closed += new EventHandler( tipWindow_Closed ); tipWindow.Expansion = this.Expansion; tipWindow.Overlay = this.Overlay; tipWindow.AutoCloseDelay = this.AutoCloseDelay; tipWindow.MouseLeaveDelay = this.MouseLeaveDelay; tipWindow.WantClicks = this.CopySupported; tipWindow.Show(); } } public void Unexpand() { if ( Expanded ) { tipWindow.Close(); } } #endregion #region Event Handlers private void tipWindow_Closed( object sender, EventArgs e ) { tipWindow = null; ClearTimer(); } protected override void OnMouseLeave(EventArgs e) { ClearTimer(); } private void OnMouseHover( object sender, System.EventArgs e ) { if ( autoExpand ) { Graphics g = Graphics.FromHwnd( Handle ); SizeF sizeNeeded = g.MeasureString( Text, Font ); bool expansionNeeded = Width < (int)sizeNeeded.Width || Height < (int)sizeNeeded.Height; if ( expansionNeeded ) Expand(); } } protected override void OnMouseMove(MouseEventArgs e) { ClearTimer(); int textExtent = this.Lines.Length * this.FontHeight; if ( e.Y <= textExtent ) { hoverTimer = new System.Windows.Forms.Timer(); hoverTimer.Interval = mouseHoverDelay; hoverTimer.Tick += new EventHandler( OnMouseHover ); hoverTimer.Start(); } base.OnMouseMove (e); } private void ClearTimer() { if ( hoverTimer != null ) { hoverTimer.Stop(); hoverTimer.Dispose(); } } /// /// Copy contents to clipboard /// private void CopyToClipboard( object sender, EventArgs e ) { Clipboard.SetDataObject( this.Text ); } #endregion } // public class HoverDetector // { // private Control control; // // private Timer hoverTimer; // // private int hoverDelay; // // public int HoverDelay // { // get { return hoverDelay; } // set { hoverDelay = value; } // } // // public event System.EventHandler Hover; // // public HoverDetector( Control control ) // { // this.control = control; // // control.MouseLeave += new EventHandler( OnMouseLeave ); // control.MouseMove += new MouseEventHandler( OnMouseMove ); // } // // private void OnMouseLeave( object sender, System.EventArgs e ) // { // ClearTimer(); // } // // private void OnMouseMove( object sender, MouseEventArgs e ) // { // ClearTimer(); // // hoverTimer = new System.Windows.Forms.Timer(); // hoverTimer.Interval = hoverDelay; // hoverTimer.Tick += new EventHandler( OnMouseHover ); // hoverTimer.Start(); // } // // private void OnMouseHover( object sender, System.EventArgs e ) // { // if ( Hover != null ) // Hover( this, e ); // } // // private void ClearTimer() // { // if ( hoverTimer != null ) // { // hoverTimer.Stop(); // hoverTimer.Dispose(); // } // } // } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextBoxDisplay.cs0000664000175000017500000001434511703030046023040 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using NUnit.Core; using NUnit.Util; using System.Diagnostics; namespace NUnit.UiKit { /// /// TextBoxDisplay is an adapter that allows accessing a /// System.Windows.Forms.TextBox using the TextDisplay interface. /// public class TextBoxDisplay : System.Windows.Forms.RichTextBox, TextDisplay, TestObserver { private MenuItem copyMenuItem; private MenuItem selectAllMenuItem; private MenuItem wordWrapMenuItem; private MenuItem fontMenuItem; private MenuItem increaseFontMenuItem; private MenuItem decreaseFontMenuItem; private MenuItem restoreFontMenuItem; private TextDisplayContent content; public TextBoxDisplay() { this.Multiline = true; this.ReadOnly = true; this.WordWrap = false; this.ContextMenu = new ContextMenu(); this.copyMenuItem = new MenuItem( "&Copy", new EventHandler( copyMenuItem_Click ) ); this.selectAllMenuItem = new MenuItem( "Select &All", new EventHandler( selectAllMenuItem_Click ) ); this.wordWrapMenuItem = new MenuItem( "&Word Wrap", new EventHandler( wordWrapMenuItem_Click ) ); this.fontMenuItem = new MenuItem( "Font" ); this.increaseFontMenuItem = new MenuItem( "Increase", new EventHandler( increaseFontMenuItem_Click ) ); this.decreaseFontMenuItem = new MenuItem( "Decrease", new EventHandler( decreaseFontMenuItem_Click ) ); this.restoreFontMenuItem = new MenuItem( "Restore", new EventHandler( restoreFontMenuItem_Click ) ); this.fontMenuItem.MenuItems.AddRange( new MenuItem[] { increaseFontMenuItem, decreaseFontMenuItem, new MenuItem("-"), restoreFontMenuItem } ); this.ContextMenu.MenuItems.AddRange( new MenuItem[] { copyMenuItem, selectAllMenuItem, wordWrapMenuItem, fontMenuItem } ); this.ContextMenu.Popup += new EventHandler(ContextMenu_Popup); } private void copyMenuItem_Click(object sender, EventArgs e) { this.Copy(); } private void selectAllMenuItem_Click(object sender, EventArgs e) { this.SelectAll(); } private void wordWrapMenuItem_Click(object sender, EventArgs e) { this.WordWrap = this.wordWrapMenuItem.Checked = !this.wordWrapMenuItem.Checked; } private void increaseFontMenuItem_Click(object sender, EventArgs e) { applyFont( new Font( this.Font.FontFamily, this.Font.SizeInPoints * 1.2f, this.Font.Style ) ); } private void decreaseFontMenuItem_Click(object sender, EventArgs e) { applyFont( new Font( this.Font.FontFamily, this.Font.SizeInPoints / 1.2f, this.Font.Style ) ); } private void restoreFontMenuItem_Click(object sender, EventArgs e) { applyFont( new Font( FontFamily.GenericMonospace, 8.0f ) ); } private void applyFont( Font font ) { this.Font = font; TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); Services.UserSettings.SaveSetting( "Gui.FixedFont", converter.ConvertToString( null, System.Globalization.CultureInfo.InvariantCulture, font ) ); } private void ContextMenu_Popup(object sender, EventArgs e) { this.copyMenuItem.Enabled = this.SelectedText != ""; this.selectAllMenuItem.Enabled = this.TextLength > 0; } private string pendingTestCaseLabel = null; private void OnTestOutput( object sender, TestEventArgs e ) { if ( ShouldInclude(e.TestOutput.Type) ) { if ( pendingTestCaseLabel != null ) { WriteLine( pendingTestCaseLabel ); pendingTestCaseLabel = null; } Write( e.TestOutput.Text ); } } // TODO: We determine whether to include output // based solely on the output type. This works // well for everything but logging. Because we // are unable - at this stage of processing - // to determine the logging level of the output // all tabs displaying log output will show // output at the most verbose level specified // on any of the tabs. Since it's not likely // that anyone will display logging on multiple // tabs, this is not seen as a serious issue. // It may be resolved in a future release by // limiting the options available when specifying // the content of the output displayed. private bool ShouldInclude(TestOutputType type) { switch (type) { default: case TestOutputType.Out: return content.Out; case TestOutputType.Error: return content.Error; case TestOutputType.Log: return true;// content.LogLevel != LoggingThreshold.Off; case TestOutputType.Trace: return content.Trace; } } private void OnTestStarting(object sender, TestEventArgs args) { if (this.content.Labels != TestLabelLevel.Off) { string label = string.Format( "***** {0}", args.TestName.FullName ); if (this.content.Labels == TestLabelLevel.On) this.pendingTestCaseLabel = label; else WriteLine(label); } } protected override void OnFontChanged(EventArgs e) { // Do nothing - this control uses it's own font } #region TextDisplay Members public TextDisplayContent Content { get { return content; } set { content = value; } } public void Write( string text ) { this.AppendText( text ); } public void Write( NUnit.Core.TestOutput output ) { Write( output.Text ); } public void WriteLine( string text ) { Write( text + Environment.NewLine ); } public string GetText() { return this.Text; } #endregion #region TestObserver Members public void Subscribe(ITestEvents events) { events.TestOutput += new TestEventHandler(OnTestOutput); events.TestStarting += new TestEventHandler(OnTestStarting); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ErrorDisplay.cs0000664000175000017500000004221511703146036022540 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NUnit.Util; using NUnit.Core; using CP.Windows.Forms; namespace NUnit.UiKit { /// /// Summary description for ErrorDisplay. /// public class ErrorDisplay : System.Windows.Forms.UserControl, TestObserver { static readonly Font DefaultFixedFont = new Font(FontFamily.GenericMonospace, 8.0F); private ISettings settings = null; int hoverIndex = -1; private System.Windows.Forms.Timer hoverTimer; TipWindow tipWindow; private bool wordWrap = false; private System.Windows.Forms.ListBox detailList; public UiException.Controls.StackTraceDisplay stackTraceDisplay; public UiException.Controls.ErrorBrowser errorBrowser; private UiException.Controls.SourceCodeDisplay sourceCode; public System.Windows.Forms.Splitter tabSplitter; private System.Windows.Forms.ContextMenu detailListContextMenu; private System.Windows.Forms.MenuItem copyDetailMenuItem; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public ErrorDisplay() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Properties private bool WordWrap { get { return wordWrap; } set { if ( value != this.wordWrap ) { this.wordWrap = value; RefillDetailList(); } } } #endregion #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.detailList = new System.Windows.Forms.ListBox(); this.tabSplitter = new System.Windows.Forms.Splitter(); this.errorBrowser = new NUnit.UiException.Controls.ErrorBrowser(); this.sourceCode = new UiException.Controls.SourceCodeDisplay(); this.stackTraceDisplay = new UiException.Controls.StackTraceDisplay(); this.detailListContextMenu = new System.Windows.Forms.ContextMenu(); this.copyDetailMenuItem = new System.Windows.Forms.MenuItem(); this.SuspendLayout(); // // detailList // this.detailList.Dock = System.Windows.Forms.DockStyle.Top; this.detailList.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; this.detailList.Font = DefaultFixedFont; this.detailList.HorizontalExtent = 2000; this.detailList.HorizontalScrollbar = true; this.detailList.ItemHeight = 16; this.detailList.Location = new System.Drawing.Point(0, 0); this.detailList.Name = "detailList"; this.detailList.ScrollAlwaysVisible = true; this.detailList.Size = new System.Drawing.Size(496, 128); this.detailList.TabIndex = 1; this.detailList.Resize += new System.EventHandler(this.detailList_Resize); this.detailList.MouseHover += new System.EventHandler(this.OnMouseHover); this.detailList.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.detailList_MeasureItem); this.detailList.MouseMove += new System.Windows.Forms.MouseEventHandler(this.detailList_MouseMove); this.detailList.MouseLeave += new System.EventHandler(this.detailList_MouseLeave); this.detailList.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.detailList_DrawItem); this.detailList.SelectedIndexChanged += new System.EventHandler(this.detailList_SelectedIndexChanged); // // tabSplitter // this.tabSplitter.Dock = System.Windows.Forms.DockStyle.Top; this.tabSplitter.Location = new System.Drawing.Point(0, 128); this.tabSplitter.MinSize = 100; this.tabSplitter.Name = "tabSplitter"; this.tabSplitter.Size = new System.Drawing.Size(496, 9); this.tabSplitter.TabIndex = 3; this.tabSplitter.TabStop = false; this.tabSplitter.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.tabSplitter_SplitterMoved); // // errorBrowser // this.errorBrowser.Dock = System.Windows.Forms.DockStyle.Fill; this.errorBrowser.Location = new System.Drawing.Point(0, 137); this.errorBrowser.Name = "errorBrowser"; this.errorBrowser.Size = new System.Drawing.Size(496, 151); this.errorBrowser.StackTraceSource = null; this.errorBrowser.TabIndex = 4; // // configure and register SourceCodeDisplay // this.sourceCode.AutoSelectFirstItem = true; this.sourceCode.ListOrderPolicy = UiException.Controls.ErrorListOrderPolicy.ReverseOrder; this.sourceCode.SplitOrientation = Orientation.Vertical; this.sourceCode.SplitterDistance = 0.3f; this.stackTraceDisplay.Font = DefaultFixedFont; this.errorBrowser.RegisterDisplay(sourceCode); this.errorBrowser.RegisterDisplay(stackTraceDisplay); // // detailListContextMenu // this.detailListContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.copyDetailMenuItem}); // // copyDetailMenuItem // this.copyDetailMenuItem.Index = 0; this.copyDetailMenuItem.Text = "Copy"; this.copyDetailMenuItem.Click += new System.EventHandler(this.copyDetailMenuItem_Click); // // ErrorDisplay // this.Controls.Add(this.errorBrowser); this.Controls.Add(this.tabSplitter); this.Controls.Add(this.detailList); this.Name = "ErrorDisplay"; this.Size = new System.Drawing.Size(496, 288); this.ResumeLayout(false); } #endregion #region Form Level Events protected override void OnLoad(EventArgs e) { // NOTE: DesignMode is not true when display is nested in another // user control and the containing form is displayed in the designer. // This is a problem with VS.Net. // // Consequently, we rely on the fact that Services.UserSettings // returns a dummy Service, if the ServiceManager has not been // initialized. if ( !this.DesignMode ) { this.settings = Services.UserSettings; settings.Changed += new SettingsEventHandler(UserSettings_Changed); int splitPosition = settings.GetSetting( "Gui.ResultTabs.ErrorsTabSplitterPosition", tabSplitter.SplitPosition ); if ( splitPosition >= tabSplitter.MinSize && splitPosition < this.ClientSize.Height ) this.tabSplitter.SplitPosition = splitPosition; this.WordWrap = settings.GetSetting( "Gui.ResultTabs.ErrorsTab.WordWrapEnabled", true ); this.detailList.Font = this.stackTraceDisplay.Font = settings.GetSetting( "Gui.FixedFont", DefaultFixedFont ); Orientation splitOrientation = (Orientation)settings.GetSetting( "Gui.ResultTabs.ErrorBrowser.SplitterOrientation", Orientation.Vertical); float splitterDistance = splitOrientation == Orientation.Vertical ? settings.GetSetting( "Gui.ResultTabs.ErrorBrowser.VerticalPosition", 0.3f ) : settings.GetSetting( "Gui.ResultTabs.ErrorBrowser.HorizontalPosition", 0.3f ); sourceCode.SplitOrientation = splitOrientation; sourceCode.SplitterDistance = splitterDistance; sourceCode.SplitOrientationChanged += new EventHandler(sourceCode_SplitOrientationChanged); sourceCode.SplitterDistanceChanged += new EventHandler(sourceCode_SplitterDistanceChanged); if ( settings.GetSetting("Gui.ResultTabs.ErrorBrowser.SourceCodeDisplay", false) ) errorBrowser.SelectedDisplay = sourceCode; else errorBrowser.SelectedDisplay = stackTraceDisplay; errorBrowser.StackTraceDisplayChanged += new EventHandler(errorBrowser_StackTraceDisplayChanged); } base.OnLoad (e); } void errorBrowser_StackTraceDisplayChanged(object sender, EventArgs e) { settings.SaveSetting("Gui.ResultTabs.ErrorBrowser.SourceCodeDisplay", errorBrowser.SelectedDisplay == sourceCode); } void sourceCode_SplitterDistanceChanged(object sender, EventArgs e) { string distanceSetting = sourceCode.SplitOrientation == Orientation.Vertical ? "Gui.ResultTabs.ErrorBrowser.VerticalPosition" : "Gui.ResultTabs.ErrorBrowser.HorizontalPosition"; settings.SaveSetting(distanceSetting, sourceCode.SplitterDistance); } void sourceCode_SplitOrientationChanged(object sender, EventArgs e) { settings.SaveSetting("Gui.ResultTabs.ErrorBrowser.SplitterOrientation", sourceCode.SplitOrientation); string distanceSetting = sourceCode.SplitOrientation == Orientation.Vertical ? "Gui.ResultTabs.ErrorBrowser.VerticalPosition" : "Gui.ResultTabs.ErrorBrowser.HorizontalPosition"; sourceCode.SplitterDistance = settings.GetSetting(distanceSetting, 0.3f); } #endregion #region Public Methods public void Clear() { detailList.Items.Clear(); detailList.ContextMenu = null; errorBrowser.StackTraceSource = ""; } #endregion #region UserSettings Events private void UserSettings_Changed( object sender, SettingsEventArgs args ) { this.WordWrap = settings.GetSetting( "Gui.ResultTabs.ErrorsTab.WordWrapEnabled", true ); Font newFont = this.stackTraceDisplay.Font = this.sourceCode.CodeDisplayFont = settings.GetSetting("Gui.FixedFont", DefaultFixedFont); if (newFont != this.detailList.Font) { this.detailList.Font = newFont; RefillDetailList(); } } #endregion #region DetailList Events /// /// When one of the detail failure items is selected, display /// the stack trace and set up the tool tip for that item. /// private void detailList_SelectedIndexChanged(object sender, System.EventArgs e) { TestResultItem resultItem = (TestResultItem)detailList.SelectedItem; errorBrowser.StackTraceSource = resultItem.StackTrace; detailList.ContextMenu = detailListContextMenu; } private void detailList_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) { TestResultItem item = (TestResultItem) detailList.Items[e.Index]; //string s = item.ToString(); SizeF size = this.WordWrap ? e.Graphics.MeasureString(item.ToString(), detailList.Font, detailList.ClientSize.Width ) : e.Graphics.MeasureString(item.ToString(), detailList.Font ); e.ItemHeight = (int)size.Height; e.ItemWidth = (int)size.Width; } private void detailList_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { if (e.Index >= 0) { e.DrawBackground(); TestResultItem item = (TestResultItem) detailList.Items[e.Index]; bool selected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ? true : false; Brush brush = selected ? SystemBrushes.HighlightText : SystemBrushes.WindowText; RectangleF layoutRect = e.Bounds; if ( this.WordWrap && layoutRect.Width > detailList.ClientSize.Width ) layoutRect.Width = detailList.ClientSize.Width; e.Graphics.DrawString(item.ToString(),detailList.Font, brush, layoutRect); } } private void detailList_Resize(object sender, System.EventArgs e) { if ( this.WordWrap ) RefillDetailList(); } private void RefillDetailList() { if ( this.detailList.Items.Count > 0 ) { this.detailList.BeginUpdate(); ArrayList copiedItems = new ArrayList( detailList.Items ); this.detailList.Items.Clear(); foreach( object item in copiedItems ) this.detailList.Items.Add( item ); this.detailList.EndUpdate(); } } private void copyDetailMenuItem_Click(object sender, System.EventArgs e) { if ( detailList.SelectedItem != null ) Clipboard.SetDataObject( detailList.SelectedItem.ToString() ); } private void OnMouseHover(object sender, System.EventArgs e) { if ( tipWindow != null ) tipWindow.Close(); if ( settings.GetSetting( "Gui.ResultTabs.ErrorsTab.ToolTipsEnabled", false ) && hoverIndex >= 0 && hoverIndex < detailList.Items.Count ) { Graphics g = Graphics.FromHwnd( detailList.Handle ); Rectangle itemRect = detailList.GetItemRectangle( hoverIndex ); string text = detailList.Items[hoverIndex].ToString(); SizeF sizeNeeded = g.MeasureString( text, detailList.Font ); bool expansionNeeded = itemRect.Width < (int)sizeNeeded.Width || itemRect.Height < (int)sizeNeeded.Height; if ( expansionNeeded ) { tipWindow = new TipWindow( detailList, hoverIndex ); tipWindow.ItemBounds = itemRect; tipWindow.TipText = text; tipWindow.Expansion = TipWindow.ExpansionStyle.Both; tipWindow.Overlay = true; tipWindow.WantClicks = true; tipWindow.Closed += new EventHandler( tipWindow_Closed ); tipWindow.Show(); } } } private void tipWindow_Closed( object sender, System.EventArgs e ) { tipWindow = null; hoverIndex = -1; ClearTimer(); } private void detailList_MouseLeave(object sender, System.EventArgs e) { hoverIndex = -1; ClearTimer(); } private void detailList_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { ClearTimer(); hoverIndex = detailList.IndexFromPoint( e.X, e.Y ); if ( hoverIndex >= 0 && hoverIndex < detailList.Items.Count ) { // Workaround problem of IndexFromPoint returning an // index when mouse is over bottom part of list. Rectangle r = detailList.GetItemRectangle( hoverIndex ); if ( e.Y > r.Bottom ) hoverIndex = -1; else { hoverTimer = new System.Windows.Forms.Timer(); hoverTimer.Interval = 800; hoverTimer.Tick += new EventHandler( OnMouseHover ); hoverTimer.Start(); } } } private void ClearTimer() { if ( hoverTimer != null ) { hoverTimer.Stop(); hoverTimer.Dispose(); } } private void tabSplitter_SplitterMoved( object sender, SplitterEventArgs e ) { settings.SaveSetting( "Gui.ResultTabs.ErrorsTabSplitterPosition", tabSplitter.SplitPosition ); } #endregion #region TestObserver Interface public void Subscribe(ITestEvents events) { events.TestFinished += new TestEventHandler(OnTestFinished); events.SuiteFinished += new TestEventHandler(OnSuiteFinished); events.TestException += new TestEventHandler(OnTestException); } #endregion #region Test Event Handlers private void OnTestFinished(object sender, TestEventArgs args) { TestResult result = args.Result; switch (result.ResultState) { case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: if (result.FailureSite != FailureSite.Parent) InsertTestResultItem(result); break; case ResultState.NotRunnable: InsertTestResultItem(result); break; } } private void OnSuiteFinished(object sender, TestEventArgs args) { TestResult result = args.Result; if( result.FailureSite != FailureSite.Child ) switch (result.ResultState) { case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: InsertTestResultItem(result); break; } } private void OnTestException(object sender, TestEventArgs args) { string msg = string.Format( "An unhandled {0} was thrown while executing this test : {1}", args.Exception.GetType().FullName, args.Exception.Message ); TestResultItem item = new TestResultItem( args.Name, msg, args.Exception.StackTrace ); InsertTestResultItem( item ); } private void InsertTestResultItem( TestResult result ) { TestResultItem item = new TestResultItem(result); InsertTestResultItem( item ); } private void InsertTestResultItem( TestResultItem item ) { detailList.BeginUpdate(); detailList.Items.Insert(detailList.Items.Count, item); detailList.SelectedIndex = 0; detailList.EndUpdate(); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ErrorDisplay.resx0000664000175000017500000001360711504175260023117 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 NUnit-2.6.0.12051/src/GuiComponents/UiKit/AddTabPageDialog.cs0000664000175000017500000001016011544330406023146 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace NUnit.UiKit { /// /// Summary description for NewTabPageDialog. /// public class AddTabPageDialog : NUnitFormBase { private TextDisplayTabSettings tabSettings; private System.Windows.Forms.TextBox titleTextBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public AddTabPageDialog(TextDisplayTabSettings tabSettings) { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // this.tabSettings = tabSettings; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.titleTextBox = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // titleTextBox // this.titleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.titleTextBox.Location = new System.Drawing.Point(16, 32); this.titleTextBox.Name = "titleTextBox"; this.titleTextBox.Size = new System.Drawing.Size(312, 22); this.titleTextBox.TabIndex = 0; this.titleTextBox.Text = ""; // // label1 // this.label1.Location = new System.Drawing.Point(16, 8); this.label1.Name = "label1"; this.label1.TabIndex = 1; this.label1.Text = "Tab Page Title:"; // // okButton // this.okButton.Location = new System.Drawing.Point(88, 72); this.okButton.Name = "okButton"; this.okButton.TabIndex = 2; this.okButton.Text = "OK"; this.okButton.Click += new System.EventHandler(this.okButton_Click); // // cancelButton // this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(184, 72); this.cancelButton.Name = "cancelButton"; this.cancelButton.TabIndex = 3; this.cancelButton.Text = "Cancel"; // // AddTabPageDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; this.ClientSize = new System.Drawing.Size(344, 104); this.ControlBox = false; this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.Controls.Add(this.label1); this.Controls.Add(this.titleTextBox); this.Name = "AddTabPageDialog"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "New Tab Page"; this.ResumeLayout(false); } #endregion public string Title { get { return titleTextBox.Text; } } private void okButton_Click(object sender, System.EventArgs e) { if ( Title == string.Empty ) { MessageDisplay.Error("No title entered"); return; } tabSettings.Tabs.AddNewTab( Title ); DialogResult = DialogResult.OK; this.Close(); } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/NotRunTree.resx0000664000175000017500000000330511504175260022537 0ustar jtaylorjtaylor text/microsoft-resx 1.0.0.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NUnit-2.6.0.12051/src/GuiComponents/UiKit/EditTabPagesDialog.resx0000664000175000017500000002324711504175260024115 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private False Private Private False Private Private Private False Private False Private Private False Private Private False (Default) False False 8, 8 True 80 True EditTabPagesDialog Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/StatusBar.resx0000664000175000017500000001323011504175260022400 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private 17, 17 Private StatusBar False Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TabbedSettingsDialog.resx0000664000175000017500000002076711504175260024527 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Family False Private Family True False True Family Private 8, 8 False TabbedSettingsDialog (Default) False False 8, 8 True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextDisplayTabPage.cs0000664000175000017500000000217511504175260023620 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { /// /// Summary description for TextDisplayTabPage. /// public class TextDisplayTabPage : TabPage { private TextBoxDisplay display; public TextDisplayTabPage() { this.display = new TextBoxDisplay(); this.display.Dock = DockStyle.Fill; this.Controls.Add( display ); } public System.Drawing.Font DisplayFont { get { return display.Font; } set { display.Font = value; } } public TextDisplayTabPage( TextDisplayTabSettings.TabInfo tabInfo ) : this() { this.Name = tabInfo.Name; this.Text = tabInfo.Title; this.Display.Content = tabInfo.Content; } public TextDisplay Display { get { return this.display; } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/AddConfigurationDialog.resx0000664000175000017500000002327211504175260025037 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False Private False Private Private False Private Private Private False Private False Private Private False Private Private False (Default) False AddConfigurationDialog False 8, 8 True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/AppContainer.cs0000664000175000017500000000411011504175260022474 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Windows.Forms; namespace NUnit.UiKit { /// /// AppContainer acts as the container nunit components, providing /// them with a Site from which services may be acquired. /// public class AppContainer : Container { public AppContainer() { // We use a single root-level service container for the app _services = new ServiceContainer(); // Add the service containter to itself as a service! // This allows components to get access to the ServiceContainer // service in order to add services themselves. _services.AddService( typeof( IServiceContainer ), _services ); } ServiceContainer _services; public IServiceContainer Services { get { return _services; } } // Override GetService so that any components in this // container get access to services in the associated // ServiceContainer. protected override object GetService(Type service) { object s = _services.GetService(service); if (s == null) s = base.GetService(service); return s; } public static ISite GetSite( Control control ) { while( control != null && control.Site == null ) control = control.Parent; return control == null ? null : control.Site; } public static IContainer GetContainer( Control control ) { ISite site = GetSite( control ); return site == null ? null : site.Container; } public static object GetService( Control control, Type service ) { ISite site = GetSite( control ); return site == null ? null : site.GetService( service ); } public static AppContainer GetAppContainer( Control control ) { return GetContainer( control ) as AppContainer; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ScrollingTextDisplayForm.cs0000664000175000017500000001110511504175260025066 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.IO; using System.Collections; using System.Reflection; using System.Windows.Forms; using System.Drawing; using NUnit.Util; using NUnit.Core; namespace NUnit.UiKit { public class ScrollingTextDisplayForm : Form { private System.Windows.Forms.Button okButton; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.RichTextBox textBox; private System.Windows.Forms.Label message; public ScrollingTextDisplayForm() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.okButton = new System.Windows.Forms.Button(); this.textBox = new System.Windows.Forms.RichTextBox(); this.message = new System.Windows.Forms.Label(); this.SuspendLayout(); // // okButton // this.okButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.okButton.Location = new System.Drawing.Point(284, 441); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(90, 27); this.okButton.TabIndex = 1; this.okButton.Text = "Close"; // // textBox // this.textBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.textBox.Location = new System.Drawing.Point(10, 65); this.textBox.Name = "textBox"; this.textBox.ReadOnly = true; this.textBox.Size = new System.Drawing.Size(640, 362); this.textBox.TabIndex = 3; this.textBox.Text = ""; // // message // this.message.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.message.Location = new System.Drawing.Point(19, 9); this.message.Name = "message"; this.message.Size = new System.Drawing.Size(631, 46); this.message.TabIndex = 2; this.message.Text = ""; // // TestAssemblyInfoForm // this.ClientSize = new System.Drawing.Size(669, 480); this.Controls.Add(this.textBox); this.Controls.Add(this.message); this.Controls.Add(this.okButton); this.Name = "ScrollingTextDisplayForm"; this.Text = "NUnit"; this.Resize += new System.EventHandler(this.ScrollingTextDisplayForm_Resize); this.ResumeLayout(false); } #endregion protected RichTextBox TextBox { get { return textBox; } } protected Label Message { get { return message; } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); SetMessageLabelSize(); } private void ScrollingTextDisplayForm_Resize(object sender, System.EventArgs e) { SetMessageLabelSize(); } private void SetMessageLabelSize() { Rectangle rect = message.ClientRectangle; Graphics g = Graphics.FromHwnd(Handle); SizeF sizeNeeded = g.MeasureString(message.Text, message.Font, rect.Width); int delta = sizeNeeded.ToSize().Height - rect.Height; message.Height += delta; textBox.Top += delta; textBox.Height -= delta; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/nunit.uikit.dll.csproj0000664000175000017500000003517611703332314024053 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {27531BBF-183D-4C3A-935B-D840B9F1A3A4} Debug AnyCPU nunit.uikit JScript Grid IE50 false Library NUnit.UiKit OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 1699 true false false 4 none prompt System System.Data System.Drawing System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False {3E87A106-EB20-4147-84C8-95B0BB43A1D4} nunit.uiexception.dll False CommonAssemblyInfo.cs Form Form Form Form UserControl Component Component Form Component Form Component Form UserControl Form Form UserControl Form Component Form Form TestPropertiesDialog.cs Component UserControl Component Component UserControl Form Form AddConfigurationDialog.cs Designer AddTabPageDialog.cs Designer ConfigurationEditor.cs Designer EditTabPagesDialog.cs Designer ErrorDisplay.cs Designer ExpandingLabel.cs Designer ExpandingTextBox.cs Designer LongRunningOperationDisplay.cs Designer NotRunTree.cs Designer ProgressBar.cs Designer RenameConfigurationDialog.cs Designer ResultTabs.cs Designer SettingsDialogBase.cs Designer SettingsPage.cs Designer SimpleSettingsDialog.cs Designer StatusBar.cs Designer TabbedSettingsDialog.cs Designer TestPropertiesDialog.cs TestSuiteTreeView.cs Designer TestTree.cs Designer TextOutputSettingsPage.cs Designer TipWindow.cs Designer TreeBasedSettingsDialog.cs Designer PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/0000775000175000017500000000000011742560362021000 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/0000775000175000017500000000000011742560362021677 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Classic/0000775000175000017500000000000011742560362023260 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Classic/Success.jpg0000664000175000017500000000140011504175260025360 0ustar jtaylorjtaylorJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?x`37Y-CO t%Ly8(''x7?k.%W2]B>x;TEM?K,f8,?0`N;f8}ibm%߶|ߑp6wvQ_7NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Classic/Ignored.jpg0000664000175000017500000000142511504175260025346 0ustar jtaylorjtaylorJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?:+Fw & hЍ 6p$oP\tW˒M4hAʒhCTa4|Oox-tB8ؠX#r*4дK[w*]Iv'y,wy8|)_\jiۛNֽ9ONUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Classic/Inconclusive.jpg0000664000175000017500000000142011504175260026413 0ustar jtaylorjtaylorJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?[ iŲw2 f p/W&/%,`e\˸S99׋;aԧıHѵX;nsPx6Mms3YN3WE⽳|ov[Km-]?NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Classic/Failure.jpg0000664000175000017500000000145011504175260025344 0ustar jtaylorjtaylorJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?o}x{:kt-Ċ[vco)8uxMKyMq ^ p3. d*< ~!Ե[m&i?luKwǛ;)Ֆh!x#3xLJBR^`#_Qapk@UtdBU0HKcr;PFQzv`kw16P0u9-HK(@OlCw"/fIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Default/Skipped.png0000664000175000017500000000257511504175260025374 0ustar jtaylorjtaylorPNG  IHDR(-SsRGBgAMA a cHRMz&u0`:pQ<PLTEMMMOOOPPPQQQRRRYYY\\\]]]```cccfffiiijjjlllmmmooopppqqqrrrsssttt{{{|||}}}~~~ĩtRNSS% pHYs oytEXtSoftwarePaint.NET v3.36%IDAT(Se0 EY(Bb,.V۪yJ$7OXR.Lj B dk;#%`ľ` QK 8_y@Of㩹6U2}\o9ѷ55A-z(̌%C%^͖¬)ƌEL} %tQMIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Default/Success.png0000664000175000017500000000263711504175260025404 0ustar jtaylorjtaylorPNG  IHDR(-SsRGBgAMA a cHRMz&u0`:pQ<PLTE     24)))???AA`9M9=X= k )f)6o6@@@DmDFxB$$--==!!6611>>55::>>ME]][[^^yy||aaaabbddkkooqq@@BBPPSSUPQQddaahhnnwwy̍߄ȅӆޏݕі̙֜ѝѴlvtRNSS% pHYs oytEXtSoftwarePaint.NET v3.36%IDAT(ScOO xhjK2xLe8A^&rv\  -ra< †@}^ )q 3t/'H@AO$c cale2hĥnjV:Zn@ƪF@ysp !fz)IENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Default/Failure.png0000664000175000017500000000264511504175260025362 0ustar jtaylorjtaylorPNG  IHDR(-SsRGBgAMA a cHRMz&u0`:pQ<PLTE$ % 79 555777AKNVXD H"P T%] K% Y-(]3.b'UUUcTReUSwww{{{3 <+8%F:H<`Wc[|}VK]M_Nrhvotiwkyo{o|r?*?+D0I7F2G4J7L8M:Q>R?Q@TAUCWE[I]K^L_NcTcVfViZdTfWm`o`iYm\vf{l}~~u{tRNSS% pHYs oytEXtSoftwarePaint.NET v3.36%IDAT(S]kWAQ)ʭҕ"QtUH܎߁iy5[kf0%TSgI?6a׀E0#pmyc=֑ 卙XQ {kP-lCpv5]j`GͺzrRy\q|0U 4h_j CowfkIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Default/Ignored.png0000664000175000017500000000112011700404620025336 0ustar jtaylorjtaylorPNG  IHDRasRGBgAMA a cHRMz&u0`:pQ< pHYs+tEXtSoftwarePaint.NET v3.36%IDAT8OSMKA}kat#-0Bv "S[An5igm]w҃޼7;Cʠ_FxZ ,C 5-e0`חgBΏ*D;:]٬d"pK&fx@nUm`a 1nۮb3Ӣ \ qtH}uhOjM>; U  j>EbLVC`Pi\ ΡKkcEŒFjtPA8՗ic:6|ĉ̑2z$iUфHŦA\(ឰ#+BMl}0$C/f؟db&lUQ*g<>iyFj.|]Ŗ }-_`3IENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/0000775000175000017500000000000011742560362024372 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/Inconclusive.png0000664000175000017500000000141611700402234027526 0ustar jtaylorjtaylorPNG  IHDRh6sRGBgAMA a pHYsodIDAT8Ou[Lqy꡴.V[#*\^+iQ _.|6 rQ(idȟDsIڟ??/Ey:|C Sh"J} C\(2|V|semO3ׯ)\&0k/Yj;Hyf8`E+\ChI<5..dڱ=*.zk̶-qq b2v`S9i{+'k'IcԏyT@F #l/VdE% O97CR1\*e&+t59 d.3:X_%X4呦FEaIN= g!4&#jobXp"^7/^g.-a{>=T{;m%$b"Bǣx~5w%E~eS:퓥% { \Yx5_y]Bm>=}Ȁ70ѱԓwݙ.K[5*:jӔV=ZZҫL(OZUGI{->}grm?J&_zƷBCfIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/Skipped.png0000664000175000017500000000257511703323226026501 0ustar jtaylorjtaylorPNG  IHDR(-SsRGBgAMA a cHRMz&u0`:pQ<PLTEMMMOOOPPPQQQRRRYYY\\\]]]```cccfffiiijjjlllmmmooopppqqqrrrsssttt{{{|||}}}~~~ĩtRNSS% pHYs oytEXtSoftwarePaint.NET v3.36%IDAT(Se0 EY(Bb,.V۪yJ$7OXR.Lj B dk;#%`ľ` QK 8_y@Of㩹6U2}\o9ѷ55A-z(̌%C%^͖¬)ƌEL} %tQMIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/Success.png0000664000175000017500000000647211700156164026514 0ustar jtaylorjtaylorPNG  IHDRagAMA|Q cHRMR@}y<s== <8Xȉ9yP:8p΍Lg kk Ѐ$t!0V87`ɀ2A. @JPA#h'@8 .: ``a!2D!UH 2 dA>P ECqB**Z:]B=h~L2  5pN:|ó@ QC !H,G6 H9R ]H/r Aw( Q(OTJCm@*QGQ-(j MF+ 6h/*t:].G7Зw7 Xa<1:L1s3bXyeb~19 vGĩp+5qy^ oó|= ?'Htv`Ba3BDxHxE$Չ"XAP44077&9$An0;T2421t.54ld+s;# V]=iY9FgM֚k&=%Ō:nc1gcbcfX.}lGv{c)LŖN퉛w/p+/<j$.$%&㒣OdxTԂԑ4i3|o~C:&S@L u[Uo3C3OfIgwdO|;W-wsz 17jl8c͉̈́3+{%lKWr[ $ llGmnacOkE&EEY׾2⫅;K,KhtiN=e²{^-_V^Oo§s]?TWީrjVQ=w}`嚢zԶiו8>k׍ E  [ly邟~_Y53rW򯎼^{7so}x>|쇊z>yz pHYs+kIDAT8OKQڪnEZ]AEIA`qAE7u%ai]&,!:3<39;l0}3xJ,[u-I,IB!_`3:b8x*]`pvD8 t#"aMV{oER8pZp+vitD#PuPB"2+8tqyMSH|IШ/0?ƿ}pL  9S3 yJ[ |r h AM E!T +NqЉB J[) @X#Pa>}4CAb.UY+2߷< ljCV D:5?] \⠪3J3Tr_x??(}yrTq`+FCF ~Taa:Z-\Al'UE TgV2:\:t :@52}QbTOh0"JZt….GC16mPCQQX J /'8"Z%s=sYgDo?@r4=؝W艠[Rk,Ǿ$ *+3S)PXZ EMRyRkvT: SYa#PI+HFlty? ?]֫Sj;tԾ'URlLB5zfBIc#MQ]ݢ&(&?S`덄.!zy,pxjF7qҊ.7D熇 ?ֿ`ss ~;*IENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/Failure.png0000664000175000017500000000135311700155650026463 0ustar jtaylorjtaylorPNG  IHDRagAMA|Q cHRMz%u0`:o_F pHYs+aIDAT8OKHQ4u4G!́`5fAK6j!A킂6P Š( BI-g&5oW|&\{?sXs ~y Ӥɇc/}/L/`.uɢuZY+ؚ:_[ C2ȤӘܵS,_9bwx` ̸h;nd¢~fW,$q[LqmGI{ws؆ x:sxm ag KV 6]WiF9|-8AcmfI["sO__Q-?L YZ%j`R~zu@_G*ӌ7yIENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Tree/Visual Studio/Ignored.png0000664000175000017500000000140511700155024026454 0ustar jtaylorjtaylorPNG  IHDRagAMA|Q cHRMz%u0`:o_F pHYs+{IDAT8O[KTQq:Zi^2,ʊ]AA/A(ȧОKBD 5BPKqqn ArڛZaei0Vqݦ6Ou-z4Bae1.{7X%ԊvGs. @?w(Ш` w^A=4LМ+4][$ͩHrs}CP2i]Lߥ 2[ΆfYS)Yk־ξM?8oi(`)IENDB`NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/Ellipsis.gif0000664000175000017500000000014511504175260023246 0ustar jtaylorjtaylorGIF89a !, I wafX;NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/unpinned.gif0000664000175000017500000000156111504175260023305 0ustar jtaylorjtaylorGIF89a3f333f3333f3ffffff3f̙3f3f333f333333333f33333333f33f3ff3f3f3f3333f33̙33333f3333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffffff3ffff̙fff3fffffff3ffffff3f333f3333f3ffffff3f̙̙3̙f̙̙̙̙3f3f̙333f3̙333f3fff̙fff3f̙̙3f̙3f̙3f333f3333f3ffffff3f̙3f3f!,N H"@! 2<5#x-@ TU V&Yi$5>$ɒ$E,eJN@ ;NUnit-2.6.0.12051/src/GuiComponents/UiKit/Images/pinned.gif0000664000175000017500000000156511504175260022746 0ustar jtaylorjtaylorGIF89a3f333f3333f3ffffff3f̙3f3f333f333333333f33333333f33f3ff3f3f3f3333f33̙33333f3333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffffff3ffff̙fff3fffffff3ffffff3f333f3333f3ffffff3f̙̙3̙f̙̙̙̙3f3f̙333f3̙333f3fff̙fff3f̙̙3f̙3f̙3f333f3333f3ffffff3f̙3f3f!,R H*! >4P &Jdx"F'>$GVa,Y0%M2 Df̃)m: 3fCu\H赀;NUnit-2.6.0.12051/src/GuiComponents/UiKit/ResultTabs.cs0000664000175000017500000003573411703144510022214 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NUnit.Util; using NUnit.Core; using CP.Windows.Forms; using System.Diagnostics; namespace NUnit.UiKit { /// /// Summary description for ResultTabs. /// public class ResultTabs : System.Windows.Forms.UserControl, TestObserver { static Logger log = InternalTrace.GetLogger(typeof(ResultTabs)); private ISettings settings; private bool updating = false; private TextDisplayController displayController; private MenuItem tabsMenu; private MenuItem errorsTabMenuItem; private MenuItem notRunTabMenuItem; private MenuItem menuSeparator; private MenuItem textOutputMenuItem; private System.Windows.Forms.TabPage errorTab; private NUnit.UiKit.ErrorDisplay errorDisplay; private System.Windows.Forms.TabPage notRunTab; private NUnit.UiKit.NotRunTree notRunTree; private System.Windows.Forms.TabControl tabControl; private System.Windows.Forms.MenuItem copyDetailMenuItem; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public ResultTabs() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); this.tabsMenu = new MenuItem(); this.errorsTabMenuItem = new System.Windows.Forms.MenuItem(); this.notRunTabMenuItem = new System.Windows.Forms.MenuItem(); this.menuSeparator = new System.Windows.Forms.MenuItem(); this.textOutputMenuItem = new System.Windows.Forms.MenuItem(); this.tabsMenu.MergeType = MenuMerge.Add; this.tabsMenu.MergeOrder = 1; this.tabsMenu.MenuItems.AddRange( new System.Windows.Forms.MenuItem[] { this.errorsTabMenuItem, this.notRunTabMenuItem, this.menuSeparator, this.textOutputMenuItem, } ); this.tabsMenu.Text = "&Result Tabs"; this.tabsMenu.Visible = true; this.errorsTabMenuItem.Index = 0; this.errorsTabMenuItem.Text = "&Errors && Failures"; this.errorsTabMenuItem.Click += new System.EventHandler(this.errorsTabMenuItem_Click); this.notRunTabMenuItem.Index = 1; this.notRunTabMenuItem.Text = "Tests &Not Run"; this.notRunTabMenuItem.Click += new System.EventHandler(this.notRunTabMenuItem_Click); this.menuSeparator.Index = 2; this.menuSeparator.Text = "-"; this.textOutputMenuItem.Index = 3; this.textOutputMenuItem.Text = "Text &Output..."; this.textOutputMenuItem.Click += new EventHandler(textOutputMenuItem_Click); displayController = new TextDisplayController(tabControl); // displayController.CreatePages(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.tabControl = new System.Windows.Forms.TabControl(); this.errorTab = new System.Windows.Forms.TabPage(); this.errorDisplay = new NUnit.UiKit.ErrorDisplay(); this.notRunTab = new System.Windows.Forms.TabPage(); this.notRunTree = new NUnit.UiKit.NotRunTree(); this.copyDetailMenuItem = new System.Windows.Forms.MenuItem(); this.tabControl.SuspendLayout(); this.errorTab.SuspendLayout(); this.notRunTab.SuspendLayout(); this.SuspendLayout(); // // tabControl // this.tabControl.Alignment = System.Windows.Forms.TabAlignment.Bottom; this.tabControl.Controls.Add(this.errorTab); this.tabControl.Controls.Add(this.notRunTab); this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl.Location = new System.Drawing.Point(0, 0); this.tabControl.Name = "tabControl"; this.tabControl.SelectedIndex = 0; this.tabControl.Size = new System.Drawing.Size(488, 280); this.tabControl.TabIndex = 3; this.tabControl.SelectedIndexChanged += new System.EventHandler(this.tabControl_SelectedIndexChanged); // // errorTab // this.errorTab.Controls.Add(this.errorDisplay); this.errorTab.ForeColor = System.Drawing.SystemColors.ControlText; this.errorTab.Location = new System.Drawing.Point(4, 4); this.errorTab.Name = "errorTab"; this.errorTab.Size = new System.Drawing.Size(480, 254); this.errorTab.TabIndex = 0; this.errorTab.Text = "Errors and Failures"; // // errorDisplay // this.errorDisplay.Dock = System.Windows.Forms.DockStyle.Fill; this.errorDisplay.Location = new System.Drawing.Point(0, 0); this.errorDisplay.Name = "errorDisplay"; this.errorDisplay.Size = new System.Drawing.Size(480, 254); this.errorDisplay.TabIndex = 0; // // notRunTab // this.notRunTab.Controls.Add(this.notRunTree); this.notRunTab.ForeColor = System.Drawing.SystemColors.ControlText; this.notRunTab.Location = new System.Drawing.Point(4, 4); this.notRunTab.Name = "notRunTab"; this.notRunTab.Size = new System.Drawing.Size(480, 254); this.notRunTab.TabIndex = 1; this.notRunTab.Text = "Tests Not Run"; this.notRunTab.Visible = false; // // notRunTree // this.notRunTree.Dock = System.Windows.Forms.DockStyle.Fill; this.notRunTree.ImageIndex = -1; this.notRunTree.Indent = 19; this.notRunTree.Location = new System.Drawing.Point(0, 0); this.notRunTree.Name = "notRunTree"; this.notRunTree.SelectedImageIndex = -1; this.notRunTree.Size = new System.Drawing.Size(480, 254); this.notRunTree.TabIndex = 0; // // copyDetailMenuItem // this.copyDetailMenuItem.Index = -1; this.copyDetailMenuItem.Text = "Copy"; // // ResultTabs // this.Controls.Add(this.tabControl); this.Name = "ResultTabs"; this.Size = new System.Drawing.Size(488, 280); this.tabControl.ResumeLayout(false); this.errorTab.ResumeLayout(false); this.notRunTab.ResumeLayout(false); this.ResumeLayout(false); } #endregion public bool IsTracingEnabled { get { return displayController.IsTracingEnabled; } } public LoggingThreshold MaximumLogLevel { get { return displayController.MaximumLogLevel; } } public void Clear() { errorDisplay.Clear(); notRunTree.Nodes.Clear(); displayController.Clear(); } public MenuItem TabsMenu { get { return tabsMenu; } } protected override void OnLoad(EventArgs e) { if ( !this.DesignMode ) { this.settings = Services.UserSettings; TextDisplayTabSettings tabSettings = new TextDisplayTabSettings(); tabSettings.LoadSettings( settings ); UpdateTabPages(); Subscribe( Services.TestLoader.Events ); Services.UserSettings.Changed += new SettingsEventHandler(UserSettings_Changed); ITestEvents events = Services.TestLoader.Events; errorDisplay.Subscribe( events ); notRunTree.Subscribe( events ); displayController.Subscribe( events ); } base.OnLoad (e); } private void UpdateTabPages() { errorsTabMenuItem.Checked = settings.GetSetting( "Gui.ResultTabs.DisplayErrorsTab", true ); notRunTabMenuItem.Checked = settings.GetSetting( "Gui.ResultTabs.DisplayNotRunTab", true ); log.Debug( "Updating tab pages" ); updating = true; tabControl.TabPages.Clear(); if ( errorsTabMenuItem.Checked ) tabControl.TabPages.Add( errorTab ); if ( notRunTabMenuItem.Checked ) tabControl.TabPages.Add( notRunTab ); displayController.UpdatePages(); tabControl.SelectedIndex = settings.GetSetting( "Gui.ResultTabs.SelectedTab", 0 ); updating = false; } private void UserSettings_Changed( object sender, SettingsEventArgs e ) { if( e.SettingName.StartsWith( "Gui.ResultTabs.Display" ) || e.SettingName == "Gui.TextOutput.TabList" || e.SettingName.StartsWith( "Gui.TextOut" ) && e.SettingName.EndsWith( "Enabled" ) ) UpdateTabPages(); } private void errorsTabMenuItem_Click(object sender, System.EventArgs e) { settings.SaveSetting( "Gui.ResultTabs.DisplayErrorsTab", errorsTabMenuItem.Checked = !errorsTabMenuItem.Checked ); } private void notRunTabMenuItem_Click(object sender, System.EventArgs e) { settings.SaveSetting( "Gui.ResultTabs.DisplayNotRunTab", notRunTabMenuItem.Checked = !notRunTabMenuItem.Checked ); } private void textOutputMenuItem_Click(object sender, System.EventArgs e) { SimpleSettingsDialog.Display( this.FindForm(), new TextOutputSettingsPage("Text Output") ); } private void tabControl_SelectedIndexChanged(object sender, System.EventArgs e) { if ( !updating ) { int index = tabControl.SelectedIndex; if ( index >=0 && index < tabControl.TabCount ) settings.SaveSetting( "Gui.ResultTabs.SelectedTab", index ); } } #region TestObserver Members public void Subscribe(ITestEvents events) { events.TestLoaded += new TestEventHandler(OnTestLoaded); events.TestUnloaded += new TestEventHandler(OnTestUnloaded); events.TestReloaded += new TestEventHandler(OnTestReloaded); events.RunStarting += new TestEventHandler(OnRunStarting); } private void OnRunStarting(object sender, TestEventArgs args) { this.Clear(); } private void OnTestLoaded(object sender, TestEventArgs args) { this.Clear(); } private void OnTestUnloaded(object sender, TestEventArgs args) { this.Clear(); } private void OnTestReloaded(object sender, TestEventArgs args) { if ( settings.GetSetting( "Options.TestLoader.ClearResultsOnReload", false ) ) this.Clear(); } #endregion private void tabControl_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { bool selected = e.Index == tabControl.SelectedIndex; Font font = selected ? new Font( e.Font, FontStyle.Bold ) : e.Font; Brush backBrush = new SolidBrush( selected ? SystemColors.Control : SystemColors.Window ); Brush foreBrush = new SolidBrush( SystemColors.ControlText ); e.Graphics.FillRectangle( backBrush, e.Bounds ); Rectangle r = e.Bounds; r.Y += 3; r.Height -= 3; StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; e.Graphics.DrawString( tabControl.TabPages[e.Index].Text, font, foreBrush, r, sf ); foreBrush.Dispose(); backBrush.Dispose(); if ( selected ) font.Dispose(); } protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); tabControl.ItemSize = new Size(tabControl.ItemSize.Width, this.Font.Height + 7); } private class TextDisplayController : TestObserver { private TabControl tabControl; List tabPages = new List(); public TextDisplayController(TabControl tabControl) { this.tabControl = tabControl; Services.UserSettings.Changed += new SettingsEventHandler(UserSettings_Changed); } public bool IsTracingEnabled { get { foreach (TextDisplayTabPage page in tabPages) if (page.Display.Content.Trace) return true; return false; } } public LoggingThreshold MaximumLogLevel { get { LoggingThreshold logLevel = LoggingThreshold.Off; foreach (TextDisplayTabPage page in tabPages) { LoggingThreshold level = page.Display.Content.LogLevel; if (level > logLevel) logLevel = level; } return logLevel; } } public void Clear() { foreach( TextDisplayTabPage page in tabPages ) page.Display.Clear(); } public void UpdatePages() { TextDisplayTabSettings tabSettings = new TextDisplayTabSettings(); tabSettings.LoadSettings(); List oldPages = tabPages; tabPages = new List(); Font displayFont = GetFixedFont(); foreach( TextDisplayTabSettings.TabInfo tabInfo in tabSettings.Tabs ) { if ( tabInfo.Enabled ) { TextDisplayTabPage thePage = null; foreach( TextDisplayTabPage page in oldPages ) if ( page.Name == tabInfo.Name ) { thePage = page; break; } if ( thePage == null ) thePage = new TextDisplayTabPage( tabInfo ); thePage.DisplayFont = displayFont; tabPages.Add( thePage ); tabControl.TabPages.Add( thePage ); } } } private void UserSettings_Changed(object sender, SettingsEventArgs args) { string settingName = args.SettingName; string prefix = "Gui.TextOutput."; if ( settingName == "Gui.FixedFont" ) { Font displayFont = GetFixedFont(); foreach( TextDisplayTabPage page in tabPages ) page.DisplayFont = displayFont; } else if ( settingName.StartsWith( prefix ) ) { string fieldName = settingName.Substring( prefix.Length ); int dot = fieldName.IndexOf('.'); if ( dot > 0 ) { string tabName = fieldName.Substring( 0, dot ); string propName = fieldName.Substring( dot + 1 ); foreach( TextDisplayTabPage page in tabPages ) if ( page.Name == tabName ) { switch(propName) { case "Title": page.Text = (string)Services.UserSettings.GetSetting( settingName ); break; case "Content": page.Display.Content.LoadSettings(tabName); break; } } } } } private static Font GetFixedFont() { ISettings settings = Services.UserSettings; return settings == null ? new Font(FontFamily.GenericMonospace, 8.0f) : settings.GetSetting("Gui.FixedFont", new Font(FontFamily.GenericMonospace, 8.0f)); } #region TestObserver Members public void Subscribe(ITestEvents events) { foreach( TextDisplayTabPage page in tabPages ) page.Display.Subscribe(events); } #endregion } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/LongRunningOperationDisplay.resx0000664000175000017500000001555411504175260026152 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private False (Default) False False LongRunningOperationDisplay 8, 8 True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/EditTabPagesDialog.cs0000664000175000017500000001634311544330406023537 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace NUnit.UiKit { /// /// Summary description for EditTabPagesDialog. /// public class EditTabPagesDialog : NUnitFormBase { private TextDisplayTabSettings tabSettings; private int selectedIndex = -1; private System.Windows.Forms.Button addButton; private System.Windows.Forms.Button closeButton; private System.Windows.Forms.Button removeButton; private System.Windows.Forms.ListBox tabPageListBox; private System.Windows.Forms.Button moveDownButton; private System.Windows.Forms.Button moveUpButton; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public EditTabPagesDialog(TextDisplayTabSettings tabSettings) { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // this.tabSettings = tabSettings; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.addButton = new System.Windows.Forms.Button(); this.closeButton = new System.Windows.Forms.Button(); this.removeButton = new System.Windows.Forms.Button(); this.tabPageListBox = new System.Windows.Forms.ListBox(); this.moveUpButton = new System.Windows.Forms.Button(); this.moveDownButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // addButton // this.addButton.Location = new System.Drawing.Point(192, 48); this.addButton.Name = "addButton"; this.addButton.Size = new System.Drawing.Size(96, 32); this.addButton.TabIndex = 10; this.addButton.Text = "&Add..."; this.addButton.Click += new System.EventHandler(this.addButton_Click); // // closeButton // this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.closeButton.Location = new System.Drawing.Point(190, 218); this.closeButton.Name = "closeButton"; this.closeButton.Size = new System.Drawing.Size(96, 32); this.closeButton.TabIndex = 9; this.closeButton.Text = "Close"; // // removeButton // this.removeButton.Location = new System.Drawing.Point(190, 10); this.removeButton.Name = "removeButton"; this.removeButton.Size = new System.Drawing.Size(96, 32); this.removeButton.TabIndex = 7; this.removeButton.Text = "&Remove"; this.removeButton.Click += new System.EventHandler(this.removeButton_Click); // // tabPageListBox // this.tabPageListBox.ItemHeight = 16; this.tabPageListBox.Location = new System.Drawing.Point(6, 10); this.tabPageListBox.Name = "tabPageListBox"; this.tabPageListBox.Size = new System.Drawing.Size(168, 212); this.tabPageListBox.TabIndex = 6; this.tabPageListBox.SelectedIndexChanged += new System.EventHandler(this.tabPageListBox_SelectedIndexChanged); // // moveUpButton // this.moveUpButton.Location = new System.Drawing.Point(192, 88); this.moveUpButton.Name = "moveUpButton"; this.moveUpButton.Size = new System.Drawing.Size(96, 32); this.moveUpButton.TabIndex = 11; this.moveUpButton.Text = "Move Up"; this.moveUpButton.Click += new System.EventHandler(this.moveUpButton_Click); // // moveDownButton // this.moveDownButton.Location = new System.Drawing.Point(192, 128); this.moveDownButton.Name = "moveDownButton"; this.moveDownButton.Size = new System.Drawing.Size(96, 32); this.moveDownButton.TabIndex = 12; this.moveDownButton.Text = "Move Down"; this.moveDownButton.Click += new System.EventHandler(this.moveDownButton_Click); // // EditTabPagesDialog // this.AcceptButton = this.closeButton; this.CancelButton = this.closeButton; this.ClientSize = new System.Drawing.Size(292, 260); this.ControlBox = false; this.Controls.Add(this.moveDownButton); this.Controls.Add(this.moveUpButton); this.Controls.Add(this.addButton); this.Controls.Add(this.closeButton); this.Controls.Add(this.removeButton); this.Controls.Add(this.tabPageListBox); this.Name = "EditTabPagesDialog"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Tab Pages"; this.Load += new System.EventHandler(this.EditTabPagesDialog_Load); this.ResumeLayout(false); } #endregion private void EditTabPagesDialog_Load(object sender, System.EventArgs e) { FillListBox(); if ( tabPageListBox.Items.Count > 0 ) tabPageListBox.SelectedIndex = selectedIndex = 0; } private void tabPageListBox_SelectedIndexChanged(object sender, System.EventArgs e) { selectedIndex = tabPageListBox.SelectedIndex; removeButton.Enabled = selectedIndex >= 0; moveUpButton.Enabled = selectedIndex > 0; moveDownButton.Enabled = selectedIndex >= 0 && selectedIndex < tabPageListBox.Items.Count - 1; } private void addButton_Click(object sender, System.EventArgs e) { using( AddTabPageDialog dlg = new AddTabPageDialog(tabSettings) ) { this.Site.Container.Add( dlg ); if ( dlg.ShowDialog() == DialogResult.OK ) FillListBox(); } } private void removeButton_Click(object sender, System.EventArgs e) { tabSettings.Tabs.RemoveAt(selectedIndex); FillListBox(); } private void renameButton_Click(object sender, System.EventArgs e) { tabSettings.Tabs[selectedIndex].Title = ""; } #region Helper Methods private void FillListBox() { tabPageListBox.Items.Clear(); foreach( TextDisplayTabSettings.TabInfo tab in tabSettings.Tabs ) tabPageListBox.Items.Add( tab.Title ); int count = tabPageListBox.Items.Count; if ( count > 0 ) { if ( selectedIndex >= count ) selectedIndex = count - 1; tabPageListBox.SelectedIndex = selectedIndex; } else selectedIndex = -1; } #endregion private void moveUpButton_Click(object sender, System.EventArgs e) { TextDisplayTabSettings.TabInfo tab = tabSettings.Tabs[selectedIndex]; tabSettings.Tabs.RemoveAt(selectedIndex--); tabSettings.Tabs.Insert(selectedIndex, tab ); FillListBox(); } private void moveDownButton_Click(object sender, System.EventArgs e) { TextDisplayTabSettings.TabInfo tab = tabSettings.Tabs[selectedIndex]; tabSettings.Tabs.RemoveAt(selectedIndex++); tabSettings.Tabs.Insert(selectedIndex, tab ); FillListBox(); } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/RenameConfigurationDialog.cs0000664000175000017500000001257211544330406025202 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { /// /// Displays a dialog for entry of a new name for an /// existing configuration. This dialog collects and /// validates the name. The caller is responsible for /// actually renaming the cofiguration. /// public class RenameConfigurationDialog : NUnitFormBase { #region Instance Variables /// /// The project in which we are renaming a configuration /// private NUnitProject project; /// /// The new name to give the configuration /// private string configurationName; /// /// The original name of the configuration /// private string originalName; private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.TextBox configurationNameTextBox; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; #endregion #region Construction and Disposal public RenameConfigurationDialog( NUnitProject project, string configurationName ) { InitializeComponent(); this.project = project; this.configurationName = configurationName; this.originalName = configurationName; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.configurationNameTextBox = new System.Windows.Forms.TextBox(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // configurationNameTextBox // this.configurationNameTextBox.Location = new System.Drawing.Point(16, 16); this.configurationNameTextBox.Name = "configurationNameTextBox"; this.configurationNameTextBox.Size = new System.Drawing.Size(264, 22); this.configurationNameTextBox.TabIndex = 0; this.configurationNameTextBox.Text = ""; this.configurationNameTextBox.TextChanged += new System.EventHandler(this.configurationNameTextBox_TextChanged); // // okButton // this.okButton.Location = new System.Drawing.Point(56, 48); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(75, 24); this.okButton.TabIndex = 1; this.okButton.Text = "OK"; this.okButton.Click += new System.EventHandler(this.okButton_Click); // // cancelButton // this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(160, 48); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(75, 24); this.cancelButton.TabIndex = 2; this.cancelButton.Text = "Cancel"; // // RenameConfigurationDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; this.ClientSize = new System.Drawing.Size(291, 79); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.Controls.Add(this.configurationNameTextBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "RenameConfigurationDialog"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Rename Configuration"; this.Load += new System.EventHandler(this.ConfigurationNameDialog_Load); this.ResumeLayout(false); } #endregion #region Properties & Methods public string ConfigurationName { get{ return configurationName; } set{ configurationName = value; } } private void ConfigurationNameDialog_Load(object sender, System.EventArgs e) { if ( configurationName != null ) { configurationNameTextBox.Text = configurationName; configurationNameTextBox.SelectAll(); } } private void okButton_Click(object sender, System.EventArgs e) { configurationName = configurationNameTextBox.Text; if ( project.Configs.Contains( configurationName ) ) // TODO: Need general error message display MessageDisplay.Error("A configuration with that name already exists"); else { DialogResult = DialogResult.OK; Close(); } } private void configurationNameTextBox_TextChanged(object sender, System.EventArgs e) { okButton.Enabled = configurationNameTextBox.TextLength > 0 && configurationNameTextBox.Text != originalName; } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/NUnitFormBase.cs0000664000175000017500000000166611544330406022601 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.UiKit { public class NUnitFormBase : Form { private IMessageDisplay messageDisplay; private string caption; public NUnitFormBase() { } public NUnitFormBase(string caption) { this.caption = caption; } public IMessageDisplay MessageDisplay { get { if (messageDisplay == null) messageDisplay = new MessageDisplay(caption == null ? Text : caption); return messageDisplay; } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/SimpleSettingsDialog.cs0000664000175000017500000000642111504175260024212 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace NUnit.UiKit { public class SimpleSettingsDialog : NUnit.UiKit.SettingsDialogBase { private System.Windows.Forms.Panel panel1; private System.Windows.Forms.GroupBox groupBox1; private System.ComponentModel.IContainer components = null; public static void Display( Form owner, SettingsPage page ) { using( SimpleSettingsDialog dialog = new SimpleSettingsDialog() ) { owner.Site.Container.Add( dialog ); dialog.Font = owner.Font; dialog.SettingsPages.Add( page ); dialog.ShowDialog(); } } public SimpleSettingsDialog() { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.panel1 = new System.Windows.Forms.Panel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.SuspendLayout(); // // cancelButton // this.cancelButton.Location = new System.Drawing.Point(410, 392); this.cancelButton.Name = "cancelButton"; // // okButton // this.okButton.Location = new System.Drawing.Point(322, 392); this.okButton.Name = "okButton"; // // panel1 // this.panel1.Location = new System.Drawing.Point(16, 16); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(456, 336); this.panel1.TabIndex = 21; // // groupBox1 // this.groupBox1.Location = new System.Drawing.Point(16, 360); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(456, 8); this.groupBox1.TabIndex = 22; this.groupBox1.TabStop = false; // // SimpleSettingsDialog // this.ClientSize = new System.Drawing.Size(490, 426); this.Controls.Add(this.panel1); this.Controls.Add(this.groupBox1); this.Name = "SimpleSettingsDialog"; this.Load += new System.EventHandler(this.SimpleSettingsDialog_Load); this.Controls.SetChildIndex(this.okButton, 0); this.Controls.SetChildIndex(this.cancelButton, 0); this.Controls.SetChildIndex(this.groupBox1, 0); this.Controls.SetChildIndex(this.panel1, 0); this.ResumeLayout(false); } #endregion private void SimpleSettingsDialog_Load(object sender, System.EventArgs e) { SettingsPage page = this.SettingsPages[0]; this.panel1.Controls.Add( page ); this.Text = page.Title; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestSuiteTreeView.resx0000664000175000017500000003023711504175260024102 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA2 DwAAAk1TRnQBSQFMAgEBBQEAAQkBAAEEAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABIAMAAQEBAAEYBgABGOEAA9YDtwOYA4ADtQPWqwADnAGdAYQBlQHIAYABsQFRASwBRgErARgBJAFc AT0BUgGeAYYBlgOcpQABhAGDAYQByQGBAbQB2AFVAbAB3AFhAbYBZgExAVYBLQEWASYBdgE5AWMB3AFk AbcBzAGJAbcBhAGDAYSfAAOcAckBfgGyAdgBUgGvAd4BaAG5AeMBegHCAeIBhAHEAb8BdAGnAc8BeQG0 AeMBegHCAd4BaAG5AcwBiQG3A5yZAAPWAZ0BhAGVAdUBSgGqAdwBYQG2AeMBegHCAekBkAHNAXYBUAFq ATABIgErAXMBTgFnAekBkAHNAeMBegHCAdwBZAG3AZ4BhgGWA9aWAAO3AcYBfAGwAdcBUAGtAd8BawG7 AeYBhwHIAe0BoQHVAZABbQGFATEBJwEuAU8BPAFJAeUBmwHOAeYBhwHIAd8BawG7AcgBhQGzA7eWAAOb AdMBaQGxAdgBUgGvAd8BbwG8AeYBjwHNAe8BqAHYAboBkwGtATMBLQIxAScBLgFaAT8BUQHcAYQBwAHf AW8BvAHWAXgBugOblgADmwHTAWkBsQHXAVABrQHbAZEB0wHfAacB3wHmAbAB4QHzAbgB4QGmAYMBmgEy ASUBLgEvASABKwFWATIBSwHVAWYBsgHWAXYBuQOblgADtwHGAXwBsAHVAUoBqgHXAbEB6AHaAbQB6QHg Aa4B4wHrAaYB2QHvAagB2AGrAXQBmgEyAR8BLAEtARgBJwGRAUABeAHIAYABsQO3lgAD1gGdAYQBlQHS AT8BpQHNAckB8wGzAZQBwQHeAZ4B2gHlAYoBygHnAYsBygHmAYcByAFpATgBWQEsARUBJQFpASgBVgGd AYQBlQPWmQADnAHJAX4BsgFhAR0BTAEvARQBJwGBATkBawHAAVwBoQHHAWMBpwG4AVgBmgE9ARsBMwEr ARABIwFzAUkBZgOcnwABfQF8AX0BQwEqATwBKQEMASABKwEOASIBKwEQASMBKwEQASMBKwEQASMBKgEO ASEBKgEaASQBeAF3AXilAAOWAVoBSgFVATQBIQEuASkBFAEiASkBFAEiASgBGAEiATEBKQEvA3+rAAPW A7QDjwONA6UD0f8A/wAGAAaDJAADygOjBn8DowPKEgADvAM3BgAD1gO3BpsDtwPWBgADNwO8EgAD1gO3 BpsDtwPWHgAD1gN/Bh8DfwPWGwADgANtA3wDcQNzA30DbQOADwADCAMAA1UDnAF+AYEBmgFvAXsBvAFa AWkBxgFaAWkBxgFyAXwBvgF+AYIBmgOcA1UDAAMIDwADnAF5AZgBeQFhAa8BYQE9AZUBPQFTAcABUwFr AbgBawF8AZgBfAOcGAADnAF+AYoBjwFeAYIBigEUASMBJgEUASQBJwFfAYYBjQF+AYwBkAOcFQADYwN9 A1wDYwNqA2wDagNmA4MDYwwAA3sGAAFXAWABkwEwAUQBxQE0AUcByQE4AUwBzAE6AU0BzgE4AUwBzAE3 AUoBygFbAWMBlgYAA3sMAAGDAYQBgwFiAbcBYgEhAbkBIQERAUEBEQEJARsBCQFAAcEBQAE+AcQBPgE1 AcABNQFvAbwBbwGDAYQBgxIAA4MBbwGVAZ4BJAF8AY0BIwGIAZYBJAGMAZkBIwGLAZYBJQGPAZwBJwGK AZgBcQGdAaUDgw8AA4ADfwNgA28DewOEA4cDhAN7A28DhwOADAADEQMAAQgBDAEkATcBSQHDAUMBVQHU AUkBWwHYAUsBXQHaAUkBWwHYAUABUQHKAQoBDgElAwADEQwAA5wBYQG3AWEBHQG4AR0BIAFrASAGAAE2 AW8BNgFhAdIBYQFRAcwBUQE6AcMBOgFvAbwBbwOcDAADnAFvAZMBnQEgAXoBiwEkAY4BmwEhAYIBiwEK AScBKAEJASMBJAEhAYYBjAEoAZ8BqQEkAY4BmwFxAZ0BpQOcCQADygNtA2ADcAOCA5IDnQOhA50DkgOC A3IDcAPKBgAD1gFSAVQBYwYAARIBFwE3AU4BXwHYAVkBaQHkAVwBbQHmAVcBZgHeARUBGQE5BgABUwFV AWUD1gYAA9YBeQGYAXkBEwGzARMBJAGOASQBAQECAQEGAAEHAQsBBwF3AckBdwFuAdcBbgFRAcwBUQE1 AcABNQF8AZgBfAPWBgAD1gF+AYoBjwEiAXIBhQEjAYgBlgEoAZ8BqQEmAZwBoQEJAScBKAEKASgBKQEi AYwBjgEsAbQBugEoAZ8BqQEnAYoBmAF+AYwBkAPWBgADowN+A2YDewOQA6MDtAO8A7QDowOQA3sDiAOj BgADtwFvAXkBvAEXASABXQYAAR0BIgFIAWYBdgHrAWwBewHvASABJQFLBgABHgEnAWIBdQGAAcEDtwYA A7cBXgG0AV4BFQGWARUBBQEPAQUDAAEEAQcBBAYAAT0BWAE9AYQB3wGEAWEB0gFhAT4BxAE+AWsBuAFr A7cGAAO3AWsBkQGaAR8BdwGJASUBkQGeASoBqwGyASwBtgG5AQoCKwELAS4BLQEUAlMBLQG7Ab4BKgGr AbIBJQGRAZ4BbQGZAaIDtwYAA38DdANpA38DlQOrA8ED1wPBA6sDlQN/A4QDfwYAA5sBVgFmAcMBMgFG AcgBGQEgAVAGAAEoAS0BWQEuATMBXQYAAR4BJQFUAUEBVAHTAWABbwHLA5sGAAObAS0BhgEtAQIBCgEC BgABXQGWAV0BOQFNATkDAAMBAXEBtQFxAWgB1AFoAUIBxgFCAVMBwAFTA5sGAAObAVEBhQGVASABegGL ASYBlAGgATQBsQG6ATEByQHKARgBZQFkAQwBMwExAQsBLgEtARIBSgFLASgBoQGoASUBlAGgAVQBlQGh A5sGAAN/A3MDZgN7A5ADowO0A7wDtAOjA5ADewOBA38GAAObAVQBYwHDATABRAHFAT4BUQHOARcBHAFB DAABGwEgAUQBTAFeAdgBPwFSAdEBYAFtAcoDmwYAA5sBFgFBARYEAAECAQABQgF4AUYBjwHeAZQBjQHM AY4BBgEIAQYDAAEfATQBHwFhAdIBYQE+AcQBPgFQAcABUAObBgADmwFRAYUBlQEfAXcBiQFkAakBwQFy Ab0B0gFfAcgB1wE1AtUBFwFhAWABCgIrAQkBJwEoAQwBMAEyAR8BegGFAVMBkgGeA5sGAAOjA3wDXQKB AYgCkgGbApYBmAOdA6EDnQOSA4IDcAODA6MGAAO3AWsBdwG5ASoBPwHDATgBTAHMATwBSAGcAgQBBwYA AgMBBwE6AUYBnwFFAVcB1gE4AUwBzAFyAXwBvgO3BgADtwFbAa8BWwEEATIBBAFFAYYBTQGWAdEBrAGc AdYBrwGVAd0BngFEAW0BRAYAASkBZgEpATEBvwExAWQBtwFkA7cGAAO3AWsBkQGaASIBcgGFAZ0BvQHe AZYBwQHgAXUBwgHYAT8BxQHMAS8BxwHIARkBZwFpAQkBJAElAQgBIAEiARABPAFCAW0BlgGfA7cGAAPK A20DUgKGAZQCnAGuApIBnAOEA4cDhAN7A28DYwNtA8oGAAPWAX0BgAGZASABMwGhARIBGQFLAQEBAgED AwACAgEDAwEDAAMBARYBHQFOASsBPAGoAX4BggGaA9YGAAPWAXkBmAF5AQUBrgEFAYUByAGdAbQB0QHV AZ0B0QG1AYYB0wGTAWQBywFkAQ0BHQENBgABEQFgAREBeQGYAXkD1gYAA9YBfgGKAY8BHwFmAXkBwQHE AeoBnQG/Ad8BbAG1AcsBMQGtAbUBKwGvAbYBKgGrAbIBEwFKAU4BBwEcAR8BCQEhASUBfgGKAY8D1gkA A4ADfQNNAqkBxAKJAZcDbQNsA2oDYwNZA30DgAkAA9ADNQMBBgABEwEUARoBbwF2AbUBSwFWAakBBgEI ARYGAAMBAzUD0AkAA5wBYQG3AWEBBQGuAQUBmQHMAbUBeQHJAYsBUAHGAVUBQgHGAUIBNgGsATYBBQEV AQUGAAM/DAADnAFEAVoBYQEHARoBHwEhAVYBYwElAYcBlgElAZEBngElAZQBoAEkAY8BnAENATMBOAEG ARgBHAEZASEBIwOWDwADYwN9A1ADTQNPA1EDTwNQA30DYwwAA4QGAAIFAQgBDwEYAlYBYwHDAVQBZAHR ASsBPwHDASUBOAGzAREBGwFYAgUBCAYAA4QMAAGDAYQBgwFhAbcBYQEFAa4BBQEPAbIBDwEaAbcBGgEd AbgBHQEaAbcBGgEQAZcBEAEIAQ4BCAYAAykJAAPfAx4BFQEdAR8BBgEUARgBCgElASwBEAE8AUUBEgFD AUwBCwEqATABBgEWARoBFQEdAR8DTBUAA4ADbQN8BnADfANtA4ASAAMgA3cDkQF8AX8BmAFoAXIBtwFN AV0BvQFOAV8BvQFpAXQBuAF9AX8BmAORA3cDIBIAA5wBeQGYAXkBXgG0AV4BPgG4Aj4BuAE+AV4BtAFe AXkBmAF5A4oDQAMAA44MAAO2AzABGAEbARwBFQEdAR8BDwEaAR0BDwEaAR0BFQEdAR8BGAEbARwDNhsA A8oDowZ/A6MDyh4AA9YDtwabA7cD1h4AA9YDtwabA7cD1gYAA6sVAAOCAzsDLAMoAyoDf88AAUIBTQE+ BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAL/BgAB+AEfBgAB8AEPBgAB4AEHBgABwAED BgABgAEBBgABgAEBBgABgAEBBgABgAEBBgABgAEBBgABgAEBBgABwAEDBgAB4AEHBgAB8AEPBgAB+AEf BgAC/wYABv8B/gF/AfgBHwGYARkB+AEfAfgBHwHwAQ8BgAEBAfABDwHwAQ8B4AEHAYABAQHgAQcB4AEH AcABAwHAAQMBwAEDAcABAwGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEB AYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQHAAQMBgAEB AcABAwHAAQMB4AEHAYABAQHgAQEBwAEHAfABDwHAAQMB8AEBAeABDwH4AR8B+AEfAfgBGwH4AR8I/ws= False NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestPropertiesDialog.cs0000664000175000017500000002463511704322234024240 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.Text; using System.IO; using System.Collections; using NUnit.Core; namespace NUnit.UiKit { public partial class TestPropertiesDialog : Form { private TestSuiteTreeNode node; private ITest test; private TestResult result; private int maxY; private int nextY; private int clientWidth; private Image pinnedImage; private Image unpinnedImage; public TestPropertiesDialog(TestSuiteTreeNode node) { InitializeComponent(); this.node = node; } #region Properties [Browsable(false)] public bool Pinned { get { return pinButton.Checked; } set { pinButton.Checked = value; } } #endregion #region Public Methods public void DisplayProperties() { DisplayProperties(this.node); } public void DisplayProperties(TestSuiteTreeNode node) { this.node = node; this.test = node.Test; this.result = node.Result; SetTitleBarText(); testResult.Text = node.StatusText; testResult.Font = new Font(this.Font, FontStyle.Bold); if (node.TestType == "Project" || node.TestType == "Assembly") testName.Text = Path.GetFileName(test.TestName.Name); else testName.Text = test.TestName.Name; testType.Text = node.TestType; fullName.Text = test.TestName.FullName; description.Text = test.Description; StringBuilder sb1 = new StringBuilder(); foreach (string cat in test.Categories) if (sb1.Length > 0) { sb1.Append(", "); sb1.Append(cat); } categories.Text = sb1.ToString(); testCaseCount.Text = test.TestCount.ToString(); switch (test.RunState) { case RunState.Explicit: shouldRun.Text = "Explicit"; break; case RunState.Runnable: shouldRun.Text = "Yes"; break; default: shouldRun.Text = "No"; break; } ignoreReason.Text = test.IgnoreReason; FillPropertyList(); elapsedTime.Text = "Execution Time:"; assertCount.Text = "Assert Count:"; message.Text = ""; stackTrace.Text = ""; if (result != null) { elapsedTime.Text = string.Format("Execution Time: {0}", result.Time); assertCount.Text = string.Format("Assert Count: {0}", result.AssertCount); // message may have a leading blank line // TODO: take care of this in label? if (result.Message != null) { if (result.Message.Length > 64000) message.Text = TrimLeadingBlankLines(result.Message.Substring(0, 64000)); else message.Text = TrimLeadingBlankLines(result.Message); } stackTrace.Text = result.StackTrace; } BeginPanel(); CreateRow(testTypeLabel, testType); CreateRow(fullNameLabel, fullName); CreateRow(descriptionLabel, description); CreateRow(categoriesLabel, categories); CreateRow(testCaseCountLabel, testCaseCount, shouldRunLabel, shouldRun); CreateRow(ignoreReasonLabel, ignoreReason); CreateRow(propertiesLabel, properties); CreateRow(hiddenProperties); groupBox1.ClientSize = new Size( groupBox1.ClientSize.Width, maxY + 12); groupBox2.Location = new Point( groupBox1.Location.X, groupBox1.Bottom + 12); BeginPanel(); CreateRow(elapsedTime, assertCount); CreateRow(messageLabel, message); CreateRow(stackTraceLabel, stackTrace); groupBox2.ClientSize = new Size( groupBox2.ClientSize.Width, this.maxY + 12); this.ClientSize = new Size( this.ClientSize.Width, groupBox2.Bottom + 12); } private void FillPropertyList() { properties.Items.Clear(); foreach (DictionaryEntry entry in test.Properties) { if (hiddenProperties.Checked || !entry.Key.ToString().StartsWith("_")) { if (entry.Value is ICollection) { ICollection items = (ICollection)entry.Value; if (items.Count == 0) continue; StringBuilder sb = new StringBuilder(); foreach (object item in items) { if (sb.Length > 0) sb.Append(","); sb.Append(item.ToString()); } properties.Items.Add(entry.Key.ToString() + "=" + sb.ToString()); } else properties.Items.Add(entry.Key.ToString() + "=" + entry.Value.ToString()); } } } #endregion #region Event Handlers and Overrides private void TestPropertiesDialog_Load(object sender, System.EventArgs e) { pinnedImage = new Bitmap(typeof(TestPropertiesDialog), "Images.pinned.gif"); unpinnedImage = new Bitmap(typeof(TestPropertiesDialog), "Images.unpinned.gif"); pinButton.Image = unpinnedImage; if (!this.DesignMode) DisplayProperties(); node.TreeView.AfterSelect += new TreeViewEventHandler(OnSelectedNodeChanged); } private void pinButton_Click(object sender, System.EventArgs e) { if (pinButton.Checked) pinButton.Image = pinnedImage; else pinButton.Image = unpinnedImage; } private void TestPropertiesDialog_SizeChanged(object sender, EventArgs e) { if (clientWidth != this.ClientSize.Width) { if (this.node != null) this.DisplayProperties(); clientWidth = this.ClientSize.Width; } } private void TestPropertiesDialog_ResizeEnd(object sender, EventArgs e) { this.ClientSize = new Size( this.ClientSize.Width, groupBox2.Bottom + 12); clientWidth = this.ClientSize.Width; } private void OnSelectedNodeChanged(object sender, TreeViewEventArgs e) { if (pinButton.Checked) { DisplayProperties((TestSuiteTreeNode)e.Node); } else this.Close(); } protected override bool ProcessKeyPreview(ref System.Windows.Forms.Message m) { const int ESCAPE = 27; const int WM_CHAR = 258; if (m.Msg == WM_CHAR && m.WParam.ToInt32() == ESCAPE) { this.Close(); return true; } return base.ProcessKeyEventArgs(ref m); } private void hiddenProperties_CheckedChanged(object sender, EventArgs e) { FillPropertyList(); } #endregion #region Helper Methods private void SetTitleBarText() { string name = test.TestName.Name; int index = name.LastIndexOfAny(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); if (index >= 0) name = name.Substring(index + 1); this.Text = string.Format("{0} Properties - {1}", node.TestType, name); } private void BeginPanel() { this.maxY = 20; this.nextY = 24; } private void SizeToFitText(Label label) { string text = label.Text; if (text == "") text = "Ay"; // Include descender to be sure of size Graphics g = Graphics.FromHwnd(label.Handle); SizeF size = g.MeasureString(text, label.Font, label.Parent.ClientSize.Width - label.Left - 8); label.ClientSize = new Size( (int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height)); } private void CreateRow(params Control[] controls) { this.nextY = this.maxY + 4; foreach (Control control in controls) { InsertInRow(control); } } private void InsertInRow(Control control) { Label label = control as Label; if (label != null) SizeToFitText(label); control.Location = new Point(control.Location.X, this.nextY); this.maxY = Math.Max(this.maxY, control.Bottom); } private string TrimLeadingBlankLines(string s) { if (s == null) return s; int start = 0; for (int i = 0; i < s.Length; i++) { switch (s[i]) { case ' ': case '\t': break; case '\r': case '\n': start = i + 1; break; default: goto getout; } } getout: return start == 0 ? s : s.Substring(start); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextDisplay.cs0000664000175000017500000000237511701273022022370 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Util; using NUnit.Core; namespace NUnit.UiKit { /// /// The TextDisplay interface is implemented by object - generally /// controls - that display text. /// public interface TextDisplay : TestObserver { /// /// The output types handled by this display /// TextDisplayContent Content { get; set; } /// /// Clears the display /// void Clear(); /// /// Appends text to the display /// /// The text to append void Write( string text ); /// /// Appends text to the display followed by a newline /// /// The text to append void WriteLine( string text ); void Write( NUnit.Core.TestOutput output ); /// /// Gets the current text - used mainly for testing /// string GetText(); } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ConfigurationEditor.cs0000664000175000017500000002264511544330406024103 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.Util; namespace NUnit.UiKit { /// /// ConfigurationEditor form is designed for adding, deleting /// and renaming configurations from a project. /// public class ConfigurationEditor : NUnitFormBase { #region Instance Variables private NUnitProject project; private int selectedIndex = -1; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.ListBox configListBox; private System.Windows.Forms.Button removeButton; private System.Windows.Forms.Button renameButton; private System.Windows.Forms.Button addButton; private System.Windows.Forms.Button activeButton; private System.Windows.Forms.HelpProvider helpProvider1; private System.Windows.Forms.Button closeButton; #endregion #region Construction and Disposal public ConfigurationEditor( NUnitProject project ) { InitializeComponent(); this.project = project; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(ConfigurationEditor)); this.configListBox = new System.Windows.Forms.ListBox(); this.removeButton = new System.Windows.Forms.Button(); this.renameButton = new System.Windows.Forms.Button(); this.closeButton = new System.Windows.Forms.Button(); this.addButton = new System.Windows.Forms.Button(); this.activeButton = new System.Windows.Forms.Button(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.SuspendLayout(); // // configListBox // this.helpProvider1.SetHelpString(this.configListBox, "Selects the configuration to operate on."); this.configListBox.ItemHeight = 16; this.configListBox.Location = new System.Drawing.Point(8, 8); this.configListBox.Name = "configListBox"; this.helpProvider1.SetShowHelp(this.configListBox, true); this.configListBox.Size = new System.Drawing.Size(168, 212); this.configListBox.TabIndex = 0; this.configListBox.SelectedIndexChanged += new System.EventHandler(this.configListBox_SelectedIndexChanged); // // removeButton // this.helpProvider1.SetHelpString(this.removeButton, "Removes the selected configuration"); this.removeButton.Location = new System.Drawing.Point(192, 8); this.removeButton.Name = "removeButton"; this.helpProvider1.SetShowHelp(this.removeButton, true); this.removeButton.Size = new System.Drawing.Size(96, 32); this.removeButton.TabIndex = 1; this.removeButton.Text = "&Remove"; this.removeButton.Click += new System.EventHandler(this.removeButton_Click); // // renameButton // this.helpProvider1.SetHelpString(this.renameButton, "Allows renaming the selected configuration"); this.renameButton.Location = new System.Drawing.Point(192, 48); this.renameButton.Name = "renameButton"; this.helpProvider1.SetShowHelp(this.renameButton, true); this.renameButton.Size = new System.Drawing.Size(96, 32); this.renameButton.TabIndex = 2; this.renameButton.Text = "Re&name"; this.renameButton.Click += new System.EventHandler(this.renameButton_Click); // // closeButton // this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.helpProvider1.SetHelpString(this.closeButton, "Closes this dialog"); this.closeButton.Location = new System.Drawing.Point(192, 216); this.closeButton.Name = "closeButton"; this.helpProvider1.SetShowHelp(this.closeButton, true); this.closeButton.Size = new System.Drawing.Size(96, 32); this.closeButton.TabIndex = 4; this.closeButton.Text = "Close"; this.closeButton.Click += new System.EventHandler(this.okButton_Click); // // addButton // this.helpProvider1.SetHelpString(this.addButton, "Allows adding a new configuration"); this.addButton.Location = new System.Drawing.Point(192, 88); this.addButton.Name = "addButton"; this.helpProvider1.SetShowHelp(this.addButton, true); this.addButton.Size = new System.Drawing.Size(96, 32); this.addButton.TabIndex = 5; this.addButton.Text = "&Add..."; this.addButton.Click += new System.EventHandler(this.addButton_Click); // // activeButton // this.helpProvider1.SetHelpString(this.activeButton, "Makes the selected configuration active"); this.activeButton.Location = new System.Drawing.Point(192, 128); this.activeButton.Name = "activeButton"; this.helpProvider1.SetShowHelp(this.activeButton, true); this.activeButton.Size = new System.Drawing.Size(96, 32); this.activeButton.TabIndex = 6; this.activeButton.Text = "&Make Active"; this.activeButton.Click += new System.EventHandler(this.activeButton_Click); // // ConfigurationEditor // this.AcceptButton = this.closeButton; this.CancelButton = this.closeButton; this.ClientSize = new System.Drawing.Size(297, 267); this.ControlBox = false; this.Controls.Add(this.activeButton); this.Controls.Add(this.addButton); this.Controls.Add(this.closeButton); this.Controls.Add(this.renameButton); this.Controls.Add(this.removeButton); this.Controls.Add(this.configListBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.HelpButton = true; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigurationEditor"; this.helpProvider1.SetShowHelp(this, false); this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Configuration Editor"; this.Load += new System.EventHandler(this.ConfigurationEditor_Load); this.ResumeLayout(false); } #endregion #region UI Event Handlers private void ConfigurationEditor_Load(object sender, System.EventArgs e) { FillListBox(); if ( configListBox.Items.Count > 0 ) configListBox.SelectedIndex = selectedIndex = 0; } private void removeButton_Click(object sender, System.EventArgs e) { if ( project.Configs.Count == 1 ) { string msg = "Removing the last configuration will make the project unloadable until you add another configuration.\r\rAre you sure you want to remove the configuration?"; if (MessageDisplay.Ask(msg) == DialogResult.No) return; } project.Configs.RemoveAt( selectedIndex ); FillListBox(); } private void renameButton_Click(object sender, System.EventArgs e) { RenameConfiguration( project.Configs[selectedIndex].Name ); } private void addButton_Click(object sender, System.EventArgs e) { using( AddConfigurationDialog dlg = new AddConfigurationDialog( project ) ) { this.Site.Container.Add( dlg ); if ( dlg.ShowDialog() == DialogResult.OK ) FillListBox(); } } private void activeButton_Click(object sender, System.EventArgs e) { project.SetActiveConfig( selectedIndex ); FillListBox(); } private void okButton_Click(object sender, System.EventArgs e) { DialogResult = DialogResult.OK; Close(); } private void configListBox_SelectedIndexChanged(object sender, System.EventArgs e) { selectedIndex = configListBox.SelectedIndex; activeButton.Enabled = selectedIndex >= 0 && project.Configs[selectedIndex].Name != project.ActiveConfigName; renameButton.Enabled = addButton.Enabled = selectedIndex >= 0; removeButton.Enabled = selectedIndex >= 0 && configListBox.Items.Count > 0; } #endregion #region Helper Methods private void RenameConfiguration( string oldName ) { using( RenameConfigurationDialog dlg = new RenameConfigurationDialog( project, oldName ) ) { this.Site.Container.Add( dlg ); if ( dlg.ShowDialog() == DialogResult.OK ) { project.Configs[oldName].Name = dlg.ConfigurationName; FillListBox(); } } } private void FillListBox() { configListBox.Items.Clear(); int count = 0; foreach( ProjectConfig config in project.Configs ) { string name = config.Name; if ( name == project.ActiveConfigName ) name += " (active)"; configListBox.Items.Add( name ); count++; } if ( count > 0 ) { if( selectedIndex >= count ) selectedIndex = count - 1; configListBox.SelectedIndex = selectedIndex; } else selectedIndex = -1; } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/RenameConfigurationDialog.resx0000664000175000017500000002001111504175260025542 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False Private False Private Private False Private Private False (Default) False False 8, 8 RenameConfigurationDialog True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextOutputSettingsPage.cs0000664000175000017500000004470511702661036024613 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NUnit.Core; using NUnit.UiKit; using NUnit.Util; using System.Diagnostics; namespace NUnit.UiKit { public class TextOutputSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.CheckBox showStandardOutput; private System.Windows.Forms.CheckBox showErrorOutput; private System.Windows.Forms.ComboBox tabSelectComboBox; private System.Windows.Forms.Button useDefaultsButton; private System.ComponentModel.IContainer components = null; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Label label5; private TextDisplayTabSettings tabSettings = new TextDisplayTabSettings(); private System.Windows.Forms.CheckBox enabledCheckBox; private System.Windows.Forms.HelpProvider helpProvider1; private Label label6; private ComboBox logLevelComboBox; private Label label3; private ComboBox labelsComboBox; private CheckBox showTraceOutput; private int selectedTabIndex = -1; public TextOutputSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); logLevelComboBox.Items.Clear(); foreach (string name in System.Enum.GetNames(typeof(LoggingThreshold))) logLevelComboBox.Items.Add(name); labelsComboBox.Items.Clear(); foreach (string name in System.Enum.GetNames(typeof(TestLabelLevel))) labelsComboBox.Items.Add(name); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.showStandardOutput = new System.Windows.Forms.CheckBox(); this.showErrorOutput = new System.Windows.Forms.CheckBox(); this.tabSelectComboBox = new System.Windows.Forms.ComboBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.useDefaultsButton = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.enabledCheckBox = new System.Windows.Forms.CheckBox(); this.label5 = new System.Windows.Forms.Label(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.label6 = new System.Windows.Forms.Label(); this.logLevelComboBox = new System.Windows.Forms.ComboBox(); this.label3 = new System.Windows.Forms.Label(); this.labelsComboBox = new System.Windows.Forms.ComboBox(); this.showTraceOutput = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 16); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(62, 13); this.label1.TabIndex = 11; this.label1.Text = "Select Tab:"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(8, 104); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(44, 13); this.label2.TabIndex = 16; this.label2.Text = "Content"; // // showStandardOutput // this.showStandardOutput.AutoSize = true; this.helpProvider1.SetHelpString(this.showStandardOutput, "If checked, standard Console output is displayed on this Tab."); this.showStandardOutput.Location = new System.Drawing.Point(40, 128); this.showStandardOutput.Name = "showStandardOutput"; this.helpProvider1.SetShowHelp(this.showStandardOutput, true); this.showStandardOutput.Size = new System.Drawing.Size(104, 17); this.showStandardOutput.TabIndex = 17; this.showStandardOutput.Text = "Standard Output"; this.showStandardOutput.CheckedChanged += new System.EventHandler(this.showStandardOutput_CheckedChanged); // // showErrorOutput // this.showErrorOutput.AutoSize = true; this.helpProvider1.SetHelpString(this.showErrorOutput, "If checked, error output is displayed on this Tab."); this.showErrorOutput.Location = new System.Drawing.Point(242, 128); this.showErrorOutput.Name = "showErrorOutput"; this.helpProvider1.SetShowHelp(this.showErrorOutput, true); this.showErrorOutput.Size = new System.Drawing.Size(83, 17); this.showErrorOutput.TabIndex = 18; this.showErrorOutput.Text = "Error Output"; this.showErrorOutput.CheckedChanged += new System.EventHandler(this.showErrorOutput_CheckedChanged); // // tabSelectComboBox // this.tabSelectComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tabSelectComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.helpProvider1.SetHelpString(this.tabSelectComboBox, "Allows the user to select an existing Tab, create a new Tab or edit the list of T" + "abs."); this.tabSelectComboBox.Location = new System.Drawing.Point(105, 14); this.tabSelectComboBox.Name = "tabSelectComboBox"; this.helpProvider1.SetShowHelp(this.tabSelectComboBox, true); this.tabSelectComboBox.Size = new System.Drawing.Size(195, 21); this.tabSelectComboBox.TabIndex = 22; this.tabSelectComboBox.SelectedIndexChanged += new System.EventHandler(this.tabSelectComboBox_SelectedIndexChanged); // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Location = new System.Drawing.Point(131, 104); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(325, 8); this.groupBox2.TabIndex = 24; this.groupBox2.TabStop = false; // // useDefaultsButton // this.useDefaultsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.useDefaultsButton.AutoSize = true; this.helpProvider1.SetHelpString(this.useDefaultsButton, "Restores the list of Tabs and their content to the default values."); this.useDefaultsButton.Location = new System.Drawing.Point(329, 12); this.useDefaultsButton.Name = "useDefaultsButton"; this.helpProvider1.SetShowHelp(this.useDefaultsButton, true); this.useDefaultsButton.Size = new System.Drawing.Size(112, 23); this.useDefaultsButton.TabIndex = 25; this.useDefaultsButton.Text = "Restore Defaults"; this.useDefaultsButton.Click += new System.EventHandler(this.button1_Click); // // textBox1 // this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.helpProvider1.SetHelpString(this.textBox1, "The title to be displayed on the selected Tab."); this.textBox1.Location = new System.Drawing.Point(105, 64); this.textBox1.Name = "textBox1"; this.helpProvider1.SetShowHelp(this.textBox1, true); this.textBox1.Size = new System.Drawing.Size(215, 20); this.textBox1.TabIndex = 30; this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); // // enabledCheckBox // this.enabledCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.enabledCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.enabledCheckBox, "If checked, the Tab is enabled. If not, it is hidden."); this.enabledCheckBox.Location = new System.Drawing.Point(350, 64); this.enabledCheckBox.Name = "enabledCheckBox"; this.helpProvider1.SetShowHelp(this.enabledCheckBox, true); this.enabledCheckBox.Size = new System.Drawing.Size(65, 17); this.enabledCheckBox.TabIndex = 31; this.enabledCheckBox.Text = "Enabled"; this.enabledCheckBox.CheckedChanged += new System.EventHandler(this.displayTab_CheckedChanged); // // label5 // this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(8, 64); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(30, 13); this.label5.TabIndex = 32; this.label5.Text = "Title:"; // // label6 // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(239, 161); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(63, 13); this.label6.TabIndex = 35; this.label6.Text = "Log Output:"; // // logLevelComboBox // this.logLevelComboBox.FormattingEnabled = true; this.helpProvider1.SetHelpString(this.logLevelComboBox, "Selects the logging threshold for display on this Tab."); this.logLevelComboBox.Location = new System.Drawing.Point(329, 161); this.logLevelComboBox.Name = "logLevelComboBox"; this.helpProvider1.SetShowHelp(this.logLevelComboBox, true); this.logLevelComboBox.Size = new System.Drawing.Size(77, 21); this.logLevelComboBox.TabIndex = 36; this.logLevelComboBox.SelectedIndexChanged += new System.EventHandler(this.logLevel_SelectedIndexChanged); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(37, 200); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(92, 13); this.label3.TabIndex = 37; this.label3.Text = "Test Case Labels:"; // // labelsComboBox // this.labelsComboBox.FormattingEnabled = true; this.helpProvider1.SetHelpString(this.labelsComboBox, "Selects whether test case labels are displayed. Option \'On\' displays labels only " + "when there is other output from the test."); this.labelsComboBox.Items.AddRange(new object[] { "Off", "On", "All"}); this.labelsComboBox.Location = new System.Drawing.Point(176, 200); this.labelsComboBox.Name = "labelsComboBox"; this.helpProvider1.SetShowHelp(this.labelsComboBox, true); this.labelsComboBox.Size = new System.Drawing.Size(77, 21); this.labelsComboBox.TabIndex = 38; this.labelsComboBox.SelectedIndexChanged += new System.EventHandler(this.labelsComboBox_SelectedIndexChanged); // // showTraceOutput // this.showTraceOutput.AutoSize = true; this.helpProvider1.SetHelpString(this.showTraceOutput, "If checked, trace output is displayed on this Tab."); this.showTraceOutput.Location = new System.Drawing.Point(40, 161); this.showTraceOutput.Name = "showTraceOutput"; this.helpProvider1.SetShowHelp(this.showTraceOutput, true); this.showTraceOutput.Size = new System.Drawing.Size(89, 17); this.showTraceOutput.TabIndex = 39; this.showTraceOutput.Text = "Trace Output"; this.showTraceOutput.UseVisualStyleBackColor = true; this.showTraceOutput.CheckedChanged += new System.EventHandler(this.showTraceOutput_CheckedChanged); // // TextOutputSettingsPage // this.Controls.Add(this.showTraceOutput); this.Controls.Add(this.labelsComboBox); this.Controls.Add(this.label3); this.Controls.Add(this.logLevelComboBox); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.enabledCheckBox); this.Controls.Add(this.textBox1); this.Controls.Add(this.useDefaultsButton); this.Controls.Add(this.groupBox2); this.Controls.Add(this.tabSelectComboBox); this.Controls.Add(this.showErrorOutput); this.Controls.Add(this.showStandardOutput); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Name = "TextOutputSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { tabSettings.LoadSettings(settings); InitializeTabSelectComboBox(); } private void InitializeTabSelectComboBox() { FillTabSelectComboBox(); if ( this.tabSelectComboBox.Items.Count > 0 ) { this.tabSelectComboBox.SelectedIndex = this.selectedTabIndex = 0; this.InitDisplay(tabSettings.Tabs[0]); } } private void FillTabSelectComboBox() { tabSelectComboBox.Items.Clear(); foreach( TextDisplayTabSettings.TabInfo tabInfo in this.tabSettings.Tabs ) this.tabSelectComboBox.Items.Add( tabInfo.Title ); tabSelectComboBox.Items.Add( "" ); tabSelectComboBox.Items.Add( "" ); } public override void ApplySettings() { tabSettings.ApplySettings(); } private void button1_Click(object sender, System.EventArgs e) { tabSettings.LoadDefaults(); InitializeTabSelectComboBox(); } private void InitDisplay(TextDisplayTabSettings.TabInfo tabInfo) { textBox1.Text = tabInfo.Title; TextDisplayContent content = tabInfo.Content; showStandardOutput.Checked = content.Out; showErrorOutput.Checked = content.Error; showTraceOutput.Checked = content.Trace; logLevelComboBox.SelectedIndex = (int)content.LogLevel; labelsComboBox.SelectedIndex = (int)content.Labels; enabledCheckBox.Checked = tabInfo.Enabled; } private void tabSelectComboBox_SelectedIndexChanged(object sender, System.EventArgs e) { int index = tabSelectComboBox.SelectedIndex; if ( index < tabSettings.Tabs.Count ) { selectedTabIndex = index; InitDisplay(tabSettings.Tabs[index]); } else // Not a tab, but a "menu" item { tabSelectComboBox.SelectedIndex = selectedTabIndex; if ( index == tabSettings.Tabs.Count ) addNewTabPage(); else editTabPages(); } } private void addNewTabPage() { using( AddTabPageDialog dlg = new AddTabPageDialog(tabSettings) ) { this.ParentForm.Site.Container.Add( dlg ); if ( dlg.ShowDialog(this) == DialogResult.OK ) { FillTabSelectComboBox(); this.tabSelectComboBox.SelectedIndex = tabSettings.Tabs.Count - 1; } } } private void editTabPages() { using( EditTabPagesDialog dlg = new EditTabPagesDialog( tabSettings) ) { this.ParentForm.Site.Container.Add( dlg ); dlg.ShowDialog(this); FillTabSelectComboBox(); if ( tabSelectComboBox.Items.Count > 0 ) tabSelectComboBox.SelectedIndex = selectedTabIndex = 0; } } private void showStandardOutput_CheckedChanged(object sender, System.EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Content.Out = showStandardOutput.Checked; } private void showErrorOutput_CheckedChanged(object sender, System.EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Content.Error = showErrorOutput.Checked; } private void textBox1_TextChanged(object sender, System.EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Title = textBox1.Text; } private void displayTab_CheckedChanged(object sender, System.EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Enabled = enabledCheckBox.Checked; } private void labelsComboBox_SelectedIndexChanged(object sender, EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Content.Labels = (TestLabelLevel)labelsComboBox.SelectedIndex; } private void logLevel_SelectedIndexChanged(object sender, EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Content.LogLevel = (LoggingThreshold)logLevelComboBox.SelectedIndex; } private void showTraceOutput_CheckedChanged(object sender, EventArgs e) { tabSettings.Tabs[tabSelectComboBox.SelectedIndex].Content.Trace = showTraceOutput.Checked; } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TreeBasedSettingsDialog.resx0000664000175000017500000003573611660212302025176 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Family False Private Family Private Private False Private Private 17, 17 AAEAAAD/////AQAAAAAAAAAMAgAAAFpTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0xLjAuNTAw MC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZT eXN0ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMA AABgCgAAAk1TRnQBSQFMAgEBAwEAAQQBAAEEAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQC AAEoAwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB 3AHAAQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IB AAM5AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8B MwMAAWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYC AAFmAZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMC AAHMAWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQAB ZgEAATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8B AAEzAWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQAB MwGZAWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQAB MwLMAQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQAB MwEAAWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMB mQEAAWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQAB ZgGZAWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYB zAH/AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMB mQEAAZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgAB mQFmATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwB AAKZAf8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB /wEzAQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQAB mQEAAcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYC AAHMAWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYB AAHMApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8C AAHMAf8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQAB mQEAAcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMB AAHMAmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB /wGZAcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC /wEzAQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC /wFmAQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gB AAHwAfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wEAD90B1g/dAdYP 3QHWEAAP/wHdAf8B+AptAfAC/wHdAf8B+AttAQcB/wHdEAAB/wH3DOwBBwHdAewBDwFDCRIB7AG8Af8B 3QH/AUMBFAnrAQ8B7AH/Ad0QAAEHARMLQwEOAW0B3QEAARABbQHvAbwBmQG8AZkBCAG8AZkBvAFDAewB /wHdAf8BQwGSCf8BFAHsAf8B3REAAZILBwESAW0B3QEAAZIBEwHrAcMBXgHDAeUCoAFeAfYBEwHsAfQB 3QH/AUMBkgL/BPQB9QL/ARQB7AH/Ad0RAAE3AqAB5QH0AV4BwwGgAeUBGwFeAcMCbQHdAQABkgETAQMB 5QHDAV4CoAHlAcMBXgEaAusB3QH/AUMBkgH/AbwEhgHPAv8BFAHsAf8B3REAAZkC5QGgAeUBoAHlAqAB 5QGgAeUBSgFtAd0BAAKSAUoBAwHlAaAB5QKgAeUBoAHlAUoBbQHdAf8BQwGSAf8B9AS1AfAC/wEUAewB /wHdEQABeQugAUoBbQHdAQABkgEHAW0BFQigAVgBUQGuAf8BQwGSAf8B8gW1Av8BFAHsAf8B3REAAVgC oAHlAaAB5QKgAeUBoAHlAaABSgFtAd0BAAGSAQcB7AHqAe8BMAEcAXMBUQEcATABHAFRASkBCgH/AUMB kgH/AfEErgG1Av8BFAHsAf8B3REAAQcC5QGgAV4BwwHlAqABXgHDAeUBAwFtAd0BAAGSAgcB7QcPAQAB DgEQAREB/wFDAZIB/wH1A/IC9ALxARUB7AH/Ad0RAAE3AqABXgH2AV4CoAHlAcMBXgHDAesBbQHdAQAB kgMHB+8BEQHsAfMB3QH/AUMBkgH/AbwDBAG1Ae8CDgEAAewB/wHdEQABIgIVASIBFAEiAhUBIgEUASIB FAHsAfAB3QEAAZIDBwHvARQFQwGSAfIB/wHdAf8BQwGSAf8B9APuAfIB7wEOAewBEAHsAf8B3RAAAewB DwEpAVEBcwEDAewBEQETBOwBvAH/Ad0B7AHqAxIB6gbsAfIC/wHdAf8BQwGSBv8B7wEOARMB7AG8Af8B 3RAAAf8B+AJRAXMBMAHtAesB7wb/Ad0B/wH4BG0B8wj/Ad0B/wFDAW0GkgFtAQ4B6gHwAv8B3RAAAv8B +ARDAQcH/wHdD/8B3QH/ARIIQwETAfQD/wHdEAAP/wHdD/8B3Q//Ad0QAAFCAU0BPgcAAT4DAAEoAwAB QAMAARADAAEBAQABAQUAAYAXAAP/lwAL False True Private 8, 8 True Private Private 8, 8 True False True Private False (Default) False False 8, 8 TreeBasedSettingsDialog True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestPropertiesDialog.resx0000664000175000017500000002541411672151200024605 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True True True True True True True True True True True True True True True True True True True True True True True True True True True True True NUnit-2.6.0.12051/src/GuiComponents/UiKit/SettingsDialogBase.resx0000664000175000017500000002234111504175260024206 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private False Private Private False (Default) False False 8, 8 SettingsDialogBase True 80 True Private AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiComponents/UiKit/ProgressBar.cs0000664000175000017500000002434511504175260022356 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; namespace NUnit.UiKit { /// /// ColorProgressBar provides a custom progress bar with the /// ability to control the color of the bar and to render itself /// in either solid or segmented style. The bar can be updated /// on the fly and has code to avoid repainting the entire bar /// when that occurs. /// public class ColorProgressBar : System.Windows.Forms.Control { #region Instance Variables /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// The current progress value /// private int val = 0; /// /// The minimum value allowed /// private int min = 0; /// /// The maximum value allowed /// private int max = 100; /// /// Amount to advance for each step /// private int step = 1; /// /// Last segment displayed when displaying asynchronously rather /// than through OnPaint calls. /// private int lastSegmentCount=0; /// /// The brush to use in painting the progress bar /// private Brush foreBrush = null; /// /// The brush to use in painting the background of the bar /// private Brush backBrush = null; /// /// Indicates whether to draw the bar in segments or not /// private bool segmented = false; #endregion #region Constructors & Disposer public ColorProgressBar() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); SetStyle(ControlStyles.ResizeRedraw, true); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } this.ReleaseBrushes(); } base.Dispose( disposing ); } #endregion #region Properties [Category("Behavior")] public int Minimum { get { return this.min; } set { if (value <= Maximum) { if (this.min != value) { this.min = value; this.Invalidate(); } } else { throw new ArgumentOutOfRangeException("Minimum", value ,"Minimum must be <= Maximum."); } } } [Category("Behavior")] public int Maximum { get { return this.max; } set { if (value >= Minimum) { if (this.max != value) { this.max = value; this.Invalidate(); } } else { throw new ArgumentOutOfRangeException("Maximum", value ,"Maximum must be >= Minimum."); } } } [Category("Behavior")] public int Step { get { return this.step; } set { if (value <= Maximum && value >= Minimum) { this.step = value; } else { throw new ArgumentOutOfRangeException("Step", value ,"Must fall between Minimum and Maximum inclusive."); } } } [Browsable(false)] private float PercentValue { get { if (0 != Maximum - Minimum) // NRG 05/28/03: Prevent divide by zero return((float)this.val / ((float)Maximum - (float)Minimum)); else return(0); } } [Category("Behavior")] public int Value { get { return this.val; } set { if(value == this.val) return; else if(value <= Maximum && value >= Minimum) { this.val = value; this.Invalidate(); } else { throw new ArgumentOutOfRangeException("Value", value ,"Must fall between Minimum and Maximum inclusive."); } } } [Category("Appearance")] public bool Segmented { get { return segmented; } set { segmented = value; } } #endregion #region Methods protected override void OnCreateControl() { } public void PerformStep() { int newValue = Value + Step; if( newValue > Maximum ) newValue = Maximum; Value = newValue; } protected override void OnBackColorChanged(System.EventArgs e) { base.OnBackColorChanged(e); this.Refresh(); } protected override void OnForeColorChanged(System.EventArgs e) { base.OnForeColorChanged(e); this.Refresh(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); this.lastSegmentCount=0; this.ReleaseBrushes(); PaintBar(e.Graphics); ControlPaint.DrawBorder3D( e.Graphics ,this.ClientRectangle ,Border3DStyle.SunkenOuter); //e.Graphics.Flush(); } private void ReleaseBrushes() { if(foreBrush != null) { foreBrush.Dispose(); backBrush.Dispose(); foreBrush=null; backBrush=null; } } private void AcquireBrushes() { if(foreBrush == null) { foreBrush = new SolidBrush(this.ForeColor); backBrush = new SolidBrush(this.BackColor); } } private void PaintBar(Graphics g) { Rectangle theBar = Rectangle.Inflate(ClientRectangle, -2, -2); int maxRight = theBar.Right-1; this.AcquireBrushes(); if ( segmented ) { int segmentWidth = (int)((float)ClientRectangle.Height * 0.66f); int maxSegmentCount = ( theBar.Width + segmentWidth ) / segmentWidth; //int maxRight = Bar.Right; int newSegmentCount = (int)System.Math.Ceiling(PercentValue*maxSegmentCount); if(newSegmentCount > lastSegmentCount) { theBar.X += lastSegmentCount*segmentWidth; while (lastSegmentCount < newSegmentCount ) { theBar.Width = System.Math.Min( maxRight - theBar.X, segmentWidth - 2 ); g.FillRectangle( foreBrush, theBar ); theBar.X += segmentWidth; lastSegmentCount++; } } else if(newSegmentCount < lastSegmentCount) { theBar.X += newSegmentCount * segmentWidth; theBar.Width = maxRight - theBar.X; g.FillRectangle(backBrush, theBar); lastSegmentCount = newSegmentCount; } } else { //g.FillRectangle( backBrush, theBar ); theBar.Width = theBar.Width * val / max; g.FillRectangle( foreBrush, theBar ); } if(Value == Minimum || Value == Maximum) this.ReleaseBrushes(); } #endregion #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { // // ProgressBar // this.CausesValidation = false; this.Enabled = false; this.ForeColor = System.Drawing.SystemColors.Highlight; this.Name = "ProgressBar"; this.Size = new System.Drawing.Size(432, 24); } #endregion } public class TestProgressBar : ColorProgressBar, TestObserver { private readonly static Color SuccessColor = Color.Lime; private readonly static Color FailureColor = Color.Red; private readonly static Color IgnoredColor = Color.Yellow; public TestProgressBar() { Initialize( 100 ); } private void Initialize( int testCount ) { Value = 0; Maximum = testCount; ForeColor = SuccessColor; } private void OnRunStarting( object Sender, TestEventArgs e ) { Initialize( e.TestCount ); } private void OnTestLoaded(object sender, TestEventArgs e) { Initialize(e.TestCount); } private void OnTestReloaded(object sender, TestEventArgs e) { if (Services.UserSettings.GetSetting("Options.TestLoader.ClearResultsOnReload", false)) Initialize(e.TestCount); else Value = Maximum = e.TestCount; } private void OnTestUnloaded(object sender, TestEventArgs e) { Initialize( 100 ); } private void OnTestFinished( object sender, TestEventArgs e ) { PerformStep(); switch (e.Result.ResultState) { case ResultState.NotRunnable: case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: ForeColor = FailureColor; break; case ResultState.Ignored: if (ForeColor == SuccessColor) ForeColor = IgnoredColor; break; default: break; } } private void OnSuiteFinished( object sender, TestEventArgs e ) { TestResult result = e.Result; if ( result.FailureSite == FailureSite.TearDown ) switch (result.ResultState) { case ResultState.Error: case ResultState.Failure: case ResultState.Cancelled: ForeColor = FailureColor; break; } } private void OnTestException(object sender, TestEventArgs e) { ForeColor = FailureColor; } #region TestObserver Members public void Subscribe(ITestEvents events) { events.TestLoaded += new TestEventHandler( OnTestLoaded ); events.TestReloaded += new TestEventHandler(OnTestReloaded); events.TestUnloaded += new TestEventHandler( OnTestUnloaded ); events.RunStarting += new TestEventHandler( OnRunStarting ); events.TestFinished += new TestEventHandler( OnTestFinished ); events.SuiteFinished += new TestEventHandler( OnSuiteFinished ); events.TestException += new TestEventHandler(OnTestException); } #endregion } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TipWindow.cs0000664000175000017500000002151011543055572022046 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.InteropServices; namespace CP.Windows.Forms { public class TipWindow : Form { /// /// Direction in which to expand /// public enum ExpansionStyle { Horizontal, Vertical, Both } #region Instance Variables /// /// Text we are displaying /// private string tipText; /// /// The control for which we are showing expanded text /// private Control control; /// /// Rectangle representing bounds to overlay. For a listbox, this /// is a single item rectangle. For other controls, it is usually /// the entire client area. /// private Rectangle itemBounds; /// /// True if we may overlay control or item /// private bool overlay = true; /// /// Directions we are allowed to expand /// private ExpansionStyle expansion = ExpansionStyle.Horizontal; /// /// Time before automatically closing /// private int autoCloseDelay = 0; /// /// Timer used for auto-close /// private System.Windows.Forms.Timer autoCloseTimer; /// /// Time to wait for after mouse leaves /// the window or the label before closing. /// private int mouseLeaveDelay = 300; /// /// Timer used for mouse leave delay /// private System.Windows.Forms.Timer mouseLeaveTimer; /// /// Rectangle used to display text /// private Rectangle textRect; /// /// Indicates whether any clicks should be passed to the underlying control /// private bool wantClicks = false; #endregion #region Construction and Initialization public TipWindow( Control control ) { InitializeComponent(); InitControl( control ); // Note: This causes an error if called on a listbox // with no item as yet selected, therefore, it is handled // differently in the constructor for a listbox. this.tipText = control.Text; } public TipWindow( ListBox listbox, int index ) { InitializeComponent(); InitControl( listbox ); this.itemBounds = listbox.GetItemRectangle( index ); this.tipText = listbox.Items[ index ].ToString(); } private void InitControl( Control control ) { this.control = control; this.Owner = control.FindForm(); this.itemBounds = control.ClientRectangle; this.ControlBox = false; this.MaximizeBox = false; this.MinimizeBox = false; this.BackColor = Color.LightYellow; this.FormBorderStyle = FormBorderStyle.None; this.StartPosition = FormStartPosition.Manual; this.Font = control.Font; } private void InitializeComponent() { // // TipWindow // this.BackColor = System.Drawing.Color.LightYellow; this.ClientSize = new System.Drawing.Size(292, 268); this.ControlBox = false; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "TipWindow"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; } protected override void OnLoad(System.EventArgs e) { // At this point, further changes to the properties // of the label will have no effect on the tip. Point origin = control.Parent.PointToScreen( control.Location ); origin.Offset( itemBounds.Left, itemBounds.Top ); if ( !overlay ) origin.Offset( 0, itemBounds.Height ); this.Location = origin; Graphics g = Graphics.FromHwnd( Handle ); Screen screen = Screen.FromControl( control ); SizeF layoutArea = new SizeF( screen.WorkingArea.Width - 40, screen.WorkingArea.Height - 40 ); if ( expansion == ExpansionStyle.Vertical ) layoutArea.Width = itemBounds.Width; else if ( expansion == ExpansionStyle.Horizontal ) layoutArea.Height = itemBounds.Height; Size sizeNeeded = Size.Ceiling( g.MeasureString( tipText, Font, layoutArea ) ); this.ClientSize = sizeNeeded; this.Size = sizeNeeded + new Size( 2, 2 ); this.textRect = new Rectangle( 1, 1, sizeNeeded.Width, sizeNeeded.Height ); // Catch mouse leaving the control control.MouseLeave += new EventHandler( control_MouseLeave ); // Catch the form that holds the control closing control.FindForm().Closed += new EventHandler( control_FormClosed ); if ( this.Right > screen.WorkingArea.Right ) { this.Left = Math.Max( screen.WorkingArea.Right - this.Width - 20, screen.WorkingArea.Left + 20); } if ( this.Bottom > screen.WorkingArea.Bottom - 20 ) { if ( overlay ) this.Top = Math.Max( screen.WorkingArea.Bottom - this.Height - 20, screen.WorkingArea.Top + 20 ); if ( this.Bottom > screen.WorkingArea.Bottom - 20 ) this.Height = screen.WorkingArea.Bottom - 20 - this.Top; } if ( autoCloseDelay > 0 ) { autoCloseTimer = new System.Windows.Forms.Timer(); autoCloseTimer.Interval = autoCloseDelay; autoCloseTimer.Tick += new EventHandler( OnAutoClose ); autoCloseTimer.Start(); } } #endregion #region Properties public bool Overlay { get { return overlay; } set { overlay = value; } } public ExpansionStyle Expansion { get { return expansion; } set { expansion = value; } } public int AutoCloseDelay { get { return autoCloseDelay; } set { autoCloseDelay = value; } } public int MouseLeaveDelay { get { return mouseLeaveDelay; } set { mouseLeaveDelay = value; } } public string TipText { get { return tipText; } set { tipText = value; } } public Rectangle ItemBounds { get { return itemBounds; } set { itemBounds = value; } } public bool WantClicks { get { return wantClicks; } set { wantClicks = value; } } #endregion #region Event Handlers protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint( e ); Graphics g = e.Graphics; Rectangle outlineRect = this.ClientRectangle; outlineRect.Inflate( -1, -1 ); g.DrawRectangle( Pens.Black, outlineRect ); g.DrawString( tipText, Font, Brushes.Black, textRect ); } private void OnAutoClose( object sender, System.EventArgs e ) { this.Close(); } protected override void OnMouseEnter(System.EventArgs e) { if ( mouseLeaveTimer != null ) { mouseLeaveTimer.Stop(); mouseLeaveTimer.Dispose(); System.Diagnostics.Debug.WriteLine( "Entered TipWindow - stopped mouseLeaveTimer" ); } } protected override void OnMouseLeave(System.EventArgs e) { if ( mouseLeaveDelay > 0 ) { mouseLeaveTimer = new System.Windows.Forms.Timer(); mouseLeaveTimer.Interval = mouseLeaveDelay; mouseLeaveTimer.Tick += new EventHandler( OnAutoClose ); mouseLeaveTimer.Start(); System.Diagnostics.Debug.WriteLine( "Left TipWindow - started mouseLeaveTimer" ); } } /// /// The form our label is on closed, so we should. /// private void control_FormClosed( object sender, System.EventArgs e ) { this.Close(); } /// /// The mouse left the label. We ignore if we are /// overlaying the label but otherwise start a /// delay for closing the window /// private void control_MouseLeave( object sender, System.EventArgs e ) { if ( mouseLeaveDelay > 0 && !overlay ) { mouseLeaveTimer = new System.Windows.Forms.Timer(); mouseLeaveTimer.Interval = mouseLeaveDelay; mouseLeaveTimer.Tick += new EventHandler( OnAutoClose ); mouseLeaveTimer.Start(); System.Diagnostics.Debug.WriteLine( "Left Control - started mouseLeaveTimer" ); } } #endregion [DllImport("user32.dll")] static extern uint SendMessage( IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam ); protected override void WndProc(ref Message m) { uint WM_LBUTTONDOWN = 0x201; uint WM_RBUTTONDOWN = 0x204; uint WM_MBUTTONDOWN = 0x207; if ( m.Msg == WM_LBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MBUTTONDOWN ) { if ( m.Msg != WM_LBUTTONDOWN ) this.Close(); SendMessage( control.Handle, m.Msg, m.WParam, m.LParam ); } else { base.WndProc (ref m); } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/AddTabPageDialog.resx0000664000175000017500000002101111504175260023520 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False Private False Private Private False Private Private False Private Private False (Default) False False AddTabPageDialog 8, 8 True 80 True Private NUnit-2.6.0.12051/src/GuiComponents/UiKit/TextOutputSettingsPage.resx0000664000175000017500000001411011702661036025152 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 17, 17 NUnit-2.6.0.12051/src/GuiComponents/UiKit/ConfigurationEditor.resx0000664000175000017500000003006211504175260024450 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False Private False Private Private False Private Private False Private Private False Private Private False Private Private Private 17, 17 Private False (Default) False False 8, 8 ConfigurationEditor True 80 True Private AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestTree.resx0000664000175000017500000005326011504175260022236 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True False True Private Private 8, 8 False True True Private Private 8, 8 False True Private 8, 8 True Private False True Private 8, 8 True Private False Private Private Private False True Private 8, 8 True False Private Private False Private Private False True True Private Private 8, 8 False True Private 8, 8 True Private False True Private 8, 8 True Private False Private Private False Private Private Private 8, 8 True False True Private Private False Private False Private Private Private 8, 8 True False True Private Private False Private TestTree False False True True 80 (Default) False Private 8, 8 NUnit-2.6.0.12051/src/GuiComponents/UiKit/ExpandingLabel.resx0000664000175000017500000001213611504175260023351 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False ExpandingLabel NUnit-2.6.0.12051/src/GuiComponents/UiKit/TabbedSettingsDialog.cs0000664000175000017500000000654511504175260024151 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace NUnit.UiKit { public class TabbedSettingsDialog : NUnit.UiKit.SettingsDialogBase { protected System.Windows.Forms.TabControl tabControl1; private System.ComponentModel.IContainer components = null; public static void Display( Form owner, params SettingsPage[] pages ) { using( TabbedSettingsDialog dialog = new TabbedSettingsDialog() ) { owner.Site.Container.Add( dialog ); dialog.Font = owner.Font; dialog.SettingsPages.AddRange( pages ); dialog.ShowDialog(); } } public TabbedSettingsDialog() { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.tabControl1 = new System.Windows.Forms.TabControl(); this.SuspendLayout(); // // cancelButton // this.cancelButton.Location = new System.Drawing.Point(394, 392); this.cancelButton.Name = "cancelButton"; // // okButton // this.okButton.Location = new System.Drawing.Point(306, 392); this.okButton.Name = "okButton"; // // tabControl1 // this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tabControl1.ItemSize = new System.Drawing.Size(46, 18); this.tabControl1.Location = new System.Drawing.Point(10, 8); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; this.tabControl1.Size = new System.Drawing.Size(456, 376); this.tabControl1.TabIndex = 2; // // TabbedSettingsDialog // this.ClientSize = new System.Drawing.Size(474, 426); this.Controls.Add(this.tabControl1); this.Name = "TabbedSettingsDialog"; this.Load += new System.EventHandler(this.TabbedSettingsDialog_Load); this.Controls.SetChildIndex(this.okButton, 0); this.Controls.SetChildIndex(this.cancelButton, 0); this.Controls.SetChildIndex(this.tabControl1, 0); this.ResumeLayout(false); } #endregion private void TabbedSettingsDialog_Load(object sender, System.EventArgs e) { foreach( SettingsPage page in SettingsPages ) { TabPage tabPage = new TabPage(page.Title); tabPage.Controls.Add( page ); page.Location = new Point(0, 16); this.tabControl1.TabPages.Add( tabPage ); } } } } NUnit-2.6.0.12051/src/GuiComponents/UiKit/TestSuiteTreeView.cs0000664000175000017500000011454311703145774023541 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Drawing; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; using System.ComponentModel; using System.Reflection; using NUnit.Core; using NUnit.Core.Filters; using NUnit.Util; namespace NUnit.UiKit { public delegate void SelectedTestChangedHandler( ITest test ); public delegate void CheckedTestChangedHandler( ITest[] tests ); /// /// TestSuiteTreeView is a tree view control /// specialized for displaying the tests /// in an assembly. Clients should always /// use TestNode rather than TreeNode when /// dealing with this class to be sure of /// calling the proper methods. /// public class TestSuiteTreeView : TreeView { static Logger log = InternalTrace.GetLogger(typeof(TestSuiteTreeView)); #region DisplayStyle Enumeraton /// /// Indicates how a tree should be displayed /// public enum DisplayStyle { Auto, // Select based on space available Expand, // Expand fully Collapse, // Collpase fully HideTests // Expand all but the fixtures, leaving // leaf nodes hidden } #endregion #region TreeStructureChangedException private class TreeStructureChangedException : Exception { public TreeStructureChangedException(string message) :base( message ) { } } #endregion #region Instance Variables /// /// Hashtable provides direct access to TestNodes /// private Hashtable treeMap = new Hashtable(); /// /// The TestNode on which a right click was done /// private TestSuiteTreeNode contextNode; /// /// Whether the browser supports running tests, /// or just loading and examining them /// private bool runCommandSupported = true; /// /// Whether or not we track progress of tests visibly in the tree /// private bool displayProgress = true; /// /// The properties dialog if displayed /// private TestPropertiesDialog propertiesDialog; /// /// Source of events that the tree responds to and /// target for the run command. /// private ITestLoader loader; public System.Windows.Forms.ImageList treeImages; private System.ComponentModel.IContainer components; /// /// True if the UI should allow a run command to be selected /// private bool runCommandEnabled = false; private ITest[] runningTests; private TestFilter categoryFilter = TestFilter.Empty; private bool suppressEvents = false; private bool fixtureLoaded = false; private bool showInconclusiveResults = false; #endregion #region Construction and Initialization public TestSuiteTreeView() { InitializeComponent(); this.ContextMenu = new System.Windows.Forms.ContextMenu(); this.ContextMenu.Popup += new System.EventHandler( ContextMenu_Popup ); LoadAlternateImages(); Services.UserSettings.Changed += new SettingsEventHandler(UserSettings_Changed); } private void UserSettings_Changed(object sender, SettingsEventArgs args) { if (args.SettingName == "Gui.TestTree.AlternateImageSet") { LoadAlternateImages(); Invalidate(); } } private void LoadAlternateImages() { string imageSet = Services.UserSettings.GetSetting("Gui.TestTree.AlternateImageSet") as string; if (imageSet != null) { string[] imageNames = { "Skipped", "Failure", "Success", "Ignored", "Inconclusive" }; for (int index = 0; index < imageNames.Length; index++) LoadAlternateImage(index, imageNames[index], imageSet); } } private void LoadAlternateImage(int index, string name, string imageSet) { string imageDir = PathUtils.Combine(Assembly.GetExecutingAssembly(), "Images", "Tree", imageSet); string[] extensions = { ".png", ".jpg" }; foreach (string ext in extensions) { string filePath = Path.Combine(imageDir, name + ext); if (File.Exists(filePath)) { treeImages.Images[index] = Image.FromFile(filePath); break; } } } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TestSuiteTreeView)); this.treeImages = new System.Windows.Forms.ImageList(this.components); this.SuspendLayout(); // // treeImages // this.treeImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("treeImages.ImageStream"))); this.treeImages.TransparentColor = System.Drawing.Color.White; this.treeImages.Images.SetKeyName(0, "Skipped.png"); this.treeImages.Images.SetKeyName(1, "Failure.png"); this.treeImages.Images.SetKeyName(2, "Success.png"); this.treeImages.Images.SetKeyName(3, "Ignored.png"); this.treeImages.Images.SetKeyName(4, "Inconclusive.png"); // // TestSuiteTreeView // this.ImageIndex = 0; this.ImageList = this.treeImages; this.SelectedImageIndex = 0; this.DoubleClick += new System.EventHandler(this.TestSuiteTreeView_DoubleClick); this.DragDrop += new System.Windows.Forms.DragEventHandler(this.TestSuiteTreeView_DragDrop); this.DragEnter += new System.Windows.Forms.DragEventHandler(this.TestSuiteTreeView_DragEnter); this.ResumeLayout(false); } public void Initialize( ITestLoader loader, ITestEvents events ) { this.loader = loader; events.TestLoaded += new TestEventHandler( OnTestLoaded ); events.TestReloaded += new TestEventHandler( OnTestChanged ); events.TestUnloaded += new TestEventHandler( OnTestUnloaded ); events.RunStarting += new TestEventHandler( OnRunStarting ); events.RunFinished += new TestEventHandler( OnRunFinished ); events.TestFinished += new TestEventHandler( OnTestResult ); events.SuiteFinished+= new TestEventHandler( OnTestResult ); } #endregion #region Properties and Events /// /// Property determining whether the run command /// is supported from the tree context menu and /// by double-clicking test cases. /// [Category( "Behavior" ), DefaultValue( true )] [Description("Indicates whether the tree context menu should include a run command")] public bool RunCommandSupported { get { return runCommandSupported; } set { runCommandSupported = value; } } /// /// Property determining whether tree should reDraw nodes /// as tests are complete in order to show progress. /// [Category( "Behavior" ), DefaultValue( true )] [Description("Indicates whether results should be displayed in the tree as each test completes")] public bool DisplayTestProgress { get { return displayProgress; } set { displayProgress = value; } } [Category( "Appearance" ), DefaultValue( false )] [Description("Indicates whether checkboxes are displayed beside test nodes")] public new bool CheckBoxes { get { return base.CheckBoxes; } set { if ( base.CheckBoxes != value ) { VisualState visualState = !value && this.TopNode != null ? new VisualState(this) : null; base.CheckBoxes = value; if ( CheckBoxesChanged != null ) CheckBoxesChanged(this, new EventArgs()); if (visualState != null) { try { suppressEvents = true; visualState.ShowCheckBoxes = this.CheckBoxes; //RestoreVisualState( visualState ); visualState.Restore(this); } finally { suppressEvents = false; } } } } } public bool ShowInconclusiveResults { get { return showInconclusiveResults; } } /// /// The currently selected test. /// [Browsable( false )] public ITest SelectedTest { get { TestSuiteTreeNode node = (TestSuiteTreeNode)SelectedNode; return node == null ? null : node.Test; } } [Browsable( false )] public ITest[] CheckedTests { get { CheckedTestFinder finder = new CheckedTestFinder( this ); return finder.GetCheckedTests( CheckedTestFinder.SelectionFlags.All ); } } [Browsable( false )] public ITest[] SelectedTests { get { ITest[] result = null; if ( this.CheckBoxes ) { CheckedTestFinder finder = new CheckedTestFinder( this ); result = finder.GetCheckedTests( CheckedTestFinder.SelectionFlags.Top | CheckedTestFinder.SelectionFlags.Explicit ); } if ( result == null || result.Length == 0 ) if ( this.SelectedTest != null ) result = new ITest[] { this.SelectedTest }; return result; } } [Browsable( false )] public ITest[] FailedTests { get { FailedTestsFilterVisitor visitor = new FailedTestsFilterVisitor(); Accept(visitor); return visitor.Tests; } } /// /// The currently selected test result or null /// [Browsable( false )] public TestResult SelectedTestResult { get { TestSuiteTreeNode node = (TestSuiteTreeNode)SelectedNode; return node == null ? null : node.Result; } } [Browsable(false)] public TestFilter CategoryFilter { get { return categoryFilter; } set { categoryFilter = value; TestFilterVisitor visitor = new TestFilterVisitor( categoryFilter ); this.Accept( visitor ); } } public event SelectedTestChangedHandler SelectedTestChanged; public event CheckedTestChangedHandler CheckedTestChanged; public event EventHandler CheckBoxesChanged; public TestSuiteTreeNode this[string uniqueName] { get { return treeMap[uniqueName] as TestSuiteTreeNode; } } /// /// Test node corresponding to a test /// private TestSuiteTreeNode this[ITest test] { get { return FindNode( test ); } } /// /// Test node corresponding to a TestResultInfo /// private TestSuiteTreeNode this[TestResult result] { get { return FindNode( result.Test ); } } #endregion #region Handlers for events related to loading and running tests private void OnTestLoaded( object sender, TestEventArgs e ) { CheckPropertiesDialog(); TestNode test = e.Test as TestNode; if ( test != null ) Load( test ); runCommandEnabled = true; } private void OnTestChanged( object sender, TestEventArgs e ) { TestNode test = e.Test as TestNode; if ( test != null ) Invoke( new LoadHandler( Reload ), new object[]{ test } ); } private void OnTestUnloaded( object sender, TestEventArgs e) { ClosePropertiesDialog(); if ( Services.UserSettings.GetSetting( "Gui.TestTree.SaveVisualState", true ) && loader != null) try { new VisualState(this).Save(VisualState.GetVisualStateFileName(loader.TestFileName)); } catch(Exception ex) { Debug.WriteLine( "Unable to save visual state." ); Debug.WriteLine( ex ); } Clear(); contextNode = null; runCommandEnabled = false; } private void OnRunStarting( object sender, TestEventArgs e ) { CheckPropertiesDialog(); #if ACCUMULATE_RESULTS if ( runningTests != null ) foreach( ITest test in runningTests ) this[test].ClearResults(); #else ClearAllResults(); #endif runCommandEnabled = false; } private void OnRunFinished( object sender, TestEventArgs e ) { if ( runningTests != null ) foreach( ITest test in runningTests ) this[test].Expand(); if ( propertiesDialog != null ) propertiesDialog.Invoke( new PropertiesDisplayHandler( propertiesDialog.DisplayProperties ) ); runningTests = null; runCommandEnabled = true; } private void OnTestResult( object sender, TestEventArgs e ) { SetTestResult(e.Result); } #endregion #region Context Menu /// /// Handles right mouse button down by /// remembering the proper context item /// and implements multiple select with the left button. /// /// MouseEventArgs structure with information about the mouse position and button state protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { if (e.Button == MouseButtons.Right ) { CheckPropertiesDialog(); TreeNode theNode = GetNodeAt( e.X, e.Y ); contextNode = theNode as TestSuiteTreeNode; } // else if (e.Button == MouseButtons.Left ) // { // if ( Control.ModifierKeys == Keys.Control ) // { // TestSuiteTreeNode theNode = GetNodeAt( e.X, e.Y ) as TestSuiteTreeNode; // if ( theNode != null ) // theNode.IsSelected = true; // } // else // { // ClearSelected(); // } // } base.OnMouseDown( e ); } /// /// Build treeview context menu dynamically on popup /// private void ContextMenu_Popup(object sender, System.EventArgs e) { this.ContextMenu.MenuItems.Clear(); TestSuiteTreeNode targetNode = contextNode != null ? contextNode : (TestSuiteTreeNode)SelectedNode; if ( targetNode == null ) return; if ( RunCommandSupported ) { // TODO: handle in Starting event if ( loader.Running ) runCommandEnabled = false; MenuItem runMenuItem = new MenuItem( "&Run", new EventHandler( runMenuItem_Click ) ); runMenuItem.DefaultItem = runMenuItem.Enabled = runCommandEnabled && targetNode.Included && (targetNode.Test.RunState == RunState.Runnable || targetNode.Test.RunState == RunState.Explicit); this.ContextMenu.MenuItems.Add( runMenuItem ); this.ContextMenu.MenuItems.Add("-"); } TestSuiteTreeNode theoryNode = targetNode.GetTheoryNode(); if (theoryNode != null) { MenuItem failedAssumptionsMenuItem = new MenuItem("Show Failed Assumptions", new EventHandler(failedAssumptionsMenuItem_Click)); failedAssumptionsMenuItem.Checked = theoryNode.ShowFailedAssumptions; this.ContextMenu.MenuItems.Add(failedAssumptionsMenuItem); this.ContextMenu.MenuItems.Add("-"); } MenuItem showCheckBoxesMenuItem = new MenuItem("Show CheckBoxes", new EventHandler(showCheckBoxesMenuItem_Click)); showCheckBoxesMenuItem.Checked = this.CheckBoxes; this.ContextMenu.MenuItems.Add(showCheckBoxesMenuItem); this.ContextMenu.MenuItems.Add("-"); MenuItem loadFixtureMenuItem = new MenuItem("Load Fixture", new EventHandler(loadFixtureMenuItem_Click)); loadFixtureMenuItem.Enabled = targetNode.Test.IsSuite && targetNode != Nodes[0]; this.ContextMenu.MenuItems.Add( loadFixtureMenuItem ); MenuItem clearFixtureMenuItem = new MenuItem( "Clear Fixture", new EventHandler( clearFixtureMenuItem_Click ) ); clearFixtureMenuItem.Enabled = fixtureLoaded; this.ContextMenu.MenuItems.Add( clearFixtureMenuItem ); this.ContextMenu.MenuItems.Add( "-" ); MenuItem propertiesMenuItem = new MenuItem( "&Properties", new EventHandler( propertiesMenuItem_Click ) ); this.ContextMenu.MenuItems.Add( propertiesMenuItem ); } private void showCheckBoxesMenuItem_Click( object sender, System.EventArgs e) { this.CheckBoxes = !this.CheckBoxes; } /// /// When Expand context menu item is clicked, expand the node /// private void expandMenuItem_Click(object sender, System.EventArgs e) { TestSuiteTreeNode targetNode = contextNode != null ? contextNode : (TestSuiteTreeNode)SelectedNode; if ( targetNode != null ) targetNode.Expand(); } /// /// When Collapse context menu item is clicked, collapse the node /// private void collapseMenuItem_Click(object sender, System.EventArgs e) { TestSuiteTreeNode targetNode = contextNode != null ? contextNode : (TestSuiteTreeNode)SelectedNode; if ( targetNode != null ) targetNode.Collapse(); } private void expandAllMenuItem_Click(object sender, System.EventArgs e) { this.BeginUpdate(); this.ExpandAll(); this.EndUpdate(); } private void collapseAllMenuItem_Click(object sender, System.EventArgs e) { this.BeginUpdate(); this.CollapseAll(); this.EndUpdate(); // Compensate for a bug in the underlying control if ( this.Nodes.Count > 0 ) this.SelectedNode = this.Nodes[0]; } private void failedAssumptionsMenuItem_Click(object sender, System.EventArgs e) { TestSuiteTreeNode targetNode = contextNode != null ? contextNode : (TestSuiteTreeNode)SelectedNode; TestSuiteTreeNode theoryNode = targetNode != null ? targetNode.GetTheoryNode() : null; if (theoryNode != null) { MenuItem item = (MenuItem)sender; BeginUpdate(); item.Checked = !item.Checked; theoryNode.ShowFailedAssumptions = item.Checked; EndUpdate(); } } /// /// When Run context menu item is clicked, run the test that /// was selected when the right click was done. /// private void runMenuItem_Click(object sender, System.EventArgs e) { //TODO: some sort of lock on these booleans? if ( runCommandEnabled ) { runCommandEnabled = false; if ( contextNode != null ) RunTests( new ITest[] { contextNode.Test }, false ); else RunSelectedTests(); } } private void runAllMenuItem_Click(object sender, System.EventArgs e) { if ( runCommandEnabled ) { runCommandEnabled = false; RunAllTests(); } } private void runFailedMenuItem_Click(object sender, System.EventArgs e) { if ( runCommandEnabled ) { runCommandEnabled = false; RunFailedTests(); } } private void loadFixtureMenuItem_Click( object sender, System.EventArgs e) { if ( contextNode != null ) { loader.LoadTest( contextNode.Test.TestName.FullName ); fixtureLoaded = true; } } private void clearFixtureMenuItem_Click( object sender, System.EventArgs e) { loader.LoadTest(); fixtureLoaded = false; } private void propertiesMenuItem_Click( object sender, System.EventArgs e) { TestSuiteTreeNode targetNode = contextNode != null ? contextNode : (TestSuiteTreeNode)SelectedNode; if ( targetNode != null ) ShowPropertiesDialog( targetNode ); } #endregion #region Drag and drop /// /// Helper method to determine if an IDataObject is valid /// for dropping on the tree view. It must be a the drop /// of a single file with a valid assembly file type. /// /// IDataObject to be tested /// True if dropping is allowed private bool IsValidFileDrop( IDataObject data ) { if ( !data.GetDataPresent( DataFormats.FileDrop ) ) return false; string [] fileNames = data.GetData( DataFormats.FileDrop ) as string []; if ( fileNames == null || fileNames.Length == 0 ) return false; // We can't open more than one project at a time // so handle length of 1 separately. if ( fileNames.Length == 1 ) { string fileName = fileNames[0]; bool isProject = NUnitProject.IsNUnitProjectFile( fileName ); if ( Services.UserSettings.GetSetting( "Options.TestLoader.VisualStudioSupport", false ) ) isProject |= Services.ProjectService.CanConvertFrom( fileName ); return isProject || PathUtils.IsAssemblyFileType( fileName ); } // Multiple assemblies are allowed - we // assume they are all in the same directory // since they are being dragged together. foreach( string fileName in fileNames ) { if ( !PathUtils.IsAssemblyFileType( fileName ) ) return false; } return true; } private void TestSuiteTreeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) { if ( IsValidFileDrop( e.Data ) ) { string[] fileNames = (string[])e.Data.GetData( DataFormats.FileDrop ); if ( fileNames.Length == 1 ) loader.LoadProject( fileNames[0] ); else loader.LoadProject( fileNames ); if (loader.IsProjectLoaded && loader.TestProject.IsLoadable) loader.LoadTest(); } } private void TestSuiteTreeView_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) { if ( IsValidFileDrop( e.Data ) ) e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.None; } #endregion #region UI Event Handlers private void TestSuiteTreeView_DoubleClick(object sender, System.EventArgs e) { TestSuiteTreeNode node = SelectedNode as TestSuiteTreeNode; if ( runCommandSupported && runCommandEnabled && node.Nodes.Count == 0 && node.Included ) { runCommandEnabled = false; // TODO: Since this is a terminal node, don't use a category filter RunTests( new ITest[] { SelectedTest }, true ); } } protected override void OnAfterSelect(System.Windows.Forms.TreeViewEventArgs e) { if ( !suppressEvents ) { if ( SelectedTestChanged != null ) SelectedTestChanged( SelectedTest ); base.OnAfterSelect( e ); } } protected override void OnAfterCheck(TreeViewEventArgs e) { if ( !suppressEvents ) { if (CheckedTestChanged != null) CheckedTestChanged(CheckedTests); base.OnAfterCheck (e); } } #endregion #region Public methods to manipulate the tree /// /// Clear all the results in the tree. /// public void ClearAllResults() { foreach ( TestSuiteTreeNode rootNode in Nodes ) rootNode.ClearResults(); } /// /// Load the tree with a test hierarchy /// /// Test to be loaded public void Load( TestNode test ) { using( new CP.Windows.Forms.WaitCursor() ) { Clear(); BeginUpdate(); try { AddTreeNodes( Nodes, test, false ); SetInitialExpansion(); } finally { EndUpdate(); contextNode = null; this.Select(); } if ( Services.UserSettings.GetSetting( "Gui.TestTree.SaveVisualState", true ) && loader != null) RestoreVisualState(); } } /// /// Load the tree from a test result /// /// public void Load( TestResult result ) { using ( new CP.Windows.Forms.WaitCursor( ) ) { Clear(); BeginUpdate(); try { AddTreeNodes( Nodes, result, false ); SetInitialExpansion(); } finally { EndUpdate(); } } } /// /// Reload the tree with a changed test hierarchy /// while maintaining as much gui state as possible. /// /// Test suite to be loaded public void Reload( TestNode test ) { TestResult result = ((TestSuiteTreeNode)Nodes[0]).Result; VisualState visualState = new VisualState(this); Load(test); visualState.Restore(this); if (result != null && !Services.UserSettings.GetSetting("Options.TestLoader.ClearResultsOnReload", false)) RestoreResults(result); } /// /// Clear all the info in the tree. /// public void Clear() { treeMap.Clear(); Nodes.Clear(); } protected override void OnAfterCollapse(TreeViewEventArgs e) { if ( !suppressEvents ) base.OnAfterCollapse (e); } protected override void OnAfterExpand(TreeViewEventArgs e) { if ( !suppressEvents ) base.OnAfterExpand (e); } public void Accept(TestSuiteTreeNodeVisitor visitor) { foreach(TestSuiteTreeNode node in Nodes) { node.Accept(visitor); } } public void ClearCheckedNodes() { Accept(new ClearCheckedNodesVisitor()); } public void CheckFailedNodes() { Accept(new CheckFailedNodesVisitor()); } /// /// Add the result of a test to the tree /// /// The result of the test public void SetTestResult(TestResult result) { TestSuiteTreeNode node = this[result]; if (node == null) { Debug.WriteLine("Test not found in tree: " + result.Test.TestName.UniqueName); } else { node.Result = result; if (result.Test.TestType == "Theory") node.RepopulateTheoryNode(); if (DisplayTestProgress && node.IsVisible) { Invalidate(node.Bounds); Update(); } } } public void HideTests() { this.BeginUpdate(); foreach( TestSuiteTreeNode node in Nodes ) HideTestsUnderNode( node ); this.EndUpdate(); } public void ShowPropertiesDialog( ITest test ) { ShowPropertiesDialog( this[ test ] ); } private void ShowPropertiesDialog( TestSuiteTreeNode node ) { if ( propertiesDialog == null ) { Form owner = this.FindForm(); propertiesDialog = new TestPropertiesDialog( node ); propertiesDialog.Owner = owner; propertiesDialog.Font = owner.Font; propertiesDialog.StartPosition = FormStartPosition.Manual; propertiesDialog.Left = Math.Max(0, owner.Left + ( owner.Width - propertiesDialog.Width ) / 2); propertiesDialog.Top = Math.Max(0, owner.Top + ( owner.Height - propertiesDialog.Height ) / 2); propertiesDialog.Show(); propertiesDialog.Closed += new EventHandler( OnPropertiesDialogClosed ); } else { propertiesDialog.DisplayProperties( node ); } } private void ClosePropertiesDialog() { if ( propertiesDialog != null ) propertiesDialog.Close(); } private void CheckPropertiesDialog() { if ( propertiesDialog != null && !propertiesDialog.Pinned ) propertiesDialog.Close(); } private void OnPropertiesDialogClosed( object sender, System.EventArgs e ) { propertiesDialog = null; } #endregion #region Running Tests public void RunAllTests() { RunAllTests(true); } public void RunAllTests(bool ignoreCategories) { if (Nodes.Count > 0) { runCommandEnabled = false; RunTests(new ITest[] { ((TestSuiteTreeNode)Nodes[0]).Test }, ignoreCategories); } } public void RunSelectedTests() { runCommandEnabled = false; RunTests( SelectedTests, false ); } public void RunFailedTests() { runCommandEnabled = false; RunTests( FailedTests, true ); } private void RunTests( ITest[] tests, bool ignoreCategories ) { if (tests != null && tests.Length > 0) { runningTests = tests; ITestFilter filter = ignoreCategories ? MakeNameFilter(tests) : MakeFilter(tests); loader.RunTests(filter); } } private TestFilter MakeFilter( ITest[] tests ) { TestFilter nameFilter = MakeNameFilter( tests ); if ( nameFilter == TestFilter.Empty ) return CategoryFilter; if ( tests.Length == 1 ) { TestSuiteTreeNode rootNode = (TestSuiteTreeNode)Nodes[0]; if ( tests[0] == rootNode.Test ) return CategoryFilter; } if ( CategoryFilter.IsEmpty ) return nameFilter; return new AndFilter( nameFilter, CategoryFilter ); } private TestFilter MakeNameFilter( ITest[] tests ) { if ( tests == null || tests.Length == 0 ) return TestFilter.Empty; NameFilter nameFilter = new NameFilter(); foreach( ITest test in tests ) nameFilter.Add( test.TestName ); return nameFilter; } #endregion #region Helper Methods /// /// Add nodes to the tree constructed from a test /// /// The TreeNodeCollection to which the new node should be added /// The test for which a node is to be built /// If true, highlight the text for this node in the tree /// A newly constructed TestNode, possibly with descendant nodes private TestSuiteTreeNode AddTreeNodes( IList nodes, TestNode rootTest, bool highlight ) { TestSuiteTreeNode node = new TestSuiteTreeNode( rootTest ); // if ( highlight ) node.ForeColor = Color.Blue; AddToMap( node ); nodes.Add( node ); if ( rootTest.IsSuite ) { foreach( TestNode test in rootTest.Tests ) AddTreeNodes( node.Nodes, test, highlight ); } return node; } private TestSuiteTreeNode AddTreeNodes( IList nodes, TestResult rootResult, bool highlight ) { TestSuiteTreeNode node = new TestSuiteTreeNode( rootResult ); AddToMap( node ); nodes.Add( node ); if ( rootResult.HasResults ) { foreach( TestResult result in rootResult.Results ) AddTreeNodes( node.Nodes, result, highlight ); } node.UpdateImageIndex(); return node; } private void AddToMap( TestSuiteTreeNode node ) { string key = node.Test.TestName.UniqueName; if ( treeMap.ContainsKey( key ) ) log.Error( "Duplicate entry: " + key ); // UserMessage.Display( string.Format( // "The test {0} is duplicated\r\rResults will not be displayed correctly in the tree.", node.Test.FullName ), "Duplicate Test" ); else { log.Debug( "Added to map: " + node.Test.TestName.UniqueName ); treeMap.Add( key, node ); } } private void RemoveFromMap( TestSuiteTreeNode node ) { foreach( TestSuiteTreeNode child in node.Nodes ) RemoveFromMap( child ); treeMap.Remove( node.Test.TestName.UniqueName ); } /// /// Remove a node from the tree itself and the hashtable /// /// Node to remove private void RemoveNode( TestSuiteTreeNode node ) { if ( contextNode == node ) contextNode = null; RemoveFromMap( node ); node.Remove(); } /// /// Delegate for use in invoking the tree loader /// from the watcher thread. /// private delegate void LoadHandler( TestNode test ); private delegate void PropertiesDisplayHandler(); /// /// Helper collapses all fixtures under a node /// /// Node under which to collapse fixtures private void HideTestsUnderNode( TestSuiteTreeNode node ) { if (node.Test.IsSuite) { if (node.Test.TestType == "TestFixture") node.Collapse(); else { node.Expand(); foreach (TestSuiteTreeNode child in node.Nodes) HideTestsUnderNode(child); } } } /// /// Helper used to figure out the display style /// to use when the setting is Auto /// /// DisplayStyle to be used private DisplayStyle GetDisplayStyle() { DisplayStyle initialDisplay = (TestSuiteTreeView.DisplayStyle) Services.UserSettings.GetSetting( "Gui.TestTree.InitialTreeDisplay", DisplayStyle.Auto ); if ( initialDisplay != DisplayStyle.Auto ) return initialDisplay; if ( VisibleCount >= this.GetNodeCount( true ) ) return DisplayStyle.Expand; return DisplayStyle.HideTests; } public void SetInitialExpansion() { CollapseAll(); switch ( GetDisplayStyle() ) { case DisplayStyle.Expand: ExpandAll(); break; case DisplayStyle.HideTests: HideTests(); break; case DisplayStyle.Collapse: default: break; } SelectedNode = Nodes[0]; SelectedNode.EnsureVisible(); } private TestSuiteTreeNode FindNode( ITest test ) { TestSuiteTreeNode node = treeMap[test.TestName.UniqueName] as TestSuiteTreeNode; if (node == null) node = FindNodeByName(test.TestName.FullName); return node; } private TestSuiteTreeNode FindNodeByName( string fullName ) { foreach( string uname in treeMap.Keys ) { int rbrack = uname.IndexOf(']'); string name = rbrack >=0 ? uname.Substring(rbrack+1) : uname; if ( name == fullName ) return treeMap[uname] as TestSuiteTreeNode; } return null; } private void RestoreVisualState() { if (loader != null) { string fileName = VisualState.GetVisualStateFileName(loader.TestFileName); if (File.Exists(fileName)) { VisualState.LoadFrom(fileName).Restore(this); } } } private void RestoreResults(TestResult result) { if (result.HasResults) foreach (TestResult childResult in result.Results) RestoreResults(childResult); SetTestResult(result); } #endregion } #region Helper Classes #region ClearCheckedNodesVisitor internal class ClearCheckedNodesVisitor : TestSuiteTreeNodeVisitor { public override void Visit(TestSuiteTreeNode node) { node.Checked = false; } } #endregion #region CheckFailedNodesVisitor internal class CheckFailedNodesVisitor : TestSuiteTreeNodeVisitor { public override void Visit(TestSuiteTreeNode node) { if (!node.Test.IsSuite && node.HasResult && (node.Result.ResultState == ResultState.Failure || node.Result.ResultState == ResultState.Error) ) { node.Checked = true; node.EnsureVisible(); } else node.Checked = false; } } #endregion #region FailedTestsFilterVisitor internal class FailedTestsFilterVisitor : TestSuiteTreeNodeVisitor { List tests = new List(); public ITest[] Tests { get { return tests.ToArray(); } } public override void Visit(TestSuiteTreeNode node) { if (!node.Test.IsSuite && node.HasResult && (node.Result.ResultState == ResultState.Failure || node.Result.ResultState == ResultState.Error) ) { tests.Add(node.Test); } } } #endregion #region TestFilterVisitor public class TestFilterVisitor : TestSuiteTreeNodeVisitor { private ITestFilter filter; public TestFilterVisitor( ITestFilter filter ) { this.filter = filter; } public override void Visit( TestSuiteTreeNode node ) { node.Included = filter.Pass( node.Test ); } } #endregion #region CheckedTestFinder internal class CheckedTestFinder { [Flags] public enum SelectionFlags { Top= 1, Sub = 2, Explicit = 4, All = Top + Sub } private List checkedTests = new List(); private struct CheckedTestInfo { public ITest Test; public bool TopLevel; public CheckedTestInfo( ITest test, bool topLevel ) { this.Test = test; this.TopLevel = topLevel; } } public ITest[] GetCheckedTests( SelectionFlags flags ) { int count = 0; foreach( CheckedTestInfo info in checkedTests ) if ( isSelected( info, flags ) ) count++; ITest[] result = new ITest[count]; int index = 0; foreach( CheckedTestInfo info in checkedTests ) if ( isSelected( info, flags ) ) result[index++] = info.Test; return result; } private bool isSelected( CheckedTestInfo info, SelectionFlags flags ) { if ( info.TopLevel && (flags & SelectionFlags.Top) != 0 ) return true; else if ( !info.TopLevel && (flags & SelectionFlags.Sub) != 0 ) return true; else if ( info.Test.RunState == RunState.Explicit && (flags & SelectionFlags.Explicit) != 0 ) return true; else return false; } public CheckedTestFinder( TestSuiteTreeView treeView ) { FindCheckedNodes( treeView.Nodes, true ); } private void FindCheckedNodes( TestSuiteTreeNode node, bool topLevel ) { if ( node.Checked ) { checkedTests.Add( new CheckedTestInfo( node.Test, topLevel ) ); topLevel = false; } FindCheckedNodes( node.Nodes, topLevel ); } private void FindCheckedNodes( TreeNodeCollection nodes, bool topLevel ) { foreach( TestSuiteTreeNode node in nodes ) FindCheckedNodes( node, topLevel ); } } #endregion #endregion } NUnit-2.6.0.12051/src/GuiComponents/UiKit/ProgressBar.resx0000664000175000017500000000330511504175260022723 0ustar jtaylorjtaylor text/microsoft-resx 1.0.0.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NUnit-2.6.0.12051/src/GuiComponents/UiKit/ExpandingLabel.cs0000664000175000017500000001243311660670272023003 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace CP.Windows.Forms { /// /// A special type of label which can display a tooltip-like /// window to show the full extent of any text which doesn't /// fit. The window may be placed directly over the label /// or immediately beneath it and will expand to fit in /// a horizontal, vertical or both directions as needed. /// public class ExpandingLabel : System.Windows.Forms.Label { #region Instance Variables /// /// Our window for displaying expanded text /// private TipWindow tipWindow; /// /// Direction of expansion /// private TipWindow.ExpansionStyle expansion = TipWindow.ExpansionStyle.Horizontal; /// /// True if tipWindow may overlay the label /// private bool overlay = true; /// /// Time in milliseconds that the tip window /// will remain displayed. /// private int autoCloseDelay = 0; /// /// Time in milliseconds that the window stays /// open after the mouse leaves the control. /// private int mouseLeaveDelay = 300; /// /// If true, a context menu with Copy is displayed which /// allows copying contents to the clipboard. /// private bool copySupported = false; #endregion #region Properties [Browsable( false )] public bool Expanded { get { return tipWindow != null && tipWindow.Visible; } } [Category ( "Behavior" ), DefaultValue( TipWindow.ExpansionStyle.Horizontal )] public TipWindow.ExpansionStyle Expansion { get { return expansion; } set { expansion = value; } } [Category( "Behavior" ), DefaultValue( true )] [Description("Indicates whether the tip window should overlay the label")] public bool Overlay { get { return overlay; } set { overlay = value; } } /// /// Time in milliseconds that the tip window /// will remain displayed. /// [Category( "Behavior" ), DefaultValue( 0 )] [Description("Time in milliseconds that the tip is displayed. Zero indicates no automatic timeout.")] public int AutoCloseDelay { get { return autoCloseDelay; } set { autoCloseDelay = value; } } /// /// Time in milliseconds that the window stays /// open after the mouse leaves the control. /// Reentering the control resets this. /// [Category( "Behavior" ), DefaultValue( 300 )] [Description("Time in milliseconds that the tip is displayed after the mouse levaes the control")] public int MouseLeaveDelay { get { return mouseLeaveDelay; } set { mouseLeaveDelay = value; } } [Category( "Behavior"), DefaultValue( false )] [Description("If true, displays a context menu with Copy")] public bool CopySupported { get { return copySupported; } set { copySupported = value; if ( copySupported ) base.ContextMenu = null; } } /// /// Override Text property to set up copy menu if /// the value is non-empty. /// public override string Text { get { return base.Text; } set { base.Text = value; if ( copySupported ) { if ( value == null || value == string.Empty ) { if ( this.ContextMenu != null ) { this.ContextMenu.Dispose(); this.ContextMenu = null; } } else { this.ContextMenu = new System.Windows.Forms.ContextMenu(); MenuItem copyMenuItem = new MenuItem( "Copy", new EventHandler( CopyToClipboard ) ); this.ContextMenu.MenuItems.Add( copyMenuItem ); } } } } #endregion #region Public Methods public void Expand() { if ( !Expanded ) { tipWindow = new TipWindow( this ); tipWindow.Closed += new EventHandler( tipWindow_Closed ); tipWindow.Expansion = this.Expansion; tipWindow.Overlay = this.Overlay; tipWindow.AutoCloseDelay = this.AutoCloseDelay; tipWindow.MouseLeaveDelay = this.MouseLeaveDelay; tipWindow.WantClicks = this.CopySupported; tipWindow.Show(); } } public void Unexpand() { if ( Expanded ) { tipWindow.Close(); } } #endregion #region Event Handlers private void tipWindow_Closed( object sender, EventArgs e ) { tipWindow = null; } protected override void OnMouseHover(System.EventArgs e) { Graphics g = Graphics.FromHwnd( Handle ); SizeF sizeNeeded = g.MeasureString( Text, Font ); bool expansionNeeded = Width < (int)sizeNeeded.Width || Height < (int)sizeNeeded.Height; if ( expansionNeeded ) Expand(); } /// /// Copy contents to clipboard /// private void CopyToClipboard( object sender, EventArgs e ) { Clipboard.SetDataObject( this.Text ); } #endregion } } NUnit-2.6.0.12051/src/GuiException/0000775000175000017500000000000011742560362016357 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/0000775000175000017500000000000011742560362017521 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/TestDefaultTextManager.cs0000664000175000017500000000541211525533664024442 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.Collections.Generic; using NUnit.Framework; namespace NUnit.UiException.Tests { [TestFixture] public class TestDefaultTextManager { private DefaultTextManager _textBlocks; [SetUp] public void SetUp() { _textBlocks = new DefaultTextManager(); } [Test] public void Test_Default() { Assert.That(_textBlocks.Text, Is.EqualTo("")); Assert.That(_textBlocks.LineCount, Is.EqualTo(0)); Assert.That(_textBlocks.MaxLength, Is.EqualTo(0)); return; } [Test] public void Test_CodeBlockCollection() { List lst; Assert.That(_textBlocks.LineCount, Is.EqualTo(0)); _textBlocks.Text = "01\r\n02\r\n03\r\n"; Assert.That(_textBlocks.Text, Is.EqualTo("01\r\n02\r\n03\r\n")); Assert.That(_textBlocks.LineCount, Is.EqualTo(3)); Assert.That(_textBlocks.GetTextAt(0), Is.EqualTo("01")); Assert.That(_textBlocks.GetTextAt(1), Is.EqualTo("02")); Assert.That(_textBlocks.GetTextAt(2), Is.EqualTo("03")); _textBlocks.Text = "01"; Assert.That(_textBlocks.LineCount, Is.EqualTo(1)); Assert.That(_textBlocks.GetTextAt(0), Is.EqualTo("01")); _textBlocks.Text = "01\r\n02"; Assert.That(_textBlocks.LineCount, Is.EqualTo(2)); Assert.That(_textBlocks.GetTextAt(0), Is.EqualTo("01")); Assert.That(_textBlocks.GetTextAt(1), Is.EqualTo("02")); lst = new List(); foreach (string line in _textBlocks) lst.Add(line); Assert.That(lst.Count, Is.EqualTo(2)); Assert.That(lst[0], Is.EqualTo(_textBlocks.GetTextAt(0))); Assert.That(lst[1], Is.EqualTo(_textBlocks.GetTextAt(1))); _textBlocks.Text = null; Assert.That(_textBlocks.Text, Is.EqualTo("")); return; } [Test] public void Test_MaxLength() { _textBlocks.Text = null; Assert.That(_textBlocks.MaxLength, Is.EqualTo(0)); _textBlocks.Text = "a\r\nabc\r\nab"; Assert.That(_textBlocks.MaxLength, Is.EqualTo(3)); _textBlocks.Text = "a\r\nab\r\nabc"; Assert.That(_textBlocks.MaxLength, Is.EqualTo(3)); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/CodeFormatters/0000775000175000017500000000000011742560362022442 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/CodeFormatters/TestGeneralCodeFormatter.cs0000664000175000017500000002402011543625326027664 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using NUnit.Framework; using NUnit.UiException.CodeFormatters; using NUnit.UiException.Tests.data; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestGeneralCodeFormatter { private GeneralCodeFormatter _formatter; [SetUp] public void SetUp() { _formatter = new GeneralCodeFormatter(); return; } [Test] public void Test_Default() { Assert.That(_formatter.DefaultFormatter, Is.Not.Null); Assert.That(_formatter.Formatters, Is.Not.Null); Assert.That(_formatter.Formatters.Extensions, Is.EquivalentTo(new string[] { "cs" })); return; } [Test] public void LanguageFromExtension() { Assert.That(_formatter.LanguageFromExtension("cs"), Is.EqualTo("C#")); Assert.That(_formatter.LanguageFromExtension(""), Is.EqualTo("Plain text")); Assert.That(_formatter.LanguageFromExtension(null), Is.EqualTo("Plain text")); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void DefaultFormatter_Can_Throw_FormatterNullException() { _formatter.DefaultFormatter = null; // throws exception } [Test] public void DefaultFormatter() { CSharpCodeFormatter csFormatter; csFormatter = new CSharpCodeFormatter(); _formatter.DefaultFormatter = csFormatter; Assert.That(_formatter.DefaultFormatter, Is.EqualTo(csFormatter)); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void GetFormatterFromExtension_Can_Throw_ExtensionNullException() { _formatter.GetFormatterFromExtension(null); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException))] public void GetFormatterFromLanguage_Can_Throw_LanguageNullException() { _formatter.GetFormatterFromLanguage(null); // throws exception } [Test] public void GetFormatterFroms() { // using extension first Assert.That(_formatter.GetFormatterFromExtension("cs"), Is.EqualTo(_formatter.Formatters["C#"])); Assert.That(_formatter.GetFormatterFromExtension("txt"), Is.EqualTo(_formatter.DefaultFormatter)); // using language name Assert.That(_formatter.GetFormatterFromLanguage("C#"), Is.EqualTo(_formatter.Formatters["C#"])); Assert.That(_formatter.GetFormatterFromLanguage("txt"), Is.EqualTo(_formatter.DefaultFormatter)); return; } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "code", MatchType = MessageMatch.Contains)] public void FormatFromExtension_Can_Throw_CodeNullException() { _formatter.FormatFromExtension(null, "cs"); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "extension", MatchType = MessageMatch.Contains)] public void FormatFromExtension_Can_Throw_ExtensionNullException() { _formatter.FormatFromExtension("test", null); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "code", MatchType = MessageMatch.Contains)] public void Format_Can_Throw_CodeNullException() { _formatter.Format(null, "C#"); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "language", MatchType = MessageMatch.Contains)] public void Format_Can_Throw_LanguageNameNullException() { _formatter.Format("test", null); // throws exception } public void FormatResource(TestResource res) { ErrorItem error; FormattedCode code; List array = GetAllFormatters(); foreach (ICodeFormatter item in array) { error = new ErrorItem(res.Path, 1); code = item.Format(error.ReadFile()); Assert.That(code, Is.Not.Null, "Formatter: " + item + " failed to format resource."); try { FormattedCode.CheckData(code); } catch (Exception e) { Assert.Fail("Formatter: " + item + " has created an ill-formed data. Error: " + e.Message); } } return; } /// /// Returns a list containing all formatters in GeneralCodeFormatter /// and the one in DefaultFormatter. /// /// private List GetAllFormatters() { List array; array = new List(); foreach (ICodeFormatter item in _formatter.Formatters) array.Add(item); array.Add(_formatter.DefaultFormatter); return (array); } [Test] public void All_Formatters_Have_Unique_Language_Value() { List formatters; List languages; formatters = GetAllFormatters(); languages = new List(); foreach (ICodeFormatter item in formatters) languages.Add(item.Language); Assert.That(languages, Is.All.Not.Null); Assert.That(languages, Is.Unique); return; } [Test] public void All_Formatters_Should_PreProcess_Tab_Character() { List formatters; FormattedCode res; // We don't have reliable way to measure '\t' at drawing time, // hence, each textFormatter should replace '\t' by one or more white spaces. formatters = GetAllFormatters(); foreach (ICodeFormatter formatter in formatters) { res = formatter.Format("hi\tthere!"); Assert.That( res.Text.IndexOf("\t") == -1, "Formatter: " + formatter + " failed to remove initial '\\t' characters."); } return; } [Test] public void All_Formatters_Should_Have_Overwrite_Behavior() { List formatters; FormattedCode res; // check that formatters reset their state before // processing new data. So new data overwrite former one. formatters = GetAllFormatters(); foreach (ICodeFormatter formatter in formatters) { // process this text first formatter.Format("line 1\r\nline 2\r\nline 3"); // after processing "hi", we expect res to contain // just one line of text. res = formatter.Format("hi"); Assert.That( res.CopyInfo().LineArray.Count, Is.EqualTo(1), "Formatter: " + formatter + " failed to reset its state."); } return; } [Test] public void Any_Formatter_Should_Format_Any_Text() { TestResource res; using (res = new TestResource("HelloWorld.txt")) { FormatResource(res); } using (res = new TestResource("Basic.cs")) { FormatResource(res); } using (res = new TestResource("TextCode.txt")) { FormatResource(res); } return; } [Test] public void Format() { Assert.That(_formatter.Format("test", "C#"), Is.Not.Null); Assert.That(_formatter.Format("test", "txt"), Is.Not.Null); return; } [Test] public void Format_Pick_Best_Formatter() { ErrorItem itemHelloTxt; ErrorItem itemBasicCs; ICodeFormatter txtFormatter; ICodeFormatter csFormatter; FormattedCode exp; using (TestResource resource = new TestResource("HelloWorld.txt")) { itemHelloTxt = new ErrorItem(resource.Path, 1); txtFormatter = new PlainTextCodeFormatter(); exp = txtFormatter.Format(itemHelloTxt.ReadFile()); Assert.That( _formatter.FormatFromExtension(itemHelloTxt.ReadFile(), itemHelloTxt.FileExtension), Is.EqualTo(exp)); FormattedCode.CheckData(exp); } using (TestResource resource = new TestResource("Basic.cs")) { itemBasicCs = new ErrorItem(resource.Path, 1); csFormatter = new CSharpCodeFormatter(); exp = csFormatter.Format(itemBasicCs.ReadFile()); Assert.That( _formatter.FormatFromExtension(itemBasicCs.ReadFile(), itemBasicCs.FileExtension), Is.EqualTo(exp)); FormattedCode.CheckData(exp); } return; } } } NUnit-2.6.0.12051/src/GuiException/tests/CodeFormatters/TestPlainTextCodeFormatter.cs0000664000175000017500000000514511525533664030231 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestPlainTextCodeFormatter { private PlainTextCodeFormatter _formatter; [SetUp] public void SetUp() { _formatter = new PlainTextCodeFormatter(); return; } [Test] public void Test_Language() { Assert.That(_formatter.Language, Is.EqualTo("Plain text")); } [Test] public void Test_PreProcess() { // PreProcess is expected to remove '\t' sequences. // This test expects that normal strings are left untouched. Assert.That(_formatter.PreProcess("hello world"), Is.EqualTo("hello world")); // This test expects to see differences Assert.That(_formatter.PreProcess("hello\tworld"), Is.EqualTo("hello world")); // test to fail: passing null has no effect. Assert.That(_formatter.PreProcess(null), Is.Null); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Format_Can_Throw_CodeNullException() { _formatter.Format(null); // throws exception } [Test] public void Format_HelloWorld() { FormattedCode res; FormattedCode exp; res = _formatter.Format("Hello world!"); exp = new FormattedCode( "Hello world!", new int[] { 0 }, new byte[] { 0 }, new int[] { 0 }); Assert.That(res, Is.EqualTo(exp)); return; } [Test] public void Format_Lines() { FormattedCode res; FormattedCode exp; res = _formatter.Format( "line 1\r\n" + "line 2\r\n" + "line 3\r\n"); exp = new FormattedCode( res.Text, new int[] { 0, 8, 16 }, new byte[] { 0, 0, 0 }, new int[] { 0, 1, 2 }); Assert.That(res, Is.EqualTo(exp)); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/CodeFormatters/TestCodeFormatterCollection.cs0000664000175000017500000001454411525533664030417 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestCodeFormatterCollection { private CodeFormatterCollection _empty; private CodeFormatterCollection _filled; private ICodeFormatter _csFormatter; private ICodeFormatter _defaultFormatter; [SetUp] public void SetUp() { _empty = new CodeFormatterCollection(); _csFormatter = new CSharpCodeFormatter(); _defaultFormatter = new PlainTextCodeFormatter(); _filled = new CodeFormatterCollection(); _filled.Register(_csFormatter, "cs"); _filled.Register(_defaultFormatter, "txt"); return; } [Test] public void Test_Default() { List extensions; // ErrorItem errorCS; // ErrorItem errorCS_Upper; // ErrorItem errorTxt; // errorCS = new ErrorItem("C:\\dir\\file.cs", 1); // errorCS_Upper = new ErrorItem("C:\\dir\\file.CS", 1); // errorTxt = new ErrorItem("C:\\dir\\file.txt", 1); Assert.That(_empty.Count, Is.EqualTo(0)); Assert.That(_empty.HasExtension("cs"), Is.False); Assert.That(_empty.HasLanguage("C#"), Is.False); Assert.That(_empty, Is.EquivalentTo(new List())); Assert.That(_filled.Count, Is.EqualTo(2)); Assert.That(_filled["C#"], Is.EqualTo(_csFormatter)); Assert.That(_filled["Plain text"], Is.EqualTo(_defaultFormatter)); Assert.That(_filled.HasExtension("cs"), Is.True); Assert.That(_filled.HasLanguage("C#"), Is.True); extensions = new List(); extensions.Add("cs"); extensions.Add("txt"); Assert.That(_filled.Extensions, Is.EquivalentTo(extensions)); return; } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "formatter", MatchType = MessageMatch.Contains)] public void Register_Can_Throw_NullFormatterException() { _empty.Register(null, "cs"); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "language", MatchType = MessageMatch.Contains)] public void Register_Can_Throw_NullExtensionException() { _empty.Register(_csFormatter, null); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "language cannot be empty", MatchType = MessageMatch.Contains)] public void Register_Check_Extension_Is_Not_Empty() { _empty.Register(_csFormatter, ""); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "language cannot contain '.'", MatchType = MessageMatch.Contains)] public void Register_Check_Extension_Not_Contain_Dot_Character() { _empty.Register(_csFormatter, ".cs"); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "language 'cs' has already an handler. Remove handler first.", MatchType = MessageMatch.Contains)] public void Register_Check_Multiple_Extension_Definition() { _empty.Register(_csFormatter, "cs"); // OK _empty.Register(_defaultFormatter, "cs"); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "language 'cs' has already an handler. Remove handler first.", MatchType = MessageMatch.Contains)] public void Register_Check_Extension_Case() { _empty.Register(_csFormatter, "cs"); // OK _empty.Register(_csFormatter, "CS"); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException))] public void StringIndexer_Can_Throw_NullExtensionException() { if (_empty[(string)null] == null) // throws exception return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void ItemIndexer_Can_Throw_NullExtensionException() { if (_empty[null] == null) // throws exception return; } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "unknown language: 'unk'", MatchType = MessageMatch.Contains)] public void Indexer_Can_Throw_UnknownExtensionException() { if (_empty["unk"] == null) // throws exception return; } [Test] public void Remove() { _filled.Remove("cs"); Assert.That(_filled.Count, Is.EqualTo(1)); Assert.That(_filled.HasExtension("cs"), Is.False); _filled.Remove("txt"); Assert.That(_filled.Count, Is.EqualTo(0)); Assert.That(_filled, Is.EquivalentTo(new List())); // should not fail _filled.Remove(null); _filled.Remove("unknown"); return; } [Test] public void Remove_Is_Not_Case_Sensitive() { _filled.Remove("CS"); _filled.Remove("TxT"); Assert.That(_filled.Count, Is.EqualTo(0)); return; } [Test] public void Clear() { _filled.Clear(); Assert.That(_filled.Count, Is.EqualTo(0)); } [Test] public void ContainsFormatterFromExtension() { Assert.That(_filled.HasExtension((string)null), Is.False); } } } NUnit-2.6.0.12051/src/GuiException/tests/TestPaintLineLocation.cs0000664000175000017500000000435111525533664024273 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using System.Drawing; using NUnit.UiException.Controls; namespace NUnit.UiException.Tests { [TestFixture] public class TestPaintLineLocation { private PaintLineLocation _line; [SetUp] public void SetUp() { _line = new PaintLineLocation(42, "hello world!", new PointF(13, 42)); } [Test] public void Test_PaintLineLocation() { Assert.That(_line.LineIndex, Is.EqualTo(42)); Assert.That(_line.Text, Is.EqualTo("hello world!")); Assert.That(_line.Location, Is.EqualTo(new PointF(13, 42))); return; } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "text", MatchType = MessageMatch.Contains)] public void Test_SetText_Throws_NullTextException() { new PaintLineLocation(0, null, new PointF(0, 0)); // throws exception } [Test] public void Test_Equals() { Assert.That(_line.Equals(null), Is.False); Assert.That(_line.Equals("hello"), Is.False); Assert.That(_line.Equals(new PaintLineLocation(0, "", new PointF(0, 0))), Is.False); Assert.That( _line.Equals(new PaintLineLocation(_line.LineIndex, _line.Text, new PointF(0, 0))), Is.False); Assert.That( _line.Equals(new PaintLineLocation(_line.LineIndex, "", _line.Location)), Is.False); Assert.That( _line.Equals(new PaintLineLocation(0, _line.Text, _line.Location)), Is.False); Assert.That(_line.Equals(_line), Is.True); Assert.That(_line.Equals( new PaintLineLocation(_line.LineIndex, _line.Text, _line.Location)), Is.True); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/TestExceptionItem.cs0000664000175000017500000001507011543625326023471 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.Tests.data; using System.IO; namespace NUnit.UiException.Tests { [TestFixture] public class TestErrorItem { [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "path", MatchType = MessageMatch.Contains)] public void Ctor_Throws_NullPathException() { new ErrorItem(null, 1); // throws exception } [Test] public void Ctor_With_Line_0() { new ErrorItem("file.txt", 0); } [Test] public void Ctor_2() { ErrorItem item; item = new ErrorItem("Test.cs", "myFunction()", 1); Assert.That(item.Path, Is.EqualTo("Test.cs")); Assert.That(item.FullyQualifiedMethodName, Is.EqualTo("myFunction()")); Assert.That(item.LineNumber, Is.EqualTo(1)); Assert.That(item.HasSourceAttachment, Is.True); Assert.That(item.FileExtension, Is.EqualTo("cs")); item = new ErrorItem(null, "myFunction()", 1); Assert.That(item.Path, Is.Null); Assert.That(item.FileExtension, Is.Null); Assert.That(item.FullyQualifiedMethodName, Is.EqualTo("myFunction()")); Assert.That(item.LineNumber, Is.EqualTo(1)); Assert.That(item.HasSourceAttachment, Is.False); return; } [Test] public void Test_MethodName() { ErrorItem item; // test to pass item = new ErrorItem("path", "namespace1.class.fullMethodName(string arg)", 1); Assert.That(item.MethodName, Is.EqualTo("fullMethodName(string arg)")); Assert.That(item.BaseMethodName, Is.EqualTo("fullMethodName")); Assert.That(item.ClassName, Is.EqualTo("class")); item = new ErrorItem("path", ".class.fullMethodName(string arg)", 1); Assert.That(item.MethodName, Is.EqualTo("fullMethodName(string arg)")); Assert.That(item.BaseMethodName, Is.EqualTo("fullMethodName")); Assert.That(item.ClassName, Is.EqualTo("class")); item = new ErrorItem("path", "0123456789012.a()", 1); Assert.That(item.MethodName, Is.EqualTo("a()")); Assert.That(item.BaseMethodName, Is.EqualTo("a")); Assert.That(item.ClassName, Is.EqualTo("0123456789012")); // test to fail item = new ErrorItem("path", "fullMethodName(string arg)", 1); Assert.That(item.MethodName, Is.EqualTo("fullMethodName(string arg)")); Assert.That(item.BaseMethodName, Is.EqualTo("fullMethodName")); Assert.That(item.ClassName, Is.EqualTo("")); item = new ErrorItem("path", "", 1); Assert.That(item.MethodName, Is.EqualTo("")); Assert.That(item.BaseMethodName, Is.EqualTo("")); Assert.That(item.ClassName, Is.EqualTo("")); return; } [Test] public void Can_Set_Properties() { ErrorItem item; item = new ErrorItem("/dir/file.txt", 13); Assert.That(item.FileName, Is.EqualTo("file.txt")); Assert.That(item.FileExtension, Is.EqualTo("txt")); Assert.That(item.Path, Is.EqualTo("/dir/file.txt")); Assert.That(item.LineNumber, Is.EqualTo(13)); Assert.That(item.HasSourceAttachment, Is.True); item = new ErrorItem(); Assert.That(item.FileName, Is.Null); Assert.That(item.FileExtension, Is.Null); Assert.That(item.Path, Is.Null); Assert.That(item.LineNumber, Is.EqualTo(0)); Assert.That(item.HasSourceAttachment, Is.False); return; } [Test] public void Test_FileExtension() { ErrorItem item; item = new ErrorItem("C:\\dir\\file.cs", 1); Assert.That(item.FileExtension, Is.EqualTo("cs")); item = new ErrorItem("C:\\dir\\file.cpp", 1); Assert.That(item.FileExtension, Is.EqualTo("cpp")); item = new ErrorItem("C:\\dir\\file.cs.cpp.plop", 1); Assert.That(item.FileExtension, Is.EqualTo("plop")); item = new ErrorItem("C:\\dir\\file.", 1); Assert.That(item.FileExtension, Is.Null); item = new ErrorItem("C:\\dir\\file", 1); Assert.That(item.FileExtension, Is.Null); return; } [Test] [ExpectedException(typeof(FileNotFoundException), ExpectedMessage = "unknown.txt", MatchType = MessageMatch.Contains)] public void ReadFile_Throws_FileNotExistException() { ErrorItem item = new ErrorItem("C:\\unknown\\unknown.txt", 1); item.ReadFile(); // throws exception } [Test] public void ReadFile() { ErrorItem item; using (TestResource resource = new TestResource("HelloWorld.txt")) { item = new ErrorItem(resource.Path, 1); Assert.That(item.ReadFile(), Is.Not.Null); Assert.That(item.ReadFile(), Is.EqualTo("Hello world!")); } return; } [Test] public void Test_Equals() { ErrorItem itemA; ErrorItem itemB; ErrorItem itemC; itemA = new ErrorItem("file1.txt", 43); itemB = new ErrorItem("file2.txt", 44); itemC = new ErrorItem("file1.txt", "myFunction()", 43); Assert.That(itemA.Equals(null), Is.False); Assert.That(itemA.Equals("hello"), Is.False); Assert.That(itemA.Equals(itemB), Is.False); Assert.That(itemA.Equals(itemC), Is.False); Assert.That(itemA.Equals(itemA), Is.True); Assert.That(itemA.Equals(new ErrorItem("file", 43)), Is.False); Assert.That(itemA.Equals(new ErrorItem("file1.txt", 42)), Is.False); Assert.That(itemA.Equals(new ErrorItem("file1.txt", 43)), Is.True); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/TestStackTraceParser.cs0000664000175000017500000002276611543625326024127 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; namespace NUnit.UiException.Tests { [TestFixture] public class TestStackTraceParser { private StackTraceParser _parser; [SetUp] public void SetUp() { _parser = new StackTraceParser(); return; } [Test] public void Test_Default() { Assert.That(_parser.Items, Is.Not.Null); Assert.That(_parser.Items.Count, Is.EqualTo(0)); return; } [Test] public void Test_Parse() { _parser.Parse("à NUnit.UiException.TraceItem.get_Text() dans C:\\TraceItem.cs:ligne 43"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo(new ErrorItem("C:\\TraceItem.cs", "NUnit.UiException.TraceItem.get_Text()", 43))); // TryParse should clear previous textFormatter _parser.Parse(""); Assert.That(_parser.Items.Count, Is.EqualTo(0)); return; } [Test] public void Test_Parse_MultipleExtension() { _parser.Parse("à get_Text() dans C:\\TraceItem.cs.cs.cs.cs:ligne 43"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0].Path, Is.EqualTo("C:\\TraceItem.cs.cs.cs.cs")); _parser.Parse("à get_Text() dans C:\\my Document1\\my document2 containing space\\file.cs:line 1"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0].Path, Is.EqualTo("C:\\my Document1\\my document2 containing space\\file.cs")); _parser.Parse("à get_Text() dans C:\\my doc\\my doc2.cs\\file.cs:line 1"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0].Path, Is.EqualTo("C:\\my doc\\my doc2.cs\\file.cs")); return; } [Test] public void Test_Parse_With_Real_Life_Samples() { // test ability to extract one trace _parser.Parse( "à Test.TestTraceItem.Can_Set_Properties() dans " + "C:\\Documents and Settings\\ihottier\\Mes documents\\" + "NUnit_Stacktrace\\Test\\TestTraceItem.cs:ligne 42\r\n"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo(new ErrorItem( "C:\\Documents and Settings\\ihottier\\Mes documents\\" + "NUnit_Stacktrace\\Test\\TestTraceItem.cs", "Test.TestTraceItem.Can_Set_Properties()", 42))); // test ability to extract two traces _parser.Parse( "à NUnit.UiException.TraceItem.get_Text() " + "dans C:\\Documents and Settings\\ihottier\\Mes documents\\" + "NUnit.UiException\\TraceItem.cs:ligne 43\r\n" + "à Test.TestTaggedText.SetUp() dans C:\\Documents and Settings\\" + "ihottier\\Mes documents\\NUnit_Stacktrace\\Test\\TestTaggedText.cs:ligne 30\r\n"); Assert.That(_parser.Items.Count, Is.EqualTo(2)); Assert.That(_parser.Items[0], Is.EqualTo( new ErrorItem( "C:\\Documents and Settings\\ihottier\\Mes documents\\" + "NUnit.UiException\\TraceItem.cs", "NUnit.UiException.TraceItem.get_Text()", 43))); Assert.That(_parser.Items[1], Is.EqualTo( new ErrorItem( "C:\\Documents and Settings\\" + "ihottier\\Mes documents\\NUnit_Stacktrace\\Test\\TestTaggedText.cs", "Test.TestTaggedText.SetUp()", 30))); return; } [Test] public void Test_Trace_When_Missing_File() { // // NUnit.UiException.Tests ability to not be confused // if source code attachment is missing // _parser.Parse( "à System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)\r\n" + "à NUnit.UiException.StackTraceParser.Parse(String stackTrace) dans C:\\StackTraceParser.cs:ligne 55\r\n" + "à Test.TestStackTraceParser.Test_Parse() dans C:\\TestStackTraceParser.cs:ligne 36\r\n" ); Assert.That(_parser.Items.Count, Is.EqualTo(3)); Assert.That(_parser.Items[0].HasSourceAttachment, Is.False); Assert.That(_parser.Items[0].FullyQualifiedMethodName, Is.EqualTo("System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)")); Assert.That(_parser.Items[1], Is.EqualTo( new ErrorItem( "C:\\StackTraceParser.cs", "NUnit.UiException.StackTraceParser.Parse(String stackTrace)", 55))); Assert.That(_parser.Items[2], Is.EqualTo( new ErrorItem( "C:\\TestStackTraceParser.cs", "Test.TestStackTraceParser.Test_Parse()", 36))); return; } [Test] public void Test_Missing_Line_Number() { // // NUnit.UiException.Tests ability to not be confused // if line number is missing // _parser.Parse("à Test.TestStackTraceParser.Test_Parse() dans C:\\TestStackTraceParser.cs:\r\n"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo(new ErrorItem( "C:\\TestStackTraceParser.cs", "Test.TestStackTraceParser.Test_Parse()", 0))); return; } [Test] public void Test_English_Stack() { // // NUnit.UiException.Tests ability of the parser to not depend // of the language // _parser.Parse("at Test.TestStackTraceParser.Test_Parse() in C:\\TestStackTraceParser.cs:line 36\r\n"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo( new ErrorItem("C:\\TestStackTraceParser.cs", "Test.TestStackTraceParser.Test_Parse()", 36))); return; } [Test] public void Test_Ability_To_Handle_Different_Path_System_Syntaxes() { // // NUnit.UiException.Tests ability to not depend of one file system // // here, an hypothetic stack containing UNIX and Windows like filePath values... _parser.Parse( "at Test.TestStackTraceParser.Test_Parse() in /home/ihottier/work/stacktrace/test/TestStackTraceParser.cs:line 36\r\n" + "at Test.TestStackTraceParser2.Text_Parse2() in C:\\folder\\file1:line 42" ); Assert.That(_parser.Items.Count, Is.EqualTo(2)); Assert.That(_parser.Items[0], Is.EqualTo( new ErrorItem( "/home/ihottier/work/stacktrace/test/TestStackTraceParser.cs", "Test.TestStackTraceParser.Test_Parse()", 36))); Assert.That(_parser.Items[1], Is.EqualTo( new ErrorItem( "C:\\folder\\file1", "Test.TestStackTraceParser2.Text_Parse2()", 42))); return; } [Test] public void Test_Ability_To_Handle_Files_With_Unknown_Extension() { _parser.Parse("à Test.TestStackTraceParser.Test_Parse() in C:\\TestStackTraceParser.vb:line 36"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo( new ErrorItem( "C:\\TestStackTraceParser.vb", "Test.TestStackTraceParser.Test_Parse()", 36))); return; } [Test] public void Test_Analysis_Does_Not_Depend_Upon_File_Extension() { // // NUnit.UiException.Tests that Stack Analyzer should not // be not aware of file language. // _parser.Parse("à Test.TestStackTraceParser.Test_Parse() in C:\\TestStackTraceParser.vb:line 36"); Assert.That(_parser.Items.Count, Is.EqualTo(1)); Assert.That(_parser.Items[0], Is.EqualTo( new ErrorItem( "C:\\TestStackTraceParser.vb", "Test.TestStackTraceParser.Test_Parse()", 36))); return; } [Test] public void Test_Parse_Null() { _parser.Parse(null); } } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/0000775000175000017500000000000011742560362022056 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestCSParser.cs0000664000175000017500000001224211525533664024734 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestCSharpCodeFormatter { private TestingCSharpCodeFormatter _parser; [SetUp] public void SetUp() { _parser = new TestingCSharpCodeFormatter(); return; } [Test] public void Test_Default() { Assert.That(_parser.CSCode, Is.Not.Null); Assert.That(_parser.CSCode.Text, Is.EqualTo("")); Assert.That(_parser.CSCode.LineCount, Is.EqualTo(0)); Assert.That(_parser.Language, Is.EqualTo("C#")); return; } [Test] public void Test_PreProcess() { // PreProcess is expected to remove '\t' sequences. // This test expects that normal strings are left untouched. Assert.That(_parser.PreProcess("hello world"), Is.EqualTo("hello world")); // This test expects to see differences Assert.That(_parser.PreProcess("hello\tworld"), Is.EqualTo("hello world")); // test to fail: passing null has no effect. Assert.That(_parser.PreProcess(null), Is.Null); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Format_Can_Throw_CSharpNullException() { _parser.Format(null); // throws exception } [Test] public void Test_Format() { FormattedCode exp; FormattedCode res; res = _parser.Format("line 1\n line 2\nline 3\n"); exp = new FormattedCode( "line 1\n line 2\nline 3\n", new int[] { 0, 7, 16 }, new byte[] { 0, 0, 0 }, new int[] { 0, 1, 2 } ); Assert.That(res, Is.EqualTo(exp)); return; } [Test] public void Test_Format_2() { FormattedCode exp; FormattedCode res; res = _parser.Format( "int i; //comment\n" + "char c='a';\n"); exp = new FormattedCode( "int i; //comment\n" + "char c='a';\n", new int[] { 0, 3, 7, 16, 17, 21, 24, 27 }, new byte[] { 1, 0, 2, 0, 1, 0, 3, 0 }, new int[] { 0, 4 } ); Assert.That(res, Is.EqualTo(exp)); return; } [Test] public void Test_Format_3() { FormattedCode exp; FormattedCode res; // Ensure that escaping sequences are // handled correctly // 0 2 14 17 21 res = _parser.Format("s=\"hi, there!"); exp = new FormattedCode( "s=\"hi, there!", new int[] { 0, 2 }, new byte[] { 0, 3 }, new int[] { 0 }); Assert.That(res, Is.EqualTo(exp)); _parser = new TestingCSharpCodeFormatter(); // 0 2 res = _parser.Format("s=\"hi, there!"); exp = new FormattedCode( "s=\"hi, there!", new int[] { 0, 2, 18, 22 }, new byte[] { 0, 3, 0, 3 }, new int[] { 0 }); Assert.That(res, Is.EqualTo(exp)); return; } [Test] public void Test_Conserve_Intermediary_Spaces() { FormattedCode res; res = _parser.Format( "{\r\n" + " class A { }\r\n" + "}\r\n"); Assert.That(res.LineCount, Is.EqualTo(3)); Assert.That(res[0].Text, Is.EqualTo("{")); Assert.That(res[1].Text, Is.EqualTo(" class A { }")); Assert.That(res[2].Text, Is.EqualTo("}")); Assert.That(res[0][0].Text, Is.EqualTo("{")); Assert.That(res[1][0].Text, Is.EqualTo(" ")); Assert.That(res[1][1].Text, Is.EqualTo("class")); Assert.That(res[1][2].Text, Is.EqualTo(" A { }")); Assert.That(res[2][0].Text, Is.EqualTo("}")); return; } #region TestingCSharpCodeFormatter class TestingCSharpCodeFormatter : CSharpCodeFormatter { public new string PreProcess(string text) { return (base.PreProcess(text)); } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestTokenClassifier.cs0000664000175000017500000006553711525533664026356 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestTokenClassifier { private TestingClassifier _classifier; [SetUp] public void SetUp() { _classifier = new TestingClassifier(); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Test_Classify_Can_Throw_ArgumentNullException() { _classifier.Classify(null); // throws exception } [Test] public void Test_NewState() { // STATE_CODE Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.EndOfLine), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.Separator), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.Text), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.CommentC_Open), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.CommentC_Close), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.CommentCpp), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.SingleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CODE, LexerTag.DoubleQuote), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); // STATE_COMMENT_C Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.EndOfLine), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.Separator), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.Text), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.CommentC_Open), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.CommentC_Close), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.CommentCpp), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.SingleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CCOMMENT, LexerTag.DoubleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CCOMMENT)); // STATE_COMMENT_CPP Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.EndOfLine), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.Separator), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.Text), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.CommentC_Open), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.CommentC_Close), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.CommentCpp), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.SingleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CPPCOMMENT, LexerTag.DoubleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CPPCOMMENT)); // SMSTATE_CHAR Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.EndOfLine), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.Separator), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.Text), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.CommentC_Open), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.CommentC_Close), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.CommentCpp), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.SingleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_CHAR, LexerTag.DoubleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CHAR)); // SMSTATE_STRING Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.EndOfLine), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.Separator), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.Text), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.CommentC_Open), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.CommentC_Close), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.CommentCpp), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.SingleQuote), Is.EqualTo(TokenClassifier.SMSTATE_STRING)); Assert.That( _classifier.GetSMSTATE(TokenClassifier.SMSTATE_STRING, LexerTag.DoubleQuote), Is.EqualTo(TokenClassifier.SMSTATE_CODE)); return; } [Test] public void test_AcceptToken() { _checkTag( "\ncode/*comment*/\nint i;//comment2\nchar c='i';string s=\"test\";", new Couple[] { new Couple(TokenClassifier.SMSTATE_CODE, "\n"), new Couple(TokenClassifier.SMSTATE_CODE, "code"), new Couple(TokenClassifier.SMSTATE_CCOMMENT, "/*"), new Couple(TokenClassifier.SMSTATE_CCOMMENT, "comment"), new Couple(TokenClassifier.SMSTATE_CCOMMENT, "*/"), new Couple(TokenClassifier.SMSTATE_CODE, "\n"), new Couple(TokenClassifier.SMSTATE_CODE, "int"), new Couple(TokenClassifier.SMSTATE_CODE, " "), new Couple(TokenClassifier.SMSTATE_CODE, "i"), new Couple(TokenClassifier.SMSTATE_CODE, ";"), new Couple(TokenClassifier.SMSTATE_CPPCOMMENT, "//"), new Couple(TokenClassifier.SMSTATE_CPPCOMMENT, "comment2"), new Couple(TokenClassifier.SMSTATE_CODE, "\n"), new Couple(TokenClassifier.SMSTATE_CODE, "char"), new Couple(TokenClassifier.SMSTATE_CODE, " "), new Couple(TokenClassifier.SMSTATE_CODE, "c"), new Couple(TokenClassifier.SMSTATE_CODE, "="), new Couple(TokenClassifier.SMSTATE_CHAR, "'"), new Couple(TokenClassifier.SMSTATE_CHAR, "i"), new Couple(TokenClassifier.SMSTATE_CHAR, "'"), new Couple(TokenClassifier.SMSTATE_CODE, ";"), new Couple(TokenClassifier.SMSTATE_CODE, "string"), new Couple(TokenClassifier.SMSTATE_CODE, " "), new Couple(TokenClassifier.SMSTATE_CODE, "s"), new Couple(TokenClassifier.SMSTATE_CODE, "="), new Couple(TokenClassifier.SMSTATE_STRING, "\""), new Couple(TokenClassifier.SMSTATE_STRING, "test"), new Couple(TokenClassifier.SMSTATE_STRING, "\""), new Couple(TokenClassifier.SMSTATE_CODE, ";") }); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Test_Classify_Throw_NullArgException() { _classifier.Classify(null); // throws exception } [Test] public void Test_Classify() { _checkClassification( "\ncode/*comment*/\nint i;//comment2\nchar c='i';string s=\"test\";", new Couple[] { new Couple(ClassificationTag.Code, "\n"), new Couple(ClassificationTag.Code, "code"), new Couple(ClassificationTag.Comment, "/*"), new Couple(ClassificationTag.Comment, "comment"), new Couple(ClassificationTag.Comment, "*/"), new Couple(ClassificationTag.Code, "\n"), new Couple(ClassificationTag.Keyword, "int"), new Couple(ClassificationTag.Code, " "), new Couple(ClassificationTag.Code, "i"), new Couple(ClassificationTag.Code, ";"), new Couple(ClassificationTag.Comment, "//"), new Couple(ClassificationTag.Comment, "comment2"), new Couple(ClassificationTag.Code, "\n"), new Couple(ClassificationTag.Keyword, "char"), new Couple(ClassificationTag.Code, " "), new Couple(ClassificationTag.Code, "c"), new Couple(ClassificationTag.Code, "="), new Couple(ClassificationTag.String, "'"), new Couple(ClassificationTag.String, "i"), new Couple(ClassificationTag.String, "'"), new Couple(ClassificationTag.Code, ";"), new Couple(ClassificationTag.Keyword, "string"), new Couple(ClassificationTag.Code, " "), new Couple(ClassificationTag.Code, "s"), new Couple(ClassificationTag.Code, "="), new Couple(ClassificationTag.String, "\""), new Couple(ClassificationTag.String, "test"), new Couple(ClassificationTag.String, "\""), new Couple(ClassificationTag.Code, ";") }); return; } [Test] public void Test_Classification_Cases() { _checkClassification("default:", new Couple[] { new Couple(ClassificationTag.Keyword, "default"), new Couple(ClassificationTag.Code, ":") }); _checkClassification("List", new Couple[]{ new Couple(ClassificationTag.Code, "List"), new Couple(ClassificationTag.Code, "<"), new Couple(ClassificationTag.Keyword, "string"), new Couple(ClassificationTag.Code, ">") }); _checkClassification("Dictionary", new Couple[] { new Couple(ClassificationTag.Code, "Dictionary"), new Couple(ClassificationTag.Code, "<"), new Couple(ClassificationTag.Keyword, "string"), new Couple(ClassificationTag.Code, ","), new Couple(ClassificationTag.Code, " "), new Couple(ClassificationTag.Keyword, "int"), new Couple(ClassificationTag.Code, ">") }); return; } [Test] public void Test_Classify_As_Keyword() { TokenClassifier classifier; ClassificationTag result; string error; Lexer lexer; lexer = new Lexer(); lexer.Parse( "abstract event new struct as explicit null switch " + "base extern object this bool false operator throw " + "break finally out true byte fixed override try case " + "float params typeof catch for private uint char " + "foreach protected ulong checked goto public unchecked " + "class if readonly unsafe const implicit ref ushort " + "continue in return using decimal int sbyte virtual " + "default interface sealed volatile delegate internal " + "short void do is sizeof while double lock stackalloc " + "else long static enum namespace string get set region " + "endregion "); classifier = new TokenClassifier(); while (lexer.Next()) { if (lexer.CurrentToken.Text.Trim() == "") continue; result = classifier.Classify(lexer.CurrentToken); error = String.Format("Classification: [{0}] was expected for token [{1}] but [{2}] was returned.", ClassificationTag.Keyword, lexer.CurrentToken, result); Assert.That( result, Is.EqualTo(ClassificationTag.Keyword), error); } return; } [Test] public void Test_Reset() { Lexer lexer; lexer = new Lexer(); lexer.Parse("/*int"); lexer.Next(); _classifier.Classify(lexer.CurrentToken); _classifier.Reset(); lexer.Next(); Assert.That(_classifier.Classify(lexer.CurrentToken), Is.EqualTo(ClassificationTag.Keyword)); return; } [Test] public void Test_Escaping_sequence() { Lexer _lexer; _lexer = new Lexer(); // this ensure that escaping can be set in string context only _lexer.Parse("\\\\"); _classifier.Reset(); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.Code)); Assert.That(_classifier.Escaping, Is.False); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.Code)); Assert.That(_classifier.Escaping, Is.False); // this ensure that parsing "\\\\" two times // set and unset Escaping flag correctly _lexer.Parse("\"\\\\\""); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.False); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.True); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.False); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.False); // this ensure that first 'a' is considered as string, second as code _lexer.Parse("\"\\\"a\"a"); _classifier.Reset(); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.True); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_classifier.Escaping, Is.False); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("a")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("a")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.Code)); // another test, this time 'a' should be considered as code _lexer.Parse("\"\\\\\"a\""); _classifier.Reset(); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\\")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("\"")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.String)); Assert.That(_lexer.Next(), Is.True); Assert.That(_lexer.CurrentToken.Text, Is.EqualTo("a")); Assert.That(_classifier.Classify(_lexer.CurrentToken), Is.EqualTo(ClassificationTag.Code)); // this ensure that Reset() reset escaping to false _lexer.Parse("\"\\"); _lexer.Next(); _classifier.Classify(_lexer.CurrentToken); _lexer.Next(); _classifier.Classify(_lexer.CurrentToken); Assert.That(_classifier.Escaping, Is.True); _classifier.Reset(); Assert.That(_classifier.Escaping, Is.False); return; } #region utility methods private void _checkTag(string sequence, Couple[] expected) { Lexer lexer; int returned_tag; TestingClassifier classifier; StringBuilder recognized; string error; int i; classifier = new TestingClassifier(); lexer = new Lexer(); lexer.Parse(sequence); recognized = new StringBuilder(); i = 0; while (lexer.Next()) { recognized.Append(lexer.CurrentToken.Text); error = String.Format( "Token [{0}] was expected, but [{1}] was returned instead, near: [{2}].", expected[i].Text, lexer.CurrentToken.Text, recognized.ToString()); Assert.That(lexer.CurrentToken.Text, Is.EqualTo(expected[i].Text), error); returned_tag = classifier.AcceptLexToken(lexer.CurrentToken); error = String.Format( "Tag [{0}] was expected, but [{1}] was returned instead, near: [{2}].", expected[i].Value, returned_tag, recognized.ToString()); Assert.That(returned_tag, Is.EqualTo(expected[i].Value), error); i++; } Assert.That(lexer.Next(), Is.False, "Error, there are unvisited tokens left."); Assert.That(i == expected.Length, "Error, more tokens were expected."); return; } private void _checkClassification(string sequence, Couple[] expected) { Lexer lexer; ClassificationTag returned_tag; TestingClassifier classifier; StringBuilder recognized; string error; int i; classifier = new TestingClassifier(); lexer = new Lexer(); lexer.Parse(sequence); recognized = new StringBuilder(); i = 0; while (lexer.Next()) { recognized.Append(lexer.CurrentToken.Text); error = String.Format( "Token [{0}] was expected, but [{1}] was returned instead, near: [{2}].", expected[i].Text, lexer.CurrentToken.Text, recognized.ToString()); Assert.That(lexer.CurrentToken.Text, Is.EqualTo(expected[i].Text), error); returned_tag = classifier.Classify(lexer.CurrentToken); error = String.Format( "ClassificationTag [{0}] was expected, but [{1}] was returned instead, near: [{2}].", expected[i].Value, returned_tag, recognized.ToString()); Assert.That(returned_tag, Is.EqualTo(expected[i].Value), error); i++; } Assert.That(lexer.Next(), Is.False, "Error, there are unvisited tokens left."); Assert.That(i == expected.Length, "Error, more tokens were expected."); return; } #endregion #region TestingClassifier class TestingClassifier : TokenClassifier { public static string ClassString(int code) { switch (code) { case TokenClassifier.SMSTATE_CODE: return ("STATE_CODE"); case TokenClassifier.SMSTATE_CCOMMENT: return ("STATE_COMMENT_C"); case TokenClassifier.SMSTATE_CPPCOMMENT: return ("STATE_COMMENT_CPP"); case TokenClassifier.SMSTATE_CHAR: return ("SMSTATE_CHAR"); case TokenClassifier.SMSTATE_STRING: return ("SMSTATE_STRING"); default: break; } return ("unknown code=" + code); } public new int AcceptLexToken(LexToken token) { return (base.AcceptLexToken(token)); } public new int GetSMSTATE(int stateCode, LexerTag transition) { return (base.GetSMSTATE(stateCode, transition)); } } #endregion #region Couple class Couple { public object Value; public string Text; public Couple(object value, string text) { Value = value; Text = text; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestCSCode.cs0000664000175000017500000002221111525533664024347 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestFormattedCode { private FormattedCode _code; [Test] public void Test_SimpleCollection() { _code = new TestingCSCode( "line 1\n line 2\nline 3\n", new int[] { 0, 7, 16 }, new byte[] { 0, 0, 0 }, new int[] { 0, 1, 2 } ); Assert.That(_code.Text, Is.EqualTo("line 1\n line 2\nline 3\n")); Assert.That(_code.LineCount, Is.EqualTo(3)); Assert.That(_code[0], Is.Not.Null); Assert.That(_code[0].Text, Is.EqualTo("line 1")); Assert.That(_code[1], Is.Not.Null); Assert.That(_code[1].Text, Is.EqualTo(" line 2")); Assert.That(_code[2], Is.Not.Null); Assert.That(_code[2].Text, Is.EqualTo("line 3")); // check internal data Assert.That(_code[0].Count, Is.EqualTo(1)); Assert.That(_code[0][0].Text, Is.EqualTo("line 1")); Assert.That(_code[0][0].Tag, Is.EqualTo(ClassificationTag.Code)); Assert.That(_code[1].Count, Is.EqualTo(1)); Assert.That(_code[1][0].Text, Is.EqualTo(" line 2")); Assert.That(_code[1][0].Tag, Is.EqualTo(ClassificationTag.Code)); Assert.That(_code[2].Count, Is.EqualTo(1)); Assert.That(_code[2][0].Text, Is.EqualTo("line 3")); Assert.That(_code[2][0].Tag, Is.EqualTo(ClassificationTag.Code)); return; } [Test] public void Empty() { Assert.NotNull(FormattedCode.Empty); Assert.That(FormattedCode.Empty, Is.EqualTo(new FormattedCode())); } [Test] public void Test_ComplexCollection() { _code = new TestingCSCode( "int i; //comment\n" + "char c='a';\n", new int[] { 0, 4, 7, 17, 22, 24, 27 }, new byte[] { 1, 0, 2, 1, 0, 3, 0 }, new int[] { 0, 3 } ); Assert.That(_code.Text, Is.EqualTo("int i; //comment\nchar c='a';\n")); Assert.That(_code.LineCount, Is.EqualTo(2)); Assert.That(_code[0], Is.Not.Null); Assert.That(_code[0].Text, Is.EqualTo("int i; //comment")); Assert.That(_code[1], Is.Not.Null); Assert.That(_code[1].Text, Is.EqualTo("char c='a';")); // check internal data Assert.That(_code[0].Count, Is.EqualTo(3)); Assert.That(_code[0][0].Text, Is.EqualTo("int ")); Assert.That(_code[0][0].Tag, Is.EqualTo(ClassificationTag.Keyword)); Assert.That(_code[0][1].Text, Is.EqualTo("i; ")); Assert.That(_code[0][1].Tag, Is.EqualTo(ClassificationTag.Code)); Assert.That(_code[0][2].Text, Is.EqualTo("//comment")); Assert.That(_code[0][2].Tag, Is.EqualTo(ClassificationTag.Comment)); Assert.That(_code[1].Count, Is.EqualTo(4)); Assert.That(_code[1][0].Text, Is.EqualTo("char ")); Assert.That(_code[1][0].Tag, Is.EqualTo(ClassificationTag.Keyword)); Assert.That(_code[1][1].Text, Is.EqualTo("c=")); Assert.That(_code[1][1].Tag, Is.EqualTo(ClassificationTag.Code)); Assert.That(_code[1][2].Text, Is.EqualTo("'a'")); Assert.That(_code[1][2].Tag, Is.EqualTo(ClassificationTag.String)); Assert.That(_code[1][3].Text, Is.EqualTo(";")); Assert.That(_code[1][3].Tag, Is.EqualTo(ClassificationTag.Code)); return; } [Test] public void Test_MaxLength() { _code = new TestingCSCode( "", new int[] { }, new byte[] { }, new int[] { }); Assert.That(_code.MaxLength, Is.EqualTo(0)); _code = new TestingCSCode( "a\r\nabc\r\nab", new int[] { 0, 3, 8 }, new byte[] { 0, 0, 0 }, new int[] { 0, 1, 2 }); Assert.That(_code.MaxLength, Is.EqualTo(3)); _code = new TestingCSCode( "a\r\nab\r\nabc", new int[] { 0, 3, 7 }, new byte[] { 0, 0, 0 }, new int[] { 0, 1, 2 }); Assert.That(_code.MaxLength, Is.EqualTo(3)); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void CheckData_Can_Throw_NullDataException() { FormattedCode.CheckData(null); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "IndexArray.Count and TagArray.Count must match.", MatchType = MessageMatch.Contains)] public void CheckData_IndexArray_And_TagArray_Count_Must_Match() { FormattedCode.CheckData( new FormattedCode("hello", new int[] { 0 }, new byte[0], new int[] { 0 })); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Bad LineArray value at index 0, value was: 1, expected to be in: [0-1[.", MatchType = MessageMatch.Contains)] public void CheckData_LineArray_Values_Must_Be_In_IndexArray_Count() { FormattedCode.CheckData( new FormattedCode("hi there!", new int[] { 0 }, new byte[] { 0 }, new int[] { 1 })); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Bad LineArray[1], value was: 0, expected to be > than LineArray[0]=0.", MatchType = MessageMatch.Contains)] public void CheckData_LineArray_Values_Must_Always_Grow_Up() { FormattedCode.CheckData( new FormattedCode("hi\r\nthere\r\n", new int[] { 0, 3 }, new byte[] { 0, 0 }, new int[] { 0, 0 })); // throws exception } [Test] public void Test_Equals() { _code = new TestingCSCode( "line", new int[] { 0 }, new byte[] { 0 }, new int[] { 0 } ); // Tests to fail Assert.That(_code.Equals(null), Is.False); Assert.That(_code.Equals("hello"), Is.False); Assert.That(_code.Equals( new TestingCSCode("a", new int[] { 0 }, new byte[] { 0 }, new int[] { 0 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 1 }, new byte[] { 0 }, new int[] { 0 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0 }, new byte[] { 1 }, new int[] { 0 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0 }, new byte[] { 0 }, new int[] { 1 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0, 0 }, new byte[] { 0 }, new int[] { 0 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0 }, new byte[] { 0, 0 }, new int[] { 0 })), Is.False); Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0 }, new byte[] { 0 }, new int[] { 0, 0 })), Is.False); // NUnit.UiException.Tests to pass Assert.That(_code.Equals( new TestingCSCode("line", new int[] { 0 }, new byte[] { 0 }, new int[] { 0 })), Is.True); return; } #region TestingCSCode class TestingCSCode : FormattedCode { public TestingCSCode(string csharpText, int[] strIndexes, byte[] tagValues, int[] lineIndexes) { _codeInfo = new CodeInfo(); _codeInfo.Text = csharpText; _codeInfo.IndexArray = new List(); foreach (int index in strIndexes) _codeInfo.IndexArray.Add(index); _codeInfo.TagArray = new List(); foreach (byte tag in tagValues) _codeInfo.TagArray.Add(tag); _codeInfo.LineArray = new List(); foreach (int line in lineIndexes) _codeInfo.LineArray.Add(line); return; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestLexer.cs0000664000175000017500000003025211525533664024332 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestLexer { private TestingLexer _lexer; [SetUp] public void SetUp() { _lexer = new TestingLexer(); return; } [Test] public void Test_Default() { Assert.That(_lexer.CurrentToken, Is.Null); Assert.That(_lexer.HasNext(), Is.False); Assert.That(_lexer.Next(), Is.False); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Test_SetText_Throws_NullArgumentException() { _lexer.Parse(null); // throws exception } private void _checkOutput(string sequence, LexToken[] expected) { Lexer lexer; StringBuilder recognized; string error; int i; int j; lexer = new Lexer(); lexer.Parse(sequence); recognized = new StringBuilder(); i = 0; while (lexer.Next()) { recognized.Append(lexer.CurrentToken.Text); error = String.Format("Token [{0}] was expected, but lexer returned [{1}] instead, near: [{2}].", expected[i], lexer.CurrentToken, recognized.ToString()); Assert.That(lexer.CurrentToken, Is.EqualTo(expected[i]), error); i++; } Assert.That(lexer.Next(), Is.False, "Error, there are unvisited tokens left."); error = "missing "; j = i; while (j < expected.Length) { error += expected[j].ToString(); error += ", "; ++j; } Assert.That(i == expected.Length, "Error, more tokens were expected. {0}", error); return; } [Test] public void Test_Split_Words() { _checkOutput("one two three\r\n'", new LexToken[] { new TestingToken("one", 0, LexerTag.Text), new TestingToken(" ", 3, LexerTag.Separator), new TestingToken("two", 4, LexerTag.Text), new TestingToken(" ", 7, LexerTag.Separator), new TestingToken("three", 8, LexerTag.Text), new TestingToken("\r", 13, LexerTag.Separator), new TestingToken("\n", 14, LexerTag.EndOfLine), new TestingToken("'", 15, LexerTag.SingleQuote) }); return; } [Test] public void Test_Split_SingleQuote() { _checkOutput("'hello'", new LexToken[] { new TestingToken("'", 0, LexerTag.SingleQuote), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("'", 6, LexerTag.SingleQuote) }); return; } [Test] public void Test_Split_DoubleQuote() { _checkOutput("\"hello\"", new LexToken[] { new TestingToken("\"", 0, LexerTag.DoubleQuote), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("\"", 6, LexerTag.DoubleQuote) }); // test to fail // lexer should not be confused by escapment character \" // expecting: // - \" // - \\\" // - hello // - \\\" // - \" _checkOutput("\"\"hello\"\"", new LexToken[] { new TestingToken("\"", 0, LexerTag.DoubleQuote), new TestingToken("\"", 1, LexerTag.DoubleQuote), new TestingToken("hello", 2, LexerTag.Text), new TestingToken("\"", 7, LexerTag.DoubleQuote), new TestingToken("\"", 8, LexerTag.DoubleQuote) }); // test to fail // lexer should not be confused by escapment character \' // expecting: // - \" // - \\\' // - A // - \\\' // - \" _checkOutput("\"\'A\'\"", new LexToken[] { new TestingToken("\"", 0, LexerTag.DoubleQuote), new TestingToken("\'", 1, LexerTag.SingleQuote), new TestingToken("A", 2, LexerTag.Text), new TestingToken("\'", 3, LexerTag.SingleQuote), new TestingToken("\"", 4, LexerTag.DoubleQuote) }); return; } [Test] public void Test_Split_NumberSign() { _checkOutput("#hello#", new LexToken[] { new TestingToken("#", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("#", 6, LexerTag.Separator) }); return; } [Test] public void Test_Dot_Character() { _checkOutput("this.Something", new LexToken[] { new TestingToken("this", 0, LexerTag.Text), new TestingToken(".", 4, LexerTag.Separator), new TestingToken("Something", 5, LexerTag.Text) }); return; } [Test] public void Test_Split_ColonCharacter() { _checkOutput(":a:", new LexToken[] { new TestingToken(":", 0, LexerTag.Separator), new TestingToken("a", 1, LexerTag.Text), new TestingToken(":", 2, LexerTag.Separator) }); _checkOutput("a>", new LexToken[] { new TestingToken(">", 0, LexerTag.Separator), new TestingToken("a", 1, LexerTag.Text), new TestingToken(">", 2, LexerTag.Separator) }); _checkOutput(",a,", new LexToken[] { new TestingToken(",", 0, LexerTag.Separator), new TestingToken("a", 1, LexerTag.Text), new TestingToken(",", 2, LexerTag.Separator) }); return; } [Test] public void Test_Split_Equals() { _checkOutput("=a=", new LexToken[] { new TestingToken("=", 0, LexerTag.Separator), new TestingToken("a", 1, LexerTag.Text), new TestingToken("=", 2, LexerTag.Separator) }); return; } [Test] public void Test_Split_New_Line() { _checkOutput("\none\n", new LexToken[] { new TestingToken("\n", 0, LexerTag.EndOfLine), new TestingToken("one", 1, LexerTag.Text), new TestingToken("\n", 4, LexerTag.EndOfLine) }); return; } [Test] public void Test_Split_WhiteSpaces() { // test with space _checkOutput(" hello ", new LexToken[] { new TestingToken(" ", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken(" ", 6, LexerTag.Separator) }); /// test with '\r' _checkOutput("\rhello\r", new LexToken[] { new TestingToken("\r", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("\r", 6, LexerTag.Separator) }); // test with ';' _checkOutput(";hello;", new LexToken[] { new TestingToken(";", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken(";", 6, LexerTag.Separator) }); // test with '[' _checkOutput("[hello[", new LexToken[] { new TestingToken("[", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("[", 6, LexerTag.Separator) }); // test with ']' _checkOutput("]hello]", new LexToken[] { new TestingToken("]", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("]", 6, LexerTag.Separator) }); // test with '(' _checkOutput("(hello(", new LexToken[] { new TestingToken("(", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken("(", 6, LexerTag.Separator) }); // test with ')' _checkOutput(")hello)", new LexToken[] { new TestingToken(")", 0, LexerTag.Separator), new TestingToken("hello", 1, LexerTag.Text), new TestingToken(")", 6, LexerTag.Separator) }); return; } [Test] public void Test_Split_CommentC() { _checkOutput("/*plop/*", new LexToken[] { new TestingToken("/*", 0, LexerTag.CommentC_Open), new TestingToken("plop", 2, LexerTag.Text), new TestingToken("/*", 6, LexerTag.CommentC_Open) }); // test with */ _checkOutput("*/plop*/", new LexToken[] { new TestingToken("*/", 0, LexerTag.CommentC_Close), new TestingToken("plop", 2, LexerTag.Text), new TestingToken("*/", 6, LexerTag.CommentC_Close) }); return; } [Test] public void Test_Split_CommentCpp() { _checkOutput("//plop//", new LexToken[] { new TestingToken("//", 0, LexerTag.CommentCpp), new TestingToken("plop", 2, LexerTag.Text), new TestingToken("//", 6, LexerTag.CommentCpp) }); return; } #region TestingLexer /// /// Subclasses Lexer to access and test internal methods. /// class TestingLexer : Lexer { public TestingLexer() { } public new void Clear() { base.Clear(); } } #endregion #region TestingToken class TestingToken : LexToken { public TestingToken(string text, int index, LexerTag tag) { _text = text; _start = index; _tag = tag; return; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestTokenDictionary.cs0000664000175000017500000002356511504175260026361 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestTokenDictionary { private TestingTokenDictionary _emptyDictionary; private TokenDictionary _filledDictionary; [SetUp] public void SetUp() { Lexer lexer; _emptyDictionary = new TestingTokenDictionary(); lexer = new Lexer(); _filledDictionary = lexer.Dictionary; Assert.That(_filledDictionary, Is.Not.Null); Assert.That(_filledDictionary.Count, Is.GreaterThan(0)); return; } [Test] public void test_default() { Assert.That(_emptyDictionary.Count, Is.EqualTo(0)); return; } [Test] public void add_token() { _emptyDictionary.Add("=", LexerTag.Separator); Assert.That(_emptyDictionary.Count, Is.EqualTo(1)); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void Add_can_throw_NullValueException() { _emptyDictionary.Add(null, LexerTag.Separator); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Token 'one' is already defined.", MatchType = MessageMatch.Contains)] public void Add_can_throw_AlreadyDefinedException() { _emptyDictionary.Add("one", LexerTag.Text); _emptyDictionary.Add("one", LexerTag.Text); // throws exception return; } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Token value must not be empty.", MatchType = MessageMatch.Contains)] public void Add_can_throw_EmptySequenceException() { _emptyDictionary.Add("", LexerTag.Text); // throws exception } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Tokens must be inserted from the longest to the shortest value.", MatchType = MessageMatch.Contains)] public void Add_can_throw_InvalidSortException() { _emptyDictionary.Add("one", LexerTag.CommentC_Close); _emptyDictionary.Add("to", LexerTag.CommentC_Close); _emptyDictionary.Add("four", LexerTag.CommentC_Close); // throws exception return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void PopulateTokenStartingWith_can_throw_NullStarterException() { _emptyDictionary.PopulateTokenStartingWith( null, new List()); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException))] public void PopulateTokenStartingWith_can_throw_NullOutputException() { LexToken token; _emptyDictionary.Add("=", LexerTag.Separator); token = _emptyDictionary[0]; _emptyDictionary.PopulateTokenStartingWith(token, null); // throws exception return; } [Test] public void PopulateTokenStartingWith() { List list; LexToken token_0; LexToken token_1; LexToken token_2; LexToken token_3; LexToken token_4; _emptyDictionary.Add("==", LexerTag.Separator); _emptyDictionary.Add("<=", LexerTag.Separator); _emptyDictionary.Add("=", LexerTag.Separator); _emptyDictionary.Add("<", LexerTag.Separator); _emptyDictionary.Add(";", LexerTag.Separator); token_0 = _emptyDictionary[0]; // == token_1 = _emptyDictionary[1]; // <= token_2 = _emptyDictionary[2]; // = token_3 = _emptyDictionary[3]; // < token_4 = _emptyDictionary[4]; // ; list = new List(); // there is only one token starting with text: "==" list.Clear(); _emptyDictionary.PopulateTokenStartingWith(token_0, list); Assert.That(list.Count, Is.EqualTo(1)); Assert.That(list[0], Is.EqualTo(token_0)); // there is only one token starting with text: "<=" list.Clear(); _emptyDictionary.PopulateTokenStartingWith(token_1, list); Assert.That(list.Count, Is.EqualTo(1)); Assert.That(list[0], Is.EqualTo(token_1)); // but, two tokens start with: "=" list.Clear(); _emptyDictionary.PopulateTokenStartingWith(token_2, list); Assert.That(list.Count, Is.EqualTo(2)); Assert.That(list[0], Is.EqualTo(token_2)); Assert.That(list[1], Is.EqualTo(token_0)); // two tokens start with: "<" list.Clear(); _emptyDictionary.PopulateTokenStartingWith(token_3, list); Assert.That(list.Count, Is.EqualTo(2)); Assert.That(list[0], Is.EqualTo(token_3)); Assert.That(list[1], Is.EqualTo(token_1)); // only one token starts with: ";" list.Clear(); _emptyDictionary.PopulateTokenStartingWith(token_4, list); Assert.That(list.Count, Is.EqualTo(1)); Assert.That(list[0], Is.EqualTo(token_4)); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void TryMatch_can_throw_NullTextException() { _emptyDictionary.TryMatch(null, ""); // throws exception } [Test] [ExpectedException(typeof(ArgumentNullException))] public void TryMatch_can_throw_NullPredictionException() { _emptyDictionary.TryMatch("", null); // throws exception } [Test] public void TryMatch_no_prediction() { LexToken match; string[] tab; tab = new string[] { "\\\"", "\\\'", "/*", "*/", "//", "\\", " ", "\t", "\r", ".", ";", "[", "]", "(", ")", "#", ":", "<", ">", "=", ",", "\n", "'", "\""}; foreach (string item in tab) _emptyDictionary.Add(item, LexerTag.Separator); // this test checks that TryMatch() doesn't fail // to identify tokens when they are passed to the method // as they are declared foreach (string item in tab) { match = _emptyDictionary.TryMatch(item, ""); Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo(item)); Assert.That(match.Tag, Is.EqualTo(LexerTag.Separator)); } foreach (string item in tab) { match = _emptyDictionary.TryMatch("123" + item, ""); Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("123")); Assert.That(match.Tag, Is.EqualTo(LexerTag.Text)); } return; } [Test] public void TryMatch_prediction() { LexToken match; _emptyDictionary.Add("===", LexerTag.Separator); _emptyDictionary.Add("=", LexerTag.Separator); // Use TryMatch as it would be by Lexer when analyzing "a=a" sequence. Assert.That(_emptyDictionary.TryMatch("a", "=a"), Is.Null); match = _emptyDictionary.TryMatch("a=", "a"); // the first 'a' should be consummed Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("a")); Assert.That(match.Tag, Is.EqualTo(LexerTag.Text)); match = _emptyDictionary.TryMatch("=", "a"); // this should consume '=' Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("=")); Assert.That(match.Tag, Is.EqualTo(LexerTag.Separator)); match = _emptyDictionary.TryMatch("a", ""); // this should consume last 'a' Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("a")); Assert.That(match.Tag, Is.EqualTo(LexerTag.Text)); // Use TryMatch as it would be by Lexer when analyzing "a===a" sequence Assert.That(_emptyDictionary.TryMatch("a", "==="), Is.Null); match = _emptyDictionary.TryMatch("a=", "==a"); // this should consume 'a' Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("a")); match = _emptyDictionary.TryMatch("=", "==a"); Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("===")); match = _emptyDictionary.TryMatch("a", ""); Assert.That(match, Is.Not.Null); Assert.That(match.Text, Is.EqualTo("a")); // this should consume last 'a' return; } #region TestingTokenDictionary class TestingTokenDictionary : TokenDictionary { public new void PopulateTokenStartingWith(LexToken starter, List output) { base.PopulateTokenStartingWith(starter, output); } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/CSharpParser/TestToken.cs0000664000175000017500000000322311525533664024331 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.CodeFormatters { [TestFixture] public class TestToken { [Test] public void Test_Equals() { Assert.That(new TestingToken("text", 0, LexerTag.Text).Equals(null), Is.False); Assert.That(new TestingToken("text", 1, LexerTag.Text).Equals("text"), Is.False); Assert.That(new TestingToken("text", 0, LexerTag.Text).Equals( new TestingToken("", 0, LexerTag.Text)), Is.False); Assert.That(new TestingToken("text", 0, LexerTag.Text).Equals( new TestingToken("text", 1, LexerTag.Text)), Is.False); Assert.That(new TestingToken("text", 0, LexerTag.Text).Equals( new TestingToken("text", 0, LexerTag.SingleQuote)), Is.False); Assert.That(new TestingToken("text", 0, LexerTag.Text).Equals( new TestingToken("text", 0, LexerTag.Text)), Is.True); return; } #region TestingToken class TestingToken : LexToken { public TestingToken(string text, int start, LexerTag attr) { _text = text; _start = start; _tag = attr; return; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/nunit.uiexception.tests.csproj0000664000175000017500000001265011707326532025600 0ustar jtaylorjtaylor Debug AnyCPU 9.0.30729 2.0 {092486D0-6AB9-4134-932F-0FDA10704455} Library NUnit.UiException.Tests nunit.uiexception.tests 512 3.5 v3.5 true full false ..\..\..\bin\Debug\tests\ TRACE;DEBUG;CLR_2_0,NET_3_5,CS_3_0 prompt 4 pdbonly true ..\..\..\bin\Release\tests\ TRACE;CLR_2_0,NET_3_5,CS_3_0 prompt 4 3.5 ..\..\..\lib\3.5\NSubstitute.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} test-utilities {3E87A106-EB20-4147-84C8-95B0BB43A1D4} nunit.uiexception.dll CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/GuiException/tests/Controls/0000775000175000017500000000000011742560362021324 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/Controls/TestCodeRenderingContext.cs0000664000175000017500000001570111525533664026600 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.Controls; using System.Drawing; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestCodeRenderingContext { private CodeRenderingContext _context; [SetUp] public void SetUp() { TestingCodeBox box = new TestingCodeBox(); _context = box.RenderingContext; } [Test] public void DefaultState() { Assert.NotNull(_context); Assert.NotNull(_context.Graphics); Assert.NotNull(_context.Font); Assert.That(_context.Font.Size, Is.EqualTo(8)); Assert.That(_context.CurrentLine, Is.EqualTo(-1)); Assert.That(_context.BackgroundColor, Is.EqualTo(Color.White)); Assert.That(_context.CurrentLineBackColor, Is.EqualTo(Color.Red)); Assert.That(_context.CurrentLineForeColor, Is.EqualTo(Color.White)); Assert.That(_context.KeywordColor, Is.EqualTo(Color.Blue)); Assert.That(_context.CommentColor, Is.EqualTo(Color.Green)); Assert.That(_context.CodeColor, Is.EqualTo(Color.Black)); Assert.That(_context.StringColor, Is.EqualTo(Color.Red)); Assert.That(_context[ClassificationTag.Code], Is.EqualTo(_context.CodeColor)); Assert.That(_context[ClassificationTag.Comment], Is.EqualTo(_context.CommentColor)); Assert.That(_context[ClassificationTag.Keyword], Is.EqualTo(_context.KeywordColor)); Assert.That(_context[ClassificationTag.String], Is.EqualTo(_context.StringColor)); CheckBrushes(_context); CheckPens(_context); return; } void CheckBrushes(CodeRenderingContext context) { Assert.NotNull(_context.BackgroundBrush); Assert.NotNull(_context.CurrentLineBackBrush); Assert.NotNull(_context.CurrentLineForeBrush); Assert.NotNull(_context.KeywordBrush); Assert.NotNull(_context.CommentBrush); Assert.NotNull(_context.CodeBrush); Assert.NotNull(_context.StringBrush); Assert.That(_context.GetBrush(ClassificationTag.Code), Is.SameAs(_context.CodeBrush)); Assert.That(_context.GetBrush(ClassificationTag.Comment), Is.SameAs(_context.CommentBrush)); Assert.That(_context.GetBrush(ClassificationTag.Keyword), Is.SameAs(_context.KeywordBrush)); Assert.That(_context.GetBrush(ClassificationTag.String), Is.SameAs(_context.StringBrush)); return; } void CheckPens(CodeRenderingContext context) { Assert.NotNull(_context.BackgroundPen); Assert.NotNull(_context.CurrentLineBackPen); Assert.NotNull(_context.CurrentLineForePen); Assert.NotNull(_context.KeywordPen); Assert.NotNull(_context.CommentPen); Assert.NotNull(_context.CodePen); Assert.NotNull(_context.StringPen); Assert.That(_context.GetPen(ClassificationTag.Code), Is.SameAs(_context.CodePen)); Assert.That(_context.GetPen(ClassificationTag.Comment), Is.SameAs(_context.CommentPen)); Assert.That(_context.GetPen(ClassificationTag.Keyword), Is.SameAs(_context.KeywordPen)); Assert.That(_context.GetPen(ClassificationTag.String), Is.SameAs(_context.StringPen)); return; } [Test] public void Can_Change_Colors() { Brush formerBrush; Pen formerPen; formerBrush = _context.BackgroundBrush; formerPen = _context.BackgroundPen; _context.BackgroundColor = Color.Pink; Assert.That(_context.BackgroundColor, Is.EqualTo(Color.Pink)); Assert.That(_context.BackgroundPen, Is.Not.SameAs(formerPen)); Assert.That(_context.BackgroundBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.CodeBrush; formerPen = _context.CodePen; _context.CodeColor = Color.Pink; Assert.That(_context.CodeColor, Is.EqualTo(Color.Pink)); Assert.That(_context.CodePen, Is.Not.SameAs(formerPen)); Assert.That(_context.CodeBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.CommentBrush; formerPen = _context.CommentPen; _context.CommentColor = Color.Pink; Assert.That(_context.CommentColor, Is.EqualTo(Color.Pink)); Assert.That(_context.CommentPen, Is.Not.SameAs(formerPen)); Assert.That(_context.CommentBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.CurrentLineBackBrush; formerPen = _context.CurrentLineBackPen; _context.CurrentLineBackColor = Color.Pink; Assert.That(_context.CurrentLineBackColor, Is.EqualTo(Color.Pink)); Assert.That(_context.CurrentLineBackPen, Is.Not.SameAs(formerPen)); Assert.That(_context.CurrentLineBackBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.CurrentLineForeBrush; formerPen = _context.CurrentLineForePen; _context.CurrentLineForeColor = Color.Pink; Assert.That(_context.CurrentLineForeColor, Is.EqualTo(Color.Pink)); Assert.That(_context.CurrentLineForePen, Is.Not.SameAs(formerPen)); Assert.That(_context.CurrentLineForeBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.KeywordBrush; formerPen = _context.KeywordPen; _context.KeywordColor = Color.Pink; Assert.That(_context.KeywordColor, Is.EqualTo(Color.Pink)); Assert.That(_context.KeywordPen, Is.Not.SameAs(formerPen)); Assert.That(_context.KeywordBrush, Is.Not.SameAs(formerBrush)); formerBrush = _context.StringBrush; formerPen = _context.StringPen; _context.StringColor = Color.Pink; Assert.That(_context.StringColor, Is.EqualTo(Color.Pink)); Assert.That(_context.StringPen, Is.Not.SameAs(formerPen)); Assert.That(_context.StringBrush, Is.Not.SameAs(formerBrush)); CheckPens(_context); CheckBrushes(_context); return; } class TestingCodeBox : CodeBox { public CodeRenderingContext RenderingContext { get { return (_workingContext); } } } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestCodeBox.cs0000664000175000017500000004246411544451536024052 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using NSubstitute; using NUnit.Framework; using System.Drawing; using NUnit.UiException.Controls; using NUnit.UiException.CodeFormatters; using System.Windows.Forms; namespace NUnit.UiException.Tests.Controls { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestCodeBox { private TestingCodeBox _box; private FormattedCode _someText; private FormattedCode _someCode; private IFormatterCatalog _mockFormatter; private ICodeRenderer _mockRenderer; [SetUp] public void SetUp() { _mockFormatter = Substitute.For(); _mockRenderer = Substitute.For(); _box = new TestingCodeBox(_mockFormatter, _mockRenderer); _box.Width = 150; _box.Height = 150; _someText = Format("some C# code", ""); _someCode = Format("some C# code", "C#"); return; } FormattedCode Format(string text, string language) { ICodeFormatter formatter; if (language == "C#") formatter = new CSharpCodeFormatter(); else formatter = new PlainTextCodeFormatter(); return (formatter.Format(text)); } TestingCodeBox SetupCodeBox(FormattedCode code, SizeF size) { TestingCodeBox box; box = new TestingCodeBox(_mockFormatter, _mockRenderer); _mockFormatter.Format(code.Text, "").Returns(code); _mockRenderer.GetDocumentSize(code, box.RenderingContext.Graphics, box.RenderingContext.Font).Returns(size); box.Text = code.Text; Assert.That(box.Text, Is.EqualTo(code.Text)); return (box); } [Test] public void DefaultState() { CodeBox box = new CodeBox(); Assert.That(box.Text, Is.EqualTo("")); Assert.That(box.Language, Is.EqualTo("")); Assert.True(box.AutoScroll); Assert.That(box.AutoScrollPosition, Is.EqualTo(new Point(0, 0))); Assert.That(box.AutoScrollMinSize, Is.EqualTo(new Size(0, 0))); Assert.False(box.ShowCurrentLine); Assert.That(box.CurrentLine, Is.EqualTo(-1)); Assert.That(box.CurrentLineBackColor, Is.EqualTo(Color.Red)); Assert.That(box.CurrentLineForeColor, Is.EqualTo(Color.White)); Assert.That(box.BackColor, Is.EqualTo(Color.White)); Assert.That(box.Font.Size, Is.EqualTo(8)); return; } [Test] public void Format_Text_With_Language() { // when setting a text, the underlying textFormatter should be called // to format data in the current language mode. // The result should be assigned to the underlying display. _mockFormatter.Format(_someText.Text, "").Returns(_someText); _mockRenderer.GetDocumentSize(_someText, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(new SizeF(100, 100)); _box.Text = _someText.Text; Assert.That(_box.Text, Is.EqualTo(_someText.Text)); Assert.That(_box.AutoScrollMinSize, Is.EqualTo(new Size(100, 100))); // passing null to Text as same effect than passing "" _mockFormatter.Format("", "").Returns(FormattedCode.Empty); _mockRenderer.GetDocumentSize(FormattedCode.Empty, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(new SizeF(0, 0)); _box.Text = null; Assert.That(_box.Text, Is.EqualTo("")); return; } [Test] public void OnPaint() { TestingCodeBox box = SetupCodeBox(_someText, new SizeF(300, 400)); box.Width = 150; box.Height = 150; box.FireOnPaint(); _mockRenderer.Received().DrawToGraphics(_someText, box.RenderingContext, new Rectangle(0, 0, 150, 150)); return; } [Test] public void Changing_Language_Causes_Reformatting() { _box = SetupCodeBox(_someCode, new SizeF(200, 400)); _mockFormatter.Format(_someCode.Text, "C#").Returns(_someCode); _mockRenderer.GetDocumentSize(_someCode, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(new SizeF(200, 400)); _box.Language = "C#"; Assert.That(_box.Language, Is.EqualTo("C#")); // setting null in language is same as setting "" or "Plain text" _mockFormatter.Format(_someCode.Text, "").Returns(_someText); _mockRenderer.GetDocumentSize(_box.FormattedCode, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(new SizeF(100, 100)); _box.Language = null; Assert.That(_box.Language, Is.EqualTo("")); return; } [Test] public void Changing_Font_Causes_Reformatting() { Font courier14 = new Font("Courier New", 14); _box = SetupCodeBox(_someCode, new SizeF(200, 400)); _mockFormatter.Format(_someCode.Text, "").Returns(_someCode); _mockRenderer.GetDocumentSize(_someCode, _box.RenderingContext.Graphics, courier14).Returns(new SizeF(200, 400)); _box.Font = courier14; Assert.That(_box.RenderingContext.Font, Is.SameAs(_box.Font)); return; } [Test] public void CurrentLine() { FormattedCode data = Format( "line 0\r\nline 1\r\nline 2\r\nline 3\r\nline 4\r\nline 5\r\nline 6\r\nline 7\r\n", ""); _box = SetupCodeBox(data, new SizeF(200, 400)); _box.Height = 30; // CurrentLine: 0 _mockRenderer.LineIndexToYCoordinate(0, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(0f); _box.CurrentLine = 0; Assert.That(_box.CurrentLine, Is.EqualTo(0)); Assert.That(_box.AutoScrollPosition, Is.EqualTo(new Point(0, 0))); // CurrentLine: 7 _mockRenderer.LineIndexToYCoordinate(7, _box.RenderingContext.Graphics, _box.RenderingContext.Font).Returns(390f); _box.CurrentLine = 7; Assert.That(_box.CurrentLine, Is.EqualTo(7)); Assert.That(_box.AutoScrollPosition, Is.EqualTo(new Point(0, -375))); return; } [Test] public void Can_Disable_ShowCurrentLine() { TestingRenderer renderer = new TestingRenderer(); _box = new TestingCodeBox(new GeneralCodeFormatter(), renderer); _box.Text = "line 1\r\nline 2\r\nline 3\r\n"; _box.ShowCurrentLine = true; _box.CurrentLine = 1; _box.FireOnPaint(); Assert.That(renderer.CURRENTLINE_INDEX, Is.EqualTo(1)); _box.ShowCurrentLine = false; _box.FireOnPaint(); Assert.That(renderer.CURRENTLINE_INDEX, Is.EqualTo(-1)); _box.ShowCurrentLine = true; _box.FireOnPaint(); Assert.That(renderer.CURRENTLINE_INDEX, Is.EqualTo(1)); return; } [Test] public void Can_Set_Back_And_Fore_Colors() { CodeBox box; box = new CodeBox(); box.Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; box.CurrentLineBackColor = Color.Black; Assert.That(box.CurrentLineBackColor, Is.EqualTo(Color.Black)); box.CurrentLineForeColor = Color.Blue; Assert.That(box.CurrentLineForeColor, Is.EqualTo(Color.Blue)); return; } class TestingCodeBox : CodeBox { public TestingCodeBox() { } public TestingCodeBox(IFormatterCatalog formatter, ICodeRenderer renderer) : base(formatter, renderer) { } public CodeRenderingContext RenderingContext { get { return (_workingContext); } } public FormattedCode FormattedCode { get { return (_formattedCode); } } public new void OnScroll(ScrollEventArgs args) { base.OnScroll(args); } public void FireOnPaint() { OnPaint(new PaintEventArgs(_workingContext.Graphics, new Rectangle(0, 0, Width, Height))); return; } } class TestingRenderer : ICodeRenderer { public int CURRENTLINE_INDEX; #region ICodeRenderer Membres public void DrawToGraphics(FormattedCode code, CodeRenderingContext args, Rectangle viewport) { CURRENTLINE_INDEX = args.CurrentLine; } public SizeF GetDocumentSize(FormattedCode code, Graphics g, Font font) { return (new SizeF(200, 400)); } public float LineIndexToYCoordinate(int lineIndex, Graphics g, Font font) { return (0); } #endregion } } /* [TestFixture] public class TestCodeBox { private InternalCodeBox _empty; private InternalCodeBox _filled; private int _repaintNotification; private int _textChangedNotification; [SetUp] public void SetUp() { _empty = new InternalCodeBox(); _filled = new InternalCodeBox(); _filled.Text = "111\r\n" + "222\r\n" + "333\r\n"; _filled.HighlightedLine = 1; _filled.Repainted += new RepaintEventArgs(_filled_Repainted); _filled.TextChanged += new EventHandler(_filled_TextChanged); _repaintNotification = 0; return; } void _filled_TextChanged(object sender, EventArgs e) { _textChangedNotification++; } void _filled_Repainted(object sender, EventArgs e) { _repaintNotification++; } [Test] public void Test_Default() { Assert.That(_empty.Text, Is.EqualTo("")); Assert.That(_empty.HighlightedLine, Is.EqualTo(0)); Assert.That(_empty.Viewport, Is.Not.Null); Assert.That(_empty.FirstLine, Is.EqualTo("")); Assert.That(_empty.CurrentLineNumber, Is.EqualTo(1)); Assert.That(_empty.MouseWheelDistance, Is.EqualTo(OLD_CodeBox.DEFAULT_MOUSEWHEEL_DISTANCE)); Assert.That(_empty.Viewport.CharHeight, Is.GreaterThan(1)); Assert.That(_empty.Viewport.CharWidth, Is.GreaterThan(1)); Assert.That(_empty.Viewport.Width, Is.GreaterThan(1)); Assert.That(_empty.Viewport.Height, Is.GreaterThan(1)); return; } [Test] public void Test_Filled() { Assert.That(_filled.Text, Is.EqualTo("111\r\n222\r\n333\r\n")); Assert.That(_filled.HighlightedLine, Is.EqualTo(1)); Assert.That(_filled.FirstLine, Is.EqualTo("111")); Assert.That(_filled.CurrentLineNumber, Is.EqualTo(1)); return; } [Test] public void Test_Setting_MouseWheelDistance() { _filled.MouseWheelDistance = 4; Assert.That(_filled.MouseWheelDistance, Is.EqualTo(4)); _filled.MouseWheelDistance = 6; Assert.That(_filled.MouseWheelDistance, Is.EqualTo(6)); return; } [Test] public void Test_Setting_Text() { _textChangedNotification = 0; _filled.Text = "hello world"; Assert.That(_repaintNotification, Is.EqualTo(1)); Assert.That(_textChangedNotification, Is.EqualTo(1)); // test to fail _filled.Text = null; Assert.That(_filled.Text, Is.EqualTo("")); return; } [Test] [ExpectedException(typeof(ArgumentNullException))] public void SetFormattedCode_Can_Throw_FormatNullException() { _filled.SetFormattedCode(null); // throws exception } [Test] public void Test_Setting_FormattedCode() { CSharpCodeFormatter textFormatter; FormattedCode format; textFormatter = new CSharpCodeFormatter(); format = textFormatter.Format("namespace test { class MyClass { } }\r\n"); _filled.SetFormattedCode(format); Assert.That(_filled.Text, Is.EqualTo("namespace test { class MyClass { } }\r\n")); return; } [Test] public void Test_Setting_Size_Invalidate_Box() { _filled.Width = 200; Assert.That(_repaintNotification, Is.EqualTo(1)); _filled.Height = 400; Assert.That(_repaintNotification, Is.EqualTo(2)); Assert.That(_filled.Viewport.Width, Is.EqualTo(200)); Assert.That(_filled.Viewport.Height, Is.EqualTo(400)); return; } [Test] public void Test_Setting_HighlighedLine_Invalidate_Box() { _filled.HighlightedLine = 2; Assert.That(_repaintNotification, Is.EqualTo(1)); } [Test] public void Test_Changing_Location_Invalidate_Box() { _filled.Viewport.Location = new PointF(0, 1); Assert.That(_repaintNotification, Is.EqualTo(1)); } [Test] public void Test_TranslateView() { _filled.Text = "******\r\n******\r\n******\r\n******\r\n******\r\n"; _filled.Viewport.SetCharSize(1, 1); _filled.Viewport.SetViewport(1, 1); _filled.TranslateView(0, 0); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(0, 0))); _filled.TranslateView(2, 1); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(2, 1))); _filled.TranslateView(3, 1); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(5, 2))); return; } [Test] public void Test_CurrentLineNumber() { _filled.Viewport.SetViewport(1, 1); _filled.Viewport.SetCharSize(1, 1); Assert.That(_filled.CurrentLineNumber, Is.EqualTo(1)); _filled.TranslateView(0, 1000); Assert.That(_filled.CurrentLineNumber, Is.EqualTo(_filled.Viewport.TextSource.LineCount)); _filled.TranslateView(0, -2000); Assert.That(_filled.CurrentLineNumber, Is.EqualTo(1)); return; } [Test] public void Test_MouseWheel_Up() { _filled.Viewport.SetViewport(1, 1); _filled.Viewport.SetCharSize(1, 1); _filled.Viewport.SetPosition(0, 2); _filled.MouseWheelDistance = 1; _filled.HandleMouseWheelUp(); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(0, 1))); _filled.HandleMouseWheelUp(); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(0, 0))); return; } [Test] public void Test_MouseWheel_Down() { _filled.Viewport.SetViewport(1, 1); _filled.Viewport.SetCharSize(1, 1); _filled.Viewport.SetPosition(0, 0); _filled.MouseWheelDistance = 1; _filled.HandleMouseWheelDown(); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(0, 1))); _filled.HandleMouseWheelDown(); Assert.That(_filled.Viewport.Location, Is.EqualTo(new PointF(0, 2))); return; } #region InternalCodeBox delegate void RepaintEventArgs(object sender, EventArgs e); class InternalCodeBox : OLD_CodeBox { public event RepaintEventArgs Repainted; protected override void Repaint() { base.Repaint(); if (Repainted != null) Repainted(this, new EventArgs()); return; } public new void HandleMouseWheelUp() { base.HandleMouseWheelUp(); } public new void HandleMouseWheelDown() { base.HandleMouseWheelDown(); } } #endregion } */ } #endifNUnit-2.6.0.12051/src/GuiException/tests/Controls/TestDefaultCodeRenderer.cs0000664000175000017500000002471211525533664026373 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.Controls; using NUnit.UiException.CodeFormatters; using System.Drawing; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestDefaultCodeRenderer { private ICodeRenderer _renderer; private FormattedCode _empty; private FormattedCode _loremIpsum; private FormattedCode _text3x7; private CodeRenderingContext _args; [SetUp] public void SetUp() { _renderer = new DefaultCodeRenderer(); ICodeFormatter formatter = new PlainTextCodeFormatter(); _empty = formatter.Format(""); _text3x7 = formatter.Format( "111\r\n" + "222\r\n" + "333\r\n" + "444\r\n" + "555\r\n" + "666\r\n" + "777\r\n"); _loremIpsum = formatter.Format( "Lorem ipsum dolor sit\r\n" + "amet, consectetur adipiscing elit.\r\n" + "Maecenas a nisi. In imperdiet, orci in\r\n" + "porta facilisis,\r\n" + "odio purus iaculis est, non varius urna turpis in mi.\r\n" + // longest line "Nullam dictum. Ut iaculis dignissim nulla.\r\n" + "Nullam condimentum porttitor leo.\r\n" + "Integer a odio et\r\n" + "velit suscipit pulvinar."); Image img = new Bitmap(100, 100); _args = new CodeRenderingContext(); _args.Graphics = Graphics.FromImage(img); _args.Font = new Font("Courier New", 12); return; } [Test] public void DrawToGraphics_Can_Raise_ArgumentNullException() { try { _renderer.DrawToGraphics(null, _args, new Rectangle()); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("code")); } try { _renderer.DrawToGraphics(_loremIpsum, null, new Rectangle()); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("g")); } return; } [Test] public void GetDocumentSize_Can_Raise_ArgumentNullException() { try { _renderer.GetDocumentSize(null, _args.Graphics, _args.Font); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("code")); } try { _renderer.GetDocumentSize(_loremIpsum, null, _args.Font); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("g")); } try { _renderer.GetDocumentSize(_loremIpsum, _args.Graphics, null); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("font")); } return; } [Test] public void LineIndexToYCoordinate_Can_Raise_ArgumentNullException() { try { _renderer.LineIndexToYCoordinate(0, null, _args.Font); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("g")); } try { _renderer.LineIndexToYCoordinate(0, _args.Graphics, null); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("font")); } } [Test] public void LineIndexToYCoordinate() { SizeF sz = _args.Graphics.MeasureString("m", _args.Font); Assert.That(_renderer.LineIndexToYCoordinate(0, _args.Graphics, _args.Font), Is.EqualTo(0)); Assert.That(_renderer.LineIndexToYCoordinate(1, _args.Graphics, _args.Font), Is.EqualTo(sz.Height)); Assert.That(_renderer.LineIndexToYCoordinate(2, _args.Graphics, _args.Font), Is.EqualTo(sz.Height * 2)); Assert.That(_renderer.LineIndexToYCoordinate(3, _args.Graphics, _args.Font), Is.EqualTo(sz.Height * 3)); return; } [Test] public void GetDocumentSize() { SizeF expSize; SizeF docSize; // measures text3x7's size expSize = _args.Graphics.MeasureString("111", _args.Font); docSize = _renderer.GetDocumentSize(_text3x7, _args.Graphics, _args.Font); Assert.That(docSize.Width, Is.EqualTo(expSize.Width)); Assert.That(docSize.Height, Is.EqualTo(7 * expSize.Height)); // measures loremIpsum's size expSize = _args.Graphics.MeasureString( "odio purus iaculis est, non varius urna turpis in mi.", _args.Font); docSize = _renderer.GetDocumentSize(_loremIpsum, _args.Graphics, _args.Font); Assert.That(docSize.Width, Is.EqualTo(expSize.Width)); Assert.That(docSize.Height, Is.EqualTo(9 * expSize.Height)); return; } [Test] public void ViewportLines() { DefaultCodeRenderer renderer = new DefaultCodeRenderer(); PaintLineLocation[] lines; RectangleF viewport = new RectangleF(0, 0, 2, 4); Assert.That(renderer.ViewportLines(_empty, viewport, 1), Is.Not.Null); Assert.That(renderer.ViewportLines(_empty, viewport, 1).Length, Is.EqualTo(0)); // Using the given text and viewport // // document viewport // 1 1 1 * * // 2 2 2 * * // 3 3 3 * * // 4 4 4 * * // 5 5 5 // 6 6 6 // 7 7 7 // // Tests below check what area of the document will be seen // through the viewport window. For simplicity issue, we assume // the code is using a Font of docSize 1x1 in pixel. lines = renderer.ViewportLines(_text3x7, viewport, 1); Assert.That(lines.Length, Is.EqualTo(5)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(0, "111", new PointF(0, 0)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(1, "222", new PointF(0, 1)))); Assert.That(lines[2], Is.EqualTo(new PaintLineLocation(2, "333", new PointF(0, 2)))); Assert.That(lines[3], Is.EqualTo(new PaintLineLocation(3, "444", new PointF(0, 3)))); Assert.That(lines[4], Is.EqualTo(new PaintLineLocation(4, "555", new PointF(0, 4)))); viewport = new RectangleF(2, 0, 2, 4); lines = renderer.ViewportLines(_text3x7, viewport, 1); Assert.That(lines.Length, Is.EqualTo(5)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(0, "111", new PointF(-2, 0)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(1, "222", new PointF(-2, 1)))); Assert.That(lines[2], Is.EqualTo(new PaintLineLocation(2, "333", new PointF(-2, 2)))); Assert.That(lines[3], Is.EqualTo(new PaintLineLocation(3, "444", new PointF(-2, 3)))); Assert.That(lines[4], Is.EqualTo(new PaintLineLocation(4, "555", new PointF(-2, 4)))); viewport = new RectangleF(0, -3, 2, 4); lines = renderer.ViewportLines(_text3x7, viewport, 1); Assert.That(lines.Length, Is.EqualTo(2)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(0, "111", new PointF(0, 3)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(1, "222", new PointF(0, 4)))); viewport = new RectangleF(1, 5, 2, 4); lines = renderer.ViewportLines(_text3x7, viewport, 1); Assert.That(lines.Length, Is.EqualTo(2)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(5, "666", new PointF(-1, 0)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(6, "777", new PointF(-1, 1)))); // using float values for location viewport = new RectangleF(1.5f, 2.5f, 2, 4); lines = renderer.ViewportLines(_text3x7, viewport, 1); Assert.That(lines.Length, Is.EqualTo(5)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(2, "333", new PointF(-1.5f, -0.5f)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(3, "444", new PointF(-1.5f, 0.5f)))); Assert.That(lines[2], Is.EqualTo(new PaintLineLocation(4, "555", new PointF(-1.5f, 1.5f)))); Assert.That(lines[3], Is.EqualTo(new PaintLineLocation(5, "666", new PointF(-1.5f, 2.5f)))); Assert.That(lines[4], Is.EqualTo(new PaintLineLocation(6, "777", new PointF(-1.5f, 3.5f)))); // using a font sized as 8x15 viewport = new RectangleF(1.5f * 8, 2.5f * 15, 2 * 8, 4 * 15); lines = renderer.ViewportLines(_text3x7, viewport, 15); Assert.That(lines.Length, Is.EqualTo(5)); Assert.That(lines[0], Is.EqualTo(new PaintLineLocation(2, "333", new PointF(-1.5f * 8, -7.5f)))); Assert.That(lines[1], Is.EqualTo(new PaintLineLocation(3, "444", new PointF(-1.5f * 8, 7.5f)))); Assert.That(lines[2], Is.EqualTo(new PaintLineLocation(4, "555", new PointF(-1.5f * 8, 22.5f)))); Assert.That(lines[3], Is.EqualTo(new PaintLineLocation(5, "666", new PointF(-1.5f * 8, 37.5f)))); Assert.That(lines[4], Is.EqualTo(new PaintLineLocation(6, "777", new PointF(-1.5f * 8, 52.5f)))); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestSplitterBox.cs0000664000175000017500000003743211525533664025007 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; using System.Drawing; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestSplitterBox { private TestingSplitterBox _vertical; private TestingSplitterBox _horizontal; [SetUp] public void SetUp() { _vertical = new TestingSplitterBox(); _horizontal = new TestingSplitterBox(); _horizontal.Orientation = Orientation.Horizontal; return; } [Test] public void DefaultState() { Assert.That(_vertical.Orientation, Is.EqualTo(Orientation.Vertical)); Assert.That(_vertical.Width, Is.EqualTo(150)); Assert.That(_vertical.Height, Is.EqualTo(150)); Assert.NotNull(_vertical.Control1); Assert.NotNull(_vertical.Control2); Assert.That(_vertical.Controls.Count, Is.EqualTo(2)); Assert.That(_vertical.Controls[0], Is.SameAs(_vertical.Control1)); Assert.That(_vertical.Controls[1], Is.SameAs(_vertical.Control2)); Assert.That(_vertical.SplitterDistance, Is.EqualTo(0.5f)); Assert.That(_horizontal.SplitterDistance, Is.EqualTo(0.5f)); CheckVerticalLayout(_vertical, 0.5f); CheckVerticalRectangles(_vertical); CheckHorizontalLayout(_horizontal, 0.5f); CheckHorizontalRectangles(_horizontal); return; } void CheckVerticalLayout(TestingSplitterBox splitter, float x) { int left = (int)Math.Max(0, x * splitter.Width - SplitterBox.SPLITTER_HALFSIZE); left = Math.Min(left, splitter.Width - SplitterBox.SPLITTER_SIZE); Assert.That(splitter.Orientation, Is.EqualTo(Orientation.Vertical)); Assert.False(splitter.SplitterRectangle.IsEmpty); Assert.That(splitter.SplitterRectangle.Left, Is.EqualTo(left)); Assert.That(splitter.SplitterRectangle.Top, Is.EqualTo(0)); Assert.That(splitter.SplitterRectangle.Width, Is.EqualTo(SplitterBox.SPLITTER_SIZE)); Assert.That(splitter.SplitterRectangle.Height, Is.EqualTo(splitter.Height)); Assert.That(splitter.Control1.Left, Is.EqualTo(0)); Assert.That(splitter.Control1.Top, Is.EqualTo(0)); Assert.That(splitter.Control1.Right, Is.EqualTo(splitter.SplitterRectangle.Left)); Assert.That(splitter.Control1.Height, Is.EqualTo(splitter.Height)); Assert.That(splitter.Control2.Left, Is.EqualTo(splitter.SplitterRectangle.Right)); Assert.That(splitter.Control2.Top, Is.EqualTo(0)); Assert.That(splitter.Control2.Right, Is.EqualTo(splitter.Width)); Assert.That(splitter.Control2.Height, Is.EqualTo(splitter.Height)); return; } void CheckHorizontalLayout(TestingSplitterBox splitter, float y) { int top = (int)Math.Max(0, y * splitter.Height - SplitterBox.SPLITTER_HALFSIZE); top = Math.Min(top, splitter.Height - SplitterBox.SPLITTER_SIZE); Assert.That(splitter.Orientation, Is.EqualTo(Orientation.Horizontal)); Assert.False(splitter.SplitterRectangle.IsEmpty); Assert.That(splitter.SplitterRectangle, Is.EqualTo(new Rectangle(0, top, splitter.Width, SplitterBox.SPLITTER_SIZE))); Assert.That(splitter.Control1.Left, Is.EqualTo(0)); Assert.That(splitter.Control1.Top, Is.EqualTo(0)); Assert.That(splitter.Control1.Right, Is.EqualTo(splitter.Width)); Assert.That(splitter.Control1.Height, Is.EqualTo(splitter.SplitterRectangle.Top)); Assert.That(splitter.Control2.Left, Is.EqualTo(0)); Assert.That(splitter.Control2.Top, Is.EqualTo(splitter.SplitterRectangle.Bottom)); Assert.That(splitter.Control2.Right, Is.EqualTo(splitter.Width)); Assert.That(splitter.Control2.Bottom, Is.EqualTo(splitter.Height)); return; } void CheckVerticalRectangles(TestingSplitterBox splitter) { Assert.False(splitter.Collapse1Rectangle.IsEmpty); Assert.False(splitter.DirectionRectangle.IsEmpty); Assert.False(splitter.Collapse2Rectangle.IsEmpty); int y = (splitter.Height - 41) / 2; Assert.That(splitter.SplitterRectangle.Left, Is.GreaterThanOrEqualTo(0)); Assert.That(splitter.SplitterRectangle.Right, Is.LessThanOrEqualTo(150)); Assert.That(splitter.Collapse1Rectangle, Is.EqualTo(new Rectangle(splitter.SplitterRectangle.Left, y, SplitterBox.SPLITTER_SIZE, SplitterBox.BUTTON_SIZE))); Assert.That(splitter.DirectionRectangle, Is.EqualTo(new Rectangle( splitter.SplitterRectangle.Left, splitter.Collapse1Rectangle.Bottom + 2, SplitterBox.SPLITTER_SIZE, SplitterBox.BUTTON_SIZE))); Assert.That(splitter.Collapse2Rectangle, Is.EqualTo(new Rectangle( splitter.SplitterRectangle.Left, splitter.DirectionRectangle.Bottom + 2, SplitterBox.SPLITTER_SIZE, SplitterBox.BUTTON_SIZE))); return; } void CheckHorizontalRectangles(TestingSplitterBox splitter) { Assert.False(splitter.Collapse1Rectangle.IsEmpty); Assert.False(splitter.DirectionRectangle.IsEmpty); Assert.False(splitter.Collapse2Rectangle.IsEmpty); int x = (splitter.Width - 41) / 2; int y = splitter.SplitterRectangle.Top; Assert.That(splitter.SplitterRectangle.Top, Is.GreaterThanOrEqualTo(0)); Assert.That(splitter.SplitterRectangle.Bottom, Is.LessThanOrEqualTo(splitter.Height)); Assert.That(splitter.Collapse1Rectangle, Is.EqualTo(new Rectangle(x, y, SplitterBox.BUTTON_SIZE, SplitterBox.SPLITTER_SIZE))); Assert.That(splitter.DirectionRectangle, Is.EqualTo(new Rectangle(splitter.Collapse1Rectangle.Right + 2, y, SplitterBox.BUTTON_SIZE, SplitterBox.SPLITTER_SIZE))); Assert.That(splitter.Collapse2Rectangle, Is.EqualTo(new Rectangle(splitter.DirectionRectangle.Right + 2, y, SplitterBox.BUTTON_SIZE, SplitterBox.SPLITTER_SIZE))); return; } [Test] public void CanChangeDefaultControl1() { Control control1 = _vertical.Control1; Panel panel = new Panel(); _vertical.Control1 = panel; Assert.False(_vertical.Controls.Contains(control1)); Assert.True(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); _vertical.Control1 = null; Assert.True(_vertical.Controls.Contains(control1)); Assert.False(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); _vertical.Control1 = null; Assert.True(_vertical.Controls.Contains(control1)); Assert.False(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); return; } [Test] public void CanChangeDefaultControl2() { Control control2 = _vertical.Control2; Panel panel = new Panel(); _vertical.Control2 = panel; Assert.False(_vertical.Controls.Contains(control2)); Assert.True(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); _vertical.Control2 = null; Assert.True(_vertical.Controls.Contains(control2)); Assert.False(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); _vertical.Control2 = null; Assert.True(_vertical.Controls.Contains(control2)); Assert.False(_vertical.Controls.Contains(panel)); CheckVerticalLayout(_vertical, 0.5f); return; } [Test] public void ChangingSizeInvokeDoLayout() { _vertical.Width = 100; CheckVerticalLayout(_vertical, 0.5f); _vertical.Height = 200; CheckVerticalLayout(_vertical, 0.5f); return; } [Test] public void OrientationAffectsLayout() { _vertical.Orientation = Orientation.Horizontal; CheckHorizontalLayout(_vertical, 0.5f); _vertical.Orientation = Orientation.Vertical; CheckVerticalLayout(_vertical, 0.5f); return; } [Test] public void SplitterDistance() { // vertical layout _vertical.SplitterDistance = 0.4f; Assert.That(_vertical.SplitterDistance, Is.EqualTo(0.4f)); CheckVerticalLayout(_vertical, 0.4f); _vertical.SplitterDistance = -1f; Assert.That(_vertical.SplitterDistance, Is.EqualTo(0f)); CheckVerticalLayout(_vertical, 0f); _vertical.SplitterDistance = 2f; Assert.That(_vertical.SplitterDistance, Is.EqualTo(1f)); CheckVerticalLayout(_vertical, 1f); // horizontal layout _horizontal.SplitterDistance = 0.4f; Assert.That(_horizontal.SplitterDistance, Is.EqualTo(0.4f)); CheckHorizontalLayout(_horizontal, 0.4f); _horizontal.SplitterDistance = -1; Assert.That(_horizontal.SplitterDistance, Is.EqualTo(0f)); CheckHorizontalLayout(_horizontal, 0); _horizontal.SplitterDistance = 2f; Assert.That(_horizontal.SplitterDistance, Is.EqualTo(1f)); CheckHorizontalLayout(_horizontal, 1); return; } [Test] public void PointToSplit() { // vertical layout _vertical.PointToSplit((int)(_vertical.Width * 0.4f), 0); CheckVerticalLayout(_vertical, 0.4f); _vertical.PointToSplit(-1, 0); CheckVerticalLayout(_vertical, 0f); _vertical.PointToSplit(_vertical.Width * 2, 0); CheckVerticalLayout(_vertical, 1f); // horizontal layout _horizontal.PointToSplit(0, (int)(_horizontal.Height * 0.4f)); CheckHorizontalLayout(_horizontal, 0.4f); _horizontal.PointToSplit(0, -1); CheckHorizontalLayout(_horizontal, 0); _horizontal.PointToSplit(0, _horizontal.Height * 2); CheckHorizontalLayout(_horizontal, 1); return; } [Test] public void CollapseControl() { // test with vertical layout _vertical.CollapseControl1(); CheckVerticalRectangles(_vertical); CheckVerticalLayout(_vertical, 0); _vertical.CollapseControl2(); CheckVerticalRectangles(_vertical); CheckVerticalLayout(_vertical, 1); // test with horizontal layout _horizontal.CollapseControl1(); CheckHorizontalRectangles(_horizontal); CheckHorizontalLayout(_horizontal, 0); _horizontal.CollapseControl2(); CheckHorizontalRectangles(_horizontal); CheckHorizontalLayout(_horizontal, 1); return; } [Test] public void MouseActions() { // test 1: check ability to move splitter _vertical = new TestingSplitterBox(); _vertical.FireMouseDown(_vertical.SplitterRectangle.Left + 1, 1); _vertical.FireMouseMove(0, 1); _vertical.FireMouseUp(0, 1); Assert.That(_vertical.SplitterDistance, Is.EqualTo(0)); // test 2: splitter doesn't move when mouse down occurs while // the mouse is hovering Collapse1Rectangle _vertical = new TestingSplitterBox(); _vertical.FireMouseDown( _vertical.Collapse1Rectangle.Left + 1, _vertical.Collapse1Rectangle.Top + 1); _vertical.FireMouseMove(0, 1); _vertical.FireMouseUp(0, 1); Assert.That(_vertical.SplitterDistance, Is.EqualTo(0.5f)); // test 3: mouse down occurs on SplitterRectangle area (except the buttons) // mouse up occurs on Collapse1Rectangle // CollapseControl1() should not be triggered and splitter // should be at the last notified mouse position _vertical = new TestingSplitterBox(); _vertical.FireMouseDown(_vertical.SplitterRectangle.Left + 1, 1); _vertical.FireMouseMove(150, 0); _vertical.FireMouseUp(_vertical.Collapse1Rectangle.Left + 1, _vertical.Collapse1Rectangle.Top + 1); Assert.That(_vertical.SplitterDistance, Is.EqualTo(1)); // test 4: mouse down occurs on SplitterRectangle // mouse up occurs on Collapse2Rectangle // CollapseControl2 shouldn't be triggered and splitter // should be at the last notified mouse position _vertical = new TestingSplitterBox(); _vertical.FireMouseDown(_vertical.SplitterRectangle.Left + 1, 1); _vertical.FireMouseMove(0, 0); _vertical.FireMouseUp(_vertical.Collapse2Rectangle.Left + 1, _vertical.Collapse2Rectangle.Top + 1); Assert.That(_vertical.SplitterDistance, Is.EqualTo(0)); // test 5: mouse down occurs on SplitterRectangle // mouse up occurs on DirectionRectangle // Orientation shouldn't be triggered and splitter // should be at the last notified mouse position _vertical = new TestingSplitterBox(); _vertical.FireMouseDown(_vertical.SplitterRectangle.Left + 1, 1); _vertical.FireMouseMove(0, 0); _vertical.FireMouseUp(_vertical.DirectionRectangle.Left + 1, _vertical.DirectionRectangle.Top + 1); Assert.That(_vertical.SplitterDistance, Is.EqualTo(0)); Assert.That(_vertical.Orientation, Is.EqualTo(Orientation.Vertical)); return; } class TestingSplitterBox : SplitterBox { public new Rectangle Collapse1Rectangle { get { return (base.Collapse1Rectangle); } } public new Rectangle Collapse2Rectangle { get { return (base.Collapse2Rectangle); } } public new Rectangle DirectionRectangle { get { return (base.DirectionRectangle); } } public void FireMouseDown(int x, int y) { OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, x, y, 0)); } public void FireMouseMove(int x, int y) { OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, x, y, 0)); } public void FireMouseUp(int x, int y) { OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, x, y, 0)); } } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestDefaultErrorListRenderer.cs0000664000175000017500000002010311525533664027434 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.Controls; using System.Drawing; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestDefaultErrorListRenderer { private ErrorList _empty; private ErrorList _filled; private DefaultErrorListRenderer _renderer; private Graphics _gr; [SetUp] public void SetUp() { _empty = new ErrorList(); _filled = new ErrorList(); _filled.StackTrace = "à SomeClass.SomeMethod() dans C:\\folder\\file1.cs:ligne 20\r\n" + "à ExternClass.ExternMethod()\r\n" + "à AnotherExternClass.AnotherExternMethod()\r\n" + "à SomeClass2.SomeMethod2() dans C:\\folder\\file2.cs:ligne 42\r\n" + "à SomeClass3.SomeMethod3() dans C:\\folder\\AnotherFile2.cs:ligne 93\r\n"; _renderer = new DefaultErrorListRenderer(); Image img = new Bitmap(300, 100); _gr = Graphics.FromImage(img); return; } [Test] public void DefaultState() { Assert.NotNull(_renderer.Font); Assert.That(_renderer.Font.Size, Is.EqualTo(8.25f)); return; } [Test] public void MeasureItem() { TestingRenderer renderer = new TestingRenderer(); SizeF exp; SizeF actual; ErrorItem itemClass = new ErrorItem("/dir/f.cs", "0123456789012.a()", 3); ErrorItem itemMethod = new ErrorItem("/dir/f.cs", "a.0123456789012()", 3); ErrorItem itemFile = new ErrorItem("/dir/0123456789012.cs", "a.b()", 3); // measure an item whoose width should be determined // by class field value exp = _gr.MeasureString("0123456789012", renderer.Font); actual = renderer.MeasureItem(_gr, itemClass); int itemHeight = renderer.Font.Height * 4 + 6; Assert.That((int)actual.Width, Is.EqualTo((int)exp.Width + 16)); Assert.That((int)actual.Height, Is.EqualTo(itemHeight)); // measure an item whoose width should be determined // by method field value exp = _gr.MeasureString("0123456789012()", renderer.Font); actual = renderer.MeasureItem(_gr, itemMethod); Assert.That((int)actual.Width, Is.EqualTo((int)exp.Width + 16)); Assert.That((int)actual.Height, Is.EqualTo(itemHeight)); // measure an item whoose width should be determined // by filename field value exp = _gr.MeasureString("0123456789012.cs", renderer.Font); actual = renderer.MeasureItem(_gr, itemFile); Assert.That((int)actual.Width, Is.EqualTo((int)exp.Width + 16)); Assert.That((int)actual.Height, Is.EqualTo(itemHeight)); return; } [Test] public void ItemAt() { ErrorItem item; int itemHeight = _renderer.Font.Height * 4 + 6; item = _renderer.ItemAt(_filled.Items, _gr, new Point(0, 0)); Assert.NotNull(item); Assert.That(item, Is.EqualTo(_filled.Items[0])); item = _renderer.ItemAt(_filled.Items, _gr, new Point(0, itemHeight + 1)); Assert.NotNull(item); Assert.That(item, Is.EqualTo(_filled.Items[1])); Assert.Null(_renderer.ItemAt(_filled.Items, _gr, new Point(0, 480))); Assert.Null(_renderer.ItemAt(_filled.Items, _gr, new Point(0, -1))); Assert.Null(_renderer.ItemAt(null, _gr, new Point(0, 0))); return; } [Test] public void GetDocumentSize() { TestingRenderer renderer = new TestingRenderer(); Size docSize; SizeF maxSize = SizeF.Empty; // measuring an empty list returns 0x0 docSize = renderer.GetDocumentSize(_empty.Items, _gr); Assert.NotNull(docSize); Assert.That(docSize, Is.EqualTo(new Size(0, 0))); // measure for a non empty list relies on the longest item // in that list foreach(ErrorItem item in _filled.Items) { SizeF sz = renderer.MeasureItem(_gr, item); if (sz.Width > maxSize.Width) maxSize = sz; } docSize = renderer.GetDocumentSize(_filled.Items, _gr); Assert.NotNull(docSize); Assert.That(docSize.Width, Is.EqualTo((int)maxSize.Width)); int itemHeight = renderer.Font.Height * 4 + 6; Assert.That(docSize.Height, Is.EqualTo(_filled.Items.Count * itemHeight)); return; } [Test] public void DrawToGraphics_Can_Throw_ArgumentNullException() { try { _renderer.DrawToGraphics(null, null, _gr, new Rectangle()); // throws exception Assert.Fail(); } catch (Exception e) { Assert.That(e.Message.Contains("items")); } try { _renderer.DrawToGraphics(_filled.Items, null, null, new Rectangle()); // throws exception Assert.Fail(); } catch (Exception e) { Assert.That(e.Message.Contains("g")); } return; } [Test] public void IsDirty() { Rectangle viewport = new Rectangle(0, 0, 200, 200); TestingRenderer renderer = new TestingRenderer(); // no change - true the second time renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); Assert.False(renderer.IsDirty(_filled.Items, _filled.Items[0], viewport)); // changing the list set dirty flag renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); Assert.True(renderer.IsDirty(_empty.Items, _filled.Items[0], viewport)); // changes selected item renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); Assert.True(renderer.IsDirty(_filled.Items, null, viewport)); Assert.True(renderer.IsDirty(_filled.Items, new ErrorItem(_filled.Items[0].Path, _filled.Items[0].FullyQualifiedMethodName, _filled.Items[0].LineNumber), viewport)); // changes viewport renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); Assert.True(renderer.IsDirty(_filled.Items, _filled.Items[0], new Rectangle())); // reversing item order set dirty flag renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); _filled.Items.Reverse(); Assert.True(renderer.IsDirty(_filled.Items, _filled.Items[_filled.Items.Count - 1], viewport)); // Calling GetDocumentSize set dirty flag renderer.DrawToGraphics(_filled.Items, _filled.Items[0], _gr, viewport); renderer.GetDocumentSize(_filled.Items, _gr); Assert.True(renderer.IsDirty(_filled.Items, _filled.Items[0], viewport)); return; } class TestingRenderer : DefaultErrorListRenderer { public new SizeF MeasureItem(Graphics g, ErrorItem item) { return (base.MeasureItem(g, item)); } public new bool IsDirty(ErrorItemCollection items, ErrorItem selection, Rectangle viewport) { return (base.IsDirty(items, selection, viewport)); } } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestStackTraceDisplay.cs0000664000175000017500000001032011525533664026065 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestStackTraceDisplay { private StackTraceDisplay _traceDisplay; [SetUp] public void SetUp() { _traceDisplay = new StackTraceDisplay(); } [Test] public void DefaultState() { Assert.NotNull(_traceDisplay.PluginItem); Assert.That(_traceDisplay.PluginItem.Text, Is.EqualTo("Display actual stack trace")); Assert.NotNull(_traceDisplay.OptionItems); Assert.That(_traceDisplay.OptionItems.Length, Is.EqualTo(1)); Assert.That(_traceDisplay.OptionItems[0].Text, Is.EqualTo("Copy stack trace to clipboard")); Assert.That(_traceDisplay.Content, Is.Not.Null); Assert.That(_traceDisplay.Content, Is.TypeOf(typeof(TextBox))); TextBox text = _traceDisplay.Content as TextBox; Assert.That(text.Text, Is.EqualTo("")); Assert.That(text.ReadOnly, Is.True); Assert.That(text.Multiline, Is.True); return; } [Test] public void OnStackTraceChanged() { string trace_1 = "à System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)\r\n" + "à System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)\r\n" + "à System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)\r\n" + "à NUnit.UiException.Tests.MockHelper.Two_Mocks_In_Dictionary() dans C:\\folder\\file1.cs:ligne 87\r\n"; string trace_2 = ""; TextBox content = _traceDisplay.Content as TextBox; _traceDisplay.OnStackTraceChanged(trace_1); Assert.That(content.Text, Is.EqualTo(trace_1)); _traceDisplay.OnStackTraceChanged(trace_2); Assert.That(content.Text, Is.EqualTo(trace_2)); // passing null should not cause error _traceDisplay.OnStackTraceChanged(null); Assert.That(content.Text, Is.EqualTo("")); return; } [Test] [STAThread] public void CopyToClipBoard() { Clipboard.Clear(); _traceDisplay.OnStackTraceChanged("hi, there!"); _traceDisplay.CopyToClipBoard(); Assert.That(Clipboard.ContainsText(), Is.True); Assert.That(Clipboard.GetText(), Is.EqualTo("hi, there!")); // calling twice doesn't add twice same content _traceDisplay.CopyToClipBoard(); _traceDisplay.CopyToClipBoard(); Assert.That(Clipboard.GetText(), Is.EqualTo("hi, there!")); // test to fail: calling copy to clipboard // with an empty stack trace is valid _traceDisplay.OnStackTraceChanged(""); _traceDisplay.CopyToClipBoard(); Assert.That(Clipboard.GetText(), Is.EqualTo("")); return; } [Test] public void FeedingDisplayWithGarbageDoesNotMakeItCrash() { _traceDisplay.OnStackTraceChanged( "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\n" + "Nam at nisi ut neque sollicitudin ultrices. Sed rhoncus\r\n" + "rhoncus arcu. Morbi eu elit ut augue congue luctus. Nullam\r\n" + "eu eros. Nunc blandit varius orci. Mauris condimentum diam\r\n" + "ac ligula. Nullam ut metus. Maecenas sagittis nibh in nisl.\r\n" + "Phasellus rhoncus diam a nulla. Integer vestibulum.\r\n"); TextBox text = _traceDisplay.Content as TextBox; Assert.That(text.Text, Is.Not.Null); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestErrorBrowser.cs0000664000175000017500000001571411544451536025162 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using NSubstitute; using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; namespace NUnit.UiException.Tests.Controls { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestErrorBrowser { private TestingErrorBrowser _errorBrowser; private bool _stackTraceChanged; [SetUp] public void Setup() { _errorBrowser = new TestingErrorBrowser(); _stackTraceChanged = false; _errorBrowser.StackTraceSourceChanged += new EventHandler(_errorBrowser_StackTraceSourceChanged); return; } void _errorBrowser_StackTraceSourceChanged(object sender, EventArgs e) { _stackTraceChanged = true; } [Test] public void DefaultState() { Assert.That(_errorBrowser.LayoutPanel, Is.Not.Null); Assert.That(_errorBrowser.Toolbar, Is.Not.Null); Assert.That(_errorBrowser.SelectedDisplay, Is.Null); Assert.That(_errorBrowser.StackTraceSource, Is.Null); Assert.That(_errorBrowser.Controls.Contains(_errorBrowser.LayoutPanel), Is.True); Assert.That(_errorBrowser.LayoutPanel.Left, Is.EqualTo(0)); Assert.That(_errorBrowser.LayoutPanel.Top, Is.EqualTo(0)); Assert.That(_errorBrowser.LayoutPanel.Toolbar.Height, Is.GreaterThan(0)); Assert.That(_errorBrowser.LayoutPanel.Toolbar, Is.SameAs(_errorBrowser.Toolbar)); Assert.That(_errorBrowser.Toolbar.Count, Is.EqualTo(0)); return; } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "display", MatchType = MessageMatch.Contains)] public void Cannot_Register_Null_Display() { _errorBrowser.RegisterDisplay(null); // throws exception } [Test] public void ErrorDisplay_Plugins_life_cycle_events() { // test #1: Asks ErrorBrowser to register an instance of IErrorDisplay // // - check the process calls successively IErrorDisplay's // properties & methods. // // - when registering an IErrorDisplay for the first time, ErrorBrowser // should select the instance automatically. IErrorDisplay mockTraceDisplay = Substitute.For(); IErrorDisplay mockSourceDisplay = Substitute.For(); ToolStripButton tracePlugin = new ToolStripButton(); Control traceContent = new TextBox(); mockTraceDisplay.PluginItem.Returns(tracePlugin); mockTraceDisplay.Content.Returns(traceContent); _errorBrowser.RegisterDisplay(mockTraceDisplay); mockTraceDisplay.Received().OnStackTraceChanged(_errorBrowser.StackTraceSource); Assert.That(_errorBrowser.SelectedDisplay, Is.Not.Null); Assert.That(_errorBrowser.SelectedDisplay, Is.SameAs(mockTraceDisplay)); Assert.That(_errorBrowser.LayoutPanel.Content, Is.EqualTo(traceContent)); // test #2: Asks ErrorBrowser to register another instance of IErrorDisplay // // - Selection should not change ToolStripItem sourcePluginItem = new ToolStripButton(); Control sourceContent = new Button(); mockSourceDisplay.PluginItem.Returns(sourcePluginItem); _errorBrowser.RegisterDisplay(mockSourceDisplay); Assert.That(_errorBrowser.SelectedDisplay, Is.Not.Null); Assert.That(_errorBrowser.SelectedDisplay, Is.SameAs(mockTraceDisplay)); // test #3: changes current selection mockTraceDisplay.PluginItem.Returns(tracePlugin); mockSourceDisplay.Content.Returns(sourceContent); _errorBrowser.Toolbar.SelectedDisplay = mockSourceDisplay; Assert.That(_errorBrowser.Toolbar.SelectedDisplay, Is.SameAs(mockSourceDisplay)); Assert.That(_errorBrowser.LayoutPanel.Content, Is.EqualTo(sourceContent)); // test #4: changing ErrorSource update all renderers string stack = "à test() C:\\file.cs:ligne 1"; _errorBrowser.StackTraceSource = stack; Assert.That(_errorBrowser.LayoutPanel.Content, Is.TypeOf(typeof(Button))); mockTraceDisplay.Received().OnStackTraceChanged(stack); mockSourceDisplay.Received().OnStackTraceChanged(stack); // clears all renderers _errorBrowser.ClearAll(); Assert.That(_errorBrowser.Toolbar.Count, Is.EqualTo(0)); Assert.That(_errorBrowser.LayoutPanel.Option, Is.Not.Null); Assert.That(_errorBrowser.LayoutPanel.Option, Is.TypeOf(typeof(Panel))); Assert.That(_errorBrowser.LayoutPanel.Content, Is.Not.Null); Assert.That(_errorBrowser.LayoutPanel.Content, Is.TypeOf(typeof(Panel))); return; } [Test] public void Can_Raise_ErrorSourceChanged() { _errorBrowser.StackTraceSource = "à test() C:\\file.cs:ligne 1"; Assert.That(_stackTraceChanged, Is.True); _stackTraceChanged = false; _errorBrowser.StackTraceSource = null; Assert.That(_stackTraceChanged, Is.True); _stackTraceChanged = false; _errorBrowser.StackTraceSource = null; Assert.That(_stackTraceChanged, Is.False); return; } [Test] public void LayoutPanel_Auto_Resizes_When_Parent_Sizes_Change() { _errorBrowser.Width = 250; _errorBrowser.Height = 300; Assert.That(_errorBrowser.LayoutPanel.Width, Is.EqualTo(_errorBrowser.Width)); Assert.That(_errorBrowser.LayoutPanel.Height, Is.EqualTo(_errorBrowser.Height)); _errorBrowser.Width = 50; _errorBrowser.Height = 70; Assert.That(_errorBrowser.LayoutPanel.Width, Is.EqualTo(_errorBrowser.Width)); Assert.That(_errorBrowser.LayoutPanel.Height, Is.EqualTo(_errorBrowser.Height)); return; } class TestingErrorBrowser : ErrorBrowser { public new ErrorToolbar Toolbar { get { return (base.Toolbar); } } public new ErrorPanelLayout LayoutPanel { get { return (base.LayoutPanel); } } } } } #endif NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestErrorPanelLayout.cs0000664000175000017500000001152711525533664025774 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; namespace NUnit.UiException.Tests.Controls { [TestFixture] public class TestErrorPanelLayout { private ErrorPanelLayout _panel; private Control _aToolbar; private Control _aContent; [SetUp] public void SetUp() { _panel = new ErrorPanelLayout(); _aToolbar = new Panel(); _aContent = new Panel(); return; } public static void CheckLayout(Control control, int left, int top, int width, int height) { Assert.That(control.Left, Is.EqualTo(left), "invalid control.Left value"); Assert.That(control.Top, Is.EqualTo(top), "invalid control.Top value"); Assert.That(control.Width, Is.EqualTo(width), "invalid control.Width value"); Assert.That(control.Height, Is.EqualTo(height), "invalid control.Height value"); return; } [Test] public void DefaultState() { Assert.That(_panel.Toolbar, Is.Not.Null); Assert.That(_panel.Content, Is.Not.Null); Assert.That(_panel.Controls.Count, Is.EqualTo(2)); Assert.That(_panel.Width, Is.EqualTo(200)); Assert.That(_panel.Height, Is.EqualTo(200)); // checks default position and docSize for child panels CheckLayout(_panel.Toolbar, 0, 0, 200, ErrorPanelLayout.TOOLBAR_HEIGHT); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 200, 200 - ErrorPanelLayout.TOOLBAR_HEIGHT); return; } [Test] public void Setting_Toolbar() { Control prev; prev = _panel.Toolbar; // replacing toolbar _panel.Toolbar = _aToolbar; Assert.That(_panel.Toolbar, Is.EqualTo(_aToolbar)); Assert.True(_panel.Controls.Contains(_aToolbar)); Assert.False(_panel.Controls.Contains(prev)); CheckLayout(_panel.Toolbar, 0, 0, 200, ErrorPanelLayout.TOOLBAR_HEIGHT); // restoring default state _panel.Toolbar = null; Assert.That(_panel.Toolbar, Is.EqualTo(prev)); Assert.False(_panel.Controls.Contains(_aToolbar)); Assert.True(_panel.Controls.Contains(prev)); CheckLayout(_panel.Toolbar, 0, 0, 200, ErrorPanelLayout.TOOLBAR_HEIGHT); return; } [Test] public void Setting_Content() { Control prev; // replacing Content prev = _panel.Content; _panel.Content = _aContent; Assert.That(_panel.Content, Is.EqualTo(_aContent)); Assert.True(_panel.Controls.Contains(_aContent)); Assert.False(_panel.Controls.Contains(prev)); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 200, 200 - ErrorPanelLayout.TOOLBAR_HEIGHT); // restoring Content to its default state _panel.Content = null; Assert.That(_panel.Content, Is.EqualTo(prev)); Assert.False(_panel.Controls.Contains(_aContent)); Assert.True(_panel.Controls.Contains(prev)); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 200, 200 - ErrorPanelLayout.TOOLBAR_HEIGHT); _panel.Content = _panel.Content; // should not cause error Assert.That(_panel.Content, Is.EqualTo(_panel.Content)); Assert.That(_panel.Controls.Contains(_panel.Content)); Assert.That(_panel.Controls.Count, Is.EqualTo(2)); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 200, 200 - ErrorPanelLayout.TOOLBAR_HEIGHT); return; } [Test] public void Can_Layout_Child_Controls_When_Size_Changed() { _panel.Width = 300; CheckLayout(_panel.Toolbar, 0, 0, 300, ErrorPanelLayout.TOOLBAR_HEIGHT); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 300, 200 - ErrorPanelLayout.TOOLBAR_HEIGHT); _panel.Height = 400; CheckLayout(_panel.Toolbar, 0, 0, 300, ErrorPanelLayout.TOOLBAR_HEIGHT); CheckLayout(_panel.Content, 0, ErrorPanelLayout.TOOLBAR_HEIGHT, 300, 400 - ErrorPanelLayout.TOOLBAR_HEIGHT); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/Controls/TestErrorList.cs0000664000175000017500000003560511544451536024453 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using NSubstitute; using NUnit.Framework; using NUnit.UiException.Controls; using System.Drawing; using System.Windows.Forms; namespace NUnit.UiException.Tests.Controls { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestErrorList { private TestingErrorList _list; private bool _selectionNotification; private string _trace1; private string _trace2; private IErrorListRenderer _mockRenderer; [SetUp] public void SetUp() { _mockRenderer = Substitute.For(); _list = new TestingErrorList(_mockRenderer); _trace1 = "à SomeClass.SomeMethod() dans C:\\folder\\file1.cs:ligne 20\r\n" + "à ExternClass.ExternMethod()\r\n" + "à AnotherExternClass.AnotherExternMethod()\r\n" + "à SomeClass2.SomeMethod2() dans C:\\folder\\file2.cs:ligne 42\r\n" + "à SomeClass3.SomeMethod3() dans C:\\folder\\AnotherFile2.cs:ligne 93\r\n"; _trace2 = "à SomeClass.SomeMethod() dans C:\\folder\\file1.cs:ligne 20\r\n" + "à ExternClass.ExternMethod()\r\n" + "à AnotherExternClass.AnotherExternMethod()\r\n" + "à SomeClass2.SomeMethod2() dans C:\\folder\\file2.cs:ligne 42\r\n"; _selectionNotification = false; _list.SelectedItemChanged += new EventHandler(_list_SelectedItemChanged); return; } void _list_SelectedItemChanged(object sender, EventArgs e) { this._selectionNotification = true; } [Test] public void DefaultState() { Assert.False(_list.AutoSelectFirstItem); Assert.Null(_list.StackTrace); Assert.NotNull(_list.Items); Assert.That(_list.Items.Count, Is.EqualTo(0)); Assert.Null(_list.SelectedItem); Assert.That(_list.HoveredIndex, Is.EqualTo(-1)); Assert.That(_list.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.InitialOrder)); return; } [Test] public void AutoSelectFirstItem() { _list.UseDefaultRenderer(); // Test #1: // Populate StackTrace with one localizable item // When AutoSelectFirstItem is set, we expect the // first item to be automatically selected. _list.AutoSelectFirstItem = true; _list.StackTrace = _trace1; Assert.NotNull(_list.SelectedItem); Assert.That(_list.SelectedItem, Is.EqualTo(_list.Items[0])); // Test #2: // Populate StackTrace with no localizable item // Though AutoSelectFirstItem is set, selection // should be null _list.StackTrace = "à SomeClass.SomeMethod()"; Assert.Null(_list.SelectedItem); // Test #3 // Populate StackTrace with one localizable item. // This time AutoSelectFirstItem is not set. We // expect selection to be null. _list.AutoSelectFirstItem = false; _list.StackTrace = "à SomeClass.SomeMethod() dans C:\\folder\\file.cs:ligne 1"; Assert.Null(_list.SelectedItem); return; } [Test] public void Populate_StackTraceSource() { Size docSize = new Size(200, 500); _mockRenderer.GetDocumentSize(_list.Items, _list.WorkingGraphics).Returns(docSize); _list.StackTrace = _trace1; Assert.That(_list.AutoScrollMinSize, Is.EqualTo(new Size(200, 500))); Assert.That(_list.StackTrace, Is.EqualTo(_trace1)); Assert.That(_list.Items.Count, Is.EqualTo(5)); Assert.That(_list.Items[0].LineNumber, Is.EqualTo(20)); Assert.That(_list.Items[3].LineNumber, Is.EqualTo(42)); Assert.That(_list.Items[4].LineNumber, Is.EqualTo(93)); return; } [Test] public void CurrentSelection() { _list.UseDefaultRenderer(); _list.StackTrace = _trace1; // can select an item with underlying source code _selectionNotification = false; _list.SelectedItem = _list.Items[0]; Assert.That(_list.SelectedItem, Is.EqualTo(_list.Items[0])); Assert.True(_selectionNotification); // attempting to select an item not localizable // has no effect _selectionNotification = false; _list.SelectedItem = _list.Items[1]; Assert.That(_list.SelectedItem, Is.EqualTo(_list.Items[0])); Assert.False(_selectionNotification); // attempting to select an item not in the list // has no effect _selectionNotification = false; _list.SelectedItem = new ErrorItem("C:\\folder\\file42.cs", "SomeClass42.SomeMethod42()", 3); Assert.That(_list.SelectedItem, Is.EqualTo(_list.Items[0])); Assert.False(_selectionNotification); // can pass null to SelectedItem _list.SelectedItem = null; Assert.Null(_list.SelectedItem); Assert.True(_selectionNotification); // select an item an clear StackTrace // selection should be reset to null _list.SelectedItem = _list.Items[0]; _selectionNotification = false; _list.StackTrace = null; Assert.Null(_list.SelectedItem); Assert.True(_selectionNotification); return; } [Test] public void ListOrderPolicy() { ErrorList list = new ErrorList(); // Check ListOrderPolicy behavior when AutoSelectFirstItem is not set list.AutoSelectFirstItem = false; list.ListOrderPolicy = ErrorListOrderPolicy.ReverseOrder; Assert.That(list.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.ReverseOrder)); list.StackTrace = _trace1; Assert.That(list.Items[0].LineNumber, Is.EqualTo(93)); Assert.That(list.Items[1].LineNumber, Is.EqualTo(42)); Assert.That(list.Items[2].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[3].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[4].LineNumber, Is.EqualTo(20)); list.StackTrace = _trace2; Assert.That(list.Items[0].LineNumber, Is.EqualTo(42)); Assert.That(list.Items[1].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[2].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[3].LineNumber, Is.EqualTo(20)); list.ListOrderPolicy = ErrorListOrderPolicy.InitialOrder; Assert.That(list.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.InitialOrder)); Assert.That(list.Items[0].LineNumber, Is.EqualTo(20)); Assert.That(list.Items[1].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[2].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[3].LineNumber, Is.EqualTo(42)); list.StackTrace = _trace1; Assert.That(list.Items[0].LineNumber, Is.EqualTo(20)); Assert.That(list.Items[1].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[2].LineNumber, Is.EqualTo(0)); Assert.That(list.Items[3].LineNumber, Is.EqualTo(42)); Assert.That(list.Items[4].LineNumber, Is.EqualTo(93)); // When the AutoSelectFirstItem flag is set, the selected item // is the one the most on top of the list, with source attachment. // Where the most on top depends whether the order is kept unchanged // or reversed. list.AutoSelectFirstItem = true; list.ListOrderPolicy = ErrorListOrderPolicy.InitialOrder; list.StackTrace = _trace1; Assert.That(list.SelectedItem.LineNumber, Is.EqualTo(20)); list.ListOrderPolicy = ErrorListOrderPolicy.ReverseOrder; list.StackTrace = _trace1; Assert.That(list.SelectedItem.LineNumber, Is.EqualTo(93)); return; } [Test] public void CanReportInvalidItems() { ErrorList list = new ErrorList(); // feeding ErrorList with garbage details should make it // fail gracefully. list.StackTrace = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\n" + "Nam at nisi ut neque sollicitudin ultrices. Sed rhoncus\r\n" + "rhoncus arcu. Morbi eu elit ut augue congue luctus. Nullam\r\n" + "eu eros. Nunc blandit varius orci. Mauris condimentum diam\r\n" + "ac ligula. Nullam ut metus. Maecenas sagittis nibh in nisl.\r\n" + "Phasellus rhoncus diam a nulla. Integer vestibulum.\r\n"; Assert.That(list.Items.Count, Is.EqualTo(1)); Assert.That(list.Items[0].BaseMethodName, Is.EqualTo("Fail to parse stack trace")); Assert.IsFalse(list.Items[0].HasSourceAttachment); return; } [Test] public void Invoking_DrawToGraphics() { Size docSize = new Size(200, 500); _mockRenderer.GetDocumentSize(_list.Items, _list.WorkingGraphics).Returns(docSize); _list.StackTrace = _trace1; _list.HoveredIndex = 0; _list.FireOnPaint(); _mockRenderer.Received().DrawToGraphics(_list.Items, _list.SelectedItem, _list.WorkingGraphics, _list.ClientRectangle); _mockRenderer.Received().DrawItem(_list.Items[0], 0, true, false, _list.WorkingGraphics, _list.ClientRectangle); return; } [Test] public void Click_Can_Select_Item() { Size docSize = new Size(200, 500); Point point; ErrorItem selection; _mockRenderer.GetDocumentSize(_list.Items, _list.WorkingGraphics).Returns(docSize); _list.StackTrace = _trace1; // simulate a click to 10, 10 - a clickable element point = new Point(10, 10); _mockRenderer.ItemAt(_list.Items, _list.WorkingGraphics, point).Returns(_list.Items[0]); _list.FireClick(point); Assert.NotNull(_list.SelectedItem); Assert.That(_list.SelectedItem, Is.EqualTo(_list.Items[0])); // simulate a click in 10, 110 - this element is not clickable => no source selection = _list.SelectedItem; point = new Point(10, 110); _mockRenderer.ItemAt(_list.Items, _list.WorkingGraphics, point).Returns(_list.Items[1]); _list.FireClick(point); Assert.NotNull(_list.SelectedItem); Assert.That(_list.SelectedItem, Is.SameAs(selection)); return; } [Test] public void DrawItem() { Size docSize = new Size(200, 500); Point point; _mockRenderer.GetDocumentSize(_list.Items, _list.WorkingGraphics).Returns(docSize); _list.StackTrace = _trace1; // mouse move hover a selectable item point = new Point(0, 0); _mockRenderer.ItemAt(_list.Items, _list.WorkingGraphics, point).Returns(_list.Items[0]); _list.FireMouseMove(point); Assert.True(_list.ITEM_ENTERED_NOTIFICATION); Assert.That(_list.HoveredIndex, Is.EqualTo(0)); _list.ResetFlags(); point = new Point(0, 50); _mockRenderer.ItemAt(_list.Items, _list.WorkingGraphics, point).Returns(_list.Items[1]); _list.FireMouseMove(point); Assert.False(_list.ITEM_ENTERED_NOTIFICATION); // items[1] is not hoverable... Assert.True(_list.ITEM_LEAVED_NOTIFICATION); // has left items[0] Assert.That(_list.HoveredIndex, Is.EqualTo(-1)); _list.ResetFlags(); point = new Point(0, 100); _mockRenderer.ItemAt(_list.Items, _list.WorkingGraphics, point).Returns(_list.Items[3]); _list.FireMouseMove(point); Assert.True(_list.ITEM_ENTERED_NOTIFICATION); // items[3] is hoverable... Assert.False(_list.ITEM_LEAVED_NOTIFICATION); // items[1] was not hoverable Assert.That(_list.HoveredIndex, Is.EqualTo(3)); // reset of stack trace causes HoverIndex to reset as well _mockRenderer.GetDocumentSize(_list.Items, _list.WorkingGraphics).Returns(docSize); _list.StackTrace = null; Assert.That(_list.HoveredIndex, Is.EqualTo(-1)); return; } class TestingErrorList : ErrorList { public bool ITEM_ENTERED_NOTIFICATION; public bool ITEM_LEAVED_NOTIFICATION; public TestingErrorList(IErrorListRenderer renderer) : base(renderer) { } public void ResetFlags() { ITEM_ENTERED_NOTIFICATION = false; ITEM_LEAVED_NOTIFICATION = false; } public void FireClick(Point point) { OnClick(point); } public void FireMouseMove(Point point) { OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0)); } public void UseDefaultRenderer() { _renderer = new DefaultErrorListRenderer(); } public int HoveredIndex { get { return (_hoveredIndex); } set { _hoveredIndex = value; } } public Graphics WorkingGraphics { get { return (_workingGraphics); } } public void FireOnPaint() { OnPaint(new PaintEventArgs(WorkingGraphics, ClientRectangle)); return; } protected override void ItemEntered(int index) { base.ItemEntered(index); ITEM_ENTERED_NOTIFICATION = true; } protected override void ItemLeaved(int index) { base.ItemLeaved(index); ITEM_LEAVED_NOTIFICATION = true; } } } } #endifNUnit-2.6.0.12051/src/GuiException/tests/Controls/TestSourceCodeDisplay.cs0000664000175000017500000001440611544451536026103 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using NSubstitute; using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; using NUnit.UiException.CodeFormatters; using NUnit.UiException.Tests.data; using System.Drawing; namespace NUnit.UiException.Tests.Controls { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestSourceCodeDisplay { private TestingCode _code; private IStackTraceView _mockStack; private ICodeView _mockCode; [SetUp] public void SetUp() { _mockStack = Substitute.For(); _mockCode = Substitute.For(); _code = new TestingCode(_mockStack, _mockCode); return; } [Test] public void DefaultState() { SourceCodeDisplay code = new SourceCodeDisplay(); Assert.NotNull(code.PluginItem); Assert.That(code.PluginItem.Text, Is.EqualTo("Display source code context")); Assert.NotNull(code.OptionItems); Assert.That(code.OptionItems.Length, Is.EqualTo(1)); Assert.NotNull(code.Content); Assert.That(code.Content, Is.TypeOf(typeof(SplitterBox))); SplitterBox splitter = code.Content as SplitterBox; Assert.That(splitter.Controls.Count, Is.EqualTo(2)); CodeBox codeBox = splitter.Control2 as CodeBox; Assert.NotNull(codeBox); Assert.True(codeBox.ShowCurrentLine); Assert.That(codeBox.CurrentLineBackColor, Is.EqualTo(Color.Red)); Assert.That(codeBox.CurrentLineForeColor, Is.EqualTo(Color.White)); Assert.True(code.AutoSelectFirstItem); Assert.That(code.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.InitialOrder)); Assert.That(code.SplitOrientation, Is.EqualTo(Orientation.Vertical)); Assert.That(code.SplitterDistance, Is.EqualTo(0.5f)); return; } [Test] public void SplitOrientation() { _code.SplitOrientation = Orientation.Horizontal; Assert.That(_code.SplitOrientation, Is.EqualTo(Orientation.Horizontal)); Assert.That(_code.Splitter.Orientation, Is.EqualTo(Orientation.Horizontal)); _code.SplitOrientation = Orientation.Vertical; Assert.That(_code.SplitOrientation, Is.EqualTo(Orientation.Vertical)); Assert.That(_code.Splitter.Orientation, Is.EqualTo(Orientation.Vertical)); return; } [Test] public void SplitterDistance() { _code.SplitterDistance = 0.1f; Assert.That(_code.Splitter.SplitterDistance, Is.EqualTo(0.1f)); _code.SplitterDistance = 0.4f; Assert.That(_code.Splitter.SplitterDistance, Is.EqualTo(0.4f)); return; } [Test] public void SelectedItemChanged() { GeneralCodeFormatter formatter = new GeneralCodeFormatter(); ErrorItem item; // test to pass: // // handle selection changed event when there // is a non null selected item using (TestResource resource = new TestResource("Basic.cs")) { item = new ErrorItem(resource.Path, 2); Assert.That(item.ReadFile(), Is.Not.Null); _mockStack.SelectedItem.Returns(item); _mockCode.Formatter.Returns(formatter); _code.RaiseSelectedItemChanged(); Assert.That(_mockCode.Text, Is.EqualTo(item.ReadFile())); Assert.That(_mockCode.Language, Is.EqualTo("C#")); // CurrentLine is a based 0 index Assert.That(_mockCode.CurrentLine, Is.EqualTo(1)); } // test to fail: // // should handle selection changed event even // if selection comes to null _mockStack.SelectedItem.Returns((ErrorItem) null); _code.RaiseSelectedItemChanged(); Assert.That(_mockCode.Text, Is.EqualTo(null)); return; } [Test] public void ListOrderPolicy() { _code.ListOrderPolicy = ErrorListOrderPolicy.ReverseOrder; Assert.That(_mockStack.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.ReverseOrder)); _mockStack.ListOrderPolicy = ErrorListOrderPolicy.ReverseOrder; Assert.That(_code.ListOrderPolicy, Is.EqualTo(ErrorListOrderPolicy.ReverseOrder)); _mockStack.ListOrderPolicy = ErrorListOrderPolicy.InitialOrder; _code.ListOrderPolicy = ErrorListOrderPolicy.InitialOrder; return; } [Test] public void CanReportFileException() { SourceCodeDisplay sourceDisplay = new SourceCodeDisplay(); sourceDisplay.AutoSelectFirstItem = true; sourceDisplay.OnStackTraceChanged( "à SomeClass.SomeMethod() dans C:\\unknownFolder\\unknownFile.cs:ligne 1"); SplitterBox splitter = sourceDisplay.Content as SplitterBox; CodeBox box = splitter.Control2 as CodeBox; Assert.IsTrue(box.Text.Contains("Cannot open file: 'C:\\unknownFolder\\unknownFile.cs'")); Assert.IsTrue(box.Text.Contains("Error:")); return; } class TestingCode : SourceCodeDisplay { public TestingCode(IStackTraceView stack, ICodeView code) { _stacktraceView = stack; _codeView = code; } public void RaiseSelectedItemChanged() { base.SelectedItemChanged(null, null); } public SplitterBox Splitter { get { return (_splitter); } } } } } #endifNUnit-2.6.0.12051/src/GuiException/tests/Controls/TestErrorToolbar.cs0000664000175000017500000001744611544451536025145 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using NSubstitute; using NUnit.Framework; using NUnit.UiException.Controls; using System.Windows.Forms; using System.Drawing; namespace NUnit.UiException.Tests.Controls { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestErrorToolbar { private ErrorToolbar _emptyToolbar; private ErrorToolbar _filledToolbar; private IErrorDisplay _raw; private IErrorDisplay _browser; private bool _rendererChangeNotification; [SetUp] public void SetUp() { _emptyToolbar = new ErrorToolbar(); _filledToolbar = new ErrorToolbar(); _raw = Substitute.For(); _raw.PluginItem.Returns(new ToolStripButton()); _browser = Substitute.For(); _browser.PluginItem.Returns(new ToolStripButton()); _filledToolbar.Register(_raw); _filledToolbar.Register(_browser); _rendererChangeNotification = false; _filledToolbar.SelectedRendererChanged += new EventHandler(_filledToolbar_SelectedRendererChanged); return; } void _filledToolbar_SelectedRendererChanged(object sender, EventArgs e) { _rendererChangeNotification = true; } [Test] public void NewStripButton() { Assert.NotNull(ErrorToolbar.NewStripButton(true, "text", new Bitmap(10, 10), null)); } [Test] public void DefaultState() { Assert.That(_emptyToolbar.Controls.Count, Is.EqualTo(0)); Assert.That(_emptyToolbar.Count, Is.EqualTo(0)); Assert.That(_emptyToolbar.SelectedDisplay, Is.Null); Assert.That(_filledToolbar.Count, Is.EqualTo(2)); Assert.That(_filledToolbar[0], Is.Not.Null); Assert.That(_filledToolbar[1], Is.Not.Null); Assert.NotNull(_filledToolbar.SelectedDisplay); Assert.That(_filledToolbar.SelectedDisplay, Is.SameAs(_raw)); return; } [Test] public void Cannot_Register_Null_Display() { try { _emptyToolbar.Register(null); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("display")); } try { _raw.PluginItem.Returns((ToolStripButton) null); _emptyToolbar.Register(_raw); // throws exception Assert.Fail(); } catch (Exception e) { Assert.True(e.Message.Contains("PluginItem")); } return; } [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "Cannot select unregistered display.", MatchType = MessageMatch.Contains)] public void Cannot_Select_UnRegistered_Display() { IErrorDisplay unknown = Substitute.For(); _filledToolbar.SelectedDisplay = unknown; // throws exception return; } [Test] public void SelectedDisplay() { // clear selection if any _filledToolbar.SelectedDisplay = null; // check ability to select raw display _filledToolbar.SelectedDisplay = _raw; Assert.NotNull(_filledToolbar.SelectedDisplay); Assert.That(_filledToolbar.SelectedDisplay, Is.SameAs(_raw)); Assert.True(_rendererChangeNotification); // check ability to select browser display _rendererChangeNotification = false; _filledToolbar.SelectedDisplay = _browser; Assert.NotNull(_filledToolbar.SelectedDisplay); Assert.That(_filledToolbar.SelectedDisplay, Is.SameAs(_browser)); Assert.True(_rendererChangeNotification); // check ability to clear selection _rendererChangeNotification = false; _filledToolbar.SelectedDisplay = null; Assert.That(_filledToolbar.SelectedDisplay, Is.Null); Assert.True(_rendererChangeNotification); // event should be raised when a real // change occurs _rendererChangeNotification = false; _filledToolbar.SelectedDisplay = null; Assert.False(_rendererChangeNotification); return; } [Test] public void Registering_displays_adds_ToolStripItem() { ToolStripButton rawView = new ToolStripButton("raw display"); ToolStripButton browserView = new ToolStripButton("code display"); ToolStripItem[] btns = new ToolStripItem[] { new ToolStripButton("swap") }; // add part _raw.PluginItem.Returns(rawView); _raw.OptionItems.Returns((ToolStripItem[]) null); _emptyToolbar.Register(_raw); Assert.True(_emptyToolbar.Items.Contains(rawView)); _browser.PluginItem.Returns(browserView); _browser.OptionItems.Returns(btns); _emptyToolbar.Register(_browser); Assert.True(_emptyToolbar.Items.Contains(rawView)); Assert.True(_emptyToolbar.Items.Contains(browserView)); Assert.True(_emptyToolbar.Items.Contains(btns[0])); // clear part _emptyToolbar.Clear(); Assert.That(_emptyToolbar.Count, Is.EqualTo(0)); Assert.False(_emptyToolbar.Items.Contains(rawView)); Assert.False(_emptyToolbar.Items.Contains(browserView)); Assert.False(_emptyToolbar.Items.Contains(btns[0])); return; } [Test] public void PluginItem_Click_Raises_SelectedRenderedChanged() { ErrorToolbar toolbar = new ErrorToolbar(); StackTraceDisplay raw = new StackTraceDisplay(); SourceCodeDisplay code = new SourceCodeDisplay(); toolbar.Register(raw); toolbar.Register(code); raw.PluginItem.PerformClick(); Assert.NotNull(toolbar.SelectedDisplay); Assert.That(toolbar.SelectedDisplay, Is.EqualTo(raw)); code.PluginItem.PerformClick(); Assert.NotNull(toolbar.SelectedDisplay); Assert.That(toolbar.SelectedDisplay, Is.EqualTo(code)); return; } [Test] public void Set_Or_Unset_Check_Flag_On_Selection() { ErrorToolbar toolbar = new ErrorToolbar(); StackTraceDisplay raw = new StackTraceDisplay(); SourceCodeDisplay code = new SourceCodeDisplay(); toolbar.Register(raw); toolbar.Register(code); toolbar.SelectedDisplay = raw; Assert.True(((ToolStripButton)raw.PluginItem).Checked); Assert.False(((ToolStripButton)code.PluginItem).Checked); toolbar.SelectedDisplay = code; Assert.False(((ToolStripButton)raw.PluginItem).Checked); Assert.True(((ToolStripButton)code.PluginItem).Checked); toolbar.SelectedDisplay = null; Assert.False(((ToolStripButton)raw.PluginItem).Checked); Assert.False(((ToolStripButton)code.PluginItem).Checked); return; } } } #endifNUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/0000775000175000017500000000000011742560362023427 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestWindowsPathParser.cs0000664000175000017500000000772011543625326030251 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestWindowsPathParser : TestIErrorParser { private IErrorParser _parser; [SetUp] public new void SetUp() { _parser = new PathCompositeParser().WindowsPathParser; Assert.That(_parser, Is.Not.Null); return; } [Test] public void Test_Ability_To_Parse_Regular_Windows_Path() { RawError res; // one basic sample res = AcceptValue(_parser, "à NUnit.UiException.TraceItem.get_Text() dans C:\\TraceItem.cs:ligne 43"); Assert.That(res.Path, Is.EqualTo("C:\\TraceItem.cs")); // check parser is not confused by file with odd extensions res = AcceptValue(_parser, "à get_Text() dans C:\\TraceItem.cs.cs.cs.cs:ligne 43"); Assert.That(res.Path, Is.EqualTo("C:\\TraceItem.cs.cs.cs.cs")); // check it supports white space in filePath res = AcceptValue(_parser, "à get_Text() dans C:\\my Document1\\my document2 containing space\\file.cs:line 1"); Assert.That(res.Path, Is.EqualTo("C:\\my Document1\\my document2 containing space\\file.cs")); // check it supports odd folder names ending like C# file res = AcceptValue(_parser, "à get_Text() dans C:\\my doc\\my doc2.cs\\file.cs:line 1"); Assert.That(res.Path, Is.EqualTo("C:\\my doc\\my doc2.cs\\file.cs")); // check it supports odd drive letters res = AcceptValue(_parser, "à get_Text() dans Z:\\work\\folder 1\\file1.cs:line 1"); Assert.That(res.Path, Is.EqualTo("Z:\\work\\folder 1\\file1.cs")); // same with lower case res = AcceptValue(_parser, "à get_Text() dans z:\\work\\folder 1\\file1.cs:line 1"); Assert.That(res.Path, Is.EqualTo("z:\\work\\folder 1\\file1.cs")); // check it doesn't rely upon a specific file language res = AcceptValue(_parser, "à get_Text() dans z:\\work\\folder 1\\file1.vb:line 1"); Assert.That(res.Path, Is.EqualTo("z:\\work\\folder 1\\file1.vb")); res = AcceptValue(_parser, "à get_Text() dans z:\\work\\folder 1\\file1.cpp: line 1"); Assert.That(res.Path, Is.EqualTo("z:\\work\\folder 1\\file1.cpp")); // check it doesn't rely upon language at all res = AcceptValue(_parser, "à get_Text() dans z:\\work\\folder 1\\file1:line 1"); Assert.That(res.Path, Is.EqualTo("z:\\work\\folder 1\\file1")); // check it doesn't rely upon method or line number information res = AcceptValue(_parser, "z:\\work\\folder\\file:"); Assert.That(res.Path, Is.EqualTo("z:\\work\\folder\\file")); return; } [Test] public void Test_Inability_To_Parse_Non_Windows_Like_Path_Values() { // check it fails to parse Unix like filePath values RejectValue(_parser, "à get_Text() dans /home/ihottier/work/file1:line1"); // check it fails to parse ill-formed windows filePath values RejectValue(_parser, "à get_Text() dans C::line1"); RejectValue(_parser, "à get_Text() dans C: :line1"); RejectValue(_parser, "à get_Text() dans C:folder 1\\file1:line1"); // check it fails to parse missing filePath value RejectValue(_parser, "à get_Text()"); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestUnixPathParser.cs0000664000175000017500000001004711543625326027536 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestUnixPathParser : TestIErrorParser { private IErrorParser _parser; [SetUp] public new void SetUp() { _parser = new PathCompositeParser().UnixPathParser; Assert.That(_parser, Is.Not.Null); return; } [Test] public void Test_Ability_To_Parse_Regular_Unix_Like_Path_Values() { RawError res; // one basic sample res = AcceptValue(_parser, "à NUnit.UiException.TraceItem.get_Text() dans /home/ihottier/TraceItem.cs:ligne 43"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/TraceItem.cs")); // check parser is not confused by file with odd extensions res = AcceptValue(_parser, "à get_Text() dans /home/ihottier/TraceItem.cs.cs.cs.cs:ligne 43"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/TraceItem.cs.cs.cs.cs")); // check it supports white space in filePath res = AcceptValue(_parser, "à get_Text() dans /home/ihottier/my Document1/my document2 containing space/file.cs:line 1"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/my Document1/my document2 containing space/file.cs")); // check it supports odd folder names ending like C# file res = AcceptValue(_parser, "à get_Text() dans /home/my doc/my doc2.cs/file.cs:line 1"); Assert.That(res.Path, Is.EqualTo("/home/my doc/my doc2.cs/file.cs")); // check it doesn't rely on a constant such as "/home" res = AcceptValue(_parser, "à get_Text() dans /root/work/folder 1/file1.cs:line 1"); Assert.That(res.Path, Is.EqualTo("/root/work/folder 1/file1.cs")); // same with upper case res = AcceptValue(_parser, "à get_Text() dans /ROOT/work/folder 1/file1.cs:line 1"); Assert.That(res.Path, Is.EqualTo("/ROOT/work/folder 1/file1.cs")); // check it doesn't rely upon a specific file language res = AcceptValue(_parser, "à get_Text() dans /home/ihottier/work/folder 1/file1.vb:line 1"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/work/folder 1/file1.vb")); res = AcceptValue(_parser, "à get_Text() dans /home/ihottier/work/folder 1/file1.cpp: line 1"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/work/folder 1/file1.cpp")); // check it doesn't rely upon language at all res = AcceptValue(_parser, "à get_Text() dans /home/work/folder 1/file1:line 1"); Assert.That(res.Path, Is.EqualTo("/home/work/folder 1/file1")); // check it doesn't rely upon method or line information res = AcceptValue(_parser, "/home/work/folder/file:"); Assert.That(res.Path, Is.EqualTo("/home/work/folder/file")); return; } [Test] public void Test_Inability_To_Parse_Non_Unix_Like_Path_Values() { // check it fails to parse Windows like filePath values RejectValue(_parser, "à get_Text() dans C:\\Users\\ihottier\\Work\\file1:line1"); // check it fails to parse ill-formed Unix filePath values RejectValue(_parser, "à get_Text() dans /:line1"); RejectValue(_parser, "à get_Text() dans / :line1"); RejectValue(_parser, "à get_Text() dans home/file1:line1"); // check it fails to parse missing filePath value RejectValue(_parser, "à get_Text()"); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestFunctionParser.cs0000664000175000017500000000620511543625326027564 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestFunctionParser : TestIErrorParser { private IErrorParser _parser; [SetUp] public new void SetUp() { _parser = new FunctionParser(); return; } [Test] public void Test_Ability_To_Parse_Regular_Function_Values() { RawError res; // check parse of basic method res = AcceptValue(_parser, "à NUnit.UiException.TraceItem.get_Text() dans C:\\TraceItem.cs:ligne 43"); Assert.That(res.Function, Is.EqualTo("NUnit.UiException.TraceItem.get_Text()")); // check parse a method with parameters res = AcceptValue(_parser, "à System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)"); Assert.That(res.Function, Is.EqualTo("System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)")); // check it supports C/C++ function as well res = AcceptValue(_parser, "à main(int argc, const char **argv) dans C:\\file1:line1"); Assert.That(res.Function, Is.EqualTo("main(int argc, const char **argv)")); // check it doesn't rely upon filePath or line information //res = AcceptValue(_parser, "get_Text()"); //Assert.That(res.Function, Is.EqualTo("get_Text()")); // a simple function name is not accepted - that is, the leading "at" is required // TODO: try to restore older behavior while still allowing a space before the // opening parenthesis. RejectValue(_parser, "get_Text()"); return; } [Test] public void Test_Ability_To_Parse_Mono_Stack_Trace() { RawError res; // mono adds a space after the name res = AcceptValue(_parser, "à NUnit.UiException.TraceItem.get_Text () dans C:\\TraceItem.cs:ligne 43"); Assert.That(res.Function, Is.EqualTo("NUnit.UiException.TraceItem.get_Text ()")); } [Test] public void Test_Fail_To_Parse_Odd_Function_Values() { // check parse relies on '(' and ')' RejectValue(_parser, "à get_Text dans C:\\file1:line1"); RejectValue(_parser, "à get_Text( dans C:\\file1:line1"); RejectValue(_parser, "à get_Text) dans C:\\file1:line1"); RejectValue(_parser, "à get_Text)( dans C:\\file1:line1"); // check function name cannot be empty RejectValue(_parser, "à (int index) dans C:\\file1:line1"); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestPathParser.cs0000664000175000017500000000277611525533664026707 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestPathParser : TestIErrorParser { private PathCompositeParser _parser; [SetUp] public new void SetUp() { _parser = new PathCompositeParser(); Assert.That(_parser.UnixPathParser, Is.Not.Null); Assert.That(_parser.WindowsPathParser, Is.Not.Null); return; } [Test] public void Test_Ability_To_Handle_Windows_Path_Like_Values() { RawError res; res = AcceptValue(_parser, "à get_Text() dans C:\\folder\\file1:line 1"); Assert.That(res.Path, Is.EqualTo("C:\\folder\\file1")); return; } [Test] public void Test_Ability_To_Handle_Unix_Path_Like_Values() { RawError res; res = AcceptValue(_parser, "à get_Text() dans /home/ihottier/folder/file1:line 1"); Assert.That(res.Path, Is.EqualTo("/home/ihottier/folder/file1")); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestIErrorParser.cs0000664000175000017500000000615711525533664027212 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.UiException.StackTraceAnalyzers; using NUnit.Framework; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestIErrorParser { protected StackTraceParser _stack; protected IErrorParser[] _array; public TestIErrorParser() { _stack = new StackTraceParser(); return; } [SetUp] public void SetUp() { PathCompositeParser pathParser; pathParser = new PathCompositeParser(); _array = new IErrorParser[] { pathParser.UnixPathParser, pathParser.WindowsPathParser, new FunctionParser(), new PathCompositeParser(), new LineNumberParser() }; return; } [Test] public void Test_IErrorParser_Can_Throw_ParserNullException() { bool hasRaisedException; foreach (IErrorParser item in _array) { hasRaisedException = false; try { item.TryParse(null, new RawError("test")); // throws exception } catch (Exception e) { Assert.That(e.Message.Contains("parser"), Is.True); hasRaisedException = true; } Assert.That(hasRaisedException, Is.True, item.ToString() + " failed to raise exception"); } return; } [Test] public void Test_IErrorParser_Can_Throw_ArgsNullException() { bool hasRaisedException; foreach (IErrorParser item in _array) { hasRaisedException = false; try { item.TryParse(_stack, null); // throws exception } catch (Exception e) { Assert.That(e.Message.Contains("args"), Is.True); hasRaisedException = true; } Assert.That(hasRaisedException, Is.True, item.ToString() + " failed to raise exception"); } return; } public RawError AcceptValue(IErrorParser parser, string error) { RawError res; res = new RawError(error); Assert.That(parser.TryParse(_stack, res), Is.True, "Failed to parse \"{0}\"", error); return (res); } public void RejectValue(IErrorParser parser, string error) { Assert.That(parser.TryParse(_stack, new RawError(error)), Is.False); } } } NUnit-2.6.0.12051/src/GuiException/tests/StackTraceAnalysers/TestLineNumberParser.cs0000664000175000017500000000626511543625326030045 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException.Tests.StackTraceAnalyzers { [TestFixture] public class TestLineNumberParser : TestIErrorParser { private IErrorParser _parser; [SetUp] public new void SetUp() { _parser = new LineNumberParser(); return; } [Test] public void Test_Ability_To_Parse_Regular_Line_Number_Values() { RawError res; // a basic test res = AcceptValue(_parser, "à get_Text() dans C:\\folder\\file1:line 1"); Assert.That(res.Line, Is.EqualTo(1)); // parser doesn't rely upon the presence of words between // the colon and the number res = AcceptValue(_parser, "à get_Text() dans C:\\folder\\file1:42"); Assert.That(res.Line, Is.EqualTo(42)); // parser doesn't rely on the existence of // a method name or filePath value res = AcceptValue(_parser, ":43"); Assert.That(res.Line, Is.EqualTo(43)); // Works for German // NOTE: German provides a period at the end of the line res = AcceptValue(_parser, @"bei CT.Business.BusinessObjectXmlSerializer.Deserialize(String serializedObject) in D:\Source\CT5\BASE\CT.Business\BusinessObjectXmlSerializer.cs:Zeile 86."); Assert.That(res.Line, Is.EqualTo(86)); // Russian works too // в Samples.ExceptionBrowserTest.Worker.DoSomething() в C:\psgdev\Projects\NUnit\Tests\Samples\ExceptionBrowserTest.cs:строка 16 // в Samples.ExceptionBrowserTest.Test() в C:\psgdev\Projects\NUnit\Tests\Samples\ExceptionBrowserTest.cs:строка 24 res = AcceptValue(_parser, @"в Samples.ExceptionBrowserTest.Worker.DoSomething() в C:\psgdev\Projects\NUnit\Tests\Samples\ExceptionBrowserTest.cs:строка 16"); Assert.That(res.Line, Is.EqualTo(16)); return; } [Test] public void Test_Ability_To_Reject_Odd_Line_Number_Values() { // after the terminal ':' parser expects to have only one integer value RejectValue(_parser, "à get_Text() dans C:\\folder\\file1 line 42"); RejectValue(_parser, "à get_Text() dans C:\\folder\\file42"); // check it fails to parse int values that are part of a word RejectValue(_parser, "à get_Text() dans C:\\folder\\file1:line43"); // a line number should not be zero RejectValue(_parser, "à get_Text() dans C:\\folder\\file1:line 0"); // a line number should not be negative RejectValue(_parser, "à get_Text() dans C:\\folder\\file1:line -42"); return; } } } NUnit-2.6.0.12051/src/GuiException/tests/TestExceptionItemCollection.cs0000664000175000017500000000637211525533664025515 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using NUnit.Framework; using NUnit.UiException.Tests.data; namespace NUnit.UiException.Tests { [TestFixture] public class TestErrorItemCollection { TestResource _resourceA; TestResource _resourceB; private ErrorItemCollection _items; private ErrorItem _itemA; private ErrorItem _itemB; [SetUp] public void SetUp() { _items = new InternalTraceItemCollection(); _resourceA = new TestResource("HelloWorld.txt"); _resourceB = new TestResource("TextCode.txt"); _itemA = new ErrorItem(_resourceA.Path, 1); _itemB = new ErrorItem(_resourceB.Path, 2); return; } [TearDown] public void TearDown() { if (_resourceA != null) { _resourceA.Dispose(); _resourceA = null; } if (_resourceB != null) { _resourceB.Dispose(); _resourceB = null; } } [Test] public void Test_TraceItems() { List lst; Assert.That(_items.Count, Is.EqualTo(0)); _items.Add(_itemA); _items.Add(_itemB); Assert.That(_items.Count, Is.EqualTo(2)); Assert.That(_items[0], Is.EqualTo(_itemA)); Assert.That(_items[1], Is.EqualTo(_itemB)); lst = new List(); foreach (ErrorItem item in _items) lst.Add(item); Assert.That(lst.Count, Is.EqualTo(2)); Assert.That(lst[0], Is.EqualTo(_items[0])); Assert.That(lst[1], Is.EqualTo(_items[1])); return; } [Test] [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "item", MatchType = MessageMatch.Contains)] public void Test_Add_Throws_NullItemException() { _items.Add(null); // throws exception } [Test] public void Test_Clear() { _items.Add(_itemA); Assert.That(_items.Count, Is.EqualTo(1)); _items.Clear(); Assert.That(_items.Count, Is.EqualTo(0)); return; } [Test] public void Test_Contains() { Assert.That(_items.Contains(null), Is.False); Assert.That(_items.Contains(_itemA), Is.False); _items.Add(_itemA); Assert.That(_items.Contains(_itemA), Is.True); return; } #region InternalTraceItemCollection class InternalTraceItemCollection : ErrorItemCollection { public InternalTraceItemCollection() { // nothing to do } } #endregion } } NUnit-2.6.0.12051/src/GuiException/tests/data/0000775000175000017500000000000011742560362020432 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/tests/data/HelloWorld.txt0000664000175000017500000000001711504175260023237 0ustar jtaylorjtaylorHello world!NUnit-2.6.0.12051/src/GuiException/tests/data/Basic.cs0000664000175000017500000000006311504175260021774 0ustar jtaylorjtaylornamespace Demo.data { class Basic { } } NUnit-2.6.0.12051/src/GuiException/tests/data/TextCode.txt0000664000175000017500000000447211504175260022714 0ustar jtaylorjtaylor01 #include 02 #include 03 #include 04 #include 05 #include 06 #include 07 #include 08 09 /* logic */ 10 #ifndef TRUE 11 # define TRUE 1 12 #endif /* TRUE */ 13 #ifndef FALSE 14 # define FALSE 0 15 #endif /* FALSE */ 16 #define EOF_OK TRUE 17 #define EOF_NOT_OK FALSE 18 19 /* global limits */ 20 #define RULE_YEAR 2004 /* NOTE: should match the current year */ 21 #define START_DATE "07Jan2004 00:00 UTC" /* first confirmation received */ 22 #define MAX_COL 79 /* max column a line should hit */ 23 #define MAX_BUILD_SIZE 521 /* max how to build size */ 24 #define MAX_PROGRAM_SIZE 4096 /* max program source size */ 25 #define MAX_PROGRAM_SIZE2 2048 /* max program source size not counting 26 whitespace and {}; not followed by 27 whitespace or EOF */ 28 #define MAX_TITLE_LEN 31 /* max chars in the title */ 29 #define MAX_ENTRY_LEN 1 /* max length in the entry input line */ 30 #define MAX_ENTRY 8 /* max number of entries per person per year */ 31 #define MAX_FILE_LEN 1024 /* max filename length for a info file */ 32 33 /* where to send entries */ 34 #define ENTRY_USER "e.2004" 35 #define ENTRY_HOST "ioccc.org" 36 37 /* uuencode process - assumes ASCII */ 38 #define UUENCODE(c) ((c) ? encode_str[(int)(c)&0x3f] : '`') 39 #define UUENCODE_LEN 45 /* max uuencode chunk size */ 40 #define UUINFO_MODE 0444 /* mode of an info file's uuencode file */ 41 #define UUBUILD_MODE 0444 /* mode of the build file's uuencode file */ 42 #define UUBUILD_NAME "build" /* name for the build file's uuencode file */ 43 #define UUPROG_MODE 0444 /* mode of the program's uuencode file */ 44 #define UUPROG_NAME "prog.c" /* name for the program's uuencode file */ 45 46 /* encode_str[(char)val] is the uuencoded character of val */ 47 char encode_str[] = "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; 48 49 /* global declarations */ 50 char *program; /* our name */ 51 long start_time; /* the startup time */ 52 53 /* forward declarations */ 54 void parse_args(int argc, char **argv, char **rname, 55 char **bname, char **pname, char **oname); 56 void usage(int exitval); 57 FILE *open_remark(char *filename); 58 FILE *open_build(char *filename); 59 FILE *open_program(char *filename);NUnit-2.6.0.12051/src/GuiException/tests/data/TestResource.cs0000664000175000017500000000050111504175260023377 0ustar jtaylorjtaylorusing System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.Tests.data { public class TestResource : NUnit.TestUtilities.TempResourceFile { public TestResource(string name) : base(typeof( TestResource ), name) { } } } NUnit-2.6.0.12051/src/GuiException/tests/nunit.uiexception.tests.build0000664000175000017500000000677211525712360025403 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiException/UiException/0000775000175000017500000000000011742560362020613 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/0000775000175000017500000000000011742560362023534 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/IFormatterCatalog.cs0000664000175000017500000000252611504175260027432 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.CodeFormatters { /// /// The interface through which SourceCodeDisplay interacts to guess /// the language from a file extension. /// /// Direct implementation is: /// - GeneralCodeFormatter /// public interface IFormatterCatalog { /// /// Format the text using the given language formatting. /// /// A text to be formatted /// The language with which formatting the text /// A FormatterCode object FormattedCode Format(string text, string language); /// /// Gets the language from the given extension. /// /// An extension without the dot, like 'cs' /// A language name, like 'C#' string LanguageFromExtension(string extension); } } NUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/ICodeFormatter.cs0000664000175000017500000000220111504175260026720 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.CodeFormatters { /// /// ICodeFormatter is the interface to make the syntax /// coloring of a string for a specific developpment language. /// public interface ICodeFormatter { /// /// The language name handled by this formatter. /// Ex: "C#", "Java", "C++" and so on... /// string Language { get; } /// /// Makes the coloring syntax of the given text. /// /// The text to be formatted. This /// parameter cannot be null. /// A FormattedCode instance. FormattedCode Format(string code); } } NUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/GeneralCodeFormatter.cs0000664000175000017500000001460211504175260030115 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.CodeFormatters { /// /// GeneralCodeFormatter is the front class responsible for making a basic /// syntax coloring of a string of text for a set of specific languages. /// The class encapsulates a set of algorithms where each of them addresses /// a specific language formatting. The use of one or another algorithm at /// analysing time is made through an language registering mechanism. /// For instance C# files are covered by CSharpCodeFormatter which has /// been assigned to "cs" language. /// If a query is made to GeneralCodeFormatter while there is no formatter /// that fit the given file language a default formatting is applyied /// through the use of the formatter registered into the property /// DefaultFormatter. /// public class GeneralCodeFormatter : IFormatterCatalog { /// /// The set of formatting algorithms. /// private CodeFormatterCollection _formatters; /// /// The default formatter to be used as last resort. /// private ICodeFormatter _default; /// /// Build and initialises GeneralCodeFormatter. /// public GeneralCodeFormatter() { _formatters = new CodeFormatterCollection(); _formatters.Register(new CSharpCodeFormatter(), "cs"); _default = new PlainTextCodeFormatter(); return; } /// /// Gets or sets the formatter to be used as last resort when /// no formatter fit the given source language. /// The value cannot be null. /// public ICodeFormatter DefaultFormatter { get { return (_default); } set { UiExceptionHelper.CheckNotNull(value, "value"); _default = value; } } /// /// Gives access to the underlying formatter collection. /// public CodeFormatterCollection Formatters { get { return (_formatters); } } /// /// Gets the best formatter that fits the given language. If there /// is no such formatter, a default one is returned. /// /// /// The language name. Ex: "C#", "Java. This parameter cannot be null. /// /// /// A non-null ICodeFormatter that best fits the request. /// public ICodeFormatter GetFormatterFromLanguage(string languageName) { UiExceptionHelper.CheckNotNull(languageName, "language"); if (_formatters.HasLanguage(languageName)) return (_formatters[languageName]); return (DefaultFormatter); } /// /// Gets the formatter assigned to the given extension. If there /// is no such assignment, the default formatter is returned. /// /// /// A file extension. Ex: "cs", "txt". This parameter cannot be null. /// /// A non-null ICodeFormatter. public ICodeFormatter GetFormatterFromExtension(string extension) { UiExceptionHelper.CheckNotNull(extension, "extension"); if (_formatters.HasExtension(extension)) return (_formatters.GetFromExtension(extension)); return (DefaultFormatter); } /// /// A convenient method to make the formatting of a piece of code when /// only the file extension is known. /// /// The piece of code to be formatted. This parameter /// cannot be null. /// The file extension associated to this piece of code. /// Ex: "cs", "cpp". This is used to pick the formatter assigned to. If no such /// formatter exists, the default one is picked up. /// The FormattedCode for this piece of code. public FormattedCode FormatFromExtension(string code, string extension) { UiExceptionHelper.CheckNotNull(code, "code"); UiExceptionHelper.CheckNotNull(extension, "extension"); if (_formatters.HasExtension(extension)) return (_formatters.GetFromExtension(extension).Format(code)); return (DefaultFormatter.Format(code)); } #region IFormatterCatalog Membres /// /// Pick the best available formatter to format the given piece of code. /// /// The code to be formatted. This parameter cannot be null. /// /// The language into which code has been written. Ex: "C#", "Java". /// If no such formatter is available, a default formatting is applied. /// This parameter cannot be null. /// /// /// The formatting for this piece of code. /// public FormattedCode Format(string code, string language) { UiExceptionHelper.CheckNotNull(code, "code"); UiExceptionHelper.CheckNotNull(language, "language"); if (_formatters.HasLanguage(language)) return (_formatters[language].Format(code)); return (DefaultFormatter.Format(code)); } public string LanguageFromExtension(string extension) { if (_formatters.HasExtension(extension)) return (_formatters.GetFromExtension(extension).Language); return (_default.Language); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/PlainTextCodeFormatter.cs0000664000175000017500000000604111504175260030446 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.CodeFormatters { /// /// Create a default FormattedCode for any string value. /// This should be used as a last resort when there is not ICodeFormatter /// that fit source code for an ErrorItem. /// public class PlainTextCodeFormatter : ICodeFormatter { #region ICodeFormatter Membres /// /// Returns "Plain text" /// public string Language { get { return ("Plain text"); } } public FormattedCode Format(string sourceCode) { DefaultTextManager text; byte[] byteArray; int[] strArray; int[] lineArray; int index; int posLineStart; int posChar; UiExceptionHelper.CheckNotNull(sourceCode, "sourceCode"); sourceCode = PreProcess(sourceCode); text = new DefaultTextManager(); text.Text = sourceCode; strArray = new int[text.LineCount]; lineArray = new int[text.LineCount]; index = 0; posLineStart = 0; posChar = 0; foreach (char c in sourceCode) { if (c == '\n') { strArray[index] = posLineStart; lineArray[index] = index; posLineStart = posChar + 1; index++; } posChar++; } if (index <= text.LineCount - 1) { strArray[index] = posLineStart; lineArray[index] = index; } byteArray = new byte[text.LineCount]; return (new FormattedCode(sourceCode, strArray, byteArray, lineArray)); } #endregion /// /// Prepare input text for the parsing stage. /// /// The text to be pre-processed. /// A string ready to be parsed. public string PreProcess(string text) { if (text == null) return (null); // this replace tabulation by space sequences. The reason is // that the technique used to measure strings at rendering time // fail to measure '\t' correctly and lines of text containing those // characters are badly aligned. // The simplest thing to fix that is to remove tabs altogether. return (text.Replace("\t", " ")); } } } NUnit-2.6.0.12051/src/GuiException/UiException/CodeFormatters/CodeFormatterCollection.cs0000664000175000017500000001504611504175260030636 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.Collections.Specialized; namespace NUnit.UiException.CodeFormatters { /// /// Makes the link between a file language and an ICodeFormatter. /// This class is used to know which formatter need to be call /// when displaying an ErrorItem. /// public class CodeFormatterCollection : IEnumerable { /// /// Maps language files to ICodeFormatters. /// private Dictionary _toFormatter; /// /// Builds an empty CodeFormatterCollection. /// public CodeFormatterCollection() { _toFormatter = new Dictionary(); return; } /// /// Gets the size of the collection. /// public int Count { get { return (_toFormatter.Count); } } /// /// Returns the ICodeFormatter that fit the given language. /// /// /// A language name, such as: "C#" or "Java". /// This parameter cannot be null. /// /// /// The ICodeFormatter that fit this language. /// /// public ICodeFormatter this[string language] { get { UiExceptionHelper.CheckNotNull(language, "language"); foreach (ICodeFormatter item in _toFormatter.Values) if (item.Language == language) return (item); throw new ArgumentException("unknown language: '" + language + "'"); } } /// /// Checks whether there is a formatter that has been /// assigned to the given file extension. /// /// A file extension such as: "cs". /// True if there is such formatter, false otherwise. public bool HasExtension(string extension) { if (extension == null) return (false); extension = extension.ToLower(); return (_toFormatter.ContainsKey(extension)); } /// /// Tests whether the collection contains a formatter for the given language. /// /// /// A language name. Ex: "C#", "Java" /// True if such formatter exists. public bool HasLanguage(string languageName) { if (languageName == null) return (false); foreach (ICodeFormatter item in _toFormatter.Values) if (item.Language == languageName) return (true); return (false); } /// /// Gets the ICodeFormatter that has been assigned to this extension. /// /// The file extension. This parameter /// cannot be null. /// The ICodeFormatter assigned to. public ICodeFormatter GetFromExtension(string extension) { UiExceptionHelper.CheckNotNull(extension, "extension"); extension = extension.ToLower(); return (_toFormatter[extension]); } /// /// Registers an ICodeFormatter for the given language. The system /// is not case sensitive. /// /// /// A non null formatter. /// /// /// A non null file language. /// The value must not be empty nor contain '.' and /// must not have been already registered. /// public void Register(ICodeFormatter formatter, string extension) { UiExceptionHelper.CheckNotNull(formatter, "formatter"); UiExceptionHelper.CheckNotNull(extension, "language"); extension = extension.ToLower(); UiExceptionHelper.CheckTrue(extension.Length > 0, "language cannot be empty", "language"); UiExceptionHelper.CheckTrue(extension.LastIndexOf('.') == -1, "language cannot contain '.'", "language"); UiExceptionHelper.CheckFalse(_toFormatter.ContainsKey(extension), "language '" + extension + "' has already an handler. Remove handler first.", "language"); _toFormatter.Add(extension, formatter); return; } /// /// Removes the formatter for the given file language. /// The language is not case sensitive. /// /// A file language. public void Remove(string extension) { if (extension == null) return; extension = extension.ToLower(); _toFormatter.Remove(extension); return; } /// /// Removes all formatters. /// public void Clear() { _toFormatter.Clear(); } /// /// Returns a string collection with all registered extensions. /// public StringCollection Extensions { get { StringCollection res; res = new StringCollection(); foreach (string extension in _toFormatter.Keys) res.Add(extension); return (res); } } #region IEnumerable Membres /// /// Returns an IEnumerator on all registered ICodeFormatter. /// public IEnumerator GetEnumerator() { return (_toFormatter.Values.GetEnumerator()); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/ExceptionItem.cs0000664000175000017500000001723711504175260023724 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.IO; namespace NUnit.UiException { /// /// (Formerly named ExceptionItem) /// /// This is the output analysis of one error line coming from /// a stack trace that still gathers the same data but in more /// convenient way to be read from. /// An ErrorItem represents one error with possible location /// informations such as: /// - filename where the error has occured /// - file's line number /// - method name /// public class ErrorItem { /// /// An access path to the source file referred by this item. /// private string _path; /// /// The full qualified name of the member method referred by this item. /// private string _fullyQualifiedMethodName; /// /// The line index where the exception occured. /// private int _line; /// /// Store the content of the file pointed by _path. /// private string _text; /// /// Create an instance of ErrorItem that /// has source code attachments. /// public ErrorItem(string path, int lineNumber) { UiExceptionHelper.CheckNotNull(path, "path"); _path = path; _line = lineNumber; return; } /// /// Create a new exception item. /// /// An absolute path to the source code file. /// A full qualified name of a member method. /// A line index where the exception occured. public ErrorItem(string path, string fullMethodName, int lineNumber) { _path = path; _fullyQualifiedMethodName = fullMethodName; _line = lineNumber; return; } /// /// Create an instance of ErrorItem that doesn't have /// any source code attachments. /// public ErrorItem() { // nothing to do } /// /// Reads and returns the part of Path that contains the filename /// of the source code file. /// public string FileName { get { return (System.IO.Path.GetFileName(_path)); } } /// /// Gets the absolute path to the source code file. /// public string Path { get { return (_path); } } /// /// Returns the file language - e.g.: the string after /// the last dot or null - /// public string FileExtension { get { int dotIndex; if (_path == null) return (null); dotIndex = _path.LastIndexOf(".", StringComparison.Ordinal); if (dotIndex > -1 && dotIndex < _path.Length - 1) return (_path.Substring(dotIndex + 1)); return (null); } } /// /// Gets the full qualified name of the member method. /// public string FullyQualifiedMethodName { get { return (_fullyQualifiedMethodName); } } /// /// Reads and return the method part from the FullyQualifiedMethodName. /// The value contains the signature of the method. /// public string MethodName { get { int index; if (FullyQualifiedMethodName == null) return (""); if ((index = FullyQualifiedMethodName.LastIndexOf(".", StringComparison.Ordinal)) == -1) return (FullyQualifiedMethodName); return (FullyQualifiedMethodName.Substring(index + 1)); } } /// /// Gets the method name without the argument list. /// public string BaseMethodName { get { string method = MethodName; int index = method.IndexOf("(", StringComparison.Ordinal); if (index > 0) return (method.Substring(0, index)); return (method); } } /// /// Reads and returns the class part from the FullyQualifiedMethodName. /// public string ClassName { get { int end_index; int start_index; if (FullyQualifiedMethodName == null) return (""); if ((end_index = FullyQualifiedMethodName.LastIndexOf(".", StringComparison.Ordinal)) == -1) return (""); start_index = end_index - 1; while (start_index > 0 && FullyQualifiedMethodName[start_index] != '.') start_index--; if (start_index >= 0 && FullyQualifiedMethodName[start_index] == '.') start_index++; return (FullyQualifiedMethodName.Substring(start_index, end_index - start_index)); } } /// /// Gets the line number where the exception occured. /// public int LineNumber { get { return (_line); } } /// /// Gets a boolean that says whether this item has source /// code localization attachments. /// public bool HasSourceAttachment { get { return (_path != null); } } /// /// Read and return the content of the underlying file. If the file /// cannot be found or read an exception is raised. /// public string ReadFile() { if (!System.IO.File.Exists(_path)) throw new FileNotFoundException("File does not exist. File: " + _path); if (_text == null) { StreamReader rder = new StreamReader(_path); _text = rder.ReadToEnd(); rder.Close(); } return (_text); } public override string ToString() { return ("TraceItem: {'" + _path + "', " + _fullyQualifiedMethodName + ", " + _line + "}"); } public override bool Equals(object obj) { ErrorItem item = obj as ErrorItem; if (item == null) return (false); return (_path == item._path && _fullyQualifiedMethodName == item._fullyQualifiedMethodName && _line == item._line); } public override int GetHashCode() { return base.GetHashCode(); } } } NUnit-2.6.0.12051/src/GuiException/UiException/AssemblyInfo.cs0000664000175000017500000000072211504175260023531 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/GuiException/UiException/DefaultTextManager.cs0000664000175000017500000000774011504175260024671 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace NUnit.UiException { /// /// This is a default implementation of ITextManager interface. /// public class DefaultTextManager : IEnumerable, ITextManager { /// /// Hold the text to be managed by this instance. /// private string _text; /// /// Array of strings where each string is a line in this text. /// private List _lines; /// /// Stores the character count of the longest line in this text. /// private int _maxLength; /// /// Builds a new instance of TextManager. /// public DefaultTextManager() { _lines = new List(); Text = ""; return; } /// /// Gets the number of lines in the text. /// public int LineCount { get { return (_lines.Count); } } /// /// Gets or sets the text to be managed by this object. /// public string Text { get { return (_text); } set { if (value == null) value = ""; _text = value; _populateLineCollection(value); } } /// /// Gets the line of text at the specified startingPosition. /// (zero based startingPosition). /// /// The startingPosition of the line to get. /// A string that represents the content of the specified line without /// the trailing characters. public string GetTextAt(int lineIndex) { return (_lines[lineIndex]); } /// /// Gets the character count of the longest line in this text. /// public int MaxLength { get { return (_maxLength); } } #region private definitions /// /// setup member data with the input text. /// private void _populateLineCollection(string text) { string line; int textIndex; int newIndex; textIndex = 0; _lines.Clear(); _maxLength = 0; while ((newIndex = text.IndexOf("\n", textIndex, StringComparison.Ordinal)) > textIndex) { line = text.Substring(textIndex, newIndex - textIndex).TrimEnd(); _maxLength = Math.Max(_maxLength, line.Length); _lines.Add(line); textIndex = newIndex + 1; } if (textIndex < text.Length) { line = text.Substring(textIndex).TrimEnd(); _maxLength = Math.Max(_maxLength, line.Length); _lines.Add(line); } return; } #endregion #region IEnumerable Membres /// /// Gets an IEnumerator that iterate through each line of the /// current text. /// /// An IEnumerator that iterate through each line of this text. public IEnumerator GetEnumerator() { return (_lines.GetEnumerator()); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/Properties/0000775000175000017500000000000011742560362022747 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/Properties/Resources.resx0000664000175000017500000001765711504175260025637 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ../../../../src/GuiException/UiException/Resources/ImageCopyToClipboard.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageErrorBrowserHeader.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageErrorList.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageReverseItemOrder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageSourceCodeDisplay.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageSplitterBox.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ../../../../src/GuiException/UiException/Resources/ImageStackTraceDisplay.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a NUnit-2.6.0.12051/src/GuiException/UiException/Properties/Resources.Designer.cs0000664000175000017500000001161411504175260027005 0ustar jtaylorjtaylor//------------------------------------------------------------------------------ // // Ce code a été généré par un outil. // Version du runtime :2.0.50727.1434 // // Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si // le code est régénéré. // //------------------------------------------------------------------------------ namespace NUnit.UiException.Properties { using System; /// /// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées. /// // Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder // à l'aide d'un outil, tel que ResGen ou Visual Studio. // Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen // avec l'option /str ou régénérez votre projet VS. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Retourne l'instance ResourceManager mise en cache utilisée par cette classe. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NUnit.UiException.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Remplace la propriété CurrentUICulture du thread actuel pour toutes /// les recherches de ressources à l'aide de cette classe de ressource fortement typée. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static System.Drawing.Bitmap ImageCopyToClipboard { get { object obj = ResourceManager.GetObject("ImageCopyToClipboard", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageErrorBrowserHeader { get { object obj = ResourceManager.GetObject("ImageErrorBrowserHeader", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageErrorList { get { object obj = ResourceManager.GetObject("ImageErrorList", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageReverseItemOrder { get { object obj = ResourceManager.GetObject("ImageReverseItemOrder", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageSourceCodeDisplay { get { object obj = ResourceManager.GetObject("ImageSourceCodeDisplay", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageSplitterBox { get { object obj = ResourceManager.GetObject("ImageSplitterBox", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap ImageStackTraceDisplay { get { object obj = ResourceManager.GetObject("ImageStackTraceDisplay", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceParser.cs0000664000175000017500000000743611504175260024350 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; using NUnit.UiException.StackTraceAnalysers; namespace NUnit.UiException { /// /// StackTraceParser is the entry class for analyzing and converting a stack /// trace - as given by .NET - into a manageable and ordered set of ErrorItem /// instances. /// StackTraceParser contains internaly a set of autonom, independent and /// interchangeable algorithms that makes the analysis of the stack robust and /// opened to changes. Its architecture is designed to abstract callers from /// secondary details such as the type of culture or file system that can /// both affect the format of the final stack as provided by .NET. /// In the future, this class could easily be extended by exposing a /// kind of register() method that would allow client code to append /// new algorithms of analysis in its internal list. /// public class StackTraceParser { /// /// Output list build from the StackTrace analyze . /// private ErrorItemCollection _items; /// /// One or more algorithms designed to locate function names /// inside a stack trace line. /// private IErrorParser _functionParsers; /// /// One or more algorithms designed to locate path names /// inside a stack strace line. /// private IErrorParser _pathParsers; /// /// One or more algorithms designed to locate line number /// information inside a stack strace line. /// private IErrorParser _lineNumberParsers; /// /// Build a new instance of StackTraceParser. /// public StackTraceParser() { _items = new ErrorItemCollection(); _functionParsers = new FunctionParser(); _pathParsers = new PathCompositeParser(); _lineNumberParsers = new LineNumberParser(); return; } /// /// Gives access to the collection of ErrorItem /// build during the analyze of the StackTrace. /// public ErrorItemCollection Items { get { return (_items); } } /// /// Reads and transforms the given stack trace into a manageable and ordered /// set of ErrorItem instances. The resulting set is stored into Items property. /// /// A string value that should contain a .Net stack trace. public void Parse(string stackTrace) { DefaultTextManager lines; RawError rawError; _items.Clear(); lines = new DefaultTextManager(); lines.Text = stackTrace; foreach (string line in lines) { rawError = new RawError(line); if (!_functionParsers.TryParse(this, rawError)) continue; _pathParsers.TryParse(this, rawError); _lineNumberParsers.TryParse(this, rawError); _items.Add(rawError.ToErrorItem()); } return; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Resources/0000775000175000017500000000000011742560362022565 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/Resources/ImageStackTraceDisplay.png0000664000175000017500000000241111504175260027601 0ustar jtaylorjtaylorPNG  IHDR rsRGBgAMA a cHRMz&u0`:pQ<PLTEce]{jBbjpdejsw~Åp3yMsSƧU[۶P۠ϭۼؠu\tRNSS%tEXtSoftwarePaint.NET v3.36%KIDATWc hl9vP\VEMIXSSUbE%X!lAqiI6F'3/ L\pn(,T|ċIENDB`NUnit-2.6.0.12051/src/GuiException/UiException/Resources/ImageSourceCodeDisplay.png0000664000175000017500000000254711504175260027622 0ustar jtaylorjtaylorPNG  IHDR exsRGBgAMA a cHRMz&u0`:pQ<PLTE/1T89VKLmXYdgiƟǟ̢ȩ̠֭պʾ̽زؾtRNSS%tEXtSoftwarePaint.NET v3.36%IDATW]@ @("k,kCEv+2;`;gs<:8ŀ`QʣhblC4' ¹߿"1&iڠ2u]tWûA% _/PluL^";\ρ_t<ڭzmK7۬3E;L4K= eIENDB`NUnit-2.6.0.12051/src/GuiException/UiException/Resources/ImageReverseItemOrder.png0000664000175000017500000000244611504175260027465 0ustar jtaylorjtaylorPNG  IHDR exsRGBgAMA a cHRMz&u0`:pQ<PLTEf33@@@333f3ffffff̙33ffffff̙f̙̙'G tRNSS%tEXtSoftwarePaint.NET v3.36%hIDATWU CQ7usY=@ZJlչc̯)׋-m?T9b0߃m #nH m}w+'gY,IENDB`NUnit-2.6.0.12051/src/GuiException/UiException/Resources/ImageErrorBrowserHeader.png0000664000175000017500000000171211504175260030000 0ustar jtaylorjtaylorPNG  IHDR gAMA aPLTEJ pHYs(JtEXtSoftwarePaint.NET v3.36%;"VID+ms>4g&IENDB`NUnit-2.6.0.12051/src/GuiException/UiException/Resources/ImageErrorList.png0000664000175000017500000000412411504175260026157 0ustar jtaylorjtaylorPNG  IHDRRKgAMA a pHYs(JtEXtSoftwarePaint.NET v3.36%IDATx^[lTEǷ[}B^ah4}FI#'񂷤@$JaB-PJaiPh)b[Joofϲj3VNeg={niʹ5J)\!5ܑJiUԦ&OMuJRFU|u>EjgW*kz\{tKHa>{)Z6g(| ݴt0*uŔ_M{3r~cwiw~tOKm[Y\LӏR^Q=%c*O}W(ֈWLU픞[Mؖ"0٨1:TꡬZ:p Ej+kz)rD1*2S轢_e:rGQluDؖj6%\TcT*6KtTcTN׎;̃H5FEtmkضz)2Tc4cA^jꜛLNTcTjֹDH RQ:5Rd!D1*R&KI#YZ#Rk:KH5Fis97CEQ6D4kU)rD1*6D4k[)r/D1*R\#EH5FEfm%Y#RwֶUYD1H]A#Y~Ǘ"C"M^dy"&cA~Tc4cA^ j]D1*2Z,o# RQj,/>7O< j4[#R'Jtrh"u r :L?? H:pK$75"lFÂ_4M某[!F׶68^̽'iˮJJ-Zkŋ31t뢹>ZGD>~>.{ abz|,Zݦ|XH߂,_+@G"%zLG%7c\/D[5ZHE'E222r}>C*%YE$ L$_2[:B"'x']m|]M1;DfY*>(=4xLxw2}2NG!2E*D.rEV]9V;pzzOtzLD׾^W+exLOH$ sz<9n" $18V N :4|>1?K헅PnwR[5ܽuE2F>ςg)$xLH= 5En'!·},_dRSl 6KY"D|ZхK=9蠜ܣ0x<)`2w|n<>GێP7vP#grBEMkk֊D̊,!/j]y^pFCB_.4r"C6Nepc8utPsk/!%8 p &0&Bz=]#;YKtɃDfonKDzQu8YOrJeh4e4s:v}"u8G$-d4rwCl /// Splits a text formatted as C# code into a list of identified tokens. /// public class Lexer { /// /// Reading position in the current text. /// private int _position; /// /// Text where to fetch tokens. /// private string _text; /// /// Last identified token. /// private InternalToken _token; /// /// Holds pre-defined sequences. /// private TokenDictionary _dictionary; /// /// Builds a new instance of Lexer. /// public Lexer() { _position = 0; _text = ""; _dictionary = new TokenDictionary(); _dictionary.Add("/*", LexerTag.CommentC_Open); _dictionary.Add("*/", LexerTag.CommentC_Close); _dictionary.Add("//", LexerTag.CommentCpp); // Here: definition of one lengthed sequences _dictionary.Add("\\", LexerTag.Text); _dictionary.Add(" ", LexerTag.Separator); _dictionary.Add("\t", LexerTag.Separator); _dictionary.Add("\r", LexerTag.Separator); _dictionary.Add(".", LexerTag.Separator); _dictionary.Add(";", LexerTag.Separator); _dictionary.Add("[", LexerTag.Separator); _dictionary.Add("]", LexerTag.Separator); _dictionary.Add("(", LexerTag.Separator); _dictionary.Add(")", LexerTag.Separator); _dictionary.Add("#", LexerTag.Separator); _dictionary.Add(":", LexerTag.Separator); _dictionary.Add("<", LexerTag.Separator); _dictionary.Add(">", LexerTag.Separator); _dictionary.Add("=", LexerTag.Separator); _dictionary.Add(",", LexerTag.Separator); _dictionary.Add("\n", LexerTag.EndOfLine); _dictionary.Add("'", LexerTag.SingleQuote); _dictionary.Add("\"", LexerTag.DoubleQuote); return; } public TokenDictionary Dictionary { get { return (_dictionary); } } /// /// Clear all previously defined sequences. /// protected void Clear() { _dictionary = new TokenDictionary(); return; } /// /// Setup the text to be splitted in tokens. /// /// Client code must call Next() first before getting /// the first available token (if any). /// public void Parse(string codeCSharp) { UiExceptionHelper.CheckNotNull(codeCSharp, "text"); _text = codeCSharp; _position = 0; return; } /// /// Gets the token identifed after a call to Next(). /// The value may be null if the end of the text has been reached. /// public LexToken CurrentToken { get { return (_token); } } /// /// Checks whether there are none visited tokens. /// public bool HasNext() { return (_position < _text.Length); } /// /// Call this method to visit iteratively all tokens in the source text. /// Each time a token has been identifier, the method returns true and the /// identified Token is place under the CurrentToken property. /// When there is not more token to visit, the method returns false /// and null is set in CurrentToken property. /// public bool Next() { char c; LexToken token; string prediction; int pos; int count; int prediction_length; _token = null; if (!HasNext()) return (false); pos = _position; _token = new InternalToken(pos); prediction_length = _dictionary[0].Text.Length; while (pos < _text.Length) { c = _text[pos]; _token.AppendsChar(c); prediction = ""; if (pos + 1 < _text.Length) { count = Math.Min(prediction_length, _text.Length - pos - 1); prediction = _text.Substring(pos + 1, count); } token = _dictionary.TryMatch(_token.Text, prediction); if (token != null) { _token.SetText(token.Text); _token.SetIndex(_position); _token.SetLexerTag(token.Tag); _position += _token.Text.Length; break; } pos++; } return (true); } #region InternalToken class InternalToken : LexToken { /// /// Builds a concrete instance of LexToken. By default, created instance /// are setup with LexerTag.Text value. /// /// The starting startingPosition of this token in the text. public InternalToken(int index) { _tag = LexerTag.Text; _text = ""; _start = index; return; } /// /// Appends this character to this token. /// public void AppendsChar(char c) { _text += c; } /// /// Removes the "count" ending character of this token. /// public void PopChars(int count) { _text = _text.Remove(_text.Length - count); } /// /// Set a new value to the Tag property. /// public void SetLexerTag(LexerTag tag) { _tag = tag; } public void SetText(string text) { _text = text; } public void SetIndex(int index) { _start = index; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/TokenClassifier.cs0000664000175000017500000004212411504175260026562 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.CodeFormatters { /// /// Used at an internal stage to convert LexToken into ClassifiedToken. This class provides /// a very basic semantic analysis to make text following in one the categories below: /// - regular code, /// - developper comments, /// - strings / character. /// The output of this class is used by CSharpCodeFormatter to achieve the basic syntax coloring. /// public class TokenClassifier { #region SMSTATE code // the list below contains constant values defining states for the finite // smState machine that makes all the work of converting LexToken into ClassifiedToken. // for instance, Lexer can send inputs like: // // [Text][Separator][CommentC_Open][Text][CommentC_Close] // // This LexToken sequence can for instance be converted that way by TokenClassifier. // // - [Text][Separator] => [Code] // - [CommentC_Open][Text][CommentC_Close] => [Comment] // /// /// State code for the smState machine. /// State when reaching a code block. /// public const int SMSTATE_CODE = 0; /// /// State code for the smState machine. /// State when reaching a C comment block. /// public const int SMSTATE_CCOMMENT = 1; /// /// State code for the smState machine. /// State when reaching a C++ comment block. /// public const int SMSTATE_CPPCOMMENT = 2; /// /// State code for the smState machine. /// State when reaching a char surrounded by single quotes. /// public const int SMSTATE_CHAR = 3; /// /// State code for the smState machine. /// State when reaching a string surrounded by double quotes. /// public const int SMSTATE_STRING = 4; #endregion /// /// A finite smState machine where states are: SMSTATE values and /// transitions are LexToken. /// private StateMachine _sm; /// /// The current StateMachine's SMTATE code. /// private int _sm_output; /// /// Makes a link between SMSTATE code and ClassificationTag. /// private Dictionary _tags; /// /// Contains the list of C# keywords. /// private Dictionary _keywords; /// /// Indicate whether Lexer is in escaping mode. /// This flag is set to true when parsing "\\" and /// can influate on the following LexerTag value. /// private bool _escaping; /// /// Build a new instance of TokenClassifier. /// public TokenClassifier() { string[] words; _sm = new StateMachine(); _tags = new Dictionary(); _tags.Add(SMSTATE_CODE, ClassificationTag.Code); _tags.Add(SMSTATE_CCOMMENT, ClassificationTag.Comment); _tags.Add(SMSTATE_CPPCOMMENT, ClassificationTag.Comment); _tags.Add(SMSTATE_CHAR, ClassificationTag.String); _tags.Add(SMSTATE_STRING, ClassificationTag.String); // build the list of predefined keywords. // this is from the official msdn site. Curiously, some keywords // were ommited from the official documentation. // For instance "get", "set", "region" and "endregion" were // not part of the official list. Maybe it's a mistake or a misunderstanding // whatever... I want them paint in blue as well! words = new string[] { "abstract", "event", "new", "struct", "as", "explicit", "null", "switch", "base", "extern", "object", "this", "bool", "false", "operator", "throw", "break", "finally", "out", "true", "byte", "fixed", "override", "try", "case", "float", "params", "typeof", "catch", "for", "private", "uint", "char", "foreach", "protected", "ulong", "checked", "goto", "public", "unchecked", "class", "if", "readonly", "unsafe", "const", "implicit", "ref", "ushort", "continue", "in", "return", "using", "decimal", "int", "sbyte", "virtual", "default", "interface", "sealed", "volatile", "delegate", "internal", "short", "void", "do", "is", "sizeof", "while", "double", "lock", "stackalloc", "else", "long", "static", "enum", "namespace", "string", "partial", "get", "set", "region", "endregion", }; _keywords = new Dictionary(); foreach (string key in words) _keywords.Add(key, true); Reset(); return; } /// /// Tells whether TokenClassifier is currently in escaping mode. When true, /// this flag causes TokenClassifier to override the final classification /// of a basic entity (such as: ") to be treated as normal text instead of /// being interpreted as a string delimiter. /// public bool Escaping { get { return (_escaping); } } /// /// Reset the StateMachine to default value. (code block). /// public void Reset() { _sm_output = SMSTATE_CODE; _escaping = false; return; } /// /// Classify the given LexToken into a ClassificationTag. /// /// The token to be classified. /// The smState value. public ClassificationTag Classify(LexToken token) { int classTag; UiExceptionHelper.CheckNotNull(token, "token"); classTag = AcceptLexToken(token); if (classTag == SMSTATE_CODE && _keywords.ContainsKey(token.Text)) return (ClassificationTag.Keyword); // Parsing a token whoose Text value is set to '\' // causes the classifier to set/reset is escaping mode. if (token.Text == "\\" && _sm_output == SMSTATE_STRING && !_escaping) _escaping = true; else _escaping = false; return (_tags[classTag]); } /// /// Classify the given token and get its corresponding SMSTATE value. /// /// The LexToken to be classified. /// An SMSTATE value. protected int AcceptLexToken(LexToken token) { int smState; if (_escaping) return (SMSTATE_STRING); smState = GetTokenSMSTATE(_sm_output, token.Tag); _sm_output = GetSMSTATE(_sm_output, token.Tag); return (smState); } /// /// Gets the SMSTATE under the "transition" going from "smState". /// /// The current smState. /// The current LexerTag. /// The new smState. protected int GetSMSTATE(int smState, LexerTag transition) { return (_sm.GetSMSTATE(smState, transition)); } /// /// Gets a token SMSTATE under the "transition" going from "smState". /// /// The current smState machine. /// The LexerTag to be classified. /// The LexerTag's classification. protected int GetTokenSMSTATE(int smState, LexerTag transition) { return (_sm.GetTokenSMSTATE(smState, transition)); } #region StateMachine /// /// Defines a transition (of a state machine). /// class TransitionData { /// /// The current transition. /// public LexerTag Transition; /// /// The SMSTATE code reached when following that transition. /// public int SMSTATE; /// /// The TokenSMSTATE reached when following that transition. /// public int TokenSMSTATE; public TransitionData(LexerTag transition, int smState) { Transition = transition; SMSTATE = smState; TokenSMSTATE = smState; return; } public TransitionData(LexerTag transition, int smState, int tokenSmState) : this(transition, smState) { TokenSMSTATE = tokenSmState; } } /// /// Defines a state (of a state machine) and its associated transitions. /// class State { public int InitialState; public TransitionData[] Transitions; public State(int initialState, TransitionData[] transitions) { int i; int j; UiExceptionHelper.CheckNotNull(transitions, "transitions"); UiExceptionHelper.CheckTrue( transitions.Length == 8, "expecting transitions.Length to be 8", "transitions"); for (i = 0; i < transitions.Length; ++i) for (j = 0; j < transitions.Length; ++j) { if (j == i) continue; if (transitions[j].Transition == transitions[i].Transition) UiExceptionHelper.CheckTrue(false, String.Format("transition '{0}' already present", transitions[j].Transition), "transitions"); } InitialState = initialState; Transitions = transitions; return; } public TransitionData this[LexerTag transition] { get { foreach (TransitionData couple in Transitions) if (couple.Transition == transition) return (couple); return (null); } } } /// /// A finite state machine. Where states are SMSTATE codes and /// transitions are LexTokens. /// class StateMachine { private State[] _states; public StateMachine() { _states = new State[5]; // defines transitions from SMSTATE_CODE _states[0] = new State( SMSTATE_CODE, new TransitionData[] { new TransitionData(LexerTag.EndOfLine, SMSTATE_CODE), new TransitionData(LexerTag.Separator, SMSTATE_CODE), new TransitionData(LexerTag.Text, SMSTATE_CODE), new TransitionData(LexerTag.CommentC_Open, SMSTATE_CCOMMENT), new TransitionData(LexerTag.CommentC_Close, SMSTATE_CODE, SMSTATE_CCOMMENT), new TransitionData(LexerTag.CommentCpp, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.SingleQuote, SMSTATE_CHAR), new TransitionData(LexerTag.DoubleQuote, SMSTATE_STRING), }); // defines transitions from SMSTATE_CCOMMENT _states[1] = new State( SMSTATE_CCOMMENT, new TransitionData[] { new TransitionData(LexerTag.EndOfLine, SMSTATE_CCOMMENT), new TransitionData(LexerTag.Separator, SMSTATE_CCOMMENT), new TransitionData(LexerTag.Text, SMSTATE_CCOMMENT), new TransitionData(LexerTag.CommentC_Open, SMSTATE_CCOMMENT), new TransitionData(LexerTag.CommentC_Close, SMSTATE_CODE, SMSTATE_CCOMMENT), new TransitionData(LexerTag.CommentCpp, SMSTATE_CCOMMENT), new TransitionData(LexerTag.SingleQuote, SMSTATE_CCOMMENT), new TransitionData(LexerTag.DoubleQuote, SMSTATE_CCOMMENT), }); // defines transitions from SMSTATE_CPPCOMMENT _states[2] = new State( SMSTATE_CPPCOMMENT, new TransitionData[] { new TransitionData(LexerTag.EndOfLine, SMSTATE_CODE), new TransitionData(LexerTag.Separator, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.Text, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.CommentC_Open, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.CommentC_Close, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.CommentCpp, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.SingleQuote, SMSTATE_CPPCOMMENT), new TransitionData(LexerTag.DoubleQuote, SMSTATE_CPPCOMMENT), }); // defines transition from SMSTATE_CHAR _states[3] = new State( SMSTATE_CHAR, new TransitionData[] { new TransitionData(LexerTag.EndOfLine, SMSTATE_CHAR), new TransitionData(LexerTag.Separator, SMSTATE_CHAR), new TransitionData(LexerTag.Text, SMSTATE_CHAR), new TransitionData(LexerTag.CommentC_Open, SMSTATE_CHAR), new TransitionData(LexerTag.CommentC_Close, SMSTATE_CHAR), new TransitionData(LexerTag.CommentCpp, SMSTATE_CHAR), new TransitionData(LexerTag.SingleQuote, SMSTATE_CODE, SMSTATE_CHAR), new TransitionData(LexerTag.DoubleQuote, SMSTATE_CHAR), }); // defines transition from SMSTATE_STRING _states[4] = new State( SMSTATE_STRING, new TransitionData[] { new TransitionData(LexerTag.EndOfLine, SMSTATE_STRING), new TransitionData(LexerTag.Separator, SMSTATE_STRING), new TransitionData(LexerTag.Text, SMSTATE_STRING), new TransitionData(LexerTag.CommentC_Open, SMSTATE_STRING), new TransitionData(LexerTag.CommentC_Close, SMSTATE_STRING), new TransitionData(LexerTag.CommentCpp, SMSTATE_STRING), new TransitionData(LexerTag.SingleQuote, SMSTATE_STRING), new TransitionData(LexerTag.DoubleQuote, SMSTATE_CODE, SMSTATE_STRING), }); return; } /// /// Follow "transition" going from "smState" and returns reached SMSTATE. /// public int GetSMSTATE(int smState, LexerTag transition) { foreach (State st in _states) if (st.InitialState == smState) return (st[transition].SMSTATE); return (SMSTATE_CODE); } /// /// Follow "transition" going from "smState" and returns reached TokenSMSTATE. /// public int GetTokenSMSTATE(int smState, LexerTag transition) { foreach (State st in _states) if (st.InitialState == smState) return (st[transition].TokenSMSTATE); return (SMSTATE_CODE); } } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/CSCode.cs0000664000175000017500000003071511504175260024600 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.CodeFormatters { /// /// (Formerly named CSCode) /// /// Implements ITextManager and adds new behaviors to provide support for basic /// syntax coloring. /// public class FormattedCode : ITextManager { /// /// Keeps tracks of the text and the data used by the syntax coloring feature. /// protected CodeInfo _codeInfo; /// /// Stores the character count of the longest line in this text. /// private int _maxLength; /// /// Builds a new instance of FormattedCode. /// public FormattedCode() { _codeInfo = NewCodeInfo(); _maxLength = 0; return; } public FormattedCode(string csharpText, int[] strIndexes, byte[] tagValues, int[] lineIndexes) { UiExceptionHelper.CheckNotNull(csharpText, "csharpText"); UiExceptionHelper.CheckNotNull(strIndexes, "strIndexes"); UiExceptionHelper.CheckNotNull(tagValues, "tagValues"); UiExceptionHelper.CheckNotNull(lineIndexes, "lineIndexes"); _codeInfo = new CodeInfo(); _codeInfo.Text = csharpText; _codeInfo.IndexArray = new List(); foreach (int index in strIndexes) _codeInfo.IndexArray.Add(index); _codeInfo.TagArray = new List(); foreach (byte tag in tagValues) _codeInfo.TagArray.Add(tag); _codeInfo.LineArray = new List(); foreach (int line in lineIndexes) _codeInfo.LineArray.Add(line); return; } public static FormattedCode Empty { get { return (new FormattedCode()); } } public CodeInfo CopyInfo() { FormattedCode copy; copy = new FormattedCode(_codeInfo.Text, _codeInfo.IndexArray.ToArray(), _codeInfo.TagArray.ToArray(), _codeInfo.LineArray.ToArray()); return (copy._codeInfo); } /// /// Builds a new instance of CodeInfo. /// public static CodeInfo NewCodeInfo() { CodeInfo res; res = new CodeInfo(); res.Text = ""; res.IndexArray = new List(); res.LineArray = new List(); res.TagArray = new List(); return (res); } /// /// Gets the text currently managed by this object. /// public string Text { get { return (_codeInfo.Text); } } /// /// Gets the line count in the text currently /// managed by this object. /// public int LineCount { get { return (_codeInfo.LineArray.Count); } } /// /// Gets the character count of the longest line /// in this text. /// public int MaxLength { get { int i; if (_maxLength == 0) for (i = 0; i < LineCount; ++i) _maxLength = Math.Max(_maxLength, this[i].Text.TrimEnd().Length); return (_maxLength); } } /// /// Gives access to the collection of ClassifiedToken at the specified lineIndex. /// /// A zero based startingPosition. /// The ClassifiedTokenCollection instance at this startingPosition. public ClassifiedTokenCollection this[int lineIndex] { get { return (new InternalCSTokenCollection(_codeInfo, lineIndex)); } } /// /// Gets the text at the specified line. /// /// A zero based startingPosition. /// The text at the specified line startingPosition. public string GetTextAt(int lineIndex) { return (this[lineIndex].Text); } /// /// An utility method that check data consistency. The operation /// raises an exception if an error is found. /// public static void CheckData(FormattedCode data) { List lines; int line; int bound; int i; UiExceptionHelper.CheckNotNull(data, "data"); UiExceptionHelper.CheckTrue( data._codeInfo.IndexArray.Count == data._codeInfo.TagArray.Count, "IndexArray.Count and TagArray.Count must match.", "data"); bound = data._codeInfo.IndexArray.Count; lines = data._codeInfo.LineArray; for (i = 0; i < lines.Count; ++i) { line = lines[i]; UiExceptionHelper.CheckTrue( line >= 0 && line < bound, "Bad LineArray value at index " + i + ", value was: " + line + ", expected to be in: [0-" + bound + "[.", "data"); if (i == 0) continue; UiExceptionHelper.CheckTrue( lines[i] > lines[i - 1], "Bad LineArray[" + i + "], value was: " + line + ", expected to be > than LineArray[" + (i - 1) + "]=" + lines[i - 1] + ".", "data"); } return; } public override bool Equals(object obj) { FormattedCode arg; int i; if (obj == null || !(obj is FormattedCode)) return (false); arg = obj as FormattedCode; if (arg._codeInfo.Text != _codeInfo.Text || arg._codeInfo.IndexArray.Count != _codeInfo.IndexArray.Count || arg._codeInfo.TagArray.Count != _codeInfo.TagArray.Count || arg._codeInfo.LineArray.Count != _codeInfo.LineArray.Count) return (false); for (i = 0; i < arg._codeInfo.IndexArray.Count; ++i) if (arg._codeInfo.IndexArray[i] != _codeInfo.IndexArray[i]) return (false); for (i = 0; i < arg._codeInfo.TagArray.Count; ++i) if (arg._codeInfo.TagArray[i] != _codeInfo.TagArray[i]) return (false); for (i = 0; i < arg._codeInfo.LineArray.Count; ++i) if (arg._codeInfo.LineArray[i] != _codeInfo.LineArray[i]) return (false); return (true); } public override int GetHashCode() { return base.GetHashCode(); } public override string ToString() { string res; string index_array; string tag_array; string line_array; int i; index_array = ""; for (i = 0; i < _codeInfo.IndexArray.Count; ++i) { if (i > 0) index_array += ", "; index_array += "" + _codeInfo.IndexArray[i]; } tag_array = ""; for (i = 0; i < _codeInfo.TagArray.Count; ++i) { if (i > 0) tag_array += ", "; tag_array += "" + _codeInfo.TagArray[i]; } line_array = ""; for (i = 0; i < _codeInfo.LineArray.Count; ++i) { if (i > 0) line_array += ", "; line_array += "" + _codeInfo.LineArray[i]; } res = String.Format( "FormattedCode: [(text=[{0}], len={1}), (startingPosition=[{2}]), (tag=[{3}]), (line=[{4}])]", _codeInfo.Text, _codeInfo.Text.Length, index_array, tag_array, line_array); return (res); } /// /// A naive attempt to modelize a structure of data that manages the text to be /// displayed and extra data to make basic syntax coloring at rendering time, /// while keeping a low memory footprint. /// /// At rendering time, CodeInfo is used to make a link between the text to be drawn /// and the brush color to be used during the process. So it is possible to distinguishes /// code, comments, keywords and strings. /// Currently, CodeInfo is used to split the text into a collection of couple of data, /// where each couple is composed of: /// - a string of characters /// - a value (called tag) that classifies this string from 0 to 3. /// Where 0 corresponds to 'Code', 1 to 'Keyword' and so on. /// These couples are named 'ClassifiedToken'. At rendering time, the process can link each /// of these values to a particular System.Drawing.Brush instance and display text /// differently. /// /// However, keeping track of all these couples at any time could have a significative /// impact on memory especially for big files. Therefore, instead of storing all theses couples, /// CodeInfo stores just primitive information that allow to build ClassifiedToken instances on the fly. /// public class CodeInfo { /// /// Holds the entire text as a simple string. /// public string Text; /// /// Array of character indexes that refers to /// the field "Text". Each value in this array /// must be interpreted as the starting index position /// in the string into Text. /// public List IndexArray; /// /// Array of ClassificationTag values held as a /// byte array. There is a one-to-one correspondance /// with 'IndexArray'. i.e.: TagArray[0] refers to the /// ClassificationTag value for string sequence at /// IndexArray[0]. TagArray[1] refers value to IndexArray[1] and /// so on... Hence, the following condition: /// - IndexArray.Count == TagArray.Count must be verified. /// public List TagArray; /// /// This index_array is used to easily locate the start of each /// line of text, for instance: startingPosition[0] refers to line startingPosition 0, /// startingPosition[1] refers to line startingPosition 1 and so on... /// However, there is a small indirection in that this index_array /// doesn't directly hold string indexes but refers to the startingPosition /// of the item to be used in 'IndexArray'. /// Therefore, LineArray[0] gives access to the startingPosition of the /// IndexArray's item to be used to get the corresponding character /// position. Hence, line 0 starts at: IndexArray[LineArray[0]] /// line 1: IndexArray[LineArray[1]] and so on... /// public List LineArray; } #region InternalCSTokenCollection class InternalCSTokenCollection : ClassifiedTokenCollection { public InternalCSTokenCollection(CodeInfo info, int lineIndex) { _info = info; _lineIndex = lineIndex; return; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/CSParser.cs0000664000175000017500000002002411504175260025152 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.CodeFormatters { /// /// (formerly named CSParser) /// /// Helper class to build and setup FormattedCode instances from formatted C# texts. /// public class CSharpCodeFormatter : ICodeFormatter { /// /// The underlying data object of a FormattedCode instance. /// private FormattedCode.CodeInfo _info; /// /// Builds a new instance of CSharpCodeFormatter. /// public CSharpCodeFormatter() { _info = FormattedCode.NewCodeInfo(); return; } /// /// Gets a new instance of FormattedCode. /// To get useful FormattedCode instances, caller should ensure /// that TryParse() was invoked first. /// public FormattedCode CSCode { get { return (new InternalFormattedCode(_info)); } } #region ICodeFormatter Membres /// /// Returns "C#" /// public string Language { get { return ("C#"); } } /// /// Interprets and highlight the given string as C# code /// and return the resulting FormattedCode instance. /// /// A string read as C# code. /// This parameter must not be null. /// A FormattedCode instance containing data /// to highlight the text with basic syntax coloring. public FormattedCode Format(string csharpCode) { UiExceptionHelper.CheckNotNull(csharpCode, "csharpCode"); _info = FormattedCode.NewCodeInfo(); csharpCode = PreProcess(csharpCode); Parse(csharpCode); return (CSCode); } #endregion /// /// Prepare input text for the parsing stage. /// /// The text to be pre-processed. /// A string ready to be parsed. protected string PreProcess(string text) { if (text == null) return (null); // this replace tabulation by space sequences. The reason is // that the technique used to measure strings at rendering time // fail to measure '\t' correctly and lines of text containing those // characters are badly aligned. // The simplest thing to fix that is to remove tabs altogether. return (text.Replace("\t", " ")); } /// /// Analyzes the input text as C# code. This method doesn't return anything. /// Callers may retrieve the result of this process by querying the FormattedCode property. /// Passing null results in raising an exception. /// /// The text to be analyzed. protected void Parse(string csharp) { TokenClassifier classifier; ConcreteToken csToken; ClassificationTag tag; Lexer lexer; StringBuilder text; int tokenIndex; UiExceptionHelper.CheckNotNull(csharp, "csharp"); csharp = PreProcess(csharp); lexer = new Lexer(); lexer.Parse(csharp); classifier = new TokenClassifier(); text = new StringBuilder(); csToken = null; tokenIndex = 0; // loop through each token in the text while (lexer.Next()) { // classify the current token tag = classifier.Classify(lexer.CurrentToken); // if the tag cannot be merged with current csToken // we flush csToken into _info and build a new instance // from the current tag. if (csToken == null || !csToken.CanMerge(_info.LineArray.Count, tag)) { _flushToken(csToken, _info); csToken = new ConcreteToken( lexer.CurrentToken.Text, tag, lexer.CurrentToken.IndexStart, _info.LineArray.Count); } // append token's text into text text.Append(lexer.CurrentToken.Text); // handle newline character. Appends tokenIndex to LineArray // and set tokenIndex to the start of the newline. if (lexer.CurrentToken.Text == "\n") { _info.LineArray.Add(tokenIndex); tokenIndex = _info.IndexArray.Count + 1; } } // flush terminal token _flushToken(csToken, _info); if (csToken != null && _info.LineArray.Count == 0) _info.LineArray.Add(tokenIndex); _info.Text = csharp; return; } /// /// Appends data in token at the end of output. /// /// Token to be merged with output. /// Target location. private void _flushToken(ClassifiedToken token, FormattedCode.CodeInfo output) { if (token == null) return; output.IndexArray.Add(token.IndexStart); output.TagArray.Add((byte)token.Tag); return; } #region InternalFormattedCode /// /// Implements FormattedCode. /// class InternalFormattedCode : FormattedCode { public InternalFormattedCode(FormattedCode.CodeInfo info) { _codeInfo = info; } } #endregion #region ConcreteToken /// /// Implements ClassifiedToken. /// class ConcreteToken : ClassifiedToken { private int _lineIndex; /// /// Builds and setup a new instance of ClassifiedToken. /// /// The text in this token. /// The smState tag. /// Starting startingPosition of the string from the beginning of the text. /// The line startingPosition. public ConcreteToken(string text, ClassificationTag tag, int indexStart, int lineIndex) { _text = text; _tag = tag; _indexStart = indexStart; _lineIndex = lineIndex; return; } /// /// Tests whether or not the given lineIndex and tag are compatible with /// the ones in the current Token. /// /// A line startingPosition. /// A smState tag. /// A boolean that says whether these data are compatible. public bool CanMerge(int lineIndex, ClassificationTag tag) { return (_tag == tag && _lineIndex == lineIndex); } } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/TokenDictionary.cs0000664000175000017500000002742711504175260026614 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace NUnit.UiException.CodeFormatters { /// /// TokenDictionary is responsible for defining and identifying a set of basic /// strings in a given text that have a particular meaning. For instance: /// - Separator, (ex: "{" ";" "]" ...) /// - comment markers, (ex: "//" "/*" "*/") /// - string markers, (ex: '"' '\'') /// - Other -> "Text" (all other strings but the ones aboves). /// To achieve this, TokenDictionary firstly defines methods to register and query which /// strings have been registered. Secondly it defines a convenient method: TryMatch() /// responsible for splitting a given string in one or two parts where the first one will /// fall in one of the above categories. When calling TryMatch() iteratively --see Lexer--, /// one can tag a text into a list of tokens that might server for a semantic analysis. /// /// TokenDictionary and Lexer are both responsible for dealing with the lexical analysis /// job that is the first step to make basic syntax coloring. /// /// Front class for the lexical analysis. public class TokenDictionary : IEnumerable { private List _list; private List _working; /// /// Build an empty instance of TokenDictionary. /// public TokenDictionary() { _list = new List(); _working = new List(); return; } /// /// Gets the token count defined in this instance. /// public int Count { get { return (_list.Count); } } /// /// Gets the token at the given index. /// /// Index of the token to be returned. /// The token at the specified index. public LexToken this[int index] { get { return (_list[index]); } } /// /// Build a new token and add it to the list of tokens known by TokenDictionary. /// Tokens must be added from the longest text value to the shortest otherwise /// an exception will be raised. /// /// /// The token's text value. It must not be null nor empty. It must not be already /// defined neither. If there are tokens already defined, value's length must not /// be longer than the previous added token. /// /// The token's tag value. public void Add(string value, LexerTag tag) { InternalLexToken newToken; UiExceptionHelper.CheckNotNull(value, "value"); UiExceptionHelper.CheckFalse(value == "", "Token value must not be empty.", "value"); UiExceptionHelper.CheckFalse( Contains(value), String.Format("Token '{0}' is already defined.", value), "value"); if (Count > 0) UiExceptionHelper.CheckTrue( _list[Count - 1].Text.Length >= value.Length, "Tokens must be inserted from the longest to the shortest value.", "value"); newToken = new InternalLexToken(value, tag); // loop through each item to populate // newToken.StartingWith list. foreach (InternalLexToken item in _list) if (item.Text.StartsWith(value)) newToken.StartingWith.Add(item); _list.Add(newToken); return; } /// /// Tests whether the given string matches a token known by this instance. /// /// /// A string to be identify with a token in this instance. /// /// /// True if the string matches a token's text /// value in this instance, false otherwise. /// public bool Contains(string value) { foreach (LexToken item in _list) if (item.Text == value) return (true); return (false); } /// /// Try to match in "text" + "prediction" a token previously defined with the Add() method. /// Since TryMatch() may return null, it should be called from a loop that scans iteratively /// all characters of an input text. /// /// TryMatch() can put the caller in the two following situations: /// 1) if parameters "text"+"prediction" don't hold any token, null will be returned. In this /// case caller is expected to append to "text" one character more and to shift "prediction" /// by one character ahead before calling TryMatch() again. /// 2) if parameters "text"+"prediction" look like [data]TOKEN --where [data] is any other string /// but the ones in tokens-- TryMatch() will return an instance of LexToken which LexToken.Text /// and LexToken.Tag properties will be setup with identified data. In this case caller is /// expected to shift its reading position by the lenght of text put in LexToken.Text. Besides /// "text" parameter should reset its length to 1 again. /// /// /// At the very beginning, text should be of size 1 and set up with the first character from the /// input text. Each time TryMatch() return null, the following character from the input text /// should be appended to "text". Once a token is returned, this parameter should reset its size /// to 1 and be filled with the character coming just after the identified string. /// This parameter cannot be null. /// /// /// This parameter represents a constant sized string that goes just before the data in "text". /// If the caller reach the end of the text and there are not enough character to fill "prediction" /// completely this parameter can be filled with remaining character and eventually becoming empty. /// The size of this string should be equal to the lenght of the longest token defined in /// this instance of TokenDictionary. /// This parameter cannot be null. /// /// /// The first identifiable LexToken in "text"+"prediction". Returns may be null. /// /// /// To have a look on the loop implementation.. /// public LexToken TryMatch(string text, string prediction) { UiExceptionHelper.CheckNotNull(text, "text"); UiExceptionHelper.CheckNotNull(prediction, "prediction"); foreach (InternalLexToken token in _list) { if (text.EndsWith(token.Text)) { // text may look like [data]TOKEN // where [data] is normal text possibly empty. if (text.Length > token.Text.Length) { // get only [data] part return (new LexToken( text.Substring(0, text.Length - token.Text.Length), LexerTag.Text, -1)); } // text looks like TOKEN, however we can't return text at // this stage before testing content of prediction. Since // there is a possibility that a longer TOKEN be in the concatenated // string: text + prediction. (note: longer TOKENs have higher // priority over shorter ones) if (prediction != "") { string pattern; int i; _working.Clear(); PopulateTokenStartingWith(token, _working); for (i = 1; i < _working.Count; ++i) { if (_working[i].Text.Length <= text.Length || _working[i].Text.Length > text.Length + prediction.Length) continue; pattern = text + prediction.Substring(0, _working[i].Text.Length - text.Length); if (_working[i].Text == pattern) return (_working[i]); } } return (token); } } // no match found, if prediction is empty // this means we reach end of text and return // text as a LexerToken.Text if (prediction == "") return (new LexToken(text, LexerTag.Text, -1)); return (null); } /// /// Builds the list of all LexToken which text value starts with the one in starter. /// /// The token that the reference text. /// The list of tokens which text starts with the one in starter. protected void PopulateTokenStartingWith(LexToken starter, List output) { InternalLexToken token; UiExceptionHelper.CheckNotNull(starter, "starter"); UiExceptionHelper.CheckNotNull(output, "output"); output.Add(starter); token = (InternalLexToken)starter; foreach (LexToken item in token.StartingWith) output.Add(item); return; } #region InternalLexToken /// /// Inherits of LexToken and add a public array that holds the list of all other tokens /// which text values start with the one in the current instance. /// class InternalLexToken : LexToken { /// /// Holds the list of all other tokens which text values start like the one /// in this instance. This array is used to solve ambiguity when finding a /// string that could possibly represents more than one token. /// public List StartingWith; /// /// Build a new instance of InternalLexToken with the given data. /// /// The token's text value. /// The token's tag value. public InternalLexToken(string value, LexerTag tag) { _start = -1; _text = value; _tag = tag; StartingWith = new List(); return; } } #endregion #region IEnumerable Membres public IEnumerator GetEnumerator() { return (_list.GetEnumerator()); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/CSToken.cs0000664000175000017500000000740711504175260025010 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.CodeFormatters { /// /// This enum indicate the kind of a string sequence. /// public enum ClassificationTag : byte { /// /// The string refer to C# source code. /// Code = 0, // 0 /// /// The string refers to C# keywords. /// Keyword = 1, // 1 /// /// The string refers to C# comments. /// Comment = 2, // 2 /// /// The string refers to a string/char value. /// String = 3 // 3 } /// /// (formerly named CSToken) /// /// Classifies a string and make it falls into one of the categories below: /// - Code (the value should be interpreted as regular code) /// - Keyword (the value should be interpreted as a language keyword) /// - Comment (the value should be interpreted as comments) /// - String (the value should be interpreted as a string) /// public class ClassifiedToken { /// /// The string held by this token. /// protected string _text; /// /// The matching tag. /// protected ClassificationTag _tag; /// /// Starting startingPosition of the string. /// protected int _indexStart; /// /// This class cannot be build directly. /// protected ClassifiedToken() { // this class requires subclassing } /// /// Gets the string value. /// public string Text { get { return (_text); } } /// /// Gets the classification value for the string in Text. /// - Code: Text should be interpreted as regular code, /// - Keyword: Text should be interpreted as a language keyword, /// - Comments: Text should be interpreted as comments, /// - String: Text should be interpreted as a string. /// public ClassificationTag Tag { get { return (_tag); } } /// /// Gets the string's starting startingPosition. /// public int IndexStart { get { return (_indexStart); } } /// /// Returns true if 'obj' is an instance of ClassifiedToken /// that contains same data that the current instance. /// public override bool Equals(object obj) { ClassifiedToken token; if (obj == null || !(obj is ClassifiedToken)) return (false); token = obj as ClassifiedToken; return (Text == token.Text && Tag == token.Tag); } public override int GetHashCode() { return base.GetHashCode(); } public override string ToString() { return (String.Format( "ClassifiedToken {Text='{0}', Tag={1}}", Text, Tag)); } } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/CSTokenCollection.cs0000664000175000017500000001563011504175260027021 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace NUnit.UiException.CodeFormatters { /// /// (formerly named CSTokenCollection) /// /// Manages an ordered collection of ClassifiedToken present in one line of text. /// public class ClassifiedTokenCollection { /// /// Target location when building a ClassifiedToken instance on the fly. /// protected ClassifiedToken _token; /// /// Keeps tracks of the data source. /// protected FormattedCode.CodeInfo _info; /// /// Store the current line startingPosition. /// protected int _lineIndex; /// /// This class requires subclassing. /// protected ClassifiedTokenCollection() { _token = new InternalToken(); } /// /// Gets the number of ClassifiedToken present in this line of text. /// public int Count { get { int count; if (_lineIndex + 1 < _info.LineArray.Count) { count = _info.LineArray[_lineIndex + 1] - _info.LineArray[_lineIndex]; } else { count = _info.IndexArray.Count - _info.LineArray[_lineIndex]; } return (count); } } /// /// Gets the ClassifiedToken instance at the specified startingPosition. /// Warning: this indexer always return the same instance. /// To keep data safe, it is strongly recommanded to make /// a deep copy of the returned ClassifiedToken. /// /// A zero based value in the range: [0 - Count[ /// The ClassifiedToken at this startingPosition. public ClassifiedToken this[int index] { get { InternalToken result; result = (InternalToken)_token; _populateToken(_lineIndex, index, result); return (result); } } /// /// Gets the part of the text at the given position. /// The returned string can be composed of one or severals words /// all with the same style. /// private void _populateToken(int lineIndex, int tokenIndex, InternalToken output) { int tagZero; int tagStart; int tagEnd; int strIndex_start; int strIndex_end; string res; ClassificationTag tag; // // Gets value of tagStart and tagEnd // from which string indexes can be extracted // tagZero = _info.LineArray[lineIndex]; tagStart = tagZero + tokenIndex; tagEnd = tagStart + 1; strIndex_start = _info.IndexArray[tagStart]; if (tagEnd < _info.IndexArray.Count) { strIndex_end = _info.IndexArray[tagEnd]; res = _info.Text.Substring(strIndex_start, strIndex_end - strIndex_start); } else res = _info.Text.Substring(strIndex_start); // // Check the need to trimEnd() the resulting string. // We only want to trimEnd when current string is the // last part of the current line. Intermediary strings // must not be trimed end. At display time this would // lead to introduce bad shifting of text sequences. // if (res.EndsWith("\n")) res = res.TrimEnd(); // // Convert the byte code into a ClassificationTag // for this string sequence // tag = _getTagFromByteValue(_info.TagArray[tagStart]); // and populate result output.Setup(res, tag); return; } /// /// Converts the given value into the matching ClassificationTag. /// private ClassificationTag _getTagFromByteValue(byte value) { switch (value) { case 0: return (ClassificationTag.Code); case 1: return (ClassificationTag.Keyword); case 2: return (ClassificationTag.Comment); case 3: return (ClassificationTag.String); default: UiExceptionHelper.CheckTrue(false, "should not reach this code", "value"); break; } return (ClassificationTag.Code); } /// /// Return a string filled with the text present at the current line startingPosition. /// public string Text { get { int index_start; int index_start_ptr; int index_end; int index_end_ptr; string text; index_start_ptr = _info.LineArray[_lineIndex]; index_start = _info.IndexArray[index_start_ptr]; if (_lineIndex + 1 >= _info.LineArray.Count) index_end = _info.Text.Length; else { index_end_ptr = _info.LineArray[_lineIndex + 1]; index_end = _info.IndexArray[index_end_ptr]; } if (index_end - index_start < 0) throw new Exception( "ClassifiedTokenCollection: Text: error: calling substring with negative length"); text = _info.Text.Substring(index_start, index_end - index_start); text = text.TrimEnd(); return (text); } } #region InternalToken class InternalToken : ClassifiedToken { public InternalToken() { } public void Setup(string text, ClassificationTag tag) { _text = text; _tag = tag; } } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/CSharpParser/LexToken.cs0000664000175000017500000000665411504175260025236 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.CodeFormatters { /// /// This enum defines the list of all tags /// that can be assigned to a particular string. /// public enum LexerTag { /// /// All sequences but the ones below /// Text, /// /// White characters: ' ' \t \n /// and other separators like: /// - '[' ']' '(' ')' ';' /// Separator, /// /// Char: \n /// EndOfLine, /// /// string: /* /// CommentC_Open, /// /// string: */ /// CommentC_Close, /// /// string: // /// CommentCpp, /// /// Char: ' /// SingleQuote, /// /// Char: " /// DoubleQuote } /// /// This class is used to make the link between a string and a LexerTag value. /// public class LexToken { /// /// The string in this token. /// protected string _text; /// /// The current tag. /// protected LexerTag _tag; /// /// The starting startingPosition. /// protected int _start; public LexToken() { _text = null; _tag = LexerTag.Text; _start = -1; return; } public LexToken(string text, LexerTag tag, int start) { _text = text; _tag = tag; _start = start; return; } /// /// Gets the string value. /// public string Text { get { return (_text); } } /// /// Gets the tag value /// public LexerTag Tag { get { return (_tag); } } /// /// Gets the starting startingPosition of the string. /// public int IndexStart { get { return (_start); } } public override bool Equals(object obj) { LexToken token; if (obj == null || !(obj is LexToken)) return (false); token = (LexToken)obj; return (token.Text == Text && token.IndexStart == IndexStart && token.Tag == Tag); } public override int GetHashCode() { return base.GetHashCode(); } public override string ToString() { return (String.Format("Token=([{0}], Index={1}, Tag={2})", Text, IndexStart, Tag)); } } } NUnit-2.6.0.12051/src/GuiException/UiException/ITextManager.cs0000664000175000017500000000260011504175260023463 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException { /// /// Provides an abstract way to manipulate a text as a whole and as separate /// sequences that can randomly be accessed one line at a time. /// public interface ITextManager { /// /// Gets the number of line in text managed by this object. /// int LineCount { get; } /// /// Gets the character count of the longest line in the text managed /// by this object. /// int MaxLength { get; } /// /// Gets the complete text managed by this object. /// string Text { get; } /// /// Gets a string filled with all characters in the line /// at the specified startingPosition without the trailing '\r\n' characters. /// /// /// string GetTextAt(int lineIndex); } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/0000775000175000017500000000000011742560362022416 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/Controls/DefaultCodeRenderer.cs0000664000175000017500000001617311504175260026616 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; using System.Drawing; using System.Diagnostics; namespace NUnit.UiException.Controls { public class DefaultCodeRenderer : ICodeRenderer { /// /// These constants below address an issue at measure text time /// that sometimes can cause big lines of text to be misaligned. /// private readonly static float MEASURECHAR_BIG_WIDTH = 5000f; private readonly static float MEASURECHAR_BIG_HEIGHT = 100f; public PaintLineLocation[] ViewportLines(FormattedCode code, RectangleF viewport, float fontHeight) { List list = new List(); int visibles = CountVisibleLines(viewport.Height, fontHeight); // int topIndex = YCoordinateToLineIndex(viewport.Top, fontHeight); int lineIndex = YCoordinateToLineIndex(viewport.Top, fontHeight); int i; for (i = 0; i < visibles; ++i, lineIndex++) { if (lineIndex < 0) continue; if (lineIndex >= code.LineCount) break; list.Add( new PaintLineLocation(lineIndex, code.GetTextAt(lineIndex), new PointF(-viewport.Left, LineIndexToYCoordinate(lineIndex, fontHeight) - viewport.Top))); } return (list.ToArray()); } #region ICodeRenderer Membres public void DrawToGraphics(FormattedCode code, CodeRenderingContext args, Rectangle viewport) { UiExceptionHelper.CheckNotNull(code, "code"); UiExceptionHelper.CheckNotNull(args, "args"); ClassifiedTokenCollection line; PaintLineLocation[] lines; ClassifiedToken token; float fontHeight; string text; float tk_width; int i; float x; fontHeight = LineIndexToYCoordinate(1, args.Graphics, args.Font); lines = ViewportLines(code, viewport, fontHeight); foreach (PaintLineLocation paintLine in lines) { // All lines that differ from CurrentLine are displayed // in using different styles of Brush to make a distinction // between code, keyword, comments. if (paintLine.LineIndex != args.CurrentLine) { line = code[paintLine.LineIndex]; x = 0; text = line.Text; for (i = 0; i < line.Count; ++i) { token = line[i]; args.Graphics.DrawString(token.Text, args.Font, args.GetBrush(token.Tag), paintLine.Location.X + x, paintLine.Location.Y); tk_width = measureStringWidth(args.Graphics, args.Font, text, token.IndexStart, token.Text.Length); x += tk_width; } continue; } // The current line is emphasized by using a // specific couples of Background & Foreground colors args.Graphics.FillRectangle( args.CurrentLineBackBrush, 0, paintLine.Location.Y, viewport.Width, fontHeight); args.Graphics.DrawString( paintLine.Text, args.Font, args.CurrentLineForeBrush, paintLine.Location.X, paintLine.Location.Y); } return; } public SizeF GetDocumentSize(FormattedCode code, Graphics g, Font font) { UiExceptionHelper.CheckNotNull(code, "code"); UiExceptionHelper.CheckNotNull(g, "g"); UiExceptionHelper.CheckNotNull(font, "font"); StringBuilder sample; SizeF measure; int i; sample = new StringBuilder(); for (i = code.MaxLength; i > 0; --i) sample.Append("m"); measure = g.MeasureString(sample.ToString(), font); return (new SizeF(measure.Width, measure.Height * code.LineCount)); } public float LineIndexToYCoordinate(int lineIndex, Graphics g, Font font) { UiExceptionHelper.CheckNotNull(g, "g"); UiExceptionHelper.CheckNotNull(font, "font"); SizeF sz = g.MeasureString("m", font); return (lineIndex * sz.Height); } #endregion /// /// Utility method that measures a region of text in the given string. /// /// The graphics instance used to render this text. /// The font instance used to render this text. /// The text that contains the region to be rendered. /// Starting startingPosition of this region. /// Length of this region. /// The width of this region of text. private float measureStringWidth(Graphics g, Font font, string text, int indexStart, int length) { CharacterRange[] ranges; StringFormat sf; Region[] regions; if (length == 0) return (0); length = Math.Min(length, text.Length); ranges = new CharacterRange[] { new CharacterRange(indexStart, length) }; sf = new StringFormat(); // the string of text may contains white spaces that need to // be measured correctly. sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; sf.SetMeasurableCharacterRanges(ranges); // here : giving a layout too small can cause returned measure // to be wrong. regions = g.MeasureCharacterRanges( text, font, new RectangleF( 0, 0, MEASURECHAR_BIG_WIDTH, MEASURECHAR_BIG_HEIGHT), sf); return (regions[0].GetBounds(g).Width); } int CountVisibleLines(float viewportHeight, float fontHeight) { return ((int)(viewportHeight / fontHeight) + 1); } int YCoordinateToLineIndex(float y, float fontHeight) { return (int)(y / fontHeight); } float LineIndexToYCoordinate(int index, float fontHeight) { return (index * fontHeight); } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/CodeRenderingContext.cs0000664000175000017500000001507511504175260027025 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Controls { /// /// Encapsulates basic colors settings to format a text according a language. /// public class CodeRenderingContext { private static readonly int INDEX_CODE = 0; private static readonly int INDEX_KEYWORD = 1; private static readonly int INDEX_COMMENT = 2; private static readonly int INDEX_STRING = 3; private static readonly int INDEX_BACKGROUND = 4; private static readonly int INDEX_CURRBACK = 5; private static readonly int INDEX_CURRFORE = 6; private Graphics _graphics; private Font _font; private int _currentLine; private ColorMaterial[] _colors; public CodeRenderingContext() { _colors = new ColorMaterial[] { new ColorMaterial(Color.Black), // code color new ColorMaterial(Color.Blue), // keyword color new ColorMaterial(Color.Green), // comment color new ColorMaterial(Color.Red), // string color new ColorMaterial(Color.White), // background new ColorMaterial(Color.Red), // current line back color new ColorMaterial(Color.White), // current line fore color }; return; } public Graphics Graphics { get { return (_graphics); } set { _graphics = value; } } public Font Font { get { return (_font); } set { _font = value; } } public int CurrentLine { get { return (_currentLine); } set { _currentLine = value; } } public Color BackgroundColor { get { return (_colors[INDEX_BACKGROUND].Color); } set { _colors[INDEX_BACKGROUND].Dispose(); _colors[INDEX_BACKGROUND] = new ColorMaterial(value); } } public Color CurrentLineBackColor { get { return (_colors[INDEX_CURRBACK].Color); } set { _colors[INDEX_CURRBACK].Dispose(); _colors[INDEX_CURRBACK] = new ColorMaterial(value); } } public Color CurrentLineForeColor { get { return (_colors[INDEX_CURRFORE].Color); } set { _colors[INDEX_CURRFORE].Dispose(); _colors[INDEX_CURRFORE] = new ColorMaterial(value); } } public Color KeywordColor { get { return (_colors[INDEX_KEYWORD].Color); } set { _colors[INDEX_KEYWORD].Dispose(); _colors[INDEX_KEYWORD] = new ColorMaterial(value); } } public Color CommentColor { get { return (_colors[INDEX_COMMENT].Color); } set { _colors[INDEX_COMMENT].Dispose(); _colors[INDEX_COMMENT] = new ColorMaterial(value); } } public Color CodeColor { get { return (_colors[INDEX_CODE].Color); } set { _colors[INDEX_CODE].Dispose(); _colors[INDEX_CODE] = new ColorMaterial(value); } } public Color StringColor { get { return (_colors[INDEX_STRING].Color); } set { _colors[INDEX_STRING].Dispose(); _colors[INDEX_STRING] = new ColorMaterial(value); } } public Color this[ClassificationTag tag] { get { int idx = (int)tag; return (_colors[idx].Color); } } public Brush GetBrush(ClassificationTag tag) { return (_colors[(int)tag].Brush); } public Pen GetPen(ClassificationTag tag) { return (_colors[(int)tag].Pen); } #region Brushes public Brush BackgroundBrush { get { return (_colors[INDEX_BACKGROUND].Brush); } } public Brush CurrentLineBackBrush { get { return (_colors[INDEX_CURRBACK].Brush); } } public Brush CurrentLineForeBrush { get { return (_colors[INDEX_CURRFORE].Brush); } } public Brush KeywordBrush { get { return (_colors[INDEX_KEYWORD].Brush); } } public Brush CommentBrush { get { return (_colors[INDEX_COMMENT].Brush); } } public Brush CodeBrush { get { return (_colors[INDEX_CODE].Brush); } } public Brush StringBrush { get { return (_colors[INDEX_STRING].Brush); } } #endregion #region Pens public Pen BackgroundPen { get { return (_colors[INDEX_BACKGROUND].Pen); } } public Pen CurrentLineBackPen { get { return (_colors[INDEX_CURRBACK].Pen); } } public Pen CurrentLineForePen { get { return (_colors[INDEX_CURRFORE].Pen); } } public Pen KeywordPen { get { return (_colors[INDEX_KEYWORD].Pen); } } public Pen CommentPen { get { return (_colors[INDEX_COMMENT].Pen); } } public Pen CodePen { get { return (_colors[INDEX_CODE].Pen); } } public Pen StringPen { get { return (_colors[INDEX_STRING].Pen); } } #endregion class ColorMaterial { public Color Color; public Brush Brush; public Pen Pen; public ColorMaterial(Color color) { this.Color = color; this.Brush = new SolidBrush(color); this.Pen = new Pen(color); return; } public void Dispose() { this.Brush.Dispose(); this.Pen.Dispose(); } } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/StackTraceDisplay.cs0000664000175000017500000000516611504175260026322 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using NUnit.UiException.Properties; namespace NUnit.UiException.Controls { /// /// Implements IErrorDisplay to show the actual stack trace in a TextBox control. /// public class StackTraceDisplay : UserControl, IErrorDisplay { private TextBox _textContent; private ToolStripButton _btnPlugin; private ToolStripButton _btnCopy; /// /// Builds a new instance of StackTraceDisplay. /// public StackTraceDisplay() { _btnPlugin = ErrorToolbar.NewStripButton(true, "Display actual stack trace", Resources.ImageStackTraceDisplay, null); _btnCopy = ErrorToolbar.NewStripButton(false, "Copy stack trace to clipboard", Resources.ImageCopyToClipboard, OnClick); _textContent = new TextBox(); _textContent.ReadOnly = true; _textContent.Multiline = true; _textContent.ScrollBars = ScrollBars.Both; return; } protected override void OnFontChanged(EventArgs e) { _textContent.Font = this.Font; base.OnFontChanged(e); } /// /// Copies the actual stack trace to the clipboard. /// public void CopyToClipBoard() { if (String.IsNullOrEmpty(_textContent.Text)) { Clipboard.Clear(); return; } Clipboard.SetText(_textContent.Text); return; } #region IErrorDisplay Membres public ToolStripButton PluginItem { get { return (_btnPlugin); } } public ToolStripItem[] OptionItems { get { return (new ToolStripItem[] { _btnCopy }); } } public Control Content { get { return (_textContent); } } public void OnStackTraceChanged(string stackTrace) { _textContent.Text = stackTrace; } #endregion private void OnClick(object sender, EventArgs args) { CopyToClipBoard(); } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ICodeView.cs0000664000175000017500000000244511504175260024563 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; using System.Windows.Forms; namespace NUnit.UiException.Controls { /// /// The interface through which SourceCodeDisplay interacts with the code display. /// /// Direct implementation is: /// - CodeBox /// public interface ICodeView { /// /// Gets or sets a text to display in the code display. /// string Text { get; set; } /// /// Gets or sets the language formatting of the code display. /// string Language { get; set; } /// /// Gets or sets the viewport location from a 0 based line index /// int CurrentLine { get; set; } /// /// Gives access to the underlying IFormatterCatalog. /// IFormatterCatalog Formatter { get; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/IErrorDisplay.cs0000664000175000017500000000353511504175260025476 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; namespace NUnit.UiException.Controls { /// /// This interface describes a feature that can be added to the ErrorWindow /// in order to show relevant information about failures/errors after a /// test suite run. /// Clients who wants to add their own display should implement this /// interface and register their instance to ErrorBrowser at run-time. /// /// Direct known implementations are: /// StackTraceDisplay /// SourceCodeDisplay /// public interface IErrorDisplay { /// /// Gives access to the ToolStripButton that enables this display. /// ToolStripButton PluginItem { get; } /// /// Gives access to a possibly null collection of option controls that will /// be shown when this display has the focus. /// ToolStripItem[] OptionItems { get; } /// /// Gives access to the content control of this display. /// Control Content { get; } /// /// Called whenever the user changes the error selection in the detail list. /// This method is called to allow the display to update its content according /// the given stack trace. /// /// void OnStackTraceChanged(string stackTrace); } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ErrorBrowser.cs0000664000175000017500000001214111504175260025374 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace NUnit.UiException.Controls { /// /// A control that encapsulates a collection of IErrorDisplay instances /// and which shows relevant information about failures & errors after /// a test suite run. /// By default, ErrorBrowser is empty and should be populated with /// IErrorDisplay instances at loading time. The example below shows how /// to achieve this: /// /// ErrorBrowser errorBrowser = new ErrorBrowser(); /// /// // configure and register a SourceCodeDisplay /// // that will display source code context on failure /// /// SourceCodeDisplay sourceCode = new SourceCodeDisplay(); /// sourceCode.AutoSelectFirstItem = true; /// sourceCode.ListOrderPolicy = ErrorListOrderPolicy.ReverseOrder; /// sourceCode.SplitOrientation = Orientation.Vertical; /// sourceCode.SplitterDistance = 0.3f; /// /// errorBrowser.RegisterDisplay(sourceCode); /// /// // configure and register a StackTraceDisplay /// // that will display the stack trace details on failure /// /// errorBrowser.RegisterDisplay(new StackTraceDisplay()); /// [...] /// // set the stack trace information /// errorBrowser.StackTraceSource = [a stack trace here] /// /// public class ErrorBrowser : UserControl { public event EventHandler StackTraceSourceChanged; public event EventHandler StackTraceDisplayChanged; private ErrorPanelLayout _layout; private string _stackStace; /// /// Builds a new instance of ErrorBrowser. /// public ErrorBrowser() { _layout = new ErrorPanelLayout(); _layout.Toolbar = new ErrorToolbar(); Toolbar.SelectedRendererChanged += new EventHandler(Toolbar_SelectedRendererChanged); Controls.Add(_layout); _layout.Left = 0; _layout.Top = 0; _layout.Width = Width; _layout.Height = Height; _layout.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right; return; } /// /// Use this property to get or set the new stack trace details. /// The changes are repercuted on the registered displays. /// public string StackTraceSource { get { return (_stackStace); } set { if (_stackStace == value) return; _stackStace = value; foreach (IErrorDisplay item in Toolbar) item.OnStackTraceChanged(value); if (StackTraceSourceChanged != null) StackTraceSourceChanged(this, new EventArgs()); return; } } /// /// Gets the selected display. /// public IErrorDisplay SelectedDisplay { get { return (Toolbar.SelectedDisplay); } set { Toolbar.SelectedDisplay = value; } } /// /// Populates ErrorBrowser with the new display passed in parameter. /// If ErrorBrowser is empty, the display becomes automatically the /// new selected display. /// /// public void RegisterDisplay(IErrorDisplay display) { UiExceptionHelper.CheckNotNull(display, "display"); Toolbar.Register(display); display.OnStackTraceChanged(_stackStace); if (Toolbar.SelectedDisplay == null) Toolbar.SelectedDisplay = display; return; } /// /// Removes all display from ErrorBrowser. /// public void ClearAll() { Toolbar.Clear(); LayoutPanel.Option = null; LayoutPanel.Content = null; return; } void Toolbar_SelectedRendererChanged(object sender, EventArgs e) { LayoutPanel.Content = Toolbar.SelectedDisplay.Content; if (StackTraceDisplayChanged != null) StackTraceDisplayChanged(this, EventArgs.Empty); return; } protected ErrorPanelLayout LayoutPanel { get { return (_layout); } } protected ErrorToolbar Toolbar { get { return ((ErrorToolbar)_layout.Toolbar); } } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/IStackTraceView.cs0000664000175000017500000000320111504175260025724 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace NUnit.UiException.Controls { /// /// This enum defines indicators telling how instances of IStackTraceView /// should deal with item order in their list. /// public enum ErrorListOrderPolicy { /// /// Tells IStackTraceView to order items in the list in the same /// order they appear in the stack trace. /// InitialOrder, /// /// Tells IStackTraceView to order items in the list in the reverse /// order they appear in the stack trace. At Test Driven Development time /// this value is useful to point out the location where a test is expected /// to fail. /// ReverseOrder, } /// /// The interface through which SourceCodeDisplay interacts with the error list. /// /// Direct implementations are: /// - ErrorList /// public interface IStackTraceView { event EventHandler SelectedItemChanged; string StackTrace { get; set; } ErrorItem SelectedItem { get; } bool AutoSelectFirstItem { get; set; } ErrorListOrderPolicy ListOrderPolicy { get; set; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/DefaultErrorListRenderer.cs0000664000175000017500000002752311504175260027672 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; using NUnit.UiException.Properties; using System.Diagnostics; namespace NUnit.UiException.Controls { /// /// Implements IErrorListRenderer. /// public class DefaultErrorListRenderer : IErrorListRenderer { //private static readonly int ITEM_HEIGHT = 54; private static readonly int TEXT_MARGIN_X = 16; private Font _font; private Font _fontUnderlined; private int _itemHeight; private Brush _brushBlue; private Brush _brushGray; private float _offsetLine; private Rectangle _rectListShadow; private Rectangle _rectListBackground; private Rectangle _rectItemGray; private Rectangle _rectItemWhite; private Rectangle _rectSelectionMiddle; private Rectangle _rectIconDll; private Rectangle _rectIconCSharp; private Rectangle _rectIconArrow; // private Rectangle _rectShadow; private PaintData _paintData; public DefaultErrorListRenderer() { this.Font = new Font(FontFamily.GenericSansSerif, 8.25f); //_fontUnderlined = new Font(_font, FontStyle.Underline); //_itemHeight = _font.Height * 4 + 6; _brushBlue = new SolidBrush(Color.FromArgb(0, 43, 114)); _brushGray = new SolidBrush(Color.FromArgb(64, 64, 64)); _rectListShadow = new Rectangle(0, 0, 48, 9); _rectListBackground = new Rectangle(0, 10, 48, 48); _rectItemGray = new Rectangle(71, 0, 9, 54); _rectItemWhite = new Rectangle(60, 0, 9, 54); _rectSelectionMiddle = new Rectangle(49, 0, 9, 54); _rectIconDll = new Rectangle(1, 59, 16, 15); _rectIconCSharp = new Rectangle(18, 59, 14, 15); _rectIconArrow = new Rectangle(35, 60, 9, 5); // _rectShadow = new Rectangle(49, 60, 4, 8); _paintData = new PaintData(); return; } public Font Font { get { return (_font); } set { _fontUnderlined = _font = value; if (_font.FontFamily.IsStyleAvailable(FontStyle.Underline)) _fontUnderlined = new Font(_font, FontStyle.Underline); _itemHeight = _font.Height * 4 + 6; } } #region IErrorListRenderer Membres public void DrawToGraphics(ErrorItemCollection items, ErrorItem selected, Graphics g, Rectangle viewport) { SizeF sizeLineSource; int last; int i; UiExceptionHelper.CheckNotNull(items, "items"); UiExceptionHelper.CheckNotNull(g, "g"); if (!_paintData.Equals(items, selected, viewport)) { _paintData.Dispose(); _paintData = new PaintData(items, selected, viewport, g); PaintBackground(Resources.ImageErrorList, _paintData.WorkingGraphics, _rectListBackground, viewport); sizeLineSource = g.MeasureString("Line 9999", _font); _offsetLine = viewport.Width - sizeLineSource.Width; last = LastIndexVisible(items.Count, viewport); for (i = FirstIndexVisible(items.Count, viewport); i <= last; ++i) DrawItem(items[i], i, selected == items[i], i == items.Count - 1, false, _paintData.WorkingGraphics, viewport); //_paintData.WorkingGraphics.DrawImage(Resources.ErrorList, //new Rectangle(0, 0, viewport.Width, _rectShadow.Height), //_rectShadow, GraphicsUnit.Pixel); } _paintData.PaintTo(g); return; } public void DrawItem(ErrorItem item, int index, bool hovered, bool selected, Graphics g, Rectangle viewport) { DrawItem(item, index, selected, false, hovered, g, viewport); } public Size GetDocumentSize(ErrorItemCollection items, Graphics g) { SizeF current; float w; _paintData = new PaintData(); if (items.Count == 0) return (new Size()); w = 0; foreach (ErrorItem item in items) { current = MeasureItem(g, item); w = Math.Max(w, current.Width); } return (new Size((int)w, items.Count * _itemHeight)); } public ErrorItem ItemAt(ErrorItemCollection items, Graphics g, Point point) { int idx = point.Y / _itemHeight; if (items == null || point.Y < 0 || idx >= items.Count) return (null); return (items[idx]); } #endregion protected bool IsDirty(ErrorItemCollection items, ErrorItem selection, Rectangle viewport) { return (!_paintData.Equals(items, selection, viewport)); } protected SizeF MeasureItem(Graphics g, ErrorItem item) { SizeF sizeMethod; SizeF sizeClass; SizeF sizeFile; UiExceptionHelper.CheckNotNull(g, "g"); UiExceptionHelper.CheckNotNull(item, "item"); sizeClass = g.MeasureString(item.ClassName, _font); sizeMethod = g.MeasureString(item.MethodName, _font); sizeFile = g.MeasureString(item.FileName, _font); return (new SizeF( Math.Max(sizeClass.Width, Math.Max(sizeMethod.Width, sizeFile.Width)) + TEXT_MARGIN_X, _itemHeight)); } private void DrawItem(ErrorItem item, int index, bool selected, bool last, bool hover, Graphics g, Rectangle viewport) { Rectangle src; Font font; int x = -viewport.X; int y = _itemHeight * index - viewport.Y; src = (index % 2 == 0) ? _rectItemWhite : _rectItemGray ; font = (hover == true) ? _fontUnderlined : _font; g.DrawImage(Resources.ImageErrorList, new Rectangle(0, y, viewport.Width, _itemHeight), src, GraphicsUnit.Pixel); if (selected) { g.DrawImage(Resources.ImageErrorList, new Rectangle(0, y + 1, viewport.Width, _itemHeight ), _rectSelectionMiddle, GraphicsUnit.Pixel); } if (item.HasSourceAttachment) { g.DrawImage(Resources.ImageErrorList, new Rectangle(x + 1, y + 2 + font.Height, 14, 15), _rectIconCSharp, GraphicsUnit.Pixel); g.DrawImage(Resources.ImageErrorList, new Rectangle(TEXT_MARGIN_X - 3 + x, y + 5 + 2 * font.Height, 9, 5), _rectIconArrow, GraphicsUnit.Pixel); g.DrawString(String.Format("Line {0}", item.LineNumber), font, _brushGray, _offsetLine, y + 2); g.DrawString(item.ClassName, font, _brushBlue, x + TEXT_MARGIN_X, y + 2 + font.Height); g.DrawString(item.BaseMethodName + "()", font, _brushBlue, x + TEXT_MARGIN_X + 5, y + 2 + 2 * font.Height); g.DrawString(item.FileName, font, _brushGray, x + TEXT_MARGIN_X, y + 2 + 3 * _font.Height); } else { g.DrawImage(Resources.ImageErrorList, new Rectangle(x + 1, y + 2 + font.Height, 16, 15), _rectIconDll, GraphicsUnit.Pixel); g.DrawString("N/A", font, _brushGray, _offsetLine, y + 2); g.DrawString(item.ClassName, font, _brushGray, x + TEXT_MARGIN_X, y + 2 + font.Height); g.DrawString(item.BaseMethodName + "()", font, _brushGray, x + TEXT_MARGIN_X, y + 2 + 2 * font.Height); } if (!last) return; PaintTile(Resources.ImageErrorList, g, _rectListShadow, new Rectangle(0, y + _itemHeight, viewport.Width, 9)); return; } private static void PaintBackground(Image img, Graphics g, Rectangle bkg, Rectangle viewport) { Rectangle destTile; int x; int y; int startY; int startX; startY = -viewport.Y % viewport.Height; startX = -viewport.X % viewport.Width; for (y = startY; y < viewport.Height; y += bkg.Height) for (x = startX; x < viewport.Width; x += bkg.Width) { destTile = new Rectangle(x, y, bkg.Width, bkg.Height); g.DrawImage(img, destTile, bkg, GraphicsUnit.Pixel); } return; } private static void PaintTile(Image tile, Graphics g, Rectangle src, Rectangle dst) { Rectangle destTile; int x; int y; for (y = dst.Top; y < dst.Bottom; y += src.Height) for (x = dst.Left; x < dst.Right; x += src.Width) { destTile = new Rectangle(x, y, src.Width, src.Height); g.DrawImage(tile, destTile, src, GraphicsUnit.Pixel); } return; } private int FirstIndexVisible(int count, Rectangle viewport) { return (Math.Max(0, viewport.Y / _itemHeight)); } private int LastIndexVisible(int count, Rectangle viewport) { return (Math.Min(count - 1, FirstIndexVisible(count, viewport) + 1 + viewport.Height / _itemHeight)); } class PaintData { public Graphics WorkingGraphics; private ErrorItem _firstItem; private ErrorItem selection; private Rectangle viewport; private Image _workingImage; public PaintData() { } public PaintData(ErrorItemCollection items, ErrorItem item, Rectangle rectangle, Graphics g) { if (item == null) item = new ErrorItem(); selection = item; _firstItem = ((items.Count > 0) ? items[0] : null); viewport = rectangle; _workingImage = new Bitmap(rectangle.Width, rectangle.Height, g); WorkingGraphics = Graphics.FromImage(_workingImage); return; } public void Dispose() { if (_workingImage != null) { _workingImage.Dispose(); WorkingGraphics.Dispose(); } return; } public void PaintTo(Graphics g) { g.DrawImage(_workingImage, 0, 0); } public bool Equals(ErrorItemCollection items, ErrorItem item, Rectangle rectangle) { ErrorItem first = ((items.Count > 0) ? items[0] : null); return (viewport.Equals(rectangle) && object.ReferenceEquals(item, selection) && object.ReferenceEquals(first, _firstItem)); } } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/SplitterBox.cs0000664000175000017500000004166411504175260025232 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using NUnit.UiException.Properties; using System.Diagnostics; // // This re-implements SplitContainer. Why re-inventing the wheel? // Well... I faced some strange behaviors in SplitContainer in particular // when I started to provide a custom paint method. It seems to me // that there is a kind of defect that affects how the Invalidate or // paint event is called. In some situations I faced a SplitContainer // that didn't redraw itself while having some parts of its window // dirty. I didn't found out the cause of the problem. // // Another feature that is quite annoying is the unability to change // the mouse cursor while hovering some special areas of the splitter // bar. Maybe there is a trick or something but the normal way doesn't // look like to work. // namespace NUnit.UiException.Controls { /// /// Implements a place holder that can be splitted either horizontally or vertically. /// The SplitterBox is layouted with two place holders, respectively named Control1 /// and Control2 where clients can put their controls. /// /// Unlike SplitContainer, the place holders in SplitterBox are the client controls /// itself. The direct consequence is the layout policy will be to dock the client /// controls in filling the maximum possible space. /// /// SplitterBox also add three buttons on the splitter bar that to change the split /// orientation and collapse either Control1 or Control2. The example below shows /// how to intialize and set up SplitterBox with two controls. /// /// // creates a new SplitterBox, with a vertical split /// // and position splitter to appear in the middle of the window /// SplitterBox splitter = new SplitterBox(); /// splitter.Orientation = Orientation.Vertical; /// splitter.SplitterDistance = 0.5f; /// splitter.Control1 = oneControl; /// splitter.Control2 = anotherControl; /// /// public class SplitterBox : Control { public static readonly int SPLITTER_SIZE = 9; public static readonly int SPLITTER_HALFSIZE = SPLITTER_SIZE / 2; public static readonly int BUTTON_SIZE = 13; private Control _emptyControl1; private Control _emptyControl2; private Control _control1; private Control _control2; private Orientation _orientation; private float _x; private float _y; private Rectangle _splitterRectangle; private Rectangle _collapse1Rectangle; private Rectangle _collapse2Rectangle; private Rectangle _directionRectangle; private bool _movingSplitter; private Brush _brush; private Pen _pen; private Rectangle _rVerticalCollapse1; private Rectangle _rVerticalDirection; private Rectangle _rVerticalCollapse2; private Rectangle _rHorizontalCollapse1; private Rectangle _rHorizontalDirection; private Rectangle _rHorizontalCollapse2; public event EventHandler OrientationChanged; public event EventHandler SplitterDistanceChanged; /// /// Creates a new SplitterBox. /// public SplitterBox() { _brush = new SolidBrush(Color.FromArgb(146, 180, 224)); _pen = new Pen(Color.FromArgb(103, 136, 190)); _rVerticalCollapse1 = new Rectangle(0, 0, 9, 13); _rVerticalDirection = new Rectangle(10, 0, 9, 13); _rVerticalCollapse2 = new Rectangle(20, 0, 9, 13); _rHorizontalCollapse1 = new Rectangle(0, 24, 13, 9); _rHorizontalDirection = new Rectangle(14, 14, 13, 9); _rHorizontalCollapse2 = new Rectangle(0, 14, 13, 9); _emptyControl1 = new Control(); _emptyControl2 = new Control(); Width = 150; Height = 150; _control1 = _emptyControl1; _control2 = _emptyControl2; Controls.Add(_control1); Controls.Add(_control2); _x = _y = 0.5f; Orientation = Orientation.Vertical; DoLayout(); return; } /// /// Gets or sets the orientation of the splitter in the SplitterBox. /// public Orientation Orientation { get { return (_orientation); } set { _orientation = value; DoLayout(); } } /// /// Gets or sets the splitter distance expressed as a float number in the /// range [0 - 1]. A value of 0 collapses Control1 and makes Control2 take /// the whole space in the window. A value of 1 collapses Control2 and makes /// Control1 take the whole space in the window. A value of 0.5 makes the /// splitter appear in the middle of the window. /// /// Values that don't fall in [0 - 1] are automatically clipped to this range. /// public float SplitterDistance { get { return (_orientation == Orientation.Vertical ? _x : _y); } set { value = Math.Max(0, Math.Min(1, value)); if (_orientation == Orientation.Vertical) _x = value; else _y = value; DoLayout(); } } /// /// Gets or sets the "first" control to be shown. This control will appear /// either at the top or on the left when the orientation is respectively /// vertical or horizontal. /// If the value is not null, the control will automatically be added /// to the SplitterBox's hierarchy of controls. /// If the value is null, the former control is removed and replaced /// by a default and empty area. /// public Control Control1 { get { return (_control1); } set { if (_control1 == value) return; Controls.Remove(_control1); if (value == null) value = _emptyControl1; _control1 = value; Controls.Add(value); DoLayout(); return; } } /// /// Gets or sets the "second" control to be shown. This control will appear /// either at the bottom or on the right when the orientation is respectively /// vertical or horizontal. /// If the value is not null, the control will automatically be added /// to the SplitterBox's hierarchy of controls. /// If the value is null, the former control is removed and replaced /// by a default and empty area. /// public Control Control2 { get { return (_control2); } set { if (_control2 == value) return; if (value == null) value = _emptyControl2; Controls.Remove(_control2); _control2 = value; Controls.Add(value); DoLayout(); return; } } /// /// Gets the rectangle occupied with the splitter. /// public Rectangle SplitterRectangle { get { return (_splitterRectangle); } } /// /// Sets a new location for the splitter expressed as client coordinate. /// /// The new location in pixels when orientation is set to Vertical. /// The new location in pixels when orientation is set to Horizontal. public void PointToSplit(int x, int y) { if (_orientation == Orientation.Vertical) { x = Math.Max(0, Math.Min(Width, x)); _x = (float)x / (float)Width; } else { y = Math.Max(0, Math.Min(Height, y)); _y = (float)y / (float)Height; } DoLayout(); return; } /// /// Collapses Control1. /// public void CollapseControl1() { PointToSplit(0, 0); } /// /// Collapses Control2. /// public void CollapseControl2() { PointToSplit(Width, Height); } protected Rectangle Collapse1Rectangle { get { return (_collapse1Rectangle); } } protected Rectangle Collapse2Rectangle { get { return (_collapse2Rectangle); } } protected Rectangle DirectionRectangle { get { return (_directionRectangle); } } private void HorizontalLayout() { int x = (Width - 41) / 2; int y; int top; top = (int)Math.Max(0, _y * Height - SPLITTER_HALFSIZE); top = Math.Min(top, Height - SPLITTER_SIZE); _splitterRectangle = new Rectangle(0, top, Width, SPLITTER_SIZE); y = _splitterRectangle.Top; _collapse1Rectangle = new Rectangle(x, y, BUTTON_SIZE, SPLITTER_SIZE); _directionRectangle = new Rectangle(_collapse1Rectangle.Right + 2, y, BUTTON_SIZE, SPLITTER_SIZE); _collapse2Rectangle = new Rectangle(_directionRectangle.Right + 2, y, BUTTON_SIZE, SPLITTER_SIZE); _control1.SetBounds(0, 0, Width, _splitterRectangle.Top); _control2.SetBounds(0, _splitterRectangle.Bottom, Width, Height - _splitterRectangle.Bottom); return; } private void VerticalLayout() { int y = (Height - 41) / 2; int left; int x; left = (int)Math.Max(0, _x * Width - SPLITTER_HALFSIZE); left = Math.Min(left, Width - SPLITTER_SIZE); _splitterRectangle = new Rectangle(left, 0, SPLITTER_SIZE, Height); x = _splitterRectangle.Left; _collapse1Rectangle = new Rectangle(x, y, SPLITTER_SIZE, BUTTON_SIZE); _directionRectangle = new Rectangle(x, _collapse1Rectangle.Bottom + 2, SPLITTER_SIZE, BUTTON_SIZE); _collapse2Rectangle = new Rectangle(x, _directionRectangle.Bottom + 2, SPLITTER_SIZE, BUTTON_SIZE); _control1.SetBounds(0, 0, _splitterRectangle.Left, Height); _control2.SetBounds(_splitterRectangle.Right, 0, Width - _splitterRectangle.Right, Height); return; } private void DoLayout() { if (_orientation == Orientation.Vertical) VerticalLayout(); else HorizontalLayout(); Invalidate(); return; } protected override void OnSizeChanged(EventArgs e) { if (_control1 != null) DoLayout(); base.OnSizeChanged(e); } protected override void OnMouseLeave(EventArgs e) { Cursor = Cursors.Default; base.OnMouseLeave(e); } protected override void OnMouseDown(MouseEventArgs e) { UpdateCursor(e.X, e.Y); if (_splitterRectangle.Contains(e.X, e.Y)) { if (HoveringButtons(e.X, e.Y)) return; _movingSplitter = true; } base.OnMouseDown(e); return; } protected override void OnMouseMove(MouseEventArgs e) { UpdateCursor(e.X, e.Y); if (_movingSplitter == true) { PointToSplit(e.X, e.Y); Invalidate(); } base.OnMouseMove(e); return; } protected override void OnMouseUp(MouseEventArgs e) { bool wasMovingSplitter; UpdateCursor(e.X, e.Y); wasMovingSplitter = _movingSplitter; _movingSplitter = false; if (wasMovingSplitter) FireSplitterDistanceChanged(); else { if (_collapse1Rectangle.Contains(e.X, e.Y)) { CollapseControl1(); FireSplitterDistanceChanged(); return; } if (_collapse2Rectangle.Contains(e.X, e.Y)) { CollapseControl2(); FireSplitterDistanceChanged(); return; } if (_directionRectangle.Contains(e.X, e.Y)) { Orientation = (_orientation == Orientation.Vertical) ? Orientation.Horizontal : Orientation.Vertical; FireOrientationChanged(); return; } } base.OnMouseUp(e); return; } private void FireOrientationChanged() { if (OrientationChanged != null) OrientationChanged(this, EventArgs.Empty); } private void FireSplitterDistanceChanged() { if (SplitterDistanceChanged != null) SplitterDistanceChanged(this, EventArgs.Empty); } protected override void OnPaint(PaintEventArgs e) { e.Graphics.FillRectangle(_brush, _splitterRectangle); if (Orientation == Orientation.Vertical) { e.Graphics.DrawLine(_pen, _splitterRectangle.Left, 0, SplitterRectangle.Left, _splitterRectangle.Height); e.Graphics.DrawLine(_pen, _splitterRectangle.Right - 1, 0, SplitterRectangle.Right - 1, _splitterRectangle.Height); e.Graphics.DrawImage(Resources.ImageSplitterBox, _collapse1Rectangle, _rVerticalCollapse1, GraphicsUnit.Pixel); e.Graphics.DrawImage(Resources.ImageSplitterBox, _directionRectangle, _rVerticalDirection, GraphicsUnit.Pixel); e.Graphics.DrawImage(Resources.ImageSplitterBox, _collapse2Rectangle, _rVerticalCollapse2, GraphicsUnit.Pixel); } else { e.Graphics.DrawLine(_pen, 0, _splitterRectangle.Top, Width, _splitterRectangle.Top); e.Graphics.DrawLine(_pen, 0, _splitterRectangle.Bottom - 1, Width, _splitterRectangle.Bottom - 1); e.Graphics.DrawImage(Resources.ImageSplitterBox, _collapse1Rectangle, _rHorizontalCollapse1, GraphicsUnit.Pixel); e.Graphics.DrawImage(Resources.ImageSplitterBox, _directionRectangle, _rHorizontalDirection, GraphicsUnit.Pixel); e.Graphics.DrawImage(Resources.ImageSplitterBox, _collapse2Rectangle, _rHorizontalCollapse2, GraphicsUnit.Pixel); } base.OnPaint(e); return; } private bool HoveringButtons(int x, int y) { if (!SplitterRectangle.Contains(x, y)) return (false); return (_collapse1Rectangle.Contains(x, y) || _collapse2Rectangle.Contains(x, y) || _directionRectangle.Contains(x, y)); } private void UpdateCursor(int x, int y) { if (!SplitterRectangle.Contains(x, y) || HoveringButtons(x, y)) { Cursor = Cursors.Default; return; } Cursor = (Orientation == Orientation.Vertical ? Cursors.VSplit : Cursors.HSplit); return; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/PaintLineLocation.cs0000664000175000017500000000625111504175260026320 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace NUnit.UiException.Controls { /// /// Encapsulate data to draw a line of text. /// public class PaintLineLocation { /// /// Index of the current line. /// private int _lineIndex; /// /// The string value at this line. /// private string _text; /// /// A client coordinate from where beginning the drawing. /// private PointF _location; /// /// Build a new instance of this object given some data. /// /// Index of the current line. /// String value at this line. /// Client coordinate where beginning the drawing. public PaintLineLocation(int lineIndex, string text, PointF location) { SetLine(lineIndex); SetText(text); SetLocation(location); return; } /// /// Index of the current line. /// public int LineIndex { get { return (_lineIndex); } } /// /// String value at this line. /// public string Text { get { return (_text); } } /// /// Client coordinate where to beginning the drawing. /// public PointF Location { get { return (_location); } } public override bool Equals(object obj) { PaintLineLocation line; if (obj == null || !(obj is PaintLineLocation)) return (false); line = obj as PaintLineLocation; return (line.LineIndex == LineIndex && line.Text == Text && line.Location == Location); } public override int GetHashCode() { return base.GetHashCode(); } public override string ToString() { return ("PaintLineLocation: {" + LineIndex + ":[" + Text + "]:(" + Location.X + ", " + Location.Y + ")}"); } #region private definitions protected void SetLine(int lineIndex) { _lineIndex = lineIndex; return; } protected void SetText(string text) { UiExceptionHelper.CheckNotNull(text, "text"); _text = text; } protected void SetLocation(PointF location) { _location = location; } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ErrorPanelLayout.cs0000664000175000017500000001754211504175260026220 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using NUnit.UiException.Properties; namespace NUnit.UiException.Controls { /// /// Provides the panels and layout of ErrorBrowser as /// shown below: /// /// +--------------------------------------------+ /// | Toolbar | /// +--------------------------------------------+ /// | | /// | | /// | Content | /// | | /// | | /// +--------------------------------------------+ /// /// Toolbar: the control which shows buttons /// to alternate between the StackTraceDisplay /// and BrowserDisplay back and forth. /// The control collection of this control /// never changes. /// /// Option: a free place holder to show subfeature /// for a specific display (e.g: StackTraceDisplay /// or BrowserDisplay). This control's /// collection changes in relation with the /// selected display. /// /// Content: the place where to put the main content /// for the current display. This control's /// collection changes in regard of the /// selected display. /// public class ErrorPanelLayout : UserControl { private static readonly int PANEL_LEFT = 0; private static readonly int PANEL_RIGHT = 1; public static readonly int TOOLBAR_HEIGHT = 26; private InternalSplitter _header; private Panel _contentDefault; private Control _contentCurrent; public ErrorPanelLayout() { _header = new InternalSplitter(); _contentDefault = new Panel(); _contentCurrent = _contentDefault; Controls.Add(_header[PANEL_LEFT]); //Controls.Add(_header[PANEL_RIGHT]); Controls.Add(_contentDefault); //_header[PANEL_LEFT].BackColor = Color.Yellow; //_header[PANEL_RIGHT].BackColor = Color.Violet; //_contentDefault.BackColor = Color.Green; SizeChanged += new EventHandler(ErrorPanelLayout_SizeChanged); _header[PANEL_RIGHT].ControlAdded += new ControlEventHandler(ErrorPanelLayout_ControlAddedOrRemoved); _header[PANEL_RIGHT].ControlRemoved += new ControlEventHandler(ErrorPanelLayout_ControlAddedOrRemoved); Width = 200; Height = 200; return; } void ErrorPanelLayout_ControlAddedOrRemoved(object sender, ControlEventArgs e) { doLayout(); } void ErrorPanelLayout_SizeChanged(object sender, EventArgs e) { doLayout(); } /// /// Gets or sets the control to be placed in Toolbar location. /// Pass null to reset Toolbar to its default state. /// /// When setting a control, the control's hierarchy of /// ErrorPanelLayout is automatically updated with the /// passed component. Besides, the passed component is /// automatically positionned to the right coordinates. /// public Control Toolbar { get { return (_header[PANEL_LEFT]); } set { Controls.Remove(_header[PANEL_LEFT]); _header[PANEL_LEFT] = value; Controls.Add(_header[PANEL_LEFT]); doLayout(); } } /// /// Gets or sets the control to be placed in Option location. /// Pass null to reset Option to its default state. /// /// When setting a control, the control's hierarchy of /// ErrorPanelLayout is automatically updated with the /// passed component. Besides, the passed component is /// automatically positionned to the right coordinates. /// public Control Option { get { return (_header[PANEL_RIGHT]); } set { Controls.Remove(_header[PANEL_RIGHT]); _header[PANEL_RIGHT] = value; Controls.Add(_header[PANEL_RIGHT]); doLayout(); } } /// /// Gets or sets the control to be placed in Content location. /// Pass null to reset content to its default state. /// /// When setting a control, the control's hierarchy of /// ErrorPanelLayout is automatically updated with the /// passed component. Besides, the passed component is /// automatically positionned to the right coordinates. /// public Control Content { get { return (_contentCurrent); } set { if (value == null) value = _contentDefault; Controls.Remove(_contentCurrent); _contentCurrent = value; Controls.Add(_contentCurrent); doLayout(); } } //protected override void OnPaint(PaintEventArgs e) //{ // e.Graphics.DrawImage(Resources.ErrorBrowserHeader, // new Rectangle(0, 0, Width, TOOLBAR_HEIGHT), // new Rectangle(0, 0, Resources.ErrorBrowserHeader.Width - 1, // Resources.ErrorBrowserHeader.Height), // GraphicsUnit.Pixel); // return; //} private void doLayout() { // int widthLeft; int widthRight; widthRight = _header.WidthAt(PANEL_RIGHT); // widthLeft = _header.WidthAt(PANEL_LEFT); _header[PANEL_LEFT].Width = Math.Max(0, Width - widthRight); _contentCurrent.Width = Width; _header[PANEL_LEFT].Height = TOOLBAR_HEIGHT; _header[PANEL_RIGHT].Height = Math.Min(TOOLBAR_HEIGHT, _header[PANEL_RIGHT].Height); _header[PANEL_RIGHT].Width = widthRight; _header[PANEL_RIGHT].Left = _header[PANEL_LEFT].Width; _contentCurrent.Height = Height - TOOLBAR_HEIGHT; _contentCurrent.Top = TOOLBAR_HEIGHT; return; } class InternalSplitter : UserControl { private Panel[] _panels; private Control[] _currents; public InternalSplitter() { _panels = new Panel[] { new Panel(), new Panel() }; _currents = new Control[] { _panels[0], _panels[1] }; _panels[0].Width = 0; _panels[1].Width = 0; return; } public Control this[int index] { get { return (_currents[index]); } set { if (value == null) value = _panels[index]; _currents[index] = value; } } public int WidthAt(int index) { if (_currents[index] == _panels[index]) return (0); return (_currents[index].Width); } } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/CodeBox.cs0000664000175000017500000001533611504175260024273 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; using NUnit.UiException.CodeFormatters; using System.Diagnostics; /// This control could have been replaced by a standard RichTextBox control, but /// it turned out that RichTextBox: /// - was hard to configure /// - was hard to set the viewport /// - doesn't use double buffer optimization /// - scrolls text one line at a time without be configurable. /// /// CodeBox has been written to address these specific issues in order to display /// C# source code where exceptions occured. namespace NUnit.UiException.Controls { /// /// A control that implements ICodeView. /// public class CodeBox : UserControl, ICodeView { protected CodeRenderingContext _workingContext; protected FormattedCode _formattedCode; private IFormatterCatalog _formatter; private ICodeRenderer _renderer; private string _language; private bool _showCurrentLine; private int _currentLine; public CodeBox() : this(new GeneralCodeFormatter(), new DefaultCodeRenderer()) { } #region ICodeView Members public override string Text { get { return (_formattedCode.Text); } set { if (value == null) value = ""; SizeF docSize; _formattedCode = _formatter.Format(value, _language); docSize = _renderer.GetDocumentSize( _formattedCode, _workingContext.Graphics, _workingContext.Font); AutoScrollMinSize = new Size((int)docSize.Width, (int)docSize.Height); Invalidate(); return; } } public string Language { get { return (_language); } set { if (value == null) value = ""; if (_language == value) return; _language = value; Text = Text; } } public int CurrentLine { get { return (_currentLine); } set { float y = _renderer.LineIndexToYCoordinate(value, _workingContext.Graphics, _workingContext.Font); y -= Height / 2; _currentLine = value; AutoScrollPosition = new Point(0, (int)y); Invalidate(); } } public IFormatterCatalog Formatter { get { return (_formatter); } } #endregion /// /// Gets or sets a value telling whether or not displaying a special /// feature for the current line at drawing time. /// public bool ShowCurrentLine { get { return (_showCurrentLine); } set { _showCurrentLine = value; } } /// /// If ShowCurrentLine is set, this set the current line's background color. /// public Color CurrentLineBackColor { get { return (_workingContext.CurrentLineBackColor); } set { _workingContext.CurrentLineBackColor = value; Invalidate(); } } /// /// If ShowCurrentLine is set, this set current line's foreground color. /// public Color CurrentLineForeColor { get { return (_workingContext.CurrentLineForeColor); } set { _workingContext.CurrentLineForeColor = value; Invalidate(); } } protected CodeBox(IFormatterCatalog formatter, ICodeRenderer renderer) { SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); DoubleBuffered = true; _formatter = formatter; _formattedCode = FormattedCode.Empty; _renderer = renderer; _currentLine = -1; _showCurrentLine = false; _language = ""; this.Font = new Font(FontFamily.GenericMonospace, 8); this.BackColor = Color.White; createGraphics(); AutoScroll = true; return; } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); Focus(); } protected override void OnPaint(PaintEventArgs e) { Graphics backup; base.OnPaint(e); backup = _workingContext.Graphics; _workingContext.Graphics = e.Graphics; _workingContext.CurrentLine = (_showCurrentLine ? _currentLine : -1); _renderer.DrawToGraphics(_formattedCode, _workingContext, new Rectangle(-AutoScrollPosition.X, -AutoScrollPosition.Y, Width, Height)); _workingContext.Graphics = backup; return; } protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); if (_workingContext != null) { _workingContext.Font = Font; Text = Text; } return; } private void createGraphics() { Graphics gCurrent = CreateGraphics(); Image img = new Bitmap(10, 10, gCurrent); Graphics gImg = Graphics.FromImage(img); gCurrent.Dispose(); _workingContext = new CodeRenderingContext(); _workingContext.Graphics = gImg; _workingContext.Font = Font; _workingContext.CurrentLine = -1; _workingContext.BackgroundColor = Color.White; _workingContext.CurrentLineBackColor = Color.Red; _workingContext.CurrentLineForeColor = Color.White; _workingContext.CodeColor = Color.Black; _workingContext.CommentColor = Color.Green; _workingContext.KeywordColor = Color.Blue; _workingContext.StringColor = Color.Red; return; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/SourceCodeDisplay.cs0000664000175000017500000001460611504175260026330 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using NUnit.UiException.Properties; using NUnit.UiException.CodeFormatters; namespace NUnit.UiException.Controls { /// /// Implements IErrorDisplay and displays data about failures and error /// after a test suite run. SourceCodeDisplay is a control composed of two /// views. /// /// The first view displays the stack trace in an ordered list of items /// where each item contains the context about a specific failure (file, class /// method, line number). /// /// The second view displays a CodeBox control and shows the source code /// of one element in this list when the localization is available. /// public class SourceCodeDisplay : IErrorDisplay { protected IStackTraceView _stacktraceView; protected ICodeView _codeView; protected SplitterBox _splitter; private CodeBox _codeBox; private ToolStripButton _btnPlugin; private ToolStripButton _btnSwap; public event EventHandler SplitOrientationChanged; public event EventHandler SplitterDistanceChanged; /// /// Builds a new instance of SourceCodeDisplay. /// public SourceCodeDisplay() { ErrorList errorList = new ErrorList(); _codeBox = new CodeBox(); _stacktraceView = errorList; _stacktraceView.AutoSelectFirstItem = true; _stacktraceView.SelectedItemChanged += new EventHandler(SelectedItemChanged); _codeView = _codeBox; _btnPlugin = ErrorToolbar.NewStripButton(true, "Display source code context", Resources.ImageSourceCodeDisplay, null); _btnSwap = ErrorToolbar.NewStripButton(false, "ReverseOrder item order", Resources.ImageReverseItemOrder, OnClick); SplitterBox splitter = new SplitterBox(); _splitter = splitter; _splitter.SplitterDistanceChanged += new EventHandler(_splitter_DistanceChanged); _splitter.OrientationChanged += new EventHandler(_splitter_OrientationChanged); splitter.Control1 = errorList; splitter.Control2 = _codeBox; _codeBox.ShowCurrentLine = true; return; } void _splitter_DistanceChanged(object sender, EventArgs e) { if (SplitterDistanceChanged != null) SplitterDistanceChanged(sender, e); } void _splitter_OrientationChanged(object sender, EventArgs e) { if (SplitOrientationChanged != null) SplitOrientationChanged(sender, e); } public Font CodeDisplayFont { get { return _codeBox.Font; } set { _codeBox.Font = value; } } /// /// Gets or sets a value telling whether or not to select automatically /// the first localizable item each time the stack trace changes. /// When set to true, the first localizable item will be selected /// and the source code context for this item displayed automatically. /// Default is True. /// public bool AutoSelectFirstItem { get { return (_stacktraceView.AutoSelectFirstItem); } set { _stacktraceView.AutoSelectFirstItem = value; } } /// /// Gets or sets a value defining the order of the item in the error list. /// public ErrorListOrderPolicy ListOrderPolicy { get { return (_stacktraceView.ListOrderPolicy); } set { _stacktraceView.ListOrderPolicy = value; } } /// /// Gets or sets the splitter orientation in the SourceCodeDisplay. /// public Orientation SplitOrientation { get { return (_splitter.Orientation); } set { _splitter.Orientation = value; } } /// /// Gets or sets the splitter distance in the SourceCodeDisplay. /// public float SplitterDistance { get { return (_splitter.SplitterDistance); } set { _splitter.SplitterDistance = value; } } private void OnClick(object sender, EventArgs e) { ListOrderPolicy = ListOrderPolicy == ErrorListOrderPolicy.InitialOrder ? ErrorListOrderPolicy.ReverseOrder : ErrorListOrderPolicy.InitialOrder; return; } protected void SelectedItemChanged(object sender, EventArgs e) { ErrorItem item; IFormatterCatalog formatter; item = _stacktraceView.SelectedItem; if (item == null) { _codeView.Text = null; return; } formatter = _codeView.Formatter; _codeView.Language = formatter.LanguageFromExtension(item.FileExtension); try { _codeView.Text = item.ReadFile(); } catch (Exception ex) { _codeView.Text = String.Format( "Cannot open file: '{0}'\r\nError: '{1}'\r\n", item.Path, ex.Message); } _codeView.CurrentLine = item.LineNumber - 1; return; } #region IErrorDisplay Membres public ToolStripButton PluginItem { get { return (_btnPlugin); } } public ToolStripItem[] OptionItems { get { return (new ToolStripItem[] { _btnSwap }); } } public Control Content { get { return (_splitter); } } public void OnStackTraceChanged(string stackTrace) { _stacktraceView.StackTrace = stackTrace; } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/IErrorListRenderer.cs0000664000175000017500000000552011504175260026467 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace NUnit.UiException.Controls { /// /// The interface through which ErrorList interacts with a painter to paint itself. /// /// Direct implementation is: /// - DefaultErrorListRenderer /// public interface IErrorListRenderer { /// /// Draws the list on the given graphics. /// /// The item collection to paint on the graphics object /// The item to paint with selection feature /// The target graphics object /// The viewport location void DrawToGraphics(ErrorItemCollection items, ErrorItem selected, Graphics g, Rectangle viewport); /// /// Draw the given item on the given graphics object. /// /// The item to be painted /// The item's index /// If true, this item can display hover feature /// If true, this item can display selection feature /// The target graphics object /// The current viewport void DrawItem(ErrorItem item, int index, bool hovered, bool selected, Graphics g, Rectangle viewport); /// /// Given a collection of items and a graphics object, this method /// measures in pixels the size of the collection. /// /// The collection /// The target graphics object /// The size in pixels of the collection Size GetDocumentSize(ErrorItemCollection items, Graphics g); /// /// Gets the Item right under point. /// /// A collection of items /// The target graphics object /// Some client coordinate values /// One item in the collection or null the location doesn't match any item ErrorItem ItemAt(ErrorItemCollection items, Graphics g, Point point); /// /// Gets and sets the font for this renderer /// Font Font { get; set; } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ErrorList.cs0000664000175000017500000001660211504175260024672 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; namespace NUnit.UiException.Controls { /// /// Displays a control which implements IStackTraceView. /// public class ErrorList : UserControl, IStackTraceView { public event EventHandler SelectedItemChanged; private ErrorListOrderPolicy _listOrder; private ErrorItemCollection _items; private ErrorItem _selection; private string _stackTrace; protected IErrorListRenderer _renderer; protected Graphics _workingGraphics; protected int _hoveredIndex; private Point _mouse; private bool _autoSelectFirstItem; /// /// Builds a new instance of ErrorList. /// public ErrorList() : this(new DefaultErrorListRenderer()) { } /// /// Gives access to the item collection. /// public ErrorItemCollection Items { get { return (_items); } } #region IStackTraceView Members public bool AutoSelectFirstItem { get { return (_autoSelectFirstItem); } set { _autoSelectFirstItem = value; } } public string StackTrace { get { return (_stackTrace); } set { ErrorItem candidate; candidate = PopulateList(value); if (!String.IsNullOrEmpty(value) && _items.Count == 0) _items.Add(new ErrorItem(null, "Fail to parse stack trace", -1)); AutoScrollMinSize = _renderer.GetDocumentSize(_items, _workingGraphics); _hoveredIndex = -1; SelectedItem = (AutoSelectFirstItem ? candidate : null); Invalidate(); return; } } public ErrorItem SelectedItem { get { return (_selection); } set { bool fireEvent; if (value != null && (!_items.Contains(value) || !value.HasSourceAttachment)) return; fireEvent = (_selection != value); _selection = value; if (fireEvent && SelectedItemChanged != null) SelectedItemChanged(this, new EventArgs()); Invalidate(); } } public ErrorListOrderPolicy ListOrderPolicy { get { return (_listOrder); } set { if (_listOrder == value) return; _listOrder = value; _items.Reverse(); Invalidate(); } } #endregion protected ErrorList(IErrorListRenderer renderer) { UiExceptionHelper.CheckNotNull(renderer, "display"); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); DoubleBuffered = true; _renderer = renderer; _items = new ErrorItemCollection(); _stackTrace = null; _selection = null; _workingGraphics = CreateGraphics(); _hoveredIndex = -1; _autoSelectFirstItem = false; _listOrder = ErrorListOrderPolicy.InitialOrder; return; } protected virtual void ItemEntered(int index) { Cursor = Cursors.Hand; } protected virtual void ItemLeaved(int index) { Cursor = Cursors.Default; } protected override void OnPaint(PaintEventArgs e) { Rectangle viewport; base.OnPaint(e); viewport = new Rectangle(-AutoScrollPosition.X, -AutoScrollPosition.Y, ClientRectangle.Width, ClientRectangle.Height); _renderer.DrawToGraphics(_items, _selection, e.Graphics, viewport); if (_hoveredIndex != -1) _renderer.DrawItem(_items[_hoveredIndex], _hoveredIndex, true, _items[_hoveredIndex] == _selection, e.Graphics, viewport); return; } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); Focus(); } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); _mouse = new Point(e.X, e.Y - AutoScrollPosition.Y); } protected override void OnMouseMove(MouseEventArgs e) { ErrorItem item; int itemIndex; base.OnMouseMove(e); item = _renderer.ItemAt(_items, _workingGraphics, new Point(e.X, e.Y - AutoScrollPosition.Y)); itemIndex = -1; for (int i = 0; i < _items.Count; ++i) if (Object.ReferenceEquals(_items[i], item)) { itemIndex = i; break; } if (itemIndex != _hoveredIndex) { if (_hoveredIndex != -1) ItemLeaved(_hoveredIndex); if (itemIndex != -1 && _items[itemIndex].HasSourceAttachment) { ItemEntered(itemIndex); _hoveredIndex = itemIndex; } else _hoveredIndex = -1; Invalidate(); } return; } protected override void OnClick(EventArgs e) { base.OnClick(e); OnClick(_mouse); return; } protected override void OnFontChanged(EventArgs e) { this._renderer.Font = this.Font; base.OnFontChanged(e); } protected void OnClick(Point point) { SelectedItem = _renderer.ItemAt(_items, _workingGraphics, point); return; } protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); Invalidate(); } private ErrorItem PopulateList(string stackTrace) { StackTraceParser parser = new StackTraceParser(); ErrorItem candidate; _stackTrace = stackTrace; parser.Parse(stackTrace); if (_listOrder == ErrorListOrderPolicy.ReverseOrder) parser.Items.Reverse(); candidate = null; _items.Clear(); foreach (ErrorItem item in parser.Items) { if (candidate == null && item.HasSourceAttachment) candidate = item; _items.Add(item); } return (candidate); } } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ErrorToolbar.cs0000664000175000017500000001504011504175260025354 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Collections; using System.Drawing; using System.Diagnostics; using NUnit.UiException.Properties; namespace NUnit.UiException.Controls { /// /// A specialization of a ToolStrip to show instances of IErrorDisplay. /// public class ErrorToolbar : ToolStrip, IEnumerable { public event EventHandler SelectedRendererChanged; private List _displays; private ToolStripItem _separator; private int _selection; public ErrorToolbar() { _displays = new List(); _separator = CreateDefaultItem("-", null, null); Items.Add(_separator); _selection = -1; BackgroundImage = Resources.ImageErrorBrowserHeader; BackgroundImageLayout = ImageLayout.Tile; return; } /// /// Create and configure a ToolStripButton. /// public static ToolStripButton NewStripButton( bool canCheck, string text, Image image, EventHandler onClick) { ToolStripButton button; button = new ToolStripButton(text, image, onClick); button.CheckOnClick = canCheck; button.Image = image; button.ImageScaling = ToolStripItemImageScaling.None; button.TextImageRelation = TextImageRelation.ImageBeforeText; button.DisplayStyle = ToolStripItemDisplayStyle.Image; return (button); } /// /// Gets the count of IErrorDisplay instances. /// public int Count { get { return (_displays.Count); } } /// /// Gets the display at the given index. /// public IErrorDisplay this[int index] { get { return (_displays[index]); } } /// /// Gets or sets the IErrorDisplay to be selected. /// public IErrorDisplay SelectedDisplay { get { if (_selection == -1) return (null); return ((IErrorDisplay)Items[_selection].Tag); } set { int index = IndexOf(value); UiExceptionHelper.CheckFalse(index == -1 && value != null, "Cannot select unregistered display.", "SelectedDisplay"); if (index == _selection) return; _selection = index; SetOrUnsetCheckedFlag(_selection); ShowOrHideOptionItems(_selection); if (SelectedRendererChanged != null) SelectedRendererChanged(this, new EventArgs()); return; } } /// /// Register a new IErrorDisplay in the toolbar. /// public void Register(IErrorDisplay display) { ToolStripItem item; int sepIndex; UiExceptionHelper.CheckNotNull(display, "display"); UiExceptionHelper.CheckNotNull(display.PluginItem, "display.PluginItem"); item = display.PluginItem; item.Tag = display; item.Click += new EventHandler(item_Click); _displays.Add(display); sepIndex = Items.IndexOf(_separator); Items.Insert(sepIndex, item); if (display.OptionItems != null) { ToolStripItem[] array = display.OptionItems; foreach (ToolStripItem value in array) { value.Visible = false; Items.Add(value); } } if (_displays.Count == 1) SelectedDisplay = display; return; } /// /// Clears all IErrorDisplay in the toolbar. /// public void Clear() { _displays.Clear(); Items.Clear(); Items.Add(_separator); return; } private void ShowOrHideOptionItems(int selectedIndex) { int index; foreach (IErrorDisplay item in _displays) { if ((index = IndexOf(item)) == -1) continue; if (item.OptionItems == null) continue; foreach (ToolStripItem stripItem in item.OptionItems) stripItem.Visible = (index == selectedIndex); } return; } private void SetOrUnsetCheckedFlag(int selectedIndex) { int index; foreach (IErrorDisplay item in _displays) { index = IndexOf(item); if (index == -1) continue; item.PluginItem.Checked = (index == selectedIndex); } return; } private int IndexOf(IErrorDisplay renderer) { int i; if (renderer == null) return (-1); for (i = 0; i < Items.Count; ++i) if (object.ReferenceEquals(Items[i].Tag, renderer)) return (i); return (-1); } private void item_Click(object sender, EventArgs e) { ToolStripItem item = sender as ToolStripItem; IErrorDisplay renderer; if (item == null || item.Tag == null) return; renderer = item.Tag as IErrorDisplay; if (renderer == null) return; SelectedDisplay = renderer; return; } #region IEnumerable Membres public IEnumerator GetEnumerator() { return (_displays.GetEnumerator()); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/Controls/ICodeRenderer.cs0000664000175000017500000000377411504175260025425 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.CodeFormatters; using System.Drawing; namespace NUnit.UiException.Controls { /// /// The interface through which CodeBox interacts with a display to display itself. /// /// Direct implementation is: /// - DefaultCodeRenderer /// public interface ICodeRenderer { /// /// Draw the given code to be displayed in the actual viewport. /// /// The code to draw /// Encapsulate graphic information about how to display the code /// The portion of interest void DrawToGraphics(FormattedCode code, CodeRenderingContext args, Rectangle viewport); /// /// Measures the code size in pixels. /// /// The code to measure /// The target graphics object /// The font with which displaying the code /// The size in pixels SizeF GetDocumentSize(FormattedCode code, Graphics g, Font font); /// /// Converts a line index to its matching Y client coordinate. /// /// The line index to convert /// The target graphics object /// The font with which displaying the code /// The Y client coordinate float LineIndexToYCoordinate(int lineIndex, Graphics g, Font font); } } NUnit-2.6.0.12051/src/GuiException/UiException/nunit.uiexception.build0000664000175000017500000000735411525675710025340 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiException/UiException/nunit.uiexception.dll.csproj0000664000175000017500000001275711574577562026330 0ustar jtaylorjtaylor Debug AnyCPU 9.0.21022 2.0 {3E87A106-EB20-4147-84C8-95B0BB43A1D4} Library Properties NUnit.UiException nunit.uiexception v2.0 512 ..\..\..\..\src\GuiException\UiException\stackSgKey.snk true full false ..\..\..\bin\Debug\lib\ TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 prompt 4 1699 pdbonly true ..\..\..\bin\Release\lib\ TRACE;CLR_2_0,NET_2_0,CS_3_0 prompt 4 1699 CommonAssemblyInfo.cs UserControl UserControl UserControl UserControl Component Component UserControl Designer NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/0000775000175000017500000000000011742560362024521 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/UnixPathParser.cs0000664000175000017500000000541111504175260027761 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; namespace NUnit.UiException.StackTraceAnalysers { /// /// This class is responsible for extracting a Unix like path value /// from a line of the given stack trace. This class bases its work /// on the following assumptions: /// - paths are supposed to be absolute, /// - paths are supposed to be made of two parts: [/][path] /// Where [/] refers to the Unix mount point /// and [path] a non empty string of characters that extends to the /// trailing ':' (as given in stack trace). /// class UnixPathParser : IErrorParser { #region IErrorParser Membres /// /// Locates and fills RawError.Path property with the first /// Unix path values found from RawError.Input property. /// /// The stack trace parser. This parameter /// must not be null. /// The RawError from which retrieving and /// filling Input and Path properties. This parameter cannot not /// be null. /// True if a match occured, false otherwise. public bool TryParse(StackTraceParser parser, RawError args) { int posSlash; int posColon; string path; UiExceptionHelper.CheckNotNull(parser, "parser"); UiExceptionHelper.CheckNotNull(args, "args"); if ((posSlash = indexOfFirstSlash(args.Input, 0)) == -1) return (false); if ((posColon = PathCompositeParser.IndexOfTrailingColon(args.Input, posSlash + 1)) == -1) return (false); path = args.Input.Substring(posSlash, posColon - posSlash); path = path.Trim(); if (path.Length <= 1) return (false); args.Path = path; return (true); } #endregion private int indexOfFirstSlash(string error, int startIndex) { for (; startIndex < error.Length; startIndex++) if (error[startIndex] == '/') { if (startIndex == 0 || startIndex > 0 && error[startIndex - 1] == ' ') return (startIndex); } return (-1); } } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/FunctionParser.cs0000664000175000017500000000623011504175260030006 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; namespace NUnit.UiException.StackTraceAnalysers { /// /// This class is responsible for locating and initializing /// RawError.Function property with the function name as it /// is mentioned in the stack trace line. /// To work correclty, the class makes some /// assumptions concerning the function format. /// A function name is made of two parts: [name][args] /// where [name] refers to a string of characters that doesn't /// contain ' ' and [args] refers to a string delimited by /// '(' and ')'. /// public class FunctionParser : IErrorParser { #region IErrorParser Membres /// /// Try to match a function name by reading RawError.Input. /// If a match is found, the method outputs the result into /// RawError.Function and returns true. /// /// An instance of parser, this parameter /// cannot be null. /// An instance of RawError. This parameter /// cannot be null. /// True if a match occurs, false otherwise. public bool TryParse(StackTraceParser parser, RawError args) { int posEndingParenthesis; int posOpeningParenthesis; int posName; int endName; string res; int i; UiExceptionHelper.CheckNotNull(parser, "parser"); UiExceptionHelper.CheckNotNull(args, "args"); posEndingParenthesis = args.Input.LastIndexOf(")"); posOpeningParenthesis = args.Input.LastIndexOf("("); if (posEndingParenthesis == -1 || posOpeningParenthesis == -1 || posOpeningParenthesis > posEndingParenthesis) return (false); endName = posOpeningParenthesis; for (i = posOpeningParenthesis - 1; i >= 0; i--) { if (args.Input[i] != ' ') break; endName = i; } posName = -1; for (i = endName - 1; i >= 0; i--) { if (args.Input[i] == ' ') break; posName = i; } // Added this test to allow for odd case where we would // otherwise include the leading "at" or "à" in name. if (posName == 0) return false; if (posName == -1) return (false); res = args.Input.Substring(posName, posEndingParenthesis - posName + 1); args.Function = res; return (true); } #endregion } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/PathCompositeParser.cs0000664000175000017500000000671311504175260031006 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; namespace NUnit.UiException.StackTraceAnalysers { /// /// Encapsulates a set of algorithms that try to match and locate /// a path value coming from a raw stack trace line. /// public class PathCompositeParser : IErrorParser { /// /// This array encapsulates a list of classes that inherit from /// IErrorParser. Each instance is made for handling a path from /// a specific file system such as: Windows or UNIX. /// private IErrorParser[] _array; /// /// Build a new instance of PathParser. /// public PathCompositeParser() { // setup this array with a couple of algorithms // that handle respectively Windows and Unix like paths. _array = new IErrorParser[] { new WindowsPathParser(), new UnixPathParser() // add your own parser here }; return; } /// /// Gives access to the IErrorParser instance that handles /// Windows like path values. /// public IErrorParser WindowsPathParser { get { return (_array[0]); } } /// /// Gives access to the IErrorParser instance that handles /// Unix like path values. /// public IErrorParser UnixPathParser { get { return (_array[1]); } } #region IErrorParser Membres /// /// Try to read from a stack trace line a path value given either /// under the form of a Windows path or a UNIX path. If a match occurs /// the method fills args.Function with the identified data. /// /// The instance of StackTraceParser, this parameter /// cannot be null. /// The instance of RawError from where read and write /// RawError.Input and RawError.Function properties. This parameter /// cannot be null. /// True if a match occurs, false otherwise. public bool TryParse(StackTraceParser parser, RawError args) { foreach (IErrorParser item in _array) if (item.TryParse(parser, args)) return (true); return (false); } #endregion /// /// Helper method that locate the trailing ':' in a stack trace row. /// /// The index position of ':' in the string or -1 if not found. public static int IndexOfTrailingColon(string error, int startIndex) { int i; for (i = startIndex; i < error.Length; ++i) if (error[i] == ':') return (i); return (-1); } } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/IErrorParser.cs0000664000175000017500000000316211504175260027424 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; namespace NUnit.UiException.StackTraceAnalyzers { public class RawError { private string _function; private string _path; private int _line; private string _input; public RawError(string input) { UiExceptionHelper.CheckNotNull(input, "input"); _input = input; return; } public string Input { get { return (_input); } } public string Function { get { return (_function); } set { _function = value; } } public string Path { get { return (_path); } set { _path = value; } } public int Line { get { return (_line); } set { _line = value; } } public ErrorItem ToErrorItem() { UiExceptionHelper.CheckTrue( _function != null, "Cannot create instance of ErrorItem without a valid value in Function", "Function"); return (new ErrorItem(_path, _function, _line)); } } public interface IErrorParser { bool TryParse(StackTraceParser parser, RawError args); } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/WindowsPathParser.cs0000664000175000017500000000570611504175260030477 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; namespace NUnit.UiException.StackTraceAnalysers { /// /// This class is responsible for extracting a Windows like path value /// from a line of the given stack trace. This class bases its work /// on the following assumptions: /// - paths are supposed to be absolute, /// - paths are supposed to be made of two parts: [drive][path] /// Where [drive] refers to a sequence like: "C:\\" /// and [path] a non empty string of characters that extends to the /// trailing ':' (as given in stack trace). /// public class WindowsPathParser : IErrorParser { #region IErrorParser Membres /// /// Locates and fills RawError.Path property with the first /// Windows path values found from RawError.Input property. /// /// The stack trace parser. This parameter /// must not be null. /// The RawError from which retrieving and /// filling Input and Path properties. This parameter cannot not /// be null. /// True if a match occured, false otherwise. public bool TryParse(StackTraceParser parser, RawError args) { int posDriveLetter; int posTrailingColon; string path; UiExceptionHelper.CheckNotNull(parser, "parser"); UiExceptionHelper.CheckNotNull(args, "args"); posDriveLetter = lookForDriveLetter(args.Input, 0); if (posDriveLetter == -1) return (false); posTrailingColon = PathCompositeParser.IndexOfTrailingColon(args.Input, posDriveLetter + 3); if (posTrailingColon == -1) return (false); path = args.Input.Substring(posDriveLetter, posTrailingColon - posDriveLetter); path = path.Trim(); if (path.Length <= 3) return (false); args.Path = path; return (true); } #endregion private int lookForDriveLetter(string error, int startIndex) { int i; for (i = startIndex; i < error.Length - 2; ++i) { if (((error[i] >= 'a' && error[i] <= 'z') || (error[i] >= 'A' && error[i] <= 'Z')) && error[i + 1] == ':' && error[i + 2] == '\\') return (i); } return (-1); } } } NUnit-2.6.0.12051/src/GuiException/UiException/StackTraceAnalysers/LineNumberParser.cs0000664000175000017500000000742211504175260030265 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using NUnit.UiException.StackTraceAnalyzers; namespace NUnit.UiException.StackTraceAnalysers { /// /// LineNumberParser tries to match a line number information /// given in a stack trace line. It relies on the following /// assumptions: /// - the line number is located after the last ':' character, /// - the line number is not part of a word, /// - there cannot be more than one line number after the last ':' /// - the line number must be > 0 /// public class LineNumberParser : IErrorParser { #region IErrorParser Membres /// /// Reads args.Input and try to locate a line number information. /// If a match occurs the method fills args.Line with the identified /// integer. /// /// The StackTraceParser instance. The /// parameter cannot be null. /// The RawError instance from where read and /// write Input and Line properties. The parameter cannot be null. /// True if a match occurs, false otherwise. public bool TryParse(StackTraceParser parser, RawError args) { int posTrailingColon; int line; UiExceptionHelper.CheckNotNull(parser, "parser"); UiExceptionHelper.CheckNotNull(args, "args"); if ((posTrailingColon = args.Input.LastIndexOf(":")) == -1) return (false); if ((line = lookForLastInteger(args.Input, posTrailingColon)) <= 0) return (false); args.Line = line; return (true); } #endregion private int lookForLastInteger(string error, int startIndex) { int res; int workPos; for (; startIndex < error.Length; ++startIndex) if (error[startIndex] >= '0' && error[startIndex] <= '9') { // the integer we are looking for // is following either a ' ' or ':' character. // ex: "line 42" or ":42" // but rejects values like: "line42" if (startIndex > 0 && error[startIndex - 1] != ' ' && error[startIndex - 1] != ':') return (-1); break; } if (startIndex >= error.Length) return (-1); // it is assumes that only one line number information will be // present on a line (if any). If two integers are found (should // never happen) we cannot distinguish which one refers to the // line number. In this case we prefer returning -1. // The next loop checks this point by moving the cursor to a // place after the current number and expects the inner call // to return -1 for (workPos = startIndex; workPos < error.Length; ++workPos) if (error[workPos] < '0' || error[workPos] > '9') break; if (lookForLastInteger(error, workPos) != -1) return (-1); Int32.TryParse(error.Substring(startIndex, workPos-startIndex), out res); return (res); } } } NUnit-2.6.0.12051/src/GuiException/UiException/TraceExceptionHelper.cs0000664000175000017500000000523111504175260025213 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace NUnit.UiException { /// /// (formerly named TraceExceptionHelper) /// /// Exposes static methods to assert predicates and throw exceptions /// as needed. /// public class UiExceptionHelper { /// /// Asserts that reference is not null; otherwise throws an /// ArgumentNullException. /// /// The reference to be tested. /// The name of this reference [DebuggerStepThrough] public static void CheckNotNull(object value, string paramName) { if (value == null) throw new ArgumentNullException(paramName); return; } /// /// Asserts that 'test' is true or throws an ArgumentException. /// /// The boolean to be tested. /// The error message. /// The parameter name to be passed to ArgumentException. [DebuggerStepThrough] public static void CheckTrue(bool test, string message, string paramName) { if (!test) throw new ArgumentException(message, paramName); return; } /// /// Asserts that 'test' is false or throws an ArgumentException. /// /// The boolean to be tested. /// The error message. /// The parameter name to be passed to ArgumentException. [DebuggerStepThrough] public static void CheckFalse(bool test, string message, string paramName) { if (test) throw new ArgumentException(message, paramName); return; } /// /// Throws an ApplicationException with the given message. /// /// The error message. [DebuggerStepThrough] public static void Fail(string message) { throw new ApplicationException(message); } } } NUnit-2.6.0.12051/src/GuiException/UiException/ExceptionItemCollection.cs0000664000175000017500000000607711504175260025740 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace NUnit.UiException { /// /// (formerly named ExceptionItemCollection) /// /// Manages an ordered set of ErrorItem. /// public class ErrorItemCollection : IEnumerable { /// /// The underlying item list. /// List _items; /// /// Build a new ErrorItemCollection. /// public ErrorItemCollection() { _items = new List(); return; } /// /// Gets the number of item in this collection. /// public int Count { get { return (_items.Count); } } /// /// Gets the ErrorItem at the specified index. /// /// The index of the wanted ErrorItem. /// The ErrorItem. public ErrorItem this[int index] { get { return (_items[index]); } } /// /// Appends the given item to the end of the collection. /// /// The ErrorItem to be added to the collection. public void Add(ErrorItem item) { UiExceptionHelper.CheckNotNull(item, "item"); _items.Add(item); return; } /// /// Clears all items from this collection. /// public void Clear() { if (_items.Count == 0) return; _items.Clear(); return; } /// /// Checks whether the given item belongs to this collection. /// /// The item to be checked. /// True if the item belongs to this collection. public bool Contains(ErrorItem item) { return (_items.Contains(item)); } /// /// Reverses the sequence order of this collection. /// public void Reverse() { _items.Reverse(); } #region IEnumerable Membres /// /// Gets an IEnumerator able to iterate through all ExceptionItems /// managed by this collection. /// /// An iterator to be used to iterator through all items /// in this collection. public IEnumerator GetEnumerator() { return (_items.GetEnumerator()); } #endregion } } NUnit-2.6.0.12051/src/nunit20under22.config0000664000175000017500000000167611504175260017651 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/nunit21under22.config0000664000175000017500000000167611504175260017652 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/0000775000175000017500000000000011742560362017066 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/0000775000175000017500000000000011742560362020043 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/SettingsGroup.cs0000664000175000017500000002247511504175260023214 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Util { using System; using System.Drawing; using System.Globalization; using System.ComponentModel; /// /// SettingsGroup is the base class representing a group /// of user or system settings. All storge of settings /// is delegated to a SettingsStorage. /// public class SettingsGroup : ISettings, IDisposable { #region Instance Fields protected ISettingsStorage storage; #endregion #region Constructors /// /// Construct a settings group. /// /// Storage for the group settings public SettingsGroup( ISettingsStorage storage ) { this.storage = storage; } /// /// Protected constructor for use by derived classes that /// set the storage themselves or don't use a storage. /// protected SettingsGroup() { } #endregion #region Properties public event SettingsEventHandler Changed; /// /// The storage used for the group settings /// public ISettingsStorage Storage { get { return storage; } } #endregion #region ISettings Members /// /// Load the value of one of the group's settings /// /// Name of setting to load /// Value of the setting or null public object GetSetting( string settingName ) { return storage.GetSetting( settingName ); } /// /// Load the value of one of the group's settings or return a default value /// /// Name of setting to load /// Value to return if the seeting is not present /// Value of the setting or the default public object GetSetting( string settingName, object defaultValue ) { object result = GetSetting(settingName ); if ( result == null ) result = defaultValue; return result; } /// /// Load the value of one of the group's integer settings /// in a type-safe manner or return a default value /// /// Name of setting to load /// Value to return if the seeting is not present /// Value of the setting or the default public int GetSetting(string settingName, int defaultValue) { object result = GetSetting(settingName); if (result == null) return defaultValue; if (result is int) return (int)result; try { return Int32.Parse(result.ToString()); } catch { return defaultValue; } } /// /// Load the value of one of the group's float settings /// in a type-safe manner or return a default value /// /// Name of setting to load /// Value to return if the setting is not present /// Value of the setting or the default public float GetSetting(string settingName, float defaultValue) { object result = GetSetting(settingName); if (result == null) return defaultValue; if (result is float) return (float)result; try { return float.Parse(result.ToString()); } catch { return defaultValue; } } /// /// Load the value of one of the group's boolean settings /// in a type-safe manner. /// /// Name of setting to load /// Value of the setting or the default /// Value of the setting public bool GetSetting( string settingName, bool defaultValue ) { object result = GetSetting(settingName ); if ( result == null ) return defaultValue; // Handle legacy formats // if ( result is int ) // return (int)result == 1; // // if ( result is string ) // { // if ( (string)result == "1" ) return true; // if ( (string)result == "0" ) return false; // } if ( result is bool ) return (bool) result ; try { return Boolean.Parse( result.ToString() ); } catch { return defaultValue; } } /// /// Load the value of one of the group's string settings /// in a type-safe manner or return a default value /// /// Name of setting to load /// Value to return if the setting is not present /// Value of the setting or the default public string GetSetting( string settingName, string defaultValue ) { object result = GetSetting(settingName ); if ( result == null ) return defaultValue; if ( result is string ) return (string) result; else return result.ToString(); } /// /// Load the value of one of the group's enum settings /// in a type-safe manner or return a default value /// /// Name of setting to load /// Value to return if the setting is not present /// Value of the setting or the default public System.Enum GetSetting(string settingName, System.Enum defaultValue) { object result = GetSetting(settingName); if (result == null) return defaultValue; if (result is System.Enum) return (System.Enum)result; try { return (System.Enum)System.Enum.Parse(defaultValue.GetType(), result.ToString(), true); } catch { return defaultValue; } } /// /// Load the value of one of the group's Font settings /// in a type-safe manner or return a default value /// /// Name of setting to load /// Value to return if the setting is not present /// Value of the setting or the default public Font GetSetting(string settingName, Font defaultFont) { object result = GetSetting(settingName); if (result == null) return defaultFont; if (result is Font) return (Font)result; try { TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); return (Font)converter.ConvertFrom(null, CultureInfo.InvariantCulture, result.ToString()); } catch { return defaultFont; } } /// /// Remove a setting from the group /// /// Name of the setting to remove public void RemoveSetting( string settingName ) { storage.RemoveSetting( settingName ); if ( Changed != null ) Changed( this, new SettingsEventArgs( settingName ) ); } /// /// Remove a group of settings /// /// public void RemoveGroup( string groupName ) { storage.RemoveGroup( groupName ); } /// /// Save the value of one of the group's settings /// /// Name of the setting to save /// Value to be saved public void SaveSetting( string settingName, object settingValue ) { object oldValue = storage.GetSetting( settingName ); // Avoid signaling "changes" when there is not really a change if ( oldValue != null ) { if( oldValue is string && settingValue is string && (string)oldValue == (string)settingValue || oldValue is int && settingValue is int && (int)oldValue == (int)settingValue || oldValue is bool && settingValue is bool && (bool)oldValue == (bool)settingValue || oldValue is Enum && settingValue is Enum && oldValue.Equals(settingValue) ) return; } storage.SaveSetting( settingName, settingValue ); if ( Changed != null ) Changed( this, new SettingsEventArgs( settingName ) ); } #endregion #region IDisposable Members /// /// Dispose of this group by disposing of it's storage implementation /// public void Dispose() { if ( storage != null ) { storage.Dispose(); storage = null; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/0000775000175000017500000000000011742560362022126 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/IRuntimeFrameworkSelector.cs0000664000175000017500000000164011504175260027564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; namespace NUnit.Util { interface IRuntimeFrameworkSelector { /// /// Selects a target runtime framework for a TestPackage based on /// the settings in the package and the assemblies themselves. /// The package RuntimeFramework setting may be updated as a /// result and the selected runtime is returned. /// /// A TestPackage /// The selected RuntimeFramework RuntimeFramework SelectRuntimeFramework(TestPackage package); } } NUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/ITestRunnerFactory.cs0000664000175000017500000000241211504175260026221 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Core; namespace NUnit.Util { /// /// A Test Runner factory can supply a suitable test runner for a given package /// public interface ITestRunnerFactory { /// /// Return a suitable runner for the package provided as an argument /// /// The test package to be loaded by the runner /// A TestRunner TestRunner MakeTestRunner(TestPackage package); /// /// Return true if the provided runner is suitable for reuse in loading /// the test package provided. Otherwise, return false. /// /// /// /// True if the runner may be reused bool CanReuse(TestRunner runner, TestPackage package); } } NUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/ITestEvents.cs0000664000175000017500000000433611504175260024673 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Core; namespace NUnit.Util { /// /// ITestEvents interface defines events related to loading /// and unloading of test projects and loading, unloading and /// running tests. /// public interface ITestEvents { // Events related to the loading and unloading // of projects - including wrapper projects // created in order to load assemblies. This // occurs separately from the loading of tests // for the assemblies in the project. event TestEventHandler ProjectLoading; event TestEventHandler ProjectLoaded; event TestEventHandler ProjectLoadFailed; event TestEventHandler ProjectUnloading; event TestEventHandler ProjectUnloaded; event TestEventHandler ProjectUnloadFailed; // Events related to loading and unloading tests. event TestEventHandler TestLoading; event TestEventHandler TestLoaded; event TestEventHandler TestLoadFailed; event TestEventHandler TestReloading; event TestEventHandler TestReloaded; event TestEventHandler TestReloadFailed; event TestEventHandler TestUnloading; event TestEventHandler TestUnloaded; event TestEventHandler TestUnloadFailed; // Events related to a running a set of tests event TestEventHandler RunStarting; event TestEventHandler RunFinished; // Events that arise while a test is running // These are translated from calls to the runner on the // EventListener interface. event TestEventHandler SuiteStarting; event TestEventHandler SuiteFinished; event TestEventHandler TestStarting; event TestEventHandler TestFinished; /// /// An unhandled exception was thrown during a test run, /// and it cannot be associated with a particular test failure. /// event TestEventHandler TestException; /// /// Console Out/Error /// event TestEventHandler TestOutput; } } NUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/ITestLoader.cs0000664000175000017500000000360611703026606024634 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core; namespace NUnit.Util { /// /// The ITestLoader interface supports the loading and running /// of tests in a remote domain. /// public interface ITestLoader { #region Properties // See if a project is loaded bool IsProjectLoaded { get; } // See if a test has been loaded from the project bool IsTestLoaded { get; } // See if a test is running bool Running { get; } // The loaded test project NUnitProject TestProject { get; } string TestFileName { get; } // Our last test results TestResult TestResult { get; } #endregion #region Methods // Create a new empty project using a default name void NewProject(); // Create a new project given a filename void NewProject( string filename ); // Load a project given a filename void LoadProject( string filename ); // Load a project given a filename and config void LoadProject( string filename, string configname ); // Load a project given an array of assemblies void LoadProject( string[] assemblies ); // Unload current project void UnloadProject(); // Load tests for current project and config void LoadTest(); // Load a specific test for current project and config void LoadTest( string testName ); // Unload current test void UnloadTest(); // Reload current test void ReloadTest(); // Run the tests void RunTests( ITestFilter filter ); // Cancel the running test void CancelTestRun(); #endregion } }NUnit-2.6.0.12051/src/ClientUtilities/util/Interfaces/ISettings.cs0000664000175000017500000001115611504175260024365 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { public delegate void SettingsEventHandler( object sender, SettingsEventArgs args ); public class SettingsEventArgs : EventArgs { private string settingName; public SettingsEventArgs( string settingName ) { this.settingName = settingName; } public string SettingName { get { return settingName; } } } /// /// The ISettings interface is used to access all user /// settings and options. /// public interface ISettings { event SettingsEventHandler Changed; /// /// Load a setting from the storage. /// /// Name of the setting to load /// Value of the setting or null object GetSetting( string settingName ); /// /// Load a setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value object GetSetting( string settingName, object defaultValue ); /// /// Load an integer setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value int GetSetting(string settingName, int defaultValue); /// /// Load a float setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value float GetSetting(string settingName, float defaultValue); /// /// Load a boolean setting or return a default value /// /// Name of setting to load /// Value to return if the setting is missing /// Value of the setting or the default value bool GetSetting( string settingName, bool defaultValue ); /// /// Load a string setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value string GetSetting( string settingName, string defaultValue ); /// /// Load an enum setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value System.Enum GetSetting(string settingName, System.Enum defaultValue); /// /// Load a Font setting from the storage or return a default value /// /// Name of the setting to load /// Value to return if the setting is missing /// Value of the setting or the default value System.Drawing.Font GetSetting(string settingName, System.Drawing.Font defaultFont); /// /// Remove a setting from the storage /// /// Name of the setting to remove void RemoveSetting( string settingName ); /// /// Remove an entire group of settings from the storage /// /// Name of the group to remove void RemoveGroup( string groupName ); /// /// Save a setting in the storage /// /// Name of the setting to save /// Value to be saved void SaveSetting( string settingName, object settingValue ); } } NUnit-2.6.0.12051/src/ClientUtilities/util/XmlResultTransform.cs0000664000175000017500000000331711544454420024226 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; using System.Xml.Xsl; using System.Xml.XPath; namespace NUnit.Util { /// /// Summary description for XmlResultTransform. /// public class XmlResultTransform { #if CLR_2_0 || CLR_4_0 private XslCompiledTransform xslTransform = new XslCompiledTransform(); #else private XslTransform xslTransform = new XslTransform(); #endif public XmlResultTransform() { } public XmlResultTransform( string stylesheet ) { Load( stylesheet ); } public XmlResultTransform( XmlReader reader ) { Load( reader ); } public void Load( string stylesheet ) { xslTransform.Load( stylesheet ); } public void Load( XmlReader reader ) { // NOTE: Not compatable with .NET 1.0. // xslTransform.Load(reader, null, null); xslTransform.Load(reader); } public void Transform( string inputFile, string outputFile ) { Transform( new StreamReader( inputFile ), new StreamWriter( outputFile ) ); } public void Transform( TextReader reader, TextWriter writer ) { Transform( new XPathDocument( reader ), writer ); } public void Transform( IXPathNavigable xpnav, TextWriter writer ) { // NOTE: Not compatable with .NET 1.0. // xslTransform.Transform(xpnav, null, writer, null); xslTransform.Transform(xpnav, null, writer); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/RecentFileEntry.cs0000664000175000017500000000313011504175260023424 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { public class RecentFileEntry { public static readonly char Separator = ','; private string path; private Version clrVersion; public RecentFileEntry( string path ) { this.path = path; this.clrVersion = Environment.Version; } public RecentFileEntry( string path, Version clrVersion ) { this.path = path; this.clrVersion = clrVersion; } public string Path { get { return path; } } public Version CLRVersion { get { return clrVersion; } } public bool Exists { get { return path != null && System.IO.File.Exists( path ); } } public bool IsCompatibleCLRVersion { get { return clrVersion.Major <= Environment.Version.Major; } } public override string ToString() { return Path + Separator + CLRVersion.ToString(); } public static RecentFileEntry Parse( string text ) { int sepIndex = text.LastIndexOf( Separator ); if ( sepIndex > 0 ) try { return new RecentFileEntry( text.Substring( 0, sepIndex ), new Version( text.Substring( sepIndex + 1 ) ) ); } catch { //The last part was not a version, so fall through and return the whole text } return new RecentFileEntry( text ); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/FileWatcher.cs0000664000175000017500000000422111544330406022560 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Timers; namespace NUnit.Util { public delegate void FileChangedHandler(string filePath); public interface IWatcher { int Delay { get; set; } void Start(); void Stop(); event FileChangedHandler Changed; } public class FileWatcher : IDisposable { private string filePath; private FileSystemWatcher watcher; private Timer timer; public FileWatcher(string filePath, int delay) { this.filePath = filePath; this.watcher = new FileSystemWatcher(); watcher.Path = Path.GetDirectoryName(filePath); watcher.Filter = Path.GetFileName(filePath); watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite; watcher.EnableRaisingEvents = false; watcher.Changed += new FileSystemEventHandler(OnChange); timer = new Timer(delay); timer.AutoReset = false; timer.Enabled = false; timer.Elapsed += new ElapsedEventHandler(OnTimer); } public void Dispose() { watcher.Dispose(); } public void Start() { watcher.EnableRaisingEvents = true; } public void Stop() { watcher.EnableRaisingEvents = false; } private void OnChange(object sender, FileSystemEventArgs e) { if (!timer.Enabled) timer.Enabled = true; timer.Start(); } private void OnTimer(object sender, ElapsedEventArgs e) { timer.Enabled = false; if (Changed != null) Changed(filePath); } public event FileChangedHandler Changed; } } NUnit-2.6.0.12051/src/ClientUtilities/util/ConsoleWriter.cs0000664000175000017500000000253511504175260023171 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util { using System; using System.IO; using System.Text; /// /// Class used for receiving console output from the running test and displaying it. /// public class ConsoleWriter : TextWriter { #region Private Fields private TextWriter console; #endregion #region Constructors public ConsoleWriter(TextWriter console) { this.console = console; } #endregion #region TextWriter Overrides public override void Close() { //console.Close (); } public override void Flush() { console.Flush (); } public override void Write(char c) { console.Write(c); } public override void Write(String s) { console.Write(s); } public override void WriteLine(string s) { console.WriteLine(s); } public override Encoding Encoding { get { return Encoding.Default; } } public override Object InitializeLifetimeService() { return null; } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestObserver.cs0000664000175000017500000000117111504175260023014 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { /// /// The TestObserver interface is implemented by a class that /// subscribes to the events generated in loading and running /// tests and uses that information in some way. /// public interface TestObserver { void Subscribe( ITestEvents events ); } } NUnit-2.6.0.12051/src/ClientUtilities/util/CommandLineOptions.cs0000664000175000017500000001740511504175260024136 0ustar jtaylorjtaylor// File: CommandLineOptions.cs // // This is a re-usable component to be used when you // need to parse command-line options/parameters. // // Separates command line parameters from command line options. // Uses reflection to populate member variables the derived class with the values // of the options. // // An option can start with "-" or "--". On Windows systems, it can start with "/" as well. // // I define 3 types of "options": // 1. Boolean options (yes/no values), e.g: /r to recurse // 2. Value options, e.g: /loglevel=3 // 2. Parameters: standalone strings like file names // // An example to explain: // csc /nologo /t:exe myfile.cs // | | | // | | + parameter // | | // | + value option // | // + boolean option // // Please see a short description of the CommandLineOptions class // at http://codeblast.com/~gert/dotnet/sells.html // // Gert Lombard (gert@codeblast.com) // James Newkirk (jim@nunit.org) namespace Codeblast { using System; using System.Reflection; using System.Collections; using System.Text; // // The Attributes // [AttributeUsage(AttributeTargets.Field)] public class OptionAttribute : Attribute { protected object optValue; protected string optName; protected string description; public string Short { get { return optName; } set { optName = value; } } public object Value { get { return optValue; } set { optValue = value; } } public string Description { get { return description; } set { description = value; } } } // // The CommandLineOptions members // public abstract class CommandLineOptions { protected ArrayList parameters; protected bool isInvalid = false; private int optionCount; private ArrayList invalidArguments = new ArrayList(); private bool allowForwardSlash; public CommandLineOptions( string[] args ) : this( System.IO.Path.DirectorySeparatorChar != '/', args ) {} public CommandLineOptions( bool allowForwardSlash, string[] args ) { this.allowForwardSlash = allowForwardSlash; optionCount = Init( args ); } public IList InvalidArguments { get { return invalidArguments; } } public bool NoArgs { get { return ParameterCount == 0 && optionCount == 0; } } public bool AllowForwardSlash { get { return allowForwardSlash; } } public int Init(params string[] args) { int count = 0; int n = 0; while (n < args.Length) { int pos = IsOption(args[n]); if (pos > 0) { // It's an option: if (GetOption(args, ref n, pos)) count++; else InvalidOption(args[Math.Min(n, args.Length-1)]); } else { if (parameters == null) parameters = new ArrayList(); parameters.Add(args[n]); if ( !IsValidParameter(args[n]) ) InvalidOption( args[n] ); } n++; } return count; } // An option starts with "/", "-" or "--": protected virtual int IsOption(string opt) { char[] c = null; if (opt.Length < 2) { return 0; } else if (opt.Length > 2) { c = opt.ToCharArray(0, 3); if (c[0] == '-' && c[1] == '-' && IsOptionNameChar(c[2])) return 2; } else { c = opt.ToCharArray(0, 2); } if ((c[0] == '-' || c[0] == '/' && AllowForwardSlash) && IsOptionNameChar(c[1])) return 1; return 0; } protected virtual bool IsOptionNameChar(char c) { return Char.IsLetterOrDigit(c) || c == '?'; } protected virtual void InvalidOption(string name) { invalidArguments.Add( name ); isInvalid = true; } protected virtual bool IsValidParameter(string param) { return true; } protected virtual bool MatchShortName(FieldInfo field, string name) { object[] atts = field.GetCustomAttributes(typeof(OptionAttribute), true); foreach (OptionAttribute att in atts) { if (string.Compare(att.Short, name, true) == 0) return true; } return false; } protected virtual FieldInfo GetMemberField(string name) { Type t = this.GetType(); FieldInfo[] fields = t.GetFields(BindingFlags.Instance|BindingFlags.Public); foreach (FieldInfo field in fields) { if (string.Compare(field.Name, name, true) == 0) return field; if (MatchShortName(field, name)) return field; } return null; } protected virtual object GetOptionValue(FieldInfo field) { object[] atts = field.GetCustomAttributes(typeof(OptionAttribute), true); if (atts.Length > 0) { OptionAttribute att = (OptionAttribute)atts[0]; return att.Value; } return null; } protected virtual bool GetOption(string[] args, ref int index, int pos) { try { object cmdLineVal = null; string opt = args[index].Substring(pos, args[index].Length-pos); SplitOptionAndValue(ref opt, ref cmdLineVal); FieldInfo field = GetMemberField(opt); if (field != null) { object value = GetOptionValue(field); if (value == null) { if (field.FieldType == typeof(bool)) value = true; // default for bool values is true else if(field.FieldType == typeof(string)) { value = cmdLineVal != null ? cmdLineVal : args[++index]; field.SetValue(this, Convert.ChangeType(value, field.FieldType)); string stringValue = (string)value; if(stringValue == null || stringValue.Length == 0) return false; return true; } else if(field.FieldType.IsEnum) value = Enum.Parse( field.FieldType, (string)cmdLineVal, true ); else value = cmdLineVal != null ? cmdLineVal : args[++index]; } field.SetValue(this, Convert.ChangeType(value, field.FieldType)); return true; } } catch (Exception) { // Ignore exceptions like type conversion errors. } return false; } protected virtual void SplitOptionAndValue(ref string opt, ref object val) { // Look for ":" or "=" separator in the option: int pos = opt.IndexOfAny( new char[] { ':', '=' } ); if (pos < 1) return; val = opt.Substring(pos+1); opt = opt.Substring(0, pos); } // Parameter accessor: public string this[int index] { get { if (parameters != null) return (string)parameters[index]; return null; } } public ArrayList Parameters { get { return parameters; } } public int ParameterCount { get { return parameters == null ? 0 : parameters.Count; } } public virtual void Help() { Console.WriteLine(GetHelpText()); } public virtual string GetHelpText() { StringBuilder helpText = new StringBuilder(); Type t = this.GetType(); FieldInfo[] fields = t.GetFields(BindingFlags.Instance|BindingFlags.Public); char optChar = allowForwardSlash ? '/' : '-'; foreach (FieldInfo field in fields) { object[] atts = field.GetCustomAttributes(typeof(OptionAttribute), true); if (atts.Length > 0) { OptionAttribute att = (OptionAttribute)atts[0]; if (att.Description != null) { string valType = ""; if (att.Value == null) { if (field.FieldType == typeof(float)) valType = "=FLOAT"; else if (field.FieldType == typeof(string)) valType = "=STR"; else if (field.FieldType != typeof(bool)) valType = "=X"; } helpText.AppendFormat("{0}{1,-20}\t{2}", optChar, field.Name+valType, att.Description); if (att.Short != null) helpText.AppendFormat(" (Short format: {0}{1}{2})", optChar, att.Short, valType); helpText.Append( Environment.NewLine ); } } } return helpText.ToString(); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/ResultSummarizer.cs0000664000175000017500000001161611504175260023727 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util { using System; using NUnit.Core; /// /// Summary description for ResultSummarizer. /// public class ResultSummarizer { private int resultCount = 0; private int testsRun = 0; private int failureCount = 0; private int errorCount = 0; private int successCount = 0; private int inconclusiveCount = 0; private int skipCount = 0; private int ignoreCount = 0; private int notRunnable = 0; private double time = 0.0d; private string name; public ResultSummarizer() { } public ResultSummarizer(TestResult result) { Summarize(result); } public ResultSummarizer(TestResult[] results) { foreach( TestResult result in results ) Summarize(result); } public void Summarize( TestResult result ) { if (this.name == null ) { this.name = result.Name; this.time = result.Time; } if (!result.Test.IsSuite) { resultCount++; switch (result.ResultState) { case ResultState.Success: successCount++; testsRun++; break; case ResultState.Failure: failureCount++; testsRun++; break; case ResultState.Error: case ResultState.Cancelled: errorCount++; testsRun++; break; case ResultState.Inconclusive: inconclusiveCount++; testsRun++; break; case ResultState.NotRunnable: notRunnable++; //errorCount++; break; case ResultState.Ignored: ignoreCount++; break; case ResultState.Skipped: default: skipCount++; break; } } if ( result.HasResults ) foreach (TestResult childResult in result.Results) Summarize( childResult ); } public string Name { get { return name; } } public bool Success { get { return failureCount == 0; } } /// /// Returns the number of test cases for which results /// have been summarized. Any tests excluded by use of /// Category or Explicit attributes are not counted. /// public int ResultCount { get { return resultCount; } } /// /// Returns the number of test cases actually run, which /// is the same as ResultCount, less any Skipped, Ignored /// or NonRunnable tests. /// public int TestsRun { get { return testsRun; } } /// /// Returns the number of tests that passed /// public int Passed { get { return successCount; } } /// /// Returns the number of test cases that had an error. /// public int Errors { get { return errorCount; } } /// /// Returns the number of test cases that failed. /// public int Failures { get { return failureCount; } } /// /// Returns the number of test cases that failed. /// public int Inconclusive { get { return inconclusiveCount; } } /// /// Returns the number of test cases that were not runnable /// due to errors in the signature of the class or method. /// Such tests are also counted as Errors. /// public int NotRunnable { get { return notRunnable; } } /// /// Returns the number of test cases that were skipped. /// public int Skipped { get { return skipCount; } } public int Ignored { get { return ignoreCount; } } public double Time { get { return time; } } public int TestsNotRun { get { return skipCount + ignoreCount + notRunnable; } } public int ErrorsAndFailures { get { return errorCount + failureCount; } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/ServerBase.cs0000664000175000017500000000542511504175260022434 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Runtime.Remoting; using System.Runtime.Remoting.Services; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Core; namespace NUnit.Util { /// /// Summary description for ServerBase. /// public abstract class ServerBase : MarshalByRefObject, IDisposable { protected string uri; protected int port; private TcpChannel channel; private bool isMarshalled; private object theLock = new object(); protected ServerBase() { } /// /// Constructor used to provide /// /// /// protected ServerBase(string uri, int port) { this.uri = uri; this.port = port; } public string ServerUrl { get { return string.Format("tcp://127.0.0.1:{0}/{1}", port, uri); } } public virtual void Start() { if (uri != null && uri != string.Empty) { lock (theLock) { this.channel = ServerUtilities.GetTcpChannel(uri + "Channel", port, 100); RemotingServices.Marshal(this, uri); this.isMarshalled = true; } if (this.port == 0) { ChannelDataStore store = this.channel.ChannelData as ChannelDataStore; if (store != null) { string channelUri = store.ChannelUris[0]; this.port = int.Parse(channelUri.Substring(channelUri.LastIndexOf(':') + 1)); } } } } [System.Runtime.Remoting.Messaging.OneWay] public virtual void Stop() { lock( theLock ) { if ( this.isMarshalled ) { RemotingServices.Disconnect( this ); this.isMarshalled = false; } if ( this.channel != null ) { ChannelServices.UnregisterChannel( this.channel ); this.channel = null; } Monitor.PulseAll( theLock ); } } public void WaitForStop() { lock( theLock ) { Monitor.Wait( theLock ); } } #region IDisposable Members public void Dispose() { this.Stop(); } #endregion #region InitializeLifetimeService public override object InitializeLifetimeService() { return null; } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/InProcessTestRunnerFactory.cs0000664000175000017500000000362311504175260025660 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; namespace NUnit.Util { /// /// InProcessTestRunnerFactory handles creation of a suitable test /// runner for a given package to be loaded and run within the /// same process. /// public class InProcessTestRunnerFactory : ITestRunnerFactory { #region ITestRunnerFactory Members /// /// Returns a test runner based on the settings in a TestPackage. /// Any setting that is "consumed" by the factory is removed, so /// that downstream runners using the factory will not repeatedly /// create the same type of runner. /// /// The TestPackage to be loaded and run /// A TestRunner public virtual TestRunner MakeTestRunner(TestPackage package) { DomainUsage domainUsage = (DomainUsage)package.GetSetting("DomainUsage", DomainUsage.Default); switch (domainUsage) { case DomainUsage.Multiple: package.Settings.Remove("DomainUsage"); return new MultipleTestDomainRunner(); case DomainUsage.None: return new RemoteTestRunner(); case DomainUsage.Single: default: return new TestDomain(); } } public virtual bool CanReuse(TestRunner runner, TestPackage package) { return false; } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestEventArgs.cs0000664000175000017500000001330711543055572023135 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using NUnit.Core; namespace NUnit.Util { #region TestEventHandler delegate /// /// The delegates for all events related to running tests /// public delegate void TestEventHandler ( object sender, TestEventArgs args ); #endregion #region TestAction enumeration /// /// Enumeration used to distiguish test events /// public enum TestAction { // Project Load Events ProjectLoading, ProjectLoaded, ProjectLoadFailed, ProjectUnloading, ProjectUnloaded, ProjectUnloadFailed, // Test Load Events TestLoading, TestLoaded, TestLoadFailed, TestReloading, TestReloaded, TestReloadFailed, TestUnloading, TestUnloaded, TestUnloadFailed, // Test Run Events RunStarting, RunFinished, SuiteStarting, SuiteFinished, TestStarting, TestFinished, TestException, TestOutput } #endregion /// /// Argument used for all test events /// public class TestEventArgs : EventArgs { #region Instance Variables // The action represented by the event private TestAction action; // The name of the test or other item private string name; // The name of the test we are running private ITest test; private TestName testName; // The results from our tests private TestResult testResult; // The exception causing a failure private Exception exception; // The test output private TestOutput testOutput; // The number of tests we are running private int testCount; #endregion #region Constructors // TestLoaded, TestReloaded public TestEventArgs( TestAction action, string name, ITest test ) { Debug.Assert( action == TestAction.TestLoaded || action == TestAction.TestReloaded, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.name = name; this.test = test; if ( test != null ) this.testCount = test.TestCount; } // ProjectLoading, ProjectLoaded, ProjectUnloading, ProjectUnloaded, // TestLoading, TestUnloading, TestUnloaded, TestReloading public TestEventArgs( TestAction action, string name ) { Debug.Assert( action == TestAction.ProjectLoading || action == TestAction.ProjectLoaded || action == TestAction.ProjectUnloading || action == TestAction.ProjectUnloaded || action == TestAction.TestLoading || action == TestAction.TestUnloading || action == TestAction.TestUnloaded || action == TestAction.TestReloading, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.name = name; } public TestEventArgs( TestAction action, string name, int testCount ) { Debug.Assert( action == TestAction.RunStarting, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.name = name; this.testCount = testCount; } // ProjectLoadFailed, ProjectUnloadFailed, TestLoadFailed, TestUnloadFailed, TestReloadFailed, TestException public TestEventArgs( TestAction action, string name, Exception exception ) { Debug.Assert( action == TestAction.ProjectLoadFailed || action == TestAction.ProjectUnloadFailed || action == TestAction.TestLoadFailed || action == TestAction.TestUnloadFailed || action == TestAction.TestReloadFailed || action == TestAction.TestException, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.name = name; this.exception = exception; } // TestStarting, SuiteStarting public TestEventArgs( TestAction action, TestName testName ) { Debug.Assert( action == TestAction.TestStarting || action == TestAction.SuiteStarting, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.testName = testName; } // TestFinished, SuiteFinished, RunFinished public TestEventArgs( TestAction action, TestResult testResult ) { Debug.Assert( action == TestAction.TestFinished || action == TestAction.SuiteFinished || action == TestAction.RunFinished, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.testResult = testResult; } // RunFinished public TestEventArgs( TestAction action, Exception exception ) { Debug.Assert( action == TestAction.RunFinished, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.exception = exception; } // TestOutput public TestEventArgs( TestAction action, TestOutput testOutput ) { Debug.Assert( action == TestAction.TestOutput, "Invalid TestAction argument to TestEventArgs constructor" ); this.action = action; this.testOutput = testOutput; } #endregion #region Properties public TestAction Action { get { return action; } } public string Name { get { return name; } } public ITest Test { get { return test; } } public TestName TestName { get { return testName; } } public int TestCount { get { return testCount; } } public TestResult Result { get { return testResult; } } public Exception Exception { get { return exception; } } public TestOutput TestOutput { get { return testOutput; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/nunit.util.dll.csproj0000664000175000017500000001645211717154346024163 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {61CE9CE5-943E-44D4-A381-814DC1406767} Debug AnyCPU nunit.util JScript Grid IE50 false Library NUnit.Util OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;NET_2_0;CLR_2_0 true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;NET_2_0;CLR_2_0 4096 1699 true false false 4 none prompt System System.Data System.Drawing System.Runtime.Remoting System.XML nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False CommonAssemblyInfo.cs Designer NUnit-2.6.0.12051/src/ClientUtilities/util/AssemblyInfo.cs0000664000175000017500000000072211504175260022761 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/ClientUtilities/util/TestLoader.cs0000664000175000017500000005752511717427410022454 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Util { using System; using System.IO; using System.Collections; using System.Diagnostics; using System.Threading; using System.Configuration; using NUnit.Core; using NUnit.Core.Filters; /// /// TestLoader handles interactions between a test runner and a /// client program - typically the user interface - for the /// purpose of loading, unloading and running tests. /// /// It implemements the EventListener interface which is used by /// the test runner and repackages those events, along with /// others as individual events that clients may subscribe to /// in collaboration with a TestEventDispatcher helper object. /// /// TestLoader is quite handy for use with a gui client because /// of the large number of events it supports. However, it has /// no dependencies on ui components and can be used independently. /// public class TestLoader : MarshalByRefObject, NUnit.Core.EventListener, ITestLoader, IService { static Logger log = InternalTrace.GetLogger(typeof(TestLoader)); #region Instance Variables /// /// Our event dispatching helper object /// private TestEventDispatcher events; /// /// Our TestRunnerFactory /// private ITestRunnerFactory factory; /// /// Loads and executes tests. Non-null when /// we have loaded a test. /// private TestRunner testRunner = null; /// /// Our current test project, if we have one. /// private NUnitProject testProject = null; /// /// The currently loaded test, returned by the testrunner /// //private ITest loadedTest = null; /// /// The test name that was specified when loading /// private string loadedTestName = null; /// /// The currently executing test /// private string currentTestName; /// /// The currently set runtime framework /// private RuntimeFramework currentRuntime; /// /// Result of the last test run /// private TestResult testResult = null; /// /// The last exception received when trying to load, unload or run a test /// private Exception lastException = null; /// /// Watcher fires when the assembly changes /// private IAssemblyWatcher watcher; /// /// Assembly changed during a test and /// needs to be reloaded later /// private bool reloadPending = false; /// /// Trace setting to use for running tests /// private bool tracing; /// /// LoggingThreshold to use for running tests /// private LoggingThreshold logLevel; /// /// The last filter used for a run - used to /// rerun tests when a change occurs /// private ITestFilter lastFilter; /// /// The last trace setting used for a run /// private bool lastTracing; /// /// Last logging level used for a run /// private LoggingThreshold lastLogLevel; /// /// The runtime framework being used for the currently /// loaded tests, or the current framework if no tests /// are loaded. /// private RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; #endregion #region Constructors public TestLoader() : this( new TestEventDispatcher() ) { } public TestLoader(TestEventDispatcher eventDispatcher) : this(eventDispatcher, new AssemblyWatcher()) { } public TestLoader(IAssemblyWatcher assemblyWatcher) : this(new TestEventDispatcher(), assemblyWatcher) { } public TestLoader(TestEventDispatcher eventDispatcher, IAssemblyWatcher assemblyWatcher) { this.events = eventDispatcher; this.watcher = assemblyWatcher; this.factory = new DefaultTestRunnerFactory(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); } #endregion #region Properties public bool IsProjectLoaded { get { return testProject != null; } } public bool IsTestLoaded { get { return testRunner != null && testRunner.Test != null; } } public ITest LoadedTest { get { return testRunner == null ? null : testRunner.Test; } } public bool Running { get { return testRunner != null && testRunner.Running; } } public NUnitProject TestProject { get { return testProject; } } public ITestEvents Events { get { return events; } } public string TestFileName { get { return testProject.ProjectPath; } } public TestResult TestResult { get { return testResult; } } public Exception LastException { get { return lastException; } } public IList AssemblyInfo { get { return testRunner == null ? new TestAssemblyInfo[0] : testRunner.AssemblyInfo; } } public int TestCount { get { return LoadedTest == null ? 0 : LoadedTest.TestCount; } } public RuntimeFramework CurrentFramework { get { return currentFramework; } } public bool IsTracingEnabled { get { return tracing; } set { tracing = value; } } public LoggingThreshold LoggingThreshold { get { return logLevel; } set { logLevel = value; } } #endregion #region EventListener Handlers public void RunStarted(string name, int testCount) { log.Debug("Got RunStarted Event"); events.FireRunStarting( name, testCount ); } public void RunFinished(NUnit.Core.TestResult testResult) { this.testResult = testResult; events.FireRunFinished(testResult); } public void RunFinished(Exception exception) { this.lastException = exception; events.FireRunFinished( exception ); } /// /// Trigger event when each test starts /// /// TestName of the Test that is starting public void TestStarted(TestName testName) { this.currentTestName = testName.FullName; events.FireTestStarting( testName ); } /// /// Trigger event when each test finishes /// /// Result of the case that finished public void TestFinished(TestResult result) { events.FireTestFinished( result ); } /// /// Trigger event when each suite starts /// /// Suite that is starting public void SuiteStarted(TestName suiteName) { events.FireSuiteStarting( suiteName ); } /// /// Trigger event when each suite finishes /// /// Result of the suite that finished public void SuiteFinished(TestResult result) { events.FireSuiteFinished( result ); } /// /// Trigger event when an unhandled exception (other than ThreadAbordException) occurs during a test /// /// The unhandled exception public void UnhandledException(Exception exception) { events.FireTestException( this.currentTestName, exception ); } void OnUnhandledException( object sender, UnhandledExceptionEventArgs args ) { switch( args.ExceptionObject.GetType().FullName ) { case "System.Threading.ThreadAbortException": break; case "NUnit.Framework.AssertionException": default: Exception ex = args.ExceptionObject as Exception; events.FireTestException( this.currentTestName, ex); break; } } /// /// Trigger event when output occurs during a test /// /// The test output public void TestOutput(TestOutput testOutput) { events.FireTestOutput( testOutput ); } #endregion #region Methods for Loading and Unloading Projects /// /// Create a new project with default naming /// public void NewProject() { log.Info("Creating empty project"); try { events.FireProjectLoading( "New Project" ); OnProjectLoad( Services.ProjectService.NewProject() ); } catch( Exception exception ) { log.Error("Project creation failed", exception); lastException = exception; events.FireProjectLoadFailed( "New Project", exception ); } } /// /// Create a new project using a given path /// public void NewProject( string filePath ) { log.Info("Creating project " + filePath); try { events.FireProjectLoading( filePath ); NUnitProject project = new NUnitProject( filePath ); project.Configs.Add( "Debug" ); project.Configs.Add( "Release" ); project.IsDirty = false; OnProjectLoad( project ); } catch( Exception exception ) { log.Error("Project creation failed", exception); lastException = exception; events.FireProjectLoadFailed( filePath, exception ); } } /// /// Load a new project, optionally selecting the config and fire events /// public void LoadProject( string filePath, string configName ) { try { log.Info("Loading project {0}, {1} config", filePath, configName == null ? "default" : configName); events.FireProjectLoading(filePath); NUnitProject newProject = Services.ProjectService.LoadProject( filePath ); if ( configName != null ) { newProject.SetActiveConfig( configName ); newProject.IsDirty = false; } OnProjectLoad( newProject ); } catch( Exception exception ) { log.Error("Project load failed", exception); lastException = exception; events.FireProjectLoadFailed( filePath, exception ); } } /// /// Load a new project using the default config and fire events /// public void LoadProject( string filePath ) { LoadProject( filePath, null ); } /// /// Load a project from a list of assemblies and fire events /// public void LoadProject( string[] assemblies ) { try { log.Info("Loading multiple assemblies as new project"); events.FireProjectLoading( "New Project" ); NUnitProject newProject = Services.ProjectService.WrapAssemblies( assemblies ); OnProjectLoad( newProject ); } catch( Exception exception ) { log.Error("Project load failed", exception); lastException = exception; events.FireProjectLoadFailed( "New Project", exception ); } } /// /// Unload the current project and fire events /// public void UnloadProject() { string testFileName = TestFileName; log.Info("Unloading project " + testFileName); try { events.FireProjectUnloading( testFileName ); if ( IsTestLoaded ) UnloadTest(); testProject = null; events.FireProjectUnloaded( testFileName ); } catch (Exception exception ) { log.Error("Project unload failed", exception); lastException = exception; events.FireProjectUnloadFailed( testFileName, exception ); } } /// /// Common operations done each time a project is loaded /// /// The newly loaded project private void OnProjectLoad( NUnitProject testProject ) { if ( IsProjectLoaded ) UnloadProject(); this.testProject = testProject; events.FireProjectLoaded( TestFileName ); } #endregion #region Methods for Loading and Unloading Tests public void LoadTest() { LoadTest( null ); } public void LoadTest( string testName ) { log.Info("Loading tests for " + Path.GetFileName(TestFileName)); long startTime = DateTime.Now.Ticks; try { events.FireTestLoading( TestFileName ); TestPackage package = MakeTestPackage(testName); if (testRunner != null) testRunner.Dispose(); testRunner = factory.MakeTestRunner(package); bool loaded = testRunner.Load(package); loadedTestName = testName; testResult = null; reloadPending = false; if ( Services.UserSettings.GetSetting( "Options.TestLoader.ReloadOnChange", true ) ) InstallWatcher( ); if (loaded) { this.currentFramework = package.Settings.Contains("RuntimeFramework") ? package.Settings["RuntimeFramework"] as RuntimeFramework : RuntimeFramework.CurrentFramework; testProject.HasChangesRequiringReload = false; events.FireTestLoaded(TestFileName, LoadedTest); } else { lastException = new ApplicationException(string.Format("Unable to find test {0} in assembly", testName)); events.FireTestLoadFailed(TestFileName, lastException); } } catch( FileNotFoundException exception ) { log.Error("File not found", exception); lastException = exception; foreach( string assembly in TestProject.ActiveConfig.Assemblies ) { if ( Path.GetFileNameWithoutExtension( assembly ) == exception.FileName && !PathUtils.SamePathOrUnder( testProject.ActiveConfig.BasePath, assembly ) ) { lastException = new ApplicationException( string.Format( "Unable to load {0} because it is not located under the AppBase", exception.FileName ), exception ); break; } } events.FireTestLoadFailed( TestFileName, lastException ); double loadTime = (double)(DateTime.Now.Ticks - startTime) / (double)TimeSpan.TicksPerSecond; log.Info("Load completed in {0} seconds", loadTime); } catch( Exception exception ) { log.Error("Failed to load test", exception); lastException = exception; events.FireTestLoadFailed( TestFileName, exception ); } } /// /// Unload the current test suite and fire the Unloaded event /// public void UnloadTest( ) { if( IsTestLoaded ) { log.Info("Unloading tests for " + Path.GetFileName(TestFileName)); // Hold the name for notifications after unload string fileName = TestFileName; try { events.FireTestUnloading( fileName ); RemoveWatcher(); testRunner.Unload(); testRunner.Dispose(); testRunner = null; loadedTestName = null; testResult = null; reloadPending = false; events.FireTestUnloaded( fileName ); log.Info("Unload complete"); } catch( Exception exception ) { log.Error("Failed to unload tests", exception); lastException = exception; events.FireTestUnloadFailed( fileName, exception ); } } } /// /// Return true if the current project can be reloaded under /// the specified CLR version. /// public bool CanReloadUnderRuntimeVersion(Version version) { if (!Services.TestAgency.IsRuntimeVersionSupported(version)) return false; if (AssemblyInfo.Count == 0) return false; foreach (TestAssemblyInfo info in AssemblyInfo) if (info == null || info.ImageRuntimeVersion > version) return false; return true; } /// /// Reload the current test on command /// public void ReloadTest(RuntimeFramework framework) { log.Info("Reloading tests for " + Path.GetFileName(TestFileName)); try { events.FireTestReloading( TestFileName ); TestPackage package = MakeTestPackage(loadedTestName); if (framework != null) package.Settings["RuntimeFramework"] = framework; RemoveWatcher(); testRunner.Unload(); if (!factory.CanReuse(testRunner, package)) { testRunner.Dispose(); testRunner = factory.MakeTestRunner(package); } if (testRunner.Load(package)) this.currentFramework = package.Settings.Contains("RuntimeFramework") ? package.Settings["RuntimeFramework"] as RuntimeFramework : RuntimeFramework.CurrentFramework; currentRuntime = framework; reloadPending = false; if (Services.UserSettings.GetSetting("Options.TestLoader.ReloadOnChange", true)) InstallWatcher(); testProject.HasChangesRequiringReload = false; events.FireTestReloaded(TestFileName, LoadedTest); log.Info("Reload complete"); } catch( Exception exception ) { log.Error("Reload failed", exception); lastException = exception; events.FireTestReloadFailed( TestFileName, exception ); } } public void ReloadTest() { ReloadTest(currentRuntime); } /// /// Handle watcher event that signals when the loaded assembly /// file has changed. Make sure it's a real change before /// firing the SuiteChangedEvent. Since this all happens /// asynchronously, we use an event to let ui components /// know that the failure happened. /// public void OnTestChanged( string testFileName ) { log.Info("Assembly changed: {0}", testFileName); if ( Running ) reloadPending = true; else { ReloadTest(); if (lastFilter != null && Services.UserSettings.GetSetting("Options.TestLoader.RerunOnChange", false)) testRunner.BeginRun( this, lastFilter, lastTracing, lastLogLevel ); } } #endregion #region Methods for Running Tests /// /// Run selected tests using a filter /// /// The filter to be used public void RunTests( ITestFilter filter ) { if ( !Running && LoadedTest != null) { if (reloadPending || Services.UserSettings.GetSetting("Options.TestLoader.ReloadOnRun", false)) ReloadTest(); // Save args for automatic rerun this.lastFilter = filter; this.lastTracing = tracing; this.lastLogLevel = logLevel; testRunner.BeginRun(this, filter, tracing, logLevel); } } /// /// Cancel the currently running test. /// Fail silently if there is none to /// allow for latency in the UI. /// public void CancelTestRun() { if ( Running ) testRunner.CancelRun(); } public IList GetCategories() { CategoryManager categoryManager = new CategoryManager(); categoryManager.AddAllCategories( this.LoadedTest ); ArrayList list = new ArrayList( categoryManager.Categories ); list.Sort(); return list; } public void SaveLastResult( string fileName ) { new XmlResultWriter( fileName ).SaveTestResult(this.testResult); } #endregion #region Helper Methods /// /// Install our watcher object so as to get notifications /// about changes to a test. /// private void InstallWatcher() { if (watcher != null) { watcher.Stop(); watcher.FreeResources(); watcher.Setup(1000, TestProject.ActiveConfig.Assemblies.ToArray()); watcher.AssemblyChanged += new AssemblyChangedHandler(OnTestChanged); watcher.Start(); } } /// /// Stop and remove our current watcher object. /// private void RemoveWatcher() { if (watcher != null) { watcher.Stop(); watcher.FreeResources(); watcher.AssemblyChanged -= new AssemblyChangedHandler(OnTestChanged); } } private TestPackage MakeTestPackage( string testName ) { TestPackage package = TestProject.ActiveConfig.MakeTestPackage(); package.TestName = testName; ISettings userSettings = Services.UserSettings; package.Settings["MergeAssemblies"] = userSettings.GetSetting("Options.TestLoader.MergeAssemblies", false); package.Settings["AutoNamespaceSuites"] = userSettings.GetSetting("Options.TestLoader.AutoNamespaceSuites", true); package.Settings["ShadowCopyFiles"] = userSettings.GetSetting("Options.TestLoader.ShadowCopyFiles", true); ProcessModel processModel = (ProcessModel)userSettings.GetSetting("Options.TestLoader.ProcessModel", ProcessModel.Default); DomainUsage domainUsage = (DomainUsage)userSettings.GetSetting("Options.TestLoader.DomainUsage", DomainUsage.Default); if (processModel != ProcessModel.Default && // Ignore default setting !package.Settings.Contains("ProcessModel")) // Ignore global setting if package has a setting { package.Settings["ProcessModel"] = processModel; } // NOTE: This code ignores DomainUsage.None because TestLoader // is only called from the GUI and the GUI can't support that setting. // TODO: Move this logic to the GUI if TestLoader is used more widely if (domainUsage != DomainUsage.Default && // Ignore default setting domainUsage != DomainUsage.None && // Ignore DomainUsage.None in Gui (processModel != ProcessModel.Multiple || domainUsage != DomainUsage.Multiple) && // Both process and domain may not be multiple !package.Settings.Contains("DomainUsage")) // Ignore global setting if package has a setting { package.Settings["DomainUsage"] = domainUsage; } if (!package.Settings.Contains("WorkDirectory")) package.Settings["WorkDirectory"] = Environment.CurrentDirectory; //if (NUnitConfiguration.ApartmentState != System.Threading.ApartmentState.Unknown) // package.Settings["ApartmentState"] = NUnitConfiguration.ApartmentState; return package; } #endregion #region InitializeLifetimeService Override public override object InitializeLifetimeService() { return null; } #endregion #region IService Members public void UnloadService() { // TODO: Add TestLoader.UnloadService implementation } public void InitializeService() { // TODO: Add TestLoader.InitializeService implementation } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/AssemblyList.cs0000664000175000017500000000430611650730114023000 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; namespace NUnit.Util { /// /// Represents a list of assemblies. It stores paths /// that are added and fires an event whenevever it /// changes. All paths must be added as absolute paths. /// public class AssemblyList : CollectionBase { #region Properties and Events public string this[int index] { get { return (string)List[index]; } set { if ( !Path.IsPathRooted( value ) ) throw new ArgumentException( "Assembly path must be absolute" ); List[index] = value; } } public event EventHandler Changed; #endregion #region Methods public string[] ToArray() { return (string[])InnerList.ToArray( typeof( string ) ); } public void Add( string assemblyPath ) { if ( !Path.IsPathRooted( assemblyPath ) ) throw new ArgumentException( "Assembly path must be absolute" ); List.Add( assemblyPath ); } public void Remove( string assemblyPath ) { for( int index = 0; index < this.Count; index++ ) { if ( this[index] == assemblyPath ) RemoveAt( index ); } } public bool Contains(string assemblyPath) { for (int index = 0; index < this.Count; index++) { if (this[index] == assemblyPath) return true; } return false; } protected override void OnRemoveComplete(int index, object value) { FireChangedEvent(); } protected override void OnInsertComplete(int index, object value) { FireChangedEvent(); } protected override void OnSetComplete(int index, object oldValue, object newValue) { FireChangedEvent(); } private void FireChangedEvent() { if ( Changed != null ) Changed( this, EventArgs.Empty ); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/XmlResultWriter.cs0000664000175000017500000002662511504175260023534 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util { using System; using System.Globalization; using System.IO; using System.Xml; using System.Collections; using System.Reflection; using NUnit.Core; /// /// Summary description for XmlResultWriter. /// public class XmlResultWriter { private XmlTextWriter xmlWriter; private TextWriter writer; private MemoryStream memoryStream; #region Constructors public XmlResultWriter(string fileName) { xmlWriter = new XmlTextWriter( new StreamWriter(fileName, false, System.Text.Encoding.UTF8) ); } public XmlResultWriter( TextWriter writer ) { this.memoryStream = new MemoryStream(); this.writer = writer; this.xmlWriter = new XmlTextWriter( new StreamWriter( memoryStream, System.Text.Encoding.UTF8 ) ); } #endregion private void InitializeXmlFile(TestResult result) { ResultSummarizer summaryResults = new ResultSummarizer(result); xmlWriter.Formatting = Formatting.Indented; xmlWriter.WriteStartDocument(false); xmlWriter.WriteComment("This file represents the results of running a test suite"); xmlWriter.WriteStartElement("test-results"); xmlWriter.WriteAttributeString("name", summaryResults.Name); xmlWriter.WriteAttributeString("total", summaryResults.TestsRun.ToString()); xmlWriter.WriteAttributeString("errors", summaryResults.Errors.ToString()); xmlWriter.WriteAttributeString("failures", summaryResults.Failures.ToString()); xmlWriter.WriteAttributeString("not-run", summaryResults.TestsNotRun.ToString()); xmlWriter.WriteAttributeString("inconclusive", summaryResults.Inconclusive.ToString()); xmlWriter.WriteAttributeString("ignored", summaryResults.Ignored.ToString()); xmlWriter.WriteAttributeString("skipped", summaryResults.Skipped.ToString()); xmlWriter.WriteAttributeString("invalid", summaryResults.NotRunnable.ToString()); DateTime now = DateTime.Now; xmlWriter.WriteAttributeString("date", XmlConvert.ToString( now, "yyyy-MM-dd" ) ); xmlWriter.WriteAttributeString("time", XmlConvert.ToString( now, "HH:mm:ss" )); WriteEnvironment(); WriteCultureInfo(); } private void WriteCultureInfo() { xmlWriter.WriteStartElement("culture-info"); xmlWriter.WriteAttributeString("current-culture", CultureInfo.CurrentCulture.ToString()); xmlWriter.WriteAttributeString("current-uiculture", CultureInfo.CurrentUICulture.ToString()); xmlWriter.WriteEndElement(); } private void WriteEnvironment() { xmlWriter.WriteStartElement("environment"); xmlWriter.WriteAttributeString("nunit-version", Assembly.GetExecutingAssembly().GetName().Version.ToString()); xmlWriter.WriteAttributeString("clr-version", Environment.Version.ToString()); xmlWriter.WriteAttributeString("os-version", Environment.OSVersion.ToString()); xmlWriter.WriteAttributeString("platform", Environment.OSVersion.Platform.ToString()); xmlWriter.WriteAttributeString("cwd", Environment.CurrentDirectory); xmlWriter.WriteAttributeString("machine-name", Environment.MachineName); xmlWriter.WriteAttributeString("user", Environment.UserName); xmlWriter.WriteAttributeString("user-domain", Environment.UserDomainName); xmlWriter.WriteEndElement(); } #region Public Methods public void SaveTestResult( TestResult result ) { InitializeXmlFile( result ); WriteResultElement( result ); TerminateXmlFile(); } private void WriteResultElement( TestResult result ) { StartTestElement( result ); WriteCategoriesElement(result); WritePropertiesElement(result); switch (result.ResultState) { case ResultState.Ignored: case ResultState.NotRunnable: case ResultState.Skipped: WriteReasonElement(result); break; case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: if (!result.Test.IsSuite || result.FailureSite == FailureSite.SetUp) WriteFailureElement(result); break; case ResultState.Success: case ResultState.Inconclusive: if (result.Message != null) WriteReasonElement(result); break; } if ( result.HasResults ) WriteChildResults( result ); xmlWriter.WriteEndElement(); // test element } private void TerminateXmlFile() { try { xmlWriter.WriteEndElement(); // test-results xmlWriter.WriteEndDocument(); xmlWriter.Flush(); if ( memoryStream != null && writer != null ) { memoryStream.Position = 0; using ( StreamReader rdr = new StreamReader( memoryStream ) ) { writer.Write( rdr.ReadToEnd() ); } } xmlWriter.Close(); } finally { //writer.Close(); } } #endregion #region Element Creation Helpers private void StartTestElement(TestResult result) { if (result.Test.IsSuite) { xmlWriter.WriteStartElement("test-suite"); xmlWriter.WriteAttributeString("type", result.Test.TestType); xmlWriter.WriteAttributeString("name", result.Name); } else { xmlWriter.WriteStartElement("test-case"); xmlWriter.WriteAttributeString("name", result.FullName); } if (result.Description != null) xmlWriter.WriteAttributeString("description", result.Description); xmlWriter.WriteAttributeString("executed", result.Executed.ToString()); xmlWriter.WriteAttributeString("result", result.ResultState.ToString()); if ( result.Executed ) { xmlWriter.WriteAttributeString("success", result.IsSuccess.ToString()); xmlWriter.WriteAttributeString("time", result.Time.ToString("#####0.000", NumberFormatInfo.InvariantInfo)); xmlWriter.WriteAttributeString("asserts", result.AssertCount.ToString()); } } private void WriteCategoriesElement(TestResult result) { if (result.Test.Categories != null && result.Test.Categories.Count > 0) { xmlWriter.WriteStartElement("categories"); foreach (string category in result.Test.Categories) { xmlWriter.WriteStartElement("category"); xmlWriter.WriteAttributeString("name", category); xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); } } private void WritePropertiesElement(TestResult result) { IDictionary props = result.Test.Properties; if (result.Test.Properties != null && props.Count > 0) { int nprops = 0; foreach (string key in result.Test.Properties.Keys) { if ( !key.StartsWith("_") ) { object val = result.Test.Properties[key]; if (val != null) { if ( nprops == 0 ) xmlWriter.WriteStartElement("properties"); xmlWriter.WriteStartElement("property"); xmlWriter.WriteAttributeString("name", key); xmlWriter.WriteAttributeString("value", val.ToString()); xmlWriter.WriteEndElement(); ++nprops; } } } if ( nprops > 0 ) xmlWriter.WriteEndElement(); } } private void WriteReasonElement(TestResult result) { xmlWriter.WriteStartElement("reason"); xmlWriter.WriteStartElement("message"); xmlWriter.WriteCData(result.Message); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); } private void WriteFailureElement(TestResult result) { xmlWriter.WriteStartElement("failure"); xmlWriter.WriteStartElement("message"); WriteCData(result.Message); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("stack-trace"); if (result.StackTrace != null) WriteCData(StackTraceFilter.Filter(result.StackTrace)); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); } private void WriteChildResults(TestResult result) { xmlWriter.WriteStartElement("results"); if ( result.HasResults ) foreach (TestResult childResult in result.Results) WriteResultElement( childResult ); xmlWriter.WriteEndElement(); } #endregion #region Output Helpers /// /// Makes string safe for xml parsing, replacing control chars with '?' /// /// string to make safe /// xml safe string private static string CharacterSafeString(string encodedString) { /*The default code page for the system will be used. Since all code pages use the same lower 128 bytes, this should be sufficient for finding uprintable control characters that make the xslt processor error. We use characters encoded by the default code page to avoid mistaking bytes as individual characters on non-latin code pages.*/ char[] encodedChars = System.Text.Encoding.Default.GetChars(System.Text.Encoding.Default.GetBytes(encodedString)); System.Collections.ArrayList pos = new System.Collections.ArrayList(); for(int x = 0 ; x < encodedChars.Length ; x++) { char currentChar = encodedChars[x]; //unprintable characters are below 0x20 in Unicode tables //some control characters are acceptable. (carriage return 0x0D, line feed 0x0A, horizontal tab 0x09) if(currentChar < 32 && (currentChar != 9 && currentChar != 10 && currentChar != 13)) { //save the array index for later replacement. pos.Add(x); } } foreach(int index in pos) { encodedChars[index] = '?';//replace unprintable control characters with ?(3F) } return System.Text.Encoding.Default.GetString(System.Text.Encoding.Default.GetBytes(encodedChars)); } private void WriteCData(string text) { int start = 0; while (true) { int illegal = text.IndexOf("]]>", start); if (illegal < 0) break; xmlWriter.WriteCData(text.Substring(start, illegal - start + 2)); start = illegal + 2; if (start >= text.Length) return; } if (start > 0) xmlWriter.WriteCData(text.Substring(start)); else xmlWriter.WriteCData(text); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/RemoteTestAgent.cs0000664000175000017500000000656311717005076023454 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Collections; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Core; namespace NUnit.Util { /// /// RemoteTestAgent represents a remote agent executing in another process /// and communicating with NUnit by TCP. Although it is similar to a /// TestServer, it does not publish a Uri at which clients may connect /// to it. Rather, it reports back to the sponsoring TestAgency upon /// startup so that the agency may in turn provide it to clients for use. /// public class RemoteTestAgent : TestAgent { static Logger log = InternalTrace.GetLogger(typeof(RemoteTestAgent)); #region Fields private ManualResetEvent stopSignal = new ManualResetEvent(false); #endregion #region Constructor /// /// Construct a RemoteTestAgent /// public RemoteTestAgent( Guid agentId, TestAgency agency ) : base(agentId, agency) { } #endregion #region Properties public int ProcessId { get { return System.Diagnostics.Process.GetCurrentProcess().Id; } } #endregion #region Public Methods public override TestRunner CreateRunner(int runnerID) { return new AgentRunner(runnerID); } public override bool Start() { log.Info("Agent starting"); try { this.Agency.Register( this ); log.Debug( "Registered with TestAgency" ); } catch( Exception ex ) { log.Error( "RemoteTestAgent: Failed to register with TestAgency", ex ); return false; } return true; } [System.Runtime.Remoting.Messaging.OneWay] public override void Stop() { log.Info( "Stopping" ); // This causes an error in the client because the agent // database is not thread-safe. //if ( agency != null ) // agency.ReportStatus(this.ProcessId, AgentStatus.Stopping); stopSignal.Set(); } public void WaitForStop() { stopSignal.WaitOne(); } #endregion #region Nested AgentRunner class class AgentRunner : ProxyTestRunner { private ITestRunnerFactory factory; public AgentRunner(int runnerID) : base(runnerID) { this.factory = new InProcessTestRunnerFactory(); } public override bool Load(TestPackage package) { this.TestRunner = factory.MakeTestRunner(package); return base.Load(package); } public override IList AssemblyInfo { get { IList result = base.AssemblyInfo; string name = Path.GetFileName(Assembly.GetEntryAssembly().Location); foreach( TestAssemblyInfo info in result ) info.ModuleName = name; return result; } } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestDomain.cs0000664000175000017500000000627211717225004022441 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { using System.Diagnostics; using System.Security.Policy; using System.Reflection; using System.Collections; using System.Configuration; using System.IO; using NUnit.Core; public class TestDomain : ProxyTestRunner, TestRunner { static Logger log = InternalTrace.GetLogger(typeof(TestDomain)); #region Instance Variables /// /// The appdomain used to load tests /// private AppDomain domain; /// /// The TestAgent in the domain /// private DomainAgent agent; #endregion #region Constructors public TestDomain() : base( 0 ) { } public TestDomain( int runnerID ) : base( runnerID ) { } #endregion #region Properties public AppDomain AppDomain { get { return domain; } } #endregion #region Loading and Unloading Tests public override bool Load( TestPackage package ) { Unload(); log.Info("Loading " + package.Name); try { if ( this.domain == null ) this.domain = Services.DomainManager.CreateDomain( package ); if (this.agent == null) { this.agent = DomainAgent.CreateInstance(domain); this.agent.Start(); } if ( this.TestRunner == null ) this.TestRunner = this.agent.CreateRunner( this.ID ); log.Info( "Loading tests in AppDomain, see {0}_{1}.log", domain.FriendlyName, Process.GetCurrentProcess().Id); return TestRunner.Load( package ); } catch { log.Error("Load failure"); Unload(); throw; } } public override void Unload() { if (this.TestRunner != null) { log.Info("Unloading"); this.TestRunner.Unload(); this.TestRunner = null; } if (this.agent != null) { log.Info("Stopping DomainAgent"); this.agent.Dispose(); this.agent = null; } if(domain != null) { log.Info("Unloading AppDomain " + domain.FriendlyName); Services.DomainManager.Unload(domain); domain = null; } } #endregion #region Running Tests public override void BeginRun(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { log.Info("BeginRun in AppDomain {0}", domain.FriendlyName); base.BeginRun(listener, filter, tracing, logLevel); } #endregion #region IDisposable Members public override void Dispose() { base.Dispose(); Unload(); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/DefaultTestRunnerFactory.cs0000664000175000017500000000677511544454420025354 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; namespace NUnit.Util { /// /// DefaultTestRunnerFactory handles creation of a suitable test /// runner for a given package to be loaded and run either in a /// separate process or within the same process. /// public class DefaultTestRunnerFactory : InProcessTestRunnerFactory, ITestRunnerFactory { #if CLR_2_0 || CLR_4_0 private RuntimeFrameworkSelector selector = new RuntimeFrameworkSelector(); /// /// Returns a test runner based on the settings in a TestPackage. /// Any setting that is "consumed" by the factory is removed, so /// that downstream runners using the factory will not repeatedly /// create the same type of runner. /// /// The TestPackage to be loaded and run /// A TestRunner public override TestRunner MakeTestRunner(TestPackage package) { ProcessModel processModel = GetTargetProcessModel(package); switch (processModel) { case ProcessModel.Multiple: package.Settings.Remove("ProcessModel"); return new MultipleTestProcessRunner(); case ProcessModel.Separate: package.Settings.Remove("ProcessModel"); return new ProcessRunner(); default: return base.MakeTestRunner(package); } } public override bool CanReuse(TestRunner runner, TestPackage package) { RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; RuntimeFramework targetFramework = selector.SelectRuntimeFramework(package); ProcessModel processModel = (ProcessModel)package.GetSetting("ProcessModel", ProcessModel.Default); if (processModel == ProcessModel.Default) if (!currentFramework.Supports(targetFramework)) processModel = ProcessModel.Separate; switch (processModel) { case ProcessModel.Multiple: return runner is MultipleTestProcessRunner; case ProcessModel.Separate: ProcessRunner processRunner = runner as ProcessRunner; return processRunner != null && processRunner.RuntimeFramework == targetFramework; default: return base.CanReuse(runner, package); } } private ProcessModel GetTargetProcessModel(TestPackage package) { RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; RuntimeFramework targetFramework = selector.SelectRuntimeFramework(package); ProcessModel processModel = (ProcessModel)package.GetSetting("ProcessModel", ProcessModel.Default); if (processModel == ProcessModel.Default) if (!currentFramework.Supports(targetFramework)) processModel = ProcessModel.Separate; return processModel; } #endif } } NUnit-2.6.0.12051/src/ClientUtilities/util/PathUtils.cs0000664000175000017500000002003511700247232022277 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Text; using System.Reflection; using System.Collections; using System.Runtime.InteropServices; namespace NUnit.Util { /// /// Static methods for manipulating project paths, including both directories /// and files. Some synonyms for System.Path methods are included as well. /// public class PathUtils { public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; public const int MAX_PATH = 256; protected static char DirectorySeparatorChar = Path.DirectorySeparatorChar; protected static char AltDirectorySeparatorChar = Path.AltDirectorySeparatorChar; #region Public methods public static bool IsAssemblyFileType( string path ) { string extension = Path.GetExtension( path ).ToLower(); return extension == ".dll" || extension == ".exe"; } /// /// Returns the relative path from a base directory to another /// directory or file. /// public static string RelativePath( string from, string to ) { if (from == null) throw new ArgumentNullException (from); if (to == null) throw new ArgumentNullException (to); string toPathRoot = Path.GetPathRoot(to); if (toPathRoot == null || toPathRoot == string.Empty) return to; string fromPathRoot = Path.GetPathRoot(from); if (!PathsEqual(toPathRoot, fromPathRoot)) return null; string fromNoRoot = from.Substring(fromPathRoot.Length); string toNoRoot = to.Substring(toPathRoot.Length); string[] _from = SplitPath(fromNoRoot); string[] _to = SplitPath(toNoRoot); StringBuilder sb = new StringBuilder (Math.Max (from.Length, to.Length)); int last_common, min = Math.Min (_from.Length, _to.Length); for (last_common = 0; last_common < min; ++last_common) { if (!PathsEqual(_from[last_common], _to[last_common])) break; } if (last_common < _from.Length) sb.Append (".."); for (int i = last_common + 1; i < _from.Length; ++i) { sb.Append (PathUtils.DirectorySeparatorChar).Append (".."); } if (sb.Length > 0) sb.Append (PathUtils.DirectorySeparatorChar); if (last_common < _to.Length) sb.Append (_to [last_common]); for (int i = last_common + 1; i < _to.Length; ++i) { sb.Append (PathUtils.DirectorySeparatorChar).Append (_to [i]); } return sb.ToString (); } /// /// Return the canonical form of a path. /// public static string Canonicalize( string path ) { ArrayList parts = new ArrayList( path.Split( DirectorySeparatorChar, AltDirectorySeparatorChar ) ); for( int index = 0; index < parts.Count; ) { string part = (string)parts[index]; switch( part ) { case ".": parts.RemoveAt( index ); break; case "..": parts.RemoveAt( index ); if ( index > 0 ) parts.RemoveAt( --index ); break; default: index++; break; } } // Trailing separator removal if (parts.Count > 1 && path.Length > 1 && (string)parts[parts.Count - 1] == "") parts.RemoveAt(parts.Count - 1); return String.Join(DirectorySeparatorChar.ToString(), (string[])parts.ToArray(typeof(string))); } /// /// True if the two paths are the same. However, two paths /// to the same file or directory using different network /// shares or drive letters are not treated as equal. /// public static bool SamePath( string path1, string path2 ) { return string.Compare( Canonicalize(path1), Canonicalize(path2), PathUtils.IsWindows() ) == 0; } /// /// True if the two paths are the same or if the second is /// directly or indirectly under the first. Note that paths /// using different network shares or drive letters are /// considered unrelated, even if they end up referencing /// the same subtrees in the file system. /// public static bool SamePathOrUnder( string path1, string path2 ) { path1 = Canonicalize( path1 ); path2 = Canonicalize( path2 ); int length1 = path1.Length; int length2 = path2.Length; // if path1 is longer, then path2 can't be under it if ( length1 > length2 ) return false; // if lengths are the same, check for equality if ( length1 == length2 ) return string.Compare( path1, path2, IsWindows() ) == 0; // path 2 is longer than path 1: see if initial parts match if ( string.Compare( path1, path2.Substring( 0, length1 ), IsWindows() ) != 0 ) return false; // must match through or up to a directory separator boundary return path2[length1-1] == DirectorySeparatorChar || path2[length1] == DirectorySeparatorChar; } public static string Combine( string path1, params string[] morePaths ) { string result = path1; foreach( string path in morePaths ) result = Path.Combine( result, path ); return result; } public static string Combine(Assembly assembly, params string[] morePaths) { return Combine(Path.GetDirectoryName(GetAssemblyPath(assembly)), morePaths); } // TODO: This logic should be in shared source public static string GetAssemblyPath( Assembly assembly ) { string uri = assembly.CodeBase; // If it wasn't loaded locally, use the Location if ( !uri.StartsWith( Uri.UriSchemeFile ) ) return assembly.Location; return GetAssemblyPathFromFileUri( uri ); } // Separate method for testability public static string GetAssemblyPathFromFileUri( string uri ) { // Skip over the file:// int start = Uri.UriSchemeFile.Length + Uri.SchemeDelimiter.Length; if ( PathUtils.DirectorySeparatorChar == '\\' ) { if ( uri[start] == '/' && uri[start+2] == ':' ) ++start; } else { if ( uri[start] != '/' ) --start; } return uri.Substring( start ); } #endregion #region Helper Methods private static bool IsWindows() { return PathUtils.DirectorySeparatorChar == '\\'; } private static string[] SplitPath(string path) { char[] separators = new char[] { PathUtils.DirectorySeparatorChar, PathUtils.AltDirectorySeparatorChar }; #if CLR_2_0 || CLR_4_0 return path.Split(separators, StringSplitOptions.RemoveEmptyEntries); #else string[] trialSplit = path.Split(separators); int emptyEntries = 0; foreach(string piece in trialSplit) if (piece == string.Empty) emptyEntries++; if (emptyEntries == 0) return trialSplit; string[] finalSplit = new string[trialSplit.Length - emptyEntries]; int index = 0; foreach(string piece in trialSplit) if (piece != string.Empty) finalSplit[index++] = piece; return finalSplit; #endif } private static bool PathsEqual(string path1, string path2) { #if CLR_2_0 || CLR_4_0 if (PathUtils.IsWindows()) return path1.Equals(path2, StringComparison.InvariantCultureIgnoreCase); else return path1.Equals(path2, StringComparison.InvariantCulture); #else if (PathUtils.IsWindows()) return path1.ToLower().Equals(path2.ToLower()); else return path1.Equals(path2); #endif } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/ProjectConverters/0000775000175000017500000000000011742560362023524 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/ProjectConverters/VisualStudioConverter.cs0000664000175000017500000001350011651210454030366 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.IO; using NUnit.Core; using NUnit.Core.Extensibility; using NUnit.Util.Extensibility; namespace NUnit.Util.ProjectConverters { /// /// Summary description for VSProjectLoader. /// public class VisualStudioConverter : IProjectConverter { #region IProjectConverter Members public bool CanConvertFrom(string path) { return VSProject.IsProjectFile(path)|| VSProject.IsSolutionFile(path); } public NUnitProject ConvertFrom(string path) { if ( VSProject.IsProjectFile(path) ) { return ConvertVSProject(path); } else if ( VSProject.IsSolutionFile(path) ) { return Services.UserSettings.GetSetting("Options.TestLoader.VisualStudio.UseSolutionConfigs", true) ? ConvertVSSolution(path) : LegacyConvertVSSolution(path); } return null; } private static NUnitProject ConvertVSProject(string path) { NUnitProject project = new NUnitProject(Path.GetFullPath(path)); project.Add(new VSProject(path)); project.IsDirty = false; return project; } private static NUnitProject ConvertVSSolution(string path) { NUnitProject project = new NUnitProject(Path.GetFullPath(path)); string solutionDirectory = Path.GetDirectoryName(path); using (StreamReader reader = new StreamReader(path)) { char[] delims = { '=', ',' }; char[] trimchars = { ' ', '"' }; string buildMarker = ".Build.0 ="; Hashtable projectLookup = new Hashtable(); string line = reader.ReadLine(); while (line != null) { if (line.StartsWith("Project(")) { string[] parts = line.Split(delims); string vsProjectPath = parts[2].Trim(trimchars); string vsProjectGuid = parts[3].Trim(trimchars); if (VSProject.IsProjectFile(vsProjectPath)) projectLookup[vsProjectGuid] = new VSProject(Path.Combine(solutionDirectory, vsProjectPath)); } else if (line.IndexOf(buildMarker) >= 0) { line = line.Trim(); int endBrace = line.IndexOf('}'); string vsProjectGuid = line.Substring(0, endBrace + 1); VSProject vsProject = projectLookup[vsProjectGuid] as VSProject; if (vsProject != null) { line = line.Substring(endBrace + 2); int split = line.IndexOf(buildMarker) + 1; string solutionConfig = line.Substring(0, split - 1); int bar = solutionConfig.IndexOf('|'); if (bar >= 0) solutionConfig = solutionConfig.Substring(0, bar); string projectConfig = line.Substring(split + buildMarker.Length); if (vsProject.Configs[projectConfig] == null) { bar = projectConfig.IndexOf('|'); if (bar >= 0) projectConfig = projectConfig.Substring(0, bar); } if (project.Configs[solutionConfig] == null) project.Configs.Add(new ProjectConfig(solutionConfig)); foreach (string assembly in vsProject.Configs[projectConfig].Assemblies) if (!project.Configs[solutionConfig].Assemblies.Contains(assembly)) project.Configs[solutionConfig].Assemblies.Add(assembly); //if (VSProject.IsProjectFile(vsProjectPath)) // project.Add(new VSProject(Path.Combine(solutionDirectory, vsProjectPath))); } } line = reader.ReadLine(); } project.IsDirty = false; return project; } } private static NUnitProject LegacyConvertVSSolution(string path) { NUnitProject project = new NUnitProject(Path.GetFullPath(path)); string solutionDirectory = Path.GetDirectoryName(path); using (StreamReader reader = new StreamReader(path)) { char[] delims = { '=', ',' }; char[] trimchars = { ' ', '"' }; string line = reader.ReadLine(); while (line != null) { if (line.StartsWith("Project(")) { string[] parts = line.Split(delims); string vsProjectPath = parts[2].Trim(trimchars); if (VSProject.IsProjectFile(vsProjectPath)) project.Add(new VSProject(Path.Combine(solutionDirectory, vsProjectPath))); } line = reader.ReadLine(); } project.IsDirty = false; return project; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestExceptionHandler.cs0000664000175000017500000000206111504175260024460 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { /// /// Summary description for UnhandledExceptionCatcher. /// public class TestExceptionHandler : IDisposable { private UnhandledExceptionEventHandler handler; public TestExceptionHandler( UnhandledExceptionEventHandler handler ) { this.handler = handler; AppDomain.CurrentDomain.UnhandledException += handler; } ~TestExceptionHandler() { if ( handler != null ) { AppDomain.CurrentDomain.UnhandledException -= handler; handler = null; } } public void Dispose() { if ( handler != null ) { AppDomain.CurrentDomain.UnhandledException -= handler; handler = null; } System.GC.SuppressFinalize( this ); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestLabelLevel.cs0000664000175000017500000000065111701402366023235 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Util { public enum TestLabelLevel { Off = 0, On = 1, All = 2, } } NUnit-2.6.0.12051/src/ClientUtilities/util/ServerUtilities.cs0000664000175000017500000001040011544454420023524 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; using System.Collections.Specialized; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Reflection; using System.Diagnostics; using NUnit.Core; namespace NUnit.Util { /// /// Summary description for RemotingUtilities. /// public class ServerUtilities { static Logger log = InternalTrace.GetLogger(typeof(ServerUtilities)); /// /// Create a TcpChannel with a given name, on a given port. /// /// /// /// private static TcpChannel CreateTcpChannel( string name, int port, int limit ) { ListDictionary props = new ListDictionary(); props.Add( "port", port ); props.Add( "name", name ); props.Add( "bindTo", "127.0.0.1" ); BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); // NOTE: TypeFilterLevel and "clientConnectionLimit" property don't exist in .NET 1.0. Type typeFilterLevelType = typeof(object).Assembly.GetType("System.Runtime.Serialization.Formatters.TypeFilterLevel"); if (typeFilterLevelType != null) { PropertyInfo typeFilterLevelProperty = serverProvider.GetType().GetProperty("TypeFilterLevel"); object typeFilterLevel = Enum.Parse(typeFilterLevelType, "Full"); typeFilterLevelProperty.SetValue(serverProvider, typeFilterLevel, null); // props.Add("clientConnectionLimit", limit); } BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); return new TcpChannel( props, clientProvider, serverProvider ); } public static TcpChannel GetTcpChannel() { return GetTcpChannel( "", 0, 2 ); } /// /// Get a channel by name, casting it to a TcpChannel. /// Otherwise, create, register and return a TcpChannel with /// that name, on the port provided as the second argument. /// /// The channel name /// The port to use if the channel must be created /// A TcpChannel or null public static TcpChannel GetTcpChannel( string name, int port ) { return GetTcpChannel( name, port, 2 ); } /// /// Get a channel by name, casting it to a TcpChannel. /// Otherwise, create, register and return a TcpChannel with /// that name, on the port provided as the second argument. /// /// The channel name /// The port to use if the channel must be created /// The client connection limit or negative for the default /// A TcpChannel or null public static TcpChannel GetTcpChannel( string name, int port, int limit ) { TcpChannel channel = ChannelServices.GetChannel( name ) as TcpChannel; if ( channel == null ) { // NOTE: Retries are normally only needed when rapidly creating // and destroying channels, as in running the NUnit tests. int retries = 10; while( --retries > 0 ) try { channel = CreateTcpChannel( name, port, limit ); #if CLR_2_0 || CLR_4_0 ChannelServices.RegisterChannel( channel, false ); #else ChannelServices.RegisterChannel( channel ); #endif break; } catch( Exception e ) { log.Error("Failed to create/register channel", e); System.Threading.Thread.Sleep(300); } } return channel; } public static void SafeReleaseChannel( IChannel channel ) { if( channel != null ) try { ChannelServices.UnregisterChannel( channel ); } catch( RemotingException ) { // Channel was not registered - ignore } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/NUnitProject.cs0000664000175000017500000003515411504175260022761 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Xml; using System.Xml.Schema; using System.IO; using System.Threading; using NUnit.Core; namespace NUnit.Util { /// /// Class that represents an NUnit test project /// public class NUnitProject { #region Constants public static readonly string Extension = ".nunit"; #endregion #region Instance variables /// /// Path to the file storing this project /// private string projectPath; /// /// Application Base for the project. Since this /// can be null, always fetch from the property /// rather than using the field directly. /// private string basePath; /// /// Whether the project is dirty /// private bool isDirty = false; /// /// Whether canges have been made requiring a reload /// private bool reloadRequired = false; /// /// Collection of configs for the project /// private ProjectConfigCollection configs; /// /// True for NUnit-related projects that follow the config /// of the NUnit build under which they are running. /// private bool autoConfig; /// /// The currently active configuration /// private ProjectConfig activeConfig; /// /// Flag indicating that this project is a /// temporary wrapper for an assembly. /// private bool isAssemblyWrapper = false; /// /// The ProcessModel to be used in loading this project /// private ProcessModel processModel; /// /// The DomainUsage setting to be used in loading this project /// private DomainUsage domainUsage; #endregion #region Constructor public NUnitProject( string projectPath ) { this.projectPath = Path.GetFullPath( projectPath ); configs = new ProjectConfigCollection( this ); } #endregion #region Properties and Events /// /// The path to which a project will be saved. /// public string ProjectPath { get { return projectPath; } set { projectPath = Path.GetFullPath( value ); isDirty = true; } } public string DefaultBasePath { get { return Path.GetDirectoryName( projectPath ); } } /// /// Indicates whether a base path was specified for the project /// public bool BasePathSpecified { get { return basePath != null && basePath != string.Empty; } } /// /// The base path for the project. Constructor sets /// it to the directory part of the project path. /// public string BasePath { get { if ( !BasePathSpecified ) return DefaultBasePath; return basePath; } set { basePath = value; if (basePath != null && basePath != string.Empty && !Path.IsPathRooted(basePath)) { basePath = Path.Combine( DefaultBasePath, basePath); } basePath = PathUtils.Canonicalize(basePath); HasChangesRequiringReload = IsDirty = true; } } /// /// The name of the project. /// public string Name { get { return Path.GetFileNameWithoutExtension( projectPath ); } } public bool AutoConfig { get { return autoConfig; } set { autoConfig = value; } } public ProjectConfig ActiveConfig { get { // In case the previous active config was removed if ( activeConfig != null && !configs.Contains( activeConfig ) ) activeConfig = null; // In case no active config is set or it was removed if (activeConfig == null && configs.Count > 0) activeConfig = configs[0]; return activeConfig; } } // Safe access to name of the active config public string ActiveConfigName { get { ProjectConfig config = ActiveConfig; return config == null ? null : config.Name; } } public bool IsLoadable { get { return ActiveConfig != null && ActiveConfig.Assemblies.Count > 0; } } // A project made from a single assembly is treated // as a transparent wrapper for some purposes until // a change is made to it. public bool IsAssemblyWrapper { get { return isAssemblyWrapper; } set { isAssemblyWrapper = value; } } public string ConfigurationFile { get { // TODO: Check this return isAssemblyWrapper ? Path.GetFileName( projectPath ) + ".config" : Path.GetFileNameWithoutExtension( projectPath ) + ".config"; } } public bool IsDirty { get { return isDirty; } set { isDirty = value; if (isAssemblyWrapper && value == true) { projectPath = Path.ChangeExtension(projectPath, ".nunit"); isAssemblyWrapper = false; HasChangesRequiringReload = true; } } } public bool HasChangesRequiringReload { get { return reloadRequired; } set { reloadRequired = value; } } public ProcessModel ProcessModel { get { return processModel; } set { processModel = value; HasChangesRequiringReload = IsDirty = true; } } public DomainUsage DomainUsage { get { return domainUsage; } set { domainUsage = value; HasChangesRequiringReload = IsDirty = true; } } public ProjectConfigCollection Configs { get { return configs; } } #endregion #region Static Methods public static bool IsNUnitProjectFile(string path) { return Path.GetExtension(path) == Extension; } public static string ProjectPathFromFile(string path) { string fileName = Path.GetFileNameWithoutExtension(path) + NUnitProject.Extension; return Path.Combine(Path.GetDirectoryName(path), fileName); } #endregion #region Instance Methods public void SetActiveConfig( int index ) { activeConfig = configs[index]; HasChangesRequiringReload = IsDirty = true; } public void SetActiveConfig( string name ) { foreach( ProjectConfig config in configs ) { if ( config.Name == name ) { activeConfig = config; HasChangesRequiringReload = IsDirty = true; break; } } } public void Add( VSProject vsProject ) { foreach( VSProjectConfig vsConfig in vsProject.Configs ) { string name = vsConfig.Name; if ( !configs.Contains( name ) ) configs.Add( name ); ProjectConfig config = this.Configs[name]; foreach ( string assembly in vsConfig.Assemblies ) config.Assemblies.Add( assembly ); } } public void Load() { XmlTextReader reader = new XmlTextReader( projectPath ); string activeConfigName = null; ProjectConfig currentConfig = null; try { reader.MoveToContent(); if ( reader.NodeType != XmlNodeType.Element || reader.Name != "NUnitProject" ) throw new ProjectFormatException( "Invalid project format: expected.", reader.LineNumber, reader.LinePosition ); while( reader.Read() ) if ( reader.NodeType == XmlNodeType.Element ) switch( reader.Name ) { case "Settings": if ( reader.NodeType == XmlNodeType.Element ) { activeConfigName = reader.GetAttribute( "activeconfig" ); string autoConfig = reader.GetAttribute("autoconfig"); if (autoConfig != null) this.AutoConfig = autoConfig.ToLower() == "true"; if (this.AutoConfig) activeConfigName = NUnitConfiguration.BuildConfiguration; string appbase = reader.GetAttribute( "appbase" ); if ( appbase != null ) this.BasePath = appbase; string processModel = reader.GetAttribute("processModel"); if (processModel != null) this.ProcessModel = (ProcessModel)Enum.Parse(typeof(ProcessModel), processModel); string domainUsage = reader.GetAttribute("domainUsage"); if (domainUsage != null) this.DomainUsage = (DomainUsage)Enum.Parse(typeof(DomainUsage), domainUsage); } break; case "Config": if ( reader.NodeType == XmlNodeType.Element ) { string configName = reader.GetAttribute( "name" ); currentConfig = new ProjectConfig( configName ); currentConfig.BasePath = reader.GetAttribute( "appbase" ); currentConfig.ConfigurationFile = reader.GetAttribute( "configfile" ); string binpath = reader.GetAttribute( "binpath" ); currentConfig.PrivateBinPath = binpath; string type = reader.GetAttribute( "binpathtype" ); if ( type == null ) if ( binpath == null ) currentConfig.BinPathType = BinPathType.Auto; else currentConfig.BinPathType = BinPathType.Manual; else currentConfig.BinPathType = (BinPathType)Enum.Parse( typeof( BinPathType ), type, true ); string runtime = reader.GetAttribute("runtimeFramework"); if ( runtime != null ) currentConfig.RuntimeFramework = RuntimeFramework.Parse(runtime); Configs.Add(currentConfig); if ( configName == activeConfigName ) activeConfig = currentConfig; } else if ( reader.NodeType == XmlNodeType.EndElement ) currentConfig = null; break; case "assembly": if ( reader.NodeType == XmlNodeType.Element && currentConfig != null ) { string path = reader.GetAttribute( "path" ); currentConfig.Assemblies.Add( Path.Combine( currentConfig.BasePath, path ) ); } break; default: break; } this.IsDirty = false; this.reloadRequired = false; } catch( FileNotFoundException ) { throw; } catch( XmlException e ) { throw new ProjectFormatException( string.Format( "Invalid project format: {0}", e.Message ), e.LineNumber, e.LinePosition ); } catch( Exception e ) { throw new ProjectFormatException( string.Format( "Invalid project format: {0} Line {1}, Position {2}", e.Message, reader.LineNumber, reader.LinePosition ), reader.LineNumber, reader.LinePosition ); } finally { reader.Close(); } } public void Save() { projectPath = ProjectPathFromFile( projectPath ); XmlTextWriter writer = new XmlTextWriter( projectPath, System.Text.Encoding.UTF8 ); writer.Formatting = Formatting.Indented; writer.WriteStartElement( "NUnitProject" ); if ( configs.Count > 0 || this.BasePath != this.DefaultBasePath ) { writer.WriteStartElement( "Settings" ); if ( configs.Count > 0 ) writer.WriteAttributeString( "activeconfig", ActiveConfigName ); if ( this.BasePath != this.DefaultBasePath ) writer.WriteAttributeString( "appbase", this.BasePath ); if (this.AutoConfig) writer.WriteAttributeString("autoconfig", "true"); if (this.ProcessModel != ProcessModel.Default) writer.WriteAttributeString("processModel", this.ProcessModel.ToString()); if (this.DomainUsage != DomainUsage.Default) writer.WriteAttributeString("domainUsage", this.DomainUsage.ToString()); writer.WriteEndElement(); } foreach( ProjectConfig config in Configs ) { writer.WriteStartElement( "Config" ); writer.WriteAttributeString( "name", config.Name ); string appbase = config.BasePath; if ( !PathUtils.SamePathOrUnder( this.BasePath, appbase ) ) writer.WriteAttributeString( "appbase", appbase ); else if ( config.RelativeBasePath != null ) writer.WriteAttributeString( "appbase", config.RelativeBasePath ); string configFile = config.ConfigurationFile; if ( configFile != null && configFile != this.ConfigurationFile ) writer.WriteAttributeString( "configfile", config.ConfigurationFile ); if ( config.BinPathType == BinPathType.Manual ) writer.WriteAttributeString( "binpath", config.PrivateBinPath ); else writer.WriteAttributeString( "binpathtype", config.BinPathType.ToString() ); if (config.RuntimeFramework != null) writer.WriteAttributeString("runtimeFramework", config.RuntimeFramework.ToString()); foreach( string assembly in config.Assemblies ) { writer.WriteStartElement( "assembly" ); writer.WriteAttributeString( "path", PathUtils.RelativePath( config.BasePath, assembly ) ); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); this.IsDirty = false; // Once we save a project, it's no longer // loaded as an assembly wrapper on reload. this.isAssemblyWrapper = false; } public void Save( string projectPath ) { this.ProjectPath = projectPath; Save(); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/0000775000175000017500000000000011742560362021626 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/Services/ProjectService.cs0000664000175000017500000001116711504175260025105 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Core; using NUnit.Util.Extensibility; using NUnit.Util.ProjectConverters; namespace NUnit.Util { /// /// Summary description for ProjectService. /// public class ProjectService : IProjectConverter, IService { /// /// Seed used to generate names for new projects /// private int projectSeed = 0; /// /// The extension used for test projects /// //private static readonly string nunitExtension = ".nunit"; /// /// Array of all installed ProjectConverters /// IProjectConverter[] converters = new IProjectConverter[] { new VisualStudioConverter() }; #region Instance Methods public bool CanLoadProject(string path) { return NUnitProject.IsNUnitProjectFile(path) || CanConvertFrom(path); } public NUnitProject LoadProject(string path) { if ( NUnitProject.IsNUnitProjectFile(path) ) { NUnitProject project = new NUnitProject( path ); project.Load(); return project; } return ConvertFrom(path); } /// /// Creates a project to wrap a list of assemblies /// public NUnitProject WrapAssemblies( string[] assemblies ) { // if only one assembly is passed in then the configuration file // should follow the name of the assembly. This will only happen // if the LoadAssembly method is called. Currently the console ui // does not differentiate between having one or multiple assemblies // passed in. if ( assemblies.Length == 1) return WrapAssembly(assemblies[0]); NUnitProject project = Services.ProjectService.EmptyProject(); ProjectConfig config = new ProjectConfig( "Default" ); foreach( string assembly in assemblies ) { string fullPath = Path.GetFullPath( assembly ); if ( !File.Exists( fullPath ) ) throw new FileNotFoundException( string.Format( "Assembly not found: {0}", fullPath ) ); config.Assemblies.Add( fullPath ); } project.Configs.Add( config ); // TODO: Deduce application base, and provide a // better value for loadpath and project path // analagous to how new projects are handled string basePath = Path.GetDirectoryName( Path.GetFullPath( assemblies[0] ) ); project.ProjectPath = Path.Combine( basePath, project.Name + ".nunit" ); project.IsDirty = true; return project; } /// /// Creates a project to wrap an assembly /// public NUnitProject WrapAssembly( string assemblyPath ) { if ( !File.Exists( assemblyPath ) ) throw new FileNotFoundException( string.Format( "Assembly not found: {0}", assemblyPath ) ); string fullPath = Path.GetFullPath( assemblyPath ); NUnitProject project = new NUnitProject( fullPath ); ProjectConfig config = new ProjectConfig( "Default" ); config.Assemblies.Add( fullPath ); project.Configs.Add( config ); project.IsAssemblyWrapper = true; project.IsDirty = false; return project; } public string GenerateProjectName() { return string.Format( "Project{0}", ++projectSeed ); } public NUnitProject EmptyProject() { return new NUnitProject( GenerateProjectName() ); } public NUnitProject NewProject() { NUnitProject project = EmptyProject(); project.Configs.Add( "Debug" ); project.Configs.Add( "Release" ); project.IsDirty = false; return project; } public void SaveProject( NUnitProject project ) { project.Save(); } #endregion #region IProjectConverter Members public bool CanConvertFrom(string path) { foreach( IProjectConverter converter in converters ) if ( converter.CanConvertFrom(path) ) return true; return false; } public NUnitProject ConvertFrom(string path) { foreach( IProjectConverter converter in converters ) { if ( converter.CanConvertFrom( path ) ) return converter.ConvertFrom( path ); } return WrapAssembly(path); } #endregion #region IService Members public void InitializeService() { // TODO: Add ProjectLoader.InitializeService implementation } public void UnloadService() { // TODO: Add ProjectLoader.UnloadService implementation } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/TestAgency.cs0000664000175000017500000003333711664256332024236 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Threading; using System.Diagnostics; using System.Collections; using System.Collections.Specialized; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Services; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Core; namespace NUnit.Util { /// /// Enumeration used to report AgentStatus /// public enum AgentStatus { Unknown, Starting, Ready, Busy, Stopping } /// /// The TestAgency class provides RemoteTestAgents /// on request and tracks their status. Agents /// are wrapped in an instance of the TestAgent /// class. Multiple agent types are supported /// but only one, ProcessAgent is implemented /// at this time. /// public class TestAgency : ServerBase, IAgency, IService { static Logger log = InternalTrace.GetLogger(typeof(TestAgency)); #region Private Fields private AgentDataBase agentData = new AgentDataBase(); #endregion #region Constructors public TestAgency() : this( "TestAgency", 0 ) { } public TestAgency( string uri, int port ) : base( uri, port ) { } #endregion #region ServerBase Overrides public override void Stop() { foreach( AgentRecord r in agentData ) { if ( !r.Process.HasExited ) { if ( r.Agent != null ) { r.Agent.Stop(); r.Process.WaitForExit(10000); } if ( !r.Process.HasExited ) r.Process.Kill(); } } agentData.Clear(); base.Stop (); } #endregion #region Public Methods - Called by Agents public void Register( TestAgent agent ) { AgentRecord r = agentData[agent.Id]; if ( r == null ) throw new ArgumentException( string.Format("Agent {0} is not in the agency database", agent.Id), "agentId"); r.Agent = agent; } public void ReportStatus( Guid agentId, AgentStatus status ) { AgentRecord r = agentData[agentId]; if ( r == null ) throw new ArgumentException( string.Format("Agent {0} is not in the agency database", agentId), "agentId" ); r.Status = status; } #endregion #region Public Methods - Called by Clients /// /// Returns true if NUnit support for the runtime specified /// is installed, independent of whether the runtime itself /// is installed on the system. /// /// In the current implementation, only .NET 1.x requires /// special handling, since all higher runtimes are /// supported normally. /// /// The desired runtime version /// True if NUnit support is installed public bool IsRuntimeVersionSupported(Version version) { return GetNUnitBinDirectory(version) != null; } public TestAgent GetAgent() { return GetAgent( RuntimeFramework.CurrentFramework, Timeout.Infinite ); } public TestAgent GetAgent(int waitTime) { return GetAgent(RuntimeFramework.CurrentFramework, waitTime); } public TestAgent GetAgent(RuntimeFramework framework, int waitTime) { return GetAgent(framework, waitTime, false); } public TestAgent GetAgent(RuntimeFramework framework, int waitTime, bool enableDebug) { log.Info("Getting agent for use under {0}", framework); if (!framework.IsAvailable) throw new ArgumentException( string.Format("The {0} framework is not available", framework), "framework"); // TODO: Decide if we should reuse agents //AgentRecord r = FindAvailableRemoteAgent(type); //if ( r == null ) // r = CreateRemoteAgent(type, framework, waitTime); return CreateRemoteAgent(framework, waitTime, enableDebug); } public void ReleaseAgent( TestAgent agent ) { AgentRecord r = agentData[agent.Id]; if ( r == null ) log.Error( string.Format( "Unable to release agent {0} - not in database", agent.Id ) ); else { r.Status = AgentStatus.Ready; log.Debug( "Releasing agent " + agent.Id.ToString() ); } } //public void DestroyAgent( ITestAgent agent ) //{ // AgentRecord r = agentData[agent.Id]; // if ( r != null ) // { // if( !r.Process.HasExited ) // r.Agent.Stop(); // agentData[r.Id] = null; // } //} #endregion #region Helper Methods private Guid LaunchAgentProcess(RuntimeFramework targetRuntime, bool enableDebug) { string agentExePath = GetTestAgentExePath(targetRuntime.ClrVersion); if (agentExePath == null) throw new ArgumentException( string.Format("NUnit components for version {0} of the CLR are not installed", targetRuntime.ClrVersion.ToString()), "targetRuntime"); log.Debug("Using nunit-agent at " + agentExePath); Process p = new Process(); p.StartInfo.UseShellExecute = false; Guid agentId = Guid.NewGuid(); string arglist = agentId.ToString() + " " + ServerUrl; if (enableDebug) arglist += " --pause"; switch( targetRuntime.Runtime ) { case RuntimeType.Mono: p.StartInfo.FileName = NUnitConfiguration.MonoExePath; string monoOptions = "--runtime=v" + targetRuntime.ClrVersion.ToString(3); if (enableDebug) monoOptions += " --debug"; p.StartInfo.Arguments = string.Format("{0} \"{1}\" {2}", monoOptions, agentExePath, arglist); break; case RuntimeType.Net: p.StartInfo.FileName = agentExePath; if (targetRuntime.ClrVersion.Build < 0) targetRuntime = RuntimeFramework.GetBestAvailableFramework(targetRuntime); string envVar = "v" + targetRuntime.ClrVersion.ToString(3); p.StartInfo.EnvironmentVariables["COMPLUS_Version"] = envVar; p.StartInfo.Arguments = arglist; break; default: p.StartInfo.FileName = agentExePath; p.StartInfo.Arguments = arglist; break; } //p.Exited += new EventHandler(OnProcessExit); p.Start(); log.Info("Launched Agent process {0} - see nunit-agent_{0}.log", p.Id); log.Info("Command line: \"{0}\" {1}", p.StartInfo.FileName, p.StartInfo.Arguments); agentData.Add( new AgentRecord( agentId, p, null, AgentStatus.Starting ) ); return agentId; } //private void OnProcessExit(object sender, EventArgs e) //{ // Process p = sender as Process; // if (p != null) // agentData.Remove(p.Id); //} private AgentRecord FindAvailableAgent() { foreach( AgentRecord r in agentData ) if ( r.Status == AgentStatus.Ready) { log.Debug( "Reusing agent {0}", r.Id ); r.Status = AgentStatus.Busy; return r; } return null; } private TestAgent CreateRemoteAgent(RuntimeFramework framework, int waitTime, bool enableDebug) { Guid agentId = LaunchAgentProcess(framework, enableDebug); log.Debug( "Waiting for agent {0} to register", agentId.ToString("B") ); int pollTime = 200; bool infinite = waitTime == Timeout.Infinite; while( infinite || waitTime > 0 ) { Thread.Sleep( pollTime ); if ( !infinite ) waitTime -= pollTime; TestAgent agent = agentData[agentId].Agent; if ( agent != null ) { log.Debug( "Returning new agent {0}", agentId.ToString("B") ); return agent; } } return null; } /// /// Return the NUnit Bin Directory for a particular /// runtime version, or null if it's not installed. /// For normal installations, there are only 1.1 and /// 2.0 directories. However, this method accomodates /// 3.5 and 4.0 directories for the benefit of NUnit /// developers using those runtimes. /// private static string GetNUnitBinDirectory(Version v) { // Get current bin directory string dir = NUnitConfiguration.NUnitBinDirectory; // Return current directory if current and requested // versions are both >= 2 or both 1 if ((Environment.Version.Major >= 2) == (v.Major >= 2)) return dir; // Check whether special support for version 1 is installed if (v.Major == 1) { string altDir = Path.Combine(dir, "net-1.1"); if (Directory.Exists(altDir)) return altDir; // The following is only applicable to the dev environment, // which uses parallel build directories. We try to substitute // one version number for another in the path. string[] search = new string[] { "2.0", "3.0", "3.5", "4.0" }; string[] replace = v.Minor == 0 ? new string[] { "1.0", "1.1" } : new string[] { "1.1", "1.0" }; // Look for current value in path so it can be replaced string current = null; foreach (string s in search) if (dir.IndexOf(s) >= 0) { current = s; break; } // Try the substitution if (current != null) { foreach (string target in replace) { altDir = dir.Replace(current, target); if (Directory.Exists(altDir)) return altDir; } } } return null; } private static string GetTestAgentExePath(Version v) { string binDir = GetNUnitBinDirectory(v); if (binDir == null) return null; #if CLR_2_0 || CLR_4_0 Assembly a = System.Reflection.Assembly.GetEntryAssembly(); string agentName = v.Major > 1 && a != null && a.GetName().ProcessorArchitecture == ProcessorArchitecture.X86 ? "nunit-agent-x86.exe" : "nunit-agent.exe"; #else string agentName = "nunit-agent.exe"; #endif string agentExePath = Path.Combine(binDir, agentName); return File.Exists(agentExePath) ? agentExePath : null; } #endregion #region IService Members public void UnloadService() { this.Stop(); } public void InitializeService() { this.Start(); } #endregion #region Nested Class - AgentRecord private class AgentRecord { public Guid Id; public Process Process; public TestAgent Agent; public AgentStatus Status; public AgentRecord( Guid id, Process p, TestAgent a, AgentStatus s ) { this.Id = id; this.Process = p; this.Agent = a; this.Status = s; } } #endregion #region Nested Class - AgentDataBase /// /// A simple class that tracks data about this /// agencies active and available agents /// private class AgentDataBase : IEnumerable { private ListDictionary agentData = new ListDictionary(); public AgentRecord this[Guid id] { get { return (AgentRecord)agentData[id]; } set { if ( value == null ) agentData.Remove( id ); else agentData[id] = value; } } public AgentRecord this[TestAgent agent] { get { foreach( System.Collections.DictionaryEntry entry in agentData ) { AgentRecord r = (AgentRecord)entry.Value; if ( r.Agent == agent ) return r; } return null; } } public void Add( AgentRecord r ) { agentData[r.Id] = r; } public void Remove(Guid agentId) { agentData.Remove(agentId); } public void Clear() { agentData.Clear(); } #region IEnumerable Members public IEnumerator GetEnumerator() { return new AgentDataEnumerator( agentData ); } #endregion #region Nested Class - AgentDataEnumerator public class AgentDataEnumerator : IEnumerator { IEnumerator innerEnum; public AgentDataEnumerator( IDictionary list ) { innerEnum = list.GetEnumerator(); } #region IEnumerator Members public void Reset() { innerEnum.Reset(); } public object Current { get { return ((DictionaryEntry)innerEnum.Current).Value; } } public bool MoveNext() { return innerEnum.MoveNext(); } #endregion } #endregion } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/DomainManager.cs0000664000175000017500000003026511677322274024672 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; using System.Text; using System.Threading; using System.Reflection; using System.Configuration; using System.Diagnostics; using System.Security; using System.Security.Permissions; using System.Security.Policy; using NUnit.Core; using System.Security.Principal; namespace NUnit.Util { /// /// The DomainManager class handles the creation and unloading /// of domains as needed and keeps track of all existing domains. /// public class DomainManager : IService { static Logger log = InternalTrace.GetLogger(typeof(DomainManager)); #region Properties private static string shadowCopyPath; public static string ShadowCopyPath { get { if ( shadowCopyPath == null ) { shadowCopyPath = Services.UserSettings.GetSetting("Options.TestLoader.ShadowCopyPath", ""); if (shadowCopyPath == "") shadowCopyPath = PathUtils.Combine(Path.GetTempPath(), "nunit20", "ShadowCopyCache"); else shadowCopyPath = Environment.ExpandEnvironmentVariables(shadowCopyPath); } return shadowCopyPath; } } #endregion #region Create and Unload Domains /// /// Construct an application domain for running a test package /// /// The TestPackage to be run public AppDomain CreateDomain( TestPackage package ) { AppDomainSetup setup = new AppDomainSetup(); //For paralell tests, we need to use distinct application name setup.ApplicationName = "Tests" + "_" + Environment.TickCount; FileInfo testFile = package.FullName != null && package.FullName != string.Empty ? new FileInfo(package.FullName) : null; string appBase = package.BasePath; string configFile = package.ConfigurationFile; string binPath = package.PrivateBinPath; if (testFile != null) { if (appBase == null || appBase == string.Empty) appBase = testFile.DirectoryName; if (configFile == null || configFile == string.Empty) configFile = Services.ProjectService.CanLoadProject(testFile.Name) ? Path.GetFileNameWithoutExtension(testFile.Name) + ".config" : testFile.Name + ".config"; } else if (appBase == null || appBase == string.Empty) appBase = GetCommonAppBase(package.Assemblies); char lastChar = appBase[appBase.Length - 1]; if (lastChar != Path.DirectorySeparatorChar && lastChar != Path.AltDirectorySeparatorChar) appBase += Path.DirectorySeparatorChar; setup.ApplicationBase = appBase; // TODO: Check whether Mono still needs full path to config file... setup.ConfigurationFile = appBase != null && configFile != null ? Path.Combine(appBase, configFile) : configFile; if (package.AutoBinPath) binPath = GetPrivateBinPath( appBase, package.Assemblies ); setup.PrivateBinPath = binPath; if (package.GetSetting("ShadowCopyFiles", true)) { setup.ShadowCopyFiles = "true"; setup.ShadowCopyDirectories = appBase; setup.CachePath = GetCachePath(); } else setup.ShadowCopyFiles = "false"; string domainName = "test-domain-" + package.Name; // Setup the Evidence Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence); if (evidence.Count == 0) { Zone zone = new Zone(SecurityZone.MyComputer); evidence.AddHost(zone); Assembly assembly = Assembly.GetExecutingAssembly(); Url url = new Url(assembly.CodeBase); evidence.AddHost(url); Hash hash = new Hash(assembly); evidence.AddHost(hash); } log.Info("Creating AppDomain " + domainName); AppDomain runnerDomain; // TODO: Try to eliminate this test. Currently, running on // Linux with the permission set specified causes an // unexplained crash when unloading the domain. #if CLR_2_0 || CLR_4_0 if (Environment.OSVersion.Platform == PlatformID.Win32NT) { PermissionSet permissionSet = new PermissionSet( PermissionState.Unrestricted ); runnerDomain = AppDomain.CreateDomain(domainName, evidence, setup, permissionSet, null); } else #endif runnerDomain = AppDomain.CreateDomain(domainName, evidence, setup); // Set PrincipalPolicy for the domain if called for in the settings if ( Services.UserSettings.GetSetting("Options.TestLoader.SetPrincipalPolicy", false )) runnerDomain.SetPrincipalPolicy((PrincipalPolicy)Services.UserSettings.GetSetting( "Options.TestLoader.PrincipalPolicy", PrincipalPolicy.UnauthenticatedPrincipal)); // HACK: Only pass down our AddinRegistry one level so that tests of NUnit // itself start without any addins defined. if ( !IsTestDomain( AppDomain.CurrentDomain ) ) runnerDomain.SetData("AddinRegistry", Services.AddinRegistry); // Inject DomainInitializer into the remote domain - there are other // approaches, but this works for all CLR versions. DomainInitializer initializer = DomainInitializer.CreateInstance(runnerDomain); // HACK: Under nunit-console, direct use of the enum fails int traceLevel = IsTestDomain(AppDomain.CurrentDomain) ? (int)InternalTraceLevel.Off : (int)InternalTrace.Level; initializer.InitializeDomain(traceLevel); return runnerDomain; } public void Unload(AppDomain domain) { new DomainUnloader(domain).Unload(); } #endregion #region Nested DomainUnloader Class class DomainUnloader { private Thread thread; private AppDomain domain; public DomainUnloader(AppDomain domain) { this.domain = domain; } public void Unload() { string domainName; try { domainName = domain.FriendlyName; } catch (AppDomainUnloadedException) { return; } log.Info("Unloading AppDomain " + domainName); thread = new Thread(new ThreadStart(UnloadOnThread)); thread.Start(); if (!thread.Join(30000)) { log.Error("Unable to unload AppDomain {0}, Unload thread timed out", domainName); ThreadUtility.Kill(thread); } } private void UnloadOnThread() { bool shadowCopy = false; string cachePath = null; string domainName = "UNKNOWN"; try { shadowCopy = domain.ShadowCopyFiles; cachePath = domain.SetupInformation.CachePath; domainName = domain.FriendlyName; AppDomain.Unload(domain); } catch (Exception ex) { // We assume that the tests did something bad and just leave // the orphaned AppDomain "out there". // TODO: Something useful. log.Error("Unable to unload AppDomain " + domainName, ex); } finally { if (shadowCopy && cachePath != null) DeleteCacheDir(new DirectoryInfo(cachePath)); } } } #endregion #region Helper Methods /// /// Get the location for caching and delete any old cache info /// private string GetCachePath() { int processId = Process.GetCurrentProcess().Id; long ticks = DateTime.Now.Ticks; string cachePath = Path.Combine( ShadowCopyPath, processId.ToString() + "_" + ticks.ToString() ); try { DirectoryInfo dir = new DirectoryInfo(cachePath); if(dir.Exists) dir.Delete(true); } catch( Exception ex) { throw new ApplicationException( string.Format( "Invalid cache path: {0}",cachePath ), ex ); } return cachePath; } /// /// Helper method to delete the cache dir. This method deals /// with a bug that occurs when files are marked read-only /// and deletes each file separately in order to give better /// exception information when problems occur. /// /// TODO: This entire method is problematic. Should we be doing it? /// /// private static void DeleteCacheDir( DirectoryInfo cacheDir ) { // Debug.WriteLine( "Modules:"); // foreach( ProcessModule module in Process.GetCurrentProcess().Modules ) // Debug.WriteLine( module.ModuleName ); if(cacheDir.Exists) { foreach( DirectoryInfo dirInfo in cacheDir.GetDirectories() ) DeleteCacheDir( dirInfo ); foreach( FileInfo fileInfo in cacheDir.GetFiles() ) { fileInfo.Attributes = FileAttributes.Normal; try { fileInfo.Delete(); } catch( Exception ex ) { Debug.WriteLine( string.Format( "Error deleting {0}, {1}", fileInfo.Name, ex.Message ) ); } } cacheDir.Attributes = FileAttributes.Normal; try { cacheDir.Delete(); } catch( Exception ex ) { Debug.WriteLine( string.Format( "Error deleting {0}, {1}", cacheDir.Name, ex.Message ) ); } } } private bool IsTestDomain(AppDomain domain) { return domain.FriendlyName.StartsWith( "test-domain-" ); } public static string GetCommonAppBase(IList assemblies) { string commonBase = null; foreach (string assembly in assemblies) { string dir = Path.GetFullPath(Path.GetDirectoryName(assembly)); if (commonBase == null) commonBase = dir; else while (!PathUtils.SamePathOrUnder(commonBase, dir) && commonBase != null) commonBase = Path.GetDirectoryName(commonBase); } return commonBase; } public static string GetPrivateBinPath( string basePath, IList assemblies ) { StringBuilder sb = new StringBuilder(200); ArrayList dirList = new ArrayList(); foreach( string assembly in assemblies ) { string dir = PathUtils.RelativePath( Path.GetFullPath(basePath), Path.GetDirectoryName( Path.GetFullPath(assembly) ) ); if ( dir != null && dir != "." && !dirList.Contains( dir ) ) { dirList.Add( dir ); if ( sb.Length > 0 ) sb.Append( Path.PathSeparator ); sb.Append( dir ); } } return sb.Length == 0 ? null : sb.ToString(); } public static void DeleteShadowCopyPath() { if ( Directory.Exists( ShadowCopyPath ) ) Directory.Delete( ShadowCopyPath, true ); } #endregion #region IService Members public void UnloadService() { // TODO: Add DomainManager.UnloadService implementation } public void InitializeService() { // TODO: Add DomainManager.InitializeService implementation } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/AddinManager.cs0000664000175000017500000000453411504175260024470 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Diagnostics; using System.Collections; using System.Reflection; using NUnit.Core; using NUnit.Core.Extensibility; namespace NUnit.Util { public class AddinManager : IService { static Logger log = InternalTrace.GetLogger(typeof(AddinManager)); #region Instance Fields IAddinRegistry addinRegistry; #endregion #region Constructor public AddinManager() { } #endregion #region Addin Registration public void RegisterAddins() { // Load any extensions in the addins directory DirectoryInfo dir = new DirectoryInfo( NUnitConfiguration.AddinDirectory ); if ( dir.Exists ) foreach( FileInfo file in dir.GetFiles( "*.dll" ) ) Register( file.FullName ); } public void Register( string path ) { try { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = Path.GetFileNameWithoutExtension(path); assemblyName.CodeBase = path; Assembly assembly = Assembly.Load(assemblyName); log.Debug( "Loaded " + Path.GetFileName(path) ); foreach ( Type type in assembly.GetExportedTypes() ) { if ( type.GetCustomAttributes(typeof(NUnitAddinAttribute), false).Length == 1 ) { Addin addin = new Addin( type ); if ( addinRegistry.IsAddinRegistered(addin.Name) ) log.Error( "Addin {0} was already registered", addin.Name ); else { addinRegistry.Register( addin ); log.Debug( "Registered addin: {0}", addin.Name ); } } } } catch( Exception ex ) { // NOTE: Since the gui isn't loaded at this point, // the trace output will only show up in Visual Studio log.Error( "Failed to load" + path, ex ); } } #endregion #region IService Members public void InitializeService() { addinRegistry = Services.AddinRegistry; RegisterAddins(); } public void UnloadService() { } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/RecentFilesService.cs0000664000175000017500000001100211504175260025666 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { /// /// Summary description for RecentFilesService. /// public class RecentFilesService : RecentFiles, NUnit.Core.IService { private RecentFilesCollection fileEntries = new RecentFilesCollection(); private ISettings settings; public static readonly int MinSize = 0; public static readonly int MaxSize = 24; public static readonly int DefaultSize = 5; #region Constructor public RecentFilesService() : this( Services.UserSettings ) { } public RecentFilesService( ISettings settings ) { this.settings = settings; } #endregion #region Properties public int Count { get { return fileEntries.Count; } } public int MaxFiles { get { int size = settings.GetSetting("Gui.RecentProjects.MaxFiles", -1 ); if (size < 0) { size = settings.GetSetting("RecentProjects.MaxFiles", DefaultSize); if (size != DefaultSize) settings.SaveSetting("Gui.RecentProjects.MaxFiles", size); settings.RemoveSetting("RecentProjects.MaxFiles"); } if ( size < MinSize ) size = MinSize; if ( size > MaxSize ) size = MaxSize; return size; } set { int oldSize = MaxFiles; int newSize = value; if ( newSize < MinSize ) newSize = MinSize; if ( newSize > MaxSize ) newSize = MaxSize; settings.SaveSetting( "Gui.RecentProjects.MaxFiles", newSize ); if ( newSize < oldSize ) SaveEntriesToSettings( this. settings ); } } #endregion #region Public Methods public RecentFilesCollection Entries { get { return fileEntries; } } public void Remove( string fileName ) { fileEntries.Remove( fileName ); } public void SetMostRecent( string fileName ) { SetMostRecent( new RecentFileEntry( fileName ) ); } public void SetMostRecent( RecentFileEntry entry ) { int index = fileEntries.IndexOf(entry.Path); if(index != -1) fileEntries.RemoveAt(index); fileEntries.Insert( 0, entry ); if( fileEntries.Count > MaxFiles ) fileEntries.RemoveAt( MaxFiles ); } #endregion #region Helper Methods for saving and restoring the settings private void LoadEntriesFromSettings( ISettings settings ) { fileEntries.Clear(); AddEntriesForPrefix("Gui.RecentProjects"); // Try legacy entries if nothing was found if (fileEntries.Count == 0) { AddEntriesForPrefix("RecentProjects.V2"); AddEntriesForPrefix("RecentProjects.V1"); } // Try even older legacy format if (fileEntries.Count == 0) AddEntriesForPrefix("RecentProjects"); } private void AddEntriesForPrefix(string prefix) { for (int index = 1; index < MaxFiles; index++) { if (fileEntries.Count >= MaxFiles) break; string fileSpec = settings.GetSetting(GetRecentFileKey(prefix, index)) as string; if (fileSpec != null) fileEntries.Add(RecentFileEntry.Parse(fileSpec)); } } private void SaveEntriesToSettings( ISettings settings ) { string prefix = "Gui.RecentProjects"; while( fileEntries.Count > MaxFiles ) fileEntries.RemoveAt( fileEntries.Count - 1 ); for( int index = 0; index < MaxSize; index++ ) { string keyName = GetRecentFileKey( prefix, index + 1 ); if ( index < fileEntries.Count ) settings.SaveSetting( keyName, fileEntries[index].Path ); else settings.RemoveSetting( keyName ); } // Remove legacy entries here settings.RemoveGroup("RecentProjects"); } private string GetRecentFileKey( string prefix, int index ) { return string.Format( "{0}.File{1}", prefix, index ); } #endregion #region IService Members public void UnloadService() { SaveEntriesToSettings( this.settings ); } public void InitializeService() { LoadEntriesFromSettings( this.settings ); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/ServiceManager.cs0000664000175000017500000000547211504175260025053 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Core; namespace NUnit.Util { /// /// Summary description for ServiceManger. /// public class ServiceManager { private ArrayList services = new ArrayList(); private Hashtable serviceIndex = new Hashtable(); private static ServiceManager defaultServiceManager = new ServiceManager(); static Logger log = InternalTrace.GetLogger(typeof(ServiceManager)); public static ServiceManager Services { get { return defaultServiceManager; } } public void AddService( IService service ) { services.Add( service ); log.Debug( "Added " + service.GetType().Name ); } public IService GetService( Type serviceType ) { IService theService = (IService)serviceIndex[serviceType]; if ( theService == null ) foreach( IService service in services ) { // TODO: Does this work on Mono? if( serviceType.IsInstanceOfType( service ) ) { serviceIndex[serviceType] = service; theService = service; break; } } if ( theService == null ) log.Error( string.Format( "Requested service {0} was not found", serviceType.FullName ) ); else log.Debug( string.Format( "Request for service {0} satisfied by {1}", serviceType.Name, theService.GetType().Name ) ); return theService; } public void InitializeServices() { foreach( IService service in services ) { log.Info( "Initializing " + service.GetType().Name ); try { service.InitializeService(); } catch (Exception ex) { log.Error("Failed to initialize service", ex); } } } public void StopAllServices() { // Stop services in reverse of initialization order // TODO: Deal with dependencies explicitly int index = services.Count; while (--index >= 0) { IService service = services[index] as IService; log.Info( "Stopping " + service.GetType().Name ); try { service.UnloadService(); } catch (Exception ex) { log.Error("Failure stopping service", ex); } } } public void ClearServices() { log.Info("Clearing Service list"); services.Clear(); } private ServiceManager() { } } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/SettingsService.cs0000664000175000017500000001310011544454420025266 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using Microsoft.Win32; using NUnit.Core; namespace NUnit.Util { /// /// Summary description for UserSettingsService. /// public class SettingsService : SettingsGroup, NUnit.Core.IService { static readonly string settingsFileName = "NUnitSettings.xml"; private bool writeable; public SettingsService() : this(true) { } public SettingsService(bool writeable) { this.writeable = writeable; #if CLR_2_0 || CLR_4_0 string settingsFile = System.Configuration.ConfigurationManager.AppSettings["settingsFile"]; #else string settingsFile = System.Configuration.ConfigurationSettings.AppSettings["settingsFile"]; #endif if ( settingsFile == null ) settingsFile = Path.Combine( NUnitConfiguration.ApplicationDirectory, settingsFileName ); this.storage = new XmlSettingsStorage( settingsFile, writeable ); if ( File.Exists( settingsFile ) ) storage.LoadSettings(); else if (writeable) ConvertLegacySettings(); } #region IService Implementation public void InitializeService() { } public void UnloadService() { if ( writeable ) storage.SaveSettings(); this.Dispose(); } #endregion #region ConvertLegacySettings void ConvertLegacySettings() { RegistryKey key = Registry.CurrentUser.OpenSubKey( NUnitRegistry.KEY ); if ( key == null ) key = Registry.CurrentUser.OpenSubKey( NUnitRegistry.LEGACY_KEY ); if ( key != null ) { using( ISettingsStorage legacyStorage = new RegistrySettingsStorage( key ) ) { new LegacySettingsConverter( legacyStorage, storage ).Convert(); } storage.SaveSettings(); } } private class LegacySettingsConverter : SettingsGroup { private ISettingsStorage legacy; public LegacySettingsConverter( ISettingsStorage legacy, ISettingsStorage current ) : base( current ) { this.legacy = legacy; } public void Convert() { Convert( "Form.x-location", "Gui.MainForm.Left" ); Convert( "Form.x-location", "Gui.MiniForm.Left" ); Convert( "Form.y-location", "Gui.MainForm.Top" ); Convert( "Form.y-location", "Gui.MiniForm.Top" ); Convert( "Form.width", "Gui.MainForm.Width" ); Convert( "Form.width", "Gui.MiniForm.Width" ); Convert( "Form.height", "Gui.MainForm.Height" ); Convert( "Form.height", "Gui.MiniForm.Height" ); Convert( "Form.maximized", "Gui.MainForm.Maximized", "False", "True" ); Convert( "Form.maximized", "Gui.MiniForm.Maximized", "False", "True" ); Convert( "Form.font", "Gui.MainForm.Font" ); Convert( "Form.font", "Gui.MiniForm.Font" ); Convert( "Form.tree-splitter-position", "Gui.MainForm.SplitPosition"); Convert( "Form.tab-splitter-position", "Gui.ResultTabs.ErrorsTabSplitterPosition"); Convert( "Options.TestLabels", "Gui.ResultTabs.DisplayTestLabels", "False", "True" ); Convert( "Options.FailureToolTips", "Gui.ResultTabs.ErrorTab.ToolTipsEnabled", "False", "True" ); Convert( "Options.EnableWordWrapForFailures", "Gui.ResultTabs.ErrorTab.WordWrapEnabled", "False", "True" ); Convert( "Options.InitialTreeDisplay", "Gui.TestTree.InitialTreeDisplay", "Auto", "Expand", "Collapse", "HideTests" ); Convert( "Options.ShowCheckBoxes", "Gui.TestTree.ShowCheckBoxes", "False", "True" ); Convert( "Options.LoadLastProject", "Options.LoadLastProject", "False", "True" ); Convert( "Options.ClearResults", "Options.TestLoader.ClearResultsOnReload", "False", "True" ); Convert( "Options.ReloadOnChange", "Options.TestLoader.ReloadOnChange", "False", "True" ); Convert( "Options.RerunOnChange", "Options.TestLoader.RerunOnChange", "False", "True" ); Convert( "Options.ReloadOnRun", "Options.TestLoader.ReloadOnRun", "False", "True" ); Convert( "Options.MergeAssemblies", "Options.TestLoader.MergeAssemblies", "False", "True" ); //Convert( "Options.MultiDomain", "Options.TestLoader.MultiDomain", "False", "True" ); Convert( "Options.AutoNamespaceSuites", "Options.TestLoader.AutoNamespaceSuites", "False", "True" ); Convert( "Options.VisualStudioSupport", "Options.TestLoader.VisualStudioSupport", "False", "True" ); Convert( "Recent-Projects.MaxFiles", "RecentProjects.MaxFiles" ); object val = legacy.GetSetting("Options.MultiDomain"); if (val != null && (bool)val) this.SaveSetting("Options.TestLoader.DomainUsage", NUnit.Core.DomainUsage.Multiple); int maxFiles = this.GetSetting( "RecentProjects.MaxFiles", 5 ); for( int i = 1; i <= maxFiles; i++ ) { string fileKey = string.Format( "File{0}", i ); object fileEntry = legacy.GetSetting( "Recent-Projects." + fileKey ); if ( fileEntry != null ) this.SaveSetting( "RecentProjects." + fileKey, fileEntry ); } } private void Convert( string legacyName, string currentName, params string[]values ) { object val = legacy.GetSetting( legacyName ); if ( val != null ) { if ( val is int && values != null ) { int ival = (int)val; if ( ival >= 0 && ival < values.Length ) val = values[(int)val]; } this.SaveSetting( currentName, val ); } } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services/AddinRegistry.cs0000664000175000017500000000350211504175260024720 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Core; using NUnit.Core.Extensibility; namespace NUnit.Util { /// /// Summary description for AddinRegistry. /// public class AddinRegistry : MarshalByRefObject, IAddinRegistry, IService { #region Instance Fields private ArrayList addins = new ArrayList(); #endregion #region IAddinRegistry Members public void Register(Addin addin) { addins.Add( addin ); } public IList Addins { get { return addins; } } public bool IsAddinRegistered(string name) { return FindAddinByName(name) != null; } public void SetStatus( string name, AddinStatus status, string message ) { Addin addin = FindAddinByName(name); if (addin != null) { addin.Status = status; addin.Message = message; } } private Addin FindAddinByName(string name) { foreach (Addin addin in addins) if (addin.Name == name) return addin; return null; } #endregion #region IService Members public void InitializeService() { } public void UnloadService() { } #endregion #region InitializeLifetimeService public override object InitializeLifetimeService() { return null; } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Transform.resx0000664000175000017500000001776511504175260022734 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method='text'/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="test-results"> <xsl:text>Tests run: </xsl:text> <xsl:value-of select="@total"/> <xsl:text>, Errors: </xsl:text> <xsl:value-of select="@errors"/> <xsl:text>, Failures: </xsl:text> <xsl:value-of select="@failures"/> <xsl:text>, Time: </xsl:text> <xsl:value-of select="test-suite/@time"/> <xsl:text> seconds </xsl:text> <xsl:text> Not run: </xsl:text> <xsl:value-of select="@not-run"/> <xsl:text>, Invalid: </xsl:text> <xsl:value-of select="@invalid"/> <xsl:text>, Ignored: </xsl:text> <xsl:value-of select="@ignored"/> <xsl:text>, Skipped: </xsl:text> <xsl:value-of select="@skipped"/> <xsl:text> </xsl:text> <xsl:if test="//test-suite[failure]"><xsl:text>Test Fixture SetUp Failures: </xsl:text></xsl:if> <xsl:apply-templates select="//test-suite[failure]"/> <xsl:if test="//test-case[failure]"><xsl:text>Test Case Failures: </xsl:text></xsl:if> <xsl:apply-templates select="//test-case[failure]"/> <xsl:if test="//test-case[@executed='False']"><xsl:text>Tests not run: </xsl:text></xsl:if> <xsl:apply-templates select="//test-case[@executed='False']"/> <xsl:text disable-output-escaping='yes'>&#xD;&#xA;</xsl:text> </xsl:template> <xsl:template match="test-case|test-suite"> <xsl:value-of select="position()"/><xsl:text>) </xsl:text> <xsl:value-of select="@name"/> <xsl:text> : </xsl:text> <xsl:value-of select="child::node()/message"/> <xsl:text disable-output-escaping='yes'>&#xD;&#xA;</xsl:text> <xsl:if test="failure"> <xsl:value-of select="failure/stack-trace"/> <xsl:text> </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> NUnit-2.6.0.12051/src/ClientUtilities/util/RegistrySettingsStorage.cs0000664000175000017500000001055111504175260025245 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using Microsoft.Win32; namespace NUnit.Util { /// /// Implementation of SettingsStorage for NUnit user settings, /// based on storage of settings in the registry. /// /// Setting names containing a dot are interpreted as a /// reference to a subkey. Only the first dot is used /// in this way, since the feature is only intended /// to support legacy registry settings, which are not /// nested any deeper. /// public class RegistrySettingsStorage : ISettingsStorage { #region Instance Variables /// /// If not null, the registry key for this storage /// private RegistryKey storageKey; #endregion #region Construction and Disposal /// /// Construct a storage on top of a pre-created registry key /// /// public RegistrySettingsStorage( RegistryKey storageKey ) { this.storageKey = storageKey; } #endregion #region Properties /// /// The registry key used to hold this storage /// public RegistryKey StorageKey { get { return storageKey; } } #endregion #region ISettingsStorage Members /// /// Load a setting from this storage /// /// Name of the setting to load /// Value of the setting public object GetSetting( string settingName ) { int dot = settingName.IndexOf( '.' ); if ( dot < 0 ) return storageKey.GetValue( settingName ); using( RegistryKey subKey = storageKey.OpenSubKey( settingName.Substring( 0, dot ) ) ) { if ( subKey != null ) return subKey.GetValue( settingName.Substring( dot + 1 ) ); } return null; } /// /// Remove a setting from the storage /// /// Name of the setting to remove public void RemoveSetting( string settingName ) { int dot = settingName.IndexOf( '.' ); if ( dot < 0 ) storageKey.DeleteValue( settingName, false ); else { using( RegistryKey subKey = storageKey.OpenSubKey( settingName.Substring( 0, dot ), true ) ) { if ( subKey != null ) subKey.DeleteValue( settingName.Substring( dot + 1 ) ); } } } public void RemoveGroup( string groupName ) { storageKey.DeleteSubKeyTree( groupName ); } /// /// Save a setting in this storage /// /// Name of the setting to save /// Value to be saved public void SaveSetting( string settingName, object settingValue ) { object val = settingValue; if ( val is bool ) val = ((bool)val) ? 1 : 0; int dot = settingName.IndexOf( '.' ); if ( dot < 0 ) storageKey.SetValue( settingName, val ); else { using( RegistryKey subKey = storageKey.CreateSubKey( settingName.Substring( 0, dot ) ) ) { subKey.SetValue( settingName.Substring( dot + 1 ), val ); } } } /// /// Make a new child storage under this one /// /// Name of the child storage to make /// New storage public ISettingsStorage MakeChildStorage( string storageName ) { return new RegistrySettingsStorage( storageKey.CreateSubKey( storageName ) ); } /// /// LoadSettings does nothing in this implementation, since the /// registry is accessed directly. /// public void LoadSettings() { } /// /// SaveSettings does nothing in this implementation, since the /// registry is accessed directly. /// public void SaveSettings() { } #endregion #region IDisposable Members /// /// Dispose of this object by closing the storage key, if any /// public void Dispose() { if ( storageKey != null ) storageKey.Close(); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Guard.cs0000664000175000017500000000271111720011506021420 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { #if CLR_2_0 || CLR_4_0 public static class Guard #else public class Guard #endif { public static void ArgumentNotNull(object value, string name) { if (value == null) throw new ArgumentNullException("Argument " + name + " must not be null", name); } public static void ArgumentNotNullOrEmpty(string value, string name) { ArgumentNotNull(value, name); if (value == string.Empty) throw new ArgumentException("Argument " + name +" must not be the empty string", name); } public static void NotNull(object value, string name) { if (value == null) throw new InvalidOperationException("Invalid object state: " + name + " is null"); } public static void Validate(ISelfValidating obj) { if (!obj.Validate()) throw new InvalidOperationException(obj.Message); } } public interface ISelfValidating { bool Validate(); string Message { get; } } } NUnit-2.6.0.12051/src/ClientUtilities/util/RecentFiles.cs0000664000175000017500000000315511504175260022574 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Util { /// /// The RecentFiles interface is used to isolate the app /// from various implementations of recent files. /// public interface RecentFiles { /// /// The max number of files saved /// int MaxFiles { get; set; } /// /// The current number of saved files /// int Count { get; } /// /// Get a list of all the file entries /// /// The most recent file list RecentFilesCollection Entries { get; } /// /// Set the most recent file entry, reordering /// the saved names as needed and removing the oldest /// if the max number of files would be exceeded. /// void SetMostRecent( RecentFileEntry entry ); /// /// Set the most recent file name, reordering /// the saved names as needed and removing the oldest /// if the max number of files would be exceeded. /// The current CLR version is used to create the entry. /// void SetMostRecent( string fileName ); /// /// Remove a file from the list /// /// The name of the file to remove void Remove( string fileName ); } } NUnit-2.6.0.12051/src/ClientUtilities/util/ProjectConfig.cs0000664000175000017500000001417011504175260023124 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Text; using System.Collections; using System.IO; using NUnit.Core; namespace NUnit.Util { public enum BinPathType { Auto, Manual, None } public class ProjectConfig { #region Instance Variables /// /// The name of this config /// private string name; /// /// IProject interface of containing project /// protected NUnitProject project = null; /// /// List of the names of the assemblies /// private AssemblyList assemblies; /// /// Base path specific to this configuration /// private string basePath; /// /// Our configuration file, if specified /// private string configFile; /// /// Private bin path, if specified /// private string binPath; /// /// True if assembly paths should be added to bin path /// private BinPathType binPathType = BinPathType.Auto; /// /// The CLR under which tests are to be run /// private RuntimeFramework runtimeFramework; #endregion #region Constructor public ProjectConfig( string name ) { this.name = name; this.assemblies = new AssemblyList(); assemblies.Changed += new EventHandler( assemblies_Changed ); } #endregion #region Properties and Events public NUnitProject Project { set { project = value; } } public string Name { get { return name; } set { if ( name != value ) { name = value; NotifyProjectOfChange(); } } } private bool BasePathSpecified { get { return project.BasePathSpecified || this.basePath != null && this.basePath != ""; } } /// /// The base directory for this config - used /// as the application base for loading tests. /// public string BasePath { get { if ( project == null || project.BasePath == null ) return basePath; if ( basePath == null ) return project.BasePath; return Path.Combine( project.BasePath, basePath ); } set { if ( BasePath != value ) { basePath = value; NotifyProjectOfChange(); } } } /// /// The base path relative to the project base /// public string RelativeBasePath { get { if ( project == null || basePath == null || !Path.IsPathRooted( basePath ) ) return basePath; return PathUtils.RelativePath( project.BasePath, basePath ); } } private bool ConfigurationFileSpecified { get { return configFile != null; } } public string ConfigurationFile { get { return configFile == null && project != null ? project.ConfigurationFile : configFile; } set { if ( ConfigurationFile != value ) { configFile = value; NotifyProjectOfChange(); } } } public string ConfigurationFilePath { get { return BasePath != null && ConfigurationFile != null ? Path.Combine( BasePath, ConfigurationFile ) : ConfigurationFile; } } private bool PrivateBinPathSpecified { get { return binPath != null; } } /// /// The Path.PathSeparator-separated path containing all the /// assemblies in the list. /// public string PrivateBinPath { get { return binPath; } set { if ( binPath != value ) { binPath = value; binPathType = binPath == null ? BinPathType.Auto : BinPathType.Manual; NotifyProjectOfChange(); } } } /// /// How our PrivateBinPath is generated /// public BinPathType BinPathType { get { return binPathType; } set { if ( binPathType != value ) { binPathType = value; NotifyProjectOfChange(); } } } /// /// Return our AssemblyList /// public AssemblyList Assemblies { get { return assemblies; } } public RuntimeFramework RuntimeFramework { get { return runtimeFramework; } set { if ( runtimeFramework != value ) { runtimeFramework = value; NotifyProjectOfChange(); } } } #endregion public TestPackage MakeTestPackage() { TestPackage package = new TestPackage( project.ProjectPath ); if ( !project.IsAssemblyWrapper ) foreach ( string assembly in this.Assemblies ) package.Assemblies.Add( assembly ); if ( this.BasePathSpecified || this.PrivateBinPathSpecified || this.ConfigurationFileSpecified ) { package.BasePath = this.BasePath; package.PrivateBinPath = this.PrivateBinPath; package.ConfigurationFile = this.ConfigurationFile; } package.AutoBinPath = this.BinPathType == BinPathType.Auto; if (this.RuntimeFramework != null) package.Settings["RuntimeFramework"] = this.RuntimeFramework; if (project.ProcessModel != ProcessModel.Default) package.Settings["ProcessModel"] = project.ProcessModel; if (project.DomainUsage != DomainUsage.Default) package.Settings["DomainUsage"] = project.DomainUsage; return package; } private void assemblies_Changed( object sender, EventArgs e ) { NotifyProjectOfChange(); } private void NotifyProjectOfChange() { if (project != null) { project.IsDirty = true; if (ReferenceEquals(this, project.ActiveConfig)) project.HasChangesRequiringReload = true; } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/Services.cs0000664000175000017500000000711511544454420022156 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; using NUnit.Core.Extensibility; namespace NUnit.Util { /// /// Services is a utility class, which is used to provide access /// to services in a more simple way than is supported by te /// ServiceManager class itself. /// public class Services { #region AddinManager private static AddinManager addinManager; public static AddinManager AddinManager { get { if (addinManager == null ) addinManager = (AddinManager)ServiceManager.Services.GetService( typeof( AddinManager ) ); return addinManager; } } #endregion #region AddinRegistry private static IAddinRegistry addinRegistry; public static IAddinRegistry AddinRegistry { get { if (addinRegistry == null) addinRegistry = (IAddinRegistry)ServiceManager.Services.GetService( typeof( IAddinRegistry ) ); return addinRegistry; } } #endregion #region DomainManager private static DomainManager domainManager; public static DomainManager DomainManager { get { if ( domainManager == null ) domainManager = (DomainManager)ServiceManager.Services.GetService( typeof( DomainManager ) ); return domainManager; } } #endregion #region UserSettings private static ISettings userSettings; public static ISettings UserSettings { get { if ( userSettings == null ) userSettings = (ISettings)ServiceManager.Services.GetService( typeof( ISettings ) ); // Temporary fix needed to run TestDomain tests in test AppDomain // TODO: Figure out how to set up the test domain correctly if ( userSettings == null ) userSettings = new SettingsService(); return userSettings; } } #endregion #region RecentFilesService #if CLR_2_0 || CLR_4_0 private static RecentFiles recentFiles; public static RecentFiles RecentFiles { get { if ( recentFiles == null ) recentFiles = (RecentFiles)ServiceManager.Services.GetService( typeof( RecentFiles ) ); return recentFiles; } } #endif #endregion #region TestLoader #if CLR_2_0 || CLR_4_0 private static TestLoader loader; public static TestLoader TestLoader { get { if ( loader == null ) loader = (TestLoader)ServiceManager.Services.GetService( typeof( TestLoader ) ); return loader; } } #endif #endregion #region TestAgency private static TestAgency agency; public static TestAgency TestAgency { get { if ( agency == null ) agency = (TestAgency)ServiceManager.Services.GetService( typeof( TestAgency ) ); // Temporary fix needed to run ProcessRunner tests in test AppDomain // TODO: Figure out how to set up the test domain correctly // if ( agency == null ) // { // agency = new TestAgency(); // agency.Start(); // } return agency; } } #endregion #region ProjectLoader private static ProjectService projectService; public static ProjectService ProjectService { get { if ( projectService == null ) projectService = (ProjectService) ServiceManager.Services.GetService( typeof( ProjectService ) ); return projectService; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/XmlSettingsStorage.cs0000664000175000017500000000552711504175260024204 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; using System.Collections; using System.ComponentModel; namespace NUnit.Util { /// /// Summary description for XmlSettingsStorage. /// public class XmlSettingsStorage : MemorySettingsStorage { private string filePath; private bool writeable; public XmlSettingsStorage(string filePath) : this(filePath, true) { } public XmlSettingsStorage( string filePath, bool writeable ) { this.filePath = filePath; this.writeable = writeable; } public override void LoadSettings() { FileInfo info = new FileInfo(filePath); if ( !info.Exists || info.Length == 0 ) return; try { XmlDocument doc = new XmlDocument(); doc.Load( filePath ); foreach( XmlElement element in doc.DocumentElement["Settings"].ChildNodes ) { if ( element.Name != "Setting" ) throw new ApplicationException( "Unknown element in settings file: " + element.Name ); if ( !element.HasAttribute( "name" ) ) throw new ApplicationException( "Setting must have 'name' attribute" ); if ( !element.HasAttribute( "value" ) ) throw new ApplicationException( "Setting must have 'value' attribute" ); settings[ element.GetAttribute( "name" ) ] = element.GetAttribute( "value" ); } } catch( Exception ex ) { throw new ApplicationException( "Error loading settings file", ex ); } } public override void SaveSettings() { if (!this.writeable) throw new InvalidOperationException("Attempted to write to a non-writeable Settings Storage"); string dirPath = Path.GetDirectoryName( filePath ); if ( !Directory.Exists( dirPath ) ) Directory.CreateDirectory( dirPath ); XmlTextWriter writer = new XmlTextWriter( filePath, System.Text.Encoding.UTF8 ); writer.Formatting = Formatting.Indented; writer.WriteProcessingInstruction( "xml", "version=\"1.0\"" ); writer.WriteStartElement( "NUnitSettings" ); writer.WriteStartElement( "Settings" ); ArrayList keys = new ArrayList( settings.Keys ); keys.Sort(); foreach( string name in keys ) { object val = settings[name]; if ( val != null ) { writer.WriteStartElement( "Setting"); writer.WriteAttributeString( "name", name ); writer.WriteAttributeString( "value", val.ToString() ); writer.WriteEndElement(); } } writer.WriteEndElement(); writer.WriteEndElement(); writer.Close(); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/ProjectConfigCollection.cs0000664000175000017500000000465111504175260025143 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Util { /// /// Summary description for ProjectConfigCollection. /// public class ProjectConfigCollection : CollectionBase { protected NUnitProject project; public ProjectConfigCollection( NUnitProject project ) { this.project = project; } #region Properties public ProjectConfig this[int index] { get { return (ProjectConfig)InnerList[index]; } } public ProjectConfig this[string name] { get { int index = IndexOf( name ); return index >= 0 ? (ProjectConfig)InnerList[index]: null; } } #endregion #region Methods public void Add( ProjectConfig config ) { List.Add( config ); config.Project = this.project; } public void Add( string name ) { Add( new ProjectConfig( name ) ); } public void Remove( string name ) { int index = IndexOf( name ); if ( index >= 0 ) { RemoveAt( index ); } } private int IndexOf( string name ) { for( int index = 0; index < InnerList.Count; index++ ) { ProjectConfig config = (ProjectConfig)InnerList[index]; if( config.Name == name ) return index; } return -1; } public bool Contains( ProjectConfig config ) { return InnerList.Contains( config ); } public bool Contains( string name ) { return IndexOf( name ) >= 0; } protected override void OnRemove(int index, object value) { if (project != null) { ProjectConfig config = value as ProjectConfig; project.IsDirty = true; if ( config.Name == project.ActiveConfigName ) project.HasChangesRequiringReload = true; } } protected override void OnInsertComplete( int index, object obj ) { if (project != null) { project.IsDirty = true; if (this.Count == 1) project.HasChangesRequiringReload = true; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/MemorySettingsStorage.cs0000664000175000017500000000343511504175260024710 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Util { /// /// MemorySettingsStorage is used to hold settings for /// the NUnit tests and also serves as the base class /// for XmlSettingsStorage. /// public class MemorySettingsStorage : ISettingsStorage { protected Hashtable settings = new Hashtable(); #region ISettingsStorage Members public object GetSetting(string settingName) { return settings[settingName]; } public void RemoveSetting(string settingName) { settings.Remove( settingName ); } public void RemoveGroup( string groupName ) { ArrayList keysToRemove = new ArrayList(); string prefix = groupName; if ( !prefix.EndsWith(".") ) prefix = prefix + "."; foreach( string key in settings.Keys ) if ( key.StartsWith( prefix ) ) keysToRemove.Add( key ); foreach( string key in keysToRemove ) settings.Remove( key ); } public void SaveSetting(string settingName, object settingValue) { settings[settingName] = settingValue; } public ISettingsStorage MakeChildStorage(string name) { return new MemorySettingsStorage(); } public virtual void LoadSettings() { // No action required } public virtual void SaveSettings() { // No action required } #endregion #region IDisposable Members public void Dispose() { // TODO: Add MemorySettingsStorage.Dispose implementation } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Extensibility/0000775000175000017500000000000011742560362022677 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/util/Extensibility/ProjectConverterCollection.cs0000664000175000017500000000362411504175260030540 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Util.Extensibility { /// /// Summary description for ProjectConverterCollection. /// public class ProjectConverterCollection : IProjectConverter, IExtensionPoint { private ArrayList converters = new ArrayList(); public ProjectConverterCollection() { // // TODO: Add constructor logic here // } #region IProjectConverter Members public bool CanConvertFrom(string path) { foreach( IProjectConverter converter in converters ) if ( converter.CanConvertFrom( path ) ) return true; return false; } public NUnitProject ConvertFrom(string path) { foreach( IProjectConverter converter in converters ) if ( converter.CanConvertFrom( path ) ) return converter.ConvertFrom( path ); return null; } #endregion #region IExtensionPoint Members public void Remove(object extension) { // TODO: Add ProjectConverterCollection.Remove implementation } public void Install(object extension) { // TODO: Add ProjectConverterCollection.Install implementation } public void Install(object extension, int priority) { // TODO: Add ProjectConverterCollection.Install implementation } public IExtensionHost Host { get { // TODO: Add ProjectConverterCollection.Host getter implementation return null; } } public string Name { get { return "Converters"; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/Extensibility/IProjectConverter.cs0000664000175000017500000000177211504175260026637 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util.Extensibility { /// /// The IProjectConverter interface is implemented by any class /// that knows how to convert a foreign project format to an /// NUnitProject. /// public interface IProjectConverter { /// /// Returns true if the file indicated is one that this /// converter knows how to convert. /// /// /// bool CanConvertFrom( string path ); /// /// Converts an external project returning an NUnitProject /// /// /// NUnitProject ConvertFrom( string path ); } } NUnit-2.6.0.12051/src/ClientUtilities/util/VSProjectConfig.cs0000664000175000017500000000176511504175260023403 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Specialized; namespace NUnit.Util { /// /// Originally, we used the same ProjectConfig class for both /// NUnit and Visual Studio projects. Since we really do very /// little with VS Projects, this class has been created to /// hold the name and the collection of assembly paths. /// public class VSProjectConfig { private string name; private StringCollection assemblies = new StringCollection(); public VSProjectConfig( string name ) { this.name = name; } public string Name { get { return name; } } public StringCollection Assemblies { get { return assemblies; } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/CategoryExpression.cs0000664000175000017500000000646111504175260024231 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Core; using NUnit.Core.Filters; namespace NUnit.Util { /// /// CategoryExpression parses strings representing boolean /// combinations of categories according to the following /// grammar: /// CategoryName ::= string not containing any of ',', '&', '+', '-' /// CategoryFilter ::= CategoryName | CategoryFilter ',' CategoryName /// CategoryPrimitive ::= CategoryFilter | '-' CategoryPrimitive /// CategoryTerm ::= CategoryPrimitive | CategoryTerm '&' CategoryPrimitive /// public class CategoryExpression { static readonly char[] ops = new char[] { ',', ';', '-', '|', '+', '(', ')' }; private string text; private int next; private string token; private TestFilter filter; public CategoryExpression(string text) { this.text = text; this.next = 0; } public TestFilter Filter { get { if( filter == null ) { filter = GetToken() == null ? TestFilter.Empty : GetExpression(); } return filter; } } private TestFilter GetExpression() { TestFilter term = GetTerm(); if ( token != "|" ) return term; OrFilter filter = new OrFilter( term ); while ( token == "|" ) { GetToken(); filter.Add( GetTerm() ); } return filter; } private TestFilter GetTerm() { TestFilter prim = GetPrimitive(); if ( token != "+" && token != "-" ) return prim; AndFilter filter = new AndFilter( prim ); while ( token == "+"|| token == "-" ) { string tok = token; GetToken(); prim = GetPrimitive(); filter.Add( tok == "-" ? new NotFilter( prim ) : prim ); } return filter; } private TestFilter GetPrimitive() { if( token == "-" ) { GetToken(); return new NotFilter( GetPrimitive() ); } else if( token == "(" ) { GetToken(); TestFilter expr = GetExpression(); GetToken(); // Skip ')' return expr; } return GetCategoryFilter(); } private CategoryFilter GetCategoryFilter() { CategoryFilter filter = new CategoryFilter( token ); while( GetToken() == "," || token == ";" ) filter.AddCategory( GetToken() ); return filter; } public string GetToken() { SkipWhiteSpace(); if ( EndOfText() ) token = null; else if ( NextIsOperator() ) token = text.Substring(next++, 1); else { int index2 = text.IndexOfAny( ops, next ); if ( index2 < 0 ) index2 = text.Length; token = text.Substring( next, index2 - next ).TrimEnd(); next = index2; } return token; } private void SkipWhiteSpace() { while( next < text.Length && Char.IsWhiteSpace( text[next] ) ) ++next; } private bool EndOfText() { return next >= text.Length; } private bool NextIsOperator() { foreach( char op in ops ) if( op == text[next] ) return true; return false; } } } NUnit-2.6.0.12051/src/ClientUtilities/util/AggregatingTestRunner.cs0000664000175000017500000003024611715742236024652 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Util { using System; using System.Collections; using System.IO; using NUnit.Core; #region AggregatingTestRunner /// /// AggregatingTestRunner allows running multiple TestRunners /// and combining the results. /// public abstract class AggregatingTestRunner : MarshalByRefObject, TestRunner, EventListener { private Logger log; private Logger Log { get { if (log == null) log = InternalTrace.GetLogger(this.GetType()); return log; } } static int AggregateTestID = 1000; #region Instance Variables /// /// Our runner ID /// protected int runnerID; /// /// The downstream TestRunners /// protected ArrayList runners; /// /// Indicates whether we should run test assemblies in parallel /// private bool runInParallel; /// /// The loaded test suite /// protected TestNode aggregateTest; /// /// The result of the last run /// private TestResult testResult; /// /// The event listener for the currently running test /// protected EventListener listener; protected TestName testName; #endregion #region Constructors public AggregatingTestRunner() : this( 0 ) { } public AggregatingTestRunner( int runnerID ) { this.runnerID = runnerID; this.testName = new TestName(); testName.TestID = new TestID( AggregateTestID ); testName.RunnerID = this.runnerID; testName.FullName = testName.Name = "Not Loaded"; } #endregion #region Properties public virtual int ID { get { return runnerID; } } public virtual bool Running { get { foreach( TestRunner runner in runners ) if ( runner.Running ) return true; return false; } } public virtual IList AssemblyInfo { get { ArrayList info = new ArrayList(); foreach( TestRunner runner in runners ) info.AddRange( runner.AssemblyInfo ); return info; } } public virtual ITest Test { get { if ( aggregateTest == null && runners != null ) { // Count non-null tests, in case we specified a fixture int count = 0; foreach( TestRunner runner in runners ) if ( runner.Test != null ) ++count; // Copy non-null tests to an array int index = 0; ITest[] tests = new ITest[count]; foreach( TestRunner runner in runners ) if ( runner.Test != null ) tests[index++] = runner.Test; // Return master node containing all the tests aggregateTest = new TestNode( testName, tests ); } return aggregateTest; } } public virtual TestResult TestResult { get { return testResult; } } #endregion #region Load and Unload Methods public bool Load(TestPackage package) { Log.Info("Loading " + package.Name); this.testName.FullName = this.testName.Name = package.FullName; runners = new ArrayList(); int nfound = 0; int index = 0; string targetAssemblyName = null; if (package.TestName != null && package.Assemblies.Contains(package.TestName)) { targetAssemblyName = package.TestName; package.TestName = null; } // NOTE: This is experimental. A normally created test package // will never have this setting. if (package.Settings.Contains("RunInParallel")) { this.runInParallel = true; package.Settings.Remove("RunInParallel"); } //string basePath = package.BasePath; //if (basePath == null) // basePath = Path.GetDirectoryName(package.FullName); //string configFile = package.ConfigurationFile; //if (configFile == null && package.Name != null && !package.IsSingleAssembly) // configFile = Path.ChangeExtension(package.Name, ".config"); foreach (string assembly in package.Assemblies) { if (targetAssemblyName == null || targetAssemblyName == assembly) { TestRunner runner = CreateRunner(this.runnerID * 100 + index + 1); TestPackage p = new TestPackage(assembly); p.AutoBinPath = package.AutoBinPath; p.ConfigurationFile = package.ConfigurationFile; p.BasePath = package.BasePath; p.PrivateBinPath = package.PrivateBinPath; p.TestName = package.TestName; foreach (object key in package.Settings.Keys) p.Settings[key] = package.Settings[key]; if (package.TestName == null) { runners.Add(runner); if (runner.Load(p)) nfound++; } else if (runner.Load(p)) { runners.Add(runner); nfound++; } } } Log.Info("Load complete"); if (package.TestName == null && targetAssemblyName == null) return nfound == package.Assemblies.Count; else return nfound > 0; } protected abstract TestRunner CreateRunner(int runnerID); public virtual void Unload() { if (aggregateTest != null) Log.Info("Unloading " + Path.GetFileName(aggregateTest.TestName.Name)); if (runners != null) foreach (TestRunner runner in runners) runner.Unload(); aggregateTest = null; Log.Info("Unload complete"); } #endregion #region CountTestCases public virtual int CountTestCases( ITestFilter filter ) { int count = 0; foreach( TestRunner runner in runners ) count += runner.CountTestCases( filter ); return count; } #endregion #region Methods for Running Tests public virtual TestResult Run(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { Log.Info("Run - EventListener={0}", listener.GetType().Name); // Save active listener for derived classes this.listener = listener; ITest[] tests = new ITest[runners.Count]; for( int index = 0; index < runners.Count; index++ ) tests[index] = ((TestRunner)runners[index]).Test; string name = this.testName.Name; int count = this.CountTestCases(filter); Log.Info("Signalling RunStarted({0},{1})", name, count); this.listener.RunStarted(name, count); long startTime = DateTime.Now.Ticks; TestResult result = new TestResult(new TestInfo(testName, tests)); if (this.runInParallel) { foreach (TestRunner runner in runners) if (filter.Pass(runner.Test)) runner.BeginRun(this, filter, tracing, logLevel); result = this.EndRun(); } else { foreach (TestRunner runner in runners) if (filter.Pass(runner.Test)) result.AddResult(runner.Run(this, filter, tracing, logLevel)); } long stopTime = DateTime.Now.Ticks; double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond; result.Time = time; this.listener.RunFinished( result ); this.testResult = result; return result; } public virtual void BeginRun( EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel ) { // Save active listener for derived classes this.listener = listener; Log.Info("BeginRun"); // ThreadedTestRunner will call our Run method on a separate thread ThreadedTestRunner threadedRunner = new ThreadedTestRunner(this); threadedRunner.BeginRun(listener, filter, tracing, logLevel); } public virtual TestResult EndRun() { Log.Info("EndRun"); TestResult suiteResult = new TestResult(Test as TestInfo); foreach( TestRunner runner in runners ) suiteResult.Results.Add( runner.EndRun() ); return suiteResult; } public virtual void CancelRun() { foreach( TestRunner runner in runners ) runner.CancelRun(); } public virtual void Wait() { foreach( TestRunner runner in runners ) runner.Wait(); } #endregion #region EventListener Members public void TestStarted(TestName testName) { this.listener.TestStarted( testName ); } public void RunStarted(string name, int testCount) { // TODO: We may want to count how many runs are started // Ignore - we provide our own } public void RunFinished(Exception exception) { // Ignore - we provide our own } void NUnit.Core.EventListener.RunFinished(TestResult result) { if (this.runInParallel) { foreach (TestRunner runner in runners) if (runner.Running) return; this.testResult = new TestResult(this.aggregateTest); foreach (TestRunner runner in runners) this.testResult.AddResult(runner.TestResult); listener.RunFinished(this.TestResult); } } public void SuiteFinished(TestResult result) { this.listener.SuiteFinished( result ); } public void TestFinished(TestResult result) { this.listener.TestFinished( result ); } public void UnhandledException(Exception exception) { this.listener.UnhandledException( exception ); } public void TestOutput(TestOutput testOutput) { this.listener.TestOutput( testOutput ); } public void SuiteStarted(TestName suiteName) { this.listener.SuiteStarted( suiteName ); } #endregion #region InitializeLifetimeService Override public override object InitializeLifetimeService() { return null; } #endregion #region IDisposable Members public void Dispose() { foreach (TestRunner runner in runners) if (runner != null) runner.Dispose(); } #endregion } #endregion #region MultipleTestDomainRunner /// /// Summary description for MultipleTestDomainRunner. /// public class MultipleTestDomainRunner : AggregatingTestRunner { #region Constructors public MultipleTestDomainRunner() : base(0) { } public MultipleTestDomainRunner(int runnerID) : base(runnerID) { } #endregion #region CreateRunner protected override TestRunner CreateRunner(int runnerID) { return new TestDomain(runnerID); } #endregion } #endregion #region MultipleTestProcessRunner #if CLR_2_0 || CLR_4_0 public class MultipleTestProcessRunner : AggregatingTestRunner { #region Constructors public MultipleTestProcessRunner() : base(0) { } public MultipleTestProcessRunner(int runnerID) : base(runnerID) { } #endregion #region CreateRunner protected override TestRunner CreateRunner(int runnerID) { return new ProcessRunner(runnerID); } #endregion } #endif #endregion } NUnit-2.6.0.12051/src/ClientUtilities/util/nunit.util.build0000664000175000017500000001136311717527744023212 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/util/StackTraceFilter.cs0000664000175000017500000000265711504175260023571 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util { using System; using System.IO; /// /// Summary description for StackTraceFilter. /// public class StackTraceFilter { public static string Filter(string stack) { if(stack == null) return null; StringWriter sw = new StringWriter(); StringReader sr = new StringReader(stack); try { string line; while ((line = sr.ReadLine()) != null) { if (!FilterLine(line)) sw.WriteLine(line.Trim()); } } catch (Exception) { return stack; } return sw.ToString(); } static bool FilterLine(string line) { string[] patterns = new string[] { "NUnit.Core.TestCase", "NUnit.Core.ExpectedExceptionTestCase", "NUnit.Core.TemplateTestCase", "NUnit.Core.TestResult", "NUnit.Core.TestSuite", "NUnit.Framework.Assertion", "NUnit.Framework.Assert", "System.Reflection.MonoMethod" }; for (int i = 0; i < patterns.Length; i++) { if (line.IndexOf(patterns[i]) > 0) return true; } return false; } } } NUnit-2.6.0.12051/src/ClientUtilities/util/RecentFilesCollection.cs0000664000175000017500000000240611504175260024606 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Util { /// /// Summary description for RecentFilesCollection. /// public class RecentFilesCollection : ReadOnlyCollectionBase { public void Add( RecentFileEntry entry ) { InnerList.Add( entry ); } public void Insert( int index, RecentFileEntry entry ) { InnerList.Insert( index, entry ); } public void Remove( string fileName ) { int index = IndexOf( fileName ); if ( index != -1 ) RemoveAt( index ); } public void RemoveAt( int index ) { InnerList.RemoveAt( index ); } public int IndexOf( string fileName ) { for( int index = 0; index < InnerList.Count; index++ ) if ( this[index].Path == fileName ) return index; return -1; } public RecentFileEntry this[int index] { get { return (RecentFileEntry)InnerList[index]; } } public void Clear() { InnerList.Clear(); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/IAssemblyWatcher.cs0000664000175000017500000000411211720432274023572 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Util { public delegate void AssemblyChangedHandler(string fullPath); /// /// AssemblyWatcher keeps track of one or more assemblies to /// see if they have changed. It incorporates a delayed notification /// and uses a standard event to notify any interested parties /// about the change. The path to the assembly is provided as /// an argument to the event handler so that one routine can /// be used to handle events from multiple watchers. /// public interface IAssemblyWatcher { /// /// Stops watching for changes. /// To release resources call FreeResources. /// void Stop(); /// /// Starts watching for assembly changes. /// You need to call Setup before start watching. /// void Start(); /// /// Initializes the watcher with assemblies to observe for changes. /// /// The delay in ms. /// The assemblies. #if CLR_2_0 || CLR_4_0 void Setup(int delayInMs, System.Collections.Generic.IList assemblies); #else void Setup(int delayInMs, System.Collections.IList assemblies); #endif /// /// Initializes the watcher with assemblies to observe for changes. /// /// The delay in ms. /// Name of the assembly file. void Setup(int delayInMs, string assemblyFileName); /// /// Releases all resources held by the watcher. /// void FreeResources(); /// /// Occurs when an assembly being watched has changed. /// event AssemblyChangedHandler AssemblyChanged; } }NUnit-2.6.0.12051/src/ClientUtilities/util/VSProjectConfigCollection.cs0000664000175000017500000000223111504175260025404 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Util { /// /// A simple collection to hold VSProjectConfigs. Originally, /// we used the (NUnit) ProjectConfigCollection, but the /// classes have since diverged. /// public class VSProjectConfigCollection : CollectionBase { public VSProjectConfig this[int index] { get { return List[index] as VSProjectConfig; } } public VSProjectConfig this[string name] { get { foreach ( VSProjectConfig config in InnerList ) if ( config.Name == name ) return config; return null; } } public void Add( VSProjectConfig config ) { List.Add( config ); } public bool Contains( string name ) { foreach( VSProjectConfig config in InnerList ) if ( config.Name == name ) return true; return false; } } } NUnit-2.6.0.12051/src/ClientUtilities/util/ProjectFormatException.cs0000664000175000017500000000241711504175260025027 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Util { /// /// Exception raised when loading a project file with /// an invalid format. /// public class ProjectFormatException : ApplicationException { #region Instance Variables private int lineNumber; private int linePosition; #endregion #region Constructors public ProjectFormatException() : base() {} public ProjectFormatException( string message ) : base( message ) {} public ProjectFormatException( string message, Exception inner ) : base( message, inner ) {} public ProjectFormatException( string message, int lineNumber, int linePosition ) : base( message ) { this.lineNumber = lineNumber; this.linePosition = linePosition; } #endregion #region Properties public int LineNumber { get { return lineNumber; } } public int LinePosition { get { return linePosition; } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/ProcessRunner.cs0000664000175000017500000000631411717005076023204 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Diagnostics; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Services; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Core; namespace NUnit.Util { /// /// Summary description for ProcessRunner. /// public class ProcessRunner : ProxyTestRunner { static Logger log = InternalTrace.GetLogger(typeof(ProcessRunner)); private TestAgent agent; private RuntimeFramework runtimeFramework; #region Constructors public ProcessRunner() : base( 0 ) { } public ProcessRunner( int runnerID ) : base( runnerID ) { } #endregion #region Properties public RuntimeFramework RuntimeFramework { get { return runtimeFramework; } } #endregion public override bool Load(TestPackage package) { log.Info("Loading " + package.Name); Unload(); runtimeFramework = package.Settings["RuntimeFramework"] as RuntimeFramework; if ( runtimeFramework == null ) runtimeFramework = RuntimeFramework.CurrentFramework; bool enableDebug = package.GetSetting("EnableDebug", false); bool loaded = false; try { if (this.agent == null) { this.agent = Services.TestAgency.GetAgent( runtimeFramework, 30000, enableDebug); if (this.agent == null) return false; } if ( this.TestRunner == null ) this.TestRunner = agent.CreateRunner(this.runnerID); loaded = base.Load (package); return loaded; } finally { // Clean up if the load failed if ( !loaded ) Unload(); } } public override void Unload() { if (Test != null) { log.Info("Unloading " + Path.GetFileName(Test.TestName.Name)); this.TestRunner.Unload(); this.TestRunner = null; } } #region IDisposable Members public override void Dispose() { // Do this first, because the next step will // make the downstream runner inaccessible. base.Dispose(); if (this.agent != null) { log.Info("Stopping remote agent"); try { agent.Stop(); } catch { // Ignore any exception } finally { this.agent = null; } } } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/VSProject.cs0000664000175000017500000002527611610162422022252 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; using System.Text.RegularExpressions; namespace NUnit.Util { /// /// This class allows loading information about /// configurations and assemblies in a Visual /// Studio project file and inspecting them. /// Only the most common project types are /// supported and an exception is thrown if /// an attempt is made to load an invalid /// file or one of an unknown type. /// public class VSProject { #region Static and Instance Variables /// /// VS Project extentions /// private static readonly string[] validExtensions = { ".csproj", ".vbproj", ".vjsproj", ".vcproj" }; /// /// VS Solution extension /// private static readonly string solutionExtension = ".sln"; /// /// Path to the file storing this project /// private string projectPath; /// /// Collection of configs for the project /// private VSProjectConfigCollection configs; #endregion #region Constructor public VSProject( string projectPath ) { this.projectPath = Path.GetFullPath( projectPath ); configs = new VSProjectConfigCollection(); Load(); } #endregion #region Properties /// /// The name of the project. /// public string Name { get { return Path.GetFileNameWithoutExtension( projectPath ); } } /// /// The path to the project /// public string ProjectPath { get { return projectPath; } } /// /// Our collection of configurations /// public VSProjectConfigCollection Configs { get { return configs; } } #endregion #region Static Methods public static bool IsProjectFile( string path ) { #if CLR_2_0 || CLR_4_0 if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0) #else if ( path.IndexOfAny( Path.InvalidPathChars ) >= 0 ) #endif return false; if ( path.ToLower().IndexOf( "http:" ) >= 0 ) return false; string extension = Path.GetExtension( path ); foreach( string validExtension in validExtensions ) if ( extension == validExtension ) return true; return false; } public static bool IsSolutionFile( string path ) { return Path.GetExtension( path ) == solutionExtension; } #endregion #region Instance Methods private void Load() { if ( !IsProjectFile( projectPath ) ) ThrowInvalidFileType( projectPath ); string projectDirectory = Path.GetFullPath( Path.GetDirectoryName( projectPath ) ); StreamReader rdr = new StreamReader( projectPath, System.Text.Encoding.UTF8 ); string[] extensions = {"", ".exe", ".dll", ".lib", "" }; try { XmlDocument doc = new XmlDocument(); doc.Load( rdr ); string extension = Path.GetExtension( projectPath ); string assemblyName = null; switch ( extension ) { case ".vcproj": // TODO: This is all very hacked up... replace it. foreach ( XmlNode configNode in doc.SelectNodes( "/VisualStudioProject/Configurations/Configuration" ) ) { string name = RequiredAttributeValue( configNode, "Name" ); int config_type = System.Convert.ToInt32(RequiredAttributeValue(configNode, "ConfigurationType" ) ); string dirName = name; int bar = dirName.IndexOf( '|' ); if ( bar >= 0 ) dirName = dirName.Substring( 0, bar ); string outputPath = RequiredAttributeValue( configNode, "OutputDirectory" ); outputPath = outputPath.Replace( "$(SolutionDir)", Path.GetFullPath( Path.GetDirectoryName( projectPath ) ) + Path.DirectorySeparatorChar ); outputPath = outputPath.Replace( "$(ConfigurationName)", dirName ); string outputDirectory = Path.Combine( projectDirectory, outputPath ); XmlNode toolNode = configNode.SelectSingleNode( "Tool[@Name='VCLinkerTool']" ); if ( toolNode != null ) { assemblyName = SafeAttributeValue( toolNode, "OutputFile" ); if ( assemblyName != null ) assemblyName = Path.GetFileName( assemblyName ); else assemblyName = Path.GetFileNameWithoutExtension(projectPath) + extensions[config_type]; } else { toolNode = configNode.SelectSingleNode( "Tool[@Name='VCNMakeTool']" ); if ( toolNode != null ) assemblyName = Path.GetFileName( RequiredAttributeValue( toolNode, "Output" ) ); } assemblyName = assemblyName.Replace( "$(OutDir)", outputPath ); assemblyName = assemblyName.Replace( "$(ProjectName)", this.Name ); VSProjectConfig config = new VSProjectConfig ( name ); if ( assemblyName != null ) config.Assemblies.Add( Path.Combine( outputDirectory, assemblyName ) ); this.configs.Add( config ); } break; case ".csproj": case ".vbproj": case ".vjsproj": LoadProject( projectDirectory, doc ); break; default: break; } } catch( FileNotFoundException ) { throw; } catch( Exception e ) { ThrowInvalidFormat( projectPath, e ); } finally { rdr.Close(); } } private bool LoadProject(string projectDirectory, XmlDocument doc) { bool loaded = LoadVS2003Project(projectDirectory, doc); if (loaded) return true; loaded = LoadMSBuildProject(projectDirectory, doc); if (loaded) return true; return false; } private bool LoadVS2003Project(string projectDirectory, XmlDocument doc) { XmlNode settingsNode = doc.SelectSingleNode("/VisualStudioProject/*/Build/Settings"); if (settingsNode == null) return false; string assemblyName = RequiredAttributeValue( settingsNode, "AssemblyName" ); string outputType = RequiredAttributeValue( settingsNode, "OutputType" ); if (outputType == "Exe" || outputType == "WinExe") assemblyName = assemblyName + ".exe"; else assemblyName = assemblyName + ".dll"; XmlNodeList nodes = settingsNode.SelectNodes("Config"); if (nodes != null) foreach (XmlNode configNode in nodes) { string name = RequiredAttributeValue( configNode, "Name" ); string outputPath = RequiredAttributeValue( configNode, "OutputPath" ); string outputDirectory = Path.Combine(projectDirectory, outputPath); string assemblyPath = Path.Combine(outputDirectory, assemblyName); VSProjectConfig config = new VSProjectConfig(name); config.Assemblies.Add(assemblyPath); configs.Add(config); } return true; } private bool LoadMSBuildProject(string projectDirectory, XmlDocument doc) { XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable); namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); XmlNodeList nodes = doc.SelectNodes("/msbuild:Project/msbuild:PropertyGroup", namespaceManager); if (nodes == null) return false; XmlElement assemblyNameElement = (XmlElement)doc.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:AssemblyName", namespaceManager); string assemblyName = assemblyNameElement.InnerText; XmlElement outputTypeElement = (XmlElement)doc.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:OutputType", namespaceManager); string outputType = outputTypeElement.InnerText; if (outputType == "Exe" || outputType == "WinExe") assemblyName = assemblyName + ".exe"; else assemblyName = assemblyName + ".dll"; string commonOutputPath = null; foreach (XmlElement configNode in nodes) { if (configNode.Name != "PropertyGroup") continue; string configurationName = null; XmlAttribute conditionAttribute = configNode.Attributes["Condition"]; if (conditionAttribute != null) { string condition = conditionAttribute.Value; if (condition.IndexOf("$(Configuration)") >= 0) { int start = condition.IndexOf("=="); if (start >= 0) { configurationName = condition.Substring(start + 2).Trim(new char[] { ' ', '\'' }); if (configurationName.EndsWith("|AnyCPU")) configurationName = configurationName.Substring(0, configurationName.Length - 7); } } } XmlElement outputPathElement = (XmlElement)configNode.SelectSingleNode("msbuild:OutputPath", namespaceManager); string outputPath = null; if (outputPathElement != null) outputPath = outputPathElement.InnerText; if (configurationName == null) { commonOutputPath = outputPath; continue; } if (outputPath == null) outputPath = commonOutputPath; if (outputPath == null) continue; string outputDirectory = Path.Combine(projectDirectory, outputPath); string assemblyPath = Path.Combine(outputDirectory, assemblyName); VSProjectConfig config = new VSProjectConfig(configurationName); config.Assemblies.Add(assemblyPath); configs.Add(config); } return true; } private void ThrowInvalidFileType(string projectPath) { throw new ArgumentException( string.Format( "Invalid project file type: {0}", Path.GetFileName( projectPath ) ) ); } private void ThrowInvalidFormat( string projectPath, Exception e ) { throw new ArgumentException( string.Format( "Invalid project file format: {0}", Path.GetFileName( projectPath ) ), e ); } private string SafeAttributeValue( XmlNode node, string attrName ) { XmlNode attrNode = node.Attributes[attrName]; return attrNode == null ? null : attrNode.Value; } private string RequiredAttributeValue( XmlNode node, string name ) { string result = SafeAttributeValue( node, name ); if ( result != null ) return result; throw new ApplicationException( "Missing required attribute " + name ); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/AssemblyWatcher.cs0000664000175000017500000001022411703133442023456 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Timers; using NUnit.Core; namespace NUnit.Util { /// /// AssemblyWatcher keeps track of one or more assemblies to /// see if they have changed. It incorporates a delayed notification /// and uses a standard event to notify any interested parties /// about the change. The path to the assembly is provided as /// an argument to the event handler so that one routine can /// be used to handle events from multiple watchers. /// public class AssemblyWatcher : IAssemblyWatcher { static Logger log = InternalTrace.GetLogger(typeof(AssemblyWatcher)); private FileSystemWatcher[] fileWatchers; private FileInfo[] files; protected System.Timers.Timer timer; protected string changedAssemblyPath; protected FileInfo GetFileInfo(int index) { return files[index]; } public void Setup(int delay, string assemblyFileName) { Setup(delay, new string[] {assemblyFileName}); } #if CLR_2_0 || CLR_4_0 public void Setup(int delay, System.Collections.Generic.IList assemblies) #else public void Setup(int delay, System.Collections.IList assemblies) #endif { log.Info("Setting up watcher"); files = new FileInfo[assemblies.Count]; fileWatchers = new FileSystemWatcher[assemblies.Count]; for (int i = 0; i < assemblies.Count; i++) { log.Debug("Setting up FileSystemWatcher for {0}", assemblies[i]); files[i] = new FileInfo((string)assemblies[i]); fileWatchers[i] = new FileSystemWatcher(); fileWatchers[i].Path = files[i].DirectoryName; fileWatchers[i].Filter = files[i].Name; fileWatchers[i].NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite; fileWatchers[i].Changed += new FileSystemEventHandler(OnChanged); fileWatchers[i].EnableRaisingEvents = false; } timer = new System.Timers.Timer(delay); timer.AutoReset = false; timer.Enabled = false; timer.Elapsed += new ElapsedEventHandler(OnTimer); } public void Start() { EnableWatchers( true ); } public void Stop() { EnableWatchers( false ); } private void EnableWatchers( bool enable ) { if (fileWatchers != null) foreach( FileSystemWatcher watcher in fileWatchers ) watcher.EnableRaisingEvents = enable; } public void FreeResources() { log.Info("FreeResources"); Stop(); if (fileWatchers != null) { foreach (FileSystemWatcher watcher in fileWatchers) { if (watcher != null) { watcher.Changed -= new FileSystemEventHandler(OnChanged); watcher.Dispose(); } } } if (timer != null) { timer.Stop(); timer.Close(); } fileWatchers = null; timer = null; } public event AssemblyChangedHandler AssemblyChanged; protected void OnTimer(Object source, ElapsedEventArgs e) { lock(this) { log.Info("Timer expired"); PublishEvent(); timer.Enabled=false; } } protected void OnChanged(object source, FileSystemEventArgs e) { log.Info("File {0} changed", e.Name); changedAssemblyPath = e.FullPath; if ( timer != null ) { lock(this) { if(!timer.Enabled) timer.Enabled=true; log.Info("Setting timer"); timer.Start(); } } else { PublishEvent(); } } protected void PublishEvent() { if (AssemblyChanged != null) { log.Debug("Publishing Event to {0} listeners", AssemblyChanged.GetInvocationList().Length); AssemblyChanged(changedAssemblyPath); } } } }NUnit-2.6.0.12051/src/ClientUtilities/util/RuntimeFrameworkSelector.cs0000664000175000017500000000713111534472646025404 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Reflection; using NUnit.Core; namespace NUnit.Util { public class RuntimeFrameworkSelector : IRuntimeFrameworkSelector { static Logger log = InternalTrace.GetLogger(typeof(RuntimeFrameworkSelector)); /// /// Selects a target runtime framework for a TestPackage based on /// the settings in the package and the assemblies themselves. /// The package RuntimeFramework setting may be updated as a /// result and the selected runtime is returned. /// /// A TestPackage /// The selected RuntimeFramework public RuntimeFramework SelectRuntimeFramework(TestPackage package) { RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; RuntimeFramework requestedFramework = package.Settings["RuntimeFramework"] as RuntimeFramework; log.Debug("Current framework is {0}", currentFramework); if (requestedFramework == null) log.Debug("No specific framework requested"); else log.Debug("Requested framework is {0}", requestedFramework); RuntimeType targetRuntime = requestedFramework == null ? RuntimeType.Any : requestedFramework.Runtime; Version targetVersion = requestedFramework == null ? RuntimeFramework.DefaultVersion : requestedFramework.FrameworkVersion; if (targetRuntime == RuntimeType.Any) targetRuntime = currentFramework.Runtime; if (targetVersion == RuntimeFramework.DefaultVersion) { if (Services.UserSettings.GetSetting("Options.TestLoader.RuntimeSelectionEnabled", true)) foreach (string assembly in package.Assemblies) { using (AssemblyReader reader = new AssemblyReader(assembly)) { Version v = new Version(reader.ImageRuntimeVersion.Substring(1)); log.Debug("Assembly {0} uses version {1}", assembly, v); if (v > targetVersion) targetVersion = v; } } else targetVersion = RuntimeFramework.CurrentFramework.ClrVersion; RuntimeFramework checkFramework = new RuntimeFramework(targetRuntime, targetVersion); if (!checkFramework.IsAvailable || !Services.TestAgency.IsRuntimeVersionSupported(targetVersion)) { log.Debug("Preferred version {0} is not installed or this NUnit installation does not support it", targetVersion); if (targetVersion < currentFramework.FrameworkVersion) targetVersion = currentFramework.FrameworkVersion; } } RuntimeFramework targetFramework = new RuntimeFramework(targetRuntime, targetVersion); package.Settings["RuntimeFramework"] = targetFramework; log.Debug("Test will use {0} framework", targetFramework); return targetFramework; } } } NUnit-2.6.0.12051/src/ClientUtilities/util/SettingsStorage.cs0000664000175000017500000000366311504175260023522 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Util { using System; /// /// The ISettingsStorage interface is implemented by all /// types of backing storage for settings. /// public interface ISettingsStorage : IDisposable { /// /// Load a setting from the storage. /// /// Name of the setting to load /// Value of the setting or null object GetSetting( string settingName ); /// /// Remove a setting from the storage /// /// Name of the setting to remove void RemoveSetting( string settingName ); /// /// Remove a group of settings from the storae /// /// Name of the group to remove void RemoveGroup( string groupName ); /// /// Save a setting in the storage /// /// Name of the setting to save /// Value to be saved void SaveSetting( string settingName, object settingValue ); /// /// Create a child storage of the same type /// /// Name of the child storage /// New child storage ISettingsStorage MakeChildStorage( string name ); /// /// Load settings from external storage if required /// by the implementation. /// void LoadSettings(); /// /// Save settings to external storage if required /// by the implementation. /// void SaveSettings(); } } NUnit-2.6.0.12051/src/ClientUtilities/util/NUnitRegistry.cs0000664000175000017500000000715711504175260023165 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util { using System; using System.IO; using System.Text; using Microsoft.Win32; /// /// NUnitRegistry provides static properties for NUnit's /// subkey under CurrentUser. /// public class NUnitRegistry { public static readonly string KEY = @"Software\nunit.org\Nunit\2.4"; public static readonly string LEGACY_KEY = @"Software\Nascent Software\Nunit\"; private static bool testMode = false; public static readonly string TEST_KEY = @"Software\nunit.org\Nunit-Test"; /// /// Prevent construction of object /// private NUnitRegistry() { } public static bool TestMode { get { return testMode; } set { testMode = value; } } /// /// Registry subkey for the current user /// public static RegistryKey CurrentUser { get { if ( testMode ) return Registry.CurrentUser.CreateSubKey( TEST_KEY ); RegistryKey newKey = Registry.CurrentUser.OpenSubKey( KEY, true ); if (newKey == null) { newKey = Registry.CurrentUser.CreateSubKey( KEY ); RegistryKey oldKey = Registry.CurrentUser.OpenSubKey( LEGACY_KEY ); if ( oldKey != null ) { CopyKey( oldKey, newKey ); oldKey.Close(); } } return newKey; } } public static bool KeyExists( string subkey ) { using ( RegistryKey key = Registry.CurrentUser.OpenSubKey( subkey, true ) ) { return key != null; } } public static void ClearTestKeys() { ClearSubKey( Registry.CurrentUser, TEST_KEY ); //ClearSubKey( Registry.LocalMachine, TEST_KEY ); } /// /// Static helper method that clears out the contents of a subkey /// /// Base key for the subkey /// Name of the subkey private static void ClearSubKey( RegistryKey baseKey, string subKey ) { using( RegistryKey key = baseKey.OpenSubKey( subKey, true ) ) { if ( key != null ) ClearKey( key ); } } /// /// Static function that clears out the contents of a key /// /// Key to be cleared public static void ClearKey( RegistryKey key ) { foreach( string name in key.GetValueNames() ) key.DeleteValue( name ); // TODO: This throws under Mono - Restore when bug is fixed //foreach( string name in key.GetSubKeyNames() ) // key.DeleteSubKeyTree( name ); foreach (string name in key.GetSubKeyNames()) { ClearSubKey(key, name); key.DeleteSubKey( name ); } } /// /// Static method that copies the contents of one key to another /// /// The source key for the copy /// The target key for the copy public static void CopyKey( RegistryKey fromKey, RegistryKey toKey ) { foreach( string name in fromKey.GetValueNames() ) toKey.SetValue( name, fromKey.GetValue( name ) ); foreach( string name in fromKey.GetSubKeyNames() ) using( RegistryKey fromSubKey = fromKey.OpenSubKey( name ) ) using( RegistryKey toSubKey = toKey.CreateSubKey( name ) ) { CopyKey( fromSubKey, toSubKey ); } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/CategoryManager.cs0000664000175000017500000000222211651467742023447 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core; namespace NUnit.Util { public class CategoryManager { private Hashtable categories = new Hashtable(); public void Add(string name) { categories[name] = name; } public void AddCategories( ITest test ) { if (test.Categories != null) foreach (string name in test.Categories) if (NUnitFramework.IsValidCategoryName(name)) Add(name); } public void AddAllCategories( ITest test ) { AddCategories( test ); if ( test.IsSuite ) foreach( ITest child in test.Tests ) AddAllCategories( child ); } public ICollection Categories { get { return categories.Values; } } public void Clear() { categories = new Hashtable(); } } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestEventDispatcher.cs0000664000175000017500000001363711504175260024327 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Core; namespace NUnit.Util { /// /// Helper class used to dispatch test events /// public class TestEventDispatcher : ITestEvents { #region Events // Project loading events public event TestEventHandler ProjectLoading; public event TestEventHandler ProjectLoaded; public event TestEventHandler ProjectLoadFailed; public event TestEventHandler ProjectUnloading; public event TestEventHandler ProjectUnloaded; public event TestEventHandler ProjectUnloadFailed; // Test loading events public event TestEventHandler TestLoading; public event TestEventHandler TestLoaded; public event TestEventHandler TestLoadFailed; public event TestEventHandler TestReloading; public event TestEventHandler TestReloaded; public event TestEventHandler TestReloadFailed; public event TestEventHandler TestUnloading; public event TestEventHandler TestUnloaded; public event TestEventHandler TestUnloadFailed; // Test running events public event TestEventHandler RunStarting; public event TestEventHandler RunFinished; public event TestEventHandler SuiteStarting; public event TestEventHandler SuiteFinished; public event TestEventHandler TestStarting; public event TestEventHandler TestFinished; public event TestEventHandler TestException; public event TestEventHandler TestOutput; #endregion #region Methods for Firing Events protected virtual void Fire( TestEventHandler handler, TestEventArgs e ) { if ( handler != null ) handler( this, e ); } public void FireProjectLoading( string fileName ) { Fire( ProjectLoading, new TestEventArgs( TestAction.ProjectLoading, fileName ) ); } public void FireProjectLoaded( string fileName ) { Fire( ProjectLoaded, new TestEventArgs( TestAction.ProjectLoaded, fileName ) ); } public void FireProjectLoadFailed( string fileName, Exception exception ) { Fire( ProjectLoadFailed, new TestEventArgs( TestAction.ProjectLoadFailed, fileName, exception ) ); } public void FireProjectUnloading( string fileName ) { Fire( ProjectUnloading, new TestEventArgs( TestAction.ProjectUnloading, fileName ) ); } public void FireProjectUnloaded( string fileName ) { Fire( ProjectUnloaded, new TestEventArgs( TestAction.ProjectUnloaded, fileName ) ); } public void FireProjectUnloadFailed( string fileName, Exception exception ) { Fire( ProjectUnloadFailed, new TestEventArgs( TestAction.ProjectUnloadFailed, fileName, exception ) ); } public void FireTestLoading( string fileName ) { Fire( TestLoading, new TestEventArgs( TestAction.TestLoading, fileName ) ); } public void FireTestLoaded( string fileName, ITest test ) { Fire( TestLoaded, new TestEventArgs( TestAction.TestLoaded, fileName, test ) ); } public void FireTestLoadFailed( string fileName, Exception exception ) { Fire( TestLoadFailed, new TestEventArgs( TestAction.TestLoadFailed, fileName, exception ) ); } public void FireTestUnloading( string fileName ) { Fire( TestUnloading, new TestEventArgs( TestAction.TestUnloading, fileName ) ); } public void FireTestUnloaded( string fileName ) { Fire( TestUnloaded, new TestEventArgs( TestAction.TestUnloaded, fileName ) ); } public void FireTestUnloadFailed( string fileName, Exception exception ) { Fire( TestUnloadFailed, new TestEventArgs( TestAction.TestUnloadFailed, fileName, exception ) ); } public void FireTestReloading( string fileName ) { Fire( TestReloading, new TestEventArgs( TestAction.TestReloading, fileName ) ); } public void FireTestReloaded( string fileName, ITest test ) { Fire( TestReloaded, new TestEventArgs( TestAction.TestReloaded, fileName, test ) ); } public void FireTestReloadFailed( string fileName, Exception exception ) { Fire( TestReloadFailed, new TestEventArgs( TestAction.TestReloadFailed, fileName, exception ) ); } public void FireRunStarting( string name, int testCount ) { Fire( RunStarting, new TestEventArgs( TestAction.RunStarting, name, testCount ) ); } public void FireRunFinished( TestResult result ) { Fire( RunFinished, new TestEventArgs( TestAction.RunFinished, result ) ); } public void FireRunFinished( Exception exception ) { Fire( RunFinished, new TestEventArgs( TestAction.RunFinished, exception ) ); } public void FireTestStarting( TestName testName ) { Fire( TestStarting, new TestEventArgs( TestAction.TestStarting, testName ) ); } public void FireTestFinished( TestResult result ) { Fire( TestFinished, new TestEventArgs( TestAction.TestFinished, result ) ); } public void FireSuiteStarting( TestName testName ) { Fire( SuiteStarting, new TestEventArgs( TestAction.SuiteStarting, testName ) ); } public void FireSuiteFinished( TestResult result ) { Fire( SuiteFinished, new TestEventArgs( TestAction.SuiteFinished, result ) ); } public void FireTestException( string name, Exception exception ) { Fire( TestException, new TestEventArgs( TestAction.TestException, name, exception ) ); } public void FireTestOutput( TestOutput testOutput ) { Fire( TestOutput, new TestEventArgs( TestAction.TestOutput, testOutput ) ); } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestResultItem.cs0000664000175000017500000000430311504175260023322 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Util { using NUnit.Core; /// /// Summary description for TestResultItem. /// public class TestResultItem { private string testName; private string message; private string stackTrace; public TestResultItem(TestResult result ) { testName = result.Test.TestName.FullName; message = result.Message; stackTrace = result.StackTrace; if ( result.Test.IsSuite && result.FailureSite == FailureSite.SetUp ) testName += " (TestFixtureSetUp)"; } public TestResultItem( string testName, string message, string stackTrace ) { this.testName = testName; this.message = message; this.stackTrace = stackTrace; } public override string ToString() { if ( message.Length > 64000 ) return string.Format( "{0}:{1}{2}", testName, Environment.NewLine, message.Substring( 0, 64000 ) ); return GetMessage(); } public string GetMessage() { return String.Format("{0}:{1}{2}", testName, Environment.NewLine, message); } public string GetToolTipMessage() //NRG 05/28/03 - Substitute spaces for tab characters { return (ReplaceTabs(GetMessage(), 8)); // Change each tab to 8 space characters } public string ReplaceTabs(string strOriginal, int nSpaces) //NRG 05/28/03 { string strSpaces = string.Empty; strSpaces = strSpaces.PadRight(nSpaces, ' '); return(strOriginal.Replace("\t", strSpaces)); } public string StackTrace { get { return stackTrace == null ? null : StackTraceFilter.Filter(stackTrace); //string trace = "No stack trace is available"; //if(stackTrace != null) // trace = StackTraceFilter.Filter(stackTrace); //return trace; } } } } NUnit-2.6.0.12051/src/ClientUtilities/util/TestServer.cs0000664000175000017500000000154011504175260022473 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Runtime.Remoting; using System.Runtime.Remoting.Services; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Core; namespace NUnit.Util { /// /// Base class for servers /// public class TestServer : ServerBase { private TestRunner runner; public TestServer( string uri, int port ) : base( uri, port ) { this.runner = new TestDomain(); } public TestRunner TestRunner { get { return runner; } } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/0000775000175000017500000000000011742560362020230 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/tests/TestDomainFixture.cs0000664000175000017500000001673311702655272024210 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using NUnit.Framework; using NUnit.Core; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { [TestFixture] public class TestDomainFixture { private static TestDomain testDomain; private static ITest loadedTest; private static readonly string mockDll = MockAssembly.AssemblyPath; [TestFixtureSetUp] public static void MakeAppDomain() { testDomain = new TestDomain(); testDomain.Load( new TestPackage(mockDll)); loadedTest = testDomain.Test; } [TestFixtureTearDown] public static void UnloadTestDomain() { if ( testDomain != null ) testDomain.Unload(); loadedTest = null; testDomain = null; } [Test] public void AssemblyIsLoadedCorrectly() { Assert.IsNotNull(loadedTest, "Test not loaded"); Assert.AreEqual(MockAssembly.Tests, loadedTest.TestCount ); } [Test, Platform("Linux,Net", Reason = "get_SetupInformation() fails on Windows+Mono")] public void AppDomainIsSetUpCorrectly() { AppDomain domain = testDomain.AppDomain; AppDomainSetup setup = testDomain.AppDomain.SetupInformation; Assert.That(setup.ApplicationName, Is.StringStarting("Tests_")); Assert.That(setup.ApplicationBase, Is.SamePath(Path.GetDirectoryName(mockDll)), "ApplicationBase"); Assert.That( Path.GetFileName( setup.ConfigurationFile ), Is.EqualTo("mock-assembly.dll.config").IgnoreCase, "ConfigurationFile"); Assert.AreEqual( null, setup.PrivateBinPath, "PrivateBinPath" ); Assert.That(setup.ShadowCopyDirectories, Is.SamePath(Path.GetDirectoryName(mockDll)), "ShadowCopyDirectories" ); Assert.That(domain.BaseDirectory, Is.SamePath(Path.GetDirectoryName(mockDll)), "BaseDirectory" ); Assert.That(domain.FriendlyName, Is.EqualTo("test-domain-mock-assembly.dll").IgnoreCase, "FriendlyName"); Assert.IsTrue( testDomain.AppDomain.ShadowCopyFiles, "ShadowCopyFiles" ); } [Test] public void CanRunMockAssemblyTests() { TestResult result = testDomain.Run( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); Assert.IsNotNull(result); ResultSummarizer summarizer = new ResultSummarizer(result); Assert.AreEqual(MockAssembly.TestsRun, summarizer.TestsRun, "TestsRun"); Assert.AreEqual(MockAssembly.Ignored, summarizer.Ignored, "Ignored"); Assert.AreEqual(MockAssembly.Errors, summarizer.Errors, "Errors"); Assert.AreEqual(MockAssembly.Failures, summarizer.Failures, "Failures"); } } [TestFixture] public class TestDomainRunnerTests : NUnit.Core.Tests.BasicRunnerTests { protected override TestRunner CreateRunner(int runnerID) { return new TestDomain(runnerID); } } [TestFixture] public class TestDomainTests { private TestDomain testDomain; private static readonly string mockDll = MockAssembly.AssemblyPath; [SetUp] public void SetUp() { testDomain = new TestDomain(); } [TearDown] public void TearDown() { testDomain.Unload(); } [Test] [ExpectedException(typeof(FileNotFoundException))] public void FileNotFound() { testDomain.Load( new TestPackage( "/xxxx.dll" ) ); } [Test] public void InvalidTestFixture() { TestPackage package = new TestPackage(mockDll); package.TestName = "NUnit.Tests.Assemblies.Bogus"; Assert.IsFalse( testDomain.Load( package ) ); } // Doesn't work under .NET 2.0 Beta 2 //[Test] //[ExpectedException(typeof(BadImageFormatException))] public void FileFoundButNotValidAssembly() { string badfile = Path.GetFullPath("x.dll"); try { StreamWriter sw = new StreamWriter( badfile ); //StreamWriter sw = file.AppendText(); sw.WriteLine("This is a new entry to add to the file"); sw.WriteLine("This is yet another line to add..."); sw.Flush(); sw.Close(); testDomain.Load( new TestPackage( badfile ) ); } finally { if ( File.Exists( badfile ) ) File.Delete( badfile ); } } [Test] public void SpecificTestFixture() { TestPackage package = new TestPackage(mockDll); package.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; testDomain.Load( package ); TestResult result = testDomain.Run( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); ResultSummarizer summarizer = new ResultSummarizer(result); Assert.AreEqual(MockTestFixture.TestsRun, summarizer.TestsRun, "TestsRun"); Assert.AreEqual(MockTestFixture.Ignored, summarizer.Ignored, "Ignored"); Assert.AreEqual(MockTestFixture.Errors, summarizer.Errors, "Errors"); Assert.AreEqual(MockTestFixture.Failures, summarizer.Failures, "Failures"); } [Test, Platform("Linux,Net", Reason = "get_SetupInformation() fails on Windows+Mono")] public void ConfigFileOverrideIsHonored() { TestPackage package = new TestPackage( "MyProject.nunit" ); package.Assemblies.Add(mockDll); package.ConfigurationFile = "override.config"; testDomain.Load( package ); Assert.AreEqual( "override.config", Path.GetFileName( testDomain.AppDomain.SetupInformation.ConfigurationFile ) ); } [Test] public void BasePathOverrideIsHonored() { TestPackage package = new TestPackage( "MyProject.nunit" ); package.Assemblies.Add( MockAssembly.AssemblyPath ); package.BasePath = Path.GetDirectoryName( Environment.CurrentDirectory ); package.PrivateBinPath = Path.GetFileName( Environment.CurrentDirectory ); testDomain.Load( package ); Assert.That(testDomain.AppDomain.BaseDirectory, Is.SamePath(package.BasePath)); } [Test, Platform("Linux,Net", Reason = "get_SetupInformation() fails on Windows+Mono")] public void BinPathOverrideIsHonored() { TestPackage package = new TestPackage( "MyProject.nunit" ); package.Assemblies.Add( MockAssembly.AssemblyPath ); package.PrivateBinPath = "dummy;junk"; testDomain.Load( package ); Assert.AreEqual( "dummy;junk", testDomain.AppDomain.SetupInformation.PrivateBinPath ); } // Turning off shadow copy only works when done for the primary app domain // So this test can only work if it's already off // This doesn't seem to be documented anywhere [Test, Platform(Exclude="mono-1.0", Reason="Test hangs under the 1.0 profile")] public void TurnOffShadowCopy() { TestPackage package = new TestPackage(mockDll); package.Settings["ShadowCopyFiles"] = false; testDomain.Load( package ); Assert.IsFalse( testDomain.AppDomain.ShadowCopyFiles ); // Prove that shadow copy is really off // string location = "NOT_FOUND"; // foreach( Assembly assembly in testDomain.AppDomain.GetAssemblies() ) // { // if ( assembly.FullName.StartsWith( "mock-assembly" ) ) // { // location = Path.GetDirectoryName( assembly.Location ); // break; // } // } // // StringAssert.StartsWith( AppDomain.CurrentDomain.BaseDirectory.ToLower(), location.ToLower() ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestEventCatcher.cs0000664000175000017500000000513011504175260023764 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core; namespace NUnit.Util.Tests { /// /// Summary description for TestEventCatcher. /// public class TestEventCatcher { public class TestEventArgsCollection : ReadOnlyCollectionBase { public EventArgs this[int index] { get { return (EventArgs)InnerList[index]; } } public void Add( EventArgs e ) { InnerList.Add( e ); } } private TestEventArgsCollection events; public bool GotRunFinished = false; public TestEventCatcher( ITestEvents source ) { events = new TestEventArgsCollection(); source.ProjectLoading += new TestEventHandler( OnTestEvent ); source.ProjectLoaded += new TestEventHandler( OnTestEvent ); source.ProjectLoadFailed+= new TestEventHandler( OnTestEvent ); source.ProjectUnloading += new TestEventHandler( OnTestEvent ); source.ProjectUnloaded += new TestEventHandler( OnTestEvent ); source.ProjectUnloadFailed+= new TestEventHandler( OnTestEvent ); source.TestLoading += new TestEventHandler( OnTestEvent ); source.TestLoaded += new TestEventHandler( OnTestEvent ); source.TestLoadFailed += new TestEventHandler( OnTestEvent ); source.TestUnloading += new TestEventHandler( OnTestEvent ); source.TestUnloaded += new TestEventHandler( OnTestEvent ); source.TestUnloadFailed += new TestEventHandler( OnTestEvent ); source.TestReloading += new TestEventHandler( OnTestEvent ); source.TestReloaded += new TestEventHandler( OnTestEvent ); source.TestReloadFailed += new TestEventHandler( OnTestEvent ); source.RunStarting += new TestEventHandler( OnTestEvent ); source.RunFinished += new TestEventHandler( OnTestEvent ); source.TestStarting += new TestEventHandler( OnTestEvent ); source.TestFinished += new TestEventHandler( OnTestEvent ); source.SuiteStarting += new TestEventHandler( OnTestEvent ); source.SuiteFinished += new TestEventHandler( OnTestEvent ); } public TestEventArgsCollection Events { get { return events; } } private void OnTestEvent( object sender, TestEventArgs e ) { events.Add( e ); if (e.Action == TestAction.RunFinished) GotRunFinished = true; } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/MockAssemblyWatcher.cs0000664000175000017500000000276111504175260024467 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using NUnit.Util; namespace NUnit.Util.Tests { /// /// MockAssemblyWatcher provides way of triggering change /// events for test purposes. /// public class MockAssemblyWatcher : AssemblyWatcher { private bool eventPublished = false; private DateTime triggerTime; private DateTime publishTime; public bool EventPublished { get { return eventPublished; } } public int ElapsedTime { get { TimeSpan elapsed = publishTime - triggerTime; return (int)elapsed.TotalMilliseconds; } } public void TriggerEvent( int delay ) { Delay = delay; TriggerEvent( ); } public void TriggerEvent( ) { eventPublished = false; triggerTime = DateTime.Now; OnChanged( this, new FileSystemEventArgs( WatcherChangeTypes.Changed, GetFileInfo(0).DirectoryName, GetFileInfo(0).Name ) ); } public int Delay { get { return (int)timer.Interval; } set { timer.Interval = value; } } protected new void PublishEvent() { publishTime = DateTime.Now; base.PublishEvent(); eventPublished = true; } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestLoaderWatcherTests.cs0000664000175000017500000001017611663741110025165 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { [TestFixture] public class TestLoaderWatcherTests { private readonly string assembly = MockAssembly.AssemblyPath; private MockAssemblyWatcher2 mockWatcher; private ITestLoader testLoader; private const string ReloadOnChangeSetting = "Options.TestLoader.ReloadOnChange"; [SetUp] public void PreprareTestLoader() { // arrange mockWatcher = new MockAssemblyWatcher2(); testLoader = new TestLoader(mockWatcher); testLoader.LoadProject(assembly); } [TearDown] public void CleanUpSettings() { Services.UserSettings.RemoveSetting(ReloadOnChangeSetting); } private void AssertWatcherIsPrepared() { Assert.IsTrue(mockWatcher.IsWatching); Assert.SamePath(assembly, mockWatcher.AssembliesToWatch[0]); } [Test] public void LoadShouldStartWatcher() { // act testLoader.LoadTest(); // assert AssertWatcherIsPrepared(); Assert.AreEqual(1, mockWatcher.DelegateCount); } [Test] public void ReloadShouldStartWatcher() { // arrange testLoader.LoadTest(); mockWatcher.AssembliesToWatch = null; mockWatcher.IsWatching = false; // act testLoader.ReloadTest(); // assert AssertWatcherIsPrepared(); Assert.AreEqual(1, mockWatcher.DelegateCount); } [Test] public void UnloadShouldStopWatcherAndFreeResources() { // act testLoader.LoadTest(); testLoader.UnloadTest(); // assert Assert.IsFalse(mockWatcher.IsWatching); Assert.IsTrue(mockWatcher.AreResourcesFreed); Assert.AreEqual(0, mockWatcher.DelegateCount); } [Test] public void LoadShouldStartWatcherDependingOnSettings() { // arrange Services.UserSettings.SaveSetting(ReloadOnChangeSetting, false); testLoader.LoadTest(); // assert Assert.IsFalse(mockWatcher.IsWatching); Assert.AreEqual(0, mockWatcher.DelegateCount); } [Test] public void ReloadShouldStartWatcherDependingOnSettings() { // arrange Services.UserSettings.SaveSetting(ReloadOnChangeSetting, false); testLoader.LoadTest(); testLoader.ReloadTest(); // assert Assert.IsFalse(mockWatcher.IsWatching); Assert.AreEqual(0, mockWatcher.DelegateCount); } } internal class MockAssemblyWatcher2 : IAssemblyWatcher { public bool IsWatching; #if CLR_2_0 || CLR_4_0 || CLR_4_0 public System.Collections.Generic.IList AssembliesToWatch; #else public System.Collections.IList AssembliesToWatch; #endif public bool AreResourcesFreed; public void Stop() { IsWatching = false; } public void Start() { IsWatching = true; } #if CLR_2_0 || CLR_4_0 public void Setup(int delayInMs, System.Collections.Generic.IList assemblies) #else public void Setup(int delayInMs, System.Collections.IList assemblies) #endif { AssembliesToWatch = assemblies; } public void Setup(int delayInMs, string assemblyFileName) { Setup(delayInMs, new string[] {assemblyFileName}); } public void FreeResources() { AreResourcesFreed = true; } // This method is not used. It exists only to supress a // warning about AssemblyChanged never being used public void FireAssemblyChanged(string path) { if (AssemblyChanged != null) AssemblyChanged(path); } public int DelegateCount { get { return AssemblyChanged == null ? 0 : AssemblyChanged.GetInvocationList().Length; } } public event AssemblyChangedHandler AssemblyChanged; } }NUnit-2.6.0.12051/src/ClientUtilities/tests/DomainManagerTests.cs0000664000175000017500000000617011720431712024300 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.IO; using NUnit.Framework; namespace NUnit.Util.Tests { public class DomainManagerTests { static string path1 = TestPath("/test/bin/debug/test1.dll"); static string path2 = TestPath("/test/bin/debug/test2.dll"); static string path3 = TestPath("/test/utils/test3.dll"); [Test] public void GetPrivateBinPath() { string[] assemblies = new string[] { path1, path2, path3 }; Assert.AreEqual( TestPath("bin/debug") + Path.PathSeparator + TestPath("utils"), DomainManager.GetPrivateBinPath(TestPath("/test"), assemblies)); } [Test] public void GetCommonAppBase_OneElement() { string[] assemblies = new string[] { path1 }; Assert.AreEqual( TestPath("/test/bin/debug"), DomainManager.GetCommonAppBase(assemblies)); } [Test] public void GetCommonAppBase_TwoElements_SameDirectory() { string[] assemblies = new string[] { path1, path2 }; Assert.AreEqual( TestPath("/test/bin/debug"), DomainManager.GetCommonAppBase(assemblies)); } [Test] public void GetCommonAppBase_TwoElements_DifferentDirectories() { string[] assemblies = new string[] { path1, path3 }; Assert.AreEqual( TestPath("/test"), DomainManager.GetCommonAppBase(assemblies)); } [Test] public void GetCommonAppBase_ThreeElements_DiferentDirectories() { string[] assemblies = new string[] { path1, path2, path3 }; Assert.AreEqual( TestPath("/test"), DomainManager.GetCommonAppBase(assemblies)); } [Test] public void UnloadUnloadedDomain() { AppDomain domain = AppDomain.CreateDomain("DomainManagerTests-domain"); AppDomain.Unload(domain); DomainManager manager = new DomainManager(); manager.Unload(domain); } /// /// Take a valid Linux filePath and make a valid windows filePath out of it /// if we are on Windows. Change slashes to backslashes and, if the /// filePath starts with a slash, add C: in front of it. /// private static string TestPath(string path) { if (Path.DirectorySeparatorChar != '/') { path = path.Replace('/', Path.DirectorySeparatorChar); if (path[0] == Path.DirectorySeparatorChar) path = "C:" + path; } return path; } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/ServiceManagerSetUpFixture.cs0000664000175000017500000000342011504175260025774 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Util.Tests { /// /// This fixture is used to set up a distinct ServiceMangager with its /// own services in the test domain when testing NUnit. We start and /// stop services selectively. In particular, we don't want to /// do a StopAllServices command, because that would cause any /// changes to UserSettings to be saved. /// /// TODO: Refactor SettingsService so we can use it without actually /// touching the backup storage. /// [SetUpFixture] public class ServiceManagerSetUpFixture { [SetUp] public void CreateServicesForTestDomain() { ServiceManager.Services.AddService( new DummySettingsService() ); ServiceManager.Services.AddService( new DomainManager() ); ServiceManager.Services.AddService( new ProjectService() ); ServiceManager.Services.AddService( new TestAgency( "TestDomain_TestAgency", 0 ) ); Services.TestAgency.Start(); } [TearDown] public void ClearServices() { Services.TestAgency.Stop(); ServiceManager.Services.ClearServices(); } } class DummySettingsService : SettingsGroup, NUnit.Core.IService { public DummySettingsService() { this.storage = new MemorySettingsStorage(); } #region IService Members public void InitializeService() { } public void UnloadService() { } #endregion } } NUnit-2.6.0.12051/src/ClientUtilities/tests/AssemblyWatcherTests.cs0000664000175000017500000001024611544330406024674 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using NUnit.Framework; using System.Text; using System.Timers; namespace NUnit.Util.Tests { [TestFixture] [Platform(Exclude = "Win95,Win98,WinMe")] public class AssemblyWatcherTests { private AssemblyWatcher watcher; private CounterEventHandler handler; private static int watcherDelayMs = 100; private string fileName; private string tempFileName; [SetUp] public void CreateFile() { string tempDir = Path.GetTempPath(); fileName = Path.Combine(tempDir, "temp.txt"); tempFileName = Path.Combine(tempDir, "newTempFile.txt"); StreamWriter writer = new StreamWriter(fileName); writer.Write("Hello"); writer.Close(); handler = new CounterEventHandler(); watcher = new AssemblyWatcher(); watcher.Setup(watcherDelayMs, fileName); watcher.AssemblyChanged += new AssemblyChangedHandler(handler.OnChanged); watcher.Start(); } [TearDown] public void DeleteFile() { watcher.Stop(); FileInfo fileInfo = new FileInfo(fileName); fileInfo.Delete(); FileInfo temp = new FileInfo(tempFileName); if (temp.Exists) temp.Delete(); } [Test] // TODO: Exclusion should really only apply to Mono on Windows [Platform(Exclude = "Mono")] public void MultipleCloselySpacedChangesTriggerWatcherOnlyOnce() { for (int i = 0; i < 3; i++) { StreamWriter writer = new StreamWriter(fileName, true); writer.WriteLine("Data"); writer.Close(); System.Threading.Thread.Sleep(20); } WaitForTimerExpiration(); Assert.AreEqual(1, handler.Counter); Assert.AreEqual(Path.GetFullPath(fileName), handler.FileName); } [Test] // TODO: Exclusion should really only apply to Mono on Windows [Platform(Exclude = "Mono")] public void ChangingFileTriggersWatcher() { StreamWriter writer = new StreamWriter(fileName); writer.Write("Goodbye"); writer.Close(); WaitForTimerExpiration(); Assert.AreEqual(1, handler.Counter); Assert.AreEqual(Path.GetFullPath(fileName), handler.FileName); } [Test] [Platform(Exclude = "Linux", Reason = "Attribute change triggers watcher")] public void ChangingAttributesDoesNotTriggerWatcher() { FileInfo fi = new FileInfo(fileName); FileAttributes attr = fi.Attributes; fi.Attributes = FileAttributes.Hidden | attr; WaitForTimerExpiration(); Assert.AreEqual(0, handler.Counter); } [Test] public void CopyingFileDoesNotTriggerWatcher() { FileInfo fi = new FileInfo(fileName); fi.CopyTo(tempFileName); fi.Delete(); WaitForTimerExpiration(); Assert.AreEqual(0, handler.Counter); } private static void WaitForTimerExpiration() { System.Threading.Thread.Sleep(watcherDelayMs * 2); } private class CounterEventHandler { int counter; String fileName; public int Counter { get { return counter; } } public String FileName { get { return fileName; } } public void OnChanged(String fullPath) { fileName = fullPath; counter++; } } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestServerTests.cs0000664000175000017500000000556111543625326023720 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Diagnostics; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Framework; using NUnit.Core; namespace NUnit.Util.Tests { /// /// Summary description for TestServerTests. /// // Exclude for release [TestFixture,Platform(Exclude="Mono")] //public class TestServerTests //{ // private string serverPath = "nunit-server.exe"; // [TestFixtureSetUp] // public void SetServerPath() // { // if ( File.Exists(serverPath) ) // return; // DirectoryInfo cwd = new DirectoryInfo( Environment.CurrentDirectory ); // if( cwd.Parent.Name == "bin" ) // { // string filePath = cwd.Parent.Parent.Parent.Parent.FullName; // filePath = Path.Combine( filePath, "NUnitTestServer" ); // filePath = Path.Combine( filePath, "nunit-server-exe" ); // filePath = Path.Combine( filePath, "bin" ); // filePath = Path.Combine( filePath, cwd.Name ); // filePath = Path.Combine( filePath, "nunit-server.exe" ); // if( File.Exists( filePath ) ) // { // serverPath = filePath; // return; // } // } // Assert.Fail( "Unable to find server" ); // } // [Test] // public void CanConnect() // { // using( TestServer server = new TestServer( "TestServer", 9000 ) ) // { // server.Start(); // object obj = Activator.GetObject( typeof(TestRunner), ServerUtilities.MakeUrl("TestServer", 9000) ); // Assert.IsNotNull( obj, "Unable to connect" ); // } // } // [Test] // public void CanConnectOutOfProcess() // { // Process process = null; // try // { // process = Process.Start( serverPath, "TestServer" ); // System.Threading.Thread.Sleep( 1000 ); // TestServer server = (TestServer)Activator.GetObject( typeof(TestRunner), "tcp://localhost:9000/TestServer" ); // Assert.IsNotNull( server, "Unable to connect" ); // server.Stop(); // } // finally // { // if ( process != null && !process.HasExited ) // process.Kill(); // } // } //} } NUnit-2.6.0.12051/src/ClientUtilities/tests/AssemblyListTests.cs0000664000175000017500000000541111504175260024211 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using NUnit.Framework; namespace NUnit.Util.Tests { /// /// This fixture tests both AssemblyList and AssemblyListItem /// [TestFixture] public class AssemblyListTests { private AssemblyList assemblies; private string path1; private string path2; private string path3; private int events = 0; [SetUp] public void CreateAssemblyList() { assemblies = new AssemblyList(); path1 = CleanPath("/tests/bin/debug/assembly1.dll"); path2 = CleanPath("/tests/bin/debug/assembly2.dll"); path3 = CleanPath("/tests/bin/debug/assembly3.dll"); events = 0; assemblies.Changed += new EventHandler( assemblies_Changed ); } private void assemblies_Changed( object sender, EventArgs e ) { ++events; } [Test] public void EmptyList() { Assert.AreEqual( 0, assemblies.Count ); } [Test] public void CanAddAssemblies() { assemblies.Add( path1 ); assemblies.Add( path2 ); Assert.AreEqual( 2, assemblies.Count ); Assert.AreEqual( path1, assemblies[0] ); Assert.AreEqual( path2, assemblies[1] ); } [Test, ExpectedException( typeof( ArgumentException ) )] public void MustAddAbsolutePath() { assemblies.Add( CleanPath( "bin/debug/assembly1.dll" ) ); } [Test] public void AddFiresChangedEvent() { assemblies.Add( path1 ); Assert.AreEqual( 1, events ); } [Test] public void CanRemoveAssemblies() { assemblies.Add(path1); assemblies.Add(path2); assemblies.Add(path3); assemblies.Remove( path2 ); Assert.AreEqual( 2, assemblies.Count ); Assert.AreEqual( path1, assemblies[0] ); Assert.AreEqual( path3, assemblies[1] ); } [Test] public void RemoveAtFiresChangedEvent() { assemblies.Add( path1 ); assemblies.RemoveAt(0); Assert.AreEqual( 2, events ); } [Test] public void RemoveFiresChangedEvent() { assemblies.Add( path1 ); assemblies.Remove( path1 ); Assert.AreEqual( 2, events ); } [Test] public void SettingFullPathFiresChangedEvent() { assemblies.Add( path1 ); assemblies[0] = path2; Assert.AreEqual( 2, events ); } private string CleanPath( string path ) { return path.Replace( '/', Path.DirectorySeparatorChar ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/NUnitProjectTests.cs0000664000175000017500000002034611543625326024174 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Xml; using System.Text; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class NUnitProjectTests { static readonly string xmlfile = Path.Combine(Path.GetTempPath(), "test.nunit"); static readonly string mockDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; private NUnitProject project; private ProjectService projectService; [SetUp] public void SetUp() { projectService = new ProjectService(); project = projectService.EmptyProject(); } [TearDown] public void EraseFile() { if ( File.Exists( xmlfile ) ) File.Delete( xmlfile ); } [Test] public void IsProjectFile() { Assert.IsTrue( NUnitProject.IsNUnitProjectFile( @"\x\y\test.nunit" ) ); Assert.IsFalse( NUnitProject.IsNUnitProjectFile( @"\x\y\test.junit" ) ); } [Test] public void NewProjectIsEmpty() { Assert.AreEqual( 0, project.Configs.Count ); Assert.IsNull( project.ActiveConfig ); } [Test] public void NewProjectIsNotDirty() { Assert.IsFalse( project.IsDirty ); } [Test] public void NewProjectDefaultPath() { Assert.AreEqual( Path.GetFullPath( "Project1" ), project.ProjectPath ); Assert.AreEqual( "Project1", project.Name ); NUnitProject another = projectService.EmptyProject(); Assert.AreEqual( Path.GetFullPath( "Project2" ), another.ProjectPath ); } [Test] public void NewProjectNotLoadable() { Assert.IsFalse( project.IsLoadable ); } [Test] public void SaveMakesProjectNotDirty() { project.Save( xmlfile ); Assert.IsFalse( project.IsDirty ); } [Test] public void SaveSetsProjectPath() { project.Save( xmlfile ); Assert.AreEqual( Path.GetFullPath( xmlfile ), project.ProjectPath ); Assert.AreEqual( "test", project.Name ); } [Test] public void DefaultApplicationBase() { project.Save( xmlfile ); Assert.AreEqual( Path.GetDirectoryName( project.ProjectPath ), project.BasePath ); } [Test] public void DefaultConfigurationFile() { Assert.AreEqual( "Project1.config", project.ConfigurationFile ); project.Save( xmlfile ); Assert.AreEqual( "test.config", project.ConfigurationFile ); } [Test] public void ConfigurationFileFromAssembly() { NUnitProject project = projectService.WrapAssembly(mockDll); string config = Path.GetFileName( project.ConfigurationFile ); Assert.That(config, Is.EqualTo("mock-assembly.dll.config").IgnoreCase); } [Test] public void ConfigurationFileFromAssemblies() { NUnitProject project = projectService.WrapAssemblies(new string[] {mockDll}); string config = Path.GetFileName( project.ConfigurationFile ); Assert.That(config, Is.EqualTo("mock-assembly.dll.config").IgnoreCase); } [Test] public void DefaultProjectName() { project.Save( xmlfile ); Assert.AreEqual( "test", project.Name ); } [Test] public void LoadMakesProjectNotDirty() { project.Save( xmlfile ); NUnitProject project2 = new ProjectService().LoadProject( xmlfile ); Assert.IsFalse( project2.IsDirty ); } [Test] public void CanSetAppBase() { project.BasePath = ".."; Assert.AreEqual( Path.GetDirectoryName( Environment.CurrentDirectory ), project.BasePath ); } [Test] public void CanAddConfigs() { project.Configs.Add("Debug"); project.Configs.Add("Release"); Assert.AreEqual( 2, project.Configs.Count ); } [Test] public void CanSetActiveConfig() { project.Configs.Add("Debug"); project.Configs.Add("Release"); project.SetActiveConfig( "Release" ); Assert.AreEqual( "Release", project.ActiveConfig.Name ); } [Test] public void CanAddAssemblies() { project.Configs.Add("Debug"); project.Configs.Add("Release"); project.Configs["Debug"].Assemblies.Add( Path.GetFullPath( @"bin\debug\assembly1.dll" ) ); project.Configs["Debug"].Assemblies.Add( Path.GetFullPath( @"bin\debug\assembly2.dll" ) ); project.Configs["Release"].Assemblies.Add( Path.GetFullPath( @"bin\debug\assembly3.dll" ) ); Assert.AreEqual( 2, project.Configs.Count ); Assert.AreEqual( 2, project.Configs["Debug"].Assemblies.Count ); Assert.AreEqual( 1, project.Configs["Release"].Assemblies.Count ); } [Test] public void AddConfigMakesProjectDirty() { project.Configs.Add("Debug"); Assert.IsTrue( project.IsDirty ); } [Test] public void RenameConfigMakesProjectDirty() { project.Configs.Add("Old"); project.IsDirty = false; project.Configs[0].Name = "New"; Assert.IsTrue( project.IsDirty ); } [Test] public void DefaultActiveConfig() { project.Configs.Add("Debug"); Assert.AreEqual( "Debug", project.ActiveConfig.Name ); } [Test] public void RenameActiveConfig() { project.Configs.Add( "Old" ); project.SetActiveConfig( "Old" ); project.Configs[0].Name = "New"; Assert.AreEqual( "New", project.ActiveConfig.Name ); } [Test] public void RemoveConfigMakesProjectDirty() { project.Configs.Add("Debug"); project.IsDirty = false; project.Configs.Remove("Debug"); Assert.IsTrue( project.IsDirty ); } [Test] public void RemoveActiveConfig() { project.Configs.Add("Debug"); project.Configs.Add("Release"); project.SetActiveConfig("Debug"); project.Configs.Remove("Debug"); Assert.AreEqual( "Release", project.ActiveConfig.Name ); } [Test] public void SettingActiveConfigMakesProjectDirty() { project.Configs.Add("Debug"); project.Configs.Add("Release"); project.SetActiveConfig( "Debug" ); project.IsDirty = false; project.SetActiveConfig( "Release" ); Assert.IsTrue( project.IsDirty ); } [Test] public void SaveAndLoadEmptyProject() { project.Save( xmlfile ); Assert.IsTrue( File.Exists( xmlfile ) ); NUnitProject project2 = projectService.LoadProject( xmlfile ); Assert.AreEqual( 0, project2.Configs.Count ); } [Test] public void SaveAndLoadEmptyConfigs() { project.Configs.Add( "Debug" ); project.Configs.Add( "Release" ); project.Save( xmlfile ); Assert.IsTrue( File.Exists( xmlfile ) ); NUnitProject project2 = projectService.LoadProject( xmlfile ); Assert.AreEqual( 2, project2.Configs.Count ); Assert.IsTrue( project2.Configs.Contains( "Debug" ) ); Assert.IsTrue( project2.Configs.Contains( "Release" ) ); } [Test] public void SaveAndLoadConfigsWithAssemblies() { string tempPath = Path.GetTempPath(); ProjectConfig config1 = new ProjectConfig( "Debug" ); config1.Assemblies.Add(Path.Combine(tempPath, @"bin\debug\assembly1.dll")); config1.Assemblies.Add(Path.Combine(tempPath, @"bin\debug\assembly2.dll")); ProjectConfig config2 = new ProjectConfig( "Release" ); config2.Assemblies.Add(Path.Combine(tempPath, @"bin\release\assembly1.dll")); config2.Assemblies.Add(Path.Combine(tempPath, @"bin\release\assembly2.dll")); project.Configs.Add( config1 ); project.Configs.Add( config2 ); project.Save( xmlfile ); Assert.IsTrue( File.Exists( xmlfile ) ); NUnitProject project2 = projectService.LoadProject( xmlfile ); Assert.AreEqual( 2, project2.Configs.Count ); config1 = project2.Configs["Debug"]; Assert.AreEqual( 2, config1.Assemblies.Count ); Assert.AreEqual(Path.Combine(tempPath, @"bin\debug\assembly1.dll"), config1.Assemblies[0]); Assert.AreEqual(Path.Combine(tempPath, @"bin\debug\assembly2.dll"), config1.Assemblies[1]); config2 = project2.Configs["Release"]; Assert.AreEqual( 2, config2.Assemblies.Count ); Assert.AreEqual(Path.Combine(tempPath, @"bin\release\assembly1.dll"), config2.Assemblies[0]); Assert.AreEqual(Path.Combine(tempPath, @"bin\release\assembly2.dll"), config2.Assemblies[1]); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestAgencyTests.cs0000664000175000017500000000361211504175260023645 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using NUnit.Framework; using NUnit.Core; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace NUnit.Util.Tests { [TestFixture] public class TestAgencyTests { private TestAgency agency; [SetUp] public void CreateAgency() { agency = new TestAgency("TempTestAgency", 0); agency.Start(); } [TearDown] public void StopAgency() { agency.Stop(); } [Test] public void CanConnectToAgency() { object obj = Activator.GetObject(typeof(TestAgency), agency.ServerUrl); Assert.IsNotNull(obj); Assert.That(obj is TestAgency); } [Test, Platform(Exclude="Mono")] public void CanLaunchAndConnectToAgent() { TestAgent agent = null; try { agent = agency.GetAgent(10000); Assert.IsNotNull(agent); } finally { if ( agent != null ) agency.ReleaseAgent(agent); } } // TODO: Decide if we really want to do this //[Test] public void CanReuseReleasedAgents() { TestAgent agent1 = agency.GetAgent(20000); Guid id1 = agent1.Id; agency.ReleaseAgent(agent1); TestAgent agent2 = agency.GetAgent(20000); Assert.AreEqual(id1, agent2.Id); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/VisualStudioConverterTests.cs0000664000175000017500000001774011651063754026140 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.Util.ProjectConverters; using NUnit.Util.Tests.resources; namespace NUnit.Util.Tests { [TestFixture] public class VisualStudioConverterTests { private VisualStudioConverter converter; static readonly bool useSolutionConfigs = Services.UserSettings.GetSetting("Options.TestLoader.VisualStudio.UseSolutionConfigs", true); private void AssertCanLoadVsProject( string resourceName ) { string fileName = Path.GetFileNameWithoutExtension( resourceName ); using( TestResource file = new TestResource(resourceName) ) { NUnitProject project = converter.ConvertFrom( file.Path ); Assert.AreEqual( fileName, project.Name ); Assert.AreEqual( project.Configs[0].Name, project.ActiveConfigName ); Assert.AreEqual( fileName.ToLower(), Path.GetFileNameWithoutExtension( project.Configs[0].Assemblies[0].ToLower() ) ); Assert.IsTrue( project.IsLoadable, "Not loadable" ); Assert.IsFalse( project.IsDirty, "Project should not be dirty" ); } } [SetUp] public void CreateImporter() { converter = new VisualStudioConverter(); } [Test] public void FromCSharpProject() { AssertCanLoadVsProject( "csharp-sample.csproj" ); } [Test] public void FromVBProject() { AssertCanLoadVsProject( "vb-sample.vbproj" ); } [Test] public void FromJsharpProject() { AssertCanLoadVsProject( "jsharp.vjsproj" ); } [Test] public void FromCppProject() { AssertCanLoadVsProject( "cpp-sample.vcproj" ); } [Test] public void FromProjectWithHebrewFileIncluded() { AssertCanLoadVsProject( "HebrewFileProblem.csproj" ); } [Test] public void FromVSSolution2003() { using(new TestResource("csharp-sample.csproj", @"csharp\csharp-sample.csproj")) using(new TestResource("jsharp.vjsproj", @"jsharp\jsharp.vjsproj")) using(new TestResource("vb-sample.vbproj", @"vb\vb-sample.vbproj")) using(new TestResource("cpp-sample.vcproj", @"cpp-sample\cpp-sample.vcproj")) using(TestResource file = new TestResource("samples.sln")) { NUnitProject project = converter.ConvertFrom( file.Path ); if (useSolutionConfigs) { Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(4, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(4, project.Configs["Release"].Assemblies.Count); } else { Assert.AreEqual(4, project.Configs.Count); Assert.AreEqual(3, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(3, project.Configs["Release"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Debug|Win32"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release|Win32"].Assemblies.Count); } Assert.IsTrue( project.IsLoadable, "Not loadable" ); Assert.IsFalse( project.IsDirty, "Project should not be dirty" ); } } [Test] public void FromVSSolution2005() { using (new TestResource("csharp-sample_VS2005.csproj", @"csharp\csharp-sample_VS2005.csproj")) using (new TestResource("jsharp_VS2005.vjsproj", @"jsharp\jsharp_VS2005.vjsproj")) using (new TestResource("vb-sample_VS2005.vbproj", @"vb\vb-sample_VS2005.vbproj")) using (new TestResource("cpp-sample_VS2005.vcproj", @"cpp-sample\cpp-sample_VS2005.vcproj")) using (TestResource file = new TestResource("samples_VS2005.sln")) { NUnitProject project = converter.ConvertFrom( file.Path ); if (useSolutionConfigs) { Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(4, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(4, project.Configs["Release"].Assemblies.Count); } else { Assert.AreEqual(4, project.Configs.Count); Assert.AreEqual(3, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(3, project.Configs["Release"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Debug|Win32"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release|Win32"].Assemblies.Count); } Assert.IsTrue( project.IsLoadable, "Not loadable" ); Assert.IsFalse( project.IsDirty, "Project should not be dirty" ); } } [Test] public void FromWebApplication() { using (new TestResource("ClassLibrary1.csproj", @"ClassLibrary1\ClassLibrary1.csproj")) using (TestResource file = new TestResource("WebApplication1.sln")) { NUnitProject project = converter.ConvertFrom( Path.GetFullPath( file.Path ) ); Assert.AreEqual( 2, project.Configs.Count ); Assert.AreEqual( 1, project.Configs["Debug"].Assemblies.Count ); Assert.AreEqual( 1, project.Configs["Release"].Assemblies.Count ); } } [Test] public void WithUnmanagedCpp() { using (new TestResource("ClassLibrary1.csproj", @"ClassLibrary1\ClassLibrary1.csproj")) using (new TestResource("Unmanaged.vcproj", @"Unmanaged\Unmanaged.vcproj")) using (TestResource file = new TestResource("Solution1.sln")) { NUnitProject project = converter.ConvertFrom( file.Path ); if (useSolutionConfigs) { Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(2, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(2, project.Configs["Release"].Assemblies.Count); } else { Assert.AreEqual(4, project.Configs.Count); Assert.AreEqual(1, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Debug|Win32"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release|Win32"].Assemblies.Count); } } } [Test] public void FromMakefileProject() { using (TestResource file = new TestResource("MakeFileProject.vcproj")) { NUnitProject project = converter.ConvertFrom( file.Path ); Assert.AreEqual( 2, project.Configs.Count ); Assert.AreEqual(1, project.Configs["Debug|Win32"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release|Win32"].Assemblies.Count); } } [Test] public void FromSolutionWithDisabledProject() { using (new TestResource("DisabledProject.csproj", @"DisabledProject\DisabledProject.csproj")) using (new TestResource("DebugOnly.csproj", @"DebugOnly\DebugOnly.csproj")) using (TestResource file = new TestResource("DisabledProject.sln")) { NUnitProject project = converter.ConvertFrom(file.Path); Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(2, project.Configs["Release"].Assemblies.Count, "Release should have 2 assemblies"); if (useSolutionConfigs) Assert.AreEqual(1, project.Configs["Debug"].Assemblies.Count, "Debug should have 1 assembly"); else Assert.AreEqual(2, project.Configs["Debug"].Assemblies.Count, "Debug should have 2 assemblies"); } } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/RegistrySettingsStorageTests.cs0000664000175000017500000000660411504175260026461 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using Microsoft.Win32; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class RegistrySettingsStorageTests { private static readonly string testKeyName = "Software\\NUnitTest"; RegistryKey testKey; RegistrySettingsStorage storage; [SetUp] public void BeforeEachTest() { testKey = Registry.CurrentUser.CreateSubKey( testKeyName ); storage = new RegistrySettingsStorage( testKey ); } [TearDown] public void AfterEachTest() { NUnitRegistry.ClearKey( testKey ); storage.Dispose(); } [Test] public void StorageHasCorrectKey() { StringAssert.AreEqualIgnoringCase( "HKEY_CURRENT_USER\\" + testKeyName, storage.StorageKey.Name ); } [Test] public void SaveAndLoadSettings() { Assert.IsNull( storage.GetSetting( "X" ), "X is not null" ); Assert.IsNull( storage.GetSetting( "NAME" ), "NAME is not null" ); storage.SaveSetting("X", 5); storage.SaveSetting("NAME", "Charlie"); Assert.AreEqual( 5, storage.GetSetting("X") ); Assert.AreEqual( "Charlie", storage.GetSetting("NAME") ); Assert.AreEqual( 5, testKey.GetValue( "X" ) ); Assert.AreEqual( "Charlie", testKey.GetValue( "NAME" ) ); } [Test] public void RemoveSettings() { storage.SaveSetting("X", 5); storage.SaveSetting("NAME", "Charlie"); storage.RemoveSetting( "X" ); Assert.IsNull( storage.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", storage.GetSetting( "NAME" ) ); storage.RemoveSetting( "NAME" ); Assert.IsNull( storage.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void MakeSubStorages() { RegistrySettingsStorage sub1 = (RegistrySettingsStorage)storage.MakeChildStorage( "Sub1" ); RegistrySettingsStorage sub2 = (RegistrySettingsStorage)storage.MakeChildStorage( "Sub2" ); Assert.IsNotNull( sub1, "Sub1 is null" ); Assert.IsNotNull( sub2, "Sub2 is null" ); StringAssert.AreEqualIgnoringCase( "HKEY_CURRENT_USER\\" + testKeyName + "\\Sub1", sub1.StorageKey.Name); StringAssert.AreEqualIgnoringCase( "HKEY_CURRENT_USER\\" + testKeyName + "\\Sub2", sub2.StorageKey.Name ); } [Test] public void SubstorageSettings() { ISettingsStorage sub = storage.MakeChildStorage( "Sub" ); sub.SaveSetting( "X", 5 ); sub.SaveSetting( "NAME", "Charlie" ); Assert.AreEqual( 5, sub.GetSetting( "X" ) ); Assert.AreEqual( "Charlie", sub.GetSetting( "NAME" ) ); sub.RemoveSetting( "X" ); Assert.IsNull( sub.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", sub.GetSetting( "NAME" ) ); sub.RemoveSetting( "NAME" ); Assert.IsNull( sub.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void TypeSafeSettings() { storage.SaveSetting( "X", 5); storage.SaveSetting( "Y", "17" ); storage.SaveSetting( "NAME", "Charlie"); Assert.AreEqual( 5, storage.GetSetting("X") ); Assert.AreEqual( "17", storage.GetSetting( "Y" ) ); Assert.AreEqual( "Charlie", storage.GetSetting( "NAME" ) ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestAgentTests.cs0000664000175000017500000000130711534472646023507 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class RemoteTestAgentTests { [Test] public void AgentReturnsProcessId() { RemoteTestAgent agent = new RemoteTestAgent(Guid.NewGuid(), null); Assert.AreEqual(Process.GetCurrentProcess().Id, agent.ProcessId); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestLoaderAssemblyTests.cs0000664000175000017500000001441011703027036025341 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Threading; using NUnit.Core; using NUnit.Framework; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { /// /// /// [TestFixture] public class TestLoaderAssemblyTests { private readonly string assembly = MockAssembly.AssemblyPath; private readonly string badFile = "/x.dll"; private TestLoader loader; private TestEventCatcher catcher; private void LoadTest( string assembly ) { loader.LoadProject( assembly ); if (loader.IsProjectLoaded && loader.TestProject.IsLoadable) loader.LoadTest(); } [SetUp] public void SetUp() { loader = new TestLoader( ); catcher = new TestEventCatcher( loader.Events ); } [TearDown] public void TearDown() { if ( loader.IsTestLoaded ) loader.UnloadTest(); if ( loader.IsProjectLoaded ) loader.UnloadProject(); } [Test] public void LoadProject() { loader.LoadProject( assembly ); Assert.IsTrue(loader.IsProjectLoaded, "Project not loaded"); Assert.IsFalse(loader.IsTestLoaded, "Test should not be loaded"); Assert.AreEqual( 2, catcher.Events.Count ); Assert.AreEqual( TestAction.ProjectLoading, ((TestEventArgs)catcher.Events[0]).Action ); Assert.AreEqual( TestAction.ProjectLoaded, ((TestEventArgs)catcher.Events[1]).Action ); } [Test] public void UnloadProject() { loader.LoadProject( assembly ); loader.UnloadProject(); Assert.IsFalse( loader.IsProjectLoaded, "Project not unloaded" ); Assert.IsFalse( loader.IsTestLoaded, "Test not unloaded" ); Assert.AreEqual( 4, catcher.Events.Count ); Assert.AreEqual( TestAction.ProjectUnloading, ((TestEventArgs)catcher.Events[2]).Action ); Assert.AreEqual( TestAction.ProjectUnloaded, ((TestEventArgs)catcher.Events[3]).Action ); } [Test] public void LoadTest() { LoadTest( assembly ); Assert.IsTrue( loader.IsProjectLoaded, "Project not loaded" ); Assert.IsTrue( loader.IsTestLoaded, "Test not loaded" ); Assert.AreEqual( 4, catcher.Events.Count ); Assert.AreEqual( TestAction.TestLoading, ((TestEventArgs)catcher.Events[2]).Action ); Assert.AreEqual( TestAction.TestLoaded, ((TestEventArgs)catcher.Events[3]).Action ); Assert.AreEqual( MockAssembly.Tests, ((TestEventArgs)catcher.Events[3]).TestCount ); } [Test] public void UnloadTest() { LoadTest( assembly ); loader.UnloadTest(); Assert.AreEqual( 6, catcher.Events.Count ); Assert.AreEqual( TestAction.TestUnloading, ((TestEventArgs)catcher.Events[4]).Action ); Assert.AreEqual( TestAction.TestUnloaded, ((TestEventArgs)catcher.Events[5]).Action ); } [Test] public void FileNotFound() { LoadTest( "xxxxx" ); Assert.IsFalse( loader.IsProjectLoaded, "Project should not load" ); Assert.IsFalse( loader.IsTestLoaded, "Test should not load" ); Assert.AreEqual( 2, catcher.Events.Count ); Assert.AreEqual( TestAction.ProjectLoadFailed, ((TestEventArgs)catcher.Events[1]).Action ); Assert.AreEqual( typeof( FileNotFoundException ), ((TestEventArgs)catcher.Events[1]).Exception.GetType() ); } // Doesn't work under .NET 2.0 Beta 2 //[Test] public void InvalidAssembly() { FileInfo file = new FileInfo(badFile); try { StreamWriter sw = file.AppendText(); sw.WriteLine("This is a new entry to add to the file"); sw.WriteLine("This is yet another line to add..."); sw.Flush(); sw.Close(); LoadTest(badFile); Assert.IsTrue(loader.IsProjectLoaded, "Project not loaded"); Assert.IsFalse(loader.IsTestLoaded, "Test should not be loaded"); Assert.AreEqual(4, catcher.Events.Count); Assert.AreEqual(TestAction.TestLoadFailed, ((TestEventArgs)catcher.Events[3]).Action); Assert.AreEqual(typeof(BadImageFormatException), ((TestEventArgs)catcher.Events[3]).Exception.GetType()); } finally { if ( file.Exists ) file.Delete(); } } [Test] public void AssemblyWithNoTests() { LoadTest( "nunit.framework.dll" ); Assert.IsTrue( loader.IsProjectLoaded, "Project not loaded" ); Assert.IsTrue( loader.IsTestLoaded, "Test not loaded" ); Assert.AreEqual( 4, catcher.Events.Count ); Assert.AreEqual( TestAction.TestLoaded, ((TestEventArgs)catcher.Events[3]).Action ); } // TODO: Should wrapper project be unloaded on failure? [Test] public void RunTest() { //loader.ReloadOnRun = false; LoadTest( assembly ); loader.RunTests(TestFilter.Empty); do { // TODO: Find a more robust way of handling this Thread.Sleep( 500 ); } while( !catcher.GotRunFinished ); Assert.AreEqual(TestAction.ProjectLoading, ((TestEventArgs)catcher.Events[0]).Action); Assert.AreEqual(TestAction.ProjectLoaded, ((TestEventArgs)catcher.Events[1]).Action); Assert.AreEqual(TestAction.TestLoading, ((TestEventArgs)catcher.Events[2]).Action); Assert.AreEqual(TestAction.TestLoaded, ((TestEventArgs)catcher.Events[3]).Action); Assert.AreEqual(TestAction.RunStarting, ((TestEventArgs)catcher.Events[4]).Action); int eventCount = 4 /* for loading */+ 2 * (MockAssembly.Nodes - MockAssembly.Explicit); if (eventCount != catcher.Events.Count) foreach (TestEventArgs e in catcher.Events) Console.WriteLine(e.Action); Assert.AreEqual(eventCount, catcher.Events.Count); Assert.AreEqual(TestAction.RunFinished, ((TestEventArgs)catcher.Events[eventCount - 1]).Action); int nTests = 0; int nRun = 0; foreach( object o in catcher.Events ) { TestEventArgs e = o as TestEventArgs; if ( e != null && e.Action == TestAction.TestFinished ) { ++nTests; if ( e.Result.Executed ) ++nRun; } } Assert.AreEqual( MockAssembly.ResultCount, nTests ); Assert.AreEqual( MockAssembly.TestsRun, nRun ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/NUnitProjectLoad.cs0000664000175000017500000000744111663740564023757 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.IO; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.Util.Tests { // TODO: Some of these tests are really tests of VSProject and should be moved there. [TestFixture] public class NUnitProjectLoad { static readonly string xmlfile = Path.Combine(Path.GetTempPath(), "test.nunit"); static readonly string mockDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; private ProjectService projectService; private NUnitProject project; [SetUp] public void SetUp() { projectService = new ProjectService(); project = projectService.EmptyProject(); } [TearDown] public void TearDown() { if ( File.Exists( xmlfile ) ) File.Delete( xmlfile ); } // Write a string out to our xml file and then load project from it private void LoadProject( string source ) { StreamWriter writer = new StreamWriter( xmlfile ); writer.Write( source ); writer.Close(); project.ProjectPath = Path.GetFullPath( xmlfile ); project.Load(); } [Test] public void LoadEmptyProject() { LoadProject( NUnitProjectXml.EmptyProject ); Assert.AreEqual( 0, project.Configs.Count ); } [Test] public void LoadEmptyConfigs() { LoadProject( NUnitProjectXml.EmptyConfigs ); Assert.AreEqual( 2, project.Configs.Count ); Assert.IsTrue( project.Configs.Contains( "Debug") ); Assert.IsTrue( project.Configs.Contains( "Release") ); } [Test] public void LoadNormalProject() { LoadProject( NUnitProjectXml.NormalProject ); Assert.AreEqual( 2, project.Configs.Count ); string tempPath = Path.GetTempPath(); ProjectConfig config1 = project.Configs["Debug"]; Assert.AreEqual( 2, config1.Assemblies.Count ); Assert.AreEqual( Path.Combine(tempPath, @"bin" + Path.DirectorySeparatorChar + "debug" + Path.DirectorySeparatorChar + "assembly1.dll" ), config1.Assemblies[0] ); Assert.AreEqual( Path.Combine(tempPath, @"bin" + Path.DirectorySeparatorChar + "debug" + Path.DirectorySeparatorChar + "assembly2.dll" ), config1.Assemblies[1] ); ProjectConfig config2 = project.Configs["Release"]; Assert.AreEqual( 2, config2.Assemblies.Count ); Assert.AreEqual( Path.Combine(tempPath, @"bin" + Path.DirectorySeparatorChar + "release" + Path.DirectorySeparatorChar + "assembly1.dll" ), config2.Assemblies[0] ); Assert.AreEqual( Path.Combine(tempPath, @"bin" + Path.DirectorySeparatorChar + "release" + Path.DirectorySeparatorChar + "assembly2.dll" ), config2.Assemblies[1] ); } [Test] public void LoadProjectWithManualBinPath() { LoadProject( NUnitProjectXml.ManualBinPathProject ); Assert.AreEqual( 1, project.Configs.Count ); ProjectConfig config1 = project.Configs["Debug"]; Assert.AreEqual( "bin_path_value", config1.PrivateBinPath ); } [Test] public void FromAssembly() { NUnitProject project = projectService.WrapAssembly(mockDll); Assert.AreEqual( "Default", project.ActiveConfigName ); Assert.SamePath( mockDll, project.ActiveConfig.Assemblies[0] ); Assert.IsTrue( project.IsLoadable, "Not loadable" ); Assert.IsTrue( project.IsAssemblyWrapper, "Not wrapper" ); Assert.IsFalse( project.IsDirty, "Not dirty" ); } [Test] public void SaveClearsAssemblyWrapper() { NUnitProject project = projectService.WrapAssembly(mockDll); project.Save( xmlfile ); Assert.IsFalse( project.IsAssemblyWrapper, "Changed project should no longer be wrapper"); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestDomainTests_Multiple.cs0000664000175000017500000000544111702655226025530 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.IO; using NUnit.Framework; using NUnit.Core; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { /// /// Summary description for MultipleAssembliesDomain. /// [TestFixture] public class TestDomainTests_Multiple { private TestDomain domain; private ITest loadedSuite; private static string path1 = NoNamespaceTestFixture.AssemblyPath; private static string path2 = MockAssembly.AssemblyPath; private string name = "Multiple Assemblies Test"; [TestFixtureSetUp] public void Init() { domain = new TestDomain(); TestPackage package = new TestPackage( name ); package.Assemblies.Add( path1 ); package.Assemblies.Add( path2 ); domain.Load( package ); loadedSuite = domain.Test; } [TestFixtureTearDown] public void UnloadTestDomain() { domain.Unload(); domain = null; } [Test] public void BuildSuite() { Assert.IsNotNull(loadedSuite); } [Test] public void RootNode() { Assert.AreEqual( name, loadedSuite.TestName.Name ); } [Test] public void AssemblyNodes() { TestNode test0 = (TestNode)loadedSuite.Tests[0]; TestNode test1 = (TestNode)loadedSuite.Tests[1]; Assert.AreEqual( path1, test0.TestName.Name ); Assert.AreEqual( path2, test1.TestName.Name ); } [Test] public void TestCaseCount() { Assert.AreEqual(NoNamespaceTestFixture.Tests + MockAssembly.Tests, loadedSuite.TestCount ); } [Test] public void RunMultipleAssemblies() { TestResult result = domain.Run(NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off); ResultSummarizer summary = new ResultSummarizer(result); Assert.AreEqual( NoNamespaceTestFixture.Tests + MockAssembly.TestsRun, summary.TestsRun); } } [TestFixture] public class TestDomainTests_MultipleFixture { [Test] public void LoadFixture() { TestDomain domain = new TestDomain(); TestPackage package = new TestPackage( "Multiple Assemblies Test" ); package.Assemblies.Add(NoNamespaceTestFixture.AssemblyPath); package.Assemblies.Add(MockAssembly.AssemblyPath); package.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; try { domain.Load(package); Assert.AreEqual(MockTestFixture.Tests, domain.Test.TestCount); } finally { domain.Unload(); } } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/ServerUtilityTests.cs0000664000175000017500000000331211504175260024426 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using NUnit.Framework; namespace NUnit.Util.Tests { /// /// Summary description for RemotingUtilitiesTests. /// [TestFixture] public class ServerUtilityTests { TcpChannel channel1; TcpChannel channel2; [TearDown] public void ReleaseChannels() { ServerUtilities.SafeReleaseChannel( channel1 ); ServerUtilities.SafeReleaseChannel( channel2 ); } [Test] public void CanGetTcpChannelOnSpecifiedPort() { channel1 = ServerUtilities.GetTcpChannel( "test", 1234 ); Assert.AreEqual( "test", channel1.ChannelName ); channel2 = ServerUtilities.GetTcpChannel( "test", 4321 ); Assert.AreEqual( "test", channel2.ChannelName ); Assert.AreEqual( channel1, channel2 ); Assert.AreSame( channel1, channel2 ); ChannelDataStore cds = (ChannelDataStore)channel1.ChannelData; Assert.AreEqual( "tcp://127.0.0.1:1234", cds.ChannelUris[0] ); } [Test] public void CanGetTcpChannelOnUnpecifiedPort() { channel1 = ServerUtilities.GetTcpChannel( "test", 0 ); Assert.AreEqual( "test", channel1.ChannelName ); channel2 = ServerUtilities.GetTcpChannel( "test", 0 ); Assert.AreEqual( "test", channel2.ChannelName ); Assert.AreEqual( channel1, channel2 ); Assert.AreSame( channel1, channel2 ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/0000775000175000017500000000000011742560362022242 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ClientUtilities/tests/resources/csharp-sample_VS2005.csproj0000664000175000017500000001011311504175260027131 0ustar jtaylorjtaylor Local 8.0.40607 2.0 {15D66EEE-A852-4A52-89C2-83E74ECF3770} Debug AnyCPU csharp-sample_VS2005 JScript Grid IE50 false Library csharp_sample OnBuildSuccess bin\Debug\ false 285212672 false DEBUG;TRACE true 4096 false false false false false 4 bin\Release\ false 285212672 false TRACE false 4096 false true false false false 4 nunit.framework E:\Program Files\NUnit 2.2\bin\nunit.framework.dll hklm\dn\nunit.framework System ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll System.Data ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll System.XML ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll Code Code NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/CPPLibrary.vcproj0000664000175000017500000001061311504175260025432 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/MissingOutputPath.csproj0000664000175000017500000000416211610162112027117 0ustar jtaylorjtaylor AnyCPU 8.0.30703 2.0 {6BF38215-C9D9-418D-9D81-4DECBA679223} Library Properties MissingOutputPath MissingOutputPath v3.5 512 bin\Common\ true full false DEBUG;TRACE prompt 4 pdbonly true TRACE prompt 4 NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/vb-sample_VS2005.vbproj0000664000175000017500000000754211504175260026276 0ustar jtaylorjtaylor Local 8.0.40607 2.0 {F199991B-6C8E-4AB0-9AAA-703CD4897700} Debug AnyCPU vb-sample_VS2005 None JScript Grid IE50 false Library Binary On Off vb_sample bin\ 285212672 true true true false false false false 1 42016,42017,42018,42019,42032 bin\ 285212672 false true false true false false false 1 42016,42017,42018,42019,42032 nunit.framework E:\Program Files\NUnit 2.2\bin\nunit.framework.dll hklm\dn\nunit.framework System System.Data System.XML Code Code NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/jsharp_VS2005.vjsproj0000664000175000017500000000714611504175260026072 0ustar jtaylorjtaylor Local 8.0.40607 2.0 {B55A6E53-57A9-4205-B396-C9983B3AF46A} Debug AnyCPU jsharp_VS2005 JScript Grid IE50 Library jsharp OnBuildSuccess bin\Debug\ 285212672 DEBUG;TRACE true false false false 4 bin\Release\ 285212672 TRACE false true false false 4 nunit.framework E:\Program Files\NUnit 2.2\bin\nunit.framework.dll hklm\dn\nunit.framework System ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll System.Data ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll System.XML ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll vjslib ..\..\..\..\..\WINDOWS\Microsoft Visual JSharp .NET\Framework\v1.0.4205\vjslib.dll Code Code NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/XNAWindowsProject.csproj0000664000175000017500000000715611504175260027020 0ustar jtaylorjtaylor {1BAC9824-B0E8-448F-B91A-80B93B9AB0F6} {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Debug x86 WinExe Properties XNAWindowsProject XNAWindowsProject v2.0 Windows 587ca330-4151-41aa-a721-18cbd58d91ce Game.ico GameThumbnail.png true full false bin\x86\Debug DEBUG;TRACE prompt 4 true false x86 pdbonly true bin\x86\Release TRACE prompt 4 true false x86 False True False True False False 04ff7472-dfb8-4502-90ea-a99a54be6748 False NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/ClassLibrary1.csproj0000664000175000017500000000707311504175260026141 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/vb-sample.vbproj0000664000175000017500000000766211504175260025362 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/MakeFileProject.vcproj0000664000175000017500000000260611504175260026472 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/jsharp.vjsproj0000664000175000017500000000754311504175260025154 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/DisabledProject.csproj0000664000175000017500000000470711650475624026536 0ustar jtaylorjtaylor Debug AnyCPU 9.0.21022 2.0 {45103FD8-4F1F-4B2D-9E75-20094E98EE64} Exe Properties DisabledProject DisabledProject v3.5 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 3.5 3.5 3.5 NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/samples_VS2005.sln0000664000175000017500000001222311504175260025336 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp-sample", "csharp\csharp-sample_VS2005.csproj", "{15D66EEE-A852-4A52-89C2-83E74ECF3770}" EndProject Project("{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}") = "jsharp", "jsharp\jsharp_VS2005.vjsproj", "{B55A6E53-57A9-4205-B396-C9983B3AF46A}" EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vb-sample", "vb\vb-sample_VS2005.vbproj", "{F199991B-6C8E-4AB0-9AAA-703CD4897700}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-sample", "cpp-sample\cpp-sample_VS2005.vcproj", "{7E5849C7-0469-4AD2-91B9-C87203934254}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed platforms = Debug|Mixed platforms Debug|Win32 = Debug|Win32 Release|Any CPU = Release|Any CPU Release|Mixed platforms = Release|Mixed platforms Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Any CPU.Build.0 = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Mixed platforms.Build.0 = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Win32.ActiveCfg = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug|Win32.Build.0 = Debug|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Any CPU.ActiveCfg = Release|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Any CPU.Build.0 = Release|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Mixed platforms.ActiveCfg = Release|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Mixed platforms.Build.0 = Release|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Win32.ActiveCfg = Release|Any CPU {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release|Win32.Build.0 = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Any CPU.Build.0 = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Mixed platforms.Build.0 = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Win32.ActiveCfg = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug|Win32.Build.0 = Debug|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Any CPU.ActiveCfg = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Any CPU.Build.0 = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Mixed platforms.ActiveCfg = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Mixed platforms.Build.0 = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Win32.ActiveCfg = Release|Any CPU {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release|Win32.Build.0 = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Any CPU.Build.0 = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Mixed platforms.Build.0 = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Win32.ActiveCfg = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug|Win32.Build.0 = Debug|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Any CPU.ActiveCfg = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Any CPU.Build.0 = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Mixed platforms.ActiveCfg = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Mixed platforms.Build.0 = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Win32.ActiveCfg = Release|Any CPU {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release|Win32.Build.0 = Release|Any CPU {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Any CPU.ActiveCfg = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Any CPU.Build.0 = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Mixed platforms.ActiveCfg = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Mixed platforms.Build.0 = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Win32.ActiveCfg = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug|Win32.Build.0 = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Any CPU.ActiveCfg = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Any CPU.Build.0 = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Mixed platforms.ActiveCfg = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Mixed platforms.Build.0 = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Win32.ActiveCfg = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/cpp-default-library_VS2005.vcproj0000664000175000017500000001227211504175260030253 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/samples.sln0000664000175000017500000000460511504175260024424 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp-sample", "csharp\csharp-sample.csproj", "{15D66EEE-A852-4A52-89C2-83E74ECF3770}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}") = "jsharp", "jsharp\jsharp.vjsproj", "{B55A6E53-57A9-4205-B396-C9983B3AF46A}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vb-sample", "vb\vb-sample.vbproj", "{F199991B-6C8E-4AB0-9AAA-703CD4897700}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-sample", "cpp-sample\cpp-sample.vcproj", "{7E5849C7-0469-4AD2-91B9-C87203934254}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug.ActiveCfg = Debug|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Debug.Build.0 = Debug|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release.ActiveCfg = Release|.NET {15D66EEE-A852-4A52-89C2-83E74ECF3770}.Release.Build.0 = Release|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug.ActiveCfg = Debug|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Debug.Build.0 = Debug|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release.ActiveCfg = Release|.NET {B55A6E53-57A9-4205-B396-C9983B3AF46A}.Release.Build.0 = Release|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug.ActiveCfg = Debug|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Debug.Build.0 = Debug|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release.ActiveCfg = Release|.NET {F199991B-6C8E-4AB0-9AAA-703CD4897700}.Release.Build.0 = Release|.NET {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug.ActiveCfg = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Debug.Build.0 = Debug|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release.ActiveCfg = Release|Win32 {7E5849C7-0469-4AD2-91B9-C87203934254}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/csharp-sample.csproj0000664000175000017500000001037011504175260026217 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/cpp-sample.vcproj0000664000175000017500000000741511504175260025532 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/Solution1.sln0000664000175000017500000000263611504175260024657 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{2F5189E6-19B3-465F-AF2D-41231B38A64E}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Unmanaged", "Unmanaged\Unmanaged.vcproj", "{FDBEFC64-EDEF-4645-81EB-C6EA9597170D}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {2F5189E6-19B3-465F-AF2D-41231B38A64E}.Debug.ActiveCfg = Debug|.NET {2F5189E6-19B3-465F-AF2D-41231B38A64E}.Debug.Build.0 = Debug|.NET {2F5189E6-19B3-465F-AF2D-41231B38A64E}.Release.ActiveCfg = Release|.NET {2F5189E6-19B3-465F-AF2D-41231B38A64E}.Release.Build.0 = Release|.NET {FDBEFC64-EDEF-4645-81EB-C6EA9597170D}.Debug.ActiveCfg = Debug|Win32 {FDBEFC64-EDEF-4645-81EB-C6EA9597170D}.Debug.Build.0 = Debug|Win32 {FDBEFC64-EDEF-4645-81EB-C6EA9597170D}.Release.ActiveCfg = Release|Win32 {FDBEFC64-EDEF-4645-81EB-C6EA9597170D}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/DisabledProject.sln0000664000175000017500000000247011650476064026024 0ustar jtaylorjtaylor Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisabledProject", "DisabledProject\DisabledProject.csproj", "{45103FD8-4F1F-4B2D-9E75-20094E98EE64}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugOnly", "DebugOnly\DebugOnly.csproj", "{B9DB5E6C-8A54-40F9-9B1E-225B58FE7ED4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {45103FD8-4F1F-4B2D-9E75-20094E98EE64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {45103FD8-4F1F-4B2D-9E75-20094E98EE64}.Debug|Any CPU.Build.0 = Debug|Any CPU {45103FD8-4F1F-4B2D-9E75-20094E98EE64}.Release|Any CPU.ActiveCfg = Release|Any CPU {45103FD8-4F1F-4B2D-9E75-20094E98EE64}.Release|Any CPU.Build.0 = Release|Any CPU {B9DB5E6C-8A54-40F9-9B1E-225B58FE7ED4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9DB5E6C-8A54-40F9-9B1E-225B58FE7ED4}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9DB5E6C-8A54-40F9-9B1E-225B58FE7ED4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/HebrewFileProblem.csproj0000664000175000017500000001164211504175260027020 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/MultiplePlatformProject.csproj0000664000175000017500000001044511504175260030312 0ustar jtaylorjtaylor Debug AnyCPU 8.0.50727 2.0 {23FF0E4C-DA55-4CC7-A948-09877A66001F} Library Properties MultiplePlatformProject MultiplePlatformProject true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 true bin\x64\Debug\ DEBUG;TRACE full x64 \rules true GlobalSuppressions.cs prompt bin\x64\Release\ TRACE true pdbonly x64 \rules true GlobalSuppressions.cs prompt true bin\x86\Debug\ DEBUG;TRACE full x86 \rules true GlobalSuppressions.cs prompt bin\x86\Release\ TRACE true pdbonly x86 \rules true GlobalSuppressions.cs prompt NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/TestResource.cs0000664000175000017500000000062111543625326025220 0ustar jtaylorjtaylorusing System; namespace NUnit.Util.Tests.resources { public class TestResource : NUnit.TestUtilities.TempResourceFile { public TestResource(string name) : base(typeof(TestResource), name) { } public TestResource(string name, string filePath) : base(typeof(TestResource), name, filePath) { } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/WebApplication1.sln0000664000175000017500000000260011504175260025733 0ustar jtaylorjtaylorMicrosoft Visual Studio Solution File, Format Version 7.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication1", "http://localhost/WebApplication1/WebApplication1.csproj", "{7123B53C-8003-454D-92D1-E9E8C533CBED}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{48E7F6A7-5E5C-4046-AD8E-5381D98D55B8}" EndProject Global GlobalSection(SolutionConfiguration) = preSolution ConfigName.0 = Debug ConfigName.1 = Release EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7123B53C-8003-454D-92D1-E9E8C533CBED}.Debug.ActiveCfg = Debug|.NET {7123B53C-8003-454D-92D1-E9E8C533CBED}.Debug.Build.0 = Debug|.NET {7123B53C-8003-454D-92D1-E9E8C533CBED}.Release.ActiveCfg = Release|.NET {7123B53C-8003-454D-92D1-E9E8C533CBED}.Release.Build.0 = Release|.NET {48E7F6A7-5E5C-4046-AD8E-5381D98D55B8}.Debug.ActiveCfg = Debug|.NET {48E7F6A7-5E5C-4046-AD8E-5381D98D55B8}.Debug.Build.0 = Debug|.NET {48E7F6A7-5E5C-4046-AD8E-5381D98D55B8}.Release.ActiveCfg = Release|.NET {48E7F6A7-5E5C-4046-AD8E-5381D98D55B8}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/DebugOnly.csproj0000664000175000017500000000467611650476064025374 0ustar jtaylorjtaylor Debug AnyCPU 9.0.21022 2.0 {B9DB5E6C-8A54-40F9-9B1E-225B58FE7ED4} Library Properties DebugOnly DebugOnly v3.5 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 3.5 3.5 3.5 NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/Unmanaged.vcproj0000664000175000017500000000662311504175260025370 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/csharp-sample_VS2005_noplatform.csproj0000664000175000017500000001005511504175260031377 0ustar jtaylorjtaylor Local 8.0.40607 2.0 {15D66EEE-A852-4A52-89C2-83E74ECF3770} Debug AnyCPU csharp-sample_VS2005_noplatform JScript Grid IE50 false Library csharp_sample OnBuildSuccess bin\Debug\ false 285212672 false DEBUG;TRACE true 4096 false false false false false 4 bin\Release\ false 285212672 false TRACE false 4096 false true false false false 4 nunit.framework E:\Program Files\NUnit 2.2\bin\nunit.framework.dll hklm\dn\nunit.framework System ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll System.Data ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll System.XML ..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll Code Code NUnit-2.6.0.12051/src/ClientUtilities/tests/resources/cpp-sample_VS2005.vcproj0000664000175000017500000001047211504175260026446 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/RecentFilesTests.cs0000664000175000017500000001276411543055572024020 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Util.Tests { using System; using System.Collections; using Microsoft.Win32; using NUnit.Framework; /// /// This fixture is used to test both RecentProjects and /// its base class RecentFiles. If we add any other derived /// classes, the tests should be refactored. /// [TestFixture] public class RecentFilesTests { static readonly int MAX = RecentFilesService.MaxSize; static readonly int MIN = RecentFilesService.MinSize; RecentFilesService recentFiles; [SetUp] public void SetUp() { recentFiles = new RecentFilesService( new SettingsGroup( new MemorySettingsStorage() ) ); } #region Helper Methods // Set RecentFiles to a list of known values up // to a maximum. Most recent will be "1", next // "2", and so on... private void SetMockValues( int count ) { for( int num = count; num > 0; --num ) recentFiles.SetMostRecent( num.ToString() ); } // Check that the list is set right: 1, 2, ... private void CheckMockValues( int count ) { RecentFilesCollection files = recentFiles.Entries; Assert.AreEqual( count, files.Count, "Count" ); for( int index = 0; index < count; index++ ) Assert.AreEqual( (index + 1).ToString(), files[index].Path, "Item" ); } // Check that we can add count items correctly private void CheckAddItems( int count ) { SetMockValues( count ); Assert.AreEqual( "1", recentFiles.Entries[0].Path, "RecentFile" ); CheckMockValues( Math.Min( count, recentFiles.MaxFiles ) ); } // Check that the list contains a set of entries // in the order given and nothing else. private void CheckListContains( params int[] item ) { RecentFilesCollection files = recentFiles.Entries; Assert.AreEqual( item.Length, files.Count, "Count" ); for( int index = 0; index < files.Count; index++ ) Assert.AreEqual( item[index].ToString(), files[index].Path, "Item" ); } #endregion [Test] public void CountDefault() { Assert.AreEqual( RecentFilesService.DefaultSize, recentFiles.MaxFiles ); } [Test] public void CountOverMax() { recentFiles.MaxFiles = MAX + 1; Assert.AreEqual( MAX, recentFiles.MaxFiles ); } [Test] public void CountUnderMin() { recentFiles.MaxFiles = MIN - 1; Assert.AreEqual( MIN, recentFiles.MaxFiles ); } [Test] public void CountAtMax() { recentFiles.MaxFiles = MAX; Assert.AreEqual( MAX, recentFiles.MaxFiles ); } [Test] public void CountAtMin() { recentFiles.MaxFiles = MIN; Assert.AreEqual( MIN, recentFiles.MaxFiles ); } [Test] public void EmptyList() { Assert.IsNotNull( recentFiles.Entries, "Entries should never be null" ); Assert.AreEqual( 0, recentFiles.Count ); Assert.AreEqual( 0, recentFiles.Entries.Count ); } [Test] public void AddSingleItem() { CheckAddItems( 1 ); } [Test] public void AddMaxItems() { CheckAddItems( 5 ); } [Test] public void AddTooManyItems() { CheckAddItems( 10 ); } [Test] public void IncreaseSize() { recentFiles.MaxFiles = 10; CheckAddItems( 10 ); } [Test] public void ReduceSize() { recentFiles.MaxFiles = 3; CheckAddItems( 10 ); } [Test] public void IncreaseSizeAfterAdd() { SetMockValues(5); recentFiles.MaxFiles = 7; recentFiles.SetMostRecent( "30" ); recentFiles.SetMostRecent( "20" ); recentFiles.SetMostRecent( "10" ); CheckListContains( 10, 20, 30, 1, 2, 3, 4 ); } [Test] public void ReduceSizeAfterAdd() { SetMockValues( 5 ); recentFiles.MaxFiles = 3; CheckMockValues( 3 ); } [Test] public void ReorderLastProject() { SetMockValues( 5 ); recentFiles.SetMostRecent( "5" ); CheckListContains( 5, 1, 2, 3, 4 ); } [Test] public void ReorderSingleProject() { SetMockValues( 5 ); recentFiles.SetMostRecent( "3" ); CheckListContains( 3, 1, 2, 4, 5 ); } [Test] public void ReorderMultipleProjects() { SetMockValues( 5 ); recentFiles.SetMostRecent( "3" ); recentFiles.SetMostRecent( "5" ); recentFiles.SetMostRecent( "2" ); CheckListContains( 2, 5, 3, 1, 4 ); } [Test] public void ReorderSameProject() { SetMockValues( 5 ); recentFiles.SetMostRecent( "1" ); CheckListContains( 1, 2, 3, 4, 5 ); } [Test] public void ReorderWithListNotFull() { SetMockValues( 3 ); recentFiles.SetMostRecent( "3" ); CheckListContains( 3, 1, 2 ); } [Test] public void RemoveFirstProject() { SetMockValues( 3 ); recentFiles.Remove("1"); CheckListContains( 2, 3 ); } [Test] public void RemoveOneProject() { SetMockValues( 4 ); recentFiles.Remove("2"); CheckListContains( 1, 3, 4 ); } [Test] public void RemoveMultipleProjects() { SetMockValues( 5 ); recentFiles.Remove( "3" ); recentFiles.Remove( "1" ); recentFiles.Remove( "4" ); CheckListContains( 2, 5 ); } [Test] public void RemoveLastProject() { SetMockValues( 5 ); recentFiles.Remove("5"); CheckListContains( 1, 2, 3, 4 ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/ProjectConfigTests.cs0000664000175000017500000003141711543625326024345 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using NUnit.Framework; namespace NUnit.Util.Tests { /// /// Summary description for ProjectConfigTests. /// [TestFixture] public class ProjectConfigTests { private ProjectConfig activeConfig; private ProjectConfig inactiveConfig; private NUnitProject project; [SetUp] public void SetUp() { activeConfig = new ProjectConfig( "Debug" ); inactiveConfig = new ProjectConfig("Release"); project = new NUnitProject( TestPath( "/test/myproject.nunit" ) ); project.Configs.Add( activeConfig ); project.Configs.Add(inactiveConfig); project.IsDirty = false; project.HasChangesRequiringReload = false; } /// /// Take a valid Linux filePath and make a valid windows filePath out of it /// if we are on Windows. Change slashes to backslashes and, if the /// filePath starts with a slash, add C: in front of it. /// private string TestPath(string path) { if (Path.DirectorySeparatorChar != '/') { path = path.Replace('/', Path.DirectorySeparatorChar); if (path[0] == Path.DirectorySeparatorChar) path = "C:" + path; } return path; } [Test] public void EmptyConfig() { Assert.AreEqual( "Debug", activeConfig.Name ); Assert.AreEqual( 0, activeConfig.Assemblies.Count ); } [Test] public void CanAddAssemblies() { string path1 = TestPath("/test/assembly1.dll"); string path2 = TestPath("/test/assembly2.dll"); activeConfig.Assemblies.Add(path1); activeConfig.Assemblies.Add( path2 ); Assert.AreEqual( 2, activeConfig.Assemblies.Count ); Assert.AreEqual( path1, activeConfig.Assemblies[0] ); Assert.AreEqual( path2, activeConfig.Assemblies[1] ); } [Test] public void ToArray() { string path1 = TestPath("/test/assembly1.dll"); string path2 = TestPath("/test/assembly2.dll"); activeConfig.Assemblies.Add( path1 ); activeConfig.Assemblies.Add( path2 ); string[] files = activeConfig.Assemblies.ToArray(); Assert.AreEqual( path1, files[0] ); Assert.AreEqual( path2, files[1] ); } [Test] public void AddToActiveConfigMarksProjectDirty() { activeConfig.Assemblies.Add(TestPath("/test/bin/debug/assembly1.dll")); Assert.IsTrue(project.IsDirty); } [Test] public void AddToActiveConfigRequiresReload() { activeConfig.Assemblies.Add(TestPath("/test/bin/debug/assembly1.dll")); Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void AddToInactiveConfigMarksProjectDirty() { inactiveConfig.Assemblies.Add(TestPath("/test/bin/release/assembly1.dll")); Assert.IsTrue(project.IsDirty); } [Test] public void AddToInactiveConfigDoesNotRequireReload() { inactiveConfig.Assemblies.Add(TestPath("/test/bin/release/assembly1.dll")); Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void AddingConfigMarksProjectDirty() { project.Configs.Add("New"); Assert.IsTrue(project.IsDirty); } [Test] public void AddingInitialConfigRequiresReload() { NUnitProject newProj = new NUnitProject("/junk"); newProj.HasChangesRequiringReload = false; newProj.Configs.Add("New"); Assert.That(newProj.HasChangesRequiringReload); } [Test] public void AddingSubsequentConfigDoesNotRequireReload() { project.Configs.Add("New"); Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void RenameActiveConfigMarksProjectDirty() { activeConfig.Name = "Renamed"; Assert.IsTrue(project.IsDirty); } [Test] public void RenameActiveConfigRequiresReload() { activeConfig.Name = "Renamed"; Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void RenameInctiveConfigMarksProjectDirty() { inactiveConfig.Name = "Renamed"; Assert.IsTrue(project.IsDirty); } [Test] public void RenameInactiveConfigDoesNotRequireReload() { inactiveConfig.Name = "Renamed"; Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void RemoveActiveConfigMarksProjectDirty() { string path1 = TestPath("/test/bin/debug/assembly1.dll"); activeConfig.Assemblies.Add(path1); project.IsDirty = false; activeConfig.Assemblies.Remove(path1); Assert.IsTrue(project.IsDirty); } [Test] public void RemoveActiveConfigRequiresReload() { string path1 = TestPath("/test/bin/debug/assembly1.dll"); activeConfig.Assemblies.Add(path1); project.IsDirty = false; activeConfig.Assemblies.Remove(path1); Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void RemoveInactiveConfigMarksProjectDirty() { string path1 = TestPath("/test/bin/debug/assembly1.dll"); inactiveConfig.Assemblies.Add(path1); project.IsDirty = false; inactiveConfig.Assemblies.Remove(path1); Assert.IsTrue(project.IsDirty); } [Test] public void RemoveInactiveConfigDoesNotRequireReload() { string path1 = TestPath("/test/bin/debug/assembly1.dll"); inactiveConfig.Assemblies.Add(path1); project.HasChangesRequiringReload = false; inactiveConfig.Assemblies.Remove(path1); Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void SettingActiveConfigApplicationBaseMarksProjectDirty() { activeConfig.BasePath = TestPath("/junk"); Assert.IsTrue(project.IsDirty); } [Test] public void SettingActiveConfigApplicationBaseRequiresReload() { activeConfig.BasePath = TestPath("/junk"); Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void SettingInactiveConfigApplicationBaseMarksProjectDirty() { inactiveConfig.BasePath = TestPath("/junk"); Assert.IsTrue(project.IsDirty); } [Test] public void SettingInactiveConfigApplicationBaseDoesNotRequireReload() { inactiveConfig.BasePath = TestPath("/junk"); Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void AbsoluteBasePath() { activeConfig.BasePath = TestPath("/junk"); string path1 = TestPath( "/junk/bin/debug/assembly1.dll" ); activeConfig.Assemblies.Add( path1 ); Assert.AreEqual( path1, activeConfig.Assemblies[0] ); } [Test] public void RelativeBasePath() { activeConfig.BasePath = @"junk"; string path1 = TestPath("/test/junk/bin/debug/assembly1.dll"); activeConfig.Assemblies.Add( path1 ); Assert.AreEqual( path1, activeConfig.Assemblies[0] ); } [Test] public void NoBasePathSet() { string path1 = TestPath( "/test/bin/debug/assembly1.dll" ); activeConfig.Assemblies.Add( path1 ); Assert.AreEqual( path1, activeConfig.Assemblies[0] ); } [Test] public void SettingActiveConfigConfigurationFileMarksProjectDirty() { activeConfig.ConfigurationFile = "MyProject.config"; Assert.IsTrue(project.IsDirty); } [Test] public void SettingActiveConfigConfigurationFileRequiresReload() { activeConfig.ConfigurationFile = "MyProject.config"; Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void SettingInactiveConfigConfigurationFileMarksProjectDirty() { inactiveConfig.ConfigurationFile = "MyProject.config"; Assert.IsTrue(project.IsDirty); } [Test] public void SettingInactiveConfigConfigurationFileDoesNotRequireReload() { inactiveConfig.ConfigurationFile = "MyProject.config"; Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void DefaultConfigurationFile() { Assert.AreEqual( "myproject.config", activeConfig.ConfigurationFile ); Assert.AreEqual( TestPath( "/test/myproject.config" ), activeConfig.ConfigurationFilePath ); } [Test] public void AbsoluteConfigurationFile() { string path1 = TestPath("/configs/myconfig.config"); activeConfig.ConfigurationFile = path1; Assert.AreEqual( path1, activeConfig.ConfigurationFilePath ); } [Test] public void RelativeConfigurationFile() { activeConfig.ConfigurationFile = "myconfig.config"; Assert.AreEqual( TestPath( "/test/myconfig.config" ), activeConfig.ConfigurationFilePath ); } [Test] public void SettingActiveConfigPrivateBinPathMarksProjectDirty() { activeConfig.PrivateBinPath = TestPath("/junk") + Path.PathSeparator + TestPath("/bin"); Assert.IsTrue(project.IsDirty); } [Test] public void SettingActiveConfigPrivateBinPathRequiresReload() { activeConfig.PrivateBinPath = TestPath("/junk") + Path.PathSeparator + TestPath("/bin"); Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void SettingInactiveConfigPrivateBinPathMarksProjectDirty() { inactiveConfig.PrivateBinPath = TestPath("/junk") + Path.PathSeparator + TestPath("/bin"); Assert.IsTrue(project.IsDirty); } [Test] public void SettingInactiveConfigPrivateBinPathDoesNotRequireReload() { inactiveConfig.PrivateBinPath = TestPath("/junk") + Path.PathSeparator + TestPath("/bin"); Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void SettingActiveConfigBinPathTypeMarksProjectDirty() { activeConfig.BinPathType = BinPathType.Manual; Assert.IsTrue(project.IsDirty); } [Test] public void SettingActiveConfigBinPathTypeRequiresReload() { activeConfig.BinPathType = BinPathType.Manual; Assert.IsTrue(project.HasChangesRequiringReload); } [Test] public void SettingInactiveConfigBinPathTypeMarksProjectDirty() { inactiveConfig.BinPathType = BinPathType.Manual; Assert.IsTrue(project.IsDirty); } [Test] public void SettingInactiveConfigBinPathTypeDoesNotRequireReload() { inactiveConfig.BinPathType = BinPathType.Manual; Assert.IsFalse(project.HasChangesRequiringReload); } [Test] public void NoPrivateBinPath() { activeConfig.Assemblies.Add( TestPath( "/bin/assembly1.dll" ) ); activeConfig.Assemblies.Add( TestPath( "/bin/assembly2.dll" ) ); activeConfig.BinPathType = BinPathType.None; Assert.IsNull( activeConfig.PrivateBinPath ); } [Test] public void ManualPrivateBinPath() { activeConfig.Assemblies.Add( TestPath( "/test/bin/assembly1.dll" ) ); activeConfig.Assemblies.Add( TestPath( "/test/bin/assembly2.dll" ) ); activeConfig.BinPathType = BinPathType.Manual; activeConfig.PrivateBinPath = TestPath( "/test" ); Assert.AreEqual( TestPath( "/test" ), activeConfig.PrivateBinPath ); } // TODO: Move to DomainManagerTests // [Test] // public void AutoPrivateBinPath() // { // config.Assemblies.Add( TestPath( "/test/bin/assembly1.dll" ) ); // config.Assemblies.Add( TestPath( "/test/bin/assembly2.dll" ) ); // config.BinPathType = BinPathType.Auto; // Assert.AreEqual( "bin", config.PrivateBinPath ); // } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/nunit.util.tests.build0000664000175000017500000000762611544333462024535 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ClientUtilities/tests/NUnitProjectSave.cs0000664000175000017500000000476511543625326023777 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Text; using System.Xml; using System.IO; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class NUnitProjectSave { static readonly string xmlfile = Path.Combine(Path.GetTempPath(), "test.nunit"); private NUnitProject project; [SetUp] public void SetUp() { project = new ProjectService().EmptyProject(); } [TearDown] public void TearDown() { if ( File.Exists( xmlfile ) ) File.Delete( xmlfile ); } private void CheckContents( string expected ) { StreamReader reader = new StreamReader( xmlfile ); string contents = reader.ReadToEnd(); reader.Close(); Assert.AreEqual( expected, contents ); } [Test] public void SaveEmptyProject() { project.Save( xmlfile ); CheckContents( NUnitProjectXml.EmptyProject ); } [Test] public void SaveEmptyConfigs() { project.Configs.Add( "Debug" ); project.Configs.Add( "Release" ); project.Save( xmlfile ); CheckContents( NUnitProjectXml.EmptyConfigs ); } [Test] public void SaveNormalProject() { string tempPath = Path.GetTempPath(); ProjectConfig config1 = new ProjectConfig( "Debug" ); config1.BasePath = "bin" + Path.DirectorySeparatorChar + "debug"; config1.Assemblies.Add( Path.Combine(tempPath, "bin" + Path.DirectorySeparatorChar + "debug" + Path.DirectorySeparatorChar + "assembly1.dll" ) ); config1.Assemblies.Add( Path.Combine(tempPath, "bin" + Path.DirectorySeparatorChar + "debug" + Path.DirectorySeparatorChar + "assembly2.dll" ) ); ProjectConfig config2 = new ProjectConfig( "Release" ); config2.BasePath = "bin" + Path.DirectorySeparatorChar + "release"; config2.Assemblies.Add( Path.Combine(tempPath, "bin" + Path.DirectorySeparatorChar + "release" + Path.DirectorySeparatorChar + "assembly1.dll" ) ); config2.Assemblies.Add( Path.Combine(tempPath, "bin" + Path.DirectorySeparatorChar + "release" + Path.DirectorySeparatorChar + "assembly2.dll" ) ); project.Configs.Add( config1 ); project.Configs.Add( config2 ); project.Save( xmlfile ); CheckContents( NUnitProjectXml.NormalProject ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/PathUtilTests.cs0000664000175000017500000002410411543625326023336 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class PathUtilTests : PathUtils { [Test] public void CheckDefaults() { Assert.AreEqual( Path.DirectorySeparatorChar, PathUtils.DirectorySeparatorChar ); Assert.AreEqual( Path.AltDirectorySeparatorChar, PathUtils.AltDirectorySeparatorChar ); } } // Local Assert extension internal class Assert : NUnit.Framework.Assert { public static void SamePath( string path1, string path2 ) { string msg = "\r\n\texpected: Same path as <{0}>\r\n\t but was: <{1}>"; Assert.IsTrue( PathUtils.SamePath( path1, path2 ), msg, path1, path2 ); } public static void NotSamePath( string path1, string path2 ) { string msg = "\r\n\texpected: Not same path as <{0}>\r\n\t but was: <{1}>"; Assert.IsFalse( PathUtils.SamePath( path1, path2 ), msg, path1, path2 ); } public static void SamePathOrUnder( string path1, string path2 ) { string msg = "\r\n\texpected: Same path or under <{0}>\r\n\t but was: <{1}>"; Assert.IsTrue( PathUtils.SamePathOrUnder( path1, path2 ), msg, path1, path2 ); } public static void NotSamePathOrUnder( string path1, string path2 ) { string msg = "\r\n\texpected: Not same path or under <{0}>\r\n\t but was: <{1}>"; Assert.IsFalse( PathUtils.SamePathOrUnder( path1, path2 ), msg, path1, path2 ); } } [TestFixture] public class PathUtilTests_Windows : PathUtils { [TestFixtureSetUp] public static void SetUpUnixSeparators() { PathUtils.DirectorySeparatorChar = '\\'; PathUtils.AltDirectorySeparatorChar = '/'; } [TestFixtureTearDown] public static void RestoreDefaultSeparators() { PathUtils.DirectorySeparatorChar = System.IO.Path.DirectorySeparatorChar; PathUtils.AltDirectorySeparatorChar = System.IO.Path.AltDirectorySeparatorChar; } [Test] public void IsAssemblyFileType() { Assert.IsTrue( PathUtils.IsAssemblyFileType( @"c:\bin\test.dll" ) ); Assert.IsTrue( PathUtils.IsAssemblyFileType( @"test.exe" ) ); Assert.IsFalse( PathUtils.IsAssemblyFileType( @"c:\bin\test.nunit" ) ); } [Test] public void Canonicalize() { Assert.AreEqual( @"C:\folder1\file.tmp", PathUtils.Canonicalize( @"C:\folder1\.\folder2\..\file.tmp" ) ); Assert.AreEqual( @"folder1\file.tmp", PathUtils.Canonicalize( @"folder1\.\folder2\..\file.tmp" ) ); Assert.AreEqual( @"folder1\file.tmp", PathUtils.Canonicalize( @"folder1\folder2\.\..\file.tmp" ) ); Assert.AreEqual( @"file.tmp", PathUtils.Canonicalize( @"folder1\folder2\..\.\..\file.tmp" ) ); Assert.AreEqual( @"file.tmp", PathUtils.Canonicalize( @"folder1\folder2\..\..\..\file.tmp" ) ); } [Test] [Platform(Exclude="Linux")] public void RelativePath() { Assert.AreEqual( @"folder2\folder3", PathUtils.RelativePath( @"c:\folder1", @"c:\folder1\folder2\folder3" ) ); Assert.AreEqual( @"..\folder2\folder3", PathUtils.RelativePath( @"c:\folder1", @"c:\folder2\folder3" ) ); Assert.AreEqual( @"bin\debug", PathUtils.RelativePath( @"c:\folder1", @"bin\debug" ) ); Assert.IsNull( PathUtils.RelativePath( @"C:\folder", @"D:\folder" ), "Unrelated paths should return null" ); Assert.IsNull(PathUtils.RelativePath(@"C:\", @"D:\"), "Unrelated roots should return null"); Assert.IsNull(PathUtils.RelativePath(@"C:", @"D:"), "Unrelated roots (no trailing separators) should return null"); Assert.AreEqual(string.Empty, PathUtils.RelativePath(@"C:\folder1", @"C:\folder1")); Assert.AreEqual(string.Empty, PathUtils.RelativePath(@"C:\", @"C:\")); // First filePath consisting just of a root: Assert.AreEqual(@"folder1\folder2", PathUtils.RelativePath( @"C:\", @"C:\folder1\folder2")); // Trailing directory separator in first filePath shall be ignored: Assert.AreEqual(@"folder2\folder3", PathUtils.RelativePath( @"c:\folder1\", @"c:\folder1\folder2\folder3")); // Case-insensitive behaviour, preserving 2nd filePath directories in result: Assert.AreEqual(@"Folder2\Folder3", PathUtils.RelativePath( @"C:\folder1", @"c:\folder1\Folder2\Folder3")); Assert.AreEqual(@"..\Folder2\folder3", PathUtils.RelativePath( @"c:\folder1", @"C:\Folder2\folder3")); } [Test] public void SamePath() { Assert.SamePath( @"C:\folder1\file.tmp", @"c:\folder1\File.TMP" ); Assert.SamePath( @"C:\folder1\file.tmp", @"C:\folder1\.\folder2\..\file.tmp" ); Assert.NotSamePath( @"C:\folder1\file.tmp", @"C:\folder1\.\folder2\..\file.temp" ); Assert.SamePath( "D:/folder1/folder2", @"d:\Folder1\Folder2" ); } [Test] public void SamePathOrUnder() { Assert.SamePathOrUnder( @"C:\folder1\folder2\folder3", @"c:\folder1\.\folder2\junk\..\folder3" ); Assert.SamePathOrUnder( @"C:\folder1\folder2\", @"c:\folder1\.\folder2\junk\..\folder3" ); Assert.SamePathOrUnder( @"C:\folder1\folder2", @"c:\folder1\.\folder2\junk\..\folder3" ); Assert.SamePathOrUnder( @"C:\folder1\folder2", @"c:\folder1\.\Folder2\junk\..\folder3" ); Assert.NotSamePathOrUnder( @"C:\folder1\folder2", @"c:\folder1\.\folder22\junk\..\folder3" ); Assert.NotSamePathOrUnder( @"C:\folder1\folder2ile.tmp", @"D:\folder1\.\folder2\folder3\file.tmp" ); Assert.NotSamePathOrUnder( @"C:\", @"D:\" ); Assert.SamePathOrUnder( @"C:\", @"c:\" ); Assert.SamePathOrUnder( @"C:\", @"c:\bin\debug" ); } [Test] public void PathFromUri() { Assert.AreEqual( @"C:\a\b\c\my.dll", PathUtils.GetAssemblyPathFromFileUri( @"file:///C:\a\b\c\my.dll" ) ); Assert.AreEqual( @"C:\a\b\c\my.dll", PathUtils.GetAssemblyPathFromFileUri( @"file://C:\a\b\c\my.dll" ) ); } } [TestFixture] public class PathUtilTests_Unix : PathUtils { [TestFixtureSetUp] public static void SetUpUnixSeparators() { PathUtils.DirectorySeparatorChar = '/'; PathUtils.AltDirectorySeparatorChar = '\\'; } [TestFixtureTearDown] public static void RestoreDefaultSeparators() { PathUtils.DirectorySeparatorChar = System.IO.Path.DirectorySeparatorChar; PathUtils.AltDirectorySeparatorChar = System.IO.Path.AltDirectorySeparatorChar; } [Test] public void IsAssemblyFileType() { Assert.IsTrue( PathUtils.IsAssemblyFileType( "/bin/test.dll" ) ); Assert.IsTrue( PathUtils.IsAssemblyFileType( "test.exe" ) ); Assert.IsFalse( PathUtils.IsAssemblyFileType( "/bin/test.nunit" ) ); } [Test] public void Canonicalize() { Assert.AreEqual( "/folder1/file.tmp", PathUtils.Canonicalize( "/folder1/./folder2/../file.tmp" ) ); Assert.AreEqual( "folder1/file.tmp", PathUtils.Canonicalize( "folder1/./folder2/../file.tmp" ) ); Assert.AreEqual( "folder1/file.tmp", PathUtils.Canonicalize( "folder1/folder2/./../file.tmp" ) ); Assert.AreEqual( "file.tmp", PathUtils.Canonicalize( "folder1/folder2/.././../file.tmp" ) ); Assert.AreEqual( "file.tmp", PathUtils.Canonicalize( "folder1/folder2/../../../file.tmp" ) ); } [Test] public void RelativePath() { Assert.AreEqual( "folder2/folder3", PathUtils.RelativePath( "/folder1", "/folder1/folder2/folder3" ) ); Assert.AreEqual( "../folder2/folder3", PathUtils.RelativePath( "/folder1", "/folder2/folder3" ) ); Assert.AreEqual( "bin/debug", PathUtils.RelativePath( "/folder1", "bin/debug" ) ); Assert.AreEqual( "../other/folder", PathUtils.RelativePath( "/folder", "/other/folder" ) ); Assert.AreEqual( "../../d", PathUtils.RelativePath( "/a/b/c", "/a/d" ) ); Assert.AreEqual(string.Empty, PathUtils.RelativePath("/a/b", "/a/b")); Assert.AreEqual(string.Empty, PathUtils.RelativePath("/", "/")); // First filePath consisting just of a root: Assert.AreEqual("folder1/folder2", PathUtils.RelativePath( "/", "/folder1/folder2")); // Trailing directory separator in first filePath shall be ignored: Assert.AreEqual("folder2/folder3", PathUtils.RelativePath( "/folder1/", "/folder1/folder2/folder3")); // Case-sensitive behaviour: Assert.AreEqual("../Folder1/Folder2/folder3", PathUtils.RelativePath("/folder1", "/Folder1/Folder2/folder3"), "folders differing in case"); } [Test] public void SamePath() { Assert.SamePath( "/folder1/file.tmp", "/folder1/./folder2/../file.tmp" ); Assert.NotSamePath( "/folder1/file.tmp", "/folder1/File.TMP" ); Assert.NotSamePath( "/folder1/file.tmp", "/folder1/./folder2/../file.temp" ); Assert.SamePath( "/folder1/folder2", @"\folder1\folder2" ); } [Test] public void SamePathOrUnder() { Assert.SamePathOrUnder( "/folder1/folder2/folder3", "/folder1/./folder2/junk/../folder3" ); Assert.SamePathOrUnder( "/folder1/folder2/", "/folder1/./folder2/junk/../folder3" ); Assert.SamePathOrUnder( "/folder1/folder2", "/folder1/./folder2/junk/../folder3" ); Assert.NotSamePathOrUnder( "/folder1/folder2", "/folder1/./Folder2/junk/../folder3" ); Assert.NotSamePathOrUnder( "/folder1/folder2", "/folder1/./folder22/junk/../folder3" ); Assert.SamePathOrUnder( "/", "/" ); Assert.SamePathOrUnder( "/", "/bin/debug" ); } [Test] public void PathFromUri() { Assert.AreEqual( @"/a/b/c/my.dll", PathUtils.GetAssemblyPathFromFileUri( @"file:///a/b/c/my.dll" ) ); Assert.AreEqual( @"/a/b/c/my.dll", PathUtils.GetAssemblyPathFromFileUri( @"file://a/b/c/my.dll" ) ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/VSProjectTests.cs0000664000175000017500000001576311610156716023473 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.Util.Tests.resources; namespace NUnit.Util.Tests { [TestFixture] public class VSProjectTests { private string invalidFile = Path.Combine(Path.GetTempPath(), "invalid.csproj"); private void WriteInvalidFile( string text ) { StreamWriter writer = new StreamWriter( invalidFile ); writer.WriteLine( text ); writer.Close(); } [TearDown] public void EraseInvalidFile() { if ( File.Exists( invalidFile ) ) File.Delete( invalidFile ); } [Test] public void SolutionExtension() { Assert.IsTrue( VSProject.IsSolutionFile( TestPath( @"/x/y/project.sln" ) ) ); Assert.IsFalse( VSProject.IsSolutionFile( TestPath( @"/x/y/project.sol" ) ) ); } [Test] public void ProjectExtensions() { Assert.IsTrue( VSProject.IsProjectFile( TestPath( @"/x/y/project.csproj" ) ) ); Assert.IsTrue( VSProject.IsProjectFile( TestPath( @"/x/y/project.vbproj" ) ) ); Assert.IsTrue( VSProject.IsProjectFile( TestPath( @"/x/y/project.vcproj" ) ) ); Assert.IsFalse( VSProject.IsProjectFile( TestPath( @"/x/y/project.xyproj" ) ) ); } [Test] public void NotWebProject() { Assert.IsFalse(VSProject.IsProjectFile( @"http://localhost/web.csproj") ); Assert.IsFalse(VSProject.IsProjectFile( @"\MyProject\http://localhost/web.csproj") ); } private void AssertCanLoadProject( string resourceName ) { string fileName = Path.GetFileNameWithoutExtension( resourceName ); using (TestResource file = new TestResource(resourceName)) { VSProject project = new VSProject( file.Path ); Assert.AreEqual( fileName, project.Name ); Assert.AreEqual( Path.GetFullPath( file.Path ), project.ProjectPath ); Assert.AreEqual( fileName.ToLower(), Path.GetFileNameWithoutExtension( project.Configs[0].Assemblies[0].ToString().ToLower() ) ); } } [Test] public void LoadCsharpProject() { AssertCanLoadProject( "csharp-sample.csproj" ); } [Test] public void LoadCsharpProjectVS2005() { AssertCanLoadProject( "csharp-sample_VS2005.csproj" ); } [Test] public void LoadVbProject() { AssertCanLoadProject( "vb-sample.vbproj" ); } [Test] public void LoadVbProjectVS2005() { AssertCanLoadProject( "vb-sample_VS2005.vbproj" ); } [Test] public void LoadJsharpProject() { AssertCanLoadProject( "jsharp.vjsproj" ); } [Test] public void LoadJsharpProjectVS2005() { AssertCanLoadProject( "jsharp_VS2005.vjsproj" ); } [Test] public void LoadCppProject() { AssertCanLoadProject( "cpp-sample.vcproj" ); } [Test] public void LoadCppProjectVS2005() { AssertCanLoadProject( "cpp-sample_VS2005.vcproj" ); } [Test] public void LoadProjectWithHebrewFileIncluded() { AssertCanLoadProject( "HebrewFileProblem.csproj" ); } [Test] public void LoadProjectWithMissingOutputPath() { AssertCanLoadProject("MissingOutputPath.csproj"); } [Test] public void LoadCppProjectWithMacros() { using (TestResource file = new TestResource("CPPLibrary.vcproj")) { VSProject project = new VSProject(file.Path); Assert.AreEqual( "CPPLibrary", project.Name ); Assert.AreEqual( Path.GetFullPath(file.Path), project.ProjectPath); Assert.AreEqual( Path.Combine(Path.GetTempPath(), @"debug\cpplibrary.dll" ).ToLower(), project.Configs["Debug|Win32"].Assemblies[0].ToString().ToLower()); Assert.AreEqual( Path.Combine(Path.GetTempPath(), @"release\cpplibrary.dll" ).ToLower(), project.Configs["Release|Win32"].Assemblies[0].ToString().ToLower()); } } [Test] public void GenerateCorrectExtensionsFromVCProjectVS2005() { using (TestResource file = new TestResource("cpp-default-library_VS2005.vcproj")) { VSProject project = new VSProject(file.Path); Assert.AreEqual("cpp-default-library_VS2005", project.Name); Assert.AreEqual(Path.GetFullPath(file.Path), project.ProjectPath); Assert.AreEqual( Path.Combine(Path.GetTempPath(), TestPath( @"debug/cpp-default-library_VS2005.dll" ) ).ToLower(), project.Configs["Debug|Win32"].Assemblies[0].ToString().ToLower()); Assert.AreEqual( Path.Combine(Path.GetTempPath(), TestPath( @"release/cpp-default-library_VS2005.dll" ) ).ToLower(), project.Configs["Release|Win32"].Assemblies[0].ToString().ToLower()); } } [Test, ExpectedException( typeof ( ArgumentException ) ) ] public void LoadInvalidFileType() { new VSProject( @"/test.junk" ); } [Test, ExpectedException( typeof ( FileNotFoundException ) ) ] public void FileNotFoundError() { new VSProject( @"/junk.csproj" ); } [Test, ExpectedException( typeof( ArgumentException ) )] public void InvalidXmlFormat() { WriteInvalidFile( "" ); new VSProject( Path.Combine(Path.GetTempPath(), "invalid.csproj" )); } [Test, ExpectedException( typeof( ArgumentException ) )] public void InvalidProjectFormat() { WriteInvalidFile( "" ); new VSProject( Path.Combine(Path.GetTempPath(), "invalid.csproj" )); } [Test, ExpectedException( typeof( ArgumentException ) )] public void MissingAttributes() { WriteInvalidFile( "" ); new VSProject( Path.Combine(Path.GetTempPath(), "invalid.csproj" )); } [Test] public void NoConfigurations() { WriteInvalidFile( "" ); VSProject project = new VSProject( Path.Combine(Path.GetTempPath(),"invalid.csproj" )); Assert.AreEqual( 0, project.Configs.Count ); } /// /// Take a valid Linux filePath and make a valid windows filePath out of it /// if we are on Windows. Change slashes to backslashes and, if the /// filePath starts with a slash, add C: in front of it. /// private string TestPath(string path) { if (Path.DirectorySeparatorChar != '/') { path = path.Replace('/', Path.DirectorySeparatorChar); if (path[0] == Path.DirectorySeparatorChar) path = "C:" + path; } return path; } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/CategoryParseTests.cs0000664000175000017500000001345611504175260024356 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; using NUnit.Core.Filters; namespace NUnit.Util.Tests { [TestFixture] public class CategoryParseTests { [Test] public void EmptyStringReturnsEmptyFilter() { CategoryExpression expr = new CategoryExpression( "" ); Assert.That( expr.Filter.IsEmpty ); } [Test] public void CanParseSimpleCategory() { CategoryExpression expr = new CategoryExpression( "Data" ); CategoryFilter filter = (CategoryFilter)expr.Filter; Assert.That( filter.Categories, Is.EqualTo( new string[] { "Data" } ) ); } [Test] public void CanParseCompoundCategory() { CategoryExpression expr = new CategoryExpression( "One , Two; Three,Four" ); CategoryFilter filter = (CategoryFilter)expr.Filter; Assert.That( filter.Categories, Is.EqualTo( new string[] { "One", "Two", "Three", "Four" } ) ); } [Test] public void CanParseExcludedCategories() { CategoryExpression expr = new CategoryExpression( "-One,Two,Three" ); NotFilter notFilter = (NotFilter)expr.Filter; CategoryFilter catFilter = (CategoryFilter)notFilter.BaseFilter; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "One", "Two", "Three" } ) ); } [Test] public void CanParseMultipleCategoriesWithAnd() { CategoryExpression expr = new CategoryExpression( "One + Two+Three" ); AndFilter andFilter = (AndFilter)expr.Filter; Assert.That( andFilter.Filters.Length, Is.EqualTo( 3 ) ); CategoryFilter catFilter = (CategoryFilter)andFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "One" } ) ); catFilter = (CategoryFilter)andFilter.Filters[1]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "Two" } ) ); catFilter = (CategoryFilter)andFilter.Filters[2]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "Three" } ) ); } [Test] public void CanParseMultipleAlternatives() { CategoryExpression expr = new CategoryExpression( "One|Two|Three" ); OrFilter orFilter = (OrFilter)expr.Filter; Assert.That( orFilter.Filters.Length, Is.EqualTo( 3 ) ); CategoryFilter catFilter = (CategoryFilter)orFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "One" } ) ); catFilter = (CategoryFilter)orFilter.Filters[1]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "Two" } ) ); catFilter = (CategoryFilter)orFilter.Filters[2]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "Three" } ) ); } [Test] public void PrecedenceTest() { CategoryExpression expr = new CategoryExpression( "A + B | C + -D,E,F" ); OrFilter orFilter = (OrFilter)expr.Filter; AndFilter andFilter = (AndFilter)orFilter.Filters[0]; CategoryFilter catFilter = (CategoryFilter)andFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "A" } ) ); catFilter = (CategoryFilter)andFilter.Filters[1]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "B" } ) ); andFilter = (AndFilter)orFilter.Filters[1]; catFilter = (CategoryFilter)andFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "C" } ) ); NotFilter notFilter = (NotFilter)andFilter.Filters[1]; catFilter = (CategoryFilter)notFilter.BaseFilter; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "D", "E", "F" } ) ); } [Test] public void PrecedenceTestWithParentheses() { CategoryExpression expr = new CategoryExpression( "A + (B | C) - D,E,F" ); AndFilter andFilter = (AndFilter)expr.Filter; Assert.That( andFilter.Filters.Length, Is.EqualTo( 3 ) ); CategoryFilter catFilter = (CategoryFilter)andFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "A" } ) ); OrFilter orFilter = (OrFilter)andFilter.Filters[1]; catFilter = (CategoryFilter)orFilter.Filters[0]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "B" } ) ); catFilter = (CategoryFilter)orFilter.Filters[1]; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "C" } ) ); NotFilter notFilter = (NotFilter)andFilter.Filters[2]; catFilter = (CategoryFilter)notFilter.BaseFilter; Assert.That( catFilter.Categories, Is.EqualTo( new string[] { "D", "E", "F" } ) ); } [Test] public void OrAndMinusCombined() { CategoryExpression expr = new CategoryExpression( "A|B-C-D|E" ); OrFilter orFilter = (OrFilter)expr.Filter; Assert.That( orFilter.Filters.Length, Is.EqualTo( 3 ) ); AndFilter andFilter = (AndFilter)orFilter.Filters[1]; Assert.That( andFilter.Filters.Length, Is.EqualTo( 3 ) ); Assert.That( andFilter.Filters[0], Is.TypeOf( typeof( CategoryFilter) ) ); Assert.That( andFilter.Filters[1], Is.TypeOf( typeof( NotFilter) ) ); Assert.That( andFilter.Filters[2], Is.TypeOf( typeof( NotFilter) ) ); } [Test] public void PlusAndMinusCombined() { CategoryExpression expr = new CategoryExpression( "A+B-C-D+E" ); AndFilter andFilter = (AndFilter)expr.Filter; Assert.That( andFilter.Filters.Length, Is.EqualTo( 5 ) ); Assert.That( andFilter.Filters[0], Is.TypeOf( typeof( CategoryFilter) ) ); Assert.That( andFilter.Filters[1], Is.TypeOf( typeof( CategoryFilter) ) ); Assert.That( andFilter.Filters[2], Is.TypeOf( typeof( NotFilter) ) ); Assert.That( andFilter.Filters[3], Is.TypeOf( typeof( NotFilter) ) ); Assert.That( andFilter.Filters[4], Is.TypeOf( typeof( CategoryFilter) ) ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/NUnitProjectXml.cs0000664000175000017500000000414511504175260023623 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; namespace NUnit.Util.Tests { /// /// Summary description for NUnitProjectXml. /// public class NUnitProjectXml { public static readonly string EmptyProject = ""; public static readonly string EmptyConfigs = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; public static readonly string NormalProject = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; public static readonly string ManualBinPathProject = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; } } NUnit-2.6.0.12051/src/ClientUtilities/tests/NUnitRegistryTests.cs0000664000175000017500000000367711504175260024400 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Text; //using System.Windows.Forms; using Microsoft.Win32; using NUnit.Framework; namespace NUnit.Util.Tests { /// /// Summary description for NUnitRegistryTests. /// [TestFixture] public class NUnitRegistryTests { [TearDown] public void RestoreRegistry() { NUnitRegistry.TestMode = false; } [Test] public void CurrentUser() { NUnitRegistry.TestMode = false; using( RegistryKey key = NUnitRegistry.CurrentUser ) { Assert.IsNotNull( key ); Assert.AreEqual( @"HKEY_CURRENT_USER\Software\nunit.org\Nunit\2.4".ToLower(), key.Name.ToLower() ); } } [Test] public void CurrentUserTestMode() { NUnitRegistry.TestMode = true; using( RegistryKey key = NUnitRegistry.CurrentUser ) { Assert.IsNotNull( key ); Assert.AreEqual( @"HKEY_CURRENT_USER\Software\nunit.org\Nunit-Test".ToLower(), key.Name.ToLower() ); } } [Test] public void TestClearRoutines() { NUnitRegistry.TestMode = true; using( RegistryKey key = NUnitRegistry.CurrentUser ) using( RegistryKey foo = key.CreateSubKey( "foo" ) ) using( RegistryKey bar = key.CreateSubKey( "bar" ) ) using( RegistryKey footoo = foo.CreateSubKey( "foo" ) ) { key.SetValue("X", 5); key.SetValue("NAME", "Joe"); foo.SetValue("Y", 17); bar.SetValue("NAME", "Jennifer"); footoo.SetValue( "X", 5 ); footoo.SetValue("NAME", "Charlie" ); NUnitRegistry.ClearTestKeys(); Assert.AreEqual( 0, key.ValueCount ); Assert.AreEqual( 0, key.SubKeyCount ); } } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/MemorySettingsStorageTests.cs0000664000175000017500000000521411504175260026115 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class MemorySettingsStorageTests { MemorySettingsStorage storage; [SetUp] public void Init() { storage = new MemorySettingsStorage(); } [TearDown] public void Cleanup() { storage.Dispose(); } [Test] public void MakeStorage() { Assert.IsNotNull( storage ); } [Test] public void SaveAndLoadSettings() { Assert.IsNull( storage.GetSetting( "X" ), "X is not null" ); Assert.IsNull( storage.GetSetting( "NAME" ), "NAME is not null" ); storage.SaveSetting("X", 5); storage.SaveSetting("NAME", "Charlie"); Assert.AreEqual( 5, storage.GetSetting("X") ); Assert.AreEqual( "Charlie", storage.GetSetting("NAME") ); } [Test] public void RemoveSettings() { storage.SaveSetting("X", 5); storage.SaveSetting("NAME", "Charlie"); storage.RemoveSetting( "X" ); Assert.IsNull( storage.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", storage.GetSetting( "NAME" ) ); storage.RemoveSetting( "NAME" ); Assert.IsNull( storage.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void MakeSubStorages() { ISettingsStorage sub1 = storage.MakeChildStorage( "Sub1" ); ISettingsStorage sub2 = storage.MakeChildStorage( "Sub2" ); Assert.IsNotNull( sub1, "Sub1 is null" ); Assert.IsNotNull( sub2, "Sub2 is null" ); } [Test] public void SubstorageSettings() { ISettingsStorage sub = storage.MakeChildStorage( "Sub" ); sub.SaveSetting( "X", 5 ); sub.SaveSetting( "NAME", "Charlie" ); Assert.AreEqual( 5, sub.GetSetting( "X" ) ); Assert.AreEqual( "Charlie", sub.GetSetting( "NAME" ) ); sub.RemoveSetting( "X" ); Assert.IsNull( sub.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", sub.GetSetting( "NAME" ) ); sub.RemoveSetting( "NAME" ); Assert.IsNull( sub.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void TypeSafeSettings() { storage.SaveSetting( "X", 5); storage.SaveSetting( "Y", "17" ); storage.SaveSetting( "NAME", "Charlie"); Assert.AreEqual( 5, storage.GetSetting("X") ); Assert.AreEqual( "17", storage.GetSetting( "Y" ) ); Assert.AreEqual( "Charlie", storage.GetSetting( "NAME" ) ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/SettingsGroupTests.cs0000664000175000017500000000565611504175260024426 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using Microsoft.Win32; namespace NUnit.Util.Tests { [TestFixture] public class SettingsGroupTests { private SettingsGroup testGroup; [SetUp] public void BeforeEachTest() { MemorySettingsStorage storage = new MemorySettingsStorage(); testGroup = new SettingsGroup( storage ); } [TearDown] public void AfterEachTest() { testGroup.Dispose(); } [Test] public void TopLevelSettings() { testGroup.SaveSetting( "X", 5 ); testGroup.SaveSetting( "NAME", "Charlie" ); Assert.AreEqual( 5, testGroup.GetSetting( "X" ) ); Assert.AreEqual( "Charlie", testGroup.GetSetting( "NAME" ) ); testGroup.RemoveSetting( "X" ); Assert.IsNull( testGroup.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", testGroup.GetSetting( "NAME" ) ); testGroup.RemoveSetting( "NAME" ); Assert.IsNull( testGroup.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void SubGroupSettings() { SettingsGroup subGroup = new SettingsGroup( testGroup.Storage ); Assert.IsNotNull( subGroup ); Assert.IsNotNull( subGroup.Storage ); subGroup.SaveSetting( "X", 5 ); subGroup.SaveSetting( "NAME", "Charlie" ); Assert.AreEqual( 5, subGroup.GetSetting( "X" ) ); Assert.AreEqual( "Charlie", subGroup.GetSetting( "NAME" ) ); subGroup.RemoveSetting( "X" ); Assert.IsNull( subGroup.GetSetting( "X" ), "X not removed" ); Assert.AreEqual( "Charlie", subGroup.GetSetting( "NAME" ) ); subGroup.RemoveSetting( "NAME" ); Assert.IsNull( subGroup.GetSetting( "NAME" ), "NAME not removed" ); } [Test] public void TypeSafeSettings() { testGroup.SaveSetting( "X", 5); testGroup.SaveSetting( "Y", "17" ); testGroup.SaveSetting( "NAME", "Charlie"); Assert.AreEqual( 5, testGroup.GetSetting("X") ); Assert.AreEqual( "17", testGroup.GetSetting( "Y" ) ); Assert.AreEqual( "Charlie", testGroup.GetSetting( "NAME" ) ); } [Test] public void DefaultSettings() { Assert.IsNull( testGroup.GetSetting( "X" ) ); Assert.IsNull( testGroup.GetSetting( "NAME" ) ); Assert.AreEqual( 5, testGroup.GetSetting( "X", 5 ) ); Assert.AreEqual( 6, testGroup.GetSetting( "X", 6 ) ); Assert.AreEqual( "7", testGroup.GetSetting( "X", "7" ) ); Assert.AreEqual( "Charlie", testGroup.GetSetting( "NAME", "Charlie" ) ); Assert.AreEqual( "Fred", testGroup.GetSetting( "NAME", "Fred" ) ); } [Test] public void BadSetting() { testGroup.SaveSetting( "X", "1y25" ); Assert.AreEqual( 12, testGroup.GetSetting( "X", 12 ) ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/nunit.util.tests.csproj0000664000175000017500000002167111705311206024721 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {74EF7165-117E-48ED-98EA-068EAE438E53} Debug AnyCPU nunit.util.tests JScript Grid IE50 false Library NUnit.Util.Tests OnBuildSuccess 2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;NET_2_0;CLR_2_0;CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;NET_2_0;CLR_2_0;CS_3_0 4096 true false false 4 none prompt System System.Data System.Drawing System.Runtime.Remoting System.XML nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False nunit.core.tests {DD758D21-E5D5-4D40-9450-5F65A32F359C} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} mock-assembly {2E368281-3BA8-4050-B05E-0E0E43F8F446} False nonamespace-assembly {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} False test-utilities {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/ClientUtilities/tests/CategoryManagerTest.cs0000664000175000017500000000412411504175260024463 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; using NUnit.TestUtilities; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { [TestFixture] public class CategoryManagerTest { private CategoryManager categoryManager; string mockDll = MockAssembly.AssemblyPath; [SetUp] public void CreateCategoryManager() { categoryManager = new CategoryManager(); } [Test] public void CanAddStringsWithoutDuplicating() { categoryManager.Clear(); string name1 = "Name1"; string name2 = "Name2"; string duplicate1 = "Name1"; categoryManager.Add(name1); categoryManager.Add(name2); categoryManager.Add(duplicate1); Assert.AreEqual(2, categoryManager.Categories.Count); } [Test] public void CanAddStrings() { categoryManager.Add( "one" ); categoryManager.Add( "two" ); Assert.AreEqual( 2, categoryManager.Categories.Count ); } [Test] public void CanClearEntries() { categoryManager.Add( "one" ); categoryManager.Add( "two" ); categoryManager.Clear(); Assert.AreEqual( 0, categoryManager.Categories.Count ); } [Test] public void CanAddTestCategories() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( mockDll ) ); Test test = TestFinder.Find( "MockTest3", suite, true ); categoryManager.AddCategories( test ); Assert.AreEqual( 2, categoryManager.Categories.Count ); } [Test] public void CanAddAllAvailableCategoriesInTestTree() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( mockDll ) ); categoryManager.AddAllCategories( suite ); Assert.AreEqual( MockAssembly.Categories, categoryManager.Categories.Count ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/XmlResultWriterTest.cs0000664000175000017500000002143211504175260024550 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Xml; using System.Globalization; namespace NUnit.Util.Tests { [TestFixture] public class XmlResultWriterTest { private XmlDocument resultDoc; [TestFixtureSetUp] public void RunMockTests() { string testsDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; TestSuiteBuilder suiteBuilder = new TestSuiteBuilder(); Test suite = suiteBuilder.Build( new TestPackage( testsDll ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); StringBuilder builder = new StringBuilder(); new XmlResultWriter(new StringWriter(builder)).SaveTestResult(result); string resultXml = builder.ToString(); resultDoc = new XmlDocument(); resultDoc.LoadXml(resultXml); } [Test, Explicit] public void DemonstrateIllegalSequenceInMessage() { Assert.Fail("Deliberate failure to illustrate ]]> in message "); } [Test, Explicit] public void DemonstrateIllegalSequenceAtEndOfMessage() { Assert.Fail("The CDATA was: ]]>"); } [Test] public void SuiteResultHasCategories() { XmlNodeList categories = resultDoc.SelectNodes("//test-suite[@name=\"MockTestFixture\"]/categories/category"); Assert.IsNotNull(categories); Assert.AreEqual(1, categories.Count); Assert.AreEqual("FixtureCategory", categories[0].Attributes["name"].Value); } [Test] public void HasSingleCategory() { XmlNodeList categories = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest2\"]/categories/category"); Assert.IsNotNull(categories); Assert.AreEqual(1, categories.Count); Assert.AreEqual("MockCategory", categories[0].Attributes["name"].Value); } [Test] public void HasSingleProperty() { XmlNodeList properties = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest2\"]/properties/property[@name=\"Severity\"]"); Assert.IsNotNull(properties); Assert.AreEqual(1, properties.Count); Assert.AreEqual("Critical",properties[0].Attributes["value"].Value); } [Test] public void HasMultipleCategories() { XmlNodeList categories = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest3\"]/categories/category[@name=\"MockCategory\"]"); Assert.IsNotNull(categories, "MockCategory not found"); categories = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest3\"]/categories/category[@name=\"AnotherCategory\"]"); Assert.IsNotNull(categories, "AnotherCategory not found"); } [Test] public void HasMultipleProperties() { XmlNodeList properties = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.TestWithManyProperties\"]/properties/property[@name=\"TargetMethod\"]"); Assert.AreEqual("SomeClassName", properties[0].Attributes["value"].Value); //properties = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.TestWithManyProperties\"]/properties/property[@name=\"TargetType\"]"); //Assert.AreEqual("System.Threading.Thread", properties[0].Attributes["value"].Value); properties = resultDoc.SelectNodes("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.TestWithManyProperties\"]/properties/property[@name=\"Size\"]"); Assert.AreEqual("5", properties[0].Attributes["value"].Value); } [Test] public void TestHasEnvironmentInfo() { XmlNode sysinfo = resultDoc.SelectSingleNode("//environment"); Assert.IsNotNull(sysinfo); // In theory, we could do some validity checking on the values // of the attributes, but that seems redundant. Assert.IsNotNull(sysinfo.Attributes["nunit-version"]); Assert.IsNotNull(sysinfo.Attributes["clr-version"]); Assert.IsNotNull(sysinfo.Attributes["os-version"]); Assert.IsNotNull(sysinfo.Attributes["platform"]); Assert.IsNotNull(sysinfo.Attributes["cwd"]); Assert.IsNotNull(sysinfo.Attributes["machine-name"]); Assert.IsNotNull(sysinfo.Attributes["user"]); Assert.IsNotNull(sysinfo.Attributes["user-domain"]); } [Test] public void TestHasCultureInfo() { XmlNode cultureInfo = resultDoc.SelectSingleNode("//culture-info"); Assert.IsNotNull(cultureInfo); Assert.IsNotNull(cultureInfo.Attributes["current-culture"]); Assert.IsNotNull(cultureInfo.Attributes["current-uiculture"]); String currentCulture = cultureInfo.Attributes["current-culture"].Value; String currentUiCulture = cultureInfo.Attributes["current-uiculture"].Value; String currentCultureOnMachine = CultureInfo.CurrentCulture.ToString(); String currentUiCultureOnMachine = CultureInfo.CurrentUICulture.ToString(); Assert.AreEqual(currentCultureOnMachine, currentCulture, "Current Culture node did not contain the same culture name as the machine"); Assert.AreEqual(currentUiCultureOnMachine, currentUiCulture, "Current UI Culture node did not contain the same Culture UI name as the machine"); } [Test] public void FailingTestHasCorrectInformation() { XmlNode testNode = resultDoc.SelectSingleNode("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.FailingTest\"]"); Assert.AreEqual("Failure", testNode.Attributes["result"].Value); Assert.AreEqual("True", testNode.Attributes["executed"].Value); Assert.AreEqual("False", testNode.Attributes["success"].Value); XmlNode failureNode = testNode.SelectSingleNode("failure"); Assert.NotNull(failureNode, "No element"); XmlNode msgNode = failureNode.SelectSingleNode("message"); Assert.NotNull(msgNode, "No element"); Assert.AreEqual("Intentional failure", msgNode.InnerText); XmlNode stackNode = failureNode.SelectSingleNode("stack-trace"); Assert.NotNull(stackNode, "No element"); } [Test] public void IgnoredTestHasCorrectInformation() { XmlNode testNode = resultDoc.SelectSingleNode("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest4\"]"); Assert.AreEqual("Ignored", testNode.Attributes["result"].Value); Assert.AreEqual("False", testNode.Attributes["executed"].Value); XmlNode reasonNode = testNode.SelectSingleNode("reason"); Assert.NotNull(reasonNode, "No element"); XmlNode msgNode = reasonNode.SelectSingleNode("message"); Assert.NotNull(msgNode, "No element"); Assert.AreEqual("ignoring this test method for now", msgNode.InnerText); } [Test] public void PassingTestHasCorrectInformation() { XmlNode testNode = resultDoc.SelectSingleNode("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.MockTest3\"]"); Assert.AreEqual("Success", testNode.Attributes["result"].Value); Assert.AreEqual("True", testNode.Attributes["executed"].Value); Assert.AreEqual("True", testNode.Attributes["success"].Value); XmlNode reasonNode = testNode.SelectSingleNode("reason"); Assert.NotNull(reasonNode, "No element"); XmlNode msgNode = reasonNode.SelectSingleNode("message"); Assert.NotNull(msgNode, "No element"); Assert.AreEqual("Succeeded!", msgNode.InnerText); } [Test] public void InconclusiveTestHasCorrectInformation() { XmlNode testNode = resultDoc.SelectSingleNode("//test-case[@name=\"NUnit.Tests.Assemblies.MockTestFixture.InconclusiveTest\"]"); Assert.AreEqual("Inconclusive", testNode.Attributes["result"].Value); Assert.AreEqual("True", testNode.Attributes["executed"].Value); Assert.AreEqual("False", testNode.Attributes["success"].Value); XmlNode reasonNode = testNode.SelectSingleNode("reason"); Assert.NotNull(reasonNode, "No element"); XmlNode msgNode = reasonNode.SelectSingleNode("message"); Assert.NotNull(msgNode, "No element"); Assert.AreEqual("No valid data", msgNode.InnerText); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/ProcessRunnerTests.cs0000664000175000017500000000333511504175260024411 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.Diagnostics; using System.IO; using NUnit.Core; using NUnit.Core.Tests; using NUnit.Framework; using NUnit.Tests.Assemblies; namespace NUnit.Util.Tests { /// /// Summary description for ProcessRunnerTests. /// [TestFixture, Timeout(30000)] [Platform(Exclude = "Mono", Reason = "Process Start not working correctly")] public class ProcessRunnerTests : BasicRunnerTests { private ProcessRunner myRunner; protected override TestRunner CreateRunner(int runnerID) { myRunner = new ProcessRunner(runnerID); return myRunner; } protected override void DestroyRunner() { if (myRunner != null) { myRunner.Unload(); myRunner.Dispose(); } } [Test] public void TestProcessIsReused() { TestPackage package = new TestPackage(MockAssembly.AssemblyPath); myRunner.Load(package); int processId = ((TestAssemblyInfo)myRunner.AssemblyInfo[0]).ProcessId; Assert.AreNotEqual(Process.GetCurrentProcess().Id, processId, "Not in separate process"); myRunner.Unload(); myRunner.Load(package); Assert.AreEqual(processId, ((TestAssemblyInfo)myRunner.AssemblyInfo[0]).ProcessId, "Reloaded in different process"); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/EventDispatcherTests.cs0000664000175000017500000001414611504175260024673 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class EventDispatcherTests { private TestEventDispatcher dispatcher; private TestEventCatcher catcher; private TestInfo test; private TestResult result; private Exception exception; private readonly string FILENAME = "MyTestFileName"; private readonly string TESTNAME = "MyTestName"; private readonly string MESSAGE = "My message!"; [SetUp] public void SetUp() { dispatcher = new TestEventDispatcher(); catcher = new TestEventCatcher( dispatcher ); test = new TestInfo( new TestSuite( TESTNAME ) ); result = new TestResult( test ); exception = new Exception( MESSAGE ); } [Test] public void ProjectLoading() { dispatcher.FireProjectLoading( FILENAME ); CheckEvent( TestAction.ProjectLoading, FILENAME ); } [Test] public void ProjectLoaded() { dispatcher.FireProjectLoaded( FILENAME ); CheckEvent( TestAction.ProjectLoaded, FILENAME ); } [Test] public void ProjectLoadFailed() { dispatcher.FireProjectLoadFailed( FILENAME, exception ); CheckEvent( TestAction.ProjectLoadFailed, FILENAME, exception ); } [Test] public void ProjectUnloading() { dispatcher.FireProjectUnloading( FILENAME ); CheckEvent( TestAction.ProjectUnloading, FILENAME ); } [Test] public void ProjectUnloaded() { dispatcher.FireProjectUnloaded( FILENAME ); CheckEvent( TestAction.ProjectUnloaded, FILENAME ); } [Test] public void ProjectUnloadFailed() { dispatcher.FireProjectUnloadFailed( FILENAME, exception ); CheckEvent( TestAction.ProjectUnloadFailed, FILENAME, exception ); } [Test] public void TestLoading() { dispatcher.FireTestLoading( FILENAME ); CheckEvent( TestAction.TestLoading, FILENAME ); } [Test] public void TestLoaded() { dispatcher.FireTestLoaded( FILENAME, test ); CheckEvent( TestAction.TestLoaded, FILENAME, test ); } [Test] public void TestLoadFailed() { dispatcher.FireTestLoadFailed( FILENAME, exception ); CheckEvent( TestAction.TestLoadFailed, FILENAME, exception ); } [Test] public void TestUnloading() { dispatcher.FireTestUnloading( FILENAME ); CheckEvent( TestAction.TestUnloading, FILENAME ); } [Test] public void TestUnloaded() { dispatcher.FireTestUnloaded( FILENAME ); CheckEvent( TestAction.TestUnloaded, FILENAME ); } [Test] public void TestUnloadFailed() { dispatcher.FireTestUnloadFailed( FILENAME, exception ); CheckEvent( TestAction.TestUnloadFailed, FILENAME, exception ); } [Test] public void TestReloading() { dispatcher.FireTestReloading( FILENAME ); CheckEvent( TestAction.TestReloading, FILENAME ); } [Test] public void TestReloaded() { dispatcher.FireTestReloaded( FILENAME, test ); CheckEvent( TestAction.TestReloaded, FILENAME, test ); } [Test] public void TestReloadFailed() { dispatcher.FireTestReloadFailed( FILENAME, exception ); CheckEvent( TestAction.TestReloadFailed, FILENAME, exception ); } [Test] public void RunStarting() { dispatcher.FireRunStarting( test.TestName.FullName, test.TestCount ); CheckEvent( TestAction.RunStarting, test.TestName.FullName, test.TestCount ); } [Test] public void RunFinished() { dispatcher.FireRunFinished( result ); CheckEvent( TestAction.RunFinished, result ); } [Test] public void RunFailed() { dispatcher.FireRunFinished( exception ); CheckEvent( TestAction.RunFinished, exception ); } [Test] public void SuiteStarting() { dispatcher.FireSuiteStarting( test.TestName ); CheckEvent( TestAction.SuiteStarting, test.TestName ); } [Test] public void SuiteFinished() { dispatcher.FireSuiteFinished( result ); CheckEvent( TestAction.SuiteFinished, result ); } [Test] public void TestStarting() { dispatcher.FireTestStarting( test.TestName ); CheckEvent( TestAction.TestStarting, test.TestName ); } [Test] public void TestFinished() { dispatcher.FireTestFinished( result ); CheckEvent( TestAction.TestFinished, result ); } private void CheckEvent( TestAction action ) { Assert.AreEqual( 1, catcher.Events.Count ); Assert.AreEqual( action, ((TestEventArgs)catcher.Events[0]).Action ); } private void CheckEvent( TestAction action, string fileName ) { CheckEvent( action ); Assert.AreEqual( fileName, ((TestEventArgs)catcher.Events[0]).Name ); } private void CheckEvent( TestAction action, string fileName, int testCount ) { CheckEvent( action, fileName ); Assert.AreEqual( testCount, ((TestEventArgs)catcher.Events[0]).TestCount ); } private void CheckEvent( TestAction action, string fileName, TestInfo test ) { CheckEvent( action, fileName ); Assert.AreEqual( TESTNAME, ((TestEventArgs)catcher.Events[0]).Test.TestName.Name ); } private void CheckEvent( TestAction action, string fileName, Exception exception ) { CheckEvent( action, fileName ); Assert.AreEqual( MESSAGE, ((TestEventArgs)catcher.Events[0]).Exception.Message ); } private void CheckEvent( TestAction action, TestName testName ) { CheckEvent( action ); Assert.AreEqual( TESTNAME, ((TestEventArgs)catcher.Events[0]).TestName.Name ); } private void CheckEvent( TestAction action, TestResult result ) { CheckEvent( action ); Assert.AreEqual( TESTNAME, result.Name ); } private void CheckEvent( TestAction action, Exception exception ) { CheckEvent( TestAction.RunFinished ); Assert.AreEqual( MESSAGE, ((TestEventArgs)catcher.Events[0]).Exception.Message ); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/SummaryResultFixture.cs0000664000175000017500000000317711504175260024765 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.Tests.Assemblies; using NUnit.TestUtilities; namespace NUnit.Util.Tests { /// /// Summary description for TestResultTests. /// [TestFixture] public class SummaryResultFixture { private TestResult result; [SetUp] public void CreateResult() { Test testFixture = TestFixtureBuilder.BuildFrom( typeof( MockTestFixture ) ); result = testFixture.Run(NullListener.NULL, TestFilter.Empty); } [Test] public void SummaryMatchesResult() { ResultSummarizer summary = new ResultSummarizer( result ); Assert.AreEqual(result.Name, summary.Name); Assert.AreEqual(result.Time, summary.Time); Assert.AreEqual(result.IsSuccess, summary.Success, "Success"); Assert.AreEqual(MockTestFixture.ResultCount, summary.ResultCount ); Assert.AreEqual(MockTestFixture.TestsRun, summary.TestsRun, "TestsRun"); Assert.AreEqual(MockTestFixture.Failures, summary.Failures, "Failures"); Assert.AreEqual(MockTestFixture.Errors, summary.Errors, "Errors"); Assert.AreEqual(MockTestFixture.Ignored, summary.Ignored, "Ignored"); Assert.AreEqual(MockTestFixture.NotRunnable, summary.NotRunnable, "NotRunnable"); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/RecentFileEntryTests.cs0000664000175000017500000000507011504175260024641 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Text; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class RecentFileEntryTests { private RecentFileEntry entry; private static readonly string entryPath = "a/b/c"; private static readonly string entryPathWithComma = @"D:\test\test, and further research\program1\program1.exe"; private static Version entryVersion = new Version("1.2"); private static Version currentVersion = Environment.Version; [Test] public void CanCreateFromSimpleFileName() { entry = new RecentFileEntry( entryPath ); Assert.AreEqual( entryPath, entry.Path ); Assert.AreEqual( currentVersion, entry.CLRVersion ); } [Test] public void CanCreateFromFileNameAndVersion() { entry = new RecentFileEntry( entryPath, entryVersion ); Assert.AreEqual( entryPath, entry.Path ); Assert.AreEqual( entryVersion, entry.CLRVersion ); } [Test] public void EntryCanDisplayItself() { entry = new RecentFileEntry( entryPath, entryVersion ); Assert.AreEqual( entryPath + RecentFileEntry.Separator + entryVersion.ToString(), entry.ToString()); } [Test] public void CanParseSimpleFileName() { entry = RecentFileEntry.Parse(entryPath); Assert.AreEqual(entryPath, entry.Path); Assert.AreEqual(currentVersion, entry.CLRVersion); } [Test] public void CanParseSimpleFileNameWithComma() { entry = RecentFileEntry.Parse(entryPathWithComma); Assert.AreEqual(entryPathWithComma, entry.Path); Assert.AreEqual(currentVersion, entry.CLRVersion); } [Test] public void CanParseFileNamePlusVersionString() { string text = entryPath + RecentFileEntry.Separator + entryVersion.ToString(); entry = RecentFileEntry.Parse(text); Assert.AreEqual(entryPath, entry.Path); Assert.AreEqual(entryVersion, entry.CLRVersion); } [Test] public void CanParseFileNameWithCommaPlusVersionString() { string text = entryPathWithComma + RecentFileEntry.Separator + entryVersion.ToString(); entry = RecentFileEntry.Parse(text); Assert.AreEqual(entryPathWithComma, entry.Path); Assert.AreEqual(entryVersion, entry.CLRVersion); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/RemoteTestResultTest.cs0000664000175000017500000000414011702655226024710 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; namespace NUnit.Util.Tests { [TestFixture] public class RemoteTestResultTest { private static readonly string mockDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; private TestDomain domain; [SetUp] public void CreateRunner() { domain = new TestDomain(); } [TearDown] public void UnloadRunner() { if ( domain != null ) domain.Unload(); } [Test] public void ResultStillValidAfterDomainUnload() { //TODO: This no longer appears to test anything TestPackage package = new TestPackage( mockDll ); Assert.IsTrue( domain.Load( package ) ); TestResult result = domain.Run( new NullListener(), TestFilter.Empty, false, LoggingThreshold.Off ); TestResult caseResult = findCaseResult(result); Assert.IsNotNull(caseResult); //TestResultItem item = new TestResultItem(caseResult); //string message = item.GetMessage(); //Assert.IsNotNull(message); } [Test, Explicit("Fails intermittently")] public void AppDomainUnloadedBug() { TestDomain domain = new TestDomain(); domain.Load( new TestPackage( mockDll ) ); domain.Run(new NullListener(), TestFilter.Empty, false, LoggingThreshold.Off); domain.Unload(); } private TestResult findCaseResult(TestResult suite) { foreach (TestResult r in suite.Results) { if (!r.Test.IsSuite) { return r; } else { TestResult result = findCaseResult(r); if (result != null) return result; } } return null; } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/TestRunnerFactoryTests.cs0000664000175000017500000000365611720431752025251 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class TestRunnerFactoryTests { private RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; private string testDll = "/test.dll"; private DefaultTestRunnerFactory factory; private TestPackage package; [SetUp] public void Init() { factory = new DefaultTestRunnerFactory(); package = new TestPackage(testDll); } [Test] public void SameFrameworkUsesTestDomain() { package.Settings["RuntimeFramework"] = currentFramework; Assert.That( factory.MakeTestRunner(package), Is.TypeOf(typeof(TestDomain))); } #if CLR_2_0 || CLR_4_0 [Test] public void DifferentRuntimeUsesProcessRunner() { RuntimeType runtime = currentFramework.Runtime == RuntimeType.Net ? RuntimeType.Mono : RuntimeType.Net; package.Settings["RuntimeFramework"] = new RuntimeFramework(runtime, currentFramework.ClrVersion); Assert.That(factory.MakeTestRunner(package), Is.TypeOf(typeof(ProcessRunner))); } [Test] public void DifferentVersionUsesProcessRunner() { int major = currentFramework.ClrVersion.Major == 2 ? 4 : 2; package.Settings["RuntimeFramework"] = new RuntimeFramework(currentFramework.Runtime, new Version(major,0)); Assert.That(factory.MakeTestRunner(package), Is.TypeOf(typeof(ProcessRunner))); } #endif } } NUnit-2.6.0.12051/src/ClientUtilities/tests/RuntimeFrameworkSelectorTests.cs0000664000175000017500000000505211720432006026573 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; using NUnit.Framework; namespace NUnit.Util.Tests { [TestFixture] public class RuntimeFrameworkSelectorTests { TestPackage package = new TestPackage("/dummy.dll"); [Datapoints] internal RuntimeFramework[] frameworks = new RuntimeFramework[] { RuntimeFramework.Parse("net-1.0"), RuntimeFramework.Parse("net-1.1"), RuntimeFramework.Parse("net-2.0"), RuntimeFramework.Parse("net-4.0"), RuntimeFramework.Parse("mono-1.0"), RuntimeFramework.Parse("mono-2.0"), RuntimeFramework.Parse("v1.1"), RuntimeFramework.Parse("v2.0"), RuntimeFramework.Parse("v4.0") // TODO: Figure out a way to run these //RuntimeFramework.Parse("net"), //RuntimeFramework.Parse("mono"), //RuntimeFramework.Parse("any") }; [Theory] public void RequestForSpecificFrameworkIsHonored(RuntimeFramework requestedFramework) { Assume.That(requestedFramework.Runtime, Is.Not.EqualTo(RuntimeType.Any)); RuntimeFrameworkSelector selector = new RuntimeFrameworkSelector(); package.Settings["RuntimeFramework"] = requestedFramework; RuntimeFramework selectedFramework = selector.SelectRuntimeFramework(package); Assert.That(selectedFramework.Runtime, Is.EqualTo(requestedFramework.Runtime)); Assert.That(selectedFramework.ClrVersion, Is.EqualTo(requestedFramework.ClrVersion)); } [Theory] public void RequestForSpecificVersionIsHonored(RuntimeFramework requestedFramework) { Assume.That(requestedFramework.Runtime, Is.EqualTo(RuntimeType.Any)); RuntimeFrameworkSelector selector = new RuntimeFrameworkSelector(); package.Settings["RuntimeFramework"] = requestedFramework; RuntimeFramework selectedFramework = selector.SelectRuntimeFramework(package); Assert.That(selectedFramework.Runtime, Is.EqualTo(RuntimeFramework.CurrentFramework.Runtime)); Assert.That(selectedFramework.ClrVersion, Is.EqualTo(requestedFramework.ClrVersion)); } } } NUnit-2.6.0.12051/src/ClientUtilities/tests/FileWatcherTests.cs0000664000175000017500000001001711544330406023770 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; using System.Text; using System.Timers; namespace NUnit.Util.Tests { [TestFixture] [Platform(Exclude = "Win95,Win98,WinMe")] public class FileWatcherTests { private FileWatcher watcher; private CounterEventHandler handler; private static int watcherDelayMs = 100; private string fileName; private string tempFileName; [SetUp] public void CreateFile() { string tempDir = Path.GetTempPath(); fileName = Path.Combine(tempDir, "temp.txt"); tempFileName = Path.Combine(tempDir, "newTempFile.txt"); StreamWriter writer = new StreamWriter(fileName); writer.Write("Hello"); writer.Close(); handler = new CounterEventHandler(); watcher = new FileWatcher(fileName, watcherDelayMs); watcher.Changed += new FileChangedHandler(handler.OnChanged); watcher.Start(); } [TearDown] public void DeleteFile() { watcher.Stop(); FileInfo fileInfo = new FileInfo(fileName); fileInfo.Delete(); FileInfo temp = new FileInfo(tempFileName); if (temp.Exists) temp.Delete(); } [Test] [Platform("Linux, Net", Reason="Fails under Mono on Windows")] public void MultipleCloselySpacedChangesTriggerWatcherOnlyOnce() { for (int i = 0; i < 3; i++) { StreamWriter writer = new StreamWriter(fileName, true); writer.WriteLine("Data"); writer.Close(); System.Threading.Thread.Sleep(20); } WaitForTimerExpiration(); Assert.AreEqual(1, handler.Counter); Assert.AreEqual(Path.GetFullPath(fileName), handler.FileName); } [Test] [Platform("Linux, Net", Reason="Fails under Mono on Windows")] public void ChangingFileTriggersWatcher() { StreamWriter writer = new StreamWriter(fileName); writer.Write("Goodbye"); writer.Close(); WaitForTimerExpiration(); Assert.AreEqual(1, handler.Counter); Assert.AreEqual(Path.GetFullPath(fileName), handler.FileName); } [Test] [Platform(Exclude = "Linux", Reason = "Attribute change triggers watcher")] public void ChangingAttributesDoesNotTriggerWatcher() { FileInfo fi = new FileInfo(fileName); FileAttributes attr = fi.Attributes; fi.Attributes = FileAttributes.Hidden | attr; WaitForTimerExpiration(); Assert.AreEqual(0, handler.Counter); } [Test] public void CopyingFileDoesNotTriggerWatcher() { FileInfo fi = new FileInfo(fileName); fi.CopyTo(tempFileName); fi.Delete(); WaitForTimerExpiration(); Assert.AreEqual(0, handler.Counter); } private static void WaitForTimerExpiration() { System.Threading.Thread.Sleep(watcherDelayMs * 2); } private class CounterEventHandler { int counter; String fileName; public int Counter { get { return counter; } } public String FileName { get { return fileName; } } public void OnChanged(String fullPath) { fileName = fullPath; counter++; } } } } NUnit-2.6.0.12051/src/nunit20under21.config0000664000175000017500000000166611504175260017647 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ProjectEditor/0000775000175000017500000000000011742560362016531 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/0000775000175000017500000000000011742560362017673 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/nunit-editor.tests.build0000664000175000017500000000471611703053666024507 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ProjectEditor/tests/Properties/0000775000175000017500000000000011742560362022027 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/Properties/AssemblyInfo.cs0000664000175000017500000000261611544330406024750 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("tests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("tests")] [assembly: AssemblyCopyright("Copyright © 2010")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("6500d115-76e1-4bdd-b765-b3765b783c15")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] NUnit-2.6.0.12051/src/ProjectEditor/tests/Views/0000775000175000017500000000000011742560362020770 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/Views/ConfigurationEditorViewTests.cs0000664000175000017500000000153211544330406027146 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Views { public class ConfigurationEditorViewTests { [Test] public void AllViewElementsAreWrapped() { ConfigurationEditorDialog view = new ConfigurationEditorDialog(); Assert.NotNull(view.AddCommand); Assert.NotNull(view.RemoveCommand); Assert.NotNull(view.RenameCommand); Assert.NotNull(view.ActiveCommand); Assert.NotNull(view.ConfigList); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Views/PropertyViewTests.cs0000664000175000017500000000172711544330406025022 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Views { public class PropertyViewTests { [Test] public void AllViewElementsAreInitialized() { PropertyView view = new PropertyView(); foreach (PropertyInfo prop in typeof(PropertyView).GetProperties()) { if (typeof(IViewElement).IsAssignableFrom(prop.PropertyType)) { if (prop.GetValue(view, new object[0]) == null) Assert.Fail("{0} was not initialized", prop.Name); } } } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Views/AddConfigurationDialogTests.cs0000664000175000017500000000541611544330406026702 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.ProjectEditor.Tests.Views { [TestFixture] public class AddConfigurationDialogTests : FormTester { private AddConfigurationDialog dlg; [SetUp] public void SetUp() { dlg = new AddConfigurationDialog(); dlg.ConfigList = new string[] { "Debug", "Release" }; this.Form = dlg; } [TearDown] public void TearDown() { dlg.Close(); } [Test] public void CheckForControls() { AssertControlExists("configurationNameTextBox", typeof(TextBox)); AssertControlExists("configurationComboBox", typeof(ComboBox)); AssertControlExists("okButton", typeof(Button)); AssertControlExists("cancelButton", typeof(Button)); } [Test] public void TextBox_OnLoad_IsEmpty() { TextBox configBox = TextBoxes["configurationNameTextBox"]; Assert.AreEqual("", configBox.Text); } [Test] public void ComboBox_OnLoad_IsInitializedCorrectly() { ComboBox combo = Combos["configurationComboBox"]; dlg.Show(); Assert.AreEqual(3, combo.Items.Count); Assert.AreEqual("", combo.Items[0]); Assert.AreEqual("Debug", combo.Items[1]); Assert.AreEqual("Release", combo.Items[2]); Assert.AreEqual("", combo.SelectedItem); } [Test] public void TestSimpleEntry() { dlg.Show(); TextBox config = TextBoxes["configurationNameTextBox"]; Button okButton = Buttons["okButton"]; config.Text = "Super"; okButton.PerformClick(); Assert.AreEqual("Super", dlg.ConfigToCreate); Assert.AreEqual(null, dlg.ConfigToCopy); } [Test] public void TestComplexEntry() { dlg.Show(); TextBox config = TextBoxes["configurationNameTextBox"]; Button okButton = Buttons["okButton"]; ComboBox combo = Combos["configurationComboBox"]; config.Text = "Super"; combo.SelectedIndex = combo.FindStringExact("Release"); okButton.PerformClick(); Assert.AreEqual("Super", dlg.ConfigToCreate); Assert.AreEqual("Release", dlg.ConfigToCopy); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/0000775000175000017500000000000011742560362022025 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/PropertyPresenterTests.cs0000664000175000017500000002250011544451536027114 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.IO; using System.Reflection; using NUnit.Framework; using NUnit.ProjectEditor.ViewElements; using NSubstitute; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class PropertyPresenterTests { IProjectDocument doc; private IProjectModel model; private IPropertyView view; private PropertyPresenter presenter; [SetUp] public void SetUp() { doc = new ProjectDocument(); doc.LoadXml(NUnitProjectXml.NormalProject); model = new ProjectModel(doc); model.ActiveConfigName = "Release"; view = Substitute.For(); view.ConfigList.Returns(new SelectionStub("ConfigList")); view.ProcessModel.Returns(new SelectionStub("ProcessModel")); view.DomainUsage.Returns(new SelectionStub("DomainUsage")); view.Runtime.Returns(new SelectionStub("Runtime")); view.RuntimeVersion.Returns(new SelectionStub("RuntimeVersion")); view.AssemblyList.Returns(new SelectionStub("AssemblyList")); presenter = new PropertyPresenter(model, view); presenter.LoadViewFromModel(); } [Test] public void ActiveConfigName_LoadFromModel_SetsViewCorrectly() { Assert.That(view.ActiveConfigName.Text, Is.EqualTo("Release")); } [Test] public void ApplicationBase_LoadFromModel_SetsViewCorrectly() { Assert.That(view.ApplicationBase.Text, Is.EqualTo(model.Configs[0].BasePath)); } [Test] public void AssemblyPath_LoadFromModel_SetsViewCorrectly() { Assert.That(view.AssemblyPath.Text, Is.EqualTo(model.Configs[0].Assemblies[0])); } [Test] public void AssemblyList_LoadFromModel_SetsListCorrectly() { Assert.That(view.AssemblyList.SelectionList, Is.EqualTo(new string[] {"assembly1.dll", "assembly2.dll"})); } [Test] public void AssemblyList_WhenEmpty_AddIsEnabled() { view.AssemblyList.SelectionList = new string[0]; view.AssemblyList.SelectedIndex = -1; Assert.True(view.AddAssemblyCommand.Enabled); } [Test] public void AssemblyList_WhenEmpty_RemoveIsDisabled() { view.AssemblyList.SelectionList = new string[0]; view.AssemblyList.SelectedIndex = -1; Assert.False(view.RemoveAssemblyCommand.Enabled); } [Test] public void AssemblyList_WhenEmpty_AssemblyPathBrowseIsDisabled() { view.AssemblyList.SelectionList = new string[0]; view.AssemblyList.SelectedIndex = -1; Assert.False(view.BrowseAssemblyPathCommand.Enabled); } [Test] public void BinPathType_LoadFromModel_SetsViewCorrectly() { Assert.That(view.BinPathType.SelectedIndex, Is.EqualTo((int)model.Configs[0].BinPathType)); } [Test] public void ConfigList_LoadFromModel_SelectsFirstConfig() { Assert.That(view.ConfigList.SelectedIndex, Is.EqualTo(0)); Assert.That(view.ConfigList.SelectedItem, Is.EqualTo("Debug")); } [Test] public void ConfigList_LoadFromModel_SetsListCorrectly() { Assert.That(view.ConfigList.SelectionList, Is.EqualTo( new string[] { "Debug", "Release" })); } public void ConfigList_SelectionChanged_UpdatesRuntime() { } [Test] public void ConfigurationFile_LoadFromModel_SetsViewCorrectly() { Assert.That(view.ConfigurationFile.Text, Is.EqualTo(model.Configs[0].ConfigurationFile)); } [Test] public void DomainUsage_LoadFromModel_SetsOptionsCorrectly() { Assert.That(view.DomainUsage.SelectionList, Is.EqualTo( new string[] { "Default", "Single", "Multiple" })); } [Test] public void DomainUsage_LoadFromModel_SelectsDefaultEntry() { Assert.That(view.DomainUsage.SelectedItem, Is.EqualTo("Default")); } [Test] public void DomainUsage_WhenChanged_UpdatesProject() { view.DomainUsage.SelectedItem = "Multiple"; Assert.That(model.DomainUsage, Is.EqualTo("Multiple")); } [Test] public void PrivateBinPath_LoadFromModel_SetsViewCorrectly() { Assert.That(view.PrivateBinPath.Text, Is.EqualTo(string.Empty)); } [Test] public void ProcessModel_LoadFromModel_SelectsDefaultEntry() { Assert.That(view.ProcessModel.SelectedItem, Is.EqualTo("Default")); } [Test] public void ProcessModel_LoadFromModel_SetsOptionsCorrectly() { Assert.That(view.ProcessModel.SelectionList, Is.EqualTo( new string[] { "Default", "Single", "Separate", "Multiple" })); } [Test] public void ProcessModel_WhenChanged_UpdatesDomainUsageOptions() { view.ProcessModel.SelectedItem = "Single"; Assert.That(view.DomainUsage.SelectionList, Is.EqualTo( new string[] { "Default", "Single", "Multiple" })); view.ProcessModel.SelectedItem = "Multiple"; Assert.That(view.DomainUsage.SelectionList, Is.EqualTo( new string[] { "Default", "Single" })); } [Test] public void ProcessModel_WhenChanged_UpdatesProject() { view.ProcessModel.SelectedItem = "Multiple"; Assert.That(model.ProcessModel, Is.EqualTo("Multiple")); } [Test] public void ProjectBase_LoadFromModel_SetsViewCorrectly() { Assert.That(view.ProjectBase.Text, Is.EqualTo(model.EffectiveBasePath)); } [Test] public void ProjectBase_WhenChanged_UpdatesProject() { view.ProjectBase.Text = "test.nunit"; view.ProjectBase.Validated += Raise.Event(); Assert.That(model.BasePath, Is.EqualTo("test.nunit")); } [Test] public void ProjectPath_LoadFromModel_SetsViewCorrectly() { Assert.That(view.ProjectPath.Text, Is.EqualTo(model.ProjectPath)); } [Test] public void Runtime_LoadFromModel_SetsOptionsCorrectly() { Assert.That(view.Runtime.SelectionList, Is.EqualTo( new string[] { "Any", "Net", "Mono" })); } [Test] public void Runtime_LoadFromModel_SelectsAnyRuntime() { Assert.That(view.Runtime.SelectedIndex, Is.EqualTo(0)); } [Test] public void Runtime_WhenChanged_UpdatesProject() { // Set to non-default values for this test IProjectConfig config = model.Configs[0]; config.RuntimeFramework = new RuntimeFramework(RuntimeType.Net, new Version("2.0.50727")); view.ConfigList.SelectedIndex = 0; view.Runtime.SelectedItem = "Mono"; Assert.That(config.RuntimeFramework.Runtime, Is.EqualTo(RuntimeType.Mono)); Assert.That(config.RuntimeFramework.Version, Is.EqualTo(new Version("2.0.50727"))); } [Test] public void RuntimeVersion_LoadFromModel_SetsOptionsCorretly() { Assert.That(view.RuntimeVersion.SelectionList, Is.EqualTo( new string[] { "1.0.3705", "1.1.4322", "2.0.50727", "4.0.21006" })); //Assert.That(xmlView.RuntimeVersion.SelectedItem, Is.EqualTo("2.0.50727")); } [Test] public void RuntimeVersion_WhenSelectionChanged_UpdatesProject() { // Set to non-default values for this test IProjectConfig config = model.Configs[0]; config.RuntimeFramework = new RuntimeFramework(RuntimeType.Net, new Version("2.0.50727")); view.RuntimeVersion.SelectedItem = "4.0.21006"; Assert.That(config.RuntimeFramework.Runtime, Is.EqualTo(RuntimeType.Net)); Assert.That(config.RuntimeFramework.Version, Is.EqualTo(new Version(4, 0, 21006))); } public void RuntimeVersion_WhenTextChanged_UpdatesProject() { // Set to non-default values for this test IProjectConfig config = model.Configs[0]; config.RuntimeFramework = new RuntimeFramework(RuntimeType.Net, new Version("2.0.50727")); view.RuntimeVersion.Text = "4.0"; Assert.That(config.RuntimeFramework.Runtime, Is.EqualTo(RuntimeType.Net)); Assert.That(config.RuntimeFramework.Version, Is.EqualTo(new Version(4, 0))); } } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/MainPresenterTests.cs0000664000175000017500000001607311544451536026164 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using NSubstitute; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class MainPresenterTests { // TODO: Embed project resources private static readonly string GOOD_PROJECT = "NUnitTests.nunit"; private static readonly string BAD_PROJECT = "BadProject.nunit"; private static readonly string NONEXISTENT_PROJECT = "NonExistent.nunit"; private IMainView view; private IProjectDocument doc; private MainPresenter presenter; [SetUp] public void Initialize() { view = Substitute.For(); doc = new ProjectDocument(); presenter = new MainPresenter(doc, view); } [Test] public void ActiveViewChanged_WhenNoProjectIsOpen_TabViewsRemainHidden() { view.SelectedView.Returns(SelectedView.XmlView); view.ActiveViewChanged += Raise.Event(); Assert.False(view.PropertyView.Visible); Assert.False(view.XmlView.Visible); view.SelectedView.Returns(SelectedView.PropertyView); view.ActiveViewChanged += Raise.Event(); Assert.False(view.PropertyView.Visible); Assert.False(view.XmlView.Visible); } [Test] public void ActiveViewChanged_WhenProjectIsOpen_TabViewsAreVisible() { doc.CreateNewProject(); view.SelectedView.Returns(SelectedView.XmlView); view.ActiveViewChanged += Raise.Event(); Assert.True(view.PropertyView.Visible); Assert.True(view.XmlView.Visible); } [Test] public void CloseProject_OnLoad_IsDisabled() { Assert.False(view.CloseProjectCommand.Enabled); } [Test] public void CloseProject_AfterCreatingNewProject_IsEnabled() { view.NewProjectCommand.Execute += Raise.Event(); Assert.True(view.CloseProjectCommand.Enabled); } [Test] public void CloseProject_AfterOpeningGoodProject_IsEnabled() { using (TempFile file = new TempFile(GOOD_PROJECT)) { view.DialogManager.GetFileOpenPath("", "", "").ReturnsForAnyArgs(file.Path); view.OpenProjectCommand.Execute += Raise.Event(); Assert.True(view.CloseProjectCommand.Enabled); } } [Test] public void NewProject_OnLoad_IsEnabled() { Assert.True(view.NewProjectCommand.Enabled); } [Test] public void NewProject_WhenClicked_CreatesNewProject() { view.NewProjectCommand.Execute += Raise.Event(); Assert.IsNotNull(doc.RootNode); Assert.That(doc.Name, Is.StringMatching("Project\\d")); } [Test] public void OpenProject_OnLoad_IsEnabled() { Assert.True(view.OpenProjectCommand.Enabled); } [Test] public void OpenProject_WhenClickedAndProjectIsValid_OpensProject() { using (TempFile file = new TempFile(GOOD_PROJECT)) { view.DialogManager.GetFileOpenPath("Open", "", "").ReturnsForAnyArgs(file.Path); view.OpenProjectCommand.Execute += Raise.Event(); Assert.NotNull(doc.XmlText); Assert.NotNull(doc.RootNode); Assert.AreEqual("NUnitTests", doc.Name); } } [Test] public void OpenProject_WhenClickedAndProjectXmlIsNotValid_OpensProject() { using (TempFile file = new TempFile(BAD_PROJECT)) { view.DialogManager.GetFileOpenPath("Open", "", "").ReturnsForAnyArgs(file.Path); view.OpenProjectCommand.Execute += Raise.Event(); Assert.NotNull(doc.XmlText); Assert.Null(doc.RootNode); Assert.AreEqual("BadProject", doc.Name); Assert.AreEqual(SelectedView.XmlView, view.SelectedView); } } [Test] public void OpenProject_WhenClickedAndProjectDoesNotExist_DisplaysError() { view.DialogManager.GetFileOpenPath("Open", "", "").ReturnsForAnyArgs(NONEXISTENT_PROJECT); view.OpenProjectCommand.Execute += Raise.Event(); view.MessageDisplay.Received().Error(Arg.Is((string x) => x.StartsWith("Could not find file"))); Assert.Null(doc.XmlText); Assert.Null(doc.RootNode); } [Test] public void SaveProject_OnLoad_IsDisabled() { Assert.False(view.SaveProjectCommand.Enabled); } [Test] public void SaveProject_AfterCreatingNewProject_IsEnabled() { view.NewProjectCommand.Execute += Raise.Event(); Assert.True(view.SaveProjectCommand.Enabled); } [Test] public void SaveProject_AfterOpeningGoodProject_IsEnabled() { using (TempFile file = new TempFile(GOOD_PROJECT)) { view.DialogManager.GetFileOpenPath("", "", "").ReturnsForAnyArgs(file.Path); view.OpenProjectCommand.Execute += Raise.Event(); Assert.True(view.SaveProjectCommand.Enabled); } } [Test] public void SaveProjectAs_OnLoad_IsDisabled() { Assert.False(view.SaveProjectAsCommand.Enabled); } [Test] public void SaveProjectAs_AfterCreatingNewProject_IsEnabled() { view.NewProjectCommand.Execute += Raise.Event(); Assert.True(view.SaveProjectAsCommand.Enabled); } [Test] public void SaveProjectAs_AfterOpeningGoodProject_IsEnabled() { using (TempFile file = new TempFile(GOOD_PROJECT)) { view.DialogManager.GetFileOpenPath("", "", "").ReturnsForAnyArgs(file.Path); view.OpenProjectCommand.Execute += Raise.Event(); Assert.True(view.SaveProjectAsCommand.Enabled); } } private class TempFile : TempResourceFile { public TempFile(string name) : base(typeof(NUnitProjectXml), "resources." + name, name) { } } } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/ConfigurationEditorTests.cs0000664000175000017500000001145511544451536027365 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.Windows.Forms; using NUnit.Framework; using NUnit.ProjectEditor.ViewElements; using NSubstitute; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class ConfigurationEditorTests { private IConfigurationEditorDialog view; private ProjectModel model; private ConfigurationEditor editor; [SetUp] public void Initialize() { ProjectDocument doc = new ProjectDocument(); doc.LoadXml(NUnitProjectXml.NormalProject); model = new ProjectModel(doc); view = Substitute.For(); editor = new ConfigurationEditor(model, view); } [Test] public void AddButton_OnLoad_IsSubscribed() { view.AddCommand.Received().Execute += editor.AddConfig; } [Test] public void RemoveButton_OnLoad_IsSubscribed() { view.RemoveCommand.Received().Execute += editor.RemoveConfig; } [Test] public void RenameButton_OnLoad_IsSubscribed() { view.RenameCommand.Received().Execute += editor.RenameConfig; } [Test] public void ActiveButton_OnLoad_IsSubscribed() { view.ActiveCommand.Received().Execute += editor.MakeActive; } [Test] public void ConfigList_OnLoad_SelectionChangedIsSubscribed() { view.ConfigList.Received().SelectionChanged += editor.SelectedConfigChanged; } [Test] public void ConfigList_OnLoad_IsCorrectlyInitialized() { Assert.That(view.ConfigList.SelectionList, Is.EqualTo( new string[] { "Debug (active)", "Release" })); } [Test] public void AddButton_OnLoad_IsEnabled() { Assert.True(view.AddCommand.Enabled); } [Test] public void RemoveButton_OnLoad_IsEnabled() { Assert.True(view.RemoveCommand.Enabled); } [Test] public void RenameButton_OnLoad_IsEnabled() { Assert.True(view.RenameCommand.Enabled); } [Test] public void ActiveButton_OnLoad_IsDisabled() { Assert.False(view.ActiveCommand.Enabled); } [Test] public void AddButton_WhenClicked_AddsNewConfig() { view.AddConfigurationDialog.ShowDialog().Returns(delegate { view.AddConfigurationDialog.OkButton.Execute += Raise.Event(); return DialogResult.OK; }); view.AddConfigurationDialog.ConfigToCreate.Returns("New"); view.AddConfigurationDialog.ConfigToCopy.Returns("Release"); view.AddCommand.Execute += Raise.Event(); Assert.That(model.Configs.Count, Is.EqualTo(3)); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "Debug", "Release", "New" })); } [Test] public void RemoveButton_WhenClicked_RemovesConfig() { view.RemoveCommand.Execute += Raise.Event(); Assert.That(model.Configs.Count, Is.EqualTo(1)); Assert.That(model.Configs[0].Name, Is.EqualTo("Release")); } private void RaiseExecute(ICommand command) { command.Execute += Raise.Event(); } [Test] public void RenameButton_WhenClicked_PerformsRename() { view.ConfigList.SelectedItem.Returns("Debug"); view.RenameConfigurationDialog.ShowDialog().Returns(delegate { view.RenameConfigurationDialog.ConfigurationName.Text = "NewName"; view.RenameConfigurationDialog.OkButton.Execute += Raise.Event(); return DialogResult.OK; }); view.RenameCommand.Execute += Raise.Event(); Assert.That(model.Configs[0].Name, Is.EqualTo("NewName")); } [Test] public void ActiveButton_WhenClicked_MakesConfigActive() { view.ConfigList.SelectedItem = "Release"; RaiseExecute(view.ActiveCommand); Assert.That(model.ActiveConfigName, Is.EqualTo("Release")); } } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/RenameConfigurationPresenterTests.cs0000664000175000017500000000600611544451536031232 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.Collections.Generic; using NSubstitute; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class RenameConfigurationPresenterTests { IProjectModel model; IRenameConfigurationDialog dlg; RenameConfigurationPresenter presenter; [SetUp] public void Initialize() { IProjectDocument doc = new ProjectDocument(); doc.LoadXml(NUnitProjectXml.EmptyConfigs); model = new ProjectModel(doc); dlg = Substitute.For(); presenter = new RenameConfigurationPresenter(model, dlg, "Debug"); } [Test] public void ConfigurationName_OnLoad_IsSetToOriginalName() { Assert.AreEqual("Debug", dlg.ConfigurationName.Text); } [Test] public void ConfigurationName_OnLoad_OriginalNameIsSelected() { dlg.ConfigurationName.Received().Select(0,5); } [Test] public void OkButton_OnLoad_IsDisabled() { Assert.False(dlg.OkButton.Enabled); } [Test] public void ConfigurationName_WhenSetToNewName_OkButtonIsEnabled() { dlg.ConfigurationName.Text = "New"; dlg.ConfigurationName.Changed += Raise.Event(); Assert.True(dlg.OkButton.Enabled); } [Test] public void ConfigurationName_WhenSetToOriginalName_OkButtonIsDisabled() { dlg.ConfigurationName.Text = "Debug"; dlg.ConfigurationName.Changed += Raise.Event(); Assert.False(dlg.OkButton.Enabled); } [Test] public void ConfigurationName_WhenCleared_OkButtonIsDisabled() { dlg.ConfigurationName.Text = string.Empty; dlg.ConfigurationName.Changed += Raise.Event(); Assert.False(dlg.OkButton.Enabled); } [Test] public void OkButton_WhenClicked_PerformsRename() { dlg.ConfigurationName.Text = "New"; dlg.OkButton.Execute += Raise.Event(); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "New", "Release" })); } [Test] public void Dialog_WhenClosedWithoutClickingOK_LeavesConfigsUnchanged() { dlg.ConfigurationName.Text = "New"; dlg.Close(); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "Debug", "Release" })); } } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/XmlPresenterTests.cs0000664000175000017500000000415311544451536026034 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.Xml; using NUnit.Framework; using NSubstitute; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class XmlPresenterTests { private IProjectDocument doc; private IXmlView xmlView; private XmlPresenter presenter; private static readonly string initialText = ""; private static readonly string changedText = ""; [SetUp] public void Initialize() { doc = new ProjectDocument(); doc.LoadXml(initialText); xmlView = Substitute.For(); presenter = new XmlPresenter(doc, xmlView); presenter.LoadViewFromModel(); } [Test] public void XmlText_OnLoad_IsInitializedCorrectly() { Assert.AreEqual(initialText, xmlView.Xml.Text); } [Test] public void XmlText_WhenChanged_ModelIsUpdated() { xmlView.Xml.Text = changedText; xmlView.Xml.Validated += Raise.Event(); Assert.AreEqual(changedText, doc.XmlText); } [Test] public void BadXmlSetsException() { xmlView.Xml.Text = ""; // Missing slash xmlView.Xml.Validated += Raise.Event(); Assert.AreEqual("", doc.XmlText); Assert.NotNull(doc.Exception); Assert.IsInstanceOf(doc.Exception); XmlException ex = doc.Exception as XmlException; xmlView.Received().DisplayError(ex.Message, ex.LineNumber, ex.LinePosition); } } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/SelectionStub.cs0000664000175000017500000000764111544447130025144 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.Collections.Generic; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor.Tests { public class SelectionStub : ISelectionList, IComboBox { private int selectedIndex = -1; private string[] selectionList; private string text; public SelectionStub(string name) { this.Name = name; } #region IComboBox Members public string Text { get { return text; } set { text = value; int index = IndexOf(text); selectedIndex = index >= 0 ? index : -1; if (TextValidated != null) TextValidated(); if (SelectionChanged != null) SelectionChanged(); } } public event ActionDelegate TextValidated; #endregion #region ISelectionList Members /// /// Gets or sets the currently selected item /// public string SelectedItem { get { return selectedIndex >= 0 && selectedIndex < selectionList.Length ? selectionList[selectedIndex] : null; } set { int index = IndexOf(value); if (index >= 0) { text = value; selectedIndex = index; if (TextValidated != null) TextValidated(); if (SelectionChanged != null) SelectionChanged(); } } } /// /// Gets or sets the contents of the selection list /// public string[] SelectionList { get { return selectionList; } set { selectionList = value; if (selectionList.Length == 0) SelectedIndex = -1; else SelectedIndex = 0; } } #endregion #region ISelection Members /// /// Gets or sets the index of the currently selected item /// public int SelectedIndex { get { return selectedIndex; } set { selectedIndex = value < 0 || value >= SelectionList.Length ? -1 : value; if (SelectionChanged != null) SelectionChanged(); } } /// /// Event raised when the selection is changed by the user /// public event ActionDelegate SelectionChanged; #endregion #region IViewElement Members /// /// Gets the name of the element in the xmlView /// public string Name { get; set; } /// /// Gets or sets the enabled status of the element /// public bool Enabled { get; set; } #endregion #region Helper Methods private int IndexOf(string item) { for (int index = 0; index < selectionList.Length; index++) if (item == selectionList[index]) return index; return -1; } #endregion } } #endif NUnit-2.6.0.12051/src/ProjectEditor/tests/Presenters/AddConfigurationPresenterTests.cs0000664000175000017500000000602511544451536030514 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.IO; using NSubstitute; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Presenters { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class AddConfigurationPresenterTests { IProjectModel model; IAddConfigurationDialog dlg; AddConfigurationPresenter presenter; [SetUp] public void SetUp() { IProjectDocument doc = new ProjectDocument(); doc.LoadXml(NUnitProjectXml.NormalProject); model = new ProjectModel(doc); dlg = Substitute.For(); presenter = new AddConfigurationPresenter(model, dlg); } [Test] public void ConfigList_LoadFromModel_SetsViewCorrectly() { Assert.That(dlg.ConfigList, Is.EqualTo(new string[] {"Debug", "Release"})); } [Test] public void AddButton_AddNewConfig_IsAddedToList() { dlg.ConfigToCreate.Returns("New"); dlg.OkButton.Execute += Raise.Event(); Assert.That(model.ConfigNames, Is.EqualTo(new string[] {"Debug", "Release", "New"})); } [Test] public void AddButton_AddExistingConfig_FailsWithErrorMessage() { dlg.ConfigToCreate.Returns("Release"); dlg.OkButton.Execute += Raise.Event(); dlg.MessageDisplay.Received().Error("A configuration with that name already exists"); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "Debug", "Release" })); } [Test] public void ConfigToCopy_WhenNotSpecified_ConfigIsEmpty() { dlg.ConfigToCreate.Returns("New"); dlg.ConfigToCopy.Returns(""); dlg.OkButton.Execute += Raise.Event(); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "Debug", "Release", "New" })); Assert.That(model.Configs[2].BasePath, Is.EqualTo(null)); Assert.That(model.Configs[2].Assemblies.Count, Is.EqualTo(0)); } [Test] public void ConfigToCopy_WhenSpecified_ConfigIsCopied() { dlg.ConfigToCreate.Returns("New"); dlg.ConfigToCopy.Returns("Release"); dlg.OkButton.Execute += Raise.Event(); Assert.That(model.ConfigNames, Is.EqualTo(new string[] { "Debug", "Release", "New" })); Assert.That(model.Configs[2].BasePath, Is.EqualTo("bin" + Path.DirectorySeparatorChar + "release")); Assert.That(model.Configs[2].Assemblies.Count, Is.EqualTo(2)); } } } #endifNUnit-2.6.0.12051/src/ProjectEditor/tests/Model/0000775000175000017500000000000011742560362020733 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/Model/ProjectCreationTests.cs0000664000175000017500000001003511626110506025367 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { [TestFixture] public class ProjectCreationTests { private ProjectDocument doc; private ProjectModel project; private string xmlfile; private bool gotChangeNotice; [SetUp] public void SetUp() { doc = new ProjectDocument(); doc.CreateNewProject(); project = new ProjectModel(doc); doc.ProjectChanged += OnProjectChange; gotChangeNotice = false; xmlfile = Path.ChangeExtension(Path.GetTempFileName(), ".nunit"); } [TearDown] public void EraseFile() { if (File.Exists(xmlfile)) File.Delete(xmlfile); } private void OnProjectChange() { gotChangeNotice = true; } [Test] public void IsNotDirty() { Assert.IsFalse(doc.HasUnsavedChanges); } [Test] public void ProjectPathIsSameAsName() { Assert.AreEqual(Path.GetFullPath(doc.Name), doc.ProjectPath); } [Test] public void NameIsUnique() { ProjectDocument anotherProject = new ProjectDocument(xmlfile); Assert.AreNotEqual(doc.Name, anotherProject.Name); } [Test] public void RootElementIsNUnitProject() { Assert.AreEqual("NUnitProject", doc.RootNode.Name); } [Test] public void ProjectNodeHasNoChildren() { Assert.AreEqual(0, doc.RootNode.ChildNodes.Count); } [Test] public void ProjectNodeHasNoAttributes() { Assert.AreEqual(0, doc.RootNode.Attributes.Count); } [Test] public void NewProjectHasNoConfigs() { Assert.AreEqual(0, project.Configs.Count); Assert.IsNull(project.ActiveConfigName); } [Test] public void SaveMakesProjectNotDirty() { project.AddConfig("Debug"); doc.Save(xmlfile); Assert.IsFalse(doc.HasUnsavedChanges); } [Test] public void SaveSetsProjectPathAndName() { doc.Save(xmlfile); Assert.AreEqual(Path.GetFullPath(xmlfile), doc.ProjectPath); Assert.AreEqual(Path.GetFileNameWithoutExtension(xmlfile), doc.Name); } [Test] public void DefaultProjectName() { Assert.That(doc.Name, Is.StringMatching(@"Project\d")); } [Test] public void CanSetAppBase() { project.BasePath = ".."; Assert.AreEqual("..", project.BasePath); } [Test] public void CanAddConfigs() { project.AddConfig("Debug"); project.AddConfig("Release"); Assert.AreEqual(2, project.Configs.Count); } [Test] public void LoadMakesProjectNotDirty() { project.AddConfig("Debug"); doc.Save(xmlfile); ProjectDocument doc2 = new ProjectDocument(xmlfile); doc2.Load(); Assert.IsFalse(doc2.HasUnsavedChanges); } [Test] public void AddConfigMakesProjectDirty() { project.AddConfig("Debug"); Assert.IsTrue(doc.HasUnsavedChanges); } [Test] public void AddConfigFiresChangedEvent() { project.AddConfig("Debug"); Assert.IsTrue(gotChangeNotice); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Model/ProjectModelChangeTests.cs0000664000175000017500000001072011544330406025774 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.IO; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { class ProjectModelChangeTests { static readonly string xmlfile = "MyProject.nunit"; private ProjectDocument doc; private ProjectModel project; private bool gotChangeNotice; [SetUp] public void SetUp() { doc = new ProjectDocument(xmlfile); project = new ProjectModel(doc); doc.ProjectChanged += OnProjectChange; gotChangeNotice = false; } private void OnProjectChange() { gotChangeNotice = true; } [Test] public void RenameConfigMakesProjectDirty() { doc.LoadXml(NUnitProjectXml.NormalProject); project.Configs[0].Name = "New"; Assert.IsTrue(doc.HasUnsavedChanges); } [Test] public void RenameConfigFiresChangedEvent() { doc.LoadXml(NUnitProjectXml.NormalProject); project.Configs[0].Name = "New"; Assert.IsTrue(gotChangeNotice); } [Test] public void RenamingActiveConfigChangesActiveConfigName() { doc.LoadXml(NUnitProjectXml.NormalProject); project.ActiveConfigName = "Debug"; project.Configs[0].Name = "New"; Assert.AreEqual("New", project.ActiveConfigName); } [Test] public void RemoveConfigMakesProjectDirty() { doc.LoadXml(NUnitProjectXml.NormalProject); project.RemoveConfig("Debug"); Assert.IsTrue(doc.HasUnsavedChanges); } [Test] public void RemoveConfigFiresChangedEvent() { doc.LoadXml(NUnitProjectXml.NormalProject); project.RemoveConfig("Debug"); Assert.IsTrue(gotChangeNotice); } [Test] public void RemovingActiveConfigRemovesActiveConfigNameAttribute() { doc.LoadXml(NUnitProjectXml.NormalProject); project.ActiveConfigName = "Debug"; project.RemoveConfig("Debug"); Assert.AreEqual(null, project.ActiveConfigName); } [Test] public void SettingActiveConfigMakesProjectDirty() { doc.LoadXml(NUnitProjectXml.NormalProject); project.ActiveConfigName = "Release"; Assert.IsTrue(doc.HasUnsavedChanges); } [Test] public void SettingActiveConfigFiresChangedEvent() { doc.LoadXml(NUnitProjectXml.NormalProject); project.ActiveConfigName = "Release"; Assert.IsTrue(gotChangeNotice); } [Test] public void CanSetActiveConfig() { doc.LoadXml(NUnitProjectXml.NormalProject); project.ActiveConfigName = "Release"; Assert.AreEqual("Release", project.ActiveConfigName); } [Test] public void CanAddAssemblies() { doc.LoadXml(NUnitProjectXml.EmptyConfigs); project.Configs["Debug"].Assemblies.Add(Path.GetFullPath(@"bin\debug\assembly1.dll")); project.Configs["Debug"].Assemblies.Add(Path.GetFullPath(@"bin\debug\assembly2.dll")); project.Configs["Release"].Assemblies.Add(Path.GetFullPath(@"bin\debug\assembly3.dll")); Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(2, project.Configs["Debug"].Assemblies.Count); Assert.AreEqual(1, project.Configs["Release"].Assemblies.Count); } [Test] public void AddingAssemblyFiresChangedEvent() { doc.LoadXml(NUnitProjectXml.EmptyConfigs); project.Configs["Debug"].Assemblies.Add("assembly1.dll"); Assert.IsTrue(gotChangeNotice); } [Test] public void RemoveAssemblyFiresChangedEvent() { doc.LoadXml(NUnitProjectXml.NormalProject); project.Configs["Debug"].Assemblies.Remove("assembly1.dll"); Assert.IsTrue(gotChangeNotice); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Model/AssemblyListTests.cs0000664000175000017500000000764611544330406024727 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Xml; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { /// /// This fixture tests AssemblyList /// [TestFixture] public class AssemblyListTests { private AssemblyList assemblies; private string path1; private string path2; private string path3; [SetUp] public void CreateAssemblyList() { XmlDocument doc = new XmlDocument(); doc.LoadXml(""); assemblies = new AssemblyList(doc.FirstChild); path1 = CleanPath("/tests/bin/debug/assembly1.dll"); path2 = CleanPath("/tests/bin/debug/assembly2.dll"); path3 = CleanPath("/tests/bin/debug/assembly3.dll"); } [Test] public void EmptyList() { Assert.AreEqual( 0, assemblies.Count ); } [Test] public void CanAddAssemblies() { assemblies.Add(path1); assemblies.Add(path2); Assert.AreEqual(2, assemblies.Count); Assert.AreEqual(path1, assemblies[0]); Assert.AreEqual(path2, assemblies[1]); } [Test] public void CanInsertAssemblies() { assemblies.Add(path1); assemblies.Add(path3); assemblies.Insert(1, path2); Assert.AreEqual(3, assemblies.Count); Assert.AreEqual(path1, assemblies[0]); Assert.AreEqual(path2, assemblies[1]); Assert.AreEqual(path3, assemblies[2]); } [Test] public void CanInsertAssemblyAtEnd() { assemblies.Add(path1); assemblies.Add(path2); assemblies.Insert(2, path3); Assert.AreEqual(3, assemblies.Count); Assert.AreEqual(path1, assemblies[0]); Assert.AreEqual(path2, assemblies[1]); Assert.AreEqual(path3, assemblies[2]); } [Test] public void CanInsertAssemblyAtStart() { assemblies.Add(path2); assemblies.Add(path3); assemblies.Insert(0, path1); Assert.AreEqual(3, assemblies.Count); Assert.AreEqual(path1, assemblies[0]); Assert.AreEqual(path2, assemblies[1]); Assert.AreEqual(path3, assemblies[2]); } [Test] public void CanRemoveAssemblies() { assemblies.Add(path1); assemblies.Add(path2); assemblies.Add(path3); assemblies.Remove(path2); Assert.AreEqual(2, assemblies.Count); Assert.AreEqual(path1, assemblies[0]); Assert.AreEqual(path3, assemblies[1]); } //[Test] //public void CanRemoveAssemblyAtIndex() //{ // assemblies.Add(path1); // assemblies.Add(path2); // assemblies.Add(path3); // assemblies.RemoveAt(1); // Assert.AreEqual(2, assemblies.Count); // Assert.AreEqual(path1, assemblies[0]); // Assert.AreEqual(path3, assemblies[1]); //} //[Test] //public void CanFindIndexOfAssembly() //{ // assemblies.Add(path1); // assemblies.Add(path2); // assemblies.Add(path3); // Assert.AreEqual(1, assemblies.IndexOf(path2)); // Assert.AreEqual(-1, assemblies.IndexOf("/Not/in/list")); //} private string CleanPath( string path ) { return path.Replace( '/', System.IO.Path.DirectorySeparatorChar ); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Model/ProjectDocumentTests.cs0000664000175000017500000000364411544330406025413 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { [TestFixture] public class ProjectDocumentTests { static readonly string xmlfile = "test.nunit"; private ProjectDocument doc; private bool gotChangeNotice; [SetUp] public void SetUp() { doc = new ProjectDocument(); doc.CreateNewProject(); doc.ProjectChanged += new ActionDelegate(OnProjectChange); gotChangeNotice = false; } [TearDown] public void EraseFile() { if (File.Exists(xmlfile)) File.Delete(xmlfile); } private void OnProjectChange() { gotChangeNotice = true; } [Test] public void AddingElementMakesProjectDirty() { XmlHelper.AddElement(doc.RootNode, "Settings"); Assert.True(doc.HasUnsavedChanges); } [Test] public void AddingElementFiresChangedEvent() { XmlHelper.AddElement(doc.RootNode, "Settings"); Assert.True(gotChangeNotice); } [Test] public void AddingAttributeMakesProjectDirty() { XmlHelper.AddAttribute(doc.RootNode, "Version", "1.0"); Assert.True(doc.HasUnsavedChanges); } [Test] public void AddingAttributeFiresChangedEvent() { XmlHelper.AddAttribute(doc.RootNode, "Version", "1.0"); Assert.True(gotChangeNotice); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Model/NUnitProjectSave.cs0000664000175000017500000001052711626110076024464 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.Xml; using System.IO; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { [TestFixture] public class NUnitProjectSave { private ProjectDocument doc; private ProjectModel project; private string xmlfile; [SetUp] public void SetUp() { doc = new ProjectDocument(); project = new ProjectModel(doc); doc.CreateNewProject(); xmlfile = Path.ChangeExtension(Path.GetTempFileName(), ".nunit"); } [TearDown] public void TearDown() { if ( File.Exists( xmlfile ) ) File.Delete( xmlfile ); } [Test] public void EmptyProject() { CheckContents( NUnitProjectXml.EmptyProject ); } [Test] public void EmptyConfigs() { project.AddConfig("Debug"); project.AddConfig("Release"); project.ActiveConfigName = "Debug"; project.Configs["Debug"].BinPathType = BinPathType.Auto; project.Configs["Release"].BinPathType = BinPathType.Auto; CheckContents( NUnitProjectXml.EmptyConfigs ); } [Test] public void NormalProject() { IProjectConfig config1 = project.AddConfig("Debug"); config1.BasePath = "bin" + Path.DirectorySeparatorChar + "debug"; config1.BinPathType = BinPathType.Auto; config1.Assemblies.Add("assembly1.dll"); config1.Assemblies.Add("assembly2.dll"); IProjectConfig config2 = project.AddConfig("Release"); config2.BasePath = "bin" + Path.DirectorySeparatorChar + "release"; config2.BinPathType = BinPathType.Auto; config2.Assemblies.Add("assembly1.dll"); config2.Assemblies.Add("assembly2.dll"); project.ActiveConfigName = "Debug"; CheckContents(NUnitProjectXml.NormalProject); } [Test] public void NormalProject_RoundTrip() { doc.LoadXml(NUnitProjectXml.NormalProject); CheckContents(NUnitProjectXml.NormalProject); } [Test] public void ProjectWithComplexSettings() { IProjectConfig config1 = project.AddConfig("Debug"); config1.BasePath = "debug"; config1.BinPathType = BinPathType.Auto; config1.RuntimeFramework = new RuntimeFramework(RuntimeType.Any, new Version(2, 0)); config1.Assemblies.Add("assembly1.dll"); config1.Assemblies.Add("assembly2.dll"); IProjectConfig config2 = project.AddConfig("Release"); config2.BasePath = "release"; config2.BinPathType = BinPathType.Auto; config2.RuntimeFramework = new RuntimeFramework(RuntimeType.Any, new Version(4, 0)); config2.Assemblies.Add("assembly1.dll"); config2.Assemblies.Add("assembly2.dll"); project.ActiveConfigName = "Release"; project.BasePath = "bin"; project.ProcessModel = "Separate"; project.DomainUsage = "Multiple"; CheckContents(NUnitProjectXml.ComplexSettingsProject); } [Test] public void ProjectWithComplexSettings_RoundTrip() { doc.LoadXml(NUnitProjectXml.ComplexSettingsProject); CheckContents(NUnitProjectXml.ComplexSettingsProject); } [Test] public void ProjectWithComplexSettings_RoundTripWithChanges() { doc.LoadXml(NUnitProjectXml.ComplexSettingsProject); project.ProcessModel = "Single"; CheckContents(NUnitProjectXml.ComplexSettingsProject .Replace("Separate", "Single")); } private void CheckContents(string expected) { doc.Save(xmlfile); StreamReader reader = new StreamReader(xmlfile); string contents = reader.ReadToEnd(); reader.Close(); Assert.That(contents, Is.EqualTo(expected)); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/Model/ProjectModelLoadtests.cs0000664000175000017500000001577411626110412025536 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.IO; using NUnit.Framework; namespace NUnit.ProjectEditor.Tests.Model { [TestFixture] public class ProjectModelLoadtests { private ProjectDocument doc; private ProjectModel project; private string xmlfile; [SetUp] public void SetUp() { xmlfile = Path.ChangeExtension(Path.GetTempFileName(), ".nunit"); doc = new ProjectDocument(xmlfile); project = new ProjectModel(doc); } [TearDown] public void TearDown() { if (File.Exists(xmlfile)) File.Delete(xmlfile); } [Test] public void LoadEmptyProject() { doc.LoadXml(NUnitProjectXml.EmptyProject); Assert.AreEqual(Path.GetFullPath(xmlfile), project.ProjectPath); Assert.AreEqual(null, project.BasePath); Assert.AreEqual(Path.GetDirectoryName(project.ProjectPath), project.EffectiveBasePath); Assert.AreEqual("Default", project.ProcessModel); Assert.AreEqual("Default", project.DomainUsage); Assert.AreEqual(0, project.Configs.Count); Assert.AreEqual(0, project.ConfigNames.Length); Assert.AreEqual(null, project.ActiveConfigName); } [Test] public void LoadEmptyConfigs() { doc.LoadXml(NUnitProjectXml.EmptyConfigs); Assert.AreEqual(Path.GetFullPath(xmlfile), project.ProjectPath); Assert.AreEqual(null, project.BasePath); Assert.AreEqual(Path.GetDirectoryName(project.ProjectPath), project.EffectiveBasePath); Assert.AreEqual("Default", project.ProcessModel); Assert.AreEqual("Default", project.DomainUsage); Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(new string[] { "Debug", "Release" }, project.ConfigNames); Assert.AreEqual("Debug", project.ActiveConfigName); Assert.AreEqual("Debug", project.Configs[0].Name); Assert.AreEqual("Release", project.Configs[1].Name); } [Test] public void LoadNormalProject() { doc.LoadXml(NUnitProjectXml.NormalProject); Assert.AreEqual(Path.GetFullPath(xmlfile), project.ProjectPath); Assert.AreEqual(null, project.BasePath); Assert.AreEqual(Path.GetDirectoryName(project.ProjectPath), project.EffectiveBasePath); Assert.AreEqual("Default", project.ProcessModel); Assert.AreEqual("Default", project.DomainUsage); Assert.AreEqual(2, project.Configs.Count); Assert.AreEqual(new string[] { "Debug", "Release" }, project.ConfigNames); Assert.AreEqual("Debug", project.ActiveConfigName); IProjectConfig config1 = project.Configs[0]; Assert.AreEqual(2, config1.Assemblies.Count); Assert.AreEqual( "assembly1.dll", config1.Assemblies[0]); Assert.AreEqual( "assembly2.dll", config1.Assemblies[1]); IProjectConfig config2 = project.Configs[1]; Assert.AreEqual(2, config2.Assemblies.Count); Assert.AreEqual( "assembly1.dll", config2.Assemblies[0]); Assert.AreEqual( "assembly2.dll", config2.Assemblies[1]); } [Test] public void LoadProjectWithManualBinPath() { doc.LoadXml(NUnitProjectXml.ManualBinPathProject); Assert.AreEqual(Path.GetFullPath(xmlfile), project.ProjectPath); Assert.AreEqual(null, project.BasePath); Assert.AreEqual(Path.GetDirectoryName(project.ProjectPath), project.EffectiveBasePath); Assert.AreEqual("Default", project.ProcessModel); Assert.AreEqual("Default", project.DomainUsage); Assert.AreEqual(1, project.Configs.Count); Assert.AreEqual(new string[] { "Debug" }, project.ConfigNames); IProjectConfig config1 = project.Configs["Debug"]; Assert.AreEqual("bin_path_value", config1.PrivateBinPath); } [Test] public void LoadProjectWithComplexSettings() { doc.LoadXml(NUnitProjectXml.ComplexSettingsProject); Assert.AreEqual("bin", project.BasePath); Assert.AreEqual("Separate", project.ProcessModel); Assert.AreEqual("Multiple", project.DomainUsage); Assert.AreEqual(2, project.Configs.Count); IProjectConfig config1 = project.Configs[0]; Assert.AreEqual( "debug", config1.BasePath); Assert.AreEqual(RuntimeType.Any, config1.RuntimeFramework.Runtime); Assert.AreEqual("2.0", config1.RuntimeFramework.Version.ToString(2)); Assert.AreEqual(2, config1.Assemblies.Count); Assert.AreEqual( "assembly1.dll", config1.Assemblies[0]); Assert.AreEqual( "assembly2.dll", config1.Assemblies[1]); IProjectConfig config2 = project.Configs[1]; Assert.AreEqual(2, config2.Assemblies.Count); Assert.AreEqual( "release", config2.BasePath); Assert.AreEqual(RuntimeType.Any, config2.RuntimeFramework.Runtime); Assert.AreEqual("4.0", config2.RuntimeFramework.Version.ToString(2)); Assert.AreEqual( "assembly1.dll", config2.Assemblies[0]); Assert.AreEqual( "assembly2.dll", config2.Assemblies[1]); } [Test] public void CanSaveAndReloadProject() { doc.LoadXml(NUnitProjectXml.NormalProject); doc.Save(xmlfile); Assert.IsTrue(File.Exists(xmlfile)); ProjectDocument doc2 = new ProjectDocument(xmlfile); doc2.Load(); ProjectModel project2 = new ProjectModel(doc2); Assert.AreEqual(2, project2.Configs.Count); Assert.AreEqual(2, project2.Configs[0].Assemblies.Count); Assert.AreEqual("assembly1.dll", project2.Configs[0].Assemblies[0]); Assert.AreEqual("assembly2.dll", project2.Configs[0].Assemblies[1]); Assert.AreEqual(2, project2.Configs[1].Assemblies.Count); Assert.AreEqual("assembly1.dll", project2.Configs[1].Assemblies[0]); Assert.AreEqual("assembly2.dll", project2.Configs[1].Assemblies[1]); } } } NUnit-2.6.0.12051/src/ProjectEditor/tests/resources/0000775000175000017500000000000011742560362021705 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/tests/resources/NUnitTests.nunit0000664000175000017500000000305311544330406025037 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ProjectEditor/tests/resources/BadProject.nunit0000664000175000017500000000310711544330406024774 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ProjectEditor/tests/NUnitProjectXml.cs0000664000175000017500000000626211544330406023267 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; namespace NUnit.ProjectEditor.Tests { /// /// Summary description for NUnitProjectXml. /// public class NUnitProjectXml { public static readonly string EmptyProject = ""; public static readonly string EmptyConfigs = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; public static readonly string NormalProject = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; public static readonly string ManualBinPathProject = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; public static readonly string ComplexSettingsProject = "" + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + " " + System.Environment.NewLine + ""; } } NUnit-2.6.0.12051/src/ProjectEditor/tests/nunit-editor.tests.csproj0000664000175000017500000001047711707326444024712 0ustar jtaylorjtaylor Debug AnyCPU 9.0.30729 2.0 {A9E1C1E9-AE97-4510-AD94-EAFADE425FBE} Library Properties NUnit.ProjectEditor.Tests nunit-editor.tests 512 v3.5 true full false ..\..\..\bin\Debug\tests\ TRACE;DEBUG;CLR_2_0,NET_3_5,CS_3_0 prompt 4 pdbonly true ..\..\..\bin\Release\tests\ TRACE;CLR_2_0,NET_3_5,CS_3_0 prompt 4 3.5 ..\..\..\lib\3.5\NSubstitute.dll Code {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} test-utilities {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB} nunit-editor NUnit-2.6.0.12051/src/ProjectEditor/editor/0000775000175000017500000000000011742560362020017 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/App.ico0000664000175000017500000000206611544330406021231 0ustar jtaylorjtaylor &(( @( ffffffffffffffffNUnit-2.6.0.12051/src/ProjectEditor/editor/nunit-editor.build0000664000175000017500000001072611703053400023452 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/0000775000175000017500000000000011742560362022426 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/RadioButtonGroup.cs0000664000175000017500000000365111544330406026223 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { public class RadioButtonGroup : ISelection { private string name; private bool enabled; private RadioButton[] buttons; public RadioButtonGroup(string name, params RadioButton[] buttons) { this.name = name; this.enabled = buttons.Length > 0 ? buttons[0].Enabled : false; this.buttons = buttons; foreach (RadioButton button in buttons) button.CheckedChanged += delegate { if (SelectionChanged != null) SelectionChanged(); }; } public string Name { get { return name; } } public bool Enabled { get { return enabled; } set { enabled = value; foreach (RadioButton button in buttons) button.Enabled = enabled; } } public int SelectedIndex { get { for (int index = 0; index < buttons.Length; index++) if (buttons[index].Checked) return index; return -1; } set { if (value >= 0 && value < buttons.Length) buttons[value].Checked = true; } } public event ActionDelegate SelectionChanged; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/IComboBox.cs0000664000175000017500000000225111544330406024570 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { /// /// IComboBox is implemented by view elements that associate /// an editable TextBox with a SelectionList. The classic /// implementation is System.Windows.Forms.ComboBox. This /// interface is only intended for use when the TextBox /// is editable. Otherwise, ISelectionList provides all /// the necessary functionality. /// public interface IComboBox : ISelectionList { /// /// Gets or sets the value of the TextBox associated /// with this ComboBox. /// string Text { get; set; } /// /// Event that is raised when the text has changed /// and the focus is moved away. /// event ActionDelegate TextValidated; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ListBoxElement.cs0000664000175000017500000000333411544330406025650 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public class ListBoxElement : ControlElement, ISelectionList { private ListBox listBox; public ListBoxElement(ListBox listBox) : base(listBox) { this.listBox = listBox; listBox.SelectedIndexChanged += delegate { if (SelectionChanged != null) SelectionChanged(); }; } public int SelectedIndex { get { return listBox.SelectedIndex; } set { listBox.SelectedIndex = value; } } public string SelectedItem { get { return (string)listBox.SelectedItem; } set { listBox.SelectedItem = value; } } public string[] SelectionList { get { string[] list = new string[listBox.Items.Count]; int index = 0; foreach (string item in listBox.Items) list[index++] = item; return list; } set { listBox.Items.Clear(); foreach (string item in value) listBox.Items.Add(item); } } public event ActionDelegate SelectionChanged; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/DialogManager.cs0000664000175000017500000000402111544330406025436 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { public class DialogManager : IDialogManager { string caption; #region Constructor public DialogManager(string defaultCaption) { this.caption = defaultCaption; } #endregion #region IDialogManager Members public string GetFileOpenPath(string title, string filter, string initialDirectory) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = title; dlg.Filter = filter; if (initialDirectory != null) dlg.InitialDirectory = initialDirectory; dlg.FilterIndex = 1; dlg.FileName = ""; dlg.Multiselect = false; return dlg.ShowDialog() == DialogResult.OK ? dlg.FileNames[0] : null; } public string GetSaveAsPath(string title, string filter) { SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = title; dlg.Filter = filter; dlg.FilterIndex = 1; dlg.FileName = ""; return dlg.ShowDialog() == DialogResult.OK ? dlg.FileName : null; } public string GetFolderPath(string message, string initialPath) { FolderBrowserDialog browser = new FolderBrowserDialog(); browser.Description = message; browser.SelectedPath = initialPath; return browser.ShowDialog() == DialogResult.OK ? browser.SelectedPath : null; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/IMessageDisplay.cs0000664000175000017500000000102611544330406025771 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { public interface IMessageDisplay { void Error(string message); bool AskYesNoQuestion(string question); } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ButtonElement.cs0000664000175000017500000000177411544330406025545 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { /// /// ControlWrapper is a general wrapper for controls used /// by the view. It implements several different interfaces /// so that the view may choose which one to expose, based /// on the type of textBox and how it is used. /// public class ButtonElement : ControlElement, ICommand { public ButtonElement(Button button) : base(button) { button.Click += delegate { if (Execute != null) Execute(); }; } public event CommandDelegate Execute; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/MessageDisplay.cs0000664000175000017500000000170211544330406025661 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { public class MessageDisplay : IMessageDisplay { private string caption; public MessageDisplay(string caption) { this.caption = caption; } public void Error(string message) { MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } public bool AskYesNoQuestion(string question) { return MessageBox.Show(question, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes; } } }NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ICommand.cs0000664000175000017500000000122711544330406024440 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { public interface ICommand : IViewElement { /// /// Execute event is raised to signal the presenter /// to execute the command with which this menu /// item is associated. /// event CommandDelegate Execute; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ISelection.cs0000664000175000017500000000135311544330406025007 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { public interface ISelection : IViewElement { /// /// Gets or sets the index of the currently selected item /// int SelectedIndex { get; set; } /// /// Event raised when the selection is changed by the user /// event ActionDelegate SelectionChanged; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/IViewElement.cs0000664000175000017500000000155211544330406025307 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { /// /// The IViewElement interface is exposed by the view /// for an individual gui element. It is the base of /// other more specific interfaces. /// public interface IViewElement { /// /// Gets the name of the element in the view /// string Name { get; } /// /// Gets or sets the enabled status of the element /// bool Enabled { get; set; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ComboBoxElement.cs0000664000175000017500000000562011544330406025774 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// ComboBoxElement is used to wrap a ComboBox. If the /// text is editable by the user, the view should expose /// the element using the IComboBox interface. Otherwise, /// the ISelectionInterface provides all the needed /// functionality. /// public class ComboBoxElement : ControlElement, ISelectionList, IComboBox { private ComboBox comboBox; public ComboBoxElement(ComboBox comboBox) : base(comboBox) { this.comboBox = comboBox; comboBox.SelectedIndexChanged += delegate { if (SelectionChanged != null) SelectionChanged(); }; comboBox.Validated += delegate { if (TextValidated != null) TextValidated(); }; } /// /// Gets or sets the SelectedIndex property of the associated ComboBox /// public int SelectedIndex { get { return comboBox.SelectedIndex; } set { comboBox.SelectedIndex = value; } } /// /// Gets or sets the SelectedItem property of the associated ComboBox /// public string SelectedItem { get { return (string)comboBox.SelectedItem; } set { comboBox.SelectedItem = value; } } /// /// Gets or sets the list of items displayed in the associated ComboBox /// public string[] SelectionList { get { string[] list = new string[comboBox.Items.Count]; int index = 0; foreach (string item in comboBox.Items) list[index++] = item; return list; } set { comboBox.Items.Clear(); foreach (string item in value) comboBox.Items.Add(item); } } /// /// Event raised when the selection in the associated ComboBox changes /// public event ActionDelegate SelectionChanged; /// /// Event raised when the Text of the associated ComboBox is validated /// public event ActionDelegate TextValidated; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/TextElement.cs0000664000175000017500000000246611544330406025215 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { public class TextElement : ControlElement, ITextElement { private TextBoxBase textBox; public TextElement(Label label) : base(label) { } public TextElement(TextBoxBase textBox) : base(textBox) { this.textBox = textBox; textBox.TextChanged += delegate { if (Changed != null) Changed(); }; textBox.Validated += delegate { if (Validated != null) Validated(); }; } public void Select(int offset, int length) { if (textBox == null) throw new InvalidOperationException("Cannot select text in a label"); textBox.Select(offset, length); } public event ActionDelegate Changed; public event ActionDelegate Validated; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ControlElement.cs0000664000175000017500000000260011544330406025677 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { /// /// ControlWrapper is a general wrapper for controls used /// by the view. It implements several different interfaces /// so that the view may choose which one to expose, based /// on the type of textBox and how it is used. /// public class ControlElement : IViewElement { private Control control; public ControlElement(Control control) { this.control = control; } public string Name { get { return control.Name; } } public bool Enabled { get { return control.Enabled; } set { control.Enabled = value; } } public bool Visible { get { return control.Visible; } set { control.Visible = value; } } public string Text { get { return control.Text; } set { control.Text = value; } } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ITextElement.cs0000664000175000017500000000172011544330406025316 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { public interface ITextElement : IViewElement { /// /// Gets or sets the text of the element /// string Text { get; set; } void Select(int offset, int length); /// /// Changed event is raised whenever the text changes /// event ActionDelegate Changed; /// /// Validated event is raised when the text has been /// changed and focus has left the UI element. /// event ActionDelegate Validated; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/IDialogManager.cs0000664000175000017500000000117211544330406025553 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { public interface IDialogManager { string GetFileOpenPath(string title, string filter, string initialDirectory); string GetSaveAsPath(string title, string filter); string GetFolderPath(string message, string initialPath); } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/MenuElement.cs0000664000175000017500000000237711544330406025176 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor.ViewElements { /// /// MenuItemWrapper is the implementation of MenuItem /// used in the actual application. /// public class MenuElement : ICommand { private ToolStripMenuItem menuItem; public MenuElement(ToolStripMenuItem menuItem) { this.menuItem = menuItem; menuItem.Click += delegate { if (Execute != null) Execute(); }; } public event CommandDelegate Execute; public string Name { get { return menuItem.Name; } } public bool Enabled { get { return menuItem.Enabled; } set { menuItem.Enabled = value; } } public string Text { get { return menuItem.Text; } set { menuItem.Text = value; } } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ViewElements/ISelectionList.cs0000664000175000017500000000160611544330406025644 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor.ViewElements { /// /// The ISelectionList interface represents /// a ui element that allows the user to select one of /// a set of items. /// public interface ISelectionList : ISelection { /// /// Gets or sets the currently selected item /// string SelectedItem { get; set; } /// /// Gets or sets the contents of the selection list /// string[] SelectionList { get; set; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/0000775000175000017500000000000011742560362023775 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/ConfigurationEditorView.Designer.cs0000664000175000017500000001453211544330406032673 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class ConfigurationEditorDialog { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(ConfigurationEditorDialog)); this.configListBox = new System.Windows.Forms.ListBox(); this.removeButton = new System.Windows.Forms.Button(); this.renameButton = new System.Windows.Forms.Button(); this.closeButton = new System.Windows.Forms.Button(); this.addButton = new System.Windows.Forms.Button(); this.activeButton = new System.Windows.Forms.Button(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.SuspendLayout(); // // configListBox // this.helpProvider1.SetHelpString(this.configListBox, "Selects the configuration to operate on."); this.configListBox.ItemHeight = 16; this.configListBox.Location = new System.Drawing.Point(8, 8); this.configListBox.Name = "configListBox"; this.helpProvider1.SetShowHelp(this.configListBox, true); this.configListBox.Size = new System.Drawing.Size(168, 212); this.configListBox.TabIndex = 0; // // removeButton // this.helpProvider1.SetHelpString(this.removeButton, "Removes the selected configuration"); this.removeButton.Location = new System.Drawing.Point(192, 8); this.removeButton.Name = "removeButton"; this.helpProvider1.SetShowHelp(this.removeButton, true); this.removeButton.Size = new System.Drawing.Size(96, 32); this.removeButton.TabIndex = 1; this.removeButton.Text = "&Remove"; // // renameButton // this.helpProvider1.SetHelpString(this.renameButton, "Allows renaming the selected configuration"); this.renameButton.Location = new System.Drawing.Point(192, 48); this.renameButton.Name = "renameButton"; this.helpProvider1.SetShowHelp(this.renameButton, true); this.renameButton.Size = new System.Drawing.Size(96, 32); this.renameButton.TabIndex = 2; this.renameButton.Text = "Re&name..."; // // closeButton // this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.helpProvider1.SetHelpString(this.closeButton, "Closes this dialog"); this.closeButton.Location = new System.Drawing.Point(192, 216); this.closeButton.Name = "closeButton"; this.helpProvider1.SetShowHelp(this.closeButton, true); this.closeButton.Size = new System.Drawing.Size(96, 32); this.closeButton.TabIndex = 4; this.closeButton.Text = "Close"; // // addButton // this.helpProvider1.SetHelpString(this.addButton, "Allows adding a new configuration"); this.addButton.Location = new System.Drawing.Point(192, 88); this.addButton.Name = "addButton"; this.helpProvider1.SetShowHelp(this.addButton, true); this.addButton.Size = new System.Drawing.Size(96, 32); this.addButton.TabIndex = 5; this.addButton.Text = "&Add..."; // // activeButton // this.helpProvider1.SetHelpString(this.activeButton, "Makes the selected configuration active"); this.activeButton.Location = new System.Drawing.Point(192, 128); this.activeButton.Name = "activeButton"; this.helpProvider1.SetShowHelp(this.activeButton, true); this.activeButton.Size = new System.Drawing.Size(96, 32); this.activeButton.TabIndex = 6; this.activeButton.Text = "&Make Active"; // // ConfigurationEditor // this.AcceptButton = this.closeButton; this.CancelButton = this.closeButton; this.ClientSize = new System.Drawing.Size(297, 267); this.ControlBox = false; this.Controls.Add(this.activeButton); this.Controls.Add(this.addButton); this.Controls.Add(this.closeButton); this.Controls.Add(this.renameButton); this.Controls.Add(this.removeButton); this.Controls.Add(this.configListBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.HelpButton = true; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigurationEditor"; this.helpProvider1.SetShowHelp(this, false); this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Configuration Editor"; this.ResumeLayout(false); } #endregion private System.Windows.Forms.ListBox configListBox; private System.Windows.Forms.Button removeButton; private System.Windows.Forms.Button renameButton; private System.Windows.Forms.Button addButton; private System.Windows.Forms.Button activeButton; private System.Windows.Forms.HelpProvider helpProvider1; private System.Windows.Forms.Button closeButton; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/ConfigurationEditorView.cs0000664000175000017500000000521011544330406031125 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// ConfigurationEditor form is designed for adding, deleting /// and renaming configurations from a doc. /// public partial class ConfigurationEditorDialog : System.Windows.Forms.Form, IConfigurationEditorDialog { #region Instance Variables private ICommand addCommand; private ICommand removeCommand; private ICommand renameCommand; private ICommand activeCommand; private ISelectionList configList; private IMessageDisplay messageDisplay; #endregion #region Constructor public ConfigurationEditorDialog() { InitializeComponent(); addCommand = new ButtonElement(addButton); removeCommand = new ButtonElement(removeButton); renameCommand = new ButtonElement(renameButton); activeCommand = new ButtonElement(activeButton); configList = new ListBoxElement(configListBox); messageDisplay = new MessageDisplay("NUnit Configuration Editor"); } #endregion #region IConfigurationEditorDialog Members #region Properties public ICommand AddCommand { get { return addCommand; } } public ICommand RemoveCommand { get { return removeCommand; } } public ICommand RenameCommand { get { return renameCommand; } } public ICommand ActiveCommand { get { return activeCommand; } } public ISelectionList ConfigList { get { return configList; } } public IAddConfigurationDialog AddConfigurationDialog { get { return new AddConfigurationDialog(); } } public IMessageDisplay MessageDisplay { get { return messageDisplay; } } public IRenameConfigurationDialog RenameConfigurationDialog { get { return new RenameConfigurationDialog(); } } #endregion #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/AddConfigurationDialog.cs0000664000175000017500000000552111544330406030661 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// Displays a dialog for creation of a new configuration. /// The dialog collects and validates the name and the /// name of a configuration to be copied and then adds the /// new configuration to the doc. /// /// A DialogResult of DialogResult.OK indicates that the /// configuration was added successfully. /// public partial class AddConfigurationDialog : System.Windows.Forms.Form, IAddConfigurationDialog { private static readonly string NONE_SELECTED = ""; #region Constructor public AddConfigurationDialog() { InitializeComponent(); okButtonWrapper = new ButtonElement(okButton); } #endregion #region Properties private MessageDisplay mbox = new MessageDisplay("Add Configuration"); public IMessageDisplay MessageDisplay { get { return mbox; } } private string[] configList; public string[] ConfigList { get { return configList; } set { configList = value; configurationComboBox.Items.Clear(); configurationComboBox.Items.Add(NONE_SELECTED); configurationComboBox.SelectedIndex = 0; foreach (string config in configList) configurationComboBox.Items.Add(config); } } public string ConfigToCreate { get { return configurationNameTextBox.Text; } } public string ConfigToCopy { get { string config = (string)configurationComboBox.SelectedItem; return config == NONE_SELECTED ? null : config; } set { string config = string.IsNullOrEmpty(value) ? NONE_SELECTED : value; configurationComboBox.SelectedItem = config; } } private ICommand okButtonWrapper; public ICommand OkButton { get { return okButtonWrapper; } } #endregion } public interface IAddConfigurationDialog : IDialog { string[] ConfigList { get; set; } string ConfigToCreate { get; } string ConfigToCopy { get; } ICommand OkButton { get; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/IConfigurationEditorView.cs0000664000175000017500000000145311544330406031243 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public interface IConfigurationEditorDialog : IDialog { ICommand AddCommand { get; } ICommand RenameCommand { get; } ICommand RemoveCommand { get; } ICommand ActiveCommand { get; } ISelectionList ConfigList { get; } IAddConfigurationDialog AddConfigurationDialog { get; } IRenameConfigurationDialog RenameConfigurationDialog { get; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/AddConfigurationPresenter.cs0000664000175000017500000000442611544330406031434 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { public class AddConfigurationPresenter { private IProjectModel model; private IAddConfigurationDialog dlg; public AddConfigurationPresenter(IProjectModel model, IAddConfigurationDialog dlg) { this.model = model; this.dlg = dlg; dlg.ConfigList = model.ConfigNames; dlg.OkButton.Execute += delegate { if (dlg.ConfigToCreate == string.Empty) { dlg.MessageDisplay.Error("No configuration name provided"); return; } foreach (string config in model.ConfigNames) { if (config == dlg.ConfigToCreate) { dlg.MessageDisplay.Error("A configuration with that name already exists"); return; } } IProjectConfig newConfig = model.AddConfig(dlg.ConfigToCreate); if (dlg.ConfigToCopy != null) { IProjectConfig copyConfig = model.Configs[dlg.ConfigToCopy]; if (copyConfig != null) { newConfig.BasePath = copyConfig.BasePath; newConfig.BinPathType = copyConfig.BinPathType; if (newConfig.BinPathType == BinPathType.Manual) newConfig.PrivateBinPath = copyConfig.PrivateBinPath; newConfig.ConfigurationFile = copyConfig.ConfigurationFile; newConfig.RuntimeFramework = copyConfig.RuntimeFramework; foreach (string assembly in copyConfig.Assemblies) newConfig.Assemblies.Add(assembly); } } dlg.Close(); }; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/AddConfigurationDialog.resx0000664000175000017500000001326611544330406031242 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/RenameConfigurationDialog.cs0000664000175000017500000000376411544330406031407 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// Displays a dialog for entry of a new name for an /// existing configuration. This dialog collects and /// validates the name. The caller is responsible for /// actually renaming the cofiguration. /// public partial class RenameConfigurationDialog : System.Windows.Forms.Form, IRenameConfigurationDialog { #region Instance Variables private ITextElement configurationName; private ICommand okButtonWrapper; private IMessageDisplay messageDisplay; #endregion #region Constructor public RenameConfigurationDialog() { InitializeComponent(); configurationName = new TextElement(configurationNameTextBox); okButtonWrapper = new ButtonElement(okButton); messageDisplay = new MessageDisplay("Rename Configuration"); } #endregion #region IRenameConfigurationDialogMembers public ITextElement ConfigurationName { get { return configurationName; } } public ICommand OkButton { get { return okButtonWrapper; } } #endregion #region IView Members public IMessageDisplay MessageDisplay { get { return messageDisplay; } } #endregion } public interface IRenameConfigurationDialog : IDialog { ITextElement ConfigurationName { get; } ICommand OkButton { get; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/ConfigurationEditor.cs0000664000175000017500000000750211544330406030300 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor { public class ConfigurationEditor { #region Instance Variables private IProjectModel model; private IConfigurationEditorDialog view; #endregion #region Constructor public ConfigurationEditor(IProjectModel model, IConfigurationEditorDialog view) { this.model = model; this.view = view; UpdateConfigList(); view.AddCommand.Execute += AddConfig; view.RemoveCommand.Execute += RemoveConfig; view.RenameCommand.Execute += RenameConfig; view.ActiveCommand.Execute += MakeActive; view.ConfigList.SelectionChanged += SelectedConfigChanged; } #endregion #region Command Event Handlers public void AddConfig() { IAddConfigurationDialog dlg = view.AddConfigurationDialog; new AddConfigurationPresenter(model, dlg); dlg.ShowDialog(); UpdateConfigList(); } public void RenameConfig() { string oldName = view.ConfigList.SelectedItem; if (oldName.EndsWith(" (active)")) oldName = oldName.Substring(0, oldName.Length - 9); IRenameConfigurationDialog dlg = view.RenameConfigurationDialog; new RenameConfigurationPresenter(model, dlg, oldName); dlg.ShowDialog(); UpdateConfigList(); } public void RemoveConfig() { model.RemoveConfigAt(view.ConfigList.SelectedIndex); UpdateConfigList(); } public void MakeActive() { model.ActiveConfigName = view.ConfigList.SelectedItem; UpdateConfigList(); } public void SelectedConfigChanged() { int index = view.ConfigList.SelectedIndex; view.AddCommand.Enabled = true; view.ActiveCommand.Enabled = index >= 0 && model.Configs[index].Name != model.ActiveConfigName; view.RenameCommand.Enabled = index >= 0; view.RemoveCommand.Enabled = index >= 0; } #endregion #region Helper Methods private void UpdateConfigList() { string selectedConfig = view.ConfigList.SelectedItem; if (selectedConfig != null && selectedConfig.EndsWith(" (active)")) selectedConfig = selectedConfig.Substring(0, selectedConfig.Length - 9); int selectedIndex = -1; int activeIndex = -1; int count = model.Configs.Count; string[] configList = new string[count]; for (int index = 0; index < count; index++) { string config = model.Configs[index].Name; if (config == model.ActiveConfigName) activeIndex = index; if (config == selectedConfig) selectedIndex = index; configList[index] = config; } if (activeIndex >= 0) configList[activeIndex] += " (active)"; view.ConfigList.SelectionList = configList; view.ConfigList.SelectedIndex = selectedIndex > 0 ? selectedIndex : configList.Length > 0 ? 0 : -1; SelectedConfigChanged(); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/RenameConfigurationDialog.resx0000664000175000017500000002001111544330406031743 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Private False Private False Private Private False Private Private False (Default) False False 8, 8 RenameConfigurationDialog True 80 True Private NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/AddConfigurationDialog.Designer.cs0000664000175000017500000001304011544330406032413 0ustar jtaylorjtaylorusing System; using System.Collections.Generic; using System.Text; namespace NUnit.ProjectEditor { partial class AddConfigurationDialog { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.configurationNameTextBox = new System.Windows.Forms.TextBox(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.configurationComboBox = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // configurationNameTextBox // this.configurationNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configurationNameTextBox.Location = new System.Drawing.Point(16, 24); this.configurationNameTextBox.Name = "configurationNameTextBox"; this.configurationNameTextBox.Size = new System.Drawing.Size(254, 22); this.configurationNameTextBox.TabIndex = 0; // // okButton // this.okButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.okButton.Location = new System.Drawing.Point(50, 120); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(76, 23); this.okButton.TabIndex = 2; this.okButton.Text = "OK"; // // cancelButton // this.cancelButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(155, 120); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(75, 23); this.cancelButton.TabIndex = 3; this.cancelButton.Text = "Cancel"; // // configurationComboBox // this.configurationComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configurationComboBox.ItemHeight = 16; this.configurationComboBox.Location = new System.Drawing.Point(16, 80); this.configurationComboBox.Name = "configurationComboBox"; this.configurationComboBox.Size = new System.Drawing.Size(256, 24); this.configurationComboBox.TabIndex = 1; // // label1 // this.label1.Location = new System.Drawing.Point(16, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(248, 16); this.label1.TabIndex = 4; this.label1.Text = "Configuration Name:"; // // label2 // this.label2.Location = new System.Drawing.Point(16, 63); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(240, 17); this.label2.TabIndex = 5; this.label2.Text = "Copy Settings From:"; // // AddConfigurationDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; this.ClientSize = new System.Drawing.Size(280, 149); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.configurationComboBox); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.Controls.Add(this.configurationNameTextBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "AddConfigurationDialog"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "New Configuration"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.TextBox configurationNameTextBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox configurationComboBox; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/RenameConfigurationDialog.Designer.cs0000664000175000017500000000637211544330406033144 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class RenameConfigurationDialog { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.configurationNameTextBox = new System.Windows.Forms.TextBox(); this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // configurationNameTextBox // this.configurationNameTextBox.Location = new System.Drawing.Point(16, 16); this.configurationNameTextBox.Name = "configurationNameTextBox"; this.configurationNameTextBox.Size = new System.Drawing.Size(264, 22); this.configurationNameTextBox.TabIndex = 0; // // okButton // this.okButton.Location = new System.Drawing.Point(56, 48); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(75, 24); this.okButton.TabIndex = 1; this.okButton.Text = "OK"; // // cancelButton // this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.cancelButton.Location = new System.Drawing.Point(160, 48); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(75, 24); this.cancelButton.TabIndex = 2; this.cancelButton.Text = "Cancel"; // // RenameConfigurationDialog // this.AcceptButton = this.okButton; this.CancelButton = this.cancelButton; this.ClientSize = new System.Drawing.Size(291, 79); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); this.Controls.Add(this.configurationNameTextBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "RenameConfigurationDialog"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Rename Configuration"; this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button okButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.TextBox configurationNameTextBox; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/RenameConfigurationPresenter.cs0000664000175000017500000000323111544330406032144 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { public class RenameConfigurationPresenter { private IProjectModel model; private IRenameConfigurationDialog dlg; private string originalName; public RenameConfigurationPresenter(IProjectModel model, IRenameConfigurationDialog dlg, string originalName) { this.model = model; this.dlg = dlg; this.originalName = originalName; dlg.ConfigurationName.Text = originalName; dlg.ConfigurationName.Select(0, originalName.Length); dlg.ConfigurationName.Changed += delegate { string text = dlg.ConfigurationName.Text; dlg.OkButton.Enabled = text != string.Empty && text != originalName; }; dlg.OkButton.Execute += delegate { string newName = dlg.ConfigurationName.Text; foreach (string existingName in model.ConfigNames) { if (existingName == newName) { dlg.MessageDisplay.Error("A configuration with that name already exists"); return; } } model.Configs[originalName].Name = newName; }; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/ConfigurationEditor/ConfigurationEditorView.resx0000664000175000017500000001737311544330406031516 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/ProjectEditor/editor/AboutBox.resx0000664000175000017500000014112711544330406022445 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 iVBORw0KGgoAAAANSUhEUgAAAHgAAAEGCAIAAAAhWcaAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAScwAA EnMBjCK5BwAAcQNJREFUeF7tfQdclFfa/ez/K/tlExUVmN7ovQ1D74Kg2BWs2CvYEVEEG0VALHTpAip2 xd57jzHGmF5MsokxdbPV/XY13//c9xleX2YAMTGJZnfy/PiNiATOnDn3POXe+xtZpew3v/mNCP/9v9/8 5j9+g4+i/xDhyf/7z//HnvzXb0T/yf7InuOvfiNij/8TiR6KRN+L/u/h/7EnDwTPv2fP2Sf/T/T9599/ //r3D28/nDFsRp8+fezt7f8f98D/zuiBb8l+hl/3A0DLK+WKKoWyWqmsUapqVeqNanW9WrNJo23Sardp tTu1VnusrA9YWx+2tj5qbXPCxuYUFydt8Nz6GPd5/G2ztdUuK6vtVlZbray2WFk1WllttLKqs9LkalSj VXJ3eW5u7htvvPHnP//5r3/96/379//3f//3H//4xz//+c8HDx48fPjwe+7xf7/ehwgoy6sMQKtqVAzo WrWmTqOp12gbtNpGrdVmDrhtVlY7raz3Wlvvs7Y+aG19xJpBzEcL1ta7ra12tMJaW6vV1mjV2WrlcKXM SVZSUvLJJ5/8C8LNgCY6M5RrWlCu02g3alnUa60aOHpusmKIN7UgvodDHEQ+xIGOANZ4AfDJvdZ4SYS8 ZlhXa7VVWvVStXKQUmYl27x58x//+Md/KbhFQFlRbQAaXFbXMTo/QrneyooPHnEQHPpAHOcRB8oIQE9Y Q0bwBS0aYsC6Uqut0KrmqxSRiqSkpBMnTvBw//3vf/91i4lIUalQVilV1RydazjR2GgA+hHERnAbIQ5d 3sWpSjOHMgVhjb/CmwDvho1WBqwrtNoNWm2JVjVFJfeRr1q16t133xXCDeE20u5fh26LFGUKRQXDmqFc q0Fo67QsNmrbBtqU4CQp4PgOK2i0AXGADugh2bQ8GmFdrtWWaTWZGuUwpcxW1tTU9Ic//AFw/+Uvf/nb 3/4Gdv/61kmRYo1CuV6pKlWpylXqSrWmWqOpYVgzzyAMIakfS3BICiEOYeGXR7we9QJel2m1pRy156oU YYrFixffuHEDcP/pT39qz5Y819QWKXIVijyFMk+pWqNSF6o1pRpNuUYLMa1ibgH+rFOIQ0xMFRz2A5IC oKEhvBVpaI11iVZbrNXkaZQjmSdpbGz85ptvvvvuO4JbKNzPuwUUKbIVyhylapVKladSr1YjNGs12vWM a0xMgTgMA2xDbec4bgQ3RAPSAROCANb88lhnxb4t9Bq8xv+oSKsp1KjmqRThiiVLlty+ffvbb7/llcR0 kXweqS1SZCqUWUpVjgpYq3PV6jy1Jl+jKeACiBdyb3AB4p3iuBBukm/ATSFIZ1phXajVrNeoc9TKOKXM TrZ79+6vv/66TSV5TqktUq5QqjJVqiwVcgr8nppVGuRyDGsebkK8iGMfONh5gpvCDUYT1rwVEfAapMb/ SLNGo0pUyf3lq1ev/uyzz6Ak5EmwSD7X1OaAXqlSZ6pZZKk1ORoWBHceB/fqFoKv0QALI0l5DMGNtJvY TcFjXdOiIRDr9Qas1UvUiliFVCa9dOnSV199ZUrt5y5xFwFlHmhNlsYQ2QK4TQm+joMbBG9R8CeDm/Id 0hDe9pFe81hz2oUiicxRtm3bti+++OJ5pzYD+hGdeaDpCcHdHsGhJ8VPoidG7AbKIDVhTbYPLxuwxsII XuPdQ1hDRvzk69evv3fvnpDapl77GV8hRYqpClU6w/oRnY3gxh87hru1fD+e3aicUPEEKFOYYr3uEdbq RWpFFDPab7311pdffskbEr4E+FzIiCggIEBqJ5UHyxXDFKqZqo7gFuqJkXzz7O6MmAipTaVBfDTFGgsj mZ8CDRYP5WClVCk9f/48qA1DAq9ttEI+425E1NDQUFRUlJKSMmLECD8/P7mnXBmrVE1WaZa26LURwTtg N2k30mvAjSUO1tso32kvpQTKFJTO8BoiwNog2fayffv2ff7558+djIi2b9++c+fOXdwD7rWgoGD69OlR UVFyN7myjxKlH82KthA3hbuFfcyZkPXujBEkC0hKgsATI702wnoy6yEggYTzwwpJMkIp+zNeihLt37// wIEDBw8ePHToEJ7gAco0NzeD5jNnzmSIe8lRRFbNMlEVXklMrfcaY9/dKWoT4o/FeiYr+5WVlX366aeQ EXIjqEaZSvYztTyKUBQ+efLkKe6BJ8ePHz927NiRI0cId4AOjk+cOFGmkSlCFaqxJpLSgXCTkoDaXNnk MUk8L9yENZVVSUOQNLaYEIMVmaeSB8rXrFmDZk3Hkv3sYC26zD2uXLmCj8gOLly4cO7cuTNnzgB3vAY8 6DCzqEIMGDCAEXyYUr1A4FKMXKAwq/wB1CYxwccOsVYvVOOFz87O/vjjj4WSLUwgn6nlUfTaa6/dunUL H2/evPnqq6++8sor169fv3r1KnAH6FjlATqYDsSPHj0Kmq9bt27s2LEyZ5myvxIVzlYJTnuOW0ht0/qU UQGWqE3BY13Kqk6teL1ao05TKyIUK1as+Oijj+7evQvnxyeQvMt+drAWocHxXsvj7bfffvPNN9GrBvTA HQXil19+GaCD6UD87NmzoDm0BYhXV1djzZTZy5hFmcPBDV53RrV5Q9JBvbs9rJHI8EsungDrdDW6YkuX Lr1z5w6/PPIlVn55fBZa7KLftzygd3gb4if+8MMPgfw777zDgw6mg+bXrl0DzXnEwXGs/rNmzWJw91Oq 56kfYd0etcmQtFSmOlohQXOCG0+I1/hX4LUQaxRh8jXqDJbOZGRk4Cen5ZG3IsLs8RfHWgSThDcdbCme 4KeE3oEaAJ9A/+CDDwA6Mf3111/nESeOQ1Wg45s2bUKnVeYiUw5Rqhe3lKWMsOZrgbyMtGn+2uzjcNxn yymwLtFqkDTyvOaxjlQsW7YMFMFPzlsRah08I7wWQdeQZcEh4SOewy0BdEDPgw6mQwSJ5oQ4hIUQxxJ6 8eJFLJ6QlNra2smTJ8u95aoxnJIIjbZRWYrSSOQ1cCOPlWyCnpvFeYQ1b645oBmvoSERiszMTDBDiDVs 3zOCtQgvO/9AUguBMwKdmE40FyIOKccSCh2HpBDBT58+XVxcHB8fj0aJaoaqI6x5N9KmZLfHa+rLcE10 VrkmXvNYY20MVeTl5QFr3vaRxX4WsBbRD4EHyup4DtsPhwTo8fPxoEP1UF4gmhPipCpYSIWSAoKTnqxc uZIJ9yAlysqstE0ZjUmBm7VvqNb6WJdNpOZnFvBuQJGPN9c81ilqeYC8sLDw/ffff9awFqH0RQ+MweHR JuhgOtGcEOc5TjoOSUFdDY0+GBXSE/hCpPUzZsxAo4SVTdrHGotbq+Wx49a7EGtKZHixJvOer4HjlOvl VVVVHWBNnu9nzmVEtBzTAz8BHm2CTjQXIg4pB8FhYIng+MWg4KQnPNww3TJrmXKgEhraHq+fAOuWl4Ep O/QdkyG8CWkhNcN6hgqFmq1btxphLVwbf36sRUYvrBB0nulCmgNxXlWweBLB4VVgraDg0BMjuFFFgQVU BHKq3Y6GPDHWEGtK0GH4eBPCY52nUU1UocN7+PBhHmsqifyCWBsDLcTdlOY84pByIcHxa5CCG8FNYgL3 jYIJmlKqESqDWJs2JGH7hBa7PQ0Rkpo3fPzC2CIg6Hbi/4X6NXTsGcG6I6B50NtEnBZPnuCk4KQnQrih 3fCCyDBRLUHuruijYF6bB1rY/O0M1oIXwDDMBxOCTiMtjAJS43+hHKCcO3culmve8+EnpLyRGup8a+Zn 0OtOAW2KOOm4EcHJpeCX4dlN2o2lEskOqihwgampqTAGqiSO2tSmEWLNr41GPkRo+EyxhgnhF0Ye61yN eoVa0UuRlZVlijVfe/rZsH4yoAlxIcF5rwKOkJ4Q3CQm0G5aKskI0jqJ8qbMTaYap2JAt4c19NeoQcNj LVQVEmujhZFePHxnYL1AjeI1TAhebORceKthRaHaE2FNWw5+hgT9hwAtJLjQqJAZ5+GGmABu/GJwJjCC +D2xTkJJkOOgf8bcSJzyEdBCXqMkQv5aOIfWDqlZxkiVED6LEZCabeyYppI5yNDfwP+dak9U54OD4vsy P4MJ+VFAGxGc1xOCm8wJORPKdGBLYLqJ2ugqjB8/HrVWvMENAiKYjTLkMlyObpiyNEoXOyPWHKkZ1lgY pVJoF2GNFx5rCXhAfRkqhvzUWD8FoNuDm18qeeGGkiBhA7VRGgS1kdfMnj1b0VvBEkgjsaYcHeLL1Z4Y 1qZ5ecdiTd+QMtJVGizC6enpWCogYni98ZPg5Rcavp9arJ8a0DzcJCb8Ugm4SbhJSYyoDf+HgQ3URtSp Jlij9kSdMH56uAOsTZ01CUgLqfH95b7yyspKvMB4V0HKhEW+n8GEPGWghXCbKgkYBCXB25anNt7LYBm6 JIoghSpZ1cZwJbCG/rZH6pYaiKEMwjtrcnutSa2aqsLuApTRkb7y5poMn9HC+FO4vZ8EaKEz4eEmJcES BGqTasMDkCHBb45diMz2zeew5scqARYMHxZGXqz5bkBbJsTgrKnkRGUQntRcvUU5VIk0Fb4e64TQhPwM C+NPBbSRcJOS8Iskr9pkSGiFRPbIilDAGkALRlgNE8PV3DiOsPPSHtbk9ig1JwFpUWr1crUiRAF/idWY NyH8wkiFzJ9IrH9aoNtUEl61hTKC5A1Wl2ENXkNDhKQmseYFRNhRNMVa2B/gBYSUmiM1pibh9jC4gvYF 1mSjhZEX66de3vs5gBYqCU9tkhFKbSAjlNeAZfn5+YpgBQYbW/VhKWMkZ82T2khGhGUQ6g/w6aKA1GhH YFwCnWWkTrQwUuXaSKyfutv7mYBuk9qU2pCMIK+B0QbWYBmmNZgPQWWVLzfD7VGXAAICQPnZD+re8u0u ozoqantUb+JXRY7U6mVqrL1r165F6kTZOVaLnzqL+VmBJmrzJW8IolBG8KtSUoPlERMEimgFGybmsebd HjkQfn6sTax5AUG9SbgqUgsih0sXbWQYyIK/FGYx5Kx/CgH5uYFuT0Yoh8S6xC+PycnJKL8JSW0oW1dy qyI/HUljTSa8NjgQvjnAr4oc0ExA+ivnz5+PsiJlMbyzFrq9pyggvwDQRjJCboR3fuSy8WuDa9OmTcOZ CK1I3ZIuGkhNA6hCsTZKFyHrqIEIV8UWUrMUxkteU1OD1JycNdYJKjn9FG7vFwPaSEaEzo9cNrBGqxe1 J7RLDFgDL6yKcCC0KgJffti3LawfFazJVpuQGntkRo8ejeYAnDU8D5Wc8Er/FALySwJtKtlUisLvyWMN HyZzl7GpM37rI+3koFWRDrfged2mgMBWC1dFWL0W9cBmdNhq5EoQELi9n1RAfmGgO4M15vzkQXKDCeFJ TbYaukGbM4yw5gWEXxWFuSJ5aih1tobl5RqWl8PtGQkIPxDyVFKYXx5ofnkUJutGvMYIErYdMlIDaH53 KU9qfseRcGE0stVYFXmrJyR1tgb2BoUtoYBgQeZre8LmwI+pgTwTQJtaEdg+IdZQT0yJQFJp47Rh9wZP auHurvYcCHUGeKsnJPUsFcZ9MIhi5EAohXlaBetnBeiOsYYPwdAwjj9QzVYxoGlJ5KrVTKlpyyICMtIx qakAQolii3pgUhDTsHPmzMEcIRwI1ZtoVUT9i59QoI7XDyb1MwS0Kdb82kj+ur6+nmXnyGLQL8eSyCfl EGja/Ny+WBvmQIxITZOYWRrMHGO0Hic9YRic6k1UA0F5gGz1j+/CPFtAt4c1mAWswTLMQaPUyYBGRs63 BSAXRtueeQERrooogJS3DDeZknqgMjExEU2fjlfFH0zqZw5o07URvEYGgTwCOTrKQMxZJ6kMQHOlaqYe EA06T4s/psIE61akJk8tUA91MiM1Rusx7sPbatNV8Qfnis8i0EZYU95IOToyNwzVwe3h/W7Y+M8viXQq CLCmcxNMV0Wa+gWpTZWa27SKjB+kRpZEqyJf2KNcka9W/zBSP6NAm+aNhDWcAJJGtFlV8SoGdMvOUcOS KDx7RYi10OpRUk6JIu/zOKCZUjvItmzZgkEfKuyZ5oo/uF/+7AItxJrqIVRTxQIFbwBE8GZnQHM7B1iZ CchyJ5UZzl5p04EQqYWeGvaDy1xoexn2PmGKDHsYMF0vzBWFBZAfZj+eaaCNsKaaKrDGwoh0EXuEHm09 p9IHAY3zm/jz9tpTaiqfUkeRlJoDGscO4KDJPXv2mFo9vgDyw0j9rAPNY02tGeHCiNoeysqM0ZBpjCSg 0AHvwZ12yLDmD8oywtqU1AKggTXG9dLS0mDbyerxBZAfSernAGgjrHmxxqwTmrlgJe2nM3gPOlaSP2yv PaXGP6HqB+/zWtQDWxRwCDP2sMLqGeUvP4bUzwfQhDUVQ3ixRjkC1FMlqOjEISbTSAuhHnR+Jx0iSYej tklqlPRQOTFZEkFqvH5oXT5dUj9PQFMPjBpgqIQgi4HnlXvIkSsaJsdIpun4ZToclU7rbFOpN7ROXlpk min1CNXIkSOfLqmfG6DbE2t0ctGFeQQ0J9OG81GBNU/q1qVqw7Av+TwT9UAPHskLdk4SqU3txw/w1M8T 0EKsKYuBaGK9QrFJvVJtmEQgoOmwZQQEpD1SY34MyQtfO229JCr7Mp8HUsN+8J6aTxSF1Y9OlpmeM6B5 sRYKCPRUGa80AM3l4uwIWqC8nxOQDkgNcRcuiUL1mMYmfXG8AHlqPlGkpiL1BJ7I5z2XQPPTqnB7SBfx 1sY7HV6YOTxKW7Ae0hH5wLo9UpPPw5JIWSIVTlu8B1sSfdlpkth9TYkiNRWNSnqdT16eP6CNBIRSGCg1 2gKGdi0BjQOs6ZB23PJApDapfjClxpLIlz5aA40y4bhx49DlouoH6lnUKUdti+rU1HzpZJnpuQTaVEBQ 24T90K7lrn4g40FA0y0PROo2fR5at3yWSOl4y6lo2ISLdiI6L9jjDntDozaoU/PzY9R86SSpn2OgeQGh FIZ56ikqQ2GaHB7drgGs93GkxmtgSmosiSh98OohAJpliYHsxAScBQNSU52ab74YJS+PXRKfV6BNSY2T QzCJypZE3koD6KPcHSZ4AlKjfModQSac1aONRoatzlShFsg0aoSjRo3C5BhOEjDNyJ9oSXy+gTZaFXFg iCpFZQz0cY7XUGpUP0yTF1oSeUPd2uSxwqlGhqMBTX2esMvVGfV4joE2XRXR9EOblc5gZ9IBdT7GrkKy BtYHudth2lsSST0oc2mtHkjHoR5YEuHz+CWRpk+fSD2eb6CBNZ+XY2nC749GF7yaodxBQOOqqVM2TEPg qWlJbFM9KHOhqqnglFB4D+ysxv594ZJIE5HoQnS+8/LcA01zwHyxCexD+c1wZwakGUDjWq8z3LVeB7gl 0bTLRerBZy5GMj2TZS7YD4olkVq31HkxyhIfqx7PPdDCVRGkBu8wZG69jbt9hwf6HMOaKTWWxDbVA96D Mpc21cNTjoNHkCWi9MFniW0a6g68x68EaCGpUXjD9OIjoE/b2JznAqSGz2tPPZC5UNXURKZxGC6OacXh ipQlokcuNNS8enScufwagDYiNY6vRZGaJd+4MA3ScdrG9ryt/Xl7RupDLephtLMc6lHJHRbZlkzjfIB+ /fqhz8Aban6aiUb0qMbUsXqwo34ea7af/S8QKjXe3ShTMOOBVAVAn7GxO2/ndMEJcDNP3Z56GJk8gZvG yLpMy7rjP0Y9fiVAE6mprwh+IcuAS2OifJwBDTq7XnQF1mB3R+rBm7zW6yEVmHJyckg9aMLmSdVDBGV5 9gnbmZ+QSE3lU6xd2CdAJtrmnA0g9rjk4X7RnZGa1ENo8gSncrYr0/2U6AWTeph6D34+rwP1YED/OtSD PDX5PJQmMA7JLm6FieaA9rzk6X3Z2/mCs0E92qx7VAlkunXaoprAOrbYfiBUDxTzTDOX9sBk5979aoCm Bi5NJfTt2xclUGgF/AZ0Ayj7XfED3GxJRDrenskT5uKCtEWdopaqpDgWijIXTK2js4MtkZS5UCuAr5q2 +f4TUUW1M+/NZ/9rhEsiinlAh1ZCt4tuvld8g64GAWvoNUvHjUwerx5CmW59iwSumcAOaqgHqldQD9NW AFVN21MIUQd/9+wja/oT8qQG+5A9QzeALATa/6p/2MthoddCATrUgw00mcg0OzUIbprSFpP1EIM18+bN w1n81AowrZp2bPIY0L8y9aAlEe9rtAJsDjOB9rrkBTr3ut4r8nokqM28xx5rVp42OaeJuWkUPdpKW1Rx KtygApnmq6ZooWHi1DRFbFOKRU/Uj3kuOM4viUOGDLEtt4VA6y/rweU+1/v0e6UfnjDvgRSxTZmGm6at +ib5IcbPwsLCMJbHmzz0XIxkmu/YmgIleqJ+zHMBNK8emO61WWRDugE6D7gxYMirQ6KvRwN6ZvIg08KG Cy/TtB6ijNfaeOBcRKyHuB6XN3k0MCbs2HYg0+z86I6Xy+cCXOEPyRtqgKIdoYXfgG4AX6A8/LXhg24M gnowmW7PTXewHrqx69F+mEyLOlkTeb7gJvWAMVD5qwAr5KLvK33jbsYl3EoA1vgjZJoNjD12PWxtPODN YWaEMk3zHiTTwj6AqUyL+JoIfrJfmaHGG1kql/ru9o14OQK6MfrW6Em3J417fRzEGp6P9QG4m9CM+wBY D1HGI+PRGmi0b9At27t3Ly/TnXfTIjpn71e2JPIyjeaIvkQPZIfdHDbh9oTENxOnvzl96KtDmclDHwDr ocm5hWgCMONBhWlBaYkNP45WDR48GDeKkZumaTHTokebqYmImoy/viWR1GP58uVeaV6g86hbo6a9OW3+ 2/MRY18fy2T6cDvrIZoAMB7k8IyAnq4KCQnB7W1ouPBumm+4CJE0TVtEP2zu5tmXbCrm4RBUt3FuoPP4 18fPfmv24ncXp72XBlKHvxyOehPri3dgPEwcHu6NcnV13bFjB2Sab9di2AOHBfHnT7SXtoh+2NzNcwE0 EjG0rh16O4DOU96YkvJOyor3V2R+kJn8djIMNbJzlh+2CTS1tUwcHho3aP7iLJX20hZ+PTTNAUWoPwmP Aun8MNkzjjWZPBR9tG7acTfHzXxzJric+2FuwZ2CjPcy4ECwHrZtPHA3Bjk8U6BRmHZjt84ZrYfY54Kj xvhBU1rwjJyFqM1hsl9HmYlkGteOJhxPAIvB5fUfrS/9uDT3Tu7E2xNZ2gLjYeTwKG3hKx6tcxbadYGD tbAe4u4CmqqhJgBfxiO7bLoeivjDyH7MTphnk90k04MGDUrYlpD+Xjq4XPn7ytrPaks+Lpn15izk5SwR N3J4BDSGxPjSkpGVjlBgQB3roTA/5Cd66eQJ2g9gRFYR706Ei+avQ0DI5OEswZFlI3M+zCn7pGzT3U3b 722v+6wu7d00pC0sEW/T4cFKtwM0WWmMmArzQ+GkB2/hjIGmRZM6BeSpf8AGjWeW0QAa7/S47Lh1H60D vrvu7Trw5YEd93YAdyTlaMG0a6Xby1nilMOHDyfjQd0WzIl1xniI+BP2nu7xFM8I9KBVSUnJwAUDK35f sfXzrYe/Onzym5MHvzxY+FHh4FcHM4eH0lIHOYtJcohBBoweYOyRNx40UkNtLd5WmBafRXREp/DUt18T qQE0Skt9J/et/6x+35f7Tn97+vJ3l/Gx5tMaZOSs4tEm0LXcIG9bWTjmzXr16gWgYTz4tlZnCtPsztmf 4niKZ4TRkGnU6SPiIyAXx78+DpQpwO7Jtyej/8JyFpOD1jE0zYZp2gQ6SYUr69G+ERamaSdzxw5PhD7Y T3po0y+LOIBGIzWwTyDk4uIfLvJAg90wHuhysWJpW0CzmUdk4SbSoZ6r9vLywpkhvMOjIbE2G7VCKy1S qdzw+gg3Pf+aVkX8qrAE3kHeJBp8QKlT30nF9AFLDk2vDkDzsD2gF6pdXFwIaGGj9rGlJZGr63SUuPCy GB3aROXTZ62qB+Ae+zBqAiCVcPVyFaKM52D38veXY6SGTae3CTT6LFRXau2jcXWznZ0dgG7TSguHpo1y FlFQUKODQxxuVjI6uPonOgtViALeOlhGMPuDsTZMJuLSWNwWglcdKQYWHH9/f3d3d3t7e41Go1QqZdwD T/BHfBJ/hS+IiIgYOHAg/glO7oeNQ/sDF+Ci3AMrhd8ZKyEe+L/YOdpd+sMlYQBrpOMY82BZeFuXYbDN Fm0BrVmq0Wq1WGDbrOHxzo3vafG/L4De5OdXaGPTCyk87cUVnvr2tI6NxPeBB4IlwvWZOEw4Li4OMLk5 OfYODUoYMmD+5HE5C+ZsyFq6rajgaF355R2Ntw/tunP64L3LJ//4yvn7r1/9x5vXH779CgJP8Ed8En+F L7jd3HS5ofxoce62zEUbkqdnTx41L67fmMjg3t4ebnbWSL7xP8LEbY+ePfI25TVcaDjxyYmL31xk8e3F NR+u0V/UM0bzJ4kJdgK0C/QKjUqlAtDt5SxGxdJWQANrnW65Wu2FoiK1DExPvufvlOrk4oZWJN4i4BcO UIPDt7HSRoUETRsVvypl7ua1ueeaagHTP958+ft3bvzYuH3p+1dOPbx08OHpnQ+PbX64v+bhzpKHm1f/ vXr5B7mzz6aMbZwwYG6A0/hgt1AXrUohjhgUMW7BuKUblqY0p+hP6bXbufMnEEZXcGHzYZuMztTI5XIA bVosBUFpG0CbySEYvZmLTR4e8xQKWwh8myffd+aEPbyYGJcCZ6dMmWKt1faLjFgwZUJl9vIzm2s/u3Ds xwLawUvy1svf3zz3/bVjD883Pzy+9eHB2oe7GNYPalc+qEh7UJx8d1H8/VXj72eO/nDBgKMTwksG6mcF O0Y4y83Ev+0S2aXnqJ7ShVJVsYqudGYb6Gqt2C5PsneZXAiUGgoGrTNNDoVbEPmqtJDRTUFBWwhuF5fJ uL8K8078NSWPPfkeSxPc4YYNGzBs6exgP3JAP3B2X2Xxh6cO/oTImoL+9vXvb138/vqJhxcPMGofrn+4 p/zh1rUP6nMeVC29u2zc/TXTOKxH3V867G9LBv4tNfZP8yOujnOtitXM9RNH2He1sPzvLmFdzMeayzJk OA0LPlqdp1ZnqzUrW7AmxFGS5oCm5JCfeQQ72yz/PwI6OHhrUNAjrB0dR2FFavPke+E1JVgq8f/Azhz8 X/tHRiyfk7i3fP1HZw7/rOAawf3mte9fO9+C9Q6GdXPFwx1FDzfl381Nul82//66xPt5k+5nj7m/LP5v 6YP/lNL73hzfuzM8705xvTvJ6XK8bWmUYqrOXG/14n+a/Uf3vt3FE8XKJezONBYrWTDQVzLpgCTCE1MW Thtb2gOat9IiAC3Aeou/f5W9/WAc88uffE8rKRVRQXB8d7TcHexsxw0bVLpiybXdm39JcAlrQAw6v3oW KH9/5cjDC/sNen2g9mHzhgfbCz9fl3K/Jv3+hpT7hbPvF0xl1F458i/pA+8lh9yd5XN3Oof1RMdPJjjc Ge/w/lj7plj1Qj/LSNuu3Xv+d7eQbpajLZWLlLgshyG+VI3FEAc+Amg+C8emWqNyh2lDC0BvE2DNqO3n V2JnF4v7q1CUotMMgTXakVjW7Gxtxg8bUpm97PWDux68xZzAT44yFkzG05MGBM/ueXh6x8MTWx8e28Li 6KaHRxsfHmlg/EUc2vjwYN1Dhm/Vw70bHu4qfbij+J9Na+6tT7m/cfn9qsX3y5PvF81mMpI74S8rR3yR FnUXWM/2vztDd3eKG3jNsB7n8G6C/dtj7N8cZbc7VrPYTxxl07V79/82CzcTjxfDR8Nf4jharIfIWfi5 Ayp3dFBXEqGra4J1k4/PWhubKJzJjj4CblMXi8WDo6NWL06G8frra5f/fht+6+V/tliup4D1q2fZOgbU gE5TwYO6TLaIlSQ/WDvrwerpD3InP8ie8CBz7IOVCQ9WjGaxfBT3ZMyDzIQHWeMe5ExgX5M39UFBIvsn 6+c8KJrH/nnpwgfli/5RmnovawqDuHT+/eK59wtn3V834/7qKX/JSfhiWb/PFwPrMIZ1kv7uNI+7k5w/ neAIXr+XYP/WKLvbI+1ujbB9dbjt5hjVHG8Lf+1L//nSf1haWq5atQq7dOHwKDmkdI8vd9AhE0YFPFFY 2P42sXZzy7K01Fur1bPGjd66Pv/Tc0e/uHzy25fP/OnVC3+7deV/fwTWzIqBdI25D0pTHuROebBsxD8X Dfzn3N7/nBXxv4mhf5ke8sdpwd9MDfpqatC9KUH3JgfenRT42aTATycF/n4iCzzBHxGfTw7E3345Jejr qUF/mBaMf/XXGSF/Twz5Z1LoP2dHsG+4IBbf+f7CQV8kRd5fFnd/xYj7WWPu5yTczxmL+EvWyHvLYj9P i/48NfJucujdOQF3Z/owrKe4fDbR8aOxDh+MMWD92gjbG8NtX463vRZnWxQmG2PT01NhiWIp3uJ8+Z8f 8MC7n59LF7ZoRRERxzisdxOvAwO3eHvXubiUuziXujhlaJSBq1PnvXVkN1wEsP7yyqk/XD/755sXeaxJ QDrWEMbW7YWMX1njOEwjAQdwAUbA6+OJAXfGB7w/zv/dsf5vj/V/c6z/Gwn+txP8X0/wuzXG77Uxfjfb Cnwef4uvQeCL8a8Q+OfvjfP/YLz/nQkB+Lb45nglPh/v+0Gc03fT/f6a6P+3pKC/zQn/W3LU3xb2/VNq n88Xht5dEMYYPT/k7twgxmtgzSTb7e4Ep0/GMazfHW1PvAbWAPrKEJsrsbbHBriuDLDpaycLDw9PSUnB ukXlf3J4lLPwDS1aDwH0SQ7rA4GBO3S6OgeHYne3Ch/vmiC/BoTeM8taHZKfMvfto3vunD702XmG9XfX zz0Ga6B/bPODmmUPciYyZGeG/3l6CMEKCIApAQqAhFC+Otrvxwf/qtDLgNfs5nCvKwMc3hzr/e54/QcT 9B9P9Lk72ffLKX5fT9PfneIE/jIWQ6MhHRR4znjNsP79WMc7CQ7AGnptwHqozbX+dreGe96M97gR71ka 7pDgprKRWi5YsADlaagH5vDoKHWsh8JzlwD06dDQoz4+u11cNuo8N/rp64P9N7VEY7B/o94zx1Ybnj1v 5jtH93505tDdC8e+unqasEY2TBpCvH5wZjeT1+wJeM/+IzEUb2e864XI4jfnGfrjMe3kd7gy1P1Mf/vr o7wQN0brbo7RvZ6ge2Os9xtjPV4ZY3trjN2bY+zfG2sPXYZiYD28O9mFoTzZ7e5El7vjnT4bx7B+fzST kddH2r06zPbVQQ5vDPd8nWHt+epwr1fiPRuinWforD3UMpSM0BpHmQX5Id2aw9/FIPLzO+TpsdNXvyck cH9Y0N7QwB3B/puNsPbV5dtZRWckTXn3WDOw/vzicSHWf99T8fd1s/938eB/zAwDuJBOgIu38FucCPDg dhKXp/5lFwe5nhngeG2kF8XLo1gA9CujXE8Ptz4XZ30x3ubKcJvrI21vjrJ7A1qRYP/hOAfoxqfjHIEy gnj9wWj7tyEjcXa3Bzu9M9LrzRFer4/wwtvlRjyw9ro+XLc91m2ur63eSgHtxvLIV+Xo5i2Rn8+BsOBj vcKOR4QeDQ85FB7cHBq4MyRgS2u4N/npC+1tBiRPTHi1eSth/WVjwbdZk7+b1+eP04IYuOMBrh8Dd+wv D67w1To/wPncIGceaP7JhREux+Otjg21OjHU6uRQqzPDrM9zoF8bYXt9hO2tkbZvjLKDaABfoIz4cAzD +p14+3fjXO6M9npvlO7tUbrbI3S3Rni9Olz3ynDdy8O9rw333tnfY66fvY+1EudpwfNBrOFAQG1Rr7BT XJzsFXYiIvRYeMjh8OB9YUG7QwKajLAO8K10shs+pW/EmdlxH86I+ni8/7vjfN9I8Hl9tM/N0b43mcL6 3mDhh3jqxPzB3/BsP8cLQ1xMgT433PnYMKtjQ1piqNVxDvHTQ63PDrO+MNTmSpwNnAa8HRQDugHQWcTZ 3xnu+kmC7s4Y3fujvYH1W6N0r4/U3RzhfWOEN8N6hP7KCP22fh4zfe3ctYri4mIkIpARHmjC+iSwjgg9 Eh4MGQHW2zisOSXxawjWVQd7bHBRDZN16VnTy/F8nO5CnPfFeO9Lw70vj9BfG+lzbaTv9VG+r7B4hrA+ 1df+4jA3U6DPDndqBTSP+BCr40OsTg62OjXY+uxg6wuwGcNs4DeAONbD20Ps7gx3+zRB9/sE748T9B+O 8X5vjPfbo73fGKW/NUp/Y6T+5RH6qyP0l4frL43Qb+zjPlFnZ6uSw3QLgeapDRk5Eh5ykJPsnSG+DcFe VcHuZUFupYFupQGupS6aCXIzzQp/qyODvU4O052J051ncON/AKx9TLEmjvPBvRIs8JUvj2RxdaTvlRE+ l0f4XBzO4jwiXo84F68/G6c/Iwj8EYHP0xfgK/H1l7h/i++AVxrfDd+25Wdgb6/j0TaX4z2ujvRCCOE+ M9yhbaAHWx0dxOLYIKvjgxjip4WID7B5O97tzmjdR2O8P0nQf5zgfSdB/0GC/t0xPm+N5t7co3yuj9Rf Yz+Snn6XwkjXoW7WAPo0Jx30USgjR8P994Z5bwn13BjkXhXgVh7gWubvWkrhbjNXbe6Z5K48MNDz+BDd 6WG6c/Fgt/7KcIY1Ufv6KL9XRvsJMcXnAQf97wHW6Tj9iTjvY8O8Dw/VHRis28/FvsFewmge5GUURl9A /wr//NAQ3dGh7LudjPPGa4OXgb1s8boDUVYXh3teGuF5eYTnFS4I9JPx9keHCqSjhdFHCeiBhgDcPOJn Bluf62uFMXashO+M8oJ03Bnj/VGC/qOxPh+O9Xl/rO/bCb63x/i+NtoHvzVwwMt/gSMNfk0CunWEnuoV cKiXT3OE984w3fYQz81BHhsD3asD3Db4uZb7uZZxUertsMJG0iveTlId6XR0iO4UqB3vfSFefwlwM51i FLs8whd0I1hPxemFmAIvQnBvS+wZ6LWbi12dCPpK/BME/x3oG9IrQejv7efWFGF1ZKj7sWHuJ+Pcz8R7 nBvucXEEw/14nM2RIdojg7VHh1hRkF4bAS1EHAQ/Ea29OsTtRpzHa/Geb4wE3N7vj/H+MMHnzljfO+N8 Pxjn926C31sJvrfG+N5gWPsS1vj1WwMNiP0P9/LZF6FvDvcGnfeEee8K0e0I9moK8mwI9Kjzd6v0bw23 o2qErKt8hb81ZOTEUC/AfWoowhsfjw9lVD04xGvfIF0z98sTrAQooblzgOeOAZ7bBbGtvyfFVpPg/wpP hP8E3wGBb0Xfk14AQn9rtFNDhNWuga6IPQPdmge7HRzifnSo+4k49+YhVvsGaQ4M0h4arD08WID4YKsj AkbzQLMn/a2OR1tfHup+daj7y3EsYXlthNcbI73fGe39XoLPh+N8Pxzn9+E4ZKdwX36vj2HuAFIGrEG1 Fo02hhgoI5pDdXtDdbtDvHaEeG0P8twU6FEf4F4jgJsR3M16jtpcN9FZ3hDjuneAx66BHrA47NfGc/bL 4wnCaycHKwFkwLGf59anGNzLw78ABH19L7uNkbbbBrhuH8hiB4c4YsdA54b+qi2xqu391Lv6q5sHavYN 1BwcxCE+SHtkIMKKohXQ/axOxNheGuIOrK8M87g2zON6vOdNOLyR3m+O0r+bAPVgQH843h/Z7zssjWD1 A6gosOaAJqHQ7+VYzCIUoWNAU/Bwc9RuBLUfwe0GrMu9nXJtZP0tXuqxUK9t6OPaGOu2ua/75lj3LbHu m/t5NPXzYB9jPZv6sXia4Hbw3bg3RGWIVV1v+839XZoQA1wRWznQN/W3r+6rrIlR1sYo6/ooN/VVbY1l iO8doNk3QHNwgPbQAO0RCiHisVan+tgxoBnWHleGelyN83w53uvGCN1rI/W3R+nfGuP77li/98f5od7y PuwvV2lAMgysRb18m3sxiKESLAhiPhjKLRGi2xOi2xXMqN0U6NEQ4F7n51bj51bl61rp41qBcNYmKXp6 xNlJ80MdqqJda2LcNsa4NfRxb+zrvqmvx+ZYjy2xBrh/Hqzxohb6yOtiHBtiXRr7uWzq5wLEt3Cg18Xa bIhRVvRWVkYrq6JbI95XvStWvaefZl8/zcH+2sNCuPtYnY51aAX0MM+rcV4vI2EZ4X2TOTyfN8ZgSfR7 lwmIgdfAGoUXUbj3rjDv3YhQoKyjaIV1C9D7Qr0RzYA7WLczyGtbgOcWf48GP8DtXuvrVu0LxN2qdE4F 1rLBFi9JprmpKnu7Vke71sW41ce4NzK4GdaIn43ajTGuJQEqoCwMQryyr7Y0WlEWpSjvrdzQ24B4NRCP VtT0Vm6MVqIAvb2PGoX/5n6aA/0NBD8crT3T3+niEHdOPTygHleHeV6L87oWz9LCV0bqXx2ph+WA8Xgz we/tsX5gNOCGhgBrUahue6j3TggxF62wDtHtRTxiNFD23hesQ+wN8tod6Lkj0HObv8dmP/dGX7eNvm6A 2xCuNgvVlkGRavNUH2tQuzYa1HZvk9o/qZLURTqWh2iNgKY/lkari3srSiIV6BMieMQreyuqohTVXNRG KRujVU0xql191XtiGcEPRGnODnC+MNgNQF8a6nF5mOcVDuiX43XXh3tfH6G/Mcrn1VEsT4bruD3Gj4Ob lSoRomCvLSHwcLodobpdPNacSjCUDeHdDHCDdfgIlPcHGaI50Gt3gOeOAAb3Fj/3TX7uDb5u9RzoG31c axzUU2TdXQbbSDID7Wqi3UypDSXZHOtZHOWWFeacEuAwTW8/ysNmgItVLweNv63K00rlpFbYKOVquUyB HrBUisAT/BGfxF/hC/Bl+GL8E/xD/HN8E3yrkii3LZx2V4XZVobbmAJdH+tcHK0silQU9WJRHPkI8XJw PFJREamojFRUI6IUNVHK+mjllhjVjhj1nnD1qQEu5wa5XRhiwPpKHJMOMJqAfmWkz42RPjAbwPq10b5U pwWdUQISYWWDnQj22gZrAaxD4DEYyoZg5NXtCfJiwT1vDtLtA9DB3gcQHOIM7kCvnRzcTRzBgXgjhbdz ka1ipKSbdoSDLC/EAdReHea80N9hks5ugIs20FbloFI4OztjaikmJgZTRRMnTsRw16JFi9A/w7HvGBHB IANua6qrq8NwDx5o1uEyicrKSoyXYw42KysLnWJsKsEkCcZ0cLxPYGAghhAdVYogO3WoovsYN+XCQNuC Xg5CuGv62hf1VvBAE9wIEJxFL3lZL3l5L8WGXgzuqha463opt4ZrD/dzOTHA9cwgt/OD3S8SqQE0V1Hi gYaDfnUUwxqWgy+Li+CLA9xr4SWCPbdioQvR7eSw3h1swHc3oRzIRRDDGsFjfTDYG0GI7w302tVCcCAO Bd/McPfY4uaQp5IO6fI7qaKnmaWFOTaf4iSNqVOnoteOOTRs2wN2GzduBIiAEp18PFAcwAPjE+iB0gNz haYPtKLxMP18eXl5cnKyhcQCc0k+4T4WEnN3rSTGSTlRp80ItlsfZdUm0AzuCEVxhBxYl0TIyyJawx2m aAiz2tnHaV+s85H+ricHuZ1lWHtejvO6Gq8D1gD6+kgfRmoOaPAahTBgTc0gEXI8+LMA92p45CDPLaB2 kNeOIK9dUGEKjrAGoNvB+lCwN4IQJ4Lv8vXY7u2+1dOtyc21yd19u5fXThcXbAsZZWFhN3ToUOwcrqio qKqqAsRgKyBGA59HFsABPkyoYBoID/RAMVGIB7rO9MAQeJsP/gvwxajB+/fyz67PRmTVZc3JmTN69uje cb09AjwU8hf1Ni8Nde0+39eysIXOBl5HKIrC5YhiLgB3aQvcFSGKhnCbbTGOO2Kcd/d1PtDP9dhAt9OD Pc4zrHVXh7PSHQN6FAOaYc0BTVgjCGgEsupKf/daf49NAZ5bsdAFee0EXlwQ1o/gbuE1ZIQ05FCI/jAi 2Puwv+6Q3nO/p3uzp2ezTrdfrz/g53cwIOCQvz+LgIDDXl4bbG0nisUumALFwSUgMlhM/AW+ABewEpSY mkAvDt1PPDDsgH4zHujK0wN9fqMH/1f0lTihNG5q3Oqtq1c3rc7fkp+3OQ9zjrmNuasaVmlSNWZDzV4M ePF/bP7HRvFCpH3Xad7m+WEyjtEMZRZhLAhrA7sDFQ297JqiHZFtbu/jtLOvy95+LocHup0c7HF2qNel eO8rwJqRGksiAxoVY2FpV+TrUuzrWuLrUuqDcC33davxd28M8NgCzYUOtId1C7UZ1kHeB/y8Dvh4HfLy PKzTnfD1PR0QcCY4+GxQ0GlEYODJwMDjiIAA9hERFHTCx2eTg8MchSIgMjISJ0JBPQAxcRb4EqxowWEO CPNQeGASF9O9aOzjgV4RHjhR0ehBn6evwRf7+vqmrEkp3FO4fvf6dbvWrdu5bu2OtQXbC+bWz5XlysSp YvFcsXi2uOeInl0jur7g/IJK9j8Rdl2neZkXhD4C+hHcQNxP3hDpsKm34+Zop60xwNoZWO+OdT0wwP3Y YM8zQ71QMb4ynJWLoR6M11xpHs9hBFETF/m4FOudi31cSvSGKOMc8UbIaztYP6K2v9devcceT/e9XgDa 5yiH74Xg4EshIZe5uBQcfDE4+Hxw8LngYPwVC0IfT0JCzgQGHnZ3z7KyGmxhocJFHHTYGXgKZAlWQInD 9TFzhS3dOJgLQ4HYqYouET2w+4Z/8J/EF+DLsH56+XuVHypHlB0sKz1QiijZX1LcXDy0dqg0VypNk0oW SCTzuZgrYYiP6tk1tOsLdi/YSl/oZ2+W7GNJKBsiRF4eqK6PcmiIIqydt8Y4b+vrsjPWdXc/t+b+HkcG e6K8g3IxKtGokV4f5QNDcn6gy9He1qdiHS8MchfpnYsQ3s7FCD1AZ3CX6l0qYIrhH2AkADdMhZDaAV67 fTx2e7nvdnPdBX3w8zsSGHgiMPAUByLQPA+IQ0KuhGLLJIurXDDcEaGhF1riYmgo4lJY2BVf33onp3kq VQgRnC6pAl6EJgau0MzHEDAeGJ/AhhGMBmJgxeiBT+KBv8XXwLcMmzSs7kxd3em62lO1NSdrqk9WV5+o rjxWGVATIM+XY5JRtlgmXSSVpkqlKVJJMgf3DLHlRMsesT1e0r3Upft/+ahfGufWIz9EBqwLA+Ubgq3q Ih02Rjo29HZsjHbaEuO8tY/L9ljXnf3c9vR3R5Hn4GDPE0N1UJITA5yP9rE/GmN7pr/zxSEwf74IAF3o zQJYs2jBGnCX+bgi36sXUtvfc5e3xy4Pt12QYOivvz9YfAxBmsCpBOAGWxnWwDcMZ82FvRIefoP7iLiO wCfDcYyDICIiXunV60Z4+BW9foOj4wyl0h9GDasZ5BuoAT403zDchsEJjLliPzAeGOLGA+19/kGfwV4S PLBnIL04velq05YrW7Zc3rL58ubGi40YRK86W2VfZ69Yo5CvlMuXyuUZclk6Q1y2SCZNlkoSJeLJYsx9 iceKLUZYmIWaveDwgq3shcGO3dO9xJWhNrW9HDZGOdZHMaAbo50Z1n1dd8S67ezvDiVpirLfFG7dFKZt jnY41t/9/FDvS3E+V+J9rsb7MKBtFcO8nddzYQr3I2r7uDfp3La6uW7T6Zp9fbG+AWIKBjRhDfHlgikD 5AJYh4VdBbIREa9GRLwWEXGrVy8+XouMvBkZiY+PIirqVlTU6717v9mr13U/v1onp8kaTTBOQEtKSoJr xuQ1htswGosH5lRwNhceGJjHFhWjBwRdF6ADvrtf273r5q6dN3fufHXnjhs7tl3ftvDkQnWDWrlWqVil UGQpFJkKxQqFfDlH8FSZdKZUmiiVTJZIJkrEEwyI9+jb4yWXl2Qv/vcwB1mmvw2yTWDd0JsBDWpv7GVX G25TFaypCdY0hNtu7e20K9Zz3wCvo4N0p4Z4nxumvxjnc5nDWtT9f16wksZ4OqxqC24m3F7OZe7Olc5O tZ6e23x9m/39mYsICDjCBQM6MJBnNEh9Ijj4ZHDwKU6Fz0EcoAyEda9er0dGvhEV9VZU1NsUvXtTvMUF nrwTHf1uTAzivZiYDyIjryECAzd5ei61sxuhVHrGxsZCWOALId/oeGKiEGNBeGDOHoNY9BEP3FGWMCvh wDsH9r+zf9/b+1i8tW/vG3v33t476OggVb1KWaRUrlYq85XKPKVylVKZo1SsVMjT5LJ5MtlMmXS6VDpV Kp3CIT5JIpkgsYyyRFaFoSRrcc9BttIMb9WGYG1ZgKrET7khSFMTZtsQ6dTUx2NbH4/tsZ47Yz139/Pc 28/r0EDvE4O9zw7VX4jzAbVFWUF2fa0sVRYBrjapLVgb2O3pVOTqWORgX+TqWqnT1ev1W319d/r5AWuI BsM6MPAohzLRmWf0yZCQU1ycDgk5GxZ2Pjz8UkTENYgD+AvCEqDR0e8DTUSfPh9ycYeLj7j4uE+fT3r3 vt279xsxMW/FxLzTp8970dE3Q0K2+/hku7pOsLYOlkhkMHDQYqSOWD8hLJgPwgOTK0gR8xrzjn549Oid o/h45IMjiEPvHTr47kHvQ97qjWpVqUpVqFKtU6nWqhjiq5WKHIV8iVy+QC6fK5fPkgNuWaJMNl0mmSKx mGDRzbMbdmIh4XzxxRe7d+8p7fJifyvLlb5Wdb2c6qNcGqNdG6PdtsS4M6z7eu4wYO21p7/uwADv44O9 zwDrYXpRYbjzmjDH4fYyqZmjo2YqYe3ltN7VYZ2D/ToXlzJPzypM43GxUa/f7Ou7zc9vj7///oCAg4GB wPpYUBCCoRwcTHQ2AB0aihmo02FhhPXFiIgr0ISoqFeBYHT02zEx73PIftK37+/79v20b9+7sbF3+/VD fN6v3z0Eod+378f9+n3cv//HAwf+fvDg38fFfTpixKejRn02dOjF2NimiIhVfn7T3dxira3d9Xo9Bg8H DBjghSzr9u6D7x089MGhIx8eYXAjPjqadytPc1ADoNXlanWJWlWkUhYqFesUstUyaZbUcpGlxTyLnjN7 dp/Wvdvkbi+Nf+nFhBd/N/p3L45+6X/kv/Pw8O/TZ/jIkYnTp6ePHTs3LKyfg1Q8xkVTGAoNcd0U47Yp xn1LH/etfT2B9XbA3c9rd3+G9b4BuqODvCEjotJeLoURDOupbirLLlIb+TBXh7WO9mtdXIo9PDbodOBy lU5Xg2iBu8HHZ6uf305//2YO68NBQUeDg49zAYgpThHKBHR4OOJcePiFiIhLkZFXo6Je6d37tejoNyER QLNv3084iO/17/9l//5fDxjw9cCBXw8ahI+fDRp0d8iQz4cO/Twu7t7w4fdGjvxizJgvxo37YsKELyZP /nLGjC9nzfpq/vyvUlO/Sku7t2DBzVmzjvj4jBiXPHnfOweb3zmw9619e95s3nV7987Xd+64tSPqYNRL 1S+9uPrFF3NefDGTxUsrX+qyskuXZV26LurWdW7XrrPMzBJ7dE/s2WOmhXmSpUWSRDxTZjFc2r27eVJS RmLisqSk5bNmZc6dmz1/fu7kyQsjIvrr1fIkL9v6aAb05j7A2gNYb4313B7rBax3cXA399cdHugtquzt UhbJsF4b5jTaRfXb//xPS8tejo4rvbwqEC1AM6y9vWv1+jq9Hryu9/Fp9PPb5u+/OzBwf1DQ4eDgoyEh x0NCToSGngwNBcqnwsIA8RkKDuizERHnIiLOR0Rc7NXrclTUNcAdHf1aTMybkIXY2DuxsZ9yWDOIhwz5 Ji7um/j4L4YP/2LUKID7ZULCl+PHfzVp0tdTpnw9Y8bXSUlfz579TXLyN4sWfZOR8c2KFd+uWvWHgoI/ 5Od/IldZlx2qOfHp+RO/P3fi03MnPzt38u65U1x4ndartmmV1VplhVZZzkJRqlGUaOTr1PJstWypSpam lC1USlOU0gVK6XwFQjJPYREpCQqKAbhz5uTMm5ezYMHqhQsLFi1au2RJ8bJlZSjYhIT0jbZTLwtw3NzH A8GwjvVC8Fhvi/Fs6uUlQm0eWOeGOg1z1drIxBC4/v37S6V6e/s5Xl6VFCC1tzfCgLWPz0Yfn3pfX2C9 JSBgZ2Bgc3DwwZCQI8AaQIeFEcqnw8MBsRBlAH2uV6/zXFyMjLzcwu6bMTFv9Onzbt++d/r1+7R//y8G DvwGWMfHfzV69FcJCd9MmPDN5MnfTp36bVLSt3Pnfpec/F1q6ndpad8tW/bHrKw/5uX9ae3aP5WU/Lmy 8i9z5mwZMCbu1N0Lpz6/cPrehTP3Lp794uJZfLx3ceVbOepjVqrNLUAD6w0c1iUaxTqNPEstX66Spatk i1WyRSpZqopHvKeHOC5u6oIFeSkpq1NT1y5eXJieXrJsWXlmZlVOzsa8vMaCgi0TJiTbymQJ7jblka5b +no0QUBivTZFe9ZHeG4M86wL9agPdRehTDzfzz7YRgnviZIjrgzAFiDszerZU21lNdzDYz1HagPWen2N Xl/r41MHrDmgEZv8/bHdCOPVGLI+HBqKCeAT4eGnwsMZ0BERIDIFQ5kHOjLyAhcM7qioK717v9y7942Y mNf79Hm7b98PYmM/6d//cwjIsGHfjBz57dixf5g8+Q/Tpn03e/Yfk5P/uGjRH9PT/7hixZ9WrfrTmjV/ Li7+S0XFX2pr/7ply99iYqZl1uSd/eLS2S8vnfvq8nkuzuH5l5cGXBui3melarRS1Vqpqrio1CIYqdcQ 0Gr5kpZIMyAunarsKRODzosWrU9LK8rIAIvLV6yozsmpy8/ftGbN1vXrdxYV7Sktbc7Orhk2bFKItTrZ 27E23KM6hEVViHt1sFttCMJVNNrD2kYhw04sXECwdu1aeKO8vDxsHcCCHh0drVCEOjkt9Pau5BhdpddX A2sfn1pf3zqkc35+Df7+AHpzQMAWjFcHB+8NCTkQiimn8OPh4Ri7Ph0RQViDyBRE50fRgji0G4hf7d37 enT0q4R4bOwH/fr9HgQfNAjs/jYhgcGdlPTdvHkMa9A5O5sBXVr6l6qqvzY0/DU7+2xgVMSh908wlL80 oExY7/v8oPM5d/VOK1U9B3Q1FwxrK2WpVpGvUWSpFSvU8gwu0rngQJcMUISGxi5ZUgQWL11atnx5ZXZ2 bW5uQ0FBU2HhzpKSZlieysojWVmHZ8w4MGTIAU/PTPOXJIOstPm+zpVBrlXBhqgB0Dh8GiX20tJSJAXY kI1aOxDHA5UHfH7ChAmWljY2NqO9vAr1egBd5eMDoGt8fWv9/Db6+dX7+zOsOaAR2Gu0IySkOTT0YFjY 0fDwExERp3r1OtOr11ku2oUb0LfmOEO8heNvgeP9+oHj9yApcXGM4FOmfDdz5ncLFjBqA+61a/9cVvaX wYPT5+Sknrl36UxrRgPoWbfnqY9Zq5qsVHVWqhouOKyZWBdpFasAtEaxQqNYSvEIcUu9bPToWRyLKzIz QeSN+fmNa9ZsKyjYnZ6+b/r0g3Fxh2NioJmHoZ/+/jvw/gZQKtVwvUQ+39WuMsilKtilMph9FKFbgQey ABhSPFAyx6OMewB9PNDsgGdSqUJdXFJ8fKp9fYEyCz+/OmAdEFAfENAQEACssSUUG0OBNfbTEdwHwsOP cjsKTOE2prYJzaEql6AqLTSHjt8W0Pwe0RygT53KJGXKlFccPfT1F3ee/OzSqbuXTn1+6TSP+JeXAy+F qputVJtMgMaSuE6ryOWAXq5RLBPEUo1shspCLsW6l55ekZxcPWNG7ZgxdYMHN8bEbAsN3QUXEBCwJyAA T2DA4As2A2UoKvemr7C1naXoJh5lqwXKFCIUuvCgNgdq8PQRZWL+I30SO+UlEitb23idLh/5McLfv44L hnVgYENgYGNg4GbwugXrbSEhO0JD92LTRlgYExMO8dMt1O4IaB50Ac0fgd7C9Df79mV2pV+/zyAvrq7Z CfNmHv7o0pGPLh39+NLRTy4d+/2l459eOvHppZVvrJYfsZFuspJWa2WVWlkFCzk+lmtkRRrpKo00SyNd rpFmqCXpLMRL1JZpaovFarMouZ3dwJCQ4oCAUhRhdDoKJqEQT2CKJYpk09/fEPgMFBV/i7e+i8tKqTSm t0qVo3dkQBOg1EZC9Z36RsIGB3ocKBbjgYYIenoqlY+z83Q/vyp//9qAAKDMB4Mbh1JgWzlH7S20fTE4 eDt2IoWF7QsPP4zNMq3hbkO1TXW8TdxbNB2r6CuhoYfVNi4lBxoOfnj+4IcXDrG4aIg7F0NPDejRpO1R oelRrOlRqOlRpOlZyKLHGk33HI1ZhtosTW2WojZboO6WrBKE8gVbsZXVNDe3bDe3HC7yPDxWe3mt9/Yu 9fau4MQTQAPibQEB2wMCdnAfEU2gtq8vsg2YtA1q9WhvsSzFzU4EiNGjQ3cODQ7qbqCvgdI7dTGo+o6P eOCPqBdjwUQvytq6t4dHakBAHRcbAwOBMgWjNoe1QUla4CaCN4Pg4eFHIiJ+CMHbW0sdHOYPT5x88IOz Bz84Z4gPzx3kovB2rXy/Q/dalVmJymy9ymydymwti25rlN1ylV2XKbqmKbouVHSdTyHn46U46W9/a+7k tMTZOd3FZamr6wp39xwPj3xPz3Xe3uV6faWv70Z//ybgC+kICtoTFLQXXoB7Ar+7HX/FsRtpR5WtbaKV mVjEQ4zuEZpGQBPVL7QqUHHHA0VhVNxRTafSOz6DKhr+Fvtq5XIre/shOt1KgjswEHC3hziEu0mA+C4O 8YOcgrMF80klRYg4fk+VtXNhcy0HtHHEnI4z26o026AwK1SYrVeYrVOYrWXRbbW8W5a8a5qsa6qs6wJZ 1/nG8TtfsUzW18lpcQvQmW5uqzw9C3S6IkgwpxubAgO3cb52H9IILpM4wHnc/cHBe+DBOGoj26jGO8DR cb4ImkAsBmfR10BTA4Ci3I6N5Ci046wlqrLjI0rD+CPK8KjH4wUA5RcuXKhUOmOfvl6f28JuHnQjgpOe 8HBDUsBxJikCxJ9YxIG4nd2cUbOmtolyzVvb1QeczTYqzUo5oFtQNluj6JYr77aMA3phGyh3mSL9rdTc 2nqak1Oas3OGi8tyV9csd3fQGbpRBpLC1+KosMBAbDreFxICiJFAHOHiMAc02A1eY7M3pLxcp1vn5ZUn Qo8OgoDuEXgK2gJi4AtYsV0f9XUU0VFZRyEYDzzBZ/B54A7QCXEoODy4SuXu5DRGr88LCIBwUzwR4jsF qsLrOHxh2+6bZzRoZePiWXa4sU2gB59N6L5dZVapMCsyoXO2vOsSjs4pbQD9Ym+JuXmQk9MiSAd0w8Vl BejMCXQhZBdrHdZAQd5wGF4WEHNxICQEAgLVRipX7eeHL4agF+p0a0QgJrQCmgB9QMcIrSBACXxx5CDK 6lT2xQP7FPEcJXaU2wlxVCZBcBAf/xCraGJiokrl4eg4xtt7lQDuxyMuVBWsnKGhewQ0N5Jy48XT2nrq pEVz2kR549s7tQddzeqVZmVt0Xl5u3SGjPyPnYVaPapFN5a5upJurNHpijl1RuoAMdwJC0sulsN3D+0+ RgGd87vQFphgiAwcC4AuEEEu0KAjIgM7QIwWBiAGuCii49wIqvPSA1sVUWgH4oAbHOfhBrshJpjN4OB2 cXCAC1zRGm4DzVtLeXsrJxOW1qBj/RQynaU/eBd7BYfUX9zVLp13tEPnHHnXdFnXRW3T+aXBUjMzL6Kz szPoDN3IdnfP45ZBoMb8BvIGZGdcggaZRgWCFn/QHJ9vxLsZlszPDy9JuY9PCYDW69eJoMiACVKAjhyo CgQJYsCKQ3qx1RYndWCzHB54gk2K2OgM9PEF4DixG308iAleJ7xa+G5YXTGjhVOD7O0HeHgsbAtuIeim Um5kV8gjQtAhL3DlpOkMd6Vy2PzVS9tEufLNJqbObdI5T95tRQudk9vQjRc8LeXygRyd01xcYDkA9EpY Dk/PfJ1urbc3FsNSIAgcIQ6cu6Ucgn4R/BHCUu3vj7+tQLRgXSTCex+KDLDAUCgDGkLAERADVuyOw2ZE 7GmmB3Yl4o+EOODGAeD4YvwTdPDwPsDrBNmB+EC4ofXwMChR4Q5Aa+twHK3n67uufcSZvAgcC35uY6a3 XkUZ7o6OyVHDBu175+SBD87wcfCDM1ycjTk9rPt2ZbeKttS5YzqPlPy2W08YMvgE/C8cHVOcnFKdnRe7 uqa7uy/z8MjR6VaDoRAEDmusijX+/jWCXw3PWXBY428Z3L6+G3x9y0QgIxQAckEHoIDIoC3t98Secdpe iwee0IOHG1+GvhGJCaQGmk5KgjcHCTcUCQssqlToOUG+cbqep2dah3C3Ky8t3txgz/F7yjW2OZvWH/jg tGmsfq1Uvs/OrE7erUzWbb2s21pDdC2Qdc2VdV0h65Im7ZIq7ZIs7TKfQtJlniF+52cuFofa2U23s0u0 t5+JKR/A7ey80NV1iZvbcg+PLPgHb+81Pj7AuoTDugLkBawcvrwR4LE2UBtYs4O6oQDQAUBGR/qAyHSG I38yGN0mjwdd6oq/whfgKDt8MbiP14ZXErwt8ObAdAAZQQg3wY0kHnqCyVsrqxBn5wne3tmdQLxN98Jy Io1mxNj50w98cKrNCD4ebbZF1q1C2q1I2m2dtNtaabc1LLqulnbNknZZIumySNJlwSNweZRfGiv+rUV3 fHNb26nA2t4eWM92dJzr7LzA1XWxm9tSd3f0Q1ZhZdPr13NAb+CAJpSFQOMnN6a2CCiDktABkgvauEwQ A1n+PhE6qJJOzSeswXdSEug4ryS0TvLCbQQ3TCQqghhKQrJjYxPp4jLVxKLwpGj3ibNzil9kRMPlnQfe P2UaC64tNd+rMquVdSuRdlsvRFnSdZWk63JJl8XiLgvFXeaLu8wzjhcCe1pY+NvYTLK1nUxYOzgkcUCn uLgwoMFonQ6MXtuiHgDalM7Cn9xAbZ0uWwSU6cw1Xi5MUebPFCOshdRuU0lIuI3gpvQSCRHcJHJ9tBdw 1zEQt7aOAMdxwmFnOI7f0EKqzqhY1SbK+KTrYV+zTdJu5dJuha3pnCfpminpkibukirusqANlF8ab/lb iZlKNdTGZqKNDYCeBkY7OMzCCJWLC6QDGr3C05M0GnQuhuxydEbNx0g3HgGNXwq/GlYp/JoiXpSN5IIo 3OYVmEZwg9q8kuAF412gEG6ICWk3lko4E+TxsJWooiAvBeI4XBSqotH4Qcfd3ef5+KxpD3S8r0fPndIe ysPPT+i+S2ZWzYmGkM75HJ2XdUjnoJ7m5n7W1kB5oq3tFE46QOc50A0Xl0UcnTO9vHIh0BydSTd4Oj/S Dfzw+BXwi+DXwS+F6XocUYNaP7srSyjKQrno4HRMI6zpkmgoCb4VucA24aalEs6EjCCyJMg3CI7sH2Us dBtwjihGBhQKG0i5o+NID4/5Pj4FPOggV3Cf6PZEY/2tCtV+B7MGabey1nQukHbNlXRd2YJym3Qea0Tn qRydZ3J0TsFK6O6+nKNzPhyxXs/T2QA0fkj8qPiB8WPjh+/duzfKnJgB52vOqNyJsKYJD0rp/O3VvGoL laQDuPkcB5knDCV8N1ZL0hMiOBScCoRw4mhd4mhIuEO5XKXR+MKS29kNV9vYZTesaY/OgcejzLZKu1Wa rIGgc7akS4a4yyJxl5Q2RANi/YI/1DlAQGfoBug828kpmaNzBkfnVd7ehmXQ2zvf3X2hs/Mke/v++PHw Q2I8E+9LOFq0SoSVZyRxVBw13NBptPR18qRXfFmbcJNwG7EbppuWShhB8t1UMyGCkz+BggsRR6kLlXE0 1ebMmePk5JS4IrH5nebmd/fve/fgvvcO73/v6P73ju1//8SB909OvJTUfY/crEbarZQTDZgNg9OQMDrz a2ByG0C/OMrit+ZmGk18izpjGZxBdKZl0MVlnqPjNEfHBBubQVptuFLpLpOpgoKCsEEEd4+gA4VKPV/T J2QJXNoRQsV9drnvD0ZZuEi2t07ycMN0w9uQEYTv5ldLnuC8ggsRh6qA48jsR88aferzU4gTn5049vtj Rz46cujOoQMfHNj33r7Cm0WafVZdNpp1KTXrsq5HlzU9u64x71pggeiSa9El07LLEssuqZZdUixbOw38 kcX/6MzMzfVqNdp1fVWqKKUSa1egTKaXSt0lEjtLSyV6pjqdDpzFLAYmLqEJoK1wUwi/74bfbkPg8rsX wBh2Lzgdz9bm0td5aneS3ZTBU5pDJSoiONw3FBy5JSQFiPMch6pg61X00OhtL28788WZM/dYnL53+lF8 fjrqYpS0WWpZb2m+wbxnSc8ehT3M1pmZrTXrmt+1S3aXlzJeejH1xd8t+N3v5v7ud7Nbx5zfvTDwhf96 6b9w/re1tTXeNJ6enjh1GvOMWCpgiiBfmAbAQYt4V6FzjT4q7bvhd4RQNV+46Ybft0D7Qmi0Hsu+iET5 x6PcMbt5Z0K+m9IcwA09QWmFEEeyY4o49M470LtkX8nZL84iGNZ8cKBPvTlVcVwh3y6XbZTJqmWySpms QibbIJOWSaXFUmmBVJIlkayQSJZKJOksxOniR5Em7qnviZ132CIGTGfMmIHVGDKFHV3AF2dQwRFh+AKr NE7sQQsbnVVADP6SJhBnhchSc4oHl3aE0L4F0dNFuQO4yZnACPIFE75ERYjzksIjjp/Sxt4mszrz3Ffn zn3J4uyXZ1lwoCPWvrvW6bSTYrdC3iiX18rlVfJHQJdKpeukkhwJA3q5AWXCmg+LIRbQBOgspAkQo7CO sWC4MezLw0H2QBn1A6AMoQCR8ZITxLTdBnV8PIiz1PYDbYEsHvymENoOQpsWGNBPpA9P9MVGSyWfVdJq CcNDJSoQHArOSwohDu0GBMn5yee/Ps/iq/MMbgoO9MOfHw68GKg8oFQ0KRR1CkWNAkDLK+XyCrmsXCYr krEx0WypFM3oZVJphnFIZkl6OveE7GILKVgMiHFIILYZYK8YGnWwPfyOUhAZSxz1VAlcIIvFg9/FRJuX QFtq+MFKEbh8iwpphOiJgPthX8zDbZRV8gSnBZMkhUd8yZIl09OmX/jmAouvWRgQ50BHDH55sPqYWrVD pWxQKmuVimqFokqhqFTIN8jlpXL5WrksRybDAdfLZbKlMulSqSFaEMd4OW2ZgVDggbYc/o+40AFLAkSZ JzKGA+hEf0AMfEFbUgMsHli0+S1Mwr02sFIwVPxeEGz4wHv05wC6PT0Rlk1IUnjEwSZM7WO62XD3wTcX DYi3gJ50O8nqjJV6t1q1WaWqU6lqVcpqpbJKqaxUKsoVikKFPE8uz5Fjr4psmYzF0lYhGS8xV5lDLkBh yDH8LxQZRg2zcNjMi3UPs0TQCnSO0KujnjXhC84SYbFi0xYm1HOwhgNZ0JZ22WClIXBpCwhWILxHf1ag CfE2Cc4XqoA4fsm4yXF7X9976dtLCNwwYQi6cOKbiznv57icc9Hs06ib1NiTQkCrqlkAaGWJUrlGqchV KLINW1Tky+TCwNYgsa8YxVuoBPAFiwExzgPEq4sLRmAtMFEEraDD5QExNBfkBb6kBgSrcPMS31lFtZnf WQNw4axgZ7ECQRV/AaDbJDifXuI3HDhmIMzco2tTOLh50Os/rfe97Ks9qNVs12gauQn+WrW6hoWqUqUq V6nWq9jmlBylMlOJvUAslrcKyUAJ5jcBLpY74AsWA2LSClgLpMuQY7oKixrWuAQK+AJcLBsgLLEVrpRg Jc4iFyNksaoDWQIXzgp2Fms+VPGXBNoUcahhvxH9Nl3YdPkPlxFGt9Tgj7hYrNe1XlbHrbQ7tZotOJpc o9mo0dSyUFer1RVqdbFatVqlylUps5XKFW2EfIpcbCuGYkCIYSogFOTe8DaCQabjt2HRqJUKiCG4IC/w RTES4PJSQFuVaIcSYEUuxiOLlQbgYtWhLiDWfKjiMwE0IQ4excbHNpxrIJSNgkAfdGOQ9Slrqz1W2iat tlGrrddqN2q1dVqGdaVGXapWrVGp8lWqVSpVlkq10jhwOYI0UIorNoEvHhAK1NUw1AmtICLzt/ZCKIjF aBsBX9JZkgIeU9qbRLAKkcVKQ+BS/48aVc8K0EixwOWG8w1Gl1oJ4R5za4z1WWurfVbaba1QZrfiVWs0 5RpcQqherVbnsms91JmtQpXJQJcPlOOqeowm40EQQytAZBhk/i5ImgmgsQtIBA0EkBTwsFLPmm9bt4ks 3wXEmo/HMwE0ftVBCYOYYgguaDN6PvWNqbhg2nq/NbsYDzfy0n3e3HVAWtxNj3uPizS4KJZdnpJjjDKB rpyklFpLYZChxQQxEZncG13WC0WGnaDrleAZwGLwl6QW4JIOEFuFhCXOGiHLV5Ao9/7lgcavHT8lHtta O0B5zltzHC84Wh/kUMZ1vHTHNI9ypZZdBNTOdbx0KZB6gVrmI8PwMSDGMDidaoOFl64X41GGY4NLo0us oL901TfwpZI91ZOFmFLnmjhLbVW6CY0vbDy6h+WH5SBP5V/hF8CKNHbO2OY3mjtAGTfUszu8ceMxLhAz RblKq8XF9Dh0ha62yja+GI+AlkfLsTEHEFPJgmZo6aJNpCEwcMiV+Qs0aSAAQkG3HRPEPKAdw9pepv2L MRrLCzKFxIzEYx8d6wDlRe8uMkYZokFcxr1W1Vp2K/1aJhptXkxPKCvjlVKplI5nosIQncNCt2wCZSR4 dEcvz2WgTK1quhNBWEmmPOBJa0S/DNBY0B1cHFLXpHYAMf4KKLtddLM+LOCyKcq4hZdEw+RWekJZNUUl c5DBLPMVZEKZv5BQqMvCa++e7r2ZvwDQcKn+4f659bkdo2xQDKCMux2bOF1uWQANXC7nruDtWJrnqeV6 OeoY/BFZUAxCGYk1qkKoBMEs89cbw8DxV07T4ia8S+XHCObPCjTegFiL+o/qX3mksmOUsfo9UozWKOPu QaYYG7TawsctgBlqRYQCtWYeZVr96IY8lN9Qu4BfRrECNQrhhd104URnbhbsPPQ/H9DIrFDnnZQyae+t vR2jPO2NacxjCFc/3swBZc7Msct3icsm18Lydw8q+7Fb6fl9UKjD0fV4VIcjaTa6QZruqnm6okEvxs8E NOoGOn9dRkkGsruOUU64lYBbpJmT4z3GD0JZFa+SKqXIrYXSDJtBtx+jPI/EBEWiNi8UfLqi8TMBDclD sot8ZMOhDR1DfOKbE4NfHYxL0Q1ZCTm59lBu857Slns0VWNVMjvDAgigycwJpRnVZKR/dMcuakPI/R57 RWbnVaLNr/xpGY23J9zFnMw5OJSkY5Qb7zZGXo+0OW1jvU+QlbR4DKbLQsXo0DKrpqnkrnKUQIULoJE0 wzUb3RqNksVPJBoGRm8oXfFTRG528tDBvcP7h+Y0ZJ387HjHsex2uvspV9k+sXSzWFJnKam0lFRYSsot JWUsxCUW4kIL8VoL8SoLy5XmlsvNLZeaWy4xt0xrI8wn9uju1DUyMiBh9MCxYwaOGzt4wrghkycOmzIp fsa0EbOSxsydPT5l/qRFC6dlLElcsXR2Tub8/FULCvJT169JK1qfXlKYUVq0tKx4WXnJ8qcLy0/CaJQO 3HRu87LnPZbIoDkMBi5Ctz5ibb3b2mqrSR2DshJ+9euQy2qYOX85+iY8l/kFEBkgSTNcM6SZbpunSVq6 Q+xpXczdnsKIhK9bRdlKisryzJbIqtqAyEZUVyByqitzaipXIWqrcg1RnVfHIn9jTX56WlJ0dPDAhP7r d609dfeEcXx+4pQgDn66v//lWOVxuWynVNYokdVJZFUSWaVEViGRbWAhLRNLi8XSdWJpnliSJZasFEuW iyUZYkm6WEqR8SgksyzNfXr2iek1d87UeXOnzZ83IyU5KXXhrCVpc5dmLMhcsSg3J31NwcriotyK8jV1 NUWbN23YvrV6z676/c1bDh/cfuzorhPH95w+2Xzm9IFzZw5cOHfowrnDF88fuXjhyKULRy9dPHb50vEr iMsnrl4+ee3KqWtXT7189fTL185cf/nsKy+fe+X6uRuvnH/1lQuv3rh488bF11699NrNy7duXrn12pXX b119/da1p8Zo1G3RrYgcGJlVm4VGaseKjL8t/bgUJ9+1Icp8tYjPsPmspH0np16kVoQrMFrImzksgHye TbkJFkDMsvKuGQUNFD+NpPlppSemvH4KjF6dt3jUiP6u3s4zVyRuv7G1DSLz1G6h85QbkxxO2smaJbIm iXSjRFrTQmSey6ViaZFYulYsybWUZFkauJzOuEwhZLRknqV5YM+IiOC5s6fMnQ06T0+en7hwQVLaojnp S5JXLFuYk52Wn7e8cH1WWUl+deW6ho2lTZsrdu2o27u74eD+piOHth/n6Xxq/9kzB86fPfhsMRqVARQ5 PXw8Zi6fufXa1seyGF+w9fOtA24MsDlvw5wycmsTUWYGA1xG5RM1OaoW0UXogivQhc/Vi9WKXoqEhAQU jHjLTGYOSwWfAZLNoKuhhQUNvmzUyXnlH2zyfiCjczKTRw7vZ+9iO37+2MpjGzpisUCpZ91Mcj3tLN8v lW2VSOvF0hqxtFIirZBIOUVmUS6RloilhWLparEkm+PyCkvJMkueyEaMlsxlXA4PC5g9a/Kc2VOhzkya FyQuSoU0z1uWkZKVuTgvd+m6NStLinIrNxTUQpoby7cxad64b++mQwe2Hj28A3Q+eXzPqVPNZ07tgzqf O3vwmWA0SjDoH/sE+cxeOXvLpS2dYTG+BjYZRLY9b4vE2uAuNrfOR/iyJwwGVfE7rHyyWn4K02VMJROX hYkJVTNoUoBKoEKb8VPnJm0nLJ10HUXrMhKnjw4P8/Pv5Ts7a2bjpfpTd4+3hIm7aO03JrwyjinyPk6R DUQWSyvE0g1iKSiMgMGAKMNgrBVLc2EwIMqWkuWWkqXgMsUjdTY8T7Q01/eIjAyZPXMy0Xn+3OkLkmcs TJkJaV4Gm7EydVV2+prVKwrXZ28oy6+pWt9YX9K0uXLndibNB/ZtPnJo29HD208cY3SG2Th9qvns6f2/ JKPhOtGWt7W3RcMpf1P+yd+f7CSL8WWrPlzFrMXZ1oosTKxRwheK8roWUW6/V8JKzDNV8MuY/xR6DJpA JC6jZkQNQPzwKIFSnk1b/IQ2g6qgnd/k8IMFmhWV2mP0soyZSK78fT38wn2mp08pP1J68u5xYXTM6JL3 iqIvRqmOKWS7JbItsBZiaTUUuYXIjMssJLxTNhZlnsvGjBaPs+jp0j02NnJm0iTQmbMZUxfMn56aMnPx otkZ6fNXLIfNWLI6f+n6tbAZeVWVa+s3FsM179hWvXvnxv3Nmzmnse3YkZ2g86kTe06d2At1PnN638/K aJQNYSQgfAERAdMWTSveW3z23tnOUxhfuevertG3RrPOyDFr6+aWwgX1rQWtawOR0fEra6ksI+vLa7dR YmiXjGV1DMwkGnEZHsOIy1TOB5dRaCbLTNtVhd2pn4fLj2od2ZnzUAeI7Rvm5mrvG+o9bl5C3uZV+99p NhQoWhOZJ7Upo7d93DTq2gjIMfMV2yTSRrG0ViytEhCZYzEjcqmlpMRSsl4sKWjtLh6JchuMthxg3kNl Fh/Xf2bSxFkzJ0Ga586Zkjxv+sKURMblJfNWLk/Jzlycn7d03drM0uJVlVwGuKmhbFtT1c4ddc17IM1I ArfCOB87suPk8d2I0yf3smzwZ2A0NsJ5+HrETYpLK0zbeGbjY+vFbbJ77xd7J92epLussznJFTlRSoZB FvqKlnzvUVO1vKV4/zinzAxGhhpVfNSX0foT1jEo9yO/TAOfNCpnxGXTTuvPyWUDo1GUaH5rT0fVtQ4Z XfF++ZArgxxO2Mn2S2TbxYzFda1Z3CLHBiIXg8iWkgJLsdAmZxjxt9UfxTMszf17BAbop0waxXF54pxZ k+cxLk9buCBxcSq4PHfFMuJyxlpY5uKcivKC2ur1jSwDrIQ0t7hmRmc4jeNHeXWG3/i5GP1E+iv84oI7 BZiEY509aDGKyB2yuJUiUxeqE0SmHja6q3zfjzbqoPWHphS1Syj3w9gnHTzSJpf5ytxT3Bn1pA5E9Nhi sZHZ2PHRtmmvTPE56y0/KpXuFku3iKX1ltJaS6bFZI0pWuSYERlyDCKvs5SsBpEtxJkW4hWWYuR7HRIZ 9tkCoqwxGzQwOmnG+KTE8QYuz52SPH86ShmLU2cxLi9Nyc5q4XJRzoay1bXVqGaUbNm8YXtT1a6dTJoP 7t986ACchoHOYDTUmfMbzySj8+7kDX11qMclD5tTzBezBG8bNzoER8FbY4EWG+QYnREqXNAABqxFh7UL wwQXsr5oBaZeeFGmm5747TqoL2NsATU5dLJpyIg/eER4JMazwGWDRj+W0flv5Q7DxcGnXGRHJIzCTWJJ vSX6INIqS2mFpXQDF+WI1iwmX1FoKVljKcmzZCxeCSJbiJdZiDMsxEssERKEIfFr9cRytHlPt+4RYQHT piYkzRhn4PLsSfPAZYPHmJWRPo/pctai/NwMrpSRXVEOLq+tryvewgrNVbt21DbvbtjfvAl0PnyQjDMz G/DOXDb4bDD6zLdnVt9ZDTvsf8WfVdqOClTYlMKtWfxIjuErULXAVBw/F9DOMBFfjWPuYrBSZivDoDjv lIWijMEXMhjUxkZ9mT9zi06DotzPdJrrSSe4nlSCH/v1rTS69L3i6TemRpwPtT9hKzvcwt8GS0mtpaS6 pZW3gevmMQpzUdbyBIwu4+S4iJPjfF6OLcTLLcRLwWJhtMFoy/HmPb17BAR4j00YNmN6QuL0sTOZLk+Y M3vy/DlTFyQj90tasnj20vR5K1csXJW9eHUecr8VJUWrKjasrmG6DC7DMleCy3t31+/b23CA0RlOo+no YVbWOH4UhTrmN34ZRpd9Ujb3rbnwD75XfNkA8nFrpr97uYwOXrhN/oLC7bEYtbeSljoyZXooJbcz4dmK yEOVmJDDcUBEZOE2YMr6+IMQ6axJMhiYMKJZcTpzy/R4l6e+L/ixzG23Zyg7LJbuEUthgdGBJvJWCcjb wl9isSG45jTjMp6UWhi0eC2nxQZT0cLidCMi8398xGjLBPOeuu5+vl6jRw6ePm0MuAxdnpk0fs6siVzi Ny1lwYzFqTOXpM1ZvjQ5c+XCVTlpBfnLCtdxud+G/NoqA5e3bqnYuZ1Z5uY9aANuOrBv0+EDTVweuJXU +RdmdBvMpYqEaXDDsnywPgg5ChQrYI1JizvNYiooI9+T2cjopj1TItO5qej4wSnTHjQ6CBGz4uhhYyKf ihg0yGx65tZPuin4SaktkoCzbdLWhMI0ZcGVKSwkRRaSdRaSAjZrwRwFAkJMjqJdFgvYnWZpMbhnD0ez 4CCfcQnDGJGnjeFEedxsiPIsZjAWzJ+WujAxbREzGCuXL8jOhMFIX1uwvGh9ZlkJ2iXMLzfWF29phC6j AQguo9BMBQ20TrYgjjA6Q50NfuOXZnSb5DVVYeqAEIVhJ3gh5h1F+209o3Yfkj1FiALnNGAzpZG14O/p 5ImM8gV/bip/ECJEuTMnmz0p6X7Srxe1El9iMTG3JdigULGFuIibFVptIc4xF2dyAVNMdqIzFOYsh+Vk 854h3buLu8VEh06dMmra1NHgciJEOXHcrMTxs2dOnDdncvL8qakpMxalzkyHKC9LzlqxMJeJcgZnMJD4 5VZXFtTVol1CHqNiJ6sy13BchjQzOpNxZt75GWW0qQTTZEUFy+vYMDKvwjQs2wk78chXzOPk2F6GPX7Y d8bLsfA8dlgLOiycTrIWHgAsPDe1Y1F+pnRZ+BYRteJvqaWBvDTrlm9hucrcMtOcTbytMBcvNxcvMxdn mIvTzcVp5q19cXvuwsIy0dy8d4/uVt0CA71HjhwwdTKIPGr61NEzpo9J4pwyRHnunEnJ86YsTJ6+aGFS etrs5UvhlBesyl6Un7dkbcEyTpRzKpjBQOJXuKmhuGlz+fat8BhI/2ogzc170DdBEth4YF8jV9Zg3vnZ YzSJL09eWAjoL/Xu+NIE2eHH5XVGWoxJOOUApcxZhjNzsLuPWCy8nJo/ZATJHgbjcEIDv72dTrLmiUzl C6NzU5/KaVA/qS63YrR4nYUY5iHPwjKHYy5HXjaxSUObGeaW6YahTcZiYbTK9Fox2mJiz57h3buru/n7 ecUN6ztl0oipk0dOmzJqBog8LSFxBucuZk2YByLPn7pwwfRFqSDyrGUZczOXp+Rkpebnpq0pWFq4bmVp cVZFWW5V5eqNNej7FW5uQBubcXnHtiroMknzvj1IAuvBZU6dmUA/o4w2MJfMAy++IO/j0rk2R4dUk1WY G5JZyXAAKXrnbbIYdWT0RIR3N/AXC9D2a9rhzh9NKyQybakUdq+fWVE2eq+IGG155raQt83R4w4YbTnb 3HxAj+7u3RwcrCPC/MeMHDR50nCeyFDkRCjyjLGzZ46bM3vivLmTFoDIKTPSQOQls5dlcIqctTAvJ23t 6qXr1y0vKcoqL82pgihXr9lYC7NctKWxdOuW8u1N4DJKGQabwei8t37/XqgzzMazz+gfxFyezhivV/Zl QoxrnnDsE09hOrCMv+GFDtQiFtOtAuiJ0GkjGCOioxroHAHyyGQt+NoFT2S0SJ6d8sUT6buoTfI+ltEW U3v27NO9u2u3bt26BAV6DxvaZ9L4+MkT4idPHDFl8ohpU0bCWsyYNjpxxphZSePmzBo/b/ak+XOnLFww bdHCGUsWJ2UsYdYia0XyqmxekZcXF2aWl6J8kVdTVVBXs7YRotxY0rSJuIypjMpd25k079lFrhk1DczP PUeMbmdKs00JhpHAbidFoEKmYefI4igiYWpHFKZ7oCDE8MX8PUX8PTp0szpqb5hTFsoxqha0yZ0/R0B4 JPvzS2Se9Z1itMXEHoy/7t3MLLt6eTpHRwWPGTVw4vi4iRPiJk2IY3I8eThYPGMaY3FSYsKspLGzZ42f O3vi/LmTU5KnpKZMX7KIM8gZc1cun5+dmZKbvWh13pJ1azIK1yHfA5FzKjesqq5YXVe9pmHj+s0NRVs2 FYPL25qIyxXg8q4dVXsYnVFrRvyKGK1OVavGqZR9lHJPOXp3dA4ynckJ/SUJ5o+SpTMjicL8yXB0chnm 7FE+RiuEtBiFNzIVqL1h3z3JMfkKtEXoKIE297k/kSA+g1/citEWST3Nh3fvGWEG8TUTd3VysgkM0PXv FzF+7JAJ44ZOHD904oRhkybGTWmh8PSpjMUQ4pkzwGJOi+dMTJ43KSV56qKF09NSEzl3PHvl8nlZK5Hp pa7OXbxmdfq6NUuL168oLc6sKAORc2sqV9fVrKmv40SZ4/LWzdDlsu1N5eDyTtB5R9Vu5jSqn29Gwzao 4pj5ZcxVSR97DjJ/LCfPX8rroMLoSROF6XA4OryMvw0KrRA6+cmIxXQJCX9DhtGBDc8gN3/YjySytVZ7 ejiFhuj79wtPGDVwPLcxz0Be8HcC+BsPCZ46efj0qSOmc14iCRROTIApxp69eXMmcBRmjmJxKuco0mcu XzoHLM5mLF64OndRQX4aJ8fLS4tWlpdkbSjDHi9Yi3yOyOsaN8IpF25phFkuAZe3NTEub99aDi7v3A6n AeP8q2A06md0ayR/wjR/fSR/Wq/wHGQ69pRO5qTDDenkSFJhnsK8EMMXo1JBh2uRNeav0hG6Y35O+XnJ 9J6U16KJE4ZOmjAMe0snM/GNnzqJkXfaFJCX09/p4O9ojr9j58waN2/O+OR5ExfMIy8xLS11evriRFAY Qrxi2dyslfNzshbk5izMz11csDptXUFG0bplJUWQ45UbSjF3AV+RV1sFRS6or2WivKl+/SaIcmNR02Zw mdGZuLxjK5zGhl8bo5GzQW07fw4yHXuKiU3iL2psdP4emni8CmO+gg405C/covO1yFHwV+n86lncqno3 Y9rIxOmIUTNxunsSErmEObPGzp09bh7pL6tLTF64APydmrZo+pLFM9KXJC1Ln7Vi6ZxM5iXm5WQlrwKF V6UW5IHCS9avzShav7S4cHlpCViM2hvkGNts2b7auurVIHJD3dqGjevA5c2NnC4zj1GydUvpNhYGdf51 Mhpu94nOQUaNGEUJHPJE50eSBJOR4I/gEx4VKRTiX6uj6Ixei+bPhW2YsGD+xJTkSakLJi9aOGXxwhby piUuTZ+1fOmsFctmZy6fmw3+ZoK/KXmrmJdYw1Q4bf2a9MJ18MXLSgpXlBGLyxmLq9l+cShy3sYaVJML GurWwF1sqmdc3tSwnuNyURPSP1LnfwVGP+k5yMKjeukISTo/kr+TT6jC/8oUNq5HL12SuCwjaXnGzBVL Z61chiwO4suRF+KbvSA3OyU/d+HqvNQ1+YvWrl7MqfAS7DksXr+0tGh5WTF88coNZVmV5YgcdvZBRW4N Tj2AItfk19fCXTAuI4jLmxsQqMmROv+LMfpJz0EW6q/QRfAdvH8pL9EZdTbMR+OomLyc5LxVC3AQy+rc hQV58A+pHHmhv0yCib/FhcvKikHhFeXsxBqc6YEDPcBi7hwPw/EdhlM7DFyuM3C5cSOKGLDM//KMplt7 O38OstGxp8IDTzv/8v4LfqVoHaNtWuHaJYiidenF6zOKuXOFuGAsxulCTIhL6ViarMoNWZwWG86hYUfR CE6gYR6jFn65oP7fjDY6geZJz0H+xUfnn9N3g6ikcCmCKMyRlwU2iLecr0SHKzFf0Zkzlf7N6HbPVGrv eOlfaxXtl3pDiHgKC1j8w08J+zejf/JTwn4ppjwv/98feKZSe+fe/ZvR/2b0L0z9fzP65zrd4Bd+of9l /vf/ZvS/Gf3rIvu/Gf1vRv+6GP3/AZ+4Ui+mkTlKAAAAAElFTkSuQmCC NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/0000775000175000017500000000000011742560362023012 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/PropertyPresenter.cs0000664000175000017500000004412611544330406027056 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Text; namespace NUnit.ProjectEditor { /// /// The ProjectPresenter handles presentation of the doc as /// a set of properties, which the ProjectView is expected to /// display. /// public class PropertyPresenter { private IProjectModel model; private IProjectConfig selectedConfig; private IPropertyView view; public PropertyPresenter(IProjectModel model, IPropertyView view) { this.model = model; this.view = view; view.ProcessModel.SelectionList = new string[] { "Default", "Single", "Separate", "Multiple" }; view.DomainUsage.SelectionList = new string[] { "Default", "Single", "Multiple" }; view.Runtime.SelectionList = new string[] { "Any", "Net", "Mono" }; view.RuntimeVersion.SelectionList = new string[] { "1.0.3705", "1.1.4322", "2.0.50727", "4.0.21006" }; view.BrowseProjectBaseCommand.Execute += BrowseForProjectBase; view.BrowseConfigBaseCommand.Execute += BrowseForConfigBase; view.EditConfigsCommand.Execute += EditConfigs; view.AddAssemblyCommand.Execute += AddAssembly; view.RemoveAssemblyCommand.Execute += RemoveAssembly; view.BrowseAssemblyPathCommand.Execute += BrowseForAssemblyPath; view.ProjectBase.Validated += OnProjectBaseChange; view.ProcessModel.SelectionChanged += OnProcessModelChange; view.DomainUsage.SelectionChanged += OnDomainUsageChange; view.ConfigList.SelectionChanged += OnSelectedConfigChange; view.Runtime.SelectionChanged += OnRuntimeChange; view.RuntimeVersion.TextValidated += OnRuntimeVersionChange; view.ApplicationBase.Validated += OnApplicationBaseChange; view.ConfigurationFile.Validated += OnConfigurationFileChange; view.BinPathType.SelectionChanged += OnBinPathTypeChange; view.PrivateBinPath.Validated += OnPrivateBinPathChange; view.AssemblyList.SelectionChanged += OnSelectedAssemblyChange; view.AssemblyPath.Validated += OnAssemblyPathChange; model.Document.ProjectCreated += OnProjectCreated; model.Document.ProjectClosed += OnProjectClosed; } public void LoadViewFromModel() { view.Visible = true; view.ProjectPath.Text = model.ProjectPath; view.ProjectBase.Text = model.EffectiveBasePath; view.ActiveConfigName.Text = model.ActiveConfigName; view.ProcessModel.SelectedItem = model.ProcessModel; view.DomainUsage.SelectedItem = model.DomainUsage; view.ConfigList.SelectionList = model.ConfigNames; if (model.ConfigNames.Length > 0) { view.ConfigList.SelectedIndex = 0; selectedConfig = model.Configs[0]; } else { view.ConfigList.SelectedIndex = -1; selectedConfig = null; } //OnSelectedConfigChange(); } #region Command Events private void BrowseForProjectBase() { string message = "Select ApplicationBase for the model as a whole."; string projectBase = view.DialogManager.GetFolderPath(message, view.ProjectBase.Text); if (projectBase != null && projectBase != model.BasePath) view.ProjectBase.Text = model.BasePath = projectBase; } private void BrowseForConfigBase() { string message = string.Format( "Select ApplicationBase for the {0} configuration, if different from the model as a whole.", model.Configs[view.ConfigList.SelectedIndex].Name); string initialFolder = view.ApplicationBase.Text; if (initialFolder == string.Empty) initialFolder = view.ProjectBase.Text; string appbase = view.DialogManager.GetFolderPath(message, initialFolder); if (appbase != null && appbase != view.ApplicationBase.Text) UpdateApplicationBase(appbase); } private void EditConfigs() { IConfigurationEditorDialog editorView = view.ConfigurationEditorDialog; new ConfigurationEditor(model, editorView); editorView.ShowDialog(); string selectedConfig = view.ConfigList.SelectedItem; string[] configs = model.ConfigNames; view.ConfigList.SelectionList = configs; if (configs.Length > 0) { view.ConfigList.SelectedIndex = 0; foreach (string config in configs) { if (config == selectedConfig) view.ConfigList.SelectedItem = config; } } view.ActiveConfigName.Text = model.ActiveConfigName; } private void AddAssembly() { string assemblyPath = view.DialogManager.GetFileOpenPath( "Select Assembly", "Assemblies (*.dll,*.exe)|*.dll;*.exe|All Files (*.*)|*.*", view.AssemblyPath.Text); if (assemblyPath != null) { assemblyPath = PathUtils.RelativePath(selectedConfig.EffectiveBasePath, assemblyPath); selectedConfig.Assemblies.Add(assemblyPath); SetAssemblyList(); } } private void RemoveAssembly() { string question = string.Format("Remove {0} from project?", view.AssemblyList.SelectedItem); if (view.MessageDisplay.AskYesNoQuestion(question)) { selectedConfig.Assemblies.Remove(view.AssemblyList.SelectedItem); SetAssemblyList(); } } private void BrowseForAssemblyPath() { string assemblyPath = view.DialogManager.GetFileOpenPath( "Select Assembly", "Assemblies (*.dll,*.exe)|*.dll;*.exe|All Files (*.*)|*.*", view.AssemblyPath.Text); if (assemblyPath != null) { selectedConfig.Assemblies[view.AssemblyList.SelectedIndex] = assemblyPath; SetAssemblyList(); } } #endregion #region View Change Events private void OnProjectBaseChange() { string projectBase = view.ProjectBase.Text; if (projectBase == string.Empty) view.ProjectBase.Text = projectBase = Path.GetDirectoryName(model.ProjectPath); if (ValidateDirectoryPath("ProjectBase", projectBase)) model.BasePath = projectBase; } private void OnProcessModelChange() { model.ProcessModel = view.ProcessModel.SelectedItem; view.DomainUsage.SelectionList = view.ProcessModel.SelectedItem == "Multiple" ? new string[] { "Default", "Single" } : new string[] { "Default", "Single", "Multiple" }; } private void OnDomainUsageChange() { model.DomainUsage = view.DomainUsage.SelectedItem; } private void OnSelectedConfigChange() { IProjectConfig selectedConfig = view.ConfigList.SelectedIndex >= 0 ? model.Configs[view.ConfigList.SelectedIndex] : null; if (selectedConfig != null) { RuntimeFramework framework = selectedConfig.RuntimeFramework; view.Runtime.SelectedItem = framework.Runtime.ToString(); view.RuntimeVersion.Text = framework.Version == new Version() ? string.Empty : framework.Version.ToString(); view.ApplicationBase.Text = selectedConfig.RelativeBasePath; view.ConfigurationFile.Text = selectedConfig.ConfigurationFile; view.BinPathType.SelectedIndex = (int)selectedConfig.BinPathType; if (selectedConfig.BinPathType == BinPathType.Manual) view.PrivateBinPath.Text = selectedConfig.PrivateBinPath; else view.PrivateBinPath.Text = string.Empty; SetAssemblyList(); } else { view.Runtime.SelectedItem = "Any"; view.RuntimeVersion.Text = string.Empty; view.ApplicationBase.Text = null; view.ConfigurationFile.Text = string.Empty; view.PrivateBinPath.Text = string.Empty; view.BinPathType.SelectedIndex = (int)BinPathType.Auto; view.AssemblyList.SelectionList = new string[0]; view.AssemblyPath.Text = string.Empty; } } #region Changes Pertaining to Selected Config private void OnRuntimeChange() { try { if (selectedConfig != null) selectedConfig.RuntimeFramework = new RuntimeFramework( (RuntimeType)Enum.Parse(typeof(RuntimeType), view.Runtime.SelectedItem), selectedConfig.RuntimeFramework.Version); } catch(Exception ex) { // Note: Should not be called with an invalid value, // but we catch and report the error in any case view.MessageDisplay.Error("Invalid Runtime: " + ex.Message); } } private void OnRuntimeVersionChange() { if (selectedConfig != null) { try { Version version = string.IsNullOrEmpty(view.RuntimeVersion.Text) ? new Version() : new Version(view.RuntimeVersion.Text); selectedConfig.RuntimeFramework = new RuntimeFramework( selectedConfig.RuntimeFramework.Runtime, version); } catch (Exception ex) { // User entered an bad value for the version view.MessageDisplay.Error("Invalid RuntimeVersion: " + ex.Message); } } } private void OnApplicationBaseChange() { if (selectedConfig != null) { string basePath = null; if (view.ApplicationBase.Text != String.Empty) { if (!ValidateDirectoryPath("ApplicationBase", view.ApplicationBase.Text)) return; basePath = Path.Combine(model.BasePath, view.ApplicationBase.Text); if (PathUtils.SamePath(model.BasePath, basePath)) basePath = null; } selectedConfig.BasePath = basePath; // TODO: Test what happens if we set it the same as doc base //if (index.RelativeBasePath == null) // view.ApplicationBase.Text = string.Empty; //else // view.ApplicationBase.Text = index.RelativeBasePath; } } private void OnConfigurationFileChange() { if (selectedConfig != null) { string configFile = view.ConfigurationFile.Text; if (configFile == string.Empty) selectedConfig.ConfigurationFile = null; else if (ValidateFilePath("DefaultConfigurationFile", configFile)) { if (configFile == Path.GetFileName(configFile)) selectedConfig.ConfigurationFile = view.ConfigurationFile.Text; else view.MessageDisplay.Error("ConfigurationFile must be specified as a file name only - without directory path. The configuration file is always located in the application base directory."); } } } private void OnBinPathTypeChange() { if (selectedConfig != null) selectedConfig.BinPathType = (BinPathType)view.BinPathType.SelectedIndex; view.PrivateBinPath.Enabled = view.BinPathType.SelectedIndex == (int)BinPathType.Manual; } private void OnPrivateBinPathChange() { if (selectedConfig != null) { if (view.PrivateBinPath.Text == string.Empty) selectedConfig.PrivateBinPath = null; else { foreach (string dir in view.PrivateBinPath.Text.Split(Path.PathSeparator)) { if (!ValidateDirectoryPath("PrivateBinPath", dir)) return; if (Path.IsPathRooted(dir)) { view.MessageDisplay.Error("Path " + dir + " is an absolute path. PrivateBinPath components must all be relative paths."); return; } } selectedConfig.PrivateBinPath = view.PrivateBinPath.Text; } } } private void OnSelectedAssemblyChange() { if (view.AssemblyList.SelectedIndex == -1) { view.AssemblyPath.Text = null; view.AddAssemblyCommand.Enabled = true; view.RemoveAssemblyCommand.Enabled = false; view.BrowseAssemblyPathCommand.Enabled = false; } else if (selectedConfig != null) { view.AssemblyPath.Text = selectedConfig.Assemblies[view.AssemblyList.SelectedIndex]; view.AddAssemblyCommand.Enabled = true; view.RemoveAssemblyCommand.Enabled = true; view.BrowseAssemblyPathCommand.Enabled = true; } } private void OnAssemblyPathChange() { if (selectedConfig != null && ValidateFilePath("AssemblyPath", view.AssemblyPath.Text)) { selectedConfig.Assemblies[view.AssemblyList.SelectedIndex] = view.AssemblyPath.Text; SetAssemblyList(); } } #endregion #endregion #region Model Change Events private void OnProjectCreated() { view.Visible = true; if (model.Document.RootNode != null) LoadViewFromModel(); } private void OnProjectClosed() { view.Visible = false; } #endregion #region Helper Methods private void UpdateApplicationBase(string appbase) { string basePath = null; if (appbase != String.Empty) { basePath = Path.Combine(model.BasePath, appbase); if (PathUtils.SamePath(model.BasePath, basePath)) basePath = null; } IProjectConfig selectedConfig = model.Configs[view.ConfigList.SelectedIndex]; view.ApplicationBase.Text = selectedConfig.BasePath = basePath; // TODO: Test what happens if we set it the same as doc base //if (index.RelativeBasePath == null) // applicationBaseTextBox.Text = string.Empty; //else // applicationBaseTextBox.Text = index.RelativeBasePath; } private void SetAssemblyList() { IProjectConfig config = model.Configs[view.ConfigList.SelectedIndex]; string[] list = new string[config.Assemblies.Count]; for (int i = 0; i < list.Length; i++) list[i] = config.Assemblies[i]; view.AssemblyList.SelectionList = list; if (list.Length > 0) { view.AssemblyList.SelectedIndex = 0; view.AssemblyPath.Text = list[0]; } else { view.AssemblyList.SelectedIndex = -1; view.AssemblyPath.Text = string.Empty; } } private bool ValidateDirectoryPath(string property, string path) { try { new DirectoryInfo(path); return true; } catch (Exception ex) { view.MessageDisplay.Error(string.Format("Invalid directory path for {0}: {1}", property, ex.Message)); return false; } } private bool ValidateFilePath(string property, string path) { try { new FileInfo(path); return true; } catch (Exception ex) { view.MessageDisplay.Error(string.Format("Invalid file path for {0}: {1}", property, ex.Message)); return false; } } public string[] ConfigNames { get { ConfigList configs = model.Configs; string[] configList = new string[configs.Count]; for (int i = 0; i < configs.Count; i++) configList[i] = configs[i].Name; return configList; } } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/IProjectConfig.cs0000664000175000017500000000146111544330406026202 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { public interface IProjectConfig { string Name { get; set; } string BasePath { get; set; } string RelativeBasePath { get; } string EffectiveBasePath { get; } string ConfigurationFile { get; set; } string PrivateBinPath { get; set; } BinPathType BinPathType { get; set; } AssemblyList Assemblies { get; } RuntimeFramework RuntimeFramework { get; set; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/PropertyView.resx0000664000175000017500000001624111544330406026372 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 R0lGODlhCgAKAIMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD///// /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAACgAKAAAIHgAfCBxIsKDBgwgJAgAgcGHDhQwf OJQYMaHFiwgDAgA7 R0lGODlhCgAKAIMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD///// /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAACgAKAAAIHgAfCBxIsKDBgwgJAgAgcGHDhQwf OJQYMaHFiwgDAgA7 R0lGODlhCgAKAIMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD///// /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAACgAKAAAIHgAfCBxIsKDBgwgJAgAgcGHDhQwf OJQYMaHFiwgDAgA7 17, 17 NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/IProjectModel.cs0000664000175000017500000000177311544330406026043 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { public interface IProjectModel { #region Properties IProjectDocument Document { get; } string ProjectPath { get; set; } string BasePath { get; set; } string EffectiveBasePath { get; } string ActiveConfigName { get; set; } string ProcessModel { get; set; } string DomainUsage { get; set; } ConfigList Configs { get; } string[] ConfigNames { get; } #endregion #region Methods IProjectConfig AddConfig(string name); void RemoveConfig(string name); void RemoveConfigAt(int index); #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/PropertyView.Designer.cs0000664000175000017500000007720711544330406027566 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class PropertyView { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PropertyView)); this.domainUsageComboBox = new System.Windows.Forms.ComboBox(); this.processModelComboBox = new System.Windows.Forms.ComboBox(); this.label10 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.projectBaseBrowseButton = new System.Windows.Forms.Button(); this.projectBaseTextBox = new System.Windows.Forms.TextBox(); this.label8 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.projectPathLabel = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.projectTabControl = new System.Windows.Forms.TabControl(); this.generalTabPage = new System.Windows.Forms.TabPage(); this.runtimeVersionComboBox = new System.Windows.Forms.ComboBox(); this.label11 = new System.Windows.Forms.Label(); this.runtimeComboBox = new System.Windows.Forms.ComboBox(); this.label7 = new System.Windows.Forms.Label(); this.autoBinPathRadioButton = new System.Windows.Forms.RadioButton(); this.manualBinPathRadioButton = new System.Windows.Forms.RadioButton(); this.noBinPathRadioButton = new System.Windows.Forms.RadioButton(); this.configBaseBrowseButton = new System.Windows.Forms.Button(); this.privateBinPathTextBox = new System.Windows.Forms.TextBox(); this.label6 = new System.Windows.Forms.Label(); this.configFileTextBox = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); this.applicationBaseTextBox = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.assemblyTabPage = new System.Windows.Forms.TabPage(); this.assemblyPathBrowseButton = new System.Windows.Forms.Button(); this.assemblyPathTextBox = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.assemblyListBox = new System.Windows.Forms.ListBox(); this.addAssemblyButton = new System.Windows.Forms.Button(); this.removeAssemblyButton = new System.Windows.Forms.Button(); this.editConfigsButton = new System.Windows.Forms.Button(); this.configComboBox = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.label12 = new System.Windows.Forms.Label(); this.activeConfigLabel = new System.Windows.Forms.Label(); this.errorProvider1 = new System.Windows.Forms.ErrorProvider(this.components); this.groupBox1.SuspendLayout(); this.projectTabControl.SuspendLayout(); this.generalTabPage.SuspendLayout(); this.assemblyTabPage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).BeginInit(); this.SuspendLayout(); // // domainUsageComboBox // this.domainUsageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.domainUsageComboBox.Items.AddRange(new object[] { "Default"}); this.domainUsageComboBox.Location = new System.Drawing.Point(262, 65); this.domainUsageComboBox.Margin = new System.Windows.Forms.Padding(2); this.domainUsageComboBox.Name = "domainUsageComboBox"; this.domainUsageComboBox.Size = new System.Drawing.Size(76, 21); this.domainUsageComboBox.TabIndex = 22; // // processModelComboBox // this.processModelComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.processModelComboBox.Items.AddRange(new object[] { "Default"}); this.processModelComboBox.Location = new System.Drawing.Point(91, 65); this.processModelComboBox.Margin = new System.Windows.Forms.Padding(2); this.processModelComboBox.Name = "processModelComboBox"; this.processModelComboBox.Size = new System.Drawing.Size(80, 21); this.processModelComboBox.TabIndex = 21; // // label10 // this.label10.Location = new System.Drawing.Point(178, 69); this.label10.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(84, 13); this.label10.TabIndex = 20; this.label10.Text = "Domain Usage:"; // // label9 // this.label9.Location = new System.Drawing.Point(4, 69); this.label9.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(82, 13); this.label9.TabIndex = 19; this.label9.Text = "Process Model:"; // // projectBaseBrowseButton // this.projectBaseBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.projectBaseBrowseButton.Image = ((System.Drawing.Image)(resources.GetObject("projectBaseBrowseButton.Image"))); this.projectBaseBrowseButton.Location = new System.Drawing.Point(491, 36); this.projectBaseBrowseButton.Margin = new System.Windows.Forms.Padding(2); this.projectBaseBrowseButton.Name = "projectBaseBrowseButton"; this.projectBaseBrowseButton.Size = new System.Drawing.Size(18, 16); this.projectBaseBrowseButton.TabIndex = 18; // // projectBaseTextBox // this.projectBaseTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.projectBaseTextBox.Location = new System.Drawing.Point(73, 34); this.projectBaseTextBox.Margin = new System.Windows.Forms.Padding(2); this.projectBaseTextBox.Name = "projectBaseTextBox"; this.projectBaseTextBox.Size = new System.Drawing.Size(404, 20); this.projectBaseTextBox.TabIndex = 17; // // label8 // this.label8.Location = new System.Drawing.Point(4, 35); this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label8.Name = "label8"; this.label8.Size = new System.Drawing.Size(75, 17); this.label8.TabIndex = 16; this.label8.Text = "Project Base:"; // // label5 // this.label5.Location = new System.Drawing.Point(4, 4); this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(63, 18); this.label5.TabIndex = 15; this.label5.Text = "Project Path:"; // // projectPathLabel // this.projectPathLabel.AutoSize = true; this.projectPathLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.projectPathLabel.Location = new System.Drawing.Point(75, 4); this.projectPathLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.projectPathLabel.Name = "projectPathLabel"; this.projectPathLabel.Size = new System.Drawing.Size(0, 13); this.projectPathLabel.TabIndex = 23; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.BackColor = System.Drawing.SystemColors.Control; this.groupBox1.Controls.Add(this.projectTabControl); this.groupBox1.Controls.Add(this.editConfigsButton); this.groupBox1.Controls.Add(this.configComboBox); this.groupBox1.Controls.Add(this.label1); this.groupBox1.Location = new System.Drawing.Point(10, 103); this.groupBox1.Margin = new System.Windows.Forms.Padding(2); this.groupBox1.Name = "groupBox1"; this.groupBox1.Padding = new System.Windows.Forms.Padding(2); this.groupBox1.Size = new System.Drawing.Size(500, 297); this.groupBox1.TabIndex = 24; this.groupBox1.TabStop = false; this.groupBox1.Text = "Configuration Properties"; // // projectTabControl // this.projectTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.projectTabControl.Controls.Add(this.generalTabPage); this.projectTabControl.Controls.Add(this.assemblyTabPage); this.projectTabControl.ItemSize = new System.Drawing.Size(49, 18); this.projectTabControl.Location = new System.Drawing.Point(5, 67); this.projectTabControl.Margin = new System.Windows.Forms.Padding(2); this.projectTabControl.Name = "projectTabControl"; this.projectTabControl.SelectedIndex = 0; this.projectTabControl.Size = new System.Drawing.Size(488, 226); this.projectTabControl.TabIndex = 9; // // generalTabPage // this.generalTabPage.Controls.Add(this.runtimeVersionComboBox); this.generalTabPage.Controls.Add(this.label11); this.generalTabPage.Controls.Add(this.runtimeComboBox); this.generalTabPage.Controls.Add(this.label7); this.generalTabPage.Controls.Add(this.autoBinPathRadioButton); this.generalTabPage.Controls.Add(this.manualBinPathRadioButton); this.generalTabPage.Controls.Add(this.noBinPathRadioButton); this.generalTabPage.Controls.Add(this.configBaseBrowseButton); this.generalTabPage.Controls.Add(this.privateBinPathTextBox); this.generalTabPage.Controls.Add(this.label6); this.generalTabPage.Controls.Add(this.configFileTextBox); this.generalTabPage.Controls.Add(this.label4); this.generalTabPage.Controls.Add(this.applicationBaseTextBox); this.generalTabPage.Controls.Add(this.label3); this.generalTabPage.Location = new System.Drawing.Point(4, 22); this.generalTabPage.Margin = new System.Windows.Forms.Padding(2); this.generalTabPage.Name = "generalTabPage"; this.generalTabPage.Size = new System.Drawing.Size(480, 200); this.generalTabPage.TabIndex = 0; this.generalTabPage.Text = "General"; // // runtimeVersionComboBox // this.runtimeVersionComboBox.Location = new System.Drawing.Point(240, 13); this.runtimeVersionComboBox.Margin = new System.Windows.Forms.Padding(2); this.runtimeVersionComboBox.Name = "runtimeVersionComboBox"; this.runtimeVersionComboBox.Size = new System.Drawing.Size(77, 21); this.runtimeVersionComboBox.TabIndex = 14; // // label11 // this.label11.Location = new System.Drawing.Point(144, 15); this.label11.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label11.Name = "label11"; this.label11.Size = new System.Drawing.Size(92, 13); this.label11.TabIndex = 13; this.label11.Text = "Runtime Version"; // // runtimeComboBox // this.runtimeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.runtimeComboBox.Items.AddRange(new object[] { "Any"}); this.runtimeComboBox.Location = new System.Drawing.Point(65, 13); this.runtimeComboBox.Margin = new System.Windows.Forms.Padding(2); this.runtimeComboBox.Name = "runtimeComboBox"; this.runtimeComboBox.Size = new System.Drawing.Size(62, 21); this.runtimeComboBox.TabIndex = 12; // // label7 // this.label7.Location = new System.Drawing.Point(10, 15); this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(51, 13); this.label7.TabIndex = 11; this.label7.Text = "Runtime:"; // // autoBinPathRadioButton // this.autoBinPathRadioButton.Location = new System.Drawing.Point(18, 125); this.autoBinPathRadioButton.Margin = new System.Windows.Forms.Padding(2); this.autoBinPathRadioButton.Name = "autoBinPathRadioButton"; this.autoBinPathRadioButton.Size = new System.Drawing.Size(205, 17); this.autoBinPathRadioButton.TabIndex = 10; this.autoBinPathRadioButton.Text = "Use automatically generated path"; // // manualBinPathRadioButton // this.manualBinPathRadioButton.Location = new System.Drawing.Point(18, 151); this.manualBinPathRadioButton.Margin = new System.Windows.Forms.Padding(2); this.manualBinPathRadioButton.Name = "manualBinPathRadioButton"; this.manualBinPathRadioButton.Size = new System.Drawing.Size(76, 16); this.manualBinPathRadioButton.TabIndex = 9; this.manualBinPathRadioButton.Text = "Use this path:"; // // noBinPathRadioButton // this.noBinPathRadioButton.Location = new System.Drawing.Point(18, 177); this.noBinPathRadioButton.Margin = new System.Windows.Forms.Padding(2); this.noBinPathRadioButton.Name = "noBinPathRadioButton"; this.noBinPathRadioButton.Size = new System.Drawing.Size(265, 17); this.noBinPathRadioButton.TabIndex = 8; this.noBinPathRadioButton.Text = "None - or specified in Configuration File"; // // configBaseBrowseButton // this.configBaseBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.configBaseBrowseButton.Image = ((System.Drawing.Image)(resources.GetObject("configBaseBrowseButton.Image"))); this.configBaseBrowseButton.Location = new System.Drawing.Point(454, 46); this.configBaseBrowseButton.Margin = new System.Windows.Forms.Padding(2); this.configBaseBrowseButton.Name = "configBaseBrowseButton"; this.configBaseBrowseButton.Size = new System.Drawing.Size(15, 16); this.configBaseBrowseButton.TabIndex = 7; // // privateBinPathTextBox // this.privateBinPathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.privateBinPathTextBox.Location = new System.Drawing.Point(108, 151); this.privateBinPathTextBox.Margin = new System.Windows.Forms.Padding(2); this.privateBinPathTextBox.Name = "privateBinPathTextBox"; this.privateBinPathTextBox.Size = new System.Drawing.Size(365, 20); this.privateBinPathTextBox.TabIndex = 5; // // label6 // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(6, 106); this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(80, 13); this.label6.TabIndex = 4; this.label6.Text = "PrivateBinPath:"; // // configFileTextBox // this.configFileTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configFileTextBox.Location = new System.Drawing.Point(126, 78); this.configFileTextBox.Margin = new System.Windows.Forms.Padding(2); this.configFileTextBox.Name = "configFileTextBox"; this.configFileTextBox.Size = new System.Drawing.Size(347, 20); this.configFileTextBox.TabIndex = 3; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(6, 80); this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(122, 13); this.label4.TabIndex = 2; this.label4.Text = "Configuration File Name:"; // // applicationBaseTextBox // this.applicationBaseTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.applicationBaseTextBox.Location = new System.Drawing.Point(96, 46); this.applicationBaseTextBox.Margin = new System.Windows.Forms.Padding(2); this.applicationBaseTextBox.Name = "applicationBaseTextBox"; this.applicationBaseTextBox.Size = new System.Drawing.Size(353, 20); this.applicationBaseTextBox.TabIndex = 1; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(6, 46); this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(86, 13); this.label3.TabIndex = 0; this.label3.Text = "ApplicationBase:"; // // assemblyTabPage // this.assemblyTabPage.Controls.Add(this.assemblyPathBrowseButton); this.assemblyTabPage.Controls.Add(this.assemblyPathTextBox); this.assemblyTabPage.Controls.Add(this.label2); this.assemblyTabPage.Controls.Add(this.assemblyListBox); this.assemblyTabPage.Controls.Add(this.addAssemblyButton); this.assemblyTabPage.Controls.Add(this.removeAssemblyButton); this.assemblyTabPage.Location = new System.Drawing.Point(4, 22); this.assemblyTabPage.Margin = new System.Windows.Forms.Padding(2); this.assemblyTabPage.Name = "assemblyTabPage"; this.assemblyTabPage.Size = new System.Drawing.Size(480, 200); this.assemblyTabPage.TabIndex = 1; this.assemblyTabPage.Text = "Assemblies"; this.assemblyTabPage.Visible = false; // // assemblyPathBrowseButton // this.assemblyPathBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.assemblyPathBrowseButton.Image = ((System.Drawing.Image)(resources.GetObject("assemblyPathBrowseButton.Image"))); this.assemblyPathBrowseButton.Location = new System.Drawing.Point(428, 169); this.assemblyPathBrowseButton.Margin = new System.Windows.Forms.Padding(2); this.assemblyPathBrowseButton.Name = "assemblyPathBrowseButton"; this.assemblyPathBrowseButton.Size = new System.Drawing.Size(15, 16); this.assemblyPathBrowseButton.TabIndex = 11; // // assemblyPathTextBox // this.assemblyPathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.assemblyPathTextBox.Location = new System.Drawing.Point(10, 169); this.assemblyPathTextBox.Margin = new System.Windows.Forms.Padding(2); this.assemblyPathTextBox.Name = "assemblyPathTextBox"; this.assemblyPathTextBox.Size = new System.Drawing.Size(405, 20); this.assemblyPathTextBox.TabIndex = 8; // // label2 // this.label2.Location = new System.Drawing.Point(10, 155); this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(80, 11); this.label2.TabIndex = 7; this.label2.Text = "Assembly Path:"; // // assemblyListBox // this.assemblyListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.assemblyListBox.Location = new System.Drawing.Point(10, 20); this.assemblyListBox.Margin = new System.Windows.Forms.Padding(2); this.assemblyListBox.Name = "assemblyListBox"; this.assemblyListBox.Size = new System.Drawing.Size(370, 121); this.assemblyListBox.TabIndex = 6; // // addAssemblyButton // this.addAssemblyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.addAssemblyButton.Location = new System.Drawing.Point(385, 17); this.addAssemblyButton.Margin = new System.Windows.Forms.Padding(2); this.addAssemblyButton.Name = "addAssemblyButton"; this.addAssemblyButton.Size = new System.Drawing.Size(58, 27); this.addAssemblyButton.TabIndex = 2; this.addAssemblyButton.Text = "&Add..."; // // removeAssemblyButton // this.removeAssemblyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.removeAssemblyButton.Location = new System.Drawing.Point(385, 49); this.removeAssemblyButton.Margin = new System.Windows.Forms.Padding(2); this.removeAssemblyButton.Name = "removeAssemblyButton"; this.removeAssemblyButton.Size = new System.Drawing.Size(58, 23); this.removeAssemblyButton.TabIndex = 5; this.removeAssemblyButton.Text = "&Remove"; // // editConfigsButton // this.editConfigsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.editConfigsButton.Location = new System.Drawing.Point(379, 27); this.editConfigsButton.Margin = new System.Windows.Forms.Padding(2); this.editConfigsButton.Name = "editConfigsButton"; this.editConfigsButton.Size = new System.Drawing.Size(110, 21); this.editConfigsButton.TabIndex = 8; this.editConfigsButton.Text = "&Edit Configs..."; // // configComboBox // this.configComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.configComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.configComboBox.ItemHeight = 13; this.configComboBox.Location = new System.Drawing.Point(81, 28); this.configComboBox.Margin = new System.Windows.Forms.Padding(2); this.configComboBox.Name = "configComboBox"; this.configComboBox.Size = new System.Drawing.Size(294, 21); this.configComboBox.TabIndex = 7; // // label1 // this.label1.Location = new System.Drawing.Point(10, 28); this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(76, 20); this.label1.TabIndex = 6; this.label1.Text = "Configuration:"; // // label12 // this.label12.AutoSize = true; this.label12.Location = new System.Drawing.Point(358, 69); this.label12.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.label12.Name = "label12"; this.label12.Size = new System.Drawing.Size(73, 13); this.label12.TabIndex = 25; this.label12.Text = "Active Config:"; // // activeConfigLabel // this.activeConfigLabel.AutoSize = true; this.activeConfigLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.activeConfigLabel.Location = new System.Drawing.Point(433, 68); this.activeConfigLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.activeConfigLabel.Name = "activeConfigLabel"; this.activeConfigLabel.Size = new System.Drawing.Size(0, 13); this.activeConfigLabel.TabIndex = 26; // // errorProvider1 // this.errorProvider1.ContainerControl = this; // // PropertyView // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.Controls.Add(this.activeConfigLabel); this.Controls.Add(this.label12); this.Controls.Add(this.groupBox1); this.Controls.Add(this.projectPathLabel); this.Controls.Add(this.domainUsageComboBox); this.Controls.Add(this.processModelComboBox); this.Controls.Add(this.label10); this.Controls.Add(this.label9); this.Controls.Add(this.projectBaseBrowseButton); this.Controls.Add(this.projectBaseTextBox); this.Controls.Add(this.label8); this.Controls.Add(this.label5); this.Margin = new System.Windows.Forms.Padding(2); this.Name = "PropertyView"; this.Size = new System.Drawing.Size(526, 403); this.groupBox1.ResumeLayout(false); this.projectTabControl.ResumeLayout(false); this.generalTabPage.ResumeLayout(false); this.generalTabPage.PerformLayout(); this.assemblyTabPage.ResumeLayout(false); this.assemblyTabPage.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.ComboBox domainUsageComboBox; private System.Windows.Forms.ComboBox processModelComboBox; private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label9; private System.Windows.Forms.Button projectBaseBrowseButton; private System.Windows.Forms.TextBox projectBaseTextBox; private System.Windows.Forms.Label label8; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label projectPathLabel; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.TabControl projectTabControl; private System.Windows.Forms.TabPage generalTabPage; private System.Windows.Forms.ComboBox runtimeVersionComboBox; private System.Windows.Forms.Label label11; private System.Windows.Forms.ComboBox runtimeComboBox; private System.Windows.Forms.Label label7; private System.Windows.Forms.RadioButton autoBinPathRadioButton; private System.Windows.Forms.RadioButton manualBinPathRadioButton; private System.Windows.Forms.RadioButton noBinPathRadioButton; private System.Windows.Forms.Button configBaseBrowseButton; private System.Windows.Forms.TextBox privateBinPathTextBox; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox configFileTextBox; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox applicationBaseTextBox; private System.Windows.Forms.Label label3; private System.Windows.Forms.TabPage assemblyTabPage; private System.Windows.Forms.Button assemblyPathBrowseButton; private System.Windows.Forms.TextBox assemblyPathTextBox; private System.Windows.Forms.Label label2; private System.Windows.Forms.ListBox assemblyListBox; private System.Windows.Forms.Button addAssemblyButton; private System.Windows.Forms.Button removeAssemblyButton; private System.Windows.Forms.Button editConfigsButton; private System.Windows.Forms.ComboBox configComboBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label12; private System.Windows.Forms.Label activeConfigLabel; private System.Windows.Forms.ErrorProvider errorProvider1; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/AssemblyList.cs0000664000175000017500000000507011544330406025750 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Xml; namespace NUnit.ProjectEditor { /// /// Represents a list of assemblies. It stores paths /// that are added and fires an event whenevever it /// changes. All paths should be added as absolute paths. /// public class AssemblyList { private XmlNode configNode; public AssemblyList(XmlNode configNode) { this.configNode = configNode; } #region Properties public string this[int index] { get { return XmlHelper.GetAttribute(AssemblyNodes[index], "path"); } set { XmlHelper.SetAttribute(AssemblyNodes[index], "path", value); } } public int Count { get { return AssemblyNodes.Count; } } #endregion #region Methods public void Add(string assemblyPath) { XmlHelper.AddAttribute( XmlHelper.AddElement(configNode, "assembly"), "path", assemblyPath); } public void Insert(int index, string assemblyPath) { XmlHelper.AddAttribute( XmlHelper.InsertElement(configNode, "assembly", index), "path", assemblyPath); } public void Remove(string assemblyPath) { foreach (XmlNode node in configNode.SelectNodes("assembly")) { string path = XmlHelper.GetAttribute(node, "path"); if (path == assemblyPath) { configNode.RemoveChild(node); break; } } } public IEnumerator GetEnumerator() { foreach (XmlNode node in AssemblyNodes) yield return XmlHelper.GetAttribute(node, "path"); } #endregion #region private Properties private XmlNodeList AssemblyNodes { get { return configNode.SelectNodes("assembly"); } } private XmlNode GetAssemblyNodes(int index) { return AssemblyNodes[index]; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/XmlHelper.cs0000664000175000017500000001051211544330406025232 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Xml; namespace NUnit.ProjectEditor { public class XmlHelper { #region Attributes public static string GetAttribute(XmlNode node, string name) { XmlAttribute attr = node.Attributes[name]; return attr == null ? null : attr.Value; } public static T GetAttributeAsEnum(XmlNode node, string name, T defaultValue) { string attrVal = XmlHelper.GetAttribute(node, name); if (attrVal == null) return defaultValue; if (typeof(T).IsEnum) { foreach (string s in Enum.GetNames(typeof(T))) if (s.Equals(attrVal, StringComparison.OrdinalIgnoreCase)) return (T)Enum.Parse(typeof(T), attrVal, true); } throw new XmlException( string.Format("Invalid attribute value: {0}", node.Attributes[name].OuterXml)); } /// /// Adds an attribute with a specified name and value to an existing XmlNode. /// /// The node to which the attribute should be added. /// The name of the attribute. /// The value of the attribute. public static void AddAttribute(XmlNode node, string name, string value) { XmlAttribute attr = node.OwnerDocument.CreateAttribute(name); attr.Value = value; node.Attributes.Append(attr); } public static void RemoveAttribute(XmlNode node, string name) { XmlAttribute attr = node.Attributes[name]; if (attr != null) node.Attributes.Remove(attr); } public static void SetAttribute(XmlNode node, string name, object value) { bool attrAdded = false; XmlAttribute attr = node.Attributes[name]; if (attr == null) { attr = node.OwnerDocument.CreateAttribute(name); node.Attributes.Append(attr); attrAdded = true; } string valString = value.ToString(); if (attrAdded || attr.Value != valString) attr.Value = valString; } #endregion #region Elements /// /// Adds a new element as a child of an existing XmlNode and returns it. /// /// The node to which the element should be added. /// The element name. /// The newly created child element public static XmlNode AddElement(XmlNode node, string name) { XmlNode childNode = node.OwnerDocument.CreateElement(name); node.AppendChild(childNode); return childNode; } /// /// Inserts a new element as a child of an existing XmlNode and returns it. /// /// The node to which the element should be inserted as a child. /// The element name. /// The index at which the element should be inserted. /// The newly created child element public static XmlNode InsertElement(XmlNode node, string name, int index) { XmlNode childNode = node.OwnerDocument.CreateElement(name); int childCount = node.ChildNodes.Count; if (index < 0 || index > childCount) throw new ArgumentOutOfRangeException("index"); if (index == node.ChildNodes.Count) node.AppendChild(childNode); else node.InsertBefore(childNode, node.ChildNodes[index]); return childNode; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/IPropertyView.cs0000664000175000017500000000341211544330406026123 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public interface IPropertyView : IView { #region Properties IDialogManager DialogManager { get; } IConfigurationEditorDialog ConfigurationEditorDialog { get; } #region Command Elements ICommand BrowseProjectBaseCommand { get; } ICommand EditConfigsCommand { get; } ICommand BrowseConfigBaseCommand { get; } ICommand AddAssemblyCommand { get; } ICommand RemoveAssemblyCommand { get; } ICommand BrowseAssemblyPathCommand { get; } #endregion #region Properties of the Model as a Whole ITextElement ProjectPath { get; } ITextElement ProjectBase { get; } ISelectionList ProcessModel { get; } ISelectionList DomainUsage { get; } ITextElement ActiveConfigName { get; } ISelectionList ConfigList { get; } #endregion #region Properties of the Selected Config ISelectionList Runtime { get; } IComboBox RuntimeVersion { get; } ITextElement ApplicationBase { get; } ITextElement ConfigurationFile { get; } ISelection BinPathType { get; } ITextElement PrivateBinPath { get; } ISelectionList AssemblyList { get; } ITextElement AssemblyPath { get; } #endregion #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/PropertyView.cs0000664000175000017500000001557011544330406026022 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public partial class PropertyView : UserControl, IPropertyView { #region Instance Variables private IDialogManager dialogManager; private IMessageDisplay messageDisplay; private ICommand browseProjectBaseCommand; private ICommand editConfigsCommand; private ICommand browseConfigBaseCommand; private ICommand addAssemblyCommand; private ICommand removeAssemblyCommand; private ICommand browseAssemblyPathCommand; private ITextElement projectPath; private ITextElement projectBase; private ISelectionList processModel; private ISelectionList domainUsage; private ISelectionList runtime; private IComboBox runtimeVersion; private ITextElement activeConfigName; private ISelectionList configList; private ITextElement applicationBase; private ITextElement configurationFile; private ISelection binPathType; private ITextElement privateBinPath; private ISelectionList assemblyList; private ITextElement assemblyPath; #endregion #region Constructor public PropertyView() { InitializeComponent(); InitializeViewElements(); } private void InitializeViewElements() { dialogManager = new DialogManager("NUnit Project Editor"); messageDisplay = new MessageDisplay("NUnit Project Editor"); browseProjectBaseCommand = new ButtonElement(projectBaseBrowseButton); editConfigsCommand = new ButtonElement(editConfigsButton); browseConfigBaseCommand = new ButtonElement(configBaseBrowseButton); addAssemblyCommand = new ButtonElement(addAssemblyButton); removeAssemblyCommand = new ButtonElement(removeAssemblyButton); browseAssemblyPathCommand = new ButtonElement(assemblyPathBrowseButton); projectPath = new TextElement(projectPathLabel); projectBase = new TextElement(projectBaseTextBox); processModel = new ComboBoxElement(processModelComboBox); domainUsage = new ComboBoxElement(domainUsageComboBox); runtime = new ComboBoxElement(runtimeComboBox); runtimeVersion = new ComboBoxElement(runtimeVersionComboBox); activeConfigName = new TextElement(activeConfigLabel); configList = new ComboBoxElement(configComboBox); applicationBase = new TextElement(applicationBaseTextBox); configurationFile = new TextElement(configFileTextBox); binPathType = new RadioButtonGroup("BinPathType", autoBinPathRadioButton, manualBinPathRadioButton, noBinPathRadioButton); privateBinPath = new TextElement(privateBinPathTextBox); assemblyPath = new TextElement(assemblyPathTextBox); assemblyList = new ListBoxElement(assemblyListBox); } #endregion #region IPropertyView Members public IDialogManager DialogManager { get { return dialogManager; } } public IMessageDisplay MessageDisplay { get { return messageDisplay; } } public IConfigurationEditorDialog ConfigurationEditorDialog { get { return new ConfigurationEditorDialog(); } } public ICommand BrowseProjectBaseCommand { get { return browseProjectBaseCommand; } } public ICommand EditConfigsCommand { get { return editConfigsCommand; } } public ICommand BrowseConfigBaseCommand { get { return browseConfigBaseCommand; } } public ICommand AddAssemblyCommand { get { return addAssemblyCommand; } } public ICommand RemoveAssemblyCommand { get { return removeAssemblyCommand; } } public ICommand BrowseAssemblyPathCommand { get { return browseAssemblyPathCommand; } } public ITextElement ProjectPath { get { return projectPath; } } public ITextElement ProjectBase { get { return projectBase; } } public ISelectionList ProcessModel { get { return processModel; } } public ISelectionList DomainUsage { get { return domainUsage; } } public ITextElement ActiveConfigName { get { return activeConfigName; } } public ISelectionList ConfigList { get { return configList; } } public ISelectionList Runtime { get { return runtime; } } public IComboBox RuntimeVersion { get { return runtimeVersion; } } public ITextElement ApplicationBase { get { return applicationBase; } } public ITextElement ConfigurationFile { get { return configurationFile; } } public ISelection BinPathType { get { return binPathType; } } public ITextElement PrivateBinPath { get { return privateBinPath; } } public ISelectionList AssemblyList { get { return assemblyList; } } public ITextElement AssemblyPath { get { return assemblyPath; } } #endregion #region Helper Methods private string[] GetComboBoxOptions(ComboBox comboBox) { string[] options = new string[comboBox.Items.Count]; for (int i = 0; i < comboBox.Items.Count; i++) options[i] = comboBox.Items[i].ToString(); return options; } private void SetComboBoxOptions(ComboBox comboBox, string[] options) { comboBox.Items.Clear(); foreach (object opt in options) comboBox.Items.Add(opt); if (comboBox.Items.Count > 0) comboBox.SelectedIndex = 0; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/ProjectModel.cs0000664000175000017500000000776011544330406025734 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; namespace NUnit.ProjectEditor { public class ProjectModel : IProjectModel { private IProjectDocument doc; public ProjectModel(IProjectDocument doc) { this.doc = doc; } #region IProjectModel Members public IProjectDocument Document { get { return doc; } } public string ProjectPath { get { return doc.ProjectPath; } set { doc.ProjectPath = value; } } /// /// BasePath is the base as it appears in the document /// and may be null if there is no setting. /// public string BasePath { get { return doc.GetSettingsAttribute("appbase"); } set { doc.SetSettingsAttribute("appbase", value); } } /// /// EffectiveBasePath uses the BasePath if present and otherwise /// defaults to the directory part of the ProjectPath. /// public string EffectiveBasePath { get { return this.BasePath == null ? Path.GetDirectoryName(this.ProjectPath) : Path.Combine( Path.GetDirectoryName(this.ProjectPath), this.BasePath); } } public string ActiveConfigName { get { return doc.GetSettingsAttribute("activeconfig"); } set { doc.SetSettingsAttribute("activeconfig", value); } } public string ProcessModel { get { return doc.GetSettingsAttribute("processModel") ?? "Default"; } set { doc.SetSettingsAttribute("processModel", value.ToString()); } } public string DomainUsage { get { return doc.GetSettingsAttribute("domainUsage") ?? "Default"; } set { doc.SetSettingsAttribute("domainUsage", value.ToString()); } } public ConfigList Configs { get { return new ConfigList(this); } } public string[] ConfigNames { get { string[] configList = new string[Configs.Count]; for (int i = 0; i < Configs.Count; i++) configList[i] = Configs[i].Name; return configList; } } public IProjectConfig AddConfig(string name) { XmlNode configNode = XmlHelper.AddElement(doc.RootNode, "Config"); XmlHelper.AddAttribute(configNode, "name", name); return new ProjectConfig(this, configNode); } public void RemoveConfigAt(int index) { bool itWasActive = ActiveConfigName == Configs[index].Name; doc.RootNode.RemoveChild(doc.ConfigNodes[index]); if (itWasActive) doc.RemoveSettingsAttribute("activeconfig"); } public void RemoveConfig(string name) { int index = IndexOf(name); if (index >= 0) { RemoveConfigAt(index); } } #endregion #region Helper Properties and Methods private int IndexOf(string name) { for (int index = 0; index < doc.ConfigNodes.Count; index++) { if (XmlHelper.GetAttribute(doc.ConfigNodes[index], "name") == name) return index; } return -1; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/ProjectConfig.cs0000664000175000017500000001204611544330406026072 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace NUnit.ProjectEditor { public enum BinPathType { Auto, Manual, None } public class ProjectConfig : IProjectConfig { #region Instance Variables /// /// The XmlNode representing this config /// private XmlNode configNode; /// /// IProject interface of containing doc /// private IProjectModel project; /// /// List of the test assemblies in this config /// private AssemblyList assemblies; #endregion #region Constructor public ProjectConfig(IProjectModel project, XmlNode configNode) { this.project = project; this.configNode = configNode; this.assemblies = new AssemblyList(configNode); } #endregion #region Properties public string Name { get { return GetAttribute("name"); } set { bool itWasActive = Name == project.ActiveConfigName; SetAttribute("name", value); if (itWasActive) project.ActiveConfigName = value; } } /// /// The base directory for this config as stored /// in the config element ofthe document. May be null. /// public string BasePath { get { return GetAttribute("appbase"); } set { SetAttribute("appbase", value); } } /// /// The base path relative to the doc base. This is what /// is stored in the document unless the user edits the /// xml directly. /// public string RelativeBasePath { get { return PathUtils.RelativePath(project.EffectiveBasePath, EffectiveBasePath); } } /// /// The actual base path used in loading the tests. Its /// value depends on the appbase entry of the config element /// as well as the project EffectiveBasePath. /// public string EffectiveBasePath { get { string basePath = BasePath; if (project == null) return basePath; if (basePath == null) return project.EffectiveBasePath; return Path.Combine(project.EffectiveBasePath, basePath); } } public string ConfigurationFile { get { return GetAttribute("configfile"); } set { SetAttribute("configfile", value); } } /// /// The Path.PathSeparator-separated path containing all the /// assemblies in the list. May be null if not specified. /// public string PrivateBinPath { get { return GetAttribute("binpath"); } set { SetAttribute("binpath", value); } } /// /// How our PrivateBinPath is generated /// public BinPathType BinPathType { get { return XmlHelper.GetAttributeAsEnum( configNode, "binpathtype", PrivateBinPath == null ? BinPathType.Auto : BinPathType.Manual); } set { SetAttribute("binpathtype", value); } } /// /// Return our AssemblyList /// public AssemblyList Assemblies { get { return assemblies; } } public RuntimeFramework RuntimeFramework { get { string runtime = GetAttribute("runtimeFramework"); return runtime == null ? RuntimeFramework.AnyRuntime : new RuntimeFramework(runtime); } set { SetAttribute("runtimeFramework", value); } } #endregion #region Helper Methods private string GetAttribute(string name) { return XmlHelper.GetAttribute(configNode, name); } private void SetAttribute(string name, object value) { if (value == null) XmlHelper.RemoveAttribute(configNode, name); else XmlHelper.SetAttribute(configNode, name, value); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/RuntimeFramework.cs0000664000175000017500000000773111544330406026644 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using System.Collections; using Microsoft.Win32; namespace NUnit.ProjectEditor { /// /// Enumeration identifying a common language /// runtime implementation. /// public enum RuntimeType { /// AnyRuntime supported runtime framework Any, /// Microsoft .NET Framework Net, /// Microsoft .NET Compact Framework NetCF, /// Microsoft Shared Source CLI SSCLI, /// Mono Mono } /// /// RuntimeFramework encapsulates the naming standards /// for identifying CLR implementations by runtime type /// and version in the XML project file and elsewhere. /// [Serializable] public sealed class RuntimeFramework { #region Instance Fields private static readonly RuntimeFramework anyRuntime = new RuntimeFramework(RuntimeType.Any, new Version()); private RuntimeType runtime; private Version version; #endregion #region Constructors /// /// Construct from a runtime type and version /// /// The runtime type of the framework /// The version of the framework public RuntimeFramework( RuntimeType runtime, Version version) { this.runtime = runtime; this.version = version; } /// /// Construct from a string /// /// A string representing the runtime public RuntimeFramework(string s) { runtime = RuntimeType.Any; version = new Version(); string[] parts = s.Split(new char[] { '-' }); if (parts.Length == 2) { runtime = (RuntimeType)System.Enum.Parse(typeof(RuntimeType), parts[0], true); string vstring = parts[1]; if (vstring != "") version = new Version(vstring); } else if (char.ToLower(s[0]) == 'v') { version = new Version(s.Substring(1)); } else if (char.IsNumber(s[0])) { version = new Version(s); } else { runtime = (RuntimeType)System.Enum.Parse(typeof(RuntimeType), s, true); version = Environment.Version; } } #endregion #region Properties /// /// Represents any runtime at all /// public static RuntimeFramework AnyRuntime { get { return anyRuntime; } } /// /// The type of this runtime framework /// public RuntimeType Runtime { get { return runtime; } } /// /// The version of this runtime framework /// public Version Version { get { return version; } } #endregion #region Public Methods /// /// Overridden to return the short name of the framework /// /// public override string ToString() { string vstring = version.ToString(); if (runtime == RuntimeType.Any) return "v" + vstring; else return runtime.ToString().ToLower() + "-" + vstring; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/VSProjectConfig.cs0000664000175000017500000000177111544330406026346 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Specialized; namespace NUnit.ProjectEditor { /// /// Originally, we used the same ProjectConfig class for both /// NUnit and Visual Studio projects. Since we really do very /// little with VS Projects, this class has been created to /// hold the name and the collection of assembly paths. /// public class VSProjectConfig { private string name; private StringCollection assemblies = new StringCollection(); public VSProjectConfig( string name ) { this.name = name; } public string Name { get { return name; } } public StringCollection Assemblies { get { return assemblies; } } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/VSProjectConfigCollection.cs0000664000175000017500000000223511544330406030356 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.ProjectEditor { /// /// A simple collection to hold VSProjectConfigs. Originally, /// we used the (NUnit) ProjectConfigCollection, but the /// classes have since diverged. /// public class VSProjectConfigCollection : CollectionBase { public VSProjectConfig this[int index] { get { return List[index] as VSProjectConfig; } } public VSProjectConfig this[string name] { get { foreach ( VSProjectConfig config in InnerList ) if ( config.Name == name ) return config; return null; } } public void Add( VSProjectConfig config ) { List.Add( config ); } public bool Contains( string name ) { foreach( VSProjectConfig config in InnerList ) if ( config.Name == name ) return true; return false; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/VSProject.cs0000664000175000017500000002353211544330406025217 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Xml; using System.Text.RegularExpressions; namespace NUnit.ProjectEditor { /// /// This class allows loading information about /// configurations and assemblies in a Visual /// Studio doc file and inspecting them. /// Only the most common doc types are /// supported and an exception is thrown if /// an attempt is made to load an invalid /// file or one of an unknown type. /// public class VSProject { #region Static and Instance Variables /// /// VS Project extentions /// private static readonly string[] validExtensions = { ".csproj", ".vbproj", ".vjsproj", ".vcproj" }; /// /// VS Solution extension /// private static readonly string solutionExtension = ".sln"; /// /// Path to the file storing this doc /// private string projectPath; /// /// Collection of configs for the doc /// private VSProjectConfigCollection configs; #endregion #region Constructor public VSProject( string projectPath ) { this.projectPath = Path.GetFullPath( projectPath ); configs = new VSProjectConfigCollection(); Load(); } #endregion #region Properties /// /// The name of the doc. /// public string Name { get { return Path.GetFileNameWithoutExtension( projectPath ); } } /// /// The path to the doc /// public string ProjectPath { get { return projectPath; } } /// /// Our collection of configurations /// public VSProjectConfigCollection Configs { get { return configs; } } #endregion #region Static Methods public static bool IsProjectFile( string path ) { if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0) return false; if ( path.ToLower().IndexOf( "http:" ) >= 0 ) return false; string extension = Path.GetExtension( path ); foreach( string validExtension in validExtensions ) if ( extension == validExtension ) return true; return false; } public static bool IsSolutionFile( string path ) { return Path.GetExtension( path ) == solutionExtension; } #endregion #region Instance Methods private void Load() { if ( !IsProjectFile( projectPath ) ) ThrowInvalidFileType( projectPath ); string projectDirectory = Path.GetFullPath( Path.GetDirectoryName( projectPath ) ); StreamReader rdr = new StreamReader( projectPath, System.Text.Encoding.UTF8 ); string[] extensions = {"", ".exe", ".dll", ".lib", "" }; try { XmlDocument doc = new XmlDocument(); doc.Load( rdr ); string extension = Path.GetExtension( projectPath ); string assemblyName = null; switch ( extension ) { case ".vcproj": XmlNode topNode = doc.SelectSingleNode( "/VisualStudioProject" ); // TODO: This is all very hacked up... replace it. foreach ( XmlNode configNode in doc.SelectNodes( "/VisualStudioProject/Configurations/Configuration" ) ) { string name = RequiredAttributeValue( configNode, "Name" ); int config_type = System.Convert.ToInt32(RequiredAttributeValue(configNode, "ConfigurationType" ) ); string dirName = name; int bar = dirName.IndexOf( '|' ); if ( bar >= 0 ) dirName = dirName.Substring( 0, bar ); string outputPath = RequiredAttributeValue( configNode, "OutputDirectory" ); outputPath = outputPath.Replace( "$(SolutionDir)", Path.GetFullPath( Path.GetDirectoryName( projectPath ) ) + Path.DirectorySeparatorChar ); outputPath = outputPath.Replace( "$(ConfigToCreate)", dirName ); string outputDirectory = Path.Combine( projectDirectory, outputPath ); XmlNode toolNode = configNode.SelectSingleNode( "Tool[@Name='VCLinkerTool']" ); if ( toolNode != null ) { assemblyName = SafeAttributeValue( toolNode, "OutputFile" ); if ( assemblyName != null ) assemblyName = Path.GetFileName( assemblyName ); else assemblyName = Path.GetFileNameWithoutExtension(projectPath) + extensions[config_type]; } else { toolNode = configNode.SelectSingleNode( "Tool[@Name='VCNMakeTool']" ); if ( toolNode != null ) assemblyName = Path.GetFileName( RequiredAttributeValue( toolNode, "Output" ) ); } assemblyName = assemblyName.Replace( "$(OutDir)", outputPath ); assemblyName = assemblyName.Replace( "$(ProjectName)", this.Name ); VSProjectConfig config = new VSProjectConfig ( name ); if ( assemblyName != null ) config.Assemblies.Add( Path.Combine( outputDirectory, assemblyName ) ); this.configs.Add( config ); } break; case ".csproj": case ".vbproj": case ".vjsproj": LoadProject( projectDirectory, doc ); break; default: break; } } catch( FileNotFoundException ) { throw; } catch( Exception e ) { ThrowInvalidFormat( projectPath, e ); } finally { rdr.Close(); } } private bool LoadProject(string projectDirectory, XmlDocument doc) { bool loaded = LoadVS2003Project(projectDirectory, doc); if (loaded) return true; loaded = LoadMSBuildProject(projectDirectory, doc); if (loaded) return true; return false; } private bool LoadVS2003Project(string projectDirectory, XmlDocument doc) { XmlNode settingsNode = doc.SelectSingleNode("/VisualStudioProject/*/Build/Settings"); if (settingsNode == null) return false; string assemblyName = RequiredAttributeValue( settingsNode, "AssemblyName" ); string outputType = RequiredAttributeValue( settingsNode, "OutputType" ); if (outputType == "Exe" || outputType == "WinExe") assemblyName = assemblyName + ".exe"; else assemblyName = assemblyName + ".dll"; XmlNodeList nodes = settingsNode.SelectNodes("Config"); if (nodes != null) foreach (XmlNode configNode in nodes) { string name = RequiredAttributeValue( configNode, "Name" ); string outputPath = RequiredAttributeValue( configNode, "OutputPath" ); string outputDirectory = Path.Combine(projectDirectory, outputPath); string assemblyPath = Path.Combine(outputDirectory, assemblyName); VSProjectConfig config = new VSProjectConfig(name); config.Assemblies.Add(assemblyPath); configs.Add(config); } return true; } private bool LoadMSBuildProject(string projectDirectory, XmlDocument doc) { XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable); namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); XmlNodeList nodes = doc.SelectNodes("/msbuild:Project/msbuild:PropertyGroup", namespaceManager); if (nodes == null) return false; XmlElement assemblyNameElement = (XmlElement)doc.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:AssemblyName", namespaceManager); string assemblyName = assemblyNameElement.InnerText; XmlElement outputTypeElement = (XmlElement)doc.SelectSingleNode("/msbuild:Project/msbuild:PropertyGroup/msbuild:OutputType", namespaceManager); string outputType = outputTypeElement.InnerText; if (outputType == "Exe" || outputType == "WinExe") assemblyName = assemblyName + ".exe"; else assemblyName = assemblyName + ".dll"; foreach (XmlElement configNode in nodes) { if (configNode.Name != "PropertyGroup") continue; XmlAttribute conditionAttribute = configNode.Attributes["Condition"]; if (conditionAttribute == null) continue; string condition = conditionAttribute.Value; int start = condition.IndexOf( "==" ); if ( start < 0 ) continue; string configurationName = condition.Substring( start + 2 ).Trim(new char[] {' ', '\'' } ); if ( configurationName.EndsWith( "|AnyCPU" ) ) configurationName = configurationName.Substring( 0, configurationName.Length - 7 ); XmlElement outputPathElement = (XmlElement)configNode.SelectSingleNode("msbuild:OutputPath", namespaceManager); string outputPath = outputPathElement.InnerText; string outputDirectory = Path.Combine(projectDirectory, outputPath); string assemblyPath = Path.Combine(outputDirectory, assemblyName); VSProjectConfig config = new VSProjectConfig(configurationName); config.Assemblies.Add(assemblyPath); configs.Add(config); } return true; } private void ThrowInvalidFileType(string projectPath) { throw new ArgumentException( string.Format( "Invalid model file type: {0}", Path.GetFileName( projectPath ) ) ); } private void ThrowInvalidFormat( string projectPath, Exception e ) { throw new ArgumentException( string.Format( "Invalid model file format: {0}", Path.GetFileName( projectPath ) ), e ); } private string SafeAttributeValue( XmlNode node, string attrName ) { XmlNode attrNode = node.Attributes[attrName]; return attrNode == null ? null : attrNode.Value; } private string RequiredAttributeValue( XmlNode node, string name ) { string result = SafeAttributeValue( node, name ); if ( result != null ) return result; throw new ApplicationException( "Missing required attribute " + name ); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PropertyEditor/ConfigList.cs0000664000175000017500000000632211544330406025377 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Xml; namespace NUnit.ProjectEditor { /// /// Summary description for ConfigList. /// public class ConfigList : IEnumerable { private IProjectModel project; private XmlNode projectNode; public ConfigList(IProjectModel project) { this.project = project; this.projectNode = project.Document.RootNode; } #region Properties public int Count { get { return ConfigNodes.Count; } } public IProjectConfig this[int index] { get { return new ProjectConfig(project, ConfigNodes[index]); } } public IProjectConfig this[string name] { get { int index = IndexOf(name); return index >= 0 ? this[index] : null; } } private XmlNodeList ConfigNodes { get { return projectNode.SelectNodes("Config"); } } private XmlNode SettingsNode { get { return projectNode.SelectSingleNode("Settings"); } } #endregion #region Methods //public IProjectConfig Add(string name) //{ // XmlNode configNode = XmlHelper.AddElement(projectNode, "Config"); // XmlHelper.AddAttribute(configNode, "name", name); // return new ProjectConfig(project, configNode); //} //public void RemoveAt(int index) //{ // bool wasActive = project.ActiveConfigName == this[index].Name; // projectNode.RemoveChild(ConfigNodes[index]); // if (wasActive) // project.ActiveConfigName = null; //} //public void Remove(string name) //{ // int index = IndexOf(name); // if (index >= 0) // { // RemoveAt(index); // } //} private int IndexOf(string name) { for (int index = 0; index < ConfigNodes.Count; index++) { if (XmlHelper.GetAttribute(ConfigNodes[index], "name") == name) return index; } return -1; } //public bool Contains(string name) //{ // return IndexOf(name) >= 0; //} #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { foreach (XmlNode node in ConfigNodes) yield return new ProjectConfig(project, node); } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Properties/0000775000175000017500000000000011742560362022153 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/Properties/AssemblyInfo.cs0000664000175000017500000000274311544330406025075 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("NUnit Project Editor")] [assembly: AssemblyDescription("Standalone NUnit project editor")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("NUnit Software")] [assembly: AssemblyProduct("NUnit Project Editor")] [assembly: AssemblyCopyright("Copyright © 2011 Charlie Poole")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this doc is exposed to COM [assembly: Guid("d04fe5e3-ffa5-4510-a7c4-c2edd4dff058")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.9.0.0")] [assembly: AssemblyFileVersion("0.9.0.0")] NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/0000775000175000017500000000000011742560362020703 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/Main/ProjectDocument.cs0000664000175000017500000002366411544330406024344 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace NUnit.ProjectEditor { public class ProjectDocument : IProjectDocument { private enum DocumentState { Empty, InvalidXml, Valid } #region Static Fields /// /// Used to generate default names for projects /// private static int projectSeed = 0; /// /// The extension used for test projects /// private static readonly string nunitExtension = ".nunit"; #endregion #region Instance Fields /// /// The original text from which the doc was loaded. /// Updated from the doc when the xml view is displayed /// and from the view when the user edits it. /// string xmlText; /// /// The XmlDocument representing the loaded doc. It /// is generated from the text when the doc is loaded /// unless an exception is thrown. It is modified as the /// user makes changes. /// XmlDocument xmlDoc; /// /// An exception thrown when trying to build the xml /// document from the xml text. /// Exception exception; /// /// Path to the file storing this doc /// private string projectPath; /// /// True if the Xml Document has been changed /// private DocumentState documentState = DocumentState.Empty; /// /// True if the doc has been changed and not yet saved /// private bool hasUnsavedChanges = false; #endregion #region Constructors public ProjectDocument() : this(GenerateProjectName()) { } public ProjectDocument(string projectPath) { this.xmlDoc = new XmlDocument(); this.projectPath = Path.GetFullPath(projectPath); xmlDoc.NodeChanged += new XmlNodeChangedEventHandler(xmlDoc_Changed); xmlDoc.NodeInserted += new XmlNodeChangedEventHandler(xmlDoc_Changed); xmlDoc.NodeRemoved += new XmlNodeChangedEventHandler(xmlDoc_Changed); } #endregion #region IProjectDocument Members #region Events public event ActionDelegate ProjectCreated; public event ActionDelegate ProjectClosed; public event ActionDelegate ProjectChanged; #endregion #region Properties /// /// The name of the doc. /// public string Name { get { return Path.GetFileNameWithoutExtension(projectPath); } } /// /// Gets or sets the path to which a doc will be saved. /// public string ProjectPath { get { return projectPath; } set { string newProjectPath = Path.GetFullPath(value); if (newProjectPath != projectPath) { projectPath = newProjectPath; } } } public string XmlText { get { return xmlText; } set { LoadXml(value); } } public Exception Exception { get { return exception; } } /// /// The top-level (NUnitProject) node /// public XmlNode RootNode { get { return xmlDoc.FirstChild; } } /// /// The Settings node if present, otherwise null /// public XmlNode SettingsNode { get { return RootNode.SelectSingleNode("Settings"); } } /// /// The collection of Config nodes - may be empty /// public XmlNodeList ConfigNodes { get { return RootNode.SelectNodes("Config"); } } public bool HasUnsavedChanges { get { return hasUnsavedChanges; } } public bool IsValid { get { return documentState == DocumentState.Valid; } } public bool IsEmpty { get { return documentState == DocumentState.Empty; } } #endregion #region Methods public void CreateNewProject() { this.XmlText = ""; hasUnsavedChanges = false; if (ProjectCreated != null) ProjectCreated(); } public void OpenProject(string fileName) { StreamReader rdr = new StreamReader(fileName); this.XmlText = rdr.ReadToEnd(); rdr.Close(); this.projectPath = Path.GetFullPath(fileName); if (ProjectCreated != null) ProjectCreated(); hasUnsavedChanges = false; } public void CloseProject() { if (ProjectClosed != null) ProjectClosed(); } public void SaveProject() { XmlTextWriter writer = new XmlTextWriter( ProjectPathFromFile(projectPath), System.Text.Encoding.UTF8); writer.Formatting = Formatting.Indented; xmlDoc.WriteTo(writer); writer.Close(); hasUnsavedChanges = false; } public void SaveProject(string fileName) { projectPath = fileName; SaveProject(); } public string GetSettingsAttribute(string name) { if (SettingsNode == null) return null; return XmlHelper.GetAttribute(SettingsNode, name); } public void SetSettingsAttribute(string name, string value) { if (value == null) RemoveSettingsAttribute(name); else { if (SettingsNode == null) XmlHelper.InsertElement(RootNode, "Settings", 0); XmlHelper.SetAttribute(SettingsNode, name, value); } } public void RemoveSettingsAttribute(string name) { if (SettingsNode != null) XmlHelper.RemoveAttribute(SettingsNode, name); } #region Load Methods public void Load() { StreamReader rdr = new StreamReader(this.projectPath); this.XmlText = rdr.ReadToEnd(); rdr.Close(); this.hasUnsavedChanges = false; } public void LoadXml(string xmlText) { // Mark as empty to avoid double updates // in the xmldoc_Changed method. this.documentState = DocumentState.Empty; this.xmlText = xmlText; try { this.xmlDoc.LoadXml(xmlText); this.documentState = DocumentState.Valid; this.exception = null; if (RootNode.Name != "NUnitProject") throw new XmlException("Top level element must be ."); } catch (Exception ex) { this.documentState = DocumentState.InvalidXml; this.exception = ex; } } #endregion #region Save methods public void Save() { using (StreamWriter writer = new StreamWriter(ProjectPathFromFile(projectPath), false, System.Text.Encoding.UTF8)) { writer.Write(xmlText); } hasUnsavedChanges = false; } public void Save(string fileName) { this.projectPath = Path.GetFullPath(fileName); Save(); } private string ToXml() { StringWriter buffer = new StringWriter(); using (XmlTextWriter writer = new XmlTextWriter(buffer)) { writer.Formatting = Formatting.Indented; xmlDoc.WriteTo(writer); } return buffer.ToString(); } #endregion #endregion #endregion #region Event Handlers void xmlDoc_Changed(object sender, XmlNodeChangedEventArgs e) { hasUnsavedChanges = true; if (this.IsValid) xmlText = this.ToXml(); if (this.ProjectChanged != null) ProjectChanged(); } #endregion #region Private Properties and Helper Methods private string DefaultBasePath { get { return Path.GetDirectoryName(projectPath); } } public static bool IsProjectFile(string path) { return Path.GetExtension(path) == nunitExtension; } private static string ProjectPathFromFile(string path) { string fileName = Path.GetFileNameWithoutExtension(path) + nunitExtension; return Path.Combine(Path.GetDirectoryName(path), fileName); } private static string GenerateProjectName() { return string.Format("Project{0}", ++projectSeed); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/IProjectDocument.cs0000664000175000017500000000307111544330406024443 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Xml; namespace NUnit.ProjectEditor { public interface IProjectDocument { #region Events event ActionDelegate ProjectCreated; event ActionDelegate ProjectClosed; event ActionDelegate ProjectChanged; #endregion #region Properties string Name { get; } /// /// Gets or sets the path to which a doc will be saved. /// string ProjectPath { get; set; } bool IsEmpty { get; } bool IsValid { get; } string XmlText { get; set; } Exception Exception { get; } XmlNode RootNode { get; } XmlNode SettingsNode { get; } XmlNodeList ConfigNodes { get; } bool HasUnsavedChanges { get; } string GetSettingsAttribute(string name); void SetSettingsAttribute(string name, string value); void RemoveSettingsAttribute(string name); #endregion #region Methods void CreateNewProject(); void OpenProject(string fileName); void CloseProject(); void SaveProject(); void SaveProject(string fileName); void LoadXml(string xmlText); #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/MainPresenter.cs0000664000175000017500000001443711544330406024011 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; namespace NUnit.ProjectEditor { /// /// MainPresenter is the top-level presenter with subordinate /// presenters for each view of the doc. It directly handles /// the menu commands from the top-level view and coordinates /// changes in the two different submodels. /// public class MainPresenter { private IMainView view; private IProjectDocument doc; private PropertyPresenter propertyPresenter; private XmlPresenter xmlPresenter; #region Constructor public MainPresenter(IProjectDocument doc, IMainView view) { this.doc = doc; this.view = view; // Set up property editor triad ProjectModel project = new ProjectModel(doc); IPropertyView propertyView = view.PropertyView; this.propertyPresenter = new PropertyPresenter(project, propertyView); // Set up XML editor triad IXmlView xmlView = view.XmlView; this.xmlPresenter = new XmlPresenter(doc, xmlView); // Enable and disable menu items view.NewProjectCommand.Enabled = true; view.OpenProjectCommand.Enabled = true; view.CloseProjectCommand.Enabled = false; view.SaveProjectCommand.Enabled = false; view.SaveProjectAsCommand.Enabled = false; // Set up handlers for view events view.FormClosing += OnFormClosing; view.NewProjectCommand.Execute += CreateNewProject; view.OpenProjectCommand.Execute += OpenProject; view.SaveProjectCommand.Execute += SaveProject; view.SaveProjectAsCommand.Execute += SaveProjectAs; view.CloseProjectCommand.Execute += CloseProject; view.ActiveViewChanging += this.ValidateActiveViewChange; view.ActiveViewChanged += this.ActiveViewChanged; // Set up handlers for model events doc.ProjectCreated += OnProjectCreated; doc.ProjectClosed += OnProjectClosed; } public void OnFormClosing(object sender, FormClosingEventArgs e) { CloseProject(); } public bool ValidateActiveViewChange() { if (doc.IsValid || doc.IsEmpty) return true; view.SaveProjectCommand.Enabled = false; view.SaveProjectAsCommand.Enabled = false; return view.SelectedView == SelectedView.XmlView; } public void ActiveViewChanged() { switch (view.SelectedView) { case SelectedView.PropertyView: if (doc.RootNode != null) propertyPresenter.LoadViewFromModel(); break; case SelectedView.XmlView: xmlPresenter.LoadViewFromModel(); break; } } #endregion #region Command Event Handlers private void CreateNewProject() { doc.CreateNewProject(); } private void OpenProject() { string path = view.DialogManager.GetFileOpenPath( "Open Project", "Test Projects (*.nunit)|*.nunit", null); if (path != null) { try { doc.OpenProject(path); } catch (Exception ex) { view.MessageDisplay.Error(ex.Message); } } } private void CloseProject() { if (doc.IsValid && doc.HasUnsavedChanges && view.MessageDisplay.AskYesNoQuestion(string.Format("Do you want to save changes to {0}?", doc.Name))) SaveProject(); doc.CloseProject(); } private void SaveProject() { if (IsValidWritableProjectPath(doc.ProjectPath)) { doc.SaveProject(); } else { this.SaveProjectAs(); } } private void SaveProjectAs() { string path = view.DialogManager.GetSaveAsPath( "Save As", "Test Projects (*.nunit)|*.nunit"); if (path != null) { doc.SaveProject(path); view.PropertyView.ProjectPath.Text = doc.ProjectPath; } } #endregion #region Model EventHandlers private void OnProjectCreated() { view.CloseProjectCommand.Enabled = true; if (doc.IsValid) { view.SaveProjectCommand.Enabled = true; view.SaveProjectAsCommand.Enabled = true; } else { view.SaveProjectCommand.Enabled = false; view.SaveProjectAsCommand.Enabled = false; view.SelectedView = SelectedView.XmlView; } } private void OnProjectClosed() { view.CloseProjectCommand.Enabled = false; view.SaveProjectCommand.Enabled = false; view.SaveProjectAsCommand.Enabled = false; } #endregion #region Helper Methods private static bool IsValidWritableProjectPath(string path) { if (!Path.IsPathRooted(path)) return false; if (!ProjectDocument.IsProjectFile(path)) return false; if (!File.Exists(path)) return true; return (File.GetAttributes(path) & FileAttributes.ReadOnly) == 0; } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/MainForm.Designer.cs0000664000175000017500000003622711544330406024505 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class MainForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.indexToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPage1 = new System.Windows.Forms.TabPage(); this.tabPage2 = new System.Windows.Forms.TabPage(); this.propertyView = new NUnit.ProjectEditor.PropertyView(); this.xmlView = new NUnit.ProjectEditor.XmlView(); this.menuStrip1.SuspendLayout(); this.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); this.tabPage2.SuspendLayout(); this.SuspendLayout(); // // menuStrip1 // this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem, this.helpToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2); this.menuStrip1.Size = new System.Drawing.Size(594, 24); this.menuStrip1.TabIndex = 0; this.menuStrip1.Text = "menuStrip1"; // // fileToolStripMenuItem // this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.newToolStripMenuItem, this.openToolStripMenuItem, this.closeToolStripMenuItem, this.toolStripSeparator, this.saveToolStripMenuItem, this.saveAsToolStripMenuItem, this.toolStripSeparator1, this.exitToolStripMenuItem}); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Text = "&File"; // // newToolStripMenuItem // this.newToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripMenuItem.Image"))); this.newToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; this.newToolStripMenuItem.Name = "newToolStripMenuItem"; this.newToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); this.newToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.newToolStripMenuItem.Text = "&New"; // // openToolStripMenuItem // this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image"))); this.openToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; this.openToolStripMenuItem.Name = "openToolStripMenuItem"; this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); this.openToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.openToolStripMenuItem.Text = "&Open"; // // closeToolStripMenuItem // this.closeToolStripMenuItem.Name = "closeToolStripMenuItem"; this.closeToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.closeToolStripMenuItem.Text = "&Close"; // // toolStripSeparator // this.toolStripSeparator.Name = "toolStripSeparator"; this.toolStripSeparator.Size = new System.Drawing.Size(143, 6); // // saveToolStripMenuItem // this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image"))); this.saveToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); this.saveToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.saveToolStripMenuItem.Text = "&Save"; // // saveAsToolStripMenuItem // this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.saveAsToolStripMenuItem.Text = "Save &As"; // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; this.toolStripSeparator1.Size = new System.Drawing.Size(143, 6); // // exitToolStripMenuItem // this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; this.exitToolStripMenuItem.Size = new System.Drawing.Size(146, 22); this.exitToolStripMenuItem.Text = "E&xit"; this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); // // helpToolStripMenuItem // this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.contentsToolStripMenuItem, this.indexToolStripMenuItem, this.searchToolStripMenuItem, this.toolStripSeparator5, this.aboutToolStripMenuItem}); this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); this.helpToolStripMenuItem.Text = "&Help"; // // contentsToolStripMenuItem // this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; this.contentsToolStripMenuItem.Size = new System.Drawing.Size(122, 22); this.contentsToolStripMenuItem.Text = "&Contents"; // // indexToolStripMenuItem // this.indexToolStripMenuItem.Name = "indexToolStripMenuItem"; this.indexToolStripMenuItem.Size = new System.Drawing.Size(122, 22); this.indexToolStripMenuItem.Text = "&Index"; // // searchToolStripMenuItem // this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; this.searchToolStripMenuItem.Size = new System.Drawing.Size(122, 22); this.searchToolStripMenuItem.Text = "&Search"; // // toolStripSeparator5 // this.toolStripSeparator5.Name = "toolStripSeparator5"; this.toolStripSeparator5.Size = new System.Drawing.Size(119, 6); // // aboutToolStripMenuItem // this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; this.aboutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); this.aboutToolStripMenuItem.Text = "&About..."; this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); // // tabControl1 // this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(this.tabPage2); this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Location = new System.Drawing.Point(0, 24); this.tabControl1.Margin = new System.Windows.Forms.Padding(2); this.tabControl1.Multiline = true; this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; this.tabControl1.Size = new System.Drawing.Size(594, 434); this.tabControl1.TabIndex = 1; this.tabControl1.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabControl1_Selecting); this.tabControl1.Selected += new System.Windows.Forms.TabControlEventHandler(this.tabControl1_Selected); // // tabPage1 // this.tabPage1.BackColor = System.Drawing.Color.Gray; this.tabPage1.Controls.Add(this.propertyView); this.tabPage1.Location = new System.Drawing.Point(4, 22); this.tabPage1.Margin = new System.Windows.Forms.Padding(2); this.tabPage1.Name = "tabPage1"; this.tabPage1.Size = new System.Drawing.Size(586, 408); this.tabPage1.TabIndex = 0; this.tabPage1.Text = "Properties"; // // tabPage2 // this.tabPage2.BackColor = System.Drawing.Color.Gray; this.tabPage2.Controls.Add(this.xmlView); this.tabPage2.Location = new System.Drawing.Point(4, 22); this.tabPage2.Margin = new System.Windows.Forms.Padding(2); this.tabPage2.Name = "tabPage2"; this.tabPage2.Size = new System.Drawing.Size(586, 415); this.tabPage2.TabIndex = 1; this.tabPage2.Text = "XML View"; // // propertyView // this.propertyView.BackColor = System.Drawing.SystemColors.Control; this.propertyView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.propertyView.Dock = System.Windows.Forms.DockStyle.Fill; this.propertyView.Location = new System.Drawing.Point(0, 0); this.propertyView.Margin = new System.Windows.Forms.Padding(2); this.propertyView.Name = "propertyView"; this.propertyView.Size = new System.Drawing.Size(586, 408); this.propertyView.TabIndex = 0; this.propertyView.Visible = false; // // xmlView // this.xmlView.Dock = System.Windows.Forms.DockStyle.Fill; this.xmlView.Location = new System.Drawing.Point(0, 0); this.xmlView.Margin = new System.Windows.Forms.Padding(2); this.xmlView.Name = "xmlView"; this.xmlView.Size = new System.Drawing.Size(586, 415); this.xmlView.TabIndex = 0; this.xmlView.Visible = false; // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Control; this.ClientSize = new System.Drawing.Size(594, 458); this.Controls.Add(this.tabControl1); this.Controls.Add(this.menuStrip1); this.MainMenuStrip = this.menuStrip1; this.Margin = new System.Windows.Forms.Padding(2); this.Name = "MainForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; this.Text = "NUnit Project Editor"; this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); this.tabControl1.ResumeLayout(false); this.tabPage1.ResumeLayout(false); this.tabPage2.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator; private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem indexToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; private System.Windows.Forms.TabControl tabControl1; private System.Windows.Forms.TabPage tabPage1; private System.Windows.Forms.TabPage tabPage2; private XmlView xmlView; private PropertyView propertyView; private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem; } }NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/MainForm.cs0000664000175000017500000000770511544330406022745 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public delegate bool ViewClosingDelegate(); public partial class MainForm : Form, IMainView { #region Instance Variables private IMessageDisplay messageDisplay; private IDialogManager dialogManager; private ICommand newProjectCommand; private ICommand openProjectCommand; private ICommand closeProjectCommand; private ICommand saveProjectCommand; private ICommand saveProjectAsCommand; #endregion #region Constructor public MainForm() { InitializeComponent(); this.messageDisplay = new MessageDisplay("Nunit Project Editor"); this.dialogManager = new DialogManager("NUnit Project Editor"); this.newProjectCommand = new MenuElement(newToolStripMenuItem); this.openProjectCommand = new MenuElement(openToolStripMenuItem); this.closeProjectCommand = new MenuElement(closeToolStripMenuItem); this.saveProjectCommand = new MenuElement(saveToolStripMenuItem); this.saveProjectAsCommand = new MenuElement(saveAsToolStripMenuItem); } #endregion #region IMainView Members #region Events public event ActiveViewChangingHandler ActiveViewChanging; public event ActiveViewChangedHandler ActiveViewChanged; #endregion #region Properties public IDialogManager DialogManager { get { return dialogManager; } } public ICommand NewProjectCommand { get { return newProjectCommand; } } public ICommand OpenProjectCommand { get {return openProjectCommand; } } public ICommand CloseProjectCommand { get { return closeProjectCommand; } } public ICommand SaveProjectCommand { get { return saveProjectCommand; } } public ICommand SaveProjectAsCommand { get { return saveProjectAsCommand; } } public IXmlView XmlView { get { return xmlView; } } public IPropertyView PropertyView { get { return propertyView; } } public SelectedView SelectedView { get { return (SelectedView)tabControl1.SelectedIndex; } set { tabControl1.SelectedIndex = (int)value; } } public IMessageDisplay MessageDisplay { get { return messageDisplay; } } #endregion #endregion #region Event Handlers private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { AboutBox box = new AboutBox(); box.ShowDialog(this); } private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e) { if (ActiveViewChanging != null && !ActiveViewChanging()) e.Cancel = true; } private void tabControl1_Selected(object sender, TabControlEventArgs e) { if (ActiveViewChanged != null) ActiveViewChanged(); } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/MainForm.resx0000664000175000017500000002243711544330406023320 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEPSURBVDhPrdPZasJAFAZgX8q+Q32N9o2kXkjphQsigoJC ixa1VAWXiohG7IakbmjcNcYl5i8TCQSdGXPhgcPczHwz5xzGZrtWRN+bOM1wqo5gvAJfrIBy4w/cu8hh VjyG3nDjuOcjkbTABB58cSRy9SMiiPSXhF6rTMDpedEPG0ktJfD8wQT26gEEMSAq4I3mqYCmaZCVHQZj WQfst3f0Ep7CGSqw3amYzBWI/TkfcAdTZ4B60LCQt+hJK3yJEz7g8ifOAGWzhzRdo9WdofYt8QFSnzlI 42bLDdqDBZqtMUpC3zpgbtxPe4rq5xDZSsc6YG6c8DtCodZDsihaA4x5s1bmGI0Zkw2X8lofWHf+AdjM 9sNc+xBlAAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJQSURBVDhPlZNdSNNRGMb/F110ZZEVhVBgeeHNICiiuggp olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdPKMgr7kApFItTUkWZqVhSVYmao5Nev/xyoQ4k88Nyc 8z6/93nP4QjCfy6lwc4ltZVso4P/tMyXRcmMHqZ0EeY6jZQVInzuf0e1Tb9Ina3P/tkpLD6XkNg8BJe5 u93C+HDVrP4M2ZkcMOOw5tLZ9nxJyJE4HSExBoKkBQhVpTrGhso9zNPfiph0JlB+U01ZcRbmwnRMeWlc 08opUCV6QissGsZ+WOY6z4hmuuXglC6pRYBbJSp+fzXNxnaZ66o1s3rkyKHWruJuWRYOcwZ2kxKr8TI3 DCkU6+QYNUnuNGWmLEY+5uOK3degoKZcx3SfEvozPfVB3OtNhi4ZvI2nrTIc23U9gtmYwa8eNXzScq8i l6bHWnfRwhHeREJzGFONgYw/CeB9qQSZNNR9FyUGBT87lfQ3plJj1zLTq4COGDegLVo0HmeqKZjx+gOM PNzDYPU2lLF+4jhyN6BIl8pgexK3bRpaXopJuhJEwGloiWDmVSgTLw4xWreXoZrtfK/wp/nKak4E+s6/ hDFHTkd9GndsOdCTBq1i3NdHmWgIYvRpAMO1OxlwSPhi2YpT641CuoWzsSfnAfnZiVRZ1Tjvx9GsF+bU pF1BvWolD9JXUZmyDnOiD1cvbCZiYXfXCPrMi+gVZ8hOiiL53DHORwdzKnw/hw/uYt9uCTskfvj7+rBp 41rWr/Fig7fX8j/Tsn/fcgx/ARfG3ml6M3rzAAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIsSURBVDhPrZPdS5NxFMf3L3TfTdBFtzU1hmuxGjzlHMqq YVgRvT2RL+XSZZqoWJlGLV8gW+HSScvpJJxU+AamSI2hTCVLM1e0xKGm2EQw+PY7v+j5tTIvoh+cy8/n POec76NS/Y/37GkUVL72ZbR5l/DYvYDGhgjuO2ZQW/MJ9tsh3CifQmnJBAoLXiMvdxQXzgeh9Cawtweo qV7FRm9ldQ3GtF4cTnvCSxF4Wxe5oLLiy195giMLK9htfg61WoblkEcI3I/muaC05PO6gp/w+/Ai4kw+ FFyexgFzkxA462e54JLt3R+CX+GRyQi2SV5Yc8aRmuIUgrq7YS7IzhqNEfwODwbD2Kx3Q5YDMJkcQlBd 9ZEL5DMBRbAe3OP/gE2JDThy9AWSkmqF4GblNLq7wE4JHD/5CpZjA3zbtDCamT6bOv+A+3DQ0glJsgvB 1bJJdPjAMgA0ub6xu39F+fU5vlRaGM2cmRFU4OTUdhgMFUJwpXAcnmbgoXONBScKY3pOTJlP2JB+roh3 Tk5h8H4P9PoyIbDljTEYqLoT5Z1JwEKCOK2EobezGJuag5x7DXuNbRzW7nFBpysSAoql4x6UzyYBwWfz b+FNaB6hmSVcLLYjXu9icCPidz2ANjFfCDIzhtncy3zmrQYPtuyQ0NLRD1/XILr7/Bh4OYR9JgvUunok MHi7pg4ajVUIKNOnT/XzeFLCKCR0ZzoVbZsWRjNTVyqCdyZkxwr+9a/+Dk60OMVjMFpXAAAAAElFTkSu QmCC 25 NUnit-2.6.0.12051/src/ProjectEditor/editor/Main/IMainView.cs0000664000175000017500000000300711544330406023054 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public delegate bool ActiveViewChangingHandler(); public delegate void ActiveViewChangedHandler(); /// /// IMainView represents the top level view for the /// Project editor. It provides a menu commands and several /// utility methods used in opening and saving files. It /// aggregates the property and xml views. /// public interface IMainView : IView { IDialogManager DialogManager { get; } ICommand NewProjectCommand { get; } ICommand OpenProjectCommand { get; } ICommand CloseProjectCommand { get; } ICommand SaveProjectCommand { get; } ICommand SaveProjectAsCommand { get; } event ActiveViewChangingHandler ActiveViewChanging; event ActiveViewChangedHandler ActiveViewChanged; event FormClosingEventHandler FormClosing; IPropertyView PropertyView { get; } IXmlView XmlView { get; } SelectedView SelectedView { get; set; } } public enum SelectedView { PropertyView = 0, XmlView = 1 } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Program.cs0000664000175000017500000000433511626127754021767 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.Windows.Forms; using System.Xml; namespace NUnit.ProjectEditor { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); #if DEBUG //MessageBox.Show("Attach to editor if desired", "Debug ProjectEditor?"); #endif // Set up main editor triad ProjectDocument doc = new ProjectDocument(); MainForm view = new MainForm(); MainPresenter presenter = new MainPresenter(doc, view); // TODO: Process arguments // -new = create new project // -config=name = create a new config (implies -new) // assemblyName = add assembly to the last config specified (or Default) if (args.Length == 1 && ProjectDocument.IsProjectFile(args[0])) doc.OpenProject(args[0]); else if (args.Length > 0) { doc.CreateNewProject(); XmlNode configNode = XmlHelper.AddElement(doc.RootNode, "Config"); XmlHelper.AddAttribute(configNode, "name", "Default"); foreach (string fileName in args) { if (PathUtils.IsAssemblyFileType(fileName)) { XmlNode assemblyNode = XmlHelper.AddElement(configNode, "assembly"); XmlHelper.AddAttribute(assemblyNode, "path", fileName); } } // Simulate view change so view gets updated presenter.ActiveViewChanged(); } Application.Run(view); } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/PathUtils.cs0000664000175000017500000001720311703246052022260 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Text; using System.Reflection; using System.Collections.Generic; using System.Runtime.InteropServices; namespace NUnit.ProjectEditor { /// /// Static methods for manipulating doc paths, including both directories /// and files. Some synonyms for System.Path methods are included as well. /// public class PathUtils { public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; public const int MAX_PATH = 256; protected static char DirectorySeparatorChar = Path.DirectorySeparatorChar; protected static char AltDirectorySeparatorChar = Path.AltDirectorySeparatorChar; #region Public methods public static bool IsAssemblyFileType( string path ) { string extension = Path.GetExtension( path ).ToLower(); return extension == ".dll" || extension == ".exe"; } /// /// Returns the relative path from a base directory to another /// directory or file. /// public static string RelativePath( string from, string to ) { if (from == null) throw new ArgumentNullException (from); if (to == null) throw new ArgumentNullException (to); string toPathRoot = Path.GetPathRoot(to); if (toPathRoot == null || toPathRoot == string.Empty) return to; string fromPathRoot = Path.GetPathRoot(from); if (!PathsEqual(toPathRoot, fromPathRoot)) return null; string fromNoRoot = from.Substring(fromPathRoot.Length); string toNoRoot = to.Substring(toPathRoot.Length); string[] _from = SplitPath(fromNoRoot); string[] _to = SplitPath(toNoRoot); StringBuilder sb = new StringBuilder (Math.Max (from.Length, to.Length)); int last_common, min = Math.Min (_from.Length, _to.Length); for (last_common = 0; last_common < min; ++last_common) { if (!PathsEqual(_from[last_common], _to[last_common])) break; } if (last_common < _from.Length) sb.Append (".."); for (int i = last_common + 1; i < _from.Length; ++i) { sb.Append (PathUtils.DirectorySeparatorChar).Append (".."); } if (sb.Length > 0) sb.Append (PathUtils.DirectorySeparatorChar); if (last_common < _to.Length) sb.Append (_to [last_common]); for (int i = last_common + 1; i < _to.Length; ++i) { sb.Append (PathUtils.DirectorySeparatorChar).Append (_to [i]); } return sb.ToString (); } /// /// Return the canonical form of a path. /// public static string Canonicalize( string path ) { List parts = new List( path.Split( DirectorySeparatorChar, AltDirectorySeparatorChar ) ); for( int index = 0; index < parts.Count; ) { string part = parts[index]; switch( part ) { case ".": parts.RemoveAt( index ); break; case "..": parts.RemoveAt( index ); if ( index > 0 ) parts.RemoveAt( --index ); break; default: index++; break; } } return String.Join( DirectorySeparatorChar.ToString(), parts.ToArray() ); } /// /// True if the two paths are the same. However, two paths /// to the same file or directory using different network /// shares or drive letters are not treated as equal. /// public static bool SamePath( string path1, string path2 ) { return string.Compare( Canonicalize(path1), Canonicalize(path2), PathUtils.IsWindows() ) == 0; } /// /// True if the two paths are the same or if the second is /// directly or indirectly under the first. Note that paths /// using different network shares or drive letters are /// considered unrelated, even if they end up referencing /// the same subtrees in the file system. /// public static bool SamePathOrUnder( string path1, string path2 ) { path1 = Canonicalize( path1 ); path2 = Canonicalize( path2 ); int length1 = path1.Length; int length2 = path2.Length; // if path1 is longer, then path2 can't be under it if ( length1 > length2 ) return false; // if lengths are the same, check for equality if ( length1 == length2 ) return string.Compare( path1, path2, IsWindows() ) == 0; // path 2 is longer than path 1: see if initial parts match if ( string.Compare( path1, path2.Substring( 0, length1 ), IsWindows() ) != 0 ) return false; // must match through or up to a directory separator boundary return path2[length1-1] == DirectorySeparatorChar || path2[length1] == DirectorySeparatorChar; } public static string Combine( string path1, params string[] morePaths ) { string result = path1; foreach( string path in morePaths ) result = Path.Combine( result, path ); return result; } // TODO: This logic should be in shared source public static string GetAssemblyPath( Assembly assembly ) { string uri = assembly.CodeBase; // If it wasn't loaded locally, use the Location if ( !uri.StartsWith( Uri.UriSchemeFile ) ) return assembly.Location; return GetAssemblyPathFromFileUri( uri ); } // Separate method for testability public static string GetAssemblyPathFromFileUri( string uri ) { // Skip over the file:// int start = Uri.UriSchemeFile.Length + Uri.SchemeDelimiter.Length; if ( PathUtils.DirectorySeparatorChar == '\\' ) { if ( uri[start] == '/' && uri[start+2] == ':' ) ++start; } else { if ( uri[start] != '/' ) --start; } return uri.Substring( start ); } #endregion #region Helper Methods private static bool IsWindows() { return PathUtils.DirectorySeparatorChar == '\\'; } private static string[] SplitPath(string path) { char[] separators = new char[] { PathUtils.DirectorySeparatorChar, PathUtils.AltDirectorySeparatorChar }; #if CLR_2_0 || CLR_4_0 return path.Split(separators, StringSplitOptions.RemoveEmptyEntries); #else string[] trialSplit = path.Split(separators); int emptyEntries = 0; foreach(string piece in trialSplit) if (piece == string.Empty) emptyEntries++; if (emptyEntries == 0) return trialSplit; string[] finalSplit = new string[trialSplit.Length - emptyEntries]; int index = 0; foreach(string piece in trialSplit) if (piece != string.Empty) finalSplit[index++] = piece; return finalSplit; #endif } private static bool PathsEqual(string path1, string path2) { #if CLR_2_0 || CLR_4_0 if (PathUtils.IsWindows()) return path1.Equals(path2, StringComparison.InvariantCultureIgnoreCase); else return path1.Equals(path2, StringComparison.InvariantCulture); #else if (PathUtils.IsWindows()) return path1.ToLower().Equals(path2.ToLower()); else return path1.Equals(path2); #endif } #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/nunit-editor.csproj0000664000175000017500000001746511703053512023666 0ustar jtaylorjtaylor Debug AnyCPU 9.0.30729 2.0 {ED57DCEC-3C16-4A90-BD3C-4D5BE5AD70FB} WinExe Properties NUnit.ProjectEditor nunit-editor v2.0 512 App.ico true full false ..\..\..\bin\Debug\ TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 prompt 4 pdbonly true ..\..\..\bin\Release\ TRACE;CLR_2_0,NET_2_0,CS_3_0 prompt 4 Form AboutBox.cs AddConfigurationDialog.cs ConfigurationEditorView.cs RenameConfigurationDialog.cs Form MainForm.cs Form Form Form UserControl PropertyView.cs AboutBox.cs Designer AddConfigurationDialog.cs Designer ConfigurationEditorView.cs Designer RenameConfigurationDialog.cs Designer MainForm.cs Designer PropertyView.cs Designer XmlView.cs Designer UserControl XmlView.cs NUnit-2.6.0.12051/src/ProjectEditor/editor/AboutBox.Designer.cs0000664000175000017500000002504711544330406023632 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class AboutBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox)); this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.logoPictureBox = new System.Windows.Forms.PictureBox(); this.labelProductName = new System.Windows.Forms.Label(); this.labelVersion = new System.Windows.Forms.Label(); this.labelCopyright = new System.Windows.Forms.Label(); this.labelCompanyName = new System.Windows.Forms.Label(); this.textBoxDescription = new System.Windows.Forms.TextBox(); this.okButton = new System.Windows.Forms.Button(); this.tableLayoutPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); this.SuspendLayout(); // // tableLayoutPanel // this.tableLayoutPanel.ColumnCount = 2; this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F)); this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F)); this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0); this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0); this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1); this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2); this.tableLayoutPanel.Controls.Add(this.labelCompanyName, 1, 3); this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 1, 4); this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5); this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel.Location = new System.Drawing.Point(12, 11); this.tableLayoutPanel.Margin = new System.Windows.Forms.Padding(4); this.tableLayoutPanel.Name = "tableLayoutPanel"; this.tableLayoutPanel.RowCount = 6; this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F)); this.tableLayoutPanel.Size = new System.Drawing.Size(556, 326); this.tableLayoutPanel.TabIndex = 0; // // logoPictureBox // this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.logoPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("logoPictureBox.Image"))); this.logoPictureBox.Location = new System.Drawing.Point(4, 4); this.logoPictureBox.Margin = new System.Windows.Forms.Padding(4); this.logoPictureBox.Name = "logoPictureBox"; this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6); this.logoPictureBox.Size = new System.Drawing.Size(175, 318); this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.logoPictureBox.TabIndex = 12; this.logoPictureBox.TabStop = false; // // labelProductName // this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelProductName.Location = new System.Drawing.Point(191, 0); this.labelProductName.Margin = new System.Windows.Forms.Padding(8, 0, 4, 0); this.labelProductName.MaximumSize = new System.Drawing.Size(0, 21); this.labelProductName.Name = "labelProductName"; this.labelProductName.Size = new System.Drawing.Size(361, 21); this.labelProductName.TabIndex = 19; this.labelProductName.Text = "Product Name"; this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // labelVersion // this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; this.labelVersion.Location = new System.Drawing.Point(191, 32); this.labelVersion.Margin = new System.Windows.Forms.Padding(8, 0, 4, 0); this.labelVersion.MaximumSize = new System.Drawing.Size(0, 21); this.labelVersion.Name = "labelVersion"; this.labelVersion.Size = new System.Drawing.Size(361, 21); this.labelVersion.TabIndex = 0; this.labelVersion.Text = "Version"; this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // labelCopyright // this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCopyright.Location = new System.Drawing.Point(191, 64); this.labelCopyright.Margin = new System.Windows.Forms.Padding(8, 0, 4, 0); this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 21); this.labelCopyright.Name = "labelCopyright"; this.labelCopyright.Size = new System.Drawing.Size(361, 21); this.labelCopyright.TabIndex = 21; this.labelCopyright.Text = "Copyright"; this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // labelCompanyName // this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelCompanyName.Location = new System.Drawing.Point(191, 96); this.labelCompanyName.Margin = new System.Windows.Forms.Padding(8, 0, 4, 0); this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 21); this.labelCompanyName.Name = "labelCompanyName"; this.labelCompanyName.Size = new System.Drawing.Size(361, 21); this.labelCompanyName.TabIndex = 22; this.labelCompanyName.Text = "Company Name"; this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // textBoxDescription // this.textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill; this.textBoxDescription.Location = new System.Drawing.Point(191, 132); this.textBoxDescription.Margin = new System.Windows.Forms.Padding(8, 4, 4, 4); this.textBoxDescription.Multiline = true; this.textBoxDescription.Name = "textBoxDescription"; this.textBoxDescription.ReadOnly = true; this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both; this.textBoxDescription.Size = new System.Drawing.Size(361, 155); this.textBoxDescription.TabIndex = 23; this.textBoxDescription.TabStop = false; this.textBoxDescription.Text = "Description"; // // okButton // this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.okButton.Location = new System.Drawing.Point(452, 295); this.okButton.Margin = new System.Windows.Forms.Padding(4); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(100, 27); this.okButton.TabIndex = 24; this.okButton.Text = "&OK"; // // AboutBox // this.AcceptButton = this.okButton; this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(580, 348); this.Controls.Add(this.tableLayoutPanel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Margin = new System.Windows.Forms.Padding(4); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "AboutBox"; this.Padding = new System.Windows.Forms.Padding(12, 11, 12, 11); this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "About ProjectEditor"; this.tableLayoutPanel.ResumeLayout(false); this.tableLayoutPanel.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; private System.Windows.Forms.PictureBox logoPictureBox; private System.Windows.Forms.Label labelProductName; private System.Windows.Forms.Label labelVersion; private System.Windows.Forms.Label labelCopyright; private System.Windows.Forms.Label labelCompanyName; private System.Windows.Forms.TextBox textBoxDescription; private System.Windows.Forms.Button okButton; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/Delegates.cs0000664000175000017500000000076111544330406022241 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.ProjectEditor { public delegate void ActionDelegate(); public delegate void CommandDelegate(); public delegate bool ActionStartingDelegate(); } NUnit-2.6.0.12051/src/ProjectEditor/editor/IView.cs0000664000175000017500000000160311544330406021363 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// Common interface implemented by all views used in /// the ProjectEditor application /// public interface IView { /// /// Object that knows how to display various messages /// in a MessageBox. /// IMessageDisplay MessageDisplay { get; } /// /// Gets or sets the visibility of the view /// bool Visible { get; set; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/0000775000175000017500000000000011742560362021726 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/XmlView.Designer.cs0000664000175000017500000000655711544330406025416 0ustar jtaylorjtaylornamespace NUnit.ProjectEditor { partial class XmlView { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.errorMessageLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // richTextBox1 // this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.richTextBox1.Font = new System.Drawing.Font("Courier New", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.richTextBox1.HideSelection = false; this.richTextBox1.Location = new System.Drawing.Point(0, 0); this.richTextBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); this.richTextBox1.Name = "richTextBox1"; this.richTextBox1.Size = new System.Drawing.Size(346, 227); this.richTextBox1.TabIndex = 0; this.richTextBox1.Text = ""; this.richTextBox1.WordWrap = false; // // errorMessageLabel // this.errorMessageLabel.BackColor = System.Drawing.SystemColors.Window; this.errorMessageLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.errorMessageLabel.Dock = System.Windows.Forms.DockStyle.Bottom; this.errorMessageLabel.ForeColor = System.Drawing.Color.Red; this.errorMessageLabel.Location = new System.Drawing.Point(0, 193); this.errorMessageLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.errorMessageLabel.Name = "errorMessageLabel"; this.errorMessageLabel.Size = new System.Drawing.Size(346, 34); this.errorMessageLabel.TabIndex = 1; this.errorMessageLabel.Text = "label1"; // // XmlView // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.errorMessageLabel); this.Controls.Add(this.richTextBox1); this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); this.Name = "XmlView"; this.Size = new System.Drawing.Size(346, 227); this.ResumeLayout(false); } #endregion private System.Windows.Forms.RichTextBox richTextBox1; private System.Windows.Forms.Label errorMessageLabel; } } NUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/XmlPresenter.cs0000664000175000017500000000470111544330406024701 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Xml; namespace NUnit.ProjectEditor { public class XmlPresenter { private IProjectDocument doc; private IXmlView view; public XmlPresenter(IProjectDocument doc, IXmlView view) { this.doc = doc; this.view = view; view.Xml.Validated += delegate { UpdateModelFromView(); if (!doc.IsValid) { XmlException ex = doc.Exception as XmlException; if (ex != null) view.DisplayError(ex.Message, ex.LineNumber, ex.LinePosition); else view.DisplayError(doc.Exception.Message); } }; doc.ProjectCreated += delegate { view.Visible = true; LoadViewFromModel(); }; doc.ProjectClosed += delegate { view.Xml.Text = null; view.Visible = false; }; } public void LoadViewFromModel() { view.Xml.Text = doc.XmlText; if (doc.Exception != null) { XmlException ex = doc.Exception as XmlException; if (ex != null) view.DisplayError(ex.Message, ex.LineNumber, ex.LinePosition); else view.DisplayError(doc.Exception.Message); } else view.RemoveError(); } private int GetOffset(int lineNumber, int charPosition) { int offset = 0; for (int lineCount = 1; lineCount < lineNumber; lineCount++ ) { int next = doc.XmlText.IndexOf(Environment.NewLine, offset); if (next < 0) break; offset = next + Environment.NewLine.Length; } return offset - lineNumber + charPosition; } public void UpdateModelFromView() { doc.XmlText = view.Xml.Text; } } } NUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/IXmlView.cs0000664000175000017500000000334311544330406023756 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { /// /// IXmlView is the interface implemented by the XmlView /// and consumed by the XmlPresenter. /// public interface IXmlView : IView { /// /// Gets or sets the XML text /// ITextElement Xml { get; } /// /// Display an error message at bottom of the view, /// adjusting the text to make edit box to make room. /// /// The message to display void DisplayError(string message); /// /// Display an error message at bottom of the view, /// adjusting the text to make edit box to make room /// and highlighting the text that caused the error. /// /// The message to display /// The line number in which the error occured. /// The position in the line that caused the error. void DisplayError(string message, int lineNumber, int linePosition); /// /// Remove any error message from the view, adjusting /// the edit box so it uses all the space. /// void RemoveError(); } } NUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/XmlView.cs0000664000175000017500000000526611544330406023653 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.ComponentModel; using System.Windows.Forms; using NUnit.ProjectEditor.ViewElements; namespace NUnit.ProjectEditor { public partial class XmlView : UserControl, IXmlView { #region Instance Variables private ITextElement xml; private IMessageDisplay messageDisplay; #endregion #region Constructor /// /// Constructor /// public XmlView() { InitializeComponent(); xml = new TextElement(richTextBox1); messageDisplay = new MessageDisplay("NUnit Project Editor"); } #endregion #region IXmlView Members /// /// Gets or sets the XML text /// public ITextElement Xml { get { return xml; } } public void DisplayError(string message) { errorMessageLabel.Visible = true; errorMessageLabel.Text = message; richTextBox1.Dock = DockStyle.Top; richTextBox1.Height = this.ClientSize.Height - errorMessageLabel.Height; } public void DisplayError(string message, int lineNumber, int linePosition) { DisplayError(message); if (lineNumber > 0 && linePosition > 0) { int offset = richTextBox1.GetFirstCharIndexFromLine(lineNumber - 1) + linePosition - 1; int length = 0; string text = richTextBox1.Text; if (char.IsLetterOrDigit(text[offset])) while (char.IsLetterOrDigit(text[offset + length])) length++; else length = 1; richTextBox1.Select(offset, length); } } public void RemoveError() { errorMessageLabel.Visible = false; richTextBox1.Dock = DockStyle.Fill; } public IMessageDisplay MessageDisplay { get { return messageDisplay; } } #endregion #region Event Handlers //private void richTextBox1_Validated(object sender, EventArgs e) //{ // if (XmlChanged != null) // XmlChanged(); //} #endregion } } NUnit-2.6.0.12051/src/ProjectEditor/editor/XmlEditor/XmlView.resx0000664000175000017500000001326611544330406024226 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NUnit-2.6.0.12051/src/ProjectEditor/editor/IDialog.cs0000664000175000017500000000120211544330406021643 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; namespace NUnit.ProjectEditor { /// /// Common interface implemented by all modal dialog views used in /// the ProjectEditor application /// public interface IDialog : IView { DialogResult ShowDialog(); void Close(); } } NUnit-2.6.0.12051/src/ProjectEditor/editor/AboutBox.cs0000664000175000017500000000723011544330406022065 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Reflection; using System.Windows.Forms; namespace NUnit.ProjectEditor { partial class AboutBox : Form { public AboutBox() { InitializeComponent(); this.Text = String.Format("About {0} {0}", AssemblyTitle); this.labelProductName.Text = AssemblyProduct; this.labelVersion.Text = String.Format("Version {0} {0}", AssemblyVersion); this.labelCopyright.Text = AssemblyCopyright; this.labelCompanyName.Text = AssemblyCompany; this.textBoxDescription.Text = AssemblyDescription; } #region Assembly Attribute Accessors public string AssemblyTitle { get { object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); if (attributes.Length > 0) { AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; if (titleAttribute.Title != "") { return titleAttribute.Title; } } return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); } } public string AssemblyVersion { get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); } } public string AssemblyDescription { get { object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyDescriptionAttribute)attributes[0]).Description; } } public string AssemblyProduct { get { object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyProductAttribute)attributes[0]).Product; } } public string AssemblyCopyright { get { object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; } } public string AssemblyCompany { get { object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyCompanyAttribute)attributes[0]).Company; } } #endregion } } NUnit-2.6.0.12051/src/nunit.snk0000664000175000017500000000075211504175260015625 0ustar jtaylorjtaylor$RSA2J 5Km 9@ j2v>-ri ^V<㓬=֢ gn&FhIaR_uF+J|1 ВQmR3GKOF c! 7:#1Vdz6!ͧ3 IbexL:k|+W]n-_9"nE;ν+Z) i0{,58Zsr2GHZYDgsb,1烵?ϤL#W;aY#P箎ixA?ʕAYq%X[3OCj*Mx!Geto7[!1\4DH(9pK fTqQJBq[i~=UHGZG/b/3/\>eNojQ/G\[@Mţč0Ԏ}MrG_KՌux!K.r"w_1/N. Por ejemplo, si KeyFile // se encuentra en el directorio del proyecto, el atributo AssemblyKeyFile se especifica // como [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Firma retardada es una opcin avanzada; consulte la documentacin de // Microsoft .NET Framework para obtener ms informacin. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/PNUnit/agent/PNUnitTestRunner.cs0000664000175000017500000004373711702655074022004 0ustar jtaylorjtaylorusing System; using System.IO; using System.Threading; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; using System.Reflection; using System.Resources; using PNUnit.Framework; using NUnit.Core; using NUnit.Util; using log4net; namespace PNUnit.Agent { public class PNUnitTestRunner { private delegate TestResult RunTestWithTimeoutDelegate(ConsoleWriter outStream, TestDomain testDomain); private static readonly ILog log = LogManager.GetLogger(typeof(PNUnitTestRunner)); private PNUnitTestInfo mPNUnitTestInfo; private AgentConfig mConfig; private static object obj = new object(); private bool mbUseDomainPool = false; private int TEST_TIMEOUT = 600000; public PNUnitTestRunner( PNUnitTestInfo info, AgentConfig config) { mConfig = config; mPNUnitTestInfo = info; mbUseDomainPool = config.UseDomainPool; } public void Run() { log.Debug("Spawning a new thread"); Thread thread = new Thread(new ThreadStart(ThreadProc)); thread.Start(); } private static Queue mFreeDomains = new Queue(); private void ThreadProc() { TestResult result = null; TestDomain testDomain = null; TestConsoleAccess consoleAccess = new TestConsoleAccess(); try { log.DebugFormat("Thread entered for Test {0}:{1} Assembly {2}", mPNUnitTestInfo.TestName, mPNUnitTestInfo.TestToRun, mPNUnitTestInfo.AssemblyName); ConsoleWriter outStream = new ConsoleWriter(Console.Out); ConsoleWriter errorStream = new ConsoleWriter(Console.Error); testDomain = SetupTest(consoleAccess); if( testDomain == null ) return; log.Debug("Running tests"); try { if(mConfig.NoTimeout) { result = RunTest(outStream, testDomain); } else { RunTestWithTimeoutDelegate deleg = new RunTestWithTimeoutDelegate( RunTest); IAsyncResult ar = deleg.BeginInvoke(outStream, testDomain, null, new object()); if (!ar.AsyncWaitHandle.WaitOne(TEST_TIMEOUT, false)) { testDomain.CancelRun(); throw new Exception("Test timeout exception"); } else { result = deleg.EndInvoke(ar); } } } catch( Exception e ) { result = BuildError(e, consoleAccess); log.ErrorFormat("Error running test {0}", e.Message); } } finally { log.Info("Notifying the results"); log.Debug("////////////////////////////////////////Notifying the results/////////////////////////"); mPNUnitTestInfo.Services.NotifyResult( mPNUnitTestInfo.TestName, BuildResult(result, consoleAccess, mPNUnitTestInfo)); log.Debug("////////////////////////////////////////Results NOTIFIED/////////////////////////"); result = null; ReleaseDomain(testDomain); } } private TestResult RunTest(ConsoleWriter outStream, TestDomain testDomain) { EventListener collector = new EventCollector( outStream ); ITestFilter filter = new NUnit.Core.Filters.SimpleNameFilter(mPNUnitTestInfo.TestToRun); TestResult result = FindResult( mPNUnitTestInfo.TestToRun, testDomain.Run(collector, filter, false, LoggingThreshold.Off) ); return result; } private void ReleaseDomain(TestDomain testDomain) { #if !NET_2_0 lock(obj) #endif { lock( mFreeDomains.SyncRoot ) { log.Debug("************************ RELEASING A TESTDOMAIN ************************************"); if( mbUseDomainPool ) { mFreeDomains.Enqueue(testDomain); } else { testDomain.Unload(); } } } } private TestDomain SetupTest(TestConsoleAccess consoleAccess) { try { TestDomain result; lock( mFreeDomains.SyncRoot ) { log.Debug(">Locking mFreeDomains.SyncRoot"); if( mbUseDomainPool && mFreeDomains.Count > 0 ) { log.Debug("Reusing a previously created TestDomain"); result = mFreeDomains.Dequeue() as TestDomain; CreatePNUnitServices(result, consoleAccess); return result; } log.Debug("Creating a new TestDomain"); result = new TestDomain(); bool testLoaded = MakeTest( result, Path.Combine(mConfig.PathToAssemblies, mPNUnitTestInfo.AssemblyName), GetShadowCopyCacheConfig()); log.Debug("MakeTest executed"); if( !testLoaded ) { log.InfoFormat("Unable to locate test {0}", mPNUnitTestInfo.TestName); TestResult testResult = BuildError("Unable to locate tests", consoleAccess); mPNUnitTestInfo.Services.NotifyResult( mPNUnitTestInfo.TestName, testResult); return null; } log.Debug("Test loaded, going to set CurrentDirectory"); Directory.SetCurrentDirectory(mConfig.PathToAssemblies); // test directory ? log.Debug("Creating PNUnit services"); CreatePNUnitServices(result, consoleAccess); return result; } } finally { log.Debug("= 0; --i) if (args[i] == flag) { args[i] = null; return true; } return false; } private static string ReadArg(string[] args) { for (int i = 0; i < args.Length; ++i) if (args[i] != null) { string result = args[i]; args[i] = null; return result; } return null; } private static void ConfigureLogging() { string log4netpath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "agent.log.conf"); XmlConfigurator.Configure(new FileInfo(log4netpath)); } } public class PNUnitAgent : MarshalByRefObject, IPNUnitAgent { private AgentConfig mConfig; private static readonly ILog log = LogManager.GetLogger(typeof(PNUnitAgent)); #region IPNUnitAgent public void RunTest(PNUnitTestInfo info) { log.InfoFormat("RunTest called for Test {0}, AssemblyName {1}, TestToRun {2}", info.TestName, info.AssemblyName, info.TestToRun); new PNUnitTestRunner(info, mConfig).Run(); } #endregion #region MarshallByRefObject // Lives forever public override object InitializeLifetimeService() { return null; } #endregion private void ConfigureRemoting(int port) { if( File.Exists("agent.remoting.conf") ) { log.Info("Using agent.remoting.conf"); #if CLR_2_0 || CLR_4_0 RemotingConfiguration.Configure("agent.remoting.conf", false); #else RemotingConfiguration.Configure("agent.remoting.conf"); #endif return; } // init remoting BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; IDictionary props = new Hashtable(); props["port"] = port; string s = System.Guid.NewGuid().ToString(); props["name"] = s; props["typeFilterLevel"] = TypeFilterLevel.Full; try { TcpChannel chan = new TcpChannel( props, clientProvider, serverProvider); log.InfoFormat("Registering channel on port {0}", port); #if CLR_2_0 || CLR_4_0 ChannelServices.RegisterChannel(chan, false); #else ChannelServices.RegisterChannel(chan); #endif } catch (Exception e) { log.InfoFormat("Can't register channel.\n{0}", e.Message); return; } } public void Run(AgentConfig config, bool bDaemonMode) { if( config.UseDomainPool ) log.Info("Agent using a domain pool to launch tests"); mConfig = config; ConfigureRemoting(mConfig.Port); // publish RemotingServices.Marshal(this, PNUnit.Framework.Names.PNUnitAgentServiceName); // otherwise in .NET 2.0 memory grows continuosly FreeMemory(); if( bDaemonMode ) { // wait continously while (true) { Thread.Sleep(10000); } } else { string line; while( (line = Console.ReadLine()) != "" ) { switch( line ) { case "gc": Console.WriteLine("Cleaning up memory {0} Mb", GC.GetTotalMemory(true)/1024/1024); break; case "collect": Console.WriteLine("Collecting memory {0} Mb", GC.GetTotalMemory(false)/1024/1024); GC.Collect(); Console.WriteLine("Memory collected {0} Mb", GC.GetTotalMemory(false)/1024/1024); break; } } } //RemotingServices.Disconnect(this); } private void FreeMemory() { GC.GetTotalMemory(true); } } } NUnit-2.6.0.12051/src/PNUnit/agent/pnunit-agent.build0000664000175000017500000000274711564560102021665 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/agent/Ship.config0000664000175000017500000000542511564560102020321 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/agent/App.config0000664000175000017500000000542511564560102020136 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/agent/AgentConfig.cs0000664000175000017500000000143011564560102020732 0ustar jtaylorjtaylorusing System; using System.IO; using System.Xml.Serialization; namespace PNUnit.Agent { [Serializable] public class AgentConfig { public int Port; public string PathToAssemblies; public bool UseDomainPool; public bool NoTimeout; } public class AgentConfigLoader { public static AgentConfig LoadFromFile(string file) { FileStream reader = new FileStream(file, FileMode.Open, FileAccess.Read); try { XmlSerializer ser= new XmlSerializer(typeof(AgentConfig)); return (AgentConfig)ser.Deserialize(reader); } finally { reader.Close(); } } } } NUnit-2.6.0.12051/src/PNUnit/agent/pnunit-agent.csproj0000664000175000017500000001162611705311206022056 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {621C27DA-CC29-4663-9FE4-BF5A67970C18} Debug AnyCPU App.ico pnunit-agent JScript Grid IE50 false Exe agent OnBuildSuccess 0.0 v2.0 true ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt ..\..\..\lib\log4net.dll Code Code Code Code {61CE9CE5-943E-44D4-A381-814DC1406767} nunit.util.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} nunit.core.interfaces.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll {5261ABA1-98E6-4603-A4F0-59CAC307AC68} pnunit.framework NUnit-2.6.0.12051/src/PNUnit/launcher/0000775000175000017500000000000011742560362016732 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/PNUnit/launcher/App.ico0000664000175000017500000000206611504175260020145 0ustar jtaylorjtaylor &(( @wwwwwwwwwwwwwwpDDDDDDDDDDDDDDppppppppppppppppppppDDDDDDDDDDDDDDpLLLLLLLLLNItpDDDDDDDDDDDDD@( wwwwwwwDDDDDDDGOGOGOGOGOGOGOGOGHGLGDDDDDDNUnit-2.6.0.12051/src/PNUnit/launcher/MessageQueue.cs0000664000175000017500000001076211564560102021652 0ustar jtaylorjtaylorusing System; using System.Collections; using System.Threading; namespace PNUnit.Launcher { public class MessageQueue { private Object mLock = new Object(); private ArrayList mMessages = new ArrayList(); public MessageQueue() { } public void Send(string tag, int receivers, object message) { MessageData msg = null; Monitor.Enter(mLock); try { msg = AddMessage(tag, receivers, message); Monitor.PulseAll(mLock); } finally { Monitor.Exit(mLock); } msg.WaitForReceptions(); } public object Receive(string tag) { Monitor.Enter(mLock); try { object msg = null; while ((msg = GetMessage(tag)) == null) { Monitor.Wait(mLock); } return msg; } finally { Monitor.Exit(mLock); } } public void ISend(string tag, int receivers, object message) { Monitor.Enter(mLock); try { AddMessage(tag, receivers, message); Monitor.PulseAll(mLock); } finally { Monitor.Exit(mLock); } } public object IReceive(string tag) { Monitor.Enter(mLock); try { return GetMessage(tag); } finally { Monitor.Exit(mLock); } } private MessageData AddMessage(string tag, int receivers, object message) { MessageData msg = new MessageData(tag, receivers, message); mMessages.Add(msg); return msg; } private object GetMessage(string tag) { int index = 0; MessageData msg = null; for (;index< mMessages.Count; index++) { msg = mMessages[index] as MessageData; if (!msg.Tag.Equals(tag)) continue; msg.ConfirmReception(); break; } if (msg == null) return null; if (!msg.HasPendingReceivers()) mMessages.RemoveAt(index); return msg.Message; } private class MessageData { private object mLock = new object(); private string mTag; private int mReceivers; private object mMessage; internal MessageData(string tag, int receivers, object message) { this.mTag = tag; this.mReceivers = receivers; this.mMessage = message; } internal string Tag { get { return mTag; } } internal object Message { get { return mMessage; } } internal void WaitForReceptions() { Monitor.Enter(mLock); try { while(mReceivers > 0) { Monitor.Wait(mLock); } } finally { Monitor.Exit(mLock); } } internal void ConfirmReception() { Monitor.Enter(mLock); try { mReceivers--; Monitor.Pulse(mLock); } finally { Monitor.Exit(mLock); } } internal bool HasPendingReceivers() { Monitor.Enter(mLock); try { return mReceivers > 0; } finally { Monitor.Exit(mLock); } } } } } NUnit-2.6.0.12051/src/PNUnit/launcher/AssemblyInfo.cs0000664000175000017500000000501111504175260021644 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // La informacin general de un ensamblado se controla mediante el siguiente // conjunto de atributos. Cambie estos atributos para modificar la informacin // asociada con un ensamblado. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // La informacin de versin de un ensamblado consta de los siguientes cuatro valores: // // Versin principal // Versin secundaria // Versin de compilacin // Revisin // // Puede especificar todos los valores o usar los valores predeterminados (nmero de versin de compilacin y de revisin) // usando el smbolo '*' como se muestra a continuacin: [assembly: AssemblyVersion("1.0.*")] // // Si desea firmar el ensamblado, debe especificar una clave para su uso. Consulte la documentacin de // Microsoft .NET Framework para obtener ms informacin sobre la firma de ensamblados. // // Utilice los atributos siguientes para controlar qu clave desea utilizar para firmar. // // Notas: // (*) Si no se especifica ninguna clave, el ensamblado no se firma. // (*) KeyName se refiere a una clave instalada en el Proveedor de servicios // de cifrado (CSP) en el equipo. KeyFile se refiere a un archivo que contiene // una clave. // (*) Si se especifican los valores KeyFile y KeyName, tendr // lugar el siguiente proceso: // (1) Si KeyName se puede encontrar en el CSP, se utilizar dicha clave. // (2) Si KeyName no existe pero s KeyFile, se instalar // y utilizar la clave de KeyFile en el CSP. // (*) Para crear KeyFile, puede ejecutar la utilidad sn.exe (Strong Name). // Cuando se especifica KeyFile, la ubicacin de KeyFile debe ser // relativa al directorio de resultados del proyecto, que es // %Directorio del proyecto%\obj\. Por ejemplo, si KeyFile // se encuentra en el directorio del proyecto, el atributo AssemblyKeyFile se especifica // como [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Firma retardada es una opcin avanzada; consulte la documentacin de // Microsoft .NET Framework para obtener ms informacin. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/PNUnit/launcher/Runner.cs0000664000175000017500000002736411564560102020540 0ustar jtaylorjtaylorusing System; using System.Collections; using System.Threading; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; using log4net; using NUnit.Core; using PNUnit.Framework; namespace PNUnit.Launcher { public class Runner: MarshalByRefObject, IPNUnitServices { private static readonly ILog log = LogManager.GetLogger("launcher"); private const string agentkey = "_AGENT"; private int mInitialTime = Environment.TickCount; private ParallelTest mTestGroup; private Thread mThread = null; private IList mResults = null; private Object mResultLock = new Object(); private ManualResetEvent mFinish; private Hashtable mBarriers; private MessageQueue mMessageQueue = new MessageQueue(); private int mLaunchedTests; private Hashtable mBarriersOfTests; private Hashtable mUserValues; public Runner(ParallelTest test, Hashtable userValues) { mTestGroup = test; mResults = new ArrayList(); mUserValues = userValues; } public string TestGroupName { get{ return mTestGroup.Name; } } public void Run() { if( mTestGroup.Tests.Length == 0 ) { log.Fatal("No tests to run, exiting"); return; } mThread = new Thread(new ThreadStart(ThreadProc)); mThread.Start(); } public void Join() { if( mThread != null ) mThread.Join(); } private void ThreadProc() { log.DebugFormat( "Thread created for TestGroup {0} with {1} tests", mTestGroup.Name, mTestGroup.Tests.Length); mFinish = new ManualResetEvent(false); mBarriers = new Hashtable(); mBarriersOfTests = new Hashtable(); init = false; RemotingServices.Marshal(this, mTestGroup.Name); mLaunchedTests = 0; foreach( TestConf test in mTestGroup.Tests ) { if( test.Machine.StartsWith(agentkey) ) test.Machine = mTestGroup.Agents[int.Parse(test.Machine.Substring(agentkey.Length))]; Launcher.Log(string.Format("Starting {0} test {1} on {2}", mTestGroup.Name, test.Name, test.Machine)); // contact the machine try { IPNUnitAgent agent = (IPNUnitAgent) Activator.GetObject( typeof(IPNUnitAgent), string.Format( "tcp://{0}/{1}", test.Machine, PNUnit.Framework.Names.PNUnitAgentServiceName)); lock( mResultLock ) { ++mLaunchedTests; } PNUnitTestInfo testToRun = new PNUnitTestInfo( test.Name, test.Assembly, test.TestToRun, test.TestParams, this, test.StartBarrier, test.EndBarrier, test.WaitBarriers); testToRun.UserValues = mUserValues; agent.RunTest(testToRun); } catch( Exception e ) { Launcher.LogError(string.Format( "An error occurred trying to contact {0} [{1}]", test.Machine, e.Message)); lock( mResultLock ) { --mLaunchedTests; } } } log.DebugFormat("Thread going to wait for results for TestGroup {0}", mTestGroup.Name); if( HasToWait() ) // wait for all tests to end mFinish.WaitOne(); log.DebugFormat("Thread going to wait for NotifyResult to finish for TestGroup {0}", mTestGroup.Name); Thread.Sleep(500); // wait for the NotifyResult call to finish RemotingServices.Disconnect(this); log.DebugFormat("Thread going to finish for TestGroup {0}", mTestGroup.Name); } private bool HasToWait() { lock( mResultLock ) { return (mLaunchedTests > 0) && (mResults.Count < mLaunchedTests); } } public TestResult[] GetTestResults() { lock(mResultLock) { TestResult[] result = new TestResult[mResults.Count]; int i = 0; foreach( TestResult res in mResults ) result[i++] = res; return result; } } #region MarshallByRefObject // Lives forever public override object InitializeLifetimeService() { return null; } #endregion #region IPNUnitServices public void NotifyResult(string TestName, TestResult result) { log.DebugFormat("NotifyResult called for TestGroup {0}, Test {1}", mTestGroup.Name, TestName); int count = 0; lock( mResultLock ) { log.DebugFormat("NotifyResult lock entered for TestGroup {0}, Test {1}", mTestGroup.Name, TestName); mResults.Add(result); if( mResults.Count == mLaunchedTests ) { log.DebugFormat( "All the tests notified the results, waking up. mResults.Count == {0}", mResults.Count); mFinish.Set(); } count = mResults.Count; } lock( mBarriers ) { if( mBarriersOfTests.Contains(TestName) ) { log.DebugFormat("Going to abandon barriers of test {0}", TestName); IList list = (IList) mBarriersOfTests[TestName]; foreach( string barrier in list ) { log.DebugFormat("Abandoning barrier {0}", barrier); ((Barrier)mBarriers[barrier]).Abandon(); } } } log.DebugFormat( "NotifyResult finishing for TestGroup {0}, Test {1}.", mTestGroup.Name, TestName); string machine = GetTestConfFromName(TestName).Machine; string message = string.Format( "Result for TestGroup {0}, Test {1}: {2}. Time {3} ms. {4}/{5} tests finished. Agent: {6}", mTestGroup.Name, TestName, result.IsSuccess ? "PASS" : "FAIL", Environment.TickCount - mInitialTime, count, mLaunchedTests, machine); if( result.IsSuccess ) { Launcher.Log(message); Launcher.WriteTestLog(result, machine, "smoke-result.log"); } else { Launcher.LogError(message); Launcher.WriteTestLog(result, machine, "smoke-errors.log"); } } private TestConf GetTestConfFromName(string testName) { foreach( TestConf testConf in mTestGroup.Tests ) if( testConf.Name == testName ) return testConf; return null; } private void DoInitBarrier(string barrier, int Max, bool bOverwrite) { lock( mBarriers ) { if( !mBarriers.Contains(barrier) || bOverwrite) { mBarriers[barrier] = new Barrier(barrier, Max); } } } private void InitTestBarriers (string testName, string barrier) { if( mBarriersOfTests.Contains(testName) ) { IList listofbarriers = (IList) mBarriersOfTests[testName]; listofbarriers.Add(barrier); log.DebugFormat("Adding barrier {0} to {1}", barrier, testName); } else { ArrayList list = new ArrayList(); list.Add(barrier); log.DebugFormat("Adding barrier {0} to {1}", barrier, testName); mBarriersOfTests.Add(testName, list); } } private void InitTestBarriers (string testName, string[] barriers) { if (barriers != null && barriers.Length > 0) { foreach (string barrier in barriers) InitTestBarriers (testName, barrier); } } private object sync = new object(); private bool init = false; public void InitBarriers () { log.Debug("InitBarriers invoked"); lock (sync) { if (init) return; Hashtable barriers = new Hashtable(); for (int i=0; i< mTestGroup.Tests.Length; i++) { AddBarrier(mTestGroup.Tests[i].StartBarrier, barriers); AddBarrier(mTestGroup.Tests[i].EndBarrier, barriers); AddBarrier(mTestGroup.Tests[i].WaitBarriers, barriers); InitTestBarriers (mTestGroup.Tests[i].Name, mTestGroup.Tests[i].StartBarrier); InitTestBarriers (mTestGroup.Tests[i].Name, mTestGroup.Tests[i].EndBarrier); InitTestBarriers (mTestGroup.Tests[i].Name, mTestGroup.Tests[i].WaitBarriers); } foreach (string key in barriers.Keys) { DoInitBarrier (key, (int)barriers[key], false); } init = true; } } public void InitBarrier(string barrier, int max) { DoInitBarrier(barrier, max, true); } private void AddBarrier (string barrier, Hashtable barriers) { if (barrier != null && barrier.Trim() != string.Empty) { if(barriers.Contains(barrier)) barriers[barrier] = (int)barriers[barrier]+1; else barriers[barrier] = 1; } } private void AddBarrier(string[] barrier, Hashtable barriers) { if( barrier != null && barrier.Length > 0 ) { foreach( string b in barrier ) AddBarrier (b, barriers); } } public void EnterBarrier(string barrier) { log.DebugFormat(">Entering Barrier {0}", barrier); ((Barrier)mBarriers[barrier]).Enter(); log.DebugFormat(" NUnit-2.6.0.12051/src/PNUnit/launcher/pnunit-launcher.csproj0000664000175000017500000001176411705311206023267 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {91FC5C92-E801-4446-B4D6-EAC5B56A4DB2} Debug AnyCPU App.ico pnunit-launcher JScript Grid IE50 false Exe launcher OnBuildSuccess 0.0 v2.0 true ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt {61CE9CE5-943E-44D4-A381-814DC1406767} nunit.util.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} nunit.core.interfaces.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll {5261ABA1-98E6-4603-A4F0-59CAC307AC68} pnunit.framework ..\..\..\lib\log4net.dll Code Code Code Code Code NUnit-2.6.0.12051/src/PNUnit/launcher/Ship.config0000664000175000017500000000542511564560102021024 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/launcher/TestConf.cs0000664000175000017500000001361311564560102021004 0ustar jtaylorjtaylorusing System; using System.IO; using System.Collections; using System.Reflection; using System.Xml.Serialization; using PNUnit.Framework; namespace PNUnit.Launcher { [Serializable] public class TestGroup { public Variable[] Variables; public ParallelTest[] ParallelTests; } [Serializable] public class ParallelTest { public string Name; public string[] Agents; public TestConf[] Tests; } [Serializable] public class TestConf { public string Name; public string Assembly; public string TestToRun; public string Machine; public string[] TestParams; public string StartBarrier = Names.ServerBarrier; public string EndBarrier = Names.EndBarrier; public string[] WaitBarriers; } public class Variable { [XmlAttribute] public string name; [XmlAttribute] public string value; public override string ToString() { return string.Format("[{0}]=[{1}]", this.name, this.value); } } public class TestConfLoader { public static TestGroup LoadFromFile(string file, string[] args) { FileStream reader = new FileStream(file, FileMode.Open, FileAccess.Read); try { XmlSerializer ser = new XmlSerializer(typeof(TestGroup)); TestGroup result = (TestGroup)ser.Deserialize(reader); Variable[] processedVars = ParseVariablesFromCommandLine(args, result.Variables); ReplaceVariables(result.ParallelTests, processedVars); return result; } finally { reader.Close(); } } public static void WriteToFile(TestGroup group, string file) { FileStream writer = new FileStream(file, FileMode.Create, FileAccess.Write); try { XmlSerializer ser = new XmlSerializer(typeof(TestGroup)); ser.Serialize(writer, group); } finally { writer.Close(); } } // Variable replacement private static void ReplaceVariables(ParallelTest[] target, Variable[] variables) { if (variables == null || target == null) return; foreach (Variable var in variables) foreach (ParallelTest test in target) ReplaceVariableOnTest(test, var); } private static void ReplaceVariableOnTest(ParallelTest t, Variable var) { t.Agents = ReplaceVarArray(t.Agents, var); t.Name = ReplaceVar (t.Name, var); foreach (TestConf tc in t.Tests) { tc.Name = ReplaceVar(tc.Name, var); tc.Assembly = ReplaceVar(tc.Assembly, var); tc.TestToRun = ReplaceVar(tc.TestToRun, var); tc.Machine = ReplaceVar(tc.Machine, var); tc.TestParams = ReplaceVarArray(tc.TestParams, var); tc.StartBarrier = ReplaceVar(tc.StartBarrier, var); tc.EndBarrier = ReplaceVar(tc.EndBarrier, var); tc.WaitBarriers = ReplaceVarArray(tc.WaitBarriers, var); } } private static string[] ReplaceVarArray(string[] source, Variable var) { if (source == null) return null; for (int i = 0; i < source.Length; ++i) { source[i] = ReplaceVar(source[i], var); } return source; } private static string ReplaceVar(string source, Variable var) { if (source == null) return null; return source.Replace(var.name, var.value); } // Command line variable handling private static Variable[] ParseVariablesFromCommandLine( string[] args, Variable[] variables) { // variables from the command line, if defined, are prefixed with "-D:" if (args == null) return variables; IDictionary varsFromCli = ParseCliVars(args); if (varsFromCli == null) return variables; return MergeVars(varsFromCli, variables); } private static IDictionary ParseCliVars(string[] args) { Hashtable result = new Hashtable(); foreach (string s in args) { if (s.StartsWith("-D:") || s.StartsWith("-d:")) { Variable var = new Variable(); string[] v = s.Substring(3).Split('='); if (v.Length >= 1) { var.name = v[0]; if (v.Length == 2) var.value = v[1]; result[var.name] = var; } } } return (result.Count > 0) ? result: null; } private static Variable[] MergeVars(IDictionary overrides, IList originals) { ArrayList result = new ArrayList(); if( originals != null ) { foreach( Variable v in originals ) { Variable ovr = overrides[v.name] as Variable; if( ovr != null ) { v.value = ovr.value; overrides.Remove(v.name); } result.Add(v); } } foreach( Variable v in overrides.Values ) result.Add(v); return result.ToArray(typeof(Variable)) as Variable[]; } } } NUnit-2.6.0.12051/src/PNUnit/launcher/Barrier.cs0000664000175000017500000000273511564560102020650 0ustar jtaylorjtaylorusing System; using System.Threading; namespace PNUnit.Launcher { public class Barrier { public int mCount; public int mMaxCount; private Object mLock = new Object(); private string mName; private static int MAX_WAIT_TIME = 300 * 1000; //milliseconds public Barrier(string name, int maxCount) { mCount = 0; mName = name; mMaxCount = maxCount; } public void Enter() { lock( mLock ) { ++mCount; if( mCount == mMaxCount ) { Monitor.PulseAll(mLock); } else if( mCount < mMaxCount ) { if (!Monitor.Wait(mLock, MAX_WAIT_TIME)) { Console.WriteLine("Barrier {0} abandoned due to timeout!!!", mName); } } else { //nothing to do, entering in a barrier already used } } } public void Abandon() { lock( mLock ) { --mMaxCount; if( mCount >= mMaxCount ) { mCount = 0; Monitor.PulseAll(mLock); } } } } } NUnit-2.6.0.12051/src/PNUnit/launcher/App.config0000664000175000017500000000542511564560102020641 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/launcher/launcher.cs0000664000175000017500000004645611662075024021076 0ustar jtaylorjtaylorusing System; using System.Collections; using System.IO; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Serialization.Formatters; using NUnit.Core; using PNUnit.Framework; using log4net; using log4net.Config; namespace PNUnit.Launcher { class Launcher { private static readonly ILog log = LogManager.GetLogger("launcher"); static string mTestPath = string.Empty; static string mTotalLog = string.Empty; private static int MAX_TEST_RETRY = 3; [STAThread] static void Main(string[] args) { string resultfile = null; string failedfile = null; string passedfile = null; int retryOnFailure = 0; int maxRetry = MAX_TEST_RETRY; ConfigureLogging(); try { // Load the test configuration file if( args.Length == 0 ) { Console.WriteLine( "Usage: launcher configfile [--result=filename] [--failed=filename] [-D:var=value] [-val:variable=value] [--retry=number] [--range=from-to] [--test=testname]"); return; } string configfile = args[0]; mTestPath = Path.GetDirectoryName(configfile); TestGroup group = TestConfLoader.LoadFromFile(configfile, args); int startTest = 0; int endTest = group.ParallelTests.Length - 1; failedfile = Path.Combine(mTestPath, "smokefailed.conf"); passedfile = Path.Combine(mTestPath, "smokepassed.conf"); if( args.Length > 1 ) { foreach( string arg in args ) { if( arg.StartsWith("--result=") ) { resultfile = arg.Substring(9); resultfile = Path.GetFullPath(resultfile); } if( arg.StartsWith("--failed=") ) { failedfile = arg.Substring(9); failedfile = Path.GetFullPath(failedfile); } if( arg.StartsWith("--retry=") ) { retryOnFailure = int.Parse(arg.Substring("--retry=".Length)); log.InfoFormat("Retry on failure activated. {0} retries", retryOnFailure); maxRetry = retryOnFailure; } if(arg.StartsWith("--test=")) { string testName = arg.Substring("--test=".Length); int index = -1; for(int i=0; i< group.ParallelTests.Length; i++) { if(group.ParallelTests[i].Name != testName) continue; index = i; break; } if(index == -1) { Console.WriteLine("The specified test was not found"); return; } startTest = index; endTest = index; } if( arg.StartsWith("--range=") ) { string range = arg.Substring("--range=".Length); // now range should be something like xx-xx if( range.IndexOf("-") < 0 ) { Console.WriteLine("Test range incorrectly specified, it must be something like 0-10"); return; } string[] ranges = range.Split('-'); if( ranges.Length != 2 ) { Console.WriteLine("Test range incorrectly specified, it must be something like 0-10"); return; } startTest = int.Parse(ranges[0]); endTest = int.Parse(ranges[1]); if( (startTest > endTest) || (startTest < 0) || (startTest > group.ParallelTests.Length - 1) ) { Console.WriteLine("Start test must be in a correct test range"); return; } if( (endTest < startTest) || (endTest < 0) || (endTest > group.ParallelTests.Length - 1) ) { Console.WriteLine("End test must be in a correct test range"); return; } log.InfoFormat("Starting test range [{0}-{1}]", startTest, endTest); } } } if( (group == null) || (group.ParallelTests.Length == 0) ) { Console.WriteLine("No tests to run"); return; } Hashtable userValues = GetUserValues(args); ConfigureRemoting(); ArrayList failedGroups = new ArrayList(); ArrayList passedGroups = new ArrayList(); int testCount = endTest - startTest + 1; // Each parallel test is launched sequencially... Runner[] runners = new Runner[testCount]; DateTime beginTimestamp = DateTime.Now; for( int i = startTest; i <= endTest; ) { ParallelTest test = group.ParallelTests[i] as ParallelTest; int retryCount = 0; bool bRetry = true; while( bRetry && retryCount < maxRetry ) { bRetry = false; if( testCount != group.ParallelTests.Length ) log.InfoFormat("Test {0} of {1}. {2}/{3}", i, group.ParallelTests.Length, i-startTest+1, testCount); else log.InfoFormat("Test {0} of {1}", i+1, group.ParallelTests.Length); Runner runner = new Runner(test, userValues); runner.Run(); runners[i-startTest] = runner; // Wait to finish runner.Join(); TestResult[] runnerResults = runner.GetTestResults(); if( runnerResults == null ) { log.Info("Error. Results are NULL"); ++i; continue; } bRetry = RetryTest(runnerResults); bool bFailed = FailedTest(runnerResults); if( bRetry || ((bFailed && (retryOnFailure > 0) && ((retryCount + 1) < maxRetry ) ) /* so that list time is printed*/) ) { bRetry = true; ++retryCount; log.Info("Test failed with retry option, trying again"); continue; } if( bFailed ) { failedGroups.Add(test); WriteGroup(failedGroups, failedfile); } else { passedGroups.Add(test); WriteGroup(passedGroups, passedfile); } } // updated at the bottom so it's not affected by retries ++i; } DateTime endTimestamp = DateTime.Now; // Print the results double TotalBiggerTime = 0; int TotalTests = 0; int TotalExecutedTests = 0; int TotalFailedTests = 0; int TotalSuccessTests = 0; IList failedTests = new ArrayList(); int j; foreach( Runner runner in runners ) { int ExecutedTests = 0; int FailedTests = 0; int SuccessTests = 0; double BiggerTime = 0; TestResult[] results = runner.GetTestResults(); Log(string.Format("==== Tests Results for Parallel TestGroup {0} ===", runner.TestGroupName)); j = 0; foreach( TestResult res in results ) { if( res.Executed ) ++ExecutedTests; if( res.IsFailure ) ++FailedTests; if( res.IsSuccess ) ++SuccessTests; PrintResult(++j, res); if( res.Time > BiggerTime ) BiggerTime = res.Time; if( res.IsFailure ) failedTests.Add(res); } Log("Summary:"); Log(string.Format("\tTotal: {0}\r\n\tExecuted: {1}\r\n\tFailed: {2}\r\n\tSuccess: {3}\r\n\t% Success: {4}\r\n\tBiggest Execution Time: {5} s\r\n", results.Length, ExecutedTests, FailedTests, SuccessTests, results.Length > 0 ? 100 * SuccessTests / results.Length : 0, BiggerTime)); TotalTests += results.Length; TotalExecutedTests += ExecutedTests; TotalFailedTests += FailedTests; TotalSuccessTests += SuccessTests; TotalBiggerTime += BiggerTime; } // print all failed tests together if( failedTests.Count > 0 ) { Log("==== Failed tests ==="); for( j = 0; j < failedTests.Count; ++j ) PrintResult(j, failedTests[j] as PNUnitTestResult); } if( runners.Length > 1 ) { Log("Summary for all the parallel tests:"); Log(string.Format("\tTotal: {0}\r\n\tExecuted: {1}\r\n\tFailed: {2}\r\n\tSuccess: {3}\r\n\t% Success: {4}\r\n\tBiggest Execution Time: {5} s\r\n", TotalTests, TotalExecutedTests, TotalFailedTests, TotalSuccessTests, TotalTests > 0 ? 100 * TotalSuccessTests / TotalTests : 0, TotalBiggerTime)); } TimeSpan elapsedTime = endTimestamp.Subtract(beginTimestamp); Log(string.Format("Launcher execution time: {0} seconds", elapsedTime.TotalSeconds)); } finally { WriteResult(resultfile); } } private static bool FailedTest(TestResult[] results) { foreach( TestResult res in results ) { if (res == null) continue; if( !res.IsSuccess ) return true; } return false; } private static bool RetryTest(TestResult[] results) { foreach(TestResult res in results) { if (res == null) continue; if (res is PNUnitTestResult) { return ((PNUnitTestResult)res).RetryTest; } } return false; } private static void ConfigureRemoting() { if( File.Exists("launcher.remoting.conf") ) { log.InfoFormat("Using launcher.remoting.conf"); #if CLR_2_0 || CLR_4_0 RemotingConfiguration.Configure("launcher.remoting.conf", false); #else RemotingConfiguration.Configure("launcher.remoting.conf"); #endif return; } BinaryClientFormatterSinkProvider clientProvider = null; BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; IDictionary props = new Hashtable(); props["port"] = 0; props["typeFilterLevel"] = TypeFilterLevel.Full; TcpChannel chan = new TcpChannel( props,clientProvider,serverProvider); #if CLR_2_0 || CLR_4_0 ChannelServices.RegisterChannel(chan, false); #else ChannelServices.RegisterChannel(chan); #endif } private static void PrintResult(int testNumber, TestResult res) { string[] messages = GetErrorMessages(res); Log(string.Format("({0}) {1}", testNumber, messages[0])); if( !res.IsSuccess ) Log(messages[1]); } private static string[] GetErrorMessages(TestResult res) { string[] result = new string[2]; result[0] = string.Format( "Name: {0}\n Result: {1,-12} Assert Count: {2,-2} Time: {3,5}", res.Name, res.IsSuccess ? "SUCCESS" : (res.IsFailure ? "FAILURE" : (! res.Executed ? "NOT EXECUTED": "UNKNOWN")), res.AssertCount, res.Time); if( !res.IsSuccess ) result[1] = string.Format( "\nMessage: {0}\nStack Trace:\n{1}\r\n\r\n", res.Message, res.StackTrace); return result; } private static object mWriteTestLogLock = new object(); internal static void WriteTestLog( TestResult result, string machine, string fileName) { if( result == null ) return; lock( mWriteTestLogLock ) DoWriteTestLog(result, machine, fileName); } private static void DoWriteTestLog( TestResult result, string machine, string fileName) { FileStream fs = null; StreamWriter writer = null; try { fs = new FileStream( Path.Combine(mTestPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); fs.Seek(0, SeekOrigin.End); writer = new StreamWriter(fs); writer.WriteLine("=============================================================="); if( result.IsFailure ) { writer.WriteLine("Errors for test [{0}] run at agent [{1}]", result.Name, machine); string[] messages = GetErrorMessages(result); writer.WriteLine(messages[0]); writer.WriteLine(messages[1]); } else { writer.WriteLine("Log for test [{0}] run at agent [{1}]", result.Name, machine); } writer.WriteLine("\nOutput:"); if( result is PNUnitTestResult ) { writer.Write(((PNUnitTestResult)result).Output); } } catch( Exception e ) { log.ErrorFormat("Error writing to {0}. {1}", fileName, e.Message); } finally { if( writer != null ) { writer.Flush(); writer.Close(); } if( fs != null ) fs.Close(); } } private static void WriteResult(string resultfile) { if (resultfile == null || resultfile == string.Empty) return; if (File.Exists(resultfile)) { File.Delete(resultfile); } FileStream fs = new FileStream(resultfile, FileMode.OpenOrCreate, FileAccess.ReadWrite); StreamWriter writer = new StreamWriter(fs); try { writer.Write(mTotalLog); } finally { writer.Flush(); writer.Close(); fs.Close(); } } private static void WriteGroup(ArrayList failedTests, string filename) { TestGroup group = new TestGroup(); group.ParallelTests = (ParallelTest[]) failedTests.ToArray(typeof(ParallelTest)); TestConfLoader.WriteToFile(group, filename); } private static void ConfigureLogging() { string log4netpath = "launcher.log.conf"; if (!File.Exists (log4netpath)) log4netpath = Path.Combine(mTestPath, log4netpath); XmlConfigurator.Configure(new FileInfo(log4netpath)); } public static void Log(string msg) { log.Info(msg); mTotalLog += string.Concat(msg, "\r\n"); } public static void LogError(string msg) { log.Error(msg); mTotalLog += string.Concat(msg, "\r\n"); } private const string USER_VALUE_KEY = "-val:"; private static Hashtable GetUserValues(string[] args) { Hashtable result = new Hashtable(); foreach( string s in args ) { if( !s.ToLower().StartsWith(USER_VALUE_KEY) ) continue; string[] v = s.Substring(USER_VALUE_KEY.Length).Split('='); if( v.Length >= 1 ) { string name = v[0]; string val = string.Empty; if( v.Length == 2 ) val = v[1]; result.Add(name, val); } } return result; } } }NUnit-2.6.0.12051/src/PNUnit/tests/0000775000175000017500000000000011742560362016273 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/PNUnit/tests/pnunit.tests.build0000664000175000017500000000243111565223322021765 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/tests/test.conf0000664000175000017500000000530311565223322020115 0ustar jtaylorjtaylor Testing Testing pnunit.tests.dll TestLibraries.Testing.EqualTo19 $agent_host:8080 Parallel_Tests ParallelTest_A_Test pnunit.tests.dll TestLibraries.ParallelExample.ParallelTest_A $agent_host:8080 2 ParallelTest_B_Test pnunit.tests.dll TestLibraries.ParallelExample.ParallelTest_B $agent_host:8080 1 Parallel_Barriers Parallel_Barriers_TestA pnunit.tests.dll TestLibraries.ParallelExampleWithBarriers.ParallelTestWithBarriersA $agent_host:8080 START_BARRIER WAIT_BARRIER Parallel_Barriers_TestB pnunit.tests.dll TestLibraries.ParallelExampleWithBarriers.ParallelTestWithBarriersB $agent_host:8081 START_BARRIER WAIT_BARRIER NUnit-2.6.0.12051/src/PNUnit/tests/Cmp.cs0000664000175000017500000000026511504175260017337 0ustar jtaylorjtaylorusing System; namespace TestLibraries { public class Cmp { public static int Add(int a, int b) { int result; result = a + b; return result; } } } NUnit-2.6.0.12051/src/PNUnit/tests/AssemblyInfo.cs0000664000175000017500000000076211504175260021215 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/PNUnit/tests/ParallelExamples.cs0000664000175000017500000001240711565343736022070 0ustar jtaylorjtaylorusing System; using System.Diagnostics; using System.Threading; using NUnit.Framework; using PNUnit.Framework; namespace TestLibraries { [TestFixture, Explicit("PNUnit Test")] //TestGroup that runs their tests without any synchronization. Each test runs in parallel public class ParallelExample { private const int MAX_ITERATIONS = 5; [Test] public void ParallelTest_A() { //Obtain the sleep time from the configuration file parameters string[] testParams = PNUnitServices.Get().GetTestParams(); int sleepTime = int.Parse(testParams[0]); int count = 0; while (count < MAX_ITERATIONS) { PNUnitServices.Get().WriteLine( string.Format("Starting ParallelTest_A, Time: {0}. Iteration:{1}", DateTime.Now.ToString(), count + 1)); PNUnitServices.Get().WriteLine( string.Format("Sleeping ParallelTest_A for {1} seconds, Time: {0}", DateTime.Now.ToString(), sleepTime)); Thread.Sleep(sleepTime * 1000); PNUnitServices.Get().WriteLine( string.Format("Waking up ParallelTest_A, Time: {0}", DateTime.Now.ToString())); count++; } } [Test] public void ParallelTest_B() { string[] testParams = PNUnitServices.Get().GetTestParams(); int sleepTime = int.Parse(testParams[0]); int count = 0; while (count < MAX_ITERATIONS) { PNUnitServices.Get().WriteLine( string.Format("Starting ParallelTest_B, Time: {0}. Iteration:{1}", DateTime.Now.ToString(), count + 1)); PNUnitServices.Get().WriteLine( string.Format("Sleeping ParallelTest_B for {1} seconds, Time: {0}", DateTime.Now.ToString(), sleepTime)); Thread.Sleep(sleepTime * 1000); PNUnitServices.Get().WriteLine( string.Format("Waking up ParallelTest_B, Time: {0}", DateTime.Now.ToString())); count++; } } } [TestFixture, Explicit("PNUnit Test")] public class ParallelExampleWithBarriers { public const string START_BARRIER = "START_BARRIER"; public const string WAIT_BARRIER = "WAIT_BARRIER"; [Test] public void ParallelTestWithBarriersA() { //First step should be the initialization of synchronization barriers PNUnitServices.Get().InitBarriers(); PNUnitServices.Get().WriteLine( string.Format( "ParallelTestWithBarriersA: Waiting for peer synchronization before starting... Time:{0}", DateTime.Now.ToString())); PNUnitServices.Get().EnterBarrier(START_BARRIER); PNUnitServices.Get().WriteLine(string.Format( "ParallelTestWithBarriersA: Sync start performed!... Time:{0}", DateTime.Now.ToString())); PNUnitServices.Get().WriteLine( string.Format("Sleeping ParallelTestWithBarriersA for 5 seconds, Time: {0}", DateTime.Now.ToString())); Thread.Sleep(5000); PNUnitServices.Get().WriteLine( string.Format( "ParallelTestWithBarriersA: Waiting for peer synchronization after sleeping... Time:{0}", DateTime.Now.ToString())); PNUnitServices.Get().EnterBarrier(WAIT_BARRIER); PNUnitServices.Get().WriteLine(string.Format("ParallelTestWithBarriersA: Sync end!. Time:{0}", DateTime.Now.ToString())); } [Test] public void ParallelTestWithBarriersB() { PNUnitServices.Get().InitBarriers(); PNUnitServices.Get().WriteLine( string.Format( "ParallelTestWithBarriersB: About to sleep for 4 seconds before starting... Time:{0}", DateTime.Now.ToString())); Thread.Sleep(4000); PNUnitServices.Get().EnterBarrier(START_BARRIER); PNUnitServices.Get().WriteLine(string.Format( "ParallelTestWithBarriersB: Sync start performed!... Time:{0}", DateTime.Now.ToString())); PNUnitServices.Get().WriteLine( string.Format("Sleeping ParallelTestWithBarriersB for 1 second, Time: {0}", DateTime.Now.ToString())); Thread.Sleep(1000); PNUnitServices.Get().WriteLine( string.Format( "ParallelTestWithBarriersB: Waiting for peer synchronization after sleeping... Time:{0}", DateTime.Now.ToString())); PNUnitServices.Get().EnterBarrier(WAIT_BARRIER); PNUnitServices.Get().WriteLine(string.Format("ParallelTestWithBarriersB: Sync end!. Time:{0}", DateTime.Now.ToString())); } } } NUnit-2.6.0.12051/src/PNUnit/tests/Testing.cs0000664000175000017500000000174011564560102020233 0ustar jtaylorjtaylorusing System; using System.Threading; using NUnit.Framework; using PNUnit.Framework; namespace TestLibraries { [TestFixture] public class Testing { [Test] public void EqualTo19() { Assert.AreEqual(19, Cmp.Add(15,4)); } [Test, Explicit("PNUnit Test")] public void Server() { PNUnitServices.Get().InitBarrier("BARRIER", 1); PNUnitServices.Get().WriteLine("Server started"); Thread.Sleep(10000); PNUnitServices.Get().EnterBarrier("BARRIER"); Assert.IsTrue(false, "The test failed"); } [Test, Explicit("PNUnit Test")] public void Client() { PNUnitServices.Get().WriteLine("The client should wait until the server starts"); PNUnitServices.Get().InitBarrier("BARRIER", 1); PNUnitServices.Get().EnterBarrier("BARRIER"); Console.WriteLine("Server should be started now"); Assert.IsTrue(true, "The test failed"); } } } NUnit-2.6.0.12051/src/PNUnit/tests/agent.log.conf0000664000175000017500000000077411565223322021023 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/tests/agent.conf0000664000175000017500000000013411504175260020231 0ustar jtaylorjtaylor 8080 . NUnit-2.6.0.12051/src/PNUnit/tests/runpnunit.bat0000664000175000017500000000012111565223322021012 0ustar jtaylorjtaylorstart pnunit-agent 8080 . start pnunit-agent 8081 . pnunit-launcher test.conf NUnit-2.6.0.12051/src/PNUnit/tests/launcher.log.conf0000664000175000017500000000077411565223322021526 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/PNUnit/tests/pnunit.tests.csproj0000664000175000017500000001103411705311206022160 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {319B9238-76BE-4335-9B4D-F8E43C4B124F} Debug AnyCPU pnunit.tests JScript Grid IE50 false Library TestLibraries OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE 4096 true false false 4 none prompt System System.Data System.XML nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} pnunit.framework {5261ABA1-98E6-4603-A4F0-59CAC307AC68} Code PreserveNewest PreserveNewest PreserveNewest PreserveNewest PreserveNewest NUnit-2.6.0.12051/src/PNUnit/pnunit.framework/0000775000175000017500000000000011742560362020442 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/PNUnit/pnunit.framework/AssemblyInfo.cs0000664000175000017500000000501111504175260023354 0ustar jtaylorjtaylorusing System.Reflection; using System.Runtime.CompilerServices; // // La informacin general de un ensamblado se controla mediante el siguiente // conjunto de atributos. Cambie estos atributos para modificar la informacin // asociada con un ensamblado. // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // La informacin de versin de un ensamblado consta de los siguientes cuatro valores: // // Versin principal // Versin secundaria // Versin de compilacin // Revisin // // Puede especificar todos los valores o usar los valores predeterminados (nmero de versin de compilacin y de revisin) // usando el smbolo '*' como se muestra a continuacin: [assembly: AssemblyVersion("1.0.*")] // // Si desea firmar el ensamblado, debe especificar una clave para su uso. Consulte la documentacin de // Microsoft .NET Framework para obtener ms informacin sobre la firma de ensamblados. // // Utilice los atributos siguientes para controlar qu clave desea utilizar para firmar. // // Notas: // (*) Si no se especifica ninguna clave, el ensamblado no se firma. // (*) KeyName se refiere a una clave instalada en el Proveedor de servicios // de cifrado (CSP) en el equipo. KeyFile se refiere a un archivo que contiene // una clave. // (*) Si se especifican los valores KeyFile y KeyName, tendr // lugar el siguiente proceso: // (1) Si KeyName se puede encontrar en el CSP, se utilizar dicha clave. // (2) Si KeyName no existe pero s KeyFile, se instalar // y utilizar la clave de KeyFile en el CSP. // (*) Para crear KeyFile, puede ejecutar la utilidad sn.exe (Strong Name). // Cuando se especifica KeyFile, la ubicacin de KeyFile debe ser // relativa al directorio de resultados del proyecto, que es // %Directorio del proyecto%\obj\. Por ejemplo, si KeyFile // se encuentra en el directorio del proyecto, el atributo AssemblyKeyFile se especifica // como [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Firma retardada es una opcin avanzada; consulte la documentacin de // Microsoft .NET Framework para obtener ms informacin. // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/PNUnit/pnunit.framework/PNUnitServices.cs0000664000175000017500000001331611564560102023650 0ustar jtaylorjtaylorusing System; namespace PNUnit.Framework { [Serializable] public class PNUnitServices { private PNUnitTestInfo mInfo = null; private ITestConsoleAccess mConsole = null; private static PNUnitServices mInstance = null; // To be used only by the runner public PNUnitServices(object info, object consoleaccess) { mInfo = info as PNUnitTestInfo; mConsole = consoleaccess as ITestConsoleAccess; mInstance = this; } public static PNUnitServices Get() { if (mInstance == null) { throw new Exception("mInstance is null"); } return mInstance; } private void CheckInfo() { if (mInfo == null) throw new Exception("TestInfo not initialized"); } // IPNUnitServices public void InitBarriers() { CheckInfo(); mInfo.Services.InitBarriers(); } public void InitBarrier(string name, int max) { CheckInfo(); mInfo.Services.InitBarrier(name, max); } public void EnterBarrier(string barrier) { CheckInfo(); mConsole.WriteLine( string.Format(">>>Test {0} entering barrier {1}", mInfo.TestName, barrier)); mInfo.Services.EnterBarrier(barrier); mConsole.WriteLine( string.Format("<<>>Message sending (tag:{1} receivers:{2} message:{3}) by test {0} ", mInfo.TestName, tag, receivers, message == null ? string.Empty : message.ToString())); mInfo.Services.SendMessage(tag, receivers, message); mConsole.WriteLine( string.Format( "<<>>Receiving message (tag:{1}) by test {0}", mInfo.TestName, tag)); object message = mInfo.Services.ReceiveMessage(tag); mConsole.WriteLine( string.Format("<<>>Message sending (tag:{1} message:{2}) by test {0} ", mInfo.TestName, tag, message == null ? string.Empty : message.ToString())); mInfo.Services.ISendMessage(tag, receivers, message); mConsole.WriteLine( string.Format( "<<>>Looking for message (tag:{1}) by test {0}", mInfo.TestName, tag)); object msg = mInfo.Services.IReceiveMessage(tag); mConsole.WriteLine( string.Format("<< NUnit-2.6.0.12051/src/PNUnit/pnunit.framework/Interfaces.cs0000664000175000017500000001040711564560102023050 0ustar jtaylorjtaylorusing System; using System.Collections; using System.Runtime.Serialization; using NUnit.Core; namespace PNUnit.Framework { public class Names { public const string PNUnitAgentServiceName = "IPNUnitAgent"; public const string ServerBarrier = "SERVERSTART"; public const string EndBarrier = "ENDBARRIER"; public const string RestartBarrier = "SERVERRESTART"; public const string RestartedOkBarrier = "SERVERRESTARTEDOK"; } public interface ITestConsoleAccess { void WriteLine(string s); void Write(char[] buf); void Write(char[] buf, int index, int count); } public interface IPNUnitServices { void NotifyResult(string TestName, TestResult result); void InitBarriers(); void InitBarrier(string name, int max); void EnterBarrier(string barrier); void SendMessage(string tag, int receivers, object message); object ReceiveMessage(string tag); void ISendMessage(string tag, int receivers, object message); object IReceiveMessage(string tag); } [Serializable] public class PNUnitTestInfo { public string TestName; public string AssemblyName; public string TestToRun; public string[] TestParams; public IPNUnitServices Services; public string StartBarrier; public string EndBarrier; public string[] WaitBarriers; public Hashtable UserValues = new Hashtable(); public PNUnitTestInfo( string TestName, string AssemblyName, string TestToRun, string[] TestParams, IPNUnitServices Services) { this.TestName = TestName; this.AssemblyName = AssemblyName; this.TestToRun = TestToRun; this.TestParams = TestParams; this.Services = Services; } public PNUnitTestInfo( string TestName, string AssemblyName, string TestToRun, string[] TestParams, IPNUnitServices Services, string StartBarrier, string EndBarrier, string[] WaitBarriers) { this.TestName = TestName; this.AssemblyName = AssemblyName; this.TestToRun = TestToRun; this.TestParams = TestParams; this.Services = Services; this.StartBarrier = StartBarrier; this.EndBarrier = EndBarrier; this.WaitBarriers = WaitBarriers; } } public interface IPNUnitAgent { void RunTest(PNUnitTestInfo info); } [Serializable] public class PNUnitRetryException : Exception { public static string RETRY_EXCEPTION = "RETRY_EXCEPTION:"; #region "constructors" public PNUnitRetryException(string message) : base(RETRY_EXCEPTION + message) { } public PNUnitRetryException(string message, Exception innerException) : base(RETRY_EXCEPTION + message, innerException) { } public PNUnitRetryException(SerializationInfo info, StreamingContext context) : base(info, context) { } #endregion } [Serializable] public class PNUnitTestResult : TestResult { private string mOutput = string.Empty; private bool mRetryTest = false; public PNUnitTestResult(TestName testName, string output) : base(testName) { mOutput = output; } public PNUnitTestResult(TestResult testResult, string output): base(testResult.Test) { mOutput = output; if (testResult.Message != null && (testResult.Message.IndexOf(PNUnitRetryException.RETRY_EXCEPTION) >= 0)) this.mRetryTest = true; if (testResult.IsSuccess) this.Success(testResult.Message); else this.Failure(testResult.Message, testResult.StackTrace); this.Time = testResult.Time; } public string Output { get { return mOutput; } } public bool RetryTest { get { return mRetryTest; } } } } NUnit-2.6.0.12051/src/PNUnit/pnunit.framework/pnunit.framework.csproj0000664000175000017500000001037311564560102025173 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {5261ABA1-98E6-4603-A4F0-59CAC307AC68} Debug AnyCPU pnunit.framework JScript Grid IE50 false Library pnunit.framework OnBuildSuccess 0.0 v2.0 ..\..\..\bin\Debug\ 285212672 DEBUG;TRACE true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE 4096 true false false 4 none prompt Code Code Code {61CE9CE5-943E-44D4-A381-814DC1406767} nunit.util.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} nunit.core.interfaces.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll NUnit-2.6.0.12051/src/NUnitTestServer/0000775000175000017500000000000011742560362017040 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/0000775000175000017500000000000011742560362022050 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/AssemblyInfo.cs0000664000175000017500000000067111504175260024771 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; [assembly: AssemblyTitle("NUnit-Agent")] [assembly: AssemblyDescription("")] NUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/Program.cs0000664000175000017500000001047011504175260024003 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Runtime.Remoting.Services; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Diagnostics; using NUnit.Core; using NUnit.Util; namespace NUnit.Agent { /// /// Summary description for Program. /// public class NUnitTestAgent { static Logger log = InternalTrace.GetLogger(typeof(NUnitTestAgent)); static Guid AgentId; static string AgencyUrl; static TestAgency Agency; /// /// Channel used for communications with the agency /// and with clients /// static TcpChannel Channel; /// /// The main entry point for the application. /// [STAThread] public static int Main(string[] args) { AgentId = new Guid(args[0]); AgencyUrl = args[1]; #if DEBUG if ( args.Length > 2 && args[2] == "--pause" ) System.Windows.Forms.MessageBox.Show( "Attach debugger if desired, then press OK", "NUnit-Agent"); #endif // Create SettingsService early so we know the trace level right at the start SettingsService settingsService = new SettingsService(false); InternalTrace.Initialize("nunit-agent_%p.log", (InternalTraceLevel)settingsService.GetSetting("Options.InternalTraceLevel", InternalTraceLevel.Default)); log.Info("Agent process {0} starting", Process.GetCurrentProcess().Id); log.Info("Running under version {0}, {1}", Environment.Version, RuntimeFramework.CurrentFramework.DisplayName); // Add Standard Services to ServiceManager log.Info("Adding Services"); ServiceManager.Services.AddService(settingsService); ServiceManager.Services.AddService(new ProjectService()); ServiceManager.Services.AddService( new DomainManager() ); //ServiceManager.Services.AddService( new RecentFilesService() ); //ServiceManager.Services.AddService( new TestLoader() ); ServiceManager.Services.AddService( new AddinRegistry() ); ServiceManager.Services.AddService( new AddinManager() ); // Initialize Services log.Info("Initializing Services"); ServiceManager.Services.InitializeServices(); Channel = ServerUtilities.GetTcpChannel(); log.Info("Connecting to TestAgency at {0}", AgencyUrl); try { Agency = Activator.GetObject(typeof(TestAgency), AgencyUrl) as TestAgency; } catch (Exception ex) { log.Error("Unable to connect", ex); } if (Channel != null) { log.Info("Starting RemoteTestAgent"); RemoteTestAgent agent = new RemoteTestAgent(AgentId, Agency); try { if (agent.Start()) { log.Debug("Waiting for stopSignal"); agent.WaitForStop(); log.Debug("Stop signal received"); } else log.Error("Failed to start RemoteTestAgent"); } catch (Exception ex) { log.Error("Exception in RemoteTestAgent", ex); } log.Info("Unregistering Channel"); try { ChannelServices.UnregisterChannel(Channel); } catch (Exception ex) { log.Error("ChannelServices.UnregisterChannel threw an exception", ex); } } log.Info("Stopping all services"); ServiceManager.Services.StopAllServices(); log.Info("Agent process {0} exiting", Process.GetCurrentProcess().Id); InternalTrace.Close(); return 0; } } } NUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/nunit-agent.exe.build0000664000175000017500000000440511654467754026122 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/nunit-agent.exe.csproj0000664000175000017500000001061111574617510026303 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {3E469CD9-FED2-4955-AE4C-669A74CA6767} Debug AnyCPU nunit-agent JScript Grid IE50 false WinExe NUnit.Agent OnBuildSuccess 2.0 true v2.0 ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE 4096 true false false 4 none prompt System System.Data System.Drawing System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False Always CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/App.config0000664000175000017500000000230111654471474023762 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitTestServer/nunit-agent-exe/App.v1.config0000664000175000017500000000552211654472140024306 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/0000775000175000017500000000000011742560362016550 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ConsoleRunner/tests/0000775000175000017500000000000011742560362017712 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ConsoleRunner/tests/TestNameParserTests.cs0000664000175000017500000000366211537111564024166 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.ConsoleRunner.Tests { public class TestNameParserTests { [TestCase("Test.Namespace.Fixture.Method")] [TestCase("Test.Namespace.Fixture.Method,")] [TestCase(" Test.Namespace.Fixture.Method ")] [TestCase(" Test.Namespace.Fixture.Method ,")] [TestCase("Test.Namespace.Fixture.Method()")] [TestCase("Test.Namespace.Fixture.Method(\"string,argument\")")] [TestCase("Test.Namespace.Fixture.Method(1,2,3)")] [TestCase("Test.Namespace.Fixture.Method()")] [TestCase("Test.Namespace.Fixture.Method(\")\")")] public void SingleName(string name) { string[] names = TestNameParser.Parse(name); Assert.AreEqual(1, names.Length); Assert.AreEqual(name.Trim(new char[] { ' ', ',' }), names[0]); } [TestCase("Test.Namespace.Fixture.Method1", "Test.Namespace.Fixture.Method2")] [TestCase("Test.Namespace.Fixture.Method1", "Test.Namespace.Fixture.Method2,")] [TestCase("Test.Namespace.Fixture.Method1(1,2)", "Test.Namespace.Fixture.Method2(3,4)")] [TestCase("Test.Namespace.Fixture.Method1(\"(\")", "Test.Namespace.Fixture.Method2(\"<\")")] public void TwoNames(string name1, string name2) { char[] delims = new char[] { ' ', ',' }; string[] names = TestNameParser.Parse(name1 + "," + name2); Assert.AreEqual(2, names.Length); Assert.AreEqual(name1.Trim(delims), names[0]); Assert.AreEqual(name2.Trim(delims), names[1]); } } } NUnit-2.6.0.12051/src/ConsoleRunner/tests/ConsoleRunnerTest.cs0000664000175000017500000001432611544454420023700 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Text; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.TestData.ConsoleRunnerTest; using NUnit.Tests.Assemblies; namespace NUnit.ConsoleRunner.Tests { [TestFixture] public class ConsoleRunnerTest { private static readonly string failureMsg = string.Format( "Errors: {0}, Failures: {1}", MockAssembly.Errors, MockAssembly.Failures ); private static readonly string xmlFile = Path.Combine(Path.GetTempPath(), "console-test.xml"); private StringBuilder output; TextWriter saveOut; [SetUp] public void Init() { output = new StringBuilder(); Console.Out.Flush(); saveOut = Console.Out; Console.SetOut( new StringWriter( output ) ); } [TearDown] public void CleanUp() { Console.SetOut( saveOut ); FileInfo file = new FileInfo(xmlFile); if(file.Exists) file.Delete(); file = new FileInfo( "TestResult.xml" ); if(file.Exists) file.Delete(); } [Test] public void FailureFixture() { int resultCode = runFixture(typeof(FailureTest), "-noxml"); Assert.AreEqual(1, resultCode); } [Test] public void MultiFailureFixture() { int resultCode = runFixture(typeof(MultiFailureTest), "-noxml"); Assert.AreEqual(3, resultCode); } [Test] public void SuccessFixture() { int resultCode = runFixture(typeof(SuccessTest), "-noxml"); Assert.AreEqual(0, resultCode); } [Test] public void XmlResult() { FileInfo info = new FileInfo(xmlFile); info.Delete(); int resultCode = runFixture(typeof(SuccessTest), "-xml:" + xmlFile); Assert.AreEqual(0, resultCode); Assert.AreEqual(true, info.Exists); } [Test] public void InvalidFixture() { int resultCode = executeConsole( new string[] { MockAssembly.AssemblyPath, "-fixture:NUnit.Tests.BogusTest", "-noxml" }); Assert.AreEqual(ConsoleUi.FIXTURE_NOT_FOUND, resultCode); } [Test] public void AssemblyNotFound() { int resultCode = executeConsole(new string[] { "badassembly.dll", "-noxml" }); Assert.AreEqual(ConsoleUi.FILE_NOT_FOUND, resultCode); } [Test] public void OneOfTwoAssembliesNotFound() { int resultCode = executeConsole(new string[] { GetType().Module.Name, "badassembly.dll", "-noxml" }); Assert.AreEqual(ConsoleUi.FILE_NOT_FOUND, resultCode); } [Test] public void XmlToConsole() { int resultCode = runFixture( typeof(SuccessTest), "-xmlconsole", "-nologo" ); Assert.AreEqual(0, resultCode); StringAssert.Contains( @" Local 9.0.21022 2.0 {8597D2C6-804D-48CB-BFC7-ED2404D389B0} Debug AnyCPU nunit-console.tests JScript Grid IE50 false Library ConsoleRunner.Tests OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} nunit.core.interfaces.dll nunit.core.tests {DD758D21-E5D5-4D40-9450-5F65A32F359C} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} {2E368281-3BA8-4050-B05E-0E0E43F8F446} mock-assembly False {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} nonamespace-assembly test-assembly {1960CAC4-9A82-47C5-A9B3-55BC37572C3C} nunit-console {9367EC89-6A38-42BA-9607-0DC288E4BC3A} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/ConsoleRunner/tests/nunit-console.tests.build0000664000175000017500000000312711537354350024674 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/tests/CommandLineTests_MultipleAssemblies.cs0000664000175000017500000000344711504175260027340 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.ConsoleRunner.Tests { using System; using System.Collections; using NUnit.Framework; [TestFixture] public class CommandLineTests_MultipleAssemblies { private readonly string firstAssembly = "nunit.tests.dll"; private readonly string secondAssembly = "mock-assembly.dll"; private readonly string fixture = "NUnit.Tests.CommandLine"; private ConsoleOptions assemblyOptions; private ConsoleOptions fixtureOptions; [SetUp] public void SetUp() { assemblyOptions = new ConsoleOptions(new string[] { firstAssembly, secondAssembly }); fixtureOptions = new ConsoleOptions(new string[] { "-fixture:"+fixture, firstAssembly, secondAssembly }); } [Test] public void MultipleAssemblyValidate() { Assert.IsTrue(assemblyOptions.Validate()); } [Test] public void ParameterCount() { Assert.AreEqual(2, assemblyOptions.Parameters.Count); } [Test] public void CheckParameters() { ArrayList parms = assemblyOptions.Parameters; Assert.IsTrue(parms.Contains(firstAssembly)); Assert.IsTrue(parms.Contains(secondAssembly)); } [Test] public void FixtureValidate() { Assert.IsTrue(fixtureOptions.Validate()); } [Test] public void FixtureParameters() { Assert.AreEqual(fixture, fixtureOptions.fixture); ArrayList parms = fixtureOptions.Parameters; Assert.IsTrue(parms.Contains(firstAssembly)); Assert.IsTrue(parms.Contains(secondAssembly)); } } } NUnit-2.6.0.12051/src/ConsoleRunner/tests/CommandLineTests.cs0000664000175000017500000001557711624521342023463 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.ConsoleRunner.Tests { using System; using System.IO; using System.Reflection; using NUnit.Framework; [TestFixture] public class CommandLineTests { [Test] public void NoParametersCount() { ConsoleOptions options = new ConsoleOptions(); Assert.IsTrue(options.NoArgs); } [Test] public void AllowForwardSlashDefaultsCorrectly() { ConsoleOptions options = new ConsoleOptions(); Assert.AreEqual( Path.DirectorySeparatorChar != '/', options.AllowForwardSlash ); } [TestCase( "nologo", "nologo")] [TestCase( "help", "help" )] [TestCase( "help", "?" )] [TestCase( "wait", "wait" )] [TestCase( "xmlConsole", "xmlConsole")] [TestCase( "labels", "labels")] [TestCase( "noshadow", "noshadow" )] [TestCase( "nothread", "nothread" )] public void BooleanOptionAreRecognized( string fieldName, string option ) { FieldInfo field = typeof(ConsoleOptions).GetField( fieldName ); Assert.IsNotNull( field, "Field '{0}' not found", fieldName ); Assert.AreEqual( typeof(bool), field.FieldType, "Field '{0}' is wrong type", fieldName ); ConsoleOptions options = new ConsoleOptions( "-" + option ); Assert.AreEqual( true, (bool)field.GetValue( options ), "Didn't recognize -" + option ); options = new ConsoleOptions( "--" + option ); Assert.AreEqual( true, (bool)field.GetValue( options ), "Didn't recognize --" + option ); options = new ConsoleOptions( false, "/" + option ); Assert.AreEqual( false, (bool)field.GetValue( options ), "Incorrectly recognized /" + option ); options = new ConsoleOptions( true, "/" + option ); Assert.AreEqual( true, (bool)field.GetValue( options ), "Didn't recognize /" + option ); } [TestCase( "fixture", "fixture" )] [TestCase( "config", "config")] [TestCase( "result", "result")] [TestCase( "result", "xml" )] [TestCase( "output", "output" )] [TestCase( "output", "out" )] [TestCase( "err", "err" )] [TestCase( "include", "include" )] [TestCase( "exclude", "exclude" )] [TestCase("run", "run")] [TestCase("runlist", "runlist")] public void StringOptionsAreRecognized( string fieldName, string option ) { FieldInfo field = typeof(ConsoleOptions).GetField( fieldName ); Assert.IsNotNull( field, "Field {0} not found", fieldName ); Assert.AreEqual( typeof(string), field.FieldType ); ConsoleOptions options = new ConsoleOptions( "-" + option + ":text" ); Assert.AreEqual( "text", (string)field.GetValue( options ), "Didn't recognize -" + option ); options = new ConsoleOptions( "--" + option + ":text" ); Assert.AreEqual( "text", (string)field.GetValue( options ), "Didn't recognize --" + option ); options = new ConsoleOptions( false, "/" + option + ":text" ); Assert.AreEqual( null, (string)field.GetValue( options ), "Incorrectly recognized /" + option ); options = new ConsoleOptions( true, "/" + option + ":text" ); Assert.AreEqual( "text", (string)field.GetValue( options ), "Didn't recognize /" + option ); } [TestCase("domain")] [TestCase("trace")] public void EnumOptionsAreRecognized( string fieldName ) { FieldInfo field = typeof(ConsoleOptions).GetField( fieldName ); Assert.IsNotNull( field, "Field {0} not found", fieldName ); Assert.IsTrue( field.FieldType.IsEnum, "Field {0} is not an enum", fieldName ); } [Test] public void AssemblyName() { ConsoleOptions options = new ConsoleOptions( "nunit.tests.dll" ); Assert.AreEqual( "nunit.tests.dll", options.Parameters[0] ); } [Test] public void FixtureNamePlusAssemblyIsValid() { ConsoleOptions options = new ConsoleOptions( "-fixture:NUnit.Tests.AllTests", "nunit.tests.dll" ); Assert.AreEqual("nunit.tests.dll", options.Parameters[0]); Assert.AreEqual("NUnit.Tests.AllTests", options.fixture); Assert.IsTrue(options.Validate()); } [Test] public void AssemblyAloneIsValid() { ConsoleOptions options = new ConsoleOptions( "nunit.tests.dll" ); Assert.IsTrue(options.Validate(), "command line should be valid"); } [Test] public void InvalidOption() { ConsoleOptions options = new ConsoleOptions( "-asembly:nunit.tests.dll" ); Assert.IsFalse(options.Validate()); } [Test] public void NoFixtureNameProvided() { ConsoleOptions options = new ConsoleOptions( "-fixture:", "nunit.tests.dll" ); Assert.IsFalse(options.Validate()); } [Test] public void InvalidCommandLineParms() { ConsoleOptions options = new ConsoleOptions( "-garbage:TestFixture", "-assembly:Tests.dll" ); Assert.IsFalse(options.Validate()); } [Test] public void XmlParameter() { ConsoleOptions options = new ConsoleOptions( "tests.dll", "-xml:results.xml" ); Assert.IsTrue(options.ParameterCount == 1, "assembly should be set"); Assert.AreEqual("tests.dll", options.Parameters[0]); Assert.AreEqual("results.xml", options.result); } [Test] public void XmlParameterWithFullPath() { ConsoleOptions options = new ConsoleOptions( "tests.dll", "-xml:C:/nunit/tests/bin/Debug/console-test.xml" ); Assert.IsTrue(options.ParameterCount == 1, "assembly should be set"); Assert.AreEqual("tests.dll", options.Parameters[0]); Assert.AreEqual("C:/nunit/tests/bin/Debug/console-test.xml", options.result); } [Test] public void XmlParameterWithFullPathUsingEqualSign() { ConsoleOptions options = new ConsoleOptions( "tests.dll", "-xml=C:/nunit/tests/bin/Debug/console-test.xml" ); Assert.IsTrue(options.ParameterCount == 1, "assembly should be set"); Assert.AreEqual("tests.dll", options.Parameters[0]); Assert.AreEqual("C:/nunit/tests/bin/Debug/console-test.xml", options.result); } [Test] public void FileNameWithoutXmlParameterLooksLikeParameter() { ConsoleOptions options = new ConsoleOptions( "tests.dll", "result.xml" ); Assert.IsTrue(options.Validate()); Assert.AreEqual(2, options.Parameters.Count); } [Test] public void XmlParameterWithoutFileNameIsInvalid() { ConsoleOptions options = new ConsoleOptions( "tests.dll", "-xml:" ); Assert.IsFalse(options.Validate()); } [Test] public void HelpTextUsesCorrectDelimiterForPlatform() { string helpText = new ConsoleOptions().GetHelpText(); char delim = System.IO.Path.DirectorySeparatorChar == '/' ? '-' : '/'; string expected = string.Format( "{0}output=", delim ); StringAssert.Contains( expected, helpText ); expected = string.Format( "{0}out=", delim ); StringAssert.Contains( expected, helpText ); } } } NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/0000775000175000017500000000000011742560362022124 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/App.ico0000664000175000017500000000206611504175260023337 0ustar jtaylorjtaylor &(( @wwwwwwwwwwwwwwpDDDDDDDDDDDDDDppppppppppppppppppppDDDDDDDDDDDDDDpLLLLLLLLLNItpDDDDDDDDDDDDD@( wwwwwwwDDDDDDDGOGOGOGOGOGOGOGOGHGLGDDDDDDNUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/nunit-console.exe.csproj0000664000175000017500000001015011574577562026735 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {53BF8787-CB9C-4BB8-AFB4-605DD3A5CA0E} Debug AnyCPU nunit-console JScript Grid IE50 false Exe NUnit.ConsoleRunner OnBuildSuccess 2.0 true v2.0 ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt true ../../NUnitTests.nunit ..\..\..\bin\Release\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.XML {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll False nunit-console {9367EC89-6A38-42BA-9607-0DC288E4BC3A} False Always CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/AssemblyInfo.cs0000664000175000017500000000067111504175260025045 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; [assembly: AssemblyTitle("NUnit-Console")] [assembly: AssemblyDescription("")]NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/nunit-console.exe.build0000664000175000017500000000411111654451526026522 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/App.config0000664000175000017500000000202411654467060024034 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/Class1.cs0000664000175000017500000000125111504175260023573 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Core; namespace NUnit.ConsoleRunner { /// /// Summary description for Class1. /// class Class1 { /// /// The main entry point for the application. /// [STAThread] public static int Main(string[] args) { return Runner.Main(args); } } } NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console-exe/App.v1.config0000664000175000017500000000520511654451664024370 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/0000775000175000017500000000000011742560362021345 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/App.ico0000664000175000017500000000206611504175260022560 0ustar jtaylorjtaylor &(( @wwwwwwwwwwwwwwpDDDDDDDDDDDDDDppppppppppppppppppppDDDDDDDDDDDDDDpLLLLLLLLLNItpDDDDDDDDDDDDD@( wwwwwwwDDDDDDDGOGOGOGOGOGOGOGOGHGLGDDDDDDNUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/EventCollector.cs0000664000175000017500000001464111504175260024625 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Diagnostics; using System.Text.RegularExpressions; using System.Collections; using System.Collections.Specialized; using NUnit.Core; using NUnit.Util; namespace NUnit.ConsoleRunner { /// /// Summary description for EventCollector. /// public class EventCollector : MarshalByRefObject, EventListener { private int testRunCount; private int testIgnoreCount; private int failureCount; private int level; private ConsoleOptions options; private TextWriter outWriter; private TextWriter errorWriter; StringCollection messages; private bool progress = false; private string currentTestName; private ArrayList unhandledExceptions = new ArrayList(); public EventCollector( ConsoleOptions options, TextWriter outWriter, TextWriter errorWriter ) { level = 0; this.options = options; this.outWriter = outWriter; this.errorWriter = errorWriter; this.currentTestName = string.Empty; this.progress = !options.xmlConsole && !options.labels && !options.nodots; AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); } public bool HasExceptions { get { return unhandledExceptions.Count > 0; } } public void WriteExceptions() { Console.WriteLine(); Console.WriteLine("Unhandled exceptions:"); int index = 1; foreach( string msg in unhandledExceptions ) Console.WriteLine( "{0}) {1}", index++, msg ); } public void RunStarted(string name, int testCount) { } public void RunFinished(TestResult result) { } public void RunFinished(Exception exception) { } public void TestFinished(TestResult testResult) { switch( testResult.ResultState ) { case ResultState.Error: case ResultState.Failure: case ResultState.Cancelled: testRunCount++; failureCount++; if ( progress ) Console.Write("F"); messages.Add( string.Format( "{0}) {1} :", failureCount, testResult.Test.TestName.FullName ) ); messages.Add( testResult.Message.Trim( Environment.NewLine.ToCharArray() ) ); string stackTrace = StackTraceFilter.Filter( testResult.StackTrace ); if ( stackTrace != null && stackTrace != string.Empty ) { string[] trace = stackTrace.Split( System.Environment.NewLine.ToCharArray() ); foreach( string s in trace ) { if ( s != string.Empty ) { string link = Regex.Replace( s.Trim(), @".* in (.*):line (.*)", "$1($2)"); messages.Add( string.Format( "at\n{0}", link ) ); } } } break; case ResultState.Inconclusive: case ResultState.Success: testRunCount++; break; case ResultState.Ignored: case ResultState.Skipped: case ResultState.NotRunnable: testIgnoreCount++; if ( progress ) Console.Write("N"); break; } currentTestName = string.Empty; } public void TestStarted(TestName testName) { currentTestName = testName.FullName; if ( options.labels ) outWriter.WriteLine("***** {0}", currentTestName ); if ( progress ) Console.Write("."); } public void SuiteStarted(TestName testName) { if ( level++ == 0 ) { messages = new StringCollection(); testRunCount = 0; testIgnoreCount = 0; failureCount = 0; Trace.WriteLine( "################################ UNIT TESTS ################################" ); Trace.WriteLine( "Running tests in '" + testName.FullName + "'..." ); } } public void SuiteFinished(TestResult suiteResult) { if ( --level == 0) { Trace.WriteLine( "############################################################################" ); if (messages.Count == 0) { Trace.WriteLine( "############## S U C C E S S #################" ); } else { Trace.WriteLine( "############## F A I L U R E S #################" ); foreach ( string s in messages ) { Trace.WriteLine(s); } } Trace.WriteLine( "############################################################################" ); Trace.WriteLine( "Executed tests : " + testRunCount ); Trace.WriteLine( "Ignored tests : " + testIgnoreCount ); Trace.WriteLine( "Failed tests : " + failureCount ); Trace.WriteLine( "Unhandled exceptions : " + unhandledExceptions.Count); Trace.WriteLine( "Total time : " + suiteResult.Time + " seconds" ); Trace.WriteLine( "############################################################################"); } } private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) { if (e.ExceptionObject.GetType() != typeof(System.Threading.ThreadAbortException)) { this.UnhandledException((Exception)e.ExceptionObject); } } public void UnhandledException( Exception exception ) { // If we do labels, we already have a newline unhandledExceptions.Add(currentTestName + " : " + exception.ToString()); //if (!options.labels) outWriter.WriteLine(); string msg = string.Format("##### Unhandled Exception while running {0}", currentTestName); //outWriter.WriteLine(msg); //outWriter.WriteLine(exception.ToString()); Trace.WriteLine(msg); Trace.WriteLine(exception.ToString()); } public void TestOutput( TestOutput output) { switch ( output.Type ) { case TestOutputType.Out: outWriter.Write( output.Text ); break; case TestOutputType.Error: errorWriter.Write( output.Text ); break; } } public override object InitializeLifetimeService() { return null; } } } NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/TestNameParser.cs0000664000175000017500000000523211537112036024564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.ConsoleRunner { /// /// TestNameParser is used to parse the arguments to the /// -run option, separating testnames at the correct point. /// public class TestNameParser { /// /// Parse the -run argument and return an array of argument /// /// argument /// public static string[] Parse(string argument) { ArrayList list = new ArrayList(); int index = 0; while (index < argument.Length) { string name = GetTestName(argument, ref index); if (name != null && name != string.Empty) list.Add(name); } return (string[])list.ToArray(typeof(string)); } private static string GetTestName(string argument, ref int index) { int separator = GetSeparator(argument, index); string result; if (separator >= 0) { result = argument.Substring(index, separator - index).Trim(); index = separator + 1; } else { result = argument.Substring(index).Trim(); index = argument.Length; } return result; } private static int GetSeparator(string argument, int index) { int nest = 0; while (index < argument.Length) { switch (argument[index]) { case ',': if (nest == 0) return index; break; case '"': while (++index < argument.Length && argument[index] != '"') ; break; case '(': case '<': nest++; break; case ')': case '>': nest--; break; } index++; } return -1; } } } NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/AssemblyInfo.cs0000664000175000017500000000072211504175260024263 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/Runner.cs0000664000175000017500000001304611712221750023141 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Reflection; using NUnit.Core; using NUnit.Util; namespace NUnit.ConsoleRunner { /// /// Summary description for Runner. /// public class Runner { static Logger log = InternalTrace.GetLogger(typeof(Runner)); [STAThread] public static int Main(string[] args) { ConsoleOptions options = new ConsoleOptions(args); // Create SettingsService early so we know the trace level right at the start SettingsService settingsService = new SettingsService(); InternalTraceLevel level = (InternalTraceLevel)settingsService.GetSetting("Options.InternalTraceLevel", InternalTraceLevel.Default); if (options.trace != InternalTraceLevel.Default) level = options.trace; InternalTrace.Initialize("nunit-console_%p.log", level); log.Info("NUnit-console.exe starting"); if(!options.nologo) WriteCopyright(); if(options.help) { options.Help(); return ConsoleUi.OK; } if (options.cleanup) { log.Info("Performing cleanup of shadow copy cache"); DomainManager.DeleteShadowCopyPath(); Console.WriteLine("Shadow copy cache emptied"); return ConsoleUi.OK; } if (options.NoArgs) { Console.Error.WriteLine("fatal error: no inputs specified"); options.Help(); return ConsoleUi.OK; } if(!options.Validate()) { foreach( string arg in options.InvalidArguments ) Console.Error.WriteLine("fatal error: invalid argument: {0}", arg ); options.Help(); return ConsoleUi.INVALID_ARG; } // Add Standard Services to ServiceManager ServiceManager.Services.AddService( settingsService ); ServiceManager.Services.AddService( new DomainManager() ); //ServiceManager.Services.AddService( new RecentFilesService() ); ServiceManager.Services.AddService( new ProjectService() ); //ServiceManager.Services.AddService( new TestLoader() ); ServiceManager.Services.AddService( new AddinRegistry() ); ServiceManager.Services.AddService( new AddinManager() ); ServiceManager.Services.AddService( new TestAgency() ); // Initialize Services ServiceManager.Services.InitializeServices(); foreach (string parm in options.Parameters) { if (!Services.ProjectService.CanLoadProject(parm) && !PathUtils.IsAssemblyFileType(parm)) { Console.WriteLine("File type not known: {0}", parm); return ConsoleUi.INVALID_ARG; } } try { ConsoleUi consoleUi = new ConsoleUi(); return consoleUi.Execute( options ); } catch( FileNotFoundException ex ) { Console.WriteLine( ex.Message ); return ConsoleUi.FILE_NOT_FOUND; } catch( Exception ex ) { Console.WriteLine( "Unhandled Exception:\n{0}", ex.ToString() ); return ConsoleUi.UNEXPECTED_ERROR; } finally { if(options.wait) { Console.Out.WriteLine("\nHit key to continue"); Console.ReadLine(); } log.Info( "NUnit-console.exe terminating" ); } } private static void WriteCopyright() { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string versionText = executingAssembly.GetName().Version.ToString(); #if CLR_1_0 string productName = "NUnit-Console (.NET 1.0)"; #elif CLR_1_1 string productName = "NUnit-Console (.NET 1.1)"; #else string productName = "NUnit-Console"; #endif string copyrightText = "Copyright (C) 2002-2012 Charlie Poole.\r\nCopyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.\r\nCopyright (C) 2000-2002 Philip Craig.\r\nAll Rights Reserved."; //object[] objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false); //if ( objectAttrs.Length > 0 ) // productName = ((AssemblyProductAttribute)objectAttrs[0]).Product; object[] objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if ( objectAttrs.Length > 0 ) copyrightText = ((AssemblyCopyrightAttribute)objectAttrs[0]).Copyright; objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyConfigurationAttribute), false); if (objectAttrs.Length > 0) { string configText = ((AssemblyConfigurationAttribute)objectAttrs[0]).Configuration; if (configText != "") versionText += string.Format(" ({0})", configText); } Console.WriteLine(String.Format("{0} version {1}", productName, versionText)); Console.WriteLine(copyrightText); Console.WriteLine(); Console.WriteLine( "Runtime Environment - " ); RuntimeFramework framework = RuntimeFramework.CurrentFramework; Console.WriteLine( string.Format(" OS Version: {0}", Environment.OSVersion ) ); Console.WriteLine( string.Format(" CLR Version: {0} ( {1} )", Environment.Version, framework.DisplayName ) ); Console.WriteLine(); } } } NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/nunit-console.csproj0000664000175000017500000001062211574577562025402 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {9367EC89-6A38-42BA-9607-0DC288E4BC3A} Debug AnyCPU nunit-console-runner JScript Grid IE50 false Library NUnit.ConsoleRunner OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 618,1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 618,1699 true false false 4 none prompt System System.Data System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/ConsoleOptions.cs0000664000175000017500000001133711700667032024653 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.ConsoleRunner { using System; using Codeblast; using NUnit.Util; using NUnit.Core; public class ConsoleOptions : CommandLineOptions { [Option(Short="load", Description = "Test fixture or namespace to be loaded (Deprecated)")] public string fixture; [Option(Description = "Name of the test case(s), fixture(s) or namespace(s) to run")] public string run; [Option(Description = "Name of a file containing a list of the tests to run")] public string runlist; [Option(Description = "Project configuration (e.g.: Debug) to load")] public string config; [Option(Short="xml", Description = "Name of XML result file (Default: TestResult.xml)")] public string result; [Option(Description = "Display XML to the console (Deprecated)")] public bool xmlConsole; [Option(Short="noxml", Description = "Suppress XML result output")] public bool noresult; [Option(Short="out", Description = "File to receive test output")] public string output; [Option(Description = "File to receive test error output")] public string err; [Option(Description = "Work directory for output files")] public string work; [Option(Description = "Label each test in stdOut")] public bool labels = false; [Option(Description = "Set internal trace level: Off, Error, Warning, Info, Verbose")] public InternalTraceLevel trace; [Option(Description = "List of categories to include")] public string include; [Option(Description = "List of categories to exclude")] public string exclude; #if CLR_2_0 || CLR_4_0 [Option(Description = "Framework version to be used for tests")] public string framework; [Option(Description = "Process model for tests: Single, Separate, Multiple")] public ProcessModel process; #endif [Option(Description = "AppDomain Usage for tests: None, Single, Multiple")] public DomainUsage domain; [Option(Description = "Apartment for running tests: MTA (Default), STA")] public System.Threading.ApartmentState apartment; [Option(Description = "Disable shadow copy when running in separate domain")] public bool noshadow; [Option (Description = "Disable use of a separate thread for tests")] public bool nothread; [Option(Description = "Set timeout for each test case in milliseconds")] public int timeout; [Option(Description = "Wait for input before closing console window")] public bool wait = false; [Option(Description = "Do not display the logo")] public bool nologo = false; [Option(Description = "Do not display progress" )] public bool nodots = false; [Option(Description = "Stop after the first test failure or error")] public bool stoponerror = false; [Option(Description = "Erase any leftover cache files and exit")] public bool cleanup; [Option(Short = "?", Description = "Display help")] public bool help = false; public ConsoleOptions( params string[] args ) : base( args ) {} public ConsoleOptions( bool allowForwardSlash, params string[] args ) : base( allowForwardSlash, args ) {} public bool Validate() { if(isInvalid) return false; if(NoArgs) return true; if(ParameterCount >= 1) return true; return false; } // protected override bool IsValidParameter(string parm) // { // return Services.ProjectLoadService.CanLoadProject( parm ) || PathUtils.IsAssemblyFileType( parm ); // } public bool IsTestProject { get { return ParameterCount == 1 && Services.ProjectService.CanLoadProject((string)Parameters[0]); } } public override void Help() { Console.WriteLine(); Console.WriteLine( "NUNIT-CONSOLE [inputfiles] [options]" ); Console.WriteLine(); Console.WriteLine( "Runs a set of NUnit tests from the console." ); Console.WriteLine(); Console.WriteLine( "You may specify one or more assemblies or a single" ); Console.WriteLine( "project file of type .nunit." ); Console.WriteLine(); Console.WriteLine( "Options:" ); base.Help(); Console.WriteLine(); Console.WriteLine( "Options that take values may use an equal sign, a colon" ); Console.WriteLine( "or a space to separate the option from its value." ); Console.WriteLine(); } } }NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/nunit-console.build0000664000175000017500000000247711537354436025202 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/ConsoleRunner/nunit-console/ConsoleUi.cs0000664000175000017500000003463311702653474023610 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.ConsoleRunner { using System; using System.IO; using System.Reflection; using System.Xml; using System.Resources; using System.Text; using NUnit.Core; using NUnit.Core.Filters; using NUnit.Util; /// /// Summary description for ConsoleUi. /// public class ConsoleUi { public static readonly int OK = 0; public static readonly int INVALID_ARG = -1; public static readonly int FILE_NOT_FOUND = -2; public static readonly int FIXTURE_NOT_FOUND = -3; public static readonly int UNEXPECTED_ERROR = -100; private string workDir; public ConsoleUi() { } public int Execute( ConsoleOptions options ) { this.workDir = options.work; if (workDir == null || workDir == string.Empty) workDir = Environment.CurrentDirectory; else { workDir = Path.GetFullPath(workDir); if (!Directory.Exists(workDir)) Directory.CreateDirectory(workDir); } TextWriter outWriter = Console.Out; bool redirectOutput = options.output != null && options.output != string.Empty; if ( redirectOutput ) { StreamWriter outStreamWriter = new StreamWriter( Path.Combine(workDir, options.output) ); outStreamWriter.AutoFlush = true; outWriter = outStreamWriter; } TextWriter errorWriter = Console.Error; bool redirectError = options.err != null && options.err != string.Empty; if ( redirectError ) { StreamWriter errorStreamWriter = new StreamWriter( Path.Combine(workDir, options.err) ); errorStreamWriter.AutoFlush = true; errorWriter = errorStreamWriter; } TestPackage package = MakeTestPackage(options); ProcessModel processModel = package.Settings.Contains("ProcessModel") ? (ProcessModel)package.Settings["ProcessModel"] : ProcessModel.Default; DomainUsage domainUsage = package.Settings.Contains("DomainUsage") ? (DomainUsage)package.Settings["DomainUsage"] : DomainUsage.Default; RuntimeFramework framework = package.Settings.Contains("RuntimeFramework") ? (RuntimeFramework)package.Settings["RuntimeFramework"] : RuntimeFramework.CurrentFramework; #if CLR_2_0 || CLR_4_0 Console.WriteLine("ProcessModel: {0} DomainUsage: {1}", processModel, domainUsage); Console.WriteLine("Execution Runtime: {0}", framework); #else Console.WriteLine("DomainUsage: {0}", domainUsage); if (processModel != ProcessModel.Default && processModel != ProcessModel.Single) Console.WriteLine("Warning: Ignoring project setting 'processModel={0}'", processModel); if (!RuntimeFramework.CurrentFramework.Supports(framework)) Console.WriteLine("Warning: Ignoring project setting 'runtimeFramework={0}'", framework); #endif using (TestRunner testRunner = new DefaultTestRunnerFactory().MakeTestRunner(package)) { testRunner.Load(package); if (testRunner.Test == null) { testRunner.Unload(); Console.Error.WriteLine("Unable to locate fixture {0}", options.fixture); return FIXTURE_NOT_FOUND; } EventCollector collector = new EventCollector( options, outWriter, errorWriter ); TestFilter testFilter = TestFilter.Empty; SimpleNameFilter nameFilter = new SimpleNameFilter(); if ( options.run != null && options.run != string.Empty ) { Console.WriteLine( "Selected test(s): " + options.run ); foreach (string name in TestNameParser.Parse(options.run)) nameFilter.Add(name); testFilter = nameFilter; } if (options.runlist != null && options.runlist != string.Empty) { Console.WriteLine("Run list: " + options.runlist); using (StreamReader rdr = new StreamReader(options.runlist)) { // NOTE: We can't use rdr.EndOfStream because it's // not present in .NET 1.x. string line = rdr.ReadLine(); while (line != null) { if (line[0] != '#') nameFilter.Add(line); line = rdr.ReadLine(); } } testFilter = nameFilter; } if ( options.include != null && options.include != string.Empty ) { TestFilter includeFilter = new CategoryExpression( options.include ).Filter; Console.WriteLine("Included categories: " + includeFilter.ToString()); if (testFilter.IsEmpty) testFilter = includeFilter; else testFilter = new AndFilter( testFilter, includeFilter ); } if ( options.exclude != null && options.exclude != string.Empty ) { TestFilter excludeFilter = new NotFilter( new CategoryExpression( options.exclude ).Filter ); Console.WriteLine("Excluded categories: " + excludeFilter.ToString()); if ( testFilter.IsEmpty ) testFilter = excludeFilter; else if ( testFilter is AndFilter ) ((AndFilter)testFilter).Add( excludeFilter ); else testFilter = new AndFilter( testFilter, excludeFilter ); } if (testFilter is NotFilter) ((NotFilter)testFilter).TopLevel = true; TestResult result = null; string savedDirectory = Environment.CurrentDirectory; TextWriter savedOut = Console.Out; TextWriter savedError = Console.Error; try { result = testRunner.Run( collector, testFilter, false, LoggingThreshold.Off ); } finally { outWriter.Flush(); errorWriter.Flush(); if ( redirectOutput ) outWriter.Close(); if ( redirectError ) errorWriter.Close(); Environment.CurrentDirectory = savedDirectory; Console.SetOut( savedOut ); Console.SetError( savedError ); } Console.WriteLine(); int returnCode = UNEXPECTED_ERROR; if (result != null) { string xmlOutput = CreateXmlOutput(result); ResultSummarizer summary = new ResultSummarizer(result); if (options.xmlConsole) { Console.WriteLine(xmlOutput); } else { WriteSummaryReport(summary); if (summary.ErrorsAndFailures > 0 || result.IsError || result.IsFailure) { if (options.stoponerror) { Console.WriteLine("Test run was stopped after first error, as requested."); Console.WriteLine(); } WriteErrorsAndFailuresReport(result); } if (summary.TestsNotRun > 0) WriteNotRunReport(result); if (!options.noresult) { // Write xml output here string xmlResultFile = options.result == null || options.result == string.Empty ? "TestResult.xml" : options.result; using (StreamWriter writer = new StreamWriter(Path.Combine(workDir, xmlResultFile))) { writer.Write(xmlOutput); } } } returnCode = summary.ErrorsAndFailures; } if ( collector.HasExceptions ) { collector.WriteExceptions(); returnCode = UNEXPECTED_ERROR; } return returnCode; } } #region Helper Methods // TODO: See if this can be unified with the Gui's MakeTestPackage private TestPackage MakeTestPackage( ConsoleOptions options ) { TestPackage package; DomainUsage domainUsage = DomainUsage.Default; ProcessModel processModel = ProcessModel.Default; RuntimeFramework framework = null; string[] parameters = new string[options.ParameterCount]; for (int i = 0; i < options.ParameterCount; i++) parameters[i] = Path.GetFullPath((string)options.Parameters[i]); if (options.IsTestProject) { NUnitProject project = Services.ProjectService.LoadProject(parameters[0]); string configName = options.config; if (configName != null) project.SetActiveConfig(configName); package = project.ActiveConfig.MakeTestPackage(); processModel = project.ProcessModel; domainUsage = project.DomainUsage; framework = project.ActiveConfig.RuntimeFramework; } else if (parameters.Length == 1) { package = new TestPackage(parameters[0]); domainUsage = DomainUsage.Single; } else { // TODO: Figure out a better way to handle "anonymous" packages package = new TestPackage(null, parameters); package.AutoBinPath = true; domainUsage = DomainUsage.Multiple; } #if CLR_2_0 || CLR_4_0 if (options.framework != null) framework = RuntimeFramework.Parse(options.framework); if (options.process != ProcessModel.Default) processModel = options.process; #endif if (options.domain != DomainUsage.Default) domainUsage = options.domain; package.TestName = options.fixture; package.Settings["ProcessModel"] = processModel; package.Settings["DomainUsage"] = domainUsage; if (framework != null) package.Settings["RuntimeFramework"] = framework; if (domainUsage == DomainUsage.None) { // Make sure that addins are available CoreExtensions.Host.AddinRegistry = Services.AddinRegistry; } package.Settings["ShadowCopyFiles"] = !options.noshadow; package.Settings["UseThreadedRunner"] = !options.nothread; package.Settings["DefaultTimeout"] = options.timeout; package.Settings["WorkDirectory"] = this.workDir; package.Settings["StopOnError"] = options.stoponerror; if (options.apartment != System.Threading.ApartmentState.Unknown) package.Settings["ApartmentState"] = options.apartment; return package; } private static string CreateXmlOutput( TestResult result ) { StringBuilder builder = new StringBuilder(); new XmlResultWriter(new StringWriter( builder )).SaveTestResult(result); return builder.ToString(); } private static void WriteSummaryReport( ResultSummarizer summary ) { Console.WriteLine( "Tests run: {0}, Errors: {1}, Failures: {2}, Inconclusive: {3}, Time: {4} seconds", summary.TestsRun, summary.Errors, summary.Failures, summary.Inconclusive, summary.Time); Console.WriteLine( " Not run: {0}, Invalid: {1}, Ignored: {2}, Skipped: {3}", summary.TestsNotRun, summary.NotRunnable, summary.Ignored, summary.Skipped); Console.WriteLine(); } private void WriteErrorsAndFailuresReport(TestResult result) { reportIndex = 0; Console.WriteLine("Errors and Failures:"); WriteErrorsAndFailures(result); Console.WriteLine(); } private void WriteErrorsAndFailures(TestResult result) { if (result.Executed) { if (result.HasResults) { if (result.IsFailure || result.IsError) if (result.FailureSite == FailureSite.SetUp || result.FailureSite == FailureSite.TearDown) WriteSingleResult(result); foreach (TestResult childResult in result.Results) WriteErrorsAndFailures(childResult); } else if (result.IsFailure || result.IsError) { WriteSingleResult(result); } } } private void WriteNotRunReport(TestResult result) { reportIndex = 0; Console.WriteLine("Tests Not Run:"); WriteNotRunResults(result); Console.WriteLine(); } private int reportIndex = 0; private void WriteNotRunResults(TestResult result) { if (result.HasResults) foreach (TestResult childResult in result.Results) WriteNotRunResults(childResult); else if (!result.Executed) WriteSingleResult( result ); } private void WriteSingleResult( TestResult result ) { string status = result.IsFailure || result.IsError ? string.Format("{0} {1}", result.FailureSite, result.ResultState) : result.ResultState.ToString(); Console.WriteLine("{0}) {1} : {2}", ++reportIndex, status, result.FullName); if ( result.Message != null && result.Message != string.Empty ) Console.WriteLine(" {0}", result.Message); if (result.StackTrace != null && result.StackTrace != string.Empty) Console.WriteLine( result.IsFailure ? StackTraceFilter.Filter(result.StackTrace) : result.StackTrace + Environment.NewLine ); } #endregion } } NUnit-2.6.0.12051/src/tests/0000775000175000017500000000000011742560362015116 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/tests/mock-assembly/0000775000175000017500000000000011742560362017664 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/tests/mock-assembly/mock-assembly.csproj0000664000175000017500000000776511574577562023710 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {2E368281-3BA8-4050-B05E-0E0E43F8F446} Debug AnyCPU mock-assembly JScript Grid IE50 false Library NUnit.Tests OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.XML nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.framework.dll CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/tests/mock-assembly/MockAssembly.cs0000664000175000017500000001723611672146720022615 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; namespace NUnit.Tests { namespace Assemblies { /// /// Constant definitions for the mock-assembly dll. /// public class MockAssembly { #if CLR_2_0 || CLR_4_0 public static int Classes = 9; #else public static int Classes = 8; #endif public static int NamespaceSuites = 6; // assembly, NUnit, Tests, Assemblies, Singletons, TestAssembly public static int Tests = MockTestFixture.Tests + Singletons.OneTestCase.Tests + TestAssembly.MockTestFixture.Tests + IgnoredFixture.Tests + ExplicitFixture.Tests + BadFixture.Tests + FixtureWithTestCases.Tests + ParameterizedFixture.Tests + GenericFixtureConstants.Tests; public static int Suites = MockTestFixture.Suites + Singletons.OneTestCase.Suites + TestAssembly.MockTestFixture.Suites + IgnoredFixture.Suites + ExplicitFixture.Suites + BadFixture.Suites + FixtureWithTestCases.Suites + ParameterizedFixture.Suites + GenericFixtureConstants.Suites + NamespaceSuites; public static readonly int Nodes = Tests + Suites; public static int ExplicitFixtures = 1; public static int SuitesRun = Suites - ExplicitFixtures; public static int Ignored = MockTestFixture.Ignored + IgnoredFixture.Tests; public static int Explicit = MockTestFixture.Explicit + ExplicitFixture.Tests; public static int NotRunnable = MockTestFixture.NotRunnable + BadFixture.Tests; public static int NotRun = Ignored + Explicit + NotRunnable; public static int TestsRun = Tests - NotRun; public static int ResultCount = Tests - Explicit; public static int Errors = MockTestFixture.Errors; public static int Failures = MockTestFixture.Failures; public static int ErrorsAndFailures = Errors + Failures; public static int Categories = MockTestFixture.Categories; public static string AssemblyPath = AssemblyHelper.GetAssemblyPath(typeof(MockAssembly)); } public class MockSuite { [Suite] public static TestSuite Suite { get { return new TestSuite( "MockSuite" ); } } } [TestFixture(Description="Fake Test Fixture")] [Category("FixtureCategory")] public class MockTestFixture { public static readonly int Tests = 11; public static readonly int Suites = 1; public static readonly int Ignored = 1; public static readonly int Explicit = 1; public static readonly int NotRunnable = 2; public static readonly int NotRun = Ignored + Explicit + NotRunnable; public static readonly int TestsRun = Tests - NotRun; public static readonly int ResultCount = Tests - Explicit; public static readonly int Failures = 1; public static readonly int Errors = 1; public static readonly int ErrorsAndFailures = Errors + Failures; public static readonly int Categories = 5; public static readonly int MockCategoryTests = 2; [Test(Description="Mock Test #1")] public void MockTest1() {} [Test] [Category("MockCategory")] [Property("Severity","Critical")] [Description("This is a really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really long description")] public void MockTest2() {} [Test] [Category("MockCategory")] [Category("AnotherCategory")] public void MockTest3() { Assert.Pass("Succeeded!"); } [Test] protected static void MockTest5() {} [Test] public void FailingTest() { Assert.Fail("Intentional failure"); } [Test, Property("TargetMethod", "SomeClassName"), Property("Size", 5), /*Property("TargetType", typeof( System.Threading.Thread ))*/] public void TestWithManyProperties() {} [Test] [Ignore("ignoring this test method for now")] [Category("Foo")] public void MockTest4() {} [Test, Explicit] [Category( "Special" )] public void ExplicitlyRunTest() {} [Test] public void NotRunnableTest( int a, int b) { } [Test] public void InconclusiveTest() { Assert.Inconclusive("No valid data"); } [Test] public void TestWithException() { MethodThrowsException(); } private void MethodThrowsException() { throw new ApplicationException("Intentional Exception"); } } } namespace Singletons { [TestFixture] public class OneTestCase { public static readonly int Tests = 1; public static readonly int Suites = 1; [Test] public virtual void TestCase() {} } } namespace TestAssembly { [TestFixture] public class MockTestFixture { public static readonly int Tests = 1; public static readonly int Suites = 1; [Test] public void MyTest() { } } } [TestFixture, Ignore] public class IgnoredFixture { public static readonly int Tests = 3; public static readonly int Suites = 1; [Test] public void Test1() { } [Test] public void Test2() { } [Test] public void Test3() { } } [TestFixture,Explicit] public class ExplicitFixture { public static readonly int Tests = 2; public static readonly int Suites = 1; public static readonly int Nodes = Tests + Suites; [Test] public void Test1() { } [Test] public void Test2() { } } [TestFixture] public class BadFixture { public static readonly int Tests = 1; public static readonly int Suites = 1; public BadFixture(int val) { } [Test] public void SomeTest() { } } [TestFixture] public class FixtureWithTestCases { #if CLR_2_0 || CLR_4_0 public static readonly int Tests = 4; public static readonly int Suites = 3; #else public static readonly int Tests = 2; public static readonly int Suites = 2; #endif [TestCase(2, 2, Result=4)] [TestCase(9, 11, Result=20)] public int MethodWithParameters(int x, int y) { return x+y; } #if CLR_2_0 || CLR_4_0 [TestCase(2, 4)] [TestCase(9.2, 11.7)] public void GenericMethod(T x, T y) { } #endif } [TestFixture(5)] [TestFixture(42)] public class ParameterizedFixture { public static readonly int Tests = 4; public static readonly int Suites = 3; public ParameterizedFixture(int num) { } [Test] public void Test1() { } [Test] public void Test2() { } } public class GenericFixtureConstants { #if CLR_2_0 || CLR_4_0 public static readonly int Tests = 4; public static readonly int Suites = 3; #else public static readonly int Tests = 0; public static readonly int Suites = 0; #endif } #if CLR_2_0 || CLR_4_0 [TestFixture(5)] [TestFixture(11.5)] public class GenericFixture { public GenericFixture(T num){ } [Test] public void Test1() { } [Test] public void Test2() { } } #endif } NUnit-2.6.0.12051/src/tests/mock-assembly/mock-assembly.build0000664000175000017500000000167311504175260023455 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/tests/test-utilities/0000775000175000017500000000000011742560362020106 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/tests/test-utilities/TestAssert.cs0000664000175000017500000000513111652212362022530 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; using NUnit.Framework; namespace NUnit.TestUtilities { public class TestAssert { #region IsRunnable public static void IsRunnable(Test test) { Assert.AreEqual(RunState.Runnable, test.RunState); } public static void IsRunnable(Type type) { TestSuite suite = TestBuilder.MakeFixture(type); Assert.NotNull(suite, "Unable to construct fixture"); Assert.AreEqual(RunState.Runnable, suite.RunState); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Success, result.ResultState); } public static void IsRunnable(Type type, string name) { IsRunnable(type, name, ResultState.Success); } public static void IsRunnable(Type type, string name, ResultState resultState) { Test test = TestBuilder.MakeTestCase(type, name); Assert.That(test.RunState, Is.EqualTo(RunState.Runnable)); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); if (result.HasResults) result = (TestResult)result.Results[0]; Assert.That(result.ResultState, Is.EqualTo(resultState)); } #endregion #region IsNotRunnable public static void IsNotRunnable(Test test) { Assert.AreEqual(RunState.NotRunnable, test.RunState); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.NotRunnable, result.ResultState); } public static void IsNotRunnable(Type type) { TestSuite fixture = TestBuilder.MakeFixture(type); Assert.NotNull(fixture, "Unable to construct fixture"); IsNotRunnable(fixture); } public static void IsNotRunnable(Type type, string name) { IsNotRunnable(TestBuilder.MakeTestCase(type, name)); } public static void ChildNotRunnable(Type type, string name) { IsNotRunnable((Test)TestBuilder.MakeTestCase(type, name).Tests[0]); } #endregion private TestAssert() { } } } NUnit-2.6.0.12051/src/tests/test-utilities/FormTester.cs0000664000175000017500000001657111504175260022534 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Windows.Forms; using NUnit.Framework; namespace NUnit.TestUtilities { /// /// TestFixtures that test Forms inherit from this class. /// public class FormTester : ControlTester { public FormTester() { } public FormTester( Form form ) : base( form ) { } public Form Form { get { return Control as Form; } set { Control = value; } } } /// /// TestFixtures that test Controls inherit from this class. /// public class ControlTester { public ControlTester() { } public ControlTester( Control control ) { this.control = control; } // TODO: Rewrite using generics when we move to .NET 2.0 // The control we are testing private Control control; // Various ways of looking at this control's controls private ControlCollection controls; private ButtonCollection buttons; private LabelCollection labels; private TextBoxCollection textboxes; private ComboBoxCollection combos; #region Properties /// /// Get and set the control to be tested /// public Control Control { get { return control; } set { control = value; InitCollections(); } } private void InitCollections() { controls = new ControlCollection( control.Controls ); // These will be initialized as needed buttons = null; labels = null; textboxes = null; combos = null; } /// /// Get our collection of all the controls on this control. /// public ControlCollection Controls { get { return controls; } } /// /// Get our collection of all the buttons on this control. /// public ButtonCollection Buttons { get { if ( buttons == null ) buttons = new ButtonCollection( control.Controls ); return buttons; } } /// /// Get our collection of all the labels on this control. /// public LabelCollection Labels { get { if (labels == null ) labels = new LabelCollection( control.Controls ); return labels; } } /// /// Get our collection of all the TextBoxes on this control. /// public TextBoxCollection TextBoxes { get { if ( textboxes == null ) textboxes = new TextBoxCollection( control.Controls ); return textboxes; } } /// /// Get our collection of all ComboBoxes on the form /// public ComboBoxCollection Combos { get { if ( combos == null ) combos = new ComboBoxCollection( control.Controls ); return combos; } } #endregion #region Assertions /// /// Assert that a control with a given name exists on this control. /// /// The name of the control. public void AssertControlExists( string targetName ) { AssertControlExists( targetName, null ); } public void AssertControlExists( string expectedName, Type expectedType ) { bool gotName = false; System.Type gotType = null; foreach( Control ctl in control.Controls ) { if ( ctl.Name == expectedName ) { gotName = true; if ( expectedType == null ) return; gotType = ctl.GetType(); if ( expectedType.IsAssignableFrom( gotType ) ) return; } } if ( gotName ) Assert.Fail( "Expected control {0} to be a {1} but was {2}", expectedName, expectedType.Name, gotType.Name ); else Assert.Fail( "{0} does not contain {1} control", control.Name, expectedName ); } public void AssertControlsAreStackedVertically( params string[] names ) { string prior = null; foreach( string current in names ) { if ( prior != null ) { if ( Controls[prior].Bottom > Controls[current].Top ) Assert.Fail( "The {0} control should be above the {1} control", prior, current ); } prior = current; } } #endregion #region Other public methods public string GetText( string name ) { return Controls[ name ].Text; } #endregion #region Nested Collection Classes #region Enumerator used by all collections public class ControlEnumerator : IEnumerator { IEnumerator sourceEnum; System.Type typeFilter; public ControlEnumerator( Control.ControlCollection source, System.Type typeFilter ) { this.sourceEnum = source.GetEnumerator(); this.typeFilter = typeFilter; } #region IEnumerator Members public void Reset() { sourceEnum.Reset(); } public object Current { get { return sourceEnum.Current; } } public bool MoveNext() { while( sourceEnum.MoveNext() ) { if ( typeFilter == null || typeFilter.IsAssignableFrom( Current.GetType() ) ) return true; } return false; } #endregion } #endregion #region Control Collection public class ControlCollection : IEnumerable { protected Control.ControlCollection source; private System.Type typeFilter; public ControlCollection( Control.ControlCollection source ) : this( source, null ) { } public ControlCollection( Control.ControlCollection source, System.Type typeFilter ) { this.source = source; this.typeFilter = typeFilter; } public Control this[string name] { get { foreach( Control control in this ) { if ( control.Name == name ) return control; } return null; } } #region IEnumerable Members public IEnumerator GetEnumerator() { return new ControlEnumerator( this.source, this.typeFilter ); } #endregion } #endregion #region ButtonCollection public class ButtonCollection : ControlCollection { public ButtonCollection( Control.ControlCollection controls ) : base( controls, typeof( Button ) ) { } public new Button this[string name] { get { return base[name] as Button; } } } #endregion #region LabelCollection public class LabelCollection : ControlCollection { public LabelCollection( Control.ControlCollection controls ) : base( controls, typeof( Label ) ) { } public new Label this[string name] { get { return base[name] as Label; } } } #endregion #region TextBoxCollection public class TextBoxCollection : ControlCollection { public TextBoxCollection( Control.ControlCollection controls ) : base( controls, typeof( TextBox ) ) { } public new TextBox this[string name] { get { return base[name] as TextBox; } } } #endregion #region ComboBoxCollection public class ComboBoxCollection : ControlCollection { public ComboBoxCollection( Control.ControlCollection controls ) : base( controls, typeof( ComboBox ) ) { } public new ComboBox this[string name] { get { return base[name] as ComboBox; } } } #endregion #endregion } } NUnit-2.6.0.12051/src/tests/test-utilities/TestFinder.cs0000664000175000017500000000321011504175260022473 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; using NUnit.Framework; namespace NUnit.TestUtilities { /// /// Utility class used to locate tests by name in a test tree /// public class TestFinder { public static Test Find(string name, Test test, bool recursive) { if (test.Tests != null) { foreach(Test child in test.Tests) { if (child.TestName.Name == name) return child; if (recursive) { Test grandchild = Find(name, child, true); if (grandchild != null) return grandchild; } } } return null; } public static TestResult Find(string name, TestResult result, bool recursive) { if ( result.HasResults ) { foreach (TestResult childResult in result.Results) { if (childResult.Test.TestName.Name == name) return childResult; if (recursive) { TestResult r = Find(name, childResult, true); if (r != null) return r; } } } return null; } private TestFinder() { } } } NUnit-2.6.0.12051/src/tests/test-utilities/test-utilities.build0000664000175000017500000000262311543625326024123 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/tests/test-utilities/TestBuilder.cs0000664000175000017500000000421511504175260022660 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using NUnit.Framework; using NUnit.Core; using NUnit.Core.Builders; using NUnit.Core.Extensibility; namespace NUnit.TestUtilities { /// /// Utility Class used to build NUnit tests for use as test data /// public class TestBuilder { private static ISuiteBuilder suiteBuilder = (ISuiteBuilder)CoreExtensions.Host.GetExtensionPoint("SuiteBuilders"); private static ITestCaseBuilder testBuilder = (ITestCaseBuilder)CoreExtensions.Host.GetExtensionPoint("TestCaseBuilders"); public static TestSuite MakeFixture( Type type ) { return (TestSuite)suiteBuilder.BuildFrom( type ); } public static TestSuite MakeFixture( object fixture ) { TestSuite suite = (TestSuite)suiteBuilder.BuildFrom( fixture.GetType() ); suite.Fixture = fixture; return suite; } public static Test MakeTestCase( Type type, string methodName ) { MethodInfo method = Reflect.GetNamedMethod(type, methodName); if (method == null) Assert.Fail("Method not found: " + methodName); return testBuilder.BuildFrom(method); } public static Test MakeTestCase( object fixture, string methodName ) { Test test = MakeTestCase( fixture.GetType(), methodName ); test.Fixture = fixture; return test; } public static TestResult RunTestFixture( Type type ) { return MakeFixture(type).Run(NullListener.NULL, TestFilter.Empty); } public static TestResult RunTestFixture( object fixture ) { return MakeFixture(fixture).Run(NullListener.NULL, TestFilter.Empty); } public static TestResult RunTestCase( Type type, string methodName ) { return MakeTestCase(type, methodName).Run(NullListener.NULL, TestFilter.Empty); } private TestBuilder() { } } } NUnit-2.6.0.12051/src/tests/test-utilities/MockTestEventSource.cs0000664000175000017500000000540711504175260024352 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core; using NUnit.Util; namespace NUnit.TestUtilities { /// /// Summary description for MockTestEventSource. /// public class MockTestEventSource : TestEventDispatcher, EventListener { //private string testFileName; private TestSuite suite; public MockTestEventSource( TestSuite suite ) { this.suite = suite; //this.testFileName = testFileName; } public void SimulateTestRun() { FireRunStarting( suite.TestName.FullName, suite.TestCount ); //TestResult result = SimulateTest( fixture, RunState.Runnable ); TestResult result = suite.Run(this, TestFilter.Empty); FireRunFinished( result ); } // private TestResult SimulateTest( Test test, RunState parentState ) // { // if ( test.IsSuite && test.RunState != RunState.Explicit ) // { // FireSuiteStarting( test.TestName ); // // TestResult result = new TestResult( test ); // // foreach( TestNode childTest in test.Tests ) // result.AddResult( SimulateTest( childTest, test.RunState ) ); // // FireSuiteFinished( result ); // // return result; // } // else // { // FireTestStarting( test.TestName ); // // TestResult result = new TestResult( test ); // // result.RunState = parentState == RunState.Runnable ? RunState.Executed : parentState; // // FireTestFinished( result ); // // return result; // } // } #region EventListener Members void EventListener.TestStarted(TestName testName) { this.FireTestStarting( testName ); } void EventListener.RunStarted(string name, int testCount) { this.FireRunStarting( name, testCount ); } void EventListener.RunFinished(Exception exception) { this.FireRunFinished(exception); } void EventListener.RunFinished(TestResult result) { this.FireRunFinished(result); } void EventListener.SuiteFinished(TestResult result) { this.FireSuiteFinished(result); } void EventListener.TestFinished(TestResult result) { this.FireTestFinished(result); } void EventListener.UnhandledException(Exception exception) { this.FireRunFinished(exception); } void EventListener.TestOutput(TestOutput testOutput) { this.FireTestOutput(testOutput); } void EventListener.SuiteStarted(TestName testName) { this.FireSuiteStarting(testName); } #endregion } } NUnit-2.6.0.12051/src/tests/test-utilities/test-utilities.csproj0000664000175000017500000001110511574617510024317 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} Debug AnyCPU test-utilities JScript Grid IE50 false Library NUnit.TestUtilities OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG true 4096 618, 672 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE 4096 618, 672 true false false 4 none prompt System System.Data System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/tests/test-utilities/TempResourceFile.cs0000664000175000017500000000327011543625326023655 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.TestUtilities { using System; using System.IO; public class TempResourceFile : IDisposable { string path; public TempResourceFile(Type type, string name) : this(type, name, null) {} public TempResourceFile(Type type, string name, string filePath) { if (filePath == null) filePath = name; if (!System.IO.Path.IsPathRooted(filePath)) filePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), filePath); this.path = filePath; Stream stream = type.Assembly.GetManifestResourceStream(type, name); byte[] buffer = new byte[(int)stream.Length]; stream.Read(buffer, 0, buffer.Length); string dir = System.IO.Path.GetDirectoryName(this.path); if(dir != null && dir.Length != 0) { Directory.CreateDirectory(dir); } using(FileStream fileStream = new FileStream(this.path, FileMode.Create)) { fileStream.Write(buffer, 0, buffer.Length); } } public void Dispose() { File.Delete(this.path); string path = this.path; while(true) { path = System.IO.Path.GetDirectoryName(path); if(path == null || path.Length == 0 || Directory.GetFiles(path).Length > 0) { break; } Directory.Delete(path); } } public string Path { get { return this.path; } } } } NUnit-2.6.0.12051/src/tests/nonamespace-assembly/0000775000175000017500000000000011742560362021224 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/tests/nonamespace-assembly/nonamespace-assembly.build0000664000175000017500000000165411504175260026354 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/tests/nonamespace-assembly/nonamespace-assembly.csproj0000664000175000017500000000734211574617510026563 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} Debug AnyCPU nonamespace-assembly JScript Grid IE50 false Library nonamespace_assembly OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE 4096 true false false 4 none prompt System System.Data System.XML {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/tests/nonamespace-assembly/NoNamespaceTestFixture.cs0000664000175000017500000000126511504175260026152 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using NUnit.Framework; [TestFixture] public class NoNamespaceTestFixture { public static readonly int Tests = 3; public static readonly string AssemblyPath = NUnit.Core.AssemblyHelper.GetAssemblyPath(typeof(NoNamespaceTestFixture)); [Test] public void Test1() { } [Test] public void Test2() { } [Test] public void Test3() { } } NUnit-2.6.0.12051/src/tests/test-assembly/0000775000175000017500000000000011742560362017712 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/tests/test-assembly/TestCaseAttributeFixture.cs0000664000175000017500000000524211654712172025212 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class TestCaseAttributeFixture { [TestCase(2,3,4,Description="My Description")] public void MethodHasDescriptionSpecified(int x, int y, int z) {} [TestCase(2,3,4,TestName="XYZ")] public void MethodHasTestNameSpecified(int x, int y, int z) {} [TestCase(2, 3, 4, Category = "XYZ")] public void MethodHasSingleCategory(int x, int y, int z) { } [TestCase(2, 3, 4, Category = "X,Y,Z")] public void MethodHasMultipleCategories(int x, int y, int z) { } [TestCase(2, 2000000, Result = 4)] public int MethodCausesConversionOverflow(short x, short y) { return x + y; } [TestCase("12-Octobar-1942")] public void MethodHasInvalidDateFormat(DateTime dt) {} [TestCase(2, 3, 4, ExpectedException = typeof(ArgumentNullException))] public void MethodThrowsExpectedException(int x, int y, int z) { throw new ArgumentNullException(); } [TestCase(2, 3, 4, ExpectedException = typeof(ArgumentNullException))] public void MethodThrowsWrongException(int x, int y, int z) { throw new ArgumentException(); } [TestCase(2, 3, 4, ExpectedException = typeof(ArgumentNullException))] public void MethodThrowsNoException(int x, int y, int z) { } [TestCase(2, 3, 4, ExpectedException = typeof(ApplicationException), ExpectedMessage="Test Exception")] public void MethodThrowsExpectedExceptionWithWrongMessage(int x, int y, int z) { throw new ApplicationException("Wrong Test Exception"); } [TestCase(2, 3, 4, ExpectedException = typeof(ArgumentNullException))] public void MethodCallsIgnore(int x, int y, int z) { Assert.Ignore("Ignore this"); } [TestCase(1)] [TestCase(2, Ignore = true)] [TestCase(3, IgnoreReason = "Don't Run Me!")] public void MethodWithIgnoredTestCases(int num) { } [TestCase(1)] [TestCase(2, Explicit = true)] [TestCase(3, Explicit = true, Reason = "Connection failing")] public void MethodWithExplicitTestCases(int num) { } } } NUnit-2.6.0.12051/src/tests/test-assembly/IgnoreFixtureTests.cs0000664000175000017500000000234611504175260024056 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.IgnoreFixture { [TestFixture] public class IgnoredTestCaseFixture { [Test] public void CallsIgnore() { Assert.Ignore("Ignore me"); } [Test, ExpectedException(typeof(InvalidOperationException))] public void CallsIgnoreWithExpectedException() { Assert.Ignore("Ignore me"); } } [TestFixture] public class IgnoredTestSuiteFixture { [TestFixtureSetUp] public void FixtureSetUp() { Assert.Ignore("Ignore this fixture"); } [Test] public void ATest() { } [Test] public void AnotherTest() { } } [TestFixture] public class IgnoreInSetUpFixture { [SetUp] public void SetUp() { Assert.Ignore( "Ignore this test" ); } [Test] public void Test1() { } [Test] public void Test2() { } } } NUnit-2.6.0.12051/src/tests/test-assembly/ThreadingFixture.cs0000664000175000017500000000234211675632520023517 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class ThreadingFixture { public bool TearDownWasRun; [SetUp] public void SetUp() { TearDownWasRun = false; } [TearDown] public void TearDown() { TearDownWasRun = true; } [Test, Timeout(50)] public void InfiniteLoopWith50msTimeout() { while (true) { } } [Test, RequiresThread] public void MethodWithThreeAsserts() { Assert.True(true); Assert.True(true); Assert.True(true); } } [TestFixture, Timeout(50)] public class ThreadingFixtureWithTimeout { [Test] public void Test1() { } [Test] public void Test2WithInfiniteLoop() { while (true) { } } [Test] public void Test3() { } } } NUnit-2.6.0.12051/src/tests/test-assembly/RepeatedTestFixtureTests.cs0000664000175000017500000000442211504175260025221 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.RepeatedTestFixture { [TestFixture] public class RepeatingTestsBase { private int fixtureSetupCount; private int fixtureTeardownCount; private int setupCount; private int teardownCount; protected int count; [TestFixtureSetUp] public void FixtureSetUp() { fixtureSetupCount++; } [TestFixtureTearDown] public void FixtureTearDown() { fixtureTeardownCount++; } [SetUp] public void SetUp() { setupCount++; } [TearDown] public void TearDown() { teardownCount++; } public int FixtureSetupCount { get { return fixtureSetupCount; } } public int FixtureTeardownCount { get { return fixtureTeardownCount; } } public int SetupCount { get { return setupCount; } } public int TeardownCount { get { return teardownCount; } } public int Count { get { return count; } } } public class RepeatSuccessFixture : RepeatingTestsBase { [Test, Repeat(3)] public void RepeatSuccess() { count++; Assert.IsTrue (true); } } public class RepeatFailOnFirstFixture : RepeatingTestsBase { [Test, Repeat(3)] public void RepeatFailOnFirst() { count++; Assert.IsFalse (true); } } public class RepeatFailOnThirdFixture : RepeatingTestsBase { [Test, Repeat(3)] public void RepeatFailOnThird() { count++; if (count == 3) Assert.IsTrue (false); } } public class RepeatedTestWithIgnore : RepeatingTestsBase { [Test, Repeat(3), Ignore("Ignore this test")] public void RepeatShouldIgnore() { Assert.Fail("Ignored test executed"); } } public class RepeatedTestWithCategory : RepeatingTestsBase { [Test, Repeat(3), Category("SAMPLE")] public void TestWithCategory() { count++; Assert.IsTrue(true); } } } NUnit-2.6.0.12051/src/tests/test-assembly/MaxTimeFixture.cs0000664000175000017500000000211711504175260023150 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class MaxTimeFixture { [Test, MaxTime(1)] public void MaxTimeExceeded() { System.Threading.Thread.Sleep(20); } } [TestFixture] public class MaxTimeFixtureWithFailure { [Test, MaxTime(1)] public void MaxTimeExceeded() { System.Threading.Thread.Sleep(20); Assert.Fail("Intentional Failure"); } } [TestFixture] public class MaxTimeFixtureWithError { [Test, MaxTime(1)] public void MaxTimeExceeded() { System.Threading.Thread.Sleep(20); throw new Exception("Exception message"); } } } NUnit-2.6.0.12051/src/tests/test-assembly/TestFixtureBuilderTests.cs0000664000175000017500000000162311504175260025056 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.TestFixtureBuilderTests { [TestFixture] [Category("fixture category")] [Category("second")] public class HasCategories { [Test] public void OneTest() {} } [TestFixture] public class SignatureTestFixture { [Test] public static void Static() { } [Test] public int NotVoid() { return 1; } [Test] public void Parameters(string test) {} [Test] protected void Protected() {} [Test] private void Private() {} [Test] public void TestVoid() {} } } NUnit-2.6.0.12051/src/tests/test-assembly/FailFixtureTests.cs0000664000175000017500000000325311504175260023504 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.FailFixture { [TestFixture] public class VerifyFailThrowsException { public static string failureMessage = "This should call fail"; [Test] public void CallAssertFail() { Assert.Fail(failureMessage); } } [TestFixture] public class VerifyTestResultRecordsInnerExceptions { [Test] public void ThrowInnerException() { throw new Exception("Outer Exception", new Exception("Inner Exception")); } } [TestFixture] public class BadStackTraceFixture { [Test] public void TestFailure() { throw new ExceptionWithBadStackTrace("thrown by me"); } } public class ExceptionWithBadStackTrace : Exception { public ExceptionWithBadStackTrace( string message ) : base( message ) { } public override string StackTrace { get { throw new InvalidOperationException( "Simulated failure getting stack trace" ); } } } [TestFixture] public class CustomExceptionFixture { [Test] public void ThrowCustomException() { throw new CustomException( "message", new CustomType() ); } private class CustomType { } private class CustomException : Exception { public CustomType custom; public CustomException( string msg, CustomType custom ) : base( msg ) { this.custom = custom; } } } } NUnit-2.6.0.12051/src/tests/test-assembly/TestMethodSignatureFixture.cs0000664000175000017500000000610211504175260025544 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class TestMethodSignatureFixture { public static int Tests = 20; public static int Runnable = 12; public static int NotRunnable = 8; public static int Errors = 3; public static int Failures = 0; [Test] public void InstanceTestMethod() { } [Test] public static void StaticTestMethod() { } [Test] public void TestMethodWithArgumentsNotProvided(int x, int y, string label) { } [Test] public static void StaticTestMethodWithArgumentsNotProvided(int x, int y, string label) { } [TestCase(5, 2, "ABC")] public void TestMethodWithoutParametersWithArgumentsProvided() { } [TestCase(5, 2, "ABC")] public void TestMethodWithArgumentsProvided(int x, int y, string label) { Assert.AreEqual(5, x); Assert.AreEqual(2, y); Assert.AreEqual("ABC", label); } [TestCase(5, 2, "ABC")] public static void StaticTestMethodWithArgumentsProvided(int x, int y, string label) { Assert.AreEqual(5, x); Assert.AreEqual(2, y); Assert.AreEqual("ABC", label); } [TestCase(2, 2)] public void TestMethodWithWrongNumberOfArgumentsProvided(int x, int y, string label) { } [TestCase(2, 2, 3.5)] public void TestMethodWithWrongArgumentTypesProvided(int x, int y, string label) { } [TestCase(2, 2)] public static void StaticTestMethodWithWrongNumberOfArgumentsProvided(int x, int y, string label) { } [TestCase(2, 2, 3.5)] public static void StaticTestMethodWithWrongArgumentTypesProvided(int x, int y, string label) { } [TestCase(3.7, 2, 5.7)] public void TestMethodWithConvertibleArguments(double x, double y, double sum) { Assert.AreEqual(sum, x + y, 0.0001); } [TestCase(3.7, 2, 5.7)] public void TestMethodWithNonConvertibleArguments(int x, int y, int sum) { Assert.AreEqual(sum, x + y, 0.0001); } [TestCase(12, 3, 4)] [TestCase( 12, 2, 6 )] [TestCase( 12, 4, 3 )] public void TestMethodWithMultipleTestCases( int n, int d, int q ) { Assert.AreEqual( q, n / d ); } [TestCase(new int[] {1, 2, 3})] public void TestMethodWithParamsArgument(params int[] n) { } // [Test] // public abstract void AbstractTestMethod() { } [Test] protected void ProtectedTestMethod() { } [Test] private void PrivateTestMethod() { } [Test] public bool TestMethodWithReturnType() { return true; } } } NUnit-2.6.0.12051/src/tests/test-assembly/AttributeInheritance.cs0000664000175000017500000000322211504175260024350 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { // Sample Test from a post by Scott Bellware [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] class ConcernAttribute : TestFixtureAttribute { public Type typeOfConcern; public ConcernAttribute( Type typeOfConcern ) { this.typeOfConcern = typeOfConcern; } } [AttributeUsage(AttributeTargets.Method, AllowMultiple=false)] class SpecAttribute : TestAttribute { } /// /// Summary description for AttributeInheritance. /// [Concern(typeof(NUnit.Core.TestRunner))] public class When_collecting_test_fixtures { [Spec] public void should_include_classes_with_an_attribute_derived_from_TestFixtureAttribute() { } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] class NYIAttribute : IgnoreAttribute { public NYIAttribute() : base("Not yet implemented") { } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] class WorkInProcessAttribute : ExplicitAttribute { public WorkInProcessAttribute() : base("Work in progress") { } } public class AttributeInheritanceFixture { [Test, WorkInProcess] public void ShouldBeExplicit() { } [Test, NYI] public void ShouldBeIgnored() { } } } NUnit-2.6.0.12051/src/tests/test-assembly/AttributeDescriptionTests.cs0000664000175000017500000000134411504175260025430 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.AttributeDescriptionFixture { [TestFixture(Description = "Fixture Description")] public class MockFixture { [Test(Description = "Test Description")] public void Method() {} [Test] public void NoDescriptionMethod() {} [Test] [Description("Separate Description")] public void SeparateDescriptionMethod() { } } } NUnit-2.6.0.12051/src/tests/test-assembly/test-assembly.csproj0000664000175000017500000001664711574577562023763 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {1960CAC4-9A82-47C5-A9B3-55BC37572C3C} Debug AnyCPU test-assembly JScript Grid IE50 false Library NUnit.TestData OnBuildSuccess 2.0 http://localhost/test-assembly/ true Web true Foreground 7 Days false false true 0 1.0.0.%2a true false true v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 618,672 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 618,672 true false false 4 none prompt System System.Data System.XML nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} {5261ABA1-98E6-4603-A4F0-59CAC307AC68} pnunit.framework {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} nonamespace-assembly False .NET Framework 2.0 %28x86%29 true False .NET Framework 3.0 %28x86%29 false False .NET Framework 3.5 false CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/tests/test-assembly/TestData.cs0000664000175000017500000000201011504175260021736 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class EmptyFixture {} /// /// Summary description for OneTestCase. This class serves the purpose of /// having a test fixture that has one and only one test case. It is used /// internally for the framework tests. /// /// [TestFixture] public class OneTestCase { /// /// The one and only test case in this fixture. It always succeeds. /// [Test] public virtual void TestCase() {} } public class InheritedTestFixture : OneTestCase { public static readonly int Tests = 2; [Test] public void Test2() {} } } NUnit-2.6.0.12051/src/tests/test-assembly/ExpectExceptionTest.cs0000664000175000017500000001357511504175260024216 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.ExpectExceptionTest { [TestFixture] public class BaseException { [Test] [ExpectedException(typeof(ArgumentException))] public void BaseExceptionTest() { throw new Exception(); } } [TestFixture] public class DerivedException { [Test] [ExpectedException(typeof(Exception))] public void DerivedExceptionTest() { throw new ArgumentException(); } } [TestFixture] public class MismatchedException { [Test] [ExpectedException(typeof(ArgumentException))] public void MismatchedExceptionType() { throw new ArgumentOutOfRangeException(); } [Test] [ExpectedException(ExpectedException=typeof(ArgumentException))] public void MismatchedExceptionTypeAsNamedParameter() { throw new ArgumentOutOfRangeException(); } [Test] [ExpectedException(typeof(ArgumentException), UserMessage="custom message")] public void MismatchedExceptionTypeWithUserMessage() { throw new ArgumentOutOfRangeException(); } [Test] [ExpectedException("System.ArgumentException")] public void MismatchedExceptionName() { throw new ArgumentOutOfRangeException(); } [Test] [ExpectedException("System.ArgumentException", UserMessage="custom message")] public void MismatchedExceptionNameWithUserMessage() { throw new ArgumentOutOfRangeException(); } } [TestFixture] public class SetUpExceptionTests { [SetUp] public void Init() { throw new ArgumentException("SetUp Exception"); } [Test] [ExpectedException(typeof(ArgumentException))] public void Test() { } } [TestFixture] public class TearDownExceptionTests { [TearDown] public void CleanUp() { throw new ArgumentException("TearDown Exception"); } [Test] [ExpectedException(typeof(ArgumentException))] public void Test() {} } [TestFixture] public class TestThrowsExceptionFixture { [Test] public void TestThrow() { throw new Exception(); } } [TestFixture] public class TestDoesNotThrowExceptionFixture { [Test, ExpectedException("System.ArgumentException")] public void TestDoesNotThrowExceptionName() { } [Test, ExpectedException("System.ArgumentException", UserMessage="custom message")] public void TestDoesNotThrowExceptionNameWithUserMessage() { } [Test, ExpectedException( typeof( System.ArgumentException ) )] public void TestDoesNotThrowExceptionType() { } [Test, ExpectedException( typeof( System.ArgumentException ), UserMessage="custom message" )] public void TestDoesNotThrowExceptionTypeWithUserMessage() { } [Test, ExpectedException] public void TestDoesNotThrowUnspecifiedException() { } [Test, ExpectedException( UserMessage="custom message" )] public void TestDoesNotThrowUnspecifiedExceptionWithUserMessage() { } } [TestFixture] public class TestThrowsExceptionWithRightMessage { [Test] [ExpectedException(typeof(Exception), ExpectedMessage="the message")] public void TestThrow() { throw new Exception("the message"); } } [TestFixture] public class TestThrowsArgumentOutOfRangeException { [Test] [ExpectedException(typeof(ArgumentOutOfRangeException)) ] public void TestThrow() { throw new ArgumentOutOfRangeException("param", "actual value", "the message"); } } [TestFixture] public class TestThrowsExceptionWithWrongMessage { [Test] [ExpectedException(typeof(Exception), ExpectedMessage="not the message")] public void TestThrow() { throw new Exception("the message"); } [Test] [ExpectedException( typeof(Exception), ExpectedMessage="not the message", UserMessage="custom message" )] public void TestThrowWithUserMessage() { throw new Exception("the message"); } } [TestFixture] public class TestAssertsBeforeThrowingException { [Test] [ExpectedException(typeof(Exception))] public void TestAssertFail() { Assert.Fail( "private message" ); } } [TestFixture] public class ExceptionHandlerCalledClass : IExpectException { public bool HandlerCalled = false; public bool AlternateHandlerCalled = false; [Test, ExpectedException(typeof(ArgumentException))] public void ThrowsArgumentException() { throw new ArgumentException(); } [Test, ExpectedException(typeof(ArgumentException), Handler = "AlternateExceptionHandler")] public void ThrowsArgumentException_AlternateHandler() { throw new ArgumentException(); } [Test, ExpectedException(typeof(ArgumentException))] public void ThrowsApplicationException() { throw new ApplicationException(); } [Test, ExpectedException(typeof(ArgumentException), Handler = "AlternateExceptionHandler")] public void ThrowsApplicationException_AlternateHandler() { throw new ApplicationException(); } [Test, ExpectedException(typeof(ArgumentException), Handler = "DeliberatelyMissingHandler")] public void MethodWithBadHandler() { throw new ArgumentException(); } public void HandleException(Exception ex) { HandlerCalled = true; } public void AlternateExceptionHandler(Exception ex) { AlternateHandlerCalled = true; } } } NUnit-2.6.0.12051/src/tests/test-assembly/ActionAttributeFixture.cs0000664000175000017500000001112011713201352024671 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; using NUnit.Framework; using System.Diagnostics; using System.Reflection; using NUnit.TestData.ActionAttributeTests; [assembly: SampleAction("AssemblySuite", ActionTargets.Suite)] [assembly: SampleAction("AssemblyTest", ActionTargets.Test)] [assembly: SampleAction("AssemblySite")] namespace NUnit.TestData.ActionAttributeTests { [SetUpFixture] [SampleAction("SetupFixtureSuite", ActionTargets.Suite)] [SampleAction("SetupFixtureTest", ActionTargets.Test)] [SampleAction("SetupFixtureSite")] public class SetupFixture : BaseSetupFixture { } [SampleAction("BaseSetupFixtureSuite", ActionTargets.Suite)] [SampleAction("BaseSetupFixtureTest", ActionTargets.Test)] [SampleAction("BaseSetupFixtureSite")] public abstract class BaseSetupFixture { } [TestFixture] [SampleAction("FixtureSuite", ActionTargets.Suite)] [SampleAction("FixtureTest", ActionTargets.Test)] [SampleAction("FixtureSite")] public class ActionAttributeFixture : BaseActionAttributeFixture, IWithAction { private static List _Results = null; public static List Results { get { return _Results; } set { _Results = value; } } List IWithAction.Results { get { return Results; } } // NOTE: Both test cases use the same message because // order of execution is indeterminate. [Test, TestCase("SomeTest"), TestCase("SomeTest")] [SampleAction("ParameterizedSuite", ActionTargets.Suite)] [SampleAction("ParameterizedTest", ActionTargets.Test)] [SampleAction("ParameterizedSite")] public void SomeTest(string message) { ((IWithAction)this).Results.Add(message); } [Test] [SampleAction("MethodSuite", ActionTargets.Suite)] // should never get invoked [SampleAction("MethodTest", ActionTargets.Test)] [SampleAction("MethodSite")] public void SomeTestNotParameterized() { ((IWithAction)this).Results.Add("SomeTestNotParameterized"); } } [SampleAction("BaseFixtureSuite", ActionTargets.Suite)] [SampleAction("BaseFixtureTest", ActionTargets.Test)] [SampleAction("BaseFixtureSite")] public abstract class BaseActionAttributeFixture : IBaseWithAction { } [SampleAction("InterfaceSuite", ActionTargets.Suite)] [SampleAction("InterfaceTest", ActionTargets.Test)] [SampleAction("InterfaceSite")] public interface IWithAction { List Results { get; } } [SampleAction("BaseInterfaceSuite", ActionTargets.Suite)] [SampleAction("BaseInterfaceTest", ActionTargets.Test)] [SampleAction("BaseInterfaceSite")] public interface IBaseWithAction { } public class SampleActionAttribute : TestActionAttribute { private readonly string _Prefix = null; private readonly ActionTargets _Targets = ActionTargets.Default; public SampleActionAttribute(string prefix) { _Prefix = prefix; } public SampleActionAttribute(string prefix, ActionTargets targets) { _Prefix = prefix; _Targets = targets; } public override void BeforeTest(TestDetails testDetails) { AddResult("Before", testDetails); } public override void AfterTest(TestDetails testDetails) { AddResult("After", testDetails); } public override ActionTargets Targets { get { return _Targets; } } private void AddResult(string phase, TestDetails testDetails) { string message = string.Format("{0}.{1}.{2}.{3}", _Prefix, phase, testDetails.Fixture != null ? "true" : "false", testDetails.Method != null ? "true" : "false"); if(ActionAttributeFixture.Results != null) ActionAttributeFixture.Results.Add(message); } } } #endif NUnit-2.6.0.12051/src/tests/test-assembly/TestCaseTest.cs0000664000175000017500000000103111504175260022602 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.TestCaseTest { [TestFixture] public class HasCategories { [Test] [Category("A category")] [Category("Another Category")] public void ATest() {} } } NUnit-2.6.0.12051/src/tests/test-assembly/ConsoleRunnerTest.cs0000664000175000017500000000275711504175260023703 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.ConsoleRunnerTest { [TestFixture] public class SuccessTest { public static readonly int Tests = 1; [Test] public void Success() {} } [TestFixture] public class FailureTest { [Test] public void Fail() { Assert.Fail(); } } [TestFixture] public class MultiFailureTest { [Test] public void Fail1() { Assert.Fail(); } [Test] public void Fail2() { Assert.Fail(); } [Test] public void Fail3() { Assert.Fail(); } } [TestFixture] public class Bug1073539Fixture { [Test] public void TestCaseMessageOutput() { //Test with lower 128 characters that are common across Windows code pages. byte[] encodedBytes = new byte[255]; byte y = 0; for(int x = 0 ; x < 255 ; x++) { encodedBytes[x] = y++; } string specialString = System.Text.Encoding.Default.GetString(encodedBytes); throw new ApplicationException("Will I break NUnit XML " + specialString); } } [TestFixture] public class Bug1311644Fixture { [Test] public void TestCaseAssertMessageOutput() { Assert.AreEqual(new char[] {(char)0}, new char[] {' '}); } } } NUnit-2.6.0.12051/src/tests/test-assembly/test-assembly.build0000664000175000017500000000530611532545564023537 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/tests/test-assembly/LegacySuiteData.cs0000664000175000017500000000240211504175260023242 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core; namespace NUnit.TestData.LegacySuiteData { public class Suite { [Suite] public static TestSuite MockSuite { get { TestSuite testSuite = new TestSuite("TestSuite"); return testSuite; } } } class NonConformingSuite { [Suite] public static int Integer { get { return 5; } } } public class LegacySuiteReturningFixtureWithArguments { [Suite] public static IEnumerable Suite { get { ArrayList suite = new ArrayList(); suite.Add(new TestClass(5)); return suite; } } [TestFixture] public class TestClass { public int num; public TestClass(int num) { this.num = num; } } } } NUnit-2.6.0.12051/src/tests/test-assembly/TestCaseSourceAttributeFixture.cs0000664000175000017500000000546011672336136026377 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class TestCaseSourceAttributeFixture { [TestCaseSource("source")] public void MethodThrowsExpectedException(int x, int y, int z) { throw new ArgumentNullException(); } [TestCaseSource("source")] public void MethodThrowsWrongException(int x, int y, int z) { throw new ArgumentException(); } [TestCaseSource("source")] public void MethodThrowsNoException(int x, int y, int z) { } [TestCaseSource("source")] public string MethodThrowsNoExceptionButReturnsResult(int x, int y, int z) { return "HELLO"; } [TestCaseSource("source")] public void MethodCallsIgnore(int x, int y, int z) { Assert.Ignore("Ignore this"); } internal static object[] source = new object[] { new TestCaseData( 2, 3, 4 ).Throws(typeof(ArgumentNullException)) }; [TestCaseSource("exception_source")] public void MethodWithSourceThrowingException(string lhs, string rhs) { } [TestCaseSource("ignored_source")] public void MethodWithIgnoredTestCases(int num) { } [TestCaseSource("explicit_source")] public void MethodWithExplicitTestCases(int num) { } private static IEnumerable ignored_source { get { return new object[] { new TestCaseData(1), new TestCaseData(2).Ignore(), new TestCaseData(3).Ignore("Don't Run Me!") }; } } private static IEnumerable explicit_source { get { return new object[] { new TestCaseData(1), new TestCaseData(2).MakeExplicit(), new TestCaseData(3).MakeExplicit("Connection failing") }; } } private static IEnumerable exception_source { get { #if CLR_2_0 || CLR_4_0 yield return new TestCaseData("a", "a"); yield return new TestCaseData("b", "b"); #endif throw new System.Exception("my message"); } } } } NUnit-2.6.0.12051/src/tests/test-assembly/UnhandledExceptions.cs0000664000175000017500000000406311504175260024203 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Text; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class UnhandledExceptions { #region Normal [NUnit.Framework.Test] public void Normal() { throw new ApplicationException("Test exception"); } #endregion Normal #region Threaded [NUnit.Framework.Test] public void Threaded() { System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Normal)); thread.Start(); System.Threading.Thread.Sleep(100); } #endregion Threaded #region ThreadedAndForget [NUnit.Framework.Test] public void ThreadedAndForget() { System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Normal)); thread.Start(); } #endregion ThreadedAndForget #region ThreadedAndWait [NUnit.Framework.Test] public void ThreadedAndWait() { System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Normal)); thread.Start(); thread.Join(); } #endregion ThreadedAndWait #region ThreadedAssert [Test] public void ThreadedAssert() { System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadedAssertProc)); thread.Start(); thread.Join(); } private void ThreadedAssertProc() { Assert.AreEqual(5, 2 + 2); } #endregion } } NUnit-2.6.0.12051/src/tests/test-assembly/FixtureSetUpTearDownTests.cs0000664000175000017500000001556011544454420025343 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.FixtureSetUpTearDown { [TestFixture] public class SetUpAndTearDownFixture { public int setUpCount = 0; public int tearDownCount = 0; [TestFixtureSetUp] public virtual void Init() { setUpCount++; } [TestFixtureTearDown] public virtual void Destroy() { tearDownCount++; } [Test] public void Success() { } [Test] public void EvenMoreSuccess() { } } [TestFixture, Explicit] public class ExplicitSetUpAndTearDownFixture { public int setUpCount = 0; public int tearDownCount = 0; [TestFixtureSetUp] public virtual void Init() { setUpCount++; } [TestFixtureTearDown] public virtual void Destroy() { tearDownCount++; } [Test] public void Success(){} [Test] public void EvenMoreSuccess(){} } [TestFixture] public class InheritSetUpAndTearDown : SetUpAndTearDownFixture { [Test] public void AnotherTest(){} [Test] public void YetAnotherTest(){} } [TestFixture] public class DefineInheritSetUpAndTearDown : SetUpAndTearDownFixture { public int derivedSetUpCount; public int derivedTearDownCount; [TestFixtureSetUp] public override void Init() { derivedSetUpCount++; } [TestFixtureTearDown] public override void Destroy() { derivedTearDownCount++; } [Test] public void AnotherTest() { } [Test] public void YetAnotherTest() { } } [TestFixture] public class DerivedSetUpAndTearDownFixture : SetUpAndTearDownFixture { public int derivedSetUpCount; public int derivedTearDownCount; public bool baseSetUpCalledFirst; public bool baseTearDownCalledLast; [TestFixtureSetUp] public void Init2() { derivedSetUpCount++; baseSetUpCalledFirst = this.setUpCount > 0; } [TestFixtureTearDown] public void Destroy2() { derivedTearDownCount++; baseTearDownCalledLast = this.tearDownCount == 0; } [Test] public void AnotherTest() { } [Test] public void YetAnotherTest() { } } [TestFixture] public class StaticSetUpAndTearDownFixture { public static int setUpCount = 0; public static int tearDownCount = 0; [TestFixtureSetUp] public static void Init() { setUpCount++; } [TestFixtureTearDown] public static void Destroy() { tearDownCount++; } } [TestFixture] public class DerivedStaticSetUpAndTearDownFixture : StaticSetUpAndTearDownFixture { public static int derivedSetUpCount; public static int derivedTearDownCount; public static bool baseSetUpCalledFirst; public static bool baseTearDownCalledLast; [TestFixtureSetUp] public static void Init2() { derivedSetUpCount++; baseSetUpCalledFirst = setUpCount > 0; } [TestFixtureTearDown] public static void Destroy2() { derivedTearDownCount++; baseTearDownCalledLast = tearDownCount == 0; } } #if CLR_2_0 || CLR_4_0 [TestFixture] public static class StaticClassSetUpAndTearDownFixture { public static int setUpCount = 0; public static int tearDownCount = 0; [TestFixtureSetUp] public static void Init() { setUpCount++; } [TestFixtureTearDown] public static void Destroy() { tearDownCount++; } } #endif [TestFixture] public class MisbehavingFixture { public bool blowUpInSetUp = false; public bool blowUpInTearDown = false; public int setUpCount = 0; public int tearDownCount = 0; public void Reinitialize() { setUpCount = 0; tearDownCount = 0; blowUpInSetUp = false; blowUpInTearDown = false; } [TestFixtureSetUp] public void BlowUpInSetUp() { setUpCount++; if (blowUpInSetUp) throw new Exception("This was thrown from fixture setup"); } [TestFixtureTearDown] public void BlowUpInTearDown() { tearDownCount++; if ( blowUpInTearDown ) throw new Exception("This was thrown from fixture teardown"); } [Test] public void nothingToTest() { } } [TestFixture] public class ExceptionInConstructor { public ExceptionInConstructor() { throw new Exception( "This was thrown in constructor" ); } [Test] public void nothingToTest() { } } [TestFixture] public class IgnoreInFixtureSetUp { [TestFixtureSetUp] public void SetUpCallsIgnore() { Assert.Ignore( "TestFixtureSetUp called Ignore" ); } [Test] public void nothingToTest() { } } [TestFixture] public class SetUpAndTearDownWithTestInName { public int setUpCount = 0; public int tearDownCount = 0; [TestFixtureSetUp] public virtual void TestFixtureSetUp() { setUpCount++; } [TestFixtureTearDown] public virtual void TestFixtureTearDown() { tearDownCount++; } [Test] public void Success(){} [Test] public void EvenMoreSuccess(){} } [TestFixture, Ignore( "Do Not Run This" )] public class IgnoredFixture { public bool setupCalled = false; public bool teardownCalled = false; [TestFixtureSetUp] public virtual void ShouldNotRun() { setupCalled = true; } [TestFixtureTearDown] public virtual void NeitherShouldThis() { teardownCalled = true; } [Test] public void Success(){} [Test] public void EvenMoreSuccess(){} } [TestFixture] public class FixtureWithNoTests { public bool setupCalled = false; public bool teardownCalled = false; [TestFixtureSetUp] public virtual void Init() { setupCalled = true; } [TestFixtureTearDown] public virtual void Destroy() { teardownCalled = true; } } [TestFixture] public class DisposableFixture : IDisposable { public bool disposeCalled = false; [Test] public void OneTest() { } public void Dispose() { disposeCalled = true; } } } NUnit-2.6.0.12051/src/tests/test-assembly/TestFixtureExtensionTests.cs0000664000175000017500000000174711504175260025453 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.TestFixtureExtension { [TestFixture] public abstract class BaseTestFixture { public bool baseSetup = false; public bool baseTeardown = false; [SetUp] public void SetUp() { baseSetup = true; } [TearDown] public void TearDown() { baseTeardown = true; } } public class DerivedTestFixture : BaseTestFixture { [Test] public void Success() { Assert.IsTrue(true); } } public class SetUpDerivedTestFixture : BaseTestFixture { [SetUp] public void Init() { base.SetUp(); } [Test] public void Success() { Assert.IsTrue(true); } } } NUnit-2.6.0.12051/src/tests/test-assembly/TestContextData.cs0000664000175000017500000000355111720455462023323 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.TestContextData { [TestFixture] public class TestStateRecordingFixture { public string stateList; public string statusList; public bool testFailure; public bool testInconclusive; public bool setUpFailure; public bool setUpIgnore; [SetUp] public void SetUp() { //stateList = TestContext.CurrentContext.Result.Outcome + "=>"; stateList = TestContext.CurrentContext.Result.State + "=>"; statusList = TestContext.CurrentContext.Result.Status + "=>"; if (setUpFailure) Assert.Fail("Failure in SetUp"); if (setUpIgnore) Assert.Ignore("Ignored in SetUp"); } [Test] public void TheTest() { //stateList += TestContext.CurrentContext.Result.Outcome; stateList += TestContext.CurrentContext.Result.State; statusList += TestContext.CurrentContext.Result.Status; if (testFailure) Assert.Fail("Deliberate failure"); if (testInconclusive) Assert.Inconclusive("Inconclusive test"); } [TearDown] public void TearDown() { //stateList += "=>" + TestContext.CurrentContext.Result.Outcome; stateList += "=>" + TestContext.CurrentContext.Result.State; statusList += "=>" + TestContext.CurrentContext.Result.Status; } } } NUnit-2.6.0.12051/src/tests/test-assembly/TypeHelperFixture.cs0000664000175000017500000000464511720455442023700 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using NUnit.Framework; public class MyNoNamespaceClass { } namespace NUnit.TestData.TypeHelperFixture { // NOTE: TestFixture attributes are not used by the unit tests but // are provided so these class may be loaded in the NUnit gui // for inspection. [TestFixture] public class SimpleClass { } public class ContainerClass { public class NestedClass { [TestFixture] public class DoublyNestedClass { } #if CLR_2_0 || CLR_4_0 [TestFixture(typeof(long))] public class DoublyNestedGeneric { } #endif } #if CLR_2_0 || CLR_4_0 public class NestedGeneric { [TestFixture(typeof(int))] public class DoublyNestedClass { } [TestFixture(typeof(int),typeof(string))] public class DoublyNestedGeneric { } } #endif } #if CLR_2_0 || CLR_4_0 [TestFixture(typeof(int[]))] [TestFixture(typeof(List))] [TestFixture(typeof(List))] [TestFixture(typeof(List>))] public class ListTester where TList : System.Collections.IList { } [TestFixture(typeof(int), typeof(decimal), typeof(string))] public class GenericClass { } public class GenericContainerClass { public class NestedClass { [TestFixture(typeof(int[]))] public class DoublyNestedClass { } [TestFixture(typeof(int), typeof(string))] [TestFixture(typeof(long), typeof(string))] public class DoublyNestedGeneric { } } public class NestedGeneric { [TestFixture(typeof(string), typeof(int))] public class DoublyNestedClass { } [TestFixture(typeof(string), typeof(int), typeof(bool))] public class DoublyNestedGeneric { } } } #endif } NUnit-2.6.0.12051/src/tests/test-assembly/SetUpTest.cs0000664000175000017500000000733311504175260022142 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.SetUpTest { [TestFixture] public class SetUpAndTearDownFixture { public bool wasSetUpCalled; public bool wasTearDownCalled; [SetUp] public virtual void Init() { wasSetUpCalled = true; } [TearDown] public virtual void Destroy() { wasTearDownCalled = true; } [Test] public void Success() { } } [TestFixture] public class SetUpAndTearDownCounterFixture { public int setUpCounter; public int tearDownCounter; [SetUp] public virtual void Init() { setUpCounter++; } [TearDown] public virtual void Destroy() { tearDownCounter++; } [Test] public void TestOne(){} [Test] public void TestTwo(){} [Test] public void TestThree(){} } [TestFixture] public class InheritSetUpAndTearDown : SetUpAndTearDownFixture { [Test] public void AnotherTest(){} } [TestFixture] public class DefineInheritSetUpAndTearDown : SetUpAndTearDownFixture { public bool derivedSetUpCalled; public bool derivedTearDownCalled; [SetUp] public override void Init() { derivedSetUpCalled = true; } [TearDown] public override void Destroy() { derivedTearDownCalled = true; } [Test] public void AnotherTest(){} } public class MultipleSetUpTearDownFixture { public bool wasSetUp1Called; public bool wasSetUp2Called; public bool wasSetUp3Called; public bool wasTearDown1Called; public bool wasTearDown2Called; [SetUp] public virtual void Init1() { wasSetUp1Called = true; } [SetUp] public virtual void Init2() { wasSetUp2Called = true; } [SetUp] public virtual void Init3() { wasSetUp3Called = true; } [TearDown] public virtual void TearDown1() { wasTearDown1Called = true; } [TearDown] public virtual void TearDown2() { wasTearDown2Called = true; } [Test] public void Success() { } } [TestFixture] public class DerivedClassWithSeparateSetUp : SetUpAndTearDownFixture { public bool wasDerivedSetUpCalled; public bool wasDerivedTearDownCalled; public bool wasBaseSetUpCalledFirst; public bool wasBaseTearDownCalledLast; [SetUp] public void DerivedInit() { wasDerivedSetUpCalled = true; wasBaseSetUpCalledFirst = wasSetUpCalled; } [TearDown] public void DerivedTearDown() { wasDerivedTearDownCalled = true; wasBaseTearDownCalledLast = !wasTearDownCalled; } } [TestFixture] public class SetupAndTearDownExceptionFixture { public Exception setupException; public Exception tearDownException; [SetUp] public void SetUp() { if (setupException != null) throw setupException; } [TearDown] public void TearDown() { if (tearDownException!=null) throw tearDownException; } [Test] public void TestOne() {} } } NUnit-2.6.0.12051/src/tests/test-assembly/DatapointFixture.cs0000664000175000017500000000620411720455406023533 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.TestData.DatapointFixture { public abstract class SquareRootTest { [Theory] public void SqrtTimesItselfGivesOriginal(double num) { Assume.That(num >= 0.0 && num < double.MaxValue); double sqrt = Math.Sqrt(num); Assert.That(sqrt >= 0.0); Assert.That(sqrt * sqrt, Is.EqualTo(num).Within(0.000001)); } } public class SquareRootTest_Field_Double : SquareRootTest { [Datapoint] public double zero = 0; [Datapoint] public double positive = 1; [Datapoint] public double negative = -1; [Datapoint] public double max = double.MaxValue; [Datapoint] public double infinity = double.PositiveInfinity; } public class SquareRootTest_Field_ArrayOfDouble : SquareRootTest { [Datapoints] public double[] values = new double[] { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } #if CS_3_0 || CS_4_0 public class SquareRootTest_Field_IEnumerableOfDouble : SquareRootTest { [Datapoints] public IEnumerable values = new List { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } public class SquareRootTest_Property_IEnumerableOfDouble : SquareRootTest { [Datapoints] public IEnumerable Values { get { return new List { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } } } public class SquareRootTest_Method_IEnumerableOfDouble : SquareRootTest { [Datapoints] public IEnumerable GetValues() { return new List { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } } public class SquareRootTest_Iterator_IEnumerableOfDouble : SquareRootTest { [Datapoints] public IEnumerable GetValues() { yield return 0.0; yield return 1.0; yield return -1.0; yield return double.MaxValue; yield return double.PositiveInfinity; } } #endif public class SquareRootTest_Property_ArrayOfDouble : SquareRootTest { [Datapoints] public double[] Values { get { return new double[] { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } } } public class SquareRootTest_Method_ArrayOfDouble : SquareRootTest { [Datapoints] public double[] GetValues() { return new double[] { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; } } } NUnit-2.6.0.12051/src/tests/test-assembly/CultureAttributeTests.cs0000664000175000017500000000144711504175260024574 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.CultureAttributeTests { [TestFixture, Culture( "en,fr,de" )] public class FixtureWithCultureAttribute { [Test, Culture("en,de")] public void EnglishAndGermanTest() { } [Test, Culture("fr")] public void FrenchTest() { } [Test, Culture("fr-CA")] public void FrenchCanadaTest() { } } [TestFixture] public class InvalidCultureFixture { [Test,SetCulture("xx-XX")] public void InvalidCultureSet() { } } }NUnit-2.6.0.12051/src/tests/test-assembly/ActionAttributeExceptionFixture.cs0000664000175000017500000000446211720455324026573 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Reflection; using NUnit.Framework; namespace NUnit.TestData { [ExceptionThrowingAction] [TestFixture] public class ActionAttributeExceptionFixture { public static bool SetUpRun = false; public static bool TestRun = false; public static bool TearDownRun = false; public static void Reset() { SetUpRun = false; TestRun = false; TearDownRun = false; } [SetUp] public void SetUp() { SetUpRun = true; } [TearDown] public void TearDown() { TearDownRun = true; } [ExceptionThrowingAction] [Test] public void SomeTest() { TestRun = true; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class ExceptionThrowingActionAttribute : TestActionAttribute { private static bool _ThrowBeforeException; private static bool _ThrowAfterException; public static void Reset() { ThrowBeforeException = false; ThrowAfterException = false; } public override void BeforeTest(TestDetails testDetails) { if (ThrowBeforeException) throw new InvalidOperationException("Failure in BeforeTest."); } public override void AfterTest(TestDetails testDetails) { if (ThrowAfterException) throw new InvalidOperationException("Failure in AfterTest."); } public static bool ThrowBeforeException { get { return _ThrowBeforeException; } set { _ThrowBeforeException = value; } } public static bool ThrowAfterException { get { return _ThrowAfterException; } set { _ThrowAfterException = value; } } } } #endifNUnit-2.6.0.12051/src/tests/test-assembly/CategoryAttributeTests.cs0000664000175000017500000000203611651462020024715 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.CategoryAttributeTests { [TestFixture, InheritableCategory("MyCategory")] public abstract class AbstractBase { } [TestFixture, Category( "DataBase" )] public class FixtureWithCategories : AbstractBase { [Test, Category("Long")] public void Test1() { } [Test, Critical] public void Test2() { } } [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public class CriticalAttribute : CategoryAttribute { } [AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited=true)] public class InheritableCategoryAttribute : CategoryAttribute { public InheritableCategoryAttribute(string name) : base(name) { } } }NUnit-2.6.0.12051/src/tests/test-assembly/TheoryFixture.cs0000664000175000017500000000276611504175260023070 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture] public class TheoryFixture { [Datapoint] internal int i0 = 0; [Datapoint] internal static int i1 = 1; [Datapoint] public int i100 = 100; private void Dummy() { } [Theory] public void TheoryWithNoArguments() { } [Theory] public void TheoryWithArgumentsButNoDatapoints(decimal x, decimal y) { } [Theory] public void TheoryWithArgumentsAndDatapoints(int x, int y) { } [TestCase(5, 10)] [TestCase(3, 12)] public void TestWithArguments(int x, int y) { } [Theory] public void TestWithBooleanArguments(bool a, bool b) { } [Theory] public void TestWithEnumAsArgument(System.Threading.ApartmentState state) { } [Theory] public void TestWithAllBadValues( [Values(-12.0, -4.0, -9.0)] double d) { Assume.That(d > 0); Assert.Pass(); } } } NUnit-2.6.0.12051/src/tests/test-assembly/DirectoryChangeFixture.cs0000664000175000017500000000104511504175260024655 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.TestData { public class DirectoryChangeFixture { [Test] public void ChangeCurrentDirectory() { Environment.CurrentDirectory = Path.GetTempPath(); } } } NUnit-2.6.0.12051/src/tests/test-assembly/PropertyAttributeTests.cs0000664000175000017500000000155611504175260024776 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.PropertyAttributeTests { [TestFixture, Property("ClassUnderTest","SomeClass" )] public class FixtureWithProperties { [Test, Property("user","Charlie")] public void Test1() { } [Test, Property("X",10.0), Property("Y",17.0)] public void Test2() { } [Test, Priority(5)] public void Test3() { } } [AttributeUsage(AttributeTargets.Method, AllowMultiple=false)] public class PriorityAttribute : PropertyAttribute { public PriorityAttribute( int level ) : base( level ) { } } } NUnit-2.6.0.12051/src/tests/test-assembly/ParameterizedTestFixture.cs0000664000175000017500000000154011720455366025247 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData { [TestFixture(1)] [TestFixture(2)] public class ParameterizedTestFixture { [Test] public void MethodWithoutParams() { } [TestCase(10,20)] public void MethodWithParams(int x, int y) { } } [TestFixture(Category = "XYZ")] public class TestFixtureWithSingleCategory { } [TestFixture(Category = "X,Y,Z")] public class TestFixtureWithMultipleCategories { } } NUnit-2.6.0.12051/src/tests/test-assembly/SetupFixtureTests.cs0000664000175000017500000003337111504175260023735 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Text; using NUnit.Framework; namespace NUnit.TestUtilities { /// /// A helper to Verify that Setup/Teardown 'events' occur, and that they are in the correct order... /// public class SimpleEventRecorder { private static System.Collections.Queue _events; /// /// Initializes the 'static' class. /// static SimpleEventRecorder() { _events = new System.Collections.Queue(); } /// /// Registers an event. /// /// The event to register. public static void RegisterEvent(string evnt) { _events.Enqueue(evnt); } /// /// Verifies the specified expected events occurred and that they occurred in the specified order. /// /// The expected events. public static void Verify(params string[] expectedEvents) { foreach (string expected in expectedEvents) { string actual = _events.Count > 0 ? _events.Dequeue() as string : null; Assert.AreEqual( expected, actual ); } } /// /// Clears any unverified events. /// public static void Clear() { _events.Clear(); } } } namespace NUnit.TestData.SetupFixture { namespace Namespace1 { #region SomeTestFixture [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown"); } } } namespace Namespace2 { #region SomeTestFixture /// /// Summary description for SetUpFixtureTests. /// [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture #region SomeTestFixture2 [TestFixture] public class SomeTestFixture2 { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture2 [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown"); } } } namespace Namespace3 { namespace SubNamespace { #region SomeTestFixture [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("SubNamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("SubNamespaceTearDown"); } } } #region SomeTestFixture [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public static void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown"); } } } namespace Namespace4 { #region SomeTestFixture [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown"); } } [SetUpFixture] public class NUnitNamespaceSetUpFixture2 { [SetUp] public void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup2"); } [TearDown] public void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown2"); } } } namespace Namespace5 { [SetUpFixture] public class CurrentDirectoryRecordingSetUpFixture { [SetUp] public void DoSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("SetUp:" + Environment.CurrentDirectory); } [TearDown] public void DoTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown:" + Environment.CurrentDirectory); } } [TestFixture] public class SomeFixture { [Test] public void SomeMethod() { } } } namespace Namespace5 { #region SomeTestFixture [TestFixture] public class SomeTestFixture { [TestFixtureSetUp] public void FixtureSetup() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureSetup"); } [SetUp] public void Setup() { TestUtilities.SimpleEventRecorder.RegisterEvent("Setup"); } [Test] public void Test() { TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } [TearDown] public void TearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("TearDown"); } [TestFixtureTearDown] public void FixtureTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("FixtureTearDown"); } } #endregion SomeTestFixture [SetUpFixture] public class NUnitNamespaceSetUpFixture { [SetUp] public static void DoNamespaceSetUp() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceSetup"); } [TearDown] public static void DoNamespaceTearDown() { TestUtilities.SimpleEventRecorder.RegisterEvent("NamespaceTearDown"); } } } } #region NoNamespaceSetupFixture [SetUpFixture] public class NoNamespaceSetupFixture { [SetUp] public void DoNamespaceSetUp() { NUnit.TestUtilities.SimpleEventRecorder.RegisterEvent("RootNamespaceSetup"); } [TearDown] public void DoNamespaceTearDown() { NUnit.TestUtilities.SimpleEventRecorder.RegisterEvent("RootNamespaceTearDown"); } } [TestFixture] public class SomeTestFixture { [Test] public void Test() { NUnit.TestUtilities.SimpleEventRecorder.RegisterEvent("Test"); } } #endregion NoNamespaceSetupFixture NUnit-2.6.0.12051/src/tests/test-assembly/TestFixtureData.cs0000664000175000017500000001652511652211050023315 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.TestData.TestFixtureData { /// /// Classes used for testing NUnit /// [TestFixture] public class NoDefaultCtorFixture { public NoDefaultCtorFixture(int index) { } [Test] public void OneTest() { } } [TestFixture(7,3)] public class FixtureWithArgsSupplied { public FixtureWithArgsSupplied(int x, int y) { } [Test] public void OneTest() { } } [TestFixture] public class BadCtorFixture { BadCtorFixture() { throw new Exception(); } [Test] public void OneTest() {} } public class FixtureWithoutTestFixtureAttributeContainingTest { [Test] public void SomeTest() { } } public class FixtureWithoutTestFixtureAttributeContainingTestCase { [TestCase(42)] public void SomeTest(int x) { } } public class FixtureWithoutTestFixtureAttributeContainingTestCaseSource { [TestCaseSource("data")] public void SomeTest(int x) { } } public class FixtureWithoutTestFixtureAttributeContainingTheory { [Theory] public void SomeTest(int x) { } } #if CLR_2_0 || CLR_4_0 public static class StaticFixtureWithoutTestFixtureAttribute { [Test] public static void StaticTest() { } } #endif [TestFixture] public class MultipleSetUpAttributes { [SetUp] public void Init1() {} [SetUp] public void Init2() {} [Test] public void OneTest() {} } [TestFixture] public class MultipleTearDownAttributes { [TearDown] public void Destroy1() {} [TearDown] public void Destroy2() {} [Test] public void OneTest() {} } [TestFixture] [Ignore("testing ignore a fixture")] public class IgnoredFixture { [Test] public void Success() {} } [TestFixture] public class OuterClass { [TestFixture] public class NestedTestFixture { [TestFixture] public class DoublyNestedTestFixture { [Test] public void Test() { } } } } [TestFixture] public abstract class AbstractTestFixture { [TearDown] public void Destroy1() {} [Test] public void SomeTest() {} } public class DerivedFromAbstractTestFixture : AbstractTestFixture { } [TestFixture] public class BaseClassTestFixture { [Test] public void Success() { } } public abstract class AbstractDerivedTestFixture : BaseClassTestFixture { } public class DerivedFromAbstractDerivedTestFixture : AbstractDerivedTestFixture { } [TestFixture] public abstract class AbstractBaseFixtureWithAttribute { } [TestFixture] public abstract class AbstractDerivedFixtureWithSecondAttribute : AbstractBaseFixtureWithAttribute { } public class DoubleDerivedClassWithTwoInheritedAttributes : AbstractDerivedFixtureWithSecondAttribute { } [TestFixture] public class MultipleFixtureSetUpAttributes { [TestFixtureSetUp] public void Init1() {} [TestFixtureSetUp] public void Init2() {} [Test] public void OneTest() {} } [TestFixture] public class MultipleFixtureTearDownAttributes { [TestFixtureTearDown] public void Destroy1() {} [TestFixtureTearDown] public void Destroy2() {} [Test] public void OneTest() {} } // Base class used to ensure following classes // all have at least one test public class OneTestBase { [Test] public void OneTest() { } } [TestFixture] public class PrivateSetUp : OneTestBase { [SetUp] private void Setup() {} } [TestFixture] public class ProtectedSetUp : OneTestBase { [SetUp] protected void Setup() {} } [TestFixture] public class StaticSetUp : OneTestBase { [SetUp] public static void Setup() {} } [TestFixture] public class SetUpWithReturnValue : OneTestBase { [SetUp] public int Setup() { return 0; } } [TestFixture] public class SetUpWithParameters : OneTestBase { [SetUp] public void Setup(int j) { } } [TestFixture] public class PrivateTearDown : OneTestBase { [TearDown] private void Teardown() {} } [TestFixture] public class ProtectedTearDown : OneTestBase { [TearDown] protected void Teardown() {} } [TestFixture] public class StaticTearDown : OneTestBase { [SetUp] public static void TearDown() {} } [TestFixture] public class TearDownWithReturnValue : OneTestBase { [TearDown] public int Teardown() { return 0; } } [TestFixture] public class TearDownWithParameters : OneTestBase { [TearDown] public void Teardown(int j) { } } [TestFixture] public class PrivateFixtureSetUp : OneTestBase { [TestFixtureSetUp] private void Setup() {} } [TestFixture] public class ProtectedFixtureSetUp : OneTestBase { [TestFixtureSetUp] protected void Setup() {} } [TestFixture] public class StaticFixtureSetUp : OneTestBase { [TestFixtureSetUp] public static void Setup() {} } [TestFixture] public class FixtureSetUpWithReturnValue : OneTestBase { [TestFixtureSetUp] public int Setup() { return 0; } } [TestFixture] public class FixtureSetUpWithParameters : OneTestBase { [SetUp] public void Setup(int j) { } } [TestFixture] public class PrivateFixtureTearDown : OneTestBase { [TestFixtureTearDown] private void Teardown() {} } [TestFixture] public class ProtectedFixtureTearDown : OneTestBase { [TestFixtureTearDown] protected void Teardown() {} } [TestFixture] public class StaticFixtureTearDown : OneTestBase { [TestFixtureTearDown] public static void Teardown() {} } [TestFixture] public class FixtureTearDownWithReturnValue : OneTestBase { [TestFixtureTearDown] public int Teardown() { return 0; } } [TestFixture] public class FixtureTearDownWithParameters : OneTestBase { [TestFixtureTearDown] public void Teardown(int j) { } } #if CLR_2_0 || CLR_4_0 [TestFixture(typeof(int))] [TestFixture(typeof(string))] public class GenericFixtureWithProperArgsProvided { [Test] public void SomeTest() { } } public class GenericFixtureWithNoTestFixtureAttribute { [Test] public void SomeTest() { } } [TestFixture] public class GenericFixtureWithNoArgsProvided { [Test] public void SomeTest() { } } [TestFixture] public abstract class AbstractFixtureBase { [Test] public void SomeTest() { } } public class GenericFixtureDerivedFromAbstractFixtureWithNoArgsProvided : AbstractFixtureBase { } [TestFixture(typeof(int))] [TestFixture(typeof(string))] public class GenericFixtureDerivedFromAbstractFixtureWithArgsProvided : AbstractFixtureBase { } #endif } NUnit-2.6.0.12051/src/CommonAssemblyInfo.cs0000664000175000017500000000264611712221470020046 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; // // Common Information about all NUnit assemblies is controlled through the following // set of attributes. Change these source values to modify the information // associated with an assembly. // // NOTE: This file is only used in the Visual Studio builds. For the NAnt builds, // an alternate file is generated and used. // [assembly: AssemblyCompany("NUnit.org")] [assembly: AssemblyProduct("NUnit")] [assembly: AssemblyCopyright("Copyright (C) 2002-2012 Charlie Poole.\r\nCopyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.\r\nCopyright (C) 2000-2002 Philip Craig.\r\nAll Rights Reserved.")] [assembly: AssemblyTrademark("NUnit is a trademark of NUnit.org")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.6.0")] [assembly: AssemblyInformationalVersion("2.6.0")] NUnit-2.6.0.12051/src/NUnitMocks/0000775000175000017500000000000011742560362016006 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitMocks/tests/0000775000175000017500000000000011742560362017150 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitMocks/tests/nunit.mocks.tests.csproj0000664000175000017500000000735111574617510024012 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {8667C588-1A05-4773-A9E8-272EB302B8AB} Debug AnyCPU nunit.mocks.tests JScript Grid IE50 false Library NUnit.Mocks.Tests OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE 4096 true false false 4 none prompt System System.Data System.XML nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} nunit.mocks {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitMocks/tests/nunit.mocks.tests.build0000664000175000017500000000204711504175260023600 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitMocks/tests/MockTests.cs0000664000175000017500000002071011525547152021414 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Mocks.Tests { /// /// Summary description for MockTests. /// [TestFixture] [Obsolete("NUnit now uses NSubstitute")] public class MockTests { private Mock mock; [SetUp] public void SetUp() { mock = new Mock( "MyMock" ); } [Test] public void MockHasName() { Assert.AreEqual( "MyMock", mock.Name ); } [Test] public void StrictDefaultsToFalse() { Assert.IsFalse( mock.Strict ); } [Test] public void VerifyNewMock() { mock.Verify(); } [Test] public void UnexpectedCallsIgnored() { mock.Call( "x" ); mock.Call( "y", 1, 2); mock.Verify(); } [Test] public void OneExpectation() { mock.Expect( "x" ); mock.Call( "x" ); mock.Verify(); } [Test, ExpectedException(typeof(AssertionException))] public void MethodNotCalled() { mock.Expect( "x" ); mock.Verify(); } [Test] public void MultipleExpectations() { mock.Expect( "x" ); mock.Expect( "y", "name" ); mock.Expect( "z", 1, 2, 3 ); mock.Call( "x" ); mock.Call( "y", "name" ); mock.Call( "z", 1, 2, 3 ); mock.Verify(); } [Test] public void MultipleCallsToSameMethod() { mock.Expect( "method" ); mock.Expect( "method" ); mock.Expect( "method" ); mock.Call( "method" ); mock.Call( "method" ); mock.Call( "method" ); mock.Verify(); } [Test, ExpectedException( typeof(AssertionException) )] public void TooManyCalls() { mock.Expect( "method" ); mock.Expect( "method" ); mock.Call( "method" ); mock.Call( "method" ); mock.Call( "method" ); mock.Verify(); } [Test, ExpectedException( typeof(AssertionException) )] public void NotEnoughCalls() { mock.Expect( "method" ); mock.Expect( "method" ); mock.Expect( "method" ); mock.Call( "method" ); mock.Call( "method" ); mock.Verify(); } [Test, ExpectedException( typeof( AssertionException ) )] public void RequireArguments() { mock.Expect("myMethod", new object[0]); mock.Call("myMethod", "world", null); mock.Verify(); } [Test] public void IgnoreArguments() { mock.Expect("myMethod"); mock.Call("myMethod", "world", null); mock.Verify(); } [Test, ExpectedException( typeof( AssertionException ) )] public void FailWithParametersSpecified() { mock.Expect("myMethod", "junk"); mock.Call("myMethod", "world", null); mock.Verify(); } [Test] public void CallMultipleMethodsInDifferentOrder() { mock.Expect("myMethod1"); mock.Expect("myMethod2"); mock.Expect("myMethod3"); mock.Call("myMethod3"); mock.Call("myMethod1"); mock.Call("myMethod2"); mock.Verify(); } [Test] public void CallMultipleMethodsSomeWithoutExpectations() { mock.Expect("myMethod1"); mock.Expect("myMethod3"); mock.Expect("myMethod3"); mock.Call("myMethod2"); mock.Call("myMethod3"); mock.Call("myMethod1"); mock.Call("myMethod3"); mock.Verify(); } [Test] public void ExpectAndReturn() { object something = new object(); mock.ExpectAndReturn("myMethod", something); object result = mock.Call("myMethod"); mock.Verify(); Assert.AreSame(something, result); } [Test] public void ExpectAndReturnWithArgument() { object something = new object(); mock.ExpectAndReturn("myMethod", something, "hello" ); object result = mock.Call("myMethod", "hello"); mock.Verify(); Assert.AreSame(something, result); } [Test, ExpectedException(typeof(AssertionException))] public void ExpectAndReturnWithWrongArgument() { object something = new object(); mock.ExpectAndReturn( "myMethod", something, "hello" ); object result = mock.Call("myMethod", "bye"); mock.Verify(); Assert.AreSame(something, result); } [Test] public void MultipleExpectAndReturn() { object something = new object(); object anotherthing = new object(); int x = 3; mock.ExpectAndReturn("myMethod", something); mock.ExpectAndReturn("myMethod", anotherthing); mock.ExpectAndReturn("myMethod", x); Assert.AreSame(something, mock.Call("myMethod")); Assert.AreSame(anotherthing, mock.Call("myMethod")); Assert.AreEqual(x, mock.Call("myMethod")); mock.Verify(); } [Test] public void ExpectAndReturnNull() { mock.ExpectAndReturn("myMethod", null); Assert.IsNull( mock.Call("myMethod") ); mock.Verify(); } [Test] public void SetReturnValue() { mock.SetReturnValue( "myMethod", 5 ); Assert.AreEqual( 5, mock.Call( "myMethod") ); mock.Verify(); } [Test] public void SetReturnValueRepeatedCalls() { mock.SetReturnValue( "myMethod", 5 ); Assert.AreEqual( 5, mock.Call( "myMethod") ); Assert.AreEqual( 5, mock.Call( "myMethod") ); Assert.AreEqual( 5, mock.Call( "myMethod") ); mock.Verify(); } [Test] public void SetReturnValueMultipleTimesOnMultipleMethods() { mock.SetReturnValue( "myMethod1", "something" ); mock.SetReturnValue( "myMethod2", "else" ); Assert.AreEqual( "something", mock.Call( "myMethod1") ); Assert.AreEqual( "something", mock.Call( "myMethod1") ); Assert.AreEqual( "else", mock.Call( "myMethod2") ); Assert.AreEqual( "something", mock.Call( "myMethod1") ); Assert.AreEqual( "else", mock.Call( "myMethod2") ); mock.SetReturnValue( "myMethod2", "magnificent" ); Assert.AreEqual( "something", mock.Call( "myMethod1") ); Assert.AreEqual( "magnificent", mock.Call( "myMethod2") ); mock.Verify(); } [Test] public void SetReturnValueWithoutCalling() { mock.SetReturnValue( "hello", "goodbye" ); mock.Verify(); } [Test, ExpectedException( typeof( System.IO.IOException ) )] public void ExpectAndThrowException() { mock.ExpectAndThrow( "method", new System.IO.IOException() ); mock.Call( "method" ); } [Test, ExpectedException( typeof( AssertionException ) )] public void ExpectNoCallFails() { mock.ExpectNoCall( "myMethod" ); mock.Call( "myMethod" ); } [Test] public void ExpectNoCallSucceeds() { mock.ExpectNoCall( "myMethod" ); mock.Call("yourMethod"); mock.Verify(); } [Test, ExpectedException(typeof(AssertionException))] public void StrictMode() { mock.Strict = true; mock.Expect("method1"); mock.Expect("method2"); mock.Call("method1"); mock.Call("method2"); mock.Call("method3"); } [Test, ExpectedException(typeof(AssertionException))] public void StrictMode_ExceptionsCaught() { mock.Strict = true; mock.Expect("method1"); mock.Expect("method2"); try { mock.Call("method1"); mock.Call("method2"); mock.Call("method3"); } catch(Exception) {} mock.Verify(); } [Test] public void ChangeFixedReturnToExpectAndReturn() { mock.SetReturnValue( "MyMethod", "x" ); Assert.AreEqual( "x", mock.Call( "MyMethod" ) ); Assert.AreEqual( "x", mock.Call( "MyMethod", 1, 2, 3 ) ); mock.ExpectAndReturn( "MyMethod", "y", 1, 2, 3 ); Assert.AreEqual( "y", mock.Call( "MyMethod", 1, 2, 3 ) ); mock.Verify(); } [Test] public void ChangeExpectAndReturnToFixedReturn() { mock.ExpectAndReturn( "MyMethod", "y", 1, 2, 3 ); Assert.AreEqual( "y", mock.Call( "MyMethod", 1, 2, 3 ) ); mock.SetReturnValue( "MyMethod", "x" ); Assert.AreEqual( "x", mock.Call( "MyMethod" ) ); Assert.AreEqual( "x", mock.Call( "MyMethod", 1, 2, 3 ) ); mock.Verify(); } [Test] public void ConstraintArgumentSucceeds() { mock.Expect( "MyMethod", Is.GreaterThan(10) ); mock.Call( "MyMethod", 42 ); } [Test,ExpectedException(typeof(AssertionException))] public void ConstraintArgumentThatFails() { mock.Expect( "MyMethod", Is.GreaterThan(10) ); mock.Call( "MyMethod", 8 ); } } } NUnit-2.6.0.12051/src/NUnitMocks/tests/DynamicMockTests.cs0000664000175000017500000001064211525547152022724 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Mocks.Tests { /// /// Summary description for DynamicMockTests. /// [TestFixture] [Obsolete("NUnit now uses NSubstitute")] public class DynamicMockTests { private DynamicMock mock; private IStuff instance; [SetUp] public void CreateMock() { mock = new DynamicMock( typeof( IStuff ) ); instance = (IStuff)mock.MockInstance; } [Test] public void MockHasDefaultName() { Assert.AreEqual( "MockIStuff", mock.Name ); } [Test] public void MockHasNonDefaultName() { DynamicMock mock2 = new DynamicMock( "MyMock", typeof( IStuff ) ); Assert.AreEqual( "MyMock", mock2.Name ); } [Test] public void CallMethod() { instance.DoSomething(); mock.Verify(); } [Test] public void CallMethodWithArgs() { instance.DoSomething( "hello" ); mock.Verify(); } [Test] public void ExpectedMethod() { mock.Expect( "DoSomething" ); instance.DoSomething(); mock.Verify(); } [Test, ExpectedException( typeof(AssertionException) )] public void ExpectedMethodNotCalled() { mock.Expect( "DoSomething" ); mock.Verify(); } [Test] public void RefParameter() { int x = 7; mock.Expect( "Increment" ); instance.Increment( ref x ); mock.Verify(); } [Test] public void MethodWithReturnValue() { mock.SetReturnValue( "GetInt", 5 ); Assert.AreEqual( 5, instance.GetInt() ); mock.Verify(); } [Test] public void DefaultReturnValues() { Assert.AreEqual( 0, instance.GetInt(), "int" ); Assert.AreEqual( 0, instance.GetSingle(), "float" ); Assert.AreEqual( 0, instance.GetDouble(), "double" ); Assert.AreEqual( 0, instance.GetDecimal(), "decimal" ); Assert.AreEqual( '?', instance.GetChar(), "char" ); mock.Verify(); } [Test, ExpectedException( typeof(InvalidCastException) )] public void WrongReturnType() { mock.SetReturnValue( "GetInt", "hello" ); instance.GetInt(); mock.Verify(); } [Test] public void OverrideMethodOnDynamicMock() { DynamicMock derivedMock = new DerivedMock(); IStuff derivedInstance = (IStuff)derivedMock.MockInstance; Assert.AreEqual( 17, derivedInstance.Add( 5, 12 ) ); derivedMock.Verify(); } [Test, ExpectedException( typeof(ArgumentException) )] public void CreateMockForNonMBRClassFails() { DynamicMock classMock = new DynamicMock( typeof( NonMBRClass ) ); instance = classMock.MockInstance as IStuff; } [Test] public void CreateMockForMBRClass() { DynamicMock classMock = new DynamicMock( typeof( MBRClass ) ); MBRClass classInstance = (MBRClass)classMock.MockInstance; classMock.Expect( "SomeMethod" ); classMock.ExpectAndReturn( "AnotherMethod", "Hello World", 5, "hello" ); classMock.ExpectAndReturn( "MethodWithParams", 42, new object[] { new string[] { "the", "answer" } } ); classInstance.SomeMethod(); Assert.AreEqual( "Hello World", classInstance.AnotherMethod( 5, "hello" ) ); Assert.AreEqual( 42, classInstance.MethodWithParams( "the", "answer" ) ); classMock.Verify(); } #region Test Interfaces and Classes interface IStuff { void DoSomething(); void DoSomething( string greeting ); int GetInt(); float GetSingle(); double GetDouble(); decimal GetDecimal(); char GetChar(); int Add( int a, int b ); void Increment( ref int n ); } class DerivedMock : DynamicMock { public DerivedMock() : base( "Derived", typeof( IStuff ) ) { } public override object Call( string methodName, params object[] args ) { switch( methodName ) { case "Add": return (int)args[0] + (int)args[1]; default: return base.Call( methodName, args ); } } } class NonMBRClass { } class MBRClass : MarshalByRefObject { public void SomeMethod(){ } public string AnotherMethod( int a, string b ) { return b + a.ToString(); } public int MethodWithParams( params string[] args ) { return args.Length; } } #endregion } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/0000775000175000017500000000000011742560362017122 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitMocks/mocks/MockCall.cs0000664000175000017500000000304611525547174021146 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Framework.Constraints; namespace NUnit.Mocks { /// /// Summary description for ExpectedCall. /// [Obsolete("NUnit now uses NSubstitute")] public class MockCall : ICall { private MethodSignature signature; private object returnVal; private Exception exception; private object[] expectedArgs; // public static object[] Any = new object[0]; public MockCall( MethodSignature signature, object returnVal, Exception exception, params object[] args ) { this.signature = signature; this.returnVal = returnVal; this.exception = exception; this.expectedArgs = args; } public object Call( object[] actualArgs ) { if ( expectedArgs != null ) { Assert.AreEqual( expectedArgs.Length, actualArgs.Length, "Invalid argument count in call to {0}", this.signature.methodName ); for( int i = 0; i < expectedArgs.Length; i++ ) { if ( expectedArgs[i] is IResolveConstraint ) Assert.That( actualArgs[i], (IResolveConstraint)expectedArgs[i] ); else Assert.AreEqual( expectedArgs[i], actualArgs[i] ); } } if ( exception != null ) throw exception; return returnVal; } } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/ICallHandler.cs0000664000175000017500000000162011525547152021733 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// The ICallHandler interface dispatches calls to methods or /// other objects implementing the ICall interface. /// [Obsolete("NUnit now uses NSubstitute")] public interface ICallHandler { /// /// Simulate a method call on the mocked object. /// /// The name of the method /// Arguments for this call /// Previously specified object or null object Call( string methodName, params object[] args ); } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/MethodSignature.cs0000664000175000017500000000262311525547340022556 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// Summary description for MockSignature. /// [Obsolete("NUnit now uses NSubstitute")] public class MethodSignature { public readonly string typeName; public readonly string methodName; public readonly Type[] argTypes; public MethodSignature( string typeName, string methodName, Type[] argTypes ) { this.typeName = typeName; this.methodName = methodName; this.argTypes = argTypes; } public bool IsCompatibleWith( object[] args ) { if ( args.Length != argTypes.Length ) return false; for( int i = 0; i < args.Length; i++ ) if ( !argTypes[i].IsAssignableFrom( args[i].GetType() ) ) return false; return true; } public static Type[] GetArgTypes( object[] args ) { if ( args == null ) return new Type[0]; Type[] argTypes = new Type[args.Length]; for (int i = 0; i < argTypes.Length; ++i) { if (args[i] == null) argTypes[i] = typeof(object); else argTypes[i] = args[i].GetType(); } return argTypes; } } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/Mock.cs0000664000175000017500000000743211525547152020351 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Messaging; using NUnit.Framework; namespace NUnit.Mocks { /// /// Summary description for MockObject. /// [Obsolete("NUnit now uses NSubstitute")] public class Mock : IMock { #region Private Fields private string name; private bool strict; private IDictionary methods = new Hashtable(); private Exception lastException; private ArrayList unexpected = new ArrayList(); #endregion #region Properties public Exception LastException { get { return lastException; } } #endregion #region Constructors public Mock() : this( "Mock" ) { } public Mock( string name ) { this.name = name; } #endregion #region IMock Members public string Name { get { return name; } } public bool Strict { get { return strict; } set { strict = value; } } public void Expect( string methodName, params object[] args ) { ExpectAndReturn( methodName, null, args ); } public void Expect( string methodName ) { ExpectAndReturn( methodName, null, null ); } public void ExpectNoCall( string methodName ) { methods[methodName] = new MockMethod( methodName, null, new AssertionException("Unexpected call to method " + methodName) ); } public void ExpectAndReturn( string methodName, object returnVal, params object[] args ) { AddExpectedCall( methodName, returnVal, null, args ); } public void ExpectAndThrow( string methodName, Exception exception, params object[] args ) { AddExpectedCall( methodName, null, exception, args ); } public void SetReturnValue( string methodName, object returnVal ) { methods[methodName] = new MockMethod( methodName, returnVal ); } #endregion #region IVerify Members public virtual void Verify() { foreach (IMethod method in methods.Values) method.Verify(); if (unexpected.Count > 0) Assert.Fail("Unexpected call to " + (string)unexpected[0]); } #endregion #region ICallHandler Members public virtual object Call( string methodName, params object[] args ) { if ( methods.Contains( methodName ) ) { try { IMethod method = (IMethod)methods[methodName]; return method.Call( args ); } catch( Exception exception ) { // Save exception in case MO is running on a separate thread lastException = exception; throw; } } else // methodName is not listed in methods if (Strict) { unexpected.Add(methodName); Assert.Fail("Unexpected call to " + methodName); } // not listed but Strict is not specified return null; } #endregion #region Helper Methods private void AddExpectedCall( string methodName, object returnVal, Exception exception, object[] args ) { IMethod method = (IMethod)methods[methodName]; if ( method == null ) { method = new MockMethod( methodName ); methods[methodName] = method; } Type[] argTypes = MethodSignature.GetArgTypes( args ); MethodSignature signature = new MethodSignature( this.Name, methodName, argTypes ); method.Expect( new MockCall( signature, returnVal, exception, args ) ); } #endregion } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/AssemblyInfo.cs0000664000175000017500000000074111504175260022041 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/NUnitMocks/mocks/IVerify.cs0000664000175000017500000000106011525547256021031 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// The IVerify interface is implemented by objects capable of self-verification. /// [Obsolete("NUnit now uses NSubstitute")] public interface IVerify { void Verify(); } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/ICall.cs0000664000175000017500000000150111525547152020433 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// The ICall interface is implemented by objects that can be called /// with an array of arguments and return a value. /// [Obsolete("NUnit now uses NSubstitute")] public interface ICall { /// /// Process a call with a possibly empty set of arguments. /// /// Arguments for this call /// An implementation-defined return value object Call( object[] args ); } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/IMethod.cs0000664000175000017500000000150311525547256021007 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// The IMethod interface represents an method or other named object that /// is both callable and self-verifying. /// [Obsolete("NUnit now uses NSubstitute")] public interface IMethod : IVerify, ICall { /// /// The name of the object /// string Name { get; } /// /// Tell the object to expect a certain call. /// /// void Expect( ICall call ); } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/DynamicMock.cs0000664000175000017500000000221611525547152021651 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// Summary description for DynamicMock. /// [Obsolete("NUnit now uses NSubstitute")] public class DynamicMock : Mock { private Type type; private object mockInstance; public object MockInstance { get { if ( mockInstance == null ) { MockInterfaceHandler handler = new MockInterfaceHandler( type, this ); mockInstance = handler.GetTransparentProxy(); } return mockInstance; } } #region Constructors public DynamicMock( Type type ) : this( "Mock" + type.Name, type ) { } public DynamicMock( string name, Type type ) : base( name ) { // if ( !type.IsInterface ) // throw new VerifyException( "DynamicMock constructor requires an interface type" ); this.type = type; } #endregion } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/IMock.cs0000664000175000017500000000462111525547256020464 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Mocks { /// /// Summary description for IMock. /// [Obsolete("NUnit now uses NSubstitute")] public interface IMock : IVerify, ICallHandler { /// /// The name of this mock - used in messages /// string Name { get; } /// /// True if unexpected calls should cause an error, false to ignore them /// bool Strict { get; set; } /// /// Set up to expect a call to a method with a set of arguments /// /// The name of the method /// Arguments for this call void Expect( string methodName, params object[] args ); void Expect( string MethodName ); /// /// Set up expectation that the named method will not be called /// /// The name of the method void ExpectNoCall( string methodName ); /// /// Set up to expect a call to a method with a set of arguments. /// The specified value will be returned. /// /// The name of the method /// The value to be returned /// Arguments for this call void ExpectAndReturn( string methodName, object returnVal, params object[] args ); /// /// Set up to expect a call to a method with a set of arguments. /// The specified exception will be thrown. /// /// The name of the method /// The exception to throw /// Arguments for this call void ExpectAndThrow( string methodname, Exception exception, params object[] args ); /// /// Set value to return for a method or property called with any arguments /// /// The name of the method /// The value to be returned void SetReturnValue( string methodName, object returnVal ); } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/nunit.mocks.build0000664000175000017500000000267611504175260022421 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitMocks/mocks/MockMethod.cs0000664000175000017500000000561111525547340021506 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; namespace NUnit.Mocks { /// /// The MockMethod object represents one named method on a mock object. /// All overloads are represented by one MockMethod. A method may return /// a fixed value, throw a fixed exception or have an expected sequence /// of calls. If it has a call sequence, then the signature must match and /// each call provides it's own return value or exception. /// [Obsolete("NUnit now uses NSubstitute")] public class MockMethod : IMethod { #region Private Fields /// /// Name of this method /// private string methodName; /// /// Fixed return value /// private object returnVal; /// /// Exception to be thrown /// private Exception exception; /// /// Expected call sequence. If null, this method has no expectations /// and simply provides a fixed return value or exception. /// private ArrayList expectedCalls = null; /// /// Actual sequence of calls... currently not used /// //private ArrayList actualCalls = null; #endregion #region Constructors public MockMethod( string methodName ) : this( methodName, null, null ) { } public MockMethod( string methodName, object returnVal ) : this( methodName, returnVal, null ) { } public MockMethod( string methodName, object returnVal, Exception exception ) { this.methodName = methodName; this.returnVal = returnVal; this.exception = exception; } #endregion #region IMethod Members public string Name { get { return methodName; } } public void Expect( ICall call ) { if ( expectedCalls == null ) expectedCalls = new ArrayList(); expectedCalls.Add( call ); } #endregion #region ICall Members public object Call( object[] args ) { if ( expectedCalls == null ) { if ( exception != null ) throw exception; return returnVal; } else { //actualCalls.Add( new MethodCall( methodName, null, null, args ) ); Assert.IsTrue( expectedCalls.Count > 0, "Too many calls to " + Name ); MockCall mockCall = (MockCall)expectedCalls[0]; expectedCalls.RemoveAt( 0 ); return mockCall.Call( args ); } } #endregion #region IVerify Members public void Verify() { if ( expectedCalls != null ) Assert.IsTrue( expectedCalls.Count == 0, "Not all methods were called" ); } #endregion } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/MockInterfaceHandler.cs0000664000175000017500000000454311525547340023467 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Messaging; using System.Reflection; namespace NUnit.Mocks { /// /// Summary description for MockInterfaceHandler. /// [Obsolete("NUnit now uses NSubstitute")] public class MockInterfaceHandler : RealProxy { private ICallHandler callHandler; public MockInterfaceHandler( Type type, ICallHandler callHandler ) : base( type ) { this.callHandler = callHandler; } public override IMessage Invoke( IMessage msg ) { IMethodCallMessage call = (IMethodCallMessage)msg; IMethodReturnMessage result = null; if ( call != null ) { try { object ret = callHandler.Call( call.MethodName, call.Args ); if ( ret == null ) { MethodInfo info = call.MethodBase as MethodInfo; Type returnType = info.ReturnType; if( returnType == typeof( System.Boolean ) ) ret = false; if( returnType == typeof( System.Byte ) ) ret = (System.Byte)0; if( returnType == typeof( System.SByte ) ) ret = (System.SByte)0; if( returnType == typeof( System.Decimal ) ) ret = (System.Decimal)0; if( returnType == typeof( System.Double ) ) ret = (System.Double)0; if( returnType == typeof( System.Single ) ) ret = (System.Single)0; if( returnType == typeof( System.Int32 ) ) ret = (System.Int32)0; if( returnType == typeof( System.UInt32 ) ) ret = (System.UInt32)0; if( returnType == typeof( System.Int64 ) ) ret = (System.Int64)0; if( returnType == typeof( System.UInt64 ) ) ret = (System.UInt64)0; if( returnType == typeof( System.Int16 ) ) ret = (System.Int16)0; if( returnType == typeof( System.UInt16 ) ) ret = (System.UInt16)0; if( returnType == typeof( System.Char ) ) ret = '?'; } result = new ReturnMessage( ret, null, 0, null, call ); } catch( Exception e ) { result = new ReturnMessage( e, call ); } } return result; } } } NUnit-2.6.0.12051/src/NUnitMocks/mocks/nunit.mocks.csproj0000664000175000017500000000775611574617510022634 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {EEE7C98B-23E6-472D-9036-C2D53B0DFE7C} Debug AnyCPU nunit.mocks JScript Grid IE50 false Library NUnit.Mocks OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\framework\ 285212672 TRACE;DEBUG true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\framework\ 285212672 TRACE 4096 1699 true false false 4 none prompt System System.Data System.XML nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitFramework/0000775000175000017500000000000011742560362016667 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/tests/0000775000175000017500000000000011742560362020031 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/tests/AssumeThatTests.cs0000664000175000017500000001323311504175260023456 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Framework.Tests { [TestFixture] public class AssumeThatTests { [Test] public void AssumptionPasses_Boolean() { Assume.That(2 + 2 == 4); } [Test] public void AssumptionPasses_BooleanWithMessage() { Assume.That(2 + 2 == 4, "Not Equal"); } [Test] public void AssumptionPasses_BooleanWithMessageAndArgs() { Assume.That(2 + 2 == 4, "Not Equal to {0}", 4); } [Test] public void AssumptionPasses_ActualAndConstraint() { Assume.That(2 + 2, Is.EqualTo(4)); } [Test] public void AssumptionPasses_ActualAndConstraintWithMessage() { Assume.That(2 + 2, Is.EqualTo(4), "Should be 4"); } [Test] public void AssumptionPasses_ActualAndConstraintWithMessageAndArgs() { Assume.That(2 + 2, Is.EqualTo(4), "Should be {0}", 4); } [Test] public void AssumptionPasses_ReferenceAndConstraint() { bool value = true; Assume.That(ref value, Is.True); } [Test] public void AssumptionPasses_ReferenceAndConstraintWithMessage() { bool value = true; Assume.That(ref value, Is.True, "Message"); } [Test] public void AssumptionPasses_ReferenceAndConstraintWithMessageAndArgs() { bool value = true; Assume.That(ref value, Is.True, "Message", 42); } [Test] public void AssumptionPasses_DelegateAndConstraint() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFour), Is.EqualTo(4)); } [Test] public void AssumptionPasses_DelegateAndConstraintWithMessage() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFour), Is.EqualTo(4), "Message"); } [Test] public void AssumptionPasses_DelegateAndConstraintWithMessageAndArgs() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFour), Is.EqualTo(4), "Should be {0}", 4); } private object ReturnsFour() { return 4; } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_Boolean() { Assume.That(2 + 2 == 5); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_BooleanWithMessage() { Assume.That(2 + 2 == 5, "message"); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_BooleanWithMessageAndArgs() { Assume.That(2 + 2 == 5, "message", 5); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ActualAndConstraint() { Assume.That(2 + 2, Is.EqualTo(5)); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ActualAndConstraintWithMessage() { Assume.That(2 + 2, Is.EqualTo(5), "Error"); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ActualAndConstraintWithMessageAndArgs() { Assume.That(2 + 2, Is.EqualTo(5), "Should be {0}", 5); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ReferenceAndConstraint() { bool value = false; Assume.That(ref value, Is.True); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ReferenceAndConstraintWithMessage() { bool value = false; Assume.That(ref value, Is.True, "message"); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_ReferenceAndConstraintWithMessageAndArgs() { bool value = false; Assume.That(ref value, Is.True, "message", 42); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_DelegateAndConstraint() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFive), Is.EqualTo(4)); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_DelegateAndConstraintWithMessage() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFive), Is.EqualTo(4), "Error"); } [Test, ExpectedException(typeof(InconclusiveException))] public void FailureThrowsInconclusiveException_DelegateAndConstraintWithMessageAndArgs() { Assume.That(new Constraints.ActualValueDelegate(ReturnsFive), Is.EqualTo(4), "Should be {0}", 4); } private object ReturnsFive() { return 5; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/0000775000175000017500000000000011742560362021317 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/EqualityTests.cs0000664000175000017500000001241011544454420024461 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Syntax { public class EqualToTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.EqualTo(999); inheritedSyntax = Helper().EqualTo(999); builderSyntax = Builder().EqualTo(999); } } public class EqualToTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.EqualTo("X").IgnoreCase; inheritedSyntax = Helper().EqualTo("X").IgnoreCase; builderSyntax = Builder().EqualTo("X").IgnoreCase; } } public class EqualToTest_WithinTolerance : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.EqualTo(0.7).Within(.005); inheritedSyntax = Helper().EqualTo(0.7).Within(.005); builderSyntax = Builder().EqualTo(0.7).Within(.005); } } public class EqualityTests { [Test] public void SimpleEqualityTests() { int[] i3 = new int[] { 1, 2, 3 }; double[] d3 = new double[] { 1.0, 2.0, 3.0 }; int[] iunequal = new int[] { 1, 3, 2 }; Assert.That(2 + 2, Is.EqualTo(4)); Assert.That(2 + 2 == 4); Assert.That(i3, Is.EqualTo(d3)); Assert.That(2 + 2, Is.Not.EqualTo(5)); Assert.That(i3, Is.Not.EqualTo(iunequal)); #if CLR_2_0 || CLR_4_0 List list = new List(); list.Add("foo"); list.Add("bar"); Assert.That(list, Is.EqualTo(new string[] { "foo", "bar" })); #endif } [Test] public void EqualityTestsWithTolerance() { Assert.That(4.99d, Is.EqualTo(5.0d).Within(0.05d)); Assert.That(4.0d, Is.Not.EqualTo(5.0d).Within(0.5d)); Assert.That(4.99f, Is.EqualTo(5.0f).Within(0.05f)); Assert.That(4.99m, Is.EqualTo(5.0m).Within(0.05m)); Assert.That(3999999999u, Is.EqualTo(4000000000u).Within(5u)); Assert.That(499, Is.EqualTo(500).Within(5)); Assert.That(4999999999L, Is.EqualTo(5000000000L).Within(5L)); Assert.That(5999999999ul, Is.EqualTo(6000000000ul).Within(5ul)); } [Test] public void EqualityTestsWithTolerance_MixedFloatAndDouble() { // Bug Fix 1743844 Assert.That(2.20492d, Is.EqualTo(2.2d).Within(0.01f), "Double actual, Double expected, Single tolerance"); Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01d), "Double actual, Single expected, Double tolerance"); Assert.That(2.20492d, Is.EqualTo(2.2f).Within(0.01f), "Double actual, Single expected, Single tolerance"); Assert.That(2.20492f, Is.EqualTo(2.2f).Within(0.01d), "Single actual, Single expected, Double tolerance"); Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01d), "Single actual, Double expected, Double tolerance"); Assert.That(2.20492f, Is.EqualTo(2.2d).Within(0.01f), "Single actual, Double expected, Single tolerance"); } [Test] public void EqualityTestsWithTolerance_MixingTypesGenerally() { // Extending tolerance to all numeric types Assert.That(202d, Is.EqualTo(200d).Within(2), "Double actual, Double expected, int tolerance"); Assert.That(4.87m, Is.EqualTo(5).Within(.25), "Decimal actual, int expected, Double tolerance"); Assert.That(4.87m, Is.EqualTo(5ul).Within(1), "Decimal actual, ulong expected, int tolerance"); Assert.That(487, Is.EqualTo(500).Within(25), "int actual, int expected, int tolerance"); Assert.That(487u, Is.EqualTo(500).Within(25), "uint actual, int expected, int tolerance"); Assert.That(487L, Is.EqualTo(500).Within(25), "long actual, int expected, int tolerance"); Assert.That(487ul, Is.EqualTo(500).Within(25), "ulong actual, int expected, int tolerance"); } [Test] public void EqualityTestsUsingDefaultFloatingPointTolerance() { GlobalSettings.DefaultFloatingPointTolerance = 0.05d; try { Assert.That(4.99d, Is.EqualTo(5.0d)); Assert.That(4.0d, Is.Not.EqualTo(5.0d)); Assert.That(4.99f, Is.EqualTo(5.0f)); } finally { GlobalSettings.DefaultFloatingPointTolerance = 0.0d; } } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/TestCompiler.cs0000664000175000017500000000324711544454420024263 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.CodeDom.Compiler; using System.IO; namespace NUnit.Framework.Syntax { class TestCompiler { Microsoft.CSharp.CSharpCodeProvider provider; #if CLR_1_0 || CLR_1_1 ICodeCompiler compiler; #endif CompilerParameters options; public TestCompiler() : this( null, null ) { } public TestCompiler( string[] assemblyNames ) : this( assemblyNames, null ) { } public TestCompiler( string[] assemblyNames, string outputName ) { this.provider = new Microsoft.CSharp.CSharpCodeProvider(); #if CLR_1_0 || CLR_1_1 this.compiler = provider.CreateCompiler(); #endif this.options = new CompilerParameters(); if ( assemblyNames != null && assemblyNames.Length > 0 ) options.ReferencedAssemblies.AddRange( assemblyNames ); if ( outputName != null ) options.OutputAssembly = outputName; options.IncludeDebugInformation = false; options.TempFiles = new TempFileCollection( Path.GetTempPath(), false ); options.GenerateInMemory = false; } public CompilerParameters Options { get { return options; } } public CompilerResults CompileCode( string code ) { #if CLR_2_0 || CLR_4_0 return provider.CompileAssemblyFromSource( options, code ); #else return compiler.CompileAssemblyFromSource(options, code); #endif } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/OperatorTests.cs0000664000175000017500000002031111504175260024454 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Syntax { #region Not public class NotTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Is.Not.Null; inheritedSyntax = Helper().Not.Null; builderSyntax = Builder().Not.Null; } } public class NotTest_Cascaded : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">>>"; staticSyntax = Is.Not.Not.Not.Null; inheritedSyntax = Helper().Not.Not.Not.Null; builderSyntax = Builder().Not.Not.Not.Null; } } #endregion #region All public class AllTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Is.All.GreaterThan(0); inheritedSyntax = Helper().All.GreaterThan(0); builderSyntax = Builder().All.GreaterThan(0); } } #endregion #region Some public class SomeTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Has.Some.EqualTo(3); inheritedSyntax = Helper().Some.EqualTo(3); builderSyntax = Builder().Some.EqualTo(3); } } public class SomeTest_BeforeBinaryOperators : SyntaxTest { [SetUp] public void SetUp() { parseTree = " > >>"; staticSyntax = Has.Some.GreaterThan(0).And.LessThan(100).Or.EqualTo(999); inheritedSyntax = Helper().Some.GreaterThan(0).And.LessThan(100).Or.EqualTo(999); builderSyntax = Builder().Some.GreaterThan(0).And.LessThan(100).Or.EqualTo(999); } } public class SomeTest_NestedSome : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">>"; staticSyntax = Has.Some.With.Some.LessThan(100); inheritedSyntax = Helper().Some.With.Some.LessThan(100); builderSyntax = Builder().Some.With.Some.LessThan(100); } } public class SomeTest_UseOfAndSome : SyntaxTest { [SetUp] public void SetUp() { parseTree = "> >>"; staticSyntax = Has.Some.GreaterThan(0).And.Some.LessThan(100); inheritedSyntax = Helper().Some.GreaterThan(0).And.Some.LessThan(100); builderSyntax = Builder().Some.GreaterThan(0).And.Some.LessThan(100); } } #endregion #region None public class NoneTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Has.None.LessThan(0); inheritedSyntax = Helper().None.LessThan(0); builderSyntax = Builder().None.LessThan(0); } } #endregion #region And public class AndTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >"; staticSyntax = Is.GreaterThan(5).And.LessThan(10); inheritedSyntax = Helper().GreaterThan(5).And.LessThan(10); builderSyntax = Builder().GreaterThan(5).And.LessThan(10); } } public class AndTest_ThreeAndsWithNot : SyntaxTest { [SetUp] public void SetUp() { parseTree = "> > >>>"; staticSyntax = Is.Not.Null.And.Not.LessThan(5).And.Not.GreaterThan(10); inheritedSyntax = Helper().Not.Null.And.Not.LessThan(5).And.Not.GreaterThan(10); builderSyntax = Builder().Not.Null.And.Not.LessThan(5).And.Not.GreaterThan(10); } } #endregion #region Or public class OrTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >"; staticSyntax = Is.LessThan(5).Or.GreaterThan(10); inheritedSyntax = Helper().LessThan(5).Or.GreaterThan(10); builderSyntax = Builder().LessThan(5).Or.GreaterThan(10); } } public class OrTest_ThreeOrs : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >>"; staticSyntax = Is.LessThan(5).Or.GreaterThan(10).Or.EqualTo(7); inheritedSyntax = Helper().LessThan(5).Or.GreaterThan(10).Or.EqualTo(7); builderSyntax = Builder().LessThan(5).Or.GreaterThan(10).Or.EqualTo(7); } } #endregion #region Binary Operator Precedence public class AndIsEvaluatedBeforeFollowingOr : SyntaxTest { [SetUp] public void SetUp() { parseTree = " > >"; staticSyntax = Is.LessThan(100).And.GreaterThan(0).Or.EqualTo(999); inheritedSyntax = Helper().LessThan(100).And.GreaterThan(0).Or.EqualTo(999); builderSyntax = Builder().LessThan(100).And.GreaterThan(0).Or.EqualTo(999); } } public class AndIsEvaluatedBeforePrecedingOr : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >>"; staticSyntax = Is.EqualTo(999).Or.GreaterThan(0).And.LessThan(100); inheritedSyntax = Helper().EqualTo(999).Or.GreaterThan(0).And.LessThan(100); builderSyntax = Builder().EqualTo(999).Or.GreaterThan(0).And.LessThan(100); } } #endregion public class OperatorPrecedenceTests { class A { B B { get { return new B(); } } string X { get { return "X in A"; } } string Y { get { return "Y in A"; } } } class B { string X { get { return "X in B"; } } string Y { get { return "Y in B"; } } } [Test] public void WithTests() { A a = new A(); Assert.That(a, Has.Property("X").EqualTo("X in A") .And.Property("Y").EqualTo("Y in A")); Assert.That(a, Has.Property("X").EqualTo("X in A") .And.Property("B").Property("X").EqualTo("X in B")); Assert.That(a, Has.Property("X").EqualTo("X in A") .And.Property("B").With.Property("X").EqualTo("X in B")); Assert.That(a, Has.Property("B").Property("X").EqualTo("X in B") .And.Property("B").Property("Y").EqualTo("Y in B")); Assert.That(a, Has.Property("B").Property("X").EqualTo("X in B") .And.Property("B").With.Property("Y").EqualTo("Y in B")); Assert.That(a, Has.Property("B").With.Property("X").EqualTo("X in B") .And.Property("Y").EqualTo("Y in B")); } [Test] public void SomeTests() { string[] array = new string[] { "a", "aa", "x", "xy", "xyz" }; //Assert.That(array, Has.Some.StartsWith("a").And.Some.Length.EqualTo(3)); Assert.That(array, Has.None.StartsWith("a").And.Length.EqualTo(3)); Assert.That(array, Has.Some.StartsWith("x").And.Length.EqualTo(3)); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/SyntaxTest.cs0000664000175000017500000000276411504175260024000 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework.Constraints; namespace NUnit.Framework.Syntax { public abstract class SyntaxTest { protected string parseTree; protected IResolveConstraint staticSyntax; protected IResolveConstraint inheritedSyntax; protected IResolveConstraint builderSyntax; protected AssertionHelper Helper() { return new AssertionHelper(); } protected ConstraintExpression Builder() { return new ConstraintExpression(); } [Test] public void SupportedByStaticSyntax() { Assert.That( staticSyntax.Resolve().ToString(), Is.EqualTo(parseTree).NoClip); } [Test] public void SupportedByConstraintBuilder() { Assert.That( builderSyntax.Resolve().ToString(), Is.EqualTo(parseTree).NoClip); } [Test] public void SupportedByInheritedSyntax() { Assert.That( inheritedSyntax.Resolve().ToString(), Is.EqualTo(parseTree).NoClip); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/CollectionTests.cs0000664000175000017500000002063311544454420024765 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using NUnit.Framework.Tests; namespace NUnit.Framework.Syntax { public class UniqueTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Unique; inheritedSyntax = Helper().Unique; builderSyntax = Builder().Unique; } } public class CollectionOrderedTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered; inheritedSyntax = Helper().Ordered; builderSyntax = Builder().Ordered; } } public class CollectionOrderedTest_Descending : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered.Descending; inheritedSyntax = Helper().Ordered.Descending; builderSyntax = Builder().Ordered.Descending; } } public class CollectionOrderedTest_Comparer : SyntaxTest { [SetUp] public void SetUp() { IComparer comparer = Comparer.Default; parseTree = ""; staticSyntax = Is.Ordered.Using(comparer); inheritedSyntax = Helper().Ordered.Using(comparer); builderSyntax = Builder().Ordered.Using(comparer); } } public class CollectionOrderedTest_Comparer_Descending : SyntaxTest { [SetUp] public void SetUp() { IComparer comparer = Comparer.Default; parseTree = ""; staticSyntax = Is.Ordered.Using(comparer).Descending; inheritedSyntax = Helper().Ordered.Using(comparer).Descending; builderSyntax = Builder().Ordered.Using(comparer).Descending; } } public class CollectionOrderedByTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered.By("SomePropertyName"); inheritedSyntax = Helper().Ordered.By("SomePropertyName"); builderSyntax = Builder().Ordered.By("SomePropertyName"); } } public class CollectionOrderedByTest_Descending : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered.By("SomePropertyName").Descending; inheritedSyntax = Helper().Ordered.By("SomePropertyName").Descending; builderSyntax = Builder().Ordered.By("SomePropertyName").Descending; } } public class CollectionOrderedByTest_Comparer : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered.By("SomePropertyName").Using(Comparer.Default); inheritedSyntax = Helper().Ordered.By("SomePropertyName").Using(Comparer.Default); builderSyntax = Builder().Ordered.By("SomePropertyName").Using(Comparer.Default); } } public class CollectionOrderedByTest_Comparer_Descending : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Ordered.By("SomePropertyName").Using(Comparer.Default).Descending; inheritedSyntax = Helper().Ordered.By("SomePropertyName").Using(Comparer.Default).Descending; builderSyntax = Builder().Ordered.By("SomePropertyName").Using(Comparer.Default).Descending; } } public class CollectionContainsTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Contains.Item(42); inheritedSyntax = Helper().Contains(42); builderSyntax = Builder().Contains(42); } } public class CollectionContainsTest_String : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Contains.Item("abc"); inheritedSyntax = Helper().Contains("abc"); builderSyntax = Builder().Contains("abc"); } } public class CollectionContainsTest_Comparer : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Contains.Item(42).Using(Comparer.Default); inheritedSyntax = Helper().Contains(42).Using(Comparer.Default); builderSyntax = Builder().Contains(42).Using(Comparer.Default); } [Test] public void ComparerIsCalled() { TestComparer comparer = new TestComparer(); Assert.That(new int[] { 1, 2, 3 }, Contains.Item(2).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } [Test] public void ComparerIsCalledInExpression() { TestComparer comparer = new TestComparer(); Assert.That(new int[] { 1, 2, 3 }, Has.Length.EqualTo(3).And.Contains(2).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } } public class CollectionContainsTest_Comparer_String : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Contains.Item("abc").Using(Comparer.Default); inheritedSyntax = Helper().Contains("abc").Using(Comparer.Default); builderSyntax = Builder().Contains("abc").Using(Comparer.Default); } [Test] public void ComparerIsCalled() { TestComparer comparer = new TestComparer(); Assert.That(new string[] { "Hello", "World" }, Contains.Item("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } [Test] public void ComparerIsCalledInExpression() { TestComparer comparer = new TestComparer(); Assert.That(new string[] { "Hello", "World" }, Has.Length.EqualTo(2).And.Contains("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } } public class CollectionMemberTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Has.Member(42); inheritedSyntax = Helper().Contains(42); builderSyntax = Builder().Contains(42); } } public class CollectionMemberTest_Comparer : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Has.Member(42).Using(Comparer.Default); inheritedSyntax = Helper().Contains(42).Using(Comparer.Default); builderSyntax = Builder().Contains(42).Using(Comparer.Default); } } public class CollectionSubsetTest : SyntaxTest { [SetUp] public void SetUp() { int[] ints = new int[] { 1, 2, 3 }; parseTree = ""; staticSyntax = Is.SubsetOf(ints); inheritedSyntax = Helper().SubsetOf(ints); builderSyntax = Builder().SubsetOf(ints); } } public class CollectionEquivalentTest : SyntaxTest { [SetUp] public void SetUp() { int[] ints = new int[] { 1, 2, 3 }; parseTree = ""; staticSyntax = Is.EquivalentTo(ints); inheritedSyntax = Helper().EquivalentTo(ints); builderSyntax = Builder().EquivalentTo(ints); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/StringConstraints.cs0000664000175000017500000001107711504175260025345 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Syntax { public class SubstringTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringContaining("X"); inheritedSyntax = Helper().ContainsSubstring("X"); builderSyntax = Builder().ContainsSubstring("X"); } } [Obsolete] public class TextContains : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Text.Contains("X"); inheritedSyntax = Helper().ContainsSubstring("X"); builderSyntax = Builder().ContainsSubstring("X"); } } public class SubstringTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringContaining("X").IgnoreCase; inheritedSyntax = Helper().ContainsSubstring("X").IgnoreCase; builderSyntax = Builder().ContainsSubstring("X").IgnoreCase; } } public class StartsWithTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringStarting("X"); inheritedSyntax = Helper().StartsWith("X"); builderSyntax = Builder().StartsWith("X"); } } [Obsolete] public class TextStartsWithTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Text.StartsWith("X"); inheritedSyntax = Helper().StartsWith("X"); builderSyntax = Builder().StartsWith("X"); } } public class StartsWithTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringStarting("X").IgnoreCase; inheritedSyntax = Helper().StartsWith("X").IgnoreCase; builderSyntax = Builder().StartsWith("X").IgnoreCase; } } public class EndsWithTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringEnding("X"); inheritedSyntax = Helper().EndsWith("X"); builderSyntax = Builder().EndsWith("X"); } } [Obsolete] public class TextEndsWithTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Text.EndsWith("X"); inheritedSyntax = Helper().EndsWith("X"); builderSyntax = Builder().EndsWith("X"); } } public class EndsWithTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringEnding("X").IgnoreCase; inheritedSyntax = Helper().EndsWith("X").IgnoreCase; builderSyntax = Builder().EndsWith("X").IgnoreCase; } } public class RegexTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringMatching("X"); inheritedSyntax = Helper().Matches("X"); builderSyntax = Builder().Matches("X"); } } [Obsolete] public class TextMatchesTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Text.Matches("X"); inheritedSyntax = Helper().Matches("X"); builderSyntax = Builder().Matches("X"); } } public class RegexTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { parseTree = @""; staticSyntax = Is.StringMatching("X").IgnoreCase; inheritedSyntax = Helper().Matches("X").IgnoreCase; builderSyntax = Builder().Matches("X").IgnoreCase; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/SerializableConstraints.cs0000664000175000017500000000206111504175260026476 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Framework.Syntax { [TestFixture] public class BinarySerializableTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.BinarySerializable; inheritedSyntax = Helper().BinarySerializable; builderSyntax = Builder().BinarySerializable; } } [TestFixture] public class XmlSerializableTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.XmlSerializable; inheritedSyntax = Helper().XmlSerializable; builderSyntax = Builder().XmlSerializable; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/TypeConstraints.cs0000664000175000017500000001345311544454420025022 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Syntax { [TestFixture] public class ExactTypeTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.TypeOf(typeof(string)); inheritedSyntax = Helper().TypeOf(typeof(string)); builderSyntax = Builder().TypeOf(typeof(string)); } } [TestFixture] public class InstanceOfTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.InstanceOf(typeof(string)); inheritedSyntax = Helper().InstanceOf(typeof(string)); builderSyntax = Builder().InstanceOf(typeof(string)); } } [TestFixture, Obsolete] public class InstanceOfTypeTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.InstanceOfType(typeof(string)); inheritedSyntax = Helper().InstanceOfType(typeof(string)); builderSyntax = Builder().InstanceOfType(typeof(string)); } } [TestFixture] public class AssignableFromTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AssignableFrom(typeof(string)); inheritedSyntax = Helper().AssignableFrom(typeof(string)); builderSyntax = Builder().AssignableFrom(typeof(string)); } } [TestFixture] public class AssignableToTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AssignableTo(typeof(string)); inheritedSyntax = Helper().AssignableTo(typeof(string)); builderSyntax = Builder().AssignableTo(typeof(string)); } } [TestFixture] public class AttributeTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Has.Attribute(typeof(TestFixtureAttribute)); inheritedSyntax = Helper().Attribute(typeof(TestFixtureAttribute)); builderSyntax = Builder().Attribute(typeof(TestFixtureAttribute)); } } [TestFixture] public class AttributeTestWithFollowingConstraint : SyntaxTest { [SetUp] public void SetUp() { parseTree = @">>>"; staticSyntax = Has.Attribute(typeof(TestFixtureAttribute)).Property("Description").Not.Null; inheritedSyntax = Helper().Attribute(typeof(TestFixtureAttribute)).Property("Description").Not.Null; builderSyntax = Builder().Attribute(typeof(TestFixtureAttribute)).Property("Description").Not.Null; } } #if CLR_2_0 || CLR_4_0 [TestFixture] public class ExactTypeTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.TypeOf(); inheritedSyntax = Helper().TypeOf(); builderSyntax = Builder().TypeOf(); } } [TestFixture] public class InstanceOfTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.InstanceOf(); inheritedSyntax = Helper().InstanceOf(); builderSyntax = Builder().InstanceOf(); } } [TestFixture, Obsolete] public class InstanceOfTypeTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.InstanceOfType(); inheritedSyntax = Helper().InstanceOfType(); builderSyntax = Builder().InstanceOfType(); } } [TestFixture] public class AssignableFromTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AssignableFrom(); inheritedSyntax = Helper().AssignableFrom(); builderSyntax = Builder().AssignableFrom(); } } [TestFixture] public class AssignableToTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AssignableTo(); inheritedSyntax = Helper().AssignableTo(); builderSyntax = Builder().AssignableTo(); } } [TestFixture] public class AttributeTest_Generic : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Has.Attribute(); inheritedSyntax = Helper().Attribute(); builderSyntax = Builder().Attribute(); } } #endif } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/SimpleConstraints.cs0000664000175000017500000000455611666105026025336 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Syntax { public class NullTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Null; inheritedSyntax = Helper().Null; builderSyntax = Builder().Null; } } public class TrueTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.True; inheritedSyntax = Helper().True; builderSyntax = Builder().True; } } public class FalseTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.False; inheritedSyntax = Helper().False; builderSyntax = Builder().False; } } public class NaNTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.NaN; inheritedSyntax = Helper().NaN; builderSyntax = Builder().NaN; } } public class PositiveTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Positive; inheritedSyntax = Helper().Positive; builderSyntax = Builder().Positive; } } public class NegativeTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Negative; inheritedSyntax = Helper().Negative; builderSyntax = Builder().Negative; } } public class EmptyTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.Empty; inheritedSyntax = Helper().Empty; builderSyntax = Builder().Empty; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/ArbitraryConstraintMatching.cs0000664000175000017500000000510211720454410027313 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework.Constraints; namespace NUnit.Framework.Syntax { [TestFixture] public class ArbitraryConstraintMatching { Constraint custom = new CustomConstraint(); Constraint another = new AnotherConstraint(); [Test] public void CanMatchCustomConstraint() { IResolveConstraint constraint = new ConstraintExpression().Matches(custom); Assert.That(constraint.Resolve().ToString(), Is.EqualTo("")); } [Test] public void CanMatchCustomConstraintAfterPrefix() { IResolveConstraint constraint = Is.All.Matches(custom); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(">")); } [Test] public void CanMatchCustomConstraintsUnderAndOperator() { IResolveConstraint constraint = Is.All.Matches(custom).And.Matches(another); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(" >>")); } #if CLR_2_0 || CLR_4_0 [Test] public void CanMatchPredicate() { IResolveConstraint constraint = new ConstraintExpression().Matches(new Predicate(IsEven)); Assert.That(constraint.Resolve().ToString(), Is.EqualTo("")); Assert.That(42, constraint); } bool IsEven(int num) { return (num & 1) == 0; } #if CS_3_0 || CS_4_0 [Test] public void CanMatchLambda() { IResolveConstraint constraint = new ConstraintExpression().Matches( (x) => (x & 1) == 0); Assert.That(constraint.Resolve().ToString(), Is.EqualTo("")); Assert.That(42, constraint); } #endif #endif class CustomConstraint : Constraint { public override bool Matches(object actual) { throw new NotImplementedException(); } public override void WriteDescriptionTo(MessageWriter writer) { throw new NotImplementedException(); } } class AnotherConstraint : CustomConstraint { } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/PathConstraintTests.cs0000664000175000017500000001246211567125300025631 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; namespace NUnit.Framework.Syntax { public class SamePathTest : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; string defaultCaseSensitivity = Path.DirectorySeparatorChar == '\\' ? "ignorecase" : "respectcase"; parseTree = string.Format(@"", path, defaultCaseSensitivity); staticSyntax = Is.SamePath(path); inheritedSyntax = Helper().SamePath(path); builderSyntax = Builder().SamePath(path); } } public class SamePathTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@"", path); staticSyntax = Is.SamePath(path).IgnoreCase; inheritedSyntax = Helper().SamePath(path).IgnoreCase; builderSyntax = Builder().SamePath(path).IgnoreCase; } } public class NotSamePathTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@">", path); staticSyntax = Is.Not.SamePath(path).IgnoreCase; inheritedSyntax = Helper().Not.SamePath(path).IgnoreCase; builderSyntax = Builder().Not.SamePath(path).IgnoreCase; } } public class SamePathTest_RespectCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@"", path); staticSyntax = Is.SamePath(path).RespectCase; inheritedSyntax = Helper().SamePath(path).RespectCase; builderSyntax = Builder().SamePath(path).RespectCase; } } public class NotSamePathTest_RespectCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@">", path); staticSyntax = Is.Not.SamePath(path).RespectCase; inheritedSyntax = Helper().Not.SamePath(path).RespectCase; builderSyntax = Builder().Not.SamePath(path).RespectCase; } } public class SamePathOrUnderTest : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; string defaultCaseSensitivity = Path.DirectorySeparatorChar == '\\' ? "ignorecase" : "respectcase"; parseTree = string.Format(@"", path, defaultCaseSensitivity); staticSyntax = Is.SamePathOrUnder(path); inheritedSyntax = Helper().SamePathOrUnder(path); builderSyntax = Builder().SamePathOrUnder(path); } } public class SamePathOrUnderTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@"", path); staticSyntax = Is.SamePathOrUnder(path).IgnoreCase; inheritedSyntax = Helper().SamePathOrUnder(path).IgnoreCase; builderSyntax = Builder().SamePathOrUnder(path).IgnoreCase; } } public class NotSamePathOrUnderTest_IgnoreCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@">", path); staticSyntax = Is.Not.SamePathOrUnder(path).IgnoreCase; inheritedSyntax = Helper().Not.SamePathOrUnder(path).IgnoreCase; builderSyntax = Builder().Not.SamePathOrUnder(path).IgnoreCase; } } public class SamePathOrUnderTest_RespectCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@"", path); staticSyntax = Is.SamePathOrUnder(path).RespectCase; inheritedSyntax = Helper().SamePathOrUnder(path).RespectCase; builderSyntax = Builder().SamePathOrUnder(path).RespectCase; } } public class NotSamePathOrUnderTest_RespectCase : SyntaxTest { [SetUp] public void SetUp() { string path = "/path/to/match"; parseTree = string.Format(@">", path); staticSyntax = Is.Not.SamePathOrUnder(path).RespectCase; inheritedSyntax = Helper().Not.SamePathOrUnder(path).RespectCase; builderSyntax = Builder().Not.SamePathOrUnder(path).RespectCase; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/OperatorOverrides.cs0000664000175000017500000000427211504175260025324 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework.Constraints; namespace NUnit.Framework.Syntax { public class NotOperatorOverride : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = !Is.Null; inheritedSyntax = !Helper().Null; builderSyntax = !Builder().Null; } } public class AndOperatorOverride : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >"; staticSyntax = Is.GreaterThan(5) & Is.LessThan(10); inheritedSyntax = Helper().GreaterThan(5) & Is.LessThan(10); builderSyntax = Builder().GreaterThan(5) & Builder().LessThan(10); } } public class OrOperatorOverride : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >"; staticSyntax = Is.LessThan(5) | Is.GreaterThan(10); inheritedSyntax = Helper().LessThan(5) | Is.GreaterThan(10); builderSyntax = Builder().LessThan(5) | Is.GreaterThan(10); } } public class MixedOperatorOverrides { [Test] public void ComplexTests() { string expected = "> >> >>"; Constraint c = Is.Not.Null & Is.Not.LessThan(5) & Is.Not.GreaterThan(10); Assert.That(c.ToString(), Is.EqualTo(expected).NoClip); c = !Is.Null & !Is.LessThan(5) & !Is.GreaterThan(10); Assert.That(c.ToString(), Is.EqualTo(expected).NoClip); Constraint x = null; c = !x & !Is.LessThan(5) & !Is.GreaterThan(10); Assert.That(c.ToString(), Is.EqualTo(expected).NoClip); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/ThrowsTests.cs0000664000175000017500000001737011544454420024164 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework.Constraints; namespace NUnit.Framework.Syntax { [TestFixture] public class ThrowsTests { [Test] public void ThrowsException() { IResolveConstraint expr = Throws.Exception; Assert.AreEqual( "", expr.Resolve().ToString()); } [Test] public void ThrowsExceptionWithConstraint() { IResolveConstraint expr = Throws.Exception.With.Property("ParamName").EqualTo("myParam"); Assert.AreEqual( @">>", expr.Resolve().ToString()); } [Test] public void ThrowsExceptionTypeOf() { IResolveConstraint expr = Throws.Exception.TypeOf(typeof(ArgumentException)); Assert.AreEqual( ">", expr.Resolve().ToString()); } [Test] public void ThrowsTypeOf() { IResolveConstraint expr = Throws.TypeOf(typeof(ArgumentException)); Assert.AreEqual( ">", expr.Resolve().ToString()); } [Test] public void ThrowsTypeOfAndConstraint() { IResolveConstraint expr = Throws.TypeOf(typeof(ArgumentException)).And.Property("ParamName").EqualTo("myParam"); Assert.AreEqual( @" >>>", expr.Resolve().ToString()); } [Test] public void ThrowsExceptionTypeOfAndConstraint() { IResolveConstraint expr = Throws.Exception.TypeOf(typeof(ArgumentException)).And.Property("ParamName").EqualTo("myParam"); Assert.AreEqual( @" >>>", expr.Resolve().ToString()); } [Test] public void ThrowsTypeOfWithConstraint() { IResolveConstraint expr = Throws.TypeOf(typeof(ArgumentException)).With.Property("ParamName").EqualTo("myParam"); Assert.AreEqual( @" >>>", expr.Resolve().ToString()); } [Test] public void ThrowsTypeofWithMessage() { IResolveConstraint expr = Throws.TypeOf(typeof(ArgumentException)).With.Message.EqualTo("my message"); Assert.AreEqual( @" >>>", expr.Resolve().ToString()); } [Test] public void ThrowsInstanceOf() { IResolveConstraint expr = Throws.InstanceOf(typeof(ArgumentException)); Assert.AreEqual( ">", expr.Resolve().ToString()); } [Test] public void ThrowsExceptionInstanceOf() { IResolveConstraint expr = Throws.Exception.InstanceOf(typeof(ArgumentException)); Assert.AreEqual( ">", expr.Resolve().ToString()); } [Test] public void ThrowsInnerException() { IResolveConstraint expr = Throws.InnerException.TypeOf(typeof(ArgumentException)); Assert.AreEqual( ">>", expr.Resolve().ToString()); } [Test] public void ThrowsExceptionWithInnerException() { IResolveConstraint expr = Throws.Exception.With.InnerException.TypeOf(typeof(ArgumentException)); Assert.AreEqual( ">>", expr.Resolve().ToString()); } [Test] public void ThrowsTypeOfWithInnerException() { IResolveConstraint expr = Throws.TypeOf(typeof(System.Reflection.TargetInvocationException)) .With.InnerException.TypeOf(typeof(ArgumentException)); Assert.AreEqual( " >>>", expr.Resolve().ToString()); } [Test] public void ThrowsTargetInvocationExceptionWithInnerException() { IResolveConstraint expr = Throws.TargetInvocationException .With.InnerException.TypeOf(typeof(ArgumentException)); Assert.AreEqual( " >>>", expr.Resolve().ToString()); } [Test] public void ThrowsArgumentException() { IResolveConstraint expr = Throws.ArgumentException; Assert.AreEqual( ">", expr.Resolve().ToString()); } [Test] public void ThrowsInvalidOperationException() { IResolveConstraint expr = Throws.InvalidOperationException; Assert.AreEqual( ">", expr.Resolve().ToString()); } // TODO: Move these to AssertThat tests #if CLR_2_0 || CLR_4_0 #if CS_3_0 || CS_4_0 [Test] public void DelegateThrowsException() { Assert.That( delegate { throw new ApplicationException(); }, Throws.Exception); } [Test] public void LambdaThrowsExcepton() { Assert.That( () => new MyClass(null), Throws.InstanceOf()); } [Test] public void LambdaThrowsExceptionWithMessage() { Assert.That( () => new MyClass(null), Throws.InstanceOf() .And.Message.Matches("null")); } internal class MyClass { public MyClass(string s) { if (s == null) { throw new ArgumentNullException(); } } } [Test] public void LambdaThrowsNothing() { Assert.That( () => null, Throws.Nothing); } #else [Test] public void DelegateThrowsException() { Assert.That( delegate { Throw(); return; }, Throws.Exception); } // Encapsulate throw to trick compiler and // avoid unreachable code warning. Can't // use pragma because this is also compiled // under the .NET 1.0 and 1.1 compilers. private void Throw() { throw new ApplicationException(); } #endif #endif } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/InvalidCodeTests.cs0000664000175000017500000000471411544454420025055 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.CodeDom.Compiler; using NUnit.Framework.Constraints; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Syntax { [TestFixture] public class InvalidCodeTests : AssertionHelper { static readonly string template1 = @"using System; using NUnit.Framework; using NUnit.Framework.Constraints; class SomeClass { void SomeMethod() { object c = $FRAGMENT$; } }"; [TestCase("Is.Null.Not")] [TestCase("Is.Not.Null.GreaterThan(10))")] [TestCase("Is.Null.All")] [TestCase("Is.And")] [TestCase("Is.All.And.And")] [TestCase("Is.Null.And.Throws")] public void CodeShouldNotCompile(string fragment) { string code = template1.Replace("$FRAGMENT$", fragment); TestCompiler compiler = new TestCompiler( new string[] { "system.dll", "nunit.framework.dll" }, "test.dll"); CompilerResults results = compiler.CompileCode(code); if (results.NativeCompilerReturnValue == 0) Assert.Fail("Code fragment \"" + fragment + "\" should not compile but it did"); } static readonly string template2 = @"using System; using NUnit.Framework; using NUnit.Framework.Constraints; class SomeClass { void SomeMethod() { Assert.That(42, $FRAGMENT$); } }"; [TestCase("Is.Not")] [TestCase("Is.All")] [TestCase("Is.Not.All")] [TestCase("Is.All.Not")] public void CodeShouldNotCompileAsFinishedConstraint(string fragment) { string code = template2.Replace("$FRAGMENT$", fragment); TestCompiler compiler = new TestCompiler( new string[] { "system.dll", "nunit.framework.dll" }, "test.dll"); CompilerResults results = compiler.CompileCode(code); if (results.NativeCompilerReturnValue == 0) Assert.Fail("Code fragment \"" + fragment + "\" should not compile as a finished constraint but it did"); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/ComparisonTests.cs0000664000175000017500000000451211504175260025000 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Syntax { public class GreaterThanTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.GreaterThan(7); inheritedSyntax = Helper().GreaterThan(7); builderSyntax = Builder().GreaterThan(7); } } public class GreaterThanOrEqualTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.GreaterThanOrEqualTo(7); inheritedSyntax = Helper().GreaterThanOrEqualTo(7); builderSyntax = Builder().GreaterThanOrEqualTo(7); } } public class AtLeastTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AtLeast(7); inheritedSyntax = Helper().AtLeast(7); builderSyntax = Builder().AtLeast(7); } } public class LessThanTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.LessThan(7); inheritedSyntax = Helper().LessThan(7); builderSyntax = Builder().LessThan(7); } } public class LessThanOrEqualTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.LessThanOrEqualTo(7); inheritedSyntax = Helper().LessThanOrEqualTo(7); builderSyntax = Builder().LessThanOrEqualTo(7); } } public class AtMostTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Is.AtMost(7); inheritedSyntax = Helper().AtMost(7); builderSyntax = Builder().AtMost(7); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/AfterTests.cs0000664000175000017500000001126611544454420023735 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Collections; namespace NUnit.Framework.Syntax { public class AfterTest_SimpleConstraint : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Is.EqualTo(10).After(1000); inheritedSyntax = Helper().EqualTo(10).After(1000); builderSyntax = Builder().EqualTo(10).After(1000); } } public class AfterTest_ProperyTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">>"; staticSyntax = Has.Property("X").EqualTo(10).After(1000); inheritedSyntax = Helper().Property("X").EqualTo(10).After(1000); builderSyntax = Builder().Property("X").EqualTo(10).After(1000); } } public class AfterTest_AndOperator : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >>"; staticSyntax = Is.GreaterThan(0).And.LessThan(10).After(1000); inheritedSyntax = Helper().GreaterThan(0).And.LessThan(10).After(1000); builderSyntax = Builder().GreaterThan(0).And.LessThan(10).After(1000); } } #if CLR_2_0 || CLR_4_0 public abstract class AfterSyntaxTests { protected bool flag; protected int num; protected object ob1, ob2, ob3; protected ArrayList list; protected string greeting; [SetUp] public void InitializeValues() { this.flag = false; this.num = 0; this.ob1 = new object(); this.ob2 = new object(); this.ob3 = new object(); this.list = new ArrayList(); this.list.Add(1); this.list.Add(2); this.list.Add(3); this.greeting = "hello"; new Thread(ModifyValuesAfterDelay).Start(); } private void ModifyValuesAfterDelay() { Thread.Sleep(100); this.flag = true; this.num = 1; this.ob1 = ob2; this.ob3 = null; this.list.Add(4); this.greeting += "world"; } } public class AfterSyntaxUsingAnonymousDelegates : AfterSyntaxTests { [Test] public void TrueTest() { Assert.That(delegate { return flag; }, Is.True.After(5000, 200)); } [Test] public void EqualToTest() { Assert.That(delegate { return num; }, Is.EqualTo(1).After(5000, 200)); } [Test] public void SameAsTest() { Assert.That(delegate { return ob1; }, Is.SameAs(ob2).After(5000, 200)); } [Test] public void GreaterTest() { Assert.That(delegate { return num; }, Is.GreaterThan(0).After(5000,200)); } [Test] public void HasMemberTest() { Assert.That(delegate { return list; }, Has.Member(4).After(5000, 200)); } [Test] public void NullTest() { Assert.That(delegate { return ob3; }, Is.Null.After(5000, 200)); } [Test] public void TextTest() { Assert.That(delegate { return greeting; }, Is.StringEnding("world").After(5000, 200)); } } public class AfterSyntaxUsingActualPassedByRef : AfterSyntaxTests { [Test] public void TrueTest() { Assert.That(ref flag, Is.True.After(5000, 200)); } [Test] public void EqualToTest() { Assert.That(ref num, Is.EqualTo(1).After(5000, 200)); } [Test] public void SameAsTest() { Assert.That(ref ob1, Is.SameAs(ob2).After(5000, 200)); } [Test] public void GreaterTest() { Assert.That(ref num, Is.GreaterThan(0).After(5000, 200)); } [Test] public void HasMemberTest() { Assert.That(ref list, Has.Member(4).After(5000, 200)); } [Test] public void NullTest() { Assert.That(ref ob3, Is.Null.After(5000, 200)); } [Test] public void TextTest() { Assert.That(ref greeting, Is.StringEnding("world").After(5000, 200)); } } #endif }NUnit-2.6.0.12051/src/NUnitFramework/tests/Syntax/PropertyTests.cs0000664000175000017500000000676211672602276024533 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Syntax { public class PropertyExistsTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ""; staticSyntax = Has.Property("X"); inheritedSyntax = Helper().Property("X"); builderSyntax = Builder().Property("X"); } } public class PropertyExistsTest_AndFollows : SyntaxTest { [SetUp] public void SetUp() { parseTree = " >"; staticSyntax = Has.Property("X").And.EqualTo(7); inheritedSyntax = Helper().Property("X").And.EqualTo(7); builderSyntax = Builder().Property("X").And.EqualTo(7); } } public class PropertyTest_ConstraintFollows : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Has.Property("X").GreaterThan(5); inheritedSyntax = Helper().Property("X").GreaterThan(5); builderSyntax = Builder().Property("X").GreaterThan(5); } } public class PropertyTest_NotFollows : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">>"; staticSyntax = Has.Property("X").Not.GreaterThan(5); inheritedSyntax = Helper().Property("X").Not.GreaterThan(5); builderSyntax = Builder().Property("X").Not.GreaterThan(5); } } public class LengthTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Has.Length.GreaterThan(5); inheritedSyntax = Helper().Length.GreaterThan(5); builderSyntax = Builder().Length.GreaterThan(5); } } public class CountTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = ">"; staticSyntax = Has.Count.EqualTo(5); inheritedSyntax = Helper().Count.EqualTo(5); builderSyntax = Builder().Count.EqualTo(5); } } public class MessageTest : SyntaxTest { [SetUp] public void SetUp() { parseTree = @">"; staticSyntax = Has.Message.StartsWith("Expected"); inheritedSyntax = Helper().Message.StartsWith("Expected"); builderSyntax = Builder().Message.StartsWith("Expected"); } } public class PropertySyntaxVariations { private readonly int[] ints = new int[] { 1, 2, 3 }; [Test] public void ExistenceTest() { Assert.That(ints, Has.Property("Length")); Assert.That(ints, Has.Length); } [Test] public void SeparateConstraintTest() { Assert.That(ints, Has.Property("Length").EqualTo(3)); Assert.That(ints, Has.Length.EqualTo(3)); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/ArrayNotEqualFixture.cs0000664000175000017500000000276211504175260024460 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { /// /// Summary description for ArrayNotEqualFixture. /// [TestFixture] public class ArrayNotEqualFixture : AssertionHelper { [Test] public void DifferentLengthArrays() { string[] array1 = { "one", "two", "three" }; string[] array2 = { "one", "two", "three", "four", "five" }; Assert.AreNotEqual(array1, array2); Assert.AreNotEqual(array2, array1); Expect(array1, Not.EqualTo(array2)); Expect(array2, Not.EqualTo(array1)); } [Test] public void SameLengthDifferentContent() { string[] array1 = { "one", "two", "three" }; string[] array2 = { "one", "two", "ten" }; Assert.AreNotEqual(array1, array2); Assert.AreNotEqual(array2, array1); Expect(array1, Not.EqualTo(array2)); Expect(array2, Not.EqualTo(array1)); } [Test] public void ArraysDeclaredAsDifferentTypes() { string[] array1 = { "one", "two", "three" }; object[] array2 = { "one", "three", "two" }; Assert.AreNotEqual(array1, array2); Expect(array1, Not.EqualTo(array2)); Expect(array2, Not.EqualTo(array1)); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/RangeTests.cs0000664000175000017500000000332411504175260022434 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class RangeTests { static readonly string NL = Environment.NewLine; [Test] public void InRangeSucceeds() { Assert.That( 7, Is.InRange(5, 10) ); Assert.That(0.23, Is.InRange(-1.0, 1.0)); Assert.That(DateTime.Parse("12-December-2008"), Is.InRange(DateTime.Parse("1-October-2008"), DateTime.Parse("31-December-2008"))); } [Test] public void InRangeFails() { string expectedMessage = " Expected: in range (5,10)" + NL + " But was: 12" + NL; Assert.That( new TestDelegate( FailingInRangeMethod ), Throws.TypeOf(typeof(AssertionException)).With.Message.EqualTo(expectedMessage)); } private void FailingInRangeMethod() { Assert.That(12, Is.InRange(5, 10)); } [Test] public void NotInRangeSucceeds() { Assert.That(12, Is.Not.InRange(5, 10)); Assert.That(2.57, Is.Not.InRange(-1.0, 1.0)); } [Test] public void NotInRangeFails() { string expectedMessage = " Expected: not in range (5,10)" + NL + " But was: 7" + NL; Assert.That( new TestDelegate(FailingNotInRangeMethod), Throws.TypeOf(typeof(AssertionException)).With.Message.EqualTo(expectedMessage)); } private void FailingNotInRangeMethod() { Assert.That(7, Is.Not.InRange(5, 10)); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/NotSameFixture.cs0000664000175000017500000000151111504175260023266 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class NotSameFixture : MessageChecker { private readonly string s1 = "S1"; private readonly string s2 = "S2"; [Test] public void NotSame() { Assert.AreNotSame(s1, s2); } [Test,ExpectedException(typeof(AssertionException))] public void NotSameFails() { expectedMessage = " Expected: not same as \"S1\"" + Environment.NewLine + " But was: \"S1\"" + Environment.NewLine; Assert.AreNotSame( s1, s1 ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/TextMessageWriterTests.cs0000664000175000017500000001141511504175260025026 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Threading; using System.Globalization; namespace NUnit.Framework.Tests { [TestFixture] public class TextMessageWriterTests : AssertionHelper { private TextMessageWriter writer; [SetUp] public void SetUp() { writer = new TextMessageWriter(); } [Test] public void ConnectorIsWrittenWithSurroundingSpaces() { writer.WriteConnector("and"); Expect(writer.ToString(), EqualTo(" and ")); } [Test] public void PredicateIsWrittenWithTrailingSpace() { writer.WritePredicate("contains"); Expect(writer.ToString(), EqualTo("contains ")); } [Test] public void IntegerIsWrittenAsIs() { writer.WriteValue(42); Expect(writer.ToString(), EqualTo("42")); } [Test] public void StringIsWrittenWithQuotes() { writer.WriteValue("Hello"); Expect(writer.ToString(), EqualTo("\"Hello\"")); } // This test currently fails because control character replacement is // done at a higher level... // TODO: See if we should do it at a lower level // [Test] // public void ControlCharactersInStringsAreEscaped() // { // WriteValue("Best Wishes,\r\n\tCharlie\r\n"); // Assert.That(writer.ToString(), Is.EqualTo("\"Best Wishes,\\r\\n\\tCharlie\\r\\n\"")); // } [Test] public void FloatIsWrittenWithTrailingF() { writer.WriteValue(0.5f); Expect(writer.ToString(), EqualTo("0.5f")); } [Test] public void FloatIsWrittenToNineDigits() { writer.WriteValue(0.33333333333333f); int digits = writer.ToString().Length - 3; // 0.dddddddddf Expect(digits, EqualTo(9)); Expect(writer.ToString().Length, EqualTo(12)); } [Test] public void DoubleIsWrittenWithTrailingD() { writer.WriteValue(0.5d); Expect(writer.ToString(), EqualTo("0.5d")); } [Test] public void DoubleIsWrittenToSeventeenDigits() { writer.WriteValue(0.33333333333333333333333333333333333333333333d); Expect(writer.ToString().Length, EqualTo(20)); // add 3 for leading 0, decimal and trailing d } [Test] public void DecimalIsWrittenWithTrailingM() { writer.WriteValue(0.5m); Expect(writer.ToString(), EqualTo("0.5m")); } [Test] public void DecimalIsWrittenToTwentyNineDigits() { writer.WriteValue(12345678901234567890123456789m); Expect(writer.ToString(), EqualTo("12345678901234567890123456789m")); } [Test] public void DateTimeTest() { writer.WriteValue(new DateTime(2007, 7, 4, 9, 15, 30, 123)); Expect(writer.ToString(), EqualTo("2007-07-04 09:15:30.123")); } [Test] public void DisplayStringDifferences() { string s72 = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; string exp = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXY..."; writer.DisplayStringDifferences(s72, "abcde", 5, false, true); // string message = writer.ToString(); Expect(writer.ToString(), EqualTo( TextMessageWriter.Pfx_Expected + Q(exp) + Environment.NewLine + TextMessageWriter.Pfx_Actual + Q("abcde") + Environment.NewLine + " ----------------^" + Environment.NewLine)); } [Test] public void DisplayStringDifferences_NoClipping() { string s72 = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; writer.DisplayStringDifferences(s72, "abcde", 5, false, false); // string message = writer.ToString(); Expect(writer.ToString(), EqualTo( TextMessageWriter.Pfx_Expected + Q(s72) + Environment.NewLine + TextMessageWriter.Pfx_Actual + Q("abcde") + Environment.NewLine + " ----------------^" + Environment.NewLine)); } private string Q(string s) { return "\"" + s + "\""; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/DirectoryAssertTests.cs0000664000175000017500000003603311543625326024537 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; namespace NUnit.Framework.Tests { public class TestDirectory : IDisposable { private bool _disposedValue = false; public string directoryName; public DirectoryInfo directoryInformation; public DirectoryInfo diSubSubDirectory; #region TestDirectory Utility Class public TestDirectory(string dirName) : this(dirName, true) { } public TestDirectory(string dirName, bool CreateSubDirectory) { this.directoryName = Path.Combine(Path.GetTempPath(), dirName); directoryInformation = Directory.CreateDirectory(this.directoryName); if (CreateSubDirectory) { DirectoryInfo diSubDirectory = directoryInformation.CreateSubdirectory("SubDirectory"); diSubSubDirectory = diSubDirectory.CreateSubdirectory("SubSubDirectory"); } } protected virtual void Dispose(bool disposing) { if (!this._disposedValue) { if (disposing) { if (Directory.Exists(directoryName)) { Directory.Delete(directoryName,true); } } } this._disposedValue = true; } #region IDisposable Members public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); GC.SuppressFinalize(this); } #endregion #endregion } /// /// Summary description for DirectoryAssertTests. /// [TestFixture, Obsolete("DirectoryAssert is obsolete")] public class DirectoryAssertTests : MessageChecker { #region AreEqual #region Success Tests [Test] public void AreEqualPassesWhenBothAreNull() { DirectoryInfo expected = null; DirectoryInfo actual = null; DirectoryAssert.AreEqual(expected, actual); } [Test] public void AreEqualPassesWithDirectoryInfos() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreEqual(td.directoryInformation, td.directoryInformation); } } [Test] public void AreEqualPassesWithStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreEqual(td.directoryName, td.directoryName); } } #endregion #region Failure Tests [Test, ExpectedException(typeof(AssertionException))] public void AreEqualFailsWhenOneIsNull() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreEqual(td.directoryInformation, null); } } [Test, ExpectedException(typeof(AssertionException))] public void AreEqualFailsWhenOneDoesNotExist() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryInfo actual = new DirectoryInfo("NotExistingDirectoryName"); DirectoryAssert.AreEqual(td.directoryInformation, actual); } } [Test, ExpectedException(typeof(AssertionException))] public void AreEqualFailsWithDirectoryInfos() { using (TestDirectory td1 = new TestDirectory("ParentDirectory1")) { using (TestDirectory td2 = new TestDirectory("ParentDirectory2")) { DirectoryAssert.AreEqual(td1.directoryInformation, td2.directoryInformation); } } } [Test, ExpectedException(typeof(AssertionException))] public void AreEqualFailsWithStringPath() { using (TestDirectory td1 = new TestDirectory("ParentDirectory1")) { using (TestDirectory td2 = new TestDirectory("ParentDirectory2")) { DirectoryAssert.AreEqual(td1.directoryName, td2.directoryName); } } } #endregion #endregion #region AreNotEqual #region Success Tests [Test] public void AreNotEqualPassesIfOneIsNull() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreNotEqual(td.directoryInformation, null); } } [Test] public void AreNotEqualPassesWhenOneDoesNotExist() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryInfo actual = new DirectoryInfo("NotExistingDirectoryName"); DirectoryAssert.AreNotEqual(td.directoryInformation, actual); } } public void AreNotEqualPassesWithDirectoryInfos() { using (TestDirectory td1 = new TestDirectory("ParentDirectory1")) { using (TestDirectory td2 = new TestDirectory("ParentDirectory2")) { DirectoryAssert.AreNotEqual(td1.directoryInformation, td2.directoryInformation); } } } [Test] public void AreNotEqualPassesWithStringPath() { using (TestDirectory td1 = new TestDirectory("ParentDirectory1")) { using (TestDirectory td2 = new TestDirectory("ParentDirectory2")) { DirectoryAssert.AreNotEqual(td1.directoryName, td2.directoryName); } } } #endregion #region Failure Tests [Test, ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWhenBothAreNull() { DirectoryInfo expected = null; DirectoryInfo actual = null; expectedMessage = " Expected: not null" + Environment.NewLine + " But was: null" + Environment.NewLine; DirectoryAssert.AreNotEqual(expected, actual); } [Test, ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWithDirectoryInfos() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreNotEqual(td.directoryInformation, td.directoryInformation); } } [Test, ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWithStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory")) { DirectoryAssert.AreNotEqual(td.directoryName, td.directoryName); } } #endregion #endregion #region IsEmpty [Test] public void IsEmptyPassesWithEmptyDirectoryUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsEmpty(td.directoryInformation); Assert.That(td.directoryInformation, Is.Empty); } } [Test] public void IsEmptyPassesWithEmptyDirectoryUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsEmpty(td.directoryName); } } [Test, ExpectedException(typeof(DirectoryNotFoundException))] public void IsEmptyFailsWithInvalidDirectory() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsEmpty(td.directoryName + "INVALID"); } } [Test,ExpectedException(typeof(ArgumentException))] public void IsEmptyThrowsUsingNull() { DirectoryAssert.IsEmpty((DirectoryInfo)null); } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsWithNonEmptyDirectoryUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsEmpty(td.directoryInformation); } } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsWithNonEmptyDirectoryUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsEmpty(td.directoryName); } } #endregion #region IsNotEmpty [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsWithEmptyDirectoryUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsNotEmpty(td.directoryInformation); } } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsWithEmptyDirectoryUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsNotEmpty(td.directoryName); } } [Test, ExpectedException(typeof(ArgumentException))] public void IsNotEmptyThrowsUsingNull() { DirectoryAssert.IsNotEmpty((DirectoryInfo) null); } [Test, ExpectedException(typeof(DirectoryNotFoundException))] public void IsNotEmptyFailsWithInvalidDirectory() { using (TestDirectory td = new TestDirectory("ParentDirectory", false)) { DirectoryAssert.IsNotEmpty(td.directoryName + "INVALID"); } } [Test] public void IsNotEmptyPassesWithNonEmptyDirectoryUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsNotEmpty(td.directoryInformation); Assert.That(td.directoryInformation, Is.Not.Empty); } } [Test] public void IsNotEmptyPassesWithNonEmptyDirectoryUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsNotEmpty(td.directoryName); } } #endregion #region IsWithin [Test, ExpectedException(typeof(ArgumentException))] public void IsWithinThrowsWhenBothAreNull() { DirectoryInfo expected = null; DirectoryInfo actual = null; DirectoryAssert.IsWithin(expected, actual); } [Test] public void IsWithinPassesWithDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory",true)) { DirectoryAssert.IsWithin(td.directoryInformation, td.diSubSubDirectory); } } [Test] public void IsWithinPassesWithStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsWithin(td.directoryName, td.diSubSubDirectory.FullName); } } [Test] public void IsWithinPassesWithTempPath() { // Special case because GetTempPath() returns with a trailing slash string tempPath = Path.GetTempPath(); string tempPathParent = Path.GetDirectoryName(Path.GetDirectoryName(tempPath)); DirectoryAssert.IsWithin(tempPathParent, tempPath); } [Test, ExpectedException(typeof(AssertionException))] public void IsWithinFailsWhenOutsidePathUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryInfo diSystemFolder = new DirectoryInfo(Environment.SpecialFolder.System.ToString()); DirectoryAssert.IsWithin(td.directoryInformation, diSystemFolder); } } [Test, ExpectedException(typeof(AssertionException))] public void IsWithinFailsWhenOutsidePathUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsWithin(td.directoryName, Environment.SpecialFolder.System.ToString()); } } #endregion #region IsNotWithin [Test, ExpectedException(typeof(ArgumentException))] public void IsNotWithinThrowsWhenBothAreNull() { DirectoryInfo expected = null; DirectoryInfo actual = null; DirectoryAssert.IsNotWithin(expected, actual); } [Test] public void IsNotWithinPassesWhenOutsidePathUsingDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryInfo diSystemFolder = new DirectoryInfo(Environment.SpecialFolder.System.ToString()); DirectoryAssert.IsNotWithin(td.directoryInformation, diSystemFolder); } } [Test] public void IsNotWithinPassesWhenOutsidePathUsingStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsNotWithin(td.directoryName, Environment.SpecialFolder.System.ToString()); } } [Test, ExpectedException(typeof(AssertionException))] public void IsNotWithinFailsWithDirectoryInfo() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsNotWithin(td.directoryInformation, td.diSubSubDirectory); } } [Test, ExpectedException(typeof(AssertionException))] public void IsNotWithinFailsWithStringPath() { using (TestDirectory td = new TestDirectory("ParentDirectory", true)) { DirectoryAssert.IsNotWithin(td.directoryName, td.diSubSubDirectory.FullName); } } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/tests/FileAssertTests.cs0000664000175000017500000003202411543625326023446 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using System.Net.Sockets; namespace NUnit.Framework.Tests { #region Nested TestFile Utility Class public class TestFile : IDisposable { private bool _disposedValue = false; private string _resourceName; private string _fileName; public TestFile(string fileName, string resourceName) { _resourceName = "NUnit.Framework.Tests.data." + resourceName; _fileName = Path.Combine(Path.GetTempPath(), fileName); Assembly a = Assembly.GetExecutingAssembly(); using (Stream s = a.GetManifestResourceStream(_resourceName)) { if (s == null) throw new Exception("Manifest Resource Stream " + _resourceName + " was not found."); byte[] buffer = new byte[1024]; using (FileStream fs = File.Create(_fileName)) { while(true) { int count = s.Read(buffer, 0, buffer.Length); if(count == 0) break; fs.Write(buffer, 0, count); } } } } public string FileName { get { return _fileName; } } protected virtual void Dispose(bool disposing) { if (!this._disposedValue) { if (disposing) { if(File.Exists(_fileName)) { File.Delete(_fileName); } } } this._disposedValue = true; } #region IDisposable Members public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); GC.SuppressFinalize(this); } #endregion } #endregion /// /// Summary description for FileAssertTests. /// [TestFixture] public class FileAssertTests : MessageChecker { #region AreEqual #region Success Tests [Test] public void AreEqualPassesWhenBothAreNull() { FileStream expected = null; FileStream actual = null; FileAssert.AreEqual( expected, actual ); } [Test] public void AreEqualPassesWithSameStream() { Stream exampleStream = new MemoryStream(new byte[] { 1, 2, 3 }); Assert.That(exampleStream, Is.EqualTo(exampleStream)); } [Test] public void AreEqualPassesWithEqualStreams() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage1.jpg")) { using (FileStream expected = File.OpenRead(tf1.FileName)) { using (FileStream actual = File.OpenRead(tf2.FileName)) { FileAssert.AreEqual(expected, actual); } } } } [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "not readable", MatchType = MessageMatch.Contains)] public void NonReadableStreamGivesException() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage1.jpg")) { using (FileStream expected = File.OpenRead(tf1.FileName)) { using (FileStream actual = File.OpenWrite(tf2.FileName)) { FileAssert.AreEqual(expected, actual); } } } } [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "not seekable", MatchType = MessageMatch.Contains)] public void NonSeekableStreamGivesException() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using (FileStream expected = File.OpenRead(tf1.FileName)) { using (FakeStream actual = new FakeStream()) { FileAssert.AreEqual(expected, actual); } } } } private class FakeStream : MemoryStream { public override bool CanSeek { get { return false; } } } [Test] public void AreEqualPassesWithFiles() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage1.jpg")) { FileAssert.AreEqual( tf1.FileName, tf2.FileName, "Failed using file names" ); } } [Test] public void AreEqualPassesUsingSameFileTwice() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { FileAssert.AreEqual( tf1.FileName, tf1.FileName ); } } [Test] public void AreEqualPassesWithFileInfos() { using(TestFile tf1 = new TestFile("Test1.jpg","TestImage1.jpg")) using(TestFile tf2 = new TestFile("Test2.jpg","TestImage1.jpg")) { FileInfo expected = new FileInfo( tf1.FileName ); FileInfo actual = new FileInfo( tf2.FileName ); FileAssert.AreEqual( expected, actual ); FileAssert.AreEqual( expected, actual ); } } [Test] public void AreEqualPassesWithTextFiles() { using(TestFile tf1 = new TestFile("Test1.txt","TestText1.txt")) { using(TestFile tf2 = new TestFile("Test2.txt","TestText1.txt")) { FileAssert.AreEqual( tf1.FileName, tf2.FileName ); } } } #endregion #region Failure Tests [Test,ExpectedException(typeof(AssertionException))] public void AreEqualFailsWhenOneIsNull() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using(FileStream expected = File.OpenRead(tf1.FileName)) { expectedMessage = " Expected: " + Environment.NewLine + " But was: null" + Environment.NewLine; FileAssert.AreEqual( expected, null ); } } } [Test,ExpectedException(typeof(AssertionException))] public void AreEqualFailsWithStreams() { string expectedFile = "Test1.jpg"; string actualFile = "Test2.jpg"; using (TestFile tf1 = new TestFile(expectedFile, "TestImage1.jpg")) { using (TestFile tf2 = new TestFile(actualFile, "TestImage2.jpg")) { using(FileStream expected = File.OpenRead(tf1.FileName)) { using(FileStream actual = File.OpenRead(tf2.FileName)) { expectedMessage = string.Format(" Expected Stream length {0} but was {1}." + Environment.NewLine, new FileInfo(tf1.FileName).Length, new FileInfo(tf2.FileName).Length); FileAssert.AreEqual( tf1.FileName, tf2.FileName); } } } } } [Test,ExpectedException(typeof(AssertionException))] public void AreEqualFailsWithFileInfos() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage2.jpg")) { FileInfo expected = new FileInfo( tf1.FileName ); FileInfo actual = new FileInfo( tf2.FileName ); expectedMessage = string.Format(" Expected Stream length {0} but was {1}." + Environment.NewLine, expected.Length, actual.Length); FileAssert.AreEqual( expected, actual ); } } } [Test,ExpectedException(typeof(AssertionException))] public void AreEqualFailsWithFiles() { string expected = "Test1.jpg"; string actual = "Test2.jpg"; using (TestFile tf1 = new TestFile(expected, "TestImage1.jpg")) { using (TestFile tf2 = new TestFile(actual, "TestImage2.jpg")) { expectedMessage = string.Format(" Expected Stream length {0} but was {1}." + Environment.NewLine, new FileInfo(tf1.FileName).Length, new FileInfo(tf2.FileName).Length); FileAssert.AreEqual( tf1.FileName, tf2.FileName ); } } } [Test] [ExpectedException(typeof(AssertionException), ExpectedMessage="Stream lengths are both", MatchType=MessageMatch.Contains)] public void AreEqualFailsWithTextFilesAfterReadingBothFiles() { using (TestFile tf1 = new TestFile("Test1.txt", "TestText1.txt")) { using (TestFile tf2 = new TestFile("Test2.txt", "TestText2.txt")) { FileAssert.AreEqual( tf1.FileName, tf2.FileName ); } } } #endregion #endregion #region AreNotEqual #region Success Tests [Test] public void AreNotEqualPassesIfOneIsNull() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using(FileStream expected = File.OpenRead(tf1.FileName)) { FileAssert.AreNotEqual( expected, null ); } } } [Test] public void AreNotEqualPassesWithStreams() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage2.jpg")) { using(FileStream expected = File.OpenRead(tf1.FileName)) { using(FileStream actual = File.OpenRead(tf2.FileName)) { FileAssert.AreNotEqual( expected, actual); } } } } } [Test] public void AreNotEqualPassesWithFiles() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage2.jpg")) { FileAssert.AreNotEqual( tf1.FileName, tf2.FileName ); } } } [Test] public void AreNotEqualPassesWithFileInfos() { using (TestFile tf1 = new TestFile("Test1.jpg", "TestImage1.jpg")) { using (TestFile tf2 = new TestFile("Test2.jpg", "TestImage2.jpg")) { FileInfo expected = new FileInfo( tf1.FileName ); FileInfo actual = new FileInfo( tf2.FileName ); FileAssert.AreNotEqual( expected, actual ); } } } [Test] public void AreNotEqualIteratesOverTheEntireFile() { using (TestFile tf1 = new TestFile("Test1.txt", "TestText1.txt")) { using (TestFile tf2 = new TestFile("Test2.txt", "TestText2.txt")) { FileAssert.AreNotEqual( tf1.FileName, tf2.FileName ); } } } #endregion #region Failure Tests [Test, ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWhenBothAreNull() { FileStream expected = null; FileStream actual = null; expectedMessage = " Expected: not null" + Environment.NewLine + " But was: null" + Environment.NewLine; FileAssert.AreNotEqual( expected, actual ); } [Test,ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWithStreams() { using(TestFile tf1 = new TestFile("Test1.jpg","TestImage1.jpg")) using(TestFile tf2 = new TestFile("Test2.jpg","TestImage1.jpg")) using(FileStream expected = File.OpenRead(tf1.FileName)) using(FileStream actual = File.OpenRead(tf2.FileName)) { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; FileAssert.AreNotEqual( expected, actual ); } } [Test,ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWithFileInfos() { using(TestFile tf1 = new TestFile("Test1.jpg","TestImage1.jpg")) { using(TestFile tf2 = new TestFile("Test2.jpg","TestImage1.jpg")) { FileInfo expected = new FileInfo( tf1.FileName ); FileInfo actual = new FileInfo( tf2.FileName ); expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; FileAssert.AreNotEqual( expected, actual ); } } } [Test,ExpectedException(typeof(AssertionException))] public void AreNotEqualFailsWithFiles() { using(TestFile tf1 = new TestFile("Test1.jpg","TestImage1.jpg")) { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; FileAssert.AreNotEqual( tf1.FileName, tf1.FileName ); } } [Test,ExpectedException(typeof(AssertionException))] public void AreNotEqualIteratesOverTheEntireFileAndFails() { using(TestFile tf1 = new TestFile("Test1.txt","TestText1.txt")) { using(TestFile tf2 = new TestFile("Test2.txt","TestText1.txt")) { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; FileAssert.AreNotEqual( tf1.FileName, tf2.FileName ); } } } #endregion #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/tests/ListContentsTests.cs0000664000175000017500000000453511504175260024036 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Framework; namespace NUnit.Framework.Tests { /// /// Summary description for ListContentsTests. /// [TestFixture] public class ListContentsTests : MessageChecker { private static readonly object[] testArray = { "abc", 123, "xyz" }; [Test] public void ArraySucceeds() { Assert.Contains( "abc", testArray ); Assert.Contains( 123, testArray ); Assert.Contains( "xyz", testArray ); } [Test,ExpectedException(typeof(AssertionException))] public void ArrayFails() { expectedMessage = " Expected: collection containing \"def\"" + Environment.NewLine + " But was: < \"abc\", 123, \"xyz\" >" + Environment.NewLine; Assert.Contains("def", testArray); } [Test,ExpectedException(typeof(AssertionException))] public void EmptyArrayFails() { expectedMessage = " Expected: collection containing \"def\"" + Environment.NewLine + " But was: " + Environment.NewLine; Assert.Contains( "def", new object[0] ); } [Test,ExpectedException(typeof(ArgumentException))] public void NullArrayIsError() { Assert.Contains( "def", null ); } [Test] public void ArrayListSucceeds() { ArrayList list = new ArrayList( testArray ); Assert.Contains( "abc", list ); Assert.Contains( 123, list ); Assert.Contains( "xyz", list ); } [Test,ExpectedException(typeof(AssertionException))] public void ArrayListFails() { expectedMessage = " Expected: collection containing \"def\"" + Environment.NewLine + " But was: < \"abc\", 123, \"xyz\" >" + Environment.NewLine; Assert.Contains( "def", new ArrayList( testArray ) ); } [Test] public void DifferentTypesMayBeEqual() { // TODO: Better message for this case expectedMessage = " Expected: collection containing 123.0d" + Environment.NewLine + " But was: < \"abc\", 123, \"xyz\" >" + Environment.NewLine; Assert.Contains( 123.0, new ArrayList( testArray ) ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/TestFixtureAttributeTests.cs0000664000175000017500000000521411544454420025554 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { public class TestFixtureAttributeTests { static object[] fixtureArgs = new object[] { 10, 20, "Charlie" }; #if CLR_2_0 || CLR_4_0 static Type[] typeArgs = new Type[] { typeof(int), typeof(string) }; static object[] combinedArgs = new object[] { typeof(int), typeof(string), 10, 20, "Charlie" }; #endif [Test] public void ConstructWithoutArguments() { TestFixtureAttribute attr = new TestFixtureAttribute(); Assert.That(attr.Arguments.Length == 0); #if CLR_2_0 || CLR_4_0 Assert.That(attr.TypeArgs.Length == 0); #endif } [Test] public void ConstructWithFixtureArgs() { TestFixtureAttribute attr = new TestFixtureAttribute(fixtureArgs); Assert.That(attr.Arguments, Is.EqualTo( fixtureArgs ) ); #if CLR_2_0 || CLR_4_0 Assert.That(attr.TypeArgs.Length == 0 ); #endif } #if CLR_2_0 || CLR_4_0 [Test, Category("Generics")] public void ConstructWithJustTypeArgs() { TestFixtureAttribute attr = new TestFixtureAttribute(typeArgs); Assert.That(attr.Arguments.Length == 0); Assert.That(attr.TypeArgs, Is.EqualTo(typeArgs)); } [Test, Category("Generics")] public void ConstructWithNoArgumentsAndSetTypeArgs() { TestFixtureAttribute attr = new TestFixtureAttribute(); attr.TypeArgs = typeArgs; Assert.That(attr.Arguments.Length == 0); Assert.That(attr.TypeArgs, Is.EqualTo(typeArgs)); } [Test, Category("Generics")] public void ConstructWithFixtureArgsAndSetTypeArgs() { TestFixtureAttribute attr = new TestFixtureAttribute(fixtureArgs); attr.TypeArgs = typeArgs; Assert.That(attr.Arguments, Is.EqualTo(fixtureArgs)); Assert.That(attr.TypeArgs, Is.EqualTo(typeArgs)); } [Test, Category("Generics")] public void ConstructWithCombinedArgs() { TestFixtureAttribute attr = new TestFixtureAttribute(combinedArgs); Assert.That(attr.Arguments, Is.EqualTo(fixtureArgs)); Assert.That(attr.TypeArgs, Is.EqualTo(typeArgs)); } #endif } } NUnit-2.6.0.12051/src/NUnitFramework/tests/MessageChecker.cs0000664000175000017500000000315611652172542023235 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { /// /// MessageCheckingTest is an abstract base for tests /// that check for an expected message in the exception /// handler. /// public abstract class MessageChecker : AssertionHelper, IExpectException { protected string expectedMessage; protected MessageMatch matchType = MessageMatch.Exact; [SetUp] public void SetUp() { expectedMessage = null; } public void HandleException( Exception ex ) { if ( expectedMessage != null ) { switch(matchType) { default: case MessageMatch.Exact: Assert.AreEqual( expectedMessage, ex.Message ); break; case MessageMatch.Contains: Assert.That(ex.Message, Is.StringContaining(expectedMessage)); break; case MessageMatch.StartsWith: Assert.That(ex.Message, Is.StringStarting(expectedMessage)); break; case MessageMatch.Regex: Assert.That(ex.Message, Is.StringMatching(expectedMessage)); break; } } } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/ValuesAttributeTests.cs0000664000175000017500000001076711674407120024535 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; namespace NUnit.Framework.Tests { public class ValuesAttributeTests { [Test] public void ValuesAttributeProvidesSpecifiedValues() { CheckValues("MethodWithValues", 1, 2, 3); } private void MethodWithValues( [Values(1, 2, 3)] int x) { } [Test] public void CanConvertSmallIntsToShort([Values(5)]short x) { } [Test] public void CanConvertSmallIntsToByte([Values(5)]byte x) { } [Test] public void CanConvertSmallIntsToSByte([Values(5)]sbyte x) { } [Test] public void CanConvertIntToDecimal([Values(12)]decimal x) { } [Test] public void CanConverDoubleToDecimal([Values(12.5)]decimal x) { } [Test] public void CanConvertStringToDecimal([Values("12.5")]decimal x) { } [Test] public void RangeAttributeWithIntRange() { CheckValues("MethodWithIntRange", 11, 12, 13, 14, 15); } private void MethodWithIntRange([Range(11, 15)] int x) { } [Test] public void RangeAttributeWithIntRangeAndStep() { CheckValues("MethodWithIntRangeAndStep", 11, 13, 15); } private void MethodWithIntRangeAndStep([Range(11, 15, 2)] int x) { } [Test] public void RangeAttributeWithLongRangeAndStep() { CheckValues("MethodWithLongRangeAndStep", 11L, 13L, 15L); } private void MethodWithLongRangeAndStep([Range(11L, 15L, 2)] long x) { } [Test] public void RangeAttributeWithDoubleRangeAndStep() { CheckValuesWithinTolerance("MethodWithDoubleRangeAndStep", 0.7, 0.9, 1.1); } private void MethodWithDoubleRangeAndStep([Range(0.7, 1.2, 0.2)] double x) { } [Test] public void RangeAttributeWithFloatRangeAndStep() { CheckValuesWithinTolerance("MethodWithFloatRangeAndStep", 0.7f, 0.9f, 1.1f); } private void MethodWithFloatRangeAndStep([Range(0.7f, 1.2f, 0.2f)] float x) { } [Test] public void CanConvertIntRangeToShort([Range(1, 3)] short x) { } [Test] public void CanConvertIntRangeToByte([Range(1, 3)] byte x) { } [Test] public void CanConvertIntRangeToSByte([Range(1, 3)] sbyte x) { } [Test] public void CanConvertIntRangeToDecimal([Range(1, 3)] decimal x) { } [Test] public void CanConvertDoubleRangeToDecimal([Range(1.0, 1.3, 0.1)] decimal x) { } [Test] public void CanConvertRandomIntToShort([Random(1, 10, 3)] short x) { } [Test] public void CanConvertRandomIntToByte([Random(1, 10, 3)] byte x) { } [Test] public void CanConvertRandomIntToSByte([Random(1, 10, 3)] sbyte x) { } [Test] public void CanConvertRandomIntToDecimal([Random(1, 10, 3)] decimal x) { } [Test] public void CanConvertRandomDoubleToDecimal([Random(1.0, 10.0, 3)] decimal x) { } #region Helper Methods private void CheckValues(string methodName, params object[] expected) { MethodInfo method = GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); ParameterInfo param = method.GetParameters()[0]; ValuesAttribute attr = param.GetCustomAttributes(typeof(ValuesAttribute), false)[0] as ValuesAttribute; Assert.That(attr.GetData(param), Is.EqualTo(expected)); } private void CheckValuesWithinTolerance(string methodName, params object[] expected) { MethodInfo method = GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); ParameterInfo param = method.GetParameters()[0]; ValuesAttribute attr = param.GetCustomAttributes(typeof(ValuesAttribute), false)[0] as ValuesAttribute; Assert.That(attr.GetData(param), Is.EqualTo(expected).Within(0.000001)); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/tests/GreaterFixture.cs0000664000175000017500000001100011504175260023303 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class GreaterFixture : MessageChecker { private readonly int i1 = 5; private readonly int i2 = 4; private readonly uint u1 = 12345879; private readonly uint u2 = 12345678; private readonly long l1 = 12345879; private readonly long l2 = 12345678; private readonly ulong ul1 = 12345879; private readonly ulong ul2 = 12345678; private readonly float f1 = 3.543F; private readonly float f2 = 2.543F; private readonly decimal de1 = 53.4M; private readonly decimal de2 = 33.4M; private readonly double d1 = 4.85948654; private readonly double d2 = 1.0; private readonly System.Enum e1 = System.Data.CommandType.TableDirect; private readonly System.Enum e2 = System.Data.CommandType.StoredProcedure; [Test] public void Greater() { Assert.Greater(i1,i2); Assert.Greater(u1,u2); Assert.Greater(l1,l2); Assert.Greater(ul1,ul2); Assert.Greater(d1,d2, "double"); Assert.Greater(de1,de2, "{0}", "decimal"); Assert.Greater(f1,f2, "float"); } [Test] public void MixedTypes() { Assert.Greater( 5, 3L, "int to long"); Assert.Greater( 5, 3.5f, "int to float" ); Assert.Greater( 5, 3.5d, "int to double" ); Assert.Greater( 5, 3U, "int to uint" ); Assert.Greater( 5, 3UL, "int to ulong" ); Assert.Greater( 5, 3M, "int to decimal" ); Assert.Greater( 5L, 3, "long to int"); Assert.Greater( 5L, 3.5f, "long to float" ); Assert.Greater( 5L, 3.5d, "long to double" ); Assert.Greater( 5L, 3U, "long to uint" ); Assert.Greater( 5L, 3UL, "long to ulong" ); Assert.Greater( 5L, 3M, "long to decimal" ); Assert.Greater( 8.2f, 5, "float to int" ); Assert.Greater( 8.2f, 8L, "float to long" ); Assert.Greater( 8.2f, 3.5d, "float to double" ); Assert.Greater( 8.2f, 8U, "float to uint" ); Assert.Greater( 8.2f, 8UL, "float to ulong" ); Assert.Greater( 8.2f, 3.5M, "float to decimal" ); Assert.Greater( 8.2d, 5, "double to int" ); Assert.Greater( 8.2d, 5L, "double to long" ); Assert.Greater( 8.2d, 3.5f, "double to float" ); Assert.Greater( 8.2d, 8U, "double to uint" ); Assert.Greater( 8.2d, 8UL, "double to ulong" ); Assert.Greater( 8.2d, 3.5M, "double to decimal" ); Assert.Greater( 5U, 3, "uint to int" ); Assert.Greater( 5U, 3L, "uint to long" ); Assert.Greater( 5U, 3.5f, "uint to float" ); Assert.Greater( 5U, 3.5d, "uint to double" ); Assert.Greater( 5U, 3UL, "uint to ulong" ); Assert.Greater( 5U, 3M, "uint to decimal" ); Assert.Greater( 5ul, 3, "ulong to int" ); Assert.Greater( 5UL, 3L, "ulong to long" ); Assert.Greater( 5UL, 3.5f, "ulong to float" ); Assert.Greater( 5UL, 3.5d, "ulong to double" ); Assert.Greater( 5UL, 3U, "ulong to uint" ); Assert.Greater( 5UL, 3M, "ulong to decimal" ); Assert.Greater( 5M, 3, "decimal to int" ); Assert.Greater( 5M, 3L, "decimal to long" ); Assert.Greater( 5M, 3.5f, "decimal to float" ); Assert.Greater( 5M, 3.5d, "decimal to double" ); Assert.Greater( 5M, 3U, "decimal to uint" ); Assert.Greater( 5M, 3UL, "decimal to ulong" ); } [Test, ExpectedException( typeof( AssertionException ))] public void NotGreaterWhenEqual() { expectedMessage = " Expected: greater than 5" + Environment.NewLine + " But was: 5" + Environment.NewLine; Assert.Greater(i1,i1); } [Test, ExpectedException( typeof( AssertionException ))] public void NotGreater() { expectedMessage = " Expected: greater than 5" + Environment.NewLine + " But was: 4" + Environment.NewLine; Assert.Greater(i2,i1); } [Test, ExpectedException( typeof( AssertionException ))] public void NotGreaterIComparable() { expectedMessage = " Expected: greater than TableDirect" + Environment.NewLine + " But was: StoredProcedure" + Environment.NewLine; Assert.Greater(e2,e1); } [Test,ExpectedException( typeof(AssertionException))] public void FailureMessage() { expectedMessage = " Expected: greater than 99" + Environment.NewLine + " But was: 7" + Environment.NewLine; Assert.Greater( 7, 99 ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/RandomizerTests.cs0000664000175000017500000000670111504175260023514 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; namespace NUnit.Framework.Tests { public class RandomizerTests { [Test] public void RandomSeedsAreUnique() { int[] seeds = new int[10]; for (int i = 0; i < 10; i++) seeds[i] = Randomizer.RandomSeed; Assert.That(seeds, Is.Unique); } [Test] public void RandomIntsAreUnique() { Randomizer r = new Randomizer(); int[] values = new int[10]; for (int i = 0; i < 10; i++) values[i] = r.Next(); Assert.That(values, Is.Unique); } [Test] public void RandomDoublesAreUnique() { Randomizer r = new Randomizer(); double[] values = new double[10]; for (int i = 0; i < 10; i++) values[i] = r.NextDouble(); Assert.That(values, Is.Unique); } [Test] public void RandomizersWithSameSeedsReturnSameValues() { Randomizer r1 = new Randomizer(1234); Randomizer r2 = new Randomizer(1234); for (int i = 0; i < 10; i++) Assert.That(r1.NextDouble(), Is.EqualTo(r2.NextDouble())); } [Test] public void RandomizersWithDifferentSeedsReturnDifferentValues() { Randomizer r1 = new Randomizer(1234); Randomizer r2 = new Randomizer(4321); for (int i = 0; i < 10; i++) Assert.That(r1.NextDouble(), Is.Not.EqualTo(r2.NextDouble())); } [Test] public void ReturnsSameRandomizerForSameParameter() { ParameterInfo p = testMethod.GetParameters()[0]; Randomizer r1 = Randomizer.GetRandomizer(p); Randomizer r2 = Randomizer.GetRandomizer(p); Assert.That(r1, Is.SameAs(r2)); } [Test] public void ReturnsSameRandomizerForDifferentParametersOfSameMethod() { ParameterInfo p1 = testMethod.GetParameters()[0]; ParameterInfo p2 = testMethod.GetParameters()[1]; Randomizer r1 = Randomizer.GetRandomizer(p1); Randomizer r2 = Randomizer.GetRandomizer(p2); Assert.That(r1, Is.SameAs(r2)); } [Test] public void ReturnsSameRandomizerForSameMethod() { Randomizer r1 = Randomizer.GetRandomizer(testMethod); Randomizer r2 = Randomizer.GetRandomizer(testMethod); Assert.That(r1, Is.SameAs(r2)); } [Test] public void ReturnsDifferentRandomizersForDifferentMethods() { Randomizer r1 = Randomizer.GetRandomizer(testMethod); Randomizer r2 = Randomizer.GetRandomizer(MethodInfo.GetCurrentMethod()); Assert.That(r1, Is.Not.SameAs(r2)); } static readonly MethodInfo testMethod = typeof(RandomizerTests).GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Instance); private void TestMethod(int x, int y) { } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/LessFixture.cs0000664000175000017500000001155111504175260022633 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class LessFixture : MessageChecker { private readonly int i1 = 5; private readonly int i2 = 8; private readonly uint u1 = 12345678; private readonly uint u2 = 12345879; private readonly long l1 = 12345678; private readonly long l2 = 12345879; private readonly ulong ul1 = 12345678; private readonly ulong ul2 = 12345879; private readonly float f1 = 3.543F; private readonly float f2 = 8.543F; private readonly decimal de1 = 53.4M; private readonly decimal de2 = 83.4M; private readonly double d1 = 4.85948654; private readonly double d2 = 8.0; private readonly System.Enum e1 = System.Data.CommandType.StoredProcedure; private readonly System.Enum e2 = System.Data.CommandType.TableDirect; [Test] public void Less() { // Testing all forms after seeing some bugs. CFP Assert.Less(i1,i2); Assert.Less(i1,i2,"int"); Assert.Less(i1,i2,"{0}","int"); Assert.Less(u1,u2,"uint"); Assert.Less(u1,u2,"{0}","uint"); Assert.Less(l1,l2,"long"); Assert.Less(l1,l2,"{0}","long"); Assert.Less(ul1,ul2,"ulong"); Assert.Less(ul1,ul2,"{0}","ulong"); Assert.Less(d1,d2); Assert.Less(d1,d2, "double"); Assert.Less(d1,d2, "{0}", "double"); Assert.Less(de1,de2); Assert.Less(de1,de2, "decimal"); Assert.Less(de1,de2, "{0}", "decimal"); Assert.Less(f1,f2); Assert.Less(f1,f2, "float"); Assert.Less(f1,f2, "{0}", "float"); } [Test] public void MixedTypes() { Assert.Less( 5, 8L, "int to long"); Assert.Less( 5, 8.2f, "int to float" ); Assert.Less( 5, 8.2d, "int to double" ); Assert.Less( 5, 8U, "int to uint" ); Assert.Less( 5, 8UL, "int to ulong" ); Assert.Less( 5, 8M, "int to decimal" ); Assert.Less( 5L, 8, "long to int"); Assert.Less( 5L, 8.2f, "long to float" ); Assert.Less( 5L, 8.2d, "long to double" ); Assert.Less( 5L, 8U, "long to uint" ); Assert.Less( 5L, 8UL, "long to ulong" ); Assert.Less( 5L, 8M, "long to decimal" ); Assert.Less( 3.5f, 5, "float to int" ); Assert.Less( 3.5f, 8L, "float to long" ); Assert.Less( 3.5f, 8.2d, "float to double" ); Assert.Less( 3.5f, 8U, "float to uint" ); Assert.Less( 3.5f, 8UL, "float to ulong" ); Assert.Less( 3.5f, 8.2M, "float to decimal" ); Assert.Less( 3.5d, 5, "double to int" ); Assert.Less( 3.5d, 5L, "double to long" ); Assert.Less( 3.5d, 8.2f, "double to float" ); Assert.Less( 3.5d, 8U, "double to uint" ); Assert.Less( 3.5d, 8UL, "double to ulong" ); Assert.Less( 3.5d, 8.2M, "double to decimal" ); Assert.Less( 5U, 8, "uint to int" ); Assert.Less( 5U, 8L, "uint to long" ); Assert.Less( 5U, 8.2f, "uint to float" ); Assert.Less( 5U, 8.2d, "uint to double" ); Assert.Less( 5U, 8UL, "uint to ulong" ); Assert.Less( 5U, 8M, "uint to decimal" ); Assert.Less( 5ul, 8, "ulong to int" ); Assert.Less( 5UL, 8L, "ulong to long" ); Assert.Less( 5UL, 8.2f, "ulong to float" ); Assert.Less( 5UL, 8.2d, "ulong to double" ); Assert.Less( 5UL, 8U, "ulong to uint" ); Assert.Less( 5UL, 8M, "ulong to decimal" ); Assert.Less( 5M, 8, "decimal to int" ); Assert.Less( 5M, 8L, "decimal to long" ); Assert.Less( 5M, 8.2f, "decimal to float" ); Assert.Less( 5M, 8.2d, "decimal to double" ); Assert.Less( 5M, 8U, "decimal to uint" ); Assert.Less( 5M, 8UL, "decimal to ulong" ); } [Test, ExpectedException( typeof( AssertionException ))] public void NotLessWhenEqual() { expectedMessage = " Expected: less than 5" + Environment.NewLine + " But was: 5" + Environment.NewLine; Assert.Less(i1,i1); } [Test, ExpectedException( typeof( AssertionException ))] public void NotLess() { expectedMessage = " Expected: less than 5" + Environment.NewLine + " But was: 8" + Environment.NewLine; Assert.Less(i2,i1); } [Test, ExpectedException( typeof( AssertionException ))] public void NotLessIComparable() { expectedMessage = " Expected: less than StoredProcedure" + Environment.NewLine + " But was: TableDirect" + Environment.NewLine; Assert.Less(e2,e1); } [Test] public void FailureMessage() { string msg = null; try { Assert.Less( 9, 4 ); } catch( AssertionException ex ) { msg = ex.Message; } StringAssert.Contains( TextMessageWriter.Pfx_Expected + "less than 4", msg ); StringAssert.Contains( TextMessageWriter.Pfx_Actual + "9", msg ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/LessEqualFixture.cs0000664000175000017500000001462211504175260023625 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class LessEqualFixture : MessageChecker { private readonly int i1 = 5; private readonly int i2 = 8; private readonly uint u1 = 12345678; private readonly uint u2 = 12345879; private readonly long l1 = 12345678; private readonly long l2 = 12345879; private readonly ulong ul1 = 12345678; private readonly ulong ul2 = 12345879; private readonly float f1 = 3.543F; private readonly float f2 = 8.543F; private readonly decimal de1 = 53.4M; private readonly decimal de2 = 83.4M; private readonly double d1 = 4.85948654; private readonly double d2 = 8.0; private readonly System.Enum e1 = System.Data.CommandType.StoredProcedure; private readonly System.Enum e2 = System.Data.CommandType.TableDirect; [Test] public void LessOrEqual() { // Test equality check for all forms Assert.LessOrEqual(i1, i1); Assert.LessOrEqual(i1, i1, "int"); Assert.LessOrEqual(i1, i1, "{0}", "int"); Assert.LessOrEqual(u1, u1); Assert.LessOrEqual(u1, u1, "uint"); Assert.LessOrEqual(u1, u1, "{0}", "uint"); Assert.LessOrEqual(l1, l1); Assert.LessOrEqual(l1, l1, "long"); Assert.LessOrEqual(l1, l1, "{0}", "long"); Assert.LessOrEqual(ul1, ul1); Assert.LessOrEqual(ul1, ul1, "ulong"); Assert.LessOrEqual(ul1, ul1, "{0}", "ulong"); Assert.LessOrEqual(d1, d1); Assert.LessOrEqual(d1, d1, "double"); Assert.LessOrEqual(d1, d1, "{0}", "double"); Assert.LessOrEqual(de1, de1); Assert.LessOrEqual(de1, de1, "decimal"); Assert.LessOrEqual(de1, de1, "{0}", "decimal"); Assert.LessOrEqual(f1, f1); Assert.LessOrEqual(f1, f1, "float"); Assert.LessOrEqual(f1, f1, "{0}", "float"); // Testing all forms after seeing some bugs. CFP Assert.LessOrEqual(i1, i2); Assert.LessOrEqual(i1, i2, "int"); Assert.LessOrEqual(i1, i2, "{0}", "int"); Assert.LessOrEqual(u1, u2); Assert.LessOrEqual(u1, u2, "uint"); Assert.LessOrEqual(u1, u2, "{0}", "uint"); Assert.LessOrEqual(l1, l2); Assert.LessOrEqual(l1, l2, "long"); Assert.LessOrEqual(l1, l2, "{0}", "long"); Assert.LessOrEqual(ul1, ul2); Assert.LessOrEqual(ul1, ul2, "ulong"); Assert.LessOrEqual(ul1, ul2, "{0}", "ulong"); Assert.LessOrEqual(d1, d2); Assert.LessOrEqual(d1, d2, "double"); Assert.LessOrEqual(d1, d2, "{0}", "double"); Assert.LessOrEqual(de1, de2); Assert.LessOrEqual(de1, de2, "decimal"); Assert.LessOrEqual(de1, de2, "{0}", "decimal"); Assert.LessOrEqual(f1, f2); Assert.LessOrEqual(f1, f2, "float"); Assert.LessOrEqual(f1, f2, "{0}", "float"); } [Test] public void MixedTypes() { Assert.LessOrEqual( 5, 8L, "int to long"); Assert.LessOrEqual( 5, 8.2f, "int to float" ); Assert.LessOrEqual( 5, 8.2d, "int to double" ); Assert.LessOrEqual( 5, 8U, "int to uint" ); Assert.LessOrEqual( 5, 8UL, "int to ulong" ); Assert.LessOrEqual( 5, 8M, "int to decimal" ); Assert.LessOrEqual( 5L, 8, "long to int"); Assert.LessOrEqual( 5L, 8.2f, "long to float" ); Assert.LessOrEqual( 5L, 8.2d, "long to double" ); Assert.LessOrEqual( 5L, 8U, "long to uint" ); Assert.LessOrEqual( 5L, 8UL, "long to ulong" ); Assert.LessOrEqual( 5L, 8M, "long to decimal" ); Assert.LessOrEqual( 3.5f, 5, "float to int" ); Assert.LessOrEqual( 3.5f, 8L, "float to long" ); Assert.LessOrEqual( 3.5f, 8.2d, "float to double" ); Assert.LessOrEqual( 3.5f, 8U, "float to uint" ); Assert.LessOrEqual( 3.5f, 8UL, "float to ulong" ); Assert.LessOrEqual( 3.5f, 8.2M, "float to decimal" ); Assert.LessOrEqual( 3.5d, 5, "double to int" ); Assert.LessOrEqual( 3.5d, 5L, "double to long" ); Assert.LessOrEqual( 3.5d, 8.2f, "double to float" ); Assert.LessOrEqual( 3.5d, 8U, "double to uint" ); Assert.LessOrEqual( 3.5d, 8UL, "double to ulong" ); Assert.LessOrEqual( 3.5d, 8.2M, "double to decimal" ); Assert.LessOrEqual( 5U, 8, "uint to int" ); Assert.LessOrEqual( 5U, 8L, "uint to long" ); Assert.LessOrEqual( 5U, 8.2f, "uint to float" ); Assert.LessOrEqual( 5U, 8.2d, "uint to double" ); Assert.LessOrEqual( 5U, 8UL, "uint to ulong" ); Assert.LessOrEqual( 5U, 8M, "uint to decimal" ); Assert.LessOrEqual( 5ul, 8, "ulong to int" ); Assert.LessOrEqual( 5UL, 8L, "ulong to long" ); Assert.LessOrEqual( 5UL, 8.2f, "ulong to float" ); Assert.LessOrEqual( 5UL, 8.2d, "ulong to double" ); Assert.LessOrEqual( 5UL, 8U, "ulong to uint" ); Assert.LessOrEqual( 5UL, 8M, "ulong to decimal" ); Assert.LessOrEqual( 5M, 8, "decimal to int" ); Assert.LessOrEqual( 5M, 8L, "decimal to long" ); Assert.LessOrEqual( 5M, 8.2f, "decimal to float" ); Assert.LessOrEqual( 5M, 8.2d, "decimal to double" ); Assert.LessOrEqual( 5M, 8U, "decimal to uint" ); Assert.LessOrEqual( 5M, 8UL, "decimal to ulong" ); } [Test, ExpectedException(typeof(AssertionException))] public void NotLessOrEqual() { expectedMessage = " Expected: less than or equal to 5" + Environment.NewLine + " But was: 8" + Environment.NewLine; Assert.LessOrEqual(i2, i1); } [Test, ExpectedException(typeof(AssertionException))] public void NotLessEqualIComparable() { expectedMessage = " Expected: less than or equal to StoredProcedure" + Environment.NewLine + " But was: TableDirect" + Environment.NewLine; Assert.LessOrEqual(e2, e1); } [Test,ExpectedException(typeof(AssertionException))] public void FailureMessage() { expectedMessage = " Expected: less than or equal to 4" + Environment.NewLine + " But was: 9" + Environment.NewLine; Assert.LessOrEqual(9, 4); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/TypeAssertTest.cs0000664000175000017500000000705311571405166023330 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; //using NUnit.Framework.Syntax; namespace NUnit.Framework.Tests { [TestFixture()] public class TypeAssertTests : MessageChecker { [Test] public void ExactType() { Expect( "Hello", TypeOf( typeof(System.String) ) ); } [Test,ExpectedException(typeof(AssertionException))] public void ExactTypeFails() { expectedMessage = " Expected: " + Environment.NewLine + " But was: " + Environment.NewLine; Expect( "Hello", TypeOf( typeof(System.Int32) ) ); } [Test] public void IsInstanceOf() { ApplicationException ex = new ApplicationException(); Assert.IsInstanceOf(typeof(System.Exception), ex ); Expect( ex, InstanceOf(typeof(Exception))); #if CLR_2_0 || CLR_4_0 Assert.IsInstanceOf( ex ); #endif } [Test,ExpectedException(typeof(AssertionException))] public void IsInstanceOfFails() { expectedMessage = " Expected: instance of " + System.Environment.NewLine + " But was: " + System.Environment.NewLine; Expect( "abc123", InstanceOf( typeof(System.Int32) ) ); } [Test] public void IsNotInstanceOf() { Assert.IsNotInstanceOf(typeof(System.Int32), "abc123" ); Expect( "abc123", Not.InstanceOf(typeof(System.Int32)) ); #if CLR_2_0 || CLR_4_0 Assert.IsNotInstanceOf("abc123"); #endif } [Test,ExpectedException(typeof(AssertionException))] public void IsNotInstanceOfFails() { expectedMessage = " Expected: not instance of " + System.Environment.NewLine + " But was: " + System.Environment.NewLine; Assert.IsNotInstanceOf( typeof(System.Exception), new ApplicationException() ); } [Test()] public void IsAssignableFrom() { int[] array10 = new int[10]; Assert.IsAssignableFrom(typeof(int[]), array10); Expect(array10, AssignableFrom(typeof(int[]))); #if CLR_2_0 || CLR_4_0 Assert.IsAssignableFrom(array10); #endif } [Test, ExpectedException(typeof(AssertionException))] public void IsAssignableFromFails() { int [] array10 = new int [10]; int [,] array2 = new int[2,2]; expectedMessage = " Expected: assignable from " + System.Environment.NewLine + " But was: " + System.Environment.NewLine; Expect( array10, AssignableFrom( array2.GetType() ) ); } [Test()] public void IsNotAssignableFrom() { int [] array10 = new int [10]; Assert.IsNotAssignableFrom( typeof(int[,] ),array10); Expect( array10, Not.AssignableFrom( typeof(int[,] ) ) ); #if CLR_2_0 || CLR_4_0 Assert.IsNotAssignableFrom(array10); #endif } [Test,ExpectedException(typeof(AssertionException))] public void IsNotAssignableFromFails() { int [] array10 = new int [10]; int [] array2 = new int[2]; expectedMessage = " Expected: not assignable from " + System.Environment.NewLine + " But was: " + System.Environment.NewLine; Expect( array10, Not.AssignableFrom( array2.GetType() ) ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/AssertThrowsTests.cs0000664000175000017500000001654511661717002024061 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; //using NUnit.Framework.Constraints; namespace NUnit.Framework.Tests { [TestFixture] public class AssertThrowsTests : MessageChecker { [Test] public void CanCatchUnspecifiedException() { Exception ex = Assert.Catch(new TestDelegate(TestDelegates.ThrowsArgumentException)); Assert.That(ex, Is.TypeOf(typeof(ArgumentException))); #if CLR_2_0 || CLR_4_0 ex = Assert.Catch(TestDelegates.ThrowsArgumentException); Assert.That(ex, Is.TypeOf(typeof(ArgumentException))); #endif } [Test] public void CanCatchExceptionOfExactType() { Exception ex = Assert.Catch(typeof(ArgumentException), new TestDelegate(TestDelegates.ThrowsArgumentException)); Assert.That(ex, Is.TypeOf(typeof(ArgumentException))); #if CLR_2_0 || CLR_4_0 ex = Assert.Catch(new TestDelegate(TestDelegates.ThrowsArgumentException)); Assert.That(ex, Is.TypeOf(typeof(ArgumentException))); #endif } [Test] public void CanCatchExceptionOfDerivedType() { Exception ex = Assert.Catch(typeof(ApplicationException), new TestDelegate(TestDelegates.ThrowsDerivedApplicationException)); Assert.That(ex, Is.TypeOf(typeof(TestDelegates.DerivedApplicationException))); #if CLR_2_0 || CLR_4_0 ex = Assert.Catch(TestDelegates.ThrowsDerivedApplicationException); Assert.That(ex, Is.TypeOf(typeof(TestDelegates.DerivedApplicationException))); #endif } [Test] public void CorrectExceptionThrown() { #if CLR_2_0 || CLR_4_0 Assert.Throws(typeof(ArgumentException), TestDelegates.ThrowsArgumentException); Assert.Throws(typeof(ArgumentException), delegate { throw new ArgumentException(); }); Assert.Throws( delegate { throw new ArgumentException(); }); Assert.Throws(TestDelegates.ThrowsArgumentException); // Without cast, delegate is ambiguous before C# 3.0. Assert.That((TestDelegate)delegate { throw new ArgumentException(); }, Throws.Exception.TypeOf() ); //Assert.Throws( Is.TypeOf(typeof(ArgumentException)), // delegate { throw new ArgumentException(); } ); #else Assert.Throws(typeof(ArgumentException), new TestDelegate( TestDelegates.ThrowsArgumentException ) ); #endif } [Test] public void CorrectExceptionIsReturnedToMethod() { ArgumentException ex = Assert.Throws(typeof(ArgumentException), new TestDelegate(TestDelegates.ThrowsArgumentException)) as ArgumentException; Assert.IsNotNull(ex, "No ArgumentException thrown"); Assert.That(ex.Message, StartsWith("myMessage")); Assert.That(ex.ParamName, Is.EqualTo("myParam")); #if CLR_2_0 || CLR_4_0 ex = Assert.Throws( delegate { throw new ArgumentException("myMessage", "myParam"); }) as ArgumentException; Assert.IsNotNull(ex, "No ArgumentException thrown"); Assert.That(ex.Message, StartsWith("myMessage")); Assert.That(ex.ParamName, Is.EqualTo("myParam")); ex = Assert.Throws(typeof(ArgumentException), delegate { throw new ArgumentException("myMessage", "myParam"); } ) as ArgumentException; Assert.IsNotNull(ex, "No ArgumentException thrown"); Assert.That(ex.Message, StartsWith("myMessage")); Assert.That(ex.ParamName, Is.EqualTo("myParam")); ex = Assert.Throws(TestDelegates.ThrowsArgumentException) as ArgumentException; Assert.IsNotNull(ex, "No ArgumentException thrown"); Assert.That(ex.Message, StartsWith("myMessage")); Assert.That(ex.ParamName, Is.EqualTo("myParam")); #endif } [Test, ExpectedException(typeof(AssertionException))] public void NoExceptionThrown() { expectedMessage = " Expected: " + Environment.NewLine + " But was: null" + Environment.NewLine; #if CLR_2_0 || CLR_4_0 Assert.Throws(TestDelegates.ThrowsNothing); #else Assert.Throws( typeof(ArgumentException), new TestDelegate( TestDelegates.ThrowsNothing ) ); #endif } [Test, ExpectedException(typeof(AssertionException))] public void UnrelatedExceptionThrown() { expectedMessage = " Expected: " + Environment.NewLine + " But was: (my message)" + Environment.NewLine; matchType = MessageMatch.StartsWith; #if CLR_2_0 || CLR_4_0 Assert.Throws(TestDelegates.ThrowsApplicationException); #else Assert.Throws( typeof(ArgumentException), new TestDelegate(TestDelegates.ThrowsApplicationException) ); #endif } [Test, ExpectedException(typeof(AssertionException))] public void BaseExceptionThrown() { expectedMessage = " Expected: " + Environment.NewLine + " But was: (my message)" + Environment.NewLine; matchType = MessageMatch.StartsWith; #if CLR_2_0 || CLR_4_0 Assert.Throws(TestDelegates.ThrowsSystemException); #else Assert.Throws( typeof(ArgumentException), new TestDelegate( TestDelegates.ThrowsSystemException) ); #endif } [Test,ExpectedException(typeof(AssertionException))] public void DerivedExceptionThrown() { expectedMessage = " Expected: " + Environment.NewLine + " But was: (myMessage" + Environment.NewLine + "Parameter name: myParam)" + Environment.NewLine; matchType = MessageMatch.StartsWith; #if CLR_2_0 || CLR_4_0 Assert.Throws(TestDelegates.ThrowsArgumentException); #else Assert.Throws( typeof(Exception), new TestDelegate( TestDelegates.ThrowsArgumentException) ); #endif } [Test] public void DoesNotThrowSuceeds() { #if CLR_2_0 || CLR_4_0 Assert.DoesNotThrow(TestDelegates.ThrowsNothing); #else Assert.DoesNotThrow( new TestDelegate( TestDelegates.ThrowsNothing ) ); Assert.That( new TestDelegate( TestDelegates.ThrowsNothing ), Throws.Nothing ); #endif } [Test, ExpectedException(typeof(AssertionException))] public void DoesNotThrowFails() { #if CLR_2_0 || CLR_4_0 Assert.DoesNotThrow(TestDelegates.ThrowsArgumentException); #else Assert.DoesNotThrow( new TestDelegate( TestDelegates.ThrowsArgumentException ) ); #endif } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/CollectionAdapter.cs0000664000175000017500000000241211504175260023746 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Tests { /// /// ICollectionAdapter is used in testing to wrap an array or /// ArrayList, ensuring that only methods of the ICollection /// interface are accessible. /// class ICollectionAdapter : ICollection { private readonly ICollection inner; public ICollectionAdapter(ICollection inner) { this.inner = inner; } public ICollectionAdapter(params object[] inner) { this.inner = inner; } #region ICollection Members public void CopyTo(Array array, int index) { inner.CopyTo(array, index); } public int Count { get { return inner.Count; } } public bool IsSynchronized { get { return inner.IsSynchronized; } } public object SyncRoot { get { return inner.SyncRoot; } } #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { return inner.GetEnumerator(); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/tests/SameFixture.cs0000664000175000017500000000231311504175260022606 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Text; using NUnit.Framework; namespace NUnit.Framework.Tests { [TestFixture] public class SameFixture : MessageChecker { [Test] public void Same() { string s1 = "S1"; Assert.AreSame(s1, s1); } [Test,ExpectedException(typeof(AssertionException))] public void SameFails() { Exception ex1 = new Exception( "one" ); Exception ex2 = new Exception( "two" ); expectedMessage = " Expected: same as " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.AreSame(ex1, ex2); } [Test,ExpectedException(typeof(AssertionException))] public void SameValueTypes() { int index = 2; expectedMessage = " Expected: same as 2" + Environment.NewLine + " But was: 2" + Environment.NewLine; Assert.AreSame(index, index); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/EqualsFixture.cs0000664000175000017500000003452311651227046023166 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Text.RegularExpressions; using System.Globalization; using System.IO; using System.Threading; namespace NUnit.Framework.Tests { [TestFixture] public class EqualsFixture : MessageChecker { [Test] public void Equals() { string nunitString = "Hello NUnit"; string expected = nunitString; string actual = nunitString; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual); } [Test] public void EqualsNull() { Assert.AreEqual(null, null); } [Test] public void Bug575936Int32Int64Comparison() { long l64 = 0; int i32 = 0; Assert.AreEqual(i32, l64); } [Test] public void IntegerLongComparison() { Assert.AreEqual(1, 1L); Assert.AreEqual(1L, 1); } [Test] public void IntegerEquals() { int val = 42; Assert.AreEqual(val, 42); } [Test,ExpectedException(typeof(AssertionException))] public void EqualsFail() { string junitString = "Goodbye JUnit"; string expected = "Hello NUnit"; expectedMessage = " Expected string length 11 but was 13. Strings differ at index 0." + Environment.NewLine + " Expected: \"Hello NUnit\"" + Environment.NewLine + " But was: \"Goodbye JUnit\"" + Environment.NewLine + " -----------^" + Environment.NewLine; Assert.AreEqual(expected, junitString); } [Test,ExpectedException(typeof(AssertionException))] public void EqualsNaNFails() { expectedMessage = " Expected: 1.234d +/- 0.0d" + Environment.NewLine + " But was: NaN" + Environment.NewLine; Assert.AreEqual(1.234, Double.NaN, 0.0); } [Test] [ExpectedException(typeof(AssertionException))] public void NanEqualsFails() { expectedMessage = " Expected: NaN" + Environment.NewLine + " But was: 1.234d" + Environment.NewLine; Assert.AreEqual(Double.NaN, 1.234, 0.0); } [Test] public void NanEqualsNaNSucceeds() { Assert.AreEqual(Double.NaN, Double.NaN, 0.0); } [Test] public void NegInfinityEqualsInfinity() { Assert.AreEqual(Double.NegativeInfinity, Double.NegativeInfinity, 0.0); } [Test] public void PosInfinityEqualsInfinity() { Assert.AreEqual(Double.PositiveInfinity, Double.PositiveInfinity, 0.0); } [Test,ExpectedException(typeof(AssertionException))] public void PosInfinityNotEquals() { expectedMessage = " Expected: Infinity" + Environment.NewLine + " But was: 1.23d" + Environment.NewLine; Assert.AreEqual(Double.PositiveInfinity, 1.23, 0.0); } [Test,ExpectedException(typeof(AssertionException))] public void PosInfinityNotEqualsNegInfinity() { expectedMessage = " Expected: Infinity" + Environment.NewLine + " But was: -Infinity" + Environment.NewLine; Assert.AreEqual(Double.PositiveInfinity, Double.NegativeInfinity, 0.0); } [Test,ExpectedException(typeof(AssertionException))] public void SinglePosInfinityNotEqualsNegInfinity() { expectedMessage = " Expected: Infinity" + Environment.NewLine + " But was: -Infinity" + Environment.NewLine; Assert.AreEqual(float.PositiveInfinity, float.NegativeInfinity, (float)0.0); } [Test,ExpectedException(typeof(AssertionException))] public void EqualsThrowsException() { object o = new object(); Assert.Equals(o, o); } [Test,ExpectedException(typeof(AssertionException))] public void ReferenceEqualsThrowsException() { object o = new object(); Assert.ReferenceEquals(o, o); } [Test] public void Float() { float val = (float)1.0; float expected = val; float actual = val; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual, (float)0.0); } [Test] public void Byte() { byte val = 1; byte expected = val; byte actual = val; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual); } [Test] public void String() { string s1 = "test"; string s2 = new System.Text.StringBuilder(s1).ToString(); Assert.IsTrue(s1.Equals(s2)); Assert.AreEqual(s1,s2); } [Test] public void Short() { short val = 1; short expected = val; short actual = val; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual); } [Test] public void Int() { int val = 1; int expected = val; int actual = val; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual); } [Test] public void UInt() { uint val = 1; uint expected = val; uint actual = val; Assert.IsTrue(expected == actual); Assert.AreEqual(expected, actual); } [Test] public void Decimal() { decimal expected = 100m; decimal actual = 100.0m; int integer = 100; Assert.IsTrue( expected == actual ); Assert.AreEqual(expected, actual); Assert.IsTrue(expected == integer); Assert.AreEqual(expected, integer); Assert.IsTrue(actual == integer); Assert.AreEqual(actual, integer); } /// /// Checks to see that a value comparison works with all types. /// Current version has problems when value is the same but the /// types are different...C# is not like Java, and doesn't automatically /// perform value type conversion to simplify this type of comparison. /// /// Related to Bug575936Int32Int64Comparison, but covers all numeric /// types. /// [Test] public void EqualsSameTypes() { byte b1 = 35; sbyte sb2 = 35; decimal d4 = 35; double d5 = 35; float f6 = 35; int i7 = 35; uint u8 = 35; long l9 = 35; short s10 = 35; ushort us11 = 35; System.Byte b12 = 35; System.SByte sb13 = 35; System.Decimal d14 = 35; System.Double d15 = 35; System.Single s16 = 35; System.Int32 i17 = 35; System.UInt32 ui18 = 35; System.Int64 i19 = 35; System.UInt64 ui20 = 35; System.Int16 i21 = 35; System.UInt16 i22 = 35; Assert.AreEqual(35, b1); Assert.AreEqual(35, sb2); Assert.AreEqual(35, d4); Assert.AreEqual(35, d5); Assert.AreEqual(35, f6); Assert.AreEqual(35, i7); Assert.AreEqual(35, u8); Assert.AreEqual(35, l9); Assert.AreEqual(35, s10); Assert.AreEqual(35, us11); Assert.AreEqual( 35, b12 ); Assert.AreEqual( 35, sb13 ); Assert.AreEqual( 35, d14 ); Assert.AreEqual( 35, d15 ); Assert.AreEqual( 35, s16 ); Assert.AreEqual( 35, i17 ); Assert.AreEqual( 35, ui18 ); Assert.AreEqual( 35, i19 ); Assert.AreEqual( 35, ui20 ); Assert.AreEqual( 35, i21 ); Assert.AreEqual( 35, i22 ); #if CLR_2_0 || CLR_4_0 byte? b23 = 35; sbyte? sb24 = 35; decimal? d25 = 35; double? d26 = 35; float? f27 = 35; int? i28 = 35; uint? u29 = 35; long? l30 = 35; short? s31 = 35; ushort? us32 = 35; Assert.AreEqual(35, b23); Assert.AreEqual(35, sb24); Assert.AreEqual(35, d25); Assert.AreEqual(35, d26); Assert.AreEqual(35, f27); Assert.AreEqual(35, i28); Assert.AreEqual(35, u29); Assert.AreEqual(35, l30); Assert.AreEqual(35, s31); Assert.AreEqual(35, us32); #endif } [Test] public void EnumsEqual() { MyEnum actual = MyEnum.a; Assert.AreEqual( MyEnum.a, actual ); } [Test, ExpectedException( typeof(AssertionException) )] public void EnumsNotEqual() { MyEnum actual = MyEnum.a; expectedMessage = " Expected: c" + Environment.NewLine + " But was: a" + Environment.NewLine; Assert.AreEqual( MyEnum.c, actual ); } [Test] public void DateTimeEqual() { DateTime dt1 = new DateTime( 2005, 6, 1, 7, 0, 0 ); DateTime dt2 = new DateTime( 2005, 6, 1, 0, 0, 0 ) + TimeSpan.FromHours( 7.0 ); Assert.AreEqual( dt1, dt2 ); } [Test, ExpectedException( typeof (AssertionException) )] public void DateTimeNotEqual() { DateTime dt1 = new DateTime( 2005, 6, 1, 7, 0, 0 ); DateTime dt2 = new DateTime( 2005, 6, 1, 0, 0, 0 ); expectedMessage = " Expected: 2005-06-01 07:00:00.000" + Environment.NewLine + " But was: 2005-06-01 00:00:00.000" + Environment.NewLine; Assert.AreEqual(dt1, dt2); } private enum MyEnum { a, b, c } [Test] public void DoubleNotEqualMessageDisplaysAllDigits() { string message = ""; try { double d1 = 36.1; double d2 = 36.099999999999994; Assert.AreEqual( d1, d2 ); } catch(AssertionException ex) { message = ex.Message; } if ( message == "" ) Assert.Fail( "Should have thrown an AssertionException" ); int i = message.IndexOf('3'); int j = message.IndexOf( 'd', i ); string expected = message.Substring( i, j - i + 1 ); i = message.IndexOf( '3', j ); j = message.IndexOf( 'd', i ); string actual = message.Substring( i , j - i + 1 ); Assert.AreNotEqual( expected, actual ); } [Test] public void FloatNotEqualMessageDisplaysAllDigits() { string message = ""; try { float f1 = 36.125F; float f2 = 36.125004F; Assert.AreEqual( f1, f2 ); } catch(AssertionException ex) { message = ex.Message; } if ( message == "" ) Assert.Fail( "Should have thrown an AssertionException" ); int i = message.IndexOf( '3' ); int j = message.IndexOf( 'f', i ); string expected = message.Substring( i, j - i + 1 ); i = message.IndexOf( '3', j ); j = message.IndexOf( 'f', i ); string actual = message.Substring( i, j - i + 1 ); Assert.AreNotEqual( expected, actual ); } [Test] public void DoubleNotEqualMessageDisplaysTolerance() { string message = ""; try { double d1 = 0.15; double d2 = 0.12; double tol = 0.005; Assert.AreEqual(d1, d2, tol); } catch (AssertionException ex) { message = ex.Message; } if (message == "") Assert.Fail("Should have thrown an AssertionException"); StringAssert.Contains("+/- 0.005", message); } [Test] public void FloatNotEqualMessageDisplaysTolerance() { string message = ""; try { float f1 = 0.15F; float f2 = 0.12F; float tol = 0.001F; Assert.AreEqual( f1, f2, tol ); } catch( AssertionException ex ) { message = ex.Message; } if ( message == "" ) Assert.Fail( "Should have thrown an AssertionException" ); StringAssert.Contains( "+/- 0.001", message ); } [Test] public void DoubleNotEqualMessageDisplaysDefaultTolerance() { string message = ""; GlobalSettings.DefaultFloatingPointTolerance = 0.005d; try { double d1 = 0.15; double d2 = 0.12; Assert.AreEqual(d1, d2); } catch (AssertionException ex) { message = ex.Message; } finally { GlobalSettings.DefaultFloatingPointTolerance = 0.0d; } if (message == "") Assert.Fail("Should have thrown an AssertionException"); StringAssert.Contains("+/- 0.005", message); } [Test] public void DoubleNotEqualWithNanDoesNotDisplayDefaultTolerance() { string message = ""; GlobalSettings.DefaultFloatingPointTolerance = 0.005d; try { double d1 = double.NaN; double d2 = 0.12; Assert.AreEqual(d1, d2); } catch (AssertionException ex) { message = ex.Message; } finally { GlobalSettings.DefaultFloatingPointTolerance = 0.0d; } if (message == "") Assert.Fail("Should have thrown an AssertionException"); Assert.That(message.IndexOf("+/-") == -1); } [Test] public void DirectoryInfoEquality() { string path = Environment.CurrentDirectory; DirectoryInfo dir1 = new DirectoryInfo(path); DirectoryInfo dir2 = new DirectoryInfo(path); Assert.AreEqual(dir1, dir2); } [Test] public void DirectoryInfoEqualityIgnoresTrailingDirectorySeparator() { string path1 = Environment.CurrentDirectory; string path2 = path1; int length = path1.Length; if (path1[length - 1] == Path.DirectorySeparatorChar) path1 = path1.Substring(0, length - 1); else path1 += Path.DirectorySeparatorChar; DirectoryInfo dir1 = new DirectoryInfo(path1); DirectoryInfo dir2 = new DirectoryInfo(path2); Assert.AreEqual(dir1, dir2); } #if CLR_2_0 || CLR_4_0 [Test] public void IEquatableSuccess_OldSyntax() { IntEquatable a = new IntEquatable(1); Assert.AreEqual(1, a); Assert.AreEqual(a, 1); } [Test] public void IEquatableSuccess_ConstraintSyntax() { IntEquatable a = new IntEquatable(1); Assert.That(a, Is.EqualTo(1)); Assert.That(1, Is.EqualTo(a)); } #endif } #if CLR_2_0 || CLR_4_0 public class IntEquatable : IEquatable { private int i; public IntEquatable(int i) { this.i = i; } public bool Equals(int other) { return i.Equals(other); } } #endif }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/0000775000175000017500000000000011742560362022340 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/TypeConstraintTests.cs0000664000175000017500000001127611672602470026706 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Constraints { [TestFixture] public class ExactTypeTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new ExactTypeConstraint(typeof(D1)); expectedDescription = string.Format("<{0}>", typeof(D1)); stringRepresentation = string.Format("", typeof(D1)); } internal object[] SuccessData = new object[] { new D1() }; internal object[] FailureData = new object[] { new B(), new D2() }; internal string[] ActualValues = new string[] { "", "" }; } [TestFixture] public class InstanceOfTypeTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new InstanceOfTypeConstraint(typeof(D1)); expectedDescription = string.Format("instance of <{0}>", typeof(D1)); stringRepresentation = string.Format("", typeof(D1)); } internal object[] SuccessData = new object[] { new D1(), new D2() }; internal object[] FailureData = new object[] { new B() }; internal string[] ActualValues = new string[] { "" }; } [TestFixture] public class AssignableFromTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new AssignableFromConstraint(typeof(D1)); expectedDescription = string.Format("assignable from <{0}>", typeof(D1)); stringRepresentation = string.Format("", typeof(D1)); } internal object[] SuccessData = new object[] { new D1(), new B() }; internal object[] FailureData = new object[] { new D2() }; internal string[] ActualValues = new string[] { "" }; } [TestFixture] public class AssignableToTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new AssignableToConstraint(typeof(D1)); expectedDescription = string.Format("assignable to <{0}>", typeof(D1)); stringRepresentation = string.Format("", typeof(D1)); } internal object[] SuccessData = new object[] { new D1(), new D2() }; internal object[] FailureData = new object[] { new B() }; internal string[] ActualValues = new string[] { "" }; } class B { } class D1 : B { } class D2 : D1 { } [TestFixture] public class AttributeExistsConstraintTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new AttributeExistsConstraint(typeof(TestFixtureAttribute)); expectedDescription = "type with attribute "; stringRepresentation = ""; } internal object[] SuccessData = new object[] { typeof(AttributeExistsConstraintTest) }; internal object[] FailureData = new object[] { typeof(D2) }; internal string[] ActualValues = new string[] { "" }; [Test, ExpectedException(typeof(System.ArgumentException))] public void NonAttributeThrowsException() { new AttributeExistsConstraint(typeof(string)); } [Test] public void AttributeExistsOnMethodInfo() { Assert.That( System.Reflection.MethodInfo.GetCurrentMethod(), new AttributeExistsConstraint(typeof(TestAttribute))); } [Test, Description("my description")] public void AttributeTestPropertyValueOnMethodInfo() { Assert.That( System.Reflection.MethodInfo.GetCurrentMethod(), Has.Attribute(typeof(DescriptionAttribute)).Property("Description").EqualTo("my description")); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/OrTest.cs0000664000175000017500000000202611567125234024107 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Constraints { [TestFixture] public class OrTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new OrConstraint(new EqualConstraint(42), new EqualConstraint(99)); expectedDescription = "42 or 99"; stringRepresentation = " >"; } internal object[] SuccessData = new object[] { 99, 42 }; internal object[] FailureData = new object[] { 37 }; internal string[] ActualValues = new string[] { "37" }; [Test] public void CanCombineTestsWithOrOperator() { Assert.That(99, new EqualConstraint(42) | new EqualConstraint(99) ); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/NotTest.cs0000664000175000017500000000357011567125206024273 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using NUnit.Framework.Constraints; namespace NUnit.Framework.Constraints { [TestFixture] public class NotTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new NotConstraint( new EqualConstraint(null) ); expectedDescription = "not null"; stringRepresentation = ">"; } internal object[] SuccessData = new object[] { 42, "Hello" }; internal object[] FailureData = new object [] { null }; internal string[] ActualValues = new string[] { "null" }; [Test, ExpectedException(typeof(AssertionException), ExpectedMessage = "ignoring case", MatchType = MessageMatch.Contains)] public void NotHonorsIgnoreCaseUsingConstructors() { Assert.That("abc", new NotConstraint(new EqualConstraint("ABC").IgnoreCase)); } [Test,ExpectedException(typeof(AssertionException),ExpectedMessage="ignoring case",MatchType=MessageMatch.Contains)] public void NotHonorsIgnoreCaseUsingPrefixNotation() { Assert.That( "abc", Is.Not.EqualTo( "ABC" ).IgnoreCase ); } [Test,ExpectedException(typeof(AssertionException),ExpectedMessage="+/-",MatchType=MessageMatch.Contains)] public void NotHonorsTolerance() { Assert.That( 4.99d, Is.Not.EqualTo( 5.0d ).Within( .05d ) ); } [Test] public void CanUseNotOperator() { Assert.That(42, !new EqualConstraint(99)); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/NumericsTest.cs0000664000175000017500000000612511504175260025313 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using NUnit.Framework.Constraints; namespace NUnit.Framework.Constraints { [TestFixture] public class NumericsTest { private Tolerance tenPercent, zeroTolerance; [SetUp] public void SetUp() { tenPercent = new Tolerance(10.0).Percent; zeroTolerance = new Tolerance(0); } [TestCase(123456789)] [TestCase(123456789U)] [TestCase(123456789L)] [TestCase(123456789UL)] [TestCase(1234.5678f)] [TestCase(1234.5678)] [Test] public void CanMatchWithoutToleranceMode(object value) { Assert.IsTrue(Numerics.AreEqual(value, value, ref zeroTolerance)); } // Separate test case because you can't use decimal in an attribute (24.1.3) [Test] public void CanMatchDecimalWithoutToleranceMode() { Assert.IsTrue(Numerics.AreEqual(123m, 123m, ref zeroTolerance)); } [TestCase((int)9500)] [TestCase((int)10000)] [TestCase((int)10500)] [TestCase((uint)9500)] [TestCase((uint)10000)] [TestCase((uint)10500)] [TestCase((long)9500)] [TestCase((long)10000)] [TestCase((long)10500)] [TestCase((ulong)9500)] [TestCase((ulong)10000)] [TestCase((ulong)10500)] [Test] public void CanMatchIntegralsWithPercentage(object value) { Assert.IsTrue(Numerics.AreEqual(10000, value, ref tenPercent)); } [Test] public void CanMatchDecimalWithPercentage() { Assert.IsTrue(Numerics.AreEqual(10000m, 9500m, ref tenPercent)); Assert.IsTrue(Numerics.AreEqual(10000m, 10000m, ref tenPercent)); Assert.IsTrue(Numerics.AreEqual(10000m, 10500m, ref tenPercent)); } [TestCase((int)8500)] [TestCase((int)11500)] [TestCase((uint)8500)] [TestCase((uint)11500)] [TestCase((long)8500)] [TestCase((long)11500)] [TestCase((ulong)8500)] [TestCase((ulong)11500)] [Test, ExpectedException(typeof(AssertionException))] public void FailsOnIntegralsOutsideOfPercentage(object value) { Assert.IsTrue(Numerics.AreEqual(10000, value, ref tenPercent)); } [Test, ExpectedException(typeof(AssertionException))] public void FailsOnDecimalBelowPercentage() { Assert.IsTrue(Numerics.AreEqual(10000m, 8500m, ref tenPercent)); } [Test, ExpectedException(typeof(AssertionException))] public void FailsOnDecimalAbovePercentage() { Assert.IsTrue(Numerics.AreEqual(10000m, 11500m, ref tenPercent)); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/SameAsTest.cs0000664000175000017500000000204211504175260024671 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Constraints { [TestFixture] public class SameAsTest : ConstraintTestBase { private static readonly object obj1 = new object(); private static readonly object obj2 = new object(); [SetUp] public void SetUp() { theConstraint = new SameAsConstraint(obj1); expectedDescription = "same as "; stringRepresentation = ""; } internal static object[] SuccessData = new object[] { obj1 }; internal static object[] FailureData = new object[] { obj2, 3, "Hello" }; internal static string[] ActualValues = new string[] { "", "3", "\"Hello\"" }; } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/EqualConstraintTests.cs0000664000175000017500000004144111672376366027045 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { [TestFixture] public class EqualConstraintTests : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new EqualConstraint(4); expectedDescription = "4"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 4, 4.0f, 4.0d, 4.0000m }; internal object[] FailureData = new object[] { 5, null, "Hello", double.NaN, double.PositiveInfinity }; internal string[] ActualValues = new string[] { "5", "null", "\"Hello\"", "NaN", "Infinity" }; [TestCase(double.NaN)] [TestCase(double.PositiveInfinity)] [TestCase(double.NegativeInfinity)] [TestCase(float.NaN)] [TestCase(float.PositiveInfinity)] [TestCase(float.NegativeInfinity)] public void CanMatchSpecialFloatingPointValues(object value) { Assert.That(value, new EqualConstraint(value)); } #region DateTime Tests [Test] public void CanMatchDates() { DateTime expected = new DateTime(2007, 4, 1); DateTime actual = new DateTime(2007, 4, 1); Assert.That(actual, new EqualConstraint(expected)); } [Test] public void CanMatchDatesWithinTimeSpan() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 13, 1, 0); TimeSpan tolerance = TimeSpan.FromMinutes(5.0); Assert.That(actual, new EqualConstraint(expected).Within(tolerance)); } [Test] public void CanMatchDatesWithinDays() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 4, 13, 0, 0); Assert.That(actual, new EqualConstraint(expected).Within(5).Days); } [Test] public void CanMatchDatesWithinHours() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 16, 0, 0); Assert.That(actual, new EqualConstraint(expected).Within(5).Hours); } [Test] public void CanMatchDatesWithinMinutes() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 13, 1, 0); Assert.That(actual, new EqualConstraint(expected).Within(5).Minutes); } [Test] public void CanMatchTimeSpanWithinMinutes() { TimeSpan expected = new TimeSpan(10, 0, 0); TimeSpan actual = new TimeSpan(10, 2, 30); Assert.That(actual, new EqualConstraint(expected).Within(5).Minutes); } [Test] public void CanMatchDatesWithinSeconds() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 13, 1, 0); Assert.That(actual, new EqualConstraint(expected).Within(300).Seconds); } [Test] public void CanMatchDatesWithinMilliseconds() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 13, 1, 0); Assert.That(actual, new EqualConstraint(expected).Within(300000).Milliseconds); } [Test] public void CanMatchDatesWithinTicks() { DateTime expected = new DateTime(2007, 4, 1, 13, 0, 0); DateTime actual = new DateTime(2007, 4, 1, 13, 1, 0); Assert.That(actual, new EqualConstraint(expected).Within(TimeSpan.TicksPerMinute * 5).Ticks); } #endregion #region Dictionary Tests // TODO: Move these to a separate fixture #if CS_3_0 || CS_4_0 [Test] public void CanMatchHashtables_SameOrder() { Assert.AreEqual(new Hashtable { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Hashtable { { 0, 0 }, { 1, 1 }, { 2, 2 } }); } [Test, ExpectedException(typeof(AssertionException))] public void CanMatchHashtables_Failure() { Assert.AreEqual(new Hashtable { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Hashtable { { 0, 0 }, { 1, 5 }, { 2, 2 } }); } [Test] public void CanMatchHashtables_DifferentOrder() { Assert.AreEqual(new Hashtable { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Hashtable { { 0, 0 }, { 2, 2 }, { 1, 1 } }); } #if CLR_2_0 || CLR_4_0 [Test] public void CanMatchDictionaries_SameOrder() { Assert.AreEqual(new Dictionary { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Dictionary { { 0, 0 }, { 1, 1 }, { 2, 2 } }); } [Test, ExpectedException(typeof(AssertionException))] public void CanMatchDictionaries_Failure() { Assert.AreEqual(new Dictionary { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Dictionary { { 0, 0 }, { 1, 5 }, { 2, 2 } }); } [Test] public void CanMatchDictionaries_DifferentOrder() { Assert.AreEqual(new Dictionary { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Dictionary { { 0, 0 }, { 2, 2 }, { 1, 1 } }); } [Test] public void CanMatchHashtableWithDictionary() { Assert.AreEqual(new Hashtable { { 0, 0 }, { 1, 1 }, { 2, 2 } }, new Dictionary { { 0, 0 }, { 2, 2 }, { 1, 1 } }); } #endif #endif #endregion [TestCase(20000000000000004.0)] [TestCase(19999999999999996.0)] public void CanMatchDoublesWithUlpTolerance(object value) { Assert.That(value, new EqualConstraint(20000000000000000.0).Within(1).Ulps); } [ExpectedException(typeof(AssertionException), ExpectedMessage = "+/- 1 Ulps", MatchType = MessageMatch.Contains)] [TestCase(20000000000000008.0)] [TestCase(19999999999999992.0)] public void FailsOnDoublesOutsideOfUlpTolerance(object value) { Assert.That(value, new EqualConstraint(20000000000000000.0).Within(1).Ulps); } [TestCase(19999998.0f)] [TestCase(20000002.0f)] public void CanMatchSinglesWithUlpTolerance(object value) { Assert.That(value, new EqualConstraint(20000000.0f).Within(1).Ulps); } [ExpectedException(typeof(AssertionException), ExpectedMessage = "+/- 1 Ulps", MatchType = MessageMatch.Contains)] [TestCase(19999996.0f)] [TestCase(20000004.0f)] public void FailsOnSinglesOutsideOfUlpTolerance(object value) { Assert.That(value, new EqualConstraint(20000000.0f).Within(1).Ulps); } [TestCase(9500.0)] [TestCase(10000.0)] [TestCase(10500.0)] public void CanMatchDoublesWithRelativeTolerance(object value) { Assert.That(value, new EqualConstraint(10000.0).Within(10.0).Percent); } [ExpectedException(typeof(AssertionException), ExpectedMessage = "+/- 10.0d Percent", MatchType = MessageMatch.Contains)] [TestCase(8500.0)] [TestCase(11500.0)] public void FailsOnDoublesOutsideOfRelativeTolerance(object value) { Assert.That(value, new EqualConstraint(10000.0).Within(10.0).Percent); } [TestCase(9500.0f)] [TestCase(10000.0f)] [TestCase(10500.0f)] public void CanMatchSinglesWithRelativeTolerance(object value) { Assert.That(value, new EqualConstraint(10000.0f).Within(10.0f).Percent); } [ExpectedException(typeof(AssertionException), ExpectedMessage = "+/- 10.0f Percent", MatchType = MessageMatch.Contains)] [TestCase(8500.0f)] [TestCase(11500.0f)] public void FailsOnSinglesOutsideOfRelativeTolerance(object value) { Assert.That(value, new EqualConstraint(10000.0f).Within(10.0f).Percent); } /// Applies both the Percent and Ulps modifiers to cause an exception [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorWithPercentAndUlpsToleranceModes() { Assert.That(100.0f, new EqualConstraint(100.0f).Within(10.0f).Percent.Ulps); } /// Applies both the Ulps and Percent modifiers to cause an exception [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorWithUlpsAndPercentToleranceModes() { Assert.That(100.0f, new EqualConstraint(100.0f).Within(10.0f).Ulps.Percent); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfPercentPrecedesWithin() { Assert.That(1010, Is.EqualTo(1000).Percent.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfUlpsPrecedesWithin() { Assert.That(1010.0, Is.EqualTo(1000.0).Ulps.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfDaysPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Days.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfHoursPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Hours.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfMinutesPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Minutes.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfSecondsPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Seconds.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfMillisecondsPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Milliseconds.Within(5)); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfTicksPrecedesWithin() { Assert.That(DateTime.Now, Is.EqualTo(DateTime.Now).Ticks.Within(5)); } [ExpectedException(typeof(InvalidOperationException))] [TestCase(1000, 1010)] [TestCase(1000U, 1010U)] [TestCase(1000L, 1010L)] [TestCase(1000UL, 1010UL)] public void ErrorIfUlpsIsUsedOnIntegralType(object x, object y) { Assert.That(y, Is.EqualTo(x).Within(2).Ulps); } [Test, ExpectedException(typeof(InvalidOperationException))] public void ErrorIfUlpsIsUsedOnDecimal() { Assert.That(100m, Is.EqualTo(100m).Within(2).Ulps); } [Test] public void UsesProvidedIComparer() { MyComparer comparer = new MyComparer(); Assert.That(2 + 2, Is.EqualTo(4).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(object x, object y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CLR_2_0 || CLR_4_0 [Test] public void UsesProvidedEqualityComparer() { MyEqualityComparer comparer = new MyEqualityComparer(); Assert.That(2 + 2, Is.EqualTo(4).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyEqualityComparer : IEqualityComparer { public bool Called; bool IEqualityComparer.Equals(object x, object y) { Called = true; return Comparer.Default.Compare(x, y) == 0; } int IEqualityComparer.GetHashCode(object x) { return x.GetHashCode(); } } [Test] public void UsesProvidedEqualityComparerOfT() { MyEqualityComparerOfT comparer = new MyEqualityComparerOfT(); Assert.That(2 + 2, Is.EqualTo(4).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyEqualityComparerOfT : IEqualityComparer { public bool Called; bool IEqualityComparer.Equals(T x, T y) { Called = true; return Comparer.Default.Compare(x, y) == 0; } int IEqualityComparer.GetHashCode(T x) { return x.GetHashCode(); } } [Test] public void UsesProvidedComparerOfT() { MyComparer comparer = new MyComparer(); Assert.That(2 + 2, Is.EqualTo(4).Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } [Test] public void UsesProvidedComparisonOfT() { MyComparison comparer = new MyComparison(); Assert.That(2 + 2, Is.EqualTo(4).Using(new Comparison(comparer.Compare))); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparison { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CS_3_0 || CS_4_0 [Test] public void UsesProvidedLambda_IntArgs() { Assert.That(2 + 2, Is.EqualTo(4).Using((x, y) => x.CompareTo(y))); } [Test] public void UsesProvidedLambda_StringArgs() { Assert.That("hello", Is.EqualTo("HELLO").Using((x, y) => String.Compare(x, y, true))); } [Test] public void UsesProvidedListComparer() { var list1 = new List() { 2, 3 }; var list2 = new List() { 3, 4 }; var list11 = new List>() { list1 }; var list22 = new List>() { list2 }; var comparer = new IntListEqualComparer(); Assert.That(list11, new CollectionEquivalentConstraint(list22).Using(comparer)); } public class IntListEqualComparer : IEqualityComparer> { public bool Equals(List x, List y) { return x.Count == y.Count; } public int GetHashCode(List obj) { return obj.Count.GetHashCode(); } } [Test] public void UsesProvidedArrayComparer() { var array1 = new int[] { 2, 3 }; var array2 = new int[] { 3, 4 }; var list11 = new List() { array1 }; var list22 = new List() { array2 }; var comparer = new IntArrayEqualComparer(); Assert.That(list11, new CollectionEquivalentConstraint(list22).Using(comparer)); } public class IntArrayEqualComparer : IEqualityComparer { public bool Equals(int[] x, int[] y) { return x.Length == y.Length; } public int GetHashCode(int[] obj) { return obj.Length.GetHashCode(); } } #endif #endif } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/AfterConstraintTests.cs0000664000175000017500000001456011665771214027032 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; namespace NUnit.Framework.Constraints { [TestFixture] public class AfterConstraintTest : ConstraintTestBase { private static bool value; //public AfterConstraintTest(int x) { } [SetUp] public void SetUp() { theConstraint = new DelayedConstraint(new EqualConstraint(true), 500); expectedDescription = "True after 500 millisecond delay"; stringRepresentation = ">"; value = false; //SetValueTrueAfterDelay(300); } internal object[] SuccessData = new object[] { true }; internal object[] FailureData = new object[] { false, 0, null }; internal string[] ActualValues = new string[] { "False", "0", "null" }; internal object[] InvalidData = new object[] { InvalidDelegate }; internal ActualValueDelegate[] SuccessDelegates = new ActualValueDelegate[] { DelegateReturningValue }; internal ActualValueDelegate[] FailureDelegates = new ActualValueDelegate[] { DelegateReturningFalse, DelegateReturningZero }; [Test, TestCaseSource("SuccessDelegates")] public void SucceedsWithGoodDelegates(ActualValueDelegate del) { SetValueTrueAfterDelay(300); Assert.That(theConstraint.Matches(del)); } [Test,TestCaseSource("FailureDelegates")] public void FailsWithBadDelegates(ActualValueDelegate del) { Assert.IsFalse(theConstraint.Matches(del)); } [Test] public void SimpleTest() { SetValueTrueAfterDelay(500); Assert.That(DelegateReturningValue, new DelayedConstraint(new EqualConstraint(true), 5000, 200)); } [Test] public void SimpleTestUsingReference() { SetValueTrueAfterDelay(500); Assert.That(ref value, new DelayedConstraint(new EqualConstraint(true), 5000, 200)); } [Test] public void ThatOverload_ZeroDelayIsAllowed() { Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), 0)); } [Test, ExpectedException(typeof(ArgumentException))] public void ThatOverload_DoesNotAcceptNegativeDelayValues() { Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), -1)); } #if CLR_2_0 || CLR_4_0 [Test] public void CanTestContentsOfList() { var worker = new System.ComponentModel.BackgroundWorker(); var list = new System.Collections.Generic.List(); worker.RunWorkerCompleted += delegate { list.Add(1); }; worker.DoWork += delegate { Thread.Sleep(1); }; worker.RunWorkerAsync(); Assert.That(list, Has.Count.EqualTo(1).After(5000, 100)); } [Test] public void CanTestContentsOfRefList() { var worker = new System.ComponentModel.BackgroundWorker(); var list = new System.Collections.Generic.List(); worker.RunWorkerCompleted += delegate { list.Add(1); }; worker.DoWork += delegate { Thread.Sleep(1); }; worker.RunWorkerAsync(); Assert.That(ref list, Has.Count.EqualTo(1).After(5000, 100)); } [Test] public void CanTestContentsOfDelegateReturningList() { var worker = new System.ComponentModel.BackgroundWorker(); var list = new System.Collections.Generic.List(); worker.RunWorkerCompleted += delegate { list.Add(1); }; worker.DoWork += delegate { Thread.Sleep(1); }; worker.RunWorkerAsync(); Assert.That(() => list, Has.Count.EqualTo(1).After(5000, 100)); } [Test] public void CanTestInitiallyNullReference() { string statusString = null; // object starts off as null var worker = new System.ComponentModel.BackgroundWorker(); worker.RunWorkerCompleted += delegate { statusString = "finished"; /* object non-null after work */ }; worker.DoWork += delegate { Thread.Sleep(TimeSpan.FromSeconds(1)); /* simulate work */ }; worker.RunWorkerAsync(); Assert.That(ref statusString, Has.Length.GreaterThan(0).After(3000, 100)); } [Test] public void CanTestInitiallyNullDelegate() { string statusString = null; // object starts off as null var worker = new System.ComponentModel.BackgroundWorker(); worker.RunWorkerCompleted += delegate { statusString = "finished"; /* object non-null after work */ }; worker.DoWork += delegate { Thread.Sleep(TimeSpan.FromSeconds(1)); /* simulate work */ }; worker.RunWorkerAsync(); Assert.That(() => statusString, Has.Length.GreaterThan(0).After(3000, 100)); } #endif private static int setValueTrueDelay; private void SetValueTrueAfterDelay(int delay) { setValueTrueDelay = delay; Thread thread = new Thread( SetValueTrueDelegate ); thread.Start(); } private static void MethodReturningVoid() { } private static TestDelegate InvalidDelegate = new TestDelegate(MethodReturningVoid); private static object MethodReturningValue() { return value; } private static ActualValueDelegate DelegateReturningValue = new ActualValueDelegate(MethodReturningValue); private static object MethodReturningFalse() { return false; } private static ActualValueDelegate DelegateReturningFalse = new ActualValueDelegate(MethodReturningFalse); private static object MethodReturningZero() { return 0; } private static ActualValueDelegate DelegateReturningZero = new ActualValueDelegate(MethodReturningZero); private static void MethodSetsValueTrue() { Thread.Sleep(setValueTrueDelay); value = true; } private ThreadStart SetValueTrueDelegate = new ThreadStart(MethodSetsValueTrue); } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/CollectionConstraintTests.cs0000664000175000017500000005662311654231422030060 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Framework.Tests; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; using RangeConstraint = NUnit.Framework.Constraints.RangeConstraint; #endif namespace NUnit.Framework.Constraints { #region AllItems [TestFixture] public class AllItemsTests : MessageChecker { [Test] public void AllItemsAreNotNull() { object[] c = new object[] { 1, "hello", 3, Environment.OSVersion }; Assert.That(c, new AllItemsConstraint( Is.Not.Null )); } [Test, ExpectedException(typeof(AssertionException))] public void AllItemsAreNotNullFails() { object[] c = new object[] { 1, "hello", null, 3 }; expectedMessage = TextMessageWriter.Pfx_Expected + "all items not null" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< 1, \"hello\", null, 3 >" + Environment.NewLine; Assert.That(c, new AllItemsConstraint(new NotConstraint(new EqualConstraint(null)))); } [Test] public void AllItemsAreInRange() { int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 }; Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100))); } [Test] public void AllItemsAreInRange_UsingIComparer() { int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 }; Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default))); } #if CLR_2_0 || CLR_4_0 [Test] public void AllItemsAreInRange_UsingIComparerOfT() { int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 }; Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default))); } [Test] public void AllItemsAreInRange_UsingComparisonOfT() { int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 }; Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default))); } #endif [Test, ExpectedException(typeof(AssertionException))] public void AllItemsAreInRangeFailureMessage() { int[] c = new int[] { 12, 27, 19, 32, 107, 99, 26 }; expectedMessage = TextMessageWriter.Pfx_Expected + "all items in range (10,100)" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< 12, 27, 19, 32, 107, 99, 26 >" + Environment.NewLine; Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100))); } [Test] public void AllItemsAreInstancesOfType() { object[] c = new object[] { 'a', 'b', 'c' }; Assert.That(c, new AllItemsConstraint(new InstanceOfTypeConstraint(typeof(char)))); } [Test, ExpectedException(typeof(AssertionException))] public void AllItemsAreInstancesOfTypeFailureMessage() { object[] c = new object[] { 'a', "b", 'c' }; expectedMessage = TextMessageWriter.Pfx_Expected + "all items instance of " + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< 'a', \"b\", 'c' >" + Environment.NewLine; Assert.That(c, new AllItemsConstraint(new InstanceOfTypeConstraint(typeof(char)))); } } #endregion #region OneItem public class ExactCountConstraintTests : MessageChecker { private static readonly string[] names = new string[] { "Charlie", "Fred", "Joe", "Charlie" }; [Test] public void ZeroItemsMatch() { Assert.That(names, new ExactCountConstraint(0, Is.EqualTo("Sam"))); Assert.That(names, Has.Exactly(0).EqualTo("Sam")); } [Test, ExpectedException(typeof(AssertionException))] public void ZeroItemsMatchFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "no item \"Charlie\"" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< \"Charlie\", \"Fred\", \"Joe\", \"Charlie\" >" + Environment.NewLine; Assert.That(names, new ExactCountConstraint(0, Is.EqualTo("Charlie"))); } [Test] public void ExactlyOneItemMatches() { Assert.That(names, new ExactCountConstraint(1, Is.EqualTo("Fred"))); Assert.That(names, Has.Exactly(1).EqualTo("Fred")); } [Test, ExpectedException(typeof(AssertionException))] public void ExactlyOneItemMatchFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "exactly one item \"Charlie\"" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< \"Charlie\", \"Fred\", \"Joe\", \"Charlie\" >" + Environment.NewLine; Assert.That(names, new ExactCountConstraint(1, Is.EqualTo("Charlie"))); } [Test] public void ExactlyTwoItemsMatch() { Assert.That(names, new ExactCountConstraint(2, Is.EqualTo("Charlie"))); Assert.That(names, Has.Exactly(2).EqualTo("Charlie")); } [Test, ExpectedException(typeof(AssertionException))] public void ExactlyTwoItemsMatchFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "exactly 2 items \"Fred\"" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< \"Charlie\", \"Fred\", \"Joe\", \"Charlie\" >" + Environment.NewLine; Assert.That(names, new ExactCountConstraint(2, Is.EqualTo("Fred"))); } } #endregion #region CollectionContains [TestFixture] public class CollectionContainsTests { [Test] public void CanTestContentsOfArray() { object item = "xyz"; object[] c = new object[] { 123, item, "abc" }; Assert.That(c, new CollectionContainsConstraint(item)); } [Test] public void CanTestContentsOfArrayList() { object item = "xyz"; ArrayList list = new ArrayList( new object[] { 123, item, "abc" } ); Assert.That(list, new CollectionContainsConstraint(item)); } [Test] public void CanTestContentsOfSortedList() { object item = "xyz"; SortedList list = new SortedList(); list.Add("a", 123); list.Add("b", item); list.Add("c", "abc"); Assert.That(list.Values, new CollectionContainsConstraint(item)); Assert.That(list.Keys, new CollectionContainsConstraint("b")); } [Test] public void CanTestContentsOfCollectionNotImplementingIList() { ICollectionAdapter ints = new ICollectionAdapter(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); Assert.That(ints, new CollectionContainsConstraint( 9 )); } [Test] public void IgnoreCaseIsHonored() { Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("WORLD").IgnoreCase); } [Test] public void UsesProvidedIComparer() { MyComparer comparer = new MyComparer(); Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(object x, object y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CLR_2_0 || CLR_4_0 [Test] public void UsesProvidedEqualityComparer() { MyEqualityComparer comparer = new MyEqualityComparer(); Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyEqualityComparer : IEqualityComparer { public bool Called; bool IEqualityComparer.Equals(object x, object y) { Called = true; return Comparer.Default.Compare(x, y) == 0; } int IEqualityComparer.GetHashCode(object x) { return x.GetHashCode(); } } [Test] public void UsesProvidedEqualityComparerOfT() { MyEqualityComparerOfT comparer = new MyEqualityComparerOfT(); Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyEqualityComparerOfT : IEqualityComparer { public bool Called; bool IEqualityComparer.Equals(T x, T y) { Called = true; return Comparer.Default.Compare(x, y) == 0; } int IEqualityComparer.GetHashCode(T x) { return x.GetHashCode(); } } [Test] public void UsesProvidedComparerOfT() { MyComparer comparer = new MyComparer(); Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("World").Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } [Test] public void UsesProvidedComparisonOfT() { MyComparison comparer = new MyComparison(); Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("World").Using(new Comparison(comparer.Compare))); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparison { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CS_3_0 || CS_4_0 [Test] public void UsesProvidedLambdaExpression() { Assert.That(new string[] { "Hello", "World" }, new CollectionContainsConstraint("WORLD").Using( (x,y)=>String.Compare(x, y, true) )); } #endif #endif } #endregion #region CollectionEquivalent public class CollectionEquivalentTests { [Test] public void EqualCollectionsAreEquivalent() { ICollection set1 = new ICollectionAdapter("x", "y", "z"); ICollection set2 = new ICollectionAdapter("x", "y", "z"); Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2)); } [Test] public void WorksWithCollectionsOfArrays() { byte[] array1 = new byte[] { 0x20, 0x44, 0x56, 0x76, 0x1e, 0xff }; byte[] array2 = new byte[] { 0x42, 0x52, 0x72, 0xef }; byte[] array3 = new byte[] { 0x20, 0x44, 0x56, 0x76, 0x1e, 0xff }; byte[] array4 = new byte[] { 0x42, 0x52, 0x72, 0xef }; ICollection set1 = new ICollectionAdapter(array1, array2); ICollection set2 = new ICollectionAdapter(array3, array4); Constraint constraint = new CollectionEquivalentConstraint(set1); Assert.That(constraint.Matches(set2)); set2 = new ICollectionAdapter(array4, array3); Assert.That(constraint.Matches(set2)); } [Test] public void EquivalentIgnoresOrder() { ICollection set1 = new ICollectionAdapter("x", "y", "z"); ICollection set2 = new ICollectionAdapter("z", "y", "x"); Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2)); } [Test] public void EquivalentFailsWithDuplicateElementInActual() { ICollection set1 = new ICollectionAdapter("x", "y", "z"); ICollection set2 = new ICollectionAdapter("x", "y", "x"); Assert.False(new CollectionEquivalentConstraint(set1).Matches(set2)); } [Test] public void EquivalentFailsWithDuplicateElementInExpected() { ICollection set1 = new ICollectionAdapter("x", "y", "x"); ICollection set2 = new ICollectionAdapter("x", "y", "z"); Assert.False(new CollectionEquivalentConstraint(set1).Matches(set2)); } [Test] public void EquivalentHandlesNull() { ICollection set1 = new ICollectionAdapter(null, "x", null, "z"); ICollection set2 = new ICollectionAdapter("z", null, "x", null); Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2)); } [Test] public void EquivalentHonorsIgnoreCase() { ICollection set1 = new ICollectionAdapter("x", "y", "z"); ICollection set2 = new ICollectionAdapter("z", "Y", "X"); Assert.That(new CollectionEquivalentConstraint(set1).IgnoreCase.Matches(set2)); } #if CS_3_0 || CS_4_0 [Test] public void EquivalentHonorsUsing() { ICollection set1 = new ICollectionAdapter("x", "y", "z"); ICollection set2 = new ICollectionAdapter("z", "Y", "X"); Assert.That(new CollectionEquivalentConstraint(set1) .Using( (x,y)=>String.Compare(x,y,true) ) .Matches(set2)); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void WorksWithHashSets() { var hash1 = new HashSet(new string[] { "presto", "abracadabra", "hocuspocus" }); var hash2 = new HashSet(new string[] { "abracadabra", "presto", "hocuspocus" }); Assert.That(new CollectionEquivalentConstraint(hash1).Matches(hash2)); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void WorksWithHashSetAndArray() { var hash = new HashSet(new string[] { "presto", "abracadabra", "hocuspocus" }); var array = new string[] { "abracadabra", "presto", "hocuspocus" }; var constraint = new CollectionEquivalentConstraint(hash); Assert.That(constraint.Matches(array)); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void WorksWithArrayAndHashSet() { var hash = new HashSet(new string[] { "presto", "abracadabra", "hocuspocus" }); var array = new string[] { "abracadabra", "presto", "hocuspocus" }; var constraint = new CollectionEquivalentConstraint(array); Assert.That(constraint.Matches(hash)); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void FailureMessageWithHashSetAndArray() { var hash = new HashSet(new string[] { "presto", "abracadabra", "hocuspocus" }); var array = new string[] { "abracadabra", "presto", "hocusfocus" }; var constraint = new CollectionEquivalentConstraint(hash); Assert.False(constraint.Matches(array)); TextMessageWriter writer = new TextMessageWriter(); constraint.WriteMessageTo(writer); Assert.That(writer.ToString(), Is.EqualTo( " Expected: equivalent to < \"presto\", \"abracadabra\", \"hocuspocus\" >" + Environment.NewLine + " But was: < \"abracadabra\", \"presto\", \"hocusfocus\" >" + Environment.NewLine)); Console.WriteLine(writer.ToString()); } #endif } #endregion #region CollectionOrdered [TestFixture] public class CollectionOrderedTests : MessageChecker { [Test] public void IsOrdered() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); Assert.That(al, Is.Ordered); } [Test] public void IsOrdered_2() { ArrayList al = new ArrayList(); al.Add(1); al.Add(2); al.Add(3); Assert.That(al, Is.Ordered); } [Test] public void IsOrderedDescending() { ArrayList al = new ArrayList(); al.Add("z"); al.Add("y"); al.Add("x"); Assert.That(al, Is.Ordered.Descending); } [Test] public void IsOrderedDescending_2() { ArrayList al = new ArrayList(); al.Add(3); al.Add(2); al.Add(1); Assert.That(al, Is.Ordered.Descending); } [Test, ExpectedException(typeof(AssertionException))] public void IsOrdered_Fails() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("z"); al.Add("y"); expectedMessage = " Expected: collection ordered" + Environment.NewLine + " But was: < \"x\", \"z\", \"y\" >" + Environment.NewLine; Assert.That(al, Is.Ordered); } [Test] public void IsOrdered_Allows_adjacent_equal_values() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("x"); al.Add("z"); Assert.That(al, Is.Ordered); } [Test, ExpectedException(typeof(ArgumentNullException), ExpectedMessage="index 1", MatchType=MessageMatch.Contains)] public void IsOrdered_Handles_null() { ArrayList al = new ArrayList(); al.Add("x"); al.Add(null); al.Add("z"); Assert.That(al, Is.Ordered); } [Test, ExpectedException(typeof(ArgumentException))] public void IsOrdered_TypesMustBeComparable() { ArrayList al = new ArrayList(); al.Add(1); al.Add("x"); Assert.That(al, Is.Ordered); } [Test, ExpectedException(typeof(ArgumentException))] public void IsOrdered_AtLeastOneArgMustImplementIComparable() { ArrayList al = new ArrayList(); al.Add(new object()); al.Add(new object()); Assert.That(al, Is.Ordered); } [Test] public void IsOrdered_Handles_custom_comparison() { ArrayList al = new ArrayList(); al.Add(new object()); al.Add(new object()); AlwaysEqualComparer comparer = new AlwaysEqualComparer(); Assert.That(al, Is.Ordered.Using(comparer)); Assert.That(comparer.Called, "TestComparer was not called"); } [Test] public void IsOrdered_Handles_custom_comparison2() { ArrayList al = new ArrayList(); al.Add(2); al.Add(1); TestComparer comparer = new TestComparer(); Assert.That(al, Is.Ordered.Using(comparer)); Assert.That(comparer.Called, "TestComparer was not called"); } #if CLR_2_0 || CLR_4_0 [Test] public void UsesProvidedComparerOfT() { ArrayList al = new ArrayList(); al.Add(1); al.Add(2); MyComparer comparer = new MyComparer(); Assert.That(al, Is.Ordered.Using(comparer)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } [Test] public void UsesProvidedComparisonOfT() { ArrayList al = new ArrayList(); al.Add(1); al.Add(2); MyComparison comparer = new MyComparison(); Assert.That(al, Is.Ordered.Using(new Comparison(comparer.Compare))); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparison { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CS_3_0 || CS_4_0 [Test] public void UsesProvidedLambda() { ArrayList al = new ArrayList(); al.Add(1); al.Add(2); Comparison comparer = (x, y) => x.CompareTo(y); Assert.That(al, Is.Ordered.Using(comparer)); } #endif #endif [Test] public void IsOrderedBy() { ArrayList al = new ArrayList(); al.Add(new OrderedByTestClass(1)); al.Add(new OrderedByTestClass(2)); Assert.That(al, Is.Ordered.By("Value")); } [Test] public void IsOrderedBy_Comparer() { ArrayList al = new ArrayList(); al.Add(new OrderedByTestClass(1)); al.Add(new OrderedByTestClass(2)); Assert.That(al, Is.Ordered.By("Value").Using(Comparer.Default)); } [Test] public void IsOrderedBy_Handles_heterogeneous_classes_as_long_as_the_property_is_of_same_type() { ArrayList al = new ArrayList(); al.Add(new OrderedByTestClass(1)); al.Add(new OrderedByTestClass2(2)); Assert.That(al, Is.Ordered.By("Value")); } class OrderedByTestClass { private int myValue; public int Value { get { return myValue; } set { myValue = value; } } public OrderedByTestClass(int value) { Value = value; } } class OrderedByTestClass2 { private int myValue; public int Value { get { return myValue; } set { myValue = value; } } public OrderedByTestClass2(int value) { Value = value; } } } #endregion } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ThrowsConstraintTests.cs0000664000175000017500000000762711652021566027257 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework.Tests; namespace NUnit.Framework.Constraints { [TestFixture] public class ThrowsConstraintTest_ExactType : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new ThrowsConstraint( new ExactTypeConstraint(typeof(ArgumentException))); expectedDescription = ""; stringRepresentation = ">"; } internal static object[] SuccessData = new object[] { new TestDelegate( TestDelegates.ThrowsArgumentException ) }; internal static object[] FailureData = new object[] { new TestDelegate( TestDelegates.ThrowsApplicationException ), new TestDelegate( TestDelegates.ThrowsNothing ), new TestDelegate( TestDelegates.ThrowsSystemException ) }; internal static string[] ActualValues = new string[] { "", "no exception thrown", "" }; } [TestFixture] public class ThrowsConstraintTest_InstanceOfType : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new ThrowsConstraint( new InstanceOfTypeConstraint(typeof(ApplicationException))); expectedDescription = "instance of "; stringRepresentation = ">"; } internal static object[] SuccessData = new object[] { new TestDelegate( TestDelegates.ThrowsApplicationException ), new TestDelegate( TestDelegates.ThrowsDerivedApplicationException ) }; internal static object[] FailureData = new object[] { new TestDelegate( TestDelegates.ThrowsArgumentException ), new TestDelegate( TestDelegates.ThrowsNothing ), new TestDelegate( TestDelegates.ThrowsSystemException ) }; internal static string[] ActualValues = new string[] { "", "no exception thrown", "" }; } public class ThrowsConstraintTest_WithConstraint : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new ThrowsConstraint( new AndConstraint( new ExactTypeConstraint(typeof(ArgumentException)), new PropertyConstraint("ParamName", new EqualConstraint("myParam")))); expectedDescription = @" and property ParamName equal to ""myParam"""; stringRepresentation = @" >>>"; } internal static object[] SuccessData = new object[] { new TestDelegate( TestDelegates.ThrowsArgumentException ) }; internal static object[] FailureData = new object[] { new TestDelegate( TestDelegates.ThrowsApplicationException ), new TestDelegate( TestDelegates.ThrowsNothing ), new TestDelegate( TestDelegates.ThrowsSystemException ) }; internal static string[] ActualValues = new string[] { "", "no exception thrown", "" }; } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ReusableConstraintTests.cs0000664000175000017500000000266711720454302027524 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { [TestFixture] public class ReusableConstraintTests { [Datapoints] internal static readonly ReusableConstraint[] constraints = new ReusableConstraint[] { Is.Not.Empty, Is.Not.Null, Has.Length.GreaterThan(3), Has.Property("Length").EqualTo(4).And.StartsWith("te") }; [Theory] public void CanReuseReusableConstraintMultipleTimes(ReusableConstraint c) { string s = "test"; Assume.That(s, c); Assert.That(s, c, "Should pass first time"); Assert.That(s, c, "Should pass second time"); Assert.That(s, c, "Should pass third time"); } [Test] public void CanCreateReusableConstraintByImplicitConversion() { ReusableConstraint c = Is.Not.Null; string s = "test"; Assert.That(s, c, "Should pass first time"); Assert.That(s, c, "Should pass second time"); Assert.That(s, c, "Should pass third time"); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ComparerTests.cs0000664000175000017500000000457011552022000025445 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { [TestFixture] public class ComparerTests { private Tolerance tolerance; [SetUp] public void Setup() { tolerance = Tolerance.Empty; } [TestCase(4, 4)] [TestCase(4.0d, 4.0d)] [TestCase(4.0f, 4.0f)] [TestCase(4, 4.0d)] [TestCase(4, 4.0f)] [TestCase(4.0d, 4)] [TestCase(4.0d, 4.0f)] [TestCase(4.0f, 4)] [TestCase(4.0f, 4.0d)] [TestCase(SpecialValue.Null, SpecialValue.Null)] #if CLR_2_0 || CLR_4_0 [TestCase(null, null)] #endif public void EqualItems(object x, object y) { Assert.That(NUnitComparer.Default.Compare(x, y) == 0); Assert.That(NUnitEqualityComparer.Default.AreEqual(x, y, ref tolerance)); } [TestCase(4, 2)] [TestCase(4.0d, 2.0d)] [TestCase(4.0f, 2.0f)] [TestCase(4, 2.0d)] [TestCase(4, 2.0f)] [TestCase(4.0d, 2)] [TestCase(4.0d, 2.0f)] [TestCase(4.0f, 2)] [TestCase(4.0f, 2.0d)] [TestCase(4, SpecialValue.Null)] #if CLR_2_0 || CLR_4_0 [TestCase(4, null)] #endif public void UnequalItems(object greater, object lesser) { Assert.That(NUnitComparer.Default.Compare(greater, lesser) > 0); Assert.That(NUnitComparer.Default.Compare(lesser, greater) < 0); Assert.False(NUnitEqualityComparer.Default.AreEqual(greater, lesser, ref tolerance)); Assert.False(NUnitEqualityComparer.Default.AreEqual(lesser, greater, ref tolerance)); } [TestCase(double.PositiveInfinity)] [TestCase(double.NegativeInfinity)] [TestCase(double.NaN)] [TestCase(float.PositiveInfinity)] [TestCase(float.NegativeInfinity)] [TestCase(float.NaN)] public void SpecialFloatingPointValues(object x) { Assert.That(NUnitEqualityComparer.Default.AreEqual(x, x, ref tolerance)); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/FloatingPointNumericsTest.cs0000664000175000017500000000676411504175260030022 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Drawing; namespace NUnit.Framework.Constraints { [TestFixture] public class FloatingPointNumericsTest { /// Tests the floating point value comparison helper [Test] public void FloatEqualityWithUlps() { Assert.IsTrue( FloatingPointNumerics.AreAlmostEqualUlps(0.00000001f, 0.0000000100000008f, 1) ); Assert.IsFalse( FloatingPointNumerics.AreAlmostEqualUlps(0.00000001f, 0.0000000100000017f, 1) ); Assert.IsTrue( FloatingPointNumerics.AreAlmostEqualUlps(1000000.00f, 1000000.06f, 1) ); Assert.IsFalse( FloatingPointNumerics.AreAlmostEqualUlps(1000000.00f, 1000000.13f, 1) ); } /// Tests the double precision floating point value comparison helper [Test] public void DoubleEqualityWithUlps() { Assert.IsTrue( FloatingPointNumerics.AreAlmostEqualUlps(0.00000001, 0.000000010000000000000002, 1) ); Assert.IsFalse( FloatingPointNumerics.AreAlmostEqualUlps(0.00000001, 0.000000010000000000000004, 1) ); Assert.IsTrue( FloatingPointNumerics.AreAlmostEqualUlps(1000000.00, 1000000.0000000001, 1) ); Assert.IsFalse( FloatingPointNumerics.AreAlmostEqualUlps(1000000.00, 1000000.0000000002, 1) ); } /// Tests the integer reinterpretation functions [Test] public void MirroredIntegerReinterpretation() { Assert.AreEqual( 12345.0f, FloatingPointNumerics.ReinterpretAsFloat( FloatingPointNumerics.ReinterpretAsInt(12345.0f) ) ); } /// Tests the long reinterpretation functions [Test] public void MirroredLongReinterpretation() { Assert.AreEqual( 12345.67890, FloatingPointNumerics.ReinterpretAsDouble( FloatingPointNumerics.ReinterpretAsLong(12345.67890) ) ); } /// Tests the floating point reinterpretation functions [Test] public void MirroredFloatReinterpretation() { Assert.AreEqual( 12345, FloatingPointNumerics.ReinterpretAsInt( FloatingPointNumerics.ReinterpretAsFloat(12345) ) ); } /// /// Tests the double prevision floating point reinterpretation functions /// [Test] public void MirroredDoubleReinterpretation() { Assert.AreEqual( 1234567890, FloatingPointNumerics.ReinterpretAsLong( FloatingPointNumerics.ReinterpretAsDouble(1234567890) ) ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/AndTest.cs0000664000175000017500000000212311567125240024224 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Constraints { [TestFixture] public class AndTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new AndConstraint(new GreaterThanConstraint(40), new LessThanConstraint(50)); expectedDescription = "greater than 40 and less than 50"; stringRepresentation = " >"; } internal object[] SuccessData = new object[] { 42 }; internal object[] FailureData = new object[] { 37, 53 }; internal string[] ActualValues = new string[] { "37", "53" }; [Test] public void CanCombineTestsWithAndOperator() { Assert.That(42, new GreaterThanConstraint(40) & new LessThanConstraint(50)); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ToStringTests.cs0000664000175000017500000000616611504175260025467 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { public class ToStringTests { [Test] public void CanDisplaySimpleConstraints_Unresolved() { Assert.That(Is.EqualTo(5).ToString(), Is.EqualTo("")); Assert.That(Has.Property("X").ToString(), Is.EqualTo("")); Assert.That(Has.Attribute(typeof(TestAttribute)).ToString(), Is.EqualTo("")); } [Test] public void CanDisplaySimpleConstraints_Resolved() { IResolveConstraint constraint = Is.EqualTo(5); Assert.That(constraint.Resolve().ToString(), Is.EqualTo("")); constraint = Has.Property("X"); Assert.That(constraint.Resolve().ToString(), Is.EqualTo("")); constraint = Has.Attribute(typeof(TestAttribute)).With.Property("Description").EqualTo("smoke"); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(">>")); } [Test] public void DisplayPrefixConstraints_Unresolved() { Assert.That(Is.Not.EqualTo(5).ToString(), Is.EqualTo(">")); Assert.That(Is.Not.All.EqualTo(5).ToString(), Is.EqualTo(">")); Assert.That(Has.Property("X").EqualTo(5).ToString(), Is.EqualTo(">")); Assert.That(Has.Attribute(typeof(TestAttribute)).With.Property("Description").EqualTo("smoke").ToString(), Is.EqualTo(">")); } [Test] public void CanDisplayPrefixConstraints_Resolved() { IResolveConstraint constraint = Is.Not.EqualTo(5); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(">")); constraint = Is.Not.All.EqualTo(5); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(">>")); constraint = Has.Property("X").EqualTo(5); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(">")); } [Test] public void DisplayBinaryConstraints_Resolved() { IResolveConstraint constraint = Is.GreaterThan(0).And.LessThan(100); Assert.That(constraint.Resolve().ToString(), Is.EqualTo(" >")); } [Test] public void DisplayBinaryConstraints_UnResolved() { IResolveConstraint constraint = Is.GreaterThan(0).And.LessThan(100); Assert.That(constraint.ToString(), Is.EqualTo(">")); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/SerializableConstraintTest.cs0000664000175000017500000000453611544454420030207 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { [TestFixture] public class BinarySerializableTest : ConstraintTestBaseWithArgumentException { [SetUp] public void SetUp() { theConstraint = new BinarySerializableConstraint(); expectedDescription = "binary serializable"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 1, "a", new ArrayList(), new InternalWithSerializableAttributeClass() }; internal object[] FailureData = new object[] { new InternalClass() }; internal string[] ActualValues = new string[] { "" }; internal object[] InvalidData = new object[] { null }; } [TestFixture] public class XmlSerializableTest : ConstraintTestBaseWithArgumentException { [SetUp] public void SetUp() { theConstraint = new XmlSerializableConstraint(); expectedDescription = "xml serializable"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 1, "a", new ArrayList() }; #if CLR_2_0 || CLR_4_0 internal object[] FailureData = new object[] { new Dictionary(), new InternalClass(), new InternalWithSerializableAttributeClass() }; internal string[] ActualValues = new string[] { "", "", "" }; #else internal object[] FailureData = new object[] { new InternalClass(), new InternalWithSerializableAttributeClass() }; internal string[] ActualValues = new string[] { "", "" }; #endif internal object[] InvalidData = new object[] { null }; } internal class InternalClass {} [Serializable] internal class InternalWithSerializableAttributeClass {} } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ComparisonConstraintTests.cs0000664000175000017500000002661311567125146030103 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { #region ComparisonTest public abstract class ComparisonConstraintTest : ConstraintTestBaseWithArgumentException { protected ComparisonConstraint comparisonConstraint; [Test] public void UsesProvidedIComparer() { MyComparer comparer = new MyComparer(); comparisonConstraint.Using(comparer).Matches(0); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(object x, object y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CLR_2_0 || CLR_4_0 [Test] public void UsesProvidedComparerOfT() { MyComparer comparer = new MyComparer(); comparisonConstraint.Using(comparer).Matches(0); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } [Test] public void UsesProvidedComparisonOfT() { MyComparison comparer = new MyComparison(); comparisonConstraint.Using(new Comparison(comparer.Compare)).Matches(0); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparison { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CS_3_0 || CS_4_0 [Test] public void UsesProvidedLambda() { Comparison comparer = (x, y) => x.CompareTo(y); comparisonConstraint.Using(comparer).Matches(0); } #endif #endif } #endregion #region GreaterThan [TestFixture] public class GreaterThanTest : ComparisonConstraintTest { [SetUp] public void SetUp() { theConstraint = comparisonConstraint = new GreaterThanConstraint(5); expectedDescription = "greater than 5"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 6, 5.001 }; internal object[] FailureData = new object[] { 4, 5 }; internal string[] ActualValues = new string[] { "4", "5" }; internal object[] InvalidData = new object[] { null, "xxx" }; [Test] public void CanCompareIComparables() { ClassWithIComparable expected = new ClassWithIComparable(0); ClassWithIComparable actual = new ClassWithIComparable(42); Assert.That(actual, Is.GreaterThan(expected)); } #if CLR_2_0 || CLR_4_0 [Test] public void CanCompareIComparablesOfT() { ClassWithIComparableOfT expected = new ClassWithIComparableOfT(0); ClassWithIComparableOfT actual = new ClassWithIComparableOfT(42); Assert.That(actual, Is.GreaterThan(expected)); } #endif } #endregion #region GreaterThanOrEqual [TestFixture] public class GreaterThanOrEqualTest : ComparisonConstraintTest { [SetUp] public void SetUp() { theConstraint = comparisonConstraint = new GreaterThanOrEqualConstraint(5); expectedDescription = "greater than or equal to 5"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 6, 5 }; internal object[] FailureData = new object[] { 4 }; internal string[] ActualValues = new string[] { "4" }; internal object[] InvalidData = new object[] { null, "xxx" }; [Test] public void CanCompareIComparables() { ClassWithIComparable expected = new ClassWithIComparable(0); ClassWithIComparable actual = new ClassWithIComparable(42); Assert.That(actual, Is.GreaterThanOrEqualTo(expected)); } #if CLR_2_0 || CLR_4_0 [Test] public void CanCompareIComparablesOfT() { ClassWithIComparableOfT expected = new ClassWithIComparableOfT(0); ClassWithIComparableOfT actual = new ClassWithIComparableOfT(42); Assert.That(actual, Is.GreaterThanOrEqualTo(expected)); } #endif } #endregion #region LessThan [TestFixture] public class LessThanTest : ComparisonConstraintTest { [SetUp] public void SetUp() { theConstraint = comparisonConstraint = new LessThanConstraint(5); expectedDescription = "less than 5"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 4, 4.999 }; internal object[] FailureData = new object[] { 6, 5 }; internal string[] ActualValues = new string[] { "6", "5" }; internal object[] InvalidData = new object[] { null, "xxx" }; [Test] public void CanCompareIComparables() { ClassWithIComparable expected = new ClassWithIComparable(42); ClassWithIComparable actual = new ClassWithIComparable(0); Assert.That(actual, Is.LessThan(expected)); } #if CLR_2_0 || CLR_4_0 [Test] public void CanCompareIComparablesOfT() { ClassWithIComparableOfT expected = new ClassWithIComparableOfT(42); ClassWithIComparableOfT actual = new ClassWithIComparableOfT(0); Assert.That(actual, Is.LessThan(expected)); } #endif } #endregion #region LessThanOrEqual [TestFixture] public class LessThanOrEqualTest : ComparisonConstraintTest { [SetUp] public void SetUp() { theConstraint = comparisonConstraint = new LessThanOrEqualConstraint(5); expectedDescription = "less than or equal to 5"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 4, 5 }; internal object[] FailureData = new object[] { 6 }; internal string[] ActualValues = new string[] { "6" }; internal object[] InvalidData = new object[] { null, "xxx" }; [Test] public void CanCompareIComparables() { ClassWithIComparable expected = new ClassWithIComparable(42); ClassWithIComparable actual = new ClassWithIComparable(0); Assert.That(actual, Is.LessThanOrEqualTo(expected)); } #if CLR_2_0 || CLR_4_0 [Test] public void CanCompareIComparablesOfT() { ClassWithIComparableOfT expected = new ClassWithIComparableOfT(42); ClassWithIComparableOfT actual = new ClassWithIComparableOfT(0); Assert.That(actual, Is.LessThanOrEqualTo(expected)); } #endif } #endregion #region RangeConstraint [TestFixture] public class RangeConstraintTest : ConstraintTestBaseWithArgumentException { #if CLR_2_0 || CLR_4_0 RangeConstraint rangeConstraint; #else RangeConstraint rangeConstraint; #endif [SetUp] public void SetUp() { #if CLR_2_0 || CLR_4_0 theConstraint = rangeConstraint = new RangeConstraint(5, 42); #else theConstraint = rangeConstraint = new RangeConstraint(5, 42); #endif expectedDescription = "in range (5,42)"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { 5, 23, 42 }; internal object[] FailureData = new object[] { 4, 43 }; internal string[] ActualValues = new string[] { "4", "43" }; internal object[] InvalidData = new object[] { null, "xxx" }; [Test] public void UsesProvidedIComparer() { MyComparer comparer = new MyComparer(); Assert.That(rangeConstraint.Using(comparer).Matches(19)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(object x, object y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CLR_2_0 || CLR_4_0 [Test] public void UsesProvidedComparerOfT() { MyComparer comparer = new MyComparer(); Assert.That(rangeConstraint.Using(comparer).Matches(19)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparer : IComparer { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } [Test] public void UsesProvidedComparisonOfT() { MyComparison comparer = new MyComparison(); Assert.That(rangeConstraint.Using(new Comparison(comparer.Compare)).Matches(19)); Assert.That(comparer.Called, "Comparer was not called"); } class MyComparison { public bool Called; public int Compare(T x, T y) { Called = true; return Comparer.Default.Compare(x, y); } } #if CS_3_0 || CS_4_0 [Test] public void UsesProvidedLambda() { Comparison comparer = (x, y) => x.CompareTo(y); Assert.That(rangeConstraint.Using(comparer).Matches(19)); } #endif #endif } #endregion #region Test Classes class ClassWithIComparable : IComparable { private int val; public ClassWithIComparable(int val) { this.val = val; } public int CompareTo(object x) { ClassWithIComparable other = x as ClassWithIComparable; if (x is ClassWithIComparable) return val.CompareTo(other.val); throw new ArgumentException(); } } #if CLR_2_0 || CLR_4_0 class ClassWithIComparableOfT : IComparable { private int val; public ClassWithIComparableOfT(int val) { this.val = val; } public int CompareTo(ClassWithIComparableOfT other) { return val.CompareTo(other.val); } } #endif #endregion }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/MsgUtilTests.cs0000664000175000017500000001022711544454420025275 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Constraints { /// /// Summary description for MsgUtilTests. /// [TestFixture] public class MsgUtilTests { [TestCase("\n", "\\n")] [TestCase("\n\n", "\\n\\n")] [TestCase("\n\n\n", "\\n\\n\\n")] [TestCase("\r", "\\r")] [TestCase("\r\r", "\\r\\r")] [TestCase("\r\r\r", "\\r\\r\\r")] [TestCase("\r\n", "\\r\\n")] [TestCase("\n\r", "\\n\\r")] [TestCase("This is a\rtest message", "This is a\\rtest message")] [TestCase("", "")] #if CLR_2_0 || CLR_4_0 [TestCase(null, null)] #endif [TestCase("\t", "\\t")] [TestCase("\t\n", "\\t\\n")] [TestCase("\\r\\n", "\\\\r\\\\n")] // TODO: Figure out why this fails in Mono // TODO: Need Platform property on test case //[TestCase("\0", "\\0")] [TestCase("\a", "\\a")] [TestCase("\b", "\\b")] [TestCase("\f", "\\f")] [TestCase("\v", "\\v")] // New Line [TestCase("\x0085", "\\x0085", Description = "Next line character")] [TestCase("\x2028", "\\x2028", Description = "Line separator character")] [TestCase("\x2029", "\\x2029", Description = "Paragraph separator character")] public void EscapeControlCharsTest(string input, string expected) { Assert.AreEqual( expected, MsgUtils.EscapeControlChars(input) ); } #if MONO [Test] public void EscapeNullCharInString() { Assert.That(MsgUtils.EscapeControlChars("\0"), Is.EqualTo("\\0")); } #endif private const string s52 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; [TestCase(s52, 52, 0, s52, TestName="NoClippingNeeded")] [TestCase(s52, 29, 0, "abcdefghijklmnopqrstuvwxyz...", TestName="ClipAtEnd")] [TestCase(s52, 29, 26, "...ABCDEFGHIJKLMNOPQRSTUVWXYZ", TestName="ClipAtStart")] [TestCase(s52, 28, 26, "...ABCDEFGHIJKLMNOPQRSTUV...", TestName="ClipAtStartAndEnd")] public void TestClipString(string input, int max, int start, string result) { Assert.AreEqual(result, MsgUtils.ClipString(input, max, start)); } //[TestCase('\0')] //[TestCase('\r')] //public void CharacterArgumentTest(char c) //{ //} [Test] public void ClipExpectedAndActual_StringsFitInLine() { string eClip = s52; string aClip = "abcde"; MsgUtils.ClipExpectedAndActual(ref eClip, ref aClip, 52, 5); Assert.AreEqual(s52, eClip); Assert.AreEqual("abcde", aClip); eClip = s52; aClip = "abcdefghijklmno?qrstuvwxyz"; MsgUtils.ClipExpectedAndActual(ref eClip, ref aClip, 52, 15); Assert.AreEqual(s52, eClip); Assert.AreEqual("abcdefghijklmno?qrstuvwxyz", aClip); } [Test] public void ClipExpectedAndActual_StringTailsFitInLine() { string s1 = s52; string s2 = s52.Replace('Z', '?'); MsgUtils.ClipExpectedAndActual(ref s1, ref s2, 29, 51); Assert.AreEqual("...ABCDEFGHIJKLMNOPQRSTUVWXYZ", s1); } [Test] public void ClipExpectedAndActual_StringsDoNotFitInLine() { string s1 = s52; string s2 = "abcdefghij"; MsgUtils.ClipExpectedAndActual(ref s1, ref s2, 29, 10); Assert.AreEqual("abcdefghijklmnopqrstuvwxyz...", s1); Assert.AreEqual("abcdefghij", s2); s1 = s52; s2 = "abcdefghijklmno?qrstuvwxyz"; MsgUtils.ClipExpectedAndActual(ref s1, ref s2, 25, 15); Assert.AreEqual("...efghijklmnopqrstuvw...", s1); Assert.AreEqual("...efghijklmno?qrstuvwxyz", s2); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/PathConstraintTests.cs0000664000175000017500000002344711567125300026657 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Summary description for PathConstraintTests. /// ] [TestFixture] public class SamePathTest_Windows : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SamePathConstraint( @"C:\folder1\file.tmp" ).IgnoreCase; expectedDescription = @"Path matching ""C:\folder1\file.tmp"""; stringRepresentation = ""; } internal object[] SuccessData = new object[] { @"C:\folder1\file.tmp", @"C:\Folder1\File.TMP", @"C:\folder1\.\file.tmp", @"C:\folder1\folder2\..\file.tmp", @"C:\FOLDER1\.\folder2\..\File.TMP", @"C:/folder1/file.tmp" }; internal object[] FailureData = new object[] { 123, @"C:\folder2\file.tmp", @"C:\folder1\.\folder2\..\file.temp" }; internal string[] ActualValues = new string[] { "123", "\"C:\\folder2\\file.tmp\"", "\"C:\\folder1\\.\\folder2\\..\\file.temp\"" }; [Test] public void RootPathEquality() { Assert.That("c:\\", Is.SamePath("C:\\junk\\..\\").IgnoreCase); } } [TestFixture] public class SamePathTest_Linux : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SamePathConstraint(@"/folder1/file.tmp").RespectCase; expectedDescription = @"Path matching ""/folder1/file.tmp"""; stringRepresentation = @""; } internal object[] SuccessData = new object[] { @"/folder1/file.tmp", @"/folder1/./file.tmp", @"/folder1/folder2/../file.tmp", @"/folder1/./folder2/../file.tmp", @"\folder1\file.tmp" }; internal object[] FailureData = new object[] { 123, @"/folder2/file.tmp", @"/folder1/./folder2/../file.temp", @"/Folder1/File.TMP", @"/FOLDER1/./folder2/../File.TMP", }; internal string[] ActualValues = new string[] { "123", "\"/folder2/file.tmp\"", "\"/folder1/./folder2/../file.temp\"", "\"/Folder1/File.TMP\"", "\"/FOLDER1/./folder2/../File.TMP\"", }; [Test] public void RootPathEquality() { Assert.That("/", Is.SamePath("/junk/../")); } } [TestFixture] public class SubPathTest_Windows : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SubPathConstraint( @"C:\folder1\folder2" ).IgnoreCase; expectedDescription = @"Path under ""C:\folder1\folder2"""; stringRepresentation = @""; } internal object[] SuccessData = new object[] { @"C:\folder1\folder2\folder3", @"C:\folder1\.\folder2\folder3", @"C:\folder1\junk\..\folder2\folder3", @"C:\FOLDER1\.\junk\..\Folder2\temp\..\Folder3", @"C:/folder1/folder2/folder3", }; internal object[] FailureData = new object[] { 123, @"C:\folder1\folder3", @"C:\folder1\.\folder2\..\file.temp", @"C:\folder1\folder2", @"C:\Folder1\Folder2", @"C:\folder1\.\folder2", @"C:\folder1\junk\..\folder2", @"C:\FOLDER1\.\junk\..\Folder2", @"C:/folder1/folder2" }; internal string[] ActualValues = new string[] { "123", "\"C:\\folder1\\folder3\"", "\"C:\\folder1\\.\\folder2\\..\\file.temp\"", "\"C:\\folder1\\folder2\"", "\"C:\\Folder1\\Folder2\"", "\"C:\\folder1\\.\\folder2\"", "\"C:\\folder1\\junk\\..\\folder2\"", "\"C:\\FOLDER1\\.\\junk\\..\\Folder2\"", "\"C:/folder1/folder2\"" }; [Test] public void SubPathOfRoot() { Assert.That("C:\\junk\\file.temp", new SubPathConstraint("C:\\")); } } [TestFixture] public class SubPathTest_Linux : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SubPathConstraint( @"/folder1/folder2" ).RespectCase; expectedDescription = @"Path under ""/folder1/folder2"""; stringRepresentation = @""; } internal object[] SuccessData = new object[] { @"/folder1/folder2/folder3", @"/folder1/./folder2/folder3", @"/folder1/junk/../folder2/folder3", @"\folder1\folder2\folder3", }; internal object[] FailureData = new object[] { 123, "/Folder1/Folder2", "/FOLDER1/./junk/../Folder2", "/FOLDER1/./junk/../Folder2/temp/../Folder3", "/folder1/folder3", "/folder1/./folder2/../folder3", "/folder1", "/folder1/folder2", "/folder1/./folder2", "/folder1/junk/../folder2", @"\folder1\folder2" }; internal string[] ActualValues = new string[] { "123", "\"/Folder1/Folder2\"", "\"/FOLDER1/./junk/../Folder2\"", "\"/FOLDER1/./junk/../Folder2/temp/../Folder3\"", "\"/folder1/folder3\"", "\"/folder1/./folder2/../folder3\"", "\"/folder1\"", "\"/folder1/folder2\"", "\"/folder1/./folder2\"", "\"/folder1/junk/../folder2\"", "\"\\folder1\\folder2\"" }; [Test] public void SubPathOfRoot() { Assert.That("/junk/file.temp", new SubPathConstraint("/")); } } [TestFixture] public class SamePathOrUnderTest_Windows : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SamePathOrUnderConstraint( @"C:\folder1\folder2" ).IgnoreCase; expectedDescription = @"Path under or matching ""C:\folder1\folder2"""; stringRepresentation = @""; } internal object[] SuccessData = new object[] { @"C:\folder1\folder2", @"C:\Folder1\Folder2", @"C:\folder1\.\folder2", @"C:\folder1\junk\..\folder2", @"C:\FOLDER1\.\junk\..\Folder2", @"C:/folder1/folder2", @"C:\folder1\folder2\folder3", @"C:\folder1\.\folder2\folder3", @"C:\folder1\junk\..\folder2\folder3", @"C:\FOLDER1\.\junk\..\Folder2\temp\..\Folder3", @"C:/folder1/folder2/folder3", }; internal object[] FailureData = new object[] { 123, @"C:\folder1\folder3", @"C:\folder1\.\folder2\..\file.temp" }; internal string[] ActualValues = new string[] { "123", "\"C:\\folder1\\folder3\"", "\"C:\\folder1\\.\\folder2\\..\\file.temp\"" }; } [TestFixture] public class SamePathOrUnderTest_Linux : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SamePathOrUnderConstraint( @"/folder1/folder2" ).RespectCase; expectedDescription = @"Path under or matching ""/folder1/folder2"""; stringRepresentation = @""; } internal object[] SuccessData = new object[] { @"/folder1/folder2", @"/folder1/./folder2", @"/folder1/junk/../folder2", @"\folder1\folder2", @"/folder1/folder2/folder3", @"/folder1/./folder2/folder3", @"/folder1/junk/../folder2/folder3", @"\folder1\folder2\folder3", }; internal object[] FailureData = new object[] { 123, "/Folder1/Folder2", "/FOLDER1/./junk/../Folder2", "/FOLDER1/./junk/../Folder2/temp/../Folder3", "/folder1/folder3", "/folder1/./folder2/../folder3", "/folder1" }; internal string[] ActualValues = new string[] { "123", "\"/Folder1/Folder2\"", "\"/FOLDER1/./junk/../Folder2\"", "\"/FOLDER1/./junk/../Folder2/temp/../Folder3\"", "\"/folder1/folder3\"", "\"/folder1/./folder2/../folder3\"", "\"/folder1\"" }; } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/EqualTest.cs0000664000175000017500000001105711651233442024575 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Drawing; namespace NUnit.Framework.Constraints { [TestFixture] public class EqualTest : IExpectException { [Test, ExpectedException(typeof(AssertionException))] public void FailedStringMatchShowsFailurePosition() { Assert.That( "abcdgfe", new EqualConstraint( "abcdefg" ) ); } static readonly string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; [Test, ExpectedException(typeof(AssertionException))] public void LongStringsAreTruncated() { string expected = testString; string actual = testString.Replace('k', 'X'); Assert.That(actual, new EqualConstraint(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void LongStringsAreTruncatedAtBothEndsIfNecessary() { string expected = testString; string actual = testString.Replace('Z', '?'); Assert.That(actual, new EqualConstraint(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void LongStringsAreTruncatedAtFrontEndIfNecessary() { string expected = testString; string actual = testString + "+++++"; Assert.That(actual, new EqualConstraint(expected)); } // [Test] // public void NamedAndUnnamedColorsCompareAsEqual() // { // EqualConstraint.SetConstraintForType(typeof(Color), typeof(SameColorAs)); // Assert.That(System.Drawing.Color.Red, // Is.EqualTo(System.Drawing.Color.FromArgb(255, 0, 0))); // } public void HandleException(Exception ex) { StringReader rdr = new StringReader(ex.Message); /* skip */ rdr.ReadLine(); string expected = rdr.ReadLine(); if (expected != null && expected.Length > 11) expected = expected.Substring(11); string actual = rdr.ReadLine(); if (actual != null && actual.Length > 11) actual = actual.Substring(11); string line = rdr.ReadLine(); Assert.That(line, new NotConstraint(new EqualConstraint(null)), "No caret line displayed"); int caret = line.Substring(11).IndexOf('^'); int minLength = Math.Min(expected.Length, actual.Length); int minMatch = Math.Min(caret, minLength); if (caret != minLength) { if (caret > minLength || expected.Substring(0, minMatch) != actual.Substring(0, minMatch) || expected[caret] == actual[caret]) Assert.Fail("Message Error: Caret does not point at first mismatch..." + Environment.NewLine + ex.Message); } if (expected.Length > 68 || actual.Length > 68 || caret > 68) Assert.Fail("Message Error: Strings are not truncated..." + Environment.NewLine + ex.Message); } public class SameColorAs : Constraint { private Color expectedColor; public SameColorAs(Color expectedColor) { this.expectedColor = expectedColor; } public override bool Matches(object actual) { this.actual = actual; return actual is Color && ((Color)actual).ToArgb() == expectedColor.ToArgb(); } public override void WriteDescriptionTo(MessageWriter writer) { writer.WriteExpectedValue( "same color as " + expectedColor ); } } #if CLR_2_0 || CLR_4_0 [Test] public void TestPropertyWithPrivateSetter() { SomeClass obj = new SomeClass(); Assert.That(obj.BrokenProp, Is.EqualTo(string.Empty)); } private class SomeClass { public string BrokenProp { get { return string.Empty; } private set { } } } #endif } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/EmptyConstraintTest.cs0000664000175000017500000000426411670446702026701 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { [TestFixture] public class EmptyConstraintTest : ConstraintTestBaseWithArgumentException { [SetUp] public void SetUp() { theConstraint = new EmptyConstraint(); expectedDescription = ""; stringRepresentation = ""; } internal static object[] SuccessData = new object[] { string.Empty, new object[0], new ArrayList(), #if CLR_2_0 || CLR_4_0 new System.Collections.Generic.List() #endif }; internal static object[] FailureData = new object[] { "Hello", new object[] { 1, 2, 3 } }; internal static string[] ActualValues = new string[] { "\"Hello\"", "< 1, 2, 3 >" }; internal static object[] InvalidData = new object[] { null, 5 }; } [TestFixture] public class NullOrEmptyStringConstraintTest : ConstraintTestBaseWithArgumentException { [SetUp] public void SetUp() { theConstraint = new NullOrEmptyStringConstraint(); expectedDescription = "null or empty string"; stringRepresentation = ""; } internal static object[] SuccessData = new object[] { string.Empty, null }; internal static object[] FailureData = new object[] { "Hello" }; internal static string[] ActualValues = new string[] { "\"Hello\"" }; internal static object[] InvalidData = new object[] { 5 }; } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/BasicConstraintTests.cs0000664000175000017500000000542511567125300027000 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Framework.Constraints; namespace NUnit.Framework.Constraints { [TestFixture] public class NullConstraintTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new NullConstraint(); expectedDescription = "null"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { null }; internal object[] FailureData = new object[] { "hello" }; internal string[] ActualValues = new string[] { "\"hello\"" }; } [TestFixture] public class TrueConstraintTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new TrueConstraint(); expectedDescription = "True"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { true, 2+2==4 }; internal object[] FailureData = new object[] { null, "hello", false, 2+2==5 }; internal string[] ActualValues = new string[] { "null", "\"hello\"", "False", "False" }; } [TestFixture] public class FalseConstraintTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new FalseConstraint(); expectedDescription = "False"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { false, 2 + 2 == 5 }; internal object[] FailureData = new object[] { null, "hello", true, 2+2==4 }; internal string[] ActualValues = new string[] { "null", "\"hello\"", "True", "True" }; } [TestFixture] public class NaNConstraintTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new NaNConstraint(); expectedDescription = "NaN"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { double.NaN, float.NaN }; internal object[] FailureData = new object[] { null, "hello", 42, double.PositiveInfinity, double.NegativeInfinity, float.PositiveInfinity, float.NegativeInfinity }; internal string[] ActualValues = new string[] { "null", "\"hello\"", "42", "Infinity", "-Infinity", "Infinity", "-Infinity" }; } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/StringConstraintTests.cs0000664000175000017500000001353011567125146027231 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Constraints { [TestFixture] public class SubstringTest : ConstraintTestBase, IExpectException { [SetUp] public void SetUp() { theConstraint = new SubstringConstraint("hello"); expectedDescription = "String containing \"hello\""; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "hello", "hello there", "I said hello", "say hello to fred" }; internal object[] FailureData = new object[] { "goodbye", "HELLO", "What the hell?", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"HELLO\"", "\"What the hell?\"", "", "null" }; public void HandleException(Exception ex) { Assert.That(ex.Message, new EqualConstraint( TextMessageWriter.Pfx_Expected + "String containing \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...\"" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...\"" + Environment.NewLine)); } } [TestFixture] public class SubstringTestIgnoringCase : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new SubstringConstraint("hello").IgnoreCase; expectedDescription = "String containing \"hello\", ignoring case"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "Hello", "HellO there", "I said HELLO", "say hello to fred" }; internal object[] FailureData = new object[] { "goodbye", "What the hell?", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"What the hell?\"", "", "null" }; } [TestFixture] public class StartsWithTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new StartsWithConstraint("hello"); expectedDescription = "String starting with \"hello\""; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "hello", "hello there" }; internal object[] FailureData = new object[] { "goodbye", "HELLO THERE", "I said hello", "say hello to fred", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"HELLO THERE\"", "\"I said hello\"", "\"say hello to fred\"", "", "null" }; } [TestFixture] public class StartsWithTestIgnoringCase : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new StartsWithConstraint("hello").IgnoreCase; expectedDescription = "String starting with \"hello\", ignoring case"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "Hello", "HELLO there" }; internal object[] FailureData = new object[] { "goodbye", "What the hell?", "I said hello", "say Hello to fred", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"What the hell?\"", "\"I said hello\"", "\"say Hello to fred\"", "", "null" }; } [TestFixture] public class EndsWithTest : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new EndsWithConstraint("hello"); expectedDescription = "String ending with \"hello\""; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "hello", "I said hello" }; internal object[] FailureData = new object[] { "goodbye", "What the hell?", "hello there", "say hello to fred", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"What the hell?\"", "\"hello there\"", "\"say hello to fred\"", "", "null" }; } [TestFixture] public class EndsWithTestIgnoringCase : ConstraintTestBase { [SetUp] public void SetUp() { theConstraint = new EndsWithConstraint("hello").IgnoreCase; expectedDescription = "String ending with \"hello\", ignoring case"; stringRepresentation = ""; } internal object[] SuccessData = new object[] { "HELLO", "I said Hello" }; internal object[] FailureData = new object[] { "goodbye", "What the hell?", "hello there", "say hello to fred", string.Empty, null }; internal string[] ActualValues = new string[] { "\"goodbye\"", "\"What the hell?\"", "\"hello there\"", "\"say hello to fred\"", "", "null" }; } //[TestFixture] //public class EqualIgnoringCaseTest : ConstraintTest //{ // [SetUp] // public void SetUp() // { // Matcher = new EqualConstraint("Hello World!").IgnoreCase; // Description = "\"Hello World!\", ignoring case"; // } // object[] SuccessData = new object[] { "hello world!", "Hello World!", "HELLO world!" }; // object[] FailureData = new object[] { "goodbye", "Hello Friends!", string.Empty, null }; // string[] ActualValues = new string[] { "\"goodbye\"", "\"Hello Friends!\"", "", "null" }; //} } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/ConstraintTestBase.cs0000664000175000017500000000574111504175260026450 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Constraints { public abstract class ConstraintTestBaseNoData { protected Constraint theConstraint; protected string expectedDescription = ""; protected string stringRepresentation = ""; [Test] public void ProvidesProperDescription() { TextMessageWriter writer = new TextMessageWriter(); theConstraint.WriteDescriptionTo(writer); Assert.AreEqual(expectedDescription, writer.ToString()); } [Test] public void ProvidesProperStringRepresentation() { Assert.AreEqual(stringRepresentation, theConstraint.ToString()); } } public abstract class ConstraintTestBase : ConstraintTestBaseNoData { [Test, TestCaseSource("SuccessData")] public void SucceedsWithGoodValues(object value) { Assert.That(theConstraint.Matches(value)); } [Test, TestCaseSource("FailureData")] public void FailsWithBadValues(object badValue) { Assert.IsFalse(theConstraint.Matches(badValue)); } [Test, Sequential] public void ProvidesProperFailureMessage( [ValueSource("FailureData")] object badValue, [ValueSource("ActualValues")] string message) { theConstraint.Matches(badValue); TextMessageWriter writer = new TextMessageWriter(); theConstraint.WriteMessageTo(writer); Assert.AreEqual( TextMessageWriter.Pfx_Expected + expectedDescription + Environment.NewLine + TextMessageWriter.Pfx_Actual + message + Environment.NewLine, writer.ToString()); } } /// /// Base class for testing constraints that can throw an ArgumentException /// public abstract class ConstraintTestBaseWithArgumentException : ConstraintTestBase { [Test, TestCaseSource("InvalidData")] [ExpectedException(typeof(ArgumentException))] public void InvalidDataThrowsArgumentException(object value) { theConstraint.Matches(value); } } /// /// Base class for tests that can throw multiple exceptions. Use /// TestCaseData class to specify the expected exception type. /// public abstract class ConstraintTestBaseWithExceptionTests : ConstraintTestBase { [Test, TestCaseSource("InvalidData")] public void InvalidDataThrowsException(object value) { theConstraint.Matches(value); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/PropertyTests.cs0000664000175000017500000000534211567125246025545 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { public class PropertyExistsTest : ConstraintTestBaseWithExceptionTests { [SetUp] public void SetUp() { theConstraint = new PropertyExistsConstraint("Length"); expectedDescription = "property Length"; stringRepresentation = ""; } internal static object[] SuccessData = new object[] { new int[0], "hello", typeof(Array) }; internal static object[] FailureData = new object[] { 42, new System.Collections.ArrayList(), typeof(Int32) }; internal static string[] ActualValues = new string[] { "", "", "" }; internal static object[] InvalidData = new TestCaseData[] { new TestCaseData(null).Throws(typeof(ArgumentNullException)) }; } public class PropertyTest : ConstraintTestBaseWithExceptionTests { [SetUp] public void SetUp() { theConstraint = new PropertyConstraint("Length", new EqualConstraint(5)); expectedDescription = "property Length equal to 5"; stringRepresentation = ">"; } internal static object[] SuccessData = new object[] { new int[5], "hello" }; internal static object[] FailureData = new object[] { new int[3], "goodbye" }; internal static string[] ActualValues = new string[] { "3", "7" }; internal static object[] InvalidData = new object[] { new TestCaseData(null).Throws(typeof(ArgumentNullException)), new TestCaseData(42).Throws(typeof(ArgumentException)), new TestCaseData(new System.Collections.ArrayList()).Throws(typeof(ArgumentException)) }; [Test] public void PropertyEqualToValueWithTolerance() { Constraint c = new EqualConstraint(105m).Within(0.1m); TextMessageWriter w = new TextMessageWriter(); c.WriteDescriptionTo(w); Assert.That(w.ToString(), Is.EqualTo("105m +/- 0.1m")); c = new PropertyConstraint("D", new EqualConstraint(105m).Within(0.1m)); w = new TextMessageWriter(); c.WriteDescriptionTo(w); Assert.That(w.ToString(), Is.EqualTo("property D equal to 105m +/- 0.1m")); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/Constraints/NUnitEqualityComparerTests.cs0000664000175000017500000001012611651233566030160 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Constraints { [TestFixture] public class EqualityComparerTests { private Tolerance tolerance; private NUnitEqualityComparer comparer; [SetUp] public void Setup() { tolerance = Tolerance.Zero; comparer = new NUnitEqualityComparer(); } [Test] public void CanCompareArrayContainingSelfToSelf() { object[] array = new object[1]; array[0] = array; Assert.True(comparer.AreEqual(array, array, ref tolerance)); } #if CLR_2_0 || CLR_4_0 [Test] public void IEquatableSuccess() { IEquatableWithoutEqualsOverridden x = new IEquatableWithoutEqualsOverridden(1); IEquatableWithoutEqualsOverridden y = new IEquatableWithoutEqualsOverridden(1); Assert.IsTrue(comparer.AreEqual(x, y, ref tolerance)); } [Test] public void IEquatableDifferentTypesSuccess_WhenActualImplementsIEquatable() { int x = 1; Int32IEquatable y = new Int32IEquatable(1); // y.Equals(x) is what gets actually called // TODO: This should work both ways Assert.IsTrue(comparer.AreEqual(x, y, ref tolerance)); } [Test] public void IEquatableDifferentTypesSuccess_WhenExpectedImplementsIEquatable() { int x = 1; Int32IEquatable y = new Int32IEquatable(1); // y.Equals(x) is what gets actually called // TODO: This should work both ways Assert.IsTrue(comparer.AreEqual(y, x, ref tolerance)); } [Test] public void ReferenceEqualityHasPrecedenceOverIEquatable() { NeverEqualIEquatable z = new NeverEqualIEquatable(); Assert.IsTrue(comparer.AreEqual(z, z, ref tolerance)); } [Test] public void IEquatableHasPrecedenceOverDefaultEquals() { NeverEqualIEquatableWithOverriddenAlwaysTrueEquals x = new NeverEqualIEquatableWithOverriddenAlwaysTrueEquals(); NeverEqualIEquatableWithOverriddenAlwaysTrueEquals y = new NeverEqualIEquatableWithOverriddenAlwaysTrueEquals(); Assert.IsFalse(comparer.AreEqual(x, y, ref tolerance)); } #endif } #if CLR_2_0 || CLR_4_0 public class NeverEqualIEquatableWithOverriddenAlwaysTrueEquals : IEquatable { public bool Equals(NeverEqualIEquatableWithOverriddenAlwaysTrueEquals other) { return false; } public override bool Equals(object obj) { return true; } public override int GetHashCode() { return base.GetHashCode(); } } public class Int32IEquatable : IEquatable { private readonly int value; public Int32IEquatable(int value) { this.value = value; } public bool Equals(int other) { return value.Equals(other); } } public class NeverEqualIEquatable : IEquatable { public bool Equals(NeverEqualIEquatable other) { return false; } } public class IEquatableWithoutEqualsOverridden : IEquatable { private readonly int value; public IEquatableWithoutEqualsOverridden(int value) { this.value = value; } public bool Equals(IEquatableWithoutEqualsOverridden other) { return value.Equals(other.value); } } #endif } NUnit-2.6.0.12051/src/NUnitFramework/tests/CollectionAssertTest.cs0000664000175000017500000004656011654252666024517 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; #if NET_3_5 || NET_4_0 using System.Linq; #endif namespace NUnit.Framework.Tests { /// /// Test Library for the NUnit CollectionAssert class. /// [TestFixture()] public class CollectionAssertTest : MessageChecker { #region AllItemsAreInstancesOfType [Test()] public void ItemsOfType() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); CollectionAssert.AllItemsAreInstancesOfType(al,typeof(string)); } [Test,ExpectedException(typeof(AssertionException))] public void ItemsOfTypeFailure() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add(new object()); expectedMessage = " Expected: all items instance of " + Environment.NewLine + " But was: < \"x\", \"y\", >" + Environment.NewLine; CollectionAssert.AllItemsAreInstancesOfType(al,typeof(string)); } #endregion #region AllItemsAreNotNull [Test()] public void ItemsNotNull() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); CollectionAssert.AllItemsAreNotNull(al); } [Test, ExpectedException(typeof(AssertionException))] public void ItemsNotNullFailure() { ArrayList al = new ArrayList(); al.Add("x"); al.Add(null); al.Add("z"); expectedMessage = " Expected: all items not null" + Environment.NewLine + " But was: < \"x\", null, \"z\" >" + Environment.NewLine; CollectionAssert.AllItemsAreNotNull(al); } #endregion #region AllItemsAreUnique [Test] public void Unique_WithObjects() { CollectionAssert.AllItemsAreUnique( new ICollectionAdapter( new object(), new object(), new object() ) ); } [Test] public void Unique_WithStrings() { CollectionAssert.AllItemsAreUnique( new ICollectionAdapter( "x", "y", "z" ) ); } [Test] public void Unique_WithNull() { CollectionAssert.AllItemsAreUnique( new ICollectionAdapter( "x", "y", null, "z" ) ); } [Test,ExpectedException(typeof(AssertionException))] public void UniqueFailure() { expectedMessage = " Expected: all items unique" + Environment.NewLine + " But was: < \"x\", \"y\", \"x\" >" + Environment.NewLine; CollectionAssert.AllItemsAreUnique( new ICollectionAdapter( "x", "y", "x" ) ); } [Test,ExpectedException(typeof(AssertionException))] public void UniqueFailure_WithTwoNulls() { CollectionAssert.AllItemsAreUnique( new ICollectionAdapter( "x", null, "y", null, "z" ) ); } #endregion #region AreEqual [Test] public void AreEqual() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("z"); CollectionAssert.AreEqual(set1,set2); CollectionAssert.AreEqual(set1,set2,new TestComparer()); Assert.AreEqual(set1,set2); } [Test,ExpectedException(typeof(AssertionException))] public void AreEqualFailCount() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("z"); set2.Add("a"); expectedMessage = " Expected is with 3 elements, actual is with 4 elements" + Environment.NewLine + " Values differ at index [3]" + Environment.NewLine + " Extra: < \"a\" >"; CollectionAssert.AreEqual(set1,set2,new TestComparer()); } [Test, ExpectedException(typeof(AssertionException))] public void AreEqualFail() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("a"); expectedMessage = " Expected and actual are both with 3 elements" + Environment.NewLine + " Values differ at index [2]" + Environment.NewLine + " String lengths are both 1. Strings differ at index 0." + Environment.NewLine + " Expected: \"z\"" + Environment.NewLine + " But was: \"a\"" + Environment.NewLine + " -----------^" + Environment.NewLine; CollectionAssert.AreEqual(set1,set2,new TestComparer()); } [Test] public void AreEqual_HandlesNull() { object[] set1 = new object[3]; object[] set2 = new object[3]; CollectionAssert.AreEqual(set1,set2); CollectionAssert.AreEqual(set1,set2,new TestComparer()); } [Test] public void EnsureComparerIsUsed() { // Create two collections int[] array1 = new int[2]; int[] array2 = new int[2]; array1[0] = 4; array1[1] = 5; array2[0] = 99; array2[1] = -99; CollectionAssert.AreEqual(array1, array2, new AlwaysEqualComparer()); } #if CLR_2_0 || CLR_4_0 [Test] public void AreEqual_UsingIterator() { int[] array = new int[] { 1, 2, 3 }; CollectionAssert.AreEqual(array, CountToThree()); } IEnumerable CountToThree() { yield return 1; yield return 2; yield return 3; } [Test] public void AreEqual_UsingIterator_Fails() { int[] array = new int[] { 1, 3, 5 }; Assert.That( delegate { CollectionAssert.AreEqual(array, CountToThree()); }, Throws.TypeOf() .With.Message.EndsWith("Expected: 3" + Environment.NewLine + " But was: 2" + Environment.NewLine)); } #endif #if NET_3_5 || CLR_4_0 [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void AreEqual_UsingLinqQuery() { int[] array = new int[] { 1, 2, 3 }; CollectionAssert.AreEqual(array, array.Select((item) => item)); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0,Mono-4.0")] public void AreEqual_UsingLinqQuery_Fails() { int[] array = new int[] { 1, 2, 3 }; Assert.That( delegate { CollectionAssert.AreEqual(array, array.Select((item) => item * 2)); }, Throws.TypeOf() .With.Message.EndsWith("Expected: 1" + Environment.NewLine + " But was: 2" + Environment.NewLine)); } #endif #endregion #region AreEquivalent [Test] public void Equivalent() { ICollection set1 = new ICollectionAdapter( "x", "y", "z" ); ICollection set2 = new ICollectionAdapter( "z", "y", "x" ); CollectionAssert.AreEquivalent(set1,set2); } [Test, ExpectedException(typeof(AssertionException))] public void EquivalentFailOne() { ICollection set1 = new ICollectionAdapter( "x", "y", "z" ); ICollection set2 = new ICollectionAdapter( "x", "y", "x" ); expectedMessage = " Expected: equivalent to < \"x\", \"y\", \"z\" >" + Environment.NewLine + " But was: < \"x\", \"y\", \"x\" >" + Environment.NewLine; CollectionAssert.AreEquivalent(set1,set2); } [Test, ExpectedException(typeof(AssertionException))] public void EquivalentFailTwo() { ICollection set1 = new ICollectionAdapter( "x", "y", "x" ); ICollection set2 = new ICollectionAdapter( "x", "y", "z" ); expectedMessage = " Expected: equivalent to < \"x\", \"y\", \"x\" >" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.AreEquivalent(set1,set2); } [Test] public void AreEquivalentHandlesNull() { ICollection set1 = new ICollectionAdapter( null, "x", null, "z" ); ICollection set2 = new ICollectionAdapter( "z", null, "x", null ); CollectionAssert.AreEquivalent(set1,set2); } #endregion #region AreNotEqual [Test] public void AreNotEqual() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("x"); CollectionAssert.AreNotEqual(set1,set2); CollectionAssert.AreNotEqual(set1,set2,new TestComparer()); CollectionAssert.AreNotEqual(set1,set2,"test"); CollectionAssert.AreNotEqual(set1,set2,new TestComparer(),"test"); CollectionAssert.AreNotEqual(set1,set2,"test {0}","1"); CollectionAssert.AreNotEqual(set1,set2,new TestComparer(),"test {0}","1"); } [Test, ExpectedException(typeof(AssertionException))] public void AreNotEqual_Fails() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("z"); expectedMessage = " Expected: not < \"x\", \"y\", \"z\" >" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.AreNotEqual(set1,set2); } [Test] public void AreNotEqual_HandlesNull() { object[] set1 = new object[3]; ArrayList set2 = new ArrayList(); set2.Add("x"); set2.Add("y"); set2.Add("z"); CollectionAssert.AreNotEqual(set1,set2); CollectionAssert.AreNotEqual(set1,set2,new TestComparer()); } #endregion #region AreNotEquivalent [Test] public void NotEquivalent() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("y"); set2.Add("x"); CollectionAssert.AreNotEquivalent(set1,set2); } [Test, ExpectedException(typeof(AssertionException))] public void NotEquivalent_Fails() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); set2.Add("x"); set2.Add("z"); set2.Add("y"); expectedMessage = " Expected: not equivalent to < \"x\", \"y\", \"z\" >" + Environment.NewLine + " But was: < \"x\", \"z\", \"y\" >" + Environment.NewLine; CollectionAssert.AreNotEquivalent(set1,set2); } [Test] public void NotEquivalentHandlesNull() { ArrayList set1 = new ArrayList(); ArrayList set2 = new ArrayList(); set1.Add("x"); set1.Add(null); set1.Add("z"); set2.Add("x"); set2.Add(null); set2.Add("x"); CollectionAssert.AreNotEquivalent(set1,set2); } #endregion #region Contains [Test] public void Contains_IList() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); CollectionAssert.Contains(al,"x"); } [Test] public void Contains_ICollection() { ICollectionAdapter ca = new ICollectionAdapter( new string[] { "x", "y", "z" } ); CollectionAssert.Contains(ca,"x"); } [Test, ExpectedException(typeof(AssertionException))] public void ContainsFails_ILIst() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); expectedMessage = " Expected: collection containing \"a\"" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.Contains(al,"a"); } [Test, ExpectedException(typeof(AssertionException))] public void ContainsFails_ICollection() { ICollectionAdapter ca = new ICollectionAdapter( new string[] { "x", "y", "z" } ); expectedMessage = " Expected: collection containing \"a\"" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.Contains(ca,"a"); } [Test, ExpectedException(typeof(AssertionException))] public void ContainsFails_EmptyIList() { ArrayList al = new ArrayList(); expectedMessage = " Expected: collection containing \"x\"" + Environment.NewLine + " But was: " + Environment.NewLine; CollectionAssert.Contains(al,"x"); } [Test, ExpectedException(typeof(AssertionException))] public void ContainsFails_EmptyICollection() { ICollectionAdapter ca = new ICollectionAdapter( new object[0] ); expectedMessage = " Expected: collection containing \"x\"" + Environment.NewLine + " But was: " + Environment.NewLine; CollectionAssert.Contains(ca,"x"); } [Test] public void ContainsNull_IList() { Object[] oa = new object[] { 1, 2, 3, null, 4, 5 }; CollectionAssert.Contains( oa, null ); } [Test] public void ContainsNull_ICollection() { ICollectionAdapter ca = new ICollectionAdapter( new object[] { 1, 2, 3, null, 4, 5 } ); CollectionAssert.Contains( ca, null ); } #endregion #region DoesNotContain [Test] public void DoesNotContain() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); CollectionAssert.DoesNotContain(al,"a"); } [Test] public void DoesNotContain_Empty() { ArrayList al = new ArrayList(); CollectionAssert.DoesNotContain(al,"x"); } [Test,ExpectedException(typeof(AssertionException))] public void DoesNotContain_Fails() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); expectedMessage = " Expected: not collection containing \"y\"" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.DoesNotContain(al,"y"); } #endregion #region IsSubsetOf [Test] public void IsSubsetOf() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); ArrayList set2 = new ArrayList(); set2.Add("y"); set2.Add("z"); CollectionAssert.IsSubsetOf(set2,set1); Expect(set2, SubsetOf(set1)); } [Test,ExpectedException(typeof(AssertionException))] public void IsSubsetOf_Fails() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); ArrayList set2 = new ArrayList(); set2.Add("y"); set2.Add("z"); set2.Add("a"); expectedMessage = " Expected: subset of < \"y\", \"z\", \"a\" >" + Environment.NewLine + " But was: < \"x\", \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.IsSubsetOf(set1,set2); } [Test] public void IsSubsetOfHandlesNull() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add(null); set1.Add("z"); ArrayList set2 = new ArrayList(); set2.Add(null); set2.Add("z"); CollectionAssert.IsSubsetOf(set2,set1); Expect(set2, SubsetOf(set1)); } #endregion #region IsNotSubsetOf [Test] public void IsNotSubsetOf() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); ArrayList set2 = new ArrayList(); set1.Add("y"); set1.Add("z"); set2.Add("a"); CollectionAssert.IsNotSubsetOf(set1,set2); Expect(set1, Not.SubsetOf(set2)); } [Test,ExpectedException(typeof(AssertionException))] public void IsNotSubsetOf_Fails() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add("y"); set1.Add("z"); ArrayList set2 = new ArrayList(); set2.Add("y"); set2.Add("z"); expectedMessage = " Expected: not subset of < \"x\", \"y\", \"z\" >" + Environment.NewLine + " But was: < \"y\", \"z\" >" + Environment.NewLine; CollectionAssert.IsNotSubsetOf(set2,set1); } [Test] public void IsNotSubsetOfHandlesNull() { ArrayList set1 = new ArrayList(); set1.Add("x"); set1.Add(null); set1.Add("z"); ArrayList set2 = new ArrayList(); set1.Add(null); set1.Add("z"); set2.Add("a"); CollectionAssert.IsNotSubsetOf(set1,set2); } #endregion #region IsOrdered [Test] public void IsOrdered() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("y"); al.Add("z"); CollectionAssert.IsOrdered(al); } [Test, ExpectedException(typeof(AssertionException))] public void IsOrdered_Fails() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("z"); al.Add("y"); expectedMessage = " Expected: collection ordered" + Environment.NewLine + " But was: < \"x\", \"z\", \"y\" >" + Environment.NewLine; CollectionAssert.IsOrdered(al); } [Test] public void IsOrdered_Allows_adjacent_equal_values() { ArrayList al = new ArrayList(); al.Add("x"); al.Add("x"); al.Add("z"); CollectionAssert.IsOrdered(al); } [Test, ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "index 1", MatchType = MessageMatch.Contains)] public void IsOrdered_Handles_null() { ArrayList al = new ArrayList(); al.Add("x"); al.Add(null); al.Add("z"); CollectionAssert.IsOrdered(al); } [Test, ExpectedException(typeof(ArgumentException))] public void IsOrdered_ContainedTypesMustBeCompatible() { ArrayList al = new ArrayList(); al.Add(1); al.Add("x"); CollectionAssert.IsOrdered(al); } [Test, ExpectedException(typeof(ArgumentException))] public void IsOrdered_TypesMustImplementIComparable() { ArrayList al = new ArrayList(); al.Add(new object()); al.Add(new object()); CollectionAssert.IsOrdered(al); } [Test] public void IsOrdered_Handles_custom_comparison() { ArrayList al = new ArrayList(); al.Add(new object()); al.Add(new object()); CollectionAssert.IsOrdered(al, new AlwaysEqualComparer()); } [Test] public void IsOrdered_Handles_custom_comparison2() { ArrayList al = new ArrayList(); al.Add(2); al.Add(1); CollectionAssert.IsOrdered(al, new TestComparer()); } #endregion } public class TestComparer : IComparer { public bool Called = false; #region IComparer Members public int Compare(object x, object y) { Called = true; if ( x == null && y == null ) return 0; if ( x == null || y == null ) return -1; if (x.Equals(y)) return 0; return -1; } #endregion } public class AlwaysEqualComparer : IComparer { public bool Called = false; int IComparer.Compare(object x, object y) { Called = true; // This comparer ALWAYS returns zero (equal)! return 0; } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/ConditionAssertTests.cs0000664000175000017500000001334211666106276024523 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Threading; using System.Globalization; using NUnit.Framework; namespace NUnit.Framework.Tests { [TestFixture] public class ConditionAssertTests : MessageChecker { [Test] public void IsTrue() { Assert.IsTrue(true); } [Test,ExpectedException(typeof(AssertionException))] public void IsTrueFails() { expectedMessage = " Expected: True" + Environment.NewLine + " But was: False" + Environment.NewLine; Assert.IsTrue(false); } [Test] public void IsFalse() { Assert.IsFalse(false); } [Test] [ExpectedException(typeof(AssertionException))] public void IsFalseFails() { expectedMessage = " Expected: False" + Environment.NewLine + " But was: True" + Environment.NewLine; Assert.IsFalse(true); } [Test] public void IsNull() { Assert.IsNull(null); } [Test] [ExpectedException(typeof(AssertionException))] public void IsNullFails() { String s1 = "S1"; expectedMessage = " Expected: null" + Environment.NewLine + " But was: \"S1\"" + Environment.NewLine; Assert.IsNull(s1); } [Test] public void IsNotNull() { String s1 = "S1"; Assert.IsNotNull(s1); } [Test] [ExpectedException(typeof(AssertionException))] public void IsNotNullFails() { expectedMessage = " Expected: not null" + Environment.NewLine + " But was: null" + Environment.NewLine; Assert.IsNotNull(null); } [Test] public void IsNaN() { Assert.IsNaN(double.NaN); } [Test] [ExpectedException(typeof(AssertionException))] public void IsNaNFails() { expectedMessage = " Expected: NaN" + Environment.NewLine + " But was: 10.0d" + Environment.NewLine; Assert.IsNaN(10.0); } [Test] public void IsEmpty() { Assert.IsEmpty( "", "Failed on empty String" ); Assert.IsEmpty( new int[0], "Failed on empty Array" ); Assert.IsEmpty( new ArrayList(), "Failed on empty ArrayList" ); Assert.IsEmpty( new Hashtable(), "Failed on empty Hashtable" ); Assert.IsEmpty( (IEnumerable)new int[0], "Failed on empty IEnumerable"); } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsOnString() { expectedMessage = " Expected: " + Environment.NewLine + " But was: \"Hi!\"" + Environment.NewLine; Assert.IsEmpty( "Hi!" ); } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsOnNullString() { expectedMessage = " Expected: " + Environment.NewLine + " But was: null" + Environment.NewLine; Assert.IsEmpty( (string)null ); } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsOnNonEmptyArray() { expectedMessage = " Expected: " + Environment.NewLine + " But was: < 1, 2, 3 >" + Environment.NewLine; Assert.IsEmpty(new int[] { 1, 2, 3 }); } [Test, ExpectedException(typeof(AssertionException))] public void IsEmptyFailsOnNonEmptyIEnumerable() { expectedMessage = " Expected: " + Environment.NewLine + " But was: < 1, 2, 3 >" + Environment.NewLine; Assert.IsEmpty((IEnumerable)new int[] { 1, 2, 3 }); } [Test] public void IsNotEmpty() { int[] array = new int[] { 1, 2, 3 }; ArrayList list = new ArrayList( array ); Hashtable hash = new Hashtable(); hash.Add( "array", array ); Assert.IsNotEmpty( "Hi!", "Failed on String" ); Assert.IsNotEmpty( array, "Failed on Array" ); Assert.IsNotEmpty( list, "Failed on ArrayList" ); Assert.IsNotEmpty( hash, "Failed on Hashtable" ); Assert.IsNotEmpty((IEnumerable)array, "Failed on IEnumerable"); } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsOnEmptyString() { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.IsNotEmpty( "" ); } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsOnEmptyArray() { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.IsNotEmpty( new int[0] ); } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsOnEmptyArrayList() { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.IsNotEmpty( new ArrayList() ); } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsOnEmptyHashTable() { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.IsNotEmpty(new Hashtable()); } [Test, ExpectedException(typeof(AssertionException))] public void IsNotEmptyFailsOnEmptyIEnumerable() { expectedMessage = " Expected: not " + Environment.NewLine + " But was: " + Environment.NewLine; Assert.IsNotEmpty((IEnumerable)new int[0]); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/nunit.framework.tests.build0000664000175000017500000001162111651233750025342 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitFramework/tests/data/0000775000175000017500000000000011742560362020742 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/tests/data/TestImage2.jpg0000664000175000017500000001213711504175260023407 0ustar jtaylorjtaylorJFIF"  # !"!%'$ '!!    }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?cڝ1_cqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.7cڝ1EqF=أX.;bהBbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( 1KE&(-rQbRG( j1N{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur{Qjur(I (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (1F(Q9@(bP (`QN 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qp(`QG( F7 vr 0)`Qڌ{R[rL{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(1F=hǵPcږ9@L{QjZ(RZq(PRG(\J)h.%QZ( E-rĢ9BQKEq(PRG(\J)h.%QZ( E-rĢ9BQKEq(PRG(\J)h.%QZ( E-rĢ9BQKEq(PRG(\J)h.%QZ( E-rĢ9BQKEq(PRG(\J)h.%QZ( E-rĢ9BQKEq(PJ0=)p(yD&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`Q`zQKF&`QQND7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(7 v(-VĢ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,Z(\J)hq(Ģ,j1KEkHԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQcڌ{RG( j1KE&=ǵ-rԴQS(qF)`Q`1NQvXS(7bF 0( `QEn(; ,qF)`Q`1NQvXS(7bF 0( `QEn(; ,qF)`Q`1NQvXS(7bF 0( `QEn(; ,qF)`Q`1NQvXS(7bF 0( `QEn(; ,qF)`Q`1NQvXS(7bF 0( `QEn(; ,qF)`Q`FV$0=(,FQ` J0=(`zQEXҌJ(`zQEҊ(QE0=(,FQ` J0=(`zQEXҌJ(`zQEҊ(QE0=(,FQ` J0=(`zQEXҌJ(`zQEҊ(QE0=(,FQ` J0=(`zQEXҌJ(`zQEҊ(QE0=(,FQ` J0=(`zQEXҌJ(`zQEҊ(QE0=(,NUnit-2.6.0.12051/src/NUnitFramework/tests/data/TestText1.txt0000664000175000017500000020010011504175260023334 0ustar jtaylorjtaylor12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 1234567890123456789012345678901234567890123456789012345678901234567890123456789! NUnit-2.6.0.12051/src/NUnitFramework/tests/data/TestImage1.jpg0000664000175000017500000001414611504175260023410 0ustar jtaylorjtaylorJFIF"  # !"!%'$ '!!    }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?#}-n|QnuR]oQ).7[EÔ}-nK7Qp%Fur}E\9IwѾF.QnuR]oQ).7[EÔ}-nK7Qp%Fur}E\9IwѾF.QnuR]oQ).7[EÔ}-nK7Qp%Fur}E\9IwѾF.QnuR]oQ).7[EÔ}-nK7Qp%Fur}E\9IwѾF.QnuR]oQ).7[EÔ}-nK7Qp%Fur}E\9IwѾF.QnuRowѾ)6z7;EÔoMލ7p&Fz}roC\9IѿޡF.P}RmowѾ)6z7;EÔoMލ7p&Fz}roC\9IѿޡF.P}RmowѾ)6z7;EÔoMލ7p&Fz}roC\9IѿޡF.P}RmowѾ)6z7;EÔoMލ7p&Fz}roC\9IѿޡF.P}RmowѾ)6z7;EÔoMލ7p&Fz}roC\9IѿޡF.P}RmowѾ)6z7;EÔuotrnuC\9IQF.ۨP}RmnwѾ)67T;EÔuoM7p&F}rnuC\9IQF.ۨP}RmnwѾ)67T;EÔuoM7p&F}rnuC\9IQF.ۨP}RmnwѾ)67T;EÔuoM7p&F}rnuC\9IQF.ۨP}RmnwѾ)67T;EÔuoM7p&F}rnuC\9IQF.ۨP}RmnwѾ)67T;EÔuoM7p&F}rnuC\9HwѿޢFܤQo}R]oѾ).z7[EÔ-oKލ7p%Fz}rE\9IwѿޢF.Qo}R]oѾ).z7[EÔ-oKލ7p%Fz}rE\9IwѿޢF.Qo}R]oѾ).z7[EÔ-oKލ7p%Fz}rE\9IwѿޢF.Qo}R]oѾ).z7[EÔ-oKލ7p%Fz}rE\9IwѿޢF.Qo}R]oѾ).z7[EÔ-oKލ7p%Fz}rE\9IwѿޢF.Qo}R owѾ7&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RmowѾ`&F}RowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}omM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p!F};o}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9HwѾFǘߔ}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9IѾF9}o9HwѾFP}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}ooM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p&F}ro}C\9IѾF.P}RmowѾ)67;EÔ}oM7p!Fe}2ѾEaLoQ@X~7(,?}P( Fe}2ѾEaLoQ@X~7(,?}P( Fe}2ѾEaLoQ@X~7(,?}P( Fe}2ѾEaLoQ@X~7(,?}P( Fe}2ѾEaLoQ@X~7(,?}P( Fe}2NUnit-2.6.0.12051/src/NUnitFramework/tests/data/TestText2.txt0000664000175000017500000020010011504175260023335 0ustar jtaylorjtaylor12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890 NUnit-2.6.0.12051/src/NUnitFramework/tests/ArrayEqualsFailureMessageFixture.cs0000664000175000017500000002677211651471336027014 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Tests { /// /// Summary description for ArrayEqualsFailureMessageFixture. /// [TestFixture] public class ArrayEqualsFailureMessageFixture : MessageChecker { [Test, ExpectedException(typeof(AssertionException))] public void ArraysHaveDifferentRanks() { int[] expected = new int[] { 1, 2, 3, 4 }; int[,] actual = new int[,] { { 1, 2 }, { 3, 4 } }; expectedMessage = " Expected is , actual is " + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void ExpectedArrayIsLonger() { int[] expected = new int[] { 1, 2, 3, 4, 5 }; int[] actual = new int[] { 1, 2, 3 }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at index [3]" + Environment.NewLine + " Missing: < 4, 5 >"; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void ActualArrayIsLonger() { int[] expected = new int[] { 1, 2, 3 }; int[] actual = new int[] { 1, 2, 3, 4, 5, 6, 7 }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at index [3]" + Environment.NewLine + " Extra: < 4, 5, 6... >"; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void FailureOnSingleDimensionedArrays() { int[] expected = new int[] { 1, 2, 3 }; int[] actual = new int[] { 1, 5, 3 }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [1]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "2" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "5" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void DoubleDimensionedArrays() { int[,] expected = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; int[,] actual = new int[,] { { 1, 3, 2 }, { 4, 0, 6 } }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [0,1]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "2" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "3" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void TripleDimensionedArrays() { int[, ,] expected = new int[,,] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }; int[, ,] actual = new int[,,] { { { 1, 2 }, { 3, 4 } }, { { 0, 6 }, { 7, 8 } } }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [1,0,0]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "5" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "0" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void FiveDimensionedArrays() { int[, , , ,] expected = new int[2, 2, 2, 2, 2] { { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } }, { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } } }; int[, , , ,] actual = new int[2, 2, 2, 2, 2] { { { { { 1, 2 }, { 4, 3 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } }, { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } } }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [0,0,0,1,0]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "3" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "4" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void JaggedArrays() { int[][] expected = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6, 7 }, new int[] { 8, 9 } }; int[][] actual = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 0, 7 }, new int[] { 8, 9 } }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [1]" + Environment.NewLine + " Expected and actual are both " + Environment.NewLine + " Values differ at index [2]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "6" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "0" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void JaggedArrayComparedToSimpleArray() { int[] expected = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int[][] actual = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 0, 7 }, new int[] { 8, 9 } }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at index [0]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "1" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "< 1, 2, 3 >" + Environment.NewLine; Expect(actual, EqualTo(expected)); } [Test, ExpectedException(typeof(AssertionException))] public void ArraysWithDifferentRanksAsCollection() { int[] expected = new int[] { 1, 2, 3, 4 }; int[,] actual = new int[,] { { 1, 0 }, { 3, 4 } }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at expected index [1], actual index [0,1]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "2" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "0" + Environment.NewLine; Expect(actual, EqualTo(expected).AsCollection); } [Test, ExpectedException(typeof(AssertionException))] public void ArraysWithDifferentDimensionsAsCollection() { int[,] expected = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; int[,] actual = new int[,] { { 1, 2 }, { 3, 0 }, { 5, 6 } }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at expected index [1,0], actual index [1,1]" + Environment.NewLine + TextMessageWriter.Pfx_Expected + "4" + Environment.NewLine + TextMessageWriter.Pfx_Actual + "0" + Environment.NewLine; Expect(actual, EqualTo(expected).AsCollection); } // [Test,ExpectedException(typeof(AssertionException))] // public void ExpectedArrayIsLonger() // { // string[] array1 = { "one", "two", "three" }; // string[] array2 = { "one", "two", "three", "four", "five" }; // // expectedMessage = // " Expected is , actual is " + Environment.NewLine + // " Values differ at index [3]" + Environment.NewLine + // " Missing: < \"four\", \"five\" >"; // Expect(array1, EqualTo(array2)); // } [Test, ExpectedException(typeof(AssertionException))] public void SameLengthDifferentContent() { string[] array1 = { "one", "two", "three" }; string[] array2 = { "one", "two", "ten" }; expectedMessage = " Expected and actual are both " + Environment.NewLine + " Values differ at index [2]" + Environment.NewLine + " Expected string length 3 but was 5. Strings differ at index 1." + Environment.NewLine + " Expected: \"ten\"" + Environment.NewLine + " But was: \"three\"" + Environment.NewLine + " ------------^" + Environment.NewLine; Expect(array1, EqualTo(array2)); } [Test, ExpectedException(typeof(AssertionException))] public void ArraysDeclaredAsDifferentTypes() { string[] array1 = { "one", "two", "three" }; object[] array2 = { "one", "three", "two" }; expectedMessage = " Expected is , actual is " + Environment.NewLine + " Values differ at index [1]" + Environment.NewLine + " Expected string length 5 but was 3. Strings differ at index 1." + Environment.NewLine + " Expected: \"three\"" + Environment.NewLine + " But was: \"two\"" + Environment.NewLine + " ------------^" + Environment.NewLine; Expect(array1, EqualTo(array2)); } [Test, ExpectedException(typeof(AssertionException))] public void ArrayAndCollection_Failure() { int[] a = new int[] { 1, 2, 3 }; ArrayList b = new ArrayList(); b.Add(1); b.Add(3); Assert.AreEqual(a, b); } [Test, ExpectedException(typeof(AssertionException))] public void DifferentArrayTypesEqualFails() { string[] array1 = { "one", "two", "three" }; object[] array2 = { "one", "three", "two" }; expectedMessage = " Expected is , actual is " + System.Environment.NewLine + " Values differ at index [1]" + System.Environment.NewLine + " Expected string length 3 but was 5. Strings differ at index 1." + System.Environment.NewLine + " Expected: \"two\"" + System.Environment.NewLine + " But was: \"three\"" + System.Environment.NewLine + " ------------^" + System.Environment.NewLine; Assert.AreEqual(array1, array2); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/ArrayEqualsFixture.cs0000664000175000017500000001474211504175260024163 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Tests { /// /// Summary description for ArrayEqualTests. /// [TestFixture] public class ArrayEqualsFixture : AssertionHelper { [Test] public void ArrayIsEqualToItself() { string[] array = { "one", "two", "three" }; Assert.AreSame( array, array ); Assert.AreEqual( array, array ); Expect(array, EqualTo(array)); } [Test] public void ArraysOfString() { string[] array1 = { "one", "two", "three" }; string[] array2 = { "one", "two", "three" }; Assert.IsFalse( array1 == array2 ); Assert.AreEqual(array1, array2); Expect(array1, EqualTo(array2)); Assert.AreEqual(array2, array1); Expect(array2, EqualTo(array1)); } [Test] public void ArraysOfInt() { int[] a = new int[] { 1, 2, 3 }; int[] b = new int[] { 1, 2, 3 }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArraysOfDouble() { double[] a = new double[] { 1.0, 2.0, 3.0 }; double[] b = new double[] { 1.0, 2.0, 3.0 }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArraysOfDecimal() { decimal[] a = new decimal[] { 1.0m, 2.0m, 3.0m }; decimal[] b = new decimal[] { 1.0m, 2.0m, 3.0m }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArrayOfIntAndArrayOfDouble() { int[] a = new int[] { 1, 2, 3 }; double[] b = new double[] { 1.0, 2.0, 3.0 }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArraysDeclaredAsDifferentTypes() { string[] array1 = { "one", "two", "three" }; object[] array2 = { "one", "two", "three" }; Assert.AreEqual( array1, array2, "String[] not equal to Object[]" ); Assert.AreEqual( array2, array1, "Object[] not equal to String[]" ); Expect(array1, EqualTo(array2), "String[] not equal to Object[]"); Expect(array2, EqualTo(array1), "Object[] not equal to String[]"); } [Test] public void ArraysOfMixedTypes() { DateTime now = DateTime.Now; object[] array1 = new object[] { 1, 2.0f, 3.5d, 7.000m, "Hello", now }; object[] array2 = new object[] { 1.0d, 2, 3.5, 7, "Hello", now }; Assert.AreEqual( array1, array2 ); Assert.AreEqual(array2, array1); Expect(array1, EqualTo(array2)); Expect(array2, EqualTo(array1)); } [Test] public void DoubleDimensionedArrays() { int[,] a = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; int[,] b = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void TripleDimensionedArrays() { int[, ,] expected = new int[,,] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }; int[,,] actual = new int[,,] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }; Assert.AreEqual(expected, actual); Expect(actual, EqualTo(expected)); } [Test] public void FiveDimensionedArrays() { int[, , , ,] expected = new int[2, 2, 2, 2, 2] { { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } }, { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } } }; int[, , , ,] actual = new int[2, 2, 2, 2, 2] { { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } }, { { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }, { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } } } }; Assert.AreEqual(expected, actual); Expect(actual, EqualTo(expected)); } [Test] public void ArraysOfArrays() { int[][] a = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } }; int[][] b = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void JaggedArrays() { int[][] expected = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6, 7 }, new int[] { 8, 9 } }; int[][] actual = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6, 7 }, new int[] { 8, 9 } }; Assert.AreEqual(expected, actual); Expect(actual, EqualTo(expected)); } [Test] public void ArraysPassedAsObjects() { object a = new int[] { 1, 2, 3 }; object b = new double[] { 1.0, 2.0, 3.0 }; Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArrayAndCollection() { int[] a = new int[] { 1, 2, 3 }; ICollection b = new ArrayList( a ); Assert.AreEqual(a, b); Assert.AreEqual(b, a); Expect(a, EqualTo(b)); Expect(b, EqualTo(a)); } [Test] public void ArraysWithDifferentRanksComparedAsCollection() { int[] expected = new int[] { 1, 2, 3, 4 }; int[,] actual = new int[,] { { 1, 2 }, { 3, 4 } }; Assert.AreNotEqual(expected, actual); Expect(actual, Not.EqualTo(expected)); Expect(actual, EqualTo(expected).AsCollection); } [Test] public void ArraysWithDifferentDimensionsMatchedAsCollection() { int[,] expected = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; int[,] actual = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 } }; Assert.AreNotEqual(expected, actual); Expect(actual, Not.EqualTo(expected)); Expect(actual, EqualTo(expected).AsCollection); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/NotEqualFixture.cs0000664000175000017500000000640611504175260023460 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class NotEqualFixture : MessageChecker { [Test] public void NotEqual() { Assert.AreNotEqual( 5, 3 ); } [Test, ExpectedException( typeof( AssertionException ) )] public void NotEqualFails() { expectedMessage = " Expected: not 5" + Environment.NewLine + " But was: 5" + Environment.NewLine; Assert.AreNotEqual( 5, 5 ); } [Test] public void NullNotEqualToNonNull() { Assert.AreNotEqual( null, 3 ); } [Test, ExpectedException( typeof( AssertionException ) )] public void NullEqualsNull() { expectedMessage = " Expected: not null" + Environment.NewLine + " But was: null" + Environment.NewLine; Assert.AreNotEqual( null, null ); } [Test] public void ArraysNotEqual() { Assert.AreNotEqual( new object[] { 1, 2, 3 }, new object[] { 1, 3, 2 } ); } [Test, ExpectedException( typeof( AssertionException ) )] public void ArraysNotEqualFails() { expectedMessage = " Expected: not < 1, 2, 3 >" + Environment.NewLine + " But was: < 1, 2, 3 >" + Environment.NewLine; Assert.AreNotEqual( new object[] { 1, 2, 3 }, new object[] { 1, 2, 3 } ); } [Test] public void UInt() { uint u1 = 5; uint u2 = 8; Assert.AreNotEqual( u1, u2 ); } [Test] public void NotEqualSameTypes() { byte b1 = 35; sbyte sb2 = 35; decimal d4 = 35; double d5 = 35; float f6 = 35; int i7 = 35; uint u8 = 35; long l9 = 35; short s10 = 35; ushort us11 = 35; System.Byte b12 = 35; System.SByte sb13 = 35; System.Decimal d14 = 35; System.Double d15 = 35; System.Single s16 = 35; System.Int32 i17 = 35; System.UInt32 ui18 = 35; System.Int64 i19 = 35; System.UInt64 ui20 = 35; System.Int16 i21 = 35; System.UInt16 i22 = 35; Assert.AreNotEqual(23, b1); Assert.AreNotEqual(23, sb2); Assert.AreNotEqual(23, d4); Assert.AreNotEqual(23, d5); Assert.AreNotEqual(23, f6); Assert.AreNotEqual(23, i7); Assert.AreNotEqual(23, u8); Assert.AreNotEqual(23, l9); Assert.AreNotEqual(23, s10); Assert.AreNotEqual(23, us11); Assert.AreNotEqual(23, b12); Assert.AreNotEqual(23, sb13); Assert.AreNotEqual(23, d14); Assert.AreNotEqual(23, d15); Assert.AreNotEqual(23, s16); Assert.AreNotEqual(23, i17); Assert.AreNotEqual(23, ui18); Assert.AreNotEqual(23, i19); Assert.AreNotEqual(23, ui20); Assert.AreNotEqual(23, i21); Assert.AreNotEqual(23, i22); } } }NUnit-2.6.0.12051/src/NUnitFramework/tests/StringAssertTests.cs0000664000175000017500000001067611504175260024040 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework.Tests { [TestFixture] public class StringAssertTests : MessageChecker { [Test] public void Contains() { StringAssert.Contains( "abc", "abc" ); StringAssert.Contains( "abc", "***abc" ); StringAssert.Contains( "abc", "**abc**" ); } [Test, ExpectedException(typeof(AssertionException))] public void ContainsFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "String containing \"abc\"" + System.Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"abxcdxbc\"" + System.Environment.NewLine; StringAssert.Contains("abc", "abxcdxbc"); } [Test] public void DoesNotContain() { StringAssert.DoesNotContain("x", "abc"); } [Test, ExpectedException(typeof(AssertionException))] public void DoesNotContainFails() { StringAssert.DoesNotContain("abc", "**abc**"); } [Test] public void StartsWith() { StringAssert.StartsWith( "abc", "abcdef" ); StringAssert.StartsWith( "abc", "abc" ); } [Test, ExpectedException(typeof(AssertionException))] public void StartsWithFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "String starting with \"xyz\"" + System.Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"abcxyz\"" + System.Environment.NewLine; StringAssert.StartsWith("xyz", "abcxyz"); } [Test] public void DoesNotStartWith() { StringAssert.DoesNotStartWith("x", "abc"); } [Test, ExpectedException(typeof(AssertionException))] public void DoesNotStartWithFails() { StringAssert.DoesNotStartWith("abc", "abc**"); } [Test] public void EndsWith() { StringAssert.EndsWith( "abc", "abc" ); StringAssert.EndsWith( "abc", "123abc" ); } [Test, ExpectedException(typeof(AssertionException))] public void EndsWithFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "String ending with \"xyz\"" + System.Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"abcdef\"" + System.Environment.NewLine; StringAssert.EndsWith( "xyz", "abcdef" ); } [Test] public void DoesNotEndWith() { StringAssert.DoesNotEndWith("x", "abc"); } [Test, ExpectedException(typeof(AssertionException))] public void DoesNotEndWithFails() { StringAssert.DoesNotEndWith("abc", "***abc"); } [Test] public void CaseInsensitiveCompare() { StringAssert.AreEqualIgnoringCase( "name", "NAME" ); } [Test, ExpectedException(typeof(AssertionException))] public void CaseInsensitiveCompareFails() { expectedMessage = " Expected string length 4 but was 5. Strings differ at index 4." + System.Environment.NewLine + TextMessageWriter.Pfx_Expected + "\"Name\", ignoring case" + System.Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"NAMES\"" + System.Environment.NewLine + " ---------------^" + System.Environment.NewLine; StringAssert.AreEqualIgnoringCase("Name", "NAMES"); } [Test] public void IsMatch() { StringAssert.IsMatch( "a?bc", "12a3bc45" ); } [Test, ExpectedException(typeof(AssertionException))] public void IsMatchFails() { expectedMessage = TextMessageWriter.Pfx_Expected + "String matching \"a?b*c\"" + System.Environment.NewLine + TextMessageWriter.Pfx_Actual + "\"12ab456\"" + System.Environment.NewLine; StringAssert.IsMatch("a?b*c", "12ab456"); } [Test] public void DifferentEncodingsOfSameStringAreNotEqual() { string input = "Hello World"; byte[] data = System.Text.Encoding.Unicode.GetBytes( input ); string garbage = System.Text.Encoding.UTF8.GetString( data ); Assert.AreNotEqual( input, garbage ); } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/NullableTypesTests.cs0000664000175000017500000001776011564560102024173 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { #if CLR_2_0 || CLR_4_0 #if !MONO [TestFixture, Category("Generics")] public class NullableTypesTests { [Test] public void CanTestForNull() { int? nullInt = null; int? five = 5; Assert.IsNull(nullInt); Assert.IsNotNull(five); Assert.That(nullInt, Is.Null); Assert.That(five, Is.Not.Null); } #if false [Test] public void CanCompareNullableInts() { int? five = 5; int? answer = 2 + 3; Assert.AreEqual(five, answer); Assert.AreEqual(five, 5); Assert.AreEqual(5, five); Assert.That(five, Is.EqualTo(answer)); Assert.That(five, Is.EqualTo(5)); Assert.That(5, Is.EqualTo(five)); Assert.Greater(five, 3); Assert.GreaterOrEqual(five, 5); Assert.Less(3, five); Assert.LessOrEqual(5, five); Assert.That(five, Is.GreaterThan(3)); Assert.That(five, Is.GreaterThanOrEqualTo(5)); //Assert.That(3, Is.LessThan(five)); //Assert.That(5, Is.LessThanOrEqualTo(five)); } [Test] public void CanCompareNullableDoubles() { double? five = 5.0; double? answer = 2.0 + 3.0; Assert.AreEqual(five, answer); Assert.AreEqual(five, 5.0); Assert.AreEqual(5.0, five); Assert.That(five, Is.EqualTo(answer)); Assert.That(five, Is.EqualTo(5.0)); Assert.That(5.0, Is.EqualTo(five)); Assert.Greater(five, 3.0); Assert.GreaterOrEqual(five, 5.0); Assert.Less(3.0, five); Assert.LessOrEqual(5.0, five); Assert.That(five, Is.GreaterThan(3.0)); Assert.That(five, Is.GreaterThanOrEqualTo(5.0)); //Assert.That(3.0, Is.LessThan(five)); //Assert.That(5.0, Is.LessThanOrEqualTo(five)); } #endif [Test] public void CanTestForNaN() { double? anNaN = Double.NaN; Assert.IsNaN(anNaN); Assert.That(anNaN, Is.NaN); } #if false [Test] public void CanCompareNullableDecimals() { decimal? five = 5m; decimal? answer = 2m + 3m; Assert.AreEqual(five, answer); Assert.AreEqual(five, 5m); Assert.AreEqual(5m, five); Assert.That(five, Is.EqualTo(answer)); Assert.That(five, Is.EqualTo(5m)); Assert.That(5m, Is.EqualTo(five)); Assert.Greater(five, 3m); Assert.GreaterOrEqual(five, 5m); Assert.Less(3m, five); Assert.LessOrEqual(5m, five); Assert.That(five, Is.GreaterThan(3m)); Assert.That(five, Is.GreaterThanOrEqualTo(5m)); //Assert.That(3m, Is.LessThan(five)); //Assert.That(5m, Is.LessThanOrEqualTo(five)); } #endif [Test] public void CanCompareWithTolerance() { double? five = 5.0; Assert.AreEqual(5.0000001, five, .0001); Assert.That( five, Is.EqualTo(5.0000001).Within(.0001)); float? three = 3.0f; Assert.AreEqual(3.00001f, three, .001); Assert.That( three, Is.EqualTo(3.00001f).Within(.001)); } private enum Colors { Red, Blue, Green } [Test] public void CanCompareNullableEnums() { Colors? color = Colors.Red; Colors? other = Colors.Red; Assert.AreEqual(color, other); Assert.AreEqual(color, Colors.Red); Assert.AreEqual(Colors.Red, color); } [Test] public void CanCompareNullableMixedNumerics() { int? int5 = 5; double? double5 = 5.0; decimal? decimal5 = 5.00m; Assert.AreEqual(int5, double5); Assert.AreEqual(int5, decimal5); Assert.AreEqual(double5, int5); Assert.AreEqual(double5, decimal5); Assert.AreEqual(decimal5, int5); Assert.AreEqual(decimal5, double5); Assert.That(int5, Is.EqualTo(double5)); Assert.That(int5, Is.EqualTo(decimal5)); Assert.That(double5, Is.EqualTo(int5)); Assert.That(double5, Is.EqualTo(decimal5)); Assert.That(decimal5, Is.EqualTo(int5)); Assert.That(decimal5, Is.EqualTo(double5)); Assert.AreEqual(5, double5); Assert.AreEqual(5, decimal5); Assert.AreEqual(5.0, int5); Assert.AreEqual(5.0, decimal5); Assert.AreEqual(5m, int5); Assert.AreEqual(5m, double5); Assert.That(5, Is.EqualTo(double5)); Assert.That(5, Is.EqualTo(decimal5)); Assert.That(5.0, Is.EqualTo(int5)); Assert.That(5.0, Is.EqualTo(decimal5)); Assert.That(5m, Is.EqualTo(int5)); Assert.That(5m, Is.EqualTo(double5)); Assert.AreEqual(double5, 5); Assert.AreEqual(decimal5, 5); Assert.AreEqual(int5, 5.0); Assert.AreEqual(decimal5, 5.0); Assert.AreEqual(int5, 5m); Assert.AreEqual(double5, 5m); Assert.That(double5, Is.EqualTo(5)); Assert.That(decimal5, Is.EqualTo(5)); Assert.That(int5, Is.EqualTo(5.0)); Assert.That(decimal5, Is.EqualTo(5.0)); Assert.That(int5, Is.EqualTo(5m)); Assert.That(double5, Is.EqualTo(5m)); #if false Assert.Greater(int5, 3.0); Assert.Greater(int5, 3m); Assert.Greater(double5, 3); Assert.Greater(double5, 3m); Assert.Greater(decimal5, 3); Assert.Greater(decimal5, 3.0); Assert.That(int5, Is.GreaterThan(3.0)); Assert.That(int5, Is.GreaterThan(3m)); Assert.That(double5, Is.GreaterThan(3)); Assert.That(double5, Is.GreaterThan(3m)); Assert.That(decimal5, Is.GreaterThan(3)); Assert.That(decimal5, Is.GreaterThan(3.0)); Assert.Less(3.0, int5); Assert.Less(3m, int5); Assert.Less(3, double5); Assert.Less(3m, double5); Assert.Less(3, decimal5); Assert.Less(3.0, decimal5); #endif //Assert.That(3.0, Is.LessThan(int5)); //Assert.That(3m, Is.LessThan(int5)); //Assert.That(3, Is.LessThan(double5)); //Assert.That(3m, Is.LessThan(double5)); //Assert.That(3, Is.LessThan(decimal5)); //Assert.That(3.0, Is.LessThan(decimal5)); } private struct MyStruct { int i; string s; public MyStruct(int i, string s) { this.i = i; this.s = s; } } [Test] public void CanCompareNullableStructs() { MyStruct struct1 = new MyStruct(5, "Hello"); MyStruct struct2 = new MyStruct(5, "Hello"); Nullable one = new MyStruct(5, "Hello"); Nullable two = new MyStruct(5, "Hello"); Assert.AreEqual(struct1, struct2); // Control Assert.AreEqual(one, two); Assert.AreEqual(one, struct1); Assert.AreEqual(struct2, two); } } #endif #endif } NUnit-2.6.0.12051/src/NUnitFramework/tests/TestDelegates.cs0000664000175000017500000000213011652173326023111 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { public class TestDelegates { public static void ThrowsArgumentException() { throw new ArgumentException("myMessage", "myParam"); } public static void ThrowsApplicationException() { throw new ApplicationException("my message"); } public static void ThrowsSystemException() { throw new Exception("my message"); } public static void ThrowsNothing() { } public static void ThrowsDerivedApplicationException() { throw new DerivedApplicationException(); } public class DerivedApplicationException : ApplicationException { } } } NUnit-2.6.0.12051/src/NUnitFramework/tests/nunit.framework.tests.csproj0000664000175000017500000001743211707326500025547 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {8C326431-AE57-4645-ACC1-A90A0B425129} Debug AnyCPU nunit.framework.tests JScript Grid IE50 false Library NUnit.Framework.Tests OnBuildSuccess 2.0 v3.5 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_3_5,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_3_5,CS_3_0 4096 618,672 true false false 4 none prompt System 3.5 System.Data System.Drawing System.Windows.Forms System.XML nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitFramework/tests/GreaterEqualFixture.cs0000664000175000017500000001320211504175260024301 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework.Tests { [TestFixture] public class GreaterEqualFixture : MessageChecker { private readonly int i1 = 5; private readonly int i2 = 4; private readonly uint u1 = 12345879; private readonly uint u2 = 12345678; private readonly long l1 = 12345879; private readonly long l2 = 12345678; private readonly ulong ul1 = 12345879; private readonly ulong ul2 = 12345678; private readonly float f1 = 3.543F; private readonly float f2 = 2.543F; private readonly decimal de1 = 53.4M; private readonly decimal de2 = 33.4M; private readonly double d1 = 4.85948654; private readonly double d2 = 1.0; private readonly System.Enum e1 = System.Data.CommandType.TableDirect; private readonly System.Enum e2 = System.Data.CommandType.StoredProcedure; [Test] public void GreaterOrEqual_Int32() { Assert.GreaterOrEqual(i1, i1); Assert.GreaterOrEqual(i1, i2); } [Test] public void GreaterOrEqual_UInt32() { Assert.GreaterOrEqual(u1, u1); Assert.GreaterOrEqual(u1, u2); } [Test] public void GreaterOrEqual_Long() { Assert.GreaterOrEqual(l1, l1); Assert.GreaterOrEqual(l1, l2); } [Test] public void GreaterOrEqual_ULong() { Assert.GreaterOrEqual(ul1, ul1); Assert.GreaterOrEqual(ul1, ul2); } [Test] public void GreaterOrEqual_Double() { Assert.GreaterOrEqual(d1, d1, "double"); Assert.GreaterOrEqual(d1, d2, "double"); } [Test] public void GreaterOrEqual_Decimal() { Assert.GreaterOrEqual(de1, de1, "{0}", "decimal"); Assert.GreaterOrEqual(de1, de2, "{0}", "decimal"); } [Test] public void GreaterOrEqual_Float() { Assert.GreaterOrEqual(f1, f1, "float"); Assert.GreaterOrEqual(f1, f2, "float"); } [Test] public void MixedTypes() { Assert.GreaterOrEqual( 5, 3L, "int to long"); Assert.GreaterOrEqual( 5, 3.5f, "int to float" ); Assert.GreaterOrEqual( 5, 3.5d, "int to double" ); Assert.GreaterOrEqual( 5, 3U, "int to uint" ); Assert.GreaterOrEqual( 5, 3UL, "int to ulong" ); Assert.GreaterOrEqual( 5, 3M, "int to decimal" ); Assert.GreaterOrEqual( 5L, 3, "long to int"); Assert.GreaterOrEqual( 5L, 3.5f, "long to float" ); Assert.GreaterOrEqual( 5L, 3.5d, "long to double" ); Assert.GreaterOrEqual( 5L, 3U, "long to uint" ); Assert.GreaterOrEqual( 5L, 3UL, "long to ulong" ); Assert.GreaterOrEqual( 5L, 3M, "long to decimal" ); Assert.GreaterOrEqual( 8.2f, 5, "float to int" ); Assert.GreaterOrEqual( 8.2f, 8L, "float to long" ); Assert.GreaterOrEqual( 8.2f, 3.5d, "float to double" ); Assert.GreaterOrEqual( 8.2f, 8U, "float to uint" ); Assert.GreaterOrEqual( 8.2f, 8UL, "float to ulong" ); Assert.GreaterOrEqual( 8.2f, 3.5M, "float to decimal" ); Assert.GreaterOrEqual( 8.2d, 5, "double to int" ); Assert.GreaterOrEqual( 8.2d, 5L, "double to long" ); Assert.GreaterOrEqual( 8.2d, 3.5f, "double to float" ); Assert.GreaterOrEqual( 8.2d, 8U, "double to uint" ); Assert.GreaterOrEqual( 8.2d, 8UL, "double to ulong" ); Assert.GreaterOrEqual( 8.2d, 3.5M, "double to decimal" ); Assert.GreaterOrEqual( 5U, 3, "uint to int" ); Assert.GreaterOrEqual( 5U, 3L, "uint to long" ); Assert.GreaterOrEqual( 5U, 3.5f, "uint to float" ); Assert.GreaterOrEqual( 5U, 3.5d, "uint to double" ); Assert.GreaterOrEqual( 5U, 3UL, "uint to ulong" ); Assert.GreaterOrEqual( 5U, 3M, "uint to decimal" ); Assert.GreaterOrEqual( 5ul, 3, "ulong to int" ); Assert.GreaterOrEqual( 5UL, 3L, "ulong to long" ); Assert.GreaterOrEqual( 5UL, 3.5f, "ulong to float" ); Assert.GreaterOrEqual( 5UL, 3.5d, "ulong to double" ); Assert.GreaterOrEqual( 5UL, 3U, "ulong to uint" ); Assert.GreaterOrEqual( 5UL, 3M, "ulong to decimal" ); Assert.GreaterOrEqual( 5M, 3, "decimal to int" ); Assert.GreaterOrEqual( 5M, 3L, "decimal to long" ); Assert.GreaterOrEqual( 5M, 3.5f, "decimal to float" ); Assert.GreaterOrEqual( 5M, 3.5d, "decimal to double" ); Assert.GreaterOrEqual( 5M, 3U, "decimal to uint" ); Assert.GreaterOrEqual( 5M, 3UL, "decimal to ulong" ); } [Test, ExpectedException(typeof(AssertionException))] public void NotGreaterOrEqual() { expectedMessage = " Expected: greater than or equal to 5" + Environment.NewLine + " But was: 4" + Environment.NewLine; Assert.GreaterOrEqual(i2, i1); } [Test, ExpectedException(typeof(AssertionException))] public void NotGreaterEqualIComparable() { expectedMessage = " Expected: greater than or equal to TableDirect" + Environment.NewLine + " But was: StoredProcedure" + Environment.NewLine; Assert.GreaterOrEqual(e2, e1); } [Test] public void FailureMessage() { string msg = null; try { Assert.GreaterOrEqual(7, 99); } catch (AssertionException ex) { msg = ex.Message; } StringAssert.Contains( TextMessageWriter.Pfx_Expected + "greater than or equal to 99", msg); StringAssert.Contains( TextMessageWriter.Pfx_Actual + "7", msg); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/0000775000175000017500000000000011742560362020664 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/framework/Interfaces/0000775000175000017500000000000011742560362022747 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/framework/Interfaces/ITestAction.cs0000664000175000017500000000246111712475522025467 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Reflection; namespace NUnit.Framework { /// /// When implemented by an attribute, this interface implemented to provide actions to execute before and after tests. /// public interface ITestAction { /// /// Executed before each test is run /// /// Provides details about the test that is going to be run. void BeforeTest(TestDetails testDetails); /// /// Executed after each test is run /// /// Provides details about the test that has just been run. void AfterTest(TestDetails testDetails); /// /// Provides the target for the action attribute /// /// The target for the action attribute ActionTargets Targets { get; } } } #endif NUnit-2.6.0.12051/src/NUnitFramework/framework/Interfaces/INUnitEqualityComparer.cs0000664000175000017500000000303511720453610027645 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// /// public interface INUnitEqualityComparer { /// /// Compares two objects for equality within a tolerance /// /// The first object to compare /// The second object to compare /// The tolerance to use in the comparison /// bool AreEqual(object x, object y, ref NUnit.Framework.Constraints.Tolerance tolerance); } #if CLR_2_0 || CLR_4_0 /// /// /// /// public interface INUnitEqualityComparer { /// /// Compares two objects of a given Type for equality within a tolerance /// /// The first object to compare /// The second object to compare /// The tolerance to use in the comparison /// bool AreEqual(T x, T y, ref NUnit.Framework.Constraints.Tolerance tolerance); } #endif } NUnit-2.6.0.12051/src/NUnitFramework/framework/TestContext.cs0000664000175000017500000001543711657751516023521 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Runtime.Remoting.Messaging; namespace NUnit.Framework { /// /// Provide the context information of the current test /// public class TestContext { private const string contextKey = "NUnit.Framework.TestContext"; private const string stateKey = "Result.State"; private IDictionary _context; private TestAdapter _test; private ResultAdapter _result; #region Constructor /// /// Constructs a TestContext using the provided context dictionary /// /// A context dictionary public TestContext(IDictionary context) { _context = context; } #endregion #region Properties /// /// Get the current test context. This is created /// as needed. The user may save the context for /// use within a test, but it should not be used /// outside the test for which it is created. /// public static TestContext CurrentContext { get { return new TestContext((IDictionary)CallContext.GetData(contextKey)); } } /// /// Gets a TestAdapter representing the currently executing test in this context. /// public TestAdapter Test { get { if (_test == null) _test = new TestAdapter(_context); return _test; } } /// /// Gets a ResultAdapter representing the current result for the test /// executing in this context. /// public ResultAdapter Result { get { if (_result == null) _result = new ResultAdapter(_context); return _result; } } /// /// Gets the directory containing the current test assembly. /// public string TestDirectory { get { return (string)_context["TestDirectory"]; } } /// /// Gets the directory to be used for outputing files created /// by this test run. /// public string WorkDirectory { get { return (string)_context["WorkDirectory"]; } } #endregion #region Nested TestAdapter Class /// /// TestAdapter adapts a Test for consumption by /// the user test code. /// public class TestAdapter { private IDictionary _context; #region Constructor /// /// Constructs a TestAdapter for this context /// /// The context dictionary public TestAdapter(IDictionary context) { _context = context; } #endregion #region Properties /// /// The name of the test. /// public string Name { get { return _context["Test.Name"] as string; } } /// /// The FullName of the test /// public string FullName { get { return _context["Test.FullName"] as string; } } /// /// The properties of the test. /// public IDictionary Properties { get { return _context["Test.Properties"] as IDictionary; } } #endregion } #endregion #region Nested ResultAdapter Class /// /// ResultAdapter adapts a TestResult for consumption by /// the user test code. /// public class ResultAdapter { private IDictionary _context; #region Constructor /// /// Construct a ResultAdapter for a context /// /// The context holding the result public ResultAdapter(IDictionary context) { this._context = context; } #endregion #region Properties /// /// The TestState of current test. This maps to the ResultState /// used in nunit.core and is subject to change in the future. /// public TestState State { get { return (TestState)_context["Result.State"]; } } /// /// The TestStatus of current test. This enum will be used /// in future versions of NUnit and so is to be preferred /// to the TestState value. /// public TestStatus Status { get { switch (State) { default: case TestState.Inconclusive: return TestStatus.Inconclusive; case TestState.Skipped: case TestState.Ignored: case TestState.NotRunnable: return TestStatus.Skipped; case TestState.Success: return TestStatus.Passed; case TestState.Failure: case TestState.Error: case TestState.Cancelled: return TestStatus.Failed; } } } #endregion } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/ITestCaseData.cs0000664000175000017500000000524311720006656023632 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// The ITestCaseData interface is implemented by a class /// that is able to return complete testcases for use by /// a parameterized test method. /// /// NOTE: This interface is used in both the framework /// and the core, even though that results in two different /// types. However, sharing the source code guarantees that /// the various implementations will be compatible and that /// the core is able to reflect successfully over the /// framework implementations of ITestCaseData. /// public interface ITestCaseData { /// /// Gets the argument list to be provided to the test /// object[] Arguments { get; } /// /// Gets the expected result /// object Result { get; } /// /// Indicates whether a result has been specified. /// This is necessary because the result may be /// null, so it's value cannot be checked. /// bool HasExpectedResult { get; } /// /// Gets the expected exception Type /// Type ExpectedException { get; } /// /// Gets the FullName of the expected exception /// string ExpectedExceptionName { get; } /// /// Gets the name to be used for the test /// string TestName { get; } /// /// Gets the description of the test /// string Description { get; } /// /// Gets a value indicating whether this is ignored. /// /// true if ignored; otherwise, false. bool Ignored { get; } /// /// Gets a value indicating whether this is explicit. /// /// true if explicit; otherwise, false. bool Explicit { get; } /// /// Gets the ignore reason. /// /// The ignore reason. string IgnoreReason { get; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/IExpectException.cs0000664000175000017500000000146611504175260024435 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Interface implemented by a user fixture in order to /// validate any expected exceptions. It is only called /// for test methods marked with the ExpectedException /// attribute. /// public interface IExpectException { /// /// Method to handle an expected exception /// /// The exception to be handled void HandleException(Exception ex); } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/0000775000175000017500000000000011742560362023012 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/RangeAttribute.cs0000664000175000017500000000577511504175260026272 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework { /// /// RangeAttribute is used to supply a range of values to an /// individual parameter of a parameterized test. /// public class RangeAttribute : ValuesAttribute { /// /// Construct a range of ints using default step of 1 /// /// /// public RangeAttribute(int from, int to) : this(from, to, 1) { } /// /// Construct a range of ints specifying the step size /// /// /// /// public RangeAttribute(int from, int to, int step) { int count = (to - from) / step + 1; this.data = new object[count]; int index = 0; for (int val = from; index < count; val += step) this.data[index++] = val; } /// /// Construct a range of longs /// /// /// /// public RangeAttribute(long from, long to, long step) { long count = (to - from) / step + 1; this.data = new object[count]; int index = 0; for (long val = from; index < count; val += step) data[index++] = val; } /// /// Construct a range of doubles /// /// /// /// public RangeAttribute(double from, double to, double step) { double tol = step / 1000; int count = (int)((to - from) / step + tol + 1); this.data = new object[count]; int index = 0; for (double val = from; index < count; val += step) data[index++] = val; } /// /// Construct a range of floats /// /// /// /// public RangeAttribute(float from, float to, float step) { float tol = step / 1000; int count = (int)((to - from) / step + tol + 1); this.data = new object[count]; int index = 0; for (float val = from; index < count; val += step) data[index++] = val; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/MaxTimeAttribute.cs0000664000175000017500000000154711504175260026573 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Summary description for MaxTimeAttribute. /// [AttributeUsage( AttributeTargets.Method, AllowMultiple=false, Inherited=false )] public sealed class MaxTimeAttribute : PropertyAttribute { /// /// Construct a MaxTimeAttribute, given a time in milliseconds. /// /// The maximum elapsed time in milliseconds public MaxTimeAttribute( int milliseconds ) : base( milliseconds ) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/IgnoreAttribute.cs0000664000175000017500000000245111504175260026445 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to mark a test that is to be ignored. /// Ignored tests result in a warning message when the /// tests are run. /// [AttributeUsage(AttributeTargets.Method|AttributeTargets.Class|AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public class IgnoreAttribute : Attribute { private string reason; /// /// Constructs the attribute without giving a reason /// for ignoring the test. /// public IgnoreAttribute() { this.reason = ""; } /// /// Constructs the attribute giving a reason for ignoring the test /// /// The reason for ignoring the test public IgnoreAttribute(string reason) { this.reason = reason; } /// /// The reason for ignoring a test /// public string Reason { get { return reason; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/PropertyAttribute.cs0000664000175000017500000000606611504175260027054 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; namespace NUnit.Framework { /// /// PropertyAttribute is used to attach information to a test as a name/value pair.. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=true, Inherited=true)] public class PropertyAttribute : Attribute { private IDictionary properties = new ListDictionary(); /// /// Construct a PropertyAttribute with a name and string value /// /// The name of the property /// The property value public PropertyAttribute(string propertyName, string propertyValue) { this.properties.Add(propertyName, propertyValue); } /// /// Construct a PropertyAttribute with a name and int value /// /// The name of the property /// The property value public PropertyAttribute(string propertyName, int propertyValue) { this.properties.Add(propertyName, propertyValue); } /// /// Construct a PropertyAttribute with a name and double value /// /// The name of the property /// The property value public PropertyAttribute(string propertyName, double propertyValue) { this.properties.Add(propertyName, propertyValue); } /// /// Constructor for derived classes that set the /// property dictionary directly. /// protected PropertyAttribute() { } /// /// Constructor for use by derived classes that use the /// name of the type as the property name. Derived classes /// must ensure that the Type of the property value is /// a standard type supported by the BCL. Any custom /// types will cause a serialization Exception when /// in the client. /// protected PropertyAttribute( object propertyValue ) { string propertyName = this.GetType().Name; if ( propertyName.EndsWith( "Attribute" ) ) propertyName = propertyName.Substring( 0, propertyName.Length - 9 ); this.properties.Add(propertyName, propertyValue); } /// /// Gets the property dictionary for this attribute /// public IDictionary Properties { get { return properties; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TheoryAttribute.cs0000664000175000017500000000274711504175260026504 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Adding this attribute to a method within a /// class makes the method callable from the NUnit test runner. There is a property /// called Description which is optional which you can provide a more detailed test /// description. This class cannot be inherited. /// /// /// /// [TestFixture] /// public class Fixture /// { /// [Test] /// public void MethodToTest() /// {} /// /// [Test(Description = "more detailed description")] /// publc void TestDescriptionMethod() /// {} /// } /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited=true)] public class TheoryAttribute : Attribute { //private string description; ///// ///// Descriptive text for this test ///// //public string Description //{ // get { return description; } // set { description = value; } //} } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TearDownAttribute.cs0000664000175000017500000000131011504175260026736 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to identify a method that is called /// immediately after each test is run. The method is /// guaranteed to be called, even if an exception is thrown. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public class TearDownAttribute : Attribute {} } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestActionAttribute.cs0000664000175000017500000000203211720453370027273 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; using System.Text; namespace NUnit.Framework { /// /// Provide actions to execute before and after tests. /// [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public abstract class TestActionAttribute : Attribute, ITestAction { public virtual void BeforeTest(TestDetails testDetails) { } public virtual void AfterTest(TestDetails testDetails) { } public virtual ActionTargets Targets { get { return ActionTargets.Default; } } } } #endifNUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/RequiredAddinAttribute.cs0000664000175000017500000000262311504175260027743 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// RequiredAddinAttribute may be used to indicate the names of any addins /// that must be present in order to run some or all of the tests in an /// assembly. If the addin is not loaded, the entire assembly is marked /// as NotRunnable. /// [AttributeUsage(AttributeTargets.Assembly,AllowMultiple=true, Inherited=false)] public class RequiredAddinAttribute : Attribute { private string requiredAddin; /// /// Initializes a new instance of the class. /// /// The required addin. public RequiredAddinAttribute(string requiredAddin) { this.requiredAddin = requiredAddin; } /// /// Gets the name of required addin. /// /// The required addin name. public string RequiredAddin { get { return requiredAddin; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestFixtureTearDownAttribute.cs0000664000175000017500000000133611504175260031155 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to identify a method that is called after /// all the tests in a fixture have run. The method is /// guaranteed to be called, even if an exception is thrown. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public class TestFixtureTearDownAttribute : Attribute { } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/SuiteAttribute.cs0000664000175000017500000000117011504175260026310 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to mark a static (shared in VB) property /// that returns a list of tests. /// [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)] public class SuiteAttribute : Attribute {} } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/SetUpFixtureAttribute.cs0000664000175000017500000000110211504175260027621 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// SetUpFixtureAttribute is used to identify a SetUpFixture /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public class SetUpFixtureAttribute : Attribute { } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/SetCultureAttribute.cs0000664000175000017500000000147011504175260027321 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Summary description for SetCultureAttribute. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=true, Inherited=true)] public class SetCultureAttribute : PropertyAttribute { /// /// Construct given the name of a culture /// /// public SetCultureAttribute( string culture ) : base( "_SETCULTURE", culture ) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/DescriptionAttribute.cs0000664000175000017500000000202411504175260027501 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Attribute used to provide descriptive text about a /// test case or fixture. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public class DescriptionAttribute : Attribute { string description; /// /// Construct the attribute /// /// Text describing the test public DescriptionAttribute(string description) { this.description=description; } /// /// Gets the test description /// public string Description { get { return description; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/ExpectedExceptionAttribute.cs0000664000175000017500000000631211504175260030642 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Enumeration indicating how the expected message parameter is to be used /// public enum MessageMatch { /// Expect an exact match Exact, /// Expect a message containing the parameter string Contains, /// Match the regular expression provided as a parameter Regex, /// Expect a message that starts with the parameter string StartsWith } /// /// ExpectedExceptionAttribute /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public class ExpectedExceptionAttribute : Attribute { private Type expectedException; private string expectedExceptionName; private string expectedMessage; private MessageMatch matchType; private string userMessage; private string handler; /// /// Constructor for a non-specific exception /// public ExpectedExceptionAttribute() { } /// /// Constructor for a given type of exception /// /// The type of the expected exception public ExpectedExceptionAttribute(Type exceptionType) { this.expectedException = exceptionType; this.expectedExceptionName = exceptionType.FullName; } /// /// Constructor for a given exception name /// /// The full name of the expected exception public ExpectedExceptionAttribute(string exceptionName) { this.expectedExceptionName = exceptionName; } /// /// Gets or sets the expected exception type /// public Type ExpectedException { get{ return expectedException; } set { expectedException = value; expectedExceptionName = expectedException.FullName; } } /// /// Gets or sets the full Type name of the expected exception /// public string ExpectedExceptionName { get{ return expectedExceptionName; } set{ expectedExceptionName = value; } } /// /// Gets or sets the expected message text /// public string ExpectedMessage { get { return expectedMessage; } set { expectedMessage = value; } } /// /// Gets or sets the user message displayed in case of failure /// public string UserMessage { get { return userMessage; } set { userMessage = value; } } /// /// Gets or sets the type of match to be performed on the expected message /// public MessageMatch MatchType { get { return matchType; } set { matchType = value; } } /// /// Gets the name of a method to be used as an exception handler /// public string Handler { get { return handler; } set { handler = value; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/CategoryAttribute.cs0000664000175000017500000000350711651467356027017 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Framework { /// /// Attribute used to apply a category to a test /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=true, Inherited=true)] public class CategoryAttribute : Attribute { /// /// The name of the category /// protected string categoryName; /// /// Construct attribute for a given category based on /// a name. The name may not contain the characters ',', /// '+', '-' or '!'. However, this is not checked in the /// constructor since it would cause an error to arise at /// as the test was loaded without giving a clear indication /// of where the problem is located. The error is handled /// in NUnitFramework.cs by marking the test as not /// runnable. /// /// The name of the category public CategoryAttribute(string name) { this.categoryName = name.Trim(); } /// /// Protected constructor uses the Type name as the name /// of the category. /// protected CategoryAttribute() { this.categoryName = this.GetType().Name; if ( categoryName.EndsWith( "Attribute" ) ) categoryName = categoryName.Substring( 0, categoryName.Length - 9 ); } /// /// The name of the category /// public string Name { get { return categoryName; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/ValueSourceAttribute.cs0000664000175000017500000000403411504175260027456 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// ValueSourceAttribute indicates the source to be used to /// provide data for one parameter of a test method. /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)] public class ValueSourceAttribute : Attribute { private readonly string sourceName; private readonly Type sourceType; /// /// Construct with the name of the factory - for use with languages /// that don't support params arrays. /// /// The name of the data source to be used public ValueSourceAttribute(string sourceName) { this.sourceName = sourceName; } /// /// Construct with a Type and name - for use with languages /// that don't support params arrays. /// /// The Type that will provide data /// The name of the method, property or field that will provide data public ValueSourceAttribute(Type sourceType, string sourceName) { this.sourceType = sourceType; this.sourceName = sourceName; } /// /// The name of a the method, property or fiend to be used as a source /// public string SourceName { get { return sourceName; } } /// /// A Type to be used as a source /// public Type SourceType { get { return sourceType; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestFixtureAttribute.cs0000664000175000017500000001167511544454420027522 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; using System.Collections; /// /// [TestFixture] /// public class ExampleClass /// {} /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited=true)] public class TestFixtureAttribute : Attribute { private string description; private object[] arguments; private bool isIgnored; private string ignoreReason; private string category; #if CLR_2_0 || CLR_4_0 private Type[] typeArgs; private bool argsSeparated; #endif /// /// Default constructor /// public TestFixtureAttribute() : this( null ) { } /// /// Construct with a object[] representing a set of arguments. /// In .NET 2.0, the arguments may later be separated into /// type arguments and constructor arguments. /// /// public TestFixtureAttribute(params object[] arguments) { this.arguments = arguments == null ? new object[0] : arguments; for (int i = 0; i < this.arguments.Length; i++) if (arguments[i] is SpecialValue && (SpecialValue)arguments[i] == SpecialValue.Null) arguments[i] = null; } /// /// Descriptive text for this fixture /// public string Description { get { return description; } set { description = value; } } /// /// Gets and sets the category for this fixture. /// May be a comma-separated list of categories. /// public string Category { get { return category; } set { category = value; } } /// /// Gets a list of categories for this fixture /// public IList Categories { get { return category == null ? null : category.Split(','); } } /// /// The arguments originally provided to the attribute /// public object[] Arguments { get { #if CLR_2_0 || CLR_4_0 if (!argsSeparated) SeparateArgs(); #endif return arguments; } } /// /// Gets or sets a value indicating whether this should be ignored. /// /// true if ignore; otherwise, false. public bool Ignore { get { return isIgnored; } set { isIgnored = value; } } /// /// Gets or sets the ignore reason. May set Ignored as a side effect. /// /// The ignore reason. public string IgnoreReason { get { return ignoreReason; } set { ignoreReason = value; isIgnored = ignoreReason != null && ignoreReason != string.Empty; } } #if CLR_2_0 || CLR_4_0 /// /// Get or set the type arguments. If not set /// explicitly, any leading arguments that are /// Types are taken as type arguments. /// public Type[] TypeArgs { get { if (!argsSeparated) SeparateArgs(); return typeArgs; } set { typeArgs = value; argsSeparated = true; } } private void SeparateArgs() { int cnt = 0; if (arguments != null) { foreach (object o in arguments) if (o is Type) cnt++; else break; typeArgs = new Type[cnt]; for (int i = 0; i < cnt; i++) typeArgs[i] = (Type)arguments[i]; if (cnt > 0) { object[] args = new object[arguments.Length - cnt]; for (int i = 0; i < args.Length; i++) args[i] = arguments[cnt + i]; arguments = args; } } else typeArgs = new Type[0]; argsSeparated = true; } #endif } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/RepeatAttribute.cs0000664000175000017500000000250611504175260026443 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// RepeatAttribute may be applied to test case in order /// to run it multiple times. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public class RepeatAttribute : PropertyAttribute { /// /// Construct a RepeatAttribute /// /// The number of times to run the test public RepeatAttribute(int count) : base(count) { } //private int count; ///// ///// Construct a RepeatAttribute ///// ///// The number of times to run the test //public RepeatAttribute(int count) //{ // this.count = count; //} ///// ///// Gets the number of times to run the test. ///// //public int Count //{ // get { return count; } //} } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/DatapointAttributes.cs0000664000175000017500000000216311504175260027330 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Used to mark a field for use as a datapoint when executing a theory /// within the same fixture that requires an argument of the field's Type. /// [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class DatapointAttribute : Attribute { } /// /// Used to mark an array as containing a set of datapoints to be used /// executing a theory within the same fixture that requires an argument /// of the Type of the array elements. /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class DatapointsAttribute : Attribute { } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/ValuesAttribute.cs0000664000175000017500000001047311504175260026464 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Framework { /// /// Abstract base class for attributes that apply to parameters /// and supply data for the parameter. /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] public abstract class ParameterDataAttribute : Attribute { /// /// Gets the data to be provided to the specified parameter /// public abstract IEnumerable GetData(ParameterInfo parameter); } /// /// ValuesAttribute is used to provide literal arguments for /// an individual parameter of a test. /// [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] public class ValuesAttribute : ParameterDataAttribute { /// /// The collection of data to be returned. Must /// be set by any derived attribute classes. /// We use an object[] so that the individual /// elements may have their type changed in GetData /// if necessary. /// // TODO: This causes a lot of boxing so we should eliminate it. protected object[] data; /// /// Construct with one argument /// /// public ValuesAttribute(object arg1) { data = new object[] { arg1 }; } /// /// Construct with two arguments /// /// /// public ValuesAttribute(object arg1, object arg2) { data = new object[] { arg1, arg2 }; } /// /// Construct with three arguments /// /// /// /// public ValuesAttribute(object arg1, object arg2, object arg3) { data = new object[] { arg1, arg2, arg3 }; } /// /// Construct with an array of arguments /// /// public ValuesAttribute(params object[] args) { data = args; } /// /// Get the collection of values to be used as arguments /// public override IEnumerable GetData(ParameterInfo parameter) { Type targetType = parameter.ParameterType; for (int i = 0; i < data.Length; i++) { object arg = data[i]; if (arg == null) continue; if (arg.GetType().FullName == "NUnit.Framework.SpecialValue" && arg.ToString() == "Null") { data[i] = null; continue; } if (targetType.IsAssignableFrom(arg.GetType())) continue; if (arg is DBNull) { data[i] = null; continue; } bool convert = false; if (targetType == typeof(short) || targetType == typeof(byte) || targetType == typeof(sbyte)) convert = arg is int; else if (targetType == typeof(decimal)) convert = arg is double || arg is string || arg is int; else if (targetType == typeof(DateTime) || targetType == typeof(TimeSpan)) convert = arg is string; if (convert) data[i] = Convert.ChangeType(arg, targetType, System.Globalization.CultureInfo.InvariantCulture); } return data; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestAttribute.cs0000664000175000017500000000250411504175260026140 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Adding this attribute to a method within a /// class makes the method callable from the NUnit test runner. There is a property /// called Description which is optional which you can provide a more detailed test /// description. This class cannot be inherited. /// /// /// /// [TestFixture] /// public class Fixture /// { /// [Test] /// public void MethodToTest() /// {} /// /// [Test(Description = "more detailed description")] /// publc void TestDescriptionMethod() /// {} /// } /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public class TestAttribute : Attribute { private string description; /// /// Descriptive text for this test /// public string Description { get { return description; } set { description = value; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/SetUpAttribute.cs0000664000175000017500000000126511504175260026264 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to mark a class that contains one-time SetUp /// and/or TearDown methods that apply to all the tests in a /// namespace or an assembly. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public class SetUpAttribute : Attribute {} } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/RandomAttribute.cs0000664000175000017500000000625511504175260026450 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Framework { /// /// RandomAttribute is used to supply a set of random values /// to a single parameter of a parameterized test. /// public class RandomAttribute : ValuesAttribute { enum SampleType { Raw, IntRange, DoubleRange } SampleType sampleType; private int count; private int min, max; private double dmin, dmax; /// /// Construct a set of doubles from 0.0 to 1.0, /// specifying only the count. /// /// public RandomAttribute(int count) { this.count = count; this.sampleType = SampleType.Raw; } /// /// Construct a set of doubles from min to max /// /// /// /// public RandomAttribute(double min, double max, int count) { this.count = count; this.dmin = min; this.dmax = max; this.sampleType = SampleType.DoubleRange; } /// /// Construct a set of ints from min to max /// /// /// /// public RandomAttribute(int min, int max, int count) { this.count = count; this.min = min; this.max = max; this.sampleType = SampleType.IntRange; } /// /// Get the collection of values to be used as arguments /// public override IEnumerable GetData(ParameterInfo parameter) { Randomizer r = Randomizer.GetRandomizer(parameter); IList values; switch (sampleType) { default: case SampleType.Raw: values = r.GetDoubles(count); break; case SampleType.IntRange: values = r.GetInts(min, max, count); break; case SampleType.DoubleRange: values = r.GetDoubles(dmin, dmax, count); break; } // Copy the random values into the data array // and call the base class which may need to // convert them to another type. this.data = new object[values.Count]; for (int i = 0; i < values.Count; i++) this.data[i] = values[i]; return base.GetData(parameter); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/ThreadingAttributes.cs0000664000175000017500000000643011615505020027305 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; namespace NUnit.Framework { /// /// Used on a method, marks the test with a timeout value in milliseconds. /// The test will be run in a separate thread and is cancelled if the timeout /// is exceeded. Used on a method or assembly, sets the default timeout /// for all contained test methods. /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited=false)] public class TimeoutAttribute : PropertyAttribute { /// /// Construct a TimeoutAttribute given a time in milliseconds /// /// The timeout value in milliseconds public TimeoutAttribute(int timeout) : base(timeout) { } } /// /// Marks a test that must run in the STA, causing it /// to run in a separate thread if necessary. /// /// On methods, you may also use STAThreadAttribute /// to serve the same purpose. /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited=false)] public class RequiresSTAAttribute : PropertyAttribute { /// /// Construct a RequiresSTAAttribute /// public RequiresSTAAttribute() { this.Properties.Add("APARTMENT_STATE", ApartmentState.STA); } } /// /// Marks a test that must run in the MTA, causing it /// to run in a separate thread if necessary. /// /// On methods, you may also use MTAThreadAttribute /// to serve the same purpose. /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited=false)] public class RequiresMTAAttribute : PropertyAttribute { /// /// Construct a RequiresMTAAttribute /// public RequiresMTAAttribute() { this.Properties.Add("APARTMENT_STATE", ApartmentState.MTA); } } /// /// Marks a test that must run on a separate thread. /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited=false)] public class RequiresThreadAttribute : PropertyAttribute { /// /// Construct a RequiresThreadAttribute /// public RequiresThreadAttribute() : base(true) { } /// /// Construct a RequiresThreadAttribute, specifying the apartment /// public RequiresThreadAttribute(ApartmentState apartment) : base(true) { this.Properties.Add("APARTMENT_STATE", apartment); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/SetUICultureAttribute.cs0000664000175000017500000000156511504175260027564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Summary description for SetUICultureAttribute. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Assembly, AllowMultiple = true, Inherited=true)] public class SetUICultureAttribute : PropertyAttribute { /// /// Construct given the name of a culture /// /// public SetUICultureAttribute(string culture) : base("_SETUICULTURE", culture) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/ExplicitAttribute.cs0000664000175000017500000000266311504175260027010 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// ExplicitAttribute marks a test or test fixture so that it will /// only be run if explicitly executed from the gui or command line /// or if it is included by use of a filter. The test will not be /// run simply because an enclosing suite is run. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public class ExplicitAttribute : Attribute { private string reason; /// /// Default constructor /// public ExplicitAttribute() { this.reason = ""; } /// /// Constructor with a reason /// /// The reason test is marked explicit public ExplicitAttribute(string reason) { this.reason = reason; } /// /// The reason test is marked explicit /// public string Reason { get { return reason; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestFixtureSetUpAttribute.cs0000664000175000017500000000121011504175260030461 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; /// /// Attribute used to identify a method that is /// called before any tests in a fixture are run. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public class TestFixtureSetUpAttribute : Attribute { } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestCaseSourceAttribute.cs0000664000175000017500000000460711650226754030132 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// FactoryAttribute indicates the source to be used to /// provide test cases for a test method. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public class TestCaseSourceAttribute : Attribute { private readonly string sourceName; private readonly Type sourceType; private string category; /// /// Construct with the name of the factory - for use with languages /// that don't support params arrays. /// /// An array of the names of the factories that will provide data public TestCaseSourceAttribute(string sourceName) { this.sourceName = sourceName; } /// /// Construct with a Type and name - for use with languages /// that don't support params arrays. /// /// The Type that will provide data /// The name of the method, property or field that will provide data public TestCaseSourceAttribute(Type sourceType, string sourceName) { this.sourceType = sourceType; this.sourceName = sourceName; } /// /// The name of a the method, property or fiend to be used as a source /// public string SourceName { get { return sourceName; } } /// /// A Type to be used as a source /// public Type SourceType { get { return sourceType; } } /// /// Gets or sets the category associated with this test. /// May be a single category or a comma-separated list. /// public string Category { get { return category; } set { category = value; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/TestCaseAttribute.cs0000664000175000017500000001735411703130500026732 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; namespace NUnit.Framework { /// /// TestCaseAttribute is used to mark parameterized test cases /// and provide them with their arguments. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited=false)] public class TestCaseAttribute : Attribute, ITestCaseData { #region Instance Variables private object[] arguments; private object expectedResult; private bool hasExpectedResult; private Type expectedExceptionType; private string expectedExceptionName; private string expectedMessage; private MessageMatch matchType; private string description; private string testName; private bool isIgnored; private bool isExplicit; private string reason; private string category; #endregion #region Constructors /// /// Construct a TestCaseAttribute with a list of arguments. /// This constructor is not CLS-Compliant /// /// public TestCaseAttribute(params object[] arguments) { if (arguments == null) this.arguments = new object[] { null }; else this.arguments = arguments; } /// /// Construct a TestCaseAttribute with a single argument /// /// public TestCaseAttribute(object arg) { this.arguments = new object[] { arg }; } /// /// Construct a TestCaseAttribute with a two arguments /// /// /// public TestCaseAttribute(object arg1, object arg2) { this.arguments = new object[] { arg1, arg2 }; } /// /// Construct a TestCaseAttribute with a three arguments /// /// /// /// public TestCaseAttribute(object arg1, object arg2, object arg3) { this.arguments = new object[] { arg1, arg2, arg3 }; } #endregion #region Properties /// /// Gets the list of arguments to a test case /// public object[] Arguments { get { return arguments; } } /// /// Gets or sets the expected result. /// /// The result. public object Result { get { return expectedResult; } set { expectedResult = value; hasExpectedResult = true; } } /// /// Gets the expected result. /// /// The result. public object ExpectedResult { get { return expectedResult; } } /// /// Gets a flag indicating whether an expected /// result has been set. /// public bool HasExpectedResult { get { return hasExpectedResult; } } /// /// Gets a list of categories associated with this test; /// public IList Categories { get { return category == null ? null : category.Split(','); } } /// /// Gets or sets the category associated with this test. /// May be a single category or a comma-separated list. /// public string Category { get { return category; } set { category = value; } } /// /// Gets or sets the expected exception. /// /// The expected exception. public Type ExpectedException { get { return expectedExceptionType; } set { expectedExceptionType = value; expectedExceptionName = expectedExceptionType.FullName; } } /// /// Gets or sets the name the expected exception. /// /// The expected name of the exception. public string ExpectedExceptionName { get { return expectedExceptionName; } set { expectedExceptionName = value; expectedExceptionType = null; } } /// /// Gets or sets the expected message of the expected exception /// /// The expected message of the exception. public string ExpectedMessage { get { return expectedMessage; } set { expectedMessage = value; } } /// /// Gets or sets the type of match to be performed on the expected message /// public MessageMatch MatchType { get { return matchType; } set { matchType = value; } } /// /// Gets or sets the description. /// /// The description. public string Description { get { return description; } set { description = value; } } /// /// Gets or sets the name of the test. /// /// The name of the test. public string TestName { get { return testName; } set { testName = value; } } /// /// Gets or sets the ignored status of the test /// public bool Ignore { get { return isIgnored; } set { isIgnored = value; } } /// /// Gets or sets the ignored status of the test /// public bool Ignored { get { return isIgnored; } set { isIgnored = value; } } /// /// Gets or sets the explicit status of the test /// public bool Explicit { get { return isExplicit; } set { isExplicit = value; } } /// /// Gets or sets the reason for not running the test /// public string Reason { get { return reason; } set { reason = value; } } /// /// Gets or sets the reason for not running the test. /// Set has the side effect of marking the test as ignored. /// /// The ignore reason. public string IgnoreReason { get { return reason; } set { reason = value; isIgnored = reason != null && reason != string.Empty; } } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/JoinTypeAttributes.cs0000664000175000017500000000467011504175260027153 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Marks a test to use a combinatorial join of any argument data /// provided. NUnit will create a test case for every combination of /// the arguments provided. This can result in a large number of test /// cases and so should be used judiciously. This is the default join /// type, so the attribute need not be used except as documentation. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited=false)] public class CombinatorialAttribute : PropertyAttribute { /// /// Default constructor /// public CombinatorialAttribute() : base("_JOINTYPE", "Combinatorial") { } } /// /// Marks a test to use pairwise join of any argument data provided. /// NUnit will attempt too excercise every pair of argument values at /// least once, using as small a number of test cases as it can. With /// only two arguments, this is the same as a combinatorial join. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited=false)] public class PairwiseAttribute : PropertyAttribute { /// /// Default constructor /// public PairwiseAttribute() : base("_JOINTYPE", "Pairwise") { } } /// /// Marks a test to use a sequential join of any argument data /// provided. NUnit will use arguements for each parameter in /// sequence, generating test cases up to the largest number /// of argument values provided and using null for any arguments /// for which it runs out of values. Normally, this should be /// used with the same number of arguments for each parameter. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited=false)] public class SequentialAttribute : PropertyAttribute { /// /// Default constructor /// public SequentialAttribute() : base("_JOINTYPE", "Sequential") { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Attributes/IncludeExcludeAttributes.cs0000664000175000017500000000626411504175260030310 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// Abstract base for Attributes that are used to include tests /// in the test run based on environmental settings. /// public abstract class IncludeExcludeAttribute : Attribute { private string include; private string exclude; private string reason; /// /// Constructor with no included items specified, for use /// with named property syntax. /// public IncludeExcludeAttribute() { } /// /// Constructor taking one or more included items /// /// Comma-delimited list of included items public IncludeExcludeAttribute( string include ) { this.include = include; } /// /// Name of the item that is needed in order for /// a test to run. Multiple itemss may be given, /// separated by a comma. /// public string Include { get { return this.include; } set { include = value; } } /// /// Name of the item to be excluded. Multiple items /// may be given, separated by a comma. /// public string Exclude { get { return this.exclude; } set { this.exclude = value; } } /// /// The reason for including or excluding the test /// public string Reason { get { return reason; } set { reason = value; } } } /// /// PlatformAttribute is used to mark a test fixture or an /// individual method as applying to a particular platform only. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)] public class PlatformAttribute : IncludeExcludeAttribute { /// /// Constructor with no platforms specified, for use /// with named property syntax. /// public PlatformAttribute() { } /// /// Constructor taking one or more platforms /// /// Comma-deliminted list of platforms public PlatformAttribute( string platforms ) : base( platforms ) { } } /// /// CultureAttribute is used to mark a test fixture or an /// individual method as applying to a particular Culture only. /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public class CultureAttribute : IncludeExcludeAttribute { /// /// Constructor with no cultures specified, for use /// with named property syntax. /// public CultureAttribute() { } /// /// Constructor taking one or more cultures /// /// Comma-deliminted list of cultures public CultureAttribute( string cultures ) : base( cultures ) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/SpecialValue.cs0000664000175000017500000000133511504175260023565 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// The SpecialValue enum is used to represent TestCase arguments /// that cannot be used as arguments to an Attribute. /// public enum SpecialValue { /// /// Null represents a null value, which cannot be used as an /// argument to an attriute under .NET 1.x /// Null } } NUnit-2.6.0.12051/src/NUnitFramework/framework/ListMapper.cs0000664000175000017500000000306311504175260023270 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Framework { /// /// ListMapper is used to transform a collection used as an actual argument /// producing another collection to be used in the assertion. /// public class ListMapper { ICollection original; /// /// Construct a ListMapper based on a collection /// /// The collection to be transformed public ListMapper( ICollection original ) { this.original = original; } /// /// Produces a collection containing all the values of a property /// /// The collection of property values /// public ICollection Property( string name ) { ArrayList propList = new ArrayList(); foreach( object item in original ) { PropertyInfo property = item.GetType().GetProperty( name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); if ( property == null ) throw new ArgumentException( string.Format( "{0} does not have a {1} property", item, name ) ); propList.Add( property.GetValue( item, null ) ); } return propList; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/AssemblyInfo.cs0000664000175000017500000000110511617036226023601 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Security; [assembly: CLSCompliant(true)] [assembly: AllowPartiallyTrustedCallers] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/NUnitFramework/framework/AssertionHelper.cs0000664000175000017500000002560711707505154024333 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// AssertionHelper is an optional base class for user tests, /// allowing the use of shorter names for constraints and /// asserts and avoiding conflict with the definition of /// , from which it inherits much of its /// behavior, in certain mock object frameworks. /// public class AssertionHelper : ConstraintFactory { #region Assert //private Assertions assert = new Assertions(); //public virtual Assertions Assert //{ // get { return assert; } //} #endregion #region Expect #region Object /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. Works /// identically to Assert.That /// /// A Constraint to be applied /// The actual value to test public void Expect(object actual, IResolveConstraint constraint) { Assert.That(actual, constraint, null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. Works /// identically to Assert.That. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure public void Expect(object actual, IResolveConstraint constraint, string message) { Assert.That(actual, constraint, message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. Works /// identically to Assert.That /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message public void Expect(object actual, IResolveConstraint constraint, string message, params object[] args) { Assert.That(actual, constraint, message, args); } #endregion #region ActualValueDelegate /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested public void Expect(ActualValueDelegate del, IResolveConstraint expr) { Assert.That(del, expr.Resolve(), null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested /// The message that will be displayed on failure public void Expect(ActualValueDelegate del, IResolveConstraint expr, string message) { Assert.That(del, expr.Resolve(), message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// An ActualValueDelegate returning the value to be tested /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message public void Expect(ActualValueDelegate del, IResolveConstraint expr, string message, params object[] args) { Assert.That(del, expr, message, args); } #endregion #region ref Object #if CLR_2_0 || CLR_4_0 /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test public void Expect(ref T actual, IResolveConstraint constraint) { Assert.That(ref actual, constraint.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure public void Expect(ref T actual, IResolveConstraint constraint, string message) { Assert.That(ref actual, constraint.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message public void Expect(ref T actual, IResolveConstraint expression, string message, params object[] args) { Assert.That(ref actual, expression, message, args); } #else /// /// Apply a constraint to a referenced boolean, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test public void Expect(ref bool actual, IResolveConstraint constraint) { Assert.That(ref actual, constraint.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure public void Expect(ref bool actual, IResolveConstraint constraint, string message) { Assert.That(ref actual, constraint.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// The actual value to test /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message public void Expect(ref bool actual, IResolveConstraint expression, string message, params object[] args) { Assert.That( ref actual, expression, message, args ); } #endif #endregion #region Boolean /// /// Asserts that a condition is true. If the condition is false the method throws /// an . Works Identically to Assert.That. /// /// The evaluated condition /// The message to display if the condition is false /// Arguments to be used in formatting the message public void Expect(bool condition, string message, params object[] args) { Assert.That(condition, Is.True, message, args); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . Works Identically to Assert.That. /// /// The evaluated condition /// The message to display if the condition is false public void Expect(bool condition, string message) { Assert.That(condition, Is.True, message, null); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . Works Identically Assert.That. /// /// The evaluated condition public void Expect(bool condition) { Assert.That(condition, Is.True, null, null); } #endregion /// /// Asserts that the code represented by a delegate throws an exception /// that satisfies the constraint provided. /// /// A TestDelegate to be executed /// A ThrowsConstraint used in the test public void Expect(TestDelegate code, IResolveConstraint constraint) { Assert.That((object)code, constraint); } #endregion #region Map /// /// Returns a ListMapper based on a collection. /// /// The original collection /// public ListMapper Map( ICollection original ) { return new ListMapper( original ); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Randomizer.cs0000664000175000017500000000720611504175260023325 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Framework { /// /// Randomizer returns a set of random values in a repeatable /// way, to allow re-running of tests if necessary. /// public class Randomizer : Random { #region Static Members private static Random seedGenerator = new Random(); private static Hashtable randomizers = new Hashtable(); /// /// Get a random seed for use in creating a randomizer. /// public static int RandomSeed { get { return seedGenerator.Next(); } } /// /// Get a randomizer for a particular member, returning /// one that has already been created if it exists. /// This ensures that the same values are generated /// each time the tests are reloaded. /// public static Randomizer GetRandomizer(MemberInfo member) { Randomizer r = (Randomizer)randomizers[member]; if ( r == null ) randomizers[member] = r = new Randomizer(); return r; } /// /// Get a randomizer for a particular parameter, returning /// one that has already been created if it exists. /// This ensures that the same values are generated /// each time the tests are reloaded. /// public static Randomizer GetRandomizer(ParameterInfo parameter) { return GetRandomizer(parameter.Member); } #endregion #region Constructors /// /// Construct a randomizer using a random seed /// public Randomizer() : base(RandomSeed) { } /// /// Construct a randomizer using a specified seed /// public Randomizer(int seed) : base(seed) { } #endregion #region Public Methods /// /// Return an array of random doubles between 0.0 and 1.0. /// /// /// public double[] GetDoubles(int count) { double[] rvals = new double[count]; for (int index = 0; index < count; index++) rvals[index] = NextDouble(); return rvals; } /// /// Return an array of random doubles with values in a specified range. /// public double[] GetDoubles(double min, double max, int count) { double range = max - min; double[] rvals = new double[count]; for (int index = 0; index < count; index++) rvals[index] = NextDouble() * range + min; return rvals; } /// /// Return an array of random ints with values in a specified range. /// public int[] GetInts(int min, int max, int count) { int[] ivals = new int[count]; for (int index = 0; index < count; index++) ivals[index] = Next(min, max); return ivals; } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/CollectionAssert.cs0000664000175000017500000007426111504175260024475 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// A set of Assert methods operationg on one or more collections /// public class CollectionAssert { #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region AllItemsAreInstancesOfType /// /// Asserts that all items contained in collection are of the type specified by expectedType. /// /// IEnumerable containing objects to be considered /// System.Type that all objects in collection must be instances of public static void AllItemsAreInstancesOfType (IEnumerable collection, Type expectedType) { AllItemsAreInstancesOfType(collection, expectedType, string.Empty, null); } /// /// Asserts that all items contained in collection are of the type specified by expectedType. /// /// IEnumerable containing objects to be considered /// System.Type that all objects in collection must be instances of /// The message that will be displayed on failure public static void AllItemsAreInstancesOfType (IEnumerable collection, Type expectedType, string message) { AllItemsAreInstancesOfType(collection, expectedType, message, null); } /// /// Asserts that all items contained in collection are of the type specified by expectedType. /// /// IEnumerable containing objects to be considered /// System.Type that all objects in collection must be instances of /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AllItemsAreInstancesOfType (IEnumerable collection, Type expectedType, string message, params object[] args) { Assert.That(collection, new AllItemsConstraint(new InstanceOfTypeConstraint(expectedType)), message, args); } #endregion #region AllItemsAreNotNull /// /// Asserts that all items contained in collection are not equal to null. /// /// IEnumerable containing objects to be considered public static void AllItemsAreNotNull (IEnumerable collection) { AllItemsAreNotNull(collection, string.Empty, null); } /// /// Asserts that all items contained in collection are not equal to null. /// /// IEnumerable containing objects to be considered /// The message that will be displayed on failure public static void AllItemsAreNotNull (IEnumerable collection, string message) { AllItemsAreNotNull(collection, message, null); } /// /// Asserts that all items contained in collection are not equal to null. /// /// IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AllItemsAreNotNull (IEnumerable collection, string message, params object[] args) { Assert.That(collection, new AllItemsConstraint(new NotConstraint(new EqualConstraint(null))), message, args); } #endregion #region AllItemsAreUnique /// /// Ensures that every object contained in collection exists within the collection /// once and only once. /// /// IEnumerable of objects to be considered public static void AllItemsAreUnique (IEnumerable collection) { AllItemsAreUnique(collection, string.Empty, null); } /// /// Ensures that every object contained in collection exists within the collection /// once and only once. /// /// IEnumerable of objects to be considered /// The message that will be displayed on failure public static void AllItemsAreUnique (IEnumerable collection, string message) { AllItemsAreUnique(collection, message, null); } /// /// Ensures that every object contained in collection exists within the collection /// once and only once. /// /// IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AllItemsAreUnique (IEnumerable collection, string message, params object[] args) { Assert.That(collection, new UniqueItemsConstraint(), message, args); } #endregion #region AreEqual /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered public static void AreEqual (IEnumerable expected, IEnumerable actual) { //AreEqual(expected, actual, null, string.Empty, null); Assert.That(actual, new EqualConstraint(expected)); } /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable public static void AreEqual (IEnumerable expected, IEnumerable actual, IComparer comparer) { AreEqual(expected, actual, comparer, string.Empty, null); } /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure public static void AreEqual (IEnumerable expected, IEnumerable actual, string message) { //AreEqual(expected, actual, null, message, null); Assert.That(actual, new EqualConstraint(expected), message); } /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable /// The message that will be displayed on failure public static void AreEqual (IEnumerable expected, IEnumerable actual, IComparer comparer, string message) { AreEqual(expected, actual, comparer, message, null); } /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreEqual (IEnumerable expected, IEnumerable actual, string message, params object[] args) { //AreEqual(expected, actual, null, message, args); Assert.That(actual, new EqualConstraint(expected), message, args); } /// /// Asserts that expected and actual are exactly equal. The collections must have the same count, /// and contain the exact same objects in the same order. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreEqual (IEnumerable expected, IEnumerable actual, IComparer comparer, string message, params object[] args) { Assert.That(actual, new EqualConstraint(expected).Using(comparer), message, args); } #endregion #region AreEquivalent /// /// Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered public static void AreEquivalent (IEnumerable expected, IEnumerable actual) { AreEquivalent(expected, actual, string.Empty, null); } /// /// Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure public static void AreEquivalent (IEnumerable expected, IEnumerable actual, string message) { AreEquivalent(expected, actual, message, null); } /// /// Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreEquivalent (IEnumerable expected, IEnumerable actual, string message, params object[] args) { Assert.That(actual, new CollectionEquivalentConstraint(expected), message, args); } #endregion #region AreNotEqual /// /// Asserts that expected and actual are not exactly equal. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered public static void AreNotEqual (IEnumerable expected, IEnumerable actual) { Assert.That(actual, new NotConstraint(new EqualConstraint(expected))); } /// /// Asserts that expected and actual are not exactly equal. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable public static void AreNotEqual (IEnumerable expected, IEnumerable actual, IComparer comparer) { AreNotEqual(expected, actual, comparer, string.Empty, null); } /// /// Asserts that expected and actual are not exactly equal. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure public static void AreNotEqual (IEnumerable expected, IEnumerable actual, string message) { Assert.That(actual, new NotConstraint(new EqualConstraint(expected)), message); } /// /// Asserts that expected and actual are not exactly equal. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable /// The message that will be displayed on failure public static void AreNotEqual (IEnumerable expected, IEnumerable actual, IComparer comparer, string message) { AreNotEqual(expected, actual, comparer, message, null); } /// /// Asserts that expected and actual are not exactly equal. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreNotEqual (IEnumerable expected, IEnumerable actual, string message, params object[] args) { //AreNotEqual(expected, actual, null, message, args); //Assert.AreNotEqual( expected, actual, message, args ); Assert.That(actual, new NotConstraint(new EqualConstraint(expected)), message, args); } /// /// Asserts that expected and actual are not exactly equal. /// If comparer is not null then it will be used to compare the objects. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The IComparer to use in comparing objects from each IEnumerable /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreNotEqual (IEnumerable expected, IEnumerable actual, IComparer comparer, string message, params object[] args) { Assert.That(actual, new NotConstraint(new EqualConstraint(expected).Using(comparer)), message, args); } #endregion #region AreNotEquivalent /// /// Asserts that expected and actual are not equivalent. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered public static void AreNotEquivalent (IEnumerable expected, IEnumerable actual) { AreNotEquivalent(expected, actual, string.Empty, null); } /// /// Asserts that expected and actual are not equivalent. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure public static void AreNotEquivalent (IEnumerable expected, IEnumerable actual, string message) { AreNotEquivalent(expected, actual, message, null); } /// /// Asserts that expected and actual are not equivalent. /// /// The first IEnumerable of objects to be considered /// The second IEnumerable of objects to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void AreNotEquivalent (IEnumerable expected, IEnumerable actual, string message, params object[] args) { Assert.That(actual, new NotConstraint(new CollectionEquivalentConstraint(expected)), message, args); } #endregion #region Contains /// /// Asserts that collection contains actual as an item. /// /// IEnumerable of objects to be considered /// Object to be found within collection public static void Contains (IEnumerable collection, Object actual) { Contains(collection, actual, string.Empty, null); } /// /// Asserts that collection contains actual as an item. /// /// IEnumerable of objects to be considered /// Object to be found within collection /// The message that will be displayed on failure public static void Contains (IEnumerable collection, Object actual, string message) { Contains(collection, actual, message, null); } /// /// Asserts that collection contains actual as an item. /// /// IEnumerable of objects to be considered /// Object to be found within collection /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void Contains (IEnumerable collection, Object actual, string message, params object[] args) { Assert.That(collection, new CollectionContainsConstraint(actual), message, args); } #endregion #region DoesNotContain /// /// Asserts that collection does not contain actual as an item. /// /// IEnumerable of objects to be considered /// Object that cannot exist within collection public static void DoesNotContain (IEnumerable collection, Object actual) { DoesNotContain(collection, actual, string.Empty, null); } /// /// Asserts that collection does not contain actual as an item. /// /// IEnumerable of objects to be considered /// Object that cannot exist within collection /// The message that will be displayed on failure public static void DoesNotContain (IEnumerable collection, Object actual, string message) { DoesNotContain(collection, actual, message, null); } /// /// Asserts that collection does not contain actual as an item. /// /// IEnumerable of objects to be considered /// Object that cannot exist within collection /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void DoesNotContain (IEnumerable collection, Object actual, string message, params object[] args) { Assert.That(collection, new NotConstraint( new CollectionContainsConstraint( actual ) ), message, args); } #endregion #region IsNotSubsetOf /// /// Asserts that superset is not a subject of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered public static void IsNotSubsetOf (IEnumerable subset, IEnumerable superset) { IsNotSubsetOf(subset, superset, string.Empty, null); } /// /// Asserts that superset is not a subject of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered /// The message that will be displayed on failure public static void IsNotSubsetOf (IEnumerable subset, IEnumerable superset, string message) { IsNotSubsetOf(subset, superset, message, null); } /// /// Asserts that superset is not a subject of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void IsNotSubsetOf (IEnumerable subset, IEnumerable superset, string message, params object[] args) { Assert.That(subset, new NotConstraint(new CollectionSubsetConstraint(superset)), message, args); } #endregion #region IsSubsetOf /// /// Asserts that superset is a subset of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered public static void IsSubsetOf (IEnumerable subset, IEnumerable superset) { IsSubsetOf(subset, superset, string.Empty, null); } /// /// Asserts that superset is a subset of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered /// The message that will be displayed on failure public static void IsSubsetOf (IEnumerable subset, IEnumerable superset, string message) { IsSubsetOf(subset, superset, message, null); } /// /// Asserts that superset is a subset of subset. /// /// The IEnumerable superset to be considered /// The IEnumerable subset to be considered /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void IsSubsetOf (IEnumerable subset, IEnumerable superset, string message, params object[] args) { Assert.That(subset, new CollectionSubsetConstraint(superset), message, args); } #endregion #region IsEmpty /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure /// Arguments to be used in formatting the message public static void IsEmpty(IEnumerable collection, string message, params object[] args) { Assert.That(collection, new EmptyConstraint(), message, args); } /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure public static void IsEmpty(IEnumerable collection, string message) { IsEmpty(collection, message, null); } /// /// Assert that an array,list or other collection is empty /// /// An array, list or other collection implementing IEnumerable public static void IsEmpty(IEnumerable collection) { IsEmpty(collection, string.Empty, null); } #endregion #region IsNotEmpty /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure /// Arguments to be used in formatting the message public static void IsNotEmpty(IEnumerable collection, string message, params object[] args) { Assert.That(collection, new NotConstraint(new EmptyConstraint()), message, args); } /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure public static void IsNotEmpty(IEnumerable collection, string message) { IsNotEmpty(collection, message, null); } /// /// Assert that an array,list or other collection is empty /// /// An array, list or other collection implementing IEnumerable public static void IsNotEmpty(IEnumerable collection) { IsNotEmpty(collection, string.Empty, null); } #endregion #region IsOrdered /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure /// Arguments to be used in formatting the message public static void IsOrdered(IEnumerable collection, string message, params object[] args) { Assert.That(collection, new CollectionOrderedConstraint(), message, args); } /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable /// The message to be displayed on failure public static void IsOrdered(IEnumerable collection, string message) { IsOrdered(collection, message, null); } /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable public static void IsOrdered(IEnumerable collection) { IsOrdered(collection, string.Empty, null); } /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable /// A custom comparer to perform the comparisons /// The message to be displayed on failure /// Arguments to be used in formatting the message public static void IsOrdered(IEnumerable collection, IComparer comparer, string message, params object[] args) { Assert.That(collection, new CollectionOrderedConstraint().Using(comparer), message, args); } /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable /// A custom comparer to perform the comparisons /// The message to be displayed on failure public static void IsOrdered(IEnumerable collection, IComparer comparer, string message) { IsOrdered(collection, comparer, message, null); } /// /// Assert that an array, list or other collection is ordered /// /// An array, list or other collection implementing IEnumerable /// A custom comparer to perform the comparisons public static void IsOrdered(IEnumerable collection, IComparer comparer) { IsOrdered(collection, comparer, string.Empty, null); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Text.cs0000664000175000017500000001104311574677674022160 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Helper class with static methods used to supply constraints /// that operate on strings. /// [Obsolete("Use Is class for string constraints")] public class Text { #region All /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them succeed. /// [Obsolete("Use Is.All")] public static ConstraintExpression All { get { return new ConstraintExpression().All; } } #endregion #region Contains /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// [Obsolete("Use Is.StringContaining")] public static SubstringConstraint Contains(string expected) { return new SubstringConstraint(expected); } #endregion #region DoesNotContain /// /// Returns a constraint that fails if the actual /// value contains the substring supplied as an argument. /// [Obsolete("Use Is.Not.StringContaining")] public static SubstringConstraint DoesNotContain(string expected) { return new ConstraintExpression().Not.ContainsSubstring(expected); } #endregion #region StartsWith /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// [Obsolete("Use Is.StringStarting")] public static StartsWithConstraint StartsWith(string expected) { return new StartsWithConstraint(expected); } #endregion #region DoesNotStartWith /// /// Returns a constraint that fails if the actual /// value starts with the substring supplied as an argument. /// public static StartsWithConstraint DoesNotStartWith(string expected) { return new ConstraintExpression().Not.StartsWith(expected); } #endregion #region EndsWith /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// [Obsolete("Use Is.StringEnding")] public static EndsWithConstraint EndsWith(string expected) { return new EndsWithConstraint(expected); } #endregion #region DoesNotEndWith /// /// Returns a constraint that fails if the actual /// value ends with the substring supplied as an argument. /// public static EndsWithConstraint DoesNotEndWith(string expected) { return new ConstraintExpression().Not.EndsWith(expected); } #endregion #region Matches /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// [Obsolete("Use Is.StringMatching")] public static RegexConstraint Matches(string pattern) { return new RegexConstraint(pattern); } #endregion #region DoesNotMatch /// /// Returns a constraint that fails if the actual /// value matches the pattern supplied as an argument. /// [Obsolete] public static RegexConstraint DoesNotMatch(string pattern) { return new ConstraintExpression().Not.Matches(pattern); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/TestCaseData.cs0000664000175000017500000003000711720007124023504 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; namespace NUnit.Framework { /// /// The TestCaseData class represents a set of arguments /// and other parameter info to be used for a parameterized /// test case. It provides a number of instance modifiers /// for use in initializing the test case. /// /// Note: Instance modifiers are getters that return /// the same instance after modifying it's state. /// public class TestCaseData : ITestCaseData { #region Constants //private static readonly string DESCRIPTION = "_DESCRIPTION"; //private static readonly string IGNOREREASON = "_IGNOREREASON"; private static readonly string CATEGORIES = "_CATEGORIES"; #endregion #region Instance Fields /// /// The argument list to be provided to the test /// private object[] arguments; /// /// The expected result to be returned /// private object expectedResult; /// /// Set to true if this has an expected result /// private bool hasExpectedResult; /// /// The expected exception Type /// private Type expectedExceptionType; /// /// The FullName of the expected exception /// private string expectedExceptionName; /// /// The name to be used for the test /// private string testName; /// /// The description of the test /// private string description; /// /// A dictionary of properties, used to add information /// to tests without requiring the class to change. /// private IDictionary properties; /// /// If true, indicates that the test case is to be ignored /// bool isIgnored; /// /// If true, indicates that the test case is marked explicit /// bool isExplicit; /// /// The reason for ignoring a test case /// string ignoreReason; #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// The arguments. public TestCaseData(params object[] args) { if (args == null) this.arguments = new object[] { null }; else this.arguments = args; } /// /// Initializes a new instance of the class. /// /// The argument. public TestCaseData(object arg) { this.arguments = new object[] { arg }; } /// /// Initializes a new instance of the class. /// /// The first argument. /// The second argument. public TestCaseData(object arg1, object arg2) { this.arguments = new object[] { arg1, arg2 }; } /// /// Initializes a new instance of the class. /// /// The first argument. /// The second argument. /// The third argument. public TestCaseData(object arg1, object arg2, object arg3) { this.arguments = new object[] { arg1, arg2, arg3 }; } #endregion #region ITestCaseData Members /// /// Gets the argument list to be provided to the test /// public object[] Arguments { get { return arguments; } } /// /// Gets the expected result /// public object Result { get { return expectedResult; } } /// /// Returns true if the result has been set /// public bool HasExpectedResult { get { return hasExpectedResult; } } /// /// Gets the expected exception Type /// public Type ExpectedException { get { return expectedExceptionType; } } /// /// Gets the FullName of the expected exception /// public string ExpectedExceptionName { get { return expectedExceptionName; } } /// /// Gets the name to be used for the test /// public string TestName { get { return testName; } } /// /// Gets the description of the test /// public string Description { get { return description; } } /// /// Gets a value indicating whether this is ignored. /// /// true if ignored; otherwise, false. public bool Ignored { get { return isIgnored; } } /// /// Gets a value indicating whether this is explicit. /// /// true if explicit; otherwise, false. public bool Explicit { get { return isExplicit; } } /// /// Gets the ignore reason. /// /// The ignore reason. public string IgnoreReason { get { return ignoreReason; } } #endregion #region Additional Public Properties /// /// Gets a list of categories associated with this test. /// public IList Categories { get { if (Properties[CATEGORIES] == null) Properties[CATEGORIES] = new ArrayList(); return (IList)Properties[CATEGORIES]; } } /// /// Gets the property dictionary for this test /// public IDictionary Properties { get { if (properties == null) properties = new ListDictionary(); return properties; } } #endregion #region Fluent Instance Modifiers /// /// Sets the expected result for the test /// /// The expected result /// A modified TestCaseData public TestCaseData Returns(object result) { this.expectedResult = result; this.hasExpectedResult = true; return this; } /// /// Sets the expected exception type for the test /// /// Type of the expected exception. /// The modified TestCaseData instance public TestCaseData Throws(Type exceptionType) { this.expectedExceptionType = exceptionType; this.expectedExceptionName = exceptionType.FullName; return this; } /// /// Sets the expected exception type for the test /// /// FullName of the expected exception. /// The modified TestCaseData instance public TestCaseData Throws(string exceptionName) { this.expectedExceptionName = exceptionName; return this; } /// /// Sets the name of the test case /// /// The modified TestCaseData instance public TestCaseData SetName(string name) { this.testName = name; return this; } /// /// Sets the description for the test case /// being constructed. /// /// The description. /// The modified TestCaseData instance. public TestCaseData SetDescription(string description) { this.description = description; return this; } /// /// Applies a category to the test /// /// /// public TestCaseData SetCategory(string category) { this.Categories.Add(category); return this; } /// /// Applies a named property to the test /// /// /// /// public TestCaseData SetProperty(string propName, string propValue) { this.Properties.Add(propName, propValue); return this; } /// /// Applies a named property to the test /// /// /// /// public TestCaseData SetProperty(string propName, int propValue) { this.Properties.Add(propName, propValue); return this; } /// /// Applies a named property to the test /// /// /// /// public TestCaseData SetProperty(string propName, double propValue) { this.Properties.Add(propName, propValue); return this; } /// /// Ignores this TestCase. /// /// public TestCaseData Ignore() { isIgnored = true; return this; } /// /// Ignores this TestCase, specifying the reason. /// /// The reason. /// public TestCaseData Ignore(string reason) { isIgnored = true; ignoreReason = reason; return this; } /// /// Marks this TestCase as Explicit /// /// public TestCaseData MakeExplicit() { isExplicit = true; return this; } /// /// Marks this TestCase as Explicit, specifying the reason. /// /// The reason. /// public TestCaseData MakeExplicit(string reason) { isExplicit = true; ignoreReason = reason; return this; } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Exceptions/0000775000175000017500000000000011742560362023005 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/framework/Exceptions/SuccessException.cs0000664000175000017500000000243211504175260026617 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; using System.Runtime.Serialization; /// /// Thrown when an assertion failed. /// [Serializable] public class SuccessException : System.Exception { /// public SuccessException(string message) : base(message) { } /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public SuccessException(string message, Exception inner) : base(message, inner) { } /// /// Serialization Constructor /// protected SuccessException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Exceptions/IgnoreException.cs0000664000175000017500000000216011504175260026430 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; using System.Runtime.Serialization; /// /// Thrown when an assertion failed. /// [Serializable] public class IgnoreException : System.Exception { /// public IgnoreException (string message) : base(message) {} /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public IgnoreException(string message, Exception inner) : base(message, inner) {} /// /// Serialization Constructor /// protected IgnoreException(SerializationInfo info, StreamingContext context) : base(info,context) {} } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Exceptions/AssertionException.cs0000664000175000017500000000230711504175260027157 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; using System.Runtime.Serialization; /// /// Thrown when an assertion failed. /// /// [Serializable] public class AssertionException : System.Exception { /// The error message that explains /// the reason for the exception public AssertionException (string message) : base(message) {} /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public AssertionException(string message, Exception inner) : base(message, inner) {} /// /// Serialization Constructor /// protected AssertionException(SerializationInfo info, StreamingContext context) : base(info,context) {} } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Exceptions/InconclusiveException.cs0000664000175000017500000000261511504175260027653 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Framework { using System; using System.Runtime.Serialization; /// /// Thrown when a test executes inconclusively. /// /// [Serializable] public class InconclusiveException : System.Exception { /// The error message that explains /// the reason for the exception public InconclusiveException(string message) : base(message) { } /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public InconclusiveException(string message, Exception inner) : base(message, inner) { } /// /// Serialization Constructor /// protected InconclusiveException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Throws.cs0000664000175000017500000000746111574677674022533 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Helper class with properties and methods that supply /// constraints that operate on exceptions. /// public class Throws { #region Exception /// /// Creates a constraint specifying an expected exception /// public static ResolvableConstraintExpression Exception { get { return new ConstraintExpression().Append(new ThrowsOperator()); } } #endregion #region InnerException /// /// Creates a constraint specifying an exception with a given InnerException /// public static ResolvableConstraintExpression InnerException { get { return Exception.InnerException; } } #endregion #region TargetInvocationException /// /// Creates a constraint specifying an expected TargetInvocationException /// public static ExactTypeConstraint TargetInvocationException { get { return TypeOf(typeof(System.Reflection.TargetInvocationException)); } } #endregion #region ArgumentException /// /// Creates a constraint specifying an expected TargetInvocationException /// public static ExactTypeConstraint ArgumentException { get { return TypeOf(typeof(System.ArgumentException)); } } #endregion #region InvalidOperationException /// /// Creates a constraint specifying an expected TargetInvocationException /// public static ExactTypeConstraint InvalidOperationException { get { return TypeOf(typeof(System.InvalidOperationException)); } } #endregion #region Nothing /// /// Creates a constraint specifying that no exception is thrown /// public static ThrowsNothingConstraint Nothing { get { return new ThrowsNothingConstraint(); } } #endregion #region TypeOf /// /// Creates a constraint specifying the exact type of exception expected /// public static ExactTypeConstraint TypeOf(Type expectedType) { return Exception.TypeOf(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Creates a constraint specifying the exact type of exception expected /// public static ExactTypeConstraint TypeOf() { return TypeOf(typeof(T)); } #endif #endregion #region InstanceOf /// /// Creates a constraint specifying the type of exception expected /// public static InstanceOfTypeConstraint InstanceOf(Type expectedType) { return Exception.InstanceOf(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Creates a constraint specifying the type of exception expected /// public static InstanceOfTypeConstraint InstanceOf() { return InstanceOf(typeof(T)); } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Assume.cs0000664000175000017500000003113611662073720022452 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Provides static methods to express the assumptions /// that must be met for a test to give a meaningful /// result. If an assumption is not met, the test /// should produce an inconclusive result. /// public class Assume { #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { // TODO: This should probably be InvalidOperationException throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region Assume.That #region Object /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test static public void That(object actual, IResolveConstraint expression) { Assume.That(actual, expression, null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(object actual, IResolveConstraint expression, string message) { Assume.That(actual, expression, message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(object actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); if (!constraint.Matches(actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new InconclusiveException(writer.ToString()); } } #endregion #region ActualValueDelegate /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested static public void That(ActualValueDelegate del, IResolveConstraint expr) { Assume.That(del, expr.Resolve(), null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested /// The message that will be displayed on failure static public void That(ActualValueDelegate del, IResolveConstraint expr, string message) { Assume.That(del, expr.Resolve(), message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// An ActualValueDelegate returning the value to be tested /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ActualValueDelegate del, IResolveConstraint expr, string message, params object[] args) { Constraint constraint = expr.Resolve(); if (!constraint.Matches(del)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new InconclusiveException(writer.ToString()); } } #endregion #region ref Object #if CLR_2_0 || CLR_4_0 /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test static public void That(ref T actual, IResolveConstraint expression) { Assume.That(ref actual, expression.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(ref T actual, IResolveConstraint expression, string message) { Assume.That(ref actual, expression.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ref T actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); if (!constraint.Matches(ref actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new InconclusiveException(writer.ToString()); } } #else /// /// Apply a constraint to a referenced boolean, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint to be applied /// The actual value to test static public void That(ref bool actual, IResolveConstraint constraint) { Assume.That(ref actual, constraint.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(ref bool actual, IResolveConstraint constraint, string message) { Assume.That(ref actual, constraint.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an InconclusiveException on failure. /// /// The actual value to test /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ref bool actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); if (!constraint.Matches(ref actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new InconclusiveException(writer.ToString()); } } #endif #endregion #region Boolean /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display if the condition is false /// Arguments to be used in formatting the message static public void That(bool condition, string message, params object[] args) { Assume.That(condition, Is.True, message, args); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display if the condition is false static public void That(bool condition, string message) { Assume.That(condition, Is.True, message, null); } /// /// Asserts that a condition is true. If the condition is false the /// method throws an . /// /// The evaluated condition static public void That(bool condition) { Assume.That(condition, Is.True, null, null); } #endregion /// /// Asserts that the code represented by a delegate throws an exception /// that satisfies the constraint provided. /// /// A TestDelegate to be executed /// A ThrowsConstraint used in the test static public void That(TestDelegate code, IResolveConstraint constraint) { Assume.That((object)code, constraint); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Iz.cs0000664000175000017500000000102311504175260021564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// The Iz class is a synonym for Is intended for use in VB, /// which regards Is as a keyword. /// public class Iz : Is { } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Has.cs0000664000175000017500000001323711647756132021742 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Helper class with properties and methods that supply /// a number of constraints used in Asserts. /// public class Has { #region No /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public static ConstraintExpression No { get { return new ConstraintExpression().Not; } } #endregion #region All /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them succeed. /// public static ConstraintExpression All { get { return new ConstraintExpression().All; } } #endregion #region Some /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if at least one of them succeeds. /// public static ConstraintExpression Some { get { return new ConstraintExpression().Some; } } #endregion #region None /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them fail. /// public static ConstraintExpression None { get { return new ConstraintExpression().None; } } #endregion #region Exactly(n) /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding only if a specified number of them succeed. /// public static ConstraintExpression Exactly(int expectedCount) { return new ConstraintExpression().Exactly(expectedCount); } #endregion #region Property /// /// Returns a new PropertyConstraintExpression, which will either /// test for the existence of the named property on the object /// being tested or apply any following constraint to that property. /// public static ResolvableConstraintExpression Property(string name) { return new ConstraintExpression().Property(name); } #endregion #region Length /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Length property of the object being tested. /// public static ResolvableConstraintExpression Length { get { return Property("Length"); } } #endregion #region Count /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Count property of the object being tested. /// public static ResolvableConstraintExpression Count { get { return Property("Count"); } } #endregion #region Message /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Message property of the object being tested. /// public static ResolvableConstraintExpression Message { get { return Property("Message"); } } #endregion #region InnerException /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the InnerException property of the object being tested. /// public static ResolvableConstraintExpression InnerException { get { return Property("InnerException"); } } #endregion #region Attribute /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public static ResolvableConstraintExpression Attribute(Type expectedType) { return new ConstraintExpression().Attribute(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public static ResolvableConstraintExpression Attribute() { return Attribute(typeof(T)); } #endif #endregion #region Member /// /// Returns a new CollectionContainsConstraint checking for the /// presence of a particular object in the collection. /// public static CollectionContainsConstraint Member(object expected) { return new CollectionContainsConstraint(expected); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/DirectoryAssert.cs0000664000175000017500000006346211504175260024347 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.IO; using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Summary description for DirectoryAssert /// [Obsolete("Use Assert with constraint-based syntax")] public class DirectoryAssert { #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region Constructor /// /// We don't actually want any instances of this object, but some people /// like to inherit from it to add other static methods. Hence, the /// protected constructor disallows any instances of this object. /// protected DirectoryAssert() { } #endregion #region AreEqual /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void AreEqual(DirectoryInfo expected, DirectoryInfo actual, string message, params object[] args) { Assert.That(actual, new EqualConstraint(expected), message, args); } /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value /// The message to display if directories are not equal static public void AreEqual(DirectoryInfo expected, DirectoryInfo actual, string message) { AreEqual(actual, expected, message, null); } /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value static public void AreEqual(DirectoryInfo expected, DirectoryInfo actual) { AreEqual(actual, expected, string.Empty, null); } /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void AreEqual(string expected, string actual, string message, params object[] args) { // create a directory info object for the expected path DirectoryInfo diExpected = new DirectoryInfo(expected); // create a directory info object for the actual path DirectoryInfo diActual = new DirectoryInfo(actual); AreEqual(diExpected, diActual, message, args); } /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value /// The message to display if directories are not equal static public void AreEqual(string expected, string actual, string message) { AreEqual(expected, actual, message, null); } /// /// Verifies that two directories are equal. Two directories are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value static public void AreEqual(string expected, string actual) { AreEqual(expected, actual, string.Empty, null); } #endregion #region AreNotEqual /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void AreNotEqual(DirectoryInfo expected, DirectoryInfo actual, string message, params object[] args) { Assert.That(actual, new NotConstraint(new EqualConstraint(expected)), message, args); } /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value /// The message to display if directories are not equal static public void AreNotEqual(DirectoryInfo expected, DirectoryInfo actual, string message) { AreNotEqual(actual, expected, message, null); } /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory containing the value that is expected /// A directory containing the actual value static public void AreNotEqual(DirectoryInfo expected, DirectoryInfo actual) { AreNotEqual(actual, expected, string.Empty, null); } /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value /// The message to display if directories are equal /// Arguments to be used in formatting the message static public void AreNotEqual(string expected, string actual, string message, params object[] args) { // create a directory info object for the expected path DirectoryInfo diExpected = new DirectoryInfo(expected); // create a directory info object for the actual path DirectoryInfo diActual = new DirectoryInfo(actual); AreNotEqual(diExpected, diActual, message, args); } /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value /// The message to display if directories are equal static public void AreNotEqual(string expected, string actual, string message) { AreNotEqual(expected, actual, message, null); } /// /// Asserts that two directories are not equal. If they are equal /// an is thrown. /// /// A directory path string containing the value that is expected /// A directory path string containing the actual value static public void AreNotEqual(string expected, string actual) { AreNotEqual(expected, actual, string.Empty, null); } #endregion #region IsEmpty /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void IsEmpty(DirectoryInfo directory, string message, params object[] args) { Assert.That( directory, new EmptyDirectoryContraint(), message, args); } /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal static public void IsEmpty(DirectoryInfo directory, string message) { IsEmpty(directory, message, null); } /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search static public void IsEmpty(DirectoryInfo directory) { IsEmpty(directory, string.Empty, null); } /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void IsEmpty(string directory, string message, params object[] args) { IsEmpty(new DirectoryInfo(directory), message, args); } /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal static public void IsEmpty(string directory, string message) { IsEmpty(directory, message, null); } /// /// Asserts that the directory is empty. If it is not empty /// an is thrown. /// /// A directory to search static public void IsEmpty(string directory) { IsEmpty(directory, string.Empty, null); } #endregion #region IsNotEmpty /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void IsNotEmpty(DirectoryInfo directory, string message, params object[] args) { Assert.That( directory, new NotConstraint(new EmptyDirectoryContraint()), message, args); } /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal static public void IsNotEmpty(DirectoryInfo directory, string message) { IsNotEmpty(directory, message, null); } /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search static public void IsNotEmpty(DirectoryInfo directory) { IsNotEmpty(directory, string.Empty, null); } /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal /// Arguments to be used in formatting the message static public void IsNotEmpty(string directory, string message, params object[] args) { DirectoryInfo diActual = new DirectoryInfo(directory); IsNotEmpty(diActual, message, args); } /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search /// The message to display if directories are not equal static public void IsNotEmpty(string directory, string message) { IsNotEmpty(directory, message, null); } /// /// Asserts that the directory is not empty. If it is empty /// an is thrown. /// /// A directory to search static public void IsNotEmpty(string directory) { IsNotEmpty(directory, string.Empty, null); } #endregion #region IsWithin /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path /// Arguments to be used in formatting the message public static void IsWithin(DirectoryInfo directory, DirectoryInfo actual, string message, params object[] args) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsWithin(directory.FullName, actual.FullName, message, args); } /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path static public void IsWithin(DirectoryInfo directory, DirectoryInfo actual, string message) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsWithin(directory.FullName, actual.FullName, message, null); } /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory static public void IsWithin(DirectoryInfo directory, DirectoryInfo actual) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsWithin(directory.FullName, actual.FullName, string.Empty, null); } /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path /// Arguments to be used in formatting the message static public void IsWithin(string directory, string actual, string message, params object[] args) { Assert.That(actual, new SubPathConstraint(directory), message, args); } /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path static public void IsWithin(string directory, string actual, string message) { IsWithin(directory, actual, message, null); } /// /// Asserts that path contains actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory static public void IsWithin(string directory, string actual) { IsWithin(directory, actual, string.Empty, null); } #endregion #region IsNotWithin /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path /// Arguments to be used in formatting the message static public void IsNotWithin(DirectoryInfo directory, DirectoryInfo actual, string message, params object[] args) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsNotWithin(directory.FullName, actual.FullName, message, args); } /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path static public void IsNotWithin(DirectoryInfo directory, DirectoryInfo actual, string message) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsNotWithin(directory.FullName, actual.FullName, message, null); } /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory static public void IsNotWithin(DirectoryInfo directory, DirectoryInfo actual) { if (directory == null) throw new ArgumentException("The directory may not be null", "directory"); if (directory == null) throw new ArgumentException("The actual value may not be null", "actual"); IsNotWithin(directory.FullName, actual.FullName, string.Empty, null); } /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path /// Arguments to be used in formatting the message static public void IsNotWithin(string directory, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint(new SubPathConstraint(directory)), message, args); } /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory /// The message to display if directory is not within the path static public void IsNotWithin(string directory, string actual, string message) { IsNotWithin(directory, actual, message, null); } /// /// Asserts that path does not contain actual as a subdirectory or /// an is thrown. /// /// A directory to search /// sub-directory asserted to exist under directory static public void IsNotWithin(string directory, string actual) { IsNotWithin(directory, actual, string.Empty, null); } #endregion } }NUnit-2.6.0.12051/src/NUnitFramework/framework/nunit.framework.dll.csproj0000664000175000017500000002233111712475522026012 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {83DD7E12-A705-4DBA-9D71-09C8973D9382} Debug AnyCPU nunit.framework JScript Grid IE50 false Library NUnit.Framework OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\framework\ 285212672 TRACE;DEBUG;CLR_2_0 ..\..\..\bin\Debug\framework\nunit.framework.xml true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\framework\ 285212672 TRACE;CLR_2_0 ..\..\..\bin\Release\framework\nunit.framework.xml 4096 1699 true false false 4 none prompt System System.Data System.XML CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/0000775000175000017500000000000011742560362023173 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/Numerics.cs0000664000175000017500000003456011504175260025312 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// The Numerics class contains common operations on numeric values. /// public class Numerics { #region Numeric Type Recognition /// /// Checks the type of the object, returning true if /// the object is a numeric type. /// /// The object to check /// true if the object is a numeric type public static bool IsNumericType(Object obj) { return IsFloatingPointNumeric( obj ) || IsFixedPointNumeric( obj ); } /// /// Checks the type of the object, returning true if /// the object is a floating point numeric type. /// /// The object to check /// true if the object is a floating point numeric type public static bool IsFloatingPointNumeric(Object obj) { if (null != obj) { if (obj is System.Double) return true; if (obj is System.Single) return true; } return false; } /// /// Checks the type of the object, returning true if /// the object is a fixed point numeric type. /// /// The object to check /// true if the object is a fixed point numeric type public static bool IsFixedPointNumeric(Object obj) { if (null != obj) { if (obj is System.Byte) return true; if (obj is System.SByte) return true; if (obj is System.Decimal) return true; if (obj is System.Int32) return true; if (obj is System.UInt32) return true; if (obj is System.Int64) return true; if (obj is System.UInt64) return true; if (obj is System.Int16) return true; if (obj is System.UInt16) return true; } return false; } #endregion #region Numeric Equality /// /// Test two numeric values for equality, performing the usual numeric /// conversions and using a provided or default tolerance. If the tolerance /// provided is Empty, this method may set it to a default tolerance. /// /// The expected value /// The actual value /// A reference to the tolerance in effect /// True if the values are equal public static bool AreEqual( object expected, object actual, ref Tolerance tolerance ) { if ( expected is double || actual is double ) return AreEqual( Convert.ToDouble(expected), Convert.ToDouble(actual), ref tolerance ); if ( expected is float || actual is float ) return AreEqual( Convert.ToSingle(expected), Convert.ToSingle(actual), ref tolerance ); if (tolerance.Mode == ToleranceMode.Ulps) throw new InvalidOperationException("Ulps may only be specified for floating point arguments"); if ( expected is decimal || actual is decimal ) return AreEqual( Convert.ToDecimal(expected), Convert.ToDecimal(actual), tolerance ); if (expected is ulong || actual is ulong) return AreEqual(Convert.ToUInt64(expected), Convert.ToUInt64(actual), tolerance ); if ( expected is long || actual is long ) return AreEqual( Convert.ToInt64(expected), Convert.ToInt64(actual), tolerance ); if ( expected is uint || actual is uint ) return AreEqual( Convert.ToUInt32(expected), Convert.ToUInt32(actual), tolerance ); return AreEqual( Convert.ToInt32(expected), Convert.ToInt32(actual), tolerance ); } private static bool AreEqual( double expected, double actual, ref Tolerance tolerance ) { if (double.IsNaN(expected) && double.IsNaN(actual)) return true; // Handle infinity specially since subtracting two infinite values gives // NaN and the following test fails. mono also needs NaN to be handled // specially although ms.net could use either method. Also, handle // situation where no tolerance is used. if (double.IsInfinity(expected) || double.IsNaN(expected) || double.IsNaN(actual)) { return expected.Equals(actual); } if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d) tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance); switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value); case ToleranceMode.Percent: if (expected == 0.0) return expected.Equals(actual); double relativeError = Math.Abs((expected - actual) / expected); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); #if !NETCF_1_0 case ToleranceMode.Ulps: return FloatingPointNumerics.AreAlmostEqualUlps( expected, actual, Convert.ToInt64(tolerance.Value)); #endif default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( float expected, float actual, ref Tolerance tolerance ) { if ( float.IsNaN(expected) && float.IsNaN(actual) ) return true; // handle infinity specially since subtracting two infinite values gives // NaN and the following test fails. mono also needs NaN to be handled // specially although ms.net could use either method. if (float.IsInfinity(expected) || float.IsNaN(expected) || float.IsNaN(actual)) { return expected.Equals(actual); } if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d) tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance); switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value); case ToleranceMode.Percent: if (expected == 0.0f) return expected.Equals(actual); float relativeError = Math.Abs((expected - actual) / expected); return (relativeError <= Convert.ToSingle(tolerance.Value) / 100.0f); #if !NETCF_1_0 case ToleranceMode.Ulps: return FloatingPointNumerics.AreAlmostEqualUlps( expected, actual, Convert.ToInt32(tolerance.Value)); #endif default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( decimal expected, decimal actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: decimal decimalTolerance = Convert.ToDecimal(tolerance.Value); if(decimalTolerance > 0m) return Math.Abs(expected - actual) <= decimalTolerance; return expected.Equals( actual ); case ToleranceMode.Percent: if(expected == 0m) return expected.Equals(actual); double relativeError = Math.Abs( (double)(expected - actual) / (double)expected); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( ulong expected, ulong actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: ulong ulongTolerance = Convert.ToUInt64(tolerance.Value); if(ulongTolerance > 0ul) { ulong diff = expected >= actual ? expected - actual : actual - expected; return diff <= ulongTolerance; } return expected.Equals( actual ); case ToleranceMode.Percent: if (expected == 0ul) return expected.Equals(actual); // Can't do a simple Math.Abs() here since it's unsigned ulong difference = Math.Max(expected, actual) - Math.Min(expected, actual); double relativeError = Math.Abs( (double)difference / (double)expected ); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( long expected, long actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: long longTolerance = Convert.ToInt64(tolerance.Value); if(longTolerance > 0L) return Math.Abs(expected - actual) <= longTolerance; return expected.Equals( actual ); case ToleranceMode.Percent: if(expected == 0L) return expected.Equals(actual); double relativeError = Math.Abs( (double)(expected - actual) / (double)expected); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( uint expected, uint actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: uint uintTolerance = Convert.ToUInt32(tolerance.Value); if(uintTolerance > 0) { uint diff = expected >= actual ? expected - actual : actual - expected; return diff <= uintTolerance; } return expected.Equals( actual ); case ToleranceMode.Percent: if(expected == 0u) return expected.Equals(actual); // Can't do a simple Math.Abs() here since it's unsigned uint difference = Math.Max(expected, actual) - Math.Min(expected, actual); double relativeError = Math.Abs((double)difference / (double)expected ); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } private static bool AreEqual( int expected, int actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: int intTolerance = Convert.ToInt32(tolerance.Value); if (intTolerance > 0) return Math.Abs(expected - actual) <= intTolerance; return expected.Equals(actual); case ToleranceMode.Percent: if (expected == 0) return expected.Equals(actual); double relativeError = Math.Abs( (double)(expected - actual) / (double)expected); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } } #endregion #region Numeric Comparisons /// /// Compare two numeric values, performing the usual numeric conversions. /// /// The expected value /// The actual value /// The relationship of the values to each other public static int Compare( object expected, object actual ) { if( !IsNumericType( expected ) || !IsNumericType( actual ) ) throw new ArgumentException( "Both arguments must be numeric"); if ( IsFloatingPointNumeric(expected) || IsFloatingPointNumeric(actual) ) return Convert.ToDouble(expected).CompareTo(Convert.ToDouble(actual)); if ( expected is decimal || actual is decimal ) return Convert.ToDecimal(expected).CompareTo(Convert.ToDecimal(actual)); if ( expected is ulong || actual is ulong ) return Convert.ToUInt64(expected).CompareTo(Convert.ToUInt64(actual)); if ( expected is long || actual is long ) return Convert.ToInt64(expected).CompareTo(Convert.ToInt64(actual)); if ( expected is uint || actual is uint ) return Convert.ToUInt32(expected).CompareTo(Convert.ToUInt32(actual)); return Convert.ToInt32(expected).CompareTo(Convert.ToInt32(actual)); } #endregion private Numerics() { } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/NUnitComparer.cs0000664000175000017500000000600511662016370026245 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Reflection; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// NUnitComparer encapsulates NUnit's default behavior /// in comparing two objects. /// public class NUnitComparer : IComparer { /// /// Returns the default NUnitComparer. /// public static NUnitComparer Default { get { return new NUnitComparer(); } } /// /// Compares two objects /// /// /// /// public int Compare(object x, object y) { if (x == null) return y == null ? 0 : -1; else if (y == null) return +1; if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) return Numerics.Compare(x, y); if (x is IComparable) return ((IComparable)x).CompareTo(y); if (y is IComparable) return -((IComparable)y).CompareTo(x); Type xType = x.GetType(); Type yType = y.GetType(); MethodInfo method = xType.GetMethod("CompareTo", new Type[] { yType }); if (method != null) return (int)method.Invoke(x, new object[] { y }); method = yType.GetMethod("CompareTo", new Type[] { xType }); if (method != null) return -(int)method.Invoke(y, new object[] { x }); throw new ArgumentException("Neither value implements IComparable or IComparable"); } } #if CLR_2_0 || CLR_4_0 /// /// Generic version of NUnitComparer /// /// public class NUnitComparer : IComparer { /// /// Compare two objects of the same type /// public int Compare(T x, T y) { if (x == null) return y == null ? 0 : -1; else if (y == null) return +1; if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) return Numerics.Compare(x, y); if (x is IComparable) return ((IComparable)x).CompareTo(y); if (x is IComparable) return ((IComparable)x).CompareTo(y); throw new ArgumentException("Neither value implements IComparable or IComparable"); } } #endif } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/EqualConstraint.cs0000664000175000017500000005205411651237536026647 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// EqualConstraint is able to compare an actual value with the /// expected value provided in its constructor. Two objects are /// considered equal if both are null, or if both have the same /// value. NUnit has special semantics for some object types. /// public class EqualConstraint : Constraint { #region Static and Instance Fields private readonly object expected; private Tolerance tolerance = Tolerance.Empty; /// /// If true, strings in error messages will be clipped /// private bool clipStrings = true; /// /// NUnitEqualityComparer used to test equality. /// private NUnitEqualityComparer comparer = new NUnitEqualityComparer(); #region Message Strings private static readonly string StringsDiffer_1 = "String lengths are both {0}. Strings differ at index {1}."; private static readonly string StringsDiffer_2 = "Expected string length {0} but was {1}. Strings differ at index {2}."; private static readonly string StreamsDiffer_1 = "Stream lengths are both {0}. Streams differ at offset {1}."; private static readonly string StreamsDiffer_2 = "Expected Stream length {0} but was {1}.";// Streams differ at offset {2}."; private static readonly string CollectionType_1 = "Expected and actual are both {0}"; private static readonly string CollectionType_2 = "Expected is {0}, actual is {1}"; private static readonly string ValuesDiffer_1 = "Values differ at index {0}"; private static readonly string ValuesDiffer_2 = "Values differ at expected index {0}, actual index {1}"; #endregion #endregion #region Constructor /// /// Initializes a new instance of the class. /// /// The expected value. public EqualConstraint(object expected) : base(expected) { this.expected = expected; } #endregion #region Constraint Modifiers /// /// Flag the constraint to ignore case and return self. /// public EqualConstraint IgnoreCase { get { comparer.IgnoreCase = true; return this; } } /// /// Flag the constraint to suppress string clipping /// and return self. /// public EqualConstraint NoClip { get { clipStrings = false; return this; } } /// /// Flag the constraint to compare arrays as collections /// and return self. /// public EqualConstraint AsCollection { get { comparer.CompareAsCollection = true; return this; } } /// /// Flag the constraint to use a tolerance when determining equality. /// /// Tolerance value to be used /// Self. public EqualConstraint Within(object amount) { if (!tolerance.IsEmpty) throw new InvalidOperationException("Within modifier may appear only once in a constraint expression"); tolerance = new Tolerance(amount); return this; } /// /// Switches the .Within() modifier to interpret its tolerance as /// a distance in representable values (see remarks). /// /// Self. /// /// Ulp stands for "unit in the last place" and describes the minimum /// amount a given value can change. For any integers, an ulp is 1 whole /// digit. For floating point values, the accuracy of which is better /// for smaller numbers and worse for larger numbers, an ulp depends /// on the size of the number. Using ulps for comparison of floating /// point results instead of fixed tolerances is safer because it will /// automatically compensate for the added inaccuracy of larger numbers. /// public EqualConstraint Ulps { get { tolerance = tolerance.Ulps; return this; } } /// /// Switches the .Within() modifier to interpret its tolerance as /// a percentage that the actual values is allowed to deviate from /// the expected value. /// /// Self public EqualConstraint Percent { get { tolerance = tolerance.Percent; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in days. /// /// Self public EqualConstraint Days { get { tolerance = tolerance.Days; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in hours. /// /// Self public EqualConstraint Hours { get { tolerance = tolerance.Hours; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in minutes. /// /// Self public EqualConstraint Minutes { get { tolerance = tolerance.Minutes; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in seconds. /// /// Self public EqualConstraint Seconds { get { tolerance = tolerance.Seconds; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in milliseconds. /// /// Self public EqualConstraint Milliseconds { get { tolerance = tolerance.Milliseconds; return this; } } /// /// Causes the tolerance to be interpreted as a TimeSpan in clock ticks. /// /// Self public EqualConstraint Ticks { get { tolerance = tolerance.Ticks; return this; } } /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. [Obsolete("Replace with 'Using'")] public EqualConstraint Comparer(IComparer comparer) { return Using(comparer); } /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public EqualConstraint Using(IComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } #if CLR_2_0 || CLR_4_0 /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public EqualConstraint Using(IComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For( comparer )); return this; } /// /// Flag the constraint to use the supplied Comparison object. /// /// The IComparer object to use. /// Self. public EqualConstraint Using(Comparison comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For( comparer )); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public EqualConstraint Using(IEqualityComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public EqualConstraint Using(IEqualityComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } #endif #endregion #region Public Methods /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; return comparer.AreEqual(expected, actual, ref tolerance); } /// /// Write a failure message. Overridden to provide custom /// failure messages for EqualConstraint. /// /// The MessageWriter to write to public override void WriteMessageTo(MessageWriter writer) { DisplayDifferences(writer, expected, actual, 0); } /// /// Write description of this constraint /// /// The MessageWriter to write to public override void WriteDescriptionTo(MessageWriter writer) { writer.WriteExpectedValue( expected ); if (tolerance != null && !tolerance.IsEmpty) { writer.WriteConnector("+/-"); writer.WriteExpectedValue(tolerance.Value); if (tolerance.Mode != ToleranceMode.Linear) writer.Write(" {0}", tolerance.Mode); } if ( comparer.IgnoreCase ) writer.WriteModifier("ignoring case"); } private void DisplayDifferences(MessageWriter writer, object expected, object actual, int depth) { if (expected is string && actual is string) DisplayStringDifferences(writer, (string)expected, (string)actual); else if (expected is ICollection && actual is ICollection) DisplayCollectionDifferences(writer, (ICollection)expected, (ICollection)actual, depth); else if (expected is IEnumerable && actual is IEnumerable) DisplayEnumerableDifferences(writer, (IEnumerable)expected, (IEnumerable)actual, depth); else if (expected is Stream && actual is Stream) DisplayStreamDifferences(writer, (Stream)expected, (Stream)actual, depth); else if (tolerance != null) writer.DisplayDifferences(expected, actual, tolerance); else writer.DisplayDifferences(expected, actual); } #endregion #region DisplayStringDifferences private void DisplayStringDifferences(MessageWriter writer, string expected, string actual) { int mismatch = MsgUtils.FindMismatchPosition(expected, actual, 0, comparer.IgnoreCase); if (expected.Length == actual.Length) writer.WriteMessageLine(StringsDiffer_1, expected.Length, mismatch); else writer.WriteMessageLine(StringsDiffer_2, expected.Length, actual.Length, mismatch); writer.DisplayStringDifferences(expected, actual, mismatch, comparer.IgnoreCase, clipStrings); } #endregion #region DisplayStreamDifferences private void DisplayStreamDifferences(MessageWriter writer, Stream expected, Stream actual, int depth) { if ( expected.Length == actual.Length ) { long offset = (long)comparer.FailurePoints[depth]; writer.WriteMessageLine(StreamsDiffer_1, expected.Length, offset); } else writer.WriteMessageLine(StreamsDiffer_2, expected.Length, actual.Length); } #endregion #region DisplayCollectionDifferences /// /// Display the failure information for two collections that did not match. /// /// The MessageWriter on which to display /// The expected collection. /// The actual collection /// The depth of this failure in a set of nested collections private void DisplayCollectionDifferences(MessageWriter writer, ICollection expected, ICollection actual, int depth) { DisplayTypesAndSizes(writer, expected, actual, depth); if (comparer.FailurePoints.Count > depth) { NUnitEqualityComparer.FailurePoint failurePoint = (NUnitEqualityComparer.FailurePoint)comparer.FailurePoints[depth]; DisplayFailurePoint(writer, expected, actual, failurePoint, depth); if (failurePoint.ExpectedHasData && failurePoint.ActualHasData) DisplayDifferences( writer, failurePoint.ExpectedValue, failurePoint.ActualValue, ++depth); else if (failurePoint.ActualHasData) { writer.Write(" Extra: "); writer.WriteCollectionElements(actual, failurePoint.Position, 3); } else { writer.Write(" Missing: "); writer.WriteCollectionElements(expected, failurePoint.Position, 3); } } } /// /// Displays a single line showing the types and sizes of the expected /// and actual enumerations, collections or arrays. If both are identical, /// the value is only shown once. /// /// The MessageWriter on which to display /// The expected collection or array /// The actual collection or array /// The indentation level for the message line private void DisplayTypesAndSizes(MessageWriter writer, IEnumerable expected, IEnumerable actual, int indent) { string sExpected = MsgUtils.GetTypeRepresentation(expected); if (expected is ICollection && !(expected is Array)) sExpected += string.Format(" with {0} elements", ((ICollection)expected).Count); string sActual = MsgUtils.GetTypeRepresentation(actual); if (actual is ICollection && !(actual is Array)) sActual += string.Format(" with {0} elements", ((ICollection)actual).Count); if (sExpected == sActual) writer.WriteMessageLine(indent, CollectionType_1, sExpected); else writer.WriteMessageLine(indent, CollectionType_2, sExpected, sActual); } /// /// Displays a single line showing the point in the expected and actual /// arrays at which the comparison failed. If the arrays have different /// structures or dimensions, both values are shown. /// /// The MessageWriter on which to display /// The expected array /// The actual array /// Index of the failure point in the underlying collections /// The indentation level for the message line private void DisplayFailurePoint(MessageWriter writer, IEnumerable expected, IEnumerable actual, NUnitEqualityComparer.FailurePoint failurePoint, int indent) { Array expectedArray = expected as Array; Array actualArray = actual as Array; int expectedRank = expectedArray != null ? expectedArray.Rank : 1; int actualRank = actualArray != null ? actualArray.Rank : 1; bool useOneIndex = expectedRank == actualRank; if (expectedArray != null && actualArray != null) for (int r = 1; r < expectedRank && useOneIndex; r++) if (expectedArray.GetLength(r) != actualArray.GetLength(r)) useOneIndex = false; int[] expectedIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(expected, failurePoint.Position); if (useOneIndex) { writer.WriteMessageLine(indent, ValuesDiffer_1, MsgUtils.GetArrayIndicesAsString(expectedIndices)); } else { int[] actualIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(actual, failurePoint.Position); writer.WriteMessageLine(indent, ValuesDiffer_2, MsgUtils.GetArrayIndicesAsString(expectedIndices), MsgUtils.GetArrayIndicesAsString(actualIndices)); } } private static object GetValueFromCollection(ICollection collection, int index) { Array array = collection as Array; if (array != null && array.Rank > 1) return array.GetValue(MsgUtils.GetArrayIndicesFromCollectionIndex(array, index)); if (collection is IList) return ((IList)collection)[index]; foreach (object obj in collection) if (--index < 0) return obj; return null; } #endregion #region DisplayEnumerableDifferences /// /// Display the failure information for two IEnumerables that did not match. /// /// The MessageWriter on which to display /// The expected enumeration. /// The actual enumeration /// The depth of this failure in a set of nested collections private void DisplayEnumerableDifferences(MessageWriter writer, IEnumerable expected, IEnumerable actual, int depth) { DisplayTypesAndSizes(writer, expected, actual, depth); if (comparer.FailurePoints.Count > depth) { NUnitEqualityComparer.FailurePoint failurePoint = (NUnitEqualityComparer.FailurePoint)comparer.FailurePoints[depth]; DisplayFailurePoint(writer, expected, actual, failurePoint, depth); if (failurePoint.ExpectedHasData && failurePoint.ActualHasData) DisplayDifferences( writer, failurePoint.ExpectedValue, failurePoint.ActualValue, ++depth); //else if (failurePoint.ActualHasData) //{ // writer.Write(" Extra: "); // writer.WriteCollectionElements(actual, failurePoint.Position, 3); //} //else //{ // writer.Write(" Missing: "); // writer.WriteCollectionElements(expected, failurePoint.Position, 3); //} } } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/LessThanOrEqualConstraint.cs0000664000175000017500000000377311550363552030612 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Tests whether a value is less than or equal to the value supplied to its constructor /// public class LessThanOrEqualConstraint : ComparisonConstraint { /// /// The value against which a comparison is to be made /// private object expected; /// /// Initializes a new instance of the class. /// /// The expected value. public LessThanOrEqualConstraint(object expected) : base(expected) { this.expected = expected; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("less than or equal to"); writer.WriteExpectedValue(expected); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (expected == null || actual == null) throw new ArgumentException("Cannot compare using a null reference"); return comparer.Compare(actual, expected) <= 0; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ConstraintOperators.cs0000664000175000017500000003754211647757010027562 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { #region ConstraintOperator Base Class /// /// The ConstraintOperator class is used internally by a /// ConstraintBuilder to represent an operator that /// modifies or combines constraints. /// /// Constraint operators use left and right precedence /// values to determine whether the top operator on the /// stack should be reduced before pushing a new operator. /// public abstract class ConstraintOperator { private object leftContext; private object rightContext; /// /// The precedence value used when the operator /// is about to be pushed to the stack. /// protected int left_precedence; /// /// The precedence value used when the operator /// is on the top of the stack. /// protected int right_precedence; /// /// The syntax element preceding this operator /// public object LeftContext { get { return leftContext; } set { leftContext = value; } } /// /// The syntax element folowing this operator /// public object RightContext { get { return rightContext; } set { rightContext = value; } } /// /// The precedence value used when the operator /// is about to be pushed to the stack. /// public virtual int LeftPrecedence { get { return left_precedence; } } /// /// The precedence value used when the operator /// is on the top of the stack. /// public virtual int RightPrecedence { get { return right_precedence; } } /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// /// public abstract void Reduce(ConstraintBuilder.ConstraintStack stack); } #endregion #region Prefix Operators #region PrefixOperator /// /// PrefixOperator takes a single constraint and modifies /// it's action in some way. /// public abstract class PrefixOperator : ConstraintOperator { /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// /// public override void Reduce(ConstraintBuilder.ConstraintStack stack) { stack.Push(ApplyPrefix(stack.Pop())); } /// /// Returns the constraint created by applying this /// prefix to another constraint. /// /// /// public abstract Constraint ApplyPrefix(Constraint constraint); } #endregion #region NotOperator /// /// Negates the test of the constraint it wraps. /// public class NotOperator : PrefixOperator { /// /// Constructs a new NotOperator /// public NotOperator() { // Not stacks on anything and only allows other // prefix ops to stack on top of it. this.left_precedence = this.right_precedence = 1; } /// /// Returns a NotConstraint applied to its argument. /// public override Constraint ApplyPrefix(Constraint constraint) { return new NotConstraint(constraint); } } #endregion #region Collection Operators /// /// Abstract base for operators that indicate how to /// apply a constraint to items in a collection. /// public abstract class CollectionOperator : PrefixOperator { /// /// Constructs a CollectionOperator /// public CollectionOperator() { // Collection Operators stack on everything // and allow all other ops to stack on them this.left_precedence = 1; this.right_precedence = 10; } } /// /// Represents a constraint that succeeds if all the /// members of a collection match a base constraint. /// public class AllOperator : CollectionOperator { /// /// Returns a constraint that will apply the argument /// to the members of a collection, succeeding if /// they all succeed. /// public override Constraint ApplyPrefix(Constraint constraint) { return new AllItemsConstraint(constraint); } } /// /// Represents a constraint that succeeds if any of the /// members of a collection match a base constraint. /// public class SomeOperator : CollectionOperator { /// /// Returns a constraint that will apply the argument /// to the members of a collection, succeeding if /// any of them succeed. /// public override Constraint ApplyPrefix(Constraint constraint) { return new SomeItemsConstraint(constraint); } } /// /// Represents a constraint that succeeds if none of the /// members of a collection match a base constraint. /// public class NoneOperator : CollectionOperator { /// /// Returns a constraint that will apply the argument /// to the members of a collection, succeeding if /// none of them succeed. /// public override Constraint ApplyPrefix(Constraint constraint) { return new NoItemConstraint(constraint); } } /// /// Represents a constraint that succeeds if the specified /// count of members of a collection match a base constraint. /// public class ExactCountOperator : CollectionOperator { private int expectedCount; /// /// Construct an ExactCountOperator for a specified count /// /// The expected count public ExactCountOperator(int expectedCount) { this.expectedCount = expectedCount; } /// /// Returns a constraint that will apply the argument /// to the members of a collection, succeeding if /// none of them succeed. /// public override Constraint ApplyPrefix(Constraint constraint) { return new ExactCountConstraint(expectedCount, constraint); } } #endregion #region WithOperator /// /// Represents a constraint that simply wraps the /// constraint provided as an argument, without any /// further functionality, but which modifes the /// order of evaluation because of its precedence. /// public class WithOperator : PrefixOperator { /// /// Constructor for the WithOperator /// public WithOperator() { this.left_precedence = 1; this.right_precedence = 4; } /// /// Returns a constraint that wraps its argument /// public override Constraint ApplyPrefix(Constraint constraint) { return constraint; } } #endregion #region SelfResolving Operators #region SelfResolvingOperator /// /// Abstract base class for operators that are able to reduce to a /// constraint whether or not another syntactic element follows. /// public abstract class SelfResolvingOperator : ConstraintOperator { } #endregion #region PropOperator /// /// Operator used to test for the presence of a named Property /// on an object and optionally apply further tests to the /// value of that property. /// public class PropOperator : SelfResolvingOperator { private string name; /// /// Gets the name of the property to which the operator applies /// public string Name { get { return name; } } /// /// Constructs a PropOperator for a particular named property /// public PropOperator(string name) { this.name = name; // Prop stacks on anything and allows only // prefix operators to stack on it. this.left_precedence = this.right_precedence = 1; } /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// /// public override void Reduce(ConstraintBuilder.ConstraintStack stack) { if (RightContext == null || RightContext is BinaryOperator) stack.Push(new PropertyExistsConstraint(name)); else stack.Push(new PropertyConstraint(name, stack.Pop())); } } #endregion #region AttributeOperator /// /// Operator that tests for the presence of a particular attribute /// on a type and optionally applies further tests to the attribute. /// public class AttributeOperator : SelfResolvingOperator { private Type type; /// /// Construct an AttributeOperator for a particular Type /// /// The Type of attribute tested public AttributeOperator(Type type) { this.type = type; // Attribute stacks on anything and allows only // prefix operators to stack on it. this.left_precedence = this.right_precedence = 1; } /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// public override void Reduce(ConstraintBuilder.ConstraintStack stack) { if (RightContext == null || RightContext is BinaryOperator) stack.Push(new AttributeExistsConstraint(type)); else stack.Push(new AttributeConstraint(type, stack.Pop())); } } #endregion #region ThrowsOperator /// /// Operator that tests that an exception is thrown and /// optionally applies further tests to the exception. /// public class ThrowsOperator : SelfResolvingOperator { /// /// Construct a ThrowsOperator /// public ThrowsOperator() { // ThrowsOperator stacks on everything but // it's always the first item on the stack // anyway. It is evaluated last of all ops. this.left_precedence = 1; this.right_precedence = 100; } /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// public override void Reduce(ConstraintBuilder.ConstraintStack stack) { if (RightContext == null || RightContext is BinaryOperator) stack.Push(new ThrowsConstraint(null)); else stack.Push(new ThrowsConstraint(stack.Pop())); } } #endregion #endregion #endregion #region Binary Operators #region BinaryOperator /// /// Abstract base class for all binary operators /// public abstract class BinaryOperator : ConstraintOperator { /// /// Reduce produces a constraint from the operator and /// any arguments. It takes the arguments from the constraint /// stack and pushes the resulting constraint on it. /// /// public override void Reduce(ConstraintBuilder.ConstraintStack stack) { Constraint right = stack.Pop(); Constraint left = stack.Pop(); stack.Push(ApplyOperator(left, right)); } /// /// Gets the left precedence of the operator /// public override int LeftPrecedence { get { return RightContext is CollectionOperator ? base.LeftPrecedence + 10 : base.LeftPrecedence; } } /// /// Gets the right precedence of the operator /// public override int RightPrecedence { get { return RightContext is CollectionOperator ? base.RightPrecedence + 10 : base.RightPrecedence; } } /// /// Abstract method that produces a constraint by applying /// the operator to its left and right constraint arguments. /// public abstract Constraint ApplyOperator(Constraint left, Constraint right); } #endregion #region AndOperator /// /// Operator that requires both it's arguments to succeed /// public class AndOperator : BinaryOperator { /// /// Construct an AndOperator /// public AndOperator() { this.left_precedence = this.right_precedence = 2; } /// /// Apply the operator to produce an AndConstraint /// public override Constraint ApplyOperator(Constraint left, Constraint right) { return new AndConstraint(left, right); } } #endregion #region OrOperator /// /// Operator that requires at least one of it's arguments to succeed /// public class OrOperator : BinaryOperator { /// /// Construct an OrOperator /// public OrOperator() { this.left_precedence = this.right_precedence = 3; } /// /// Apply the operator to produce an OrConstraint /// public override Constraint ApplyOperator(Constraint left, Constraint right) { return new OrConstraint(left, right); } } #endregion #endregion } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/MsgUtils.cs0000664000175000017500000002337311565352274025305 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.Collections; namespace NUnit.Framework.Constraints { /// /// Static methods used in creating messages /// public class MsgUtils { /// /// Static string used when strings are clipped /// private static readonly string ELLIPSIS = "..."; /// /// Returns the representation of a type as used in NUnitLite. /// This is the same as Type.ToString() except for arrays, /// which are displayed with their declared sizes. /// /// /// public static string GetTypeRepresentation(object obj) { Array array = obj as Array; if ( array == null ) return string.Format( "<{0}>", obj.GetType() ); StringBuilder sb = new StringBuilder(); Type elementType = array.GetType(); int nest = 0; while (elementType.IsArray) { elementType = elementType.GetElementType(); ++nest; } sb.Append(elementType.ToString()); sb.Append('['); for (int r = 0; r < array.Rank; r++) { if (r > 0) sb.Append(','); sb.Append(array.GetLength(r)); } sb.Append(']'); while (--nest > 0) sb.Append("[]"); return string.Format( "<{0}>", sb.ToString() ); } /// /// Converts any control characters in a string /// to their escaped representation. /// /// The string to be converted /// The converted string public static string EscapeControlChars(string s) { if (s != null) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.Length; i++) { char c = s[i]; switch (c) { //case '\'': // sb.Append("\\\'"); // break; //case '\"': // sb.Append("\\\""); // break; case '\\': sb.Append("\\\\"); break; case '\0': sb.Append("\\0"); break; case '\a': sb.Append("\\a"); break; case '\b': sb.Append("\\b"); break; case '\f': sb.Append("\\f"); break; case '\n': sb.Append("\\n"); break; case '\r': sb.Append("\\r"); break; case '\t': sb.Append("\\t"); break; case '\v': sb.Append("\\v"); break; case '\x0085': case '\x2028': case '\x2029': sb.AppendFormat("\\x{0:X4}", (int)c); break; default: sb.Append(c); break; } } s = sb.ToString(); } return s; } /// /// Return the a string representation for a set of indices into an array /// /// Array of indices for which a string is needed public static string GetArrayIndicesAsString(int[] indices) { StringBuilder sb = new StringBuilder(); sb.Append('['); for (int r = 0; r < indices.Length; r++) { if (r > 0) sb.Append(','); sb.Append(indices[r].ToString()); } sb.Append(']'); return sb.ToString(); } /// /// Get an array of indices representing the point in a enumerable, /// collection or array corresponding to a single int index into the /// collection. /// /// The collection to which the indices apply /// Index in the collection /// Array of indices public static int[] GetArrayIndicesFromCollectionIndex(IEnumerable collection, int index) { Array array = collection as Array; int rank = array == null ? 1 : array.Rank; int[] result = new int[rank]; for (int r = rank; --r > 0; ) { int l = array.GetLength(r); result[r] = index % l; index /= l; } result[0] = index; return result; } /// /// Clip a string to a given length, starting at a particular offset, returning the clipped /// string with ellipses representing the removed parts /// /// The string to be clipped /// The maximum permitted length of the result string /// The point at which to start clipping /// The clipped string public static string ClipString(string s, int maxStringLength, int clipStart) { int clipLength = maxStringLength; StringBuilder sb = new StringBuilder(); if (clipStart > 0) { clipLength -= ELLIPSIS.Length; sb.Append( ELLIPSIS ); } if (s.Length - clipStart > clipLength) { clipLength -= ELLIPSIS.Length; sb.Append( s.Substring( clipStart, clipLength )); sb.Append(ELLIPSIS); } else if (clipStart > 0) sb.Append( s.Substring(clipStart)); else sb.Append( s ); return sb.ToString(); } /// /// Clip the expected and actual strings in a coordinated fashion, /// so that they may be displayed together. /// /// /// /// /// public static void ClipExpectedAndActual(ref string expected, ref string actual, int maxDisplayLength, int mismatch) { // Case 1: Both strings fit on line int maxStringLength = Math.Max(expected.Length, actual.Length); if (maxStringLength <= maxDisplayLength) return; // Case 2: Assume that the tail of each string fits on line int clipLength = maxDisplayLength - ELLIPSIS.Length; int clipStart = maxStringLength - clipLength; // Case 3: If it doesn't, center the mismatch position if ( clipStart > mismatch ) clipStart = Math.Max( 0, mismatch - clipLength / 2 ); expected = ClipString(expected, maxDisplayLength, clipStart); actual = ClipString(actual, maxDisplayLength, clipStart); } /// /// Shows the position two strings start to differ. Comparison /// starts at the start index. /// /// The expected string /// The actual string /// The index in the strings at which comparison should start /// Boolean indicating whether case should be ignored /// -1 if no mismatch found, or the index where mismatch found static public int FindMismatchPosition(string expected, string actual, int istart, bool ignoreCase) { int length = Math.Min(expected.Length, actual.Length); string s1 = ignoreCase ? expected.ToLower() : expected; string s2 = ignoreCase ? actual.ToLower() : actual; for (int i = istart; i < length; i++) { if (s1[i] != s2[i]) return i; } // // Strings have same content up to the length of the shorter string. // Mismatch occurs because string lengths are different, so show // that they start differing where the shortest string ends // if (expected.Length != actual.Length) return length; // // Same strings : We shouldn't get here // return -1; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ComparisonAdapter.cs0000664000175000017500000001233311651440634027135 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// ComparisonAdapter class centralizes all comparisons of /// values in NUnit, adapting to the use of any provided /// IComparer, IComparer<T> or Comparison<T> /// public abstract class ComparisonAdapter { /// /// Gets the default ComparisonAdapter, which wraps an /// NUnitComparer object. /// public static ComparisonAdapter Default { get { return new DefaultComparisonAdapter(); } } /// /// Returns a ComparisonAdapter that wraps an IComparer /// public static ComparisonAdapter For(IComparer comparer) { return new ComparerAdapter(comparer); } #if CLR_2_0 || CLR_4_0 /// /// Returns a ComparisonAdapter that wraps an IComparer<T> /// public static ComparisonAdapter For(IComparer comparer) { return new ComparerAdapter(comparer); } /// /// Returns a ComparisonAdapter that wraps a Comparison<T> /// public static ComparisonAdapter For(Comparison comparer) { return new ComparisonAdapterForComparison(comparer); } #endif /// /// Compares two objects /// public abstract int Compare(object expected, object actual); class DefaultComparisonAdapter : ComparerAdapter { /// /// Construct a default ComparisonAdapter /// public DefaultComparisonAdapter() : base( NUnitComparer.Default ) { } } class ComparerAdapter : ComparisonAdapter { private IComparer comparer; /// /// Construct a ComparisonAdapter for an IComparer /// public ComparerAdapter(IComparer comparer) { this.comparer = comparer; } /// /// Compares two objects /// /// /// /// public override int Compare(object expected, object actual) { return comparer.Compare(expected, actual); } } #if CLR_2_0 || CLR_4_0 /// /// ComparisonAdapter<T> extends ComparisonAdapter and /// allows use of an IComparer<T> or Comparison<T> /// to actually perform the comparison. /// class ComparerAdapter : ComparisonAdapter { private IComparer comparer; /// /// Construct a ComparisonAdapter for an IComparer<T> /// public ComparerAdapter(IComparer comparer) { this.comparer = comparer; } /// /// Compare a Type T to an object /// public override int Compare(object expected, object actual) { if (!typeof(T).IsAssignableFrom(expected.GetType())) throw new ArgumentException("Cannot compare " + expected.ToString()); if (!typeof(T).IsAssignableFrom(actual.GetType())) throw new ArgumentException("Cannot compare to " + actual.ToString()); return comparer.Compare((T)expected, (T)actual); } } class ComparisonAdapterForComparison : ComparisonAdapter { private Comparison comparison; /// /// Construct a ComparisonAdapter for a Comparison<T> /// public ComparisonAdapterForComparison(Comparison comparer) { this.comparison = comparer; } /// /// Compare a Type T to an object /// public override int Compare(object expected, object actual) { if (!typeof(T).IsAssignableFrom(expected.GetType())) throw new ArgumentException("Cannot compare " + expected.ToString()); if (!typeof(T).IsAssignableFrom(actual.GetType())) throw new ArgumentException("Cannot compare to " + actual.ToString()); return comparison.Invoke((T)expected, (T)actual); } } #endif } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/NUnitEqualityComparer.cs0000664000175000017500000003500511672376472030002 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; using System.Reflection; #endif namespace NUnit.Framework.Constraints { /// /// NUnitEqualityComparer encapsulates NUnit's handling of /// equality tests between objects. /// public class NUnitEqualityComparer : INUnitEqualityComparer { #region Static and Instance Fields /// /// If true, all string comparisons will ignore case /// private bool caseInsensitive; /// /// If true, arrays will be treated as collections, allowing /// those of different dimensions to be compared /// private bool compareAsCollection; /// /// Comparison objects used in comparisons for some constraints. /// private ArrayList externalComparers = new ArrayList(); private ArrayList failurePoints; private static readonly int BUFFER_SIZE = 4096; #endregion #region Properties /// /// Returns the default NUnitEqualityComparer /// public static NUnitEqualityComparer Default { get { return new NUnitEqualityComparer(); } } /// /// Gets and sets a flag indicating whether case should /// be ignored in determining equality. /// public bool IgnoreCase { get { return caseInsensitive; } set { caseInsensitive = value; } } /// /// Gets and sets a flag indicating that arrays should be /// compared as collections, without regard to their shape. /// public bool CompareAsCollection { get { return compareAsCollection; } set { compareAsCollection = value; } } /// /// Gets and sets an external comparer to be used to /// test for equality. It is applied to members of /// collections, in place of NUnit's own logic. /// public IList ExternalComparers { get { return externalComparers; } } /// /// Gets the list of failure points for the last Match performed. /// public IList FailurePoints { get { return failurePoints; } } #endregion #region Public Methods /// /// Compares two objects for equality within a tolerance. /// public bool AreEqual(object x, object y, ref Tolerance tolerance) { this.failurePoints = new ArrayList(); if (x == null && y == null) return true; if (x == null || y == null) return false; if (object.ReferenceEquals(x, y)) return true; Type xType = x.GetType(); Type yType = y.GetType(); EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) return externalComparer.AreEqual(x, y); if (xType.IsArray && yType.IsArray && !compareAsCollection) return ArraysEqual((Array)x, (Array)y, ref tolerance); if (x is IDictionary && y is IDictionary) return DictionariesEqual((IDictionary)x, (IDictionary)y, ref tolerance); //if (x is ICollection && y is ICollection) // return CollectionsEqual((ICollection)x, (ICollection)y, ref tolerance); if (x is IEnumerable && y is IEnumerable && !(x is string && y is string)) return EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance); if (x is string && y is string) return StringsEqual((string)x, (string)y); if (x is Stream && y is Stream) return StreamsEqual((Stream)x, (Stream)y); if (x is DirectoryInfo && y is DirectoryInfo) return DirectoriesEqual((DirectoryInfo)x, (DirectoryInfo)y); if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) return Numerics.AreEqual(x, y, ref tolerance); if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; if (x is DateTime && y is DateTime) return ((DateTime)x - (DateTime)y).Duration() <= amount; if (x is TimeSpan && y is TimeSpan) return ((TimeSpan)x - (TimeSpan)y).Duration() <= amount; } #if CLR_2_0 || CLR_4_0 if (FirstImplementsIEquatableOfSecond(xType, yType)) return InvokeFirstIEquatableEqualsSecond(x, y); else if (FirstImplementsIEquatableOfSecond(yType, xType)) return InvokeFirstIEquatableEqualsSecond(y, x); #endif return x.Equals(y); } #if CLR_2_0 || CLR_4_0 private static bool FirstImplementsIEquatableOfSecond(Type first, Type second) { Type[] equatableArguments = GetEquatableGenericArguments(first); foreach (var xEquatableArgument in equatableArguments) if (xEquatableArgument.Equals(second)) return true; return false; } private static Type[] GetEquatableGenericArguments(Type type) { return Array.ConvertAll(Array.FindAll(type.GetInterfaces(), delegate(Type @interface) { return @interface.IsGenericType && @interface.GetGenericTypeDefinition().Equals(typeof (IEquatable<>)); }), delegate(Type iEquatableInterface) { return iEquatableInterface.GetGenericArguments()[0]; }); } private static bool InvokeFirstIEquatableEqualsSecond(object first, object second) { MethodInfo equals = typeof (IEquatable<>).MakeGenericType(second.GetType()).GetMethod("Equals"); return (bool) equals.Invoke(first, new object[] {second}); } #endif #endregion #region Helper Methods private EqualityAdapter GetExternalComparer(object x, object y) { foreach (EqualityAdapter adapter in externalComparers) if (adapter.CanCompare(x, y)) return adapter; return null; } /// /// Helper method to compare two arrays /// private bool ArraysEqual(Array x, Array y, ref Tolerance tolerance) { int rank = x.Rank; if (rank != y.Rank) return false; for (int r = 1; r < rank; r++) if (x.GetLength(r) != y.GetLength(r)) return false; return EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance); } private bool DictionariesEqual(IDictionary x, IDictionary y, ref Tolerance tolerance) { if (x.Count != y.Count) return false; CollectionTally tally = new CollectionTally(this, x.Keys); if (!tally.TryRemove(y.Keys) || tally.Count > 0) return false; foreach (object key in x.Keys) if (!AreEqual(x[key], y[key], ref tolerance)) return false; return true; } private bool CollectionsEqual(ICollection x, ICollection y, ref Tolerance tolerance) { IEnumerator expectedEnum = x.GetEnumerator(); IEnumerator actualEnum = y.GetEnumerator(); int count; for (count = 0; ; count++) { bool expectedHasData = expectedEnum.MoveNext(); bool actualHasData = actualEnum.MoveNext(); if (!expectedHasData && !actualHasData) return true; if (expectedHasData != actualHasData || !AreEqual(expectedEnum.Current, actualEnum.Current, ref tolerance)) { FailurePoint fp = new FailurePoint(); fp.Position = count; fp.ExpectedHasData = expectedHasData; if (expectedHasData) fp.ExpectedValue = expectedEnum.Current; fp.ActualHasData = actualHasData; if (actualHasData) fp.ActualValue = actualEnum.Current; failurePoints.Insert(0, fp); return false; } } } private bool StringsEqual(string x, string y) { string s1 = caseInsensitive ? x.ToLower() : x; string s2 = caseInsensitive ? y.ToLower() : y; return s1.Equals(s2); } private bool EnumerablesEqual(IEnumerable x, IEnumerable y, ref Tolerance tolerance) { IEnumerator expectedEnum = x.GetEnumerator(); IEnumerator actualEnum = y.GetEnumerator(); int count; for (count = 0; ; count++) { bool expectedHasData = expectedEnum.MoveNext(); bool actualHasData = actualEnum.MoveNext(); if (!expectedHasData && !actualHasData) return true; if (expectedHasData != actualHasData || !AreEqual(expectedEnum.Current, actualEnum.Current, ref tolerance)) { FailurePoint fp = new FailurePoint(); fp.Position = count; fp.ExpectedHasData = expectedHasData; if (expectedHasData) fp.ExpectedValue = expectedEnum.Current; fp.ActualHasData = actualHasData; if (actualHasData) fp.ActualValue = actualEnum.Current; failurePoints.Insert(0, fp); return false; } } } /// /// Method to compare two DirectoryInfo objects /// /// first directory to compare /// second directory to compare /// true if equivalent, false if not private bool DirectoriesEqual(DirectoryInfo x, DirectoryInfo y) { // Do quick compares first if (x.Attributes != y.Attributes || x.CreationTime != y.CreationTime || x.LastAccessTime != y.LastAccessTime) { return false; } // TODO: Find a cleaner way to do this return new SamePathConstraint(x.FullName).Matches(y.FullName); } private bool StreamsEqual(Stream x, Stream y) { if (x == y) return true; if (!x.CanRead) throw new ArgumentException("Stream is not readable", "expected"); if (!y.CanRead) throw new ArgumentException("Stream is not readable", "actual"); if (!x.CanSeek) throw new ArgumentException("Stream is not seekable", "expected"); if (!y.CanSeek) throw new ArgumentException("Stream is not seekable", "actual"); if (x.Length != y.Length) return false; byte[] bufferExpected = new byte[BUFFER_SIZE]; byte[] bufferActual = new byte[BUFFER_SIZE]; BinaryReader binaryReaderExpected = new BinaryReader(x); BinaryReader binaryReaderActual = new BinaryReader(y); long expectedPosition = x.Position; long actualPosition = y.Position; try { binaryReaderExpected.BaseStream.Seek(0, SeekOrigin.Begin); binaryReaderActual.BaseStream.Seek(0, SeekOrigin.Begin); for (long readByte = 0; readByte < x.Length; readByte += BUFFER_SIZE) { binaryReaderExpected.Read(bufferExpected, 0, BUFFER_SIZE); binaryReaderActual.Read(bufferActual, 0, BUFFER_SIZE); for (int count = 0; count < BUFFER_SIZE; ++count) { if (bufferExpected[count] != bufferActual[count]) { failurePoints.Insert(0, readByte + count); //FailureMessage.WriteLine("\tIndex : {0}", readByte + count); return false; } } } } finally { x.Position = expectedPosition; y.Position = actualPosition; } return true; } #endregion #region Nested FailurePoint Class /// /// FailurePoint class represents one point of failure /// in an equality test. /// public class FailurePoint { /// /// The location of the failure /// public int Position; /// /// The expected value /// public object ExpectedValue; /// /// The actual value /// public object ActualValue; /// /// Indicates whether the expected value is valid /// public bool ExpectedHasData; /// /// Indicates whether the actual value is valid /// public bool ActualHasData; } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/DirectoryConstraints.cs0000664000175000017500000000472211504175260027716 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.IO; namespace NUnit.Framework.Constraints { /// /// EmptyDirectoryConstraint is used to test that a directory is empty /// public class EmptyDirectoryContraint : Constraint { private int files = 0; private int subdirs = 0; /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; DirectoryInfo dirInfo = actual as DirectoryInfo; if (dirInfo == null) throw new ArgumentException("The actual value must be a DirectoryInfo", "actual"); files = dirInfo.GetFiles().Length; subdirs = dirInfo.GetDirectories().Length; return files == 0 && subdirs == 0; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write( "An empty directory" ); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { DirectoryInfo dir = actual as DirectoryInfo; if (dir == null) base.WriteActualValueTo(writer); else { writer.WriteActualValue(dir); writer.Write(" with {0} files and {1} directories", files, subdirs); } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/GreaterThanOrEqualConstraint.cs0000664000175000017500000000401111550363552031257 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Tests whether a value is greater than or equal to the value supplied to its constructor /// public class GreaterThanOrEqualConstraint : ComparisonConstraint { /// /// The value against which a comparison is to be made /// private object expected; /// /// Initializes a new instance of the class. /// /// The expected value. public GreaterThanOrEqualConstraint(object expected) : base(expected) { this.expected = expected; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("greater than or equal to"); writer.WriteExpectedValue(expected); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (expected == null || actual == null) throw new ArgumentException("Cannot compare using a null reference"); return comparer.Compare(actual, expected) >= 0; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/CollectionTally.cs0000664000175000017500000000472111552022000026604 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { /// /// CollectionTally counts (tallies) the number of /// occurences of each object in one or more enumerations. /// public class CollectionTally { // Internal list used to track occurences private ArrayList list = new ArrayList(); private NUnitEqualityComparer comparer; /// /// Construct a CollectionTally object from a comparer and a collection /// public CollectionTally(NUnitEqualityComparer comparer, IEnumerable c) { this.comparer = comparer; foreach (object o in c) list.Add(o); } /// /// The number of objects remaining in the tally /// public int Count { get { return list.Count; } } private bool ItemsEqual(object expected, object actual) { Tolerance tolerance = Tolerance.Zero; return comparer.AreEqual(expected, actual, ref tolerance); } /// /// Try to remove an object from the tally /// /// The object to remove /// True if successful, false if the object was not found public bool TryRemove(object o) { for (int index = 0; index < list.Count; index++) if (ItemsEqual(list[index], o)) { list.RemoveAt(index); return true; } return false; } /// /// Try to remove a set of objects from the tally /// /// The objects to remove /// True if successful, false if any object was not found public bool TryRemove(IEnumerable c) { foreach (object o in c) if (!TryRemove(o)) return false; return true; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/CollectionConstraints.cs0000664000175000017500000004356211707326126030056 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; using System.Text; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { #region CollectionConstraint /// /// CollectionConstraint is the abstract base class for /// constraints that operate on collections. /// public abstract class CollectionConstraint : Constraint { /// /// Construct an empty CollectionConstraint /// public CollectionConstraint() { } /// /// Construct a CollectionConstraint /// /// public CollectionConstraint(object arg) : base(arg) { } /// /// Determines whether the specified enumerable is empty. /// /// The enumerable. /// /// true if the specified enumerable is empty; otherwise, false. /// protected static bool IsEmpty( IEnumerable enumerable ) { ICollection collection = enumerable as ICollection; if ( collection != null ) return collection.Count == 0; foreach (object o in enumerable) return false; return true; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; IEnumerable enumerable = actual as IEnumerable; if ( enumerable == null ) throw new ArgumentException( "The actual value must be an IEnumerable", "actual" ); return doMatch( enumerable ); } /// /// Protected method to be implemented by derived classes /// /// /// protected abstract bool doMatch(IEnumerable collection); } #endregion #region CollectionItemsEqualConstraint /// /// CollectionItemsEqualConstraint is the abstract base class for all /// collection constraints that apply some notion of item equality /// as a part of their operation. /// public abstract class CollectionItemsEqualConstraint : CollectionConstraint { // This is internal so that ContainsConstraint can set it // TODO: Figure out a way to avoid this indirection internal NUnitEqualityComparer comparer = NUnitEqualityComparer.Default; /// /// Construct an empty CollectionConstraint /// public CollectionItemsEqualConstraint() { } /// /// Construct a CollectionConstraint /// /// public CollectionItemsEqualConstraint(object arg) : base(arg) { } #region Modifiers /// /// Flag the constraint to ignore case and return self. /// public CollectionItemsEqualConstraint IgnoreCase { get { comparer.IgnoreCase = true; return this; } } /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public CollectionItemsEqualConstraint Using(IComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } #if CLR_2_0 || CLR_4_0 /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public CollectionItemsEqualConstraint Using(IComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } /// /// Flag the constraint to use the supplied Comparison object. /// /// The IComparer object to use. /// Self. public CollectionItemsEqualConstraint Using(Comparison comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public CollectionItemsEqualConstraint Using(IEqualityComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public CollectionItemsEqualConstraint Using(IEqualityComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return this; } #endif #endregion /// /// Compares two collection members for equality /// protected bool ItemsEqual(object x, object y) { Tolerance tolerance = Tolerance.Zero; return comparer.AreEqual(x, y, ref tolerance); } /// /// Return a new CollectionTally for use in making tests /// /// The collection to be included in the tally protected CollectionTally Tally(IEnumerable c) { return new CollectionTally(comparer, c); } } #endregion #region EmptyCollectionConstraint /// /// EmptyCollectionConstraint tests whether a collection is empty. /// public class EmptyCollectionConstraint : CollectionConstraint { /// /// Check that the collection is empty /// /// /// protected override bool doMatch(IEnumerable collection) { return IsEmpty( collection ); } /// /// Write the constraint description to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.Write( "" ); } } #endregion #region UniqueItemsConstraint /// /// UniqueItemsConstraint tests whether all the items in a /// collection are unique. /// public class UniqueItemsConstraint : CollectionItemsEqualConstraint { /// /// Check that all items are unique. /// /// /// protected override bool doMatch(IEnumerable actual) { ArrayList list = new ArrayList(); foreach (object o1 in actual) { foreach( object o2 in list ) if ( ItemsEqual(o1, o2) ) return false; list.Add(o1); } return true; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("all items unique"); } } #endregion #region CollectionContainsConstraint /// /// CollectionContainsConstraint is used to test whether a collection /// contains an expected object as a member. /// public class CollectionContainsConstraint : CollectionItemsEqualConstraint { private object expected; /// /// Construct a CollectionContainsConstraint /// /// public CollectionContainsConstraint(object expected) : base(expected) { this.expected = expected; this.DisplayName = "contains"; } /// /// Test whether the expected item is contained in the collection /// /// /// protected override bool doMatch(IEnumerable actual) { foreach (object obj in actual) if (ItemsEqual(obj, expected)) return true; return false; } /// /// Write a descripton of the constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("collection containing"); writer.WriteExpectedValue(expected); } } #endregion #region CollectionEquivalentConstraint /// /// CollectionEquivalentCOnstraint is used to determine whether two /// collections are equivalent. /// public class CollectionEquivalentConstraint : CollectionItemsEqualConstraint { private IEnumerable expected; /// /// Construct a CollectionEquivalentConstraint /// /// public CollectionEquivalentConstraint(IEnumerable expected) : base(expected) { this.expected = expected; this.DisplayName = "equivalent"; } /// /// Test whether two collections are equivalent /// /// /// protected override bool doMatch(IEnumerable actual) { // This is just an optimization if( expected is ICollection && actual is ICollection ) if( ((ICollection)actual).Count != ((ICollection)expected).Count ) return false; CollectionTally tally = Tally(expected); return tally.TryRemove(actual) && tally.Count == 0; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("equivalent to"); writer.WriteExpectedValue(expected); } } #endregion #region CollectionSubsetConstraint /// /// CollectionSubsetConstraint is used to determine whether /// one collection is a subset of another /// public class CollectionSubsetConstraint : CollectionItemsEqualConstraint { private IEnumerable expected; /// /// Construct a CollectionSubsetConstraint /// /// The collection that the actual value is expected to be a subset of public CollectionSubsetConstraint(IEnumerable expected) : base(expected) { this.expected = expected; this.DisplayName = "subsetof"; } /// /// Test whether the actual collection is a subset of /// the expected collection provided. /// /// /// protected override bool doMatch(IEnumerable actual) { return Tally(expected).TryRemove( actual ); } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate( "subset of" ); writer.WriteExpectedValue(expected); } } #endregion #region CollectionOrderedConstraint /// /// CollectionOrderedConstraint is used to test whether a collection is ordered. /// public class CollectionOrderedConstraint : CollectionConstraint { private ComparisonAdapter comparer = ComparisonAdapter.Default; private string comparerName; private string propertyName; private bool descending; /// /// Construct a CollectionOrderedConstraint /// public CollectionOrderedConstraint() { this.DisplayName = "ordered"; } /// /// If used performs a reverse comparison /// public CollectionOrderedConstraint Descending { get { descending = true; return this; } } /// /// Modifies the constraint to use an IComparer and returns self. /// public CollectionOrderedConstraint Using(IComparer comparer) { this.comparer = ComparisonAdapter.For( comparer ); this.comparerName = comparer.GetType().FullName; return this; } #if CLR_2_0 || CLR_4_0 /// /// Modifies the constraint to use an IComparer<T> and returns self. /// public CollectionOrderedConstraint Using(IComparer comparer) { this.comparer = ComparisonAdapter.For(comparer); this.comparerName = comparer.GetType().FullName; return this; } /// /// Modifies the constraint to use a Comparison<T> and returns self. /// public CollectionOrderedConstraint Using(Comparison comparer) { this.comparer = ComparisonAdapter.For(comparer); this.comparerName = comparer.GetType().FullName; return this; } #endif /// /// Modifies the constraint to test ordering by the value of /// a specified property and returns self. /// public CollectionOrderedConstraint By(string propertyName) { this.propertyName = propertyName; return this; } /// /// Test whether the collection is ordered /// /// /// protected override bool doMatch(IEnumerable actual) { object previous = null; int index = 0; foreach(object obj in actual) { object objToCompare = obj; if (obj == null) throw new ArgumentNullException("actual", "Null value at index " + index.ToString()); if (this.propertyName != null) { PropertyInfo prop = obj.GetType().GetProperty(propertyName); objToCompare = prop.GetValue(obj, null); if (objToCompare == null) throw new ArgumentNullException("actual", "Null property value at index " + index.ToString()); } if (previous != null) { //int comparisonResult = comparer.Compare(al[i], al[i + 1]); int comparisonResult = comparer.Compare(previous, objToCompare); if (descending && comparisonResult < 0) return false; if (!descending && comparisonResult > 0) return false; } previous = objToCompare; index++; } return true; } /// /// Write a description of the constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { if (propertyName == null) writer.Write("collection ordered"); else { writer.WritePredicate("collection ordered by"); writer.WriteExpectedValue(propertyName); } if (descending) writer.WriteModifier("descending"); } /// /// Returns the string representation of the constraint. /// /// protected override string GetStringRepresentation() { StringBuilder sb = new StringBuilder(""); return sb.ToString(); } } #endregion } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/StringConstraints.cs0000664000175000017500000002477411661763734027246 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; #if !NETCF using System.Text.RegularExpressions; #endif namespace NUnit.Framework.Constraints { #region StringConstraint /// /// StringConstraint is the abstract base for constraints /// that operate on strings. It supports the IgnoreCase /// modifier for string operations. /// public abstract class StringConstraint : Constraint { /// /// The expected value /// protected string expected; /// /// Indicates whether tests should be case-insensitive /// protected bool caseInsensitive; /// /// Constructs a StringConstraint given an expected value /// /// The expected value public StringConstraint(string expected) : base(expected) { this.expected = expected; } /// /// Modify the constraint to ignore case in matching. /// public StringConstraint IgnoreCase { get { caseInsensitive = true; return this; } } } #endregion #region EmptyStringConstraint /// /// EmptyStringConstraint tests whether a string is empty. /// public class EmptyStringConstraint : Constraint { /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (!(actual is string)) return false; return (string)actual == string.Empty; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write(""); } } #endregion #region NullOrEmptyStringConstraint /// /// NullEmptyStringConstraint tests whether a string is either null or empty. /// public class NullOrEmptyStringConstraint : Constraint { /// /// Constructs a new NullOrEmptyStringConstraint /// public NullOrEmptyStringConstraint() { this.DisplayName = "nullorempty"; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (actual == null) return true; if (!(actual is string)) throw new ArgumentException("Actual value must be a string", "actual"); return (string)actual == string.Empty; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("null or empty string"); } } #endregion #region Substring Constraint /// /// SubstringConstraint can test whether a string contains /// the expected substring. /// public class SubstringConstraint : StringConstraint { /// /// Initializes a new instance of the class. /// /// The expected. public SubstringConstraint(string expected) : base(expected) { } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if ( !(actual is string) ) return false; if (this.caseInsensitive) return ((string)actual).ToLower().IndexOf(expected.ToLower()) >= 0; else return ((string)actual).IndexOf(expected) >= 0; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("String containing"); writer.WriteExpectedValue(expected); if ( this.caseInsensitive ) writer.WriteModifier( "ignoring case" ); } } #endregion #region StartsWithConstraint /// /// StartsWithConstraint can test whether a string starts /// with an expected substring. /// public class StartsWithConstraint : StringConstraint { /// /// Initializes a new instance of the class. /// /// The expected string public StartsWithConstraint(string expected) : base(expected) { } /// /// Test whether the constraint is matched by the actual value. /// This is a template method, which calls the IsMatch method /// of the derived class. /// /// /// public override bool Matches(object actual) { this.actual = actual; if (!(actual is string)) return false; if ( this.caseInsensitive ) return ((string)actual).ToLower().StartsWith(expected.ToLower()); else return ((string)actual).StartsWith(expected); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("String starting with"); writer.WriteExpectedValue( MsgUtils.ClipString(expected, writer.MaxLineLength - 40, 0) ); if ( this.caseInsensitive ) writer.WriteModifier( "ignoring case" ); } } #endregion #region EndsWithConstraint /// /// EndsWithConstraint can test whether a string ends /// with an expected substring. /// public class EndsWithConstraint : StringConstraint { /// /// Initializes a new instance of the class. /// /// The expected string public EndsWithConstraint(string expected) : base(expected) { } /// /// Test whether the constraint is matched by the actual value. /// This is a template method, which calls the IsMatch method /// of the derived class. /// /// /// public override bool Matches(object actual) { this.actual = actual; if (!(actual is string)) return false; if ( this.caseInsensitive ) return ((string)actual).ToLower().EndsWith(expected.ToLower()); else return ((string)actual).EndsWith(expected); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("String ending with"); writer.WriteExpectedValue(expected); if ( this.caseInsensitive ) writer.WriteModifier( "ignoring case" ); } } #endregion #region RegexConstraint #if !NETCF /// /// RegexConstraint can test whether a string matches /// the pattern provided. /// public class RegexConstraint : StringConstraint { /// /// Initializes a new instance of the class. /// /// The pattern. public RegexConstraint(string pattern) : base(pattern) { } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; return actual is string && Regex.IsMatch( (string)actual, this.expected, this.caseInsensitive ? RegexOptions.IgnoreCase : RegexOptions.None ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("String matching"); writer.WriteExpectedValue(this.expected); if ( this.caseInsensitive ) writer.WriteModifier( "ignoring case" ); } } #endif #endregion } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/IResolveConstraint.cs0000664000175000017500000000134311504175260027313 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Framework.Constraints { /// /// The IConstraintExpression interface is implemented by all /// complete and resolvable constraints and expressions. /// public interface IResolveConstraint { /// /// Return the top-level constraint for this expression /// /// Constraint Resolve(); } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ConstraintFactory.cs0000664000175000017500000005621611666104422027204 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { /// /// Helper class with properties and methods that supply /// a number of constraints used in Asserts. /// public class ConstraintFactory { #region Not /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public ConstraintExpression Not { get { return Is.Not; } } /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public ConstraintExpression No { get { return Has.No; } } #endregion #region All /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them succeed. /// public ConstraintExpression All { get { return Is.All; } } #endregion #region Some /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if at least one of them succeeds. /// public ConstraintExpression Some { get { return Has.Some; } } #endregion #region None /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them fail. /// public ConstraintExpression None { get { return Has.None; } } #endregion #region Exactly(n) /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding only if a specified number of them succeed. /// public static ConstraintExpression Exactly(int expectedCount) { return Has.Exactly(expectedCount); } #endregion #region Property /// /// Returns a new PropertyConstraintExpression, which will either /// test for the existence of the named property on the object /// being tested or apply any following constraint to that property. /// public ResolvableConstraintExpression Property(string name) { return Has.Property(name); } #endregion #region Length /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Length property of the object being tested. /// public ResolvableConstraintExpression Length { get { return Has.Length; } } #endregion #region Count /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Count property of the object being tested. /// public ResolvableConstraintExpression Count { get { return Has.Count; } } #endregion #region Message /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Message property of the object being tested. /// public ResolvableConstraintExpression Message { get { return Has.Message; } } #endregion #region InnerException /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the InnerException property of the object being tested. /// public ResolvableConstraintExpression InnerException { get { return Has.InnerException; } } #endregion #region Attribute /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public ResolvableConstraintExpression Attribute(Type expectedType) { return Has.Attribute(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public ResolvableConstraintExpression Attribute() { return Attribute(typeof(T)); } #endif #endregion #region Null /// /// Returns a constraint that tests for null /// public NullConstraint Null { get { return new NullConstraint(); } } #endregion #region True /// /// Returns a constraint that tests for True /// public TrueConstraint True { get { return new TrueConstraint(); } } #endregion #region False /// /// Returns a constraint that tests for False /// public FalseConstraint False { get { return new FalseConstraint(); } } #endregion #region Positive /// /// Returns a constraint that tests for a positive value /// public GreaterThanConstraint Positive { get { return new GreaterThanConstraint(0); } } #endregion #region Negative /// /// Returns a constraint that tests for a negative value /// public LessThanConstraint Negative { get { return new LessThanConstraint(0); } } #endregion #region NaN /// /// Returns a constraint that tests for NaN /// public NaNConstraint NaN { get { return new NaNConstraint(); } } #endregion #region Empty /// /// Returns a constraint that tests for empty /// public EmptyConstraint Empty { get { return new EmptyConstraint(); } } #endregion #region Unique /// /// Returns a constraint that tests whether a collection /// contains all unique items. /// public UniqueItemsConstraint Unique { get { return new UniqueItemsConstraint(); } } #endregion #region BinarySerializable /// /// Returns a constraint that tests whether an object graph is serializable in binary format. /// public BinarySerializableConstraint BinarySerializable { get { return new BinarySerializableConstraint(); } } #endregion #region XmlSerializable /// /// Returns a constraint that tests whether an object graph is serializable in xml format. /// public XmlSerializableConstraint XmlSerializable { get { return new XmlSerializableConstraint(); } } #endregion #region EqualTo /// /// Returns a constraint that tests two items for equality /// public EqualConstraint EqualTo(object expected) { return new EqualConstraint(expected); } #endregion #region SameAs /// /// Returns a constraint that tests that two references are the same object /// public SameAsConstraint SameAs(object expected) { return new SameAsConstraint(expected); } #endregion #region GreaterThan /// /// Returns a constraint that tests whether the /// actual value is greater than the suppled argument /// public GreaterThanConstraint GreaterThan(object expected) { return new GreaterThanConstraint(expected); } #endregion #region GreaterThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public GreaterThanOrEqualConstraint GreaterThanOrEqualTo(object expected) { return new GreaterThanOrEqualConstraint(expected); } /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public GreaterThanOrEqualConstraint AtLeast(object expected) { return new GreaterThanOrEqualConstraint(expected); } #endregion #region LessThan /// /// Returns a constraint that tests whether the /// actual value is less than the suppled argument /// public LessThanConstraint LessThan(object expected) { return new LessThanConstraint(expected); } #endregion #region LessThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public LessThanOrEqualConstraint LessThanOrEqualTo(object expected) { return new LessThanOrEqualConstraint(expected); } /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public LessThanOrEqualConstraint AtMost(object expected) { return new LessThanOrEqualConstraint(expected); } #endregion #region TypeOf /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public ExactTypeConstraint TypeOf(Type expectedType) { return new ExactTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public ExactTypeConstraint TypeOf() { return new ExactTypeConstraint(typeof(T)); } #endif #endregion #region InstanceOf /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public InstanceOfTypeConstraint InstanceOf(Type expectedType) { return new InstanceOfTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public InstanceOfTypeConstraint InstanceOf() { return new InstanceOfTypeConstraint(typeof(T)); } #endif /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf(expectedType)")] public InstanceOfTypeConstraint InstanceOfType(Type expectedType) { return new InstanceOfTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf()")] public InstanceOfTypeConstraint InstanceOfType() { return new InstanceOfTypeConstraint(typeof(T)); } #endif #endregion #region AssignableFrom /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableFromConstraint AssignableFrom(Type expectedType) { return new AssignableFromConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableFromConstraint AssignableFrom() { return new AssignableFromConstraint(typeof(T)); } #endif #endregion #region AssignableTo /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableToConstraint AssignableTo(Type expectedType) { return new AssignableToConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableToConstraint AssignableTo() { return new AssignableToConstraint(typeof(T)); } #endif #endregion #region EquivalentTo /// /// Returns a constraint that tests whether the actual value /// is a collection containing the same elements as the /// collection supplied as an argument. /// public CollectionEquivalentConstraint EquivalentTo(IEnumerable expected) { return new CollectionEquivalentConstraint(expected); } #endregion #region SubsetOf /// /// Returns a constraint that tests whether the actual value /// is a subset of the collection supplied as an argument. /// public CollectionSubsetConstraint SubsetOf(IEnumerable expected) { return new CollectionSubsetConstraint(expected); } #endregion #region Ordered /// /// Returns a constraint that tests whether a collection is ordered /// public CollectionOrderedConstraint Ordered { get { return new CollectionOrderedConstraint(); } } #endregion #region Member /// /// Returns a new CollectionContainsConstraint checking for the /// presence of a particular object in the collection. /// public CollectionContainsConstraint Member(object expected) { return new CollectionContainsConstraint(expected); } /// /// Returns a new CollectionContainsConstraint checking for the /// presence of a particular object in the collection. /// public CollectionContainsConstraint Contains(object expected) { return new CollectionContainsConstraint(expected); } #endregion #region Contains /// /// Returns a new ContainsConstraint. This constraint /// will, in turn, make use of the appropriate second-level /// constraint, depending on the type of the actual argument. /// This overload is only used if the item sought is a string, /// since any other type implies that we are looking for a /// collection member. /// public ContainsConstraint Contains(string expected) { return new ContainsConstraint(expected); } #endregion #region StringContaining /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// public SubstringConstraint StringContaining(string expected) { return new SubstringConstraint(expected); } /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// public SubstringConstraint ContainsSubstring(string expected) { return new SubstringConstraint(expected); } #endregion #region DoesNotContain /// /// Returns a constraint that fails if the actual /// value contains the substring supplied as an argument. /// public SubstringConstraint DoesNotContain(string expected) { return new ConstraintExpression().Not.ContainsSubstring(expected); } #endregion #region StartsWith /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// public StartsWithConstraint StartsWith(string expected) { return new StartsWithConstraint(expected); } /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// public StartsWithConstraint StringStarting(string expected) { return new StartsWithConstraint(expected); } #endregion #region DoesNotStartWith /// /// Returns a constraint that fails if the actual /// value starts with the substring supplied as an argument. /// public StartsWithConstraint DoesNotStartWith(string expected) { return new ConstraintExpression().Not.StartsWith(expected); } #endregion #region EndsWith /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// public EndsWithConstraint EndsWith(string expected) { return new EndsWithConstraint(expected); } /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// public EndsWithConstraint StringEnding(string expected) { return new EndsWithConstraint(expected); } #endregion #region DoesNotEndWith /// /// Returns a constraint that fails if the actual /// value ends with the substring supplied as an argument. /// public EndsWithConstraint DoesNotEndWith(string expected) { return new ConstraintExpression().Not.EndsWith(expected); } #endregion #region Matches /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// public RegexConstraint Matches(string pattern) { return new RegexConstraint(pattern); } /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// public RegexConstraint StringMatching(string pattern) { return new RegexConstraint(pattern); } #endregion #region DoesNotMatch /// /// Returns a constraint that fails if the actual /// value matches the pattern supplied as an argument. /// public RegexConstraint DoesNotMatch(string pattern) { return new ConstraintExpression().Not.Matches(pattern); } #endregion #region SamePath /// /// Returns a constraint that tests whether the path provided /// is the same as an expected path after canonicalization. /// public SamePathConstraint SamePath(string expected) { return new SamePathConstraint(expected); } #endregion #region SubPath /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public SubPathConstraint SubPath(string expected) { return new SubPathConstraint(expected); } #endregion #region SamePathOrUnder /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public SamePathOrUnderConstraint SamePathOrUnder(string expected) { return new SamePathOrUnderConstraint(expected); } #endregion #region InRange #if !CLR_2_0 && !CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public RangeConstraint InRange(IComparable from, IComparable to) { return new RangeConstraint(from, to); } #endif #endregion #region InRange #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public RangeConstraint InRange(T from, T to) where T : IComparable { return new RangeConstraint(from, to); } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/DelayedConstraint.cs0000664000175000017500000001633611665771550027156 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; namespace NUnit.Framework.Constraints { /// /// Applies a delay to the match so that a match can be evaluated in the future. /// public class DelayedConstraint : PrefixConstraint { private readonly int delayInMilliseconds; private readonly int pollingInterval; /// /// Creates a new DelayedConstraint /// ///The inner constraint two decorate ///The time interval after which the match is performed ///If the value of is less than 0 public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds) : this(baseConstraint, delayInMilliseconds, 0) { } /// /// Creates a new DelayedConstraint /// ///The inner constraint two decorate ///The time interval after which the match is performed ///The time interval used for polling ///If the value of is less than 0 public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds, int pollingInterval) : base(baseConstraint) { if (delayInMilliseconds < 0) throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds"); this.delayInMilliseconds = delayInMilliseconds; this.pollingInterval = pollingInterval; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for if the base constraint fails, false if it succeeds public override bool Matches(object actual) { int remainingDelay = delayInMilliseconds; while (pollingInterval > 0 && pollingInterval < remainingDelay) { remainingDelay -= pollingInterval; Thread.Sleep(pollingInterval); this.actual = actual; if (baseConstraint.Matches(actual)) return true; } if (remainingDelay > 0) Thread.Sleep(remainingDelay); this.actual = actual; return baseConstraint.Matches(actual); } /// /// Test whether the constraint is satisfied by a delegate /// /// The delegate whose value is to be tested /// True for if the base constraint fails, false if it succeeds public override bool Matches(ActualValueDelegate del) { int remainingDelay = delayInMilliseconds; while (pollingInterval > 0 && pollingInterval < remainingDelay) { remainingDelay -= pollingInterval; Thread.Sleep(pollingInterval); this.actual = del(); try { if (baseConstraint.Matches(actual)) return true; } catch (Exception) { // Ignore any exceptions when polling } } if ( remainingDelay > 0 ) Thread.Sleep(remainingDelay); this.actual = del(); return baseConstraint.Matches(actual); } #if CLR_2_0 || CLR_4_0 /// /// Test whether the constraint is satisfied by a given reference. /// Overridden to wait for the specified delay period before /// calling the base constraint with the dereferenced value. /// /// A reference to the value to be tested /// True for success, false for failure public override bool Matches(ref T actual) { int remainingDelay = delayInMilliseconds; while (pollingInterval > 0 && pollingInterval < remainingDelay) { remainingDelay -= pollingInterval; Thread.Sleep(pollingInterval); this.actual = actual; try { if (baseConstraint.Matches(actual)) return true; } catch (Exception) { // Ignore any exceptions when polling } } if ( remainingDelay > 0 ) Thread.Sleep(remainingDelay); this.actual = actual; return baseConstraint.Matches(actual); } #else /// /// Test whether the constraint is satisfied by a given boolean reference. /// Overridden to wait for the specified delay period before /// calling the base constraint with the dereferenced value. /// /// A reference to the value to be tested /// True for success, false for failure public override bool Matches(ref bool actual) { int remainingDelay = delayInMilliseconds; while (pollingInterval > 0 && pollingInterval < remainingDelay) { remainingDelay -= pollingInterval; Thread.Sleep(pollingInterval); this.actual = actual; if (baseConstraint.Matches(actual)) return true; } if ( remainingDelay > 0 ) Thread.Sleep(remainingDelay); this.actual = actual; return baseConstraint.Matches(actual); } #endif /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { baseConstraint.WriteDescriptionTo(writer); writer.Write(string.Format(" after {0} millisecond delay", delayInMilliseconds)); } /// /// Write the actual value for a failing constraint test to a MessageWriter. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { baseConstraint.WriteActualValueTo(writer); } /// /// Returns the string representation of the constraint. /// protected override string GetStringRepresentation() { return string.Format("", delayInMilliseconds, baseConstraint); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ConstraintExpressionBase.cs0000664000175000017500000000662611672426460030535 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { /// /// ConstraintExpressionBase is the abstract base class for the /// ConstraintExpression class, which represents a /// compound constraint in the process of being constructed /// from a series of syntactic elements. /// /// NOTE: ConstraintExpressionBase is separate because the /// ConstraintExpression class was generated in earlier /// versions of NUnit. The two classes may be combined /// in a future version. /// public abstract class ConstraintExpressionBase { #region Instance Fields /// /// The ConstraintBuilder holding the elements recognized so far /// protected ConstraintBuilder builder; #endregion #region Constructors /// /// Initializes a new instance of the class. /// public ConstraintExpressionBase() { this.builder = new ConstraintBuilder(); } /// /// Initializes a new instance of the /// class passing in a ConstraintBuilder, which may be pre-populated. /// /// The builder. public ConstraintExpressionBase(ConstraintBuilder builder) { this.builder = builder; } #endregion #region ToString() /// /// Returns a string representation of the expression as it /// currently stands. This should only be used for testing, /// since it has the side-effect of resolving the expression. /// /// public override string ToString() { return builder.Resolve().ToString(); } #endregion #region Append Methods /// /// Appends an operator to the expression and returns the /// resulting expression itself. /// public ConstraintExpression Append(ConstraintOperator op) { builder.Append(op); return (ConstraintExpression)this; } /// /// Appends a self-resolving operator to the expression and /// returns a new ResolvableConstraintExpression. /// public ResolvableConstraintExpression Append(SelfResolvingOperator op) { builder.Append(op); return new ResolvableConstraintExpression(builder); } /// /// Appends a constraint to the expression and returns that /// constraint, which is associated with the current state /// of the expression being built. /// public Constraint Append(Constraint constraint) { builder.Append(constraint); return constraint; } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/BasicConstraints.cs0000664000175000017500000000761611504175260027000 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// BasicConstraint is the abstract base for constraints that /// perform a simple comparison to a constant value. /// public abstract class BasicConstraint : Constraint { private object expected; private string description; /// /// Initializes a new instance of the class. /// /// The expected. /// The description. public BasicConstraint(object expected, string description) { this.expected = expected; this.description = description; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (actual == null && expected == null) return true; if (actual == null || expected == null) return false; return expected.Equals(actual); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write(description); } } /// /// NullConstraint tests that the actual value is null /// public class NullConstraint : BasicConstraint { /// /// Initializes a new instance of the class. /// public NullConstraint() : base(null, "null") { } } /// /// TrueConstraint tests that the actual value is true /// public class TrueConstraint : BasicConstraint { /// /// Initializes a new instance of the class. /// public TrueConstraint() : base(true, "True") { } } /// /// FalseConstraint tests that the actual value is false /// public class FalseConstraint : BasicConstraint { /// /// Initializes a new instance of the class. /// public FalseConstraint() : base(false, "False") { } } /// /// NaNConstraint tests that the actual value is a double or float NaN /// public class NaNConstraint : Constraint { /// /// Test that the actual value is an NaN /// /// /// public override bool Matches(object actual) { this.actual = actual; return actual is double && double.IsNaN((double)actual) || actual is float && float.IsNaN((float)actual); } /// /// Write the constraint description to a specified writer /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("NaN"); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ThrowsConstraint.cs0000664000175000017500000001546111544454420027061 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { #region ThrowsConstraint /// /// ThrowsConstraint is used to test the exception thrown by /// a delegate by applying a constraint to it. /// public class ThrowsConstraint : PrefixConstraint { private Exception caughtException; /// /// Initializes a new instance of the class, /// using a constraint to be applied to the exception. /// /// A constraint to apply to the caught exception. public ThrowsConstraint(Constraint baseConstraint) : base(baseConstraint) { } /// /// Get the actual exception thrown - used by Assert.Throws. /// public Exception ActualException { get { return caughtException; } } #region Constraint Overrides /// /// Executes the code of the delegate and captures any exception. /// If a non-null base constraint was provided, it applies that /// constraint to the exception. /// /// A delegate representing the code to be tested /// True if an exception is thrown and the constraint succeeds, otherwise false public override bool Matches(object actual) { TestDelegate code = actual as TestDelegate; if (code == null) throw new ArgumentException( string.Format("The actual value must be a TestDelegate but was {0}",actual.GetType().Name), "actual"); this.caughtException = null; try { code(); } catch (Exception ex) { this.caughtException = ex; } if (this.caughtException == null) return false; return baseConstraint == null || baseConstraint.Matches(caughtException); } #if CLR_2_0 || CLR_4_0 /// /// Converts an ActualValueDelegate to a TestDelegate /// before calling the primary overload. /// /// /// public override bool Matches(ActualValueDelegate del) { TestDelegate testDelegate = new TestDelegate(delegate { del(); }); return Matches((object)testDelegate); } #endif /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { if (baseConstraint == null) writer.WritePredicate("an exception"); else baseConstraint.WriteDescriptionTo(writer); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { if (caughtException == null) writer.Write("no exception thrown"); else if (baseConstraint != null) baseConstraint.WriteActualValueTo(writer); else writer.WriteActualValue(caughtException); } #endregion /// /// Returns the string representation of this constraint /// protected override string GetStringRepresentation() { if (baseConstraint == null) return ""; return base.GetStringRepresentation(); } } #endregion #region ThrowsNothingConstraint /// /// ThrowsNothingConstraint tests that a delegate does not /// throw an exception. /// public class ThrowsNothingConstraint : Constraint { private Exception caughtException; /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True if no exception is thrown, otherwise false public override bool Matches(object actual) { TestDelegate code = actual as TestDelegate; if (code == null) throw new ArgumentException("The actual value must be a TestDelegate", "actual"); this.caughtException = null; try { code(); } catch (Exception ex) { this.caughtException = ex; } return this.caughtException == null; } #if CLR_2_0 || CLR_4_0 /// /// Converts an ActualValueDelegate to a TestDelegate /// before calling the primary overload. /// /// /// public override bool Matches(ActualValueDelegate del) { TestDelegate testDelegate = new TestDelegate(delegate { del(); }); return Matches((object)testDelegate); } #endif /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write(string.Format("No Exception to be thrown")); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue( this.caughtException.GetType() ); } } #endregion } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ComparisonConstraints.cs0000664000175000017500000000443211550366462030071 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// Abstract base class for constraints that compare values to /// determine if one is greater than, equal to or less than /// the other. This class supplies the Using modifiers. /// public abstract class ComparisonConstraint : Constraint { /// /// ComparisonAdapter to be used in making the comparison /// protected ComparisonAdapter comparer = ComparisonAdapter.Default; /// /// Initializes a new instance of the class. /// public ComparisonConstraint(object arg) : base(arg) { } /// /// Initializes a new instance of the class. /// public ComparisonConstraint(object arg1, object arg2) : base(arg1, arg2) { } /// /// Modifies the constraint to use an IComparer and returns self /// public ComparisonConstraint Using(IComparer comparer) { this.comparer = ComparisonAdapter.For(comparer); return this; } #if CLR_2_0 || CLR_4_0 /// /// Modifies the constraint to use an IComparer<T> and returns self /// public ComparisonConstraint Using(IComparer comparer) { this.comparer = ComparisonAdapter.For(comparer); return this; } /// /// Modifies the constraint to use a Comparison<T> and returns self /// public ComparisonConstraint Using(Comparison comparer) { this.comparer = ComparisonAdapter.For(comparer); return this; } #endif } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/SerializableConstraints.cs0000664000175000017500000001240411504175260030354 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; #if !NETCF using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; #endif using System.Xml.Serialization; namespace NUnit.Framework.Constraints { #if !NETCF #region BinarySerializableConstraint /// /// BinarySerializableConstraint tests whether /// an object is serializable in binary format. /// public class BinarySerializableConstraint : Constraint { readonly BinaryFormatter serializer = new BinaryFormatter(); /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if(actual == null) throw new ArgumentException(); MemoryStream stream = new MemoryStream(); try { serializer.Serialize(stream, actual); stream.Seek(0, SeekOrigin.Begin); object value = serializer.Deserialize(stream); return value != null; } catch (SerializationException) { return false; } } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("binary serializable"); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.Write("<{0}>", actual.GetType().Name); } /// /// Returns the string representation /// protected override string GetStringRepresentation() { return ""; } } #endregion #endif #if !NETCF_1_0 #region XmlSerializableConstraint /// /// BinarySerializableConstraint tests whether /// an object is serializable in binary format. /// public class XmlSerializableConstraint : Constraint { private XmlSerializer serializer; /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if(actual == null) throw new ArgumentException(); MemoryStream stream = new MemoryStream(); try { serializer = new XmlSerializer(actual.GetType()); serializer.Serialize(stream, actual); stream.Seek(0, SeekOrigin.Begin); object value = serializer.Deserialize(stream); return value != null; } catch (NotSupportedException) { return false; } catch (InvalidOperationException) { return false; } } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("xml serializable"); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.Write("<{0}>", actual.GetType().Name); } /// /// Returns the string representation of this constraint /// protected override string GetStringRepresentation() { return ""; } } #endregion #endif } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/Constraint.cs0000664000175000017500000003207411550364632025653 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.Collections; namespace NUnit.Framework.Constraints { /// /// Delegate used to delay evaluation of the actual value /// to be used in evaluating a constraint /// public delegate object ActualValueDelegate(); /// /// The Constraint class is the base of all built-in constraints /// within NUnit. It provides the operator overloads used to combine /// constraints. /// public abstract class Constraint : IResolveConstraint { #region UnsetObject Class /// /// Class used to detect any derived constraints /// that fail to set the actual value in their /// Matches override. /// private class UnsetObject { public override string ToString() { return "UNSET"; } } #endregion #region Static and Instance Fields /// /// Static UnsetObject used to detect derived constraints /// failing to set the actual value. /// protected static object UNSET = new UnsetObject(); /// /// The actual value being tested against a constraint /// protected object actual = UNSET; /// /// The display name of this Constraint for use by ToString() /// private string displayName; /// /// Argument fields used by ToString(); /// private readonly int argcnt; private readonly object arg1; private readonly object arg2; /// /// The builder holding this constraint /// private ConstraintBuilder builder; #endregion #region Constructors /// /// Construct a constraint with no arguments /// public Constraint() { argcnt = 0; } /// /// Construct a constraint with one argument /// public Constraint(object arg) { argcnt = 1; this.arg1 = arg; } /// /// Construct a constraint with two arguments /// public Constraint(object arg1, object arg2) { argcnt = 2; this.arg1 = arg1; this.arg2 = arg2; } #endregion #region Set Containing ConstraintBuilder /// /// Sets the ConstraintBuilder holding this constraint /// internal void SetBuilder(ConstraintBuilder builder) { this.builder = builder; } #endregion #region Properties /// /// The display name of this Constraint for use by ToString(). /// The default value is the name of the constraint with /// trailing "Constraint" removed. Derived classes may set /// this to another name in their constructors. /// public string DisplayName { get { if (displayName == null) { displayName = this.GetType().Name.ToLower(); if (displayName.EndsWith("`1") || displayName.EndsWith("`2")) displayName = displayName.Substring(0, displayName.Length - 2); if (displayName.EndsWith("constraint")) displayName = displayName.Substring(0, displayName.Length - 10); } return displayName; } set { displayName = value; } } #endregion #region Abstract and Virtual Methods /// /// Write the failure message to the MessageWriter provided /// as an argument. The default implementation simply passes /// the constraint and the actual value to the writer, which /// then displays the constraint description and the value. /// /// Constraints that need to provide additional details, /// such as where the error occured can override this. /// /// The MessageWriter on which to display the message public virtual void WriteMessageTo(MessageWriter writer) { writer.DisplayDifferences(this); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public abstract bool Matches(object actual); /// /// Test whether the constraint is satisfied by an /// ActualValueDelegate that returns the value to be tested. /// The default implementation simply evaluates the delegate /// but derived classes may override it to provide for delayed /// processing. /// /// An ActualValueDelegate /// True for success, false for failure public virtual bool Matches(ActualValueDelegate del) { return Matches(del()); } #if CLR_2_0 || CLR_4_0 /// /// Test whether the constraint is satisfied by a given reference. /// The default implementation simply dereferences the value but /// derived classes may override it to provide for delayed processing. /// /// A reference to the value to be tested /// True for success, false for failure public virtual bool Matches(ref T actual) { return Matches(actual); } #else /// /// Test whether the constraint is satisfied by a given bool reference. /// The default implementation simply dereferences the value but /// derived classes may override it to provide for delayed processing. /// /// A reference to the value to be tested /// True for success, false for failure public virtual bool Matches(ref bool actual) { return Matches(actual); } #endif /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public abstract void WriteDescriptionTo(MessageWriter writer); /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public virtual void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue( actual ); } #endregion #region ToString Override /// /// Default override of ToString returns the constraint DisplayName /// followed by any arguments within angle brackets. /// /// public override string ToString() { string rep = GetStringRepresentation(); return this.builder == null ? rep : string.Format("", rep); } /// /// Returns the string representation of this constraint /// protected virtual string GetStringRepresentation() { switch (argcnt) { default: case 0: return string.Format("<{0}>", DisplayName); case 1: return string.Format("<{0} {1}>", DisplayName, _displayable(arg1)); case 2: return string.Format("<{0} {1} {2}>", DisplayName, _displayable(arg1), _displayable(arg2)); } } private string _displayable(object o) { if (o == null) return "null"; string fmt = o is string ? "\"{0}\"" : "{0}"; return string.Format(System.Globalization.CultureInfo.InvariantCulture, fmt, o); } #endregion #region Operator Overloads /// /// This operator creates a constraint that is satisfied only if both /// argument constraints are satisfied. /// public static Constraint operator &(Constraint left, Constraint right) { IResolveConstraint l = (IResolveConstraint)left; IResolveConstraint r = (IResolveConstraint)right; return new AndConstraint(l.Resolve(), r.Resolve()); } /// /// This operator creates a constraint that is satisfied if either /// of the argument constraints is satisfied. /// public static Constraint operator |(Constraint left, Constraint right) { IResolveConstraint l = (IResolveConstraint)left; IResolveConstraint r = (IResolveConstraint)right; return new OrConstraint(l.Resolve(), r.Resolve()); } /// /// This operator creates a constraint that is satisfied if the /// argument constraint is not satisfied. /// public static Constraint operator !(Constraint constraint) { IResolveConstraint r = constraint as IResolveConstraint; return new NotConstraint(r == null ? new NullConstraint() : r.Resolve()); } #endregion #region Binary Operators /// /// Returns a ConstraintExpression by appending And /// to the current constraint. /// public ConstraintExpression And { get { ConstraintBuilder builder = this.builder; if (builder == null) { builder = new ConstraintBuilder(); builder.Append(this); } builder.Append(new AndOperator()); return new ConstraintExpression(builder); } } /// /// Returns a ConstraintExpression by appending And /// to the current constraint. /// public ConstraintExpression With { get { return this.And; } } /// /// Returns a ConstraintExpression by appending Or /// to the current constraint. /// public ConstraintExpression Or { get { ConstraintBuilder builder = this.builder; if (builder == null) { builder = new ConstraintBuilder(); builder.Append(this); } builder.Append(new OrOperator()); return new ConstraintExpression(builder); } } #endregion #region After Modifier /// /// Returns a DelayedConstraint with the specified delay time. /// /// The delay in milliseconds. /// public DelayedConstraint After(int delayInMilliseconds) { return new DelayedConstraint( builder == null ? this : builder.Resolve(), delayInMilliseconds); } /// /// Returns a DelayedConstraint with the specified delay time /// and polling interval. /// /// The delay in milliseconds. /// The interval at which to test the constraint. /// public DelayedConstraint After(int delayInMilliseconds, int pollingInterval) { return new DelayedConstraint( builder == null ? this : builder.Resolve(), delayInMilliseconds, pollingInterval); } #endregion #region IResolveConstraint Members Constraint IResolveConstraint.Resolve() { return builder == null ? this : builder.Resolve(); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/TypeConstraints.cs0000664000175000017500000001746011672602350026677 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// TypeConstraint is the abstract base for constraints /// that take a Type as their expected value. /// public abstract class TypeConstraint : Constraint { /// /// The expected Type used by the constraint /// protected Type expectedType; /// /// Construct a TypeConstraint for a given Type /// /// public TypeConstraint(Type type) : base(type) { this.expectedType = type; } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. TypeConstraints override this method to write /// the name of the type. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue( actual == null ? null : actual.GetType() ); } } /// /// ExactTypeConstraint is used to test that an object /// is of the exact type provided in the constructor /// public class ExactTypeConstraint : TypeConstraint { /// /// Construct an ExactTypeConstraint for a given Type /// /// The expected Type. public ExactTypeConstraint(Type type) : base( type ) { this.DisplayName = "typeof"; } /// /// Test that an object is of the exact type specified /// /// The actual value. /// True if the tested object is of the exact type provided, otherwise false. public override bool Matches(object actual) { this.actual = actual; return actual != null && actual.GetType() == this.expectedType; } /// /// Write the description of this constraint to a MessageWriter /// /// The MessageWriter to use public override void WriteDescriptionTo(MessageWriter writer) { writer.WriteExpectedValue(expectedType); } } /// /// ExceptionTypeConstraint is a special version of ExactTypeConstraint /// used to provided detailed info about the exception thrown in /// an error message. /// public class ExceptionTypeConstraint : ExactTypeConstraint { /// /// Constructs an ExceptionTypeConstraint /// public ExceptionTypeConstraint(Type type) : base(type) { } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. Overriden to write additional information /// in the case of an Exception. /// /// The MessageWriter to use public override void WriteActualValueTo(MessageWriter writer) { Exception ex = actual as Exception; base.WriteActualValueTo(writer); if (ex != null) { writer.WriteLine(" ({0})", ex.Message); writer.Write(ex.StackTrace); } } } /// /// InstanceOfTypeConstraint is used to test that an object /// is of the same type provided or derived from it. /// public class InstanceOfTypeConstraint : TypeConstraint { /// /// Construct an InstanceOfTypeConstraint for the type provided /// /// The expected Type public InstanceOfTypeConstraint(Type type) : base(type) { this.DisplayName = "instanceof"; } /// /// Test whether an object is of the specified type or a derived type /// /// The object to be tested /// True if the object is of the provided type or derives from it, otherwise false. public override bool Matches(object actual) { this.actual = actual; return actual != null && expectedType.IsInstanceOfType(actual); } /// /// Write a description of this constraint to a MessageWriter /// /// The MessageWriter to use public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("instance of"); writer.WriteExpectedValue(expectedType); } } /// /// AssignableFromConstraint is used to test that an object /// can be assigned from a given Type. /// public class AssignableFromConstraint : TypeConstraint { /// /// Construct an AssignableFromConstraint for the type provided /// /// public AssignableFromConstraint(Type type) : base(type) { } /// /// Test whether an object can be assigned from the specified type /// /// The object to be tested /// True if the object can be assigned a value of the expected Type, otherwise false. public override bool Matches(object actual) { this.actual = actual; return actual != null && actual.GetType().IsAssignableFrom(expectedType); } /// /// Write a description of this constraint to a MessageWriter /// /// The MessageWriter to use public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("assignable from"); writer.WriteExpectedValue(expectedType); } } /// /// AssignableToConstraint is used to test that an object /// can be assigned to a given Type. /// public class AssignableToConstraint : TypeConstraint { /// /// Construct an AssignableToConstraint for the type provided /// /// public AssignableToConstraint(Type type) : base(type) { } /// /// Test whether an object can be assigned to the specified type /// /// The object to be tested /// True if the object can be assigned a value of the expected Type, otherwise false. public override bool Matches(object actual) { this.actual = actual; return actual != null && expectedType.IsAssignableFrom(actual.GetType()); } /// /// Write a description of this constraint to a MessageWriter /// /// The MessageWriter to use public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("assignable to"); writer.WriteExpectedValue(expectedType); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/RangeConstraint.cs0000664000175000017500000000725211550547702026631 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// RangeConstraint tests whethe two values are within a /// specified range. /// #if CLR_2_0 || CLR_4_0 public class RangeConstraint : ComparisonConstraint where T : IComparable { private T from; private T to; /// /// Initializes a new instance of the class. /// /// From. /// To. public RangeConstraint(T from, T to) : base(from, to) { this.from = from; this.to = to; this.comparer = ComparisonAdapter.For(new NUnitComparer()); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (from == null || to == null || actual == null) throw new ArgumentException("Cannot compare using a null reference", "expected"); return comparer.Compare(from, actual) <= 0 && comparer.Compare(to, actual) >= 0; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("in range ({0},{1})", from, to); } } #else public class RangeConstraint : ComparisonConstraint { private IComparable from; private IComparable to; /// /// Initializes a new instance of the class. /// /// From. /// To. public RangeConstraint(IComparable from, IComparable to) : base( from, to ) { this.from = from; this.to = to; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if ( from == null || to == null || actual == null) throw new ArgumentException( "Cannot compare using a null reference", "expected" ); return comparer.Compare(from, actual) <= 0 && comparer.Compare(to, actual) >= 0; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("in range ({0},{1})", from, to); } } #endif } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/BinaryOperations.cs0000664000175000017500000001165611504175260027016 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// BinaryConstraint is the abstract base of all constraints /// that combine two other constraints in some fashion. /// public abstract class BinaryConstraint : Constraint { /// /// The first constraint being combined /// protected Constraint left; /// /// The second constraint being combined /// protected Constraint right; /// /// Construct a BinaryConstraint from two other constraints /// /// The first constraint /// The second constraint public BinaryConstraint(Constraint left, Constraint right) : base(left, right) { this.left = left; this.right = right; } } /// /// AndConstraint succeeds only if both members succeed. /// public class AndConstraint : BinaryConstraint { private enum FailurePoint { None, Left, Right }; private FailurePoint failurePoint; /// /// Create an AndConstraint from two other constraints /// /// The first constraint /// The second constraint public AndConstraint(Constraint left, Constraint right) : base(left, right) { } /// /// Apply both member constraints to an actual value, succeeding /// succeeding only if both of them succeed. /// /// The actual value /// True if the constraints both succeeded public override bool Matches(object actual) { this.actual = actual; failurePoint = left.Matches(actual) ? right.Matches(actual) ? FailurePoint.None : FailurePoint.Right : FailurePoint.Left; return failurePoint == FailurePoint.None; } /// /// Write a description for this contraint to a MessageWriter /// /// The MessageWriter to receive the description public override void WriteDescriptionTo(MessageWriter writer) { left.WriteDescriptionTo(writer); writer.WriteConnector("and"); right.WriteDescriptionTo(writer); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { switch (failurePoint) { case FailurePoint.Left: left.WriteActualValueTo(writer); break; case FailurePoint.Right: right.WriteActualValueTo(writer); break; default: base.WriteActualValueTo(writer); break; } } } /// /// OrConstraint succeeds if either member succeeds /// public class OrConstraint : BinaryConstraint { /// /// Create an OrConstraint from two other constraints /// /// The first constraint /// The second constraint public OrConstraint(Constraint left, Constraint right) : base(left, right) { } /// /// Apply the member constraints to an actual value, succeeding /// succeeding as soon as one of them succeeds. /// /// The actual value /// True if either constraint succeeded public override bool Matches(object actual) { this.actual = actual; return left.Matches(actual) || right.Matches(actual); } /// /// Write a description for this contraint to a MessageWriter /// /// The MessageWriter to receive the description public override void WriteDescriptionTo(MessageWriter writer) { left.WriteDescriptionTo(writer); writer.WriteConnector("or"); right.WriteDescriptionTo(writer); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/PredicateConstraint.cs0000664000175000017500000000334511544454420027471 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; namespace NUnit.Framework.Constraints { /// /// Predicate constraint wraps a Predicate in a constraint, /// returning success if the predicate is true. /// public class PredicateConstraint : Constraint { Predicate predicate; /// /// Construct a PredicateConstraint from a predicate /// public PredicateConstraint(Predicate predicate) { this.predicate = predicate; } /// /// Determines whether the predicate succeeds when applied /// to the actual value. /// public override bool Matches(object actual) { this.actual = actual; if (!(actual is T)) throw new ArgumentException("The actual value is not of type " + typeof(T).Name, "actual"); return predicate((T)actual); } /// /// Writes the description to a MessageWriter /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("value matching"); writer.Write(predicate.Method.Name.StartsWith("<") ? "lambda expression" : predicate.Method.Name); } } } #endif NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/SameAsConstraint.cs0000664000175000017500000000354511504175260026742 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// SameAsConstraint tests whether an object is identical to /// the object passed to its constructor /// public class SameAsConstraint : Constraint { private object expected; /// /// Initializes a new instance of the class. /// /// The expected object. public SameAsConstraint(object expected) : base(expected) { this.expected = expected; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; #if NETCF_1_0 // TODO: THis makes it compile, now make it work. return expected.Equals(actual); #else return Object.ReferenceEquals(expected, actual); #endif } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("same as"); writer.WriteExpectedValue(expected); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/MessageWriter.cs0000664000175000017500000001355611626703556026322 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.IO; using System.Collections; namespace NUnit.Framework.Constraints { /// /// MessageWriter is the abstract base for classes that write /// constraint descriptions and messages in some form. The /// class has separate methods for writing various components /// of a message, allowing implementations to tailor the /// presentation as needed. /// public abstract class MessageWriter : StringWriter { /// /// Construct a MessageWriter given a culture /// public MessageWriter() : base( System.Globalization.CultureInfo.InvariantCulture ) { } /// /// Abstract method to get the max line length /// public abstract int MaxLineLength { get; set; } /// /// Method to write single line message with optional args, usually /// written to precede the general failure message. /// /// The message to be written /// Any arguments used in formatting the message public void WriteMessageLine(string message, params object[] args) { WriteMessageLine(0, message, args); } /// /// Method to write single line message with optional args, usually /// written to precede the general failure message, at a givel /// indentation level. /// /// The indentation level of the message /// The message to be written /// Any arguments used in formatting the message public abstract void WriteMessageLine(int level, string message, params object[] args); /// /// Display Expected and Actual lines for a constraint. This /// is called by MessageWriter's default implementation of /// WriteMessageTo and provides the generic two-line display. /// /// The constraint that failed public abstract void DisplayDifferences(Constraint constraint); /// /// Display Expected and Actual lines for given values. This /// method may be called by constraints that need more control over /// the display of actual and expected values than is provided /// by the default implementation. /// /// The expected value /// The actual value causing the failure public abstract void DisplayDifferences(object expected, object actual); /// /// Display Expected and Actual lines for given values, including /// a tolerance value on the Expected line. /// /// The expected value /// The actual value causing the failure /// The tolerance within which the test was made public abstract void DisplayDifferences(object expected, object actual, Tolerance tolerance); /// /// Display the expected and actual string values on separate lines. /// If the mismatch parameter is >=0, an additional line is displayed /// line containing a caret that points to the mismatch point. /// /// The expected string value /// The actual string value /// The point at which the strings don't match or -1 /// If true, case is ignored in locating the point where the strings differ /// If true, the strings should be clipped to fit the line public abstract void DisplayStringDifferences(string expected, string actual, int mismatch, bool ignoreCase, bool clipping); /// /// Writes the text for a connector. /// /// The connector. public abstract void WriteConnector(string connector); /// /// Writes the text for a predicate. /// /// The predicate. public abstract void WritePredicate(string predicate); /// /// Writes the text for an expected value. /// /// The expected value. public abstract void WriteExpectedValue(object expected); /// /// Writes the text for a modifier /// /// The modifier. public abstract void WriteModifier(string modifier); /// /// Writes the text for an actual value. /// /// The actual value. public abstract void WriteActualValue(object actual); /// /// Writes the text for a generalized value. /// /// The value. public abstract void WriteValue(object val); /// /// Writes the text for a collection value, /// starting at a particular point, to a max length /// /// The collection containing elements to write. /// The starting point of the elements to write /// The maximum number of elements to write public abstract void WriteCollectionElements(IEnumerable collection, int start, int max); } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ReusableConstraint.cs0000664000175000017500000000371011720453462027330 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// ReusableConstraint wraps a resolved constraint so that it /// may be saved and reused as needed. /// public class ReusableConstraint : IResolveConstraint { private Constraint constraint; /// /// Construct a ReusableConstraint /// /// The constraint or expression to be reused public ReusableConstraint(IResolveConstraint c) { this.constraint = c.Resolve(); } /// /// Conversion operator from a normal constraint to a ReusableConstraint. /// /// The original constraint to be wrapped as a ReusableConstraint /// public static implicit operator ReusableConstraint(Constraint c) { return new ReusableConstraint(c); } /// /// Returns the string representation of the constraint. /// /// A string representing the constraint public override string ToString() { return constraint.ToString(); } #region IResolveConstraint Members /// /// Resolves the ReusableConstraint by returning the constraint /// that it originally wrapped. /// /// A resolved constraint public Constraint Resolve() { return constraint; } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ResolvableConstraintExpression.cs0000664000175000017500000000417611504175260031750 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// ResolvableConstraintExpression is used to represent a compound /// constraint being constructed at a point where the last operator /// may either terminate the expression or may have additional /// qualifying constraints added to it. /// /// It is used, for example, for a Property element or for /// an Exception element, either of which may be optionally /// followed by constraints that apply to the property or /// exception. /// public class ResolvableConstraintExpression : ConstraintExpression, IResolveConstraint { /// /// Create a new instance of ResolvableConstraintExpression /// public ResolvableConstraintExpression() { } /// /// Create a new instance of ResolvableConstraintExpression, /// passing in a pre-populated ConstraintBuilder. /// public ResolvableConstraintExpression(ConstraintBuilder builder) : base(builder) { } /// /// Appends an And Operator to the expression /// public ConstraintExpression And { get { return this.Append(new AndOperator()); } } /// /// Appends an Or operator to the expression. /// public ConstraintExpression Or { get { return this.Append(new OrOperator()); } } #region IResolveConstraint Members /// /// Resolve the current expression to a Constraint /// Constraint IResolveConstraint.Resolve() { return builder.Resolve(); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/FloatingPointNumerics.cs0000664000175000017500000002370611504175260030010 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if !NETCF_1_0 using System; using System.Runtime.InteropServices; namespace NUnit.Framework.Constraints { /// Helper routines for working with floating point numbers /// /// /// The floating point comparison code is based on this excellent article: /// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm /// /// /// "ULP" means Unit in the Last Place and in the context of this library refers to /// the distance between two adjacent floating point numbers. IEEE floating point /// numbers can only represent a finite subset of natural numbers, with greater /// accuracy for smaller numbers and lower accuracy for very large numbers. /// /// /// If a comparison is allowed "2 ulps" of deviation, that means the values are /// allowed to deviate by up to 2 adjacent floating point values, which might be /// as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. /// /// public class FloatingPointNumerics { #region struct FloatIntUnion /// Union of a floating point variable and an integer [StructLayout(LayoutKind.Explicit)] private struct FloatIntUnion { /// The union's value as a floating point variable [FieldOffset(0)] public float Float; /// The union's value as an integer [FieldOffset(0)] public int Int; /// The union's value as an unsigned integer [FieldOffset(0)] public uint UInt; } #endregion // struct FloatIntUnion #region struct DoubleLongUnion /// Union of a double precision floating point variable and a long [StructLayout(LayoutKind.Explicit)] private struct DoubleLongUnion { /// The union's value as a double precision floating point variable [FieldOffset(0)] public double Double; /// The union's value as a long [FieldOffset(0)] public long Long; /// The union's value as an unsigned long [FieldOffset(0)] public ulong ULong; } #endregion // struct DoubleLongUnion /// Compares two floating point values for equality /// First floating point value to be compared /// Second floating point value t be compared /// /// Maximum number of representable floating point values that are allowed to /// be between the left and the right floating point values /// /// True if both numbers are equal or close to being equal /// /// /// Floating point values can only represent a finite subset of natural numbers. /// For example, the values 2.00000000 and 2.00000024 can be stored in a float, /// but nothing inbetween them. /// /// /// This comparison will count how many possible floating point values are between /// the left and the right number. If the number of possible values between both /// numbers is less than or equal to maxUlps, then the numbers are considered as /// being equal. /// /// /// Implementation partially follows the code outlined here: /// http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ /// /// public static bool AreAlmostEqualUlps(float left, float right, int maxUlps) { FloatIntUnion leftUnion = new FloatIntUnion(); FloatIntUnion rightUnion = new FloatIntUnion(); leftUnion.Float = left; rightUnion.Float = right; uint leftSignMask = (leftUnion.UInt >> 31); uint rightSignMask = (rightUnion.UInt >> 31); uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask); leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask); uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask); rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask); return (Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps); } /// Compares two double precision floating point values for equality /// First double precision floating point value to be compared /// Second double precision floating point value t be compared /// /// Maximum number of representable double precision floating point values that are /// allowed to be between the left and the right double precision floating point values /// /// True if both numbers are equal or close to being equal /// /// /// Double precision floating point values can only represent a limited series of /// natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004 /// can be stored in a double, but nothing inbetween them. /// /// /// This comparison will count how many possible double precision floating point /// values are between the left and the right number. If the number of possible /// values between both numbers is less than or equal to maxUlps, then the numbers /// are considered as being equal. /// /// /// Implementation partially follows the code outlined here: /// http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ /// /// public static bool AreAlmostEqualUlps(double left, double right, long maxUlps) { DoubleLongUnion leftUnion = new DoubleLongUnion(); DoubleLongUnion rightUnion = new DoubleLongUnion(); leftUnion.Double = left; rightUnion.Double = right; ulong leftSignMask = (leftUnion.ULong >> 63); ulong rightSignMask = (rightUnion.ULong >> 63); ulong leftTemp = ((0x8000000000000000 - leftUnion.ULong) & leftSignMask); leftUnion.ULong = leftTemp | (leftUnion.ULong & ~leftSignMask); ulong rightTemp = ((0x8000000000000000 - rightUnion.ULong) & rightSignMask); rightUnion.ULong = rightTemp | (rightUnion.ULong & ~rightSignMask); return (Math.Abs(leftUnion.Long - rightUnion.Long) <= maxUlps); } /// /// Reinterprets the memory contents of a floating point value as an integer value /// /// /// Floating point value whose memory contents to reinterpret /// /// /// The memory contents of the floating point value interpreted as an integer /// public static int ReinterpretAsInt(float value) { FloatIntUnion union = new FloatIntUnion(); union.Float = value; return union.Int; } /// /// Reinterprets the memory contents of a double precision floating point /// value as an integer value /// /// /// Double precision floating point value whose memory contents to reinterpret /// /// /// The memory contents of the double precision floating point value /// interpreted as an integer /// public static long ReinterpretAsLong(double value) { DoubleLongUnion union = new DoubleLongUnion(); union.Double = value; return union.Long; } /// /// Reinterprets the memory contents of an integer as a floating point value /// /// Integer value whose memory contents to reinterpret /// /// The memory contents of the integer value interpreted as a floating point value /// public static float ReinterpretAsFloat(int value) { FloatIntUnion union = new FloatIntUnion(); union.Int = value; return union.Float; } /// /// Reinterprets the memory contents of an integer value as a double precision /// floating point value /// /// Integer whose memory contents to reinterpret /// /// The memory contents of the integer interpreted as a double precision /// floating point value /// public static double ReinterpretAsDouble(long value) { DoubleLongUnion union = new DoubleLongUnion(); union.Long = value; return union.Double; } private FloatingPointNumerics() { } } } #endif NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/EqualityAdapter.cs0000664000175000017500000001564611651451216026630 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// EqualityAdapter class handles all equality comparisons /// that use an IEqualityComparer, IEqualityComparer<T> /// or a ComparisonAdapter. /// public abstract class EqualityAdapter { /// /// Compares two objects, returning true if they are equal /// public abstract bool AreEqual(object x, object y); /// /// Returns true if the two objects can be compared by this adapter. /// The base adapter cannot handle IEnumerables except for strings. /// public virtual bool CanCompare(object x, object y) { if (x is string && y is string) return true; if (x is IEnumerable || y is IEnumerable) return false; return true; } #region Nested IComparer Adapter /// /// Returns an EqualityAdapter that wraps an IComparer. /// public static EqualityAdapter For(IComparer comparer) { return new ComparerAdapter(comparer); } /// /// EqualityAdapter that wraps an IComparer. /// class ComparerAdapter : EqualityAdapter { private IComparer comparer; public ComparerAdapter(IComparer comparer) { this.comparer = comparer; } public override bool AreEqual(object x, object y) { return comparer.Compare(x, y) == 0; } } #endregion #if CLR_2_0 || CLR_4_0 #region Nested IEqualityComparer Adapter /// /// Returns an EqualityAdapter that wraps an IEqualityComparer. /// public static EqualityAdapter For(IEqualityComparer comparer) { return new EqualityComparerAdapter(comparer); } class EqualityComparerAdapter : EqualityAdapter { private IEqualityComparer comparer; public EqualityComparerAdapter(IEqualityComparer comparer) { this.comparer = comparer; } public override bool AreEqual(object x, object y) { return comparer.Equals(x, y); } } #endregion #region Nested GenericEqualityAdapter abstract class GenericEqualityAdapter : EqualityAdapter { /// /// Returns true if the two objects can be compared by this adapter. /// Generic adapter requires objects of the specified type. /// public override bool CanCompare(object x, object y) { return typeof(T).IsAssignableFrom(x.GetType()) && typeof(T).IsAssignableFrom(y.GetType()); } protected void ThrowIfNotCompatible(object x, object y) { if (!typeof(T).IsAssignableFrom(x.GetType())) throw new ArgumentException("Cannot compare " + x.ToString()); if (!typeof(T).IsAssignableFrom(y.GetType())) throw new ArgumentException("Cannot compare " + y.ToString()); } } #endregion #region Nested IEqualityComparer Adapter /// /// Returns an EqualityAdapter that wraps an IEqualityComparer<T>. /// public static EqualityAdapter For(IEqualityComparer comparer) { return new EqualityComparerAdapter(comparer); } class EqualityComparerAdapter : GenericEqualityAdapter { private IEqualityComparer comparer; public EqualityComparerAdapter(IEqualityComparer comparer) { this.comparer = comparer; } public override bool AreEqual(object x, object y) { ThrowIfNotCompatible(x, y); return comparer.Equals((T)x, (T)y); } } #endregion #region Nested IComparer Adapter /// /// Returns an EqualityAdapter that wraps an IComparer<T>. /// public static EqualityAdapter For(IComparer comparer) { return new ComparerAdapter(comparer); } /// /// EqualityAdapter that wraps an IComparer. /// class ComparerAdapter : GenericEqualityAdapter { private IComparer comparer; public ComparerAdapter(IComparer comparer) { this.comparer = comparer; } public override bool AreEqual(object x, object y) { ThrowIfNotCompatible(x, y); return comparer.Compare((T)x, (T)y) == 0; } } #endregion #region Nested Comparison Adapter /// /// Returns an EqualityAdapter that wraps a Comparison<T>. /// public static EqualityAdapter For(Comparison comparer) { return new ComparisonAdapter(comparer); } class ComparisonAdapter : GenericEqualityAdapter { private Comparison comparer; public ComparisonAdapter(Comparison comparer) { this.comparer = comparer; } public override bool AreEqual(object x, object y) { ThrowIfNotCompatible(x, y); return comparer.Invoke((T)x, (T)y) == 0; } } #endregion #endif } #if CLR_2_0x || CLR_4_0x /// /// EqualityAdapter class handles all equality comparisons /// that use an IEqualityComparer, IEqualityComparer<T> /// or a ComparisonAdapter. /// public abstract class EqualityAdapter : EqualityAdapter, INUnitEqualityComparer { /// /// Compares two objects, returning true if they are equal /// public abstract bool AreEqual(T x, T y, ref Tolerance tolerance); } #endif } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ConstraintBuilder.cs0000664000175000017500000002234011544454420027153 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { /// /// ConstraintBuilder maintains the stacks that are used in /// processing a ConstraintExpression. An OperatorStack /// is used to hold operators that are waiting for their /// operands to be reognized. a ConstraintStack holds /// input constraints as well as the results of each /// operator applied. /// public class ConstraintBuilder { #region Nested Operator Stack Class /// /// OperatorStack is a type-safe stack for holding ConstraintOperators /// public class OperatorStack { #if CLR_2_0 || CLR_4_0 private Stack stack = new Stack(); #else private Stack stack = new Stack(); #endif /// /// Initializes a new instance of the class. /// /// The builder. public OperatorStack(ConstraintBuilder builder) { } /// /// Gets a value indicating whether this is empty. /// /// true if empty; otherwise, false. public bool Empty { get { return stack.Count == 0; } } /// /// Gets the topmost operator without modifying the stack. /// /// The top. public ConstraintOperator Top { get { return (ConstraintOperator)stack.Peek(); } } /// /// Pushes the specified operator onto the stack. /// /// The op. public void Push(ConstraintOperator op) { stack.Push(op); } /// /// Pops the topmost operator from the stack. /// /// public ConstraintOperator Pop() { return (ConstraintOperator)stack.Pop(); } } #endregion #region Nested Constraint Stack Class /// /// ConstraintStack is a type-safe stack for holding Constraints /// public class ConstraintStack { #if CLR_2_0 || CLR_4_0 private Stack stack = new Stack(); #else private Stack stack = new Stack(); #endif private ConstraintBuilder builder; /// /// Initializes a new instance of the class. /// /// The builder. public ConstraintStack(ConstraintBuilder builder) { this.builder = builder; } /// /// Gets a value indicating whether this is empty. /// /// true if empty; otherwise, false. public bool Empty { get { return stack.Count == 0; } } /// /// Gets the topmost constraint without modifying the stack. /// /// The topmost constraint public Constraint Top { get { return (Constraint)stack.Peek(); } } /// /// Pushes the specified constraint. As a side effect, /// the constraint's builder field is set to the /// ConstraintBuilder owning this stack. /// /// The constraint. public void Push(Constraint constraint) { stack.Push(constraint); constraint.SetBuilder( this.builder ); } /// /// Pops this topmost constrait from the stack. /// As a side effect, the constraint's builder /// field is set to null. /// /// public Constraint Pop() { Constraint constraint = (Constraint)stack.Pop(); constraint.SetBuilder( null ); return constraint; } } #endregion #region Instance Fields private OperatorStack ops; private ConstraintStack constraints; private object lastPushed; #endregion #region Constructor /// /// Initializes a new instance of the class. /// public ConstraintBuilder() { this.ops = new OperatorStack(this); this.constraints = new ConstraintStack(this); } #endregion #region Properties /// /// Gets a value indicating whether this instance is resolvable. /// /// /// true if this instance is resolvable; otherwise, false. /// public bool IsResolvable { get { return lastPushed is Constraint || lastPushed is SelfResolvingOperator; } } #endregion #region Public Methods /// /// Appends the specified operator to the expression by first /// reducing the operator stack and then pushing the new /// operator on the stack. /// /// The operator to push. public void Append(ConstraintOperator op) { op.LeftContext = lastPushed; if (lastPushed is ConstraintOperator) SetTopOperatorRightContext(op); // Reduce any lower precedence operators ReduceOperatorStack(op.LeftPrecedence); ops.Push(op); lastPushed = op; } /// /// Appends the specified constraint to the expresson by pushing /// it on the constraint stack. /// /// The constraint to push. public void Append(Constraint constraint) { if (lastPushed is ConstraintOperator) SetTopOperatorRightContext(constraint); constraints.Push(constraint); lastPushed = constraint; constraint.SetBuilder( this ); } /// /// Sets the top operator right context. /// /// The right context. private void SetTopOperatorRightContext(object rightContext) { // Some operators change their precedence based on // the right context - save current precedence. int oldPrecedence = ops.Top.LeftPrecedence; ops.Top.RightContext = rightContext; // If the precedence increased, we may be able to // reduce the region of the stack below the operator if (ops.Top.LeftPrecedence > oldPrecedence) { ConstraintOperator changedOp = ops.Pop(); ReduceOperatorStack(changedOp.LeftPrecedence); ops.Push(changedOp); } } /// /// Reduces the operator stack until the topmost item /// precedence is greater than or equal to the target precedence. /// /// The target precedence. private void ReduceOperatorStack(int targetPrecedence) { while (!ops.Empty && ops.Top.RightPrecedence < targetPrecedence) ops.Pop().Reduce(constraints); } /// /// Resolves this instance, returning a Constraint. If the builder /// is not currently in a resolvable state, an exception is thrown. /// /// The resolved constraint public Constraint Resolve() { if (!IsResolvable) throw new InvalidOperationException("A partial expression may not be resolved"); while (!ops.Empty) { ConstraintOperator op = ops.Pop(); op.Reduce(constraints); } return constraints.Pop(); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/PathConstraints.cs0000664000175000017500000002563611504175260026655 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; namespace NUnit.Framework.Constraints { #region PathConstraint /// /// PathConstraint serves as the abstract base of constraints /// that operate on paths and provides several helper methods. /// public abstract class PathConstraint : Constraint { private static readonly char[] DirectorySeparatorChars = new char[] { '\\', '/' }; /// /// The expected path used in the constraint /// protected string expectedPath; /// /// The actual path being tested /// protected string actualPath; /// /// Flag indicating whether a caseInsensitive comparison should be made /// protected bool caseInsensitive = Path.DirectorySeparatorChar == '\\'; /// /// Construct a PathConstraint for a give expected path /// /// The expected path protected PathConstraint( string expected ) : base(expected) { this.expectedPath = expected; } /// /// Modifies the current instance to be case-insensitve /// and returns it. /// public PathConstraint IgnoreCase { get { caseInsensitive = true; return this; } } /// /// Modifies the current instance to be case-sensitve /// and returns it. /// public PathConstraint RespectCase { get { caseInsensitive = false; return this; } } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches (object actual) { this.actual = actual; this.actualPath = actual as string; if (actualPath == null) return false; return IsMatch(expectedPath, actualPath); } /// /// Returns true if the expected path and actual path match /// protected abstract bool IsMatch(string expectedPath, string actualPath); /// /// Returns the string representation of this constraint /// protected override string GetStringRepresentation() { return string.Format( "<{0} \"{1}\" {2}>", DisplayName, expectedPath, caseInsensitive ? "ignorecase" : "respectcase" ); } #region Helper Methods /// /// Canonicalize the provided path /// /// /// The path in standardized form protected static string Canonicalize( string path ) { bool initialSeparator = false; if (path.Length > 0) foreach(char c in DirectorySeparatorChars) if (path[0] == c) initialSeparator = true; ArrayList parts = new ArrayList( path.Split( DirectorySeparatorChars ) ); for( int index = 0; index < parts.Count; ) { string part = (string)parts[index]; switch( part ) { case ".": parts.RemoveAt( index ); break; case "..": parts.RemoveAt( index ); if ( index > 0 ) parts.RemoveAt( --index ); break; default: index++; break; } } // Trailing separator removal if ((string)parts[parts.Count - 1] == "") parts.RemoveAt(parts.Count - 1); string result = String.Join(Path.DirectorySeparatorChar.ToString(), (string[])parts.ToArray( typeof( string ) ) ); if (initialSeparator) result = Path.DirectorySeparatorChar.ToString() + result; return result; } /// /// Test whether two paths are the same /// /// The first path /// The second path /// Indicates whether case should be ignored /// protected static bool IsSamePath( string path1, string path2, bool ignoreCase ) { return string.Compare( path1, path2, ignoreCase ) == 0; } /// /// Test whether one path is under another path /// /// The first path - supposed to be the parent path /// The second path - supposed to be the child path /// Indicates whether case should be ignored /// protected static bool IsSubPath( string path1, string path2, bool ignoreCase ) { int length1 = path1.Length; int length2 = path2.Length; // if path1 is longer or equal, then path2 can't be under it if ( length1 >= length2 ) return false; // path 2 is longer than path 1: see if initial parts match if ( string.Compare( path1, path2.Substring( 0, length1 ), ignoreCase ) != 0 ) return false; // must match through or up to a directory separator boundary return path2[length1-1] == Path.DirectorySeparatorChar || length2 > length1 && path2[length1] == Path.DirectorySeparatorChar; } /// /// Test whether one path is the same as or under another path /// /// The first path - supposed to be the parent path /// The second path - supposed to be the child path /// protected bool IsSamePathOrUnder( string path1, string path2 ) { int length1 = path1.Length; int length2 = path2.Length; // if path1 is longer, then path2 can't be under it if ( length1 > length2 ) return false; // if lengths are the same, check for equality if ( length1 == length2 ) return string.Compare( path1, path2, caseInsensitive ) == 0; // path 2 is longer than path 1: see if initial parts match if ( string.Compare( path1, path2.Substring( 0, length1 ), caseInsensitive ) != 0 ) return false; // must match through or up to a directory separator boundary return path2[length1-1] == Path.DirectorySeparatorChar || path2[length1] == Path.DirectorySeparatorChar; } #endregion } #endregion #region SamePathConstraint /// /// Summary description for SamePathConstraint. /// public class SamePathConstraint : PathConstraint { /// /// Initializes a new instance of the class. /// /// The expected path public SamePathConstraint( string expected ) : base( expected ) { } /// /// Test whether the constraint is satisfied by a given value /// /// The expected path /// The actual path /// True for success, false for failure protected override bool IsMatch(string expectedPath, string actualPath) { return IsSamePath( Canonicalize(expectedPath), Canonicalize(actualPath), caseInsensitive ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate( "Path matching" ); writer.WriteExpectedValue( expectedPath ); } } #endregion #region SubPathConstraint /// /// SubPathConstraint tests that the actual path is under the expected path /// public class SubPathConstraint : PathConstraint { /// /// Initializes a new instance of the class. /// /// The expected path public SubPathConstraint( string expected ) : base( expected ) { } /// /// Test whether the constraint is satisfied by a given value /// /// The expected path /// The actual path /// True for success, false for failure protected override bool IsMatch(string expectedPath, string actualPath) { if (actualPath == null) throw new ArgumentException("The actual value may not be null", "actual"); return IsSubPath( Canonicalize(expectedPath), Canonicalize(actualPath), caseInsensitive ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate( "Path under" ); writer.WriteExpectedValue( expectedPath ); } } #endregion #region SamePathOrUnderConstraint /// /// SamePathOrUnderConstraint tests that one path is under another /// public class SamePathOrUnderConstraint : PathConstraint { /// /// Initializes a new instance of the class. /// /// The expected path public SamePathOrUnderConstraint( string expected ) : base( expected ) { } /// /// Test whether the constraint is satisfied by a given value /// /// The expected path /// The actual path /// True for success, false for failure protected override bool IsMatch(string expectedPath, string actualPath) { string path1 = Canonicalize(expectedPath); string path2 = Canonicalize(actualPath); return IsSamePath(path1, path2, caseInsensitive) || IsSubPath(path1, path2, caseInsensitive); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate( "Path under or matching" ); writer.WriteExpectedValue( expectedPath ); } } #endregion } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/Tolerance.cs0000664000175000017500000001716611552022000025426 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/ // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Modes in which the tolerance value for a comparison can /// be interpreted. /// public enum ToleranceMode { /// /// The tolerance was created with a value, without specifying /// how the value would be used. This is used to prevent setting /// the mode more than once and is generally changed to Linear /// upon execution of the test. /// None, /// /// The tolerance is used as a numeric range within which /// two compared values are considered to be equal. /// Linear, /// /// Interprets the tolerance as the percentage by which /// the two compared values my deviate from each other. /// Percent, /// /// Compares two values based in their distance in /// representable numbers. /// Ulps } /// /// The Tolerance class generalizes the notion of a tolerance /// within which an equality test succeeds. Normally, it is /// used with numeric types, but it can be used with any /// type that supports taking a difference between two /// objects and comparing that difference to a value. /// public class Tolerance { private ToleranceMode mode; private object amount; private static readonly string ModeMustFollowTolerance = "Tolerance amount must be specified before setting mode"; private static readonly string MultipleToleranceModes = "Tried to use multiple tolerance modes at the same time"; private static readonly string NumericToleranceRequired = "A numeric tolerance is required"; /// /// Returns an empty Tolerance object, equivalent to /// specifying no tolerance. In most cases, it results /// in an exact match but for floats and doubles a /// default tolerance may be used. /// public static Tolerance Empty { get { return new Tolerance(0, ToleranceMode.None); } } /// /// Returns a zero Tolerance object, equivalent to /// specifying an exact match. /// public static Tolerance Zero { get { return new Tolerance(0, ToleranceMode.Linear); } } /// /// Constructs a linear tolerance of a specdified amount /// public Tolerance(object amount) : this(amount, ToleranceMode.Linear) { } /// /// Constructs a tolerance given an amount and ToleranceMode /// public Tolerance(object amount, ToleranceMode mode) { this.amount = amount; this.mode = mode; } /// /// Gets the ToleranceMode for the current Tolerance /// public ToleranceMode Mode { get { return this.mode; } } /// /// Tests that the current Tolerance is linear with a /// numeric value, throwing an exception if it is not. /// private void CheckLinearAndNumeric() { if (mode != ToleranceMode.Linear) throw new InvalidOperationException(mode == ToleranceMode.None ? ModeMustFollowTolerance : MultipleToleranceModes); if (!Numerics.IsNumericType(amount)) throw new InvalidOperationException(NumericToleranceRequired); } /// /// Gets the value of the current Tolerance instance. /// public object Value { get { return this.amount; } } /// /// Returns a new tolerance, using the current amount as a percentage. /// public Tolerance Percent { get { CheckLinearAndNumeric(); return new Tolerance(this.amount, ToleranceMode.Percent); } } /// /// Returns a new tolerance, using the current amount in Ulps. /// public Tolerance Ulps { get { CheckLinearAndNumeric(); return new Tolerance(this.amount, ToleranceMode.Ulps); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of days. /// public Tolerance Days { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromDays(Convert.ToDouble(amount))); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of hours. /// public Tolerance Hours { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromHours(Convert.ToDouble(amount))); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of minutes. /// public Tolerance Minutes { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromMinutes(Convert.ToDouble(amount))); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of seconds. /// public Tolerance Seconds { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromSeconds(Convert.ToDouble(amount))); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of milliseconds. /// public Tolerance Milliseconds { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromMilliseconds(Convert.ToDouble(amount))); } } /// /// Returns a new tolerance with a TimeSpan as the amount, using /// the current amount as a number of clock ticks. /// public Tolerance Ticks { get { CheckLinearAndNumeric(); return new Tolerance(TimeSpan.FromTicks(Convert.ToInt64(amount))); } } /// /// Returns true if the current tolerance is empty. /// public bool IsEmpty { get { return mode == ToleranceMode.None; } } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/PropertyConstraint.cs0000664000175000017500000001371111504175260027411 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Framework.Constraints { /// /// PropertyExistsConstraint tests that a named property /// exists on the object provided through Match. /// /// Originally, PropertyConstraint provided this feature /// in addition to making optional tests on the vaue /// of the property. The two constraints are now separate. /// public class PropertyExistsConstraint : Constraint { private string name; Type actualType; /// /// Initializes a new instance of the class. /// /// The name of the property. public PropertyExistsConstraint(string name) : base(name) { this.name = name; } /// /// Test whether the property exists for a given object /// /// The object to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (actual == null) throw new ArgumentNullException("actual"); this.actualType = actual as Type; if (actualType == null) actualType = actual.GetType(); PropertyInfo property = actualType.GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty); return property != null; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("property " + name); } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue(actualType); } /// /// Returns the string representation of the constraint. /// /// protected override string GetStringRepresentation() { return string.Format("", name); } } /// /// PropertyConstraint extracts a named property and uses /// its value as the actual value for a chained constraint. /// public class PropertyConstraint : PrefixConstraint { private string name; private object propValue; /// /// Initializes a new instance of the class. /// /// The name. /// The constraint to apply to the property. public PropertyConstraint(string name, Constraint baseConstraint) : base( baseConstraint ) { this.name = name; } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (actual == null) throw new ArgumentNullException("actual"); Type actualType = actual as Type; if ( actualType == null ) actualType = actual.GetType(); PropertyInfo property = actualType.GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty); if (property == null) throw new ArgumentException(string.Format("Property {0} was not found",name), "name"); propValue = property.GetValue( actual, null ); return baseConstraint.Matches( propValue ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate( "property " + name ); if (baseConstraint != null) { if (baseConstraint is EqualConstraint) writer.WritePredicate("equal to"); baseConstraint.WriteDescriptionTo(writer); } } /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue(propValue); } /// /// Returns the string representation of the constraint. /// /// protected override string GetStringRepresentation() { return string.Format("", name, baseConstraint); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/GreaterThanConstraint.cs0000664000175000017500000000373311550611246027774 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Tests whether a value is greater than the value supplied to its constructor /// public class GreaterThanConstraint : ComparisonConstraint { /// /// The value against which a comparison is to be made /// private object expected; /// /// Initializes a new instance of the class. /// /// The expected value. public GreaterThanConstraint(object expected) : base(expected) { this.expected = expected; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("greater than"); writer.WriteExpectedValue(expected); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (expected == null || actual == null) throw new ArgumentException("Cannot compare using a null reference"); return comparer.Compare(actual, expected) > 0; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/AttributeConstraints.cs0000664000175000017500000001241711504175260027715 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// AttributeExistsConstraint tests for the presence of a /// specified attribute on a Type. /// public class AttributeExistsConstraint : Constraint { private Type expectedType; /// /// Constructs an AttributeExistsConstraint for a specific attribute Type /// /// public AttributeExistsConstraint(Type type) : base(type) { this.expectedType = type; if (!typeof(Attribute).IsAssignableFrom(expectedType)) throw new ArgumentException(string.Format( "Type {0} is not an attribute", expectedType), "type"); } /// /// Tests whether the object provides the expected attribute. /// /// A Type, MethodInfo, or other ICustomAttributeProvider /// True if the expected attribute is present, otherwise false public override bool Matches(object actual) { this.actual = actual; System.Reflection.ICustomAttributeProvider attrProvider = actual as System.Reflection.ICustomAttributeProvider; if (attrProvider == null) throw new ArgumentException(string.Format("Actual value {0} does not implement ICustomAttributeProvider", actual), "actual"); return attrProvider.GetCustomAttributes(expectedType, true).Length > 0; } /// /// Writes the description of the constraint to the specified writer /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("type with attribute"); writer.WriteExpectedValue(expectedType); } } /// /// AttributeConstraint tests that a specified attribute is present /// on a Type or other provider and that the value of the attribute /// satisfies some other constraint. /// public class AttributeConstraint : PrefixConstraint { private Type expectedType; private Attribute attrFound; /// /// Constructs an AttributeConstraint for a specified attriute /// Type and base constraint. /// /// /// public AttributeConstraint(Type type, Constraint baseConstraint) : base( baseConstraint ) { this.expectedType = type; if (!typeof(Attribute).IsAssignableFrom(expectedType)) throw new ArgumentException(string.Format( "Type {0} is not an attribute", expectedType), "type"); } /// /// Determines whether the Type or other provider has the /// expected attribute and if its value matches the /// additional constraint specified. /// public override bool Matches(object actual) { this.actual = actual; System.Reflection.ICustomAttributeProvider attrProvider = actual as System.Reflection.ICustomAttributeProvider; if (attrProvider == null) throw new ArgumentException(string.Format("Actual value {0} does not implement ICustomAttributeProvider", actual), "actual"); Attribute[] attrs = (Attribute[])attrProvider.GetCustomAttributes(expectedType, true); if (attrs.Length == 0) throw new ArgumentException(string.Format("Attribute {0} was not found", expectedType), "actual"); this.attrFound = attrs[0]; return baseConstraint.Matches(attrFound); } /// /// Writes a description of the attribute to the specified writer. /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("attribute " + expectedType.FullName); if (baseConstraint != null) { if (baseConstraint is EqualConstraint) writer.WritePredicate("equal to"); baseConstraint.WriteDescriptionTo(writer); } } /// /// Writes the actual value supplied to the specified writer. /// public override void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue(attrFound); } /// /// Returns a string representation of the constraint. /// protected override string GetStringRepresentation() { return string.Format("", expectedType, baseConstraint); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/LessThanConstraint.cs0000664000175000017500000000371511550363552027315 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework.Constraints { /// /// Tests whether a value is less than the value supplied to its constructor /// public class LessThanConstraint : ComparisonConstraint { /// /// The value against which a comparison is to be made /// private object expected; /// /// Initializes a new instance of the class. /// /// The expected value. public LessThanConstraint(object expected) : base(expected) { this.expected = expected; } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("less than"); writer.WriteExpectedValue(expected); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (expected == null || actual == null) throw new ArgumentException("Cannot compare using a null reference"); return comparer.Compare(actual, expected) < 0; } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/PrefixConstraints.cs0000664000175000017500000002156111662016254027211 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { #region PrefixConstraint /// /// Abstract base class used for prefixes /// public abstract class PrefixConstraint : Constraint { /// /// The base constraint /// protected Constraint baseConstraint; /// /// Construct given a base constraint /// /// protected PrefixConstraint(IResolveConstraint resolvable) : base(resolvable) { if ( resolvable != null ) this.baseConstraint = resolvable.Resolve(); } } #endregion #region NotConstraint /// /// NotConstraint negates the effect of some other constraint /// public class NotConstraint : PrefixConstraint { /// /// Initializes a new instance of the class. /// /// The base constraint to be negated. public NotConstraint(Constraint baseConstraint) : base( baseConstraint ) { } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for if the base constraint fails, false if it succeeds public override bool Matches(object actual) { this.actual = actual; return !baseConstraint.Matches(actual); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo( MessageWriter writer ) { writer.WritePredicate( "not" ); baseConstraint.WriteDescriptionTo( writer ); } /// /// Write the actual value for a failing constraint test to a MessageWriter. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { baseConstraint.WriteActualValueTo (writer); } } #endregion #region AllItemsConstraint /// /// AllItemsConstraint applies another constraint to each /// item in a collection, succeeding if they all succeed. /// public class AllItemsConstraint : PrefixConstraint { /// /// Construct an AllItemsConstraint on top of an existing constraint /// /// public AllItemsConstraint(Constraint itemConstraint) : base( itemConstraint ) { this.DisplayName = "all"; } /// /// Apply the item constraint to each item in the collection, /// failing if any item fails. /// /// /// public override bool Matches(object actual) { this.actual = actual; if ( !(actual is IEnumerable) ) throw new ArgumentException( "The actual value must be an IEnumerable", "actual" ); foreach(object item in (IEnumerable)actual) if (!baseConstraint.Matches(item)) return false; return true; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("all items"); baseConstraint.WriteDescriptionTo(writer); } } #endregion #region SomeItemsConstraint /// /// SomeItemsConstraint applies another constraint to each /// item in a collection, succeeding if any of them succeeds. /// public class SomeItemsConstraint : PrefixConstraint { /// /// Construct a SomeItemsConstraint on top of an existing constraint /// /// public SomeItemsConstraint(Constraint itemConstraint) : base( itemConstraint ) { this.DisplayName = "some"; } /// /// Apply the item constraint to each item in the collection, /// succeeding if any item succeeds. /// /// /// public override bool Matches(object actual) { this.actual = actual; if ( !(actual is IEnumerable) ) throw new ArgumentException( "The actual value must be an IEnumerable", "actual" ); foreach(object item in (IEnumerable)actual) if (baseConstraint.Matches(item)) return true; return false; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("some item"); baseConstraint.WriteDescriptionTo(writer); } } #endregion #region NoItemConstraint /// /// NoItemConstraint applies another constraint to each /// item in a collection, failing if any of them succeeds. /// public class NoItemConstraint : PrefixConstraint { /// /// Construct a SomeItemsConstraint on top of an existing constraint /// /// public NoItemConstraint(Constraint itemConstraint) : base( itemConstraint ) { this.DisplayName = "none"; } /// /// Apply the item constraint to each item in the collection, /// failing if any item fails. /// /// /// public override bool Matches(object actual) { this.actual = actual; if ( !(actual is IEnumerable) ) throw new ArgumentException( "The actual value must be an IEnumerable", "actual" ); foreach(object item in (IEnumerable)actual) if (baseConstraint.Matches(item)) return false; return true; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("no item"); baseConstraint.WriteDescriptionTo(writer); } } #endregion #region ExactCountConstraint /// /// ExactCoutConstraint applies another constraint to each /// item in a collection, succeeding only if a specified /// number of items succeed. /// public class ExactCountConstraint : PrefixConstraint { private int expectedCount; /// /// Construct an ExactCountConstraint on top of an existing constraint /// /// /// public ExactCountConstraint(int expectedCount, Constraint itemConstraint) : base(itemConstraint) { this.DisplayName = "one"; this.expectedCount = expectedCount; } /// /// Apply the item constraint to each item in the collection, /// succeeding only if the expected number of items pass. /// /// /// public override bool Matches(object actual) { this.actual = actual; if (!(actual is IEnumerable)) throw new ArgumentException("The actual value must be an IEnumerable", "actual"); int count = 0; foreach (object item in (IEnumerable)actual) if (baseConstraint.Matches(item)) count++; return count == expectedCount; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { switch(expectedCount) { case 0: writer.WritePredicate("no item"); break; case 1: writer.WritePredicate("exactly one item"); break; default: writer.WritePredicate("exactly " + expectedCount.ToString() + " items"); break; } baseConstraint.WriteDescriptionTo(writer); } } #endregion }NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ContainsConstraint.cs0000664000175000017500000001221011651237660027342 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Framework.Constraints { // TODO Needs tests /// /// ContainsConstraint tests a whether a string contains a substring /// or a collection contains an object. It postpones the decision of /// which test to use until the type of the actual argument is known. /// This allows testing whether a string is contained in a collection /// or as a substring of another string using the same syntax. /// public class ContainsConstraint : Constraint { object expected; Constraint realConstraint; bool ignoreCase; private EqualityAdapter adapter = null; private Constraint RealConstraint { get { if ( realConstraint == null ) { if (actual is string) { StringConstraint constraint = new SubstringConstraint((string)expected); if (this.ignoreCase) constraint = constraint.IgnoreCase; this.realConstraint = constraint; } else { CollectionContainsConstraint constraint = new CollectionContainsConstraint(expected); if (this.adapter != null) constraint.comparer.ExternalComparers.Add(adapter); this.realConstraint = constraint; } } return realConstraint; } set { realConstraint = value; } } /// /// Initializes a new instance of the class. /// /// The expected. public ContainsConstraint( object expected ) : base(expected) { this.expected = expected; } /// /// Flag the constraint to ignore case and return self. /// public ContainsConstraint IgnoreCase { get { this.ignoreCase = true; return this; } } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; return this.RealConstraint.Matches( actual ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { this.RealConstraint.WriteDescriptionTo(writer); } /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public ContainsConstraint Using(IComparer comparer) { this.adapter = EqualityAdapter.For(comparer); return this; } #if CLR_2_0 || CLR_4_0 /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public ContainsConstraint Using(IComparer comparer) { this.adapter = EqualityAdapter.For(comparer); return this; } /// /// Flag the constraint to use the supplied Comparison object. /// /// The IComparer object to use. /// Self. public ContainsConstraint Using(Comparison comparer) { this.adapter = EqualityAdapter.For(comparer); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public ContainsConstraint Using(IEqualityComparer comparer) { this.adapter = EqualityAdapter.For(comparer); return this; } /// /// Flag the constraint to use the supplied IEqualityComparer object. /// /// The IComparer object to use. /// Self. public ContainsConstraint Using(IEqualityComparer comparer) { this.adapter = EqualityAdapter.For(comparer); return this; } #endif } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/ConstraintExpression.cs0000664000175000017500000006242011672602234027727 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { /// /// ConstraintExpression represents a compound constraint in the /// process of being constructed from a series of syntactic elements. /// /// Individual elements are appended to the expression as they are /// reognized. Once an actual Constraint is appended, the expression /// returns a resolvable Constraint. /// public class ConstraintExpression : ConstraintExpressionBase { /// /// Initializes a new instance of the class. /// public ConstraintExpression() { } /// /// Initializes a new instance of the /// class passing in a ConstraintBuilder, which may be pre-populated. /// /// The builder. public ConstraintExpression(ConstraintBuilder builder) : base( builder ) { } #region Not /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public ConstraintExpression Not { get { return this.Append(new NotOperator()); } } /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public ConstraintExpression No { get { return this.Append(new NotOperator()); } } #endregion #region All /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them succeed. /// public ConstraintExpression All { get { return this.Append(new AllOperator()); } } #endregion #region Some /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if at least one of them succeeds. /// public ConstraintExpression Some { get { return this.Append(new SomeOperator()); } } #endregion #region None /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them fail. /// public ConstraintExpression None { get { return this.Append(new NoneOperator()); } } #endregion #region Exactly(n) /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding only if a specified number of them succeed. /// public ConstraintExpression Exactly(int expectedCount) { return this.Append(new ExactCountOperator(expectedCount)); } #endregion #region Property /// /// Returns a new PropertyConstraintExpression, which will either /// test for the existence of the named property on the object /// being tested or apply any following constraint to that property. /// public ResolvableConstraintExpression Property(string name) { return this.Append(new PropOperator(name)); } #endregion #region Length /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Length property of the object being tested. /// public ResolvableConstraintExpression Length { get { return Property("Length"); } } #endregion #region Count /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Count property of the object being tested. /// public ResolvableConstraintExpression Count { get { return Property("Count"); } } #endregion #region Message /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the Message property of the object being tested. /// public ResolvableConstraintExpression Message { get { return Property("Message"); } } #endregion #region InnerException /// /// Returns a new ConstraintExpression, which will apply the following /// constraint to the InnerException property of the object being tested. /// public ResolvableConstraintExpression InnerException { get { return Property("InnerException"); } } #endregion #region Attribute /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public ResolvableConstraintExpression Attribute(Type expectedType) { return this.Append(new AttributeOperator(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a new AttributeConstraint checking for the /// presence of a particular attribute on an object. /// public ResolvableConstraintExpression Attribute() { return Attribute(typeof(T)); } #endif #endregion #region With /// /// With is currently a NOP - reserved for future use. /// public ConstraintExpression With { get { return this.Append(new WithOperator()); } } #endregion #region Matches /// /// Returns the constraint provided as an argument - used to allow custom /// custom constraints to easily participate in the syntax. /// public Constraint Matches(Constraint constraint) { return this.Append(constraint); } #if CLR_2_0 || CLR_4_0 /// /// Returns the constraint provided as an argument - used to allow custom /// custom constraints to easily participate in the syntax. /// public Constraint Matches(Predicate predicate) { return this.Append(new PredicateConstraint(predicate)); } #endif #endregion #region Null /// /// Returns a constraint that tests for null /// public NullConstraint Null { get { return (NullConstraint)this.Append(new NullConstraint()); } } #endregion #region True /// /// Returns a constraint that tests for True /// public TrueConstraint True { get { return (TrueConstraint)this.Append(new TrueConstraint()); } } #endregion #region False /// /// Returns a constraint that tests for False /// public FalseConstraint False { get { return (FalseConstraint)this.Append(new FalseConstraint()); } } #endregion #region Positive /// /// Returns a constraint that tests for a positive value /// public GreaterThanConstraint Positive { get { return (GreaterThanConstraint)this.Append(new GreaterThanConstraint(0)); } } #endregion #region Negative /// /// Returns a constraint that tests for a negative value /// public LessThanConstraint Negative { get { return (LessThanConstraint)this.Append(new LessThanConstraint(0)); } } #endregion #region NaN /// /// Returns a constraint that tests for NaN /// public NaNConstraint NaN { get { return (NaNConstraint)this.Append(new NaNConstraint()); } } #endregion #region Empty /// /// Returns a constraint that tests for empty /// public EmptyConstraint Empty { get { return (EmptyConstraint)this.Append(new EmptyConstraint()); } } #endregion #region Unique /// /// Returns a constraint that tests whether a collection /// contains all unique items. /// public UniqueItemsConstraint Unique { get { return (UniqueItemsConstraint)this.Append(new UniqueItemsConstraint()); } } #endregion #region BinarySerializable /// /// Returns a constraint that tests whether an object graph is serializable in binary format. /// public BinarySerializableConstraint BinarySerializable { get { return (BinarySerializableConstraint)this.Append(new BinarySerializableConstraint()); } } #endregion #region XmlSerializable /// /// Returns a constraint that tests whether an object graph is serializable in xml format. /// public XmlSerializableConstraint XmlSerializable { get { return (XmlSerializableConstraint)this.Append(new XmlSerializableConstraint()); } } #endregion #region EqualTo /// /// Returns a constraint that tests two items for equality /// public EqualConstraint EqualTo(object expected) { return (EqualConstraint)this.Append(new EqualConstraint(expected)); } #endregion #region SameAs /// /// Returns a constraint that tests that two references are the same object /// public SameAsConstraint SameAs(object expected) { return (SameAsConstraint)this.Append(new SameAsConstraint(expected)); } #endregion #region GreaterThan /// /// Returns a constraint that tests whether the /// actual value is greater than the suppled argument /// public GreaterThanConstraint GreaterThan(object expected) { return (GreaterThanConstraint)this.Append(new GreaterThanConstraint(expected)); } #endregion #region GreaterThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public GreaterThanOrEqualConstraint GreaterThanOrEqualTo(object expected) { return (GreaterThanOrEqualConstraint)this.Append(new GreaterThanOrEqualConstraint(expected)); } /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public GreaterThanOrEqualConstraint AtLeast(object expected) { return (GreaterThanOrEqualConstraint)this.Append(new GreaterThanOrEqualConstraint(expected)); } #endregion #region LessThan /// /// Returns a constraint that tests whether the /// actual value is less than the suppled argument /// public LessThanConstraint LessThan(object expected) { return (LessThanConstraint)this.Append(new LessThanConstraint(expected)); } #endregion #region LessThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public LessThanOrEqualConstraint LessThanOrEqualTo(object expected) { return (LessThanOrEqualConstraint)this.Append(new LessThanOrEqualConstraint(expected)); } /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public LessThanOrEqualConstraint AtMost(object expected) { return (LessThanOrEqualConstraint)this.Append(new LessThanOrEqualConstraint(expected)); } #endregion #region TypeOf /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public ExactTypeConstraint TypeOf(Type expectedType) { return (ExactTypeConstraint)this.Append(new ExactTypeConstraint(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public ExactTypeConstraint TypeOf() { return (ExactTypeConstraint)this.Append(new ExactTypeConstraint(typeof(T))); } #endif #endregion #region InstanceOf /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public InstanceOfTypeConstraint InstanceOf(Type expectedType) { return (InstanceOfTypeConstraint)this.Append(new InstanceOfTypeConstraint(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public InstanceOfTypeConstraint InstanceOf() { return (InstanceOfTypeConstraint)this.Append(new InstanceOfTypeConstraint(typeof(T))); } #endif /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf(expectedType)")] public InstanceOfTypeConstraint InstanceOfType(Type expectedType) { return (InstanceOfTypeConstraint)this.Append(new InstanceOfTypeConstraint(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf()")] public InstanceOfTypeConstraint InstanceOfType() { return (InstanceOfTypeConstraint)this.Append(new InstanceOfTypeConstraint(typeof(T))); } #endif #endregion #region AssignableFrom /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableFromConstraint AssignableFrom(Type expectedType) { return (AssignableFromConstraint)this.Append(new AssignableFromConstraint(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableFromConstraint AssignableFrom() { return (AssignableFromConstraint)this.Append(new AssignableFromConstraint(typeof(T))); } #endif #endregion #region AssignableTo /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableToConstraint AssignableTo(Type expectedType) { return (AssignableToConstraint)this.Append(new AssignableToConstraint(expectedType)); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public AssignableToConstraint AssignableTo() { return (AssignableToConstraint)this.Append(new AssignableToConstraint(typeof(T))); } #endif #endregion #region EquivalentTo /// /// Returns a constraint that tests whether the actual value /// is a collection containing the same elements as the /// collection supplied as an argument. /// public CollectionEquivalentConstraint EquivalentTo(IEnumerable expected) { return (CollectionEquivalentConstraint)this.Append(new CollectionEquivalentConstraint(expected)); } #endregion #region SubsetOf /// /// Returns a constraint that tests whether the actual value /// is a subset of the collection supplied as an argument. /// public CollectionSubsetConstraint SubsetOf(IEnumerable expected) { return (CollectionSubsetConstraint)this.Append(new CollectionSubsetConstraint(expected)); } #endregion #region Ordered /// /// Returns a constraint that tests whether a collection is ordered /// public CollectionOrderedConstraint Ordered { get { return (CollectionOrderedConstraint)this.Append(new CollectionOrderedConstraint()); } } #endregion #region Member /// /// Returns a new CollectionContainsConstraint checking for the /// presence of a particular object in the collection. /// public CollectionContainsConstraint Member(object expected) { return (CollectionContainsConstraint)this.Append(new CollectionContainsConstraint(expected)); } /// /// Returns a new CollectionContainsConstraint checking for the /// presence of a particular object in the collection. /// public CollectionContainsConstraint Contains(object expected) { return (CollectionContainsConstraint)this.Append(new CollectionContainsConstraint(expected)); } #endregion #region Contains /// /// Returns a new ContainsConstraint. This constraint /// will, in turn, make use of the appropriate second-level /// constraint, depending on the type of the actual argument. /// This overload is only used if the item sought is a string, /// since any other type implies that we are looking for a /// collection member. /// public ContainsConstraint Contains(string expected) { return (ContainsConstraint)this.Append(new ContainsConstraint(expected)); } #endregion #region StringContaining /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// public SubstringConstraint StringContaining(string expected) { return (SubstringConstraint)this.Append(new SubstringConstraint(expected)); } /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// public SubstringConstraint ContainsSubstring(string expected) { return (SubstringConstraint)this.Append(new SubstringConstraint(expected)); } #endregion #region StartsWith /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// public StartsWithConstraint StartsWith(string expected) { return (StartsWithConstraint)this.Append(new StartsWithConstraint(expected)); } /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// public StartsWithConstraint StringStarting(string expected) { return (StartsWithConstraint)this.Append(new StartsWithConstraint(expected)); } #endregion #region EndsWith /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// public EndsWithConstraint EndsWith(string expected) { return (EndsWithConstraint)this.Append(new EndsWithConstraint(expected)); } /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// public EndsWithConstraint StringEnding(string expected) { return (EndsWithConstraint)this.Append(new EndsWithConstraint(expected)); } #endregion #region Matches /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// public RegexConstraint Matches(string pattern) { return (RegexConstraint)this.Append(new RegexConstraint(pattern)); } /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// public RegexConstraint StringMatching(string pattern) { return (RegexConstraint)this.Append(new RegexConstraint(pattern)); } #endregion #region SamePath /// /// Returns a constraint that tests whether the path provided /// is the same as an expected path after canonicalization. /// public SamePathConstraint SamePath(string expected) { return (SamePathConstraint)this.Append(new SamePathConstraint(expected)); } #endregion #region SubPath /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public SubPathConstraint SubPath(string expected) { return (SubPathConstraint)this.Append(new SubPathConstraint(expected)); } #endregion #region SamePathOrUnder /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public SamePathOrUnderConstraint SamePathOrUnder(string expected) { return (SamePathOrUnderConstraint)this.Append(new SamePathOrUnderConstraint(expected)); } #endregion #region InRange #if !CLR_2_0 && !CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public RangeConstraint InRange(IComparable from, IComparable to) { return (RangeConstraint)this.Append(new RangeConstraint(from, to)); } #endif #endregion #region InRange #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public RangeConstraint InRange(T from, T to) where T : IComparable { return (RangeConstraint)this.Append(new RangeConstraint(from, to)); } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Constraints/EmptyConstraint.cs0000664000175000017500000000354111670446572026676 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Framework.Constraints { /// /// EmptyConstraint tests a whether a string or collection is empty, /// postponing the decision about which test is applied until the /// type of the actual argument is known. /// public class EmptyConstraint : Constraint { private Constraint RealConstraint { get { if (actual is string) return new EmptyStringConstraint(); else if (actual is System.IO.DirectoryInfo) return new EmptyDirectoryContraint(); else return new EmptyCollectionConstraint(); } } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public override bool Matches(object actual) { this.actual = actual; if (actual == null) throw new ArgumentException("The actual value must be a non-null string, IEnumerable or DirectoryInfo", "actual"); return this.RealConstraint.Matches( actual ); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo(MessageWriter writer) { this.RealConstraint.WriteDescriptionTo( writer ); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Assert.cs0000664000175000017500000053117511707610160022461 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Delegate used by tests that execute code and /// capture any thrown exception. /// public delegate void TestDelegate(); /// /// The Assert class contains a collection of static methods that /// implement the most common assertions used in NUnit. /// public class Assert { #region Constructor /// /// We don't actually want any instances of this object, but some people /// like to inherit from it to add other static methods. Hence, the /// protected constructor disallows any instances of this object. /// protected Assert() { } #endregion #region Assert Counting private static int counter = 0; /// /// Gets the number of assertions executed so far and /// resets the counter to zero. /// public static int Counter { get { int cnt = counter; counter = 0; return cnt; } } private static void IncrementAssertCount() { ++counter; } #endregion #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { // TODO: This should probably be InvalidOperationException throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region Helper Methods /// /// Helper for Assert.AreEqual(double expected, double actual, ...) /// allowing code generation to work consistently. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual /// The message to display in case of failure /// Array of objects to be used in formatting the message protected static void AssertDoublesAreEqual(double expected, double actual, double delta, string message, object[] args) { if (double.IsNaN(expected) || double.IsInfinity(expected)) Assert.That(actual, Is.EqualTo(expected), message, args); else Assert.That(actual, Is.EqualTo(expected).Within(delta), message, args); } #endregion #region Utility Asserts #region Pass /// /// Throws a with the message and arguments /// that are passed in. This allows a test to be cut short, with a result /// of success returned to NUnit. /// /// The message to initialize the with. /// Arguments to be used in formatting the message static public void Pass(string message, params object[] args) { if (message == null) message = string.Empty; else if (args != null && args.Length > 0) message = string.Format(message, args); throw new SuccessException(message); } /// /// Throws a with the message and arguments /// that are passed in. This allows a test to be cut short, with a result /// of success returned to NUnit. /// /// The message to initialize the with. static public void Pass(string message) { Assert.Pass(message, null); } /// /// Throws a with the message and arguments /// that are passed in. This allows a test to be cut short, with a result /// of success returned to NUnit. /// static public void Pass() { Assert.Pass(string.Empty, null); } #endregion #region Fail /// /// Throws an with the message and arguments /// that are passed in. This is used by the other Assert functions. /// /// The message to initialize the with. /// Arguments to be used in formatting the message static public void Fail(string message, params object[] args) { if (message == null) message = string.Empty; else if (args != null && args.Length > 0) message = string.Format(message, args); throw new AssertionException(message); } /// /// Throws an with the message that is /// passed in. This is used by the other Assert functions. /// /// The message to initialize the with. static public void Fail(string message) { Assert.Fail(message, null); } /// /// Throws an . /// This is used by the other Assert functions. /// static public void Fail() { Assert.Fail(string.Empty, null); } #endregion #region Ignore /// /// Throws an with the message and arguments /// that are passed in. This causes the test to be reported as ignored. /// /// The message to initialize the with. /// Arguments to be used in formatting the message static public void Ignore(string message, params object[] args) { if (message == null) message = string.Empty; else if (args != null && args.Length > 0) message = string.Format(message, args); throw new IgnoreException(message); } /// /// Throws an with the message that is /// passed in. This causes the test to be reported as ignored. /// /// The message to initialize the with. static public void Ignore(string message) { Assert.Ignore(message, null); } /// /// Throws an . /// This causes the test to be reported as ignored. /// static public void Ignore() { Assert.Ignore(string.Empty, null); } #endregion #region InConclusive /// /// Throws an with the message and arguments /// that are passed in. This causes the test to be reported as inconclusive. /// /// The message to initialize the with. /// Arguments to be used in formatting the message static public void Inconclusive(string message, params object[] args) { if (message == null) message = string.Empty; else if (args != null && args.Length > 0) message = string.Format(message, args); throw new InconclusiveException(message); } /// /// Throws an with the message that is /// passed in. This causes the test to be reported as inconclusive. /// /// The message to initialize the with. static public void Inconclusive(string message) { Assert.Inconclusive(message, null); } /// /// Throws an . /// This causes the test to be reported as Inconclusive. /// static public void Inconclusive() { Assert.Inconclusive(string.Empty, null); } #endregion #endregion #region Assert.That #region Object /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test static public void That(object actual, IResolveConstraint expression) { Assert.That(actual, expression, null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(object actual, IResolveConstraint expression, string message) { Assert.That(actual, expression, message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(object actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); Assert.IncrementAssertCount(); if (!constraint.Matches(actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new AssertionException(writer.ToString()); } } #endregion #region ActualValueDelegate /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested static public void That(ActualValueDelegate del, IResolveConstraint expr) { Assert.That(del, expr.Resolve(), null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint expression to be applied /// An ActualValueDelegate returning the value to be tested /// The message that will be displayed on failure static public void That(ActualValueDelegate del, IResolveConstraint expr, string message) { Assert.That(del, expr.Resolve(), message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// An ActualValueDelegate returning the value to be tested /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ActualValueDelegate del, IResolveConstraint expr, string message, params object[] args) { Constraint constraint = expr.Resolve(); Assert.IncrementAssertCount(); if (!constraint.Matches(del)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new AssertionException(writer.ToString()); } } #endregion #region ref Object #if CLR_2_0 || CLR_4_0 /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test static public void That(ref T actual, IResolveConstraint expression) { Assert.That(ref actual, expression.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(ref T actual, IResolveConstraint expression, string message) { Assert.That(ref actual, expression.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ref T actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); Assert.IncrementAssertCount(); if (!constraint.Matches(ref actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new AssertionException(writer.ToString()); } } #else /// /// Apply a constraint to a referenced boolean, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test static public void That(ref bool actual, IResolveConstraint constraint) { Assert.That(ref actual, constraint.Resolve(), null, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure static public void That(ref bool actual, IResolveConstraint constraint, string message) { Assert.That(ref actual, constraint.Resolve(), message, null); } /// /// Apply a constraint to a referenced value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// /// The actual value to test /// A Constraint expression to be applied /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void That(ref bool actual, IResolveConstraint expression, string message, params object[] args) { Constraint constraint = expression.Resolve(); Assert.IncrementAssertCount(); if (!constraint.Matches(ref actual)) { MessageWriter writer = new TextMessageWriter(message, args); constraint.WriteMessageTo(writer); throw new AssertionException(writer.ToString()); } } #endif #endregion #region Boolean /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display if the condition is false /// Arguments to be used in formatting the message static public void That(bool condition, string message, params object[] args) { Assert.That(condition, Is.True, message, args); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display if the condition is false static public void That(bool condition, string message) { Assert.That(condition, Is.True, message, null); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition static public void That(bool condition) { Assert.That(condition, Is.True, null, null); } #endregion /// /// Asserts that the code represented by a delegate throws an exception /// that satisfies the constraint provided. /// /// A TestDelegate to be executed /// A ThrowsConstraint used in the test static public void That(TestDelegate code, IResolveConstraint constraint) { Assert.That((object)code, constraint); } #endregion #region Assert.ByVal /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// Used as a synonym for That in rare cases where a private setter /// causes a Visual Basic compilation error. /// /// A Constraint to be applied /// The actual value to test static public void ByVal(object actual, IResolveConstraint expression) { Assert.That(actual, expression, null, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// Used as a synonym for That in rare cases where a private setter /// causes a Visual Basic compilation error. /// /// A Constraint to be applied /// The actual value to test /// The message that will be displayed on failure static public void ByVal(object actual, IResolveConstraint expression, string message) { Assert.That(actual, expression, message, null); } /// /// Apply a constraint to an actual value, succeeding if the constraint /// is satisfied and throwing an assertion exception on failure. /// Used as a synonym for That in rare cases where a private setter /// causes a Visual Basic compilation error. /// /// /// This method is provided for use by VB developers needing to test /// the value of properties with private setters. /// /// A Constraint expression to be applied /// The actual value to test /// The message that will be displayed on failure /// Arguments to be used in formatting the message static public void ByVal(object actual, IResolveConstraint expression, string message, params object[] args) { Assert.That(actual, expression, message, args); } #endregion #region Throws, Catch and DoesNotThrow #region Throws /// /// Verifies that a delegate throws a particular exception when called. /// /// A constraint to be satisfied by the exception /// A TestSnippet delegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static Exception Throws(IResolveConstraint expression, TestDelegate code, string message, params object[] args) { Exception caughtException = null; try { code(); } catch (Exception ex) { caughtException = ex; } Assert.That(caughtException, expression, message, args); return caughtException; } /// /// Verifies that a delegate throws a particular exception when called. /// /// A constraint to be satisfied by the exception /// A TestSnippet delegate /// The message that will be displayed on failure public static Exception Throws(IResolveConstraint expression, TestDelegate code, string message) { return Throws(expression, code, message, null); } /// /// Verifies that a delegate throws a particular exception when called. /// /// A constraint to be satisfied by the exception /// A TestSnippet delegate public static Exception Throws(IResolveConstraint expression, TestDelegate code) { return Throws(expression, code, string.Empty, null); } /// /// Verifies that a delegate throws a particular exception when called. /// /// The exception Type expected /// A TestSnippet delegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static Exception Throws(Type expectedExceptionType, TestDelegate code, string message, params object[] args) { return Throws(new ExceptionTypeConstraint(expectedExceptionType), code, message, args); } /// /// Verifies that a delegate throws a particular exception when called. /// /// The exception Type expected /// A TestSnippet delegate /// The message that will be displayed on failure public static Exception Throws(Type expectedExceptionType, TestDelegate code, string message) { return Throws(new ExceptionTypeConstraint(expectedExceptionType), code, message, null); } /// /// Verifies that a delegate throws a particular exception when called. /// /// The exception Type expected /// A TestSnippet delegate public static Exception Throws(Type expectedExceptionType, TestDelegate code) { return Throws(new ExceptionTypeConstraint(expectedExceptionType), code, string.Empty, null); } #endregion #region Throws #if CLR_2_0 || CLR_4_0 /// /// Verifies that a delegate throws a particular exception when called. /// /// Type of the expected exception /// A TestSnippet delegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static T Throws(TestDelegate code, string message, params object[] args) where T : Exception { return (T)Throws(typeof(T), code, message, args); } /// /// Verifies that a delegate throws a particular exception when called. /// /// Type of the expected exception /// A TestSnippet delegate /// The message that will be displayed on failure public static T Throws(TestDelegate code, string message) where T : Exception { return Throws(code, message, null); } /// /// Verifies that a delegate throws a particular exception when called. /// /// Type of the expected exception /// A TestSnippet delegate public static T Throws(TestDelegate code) where T : Exception { return Throws(code, string.Empty, null); } #endif #endregion #region Catch /// /// Verifies that a delegate throws an exception when called /// and returns it. /// /// A TestDelegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static Exception Catch(TestDelegate code, string message, params object[] args) { return Throws(new InstanceOfTypeConstraint(typeof(Exception)), code, message, args); } /// /// Verifies that a delegate throws an exception when called /// and returns it. /// /// A TestDelegate /// The message that will be displayed on failure public static Exception Catch(TestDelegate code, string message) { return Throws(new InstanceOfTypeConstraint(typeof(Exception)), code, message); } /// /// Verifies that a delegate throws an exception when called /// and returns it. /// /// A TestDelegate public static Exception Catch(TestDelegate code) { return Throws(new InstanceOfTypeConstraint(typeof(Exception)), code); } /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static Exception Catch(Type expectedExceptionType, TestDelegate code, string message, params object[] args) { return Throws(new InstanceOfTypeConstraint(expectedExceptionType), code, message, args); } /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate /// The message that will be displayed on failure public static Exception Catch(Type expectedExceptionType, TestDelegate code, string message) { return Throws(new InstanceOfTypeConstraint(expectedExceptionType), code, message); } /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate public static Exception Catch(Type expectedExceptionType, TestDelegate code) { return Throws(new InstanceOfTypeConstraint(expectedExceptionType), code); } #endregion #region Catch #if CLR_2_0 || CLR_4_0 /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static T Catch(TestDelegate code, string message, params object[] args) where T : System.Exception { return (T)Throws(new InstanceOfTypeConstraint(typeof(T)), code, message, args); } /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate /// The message that will be displayed on failure public static T Catch(TestDelegate code, string message) where T : System.Exception { return (T)Throws(new InstanceOfTypeConstraint(typeof(T)), code, message); } /// /// Verifies that a delegate throws an exception of a certain Type /// or one derived from it when called and returns it. /// /// The expected Exception Type /// A TestDelegate public static T Catch(TestDelegate code) where T : System.Exception { return (T)Throws(new InstanceOfTypeConstraint(typeof(T)), code); } #endif #endregion #region DoesNotThrow /// /// Verifies that a delegate does not throw an exception /// /// A TestSnippet delegate /// The message that will be displayed on failure /// Arguments to be used in formatting the message public static void DoesNotThrow(TestDelegate code, string message, params object[] args) { try { code(); } catch (Exception ex) { TextMessageWriter writer = new TextMessageWriter(message, args); writer.WriteLine("Unexpected exception: {0}", ex.GetType()); Assert.Fail(writer.ToString()); } } /// /// Verifies that a delegate does not throw an exception. /// /// A TestSnippet delegate /// The message that will be displayed on failure public static void DoesNotThrow(TestDelegate code, string message) { DoesNotThrow(code, message, null); } /// /// Verifies that a delegate does not throw an exception. /// /// A TestSnippet delegate public static void DoesNotThrow(TestDelegate code) { DoesNotThrow(code, string.Empty, null); } #endregion #endregion #region True /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void True(bool condition, string message, params object[] args) { Assert.That(condition, Is.True, message, args); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure public static void True(bool condition, string message) { Assert.That(condition, Is.True, message, null); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition public static void True(bool condition) { Assert.That(condition, Is.True, null, null); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsTrue(bool condition, string message, params object[] args) { Assert.That(condition, Is.True, message, args); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure public static void IsTrue(bool condition, string message) { Assert.That(condition, Is.True, message, null); } /// /// Asserts that a condition is true. If the condition is false the method throws /// an . /// /// The evaluated condition public static void IsTrue(bool condition) { Assert.That(condition, Is.True, null, null); } #endregion #region False /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void False(bool condition, string message, params object[] args) { Assert.That(condition, Is.False, message, args); } /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure public static void False(bool condition, string message) { Assert.That(condition, Is.False, message, null); } /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition public static void False(bool condition) { Assert.That(condition, Is.False, null, null); } /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsFalse(bool condition, string message, params object[] args) { Assert.That(condition, Is.False, message, args); } /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition /// The message to display in case of failure public static void IsFalse(bool condition, string message) { Assert.That(condition, Is.False, message, null); } /// /// Asserts that a condition is false. If the condition is true the method throws /// an . /// /// The evaluated condition public static void IsFalse(bool condition) { Assert.That(condition, Is.False, null, null); } #endregion #region NotNull /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void NotNull(object anObject, string message, params object[] args) { Assert.That(anObject, Is.Not.Null, message, args); } /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure public static void NotNull(object anObject, string message) { Assert.That(anObject, Is.Not.Null, message, null); } /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested public static void NotNull(object anObject) { Assert.That(anObject, Is.Not.Null, null, null); } /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotNull(object anObject, string message, params object[] args) { Assert.That(anObject, Is.Not.Null, message, args); } /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure public static void IsNotNull(object anObject, string message) { Assert.That(anObject, Is.Not.Null, message, null); } /// /// Verifies that the object that is passed in is not equal to null /// If the object is null then an /// is thrown. /// /// The object that is to be tested public static void IsNotNull(object anObject) { Assert.That(anObject, Is.Not.Null, null, null); } #endregion #region Null /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Null(object anObject, string message, params object[] args) { Assert.That(anObject, Is.Null, message, args); } /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure public static void Null(object anObject, string message) { Assert.That(anObject, Is.Null, message, null); } /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested public static void Null(object anObject) { Assert.That(anObject, Is.Null, null, null); } /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNull(object anObject, string message, params object[] args) { Assert.That(anObject, Is.Null, message, args); } /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested /// The message to display in case of failure public static void IsNull(object anObject, string message) { Assert.That(anObject, Is.Null, message, null); } /// /// Verifies that the object that is passed in is equal to null /// If the object is not null then an /// is thrown. /// /// The object that is to be tested public static void IsNull(object anObject) { Assert.That(anObject, Is.Null, null, null); } #endregion #region IsNaN /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNaN(double aDouble, string message, params object[] args) { Assert.That(aDouble, Is.NaN, message, args); } /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested /// The message to display in case of failure public static void IsNaN(double aDouble, string message) { Assert.That(aDouble, Is.NaN, message, null); } /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested public static void IsNaN(double aDouble) { Assert.That(aDouble, Is.NaN, null, null); } #if CLR_2_0 || CLR_4_0 /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNaN(double? aDouble, string message, params object[] args) { Assert.That(aDouble, Is.NaN, message, args); } /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested /// The message to display in case of failure public static void IsNaN(double? aDouble, string message) { Assert.That(aDouble, Is.NaN, message, null); } /// /// Verifies that the double that is passed in is an NaN value. /// If the object is not NaN then an /// is thrown. /// /// The value that is to be tested public static void IsNaN(double? aDouble) { Assert.That(aDouble, Is.NaN, null, null); } #endif #endregion #region IsEmpty /// /// Assert that a string is empty - that is equal to string.Empty /// /// The string to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsEmpty(string aString, string message, params object[] args) { Assert.That(aString, new EmptyStringConstraint(), message, args); } /// /// Assert that a string is empty - that is equal to string.Empty /// /// The string to be tested /// The message to display in case of failure public static void IsEmpty(string aString, string message) { Assert.That(aString, new EmptyStringConstraint(), message, null); } /// /// Assert that a string is empty - that is equal to string.Empty /// /// The string to be tested public static void IsEmpty(string aString) { Assert.That(aString, new EmptyStringConstraint(), null, null); } #endregion #region IsEmpty /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing ICollection /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsEmpty(IEnumerable collection, string message, params object[] args) { Assert.That(collection, new EmptyCollectionConstraint(), message, args); } /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing ICollection /// The message to display in case of failure public static void IsEmpty(IEnumerable collection, string message) { Assert.That(collection, new EmptyCollectionConstraint(), message, null); } /// /// Assert that an array, list or other collection is empty /// /// An array, list or other collection implementing ICollection public static void IsEmpty(IEnumerable collection) { Assert.That(collection, new EmptyCollectionConstraint(), null, null); } #endregion #region IsNotEmpty /// /// Assert that a string is not empty - that is not equal to string.Empty /// /// The string to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotEmpty(string aString, string message, params object[] args) { Assert.That(aString, Is.Not.Empty, message, args); } /// /// Assert that a string is not empty - that is not equal to string.Empty /// /// The string to be tested /// The message to display in case of failure public static void IsNotEmpty(string aString, string message) { Assert.That(aString, Is.Not.Empty, message, null); } /// /// Assert that a string is not empty - that is not equal to string.Empty /// /// The string to be tested public static void IsNotEmpty(string aString) { Assert.That(aString, Is.Not.Empty, null, null); } #endregion #region IsNotEmpty /// /// Assert that an array, list or other collection is not empty /// /// An array, list or other collection implementing ICollection /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotEmpty(IEnumerable collection, string message, params object[] args) { Assert.That(collection, Is.Not.Empty, message, args); } /// /// Assert that an array, list or other collection is not empty /// /// An array, list or other collection implementing ICollection /// The message to display in case of failure public static void IsNotEmpty(IEnumerable collection, string message) { Assert.That(collection, Is.Not.Empty, message, null); } /// /// Assert that an array, list or other collection is not empty /// /// An array, list or other collection implementing ICollection public static void IsNotEmpty(IEnumerable collection) { Assert.That(collection, Is.Not.Empty, null, null); } #endregion #region IsNullOrEmpty /// /// Assert that a string is either null or equal to string.Empty /// /// The string to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNullOrEmpty(string aString, string message, params object[] args) { Assert.That(aString, new NullOrEmptyStringConstraint(), message, args); } /// /// Assert that a string is either null or equal to string.Empty /// /// The string to be tested /// The message to display in case of failure public static void IsNullOrEmpty(string aString, string message) { Assert.That(aString, new NullOrEmptyStringConstraint(), message, null); } /// /// Assert that a string is either null or equal to string.Empty /// /// The string to be tested public static void IsNullOrEmpty(string aString) { Assert.That(aString, new NullOrEmptyStringConstraint(), null, null); } #endregion #region IsNotNullOrEmpty /// /// Assert that a string is not null or empty /// /// The string to be tested /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotNullOrEmpty(string aString, string message, params object[] args) { Assert.That(aString, new NotConstraint(new NullOrEmptyStringConstraint()), message, args); } /// /// Assert that a string is not null or empty /// /// The string to be tested /// The message to display in case of failure public static void IsNotNullOrEmpty(string aString, string message) { Assert.That(aString, new NotConstraint(new NullOrEmptyStringConstraint()), message, null); } /// /// Assert that a string is not null or empty /// /// The string to be tested public static void IsNotNullOrEmpty(string aString) { Assert.That(aString, new NotConstraint(new NullOrEmptyStringConstraint()), null, null); } #endregion #region IsAssignableFrom /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsAssignableFrom(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.AssignableFrom(expected), message, args); } /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure public static void IsAssignableFrom(Type expected, object actual, string message) { Assert.That(actual, Is.AssignableFrom(expected), message, null); } /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination public static void IsAssignableFrom(Type expected, object actual) { Assert.That(actual, Is.AssignableFrom(expected), null, null); } #endregion #region IsAssignableFrom #if CLR_2_0 || CLR_4_0 /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsAssignableFrom(object actual, string message, params object[] args) { Assert.That(actual, Is.AssignableFrom(typeof(T)), message, args); } /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure public static void IsAssignableFrom(object actual, string message) { Assert.That(actual, Is.AssignableFrom(typeof(T)), message, null); } /// /// Asserts that an object may be assigned a value of a given Type. /// /// The expected Type. /// The object under examination public static void IsAssignableFrom(object actual) { Assert.That(actual, Is.AssignableFrom(typeof(T)), null, null); } #endif #endregion #region IsNotAssignableFrom /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotAssignableFrom(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.Not.AssignableFrom(expected), message, args); } /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure public static void IsNotAssignableFrom(Type expected, object actual, string message) { Assert.That(actual, Is.Not.AssignableFrom(expected), message, null); } /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination public static void IsNotAssignableFrom(Type expected, object actual) { Assert.That(actual, Is.Not.AssignableFrom(expected), null, null); } #endregion #region IsNotAssignableFrom #if CLR_2_0 || CLR_4_0 /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotAssignableFrom(object actual, string message, params object[] args) { Assert.That(actual, Is.Not.AssignableFrom(typeof(T)), message, args); } /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination /// The message to display in case of failure public static void IsNotAssignableFrom(object actual, string message) { Assert.That(actual, Is.Not.AssignableFrom(typeof(T)), message, null); } /// /// Asserts that an object may not be assigned a value of a given Type. /// /// The expected Type. /// The object under examination public static void IsNotAssignableFrom(object actual) { Assert.That(actual, Is.Not.AssignableFrom(typeof(T)), null, null); } #endif #endregion #region IsInstanceOf /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsInstanceOf(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.InstanceOf(expected), message, args); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure public static void IsInstanceOf(Type expected, object actual, string message) { Assert.That(actual, Is.InstanceOf(expected), message, null); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined public static void IsInstanceOf(Type expected, object actual) { Assert.That(actual, Is.InstanceOf(expected), null, null); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message [Obsolete] public static void IsInstanceOfType(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.InstanceOf(expected), message, args); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure [Obsolete] public static void IsInstanceOfType(Type expected, object actual, string message) { Assert.That(actual, Is.InstanceOf(expected), message, null); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined [Obsolete] public static void IsInstanceOfType(Type expected, object actual) { Assert.That(actual, Is.InstanceOf(expected), null, null); } #endregion #region IsInstanceOf #if CLR_2_0 || CLR_4_0 /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsInstanceOf(object actual, string message, params object[] args) { Assert.That(actual, Is.InstanceOf(typeof(T)), message, args); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure public static void IsInstanceOf(object actual, string message) { Assert.That(actual, Is.InstanceOf(typeof(T)), message, null); } /// /// Asserts that an object is an instance of a given type. /// /// The expected Type /// The object being examined public static void IsInstanceOf(object actual) { Assert.That(actual, Is.InstanceOf(typeof(T)), null, null); } #endif #endregion #region IsNotInstanceOf /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotInstanceOf(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.Not.InstanceOf(expected), message, args); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure public static void IsNotInstanceOf(Type expected, object actual, string message) { Assert.That(actual, Is.Not.InstanceOf(expected), message, null); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined public static void IsNotInstanceOf(Type expected, object actual) { Assert.That(actual, Is.Not.InstanceOf(expected), null, null); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message [Obsolete] public static void IsNotInstanceOfType(Type expected, object actual, string message, params object[] args) { Assert.That(actual, Is.Not.InstanceOf(expected), message, args); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure [Obsolete] public static void IsNotInstanceOfType(Type expected, object actual, string message) { Assert.That(actual, Is.Not.InstanceOf(expected), message, null); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined [Obsolete] public static void IsNotInstanceOfType(Type expected, object actual) { Assert.That(actual, Is.Not.InstanceOf(expected), null, null); } #endregion #region IsNotInstanceOf #if CLR_2_0 || CLR_4_0 /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void IsNotInstanceOf(object actual, string message, params object[] args) { Assert.That(actual, Is.Not.InstanceOf(typeof(T)), message, args); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined /// The message to display in case of failure public static void IsNotInstanceOf(object actual, string message) { Assert.That(actual, Is.Not.InstanceOf(typeof(T)), message, null); } /// /// Asserts that an object is not an instance of a given type. /// /// The expected Type /// The object being examined public static void IsNotInstanceOf(object actual) { Assert.That(actual, Is.Not.InstanceOf(typeof(T)), null, null); } #endif #endregion #region AreEqual /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(int expected, int actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreEqual(int expected, int actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value public static void AreEqual(int expected, int actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(long expected, long actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreEqual(long expected, long actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value public static void AreEqual(long expected, long actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void AreEqual(uint expected, uint actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure [CLSCompliant(false)] public static void AreEqual(uint expected, uint actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value [CLSCompliant(false)] public static void AreEqual(uint expected, uint actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void AreEqual(ulong expected, ulong actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure [CLSCompliant(false)] public static void AreEqual(ulong expected, ulong actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value [CLSCompliant(false)] public static void AreEqual(ulong expected, ulong actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(decimal expected, decimal actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreEqual(decimal expected, decimal actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two values are equal. If they are not, then an /// is thrown. /// /// The expected value /// The actual value public static void AreEqual(decimal expected, decimal actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } #endregion #region AreEqual /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(double expected, double actual, double delta, string message, params object[] args) { AssertDoublesAreEqual(expected, actual, delta, message, args); } /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual /// The message to display in case of failure public static void AreEqual(double expected, double actual, double delta, string message) { AssertDoublesAreEqual(expected, actual, delta, message, null); } /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual public static void AreEqual(double expected, double actual, double delta) { AssertDoublesAreEqual(expected, actual, delta, null, null); } #if CLR_2_0 || CLR_4_0 /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(double expected, double? actual, double delta, string message, params object[] args) { AssertDoublesAreEqual(expected, (double)actual, delta, message, args); } /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual /// The message to display in case of failure public static void AreEqual(double expected, double? actual, double delta, string message) { AssertDoublesAreEqual(expected, (double)actual, delta, message, null); } /// /// Verifies that two doubles are equal considering a delta. If the /// expected value is infinity then the delta value is ignored. If /// they are not equal then an is /// thrown. /// /// The expected value /// The actual value /// The maximum acceptable difference between the /// the expected and the actual public static void AreEqual(double expected, double? actual, double delta) { AssertDoublesAreEqual(expected, (double)actual, delta, null, null); } #endif #endregion #region AreEqual /// /// Verifies that two objects are equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are not equal an is thrown. /// /// The value that is expected /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreEqual(object expected, object actual, string message, params object[] args) { Assert.That(actual, Is.EqualTo(expected), message, args); } /// /// Verifies that two objects are equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are not equal an is thrown. /// /// The value that is expected /// The actual value /// The message to display in case of failure public static void AreEqual(object expected, object actual, string message) { Assert.That(actual, Is.EqualTo(expected), message, null); } /// /// Verifies that two objects are equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are not equal an is thrown. /// /// The value that is expected /// The actual value public static void AreEqual(object expected, object actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } #endregion #region AreNotEqual /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(int expected, int actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreNotEqual(int expected, int actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value public static void AreNotEqual(int expected, int actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(long expected, long actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreNotEqual(long expected, long actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value public static void AreNotEqual(long expected, long actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void AreNotEqual(uint expected, uint actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure [CLSCompliant(false)] public static void AreNotEqual(uint expected, uint actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value [CLSCompliant(false)] public static void AreNotEqual(uint expected, uint actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void AreNotEqual(ulong expected, ulong actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure [CLSCompliant(false)] public static void AreNotEqual(ulong expected, ulong actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value [CLSCompliant(false)] public static void AreNotEqual(ulong expected, ulong actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(decimal expected, decimal actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreNotEqual(decimal expected, decimal actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value public static void AreNotEqual(decimal expected, decimal actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(float expected, float actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreNotEqual(float expected, float actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value public static void AreNotEqual(float expected, float actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(double expected, double actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value /// The message to display in case of failure public static void AreNotEqual(double expected, double actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two values are not equal. If they are equal, then an /// is thrown. /// /// The expected value /// The actual value public static void AreNotEqual(double expected, double actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } #endregion #region AreNotEqual /// /// Verifies that two objects are not equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are equal an is thrown. /// /// The value that is expected /// The actual value /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotEqual(object expected, object actual, string message, params object[] args) { Assert.That(actual, Is.Not.EqualTo(expected), message, args); } /// /// Verifies that two objects are not equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are equal an is thrown. /// /// The value that is expected /// The actual value /// The message to display in case of failure public static void AreNotEqual(object expected, object actual, string message) { Assert.That(actual, Is.Not.EqualTo(expected), message, null); } /// /// Verifies that two objects are not equal. Two objects are considered /// equal if both are null, or if both have the same value. NUnit /// has special semantics for some object types. /// If they are equal an is thrown. /// /// The value that is expected /// The actual value public static void AreNotEqual(object expected, object actual) { Assert.That(actual, Is.Not.EqualTo(expected), null, null); } #endregion #region AreSame /// /// Asserts that two objects refer to the same object. If they /// are not the same an is thrown. /// /// The expected object /// The actual object /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreSame(object expected, object actual, string message, params object[] args) { Assert.That(actual, Is.SameAs(expected), message, args); } /// /// Asserts that two objects refer to the same object. If they /// are not the same an is thrown. /// /// The expected object /// The actual object /// The message to display in case of failure public static void AreSame(object expected, object actual, string message) { Assert.That(actual, Is.SameAs(expected), message, null); } /// /// Asserts that two objects refer to the same object. If they /// are not the same an is thrown. /// /// The expected object /// The actual object public static void AreSame(object expected, object actual) { Assert.That(actual, Is.SameAs(expected), null, null); } #endregion #region AreNotSame /// /// Asserts that two objects do not refer to the same object. If they /// are the same an is thrown. /// /// The expected object /// The actual object /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void AreNotSame(object expected, object actual, string message, params object[] args) { Assert.That(actual, Is.Not.SameAs(expected), message, args); } /// /// Asserts that two objects do not refer to the same object. If they /// are the same an is thrown. /// /// The expected object /// The actual object /// The message to display in case of failure public static void AreNotSame(object expected, object actual, string message) { Assert.That(actual, Is.Not.SameAs(expected), message, null); } /// /// Asserts that two objects do not refer to the same object. If they /// are the same an is thrown. /// /// The expected object /// The actual object public static void AreNotSame(object expected, object actual) { Assert.That(actual, Is.Not.SameAs(expected), null, null); } #endregion #region Greater /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(int arg1, int arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(int arg1, int arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(int arg1, int arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void Greater(uint arg1, uint arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure [CLSCompliant(false)] public static void Greater(uint arg1, uint arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less [CLSCompliant(false)] public static void Greater(uint arg1, uint arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(long arg1, long arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(long arg1, long arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(long arg1, long arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void Greater(ulong arg1, ulong arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure [CLSCompliant(false)] public static void Greater(ulong arg1, ulong arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less [CLSCompliant(false)] public static void Greater(ulong arg1, ulong arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(decimal arg1, decimal arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(decimal arg1, decimal arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(decimal arg1, decimal arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(double arg1, double arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(double arg1, double arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(double arg1, double arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(float arg1, float arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(float arg1, float arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(float arg1, float arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Greater(IComparable arg1, IComparable arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThan(arg2), message, args); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void Greater(IComparable arg1, IComparable arg2, string message) { Assert.That(arg1, Is.GreaterThan(arg2), message, null); } /// /// Verifies that the first value is greater than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void Greater(IComparable arg1, IComparable arg2) { Assert.That(arg1, Is.GreaterThan(arg2), null, null); } #endregion #region Less /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(int arg1, int arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(int arg1, int arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(int arg1, int arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void Less(uint arg1, uint arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure [CLSCompliant(false)] public static void Less(uint arg1, uint arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater [CLSCompliant(false)] public static void Less(uint arg1, uint arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(long arg1, long arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(long arg1, long arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(long arg1, long arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void Less(ulong arg1, ulong arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure [CLSCompliant(false)] public static void Less(ulong arg1, ulong arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater [CLSCompliant(false)] public static void Less(ulong arg1, ulong arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(decimal arg1, decimal arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(decimal arg1, decimal arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(decimal arg1, decimal arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(double arg1, double arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(double arg1, double arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(double arg1, double arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(float arg1, float arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(float arg1, float arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(float arg1, float arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Less(IComparable arg1, IComparable arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThan(arg2), message, args); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void Less(IComparable arg1, IComparable arg2, string message) { Assert.That(arg1, Is.LessThan(arg2), message, null); } /// /// Verifies that the first value is less than the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void Less(IComparable arg1, IComparable arg2) { Assert.That(arg1, Is.LessThan(arg2), null, null); } #endregion #region GreaterOrEqual /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(int arg1, int arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(int arg1, int arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(int arg1, int arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void GreaterOrEqual(uint arg1, uint arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure [CLSCompliant(false)] public static void GreaterOrEqual(uint arg1, uint arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less [CLSCompliant(false)] public static void GreaterOrEqual(uint arg1, uint arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(long arg1, long arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(long arg1, long arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(long arg1, long arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void GreaterOrEqual(ulong arg1, ulong arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure [CLSCompliant(false)] public static void GreaterOrEqual(ulong arg1, ulong arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less [CLSCompliant(false)] public static void GreaterOrEqual(ulong arg1, ulong arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(decimal arg1, decimal arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(decimal arg1, decimal arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(decimal arg1, decimal arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(double arg1, double arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(double arg1, double arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(double arg1, double arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(float arg1, float arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(float arg1, float arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(float arg1, float arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void GreaterOrEqual(IComparable arg1, IComparable arg2, string message, params object[] args) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less /// The message to display in case of failure public static void GreaterOrEqual(IComparable arg1, IComparable arg2, string message) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is greater than or equal tothe second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be greater /// The second value, expected to be less public static void GreaterOrEqual(IComparable arg1, IComparable arg2) { Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), null, null); } #endregion #region LessOrEqual /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(int arg1, int arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(int arg1, int arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(int arg1, int arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void LessOrEqual(uint arg1, uint arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure [CLSCompliant(false)] public static void LessOrEqual(uint arg1, uint arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater [CLSCompliant(false)] public static void LessOrEqual(uint arg1, uint arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(long arg1, long arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(long arg1, long arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(long arg1, long arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message [CLSCompliant(false)] public static void LessOrEqual(ulong arg1, ulong arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure [CLSCompliant(false)] public static void LessOrEqual(ulong arg1, ulong arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater [CLSCompliant(false)] public static void LessOrEqual(ulong arg1, ulong arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(decimal arg1, decimal arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(decimal arg1, decimal arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(decimal arg1, decimal arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(double arg1, double arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(double arg1, double arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(double arg1, double arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(float arg1, float arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(float arg1, float arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(float arg1, float arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void LessOrEqual(IComparable arg1, IComparable arg2, string message, params object[] args) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater /// The message to display in case of failure public static void LessOrEqual(IComparable arg1, IComparable arg2, string message) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, null); } /// /// Verifies that the first value is less than or equal to the second /// value. If it is not, then an /// is thrown. /// /// The first value, expected to be less /// The second value, expected to be greater public static void LessOrEqual(IComparable arg1, IComparable arg2) { Assert.That(arg1, Is.LessThanOrEqualTo(arg2), null, null); } #endregion #region Contains /// /// Asserts that an object is contained in a list. /// /// The expected object /// The list to be examined /// The message to display in case of failure /// Array of objects to be used in formatting the message public static void Contains(object expected, ICollection actual, string message, params object[] args) { Assert.That(actual, new CollectionContainsConstraint(expected), message, args); } /// /// Asserts that an object is contained in a list. /// /// The expected object /// The list to be examined /// The message to display in case of failure public static void Contains(object expected, ICollection actual, string message) { Assert.That(actual, new CollectionContainsConstraint(expected), message, null); } /// /// Asserts that an object is contained in a list. /// /// The expected object /// The list to be examined public static void Contains(object expected, ICollection actual) { Assert.That(actual, new CollectionContainsConstraint(expected), null, null); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/TestState.cs0000664000175000017500000000247411504175260023135 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// The ResultState enum indicates the result of running a test /// public enum TestState { /// /// The result is inconclusive /// Inconclusive = 0, /// /// The test was not runnable. /// NotRunnable = 1, /// /// The test has been skipped. /// Skipped = 2, /// /// The test has been ignored. /// Ignored = 3, /// /// The test succeeded /// Success = 4, /// /// The test failed /// Failure = 5, /// /// The test encountered an unexpected exception /// Error = 6, /// /// The test was cancelled by the user /// Cancelled =7 } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Is.cs0000664000175000017500000003661411672602234021575 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Helper class with properties and methods that supply /// a number of constraints used in Asserts. /// public class Is { #region Not /// /// Returns a ConstraintExpression that negates any /// following constraint. /// public static ConstraintExpression Not { get { return new ConstraintExpression().Not; } } #endregion #region All /// /// Returns a ConstraintExpression, which will apply /// the following constraint to all members of a collection, /// succeeding if all of them succeed. /// public static ConstraintExpression All { get { return new ConstraintExpression().All; } } #endregion #region Null /// /// Returns a constraint that tests for null /// public static NullConstraint Null { get { return new NullConstraint(); } } #endregion #region True /// /// Returns a constraint that tests for True /// public static TrueConstraint True { get { return new TrueConstraint(); } } #endregion #region False /// /// Returns a constraint that tests for False /// public static FalseConstraint False { get { return new FalseConstraint(); } } #endregion #region Positive /// /// Returns a constraint that tests for a positive value /// public static GreaterThanConstraint Positive { get { return new GreaterThanConstraint(0); } } #endregion #region Negative /// /// Returns a constraint that tests for a negative value /// public static LessThanConstraint Negative { get { return new LessThanConstraint(0); } } #endregion #region NaN /// /// Returns a constraint that tests for NaN /// public static NaNConstraint NaN { get { return new NaNConstraint(); } } #endregion #region Empty /// /// Returns a constraint that tests for empty /// public static EmptyConstraint Empty { get { return new EmptyConstraint(); } } #endregion #region Unique /// /// Returns a constraint that tests whether a collection /// contains all unique items. /// public static UniqueItemsConstraint Unique { get { return new UniqueItemsConstraint(); } } #endregion #region BinarySerializable /// /// Returns a constraint that tests whether an object graph is serializable in binary format. /// public static BinarySerializableConstraint BinarySerializable { get { return new BinarySerializableConstraint(); } } #endregion #region XmlSerializable /// /// Returns a constraint that tests whether an object graph is serializable in xml format. /// public static XmlSerializableConstraint XmlSerializable { get { return new XmlSerializableConstraint(); } } #endregion #region EqualTo /// /// Returns a constraint that tests two items for equality /// public static EqualConstraint EqualTo(object expected) { return new EqualConstraint(expected); } #endregion #region SameAs /// /// Returns a constraint that tests that two references are the same object /// public static SameAsConstraint SameAs(object expected) { return new SameAsConstraint(expected); } #endregion #region GreaterThan /// /// Returns a constraint that tests whether the /// actual value is greater than the suppled argument /// public static GreaterThanConstraint GreaterThan(object expected) { return new GreaterThanConstraint(expected); } #endregion #region GreaterThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public static GreaterThanOrEqualConstraint GreaterThanOrEqualTo(object expected) { return new GreaterThanOrEqualConstraint(expected); } /// /// Returns a constraint that tests whether the /// actual value is greater than or equal to the suppled argument /// public static GreaterThanOrEqualConstraint AtLeast(object expected) { return new GreaterThanOrEqualConstraint(expected); } #endregion #region LessThan /// /// Returns a constraint that tests whether the /// actual value is less than the suppled argument /// public static LessThanConstraint LessThan(object expected) { return new LessThanConstraint(expected); } #endregion #region LessThanOrEqualTo /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public static LessThanOrEqualConstraint LessThanOrEqualTo(object expected) { return new LessThanOrEqualConstraint(expected); } /// /// Returns a constraint that tests whether the /// actual value is less than or equal to the suppled argument /// public static LessThanOrEqualConstraint AtMost(object expected) { return new LessThanOrEqualConstraint(expected); } #endregion #region TypeOf /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public static ExactTypeConstraint TypeOf(Type expectedType) { return new ExactTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual /// value is of the exact type supplied as an argument. /// public static ExactTypeConstraint TypeOf() { return new ExactTypeConstraint(typeof(T)); } #endif #endregion #region InstanceOf /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public static InstanceOfTypeConstraint InstanceOf(Type expectedType) { return new InstanceOfTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// public static InstanceOfTypeConstraint InstanceOf() { return new InstanceOfTypeConstraint(typeof(T)); } #endif /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf(expectedType)")] public static InstanceOfTypeConstraint InstanceOfType(Type expectedType) { return new InstanceOfTypeConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is of the type supplied as an argument or a derived type. /// [Obsolete("Use InstanceOf()")] public static InstanceOfTypeConstraint InstanceOfType() { return new InstanceOfTypeConstraint(typeof(T)); } #endif #endregion #region AssignableFrom /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public static AssignableFromConstraint AssignableFrom(Type expectedType) { return new AssignableFromConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public static AssignableFromConstraint AssignableFrom() { return new AssignableFromConstraint(typeof(T)); } #endif #endregion #region AssignableTo /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public static AssignableToConstraint AssignableTo(Type expectedType) { return new AssignableToConstraint(expectedType); } #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value /// is assignable from the type supplied as an argument. /// public static AssignableToConstraint AssignableTo() { return new AssignableToConstraint(typeof(T)); } #endif #endregion #region EquivalentTo /// /// Returns a constraint that tests whether the actual value /// is a collection containing the same elements as the /// collection supplied as an argument. /// public static CollectionEquivalentConstraint EquivalentTo(IEnumerable expected) { return new CollectionEquivalentConstraint(expected); } #endregion #region SubsetOf /// /// Returns a constraint that tests whether the actual value /// is a subset of the collection supplied as an argument. /// public static CollectionSubsetConstraint SubsetOf(IEnumerable expected) { return new CollectionSubsetConstraint(expected); } #endregion #region Ordered /// /// Returns a constraint that tests whether a collection is ordered /// public static CollectionOrderedConstraint Ordered { get { return new CollectionOrderedConstraint(); } } #endregion #region StringContaining /// /// Returns a constraint that succeeds if the actual /// value contains the substring supplied as an argument. /// public static SubstringConstraint StringContaining(string expected) { return new SubstringConstraint(expected); } #endregion #region StringStarting /// /// Returns a constraint that succeeds if the actual /// value starts with the substring supplied as an argument. /// public static StartsWithConstraint StringStarting(string expected) { return new StartsWithConstraint(expected); } #endregion #region StringEnding /// /// Returns a constraint that succeeds if the actual /// value ends with the substring supplied as an argument. /// public static EndsWithConstraint StringEnding(string expected) { return new EndsWithConstraint(expected); } #endregion #region StringMatching /// /// Returns a constraint that succeeds if the actual /// value matches the Regex pattern supplied as an argument. /// public static RegexConstraint StringMatching(string pattern) { return new RegexConstraint(pattern); } #endregion #region SamePath /// /// Returns a constraint that tests whether the path provided /// is the same as an expected path after canonicalization. /// public static SamePathConstraint SamePath(string expected) { return new SamePathConstraint(expected); } #endregion #region SubPath /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public static SubPathConstraint SubPath(string expected) { return new SubPathConstraint(expected); } #endregion #region SamePathOrUnder /// /// Returns a constraint that tests whether the path provided /// is the same path or under an expected path after canonicalization. /// public static SamePathOrUnderConstraint SamePathOrUnder(string expected) { return new SamePathOrUnderConstraint(expected); } #endregion #region InRange #if !CLR_2_0 && !CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public static RangeConstraint InRange(IComparable from, IComparable to) { return new RangeConstraint(from, to); } #endif #endregion #region InRange #if CLR_2_0 || CLR_4_0 /// /// Returns a constraint that tests whether the actual value falls /// within a specified range. /// public static RangeConstraint InRange(T from, T to) where T : IComparable { return new RangeConstraint(from, to); } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/GlobalSettings.cs0000664000175000017500000000124411504175260024130 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Framework { /// /// GlobalSettings is a place for setting default values used /// by the framework in performing asserts. /// public class GlobalSettings { /// /// Default tolerance for floating point equality /// public static double DefaultFloatingPointTolerance = 0.0d; } } NUnit-2.6.0.12051/src/NUnitFramework/framework/List.cs0000664000175000017500000000164011504175260022122 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// The List class is a helper class with properties and methods /// that supply a number of constraints used with lists and collections. /// public class List { /// /// List.Map returns a ListMapper, which can be used to map /// the original collection to another collection. /// /// /// public static ListMapper Map( ICollection actual ) { return new ListMapper( actual ); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/StringAssert.cs0000664000175000017500000004242511504175260023645 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Basic Asserts on strings. /// public class StringAssert { #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region Contains /// /// Asserts that a string is found within another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void Contains(string expected, string actual, string message, params object[] args) { Assert.That(actual, new SubstringConstraint(expected), message, args); } /// /// Asserts that a string is found within another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void Contains(string expected, string actual, string message) { Contains(expected, actual, message, null); } /// /// Asserts that a string is found within another string. /// /// The expected string /// The string to be examined static public void Contains(string expected, string actual) { Contains(expected, actual, string.Empty, null); } #endregion #region DoesNotContain /// /// Asserts that a string is not found within another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void DoesNotContain(string expected, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint( new SubstringConstraint(expected) ), message, args ); } /// /// Asserts that a string is found within another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void DoesNotContain(string expected, string actual, string message) { DoesNotContain(expected, actual, message, null); } /// /// Asserts that a string is found within another string. /// /// The expected string /// The string to be examined static public void DoesNotContain(string expected, string actual) { DoesNotContain(expected, actual, string.Empty, null); } #endregion #region StartsWith /// /// Asserts that a string starts with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void StartsWith(string expected, string actual, string message, params object[] args) { Assert.That(actual, new StartsWithConstraint(expected), message, args); } /// /// Asserts that a string starts with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void StartsWith(string expected, string actual, string message) { StartsWith(expected, actual, message, null); } /// /// Asserts that a string starts with another string. /// /// The expected string /// The string to be examined static public void StartsWith(string expected, string actual) { StartsWith(expected, actual, string.Empty, null); } #endregion #region DoesNotStartWith /// /// Asserts that a string does not start with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void DoesNotStartWith(string expected, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint( new StartsWithConstraint(expected) ), message, args); } /// /// Asserts that a string does not start with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void DoesNotStartWith(string expected, string actual, string message) { DoesNotStartWith(expected, actual, message, null); } /// /// Asserts that a string does not start with another string. /// /// The expected string /// The string to be examined static public void DoesNotStartWith(string expected, string actual) { DoesNotStartWith(expected, actual, string.Empty, null); } #endregion #region EndsWith /// /// Asserts that a string ends with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void EndsWith(string expected, string actual, string message, params object[] args) { Assert.That(actual, new EndsWithConstraint(expected), message, args); } /// /// Asserts that a string ends with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void EndsWith(string expected, string actual, string message) { EndsWith(expected, actual, message, null); } /// /// Asserts that a string ends with another string. /// /// The expected string /// The string to be examined static public void EndsWith(string expected, string actual) { EndsWith(expected, actual, string.Empty, null); } #endregion #region DoesNotEndWith /// /// Asserts that a string does not end with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure /// Arguments used in formatting the message static public void DoesNotEndWith(string expected, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint( new EndsWithConstraint(expected) ), message, args); } /// /// Asserts that a string does not end with another string. /// /// The expected string /// The string to be examined /// The message to display in case of failure static public void DoesNotEndWith(string expected, string actual, string message) { DoesNotEndWith(expected, actual, message, null); } /// /// Asserts that a string does not end with another string. /// /// The expected string /// The string to be examined static public void DoesNotEndWith(string expected, string actual) { DoesNotEndWith(expected, actual, string.Empty, null); } #endregion #region AreEqualIgnoringCase /// /// Asserts that two strings are equal, without regard to case. /// /// The expected string /// The actual string /// The message to display in case of failure /// Arguments used in formatting the message static public void AreEqualIgnoringCase(string expected, string actual, string message, params object[] args) { Assert.That(actual, new EqualConstraint(expected).IgnoreCase, message, args); } /// /// Asserts that two strings are equal, without regard to case. /// /// The expected string /// The actual string /// The message to display in case of failure static public void AreEqualIgnoringCase(string expected, string actual, string message) { AreEqualIgnoringCase(expected, actual, message, null); } /// /// Asserts that two strings are equal, without regard to case. /// /// The expected string /// The actual string static public void AreEqualIgnoringCase(string expected, string actual) { AreEqualIgnoringCase(expected, actual, string.Empty, null); } #endregion #region AreNotEqualIgnoringCase /// /// Asserts that two strings are not equal, without regard to case. /// /// The expected string /// The actual string /// The message to display in case of failure /// Arguments used in formatting the message static public void AreNotEqualIgnoringCase(string expected, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint( new EqualConstraint(expected).IgnoreCase ), message, args); } /// /// Asserts that two strings are Notequal, without regard to case. /// /// The expected string /// The actual string /// The message to display in case of failure static public void AreNotEqualIgnoringCase(string expected, string actual, string message) { AreNotEqualIgnoringCase(expected, actual, message, null); } /// /// Asserts that two strings are not equal, without regard to case. /// /// The expected string /// The actual string static public void AreNotEqualIgnoringCase(string expected, string actual) { AreNotEqualIgnoringCase(expected, actual, string.Empty, null); } #endregion #region IsMatch /// /// Asserts that a string matches an expected regular expression pattern. /// /// The regex pattern to be matched /// The actual string /// The message to display in case of failure /// Arguments used in formatting the message static public void IsMatch(string pattern, string actual, string message, params object[] args) { Assert.That(actual, new RegexConstraint(pattern), message, args); } /// /// Asserts that a string matches an expected regular expression pattern. /// /// The regex pattern to be matched /// The actual string /// The message to display in case of failure static public void IsMatch(string pattern, string actual, string message) { IsMatch(pattern, actual, message, null); } /// /// Asserts that a string matches an expected regular expression pattern. /// /// The regex pattern to be matched /// The actual string static public void IsMatch(string pattern, string actual) { IsMatch(pattern, actual, string.Empty, null); } #endregion #region DoesNotMatch /// /// Asserts that a string does not match an expected regular expression pattern. /// /// The regex pattern to be used /// The actual string /// The message to display in case of failure /// Arguments used in formatting the message static public void DoesNotMatch(string pattern, string actual, string message, params object[] args) { Assert.That(actual, new NotConstraint( new RegexConstraint(pattern) ), message, args); } /// /// Asserts that a string does not match an expected regular expression pattern. /// /// The regex pattern to be used /// The actual string /// The message to display in case of failure static public void DoesNotMatch(string pattern, string actual, string message) { DoesNotMatch(pattern, actual, message, null); } /// /// Asserts that a string does not match an expected regular expression pattern. /// /// The regex pattern to be used /// The actual string static public void DoesNotMatch(string pattern, string actual) { DoesNotMatch(pattern, actual, string.Empty, null); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/TestStatus.cs0000664000175000017500000000160311720453714023334 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Framework { /// /// The TestStatus enum indicates the result of running a test /// public enum TestStatus { /// /// The test was inconclusive /// Inconclusive = 0, /// /// The test has skipped /// Skipped = 1, /// /// The test succeeded /// Passed = 2, /// /// The test failed /// Failed = 3 } } NUnit-2.6.0.12051/src/NUnitFramework/framework/FileAssert.cs0000664000175000017500000003174211504175260023256 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.ComponentModel; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Summary description for FileAssert. /// public class FileAssert { #region Equals and ReferenceEquals /// /// The Equals method throws an AssertionException. This is done /// to make sure there is no mistake by calling this function. /// /// /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object a, object b) { throw new AssertionException("Assert.Equals should not be used for Assertions"); } /// /// override the default ReferenceEquals to throw an AssertionException. This /// implementation makes sure there is no mistake in calling this function /// as part of Assert. /// /// /// public static new void ReferenceEquals(object a, object b) { throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions"); } #endregion #region Constructor /// /// We don't actually want any instances of this object, but some people /// like to inherit from it to add other static methods. Hence, the /// protected constructor disallows any instances of this object. /// protected FileAssert() {} #endregion #region AreEqual #region Streams /// /// Verifies that two Streams are equal. Two Streams are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The expected Stream /// The actual Stream /// The message to display if Streams are not equal /// Arguments to be used in formatting the message static public void AreEqual(Stream expected, Stream actual, string message, params object[] args) { Assert.That( actual, new EqualConstraint( expected ), message, args ); } /// /// Verifies that two Streams are equal. Two Streams are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The expected Stream /// The actual Stream /// The message to display if objects are not equal static public void AreEqual(Stream expected, Stream actual, string message) { AreEqual(expected, actual, message, null); } /// /// Verifies that two Streams are equal. Two Streams are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The expected Stream /// The actual Stream static public void AreEqual(Stream expected, Stream actual) { AreEqual(expected, actual, string.Empty, null); } #endregion #region FileInfo /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value /// The message to display if Streams are not equal /// Arguments to be used in formatting the message static public void AreEqual(FileInfo expected, FileInfo actual, string message, params object[] args) { using (FileStream exStream = expected.OpenRead()) { using (FileStream acStream = actual.OpenRead()) { AreEqual(exStream,acStream,message,args); } } } /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value /// The message to display if objects are not equal static public void AreEqual(FileInfo expected, FileInfo actual, string message) { AreEqual(expected, actual, message, null); } /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value static public void AreEqual(FileInfo expected, FileInfo actual) { AreEqual(expected, actual, string.Empty, null); } #endregion #region String /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value /// The message to display if Streams are not equal /// Arguments to be used in formatting the message static public void AreEqual(string expected, string actual, string message, params object[] args) { using (FileStream exStream = File.OpenRead(expected)) { using (FileStream acStream = File.OpenRead(actual)) { AreEqual(exStream,acStream,message,args); } } } /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value /// The message to display if objects are not equal static public void AreEqual(string expected, string actual, string message) { AreEqual(expected, actual, message, null); } /// /// Verifies that two files are equal. Two files are considered /// equal if both are null, or if both have the same value byte for byte. /// If they are not equal an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value static public void AreEqual(string expected, string actual) { AreEqual(expected, actual, string.Empty, null); } #endregion #endregion #region AreNotEqual #region Streams /// /// Asserts that two Streams are not equal. If they are equal /// an is thrown. /// /// The expected Stream /// The actual Stream /// The message to be displayed when the two Stream are the same. /// Arguments to be used in formatting the message static public void AreNotEqual( Stream expected, Stream actual, string message, params object[] args) { Assert.That( actual, new NotConstraint( new EqualConstraint( expected ) ), message, args ); } /// /// Asserts that two Streams are not equal. If they are equal /// an is thrown. /// /// The expected Stream /// The actual Stream /// The message to be displayed when the Streams are the same. static public void AreNotEqual(Stream expected, Stream actual, string message) { AreNotEqual(expected, actual, message, null); } /// /// Asserts that two Streams are not equal. If they are equal /// an is thrown. /// /// The expected Stream /// The actual Stream static public void AreNotEqual(Stream expected, Stream actual) { AreNotEqual(expected, actual, string.Empty, null); } #endregion #region FileInfo /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value /// The message to display if Streams are not equal /// Arguments to be used in formatting the message static public void AreNotEqual(FileInfo expected, FileInfo actual, string message, params object[] args) { using (FileStream exStream = expected.OpenRead()) { using (FileStream acStream = actual.OpenRead()) { AreNotEqual(exStream,acStream,message,args); } } } /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value /// The message to display if objects are not equal static public void AreNotEqual(FileInfo expected, FileInfo actual, string message) { AreNotEqual(expected, actual, message, null); } /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// A file containing the value that is expected /// A file containing the actual value static public void AreNotEqual(FileInfo expected, FileInfo actual) { AreNotEqual(expected, actual, string.Empty, null); } #endregion #region String /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value /// The message to display if Streams are not equal /// Arguments to be used in formatting the message static public void AreNotEqual(string expected, string actual, string message, params object[] args) { using (FileStream exStream = File.OpenRead(expected)) { using (FileStream acStream = File.OpenRead(actual)) { AreNotEqual(exStream,acStream,message,args); } } } /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value /// The message to display if objects are not equal static public void AreNotEqual(string expected, string actual, string message) { AreNotEqual(expected, actual, message, null); } /// /// Asserts that two files are not equal. If they are equal /// an is thrown. /// /// The path to a file containing the value that is expected /// The path to a file containing the actual value static public void AreNotEqual(string expected, string actual) { AreNotEqual(expected, actual, string.Empty, null); } #endregion #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/TextMessageWriter.cs0000664000175000017500000003720511626705732024653 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Globalization; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// TextMessageWriter writes constraint descriptions and messages /// in displayable form as a text stream. It tailors the display /// of individual message components to form the standard message /// format of NUnit assertion failure messages. /// public class TextMessageWriter : MessageWriter { #region Message Formats and Constants private static readonly int DEFAULT_LINE_LENGTH = 78; // Prefixes used in all failure messages. All must be the same // length, which is held in the PrefixLength field. Should not // contain any tabs or newline characters. /// /// Prefix used for the expected value line of a message /// public static readonly string Pfx_Expected = " Expected: "; /// /// Prefix used for the actual value line of a message /// public static readonly string Pfx_Actual = " But was: "; /// /// Length of a message prefix /// public static readonly int PrefixLength = Pfx_Expected.Length; private static readonly string Fmt_Connector = " {0} "; private static readonly string Fmt_Predicate = "{0} "; //private static readonly string Fmt_Label = "{0}"; private static readonly string Fmt_Modifier = ", {0}"; private static readonly string Fmt_Null = "null"; private static readonly string Fmt_EmptyString = ""; private static readonly string Fmt_EmptyCollection = ""; private static readonly string Fmt_String = "\"{0}\""; private static readonly string Fmt_Char = "'{0}'"; private static readonly string Fmt_DateTime = "yyyy-MM-dd HH:mm:ss.fff"; private static readonly string Fmt_ValueType = "{0}"; private static readonly string Fmt_Default = "<{0}>"; #endregion private int maxLineLength = DEFAULT_LINE_LENGTH; #region Constructors /// /// Construct a TextMessageWriter /// public TextMessageWriter() { } /// /// Construct a TextMessageWriter, specifying a user message /// and optional formatting arguments. /// /// /// public TextMessageWriter(string userMessage, params object[] args) { if ( userMessage != null && userMessage != string.Empty) this.WriteMessageLine(userMessage, args); } #endregion #region Properties /// /// Gets or sets the maximum line length for this writer /// public override int MaxLineLength { get { return maxLineLength; } set { maxLineLength = value; } } #endregion #region Public Methods - High Level /// /// Method to write single line message with optional args, usually /// written to precede the general failure message, at a givel /// indentation level. /// /// The indentation level of the message /// The message to be written /// Any arguments used in formatting the message public override void WriteMessageLine(int level, string message, params object[] args) { if (message != null) { while (level-- >= 0) Write(" "); if (args != null && args.Length > 0) message = string.Format(message, args); WriteLine(message); } } /// /// Display Expected and Actual lines for a constraint. This /// is called by MessageWriter's default implementation of /// WriteMessageTo and provides the generic two-line display. /// /// The constraint that failed public override void DisplayDifferences(Constraint constraint) { WriteExpectedLine(constraint); WriteActualLine(constraint); } /// /// Display Expected and Actual lines for given values. This /// method may be called by constraints that need more control over /// the display of actual and expected values than is provided /// by the default implementation. /// /// The expected value /// The actual value causing the failure public override void DisplayDifferences(object expected, object actual) { WriteExpectedLine(expected); WriteActualLine(actual); } /// /// Display Expected and Actual lines for given values, including /// a tolerance value on the expected line. /// /// The expected value /// The actual value causing the failure /// The tolerance within which the test was made public override void DisplayDifferences(object expected, object actual, Tolerance tolerance) { WriteExpectedLine(expected, tolerance); WriteActualLine(actual); } /// /// Display the expected and actual string values on separate lines. /// If the mismatch parameter is >=0, an additional line is displayed /// line containing a caret that points to the mismatch point. /// /// The expected string value /// The actual string value /// The point at which the strings don't match or -1 /// If true, case is ignored in string comparisons /// If true, clip the strings to fit the max line length public override void DisplayStringDifferences(string expected, string actual, int mismatch, bool ignoreCase, bool clipping) { // Maximum string we can display without truncating int maxDisplayLength = MaxLineLength - PrefixLength // Allow for prefix - 2; // 2 quotation marks if ( clipping ) MsgUtils.ClipExpectedAndActual(ref expected, ref actual, maxDisplayLength, mismatch); expected = MsgUtils.EscapeControlChars(expected); actual = MsgUtils.EscapeControlChars(actual); // The mismatch position may have changed due to clipping or white space conversion mismatch = MsgUtils.FindMismatchPosition(expected, actual, 0, ignoreCase); Write( Pfx_Expected ); WriteExpectedValue( expected ); if ( ignoreCase ) WriteModifier( "ignoring case" ); WriteLine(); WriteActualLine( actual ); //DisplayDifferences(expected, actual); if (mismatch >= 0) WriteCaretLine(mismatch); } #endregion #region Public Methods - Low Level /// /// Writes the text for a connector. /// /// The connector. public override void WriteConnector(string connector) { Write(Fmt_Connector, connector); } /// /// Writes the text for a predicate. /// /// The predicate. public override void WritePredicate(string predicate) { Write(Fmt_Predicate, predicate); } //public override void WriteLabel(string label) //{ // Write(Fmt_Label, label); //} /// /// Write the text for a modifier. /// /// The modifier. public override void WriteModifier(string modifier) { Write(Fmt_Modifier, modifier); } /// /// Writes the text for an expected value. /// /// The expected value. public override void WriteExpectedValue(object expected) { WriteValue(expected); } /// /// Writes the text for an actual value. /// /// The actual value. public override void WriteActualValue(object actual) { WriteValue(actual); } /// /// Writes the text for a generalized value. /// /// The value. public override void WriteValue(object val) { if (val == null) Write(Fmt_Null); else if (val.GetType().IsArray) WriteArray((Array)val); else if (val is string) WriteString((string)val); else if (val is IEnumerable) WriteCollectionElements((IEnumerable)val, 0, 10); else if (val is char) WriteChar((char)val); else if (val is double) WriteDouble((double)val); else if (val is float) WriteFloat((float)val); else if (val is decimal) WriteDecimal((decimal)val); else if (val is DateTime) WriteDateTime((DateTime)val); else if (val.GetType().IsValueType) Write(Fmt_ValueType, val); else Write(Fmt_Default, val); } /// /// Writes the text for a collection value, /// starting at a particular point, to a max length /// /// The collection containing elements to write. /// The starting point of the elements to write /// The maximum number of elements to write public override void WriteCollectionElements(IEnumerable collection, int start, int max) { int count = 0; int index = 0; foreach (object obj in collection) { if ( index++ >= start) { if (++count > max) break; Write(count == 1 ? "< " : ", "); WriteValue(obj); } } if (count == 0) { Write(Fmt_EmptyCollection); return; } if (count > max) Write("..."); Write(" >"); } private void WriteArray(Array array) { if ( array.Length == 0 ) { Write( Fmt_EmptyCollection ); return; } int rank = array.Rank; int[] products = new int[rank]; for (int product = 1, r = rank; --r >= 0; ) products[r] = product *= array.GetLength(r); int count = 0; foreach (object obj in array) { if (count > 0) Write(", "); bool startSegment = false; for (int r = 0; r < rank; r++) { startSegment = startSegment || count % products[r] == 0; if (startSegment) Write("< "); } WriteValue(obj); ++count; bool nextSegment = false; for (int r = 0; r < rank; r++) { nextSegment = nextSegment || count % products[r] == 0; if (nextSegment) Write(" >"); } } } private void WriteString(string s) { if (s == string.Empty) Write(Fmt_EmptyString); else Write(Fmt_String, s); } private void WriteChar(char c) { Write(Fmt_Char, c); } private void WriteDouble(double d) { if (double.IsNaN(d) || double.IsInfinity(d)) Write(d); else { string s = d.ToString("G17", CultureInfo.InvariantCulture); if (s.IndexOf('.') > 0) Write(s + "d"); else Write(s + ".0d"); } } private void WriteFloat(float f) { if (float.IsNaN(f) || float.IsInfinity(f)) Write(f); else { string s = f.ToString("G9", CultureInfo.InvariantCulture); if (s.IndexOf('.') > 0) Write(s + "f"); else Write(s + ".0f"); } } private void WriteDecimal(Decimal d) { Write(d.ToString("G29", CultureInfo.InvariantCulture) + "m"); } private void WriteDateTime(DateTime dt) { Write(dt.ToString(Fmt_DateTime, CultureInfo.InvariantCulture)); } #endregion #region Helper Methods /// /// Write the generic 'Expected' line for a constraint /// /// The constraint that failed private void WriteExpectedLine(Constraint constraint) { Write(Pfx_Expected); constraint.WriteDescriptionTo(this); WriteLine(); } /// /// Write the generic 'Expected' line for a given value /// /// The expected value private void WriteExpectedLine(object expected) { WriteExpectedLine(expected, null); } /// /// Write the generic 'Expected' line for a given value /// and tolerance. /// /// The expected value /// The tolerance within which the test was made private void WriteExpectedLine(object expected, Tolerance tolerance) { Write(Pfx_Expected); WriteExpectedValue(expected); if (tolerance != null && !tolerance.IsEmpty) { WriteConnector("+/-"); WriteExpectedValue(tolerance.Value); if (tolerance.Mode != ToleranceMode.Linear) Write(" {0}", tolerance.Mode); } WriteLine(); } /// /// Write the generic 'Actual' line for a constraint /// /// The constraint for which the actual value is to be written private void WriteActualLine(Constraint constraint) { Write(Pfx_Actual); constraint.WriteActualValueTo(this); WriteLine(); } /// /// Write the generic 'Actual' line for a given value /// /// The actual value causing a failure private void WriteActualLine(object actual) { Write(Pfx_Actual); WriteActualValue(actual); WriteLine(); } private void WriteCaretLine(int mismatch) { // We subtract 2 for the initial 2 blanks and add back 1 for the initial quote WriteLine(" {0}^", new string('-', PrefixLength + mismatch - 2 + 1)); } #endregion } } NUnit-2.6.0.12051/src/NUnitFramework/framework/Contains.cs0000664000175000017500000000244611720454026022772 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework.Constraints; namespace NUnit.Framework { /// /// Static helper class used in the constraint-based syntax /// public class Contains { /// /// Creates a new SubstringConstraint /// /// The value of the substring /// A SubstringConstraint public static SubstringConstraint Substring(string substring) { return new SubstringConstraint(substring); } /// /// Creates a new CollectionContainsConstraint. /// /// The item that should be found. /// A new CollectionContainsConstraint public static CollectionContainsConstraint Item(object item) { return new CollectionContainsConstraint(item); } } } NUnit-2.6.0.12051/src/NUnitFramework/framework/TestDetails.cs0000664000175000017500000000427411720453736023451 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; using System.Reflection; using System.Text; namespace NUnit.Framework { /// /// Provides details about a test /// public class TestDetails { /// /// Creates an instance of TestDetails /// ///The fixture that the test is a member of, if available. ///The method that implements the test, if available. ///The full name of the test. ///A string representing the type of test, e.g. "Test Case". ///Indicates if the test represents a suite of tests. public TestDetails(object fixture, MethodInfo method, string fullName, string type, bool isSuite) { Fixture = fixture; Method = method; FullName = fullName; Type = type; IsSuite = isSuite; } /// /// The fixture that the test is a member of, if available. /// public object Fixture { get; private set; } /// /// The method that implements the test, if available. /// public MethodInfo Method { get; private set; } /// /// The full name of the test. /// public string FullName { get; private set; } /// /// A string representing the type of test, e.g. "Test Case". /// public string Type { get; private set; } /// /// Indicates if the test represents a suite of tests. /// public bool IsSuite { get; private set; } } } #endifNUnit-2.6.0.12051/src/NUnitFramework/framework/ActionTargets.cs0000664000175000017500000000164311712475522023766 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; namespace NUnit.Framework { /// /// The different targets a test action attribute can be applied to /// [Flags] public enum ActionTargets { /// /// Default target, which is determined by where the action attribute is attached /// Default = 0, /// /// Target a individual test case /// Test = 1, /// /// Target a suite of test cases /// Suite = 2 } } #endif NUnit-2.6.0.12051/src/NUnitFramework/framework/nunit.framework.build0000664000175000017500000001623011713171356025037 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiRunner/0000775000175000017500000000000011742560362015672 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiRunner/nunit-gui/0000775000175000017500000000000011742560362017611 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiRunner/nunit-gui/nunit-gui.build0000664000175000017500000000756611544347372022573 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/RecentFileMenuHandler.cs0000664000175000017500000000533311544330406024301 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Windows.Forms; using NUnit.Util; namespace NUnit.Gui { public class RecentFileMenuHandler { private MenuItem menu; private RecentFiles recentFiles; private bool checkFilesExist = true; private bool showNonRunnableFiles = false; public RecentFileMenuHandler( MenuItem menu, RecentFiles recentFiles ) { this.menu = menu; this.recentFiles = recentFiles; } public bool CheckFilesExist { get { return checkFilesExist; } set { checkFilesExist = value; } } public bool ShowNonRunnableFiles { get { return showNonRunnableFiles; } set { showNonRunnableFiles = value; } } public MenuItem Menu { get { return menu; } } public string this[int index] { get { return menu.MenuItems[index].Text.Substring( 2 ); } } public void Load() { if ( recentFiles.Count == 0 ) Menu.Enabled = false; else { Menu.Enabled = true; Menu.MenuItems.Clear(); int index = 1; foreach ( RecentFileEntry entry in recentFiles.Entries ) { // Rather than show files that don't exist, we skip them. As // new recent files are opened, they will be pushed down and // eventually fall off the list unless the file is re-created // and subsequently opened. if ( !checkFilesExist || entry.Exists ) { // NOTE: In the current version, all the files listed should // have a compatible version, since we are using separate // settings for V1 and V2. This code will be changed in // a future release to allow running under other runtimes. if ( showNonRunnableFiles || entry.IsCompatibleCLRVersion ) { MenuItem item = new MenuItem(String.Format("{0} {1}", index++, entry.Path)); item.Click += new System.EventHandler(OnRecentFileClick); Menu.MenuItems.Add(item); } } } } } private void OnRecentFileClick( object sender, EventArgs e ) { MenuItem item = (MenuItem) sender; string testFileName = item.Text.Substring( 2 ); // TODO: Figure out a better way NUnitForm form = item.GetMainMenu().GetForm() as NUnit.Gui.NUnitForm; if ( form != null) form.Presenter.OpenProject( testFileName ); } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/NUnitPresenter.cs0000664000175000017500000004356011626127226023074 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using System.IO; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; using NUnit.UiKit; namespace NUnit.Gui { /// /// NUnitPresenter does all file opening and closing that /// involves interacting with the user. /// /// NOTE: This class originated as the static class /// TestLoaderUI and is slowly being converted to a /// true presenter. Current limitations include: /// /// 1. At this time, the presenter is created by /// the form and interacts with it directly, rather /// than through an interface. /// /// 2. Many functions, which should properly be in /// the presenter, remain in the form. /// /// 3. The presenter creates dialogs itself, which /// limits testability. /// public class NUnitPresenter { #region Instance Variables private NUnitForm form; private TestLoader loader; // Our nunit project watcher private FileWatcher projectWatcher; #endregion #region Constructor // TODO: Use an interface for view and model public NUnitPresenter(NUnitForm form, TestLoader loader) { this.form = form; this.loader = loader; } #endregion #region Public Properties public NUnitForm Form { get { return form; } } #endregion #region Public Methods #region New Project Methods public void NewProject() { if (loader.IsProjectLoaded) CloseProject(); SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "New Test Project"; dlg.Filter = "NUnit Test Project (*.nunit)|*.nunit|All Files (*.*)|*.*"; dlg.FileName = Services.ProjectService.GenerateProjectName(); dlg.DefaultExt = "nunit"; dlg.ValidateNames = true; dlg.OverwritePrompt = true; if (dlg.ShowDialog(Form) == DialogResult.OK) loader.NewProject(dlg.FileName); } #endregion #region Open Methods public void OpenProject() { OpenFileDialog dlg = new OpenFileDialog(); System.ComponentModel.ISite site = Form == null ? null : Form.Site; if ( site != null ) dlg.Site = site; dlg.Title = "Open Project"; if ( VisualStudioSupport ) { dlg.Filter = "Projects & Assemblies(*.nunit,*.csproj,*.vbproj,*.vjsproj, *.vcproj,*.sln,*.dll,*.exe )|*.nunit;*.csproj;*.vjsproj;*.vbproj;*.vcproj;*.sln;*.dll;*.exe|" + "All Project Types (*.nunit,*.csproj,*.vbproj,*.vjsproj,*.vcproj,*.sln)|*.nunit;*.csproj;*.vjsproj;*.vbproj;*.vcproj;*.sln|" + "Test Projects (*.nunit)|*.nunit|" + "Solutions (*.sln)|*.sln|" + "C# Projects (*.csproj)|*.csproj|" + "J# Projects (*.vjsproj)|*.vjsproj|" + "VB Projects (*.vbproj)|*.vbproj|" + "C++ Projects (*.vcproj)|*.vcproj|" + "Assemblies (*.dll,*.exe)|*.dll;*.exe"; } else { dlg.Filter = "Projects & Assemblies(*.nunit,*.dll,*.exe)|*.nunit;*.dll;*.exe|" + "Test Projects (*.nunit)|*.nunit|" + "Assemblies (*.dll,*.exe)|*.dll;*.exe"; } dlg.FilterIndex = 1; dlg.FileName = ""; if ( dlg.ShowDialog( Form ) == DialogResult.OK ) OpenProject( dlg.FileName ); } public void WatchProject(string projectPath) { this.projectWatcher = new FileWatcher(projectPath, 100); this.projectWatcher.Changed += new FileChangedHandler(OnTestProjectChanged); this.projectWatcher.Start(); } public void RemoveWatcher() { if (projectWatcher != null) { projectWatcher.Stop(); projectWatcher.Dispose(); projectWatcher = null; } } private void OnTestProjectChanged(string filePath) { string message = filePath + Environment.NewLine + Environment.NewLine + "This file has been modified outside of NUnit." + Environment.NewLine + "Do you want to reload it?"; if (Form.MessageDisplay.Ask(message) == DialogResult.Yes) ReloadProject(); } public void OpenProject(string testFileName, string configName, string testName) { if ( loader.IsProjectLoaded && SaveProjectIfDirty() == DialogResult.Cancel ) return; loader.LoadProject( testFileName, configName ); if ( loader.IsProjectLoaded ) { NUnitProject testProject = loader.TestProject; if ( testProject.Configs.Count == 0 ) Form.MessageDisplay.Info("Loaded project contains no configuration data"); else if ( testProject.ActiveConfig == null ) Form.MessageDisplay.Info("Loaded project has no active configuration"); else if ( testProject.ActiveConfig.Assemblies.Count == 0 ) Form.MessageDisplay.Info("Active configuration contains no assemblies"); else loader.LoadTest( testName ); } } public void OpenProject( string testFileName ) { OpenProject( testFileName, null, null ); } // public static void OpenResults( Form owner ) // { // OpenFileDialog dlg = new OpenFileDialog(); // System.ComponentModel.ISite site = owner == null ? null : owner.Site; // if ( site != null ) dlg.Site = site; // dlg.Title = "Open Test Results"; // // dlg.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; // dlg.FilterIndex = 1; // dlg.FileName = ""; // // if ( dlg.ShowDialog( owner ) == DialogResult.OK ) // OpenProject( owner, dlg.FileName ); // } #endregion #region Close Methods public DialogResult CloseProject() { DialogResult result = SaveProjectIfDirty(); if (result != DialogResult.Cancel) loader.UnloadProject(); return result; } #endregion #region Add Methods public void AddToProject() { AddToProject( null ); } // TODO: Not used? public void AddToProject( string configName ) { ProjectConfig config = configName == null ? loader.TestProject.ActiveConfig : loader.TestProject.Configs[configName]; OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Add Assemblies To Project"; dlg.InitialDirectory = config.BasePath; if ( VisualStudioSupport ) dlg.Filter = "Projects & Assemblies(*.csproj,*.vbproj,*.vjsproj, *.vcproj,*.dll,*.exe )|*.csproj;*.vjsproj;*.vbproj;*.vcproj;*.dll;*.exe|" + "Visual Studio Projects (*.csproj,*.vjsproj,*.vbproj,*.vcproj)|*.csproj;*.vjsproj;*.vbproj;*.vcproj|" + "C# Projects (*.csproj)|*.csproj|" + "J# Projects (*.vjsproj)|*.vjsproj|" + "VB Projects (*.vbproj)|*.vbproj|" + "C++ Projects (*.vcproj)|*.vcproj|" + "Assemblies (*.dll,*.exe)|*.dll;*.exe"; else dlg.Filter = "Assemblies (*.dll,*.exe)|*.dll;*.exe"; dlg.FilterIndex = 1; dlg.FileName = ""; if ( dlg.ShowDialog( Form ) != DialogResult.OK ) return; if (PathUtils.IsAssemblyFileType(dlg.FileName)) { config.Assemblies.Add(dlg.FileName); return; } else if (VSProject.IsProjectFile(dlg.FileName)) try { VSProject vsProject = new VSProject(dlg.FileName); MessageBoxButtons buttons; string msg; if (configName != null && vsProject.Configs.Contains(configName)) { msg = "The project being added may contain multiple configurations;\r\r" + "Select\tYes to add all configurations found.\r" + "\tNo to add only the " + configName + " configuration.\r" + "\tCancel to exit without modifying the project."; buttons = MessageBoxButtons.YesNoCancel; } else { msg = "The project being added may contain multiple configurations;\r\r" + "Select\tOK to add all configurations found.\r" + "\tCancel to exit without modifying the project."; buttons = MessageBoxButtons.OKCancel; } DialogResult result = Form.MessageDisplay.Ask(msg, buttons); if (result == DialogResult.Yes || result == DialogResult.OK) { loader.TestProject.Add(vsProject); return; } else if (result == DialogResult.No) { foreach (string assembly in vsProject.Configs[configName].Assemblies) config.Assemblies.Add(assembly); return; } } catch (Exception ex) { Form.MessageDisplay.Error("Invalid VS Project", ex); } } public void AddAssembly() { AddAssembly( null ); } public void AddAssembly( string configName ) { ProjectConfig config = configName == null ? loader.TestProject.ActiveConfig : loader.TestProject.Configs[configName]; OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Add Assembly"; dlg.InitialDirectory = config.BasePath; dlg.Filter = "Assemblies (*.dll,*.exe)|*.dll;*.exe"; dlg.FilterIndex = 1; dlg.FileName = ""; if (dlg.ShowDialog(Form) == DialogResult.OK) config.Assemblies.Add(dlg.FileName); } public void AddVSProject() { OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Add Visual Studio Project"; dlg.Filter = "All Project Types (*.csproj,*.vjsproj,*.vbproj,*.vcproj)|*.csproj;*.vjsproj;*.vbproj;*.vcproj|" + "C# Projects (*.csproj)|*.csproj|" + "J# Projects (*.vjsproj)|*.vjsproj|" + "VB Projects (*.vbproj)|*.vbproj|" + "C++ Projects (*.vcproj)|*.vcproj|" + "All Files (*.*)|*.*"; dlg.FilterIndex = 1; dlg.FileName = ""; if ( dlg.ShowDialog( Form ) == DialogResult.OK ) { try { VSProject vsProject = new VSProject( dlg.FileName ); loader.TestProject.Add( vsProject ); } catch( Exception ex ) { Form.MessageDisplay.Error("Invalid VS Project", ex); } } } #endregion #region Save Methods public void SaveProject() { if ( Path.IsPathRooted( loader.TestProject.ProjectPath ) && NUnitProject.IsNUnitProjectFile( loader.TestProject.ProjectPath ) && CanWriteProjectFile( loader.TestProject.ProjectPath ) ) loader.TestProject.Save(); else SaveProjectAs(); } public void SaveProjectAs() { SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "Save Test Project"; dlg.Filter = "NUnit Test Project (*.nunit)|*.nunit|All Files (*.*)|*.*"; string path = NUnitProject.ProjectPathFromFile( loader.TestProject.ProjectPath ); if ( CanWriteProjectFile( path ) ) dlg.FileName = path; dlg.DefaultExt = "nunit"; dlg.ValidateNames = true; dlg.OverwritePrompt = true; while( dlg.ShowDialog( Form ) == DialogResult.OK ) { if ( !CanWriteProjectFile( dlg.FileName ) ) Form.MessageDisplay.Info(string.Format("File {0} is write-protected. Select another file name.", dlg.FileName)); else { loader.TestProject.Save( dlg.FileName ); ReloadProject(); return; } } } private DialogResult SaveProjectIfDirty() { DialogResult result = DialogResult.OK; NUnitProject project = loader.TestProject; if (project.IsDirty) { string msg = string.Format( "Project {0} has been changed. Do you want to save changes?", project.Name); result = Form.MessageDisplay.Ask(msg, MessageBoxButtons.YesNoCancel); if (result == DialogResult.Yes) SaveProject(); } return result; } public void SaveLastResult() { //TODO: Save all results SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "Save Test Results as XML"; dlg.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; dlg.FileName = "TestResult.xml"; dlg.InitialDirectory = Path.GetDirectoryName(loader.TestFileName); dlg.DefaultExt = "xml"; dlg.ValidateNames = true; dlg.OverwritePrompt = true; if (dlg.ShowDialog(Form) == DialogResult.OK) { try { string fileName = dlg.FileName; loader.SaveLastResult(fileName); Form.MessageDisplay.Info(String.Format("Results saved as {0}", fileName)); } catch (Exception exception) { Form.MessageDisplay.Error("Unable to Save Results", exception); } } } #endregion #region Reload Methods public void ReloadProject() { NUnitProject project = loader.TestProject; bool wrapper = project.IsAssemblyWrapper; string projectPath = project.ProjectPath; string activeConfigName = project.ActiveConfigName; // Unload first to avoid message asking about saving loader.UnloadProject(); if (wrapper) OpenProject(projectPath); else OpenProject(projectPath, activeConfigName, null); } #endregion #region Edit Project public void EditProject() { NUnitProject project = loader.TestProject; string editorPath = GetProjectEditorPath(); if (!File.Exists(editorPath)) { string NL = Environment.NewLine; string message = "Unable to locate the specified Project Editor:" + NL + NL + editorPath + NL + NL + (Services.UserSettings.GetSetting("Options.ProjectEditor.EditorPath") == null ? "Verify that nunit.editor.exe is properly installed in the NUnit bin directory." : "Verify that you have set the path to the editor correctly."); Form.MessageDisplay.Error(message); return; } if (!NUnitProject.IsNUnitProjectFile(project.ProjectPath)) { if (Form.MessageDisplay.Display( "The project has not yet been saved. In order to edit the project, it must first be saved. Click OK to save the project or Cancel to exit.", MessageBoxButtons.OKCancel) == DialogResult.OK) { project.Save(); } } else if (!File.Exists(project.ProjectPath)) { project.Save(); } else if (project.IsDirty) { switch (Form.MessageDisplay.Ask( "There are unsaved changes. Do you want to save them before running the editor?", MessageBoxButtons.YesNoCancel)) { case DialogResult.Yes: project.Save(); break; case DialogResult.Cancel: return; } } // In case we tried to save project and failed if (NUnitProject.IsNUnitProjectFile(project.ProjectPath) && File.Exists(project.ProjectPath)) { Process p = new Process(); p.StartInfo.FileName = Quoted(editorPath); p.StartInfo.Arguments = Quoted(project.ProjectPath); p.Start(); } } #endregion #endregion #region Helper Properties and Methods private static bool VisualStudioSupport { get { return Services.UserSettings.GetSetting("Options.TestLoader.VisualStudioSupport", false); } } private static bool CanWriteProjectFile(string path) { return !File.Exists(path) || (File.GetAttributes(path) & FileAttributes.ReadOnly) == 0; } private static string GetProjectEditorPath() { string editorPath = (string)Services.UserSettings.GetSetting("Options.ProjectEditor.EditorPath"); if (editorPath == null) editorPath = Path.Combine(NUnitConfiguration.NUnitBinDirectory, "nunit-editor.exe"); return editorPath; } private static string Quoted(string s) { return "\"" + s + "\""; } #endregion } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/OptionsDialog.resx0000664000175000017500000003635611504175260023277 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private False Private Private Private 17, 17 Private True False True 8, 8 Private Private False True True Private Private 8, 8 False Private Private False True True Private Private 8, 8 False Private Private False True True Private Private 8, 8 False (Default) False False 8, 8 OptionsDialog True 80 True Private AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AboutBox.resx0000664000175000017500000001706211664125100022233 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/TestAssemblyInfoForm.cs0000664000175000017500000001150111664123202024204 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.IO; using System.Collections; using System.Reflection; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; using NUnit.UiKit; using NUnit.Util; using NUnit.Core; namespace NUnit.Gui { public class TestAssemblyInfoForm : ScrollingTextDisplayForm { protected override void OnLoad(EventArgs e) { this.Text = "Test Assemblies"; this.TextBox.WordWrap = false; //this.TextBox.ContentsResized += new ContentsResizedEventHandler(TextBox_ContentsResized); this.TextBox.Font = new System.Drawing.Font(FontFamily.GenericMonospace, 8.25F); base.OnLoad(e); Process p = Process.GetCurrentProcess(); int currentProcessId = p.Id; string currentDomainName = ""; AppendProcessInfo( currentProcessId, Path.GetFileName(Assembly.GetEntryAssembly().Location), RuntimeFramework.CurrentFramework ); foreach (TestAssemblyInfo info in Services.TestLoader.AssemblyInfo) { if (info.ProcessId != currentProcessId) { this.TextBox.AppendText("\r\n"); AppendProcessInfo(info); currentProcessId = info.ProcessId; } if (info.DomainName != currentDomainName) { AppendDomainInfo(info); currentDomainName = info.DomainName; } AppendAssemblyInfo(info); } TextBox.Select(0,0); TextBox.ScrollToCaret(); } private void AppendProcessInfo(TestAssemblyInfo info) { AppendProcessInfo(info.ProcessId, info.ModuleName, info.RunnerRuntimeFramework); } private void AppendProcessInfo( int pid, string moduleName, RuntimeFramework framework ) { AppendBoldText(string.Format("{0} ( {1} )\r\n", moduleName, pid)); TextBox.AppendText(string.Format( " Framework Version: {0}\r\n", framework.DisplayName)); TextBox.AppendText(string.Format( " CLR Version: {0}\r\n", framework.ClrVersion.ToString())); } private void AppendDomainInfo(TestAssemblyInfo info) { AppendBoldText(string.Format("\r\n {0}\r\n", info.DomainName)); StringBuilder sb = new StringBuilder(); sb.AppendFormat( " ApplicationBase: {0}\r\n", info.ApplicationBase ); if (info.PrivateBinPath != null) { string prefix = " PrivateBinPath: "; foreach (string s in info.PrivateBinPath.Split(new char[] { ';' })) { sb.AppendFormat("{0}{1}\r\n", prefix, s); prefix = " "; } } sb.AppendFormat(" Configuration File: {0}\r\n", info.ConfigurationFile); TextBox.AppendText(sb.ToString()); } private void AppendAssemblyInfo(TestAssemblyInfo info) { AppendBoldText( string.Format(" {0}\r\n", Path.GetFileNameWithoutExtension(info.Name))); StringBuilder sb = new StringBuilder(); sb.AppendFormat(" Path: {0}\r\n", info.Name); sb.AppendFormat(" Image Runtime Version: {0}\r\n", info.ImageRuntimeVersion.ToString()); if (info.TestFrameworks != null) { string prefix = " Uses: "; foreach (AssemblyName framework in info.TestFrameworks) { sb.AppendFormat("{0}{1}\r\n", prefix, framework.FullName); prefix = " "; } } TextBox.AppendText(sb.ToString()); } private void AppendBoldText(string text) { TextBox.Select(TextBox.Text.Length, 0); TextBox.SelectionFont = new Font(TextBox.Font, FontStyle.Bold); TextBox.SelectedText += text; } void TextBox_ContentsResized(object sender, ContentsResizedEventArgs e) { int increase = e.NewRectangle.Width - TextBox.ClientSize.Width; if (increase > 0) { TextBox.Width += increase; this.Width += increase; } } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AssemblyInfo.cs0000664000175000017500000000072211504175260022527 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AddinDialog.resx0000664000175000017500000003037011504175260022651 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private Private Private Private Private Private False Private False Private Private False Private Private Private False Private Private False Private AddinDialog False (Default) False False 8, 8 True 80 True Private AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/OptionsDialog.cs0000664000175000017500000000347011544330406022711 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** #define TREE_BASED using System; using System.Windows.Forms; using NUnit.UiKit; using NUnit.Gui.SettingsPages; namespace NUnit.Gui { /// /// Summary description for OptionsDialog. /// public class OptionsDialog { #if TREE_BASED public static void Display( Form owner ) { TreeBasedSettingsDialog.Display( owner, new GuiSettingsPage("Gui.General"), new TreeSettingsPage("Gui.Tree Display"), new TestResultSettingsPage("Gui.Test Results"), new TextOutputSettingsPage("Gui.Text Output"), new ProjectEditorSettingsPage("Gui.Project Editor"), new TestLoaderSettingsPage("Test Loader.Assembly Isolation"), new AssemblyReloadSettingsPage("Test Loader.Assembly Reload"), new RuntimeSelectionSettingsPage("Test Loader.Runtime Selection"), new AdvancedLoaderSettingsPage("Test Loader.Advanced"), new VisualStudioSettingsPage("IDE Support.Visual Studio"), new InternalTraceSettingsPage("Advanced Settings.Internal Trace")); } #else public static void Display( Form owner ) { TabbedSettingsDialog.Display( owner, new GuiSettingsPage("General"), new TreeSettingsPage("Tree"), new TestResultSettingsPage("Results"), new TextOutputSettingsPage("Text Output"), new TestLoaderSettingsPage("Test Load"), new AssemblyReloadSettingsPage("Reload"), new VisualStudioSettingsPage("Visual Studio")); } #endif private OptionsDialog() { } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AppEntry.cs0000664000175000017500000001230711544330406021677 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using NUnit.UiKit; using NUnit.Util; using NUnit.Core; using NUnit.Core.Extensibility; namespace NUnit.Gui { /// /// Class to manage application startup. /// public class AppEntry { static Logger log = InternalTrace.GetLogger(typeof(AppEntry)); /// /// The main entry point for the application. /// [STAThread] public static int Main(string[] args) { // Create SettingsService early so we know the trace level right at the start SettingsService settingsService = new SettingsService(); InternalTrace.Initialize("nunit-gui_%p.log", (InternalTraceLevel)settingsService.GetSetting("Options.InternalTraceLevel", InternalTraceLevel.Default)); log.Info("Starting NUnit GUI"); GuiOptions guiOptions = new GuiOptions(args); GuiAttachedConsole attachedConsole = null; if (guiOptions.console) { log.Info("Creating attached console"); attachedConsole = new GuiAttachedConsole(); } if (guiOptions.help) { MessageDisplay.Display(guiOptions.GetHelpText()); return 0; } if (!guiOptions.Validate()) { string message = "Error in command line"; MessageDisplay.Error(message + Environment.NewLine + Environment.NewLine + guiOptions.GetHelpText()); log.Error(message); return 2; } if (guiOptions.cleanup) { log.Info("Performing cleanup of shadow copy cache"); DomainManager.DeleteShadowCopyPath(); return 0; } if (!guiOptions.NoArgs) { if (guiOptions.lang != null) { log.Info("Setting culture to " + guiOptions.lang); Thread.CurrentThread.CurrentUICulture = new CultureInfo(guiOptions.lang); } } try { // Add Standard Services to ServiceManager log.Info("Adding Services"); ServiceManager.Services.AddService(settingsService); ServiceManager.Services.AddService(new DomainManager()); ServiceManager.Services.AddService(new RecentFilesService()); ServiceManager.Services.AddService(new ProjectService()); ServiceManager.Services.AddService(new TestLoader(new GuiTestEventDispatcher())); ServiceManager.Services.AddService(new AddinRegistry()); ServiceManager.Services.AddService(new AddinManager()); ServiceManager.Services.AddService(new TestAgency()); // Initialize Services log.Info("Initializing Services"); ServiceManager.Services.InitializeServices(); } catch (Exception ex) { MessageDisplay.FatalError("Service initialization failed.", ex); log.Error("Service initialization failed", ex); return 2; } // Create container in order to allow ambient properties // to be shared across all top-level forms. log.Info("Initializing AmbientProperties"); AppContainer c = new AppContainer(); AmbientProperties ambient = new AmbientProperties(); c.Services.AddService(typeof(AmbientProperties), ambient); log.Info("Constructing Form"); NUnitForm form = new NUnitForm(guiOptions); c.Add(form); try { log.Info("Starting Gui Application"); Application.Run(form); log.Info("Application Exit"); } catch( Exception ex ) { log.Error("Gui Application threw an excepion", ex ); throw; } finally { log.Info("Stopping Services"); ServiceManager.Services.StopAllServices(); } if (attachedConsole != null) { Console.WriteLine("Press Enter to exit"); Console.ReadLine(); attachedConsole.Close(); } log.Info("Exiting NUnit GUI"); InternalTrace.Close(); return 0; } private static IMessageDisplay MessageDisplay { get { return new MessageDisplay("NUnit"); } } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/NUnitForm.resx0000664000175000017500000002014711671353534022403 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 130, 17 65 AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/GuiOptions.cs0000664000175000017500000000443711544330406022242 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Gui { using System; using System.Text; using Codeblast; public class GuiOptions : CommandLineOptions { [Option(Description = "Fixture to test")] public string fixture; [Option(Description = "List of categories to include")] public string include; [Option(Description = "List of categories to exclude")] public string exclude; [Option(Description = "Project configuration to load")] public string config; [Option(Description = "Suppress loading of last project")] public bool noload; [Option(Description = "Automatically run the loaded project")] public bool run; [Option(Description = "Automatically run selected tests or all tests if none are selected")] public bool runselected; [Option(Description = "Create console display for viewing any unmanaged output")] public bool console; [Option(Description = "Language to use for the NUnit GUI")] public string lang; [Option(Description = "Erase any leftover cache files and exit")] public bool cleanup; [Option(Short="?", Description = "Display help")] public bool help = false; public GuiOptions(String[] args) : base(args) { } private bool HasInclude { get { return include != null && include.Length != 0; } } private bool HasExclude { get { return exclude != null && exclude.Length != 0; } } public bool Validate() { if ( isInvalid ) return false; if ( HasInclude && HasExclude ) return false; return NoArgs || ParameterCount <= 1; } public override string GetHelpText() { return "NUNIT [inputfile] [options]\r\r" + "Runs a set of NUnit tests from the console. You may specify\r" + "an assembly or a project file of type .nunit as input.\r\r" + "Options:\r" + base.GetHelpText() + "\rOptions that take values may use an equal sign, a colon\r" + "or a space to separate the option from its value."; } } }NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/Logo.ico0000664000175000017500000000206611504175260021204 0ustar jtaylorjtaylor &(( @( ffffffffffffffffNUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/0000775000175000017500000000000011742560362022371 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/GuiSettingsPage.resx0000664000175000017500000001411011660146340026326 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 17, 17 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TestLoaderSettingsPage.resx0000664000175000017500000001357711660154606027674 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/ProjectEditorSettingsPage.Designer.cs0000664000175000017500000001457311660154064031561 0ustar jtaylorjtaylornamespace NUnit.Gui.SettingsPages { partial class ProjectEditorSettingsPage { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectEditorSettingsPage)); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.label1 = new System.Windows.Forms.Label(); this.editorPathTextBox = new System.Windows.Forms.TextBox(); this.editorPathBrowseButton = new System.Windows.Forms.Button(); this.useNUnitEditorRadioButton = new System.Windows.Forms.RadioButton(); this.useOtherEditorRadioButton = new System.Windows.Forms.RadioButton(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(112, 10); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(333, 8); this.groupBox1.TabIndex = 1; this.groupBox1.TabStop = false; // // label1 // this.label1.Location = new System.Drawing.Point(2, 10); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(88, 16); this.label1.TabIndex = 0; this.label1.Text = "Project Editor"; // // editorPathTextBox // this.editorPathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.editorPathTextBox.Location = new System.Drawing.Point(112, 64); this.editorPathTextBox.Name = "editorPathTextBox"; this.editorPathTextBox.Size = new System.Drawing.Size(298, 20); this.editorPathTextBox.TabIndex = 4; this.editorPathTextBox.TextChanged += new System.EventHandler(this.editorPathTextBox_TextChanged); // // editorPathBrowseButton // this.editorPathBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.editorPathBrowseButton.Image = ((System.Drawing.Image)(resources.GetObject("editorPathBrowseButton.Image"))); this.editorPathBrowseButton.Location = new System.Drawing.Point(418, 61); this.editorPathBrowseButton.Margin = new System.Windows.Forms.Padding(2); this.editorPathBrowseButton.Name = "editorPathBrowseButton"; this.editorPathBrowseButton.Size = new System.Drawing.Size(27, 26); this.editorPathBrowseButton.TabIndex = 5; this.editorPathBrowseButton.Click += new System.EventHandler(this.editorPathBrowseButton_Click); // // useNUnitEditorRadioButton // this.useNUnitEditorRadioButton.AutoSize = true; this.useNUnitEditorRadioButton.Location = new System.Drawing.Point(20, 39); this.useNUnitEditorRadioButton.Name = "useNUnitEditorRadioButton"; this.useNUnitEditorRadioButton.Size = new System.Drawing.Size(140, 17); this.useNUnitEditorRadioButton.TabIndex = 2; this.useNUnitEditorRadioButton.TabStop = true; this.useNUnitEditorRadioButton.Text = "Use NUnit Project Editor"; this.useNUnitEditorRadioButton.UseVisualStyleBackColor = true; // // useOtherEditorRadioButton // this.useOtherEditorRadioButton.AutoSize = true; this.useOtherEditorRadioButton.Location = new System.Drawing.Point(20, 66); this.useOtherEditorRadioButton.Name = "useOtherEditorRadioButton"; this.useOtherEditorRadioButton.Size = new System.Drawing.Size(89, 17); this.useOtherEditorRadioButton.TabIndex = 3; this.useOtherEditorRadioButton.TabStop = true; this.useOtherEditorRadioButton.Text = "Use Program:"; this.useOtherEditorRadioButton.UseVisualStyleBackColor = true; // // ProjectEditorSettingsPage // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.useOtherEditorRadioButton); this.Controls.Add(this.useNUnitEditorRadioButton); this.Controls.Add(this.editorPathBrowseButton); this.Controls.Add(this.editorPathTextBox); this.Controls.Add(this.groupBox1); this.Controls.Add(this.label1); this.Name = "ProjectEditorSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox editorPathTextBox; private System.Windows.Forms.Button editorPathBrowseButton; private System.Windows.Forms.RadioButton useNUnitEditorRadioButton; private System.Windows.Forms.RadioButton useOtherEditorRadioButton; } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TestResultSettingsPage.cs0000664000175000017500000002154111660152440027350 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace NUnit.Gui.SettingsPages { public class TestResultSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.CheckBox errorsTabCheckBox; private System.Windows.Forms.CheckBox failureToolTips; private System.Windows.Forms.CheckBox enableWordWrap; private System.Windows.Forms.CheckBox notRunTabCheckBox; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.Label label2; private System.Windows.Forms.HelpProvider helpProvider1; private System.ComponentModel.IContainer components = null; public TestResultSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.label1 = new System.Windows.Forms.Label(); this.errorsTabCheckBox = new System.Windows.Forms.CheckBox(); this.failureToolTips = new System.Windows.Forms.CheckBox(); this.enableWordWrap = new System.Windows.Forms.CheckBox(); this.notRunTabCheckBox = new System.Windows.Forms.CheckBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.label2 = new System.Windows.Forms.Label(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(149, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(307, 8); this.groupBox1.TabIndex = 8; this.groupBox1.TabStop = false; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(56, 13); this.label1.TabIndex = 9; this.label1.Text = "Errors Tab"; // // errorsTabCheckBox // this.errorsTabCheckBox.AutoSize = true; this.errorsTabCheckBox.Checked = true; this.errorsTabCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; this.helpProvider1.SetHelpString(this.errorsTabCheckBox, "If checked, the Errors and Failures Tab will be displayed in the Gui"); this.errorsTabCheckBox.Location = new System.Drawing.Point(32, 24); this.errorsTabCheckBox.Name = "errorsTabCheckBox"; this.helpProvider1.SetShowHelp(this.errorsTabCheckBox, true); this.errorsTabCheckBox.Size = new System.Drawing.Size(172, 17); this.errorsTabCheckBox.TabIndex = 10; this.errorsTabCheckBox.Text = "Display Errors and Failures Tab"; // // failureToolTips // this.failureToolTips.AutoSize = true; this.helpProvider1.SetHelpString(this.failureToolTips, "If checked, a tooltip will be displayed when hovering over an error that does not" + " fit the display."); this.failureToolTips.Location = new System.Drawing.Point(48, 56); this.failureToolTips.Name = "failureToolTips"; this.helpProvider1.SetShowHelp(this.failureToolTips, true); this.failureToolTips.Size = new System.Drawing.Size(137, 17); this.failureToolTips.TabIndex = 11; this.failureToolTips.Text = "Enable Failure ToolTips"; // // enableWordWrap // this.enableWordWrap.AutoSize = true; this.helpProvider1.SetHelpString(this.enableWordWrap, "If checked, error messages will be word wrapped to subsequent display lines."); this.enableWordWrap.Location = new System.Drawing.Point(48, 88); this.enableWordWrap.Name = "enableWordWrap"; this.helpProvider1.SetShowHelp(this.enableWordWrap, true); this.enableWordWrap.Size = new System.Drawing.Size(117, 17); this.enableWordWrap.TabIndex = 12; this.enableWordWrap.Text = "Enable Word Wrap"; // // notRunTabCheckBox // this.notRunTabCheckBox.AutoSize = true; this.notRunTabCheckBox.Checked = true; this.notRunTabCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; this.helpProvider1.SetHelpString(this.notRunTabCheckBox, "If checked, the Tests Not Run Tab will be displayed in the Gui."); this.notRunTabCheckBox.Location = new System.Drawing.Point(32, 152); this.notRunTabCheckBox.Name = "notRunTabCheckBox"; this.helpProvider1.SetShowHelp(this.notRunTabCheckBox, true); this.notRunTabCheckBox.Size = new System.Drawing.Size(154, 17); this.notRunTabCheckBox.TabIndex = 13; this.notRunTabCheckBox.Text = "Display Tests Not Run Tab"; // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Location = new System.Drawing.Point(149, 128); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(307, 8); this.groupBox2.TabIndex = 14; this.groupBox2.TabStop = false; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(8, 128); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(69, 13); this.label2.TabIndex = 15; this.label2.Text = "Not Run Tab"; // // TestResultSettingsPage // this.Controls.Add(this.groupBox2); this.Controls.Add(this.label2); this.Controls.Add(this.groupBox1); this.Controls.Add(this.errorsTabCheckBox); this.Controls.Add(this.failureToolTips); this.Controls.Add(this.enableWordWrap); this.Controls.Add(this.notRunTabCheckBox); this.Controls.Add(this.label1); this.Name = "TestResultSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { errorsTabCheckBox.Checked = settings.GetSetting( "Gui.ResultTabs.DisplayErrorsTab", true ); failureToolTips.Checked = settings.GetSetting( "Gui.ResultTabs.ErrorsTab.ToolTipsEnabled", true ); enableWordWrap.Checked = settings.GetSetting( "Gui.ResultTabs.ErrorsTab.WordWrapEnabled", true ); notRunTabCheckBox.Checked = settings.GetSetting( "Gui.ResultTabs.DisplayNotRunTab", true ); } public override void ApplySettings() { settings.SaveSetting( "Gui.ResultTabs.DisplayErrorsTab", errorsTabCheckBox.Checked ); settings.SaveSetting( "Gui.ResultTabs.ErrorsTab.ToolTipsEnabled", failureToolTips.Checked ); settings.SaveSetting( "Gui.ResultTabs.ErrorsTab.WordWrapEnabled", enableWordWrap.Checked ); settings.SaveSetting( "Gui.ResultTabs.DisplayNotRunTab", notRunTabCheckBox.Checked ); } private void errorsTabCheckBox_CheckedChanged(object sender, System.EventArgs e) { this.failureToolTips.Enabled = this.enableWordWrap.Enabled = this.errorsTabCheckBox.Checked; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TestLoaderSettingsPage.cs0000664000175000017500000003376511660154606027321 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NUnit.Util; using NUnit.Core; namespace NUnit.Gui.SettingsPages { public class TestLoaderSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.CheckBox mergeAssembliesCheckBox; private System.Windows.Forms.RadioButton singleDomainRadioButton; private System.Windows.Forms.RadioButton multiDomainRadioButton; private System.Windows.Forms.HelpProvider helpProvider1; private Label label3; private GroupBox groupBox3; private RadioButton multiProcessRadioButton; private RadioButton separateProcessRadioButton; private RadioButton sameProcessRadioButton; private Label label2; private GroupBox groupBox2; private System.ComponentModel.IContainer components = null; public TestLoaderSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.mergeAssembliesCheckBox = new System.Windows.Forms.CheckBox(); this.singleDomainRadioButton = new System.Windows.Forms.RadioButton(); this.multiDomainRadioButton = new System.Windows.Forms.RadioButton(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.label3 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.multiProcessRadioButton = new System.Windows.Forms.RadioButton(); this.separateProcessRadioButton = new System.Windows.Forms.RadioButton(); this.sameProcessRadioButton = new System.Windows.Forms.RadioButton(); this.label2 = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.SuspendLayout(); // // mergeAssembliesCheckBox // this.mergeAssembliesCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.mergeAssembliesCheckBox, "If checked, tests in each assembly will be merged into a single tree."); this.mergeAssembliesCheckBox.Location = new System.Drawing.Point(48, 221); this.mergeAssembliesCheckBox.Name = "mergeAssembliesCheckBox"; this.helpProvider1.SetShowHelp(this.mergeAssembliesCheckBox, true); this.mergeAssembliesCheckBox.Size = new System.Drawing.Size(169, 17); this.mergeAssembliesCheckBox.TabIndex = 10; this.mergeAssembliesCheckBox.Text = "Merge tests across assemblies"; // // singleDomainRadioButton // this.singleDomainRadioButton.AutoCheck = false; this.singleDomainRadioButton.AutoSize = true; this.singleDomainRadioButton.Checked = true; this.helpProvider1.SetHelpString(this.singleDomainRadioButton, "If selected, all test assemblies will be loaded in the same AppDomain."); this.singleDomainRadioButton.Location = new System.Drawing.Point(32, 190); this.singleDomainRadioButton.Name = "singleDomainRadioButton"; this.helpProvider1.SetShowHelp(this.singleDomainRadioButton, true); this.singleDomainRadioButton.Size = new System.Drawing.Size(194, 17); this.singleDomainRadioButton.TabIndex = 9; this.singleDomainRadioButton.TabStop = true; this.singleDomainRadioButton.Text = "Use a single AppDomain for all tests"; this.singleDomainRadioButton.Click += new System.EventHandler(this.toggleMultiDomain); // // multiDomainRadioButton // this.multiDomainRadioButton.AutoCheck = false; this.multiDomainRadioButton.AutoSize = true; this.helpProvider1.SetHelpString(this.multiDomainRadioButton, "If selected, each test assembly will be loaded in a separate AppDomain."); this.multiDomainRadioButton.Location = new System.Drawing.Point(32, 160); this.multiDomainRadioButton.Name = "multiDomainRadioButton"; this.helpProvider1.SetShowHelp(this.multiDomainRadioButton, true); this.multiDomainRadioButton.Size = new System.Drawing.Size(220, 17); this.multiDomainRadioButton.TabIndex = 8; this.multiDomainRadioButton.Text = "Use a separate AppDomain per Assembly"; this.multiDomainRadioButton.Click += new System.EventHandler(this.toggleMultiDomain); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(16, 8); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(114, 13); this.label3.TabIndex = 35; this.label3.Text = "Default Process Model"; // // groupBox3 // this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox3.Location = new System.Drawing.Point(199, 8); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(253, 8); this.groupBox3.TabIndex = 34; this.groupBox3.TabStop = false; // // multiProcessRadioButton // this.multiProcessRadioButton.AutoSize = true; this.multiProcessRadioButton.Location = new System.Drawing.Point(32, 99); this.multiProcessRadioButton.Name = "multiProcessRadioButton"; this.multiProcessRadioButton.Size = new System.Drawing.Size(239, 17); this.multiProcessRadioButton.TabIndex = 36; this.multiProcessRadioButton.Text = "Run tests in a separate process per Assembly"; this.multiProcessRadioButton.CheckedChanged += new System.EventHandler(this.toggleProcessUsage); // // separateProcessRadioButton // this.separateProcessRadioButton.AutoSize = true; this.separateProcessRadioButton.Location = new System.Drawing.Point(32, 66); this.separateProcessRadioButton.Name = "separateProcessRadioButton"; this.separateProcessRadioButton.Size = new System.Drawing.Size(204, 17); this.separateProcessRadioButton.TabIndex = 37; this.separateProcessRadioButton.Text = "Run tests in a single separate process"; this.separateProcessRadioButton.CheckedChanged += new System.EventHandler(this.toggleProcessUsage); // // sameProcessRadioButton // this.sameProcessRadioButton.AutoSize = true; this.sameProcessRadioButton.Checked = true; this.sameProcessRadioButton.Location = new System.Drawing.Point(32, 33); this.sameProcessRadioButton.Name = "sameProcessRadioButton"; this.sameProcessRadioButton.Size = new System.Drawing.Size(205, 17); this.sameProcessRadioButton.TabIndex = 38; this.sameProcessRadioButton.TabStop = true; this.sameProcessRadioButton.Text = "Run tests directly in the NUnit process"; this.sameProcessRadioButton.CheckedChanged += new System.EventHandler(this.toggleProcessUsage); // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(16, 136); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(114, 13); this.label2.TabIndex = 40; this.label2.Text = "Default Domain Usage"; // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Location = new System.Drawing.Point(199, 136); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(253, 8); this.groupBox2.TabIndex = 39; this.groupBox2.TabStop = false; // // TestLoaderSettingsPage // this.Controls.Add(this.label2); this.Controls.Add(this.groupBox2); this.Controls.Add(this.sameProcessRadioButton); this.Controls.Add(this.separateProcessRadioButton); this.Controls.Add(this.multiProcessRadioButton); this.Controls.Add(this.label3); this.Controls.Add(this.groupBox3); this.Controls.Add(this.mergeAssembliesCheckBox); this.Controls.Add(this.singleDomainRadioButton); this.Controls.Add(this.multiDomainRadioButton); this.Name = "TestLoaderSettingsPage"; this.Size = new System.Drawing.Size(456, 341); this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { switch( GetSavedProcessModel() ) { case ProcessModel.Separate: separateProcessRadioButton.Checked = true; sameProcessRadioButton.Checked = false; multiProcessRadioButton.Checked = false; break; case ProcessModel.Multiple: multiProcessRadioButton.Checked = true; sameProcessRadioButton.Checked = false; separateProcessRadioButton.Checked = false; break; default: sameProcessRadioButton.Checked = true; multiProcessRadioButton.Checked = false; separateProcessRadioButton.Checked = false; break; } bool multiDomain = GetSavedDomainUsage() == DomainUsage.Multiple; multiDomainRadioButton.Checked = multiDomain; singleDomainRadioButton.Checked = !multiDomain; mergeAssembliesCheckBox.Enabled = !multiDomain; mergeAssembliesCheckBox.Checked = settings.GetSetting( "Options.TestLoader.MergeAssemblies", false ); } public override void ApplySettings() { if (multiProcessRadioButton.Checked) settings.SaveSetting("Options.TestLoader.ProcessModel", ProcessModel.Multiple); else if (separateProcessRadioButton.Checked) settings.SaveSetting("Options.TestLoader.ProcessModel", ProcessModel.Separate); else settings.RemoveSetting("Options.TestLoader.ProcessModel"); if (multiDomainRadioButton.Checked) settings.SaveSetting("Options.TestLoader.DomainUsage", DomainUsage.Multiple); else settings.RemoveSetting("Options.TestLoader.DomainUsage"); settings.SaveSetting( "Options.TestLoader.MergeAssemblies", mergeAssembliesCheckBox.Checked ); } // TODO: Combine toggleProcessUsage and toggleMultiDomain private void toggleProcessUsage(object sender, EventArgs e) { bool enable = sameProcessRadioButton.Checked || separateProcessRadioButton.Checked; singleDomainRadioButton.Enabled = enable; multiDomainRadioButton.Enabled = enable; mergeAssembliesCheckBox.Enabled = enable && singleDomainRadioButton.Checked; } private void toggleMultiDomain(object sender, System.EventArgs e) { bool multiDomain = multiDomainRadioButton.Checked = ! multiDomainRadioButton.Checked; singleDomainRadioButton.Checked = !multiDomain; mergeAssembliesCheckBox.Enabled = !multiDomain && !multiProcessRadioButton.Checked; } public override bool HasChangesRequiringReload { get { return GetSavedProcessModel() != GetSelectedProcessModel() || GetSavedDomainUsage() != GetSelectedDomainUsage() || settings.GetSetting("Options.TestLoader.MergeAssemblies", false ) != mergeAssembliesCheckBox.Checked; } } private ProcessModel GetSavedProcessModel() { return (ProcessModel)settings.GetSetting("Options.TestLoader.ProcessModel", ProcessModel.Default); } private DomainUsage GetSavedDomainUsage() { return (DomainUsage)settings.GetSetting("Options.TestLoader.DomainUsage", DomainUsage.Default); } private ProcessModel GetSelectedProcessModel() { return separateProcessRadioButton.Checked ? ProcessModel.Separate : multiProcessRadioButton.Checked ? ProcessModel.Multiple : ProcessModel.Single; } private DomainUsage GetSelectedDomainUsage() { return multiDomainRadioButton.Checked ? DomainUsage.Multiple : DomainUsage.Single; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/AssemblyReloadSettingsPage.resx0000664000175000017500000001411011660155022030505 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 17, 17 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/ProjectEditorSettingsPage.cs0000664000175000017500000000441411720452154030011 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; using NUnit.UiKit; namespace NUnit.Gui.SettingsPages { public partial class ProjectEditorSettingsPage : SettingsPage { private static readonly string EDITOR_PATH_SETTING = "Options.ProjectEditor.EditorPath"; public ProjectEditorSettingsPage(string key) : base(key) { InitializeComponent(); } public override void LoadSettings() { string editorPath = (string)settings.GetSetting(EDITOR_PATH_SETTING); if (editorPath != null) { useOtherEditorRadioButton.Checked = true; editorPathTextBox.Text = editorPath; } else { useNUnitEditorRadioButton.Checked = true; editorPathTextBox.Text = ""; } } public override void ApplySettings() { if (useNUnitEditorRadioButton.Checked) settings.RemoveSetting(EDITOR_PATH_SETTING); else settings.SaveSetting(EDITOR_PATH_SETTING, editorPathTextBox.Text); } private void editorPathTextBox_TextChanged(object sender, EventArgs e) { if (editorPathTextBox.TextLength == 0) useNUnitEditorRadioButton.Checked = true; else useOtherEditorRadioButton.Checked = true; } private void editorPathBrowseButton_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); if ( Site != null ) dlg.Site = Site; dlg.Title = "Select Project Editor"; dlg.Filter = "Executable Files (*.exe)|*.exe"; dlg.FilterIndex = 1; dlg.FileName = ""; if ( dlg.ShowDialog( this ) == DialogResult.OK ) editorPathTextBox.Text = dlg.FileName; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/VisualStudioSettingsPage.resx0000664000175000017500000001425511660166020030244 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 This setting should normally be checked if VS solutions are used. If it is unchecked, solution configs are ignored and all project configs are included in the NUnit project, as was done in versions of NUnit prior to 2.6. NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/GuiSettingsPage.cs0000664000175000017500000002742711660146340025771 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NUnit.Util; using NUnit.UiKit; namespace NUnit.Gui.SettingsPages { public class GuiSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.Label label1; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Label label2; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox recentFilesCountTextBox; private System.Windows.Forms.Label label4; private System.Windows.Forms.CheckBox loadLastProjectCheckBox; private System.Windows.Forms.RadioButton fullGuiRadioButton; private System.Windows.Forms.RadioButton miniGuiRadioButton; private System.Windows.Forms.HelpProvider helpProvider1; private CheckBox checkFilesExistCheckBox; private System.ComponentModel.IContainer components = null; public GuiSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.label2 = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.label3 = new System.Windows.Forms.Label(); this.recentFilesCountTextBox = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); this.loadLastProjectCheckBox = new System.Windows.Forms.CheckBox(); this.fullGuiRadioButton = new System.Windows.Forms.RadioButton(); this.miniGuiRadioButton = new System.Windows.Forms.RadioButton(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.checkFilesExistCheckBox = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(60, 13); this.label1.TabIndex = 7; this.label1.Text = "Gui Display"; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(135, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(313, 8); this.groupBox1.TabIndex = 6; this.groupBox1.TabStop = false; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(8, 96); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(66, 13); this.label2.TabIndex = 9; this.label2.Text = "Recent Files"; // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Location = new System.Drawing.Point(135, 96); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(313, 8); this.groupBox2.TabIndex = 8; this.groupBox2.TabStop = false; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(152, 120); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(65, 13); this.label3.TabIndex = 30; this.label3.Text = "files in menu"; // // recentFilesCountTextBox // this.helpProvider1.SetHelpString(this.recentFilesCountTextBox, "The maximum number of files to display in the Recent Files list."); this.recentFilesCountTextBox.Location = new System.Drawing.Point(96, 120); this.recentFilesCountTextBox.Name = "recentFilesCountTextBox"; this.helpProvider1.SetShowHelp(this.recentFilesCountTextBox, true); this.recentFilesCountTextBox.Size = new System.Drawing.Size(40, 20); this.recentFilesCountTextBox.TabIndex = 29; this.recentFilesCountTextBox.Validated += new System.EventHandler(this.recentFilesCountTextBox_Validated); this.recentFilesCountTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.recentFilesCountTextBox_Validating); // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(32, 120); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(23, 13); this.label4.TabIndex = 28; this.label4.Text = "List"; // // loadLastProjectCheckBox // this.loadLastProjectCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.loadLastProjectCheckBox, "If checked, most recent project is loaded at startup."); this.loadLastProjectCheckBox.Location = new System.Drawing.Point(32, 198); this.loadLastProjectCheckBox.Name = "loadLastProjectCheckBox"; this.helpProvider1.SetShowHelp(this.loadLastProjectCheckBox, true); this.loadLastProjectCheckBox.Size = new System.Drawing.Size(193, 17); this.loadLastProjectCheckBox.TabIndex = 31; this.loadLastProjectCheckBox.Text = "Load most recent project at startup."; // // fullGuiRadioButton // this.fullGuiRadioButton.AutoSize = true; this.helpProvider1.SetHelpString(this.fullGuiRadioButton, "If selected, the full Gui is displayed, including the progress bar and output tab" + "s."); this.fullGuiRadioButton.Location = new System.Drawing.Point(32, 24); this.fullGuiRadioButton.Name = "fullGuiRadioButton"; this.helpProvider1.SetShowHelp(this.fullGuiRadioButton, true); this.fullGuiRadioButton.Size = new System.Drawing.Size(215, 17); this.fullGuiRadioButton.TabIndex = 32; this.fullGuiRadioButton.Text = "Full Gui with progress bar and result tabs"; // // miniGuiRadioButton // this.miniGuiRadioButton.AutoSize = true; this.helpProvider1.SetHelpString(this.miniGuiRadioButton, "If selected, the mini-Gui, consisting of only the tree of tests, is displayed."); this.miniGuiRadioButton.Location = new System.Drawing.Point(32, 56); this.miniGuiRadioButton.Name = "miniGuiRadioButton"; this.helpProvider1.SetShowHelp(this.miniGuiRadioButton, true); this.miniGuiRadioButton.Size = new System.Drawing.Size(148, 17); this.miniGuiRadioButton.TabIndex = 33; this.miniGuiRadioButton.Text = "Mini Gui showing tree only"; // // checkFilesExistCheckBox // this.checkFilesExistCheckBox.AutoSize = true; this.checkFilesExistCheckBox.Location = new System.Drawing.Point(32, 159); this.checkFilesExistCheckBox.Name = "checkFilesExistCheckBox"; this.checkFilesExistCheckBox.Size = new System.Drawing.Size(185, 17); this.checkFilesExistCheckBox.TabIndex = 34; this.checkFilesExistCheckBox.Text = "Check that files exist before listing"; this.checkFilesExistCheckBox.UseVisualStyleBackColor = true; // // GuiSettingsPage // this.Controls.Add(this.checkFilesExistCheckBox); this.Controls.Add(this.miniGuiRadioButton); this.Controls.Add(this.fullGuiRadioButton); this.Controls.Add(this.label3); this.Controls.Add(this.recentFilesCountTextBox); this.Controls.Add(this.label4); this.Controls.Add(this.loadLastProjectCheckBox); this.Controls.Add(this.groupBox2); this.Controls.Add(this.label2); this.Controls.Add(this.groupBox1); this.Controls.Add(this.label1); this.Name = "GuiSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { string displayFormat = settings.GetSetting( "Gui.DisplayFormat", "Full" ); switch( displayFormat ) { case "Full": fullGuiRadioButton.Checked = true; break; case "Mini": miniGuiRadioButton.Checked = true; break; } recentFilesCountTextBox.Text = Services.RecentFiles.MaxFiles.ToString(); checkFilesExistCheckBox.Checked = settings.GetSetting("Gui.RecentProjects.CheckFilesExist", true); loadLastProjectCheckBox.Checked = settings.GetSetting( "Options.LoadLastProject", true ); } public override void ApplySettings() { string fmt = fullGuiRadioButton.Checked ? "Full" : "Mini"; settings.SaveSetting( "Gui.DisplayFormat", fmt ); settings.SaveSetting("Gui.RecentProjects.CheckFilesExist", checkFilesExistCheckBox.Checked); settings.SaveSetting( "Options.LoadLastProject", loadLastProjectCheckBox.Checked ); } private void recentFilesCountTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if ( recentFilesCountTextBox.Text.Length == 0 ) { recentFilesCountTextBox.Text = Services.RecentFiles.MaxFiles.ToString(); recentFilesCountTextBox.SelectAll(); e.Cancel = true; } else { string errmsg = null; try { int count = int.Parse( recentFilesCountTextBox.Text ); if ( count < RecentFilesService.MinSize || count > RecentFilesService.MaxSize ) { errmsg = string.Format( "Number of files must be from {0} to {1}", RecentFilesService.MinSize, RecentFilesService.MaxSize ); } } catch { errmsg = "Number of files must be numeric"; } if ( errmsg != null ) { recentFilesCountTextBox.SelectAll(); MessageDisplay.Error(errmsg); e.Cancel = true; } } } private void recentFilesCountTextBox_Validated(object sender, System.EventArgs e) { int count = int.Parse( recentFilesCountTextBox.Text ); Services.RecentFiles.MaxFiles = count; if (count == 0) loadLastProjectCheckBox.Checked = false; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/InternalTraceSettingsPage.cs0000664000175000017500000000223411660511152027762 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Core; namespace NUnit.Gui.SettingsPages { public partial class InternalTraceSettingsPage : NUnit.UiKit.SettingsPage { public InternalTraceSettingsPage(string key) : base(key) { InitializeComponent(); } public override void LoadSettings() { traceLevelComboBox.SelectedIndex = (int)(InternalTraceLevel)settings.GetSetting("Options.InternalTraceLevel", InternalTraceLevel.Default); logDirectoryLabel.Text = NUnitConfiguration.LogDirectory; } public override void ApplySettings() { InternalTraceLevel level = (InternalTraceLevel)traceLevelComboBox.SelectedIndex; settings.SaveSetting("Options.InternalTraceLevel", level); InternalTrace.Level = level; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/RuntimeSelectionSettingsPage.resx0000664000175000017500000001357711660155404031114 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/RuntimeSelectionSettingsPage.Designer.cs0000664000175000017500000000763411660155404032274 0ustar jtaylorjtaylornamespace NUnit.Gui.SettingsPages { partial class RuntimeSelectionSettingsPage { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.label3 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.runtimeSelectionCheckBox = new System.Windows.Forms.CheckBox(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.SuspendLayout(); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(9, 5); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(93, 13); this.label3.TabIndex = 14; this.label3.Text = "Runtime Selection"; // // groupBox3 // this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox3.Location = new System.Drawing.Point(169, 5); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(280, 8); this.groupBox3.TabIndex = 13; this.groupBox3.TabStop = false; // // runtimeSelectionCheckBox // this.helpProvider1.SetHelpString(this.runtimeSelectionCheckBox, "If checked and no specific runtime is requested, NUnit examines each assembly and" + " attempts to load it using the runtime version for which it was built. If not ch" + "ecked, the current runtime is used."); this.runtimeSelectionCheckBox.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.runtimeSelectionCheckBox.Location = new System.Drawing.Point(35, 28); this.runtimeSelectionCheckBox.Name = "runtimeSelectionCheckBox"; this.helpProvider1.SetShowHelp(this.runtimeSelectionCheckBox, true); this.runtimeSelectionCheckBox.Size = new System.Drawing.Size(372, 48); this.runtimeSelectionCheckBox.TabIndex = 15; this.runtimeSelectionCheckBox.Text = "Select default runtime version based on target framework of test assembly"; this.runtimeSelectionCheckBox.UseVisualStyleBackColor = true; // // RuntimeSelectionSettingsPage // this.Controls.Add(this.runtimeSelectionCheckBox); this.Controls.Add(this.label3); this.Controls.Add(this.groupBox3); this.Name = "RuntimeSelectionSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label label3; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.CheckBox runtimeSelectionCheckBox; private System.Windows.Forms.HelpProvider helpProvider1; } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/AdvancedLoaderSettingsPage.resx0000664000175000017500000001431711660166566030463 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 If checked, NUnit will enable copying of the assemblies to the shadow copy cache by the CLR. This is the default. Note that with shadow copying disabled, it is not possible to make changes to the assemblies while NUnit is running. NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/AssemblyReloadSettingsPage.cs0000664000175000017500000001572311660155022030144 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NUnit.Util; namespace NUnit.Gui.SettingsPages { public class AssemblyReloadSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.Label label1; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.CheckBox rerunOnChangeCheckBox; private System.Windows.Forms.CheckBox reloadOnRunCheckBox; private System.Windows.Forms.CheckBox reloadOnChangeCheckBox; private System.Windows.Forms.HelpProvider helpProvider1; private System.ComponentModel.IContainer components = null; public AssemblyReloadSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.rerunOnChangeCheckBox = new System.Windows.Forms.CheckBox(); this.reloadOnRunCheckBox = new System.Windows.Forms.CheckBox(); this.reloadOnChangeCheckBox = new System.Windows.Forms.CheckBox(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 4); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(88, 13); this.label1.TabIndex = 7; this.label1.Text = "Assembly Reload"; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(181, 4); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(259, 8); this.groupBox1.TabIndex = 6; this.groupBox1.TabStop = false; // // rerunOnChangeCheckBox // this.rerunOnChangeCheckBox.AutoSize = true; this.rerunOnChangeCheckBox.Enabled = false; this.helpProvider1.SetHelpString(this.rerunOnChangeCheckBox, "If checked, the last tests run will be re-run automatically whenever the assembly" + " changes."); this.rerunOnChangeCheckBox.Location = new System.Drawing.Point(48, 96); this.rerunOnChangeCheckBox.Name = "rerunOnChangeCheckBox"; this.helpProvider1.SetShowHelp(this.rerunOnChangeCheckBox, true); this.rerunOnChangeCheckBox.Size = new System.Drawing.Size(120, 17); this.rerunOnChangeCheckBox.TabIndex = 13; this.rerunOnChangeCheckBox.Text = "Re-run last tests run"; // // reloadOnRunCheckBox // this.reloadOnRunCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.reloadOnRunCheckBox, "If checked, the assembly is reloaded before each run"); this.reloadOnRunCheckBox.Location = new System.Drawing.Point(24, 32); this.reloadOnRunCheckBox.Name = "reloadOnRunCheckBox"; this.helpProvider1.SetShowHelp(this.reloadOnRunCheckBox, true); this.reloadOnRunCheckBox.Size = new System.Drawing.Size(158, 17); this.reloadOnRunCheckBox.TabIndex = 11; this.reloadOnRunCheckBox.Text = "Reload before each test run"; // // reloadOnChangeCheckBox // this.reloadOnChangeCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.reloadOnChangeCheckBox, "If checked, the assembly is reloaded whenever it changes. Changes to this setting" + " do not take effect until the next time an assembly is loaded."); this.reloadOnChangeCheckBox.Location = new System.Drawing.Point(24, 64); this.reloadOnChangeCheckBox.Name = "reloadOnChangeCheckBox"; this.helpProvider1.SetShowHelp(this.reloadOnChangeCheckBox, true); this.reloadOnChangeCheckBox.Size = new System.Drawing.Size(199, 17); this.reloadOnChangeCheckBox.TabIndex = 12; this.reloadOnChangeCheckBox.Text = "Reload when test assembly changes"; this.reloadOnChangeCheckBox.CheckedChanged += new System.EventHandler(this.reloadOnChangeCheckBox_CheckedChanged); // // AssemblyReloadSettingsPage // this.Controls.Add(this.rerunOnChangeCheckBox); this.Controls.Add(this.reloadOnRunCheckBox); this.Controls.Add(this.reloadOnChangeCheckBox); this.Controls.Add(this.label1); this.Controls.Add(this.groupBox1); this.Name = "AssemblyReloadSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { reloadOnChangeCheckBox.Checked = settings.GetSetting( "Options.TestLoader.ReloadOnChange", true ); rerunOnChangeCheckBox.Checked = settings.GetSetting( "Options.TestLoader.RerunOnChange", false ); reloadOnRunCheckBox.Checked = settings.GetSetting( "Options.TestLoader.ReloadOnRun", false ); } public override void ApplySettings() { settings.SaveSetting( "Options.TestLoader.ReloadOnChange", reloadOnChangeCheckBox.Checked ); settings.SaveSetting( "Options.TestLoader.RerunOnChange", rerunOnChangeCheckBox.Checked ); settings.SaveSetting( "Options.TestLoader.ReloadOnRun", reloadOnRunCheckBox.Checked ); } private void reloadOnChangeCheckBox_CheckedChanged(object sender, System.EventArgs e) { rerunOnChangeCheckBox.Enabled = reloadOnChangeCheckBox.Checked; } protected override void OnHelpRequested(HelpEventArgs hevent) { System.Diagnostics.Process.Start( "http://nunit.com/?p=optionsDialog&r=2.4.5" ); } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/RuntimeSelectionSettingsPage.cs0000664000175000017500000000205011660155404030520 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Core; namespace NUnit.Gui.SettingsPages { public partial class RuntimeSelectionSettingsPage : NUnit.UiKit.SettingsPage { private static readonly string RUNTIME_SELECTION_ENABLED = "Options.TestLoader.RuntimeSelectionEnabled"; public RuntimeSelectionSettingsPage(string key) : base(key) { InitializeComponent(); } public override void LoadSettings() { runtimeSelectionCheckBox.Checked = settings.GetSetting(RUNTIME_SELECTION_ENABLED, true); } public override void ApplySettings() { settings.SaveSetting(RUNTIME_SELECTION_ENABLED, runtimeSelectionCheckBox.Checked); } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/InternalTraceSettingsPage.Designer.cs0000664000175000017500000001150311660511152031520 0ustar jtaylorjtaylornamespace NUnit.Gui.SettingsPages { partial class InternalTraceSettingsPage { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.label3 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.label1 = new System.Windows.Forms.Label(); this.traceLevelComboBox = new System.Windows.Forms.ComboBox(); this.label4 = new System.Windows.Forms.Label(); this.logDirectoryLabel = new CP.Windows.Forms.ExpandingLabel(); this.SuspendLayout(); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(9, 5); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(73, 13); this.label3.TabIndex = 14; this.label3.Text = "Internal Trace"; // // groupBox3 // this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox3.Location = new System.Drawing.Point(158, 5); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(283, 8); this.groupBox3.TabIndex = 13; this.groupBox3.TabStop = false; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(19, 46); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(67, 13); this.label1.TabIndex = 15; this.label1.Text = "Trace Level:"; // // traceLevelComboBox // this.traceLevelComboBox.FormattingEnabled = true; this.traceLevelComboBox.Items.AddRange(new object[] { "Default", "Off", "Error", "Warning", "Info", "Verbose"}); this.traceLevelComboBox.Location = new System.Drawing.Point(134, 43); this.traceLevelComboBox.Name = "traceLevelComboBox"; this.traceLevelComboBox.Size = new System.Drawing.Size(89, 21); this.traceLevelComboBox.TabIndex = 16; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(19, 87); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(73, 13); this.label4.TabIndex = 18; this.label4.Text = "Log Directory:"; // // logDirectoryLabel // this.logDirectoryLabel.Location = new System.Drawing.Point(131, 87); this.logDirectoryLabel.Name = "logDirectoryLabel"; this.logDirectoryLabel.Size = new System.Drawing.Size(310, 22); this.logDirectoryLabel.TabIndex = 19; // // InternalTraceSettingsPage // this.Controls.Add(this.logDirectoryLabel); this.Controls.Add(this.label4); this.Controls.Add(this.traceLevelComboBox); this.Controls.Add(this.label1); this.Controls.Add(this.label3); this.Controls.Add(this.groupBox3); this.Name = "InternalTraceSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label label3; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.Label label1; private System.Windows.Forms.ComboBox traceLevelComboBox; private System.Windows.Forms.Label label4; private CP.Windows.Forms.ExpandingLabel logDirectoryLabel; } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TestResultSettingsPage.resx0000664000175000017500000001357711660152440027736 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TreeSettingsPage.resx0000664000175000017500000003135111700327602026504 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 17, 17 /9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBAxEB/8QA HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDu9f8AEt3LePb2rGCKM4OANxNZ3gjxxfal4i1DT5wJdPglFtFM 33mmAJkBzjgfKOnPJyeyeNPA1zfXP2uzLiVXMttdQj54HIweO6noVPBFTeA/BUuj29jFLGY4LNM/MMGR +ctgk4ySTjtmvDh9aWKbbbu9uiXfttp835HzcPryxjbbd3a32VG+/Z6WXzfZH//Z /9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBAxEB/8QA HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwBvi7x9r3h7xDqWlWuqznS/tbstxIqmW3Zjkxlv+eYYnaeqjCk4 AqTwH4x1nxN4o0201fVLwaajtJbLG3lNcSBeDKVwzR4zhP4uC2QAKr+MPAmu634h1LVbbSbgaT9sdUt3 x5s7KcGQrn/Vlgdo/iGCeCMzeA/B+seHPFWmXeraZeHS2kaO3dIzK1vIV+USqORHyQHx8pADEDmuJOr7 X5/K3+f9bn07WB+o9LW025+e3Xry3+d/7p//2Q== /9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBAxEB/8QA HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0vxHquvS3lpY6HCu64kbddyAmC2jQjczYILM2cKgIzySQFNVv CPinUJ9c1XQdV8uS902eNJZoQRHKkqlomUMSVOBhlJIBHBOeNHxPb3iaDqwt1u90ltMYpLJC86MVONig glgemCOcciqvgjQVsdC01EtbiHcq3V1JdoUnnuGUF3kBLHeSeck46Z4FfKUp5l9camnbm07Wve7e3w6W 76777tQ5T//Z /9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBAxEB/8QA HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDs/FviDWn1xbLSd8YDMrztkRwKpAZmCsCzEnCrkZ6nABqLwd4v 1NvEV5omqS+fJbSorSxg7ZFlXMbLuJZTjAKkkDnBOeLXi/Q76GHUp7GG6cSxSNG1ou+VWKnO1Rg7gemP bnNQeBPDFzb29hJNbXMCjbczvcoUmlmIBZnBydxOM5PbGeBXykXivbO6fNzab992+1tLbdT0LQ5d9Lf1 8z//2Q== /9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBAxEB/8QA HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD1zVdYnS6eC3bYqHBYDJJp+kavPLci3uG37s7Wxgj2qPVdInN0 88CeYkhyQOoP9ado+kzx3K3FwuwJyqnqTQB//9k= NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/AdvancedLoaderSettingsPage.cs0000664000175000017500000003104311660166566030102 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Security.Principal; using System.Windows.Forms; using NUnit.Util; namespace NUnit.Gui.SettingsPages { public class AdvancedLoaderSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.Label label3; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.CheckBox enableShadowCopyCheckBox; private System.Windows.Forms.Label label2; private System.Windows.Forms.HelpProvider helpProvider1; private Label label4; private TextBox shadowCopyPathTextBox; private CheckBox principalPolicyCheckBox; private Label label7; private Label label6; private GroupBox groupBox1; private ListBox principalPolicyListBox; private Label label1; private System.ComponentModel.IContainer components = null; public AdvancedLoaderSettingsPage( string key ) : base( key ) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedLoaderSettingsPage)); this.label3 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.enableShadowCopyCheckBox = new System.Windows.Forms.CheckBox(); this.label2 = new System.Windows.Forms.Label(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.shadowCopyPathTextBox = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); this.principalPolicyCheckBox = new System.Windows.Forms.CheckBox(); this.label7 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.principalPolicyListBox = new System.Windows.Forms.ListBox(); this.label1 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(8, 8); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(73, 13); this.label3.TabIndex = 0; this.label3.Text = "Shadow Copy"; // // groupBox3 // this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox3.Location = new System.Drawing.Point(139, 8); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(309, 8); this.groupBox3.TabIndex = 1; this.groupBox3.TabStop = false; // // enableShadowCopyCheckBox // this.enableShadowCopyCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.enableShadowCopyCheckBox, resources.GetString("enableShadowCopyCheckBox.HelpString")); this.enableShadowCopyCheckBox.Location = new System.Drawing.Point(24, 32); this.enableShadowCopyCheckBox.Name = "enableShadowCopyCheckBox"; this.helpProvider1.SetShowHelp(this.enableShadowCopyCheckBox, true); this.enableShadowCopyCheckBox.Size = new System.Drawing.Size(128, 17); this.enableShadowCopyCheckBox.TabIndex = 2; this.enableShadowCopyCheckBox.Text = "Enable Shadow Copy"; this.enableShadowCopyCheckBox.CheckedChanged += new System.EventHandler(this.enableShadowCopyCheckBox_CheckedChanged); // // label2 // this.label2.Location = new System.Drawing.Point(139, 101); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(260, 59); this.label2.TabIndex = 6; this.label2.Text = "Shadow copy should normally be enabled. If it is disabled, the NUnit Gui may not " + "function correctly."; // // shadowCopyPathTextBox // this.helpProvider1.SetHelpString(this.shadowCopyPathTextBox, "Leave this blank to permit NUnit to select a location under your temp directory."); this.shadowCopyPathTextBox.Location = new System.Drawing.Point(139, 65); this.shadowCopyPathTextBox.Name = "shadowCopyPathTextBox"; this.helpProvider1.SetShowHelp(this.shadowCopyPathTextBox, true); this.shadowCopyPathTextBox.Size = new System.Drawing.Size(309, 20); this.shadowCopyPathTextBox.TabIndex = 4; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(42, 66); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(66, 13); this.label4.TabIndex = 3; this.label4.Text = "Cache Path:"; // // principalPolicyCheckBox // this.principalPolicyCheckBox.AutoSize = true; this.principalPolicyCheckBox.Location = new System.Drawing.Point(24, 199); this.principalPolicyCheckBox.Name = "principalPolicyCheckBox"; this.principalPolicyCheckBox.Size = new System.Drawing.Size(214, 17); this.principalPolicyCheckBox.TabIndex = 9; this.principalPolicyCheckBox.Text = "Set Principal Policy for test AppDomains"; this.principalPolicyCheckBox.UseVisualStyleBackColor = true; this.principalPolicyCheckBox.CheckedChanged += new System.EventHandler(this.principalPolicyCheckBox_CheckedChanged); // // label7 // this.label7.AutoSize = true; this.label7.Location = new System.Drawing.Point(42, 225); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(38, 13); this.label7.TabIndex = 10; this.label7.Text = "Policy:"; // // label6 // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(8, 163); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(78, 13); this.label6.TabIndex = 7; this.label6.Text = "Principal Policy"; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(139, 163); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(309, 8); this.groupBox1.TabIndex = 8; this.groupBox1.TabStop = false; // // principalPolicyListBox // this.principalPolicyListBox.FormattingEnabled = true; this.principalPolicyListBox.Items.AddRange(new object[] { "UnauthenticatedPrincipal", "NoPrincipal", "WindowsPrincipal"}); this.principalPolicyListBox.Location = new System.Drawing.Point(139, 225); this.principalPolicyListBox.Name = "principalPolicyListBox"; this.principalPolicyListBox.Size = new System.Drawing.Size(241, 69); this.principalPolicyListBox.TabIndex = 11; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(42, 101); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(50, 13); this.label1.TabIndex = 12; this.label1.Text = "Warning:"; // // AdvancedLoaderSettingsPage // this.Controls.Add(this.label1); this.Controls.Add(this.principalPolicyListBox); this.Controls.Add(this.principalPolicyCheckBox); this.Controls.Add(this.label7); this.Controls.Add(this.label6); this.Controls.Add(this.groupBox1); this.Controls.Add(this.shadowCopyPathTextBox); this.Controls.Add(this.label4); this.Controls.Add(this.label2); this.Controls.Add(this.label3); this.Controls.Add(this.groupBox3); this.Controls.Add(this.enableShadowCopyCheckBox); this.Name = "AdvancedLoaderSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { this.settings = Services.UserSettings; enableShadowCopyCheckBox.Checked = settings.GetSetting( "Options.TestLoader.ShadowCopyFiles", true ); shadowCopyPathTextBox.Text = settings.GetSetting("Options.TestLoader.ShadowCopyPath", ""); principalPolicyCheckBox.Checked = principalPolicyListBox.Enabled = settings.GetSetting( "Options.TestLoader.SetPrincipalPolicy", false ); principalPolicyListBox.SelectedIndex = (int)(PrincipalPolicy)settings.GetSetting("Options.TestLoader.PrincipalPolicy", PrincipalPolicy.UnauthenticatedPrincipal); } public override void ApplySettings() { settings.SaveSetting( "Options.TestLoader.ShadowCopyFiles", enableShadowCopyCheckBox.Checked ); if (shadowCopyPathTextBox.Text != "") settings.SaveSetting("Options.TestLoader.ShadowCopyPath", shadowCopyPathTextBox.Text); else settings.RemoveSetting("Options.TestLoader.ShadowCopyPath"); settings.SaveSetting("Options.TestLoader.SetPrincipalPolicy", principalPolicyCheckBox.Checked); if (principalPolicyCheckBox.Checked) settings.SaveSetting("Options.TestLoader.PrincipalPolicy", (PrincipalPolicy)principalPolicyListBox.SelectedIndex); else settings.RemoveSetting("Options.TestLoader.PrincipalPolicy"); } public override bool HasChangesRequiringReload { get { bool oldShadowCopyFiles = settings.GetSetting( "Options.TestLoader.ShadowCopyFiles", true ); string oldShadowCopyPath = settings.GetSetting("Options.TestLoader.ShadowCopyPath", ""); bool oldSetPrincipalPolicy = settings.GetSetting("Options.TestLoader.SetPrincipalPolicy", false); PrincipalPolicy oldPrincipalPolicy = (PrincipalPolicy)settings.GetSetting("Options.TestLoader.PrincipalPolicy", PrincipalPolicy.UnauthenticatedPrincipal); return enableShadowCopyCheckBox.Checked != oldShadowCopyFiles || shadowCopyPathTextBox.Text != oldShadowCopyPath || principalPolicyCheckBox.Checked != oldSetPrincipalPolicy || principalPolicyListBox.SelectedIndex != (int)oldPrincipalPolicy; } } private void enableShadowCopyCheckBox_CheckedChanged(object sender, EventArgs e) { shadowCopyPathTextBox.Enabled = enableShadowCopyCheckBox.Checked; } private void principalPolicyCheckBox_CheckedChanged(object sender, EventArgs e) { principalPolicyListBox.Enabled = principalPolicyCheckBox.Checked; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/InternalTraceSettingsPage.resx0000664000175000017500000001326611660511152030345 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/ProjectEditorSettingsPage.resx0000664000175000017500000001430011660154064030362 0ustar jtaylorjtaylor text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 R0lGODlhCgAKAIMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD///// /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAACgAKAAAIHgAfCBxIsKDBgwgJAgAgcGHDhQwf OJQYMaHFiwgDAgA7 NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/VisualStudioSettingsPage.cs0000664000175000017500000001556111660166020027671 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace NUnit.Gui.SettingsPages { public class VisualStudioSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.Label label1; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.CheckBox visualStudioSupportCheckBox; private System.Windows.Forms.HelpProvider helpProvider1; private CheckBox useSolutionConfigsCheckBox; private Label label2; private Label label3; private System.ComponentModel.IContainer components = null; public VisualStudioSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VisualStudioSettingsPage)); this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.visualStudioSupportCheckBox = new System.Windows.Forms.CheckBox(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.useSolutionConfigsCheckBox = new System.Windows.Forms.CheckBox(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(68, 13); this.label1.TabIndex = 9; this.label1.Text = "Visual Studio"; // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(151, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(293, 8); this.groupBox1.TabIndex = 8; this.groupBox1.TabStop = false; // // visualStudioSupportCheckBox // this.visualStudioSupportCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.visualStudioSupportCheckBox, "If checked, Visual Studio projects and solutions may be opened or added to existi" + "ng test projects."); this.visualStudioSupportCheckBox.Location = new System.Drawing.Point(24, 24); this.visualStudioSupportCheckBox.Name = "visualStudioSupportCheckBox"; this.helpProvider1.SetShowHelp(this.visualStudioSupportCheckBox, true); this.visualStudioSupportCheckBox.Size = new System.Drawing.Size(163, 17); this.visualStudioSupportCheckBox.TabIndex = 30; this.visualStudioSupportCheckBox.Text = "Enable Visual Studio Support"; this.visualStudioSupportCheckBox.CheckedChanged += new System.EventHandler(this.visualStudioSupportCheckBox_CheckedChanged); // // useSolutionConfigsCheckBox // this.useSolutionConfigsCheckBox.AutoSize = true; this.useSolutionConfigsCheckBox.Location = new System.Drawing.Point(44, 60); this.useSolutionConfigsCheckBox.Name = "useSolutionConfigsCheckBox"; this.useSolutionConfigsCheckBox.Size = new System.Drawing.Size(255, 17); this.useSolutionConfigsCheckBox.TabIndex = 31; this.useSolutionConfigsCheckBox.Text = "Use solution configs when opening VS solutions."; this.useSolutionConfigsCheckBox.UseVisualStyleBackColor = true; // // label2 // this.label2.Location = new System.Drawing.Point(110, 89); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(322, 124); this.label2.TabIndex = 33; this.label2.Text = resources.GetString("label2.Text"); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(39, 89); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(33, 13); this.label3.TabIndex = 32; this.label3.Text = "Note:"; // // VisualStudioSettingsPage // this.Controls.Add(this.label2); this.Controls.Add(this.label3); this.Controls.Add(this.useSolutionConfigsCheckBox); this.Controls.Add(this.visualStudioSupportCheckBox); this.Controls.Add(this.groupBox1); this.Controls.Add(this.label1); this.Name = "VisualStudioSettingsPage"; this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { visualStudioSupportCheckBox.Checked = settings.GetSetting( "Options.TestLoader.VisualStudioSupport", false ); useSolutionConfigsCheckBox.Enabled = visualStudioSupportCheckBox.Checked; useSolutionConfigsCheckBox.Checked = settings.GetSetting("Options.TestLoader.VisualStudio.UseSolutionConfigs", true); } public override void ApplySettings() { settings.SaveSetting( "Options.TestLoader.VisualStudioSupport", visualStudioSupportCheckBox.Checked ); settings.SaveSetting("Options.TestLoader.VisualStudio.UseSolutionConfigs", useSolutionConfigsCheckBox.Checked); } private void visualStudioSupportCheckBox_CheckedChanged(object sender, EventArgs e) { useSolutionConfigsCheckBox.Enabled = visualStudioSupportCheckBox.Checked; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/SettingsPages/TreeSettingsPage.cs0000664000175000017500000005143111700400030026114 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.IO; using System.Reflection; using System.Windows.Forms; using NUnit.UiKit; using NUnit.Util; namespace NUnit.Gui.SettingsPages { public class TreeSettingsPage : NUnit.UiKit.SettingsPage { private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox initialDisplayComboBox; private System.Windows.Forms.CheckBox clearResultsCheckBox; private System.Windows.Forms.CheckBox saveVisualStateCheckBox; private System.Windows.Forms.CheckBox showCheckBoxesCheckBox; private System.Windows.Forms.HelpProvider helpProvider1; private System.Windows.Forms.RadioButton flatTestList; private System.Windows.Forms.RadioButton autoNamespaceSuites; private System.Windows.Forms.Label label3; private System.Windows.Forms.GroupBox groupBox2; private Label label6; private PictureBox successImage; private PictureBox failureImage; private PictureBox ignoredImage; private PictureBox inconclusiveImage; private PictureBox skippedImage; private System.ComponentModel.IContainer components = null; private Label label4; private ListBox imageSetListBox; private static string treeImageDir = PathUtils.Combine(Assembly.GetExecutingAssembly(), "Images", "Tree"); public TreeSettingsPage(string key) : base(key) { // This call is required by the Windows Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TreeSettingsPage)); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.initialDisplayComboBox = new System.Windows.Forms.ComboBox(); this.clearResultsCheckBox = new System.Windows.Forms.CheckBox(); this.saveVisualStateCheckBox = new System.Windows.Forms.CheckBox(); this.showCheckBoxesCheckBox = new System.Windows.Forms.CheckBox(); this.helpProvider1 = new System.Windows.Forms.HelpProvider(); this.flatTestList = new System.Windows.Forms.RadioButton(); this.autoNamespaceSuites = new System.Windows.Forms.RadioButton(); this.label3 = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.label6 = new System.Windows.Forms.Label(); this.successImage = new System.Windows.Forms.PictureBox(); this.failureImage = new System.Windows.Forms.PictureBox(); this.ignoredImage = new System.Windows.Forms.PictureBox(); this.inconclusiveImage = new System.Windows.Forms.PictureBox(); this.skippedImage = new System.Windows.Forms.PictureBox(); this.label4 = new System.Windows.Forms.Label(); this.imageSetListBox = new System.Windows.Forms.ListBox(); ((System.ComponentModel.ISupportInitialize)(this.successImage)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.failureImage)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.ignoredImage)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.inconclusiveImage)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.skippedImage)).BeginInit(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Location = new System.Drawing.Point(144, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(304, 8); this.groupBox1.TabIndex = 8; this.groupBox1.TabStop = false; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(55, 13); this.label1.TabIndex = 9; this.label1.Text = "Tree View"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(32, 24); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(104, 13); this.label2.TabIndex = 32; this.label2.Text = "Initial display on load"; // // initialDisplayComboBox // this.initialDisplayComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.helpProvider1.SetHelpString(this.initialDisplayComboBox, "Selects the initial display style of the tree when an assembly is loaded"); this.initialDisplayComboBox.ItemHeight = 13; this.initialDisplayComboBox.Items.AddRange(new object[] { "Auto", "Expand", "Collapse", "HideTests"}); this.initialDisplayComboBox.Location = new System.Drawing.Point(236, 24); this.initialDisplayComboBox.Name = "initialDisplayComboBox"; this.helpProvider1.SetShowHelp(this.initialDisplayComboBox, true); this.initialDisplayComboBox.Size = new System.Drawing.Size(168, 21); this.initialDisplayComboBox.TabIndex = 33; // // clearResultsCheckBox // this.clearResultsCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.clearResultsCheckBox, "If checked, any prior results are cleared when reloading"); this.clearResultsCheckBox.Location = new System.Drawing.Point(32, 129); this.clearResultsCheckBox.Name = "clearResultsCheckBox"; this.helpProvider1.SetShowHelp(this.clearResultsCheckBox, true); this.clearResultsCheckBox.Size = new System.Drawing.Size(161, 17); this.clearResultsCheckBox.TabIndex = 34; this.clearResultsCheckBox.Text = "Clear results when reloading."; // // saveVisualStateCheckBox // this.saveVisualStateCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.saveVisualStateCheckBox, "If checked, the visual state of the project is saved on exit. This includes selec" + "ted tests, categories and the state of the tree itself."); this.saveVisualStateCheckBox.Location = new System.Drawing.Point(32, 155); this.saveVisualStateCheckBox.Name = "saveVisualStateCheckBox"; this.helpProvider1.SetShowHelp(this.saveVisualStateCheckBox, true); this.saveVisualStateCheckBox.Size = new System.Drawing.Size(184, 17); this.saveVisualStateCheckBox.TabIndex = 35; this.saveVisualStateCheckBox.Text = "Save Visual State of each project"; // // showCheckBoxesCheckBox // this.showCheckBoxesCheckBox.AutoSize = true; this.helpProvider1.SetHelpString(this.showCheckBoxesCheckBox, "If selected, the tree displays checkboxes for use in selecting multiple tests."); this.showCheckBoxesCheckBox.Location = new System.Drawing.Point(32, 181); this.showCheckBoxesCheckBox.Name = "showCheckBoxesCheckBox"; this.helpProvider1.SetShowHelp(this.showCheckBoxesCheckBox, true); this.showCheckBoxesCheckBox.Size = new System.Drawing.Size(116, 17); this.showCheckBoxesCheckBox.TabIndex = 36; this.showCheckBoxesCheckBox.Text = "Show CheckBoxes"; // // flatTestList // this.flatTestList.AutoCheck = false; this.flatTestList.AutoSize = true; this.helpProvider1.SetHelpString(this.flatTestList, "If selected, the tree will consist of a flat list of fixtures, without any higher" + "-level structure beyond the assemblies."); this.flatTestList.Location = new System.Drawing.Point(32, 269); this.flatTestList.Name = "flatTestList"; this.helpProvider1.SetShowHelp(this.flatTestList, true); this.flatTestList.Size = new System.Drawing.Size(129, 17); this.flatTestList.TabIndex = 40; this.flatTestList.Text = "Flat list of TestFixtures"; this.flatTestList.Click += new System.EventHandler(this.toggleTestStructure); // // autoNamespaceSuites // this.autoNamespaceSuites.AutoCheck = false; this.autoNamespaceSuites.AutoSize = true; this.autoNamespaceSuites.Checked = true; this.helpProvider1.SetHelpString(this.autoNamespaceSuites, "If selected, the tree will follow the namespace structure of the tests, with suit" + "es automatically created at each level."); this.autoNamespaceSuites.Location = new System.Drawing.Point(32, 243); this.autoNamespaceSuites.Name = "autoNamespaceSuites"; this.helpProvider1.SetShowHelp(this.autoNamespaceSuites, true); this.autoNamespaceSuites.Size = new System.Drawing.Size(162, 17); this.autoNamespaceSuites.TabIndex = 39; this.autoNamespaceSuites.TabStop = true; this.autoNamespaceSuites.Text = "Automatic Namespace suites"; this.autoNamespaceSuites.Click += new System.EventHandler(this.toggleTestStructure); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(8, 218); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(74, 13); this.label3.TabIndex = 38; this.label3.Text = "Test Structure"; // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Location = new System.Drawing.Point(144, 218); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(304, 8); this.groupBox2.TabIndex = 37; this.groupBox2.TabStop = false; // // label6 // this.label6.BackColor = System.Drawing.SystemColors.Window; this.label6.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.label6.Location = new System.Drawing.Point(66, 81); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(137, 36); this.label6.TabIndex = 47; // // successImage // this.successImage.Image = ((System.Drawing.Image)(resources.GetObject("successImage.Image"))); this.successImage.Location = new System.Drawing.Point(78, 92); this.successImage.Name = "successImage"; this.successImage.Size = new System.Drawing.Size(16, 16); this.successImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.successImage.TabIndex = 48; this.successImage.TabStop = false; // // failureImage // this.failureImage.Image = ((System.Drawing.Image)(resources.GetObject("failureImage.Image"))); this.failureImage.Location = new System.Drawing.Point(103, 92); this.failureImage.Name = "failureImage"; this.failureImage.Size = new System.Drawing.Size(16, 16); this.failureImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.failureImage.TabIndex = 49; this.failureImage.TabStop = false; // // ignoredImage // this.ignoredImage.Image = ((System.Drawing.Image)(resources.GetObject("ignoredImage.Image"))); this.ignoredImage.Location = new System.Drawing.Point(128, 92); this.ignoredImage.Name = "ignoredImage"; this.ignoredImage.Size = new System.Drawing.Size(16, 16); this.ignoredImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.ignoredImage.TabIndex = 50; this.ignoredImage.TabStop = false; // // inconclusiveImage // this.inconclusiveImage.Image = ((System.Drawing.Image)(resources.GetObject("inconclusiveImage.Image"))); this.inconclusiveImage.Location = new System.Drawing.Point(152, 92); this.inconclusiveImage.Name = "inconclusiveImage"; this.inconclusiveImage.Size = new System.Drawing.Size(16, 16); this.inconclusiveImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.inconclusiveImage.TabIndex = 51; this.inconclusiveImage.TabStop = false; // // skippedImage // this.skippedImage.Image = ((System.Drawing.Image)(resources.GetObject("skippedImage.Image"))); this.skippedImage.Location = new System.Drawing.Point(177, 92); this.skippedImage.Name = "skippedImage"; this.skippedImage.Size = new System.Drawing.Size(16, 16); this.skippedImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.skippedImage.TabIndex = 52; this.skippedImage.TabStop = false; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(32, 60); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(66, 13); this.label4.TabIndex = 53; this.label4.Text = "Tree Images"; // // imageSetListBox // this.imageSetListBox.FormattingEnabled = true; this.imageSetListBox.Location = new System.Drawing.Point(236, 61); this.imageSetListBox.Name = "imageSetListBox"; this.imageSetListBox.Size = new System.Drawing.Size(168, 56); this.imageSetListBox.TabIndex = 54; this.imageSetListBox.SelectedIndexChanged += new System.EventHandler(this.imageSetListBox_SelectedIndexChanged); // // TreeSettingsPage // this.Controls.Add(this.imageSetListBox); this.Controls.Add(this.label4); this.Controls.Add(this.skippedImage); this.Controls.Add(this.inconclusiveImage); this.Controls.Add(this.ignoredImage); this.Controls.Add(this.failureImage); this.Controls.Add(this.successImage); this.Controls.Add(this.label6); this.Controls.Add(this.label3); this.Controls.Add(this.flatTestList); this.Controls.Add(this.autoNamespaceSuites); this.Controls.Add(this.groupBox2); this.Controls.Add(this.showCheckBoxesCheckBox); this.Controls.Add(this.label2); this.Controls.Add(this.initialDisplayComboBox); this.Controls.Add(this.clearResultsCheckBox); this.Controls.Add(this.saveVisualStateCheckBox); this.Controls.Add(this.groupBox1); this.Controls.Add(this.label1); this.Name = "TreeSettingsPage"; ((System.ComponentModel.ISupportInitialize)(this.successImage)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.failureImage)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.ignoredImage)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.inconclusiveImage)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.skippedImage)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion public override void LoadSettings() { initialDisplayComboBox.SelectedIndex = (int)(TestSuiteTreeView.DisplayStyle)settings.GetSetting( "Gui.TestTree.InitialTreeDisplay", TestSuiteTreeView.DisplayStyle.Auto ); clearResultsCheckBox.Checked = settings.GetSetting( "Options.TestLoader.ClearResultsOnReload", true ); saveVisualStateCheckBox.Checked = settings.GetSetting( "Gui.TestTree.SaveVisualState", true ); showCheckBoxesCheckBox.Checked = settings.GetSetting( "Options.ShowCheckBoxes", false ); string[] altDirs = Directory.Exists(treeImageDir) ? Directory.GetDirectories(treeImageDir) : new string[0]; foreach (string altDir in altDirs) imageSetListBox.Items.Add(Path.GetFileName(altDir)); string imageSet = settings.GetSetting("Gui.TestTree.AlternateImageSet", "Default"); if (imageSetListBox.Items.Contains(imageSet)) imageSetListBox.SelectedItem = imageSet; autoNamespaceSuites.Checked = settings.GetSetting( "Options.TestLoader.AutoNamespaceSuites", true ); flatTestList.Checked = !autoNamespaceSuites.Checked; } public override void ApplySettings() { settings.SaveSetting( "Gui.TestTree.InitialTreeDisplay", (TestSuiteTreeView.DisplayStyle)initialDisplayComboBox.SelectedIndex ); settings.SaveSetting( "Options.TestLoader.ClearResultsOnReload", clearResultsCheckBox.Checked ); settings.SaveSetting( "Gui.TestTree.SaveVisualState", saveVisualStateCheckBox.Checked ); settings.SaveSetting( "Options.ShowCheckBoxes", showCheckBoxesCheckBox.Checked ); if (imageSetListBox.SelectedIndex >= 0) settings.SaveSetting("Gui.TestTree.AlternateImageSet", imageSetListBox.SelectedItem); settings.SaveSetting( "Options.TestLoader.AutoNamespaceSuites", autoNamespaceSuites.Checked ); } private void toggleTestStructure(object sender, System.EventArgs e) { bool auto = autoNamespaceSuites.Checked = !autoNamespaceSuites.Checked; flatTestList.Checked = !auto; } public override bool HasChangesRequiringReload { get { return settings.GetSetting("Options.TestLoader.AutoNamespaceSuites", true) != autoNamespaceSuites.Checked; } } private void imageSetListBox_SelectedIndexChanged(object sender, EventArgs e) { string imageSet = imageSetListBox.SelectedItem as string; if (imageSet != null) DisplayImageSet(imageSet); } private void DisplayImageSet(string imageSet) { string imageSetDir = Path.Combine(treeImageDir, imageSet); DisplayImage(imageSetDir, "Success", successImage); DisplayImage(imageSetDir, "Failure", failureImage); DisplayImage(imageSetDir, "Ignored", ignoredImage); DisplayImage(imageSetDir, "Inconclusive", inconclusiveImage); DisplayImage(imageSetDir, "Skipped", skippedImage); } private void DisplayImage(string imageDir, string filename, PictureBox box) { string[] extensions = { ".png", ".jpg" }; foreach (string ext in extensions) { string filePath = Path.Combine(imageDir, filename + ext); if (File.Exists(filePath)) { box.Load(filePath); break; } } } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AddinDialog.cs0000664000175000017500000002013111504175260022267 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using NUnit.Core; using NUnit.Core.Extensibility; namespace NUnit.Gui { /// /// Summary description for AddinDialog. /// public class AddinDialog : System.Windows.Forms.Form { private IList addins; private System.Windows.Forms.TextBox descriptionTextBox; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; private System.Windows.Forms.ListView addinListView; private System.Windows.Forms.ColumnHeader addinNameColumn; private System.Windows.Forms.ColumnHeader addinStatusColumn; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox messageTextBox; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public AddinDialog() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(AddinDialog)); this.addinListView = new System.Windows.Forms.ListView(); this.addinNameColumn = new System.Windows.Forms.ColumnHeader(); this.addinStatusColumn = new System.Windows.Forms.ColumnHeader(); this.descriptionTextBox = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.button1 = new System.Windows.Forms.Button(); this.label2 = new System.Windows.Forms.Label(); this.messageTextBox = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // addinListView // this.addinListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.addinListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.addinNameColumn, this.addinStatusColumn}); this.addinListView.FullRowSelect = true; this.addinListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.addinListView.Location = new System.Drawing.Point(8, 8); this.addinListView.MultiSelect = false; this.addinListView.Name = "addinListView"; this.addinListView.Size = new System.Drawing.Size(448, 136); this.addinListView.TabIndex = 0; this.addinListView.View = System.Windows.Forms.View.Details; this.addinListView.Resize += new System.EventHandler(this.addinListView_Resize); this.addinListView.SelectedIndexChanged += new System.EventHandler(this.addinListView_SelectedIndexChanged); // // addinNameColumn // this.addinNameColumn.Text = "Addin"; this.addinNameColumn.Width = 352; // // addinStatusColumn // this.addinStatusColumn.Text = "Status"; this.addinStatusColumn.Width = 89; // // descriptionTextBox // this.descriptionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.descriptionTextBox.Location = new System.Drawing.Point(8, 184); this.descriptionTextBox.Multiline = true; this.descriptionTextBox.Name = "descriptionTextBox"; this.descriptionTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.descriptionTextBox.Size = new System.Drawing.Size(448, 56); this.descriptionTextBox.TabIndex = 1; this.descriptionTextBox.Text = ""; // // label1 // this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label1.Location = new System.Drawing.Point(8, 160); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(304, 16); this.label1.TabIndex = 2; this.label1.Text = "Description:"; // // button1 // this.button1.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.button1.Location = new System.Drawing.Point(192, 344); this.button1.Name = "button1"; this.button1.TabIndex = 3; this.button1.Text = "OK"; this.button1.Click += new System.EventHandler(this.button1_Click); // // label2 // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label2.Location = new System.Drawing.Point(8, 256); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(304, 16); this.label2.TabIndex = 5; this.label2.Text = " Message:"; // // messageTextBox // this.messageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.messageTextBox.Location = new System.Drawing.Point(8, 280); this.messageTextBox.Multiline = true; this.messageTextBox.Name = "messageTextBox"; this.messageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.messageTextBox.Size = new System.Drawing.Size(448, 56); this.messageTextBox.TabIndex = 4; this.messageTextBox.Text = ""; // // AddinDialog // this.ClientSize = new System.Drawing.Size(464, 376); this.Controls.Add(this.label2); this.Controls.Add(this.messageTextBox); this.Controls.Add(this.button1); this.Controls.Add(this.label1); this.Controls.Add(this.descriptionTextBox); this.Controls.Add(this.addinListView); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "AddinDialog"; this.ShowInTaskbar = false; this.Text = "Registered Addins"; this.Load += new System.EventHandler(this.AddinDialog_Load); this.ResumeLayout(false); } #endregion private void AddinDialog_Load(object sender, System.EventArgs e) { this.addins = NUnit.Util.Services.AddinRegistry.Addins; foreach( Addin addin in addins ) { ListViewItem item = new ListViewItem( new string[] { addin.Name, addin.Status.ToString() } ); addinListView.Items.Add( item ); } if ( addinListView.Items.Count > 0 ) addinListView.Items[0].Selected = true; AutoSizeFirstColumnOfListView(); } private void button1_Click(object sender, System.EventArgs e) { this.Close(); } private void addinListView_SelectedIndexChanged(object sender, System.EventArgs e) { if ( addinListView.SelectedIndices.Count > 0 ) { int index = addinListView.SelectedIndices[0]; Addin addin = (Addin)addins[index]; this.descriptionTextBox.Text = addin.Description; this.messageTextBox.Text = addin.Message; } } private void addinListView_Resize(object sender, System.EventArgs e) { AutoSizeFirstColumnOfListView(); } private void AutoSizeFirstColumnOfListView() { int width = addinListView.ClientSize.Width; for( int i = 1; i < addinListView.Columns.Count; i++ ) width -= addinListView.Columns[i].Width; addinListView.Columns[0].Width = width; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/nunit-gui.csproj0000664000175000017500000002371211700667032022753 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148} Debug AnyCPU nunit-gui-runner JScript Grid IE50 false Library NUnit.Gui OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 1699 true false false 4 none prompt System System.Data System.Drawing System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.uikit.dll {27531BBF-183D-4C3A-935B-D840B9F1A3A4} False {3E87A106-EB20-4147-84C8-95B0BB43A1D4} nunit.uiexception.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} nunit.core.dll False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False CommonAssemblyInfo.cs Form Form Form Form UserControl UserControl UserControl RuntimeSelectionSettingsPage.cs UserControl UserControl InternalTraceSettingsPage.cs UserControl ProjectEditorSettingsPage.cs UserControl UserControl UserControl UserControl Form AboutBox.cs Designer AddinDialog.cs Designer ExceptionDetailsForm.cs Designer NUnitForm.cs Designer OptionsDialog.cs Designer AdvancedLoaderSettingsPage.cs Designer AssemblyReloadSettingsPage.cs Designer RuntimeSelectionSettingsPage.cs Designer GuiSettingsPage.cs Designer InternalTraceSettingsPage.cs Designer ProjectEditorSettingsPage.cs Designer TestLoaderSettingsPage.cs Designer TestResultSettingsPage.cs Designer TreeSettingsPage.cs Designer VisualStudioSettingsPage.cs Designer NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/NUnitForm.cs0000664000175000017500000021160211717422646022027 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Drawing; using System.Collections; using System.Configuration; using System.ComponentModel; using System.ComponentModel.Design; using System.Globalization; using System.Windows.Forms; using System.IO; using System.Reflection; using System.Text; namespace NUnit.Gui { using NUnit.Core; using NUnit.Util; using NUnit.UiKit; using CP.Windows.Forms; public class NUnitForm : NUnitFormBase { static Logger log = InternalTrace.GetLogger(typeof(NUnitForm)); #region Instance variables // Handlers for our recentFiles and recentProjects private RecentFileMenuHandler recentProjectsMenuHandler; private RecentFiles recentFilesService; private ISettings userSettings; private string displayFormat = "Full"; private LongRunningOperationDisplay longOpDisplay; private System.Drawing.Font fixedFont; // Our current run command line options private GuiOptions guiOptions; // Our 'presenter' - under development private NUnitPresenter presenter; private System.ComponentModel.IContainer components; private System.Windows.Forms.Panel leftPanel; public System.Windows.Forms.Splitter treeSplitter; public System.Windows.Forms.Panel rightPanel; private TestTree testTree; public System.Windows.Forms.GroupBox groupBox1; public System.Windows.Forms.Button runButton; private System.Windows.Forms.Button stopButton; public NUnit.UiKit.TestProgressBar progressBar; private CP.Windows.Forms.ExpandingLabel runCount; public NUnit.UiKit.ResultTabs resultTabs; public NUnit.UiKit.StatusBar statusBar; public System.Windows.Forms.ToolTip toolTip; public System.Windows.Forms.MainMenu mainMenu; public System.Windows.Forms.MenuItem fileMenu; private System.Windows.Forms.MenuItem saveMenuItem; private System.Windows.Forms.MenuItem saveAsMenuItem; private System.Windows.Forms.MenuItem newMenuItem; private System.Windows.Forms.MenuItem openMenuItem; private System.Windows.Forms.MenuItem recentProjectsMenu; private System.Windows.Forms.MenuItem fileMenuSeparator1; private System.Windows.Forms.MenuItem fileMenuSeparator2; public System.Windows.Forms.MenuItem fileMenuSeparator4; private System.Windows.Forms.MenuItem closeMenuItem; public System.Windows.Forms.MenuItem exitMenuItem; private System.Windows.Forms.MenuItem projectMenu; private System.Windows.Forms.MenuItem editProjectMenuItem; private System.Windows.Forms.MenuItem configMenuItem; private System.Windows.Forms.MenuItem projectMenuSeparator1; private System.Windows.Forms.MenuItem projectMenuSeparator2; private System.Windows.Forms.MenuItem toolsMenu; private System.Windows.Forms.MenuItem settingsMenuItem; private System.Windows.Forms.MenuItem saveXmlResultsMenuItem; public System.Windows.Forms.MenuItem helpMenuItem; public System.Windows.Forms.MenuItem helpItem; public System.Windows.Forms.MenuItem helpMenuSeparator1; public System.Windows.Forms.MenuItem aboutMenuItem; private System.Windows.Forms.MenuItem addVSProjectMenuItem; private System.Windows.Forms.MenuItem exceptionDetailsMenuItem; private System.Windows.Forms.MenuItem viewMenu; private System.Windows.Forms.MenuItem statusBarMenuItem; private System.Windows.Forms.MenuItem toolsMenuSeparator2; private System.Windows.Forms.MenuItem miniGuiMenuItem; private System.Windows.Forms.MenuItem fullGuiMenuItem; private System.Windows.Forms.MenuItem fontChangeMenuItem; private System.Windows.Forms.MenuItem defaultFontMenuItem; private System.Windows.Forms.MenuItem decreaseFontMenuItem; private System.Windows.Forms.MenuItem increaseFontMenuItem; private System.Windows.Forms.MenuItem testMenu; private System.Windows.Forms.MenuItem runAllMenuItem; private System.Windows.Forms.MenuItem runSelectedMenuItem; private System.Windows.Forms.MenuItem runFailedMenuItem; private System.Windows.Forms.MenuItem stopRunMenuItem; private System.Windows.Forms.MenuItem addinInfoMenuItem; private System.Windows.Forms.MenuItem viewMenuSeparator1; private System.Windows.Forms.MenuItem viewMenuSeparator2; private System.Windows.Forms.MenuItem viewMenuSeparator3; private System.Windows.Forms.MenuItem fontMenuSeparator; private System.Windows.Forms.MenuItem testMenuSeparator; private System.Windows.Forms.MenuItem guiFontMenuItem; private System.Windows.Forms.MenuItem fixedFontMenuItem; private System.Windows.Forms.MenuItem increaseFixedFontMenuItem; private System.Windows.Forms.MenuItem decreaseFixedFontMenuItem; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem restoreFixedFontMenuItem; private System.Windows.Forms.MenuItem reloadTestsMenuItem; private System.Windows.Forms.MenuItem reloadProjectMenuItem; private System.Windows.Forms.MenuItem menuItem2; private System.Windows.Forms.MenuItem toolsMenuSeparator1; private System.Windows.Forms.MenuItem assemblyDetailsMenuItem; private MenuItem runtimeMenuItem; private MenuItem openLogDirectoryMenuItem; private ExpandingLabel suiteName; private System.Windows.Forms.MenuItem addAssemblyMenuItem; #endregion #region Construction and Disposal public NUnitForm( GuiOptions guiOptions ) : base("NUnit") { InitializeComponent(); this.guiOptions = guiOptions; this.recentFilesService = Services.RecentFiles; this.userSettings = Services.UserSettings; this.presenter = new NUnitPresenter(this, TestLoader); } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NUnitForm)); this.statusBar = new NUnit.UiKit.StatusBar(); this.mainMenu = new System.Windows.Forms.MainMenu(this.components); this.fileMenu = new System.Windows.Forms.MenuItem(); this.newMenuItem = new System.Windows.Forms.MenuItem(); this.openMenuItem = new System.Windows.Forms.MenuItem(); this.closeMenuItem = new System.Windows.Forms.MenuItem(); this.fileMenuSeparator1 = new System.Windows.Forms.MenuItem(); this.saveMenuItem = new System.Windows.Forms.MenuItem(); this.saveAsMenuItem = new System.Windows.Forms.MenuItem(); this.fileMenuSeparator2 = new System.Windows.Forms.MenuItem(); this.reloadProjectMenuItem = new System.Windows.Forms.MenuItem(); this.reloadTestsMenuItem = new System.Windows.Forms.MenuItem(); this.runtimeMenuItem = new System.Windows.Forms.MenuItem(); this.menuItem2 = new System.Windows.Forms.MenuItem(); this.recentProjectsMenu = new System.Windows.Forms.MenuItem(); this.fileMenuSeparator4 = new System.Windows.Forms.MenuItem(); this.exitMenuItem = new System.Windows.Forms.MenuItem(); this.viewMenu = new System.Windows.Forms.MenuItem(); this.fullGuiMenuItem = new System.Windows.Forms.MenuItem(); this.miniGuiMenuItem = new System.Windows.Forms.MenuItem(); this.viewMenuSeparator1 = new System.Windows.Forms.MenuItem(); this.viewMenuSeparator2 = new System.Windows.Forms.MenuItem(); this.guiFontMenuItem = new System.Windows.Forms.MenuItem(); this.increaseFontMenuItem = new System.Windows.Forms.MenuItem(); this.decreaseFontMenuItem = new System.Windows.Forms.MenuItem(); this.fontMenuSeparator = new System.Windows.Forms.MenuItem(); this.fontChangeMenuItem = new System.Windows.Forms.MenuItem(); this.defaultFontMenuItem = new System.Windows.Forms.MenuItem(); this.fixedFontMenuItem = new System.Windows.Forms.MenuItem(); this.increaseFixedFontMenuItem = new System.Windows.Forms.MenuItem(); this.decreaseFixedFontMenuItem = new System.Windows.Forms.MenuItem(); this.menuItem1 = new System.Windows.Forms.MenuItem(); this.restoreFixedFontMenuItem = new System.Windows.Forms.MenuItem(); this.viewMenuSeparator3 = new System.Windows.Forms.MenuItem(); this.statusBarMenuItem = new System.Windows.Forms.MenuItem(); this.projectMenu = new System.Windows.Forms.MenuItem(); this.configMenuItem = new System.Windows.Forms.MenuItem(); this.projectMenuSeparator1 = new System.Windows.Forms.MenuItem(); this.addAssemblyMenuItem = new System.Windows.Forms.MenuItem(); this.addVSProjectMenuItem = new System.Windows.Forms.MenuItem(); this.projectMenuSeparator2 = new System.Windows.Forms.MenuItem(); this.editProjectMenuItem = new System.Windows.Forms.MenuItem(); this.testMenu = new System.Windows.Forms.MenuItem(); this.runAllMenuItem = new System.Windows.Forms.MenuItem(); this.runSelectedMenuItem = new System.Windows.Forms.MenuItem(); this.runFailedMenuItem = new System.Windows.Forms.MenuItem(); this.testMenuSeparator = new System.Windows.Forms.MenuItem(); this.stopRunMenuItem = new System.Windows.Forms.MenuItem(); this.toolsMenu = new System.Windows.Forms.MenuItem(); this.assemblyDetailsMenuItem = new System.Windows.Forms.MenuItem(); this.saveXmlResultsMenuItem = new System.Windows.Forms.MenuItem(); this.exceptionDetailsMenuItem = new System.Windows.Forms.MenuItem(); this.openLogDirectoryMenuItem = new System.Windows.Forms.MenuItem(); this.toolsMenuSeparator1 = new System.Windows.Forms.MenuItem(); this.settingsMenuItem = new System.Windows.Forms.MenuItem(); this.toolsMenuSeparator2 = new System.Windows.Forms.MenuItem(); this.addinInfoMenuItem = new System.Windows.Forms.MenuItem(); this.helpItem = new System.Windows.Forms.MenuItem(); this.helpMenuItem = new System.Windows.Forms.MenuItem(); this.helpMenuSeparator1 = new System.Windows.Forms.MenuItem(); this.aboutMenuItem = new System.Windows.Forms.MenuItem(); this.treeSplitter = new System.Windows.Forms.Splitter(); this.rightPanel = new System.Windows.Forms.Panel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.suiteName = new CP.Windows.Forms.ExpandingLabel(); this.runCount = new CP.Windows.Forms.ExpandingLabel(); this.stopButton = new System.Windows.Forms.Button(); this.runButton = new System.Windows.Forms.Button(); this.progressBar = new NUnit.UiKit.TestProgressBar(); this.resultTabs = new NUnit.UiKit.ResultTabs(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.testTree = new NUnit.UiKit.TestTree(); this.leftPanel = new System.Windows.Forms.Panel(); this.rightPanel.SuspendLayout(); this.groupBox1.SuspendLayout(); this.leftPanel.SuspendLayout(); this.SuspendLayout(); // // statusBar // this.statusBar.DisplayTestProgress = true; this.statusBar.Location = new System.Drawing.Point(0, 407); this.statusBar.Name = "statusBar"; this.statusBar.ShowPanels = true; this.statusBar.Size = new System.Drawing.Size(744, 24); this.statusBar.TabIndex = 0; this.statusBar.Text = "Status"; // // mainMenu // this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.fileMenu, this.viewMenu, this.projectMenu, this.testMenu, this.toolsMenu, this.helpItem}); // // fileMenu // this.fileMenu.Index = 0; this.fileMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.newMenuItem, this.openMenuItem, this.closeMenuItem, this.fileMenuSeparator1, this.saveMenuItem, this.saveAsMenuItem, this.fileMenuSeparator2, this.reloadProjectMenuItem, this.reloadTestsMenuItem, this.runtimeMenuItem, this.menuItem2, this.recentProjectsMenu, this.fileMenuSeparator4, this.exitMenuItem}); this.fileMenu.Text = "&File"; this.fileMenu.Popup += new System.EventHandler(this.fileMenu_Popup); // // newMenuItem // this.newMenuItem.Index = 0; this.newMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlN; this.newMenuItem.Text = "&New Project..."; this.newMenuItem.Click += new System.EventHandler(this.newMenuItem_Click); // // openMenuItem // this.openMenuItem.Index = 1; this.openMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlO; this.openMenuItem.Text = "&Open Project..."; this.openMenuItem.Click += new System.EventHandler(this.openMenuItem_Click); // // closeMenuItem // this.closeMenuItem.Index = 2; this.closeMenuItem.Text = "&Close"; this.closeMenuItem.Click += new System.EventHandler(this.closeMenuItem_Click); // // fileMenuSeparator1 // this.fileMenuSeparator1.Index = 3; this.fileMenuSeparator1.Text = "-"; // // saveMenuItem // this.saveMenuItem.Index = 4; this.saveMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlS; this.saveMenuItem.Text = "&Save"; this.saveMenuItem.Click += new System.EventHandler(this.saveMenuItem_Click); // // saveAsMenuItem // this.saveAsMenuItem.Index = 5; this.saveAsMenuItem.Text = "Save &As..."; this.saveAsMenuItem.Click += new System.EventHandler(this.saveAsMenuItem_Click); // // fileMenuSeparator2 // this.fileMenuSeparator2.Index = 6; this.fileMenuSeparator2.Text = "-"; // // reloadProjectMenuItem // this.reloadProjectMenuItem.Index = 7; this.reloadProjectMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlL; this.reloadProjectMenuItem.Text = "Re&load Project"; this.reloadProjectMenuItem.Click += new System.EventHandler(this.reloadProjectMenuItem_Click); // // reloadTestsMenuItem // this.reloadTestsMenuItem.Index = 8; this.reloadTestsMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlR; this.reloadTestsMenuItem.Text = "&Reload Tests"; this.reloadTestsMenuItem.Click += new System.EventHandler(this.reloadTestsMenuItem_Click); // // runtimeMenuItem // this.runtimeMenuItem.Index = 9; this.runtimeMenuItem.Text = " Select R&untime"; // // menuItem2 // this.menuItem2.Index = 10; this.menuItem2.Text = "-"; // // recentProjectsMenu // this.recentProjectsMenu.Index = 11; this.recentProjectsMenu.Text = "Recent &Projects"; // // fileMenuSeparator4 // this.fileMenuSeparator4.Index = 12; this.fileMenuSeparator4.Text = "-"; // // exitMenuItem // this.exitMenuItem.Index = 13; this.exitMenuItem.Text = "E&xit"; this.exitMenuItem.Click += new System.EventHandler(this.exitMenuItem_Click); // // viewMenu // this.viewMenu.Index = 1; this.viewMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.fullGuiMenuItem, this.miniGuiMenuItem, this.viewMenuSeparator1, this.viewMenuSeparator2, this.guiFontMenuItem, this.fixedFontMenuItem, this.viewMenuSeparator3, this.statusBarMenuItem}); this.viewMenu.Text = "&View"; this.viewMenu.Popup += new System.EventHandler(this.viewMenu_Popup); // // fullGuiMenuItem // this.fullGuiMenuItem.Checked = true; this.fullGuiMenuItem.Index = 0; this.fullGuiMenuItem.RadioCheck = true; this.fullGuiMenuItem.Text = "&Full GUI"; this.fullGuiMenuItem.Click += new System.EventHandler(this.fullGuiMenuItem_Click); // // miniGuiMenuItem // this.miniGuiMenuItem.Index = 1; this.miniGuiMenuItem.RadioCheck = true; this.miniGuiMenuItem.Text = "&Mini GUI"; this.miniGuiMenuItem.Click += new System.EventHandler(this.miniGuiMenuItem_Click); // // viewMenuSeparator1 // this.viewMenuSeparator1.Index = 2; this.viewMenuSeparator1.Text = "-"; // // viewMenuSeparator2 // this.viewMenuSeparator2.Index = 3; this.viewMenuSeparator2.Text = "-"; // // guiFontMenuItem // this.guiFontMenuItem.Index = 4; this.guiFontMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.increaseFontMenuItem, this.decreaseFontMenuItem, this.fontMenuSeparator, this.fontChangeMenuItem, this.defaultFontMenuItem}); this.guiFontMenuItem.Text = "GUI Fo&nt"; // // increaseFontMenuItem // this.increaseFontMenuItem.Index = 0; this.increaseFontMenuItem.Text = "&Increase"; this.increaseFontMenuItem.Click += new System.EventHandler(this.increaseFontMenuItem_Click); // // decreaseFontMenuItem // this.decreaseFontMenuItem.Index = 1; this.decreaseFontMenuItem.Text = "&Decrease"; this.decreaseFontMenuItem.Click += new System.EventHandler(this.decreaseFontMenuItem_Click); // // fontMenuSeparator // this.fontMenuSeparator.Index = 2; this.fontMenuSeparator.Text = "-"; // // fontChangeMenuItem // this.fontChangeMenuItem.Index = 3; this.fontChangeMenuItem.Text = "&Change..."; this.fontChangeMenuItem.Click += new System.EventHandler(this.fontChangeMenuItem_Click); // // defaultFontMenuItem // this.defaultFontMenuItem.Index = 4; this.defaultFontMenuItem.Text = "&Restore"; this.defaultFontMenuItem.Click += new System.EventHandler(this.defaultFontMenuItem_Click); // // fixedFontMenuItem // this.fixedFontMenuItem.Index = 5; this.fixedFontMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.increaseFixedFontMenuItem, this.decreaseFixedFontMenuItem, this.menuItem1, this.restoreFixedFontMenuItem}); this.fixedFontMenuItem.Text = "Fi&xed Font"; // // increaseFixedFontMenuItem // this.increaseFixedFontMenuItem.Index = 0; this.increaseFixedFontMenuItem.Text = "&Increase"; this.increaseFixedFontMenuItem.Click += new System.EventHandler(this.increaseFixedFontMenuItem_Click); // // decreaseFixedFontMenuItem // this.decreaseFixedFontMenuItem.Index = 1; this.decreaseFixedFontMenuItem.Text = "&Decrease"; this.decreaseFixedFontMenuItem.Click += new System.EventHandler(this.decreaseFixedFontMenuItem_Click); // // menuItem1 // this.menuItem1.Index = 2; this.menuItem1.Text = "-"; // // restoreFixedFontMenuItem // this.restoreFixedFontMenuItem.Index = 3; this.restoreFixedFontMenuItem.Text = "&Restore"; this.restoreFixedFontMenuItem.Click += new System.EventHandler(this.restoreFixedFontMenuItem_Click); // // viewMenuSeparator3 // this.viewMenuSeparator3.Index = 6; this.viewMenuSeparator3.Text = "-"; // // statusBarMenuItem // this.statusBarMenuItem.Checked = true; this.statusBarMenuItem.Index = 7; this.statusBarMenuItem.Text = "&Status Bar"; this.statusBarMenuItem.Click += new System.EventHandler(this.statusBarMenuItem_Click); // // projectMenu // this.projectMenu.Index = 2; this.projectMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.configMenuItem, this.projectMenuSeparator1, this.addAssemblyMenuItem, this.addVSProjectMenuItem, this.projectMenuSeparator2, this.editProjectMenuItem}); this.projectMenu.Text = "&Project"; this.projectMenu.Visible = false; this.projectMenu.Popup += new System.EventHandler(this.projectMenu_Popup); // // configMenuItem // this.configMenuItem.Index = 0; this.configMenuItem.Text = "&Configurations"; // // projectMenuSeparator1 // this.projectMenuSeparator1.Index = 1; this.projectMenuSeparator1.Text = "-"; // // addAssemblyMenuItem // this.addAssemblyMenuItem.Index = 2; this.addAssemblyMenuItem.Text = "Add Assembly..."; this.addAssemblyMenuItem.Click += new System.EventHandler(this.addAssemblyMenuItem_Click); // // addVSProjectMenuItem // this.addVSProjectMenuItem.Index = 3; this.addVSProjectMenuItem.Text = "Add VS Project..."; this.addVSProjectMenuItem.Click += new System.EventHandler(this.addVSProjectMenuItem_Click); // // projectMenuSeparator2 // this.projectMenuSeparator2.Index = 4; this.projectMenuSeparator2.Text = "-"; // // editProjectMenuItem // this.editProjectMenuItem.Index = 5; this.editProjectMenuItem.Text = "Edit..."; this.editProjectMenuItem.Click += new System.EventHandler(this.editProjectMenuItem_Click); // // testMenu // this.testMenu.Index = 3; this.testMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.runAllMenuItem, this.runSelectedMenuItem, this.runFailedMenuItem, this.testMenuSeparator, this.stopRunMenuItem}); this.testMenu.Text = "&Tests"; // // runAllMenuItem // this.runAllMenuItem.Index = 0; this.runAllMenuItem.Shortcut = System.Windows.Forms.Shortcut.F5; this.runAllMenuItem.Text = "&Run All"; this.runAllMenuItem.Click += new System.EventHandler(this.runAllMenuItem_Click); // // runSelectedMenuItem // this.runSelectedMenuItem.Index = 1; this.runSelectedMenuItem.Shortcut = System.Windows.Forms.Shortcut.F6; this.runSelectedMenuItem.Text = "Run &Selected"; this.runSelectedMenuItem.Click += new System.EventHandler(this.runSelectedMenuItem_Click); // // runFailedMenuItem // this.runFailedMenuItem.Enabled = false; this.runFailedMenuItem.Index = 2; this.runFailedMenuItem.Shortcut = System.Windows.Forms.Shortcut.F7; this.runFailedMenuItem.Text = "Run &Failed"; this.runFailedMenuItem.Click += new System.EventHandler(this.runFailedMenuItem_Click); // // testMenuSeparator // this.testMenuSeparator.Index = 3; this.testMenuSeparator.Text = "-"; // // stopRunMenuItem // this.stopRunMenuItem.Index = 4; this.stopRunMenuItem.Text = "S&top Run"; this.stopRunMenuItem.Click += new System.EventHandler(this.stopRunMenuItem_Click); // // toolsMenu // this.toolsMenu.Index = 4; this.toolsMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.assemblyDetailsMenuItem, this.saveXmlResultsMenuItem, this.exceptionDetailsMenuItem, this.openLogDirectoryMenuItem, this.toolsMenuSeparator1, this.settingsMenuItem, this.toolsMenuSeparator2, this.addinInfoMenuItem}); this.toolsMenu.Text = "T&ools"; this.toolsMenu.Popup += new System.EventHandler(this.toolsMenu_Popup); // // assemblyDetailsMenuItem // this.assemblyDetailsMenuItem.Index = 0; this.assemblyDetailsMenuItem.Text = "&Test Assemblies..."; this.assemblyDetailsMenuItem.Click += new System.EventHandler(this.assemblyDetailsMenuItem_Click); // // saveXmlResultsMenuItem // this.saveXmlResultsMenuItem.Index = 1; this.saveXmlResultsMenuItem.Text = "&Save Results as XML..."; this.saveXmlResultsMenuItem.Click += new System.EventHandler(this.saveXmlResultsMenuItem_Click); // // exceptionDetailsMenuItem // this.exceptionDetailsMenuItem.Index = 2; this.exceptionDetailsMenuItem.Text = "&Exception Details..."; this.exceptionDetailsMenuItem.Click += new System.EventHandler(this.exceptionDetailsMenuItem_Click); // // openLogDirectoryMenuItem // this.openLogDirectoryMenuItem.Index = 3; this.openLogDirectoryMenuItem.Text = "Open &Log Directory..."; this.openLogDirectoryMenuItem.Click += new System.EventHandler(this.openLogDirectoryMenuItem_Click); // // toolsMenuSeparator1 // this.toolsMenuSeparator1.Index = 4; this.toolsMenuSeparator1.Text = "-"; // // settingsMenuItem // this.settingsMenuItem.Index = 5; this.settingsMenuItem.Text = "&Settings..."; this.settingsMenuItem.Click += new System.EventHandler(this.settingsMenuItem_Click); // // toolsMenuSeparator2 // this.toolsMenuSeparator2.Index = 6; this.toolsMenuSeparator2.Text = "-"; // // addinInfoMenuItem // this.addinInfoMenuItem.Index = 7; this.addinInfoMenuItem.Text = "Addins..."; this.addinInfoMenuItem.Click += new System.EventHandler(this.addinInfoMenuItem_Click); // // helpItem // this.helpItem.Index = 5; this.helpItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.helpMenuItem, this.helpMenuSeparator1, this.aboutMenuItem}); this.helpItem.Text = "&Help"; // // helpMenuItem // this.helpMenuItem.Index = 0; this.helpMenuItem.Shortcut = System.Windows.Forms.Shortcut.F1; this.helpMenuItem.Text = "NUnit &Help..."; this.helpMenuItem.Click += new System.EventHandler(this.helpMenuItem_Click); // // helpMenuSeparator1 // this.helpMenuSeparator1.Index = 1; this.helpMenuSeparator1.Text = "-"; // // aboutMenuItem // this.aboutMenuItem.Index = 2; this.aboutMenuItem.Text = "&About NUnit..."; this.aboutMenuItem.Click += new System.EventHandler(this.aboutMenuItem_Click); // // treeSplitter // this.treeSplitter.Location = new System.Drawing.Point(240, 0); this.treeSplitter.MinSize = 240; this.treeSplitter.Name = "treeSplitter"; this.treeSplitter.Size = new System.Drawing.Size(6, 407); this.treeSplitter.TabIndex = 2; this.treeSplitter.TabStop = false; // // rightPanel // this.rightPanel.BackColor = System.Drawing.SystemColors.Control; this.rightPanel.Controls.Add(this.groupBox1); this.rightPanel.Controls.Add(this.resultTabs); this.rightPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.rightPanel.Location = new System.Drawing.Point(246, 0); this.rightPanel.Name = "rightPanel"; this.rightPanel.Size = new System.Drawing.Size(498, 407); this.rightPanel.TabIndex = 3; // // groupBox1 // this.groupBox1.Controls.Add(this.suiteName); this.groupBox1.Controls.Add(this.runCount); this.groupBox1.Controls.Add(this.stopButton); this.groupBox1.Controls.Add(this.runButton); this.groupBox1.Controls.Add(this.progressBar); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; this.groupBox1.Location = new System.Drawing.Point(0, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(498, 120); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; // // suiteName // this.suiteName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.suiteName.AutoEllipsis = true; this.suiteName.Location = new System.Drawing.Point(145, 21); this.suiteName.Name = "suiteName"; this.suiteName.Size = new System.Drawing.Size(343, 23); this.suiteName.TabIndex = 1; // // runCount // this.runCount.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.runCount.AutoEllipsis = true; this.runCount.Location = new System.Drawing.Point(8, 89); this.runCount.Name = "runCount"; this.runCount.Size = new System.Drawing.Size(480, 21); this.runCount.TabIndex = 5; // // stopButton // this.stopButton.AutoSize = true; this.stopButton.Location = new System.Drawing.Point(75, 16); this.stopButton.Name = "stopButton"; this.stopButton.Size = new System.Drawing.Size(64, 31); this.stopButton.TabIndex = 4; this.stopButton.Text = "&Stop"; this.stopButton.Click += new System.EventHandler(this.stopButton_Click); // // runButton // this.runButton.Location = new System.Drawing.Point(8, 16); this.runButton.Name = "runButton"; this.runButton.Size = new System.Drawing.Size(64, 31); this.runButton.TabIndex = 3; this.runButton.Text = "&Run"; this.runButton.Click += new System.EventHandler(this.runButton_Click); // // progressBar // this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.progressBar.BackColor = System.Drawing.SystemColors.Control; this.progressBar.CausesValidation = false; this.progressBar.Enabled = false; this.progressBar.ForeColor = System.Drawing.SystemColors.Highlight; this.progressBar.Location = new System.Drawing.Point(8, 54); this.progressBar.Maximum = 100; this.progressBar.Minimum = 0; this.progressBar.Name = "progressBar"; this.progressBar.Segmented = true; this.progressBar.Size = new System.Drawing.Size(480, 28); this.progressBar.Step = 1; this.progressBar.TabIndex = 0; this.progressBar.Value = 0; // // resultTabs // this.resultTabs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.resultTabs.Location = new System.Drawing.Point(0, 120); this.resultTabs.Name = "resultTabs"; this.resultTabs.Size = new System.Drawing.Size(498, 284); this.resultTabs.TabIndex = 2; // // testTree // this.testTree.Dock = System.Windows.Forms.DockStyle.Fill; this.testTree.Location = new System.Drawing.Point(0, 0); this.testTree.Name = "testTree"; this.testTree.ShowCheckBoxes = false; this.testTree.Size = new System.Drawing.Size(240, 407); this.testTree.TabIndex = 0; this.testTree.SelectedTestsChanged += new NUnit.UiKit.SelectedTestsChangedEventHandler(this.testTree_SelectedTestsChanged); // // leftPanel // this.leftPanel.Controls.Add(this.testTree); this.leftPanel.Dock = System.Windows.Forms.DockStyle.Left; this.leftPanel.Location = new System.Drawing.Point(0, 0); this.leftPanel.Name = "leftPanel"; this.leftPanel.Size = new System.Drawing.Size(240, 407); this.leftPanel.TabIndex = 4; // // NUnitForm // this.ClientSize = new System.Drawing.Size(744, 431); this.Controls.Add(this.rightPanel); this.Controls.Add(this.treeSplitter); this.Controls.Add(this.leftPanel); this.Controls.Add(this.statusBar); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Menu = this.mainMenu; this.MinimumSize = new System.Drawing.Size(160, 32); this.Name = "NUnitForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.Text = "NUnit"; this.Load += new System.EventHandler(this.NUnitForm_Load); this.Closing += new System.ComponentModel.CancelEventHandler(this.NUnitForm_Closing); this.rightPanel.ResumeLayout(false); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.leftPanel.ResumeLayout(false); this.ResumeLayout(false); } #endregion #region Public Properties public NUnitPresenter Presenter { get { return presenter; } } #endregion #region Properties used internally private TestLoader _testLoader; private TestLoader TestLoader { get { if ( _testLoader == null ) _testLoader = Services.TestLoader; return _testLoader; } } private bool IsProjectLoaded { get { return TestLoader.IsProjectLoaded; } } private NUnitProject TestProject { get { return TestLoader.TestProject; } } private bool IsTestLoaded { get { return TestLoader.IsTestLoaded; } } private bool IsTestRunning { get { return TestLoader.Running; } } #endregion #region Menu Handlers #region File Menu private void fileMenu_Popup(object sender, System.EventArgs e) { newMenuItem.Enabled = !IsTestRunning; openMenuItem.Enabled = !IsTestRunning; closeMenuItem.Enabled = IsProjectLoaded && !IsTestRunning; saveMenuItem.Enabled = IsProjectLoaded; saveAsMenuItem.Enabled = IsProjectLoaded; reloadTestsMenuItem.Enabled = IsTestLoaded && !IsTestRunning; reloadProjectMenuItem.Enabled = runtimeMenuItem.Enabled = IsProjectLoaded && File.Exists(TestProject.ProjectPath) && !IsTestRunning; RuntimeFramework current = TestLoader.CurrentFramework; RuntimeFramework[] frameworks = RuntimeFramework.AvailableFrameworks; runtimeMenuItem.Visible = frameworks.Length > 1; if (runtimeMenuItem.Visible && runtimeMenuItem.Enabled) { runtimeMenuItem.MenuItems.Clear(); foreach (RuntimeFramework framework in frameworks) { MenuItem item = new MenuItem(framework.DisplayName); item.Checked = current.Supports(framework); item.Tag = framework; item.Click += new EventHandler(runtimeFrameworkMenuItem_Click); try { item.Enabled = TestLoader.CanReloadUnderRuntimeVersion(framework.ClrVersion); } catch { item.Enabled = false; } runtimeMenuItem.MenuItems.Add(item); } } recentProjectsMenu.Enabled = !IsTestRunning; if ( !IsTestRunning ) { recentProjectsMenuHandler.Load(); } } private void newMenuItem_Click(object sender, System.EventArgs e) { presenter.NewProject(); } private void openMenuItem_Click(object sender, System.EventArgs e) { presenter.OpenProject(); } private void closeMenuItem_Click(object sender, System.EventArgs e) { presenter.CloseProject(); } private void saveMenuItem_Click(object sender, System.EventArgs e) { presenter.SaveProject(); } private void saveAsMenuItem_Click(object sender, System.EventArgs e) { presenter.SaveProjectAs(); SetTitleBar(TestProject.Name); } private void runtimeFrameworkMenuItem_Click(object sender, System.EventArgs e) { TestLoader.ReloadTest(((MenuItem)sender).Tag as RuntimeFramework); } private void reloadProjectMenuItem_Click(object sender, System.EventArgs e) { presenter.ReloadProject(); } private void reloadTestsMenuItem_Click(object sender, System.EventArgs e) { TestLoader.ReloadTest(); } private void exitMenuItem_Click(object sender, System.EventArgs e) { this.Close(); } #endregion #region View Menu private void viewMenu_Popup(object sender, System.EventArgs e) { assemblyDetailsMenuItem.Enabled = this.TestLoader.IsTestLoaded; } private void statusBarMenuItem_Click(object sender, System.EventArgs e) { statusBarMenuItem.Checked = !statusBarMenuItem.Checked; statusBar.Visible = statusBarMenuItem.Checked; } private void fontChangeMenuItem_Click(object sender, System.EventArgs e) { FontDialog fontDialog = new FontDialog(); fontDialog.FontMustExist = true; fontDialog.Font = this.Font; fontDialog.MinSize = 6; fontDialog.MaxSize = 12; fontDialog.AllowVectorFonts = false; fontDialog.ScriptsOnly = true; fontDialog.ShowEffects = false; fontDialog.ShowApply = true; fontDialog.Apply += new EventHandler(fontDialog_Apply); if( fontDialog.ShowDialog() == DialogResult.OK ) applyFont( fontDialog.Font ); } private void fontDialog_Apply(object sender, EventArgs e) { applyFont( ((FontDialog)sender).Font ); } private void defaultFontMenuItem_Click(object sender, System.EventArgs e) { applyFont( System.Windows.Forms.Form.DefaultFont ); } private void fullGuiMenuItem_Click(object sender, System.EventArgs e) { if ( !fullGuiMenuItem.Checked ) displayFullGui(); } private void miniGuiMenuItem_Click(object sender, System.EventArgs e) { if ( !miniGuiMenuItem.Checked ) displayMiniGui(); } private void displayFullGui() { fullGuiMenuItem.Checked = true; miniGuiMenuItem.Checked = false; this.displayFormat = "Full"; userSettings.SaveSetting( "Gui.DisplayFormat", "Full" ); this.leftPanel.Visible = true; this.leftPanel.Dock = DockStyle.Left; this.treeSplitter.Visible = true; this.rightPanel.Visible = true; this.statusBar.Visible = true; resultTabs.TabsMenu.Visible = true; int x = userSettings.GetSetting("Gui.MainForm.Left", 10); int y = userSettings.GetSetting( "Gui.MainForm.Top", 10 ); Point location = new Point( x, y ); if ( !IsValidLocation( location ) ) location = new Point( 10, 10 ); this.Location = location; int width = userSettings.GetSetting( "Gui.MainForm.Width", this.Size.Width ); int height = userSettings.GetSetting( "Gui.MainForm.Height", this.Size.Height ); if ( width < 160 ) width = 160; if ( height < 32 ) height = 32; this.Size = new Size( width, height ); // Set to maximized if required if ( userSettings.GetSetting( "Gui.MainForm.Maximized", false ) ) this.WindowState = FormWindowState.Maximized; // Set the font to use applyFont(userSettings.GetSetting("Gui.MainForm.Font", Form.DefaultFont)); } private void displayMiniGui() { miniGuiMenuItem.Checked = true; fullGuiMenuItem.Checked = false; this.displayFormat = "Mini"; userSettings.SaveSetting( "Gui.DisplayFormat", "Mini" ); this.leftPanel.Visible = true; this.leftPanel.Dock = DockStyle.Fill; this.treeSplitter.Visible = false; this.rightPanel.Visible = false; this.statusBar.Visible = false; resultTabs.TabsMenu.Visible = false; int x = userSettings.GetSetting("Gui.MiniForm.Left", 10); int y = userSettings.GetSetting( "Gui.MiniForm.Top", 10 ); Point location = new Point( x, y ); if ( !IsValidLocation( location ) ) location = new Point( 10, 10 ); this.Location = location; int width = userSettings.GetSetting( "Gui.MiniForm.Width", 300 ); int height = userSettings.GetSetting( "Gui.MiniForm.Height", this.Size.Height ); if ( width < 160 ) width = 160; if ( height < 32 ) height = 32; this.Size = new Size( width, height ); // Set the font to use applyFont(userSettings.GetSetting("Gui.MiniForm.Font", Form.DefaultFont)); } private void increaseFontMenuItem_Click(object sender, System.EventArgs e) { applyFont( new Font( this.Font.FontFamily, this.Font.SizeInPoints * 1.2f, this.Font.Style ) ); } private void decreaseFontMenuItem_Click(object sender, System.EventArgs e) { applyFont( new Font( this.Font.FontFamily, this.Font.SizeInPoints / 1.2f, this.Font.Style ) ); } private void applyFont( Font font ) { this.Font = font; this.runCount.Font = font.FontFamily.IsStyleAvailable( FontStyle.Bold ) ? new Font( font, FontStyle.Bold ) : font; TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); userSettings.SaveSetting( displayFormat == "Mini" ? "Gui.MiniForm.Font" : "Gui.MainForm.Font", converter.ConvertToString( null, CultureInfo.InvariantCulture, font ) ); } private void increaseFixedFontMenuItem_Click(object sender, System.EventArgs e) { applyFixedFont( new Font( fixedFont.FontFamily, fixedFont.SizeInPoints * 1.2f, fixedFont.Style ) ); } private void decreaseFixedFontMenuItem_Click(object sender, System.EventArgs e) { applyFixedFont( new Font( fixedFont.FontFamily, fixedFont.SizeInPoints / 1.2f, fixedFont.Style ) ); } private void restoreFixedFontMenuItem_Click(object sender, System.EventArgs e) { applyFixedFont( new Font( FontFamily.GenericMonospace, 8.0f ) ); } private void applyFixedFont( Font font ) { this.fixedFont = font; TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font)); userSettings.SaveSetting( "Gui.FixedFont", converter.ConvertToString( null, CultureInfo.InvariantCulture, font ) ); } #endregion #region Project Menu /// /// When the project menu pops up, we populate the /// submenu for configurations dynamically. /// private void projectMenu_Popup(object sender, System.EventArgs e) { int index = 0; configMenuItem.MenuItems.Clear(); foreach ( ProjectConfig config in TestProject.Configs ) { string text = string.Format( "&{0} {1}", index+1, config.Name ); MenuItem item = new MenuItem( text, new EventHandler( configMenuItem_Click ) ); if ( config.Name == TestProject.ActiveConfigName ) item.Checked = true; configMenuItem.MenuItems.Add( index++, item ); } configMenuItem.MenuItems.Add( "-" ); configMenuItem.MenuItems.Add( "&Add...", new System.EventHandler( addConfigurationMenuItem_Click ) ); configMenuItem.MenuItems.Add( "&Edit...", new System.EventHandler( editConfigurationsMenuItem_Click ) ); addVSProjectMenuItem.Visible = userSettings.GetSetting( "Options.TestLoader.VisualStudioSupport", false ); addAssemblyMenuItem.Enabled = TestProject.Configs.Count > 0; } private void configMenuItem_Click( object sender, EventArgs e ) { MenuItem item = (MenuItem)sender; if (!item.Checked) { TestProject.SetActiveConfig(TestProject.Configs[item.Index].Name); LoadOrReloadTestAsNeeded(); } } private void addConfigurationMenuItem_Click( object sender, System.EventArgs e ) { using( AddConfigurationDialog dlg = new AddConfigurationDialog( TestProject ) ) { this.Site.Container.Add( dlg ); dlg.ShowDialog(); } LoadOrReloadTestAsNeeded(); } private void editConfigurationsMenuItem_Click( object sender, System.EventArgs e ) { using( ConfigurationEditor editor = new ConfigurationEditor( TestProject ) ) { this.Site.Container.Add( editor ); editor.ShowDialog(); } LoadOrReloadTestAsNeeded(); } private void addAssemblyMenuItem_Click(object sender, System.EventArgs e) { presenter.AddAssembly(); LoadOrReloadTestAsNeeded(); } private void addVSProjectMenuItem_Click(object sender, System.EventArgs e) { presenter.AddVSProject(); LoadOrReloadTestAsNeeded(); } private void editProjectMenuItem_Click(object sender, System.EventArgs e) { presenter.EditProject(); } private void LoadOrReloadTestAsNeeded() { if (TestProject.HasChangesRequiringReload) { if (TestProject.IsLoadable) { if (IsTestLoaded) TestLoader.ReloadTest(); else TestLoader.LoadTest(); } else TestLoader.UnloadTest(); } } #endregion #region Test Menu private void runAllMenuItem_Click(object sender, System.EventArgs e) { this.testTree.RunAllTests(); } private void runSelectedMenuItem_Click(object sender, System.EventArgs e) { this.testTree.RunSelectedTests(); } private void runFailedMenuItem_Click(object sender, System.EventArgs e) { this.testTree.RunFailedTests(); } private void stopRunMenuItem_Click(object sender, System.EventArgs e) { CancelRun(); } #endregion #region Tools Menu private void toolsMenu_Popup(object sender, System.EventArgs e) { assemblyDetailsMenuItem.Enabled = IsTestLoaded; saveXmlResultsMenuItem.Enabled = IsTestLoaded && TestLoader.TestResult != null; exceptionDetailsMenuItem.Enabled = TestLoader.LastException != null; } private void saveXmlResultsMenuItem_Click(object sender, System.EventArgs e) { presenter.SaveLastResult(); } private void exceptionDetailsMenuItem_Click(object sender, System.EventArgs e) { using( ExceptionDetailsForm details = new ExceptionDetailsForm( TestLoader.LastException ) ) { this.Site.Container.Add( details ); details.ShowDialog(); } } private void settingsMenuItem_Click(object sender, System.EventArgs e) { OptionsDialog.Display( this ); } private void assemblyDetailsMenuItem_Click(object sender, System.EventArgs e) { new TestAssemblyInfoForm().ShowDialog(); } private void addinInfoMenuItem_Click(object sender, System.EventArgs e) { AddinDialog dlg = new AddinDialog(); dlg.ShowDialog(); } private void openLogDirectoryMenuItem_Click(object sender, EventArgs e) { if (!Directory.Exists(NUnitConfiguration.LogDirectory)) Directory.CreateDirectory(NUnitConfiguration.LogDirectory); System.Diagnostics.Process.Start(NUnitConfiguration.LogDirectory); } #endregion #region Help Menu private void helpMenuItem_Click(object sender, System.EventArgs e) { System.Diagnostics.Process.Start( NUnitConfiguration.HelpUrl ); } /// /// Display the about box when menu item is selected /// private void aboutMenuItem_Click(object sender, System.EventArgs e) { using( AboutBox aboutBox = new AboutBox() ) { this.Site.Container.Add( aboutBox ); aboutBox.ShowDialog(); } } #endregion #endregion #region Form Level Events /// /// Get saved options when form loads /// private void NUnitForm_Load(object sender, System.EventArgs e) { if ( !this.DesignMode ) { // TODO: Can these controls add their menus themselves? this.viewMenu.MenuItems.Add(3, resultTabs.TabsMenu); this.viewMenu.MenuItems.Add(4, testTree.TreeMenu); EnableRunCommand( false ); EnableStopCommand( false ); recentProjectsMenuHandler = new RecentFileMenuHandler( recentProjectsMenu, recentFilesService ); recentProjectsMenuHandler.CheckFilesExist = userSettings.GetSetting("Gui.RecentProjects.CheckFilesExist", true); LoadFormSettings(); SubscribeToTestEvents(); InitializeControls(); // Force display so that any "Loading..." or error // message overlays the main form. this.Show(); this.Invalidate(); this.Update(); // Set Capture options for the TestLoader TestLoader.IsTracingEnabled = resultTabs.IsTracingEnabled; TestLoader.LoggingThreshold = resultTabs.MaximumLogLevel; // Load test specified on command line or // the most recent one if options call for it if ( guiOptions.ParameterCount != 0 ) presenter.OpenProject((string)guiOptions.Parameters[0], guiOptions.config, guiOptions.fixture); else if( userSettings.GetSetting( "Options.LoadLastProject", true ) && !guiOptions.noload ) { foreach( RecentFileEntry entry in recentFilesService.Entries ) { if ( entry != null && entry.Exists && entry.IsCompatibleCLRVersion ) { presenter.OpenProject(entry.Path, guiOptions.config, guiOptions.fixture); break; } } } if ( guiOptions.include != null ) { string[] categories = guiOptions.include.Split( ',' ); if ( categories.Length > 0 ) this.testTree.SelectCategories( categories, false ); } else if ( guiOptions.exclude != null ) { string[] categories = guiOptions.exclude.Split( ',' ); if ( categories.Length > 0 ) this.testTree.SelectCategories( categories, true ); } // Run loaded test automatically if called for if ( TestLoader.IsTestLoaded ) if ( guiOptions.run || guiOptions.runselected ) { // TODO: Temporary fix to avoid problem when /run is used // with ReloadOnRun turned on. Refactor TestLoader so // we can just do a run without reload. bool reload = Services.UserSettings.GetSetting("Options.TestLoader.ReloadOnRun", false); try { Services.UserSettings.SaveSetting("Options.TestLoader.ReloadOnRun", false); if (guiOptions.runselected) testTree.RunSelectedTests(); else testTree.RunAllTests(false); } finally { Services.UserSettings.SaveSetting("Options.TestLoader.ReloadOnRun", reload); } } } } private void LoadFormSettings() { this.displayFormat = userSettings.GetSetting( "Gui.DisplayFormat", "Full" ); switch (displayFormat) { case "Full": displayFullGui(); break; case "Mini": displayMiniGui(); break; default: throw new ApplicationException("Invalid Setting"); } // Handle changes to form position this.Move += new System.EventHandler(this.NUnitForm_Move); this.Resize += new System.EventHandler(this.NUnitForm_Resize); // Set the splitter position int splitPosition = userSettings.GetSetting( "Gui.MainForm.SplitPosition", treeSplitter.SplitPosition ); if ( splitPosition >= treeSplitter.MinSize && splitPosition < this.ClientSize.Width ) this.treeSplitter.SplitPosition = splitPosition; // Handle changes in splitter positions this.treeSplitter.SplitterMoved += new SplitterEventHandler( treeSplitter_SplitterMoved ); // Get the fixed font used by result tabs this.fixedFont = userSettings.GetSetting("Gui.FixedFont", new Font(FontFamily.GenericMonospace, 8.0f)); // Handle changes in form settings userSettings.Changed += new SettingsEventHandler(userSettings_Changed); } private bool IsValidLocation( Point location ) { Rectangle myArea = new Rectangle( location, this.Size ); bool intersect = false; foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens) { intersect |= myArea.IntersectsWith(screen.WorkingArea); } return intersect; } private void SubscribeToTestEvents() { ITestEvents events = TestLoader.Events; events.RunStarting += new TestEventHandler( OnRunStarting ); events.RunFinished += new TestEventHandler( OnRunFinished ); events.ProjectLoaded += new TestEventHandler( OnTestProjectLoaded ); events.ProjectLoadFailed+= new TestEventHandler( OnProjectLoadFailure ); events.ProjectUnloading += new TestEventHandler( OnTestProjectUnloading ); events.ProjectUnloaded += new TestEventHandler( OnTestProjectUnloaded ); events.TestLoading += new TestEventHandler( OnTestLoadStarting ); events.TestLoaded += new TestEventHandler( OnTestLoaded ); events.TestLoadFailed += new TestEventHandler( OnTestLoadFailure ); events.TestUnloading += new TestEventHandler( OnTestUnloadStarting ); events.TestUnloaded += new TestEventHandler( OnTestUnloaded ); events.TestReloading += new TestEventHandler( OnReloadStarting ); events.TestReloaded += new TestEventHandler( OnTestChanged ); events.TestReloadFailed += new TestEventHandler( OnTestLoadFailure ); } private void InitializeControls() { // ToDo: Migrate more ui elements to handle events on their own. this.progressBar.Subscribe( TestLoader.Events ); this.statusBar.Subscribe( TestLoader.Events ); } // Save settings changed by moving the form private void NUnitForm_Move(object sender, System.EventArgs e) { switch( this.displayFormat ) { case "Full": default: if ( this.WindowState == FormWindowState.Normal ) { userSettings.SaveSetting( "Gui.MainForm.Left", this.Location.X ); userSettings.SaveSetting( "Gui.MainForm.Top", this.Location.Y ); userSettings.SaveSetting( "Gui.MainForm.Maximized", false ); this.statusBar.SizingGrip = true; } else if ( this.WindowState == FormWindowState.Maximized ) { userSettings.SaveSetting( "Gui.MainForm.Maximized", true ); this.statusBar.SizingGrip = false; } break; case "Mini": if ( this.WindowState == FormWindowState.Normal ) { userSettings.SaveSetting( "Gui.MiniForm.Left", this.Location.X ); userSettings.SaveSetting( "Gui.MiniForm.Top", this.Location.Y ); userSettings.SaveSetting( "Gui.MiniForm.Maximized", false ); this.statusBar.SizingGrip = true; } else if ( this.WindowState == FormWindowState.Maximized ) { userSettings.SaveSetting( "Gui.MiniForm.Maximized", true ); this.statusBar.SizingGrip = false; } break; } } // Save settings that change when window is resized private void NUnitForm_Resize(object sender,System.EventArgs e) { if ( this.WindowState == FormWindowState.Normal ) { if ( this.displayFormat == "Full" ) { userSettings.SaveSetting( "Gui.MainForm.Width", this.Size.Width ); userSettings.SaveSetting( "Gui.MainForm.Height", this.Size.Height ); } else { userSettings.SaveSetting( "Gui.MiniForm.Width", this.Size.Width ); userSettings.SaveSetting( "Gui.MiniForm.Height", this.Size.Height ); } } } // Splitter moved so save it's position private void treeSplitter_SplitterMoved( object sender, SplitterEventArgs e ) { userSettings.SaveSetting( "Gui.MainForm.SplitPosition", treeSplitter.SplitPosition ); } /// /// Form is about to close, first see if we /// have a test run going on and if so whether /// we should cancel it. Then unload the /// test and save the latest form position. /// private void NUnitForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if ( IsTestRunning ) { DialogResult dialogResult = MessageDisplay.Ask( "A test is running, do you want to stop the test and exit?" ); if ( dialogResult == DialogResult.No ) e.Cancel = true; else TestLoader.CancelTestRun(); } if ( !e.Cancel && IsProjectLoaded && presenter.CloseProject() == DialogResult.Cancel) e.Cancel = true; } private void userSettings_Changed(object sender, SettingsEventArgs args) { if ( args.SettingName == "Gui.DisplayFormat" ) { string newFormat = userSettings.GetSetting( "Gui.DisplayFormat", this.displayFormat ); if ( newFormat != displayFormat ) if ( newFormat == "Full" ) displayFullGui(); else displayMiniGui(); } else if (args.SettingName.StartsWith("Gui.TextOutput.") && args.SettingName.EndsWith(".Content")) { TestLoader.IsTracingEnabled = resultTabs.IsTracingEnabled; TestLoader.LoggingThreshold = resultTabs.MaximumLogLevel; } } #endregion #region Other UI Event Handlers /// /// When the Run Button is clicked, run the selected test. /// private void runButton_Click(object sender, System.EventArgs e) { testTree.RunSelectedTests(); } /// /// When the Stop Button is clicked, cancel running test /// private void stopButton_Click(object sender, System.EventArgs e) { CancelRun(); } private void CancelRun() { EnableStopCommand( false ); if ( IsTestRunning ) { DialogResult dialogResult = MessageDisplay.Ask( "Do you want to cancel the running test?" ); if ( dialogResult == DialogResult.No ) EnableStopCommand( true ); else TestLoader.CancelTestRun(); } } private void testTree_SelectedTestsChanged(object sender, SelectedTestsChangedEventArgs e) { if (!IsTestRunning) { suiteName.Text = e.TestName; statusBar.Initialize(e.TestCount, e.TestName ); } } #endregion #region Event Handlers for Project Load and Unload private void OnTestProjectLoaded( object sender, TestEventArgs e ) { string projectPath = e.Name; SetTitleBar( projectPath ); projectMenu.Visible = true; runCount.Text = ""; // If this is an NUnit project, set up watcher if (NUnitProject.IsNUnitProjectFile(projectPath) && File.Exists(projectPath)) presenter.WatchProject(projectPath); } private void OnTestProjectUnloading(object sender, TestEventArgs e) { // Remove any watcher if (e.Name != null && File.Exists(e.Name)) { presenter.RemoveWatcher(); Version version = Environment.Version; foreach( TestAssemblyInfo info in TestLoader.AssemblyInfo ) if ( info.ImageRuntimeVersion < version ) version = info.ImageRuntimeVersion; recentFilesService.SetMostRecent( new RecentFileEntry( e.Name, version ) ); } } private void OnTestProjectUnloaded( object sender, TestEventArgs e ) { SetTitleBar( null ); projectMenu.Visible = false; runCount.Text = ""; } private void OnProjectLoadFailure(object sender, TestEventArgs e) { MessageDisplay.Error("Project Not Loaded", e.Exception); recentFilesService.Remove(e.Name); EnableRunCommand(IsProjectLoaded); } #endregion #region Event Handlers for Test Load and Unload private void OnTestLoadStarting(object sender, TestEventArgs e) { EnableRunCommand( false ); longOpDisplay = new LongRunningOperationDisplay( this, "Loading..." ); } private void OnTestUnloadStarting( object sender, TestEventArgs e ) { EnableRunCommand( false ); } private void OnReloadStarting( object sender, TestEventArgs e ) { EnableRunCommand( false ); longOpDisplay = new LongRunningOperationDisplay( this, "Reloading..." ); } /// /// A test suite has been loaded, so update /// recent assemblies and display the tests in the UI /// private void OnTestLoaded( object sender, TestEventArgs e ) { if ( longOpDisplay != null ) { longOpDisplay.Dispose(); longOpDisplay = null; } EnableRunCommand( true ); if ( TestLoader.TestCount == 0 ) { foreach( TestAssemblyInfo info in TestLoader.AssemblyInfo ) if ( info.TestFrameworks.Count > 0 ) return; MessageDisplay.Error("This assembly was not built with any known testing framework."); } } /// /// A test suite has been unloaded, so clear the UI /// and remove any references to the suite. /// private void OnTestUnloaded( object sender, TestEventArgs e ) { suiteName.Text = null; runCount.Text = null; EnableRunCommand( false ); Refresh(); } /// /// The current test suite has changed in some way, /// so update the info in the UI and clear the /// test results, since they are no longer valid. /// private void OnTestChanged( object sender, TestEventArgs e ) { SetTitleBar(TestProject.Name); if ( longOpDisplay != null ) { longOpDisplay.Dispose(); longOpDisplay = null; } if (userSettings.GetSetting("Options.TestLoader.ClearResultsOnReload", false)) runCount.Text = null; EnableRunCommand( true ); } /// /// Event handler for assembly load failures. We do this via /// an event since some errors may occur asynchronously. /// private void OnTestLoadFailure( object sender, TestEventArgs e ) { if ( longOpDisplay != null ) { longOpDisplay.Dispose(); longOpDisplay = null; } string message = e.Action == NUnit.Util.TestAction.TestReloadFailed ? "Test reload failed!" : "Test load failed!"; if ( e.Exception is BadImageFormatException ) message += string.Format( Environment.NewLine + Environment.NewLine + @"You may be attempting to load an assembly built with a later version of the CLR than the version under which NUnit is currently running ({0}) or trying to load a 64-bit assembly into a 32-bit process.", Environment.Version.ToString(3) ); MessageDisplay.Error(message, e.Exception); if ( !IsTestLoaded ) OnTestUnloaded( sender, e ); else EnableRunCommand( true ); } #endregion #region Handlers for Test Running Events private void OnRunStarting( object sender, TestEventArgs e ) { suiteName.Text = e.Name; EnableRunCommand( false ); EnableStopCommand( true ); runCount.Text = ""; } private void OnRunFinished( object sender, TestEventArgs e ) { EnableStopCommand( false ); EnableRunCommand( false ); if ( e.Exception != null ) { if ( ! ( e.Exception is System.Threading.ThreadAbortException ) ) MessageDisplay.Error("NUnit Test Run Failed", e.Exception); } ResultSummarizer summary = new ResultSummarizer( e.Result ); this.runCount.Text = string.Format( "Passed: {0} Failed: {1} Errors: {2} Inconclusive: {3} Invalid: {4} Ignored: {5} Skipped: {6} Time: {7}", summary.Passed, summary.Failures, summary.Errors, summary.Inconclusive, summary.NotRunnable, summary.Ignored, summary.Skipped, summary.Time); try { TestLoader.SaveLastResult("TestResult.xml"); } catch (Exception ex) { log.Warning("Unable to save TestResult.xml\n{0}", ex.ToString()); } EnableRunCommand(true); if (e.Result.ResultState == ResultState.Failure || e.Result.ResultState == ResultState.Error || e.Result.ResultState == ResultState.Cancelled) { this.Activate(); } } #endregion #region Helper methods for modifying the UI display /// /// Set the title bar based on the loaded file or project /// /// private void SetTitleBar( string fileName ) { this.Text = fileName == null ? "NUnit" : string.Format( "{0} - NUnit", Path.GetFileName( fileName ) ); } private void EnableRunCommand( bool enable ) { runButton.Enabled = enable; runAllMenuItem.Enabled = enable; runSelectedMenuItem.Enabled = enable; runFailedMenuItem.Enabled = enable && this.TestLoader.TestResult != null && (this.TestLoader.TestResult.ResultState == ResultState.Failure || this.TestLoader.TestResult.ResultState == ResultState.Error); } private void EnableStopCommand( bool enable ) { stopButton.Enabled = enable; stopRunMenuItem.Enabled = enable; } #endregion } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/DetailResults.cs0000664000175000017500000000410511504175260022717 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Gui { using System; using System.Windows.Forms; using NUnit.Core; using NUnit.Util; /// /// Summary description for DetailResults /// public class DetailResults { private readonly ListBox testDetails; private readonly TreeView notRunTree; public DetailResults(ListBox listBox, TreeView notRun) { testDetails = listBox; notRunTree = notRun; } public void DisplayResults( TestResult results ) { notRunTree.BeginUpdate(); ProcessResults( results ); notRunTree.EndUpdate(); if( testDetails.Items.Count > 0 ) testDetails.SelectedIndex = 0; } private void ProcessResults(TestResult result) { switch( result.ResultState ) { case ResultState.Failure: case ResultState.Error: case ResultState.Cancelled: TestResultItem item = new TestResultItem(result); //string resultString = String.Format("{0}:{1}", result.Name, result.Message); testDetails.BeginUpdate(); testDetails.Items.Insert(testDetails.Items.Count, item); testDetails.EndUpdate(); break; case ResultState.Skipped: case ResultState.NotRunnable: case ResultState.Ignored: notRunTree.Nodes.Add(MakeNotRunNode(result)); break; } if ( result.HasResults ) foreach (TestResult childResult in result.Results) ProcessResults( childResult ); } private static TreeNode MakeNotRunNode(TestResult result) { TreeNode node = new TreeNode(result.Name); TreeNode reasonNode = new TreeNode("Reason: " + result.Message); node.Nodes.Add(reasonNode); return node; } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/ExceptionDetailsForm.resx0000664000175000017500000002341511504175260024604 0ustar jtaylorjtaylor text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 False Private Private False Private Private False Private Private False (Default) False False 8, 8 True ExceptionDetailsForm 80 True Private AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ////////////////////////////////////////qqqqqv///6qq/5mZmZn//6qqqqr///+qqvmZmZmZ n/+qqqqq///6qqqZmf//mZn//6qv////+qqqmZ////mZ//+qr////6qqqpmf///5mf//qq////+qqqqZ n///+Zn//6qv///6qqqqmZ////mZ//+qr///+qqqqpmf///5mf//qq///6qq+qqZn///+Zn//6qv//qq qvqqmZ////mZ//+qr//6qq/6qpmf///5mf//qq//qqqv+qqZn///+Zn//6qv/6qq//qZmZmf+ZmZmf+q r/qqqv/6mZmZn/mZmZn/qq/6qq//+qr//////////6qvqqqv//qq//////////+qqqqq///6qv////// ////qqqqqv//+qr//////////6qqqq////qq/////////6qqqqqv/6qqqqqv//////+qqqqq//+qqqqq r///////qqqqqv//qqqqqq////////////////////////////////////////////////////////// ////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAoAAAAEAAAACAAAAABAAQAAAAAAIAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA AACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AGZmZmZmZmZmZmZmZmZm Zmb/////////////////////qqr/qv+Zn//6r/qq+f/5//qv+qr5//n/+q+qqvn/+f/6r6+q+f/5//qq r6qZn5mf+qqvqv////+qqvqqr///////////////////////////////////////////////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/ExceptionDetailsForm.cs0000664000175000017500000001247411504175260024233 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace NUnit.Gui { /// /// Summary description for ExceptionDetailsForm. /// public class ExceptionDetailsForm : System.Windows.Forms.Form { private System.Windows.Forms.Button okButton; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.RichTextBox stackTrace; private System.Windows.Forms.Label message; private Exception exception; public ExceptionDetailsForm( Exception exception ) { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // this.exception = exception; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.okButton = new System.Windows.Forms.Button(); this.stackTrace = new System.Windows.Forms.RichTextBox(); this.message = new System.Windows.Forms.Label(); this.SuspendLayout(); // // okButton // this.okButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.okButton.Location = new System.Drawing.Point(434, 512); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(90, 27); this.okButton.TabIndex = 1; this.okButton.Text = "OK"; // // stackTrace // this.stackTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.stackTrace.Location = new System.Drawing.Point(10, 65); this.stackTrace.Name = "stackTrace"; this.stackTrace.ReadOnly = true; this.stackTrace.Size = new System.Drawing.Size(940, 433); this.stackTrace.TabIndex = 3; this.stackTrace.Text = ""; // // message // this.message.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.message.Location = new System.Drawing.Point(19, 9); this.message.Name = "message"; this.message.Size = new System.Drawing.Size(931, 46); this.message.TabIndex = 2; // // ExceptionDetailsForm // this.ClientSize = new System.Drawing.Size(969, 551); this.Controls.Add(this.stackTrace); this.Controls.Add(this.message); this.Controls.Add(this.okButton); this.Name = "ExceptionDetailsForm"; this.Text = "Exception Details"; this.Resize += new System.EventHandler(this.ExceptionDetailsForm_Resize); this.Load += new System.EventHandler(this.ExceptionDetailsForm_Load); this.ResumeLayout(false); } #endregion private void ExceptionDetailsForm_Load(object sender, System.EventArgs e) { //TODO: Put some of this in the constructor for easier testing? this.message.Text = FormatMessage( exception ); SetMessageLabelSize(); this.stackTrace.Text = FormatStackTrace( exception ); } private string FormatMessage( Exception exception ) { StringBuilder sb = new StringBuilder(); for( Exception ex = exception; ex != null; ex = ex.InnerException ) { if ( ex != exception ) sb.Append( "\r\n----> " ); sb.Append( ex.GetType().ToString() ); sb.Append( ": " ); sb.Append( ex.Message ); } return sb.ToString(); } private string FormatStackTrace( Exception exception ) { StringBuilder sb = new StringBuilder(); AppendStackTrace( sb, exception ); return sb.ToString(); } private void AppendStackTrace( StringBuilder sb, Exception ex ) { if ( ex.InnerException != null ) AppendStackTrace( sb, ex.InnerException ); sb.Append( ex.GetType().ToString() ); sb.Append( "...\r\n" ); sb.Append( ex.StackTrace ); sb.Append( "\r\n\r\n" ); } private void ExceptionDetailsForm_Resize(object sender, System.EventArgs e) { SetMessageLabelSize(); } private void SetMessageLabelSize() { Rectangle rect = message.ClientRectangle; Graphics g = Graphics.FromHwnd( Handle ); SizeF sizeNeeded = g.MeasureString( message.Text, message.Font, rect.Width ); int delta = sizeNeeded.ToSize().Height - rect.Height; message.Height += delta; stackTrace.Top += delta; stackTrace.Height -= delta; } } }NUnit-2.6.0.12051/src/GuiRunner/nunit-gui/AboutBox.cs0000664000175000017500000002546311712221750021665 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; namespace NUnit.Gui { public class AboutBox : System.Windows.Forms.Form { private System.Windows.Forms.Button OkButton; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label versionLabel; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.LinkLabel linkLabel1; private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label7; private System.Windows.Forms.Label copyright; private System.Windows.Forms.Label dotNetVersionLabel; private System.Windows.Forms.Label clrTypeLabel; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public AboutBox() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // Assembly executingAssembly = Assembly.GetExecutingAssembly(); string versionText = executingAssembly.GetName().Version.ToString(); object [] objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); if ( objectAttrs.Length > 0 ) versionText = ((AssemblyInformationalVersionAttribute)objectAttrs[0]).InformationalVersion; objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyConfigurationAttribute), false); if ( objectAttrs.Length > 0 ) { string configText = ((AssemblyConfigurationAttribute)objectAttrs[0]).Configuration; if ( configText != "" ) versionText += string.Format(" ({0})",configText); } string copyrightText = "Copyright (C) 2002-2012 Charlie Poole.\r\nCopyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.\r\nCopyright (C) 2000-2002 Philip Craig.\r\nAll Rights Reserved."; objectAttrs = executingAssembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if ( objectAttrs.Length > 0 ) copyrightText = ((AssemblyCopyrightAttribute)objectAttrs[0]).Copyright; versionLabel.Text = versionText; copyright.Text = copyrightText; dotNetVersionLabel.Text = NUnit.Core.RuntimeFramework.CurrentFramework.DisplayName; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox)); this.OkButton = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.versionLabel = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.label4 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); this.copyright = new System.Windows.Forms.Label(); this.clrTypeLabel = new System.Windows.Forms.Label(); this.dotNetVersionLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // OkButton // this.OkButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.OkButton.Location = new System.Drawing.Point(368, 304); this.OkButton.Name = "OkButton"; this.OkButton.Size = new System.Drawing.Size(96, 29); this.OkButton.TabIndex = 0; this.OkButton.Text = "OK"; this.OkButton.Click += new System.EventHandler(this.button1_Click); // // label1 // this.label1.Location = new System.Drawing.Point(31, 240); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(102, 23); this.label1.TabIndex = 1; this.label1.Text = "NUnit Version:"; // // versionLabel // this.versionLabel.Location = new System.Drawing.Point(164, 240); this.versionLabel.Name = "versionLabel"; this.versionLabel.Size = new System.Drawing.Size(156, 23); this.versionLabel.TabIndex = 2; this.versionLabel.Text = "label2"; // // label2 // this.label2.Location = new System.Drawing.Point(31, 144); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(102, 29); this.label2.TabIndex = 3; this.label2.Text = "Developers:"; // // label3 // this.label3.Location = new System.Drawing.Point(164, 144); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(287, 48); this.label3.TabIndex = 4; this.label3.Text = "James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Philip Craig, Ethan Smith," + " Doug de la Torre, Charlie Poole"; // // linkLabel1 // this.linkLabel1.LinkArea = new System.Windows.Forms.LinkArea(0, 21); this.linkLabel1.Location = new System.Drawing.Point(164, 112); this.linkLabel1.Name = "linkLabel1"; this.linkLabel1.Size = new System.Drawing.Size(266, 16); this.linkLabel1.TabIndex = 5; this.linkLabel1.TabStop = true; this.linkLabel1.Text = "http://www.nunit.org "; this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); // // label4 // this.label4.Location = new System.Drawing.Point(31, 112); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(102, 16); this.label4.TabIndex = 6; this.label4.Text = "Information:"; // // label5 // this.label5.Location = new System.Drawing.Point(31, 200); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(102, 29); this.label5.TabIndex = 7; this.label5.Text = "Thanks to:"; // // label6 // this.label6.Location = new System.Drawing.Point(164, 200); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(215, 29); this.label6.TabIndex = 8; this.label6.Text = "Kent Beck and Erich Gamma"; // // label7 // this.label7.Location = new System.Drawing.Point(31, 20); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(102, 28); this.label7.TabIndex = 9; this.label7.Text = "Copyright:"; // // copyright // this.copyright.Location = new System.Drawing.Point(164, 20); this.copyright.Name = "copyright"; this.copyright.Size = new System.Drawing.Size(297, 84); this.copyright.TabIndex = 10; this.copyright.Text = "label8"; // // clrTypeLabel // this.clrTypeLabel.Location = new System.Drawing.Point(31, 272); this.clrTypeLabel.Name = "clrTypeLabel"; this.clrTypeLabel.Size = new System.Drawing.Size(127, 23); this.clrTypeLabel.TabIndex = 11; this.clrTypeLabel.Text = "Framework Version:"; // // dotNetVersionLabel // this.dotNetVersionLabel.Location = new System.Drawing.Point(164, 272); this.dotNetVersionLabel.Name = "dotNetVersionLabel"; this.dotNetVersionLabel.Size = new System.Drawing.Size(284, 23); this.dotNetVersionLabel.TabIndex = 12; this.dotNetVersionLabel.Text = "label9"; // // AboutBox // this.AcceptButton = this.OkButton; this.CancelButton = this.OkButton; this.ClientSize = new System.Drawing.Size(490, 346); this.Controls.Add(this.dotNetVersionLabel); this.Controls.Add(this.clrTypeLabel); this.Controls.Add(this.copyright); this.Controls.Add(this.label7); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.label4); this.Controls.Add(this.linkLabel1); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.versionLabel); this.Controls.Add(this.label1); this.Controls.Add(this.OkButton); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "AboutBox"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "About NUnit"; this.ResumeLayout(false); } #endregion private void button1_Click(object sender, System.EventArgs e) { this.Close(); } private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) { System.Diagnostics.Process.Start("http://nunit.org"); linkLabel1.LinkVisited = true; } } } NUnit-2.6.0.12051/src/GuiRunner/tests/0000775000175000017500000000000011742560362017034 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiRunner/tests/nunit-gui.tests.build0000664000175000017500000000245711544330406023137 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiRunner/tests/ExceptionDetailsFormTests.cs0000664000175000017500000000236211504175260024474 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Windows.Forms; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.Gui.Tests { [TestFixture] public class ExceptionDetailsFormTests : FormTester { [TestFixtureSetUp] public void CreateForm() { this.Form = new ExceptionDetailsForm( new Exception( "My message" ) ); } [TestFixtureTearDown] public void CloseForm() { this.Form.Close(); } [Test] public void ControlsExist() { AssertControlExists( "message", typeof( Label ) ); AssertControlExists( "stackTrace", typeof( RichTextBox ) ); AssertControlExists( "okButton", typeof( Button ) ); } [Test] public void ControlsArePositionedCorrectly() { AssertControlsAreStackedVertically( "message", "stackTrace", "okButton" ); } [Test] public void MessageDisplaysCorrectly() { this.Form.Show(); Assert.AreEqual( "System.Exception: My message", GetText( "message" ) ); } } } NUnit-2.6.0.12051/src/GuiRunner/tests/RecentFileMenuHandlerTests.cs0000664000175000017500000000424311544330406024546 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2002-2003, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Windows.Forms; using NUnit.Framework; using NUnit.Util; namespace NUnit.Gui.Tests { [TestFixture] public class RecentFileMenuHandlerTests { private MenuItem menu; private RecentFiles files; private RecentFileMenuHandler handler; [SetUp] public void SetUp() { menu = new MenuItem(); files = new FakeRecentFiles(); handler = new RecentFileMenuHandler( menu, files ); handler.CheckFilesExist = false; } [Test] public void DisableOnLoadWhenEmpty() { handler.Load(); Assert.IsFalse( menu.Enabled ); } [Test] public void EnableOnLoadWhenNotEmpty() { files.SetMostRecent( "Test" ); handler.Load(); Assert.IsTrue( menu.Enabled ); } [Test] public void LoadMenuItems() { files.SetMostRecent( "Third" ); files.SetMostRecent( "Second" ); files.SetMostRecent( "First" ); handler.Load(); Assert.AreEqual( 3, menu.MenuItems.Count ); Assert.AreEqual( "1 First", menu.MenuItems[0].Text ); } private class FakeRecentFiles : RecentFiles { private RecentFilesCollection files = new RecentFilesCollection(); private int maxFiles = 24; public int Count { get { return files.Count; } } public int MaxFiles { get { return maxFiles; } set { maxFiles = value; } } public void SetMostRecent( string fileName ) { SetMostRecent( new RecentFileEntry( fileName ) ); } public void SetMostRecent( RecentFileEntry entry ) { files.Insert( 0, entry ); } public RecentFilesCollection Entries { get { return files; } } public void Clear() { files.Clear(); } public void Remove( string fileName ) { files.Remove( fileName ); } } // TODO: Need mock loader to test clicking } } NUnit-2.6.0.12051/src/GuiRunner/tests/nunit-gui.tests.csproj0000664000175000017500000001074411574577562023361 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {AAD27267-DE1F-4F61-A1FB-D1680A5B8001} Debug AnyCPU nunit-gui.tests JScript Grid IE50 false Library NUnit.Gui.Tests OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.Drawing System.Windows.Forms System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} test-utilities {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} nunit-gui {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148} False CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/GuiRunner/tests/CommandLineTests.cs0000664000175000017500000000426211504175260022573 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Gui.Tests { using System; using NUnit.Framework; [TestFixture] public class CommandLineTests { [Test] public void NoParametersCount() { GuiOptions options = new GuiOptions(new string[] {}); Assert.IsTrue(options.NoArgs); } [Test] public void Help() { GuiOptions options = new GuiOptions(new string[] {"-help"}); Assert.IsTrue(options.help); } [Test] public void ShortHelp() { GuiOptions options = new GuiOptions(new string[] {"-?"}); Assert.IsTrue(options.help); } [Test] public void AssemblyName() { string assemblyName = "nunit.tests.dll"; GuiOptions options = new GuiOptions(new string[]{ assemblyName }); Assert.AreEqual(assemblyName, options.Parameters[0]); } [Test] public void ValidateSuccessful() { GuiOptions options = new GuiOptions(new string[] { "nunit.tests.dll" }); Assert.IsTrue(options.Validate(), "command line should be valid"); } [Test] public void InvalidArgs() { GuiOptions options = new GuiOptions(new string[] { "-asembly:nunit.tests.dll" }); Assert.IsFalse(options.Validate()); } [Test] public void InvalidCommandLineParms() { GuiOptions parser = new GuiOptions(new String[]{"-garbage:TestFixture", "-assembly:Tests.dll"}); Assert.IsFalse(parser.Validate()); } [Test] public void NoNameValuePairs() { GuiOptions parser = new GuiOptions(new String[]{"TestFixture", "Tests.dll"}); Assert.IsFalse(parser.Validate()); } [Test] public void HelpTextUsesCorrectDelimiterForPlatform() { string helpText = new GuiOptions(new String[] {"Tests.dll"} ).GetHelpText(); char delim = System.IO.Path.DirectorySeparatorChar == '/' ? '-' : '/'; string expected = string.Format( "{0}config=", delim ); StringAssert.Contains( expected, helpText ); } } } NUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/0000775000175000017500000000000011742560362020370 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/App.ico0000664000175000017500000000206611504175260021603 0ustar jtaylorjtaylor &(( @( ffffffffffffffffNUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/AssemblyInfo.cs0000664000175000017500000000016211504175260023304 0ustar jtaylorjtaylorusing System; using System.Reflection; [assembly: AssemblyTitle("NUnit")] [assembly: AssemblyDescription("")]NUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/nunit-gui.exe.csproj0000664000175000017500000001302111574577562024323 0ustar jtaylorjtaylor Local 9.0.21022 2.0 {AAB186A4-FA3D-404D-AD78-7EB5BB861655} Debug AnyCPU nunit JScript Grid IE50 false WinExe NUnit.Gui OnBuildSuccess 2.0 http://localhost/nunit/ true Web true Foreground 7 Days false false true 0 1.0.0.%2a true false true LocalIntranet false true v2.0 ..\..\..\bin\Debug\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 false false false 4 full prompt ..\..\..\bin\Release\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 true false false 4 none prompt System System.Data System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit-gui {3FF340D5-D3B4-4DF0-BAF1-98B3C00B6148} False False .NET Framework 2.0 %28x86%29 true False .NET Framework 3.0 %28x86%29 false False .NET Framework 3.5 false CommonAssemblyInfo.cs Always NUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/nunit-gui.exe.build0000664000175000017500000000347511654450230024113 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/App.config0000664000175000017500000000176311677275116022315 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/GuiRunner/nunit-gui-exe/Class1.cs0000664000175000017500000000117011504175260022037 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Gui { /// /// Summary description for Class1. /// public class Class1 { /// /// The main entry point for the application. /// [STAThread] public static int Main(string[] args) { return NUnit.Gui.AppEntry.Main( args ); } } } NUnit-2.6.0.12051/src/NUnitCore/0000775000175000017500000000000011742560362015622 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/interfaces/0000775000175000017500000000000011742560362017745 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/interfaces/IAgency.cs0000664000175000017500000000132211504175260021604 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// The IAgency interface is implemented by a TestAgency in /// order to allow TestAgents to register with it. /// public interface IAgency { /// /// Registers an agent with an agency /// /// void Register(TestAgent agent); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestInfo.cs0000664000175000017500000001456211543055572022040 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; namespace NUnit.Core { /// /// TestInfo holds common info about a test. It represents only /// a single test or a suite and contains no references to other /// tests. Since it is informational only, it can easily be passed /// around using .Net remoting. /// /// TestInfo is used directly in all EventListener events and in /// TestResults. It contains an ID, which can be used by a /// runner to locate the actual test. /// /// TestInfo also serves as the base class for TestNode, which /// adds hierarchical information and is used in client code to /// maintain a visible image of the structure of the tests. /// [Serializable] public class TestInfo : ITest { #region Instance Variables /// /// TestName that identifies this test /// private TestName testName; private string testType; private RunState runState; /// /// Reason for not running the test /// private string ignoreReason; /// /// Number of test cases in this test or suite /// private int testCaseCount; /// /// True if this is a suite /// private bool isSuite; /// /// The test description /// private string description; /// /// A list of all the categories assigned to a test /// private ArrayList categories = new ArrayList(); /// /// A dictionary of properties, used to add information /// to tests without requiring the class to change. /// private ListDictionary properties = new ListDictionary(); #endregion #region Constructors /// /// Construct from an ITest /// /// Test from which a TestNode is to be constructed public TestInfo( ITest test ) { this.testName = (TestName)test.TestName.Clone(); this.testType = test.TestType; this.runState = test.RunState; this.ignoreReason = test.IgnoreReason; this.description = test.Description; this.isSuite = test.IsSuite; if (test.Categories != null) this.categories.AddRange(test.Categories); if (test.Properties != null) { this.properties = new ListDictionary(); foreach( DictionaryEntry entry in test.Properties ) this.properties.Add( entry.Key, entry.Value ); } this.testCaseCount = test.TestCount; } /// /// Construct as a parent to multiple tests. /// /// The name to use for the new test /// An array of child tests public TestInfo( TestName testName, ITest[] tests ) { this.testName = testName; this.testType = "Test Project"; this.runState = RunState.Runnable; this.ignoreReason = null; this.description = null; this.isSuite = true; if ( tests != null ) foreach( ITest test in tests ) this.testCaseCount += test.TestCount; } /// /// Construct given a test name /// /// The TestName for the new test public TestInfo( TestName testName ) : this( testName, null) { } #endregion #region Properties /// /// Gets the completely specified name of the test /// encapsulated in a TestName object. /// public TestName TestName { get { return testName; } } /// /// Gets a string representing the kind of test this /// object represents for display purposes. /// public string TestType { get { return testType; } } /// /// The test description /// public string Description { get { return description; } set { description = value; } } /// /// Gets the RunState for this test /// public RunState RunState { get { return runState; } set { runState = value; } } /// /// The reason for ignoring a test /// public string IgnoreReason { get { return ignoreReason; } set { ignoreReason = value; } } /// /// Count of test cases in this test. /// public int TestCount { get { return testCaseCount; } } /// /// Gets the parent test of this test /// public virtual ITest Parent { get { return null; } } /// /// Gets a list of the categories applied to this test /// public IList Categories { get { return categories; } } /// /// Gets a list of any child tests /// public virtual IList Tests { get { return null; } } /// /// True if this is a suite, false if a test case /// public bool IsSuite { get { return isSuite; } } /// /// Gets the Properties dictionary for this test /// public IDictionary Properties { get { if ( properties == null ) properties = new ListDictionary(); return properties; } } #endregion #region Methods /// /// Counts the test cases that would be run if this /// test were executed using the provided filter. /// /// The filter to apply /// A count of test cases public virtual int CountTestCases(ITestFilter filter) { if (filter.IsEmpty) return TestCount; if (!isSuite) return filter.Pass(this) ? 1 : 0; int count = 0; if (filter.Pass(this)) { foreach (ITest test in Tests) { count += test.CountTestCases(filter); } } return count; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestName.cs0000664000175000017500000001254111543055572022020 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// TestName encapsulates all info needed to identify and /// locate a test that has been loaded by a runner. It consists /// of a three components: the simple name of the test, an int /// id that is unique to a given tree of tests and an int /// runner id that identifies the particular runner that /// holds the test instance. /// [Serializable] public class TestName : ICloneable { #region Fields /// /// ID that uniquely identifies the test /// private TestID testID; private int runnerID; /// /// The simple name of the test, without qualification /// private string name; /// /// The fully qualified name of the test /// private string fullName; #endregion #region Properties /// /// Gets or sets the TestID that uniquely identifies this test /// public TestID TestID { get { return testID; } set { testID = value; } } /// /// Gets the ID for the runner that created the test from /// the TestID, or returns -1 if the TestID is null. /// public int RunnerID { get { return runnerID; } set { runnerID = value; } } /// /// Gets or sets the simple name of the test /// public string Name { get { return name; } set { name = value; } } /// /// Gets or sets the full (qualified) name of the test /// public string FullName { get { return fullName; } set { fullName = value; } } /// /// Get the string representation of this test name, incorporating all /// the components of the name. /// public string UniqueName { get { if ( this.testID == null ) return string.Format( "[{0}]{1}", this.runnerID, this.fullName ); else return string.Format( "[{0}-{1}]{2}", this.RunnerID, this.testID, this.fullName ); } } #endregion #region Static Methods /// /// Parse a string representation of a TestName, /// returning a TestName. /// /// The string to parse /// A TestName public static TestName Parse( string s ) { if ( s == null ) throw new ArgumentNullException( "s", "Cannot parse a null string" ); TestName testName = new TestName(); testName.FullName = testName.Name = s; if ( s.StartsWith( "[" ) ) { int rbrack = s.IndexOf( "]" ); if ( rbrack < 0 || rbrack == s.Length - 1 ) throw new FormatException( "Invalid TestName format: " + s ); testName.FullName = testName.Name = s.Substring( rbrack + 1 ); int dash = s.IndexOf( "-" ); if ( dash < 0 || dash > rbrack ) testName.RunnerID = Int32.Parse( s.Substring( 1, rbrack - 1 ) ); else { testName.RunnerID = Int32.Parse( s.Substring( 1, dash - 1 ) ); testName.TestID = TestID.Parse( s.Substring( dash + 1, rbrack - dash - 1 ) ); } } return testName; } #endregion #region Object Overrides /// /// Compares two TestNames for equality /// /// the other TestID /// True if the two TestIDs are equal public override bool Equals(object obj) { TestName other = obj as TestName; if ( other == null ) return base.Equals (obj); return this.TestID == other.testID && this.runnerID == other.runnerID && this.fullName == other.fullName; } /// /// Calculates a hashcode for this TestID /// /// The hash code. public override int GetHashCode() { return unchecked( this.testID.GetHashCode() + this.fullName.GetHashCode() ); } /// /// Override ToString() to display the UniqueName /// /// public override string ToString() { return this.UniqueName; } #endregion #region Operator Overrides /// /// Override the == operator /// /// /// /// public static bool operator ==( TestName name1, TestName name2 ) { if ( Object.Equals( name1, null ) ) return Object.Equals( name2, null ); return name1.Equals( name2 ); } /// /// Override the != operator /// /// /// /// public static bool operator !=( TestName name1, TestName name2 ) { return name1 == name2 ? false : true; } #endregion #region ICloneable Implementation /// /// Returns a duplicate of this TestName /// /// public object Clone() { return this.MemberwiseClone(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/EventListener.cs0000664000175000017500000000476611504175260023073 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; /// /// The EventListener interface is used within the NUnit core to receive /// notifications of significant events while a test is being run. These /// events are propogated to any client, which may choose to convert them /// to .NET events or to use them directly. /// public interface EventListener { /// /// Called when a test run is starting /// /// The name of the test being started /// The number of test cases under this test void RunStarted( string name, int testCount ); /// /// Called when a run finishes normally /// /// The result of the test void RunFinished( TestResult result ); /// /// Called when a run is terminated due to an exception /// /// Exception that was thrown void RunFinished( Exception exception ); /// /// Called when a test case is starting /// /// The name of the test case void TestStarted(TestName testName); /// /// Called when a test case has finished /// /// The result of the test void TestFinished(TestResult result); /// /// Called when a suite is starting /// /// The name of the suite void SuiteStarted(TestName testName); /// /// Called when a suite has finished /// /// The result of the suite void SuiteFinished(TestResult result); /// /// Called when an unhandled exception is detected during /// the execution of a test run. /// /// The exception thta was detected void UnhandledException( Exception exception ); /// /// Called when the test direts output to the console. /// /// A console message void TestOutput(TestOutput testOutput); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/nunit.core.interfaces.build0000664000175000017500000000620311703040336025164 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestFilter.cs0000664000175000017500000000642711504175260022365 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// Interface to be implemented by filters applied to tests. /// The filter applies when running the test, after it has been /// loaded, since this is the only time an ITest exists. /// [Serializable] public abstract class TestFilter : ITestFilter { /// /// Unique Empty filter. /// public static TestFilter Empty = new EmptyFilter(); /// /// Indicates whether this is the EmptyFilter /// public bool IsEmpty { get { return this is TestFilter.EmptyFilter; } } /// /// Determine if a particular test passes the filter criteria. The default /// implementation checks the test itself, its parents and any descendants. /// /// Derived classes may override this method or any of the Match methods /// to change the behavior of the filter. /// /// The test to which the filter is applied /// True if the test passes the filter, otherwise false public virtual bool Pass( ITest test ) { return Match(test) || MatchParent(test) || MatchDescendant(test); } /// /// Determine whether the test itself matches the filter criteria, without /// examining either parents or descendants. /// /// The test to which the filter is applied /// True if the filter matches the any parent of the test public abstract bool Match(ITest test); /// /// Determine whether any ancestor of the test mateches the filter criteria /// /// The test to which the filter is applied /// True if the filter matches the an ancestor of the test protected virtual bool MatchParent(ITest test) { return (test.RunState != RunState.Explicit && test.Parent != null && ( Match(test.Parent) || MatchParent(test.Parent)) ); } /// /// Determine whether any descendant of the test matches the filter criteria. /// /// The test to be matched /// True if at least one descendant matches the filter criteria protected virtual bool MatchDescendant(ITest test) { if (!test.IsSuite || test.Tests == null) return false; foreach (ITest child in test.Tests) { if (Match(child) || MatchDescendant(child)) return true; } return false; } /// /// Nested class provides an empty filter - one that always /// returns true when called, unless the test is marked explicit. /// [Serializable] private class EmptyFilter : TestFilter { public override bool Match( ITest test ) { return test.RunState != RunState.Explicit; } public override bool Pass( ITest test ) { return test.RunState != RunState.Explicit; } } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/IService.cs0000664000175000017500000000125411504175260022002 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// The IService interface is implemented by all Services. /// public interface IService { /// /// Initialize the Service /// void InitializeService(); /// /// Do any cleanup needed before terminating the service /// void UnloadService(); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestRunner.cs0000664000175000017500000001377111717225024022411 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org // **************************************************************** using System; using System.Collections; using System.IO; namespace NUnit.Core { /// /// The TestRunner Interface allows client code, such as the NUnit console and /// gui runners, to load and run tests. This is the lowest level interface generally /// supported for running tests and is implemented by the RemoteTestRunner class in /// the NUnit core as well as by other classes running on the client side. /// /// The Load method is used to load a suite of tests from one or more /// assemblies, returning a tree of TestNodes to the caller. /// /// The CountTestCases family of methods returns the number of test cases in the /// loaded suite, either in its entirety or by using a filter to count a subset of tests. /// /// The Run family of methods performs a test run synchronously, returning a TestResult /// or TestResult[] to the caller. If provided, an EventListener interface will be /// notified of significant events in the running of the tests. A filter may be used /// to run a subset of the tests. /// /// BeginRun and EndRun provide a simplified form of the asynchronous invocation /// pattern used in many places within the .NET framework. Because the current /// implementation allows only one run to be in process at a time, an IAsyncResult /// is not used at this time. /// /// Methods to cancel a run and to wait for a run to complete are also provided. The /// result of the last run may be obtained by querying the TestResult property. /// /// public interface TestRunner : IDisposable { #region Properties /// /// TestRunners are identified by an ID. So long as there /// is only one test runner or a single chain of test runners, /// the default id of 0 may be used. However, any client that /// creates multiple runners must ensure that each one has a /// unique ID in order to locate and run specific tests. /// int ID { get; } /// /// Running indicates whether a test is in progress. To retrieve the /// results from an asynchronous test run, wait till Running is false. /// bool Running { get; } /// /// Returns information about loaded assemblies /// IList AssemblyInfo { get; } /// /// The loaded test, converted to a tree of TestNodes so they can be /// serialized and marshalled to a remote client. /// ITest Test { get; } /// /// Result of the last test run. /// TestResult TestResult { get; } #endregion #region Load and Unload Methods /// /// Load the assemblies in a test package /// /// The test package to be loaded /// True if the tests were loaded successfully, otherwise false bool Load( TestPackage package ); /// /// Unload all tests previously loaded /// void Unload(); #endregion #region CountTestCases Methods /// /// Count Test Cases using a filter /// /// The filter to apply /// The number of test cases found int CountTestCases(ITestFilter filter ); #endregion #region Run Methods /// /// Run selected tests and return a test result. The test is run synchronously, /// and the listener interface is notified as it progresses. Arguments control whether /// trace and log output are passed back to the caller. /// /// Interface to receive EventListener notifications. /// The filter to apply when running the tests /// If true, trace output is returned as a TestOutput event /// The threshold for log output to be returned as a TestOutput event TestResult Run(NUnit.Core.EventListener listener, ITestFilter filter, bool captureTrace, LoggingThreshold logLevel); /// /// Start a run of selected tests. The tests are run aynchronously and the /// listener interface is notified as it progresses. Arguments control whether /// trace and log output are passed back to the caller. /// /// Interface to receive EventListener notifications. /// The filter to apply when running the tests /// If true, trace output is returned as a TestOutput event /// The threshold for log output to be returned as a TestOutput event void BeginRun(NUnit.Core.EventListener listener, ITestFilter filter, bool captureTrace, LoggingThreshold logLevel); /// /// Wait for an asynchronous run to complete and return the result. /// /// A TestResult for the entire run TestResult EndRun(); /// /// Cancel the test run that is in progress. For a synchronous run, /// a client wanting to call this must create a separate run thread. /// void CancelRun(); /// /// Wait for the test run in progress to complete. For a synchronous run, /// a client wanting to call this must create a separate run thread. In /// particular, a gui client calling this method is likely to hang, since /// events will not be able to invoke methods on the gui thread. /// void Wait(); #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/AssemblyInfo.cs0000664000175000017500000000100311504175260022654 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; [assembly: CLSCompliant(true)] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/NUnitCore/interfaces/LoggingThreshold.cs0000664000175000017500000000234711703126572023543 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Core { /// /// Enumeration expressing the level of log messages to be /// captured by NUnit and sent to the runner. These happen /// to match the standard levels used by log4net, but will /// be translated for any other loggers we support. /// public enum LoggingThreshold { /// No logging Off = 0, /// Severe error beyond which continuation is not possible Fatal = 1, /// Error that may allow continuation Error = 2, /// A warning message Warn = 3, /// An informational message Info = 4, /// Messages used for debugging Debug = 5, /// All of the preceding plus more detailled messages if supported All = 6, } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/OSPlatform.cs0000664000175000017500000002466211710343654022332 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Runtime.InteropServices; namespace NUnit.Core { /// /// OSPlatform represents a particular operating system platform /// public class OSPlatform { PlatformID platform; Version version; ProductType product; #region Static Members private static OSPlatform currentPlatform; /// /// Platform ID for Unix as defined by Microsoft .NET 2.0 and greater /// public static readonly PlatformID UnixPlatformID_Microsoft = (PlatformID)4; /// /// Platform ID for Unix as defined by Mono /// public static readonly PlatformID UnixPlatformID_Mono = (PlatformID)128; /// /// Get the OSPlatform under which we are currently running /// public static OSPlatform CurrentPlatform { get { if (currentPlatform == null) { OperatingSystem os = Environment.OSVersion; if (os.Platform == PlatformID.Win32NT && os.Version.Major >= 5) { OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); GetVersionEx(ref osvi); currentPlatform = new OSPlatform(os.Platform, os.Version, (ProductType)osvi.ProductType); } else currentPlatform = new OSPlatform(os.Platform, os.Version); } return currentPlatform; } } #endregion #region Members used for Win32NT platform only /// /// Product Type Enumeration used for Windows /// public enum ProductType { /// /// Product type is unknown or unspecified /// Unknown, /// /// Product type is Workstation /// WorkStation, /// /// Product type is Domain Controller /// DomainController, /// /// Product type is Server /// Server, } [StructLayout(LayoutKind.Sequential)] struct OSVERSIONINFOEX { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public Int16 wServicePackMajor; public Int16 wServicePackMinor; public Int16 wSuiteMask; public Byte ProductType; public Byte Reserved; } [DllImport("Kernel32.dll")] private static extern bool GetVersionEx(ref OSVERSIONINFOEX osvi); #endregion /// /// Construct from a platform ID and version /// public OSPlatform(PlatformID platform, Version version) { this.platform = platform; this.version = version; } /// /// Construct from a platform ID, version and product type /// public OSPlatform(PlatformID platform, Version version, ProductType product) : this( platform, version ) { this.product = product; } /// /// Get the platform ID of this instance /// public PlatformID Platform { get { return platform; } } /// /// Get the Version of this instance /// public Version Version { get { return version; } } /// /// Get the Product Type of this instance /// public ProductType Product { get { return product; } } /// /// Return true if this is a windows platform /// public bool IsWindows { get { return platform == PlatformID.Win32NT || platform == PlatformID.Win32Windows || platform == PlatformID.Win32S || platform == PlatformID.WinCE; } } /// /// Return true if this is a Unix or Linux platform /// public bool IsUnix { get { return platform == UnixPlatformID_Microsoft || platform == UnixPlatformID_Mono; } } /// /// Return true if the platform is Win32S /// public bool IsWin32S { get { return platform == PlatformID.Win32S; } } /// /// Return true if the platform is Win32Windows /// public bool IsWin32Windows { get { return platform == PlatformID.Win32Windows; } } /// /// Return true if the platform is Win32NT /// public bool IsWin32NT { get { return platform == PlatformID.Win32NT; } } /// /// Return true if the platform is Windows CE /// public bool IsWinCE { get { return (int)platform == 3; } // PlatformID.WinCE not defined in .NET 1.0 } /// /// Return true if the platform is Windows 95 /// public bool IsWin95 { get { return platform == PlatformID.Win32Windows && version.Major == 4 && version.Minor == 0; } } /// /// Return true if the platform is Windows 98 /// public bool IsWin98 { get { return platform == PlatformID.Win32Windows && version.Major == 4 && version.Minor == 10; } } /// /// Return true if the platform is Windows ME /// public bool IsWinME { get { return platform == PlatformID.Win32Windows && version.Major == 4 && version.Minor == 90; } } /// /// Return true if the platform is NT 3 /// public bool IsNT3 { get { return platform == PlatformID.Win32NT && version.Major == 3; } } /// /// Return true if the platform is NT 4 /// public bool IsNT4 { get { return platform == PlatformID.Win32NT && version.Major == 4; } } /// /// Return true if the platform is NT 5 /// public bool IsNT5 { get { return platform == PlatformID.Win32NT && version.Major == 5; } } /// /// Return true if the platform is Windows 2000 /// public bool IsWin2K { get { return IsNT5 && version.Minor == 0; } } /// /// Return true if the platform is Windows XP /// public bool IsWinXP { get { return IsNT5 && version.Minor == 1 || (version.Minor == 2 && Product == ProductType.WorkStation); } } /// /// Return true if the platform is Windows 2003 Server /// public bool IsWin2003Server { get { return IsNT5 && version.Minor == 2 && Product == ProductType.Server; } } /// /// Return true if the platform is NT 6 /// public bool IsNT6 { get { return platform == PlatformID.Win32NT && version.Major == 6; } } /// /// Return true if the platform is Vista /// public bool IsVista { get { return IsNT6 && version.Minor == 0 && Product == ProductType.WorkStation; } } /// /// Return true if the platform is Windows 2008 Server (original or R2) /// public bool IsWin2008Server { get { return IsNT6 && Product == ProductType.Server; } } /// /// Return true if the platform is Windows 2008 Server (original) /// public bool IsWin2008ServerR1 { get { return IsNT6 && version.Minor == 0 && Product == ProductType.Server; } } /// /// Return true if the platform is Windows 2008 Server R2 /// public bool IsWin2008ServerR2 { get { return IsNT6 && version.Minor == 1 && Product == ProductType.Server; } } /// /// Return true if the platform is Windows 2012 Server /// public bool IsWin2012Server { get { return IsNT6 && version.Minor == 2 && Product == ProductType.Server; } } /// /// Return true if the platform is Windows 7 /// public bool IsWindows7 { get { return IsNT6 && version.Minor == 1 && Product == ProductType.WorkStation; } } /// /// Return true if the platform is Windows 8 /// public bool IsWindows8 { get { return IsNT6 && version.Minor == 2 && Product == ProductType.WorkStation; } } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestOutput.cs0000664000175000017500000000410611504175260022430 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Core { using System; /// /// The TestOutput class holds a unit of output from /// a test to either stdOut or stdErr /// [Serializable] public class TestOutput { string text; TestOutputType type; /// /// Construct with text and an ouput destination type /// /// Text to be output /// Destination of output public TestOutput(string text, TestOutputType type) { this.text = text; this.type = type; } /// /// Return string representation of the object for debugging /// /// public override string ToString() { return type + ": " + text; } /// /// Get the text /// public string Text { get { return this.text; } } /// /// Get the output type /// public TestOutputType Type { get { return this.type; } } } /// /// Enum representing the output destination /// It uses combinable flags so that a given /// output control can accept multiple types /// of output. Normally, each individual /// output uses a single flag value. /// public enum TestOutputType { /// /// Send output to stdOut /// Out, /// /// Send output to stdErr /// Error, /// /// Send output to Trace /// Trace, /// /// Send output to Log /// Log } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestResult.cs0000664000175000017500000003710611715540416022417 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Text; using System.Collections; /// /// The TestResult class represents /// the result of a test and is used to /// communicate results across AppDomains. /// /// [Serializable] public class TestResult { #region Fields /// /// Indicates the result of the test /// private ResultState resultState; /// /// Indicates the location of a failure /// private FailureSite failureSite; /// /// The elapsed time for executing this test /// private double time = 0.0; /// /// The test that this result pertains to /// private readonly TestInfo test; /// /// The stacktrace at the point of failure /// private string stackTrace; /// /// Message giving the reason for failure /// private string message; /// /// List of child results /// private IList results; /// /// Number of asserts executed by this test /// private int assertCount = 0; #endregion #region Constructor /// /// Construct a test result given a TestInfo /// /// The test to be used public TestResult(TestInfo test) { this.test = test; this.message = test.IgnoreReason; } /// /// Construct a TestResult given an ITest /// /// public TestResult(ITest test) : this( new TestInfo(test) ) { } /// /// Construct a TestResult given a TestName /// /// A TestName public TestResult(TestName testName) : this( new TestInfo( testName ) ) { } #endregion #region Properties /// /// Gets the ResultState of the test result, which /// indicates the success or failure of the test. /// public ResultState ResultState { get { return resultState; } } /// /// Gets the stage of the test in which a failure /// or error occured. /// public FailureSite FailureSite { get { return failureSite; } } /// /// Indicates whether the test executed /// public bool Executed { get { return resultState == ResultState.Success || resultState == ResultState.Failure || resultState == ResultState.Error || resultState == ResultState.Inconclusive; } } /// /// Gets the name of the test result /// public virtual string Name { get { return test.TestName.Name; } } /// /// Gets the full name of the test result /// public virtual string FullName { get { return test.TestName.FullName; } } /// /// Gets the test associated with this result /// public ITest Test { get { return test; } } /// /// Indicates whether the test ran successfully /// public virtual bool IsSuccess { get { return resultState == ResultState.Success; } } /// /// Indicates whether the test failed /// public virtual bool IsFailure { get { return resultState == ResultState.Failure; } } /// /// Indicates whether the test had an error (as opposed to a failure) /// public virtual bool IsError { get { return resultState == ResultState.Error; } } /// /// Gets a description associated with the test /// public string Description { get { return test.Description; } } /// /// Gets the elapsed time for running the test /// public double Time { get { return time; } set { time = value; } } /// /// Gets the message associated with a test /// failure or with not running the test /// public string Message { get { return message; } } /// /// Gets any stacktrace associated with an /// error or failure. /// public virtual string StackTrace { get { return stackTrace; } set { stackTrace = value; } } /// /// Gets or sets the count of asserts executed /// when running the test. /// public int AssertCount { get { return assertCount; } set { assertCount = value; } } /// /// Return true if this result has any child results /// public bool HasResults { get { return results != null && results.Count > 0; } } /// /// Gets a list of the child results of this TestResult /// public IList Results { get { return results; } } #endregion #region Public Methods /// /// Mark the test as succeeding /// public void Success() { SetResult( ResultState.Success, null, null ); } /// /// Mark the test as succeeding and set a message /// public void Success( string message ) { SetResult( ResultState.Success, message, null ); } /// /// Mark the test as ignored. /// /// The reason the test was not run public void Ignore(string reason) { Ignore( reason, null ); } /// /// Mark the test as ignored. /// /// The ignore exception that was thrown public void Ignore( Exception ex ) { Ignore( ex.Message, BuildStackTrace( ex ) ); } /// /// Mark the test as ignored. /// /// The reason the test was not run /// Stack trace giving the location of the command public void Ignore(string reason, string stackTrace) { SetResult( ResultState.Ignored, reason, stackTrace ); } /// /// Mark the test as skipped. /// /// The reason the test was not run public void Skip(string reason) { SetResult(ResultState.Skipped, reason, null); } /// /// Mark the test a not runnable with a reason /// /// The reason the test is invalid public void Invalid( string reason ) { SetResult( ResultState.NotRunnable, reason, null ); } /// /// Mark the test as not runnable due to a builder exception /// /// The exception thrown by the builder or an addin public void Invalid(Exception ex) { SetResult(ResultState.NotRunnable, BuildMessage( ex ), BuildStackTrace(ex)); } /// /// Set the result of the test /// /// The ResultState to use in the result /// The reason the test was not run /// Stack trace giving the location of the command /// The location of the failure, if any public void SetResult(ResultState resultState, string reason, string stackTrace, FailureSite failureSite) { if (failureSite == FailureSite.SetUp) reason = "SetUp : " + reason; else if (failureSite == FailureSite.TearDown) { reason = "TearDown : " + reason; stackTrace = "--TearDown" + Environment.NewLine + stackTrace; if (this.message != null) reason = this.message + Environment.NewLine + reason; if (this.stackTrace != null) stackTrace = this.stackTrace + Environment.NewLine + stackTrace; } this.resultState = resultState; this.message = reason; this.stackTrace = stackTrace; this.failureSite = failureSite; } /// /// Set the result of the test /// /// The ResultState to use in the result /// The reason the test was not run /// Stack trace giving the location of the command public void SetResult(ResultState resultState, string reason, string stackTrace) { SetResult(resultState, reason, stackTrace, FailureSite.Test); } /// /// Set the result of the test. /// /// The ResultState to use in the result /// The exception that caused this result /// The site at which an error or failure occured public void SetResult(ResultState resultState, Exception ex, FailureSite failureSite) { if (resultState == ResultState.Cancelled) SetResult(resultState, "Test cancelled by user", BuildStackTrace(ex)); else if (resultState == ResultState.Error) SetResult( resultState, BuildMessage(ex), BuildStackTrace(ex), failureSite); else SetResult(resultState, ex.Message, ex.StackTrace, failureSite); } /// /// Mark the test as a failure due to an /// assertion having failed. /// /// Message to display /// Stack trace giving the location of the failure public void Failure(string message, string stackTrace) { Failure(message, stackTrace, FailureSite.Test); } /// /// Mark the test as a failure due to an /// assertion having failed. /// /// Message to display /// Stack trace giving the location of the failure /// The site of the failure public void Failure(string message, string stackTrace, FailureSite failureSite ) { SetResult( Core.ResultState.Failure, message, stackTrace ); this.failureSite = failureSite; } /// /// Marks the result as an error due to an exception thrown /// by the test. /// /// The exception that was caught public void Error(Exception exception) { Error(exception, FailureSite.Test); } /// /// Marks the result as an error due to an exception thrown /// from the indicated FailureSite. /// /// The exception that was caught /// The site from which it was thrown public void Error(Exception exception, FailureSite failureSite) { SetResult(ResultState.Error, exception, failureSite); //string message = BuildMessage(exception); //string stackTrace = BuildStackTrace(exception); //if (failureSite == FailureSite.TearDown) //{ // message = "TearDown : " + message; // stackTrace = "--TearDown" + Environment.NewLine + stackTrace; // if (this.message != null) // message = this.message + Environment.NewLine + message; // if (this.stackTrace != null) // stackTrace = this.stackTrace + Environment.NewLine + stackTrace; //} //SetResult( ResultState.Error, message, stackTrace ); //this.failureSite = failureSite; } /// /// Add a child result /// /// The child result to be added public void AddResult(TestResult result) { if ( results == null ) results = new ArrayList(); this.results.Add(result); switch (result.ResultState) { case ResultState.Failure: case ResultState.Error: case ResultState.NotRunnable: if (!this.IsFailure && !this.IsError && this.ResultState != ResultState.NotRunnable) this.Failure("One or more child tests had errors", null, FailureSite.Child); break; case ResultState.Success: if (this.ResultState == ResultState.Inconclusive) this.Success(); break; // Removed this case due to bug #928018 //case ResultState.Ignored: // if (this.ResultState == ResultState.Inconclusive || ResultState == ResultState.Success) // this.SetResult(ResultState.Ignored, "One or more child tests were ignored", null, FailureSite.Child); // break; case ResultState.Cancelled: this.SetResult(ResultState.Cancelled, result.Message, null, FailureSite.Child); break; } } #endregion #region Exception Helpers private static string BuildMessage(Exception exception) { StringBuilder sb = new StringBuilder(); sb.AppendFormat( "{0} : {1}", exception.GetType().ToString(), exception.Message ); Exception inner = exception.InnerException; while( inner != null ) { sb.Append( Environment.NewLine ); sb.AppendFormat( " ----> {0} : {1}", inner.GetType().ToString(), inner.Message ); inner = inner.InnerException; } return sb.ToString(); } private static string BuildStackTrace(Exception exception) { StringBuilder sb = new StringBuilder( GetStackTrace( exception ) ); Exception inner = exception.InnerException; while( inner != null ) { sb.Append( Environment.NewLine ); sb.Append( "--" ); sb.Append( inner.GetType().Name ); sb.Append( Environment.NewLine ); sb.Append( GetStackTrace( inner ) ); inner = inner.InnerException; } return sb.ToString(); } private static string GetStackTrace(Exception exception) { try { return exception.StackTrace; } catch( Exception ) { return "No stack trace available"; } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Test.cs0000664000175000017500000002251111544454420021211 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Collections; using System.Collections.Specialized; using System.Threading; using System.Reflection; /// /// Test Class. /// public abstract class Test : ITest, IComparable { #region Constants //private static readonly string SETCULTURE = "_SETCULTURE"; private static readonly string DESCRIPTION = "_DESCRIPTION"; private static readonly string IGNOREREASON = "_IGNOREREASON"; private static readonly string CATEGORIES = "_CATEGORIES"; #endregion #region Fields /// /// TestName that identifies this test /// private TestName testName; /// /// Indicates whether the test should be executed /// private RunState runState; /// /// Test suite containing this test, or null /// private Test parent; /// /// A dictionary of properties, used to add information /// to tests without requiring the class to change. /// private IDictionary properties; #endregion #region Properties /// /// Return true if the test requires a thread /// public bool RequiresThread { get { return Properties.Contains("RequiresThread") && (bool)Properties["RequiresThread"]; } } /// /// Get the desired apartment state for running the test /// public ApartmentState ApartmentState { get { return Properties.Contains("APARTMENT_STATE") ? (ApartmentState)Properties["APARTMENT_STATE"] : GetCurrentApartment(); } } /// /// Get the current apartment state of the test /// protected ApartmentState GetCurrentApartment() { #if CLR_2_0 || CLR_4_0 return Thread.CurrentThread.GetApartmentState(); #else return Thread.CurrentThread.ApartmentState; #endif } /// /// Gets a boolean value indicating whether this /// test should run on it's own thread. /// protected virtual bool ShouldRunOnOwnThread { get { return RequiresThread || ApartmentState != ApartmentState.Unknown && ApartmentState != GetCurrentApartment(); } } #endregion #region Construction /// /// Constructs a test given its name /// /// The name of the test protected Test( string name ) { this.testName = new TestName(); this.testName.FullName = name; this.testName.Name = name; this.testName.TestID = new TestID(); this.runState = RunState.Runnable; } /// /// Constructs a test given the path through the /// test hierarchy to its parent and a name. /// /// The parent tests full name /// The name of the test protected Test( string pathName, string name ) { this.testName = new TestName(); this.testName.FullName = pathName == null || pathName == string.Empty ? name : pathName + "." + name; this.testName.Name = name; this.testName.TestID = new TestID(); this.runState = RunState.Runnable; } /// /// Constructs a test given a TestName object /// /// The TestName for this test protected Test( TestName testName ) { this.testName = testName; this.runState = RunState.Runnable; } /// /// Sets the runner id of a test and optionally its children /// /// The runner id to be used /// True if all children should get the same id public void SetRunnerID( int runnerID, bool recursive ) { this.testName.RunnerID = runnerID; if ( recursive && this.Tests != null ) foreach( Test child in this.Tests ) child.SetRunnerID( runnerID, true ); } #endregion #region ITest Members #region Properties /// /// Gets the TestName of the test /// public TestName TestName { get { return testName; } } /// /// Gets a string representing the kind of test /// that this object represents, for use in display. /// public abstract string TestType { get; } /// /// Whether or not the test should be run /// public RunState RunState { get { return runState; } set { runState = value; } } /// /// Reason for not running the test, if applicable /// public string IgnoreReason { get { return (string)Properties[IGNOREREASON]; } set { if (value == null) Properties.Remove(IGNOREREASON); else Properties[IGNOREREASON] = value; } } /// /// Gets a count of test cases represented by /// or contained under this test. /// public virtual int TestCount { get { return 1; } } /// /// Gets a list of categories associated with this test. /// public IList Categories { get { if (Properties[CATEGORIES] == null) Properties[CATEGORIES] = new ArrayList(); return (IList)Properties[CATEGORIES]; } set { Properties[CATEGORIES] = value; } } /// /// Gets a description associated with this test. /// public String Description { get { return (string)Properties[DESCRIPTION]; } set { if (value == null) Properties.Remove(DESCRIPTION); else Properties[DESCRIPTION] = value; } } /// /// Gets the property dictionary for this test /// public IDictionary Properties { get { if ( properties == null ) properties = new ListDictionary(); return properties; } set { properties = value; } } /// /// Indicates whether this test is a suite /// public virtual bool IsSuite { get { return false; } } /// /// Gets the parent test of this test /// ITest ITest.Parent { get { return parent; } } /// /// Gets the parent as a Test object. /// Used by the core to set the parent. /// public Test Parent { get { return parent; } set { parent = value; } } /// /// Gets this test's child tests /// public virtual IList Tests { get { return null; } } /// /// Gets the Type of the fixture used in running this test /// public virtual Type FixtureType { get { return null; } } /// /// Gets or sets a fixture object for running this test /// public abstract object Fixture { get; set; } #endregion #region Methods /// /// Gets a count of test cases that would be run using /// the specified filter. /// /// /// public virtual int CountTestCases(ITestFilter filter) { if (filter.Pass(this)) return 1; return 0; } /// /// Runs the test under a particular filter, sending /// notifications to a listener. /// /// An event listener to receive notifications /// A filter used in running the test /// public abstract TestResult Run(EventListener listener, ITestFilter filter); #endregion #endregion #region IComparable Members /// /// Compares this test to another test for sorting purposes /// /// The other test /// Value of -1, 0 or +1 depending on whether the current test is less than, equal to or greater than the other test public int CompareTo(object obj) { Test other = obj as Test; if ( other == null ) return -1; return this.TestName.FullName.CompareTo( other.TestName.FullName ); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/PropertyNames.cs0000664000175000017500000000646711720006750023111 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// The PropertyNames struct lists common property names, which are /// accessed by reflection in the NUnit core. This provides a modicum /// of type safety as opposed to using the strings directly. /// public struct PropertyNames { /// Exception Type expected from a test public static readonly string ExpectedException = "ExpectedException"; /// Exception Type expected from a test (pre-2.5) public static readonly string LegacyExceptionType = "ExceptionType"; /// FullName of the Exception Type expected from a test public static readonly string ExpectedExceptionName = "ExpectedExceptionName"; /// FullName of the Exception Type expected from a test (pre-2.5) public static readonly string LegacyExceptionName = "ExceptionName"; /// ExpectedException Message public static readonly string ExpectedMessage = "ExpectedMessage"; /// ExpectedException MatchType public static readonly string MatchType = "MatchType"; /// Expected return result from test public static readonly string ExpectedResult = "Result"; /// Indicates whether there is an expected return result public static readonly string HasExpectedResult = "HasExpectedResult"; /// Description of the test public static readonly string Description = "Description"; /// Alternate test name public static readonly string TestName = "TestName"; /// Arguments for the test public static readonly string Arguments = "Arguments"; /// Indicates test case is ignored public static readonly string Ignored = "Ignored"; /// Indicates test case is explicit public static readonly string Explicit = "Explicit"; /// The reason a test case is ignored public static readonly string IgnoreReason = "IgnoreReason"; /// Properties of the test public static readonly string Properties = "Properties"; /// Categories of the test public static readonly string Categories = "Categories"; /// Name of a category public static readonly string CategoryName = "Name"; /// Reason for not running a test public static readonly string Reason = "Reason"; /// Flag indicating excluded test should be marked as Ignored public static readonly string IgnoreExcluded = "IgnoreExcluded"; /// Name of an addin that must be present to run a test public static readonly string RequiredAddin = "RequiredAddin"; } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/0000775000175000017500000000000011742560362021355 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/SimpleNameFilter.cs0000664000175000017500000000433411537032266025107 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Core.Filters { /// /// SimpleName filter selects tests based on their name /// [Serializable] public class SimpleNameFilter : TestFilter { private ArrayList names = new ArrayList(); /// /// Construct an empty SimpleNameFilter /// public SimpleNameFilter() { } /// /// Construct a SimpleNameFilter for a single name /// /// The name the filter will recognize. public SimpleNameFilter(string name) { names.Add(name); } /// /// Construct a SimpleNameFilter for an array of names /// /// The names the filter will recognize. public SimpleNameFilter(string[] namesToAdd) { this.names.AddRange(namesToAdd); } /// /// Add a name to a SimpleNameFilter /// /// The name to be added. public void Add(string name) { names.Add(name); } /// /// Add an array of names to a SimpleNameFilter /// /// The name to be added. public void Add(string[] namesToAdd) { foreach (string name in namesToAdd) names.Add(name); } /// /// Check whether the filter matches a test /// /// The test to be matched /// True if it matches, otherwise false public override bool Match( ITest test ) { foreach( string name in names ) if ( test.TestName.FullName == name ) return true; return false; } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/OrFilter.cs0000664000175000017500000000517611651755452023450 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Text; namespace NUnit.Core.Filters { /// /// Combines multiple filters so that a test must pass one /// of them in order to pass this filter. /// [Serializable] public class OrFilter : TestFilter { private ArrayList filters = new ArrayList(); /// /// Constructs an empty OrFilter /// public OrFilter() { } /// /// Constructs an AndFilter from an array of filters /// /// public OrFilter( params ITestFilter[] filters ) { this.filters.AddRange( filters ); } /// /// Adds a filter to the list of filters /// /// The filter to be added public void Add( ITestFilter filter ) { this.filters.Add( filter ); } /// /// Return an array of the composing filters /// public ITestFilter[] Filters { get { return (ITestFilter[])filters.ToArray(typeof(ITestFilter)); } } /// /// Checks whether the OrFilter is matched by a test /// /// The test to be matched /// True if any of the component filters pass, otherwise false public override bool Pass( ITest test ) { foreach( ITestFilter filter in filters ) if ( filter.Pass( test ) ) return true; return false; } /// /// Checks whether the OrFilter is matched by a test /// /// The test to be matched /// True if any of the component filters match, otherwise false public override bool Match( ITest test ) { foreach( ITestFilter filter in filters ) if ( filter.Match( test ) ) return true; return false; } /// /// Return the string representation of an or filter /// /// public override string ToString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < filters.Count; i++) { if (i > 0) sb.Append(" or "); sb.Append(filters[i]); } return sb.ToString(); } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/CategoryFilter.cs0000664000175000017500000000501011504175260024616 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Text; using System.Collections; namespace NUnit.Core.Filters { /// /// CategoryFilter is able to select or exclude tests /// based on their categories. /// /// [Serializable] public class CategoryFilter : TestFilter { ArrayList categories; /// /// Construct an empty CategoryFilter /// public CategoryFilter() { categories = new ArrayList(); } /// /// Construct a CategoryFilter using a single category name /// /// A category name public CategoryFilter( string name ) { categories = new ArrayList(); if ( name != null && name != string.Empty ) categories.Add( name ); } /// /// Construct a CategoryFilter using an array of category names /// /// An array of category names public CategoryFilter( string[] names ) { categories = new ArrayList(); if ( names != null ) categories.AddRange( names ); } /// /// Add a category name to the filter /// /// A category name public void AddCategory(string name) { categories.Add( name ); } /// /// Check whether the filter matches a test /// /// The test to be matched /// public override bool Match(ITest test) { if ( test.Categories == null ) return false; foreach( string cat in categories ) if ( test.Categories.Contains( cat ) ) return true; return false; } /// /// Return the string representation of a category filter /// /// public override string ToString() { StringBuilder sb = new StringBuilder(); for( int i = 0; i < categories.Count; i++ ) { if ( i > 0 ) sb.Append( ',' ); sb.Append( categories[i] ); } return sb.ToString(); } /// /// Gets the list of categories from this filter /// public IList Categories { get { return categories; } } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/AndFilter.cs0000664000175000017500000000524011662016114023545 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Core.Filters { /// /// Combines multiple filters so that a test must pass all /// of them in order to pass this filter. /// [Serializable] public class AndFilter : TestFilter { private ArrayList filters = new ArrayList(); /// /// Constructs an empty AndFilter /// public AndFilter() { } /// /// Constructs an AndFilter from an array of filters /// /// public AndFilter( params ITestFilter[] filters ) { this.filters.AddRange( filters ); } /// /// Adds a filter to the list of filters /// /// The filter to be added public void Add( ITestFilter filter ) { this.filters.Add( filter ); } /// /// Return an array of the composing filters /// public ITestFilter[] Filters { get { return (ITestFilter[])filters.ToArray(typeof(ITestFilter)); } } /// /// Checks whether the AndFilter is matched by a test /// /// The test to be matched /// True if all the component filters pass, otherwise false public override bool Pass( ITest test ) { foreach( ITestFilter filter in filters ) if ( !filter.Pass( test ) ) return false; return true; } /// /// Checks whether the AndFilter is matched by a test /// /// The test to be matched /// True if all the component filters match, otherwise false public override bool Match( ITest test ) { foreach( ITestFilter filter in filters ) if ( !filter.Match( test ) ) return false; return true; } /// /// Return string representation of the filter. /// public override string ToString() { int count = 0; System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (TestFilter filter in filters) { if (count++ > 0) sb.Append(" and "); sb.Append(filter.ToString()); } return sb.ToString(); } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/NameFilter.cs0000664000175000017500000000267511504175260023737 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Core.Filters { /// /// Summary description for NameFilter. /// /// [Serializable] public class NameFilter : TestFilter { private ArrayList testNames = new ArrayList(); /// /// Construct an empty NameFilter /// public NameFilter() { } /// /// Construct a NameFilter for a single TestName /// /// public NameFilter( TestName testName ) { testNames.Add( testName ); } /// /// Add a TestName to a NameFilter /// /// public void Add( TestName testName ) { testNames.Add( testName ); } /// /// Check if a test matches the filter /// /// The test to match /// True if it matches, false if not public override bool Match( ITest test ) { foreach( TestName testName in testNames ) if ( test.TestName == testName ) return true; return false; } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Filters/NotFilter.cs0000664000175000017500000000456711662016114023616 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Filters { /// /// NotFilter negates the operation of another filter /// [Serializable] public class NotFilter : TestFilter { ITestFilter baseFilter; bool topLevel = false; /// /// Construct a not filter on another filter /// /// The filter to be negated public NotFilter( ITestFilter baseFilter) { this.baseFilter = baseFilter; } /// /// Indicates whether this is a top-level NotFilter, /// requiring special handling of Explicit /// public bool TopLevel { get { return topLevel; } set { topLevel = value; } } /// /// Gets the base filter /// public ITestFilter BaseFilter { get { return baseFilter; } } /// /// Check whether the filter matches a test /// /// The test to be matched /// True if it matches, otherwise false public override bool Match( ITest test ) { if (topLevel && test.RunState == RunState.Explicit) return false; return !baseFilter.Pass( test ); } /// /// Determine whether any descendant of the test matches the filter criteria. /// /// The test to be matched /// True if at least one descendant matches the filter criteria protected override bool MatchDescendant(ITest test) { if (!test.IsSuite || test.Tests == null || topLevel && test.RunState == RunState.Explicit) return false; foreach (ITest child in test.Tests) { if (Match(child) || MatchDescendant(child)) return true; } return false; } /// /// Return string representation of the filter /// public override string ToString() { return "not " + baseFilter.ToString(); } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestNode.cs0000664000175000017500000000477611504175260022032 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Core { /// /// TestNode represents a single test or suite in the test hierarchy. /// TestNode holds common info needed about a test and represents a /// single node - either a test or a suite - in the hierarchy of tests. /// /// TestNode extends TestInfo, which holds all the information with /// the exception of the list of child classes. When constructed from /// a Test, TestNodes are always fully populated with child TestNodes. /// /// Like TestInfo, TestNode is purely a data class, and is not able /// to execute tests. /// /// [Serializable] public class TestNode : TestInfo { #region Instance Variables private ITest parent; /// /// For a test suite, the child tests or suites /// Null if this is not a test suite /// private ArrayList tests; #endregion #region Constructors /// /// Construct from an ITest /// /// Test from which a TestNode is to be constructed public TestNode ( ITest test ) : base( test ) { if ( test.IsSuite ) { this.tests = new ArrayList(); foreach( ITest child in test.Tests ) { TestNode node = new TestNode( child ); this.Tests.Add( node ); node.parent = this; } } } /// /// Construct a TestNode given a TestName and an /// array of child tests. /// /// The TestName of the new test /// An array of tests to be added as children of the new test public TestNode ( TestName testName, ITest[] tests ) : base( testName, tests ) { this.tests = new ArrayList(); this.tests.AddRange( tests ); } #endregion #region Properties /// /// Gets the parent test of the current test /// public override ITest Parent { get { return parent; } } /// /// Array of child tests, null if this is a test case. /// public override IList Tests { get { return tests; } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/RuntimeFramework.cs0000664000175000017500000004674711664123610023611 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using System.Collections; using Microsoft.Win32; namespace NUnit.Core { /// /// Enumeration identifying a common language /// runtime implementation. /// public enum RuntimeType { /// Any supported runtime framework Any, /// Microsoft .NET Framework Net, /// Microsoft .NET Compact Framework NetCF, /// Microsoft Shared Source CLI SSCLI, /// Mono Mono } /// /// RuntimeFramework represents a particular version /// of a common language runtime implementation. /// [Serializable] public sealed class RuntimeFramework { #region Static and Instance Fields /// /// DefaultVersion is an empty Version, used to indicate that /// NUnit should select the CLR version to use for the test. /// public static readonly Version DefaultVersion = new Version(); private static RuntimeFramework currentFramework; private static RuntimeFramework[] availableFrameworks; private static Version[] knownVersions = new Version[] { new Version(1, 0, 3705), new Version(1, 1, 4322), new Version(2, 0, 50727), new Version(4, 0, 30319) }; private RuntimeType runtime; private Version frameworkVersion; private Version clrVersion; private string displayName; #endregion #region Constructor /// /// Construct from a runtime type and version /// /// The runtime type of the framework /// The version of the framework public RuntimeFramework( RuntimeType runtime, Version version) { this.runtime = runtime; if (version.Build < 0) InitFromFrameworkVersion(version); else InitFromClrVersion(version); if (version.Major == 3) this.clrVersion = new Version(2, 0, 50727); //else if (runtime == RuntimeType.Mono && version.Major == 1) //{ // if (version.Minor == 0) // this.clrVersion = new Version(1, 1); // else if (version.Minor == 1) // this.frameworkVersion = new Version(1, 0); //} this.displayName = GetDefaultDisplayName(runtime, version); } private void InitFromFrameworkVersion(Version version) { this.frameworkVersion = this.clrVersion = version; foreach (Version v in knownVersions) if (v.Major == version.Major && v.Minor == version.Minor) { this.clrVersion = v; break; } if (this.runtime == RuntimeType.Mono && version.Major == 1) { this.frameworkVersion = new Version(1, 0); this.clrVersion = new Version(1, 1, 4322); } } private void InitFromClrVersion(Version version) { this.frameworkVersion = new Version(version.Major, version.Minor); this.clrVersion = version; if (runtime == RuntimeType.Mono && version.Major == 1) this.frameworkVersion = new Version(1, 0); } #endregion #region Properties /// /// Static method to return a RuntimeFramework object /// for the framework that is currently in use. /// public static RuntimeFramework CurrentFramework { get { if (currentFramework == null) { Type monoRuntimeType = Type.GetType("Mono.Runtime", false); bool isMono = monoRuntimeType != null; RuntimeType runtime = isMono ? RuntimeType.Mono : RuntimeType.Net; int major = Environment.Version.Major; int minor = Environment.Version.Minor; if (isMono) { switch (major) { case 1: minor = 0; break; case 2: major = 3; minor = 5; break; } } else /* It's windows */ if (major == 2) { RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework"); if (key != null) { string installRoot = key.GetValue("InstallRoot") as string; if (installRoot != null) { if (Directory.Exists(Path.Combine(installRoot, "v3.5"))) { major = 3; minor = 5; } else if (Directory.Exists(Path.Combine(installRoot, "v3.0"))) { major = 3; minor = 0; } } } } currentFramework = new RuntimeFramework(runtime, new Version(major, minor)); currentFramework.clrVersion = Environment.Version; if (isMono) { MethodInfo getDisplayNameMethod = monoRuntimeType.GetMethod( "GetDisplayName", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding); if (getDisplayNameMethod != null) currentFramework.displayName += string.Format(" ( {0} )", (string)getDisplayNameMethod.Invoke(null, new object[0])); } } return currentFramework; } } /// /// Gets an array of all available frameworks /// public static RuntimeFramework[] AvailableFrameworks { get { if (availableFrameworks == null) { FrameworkCollection frameworks = new FrameworkCollection(); AppendDotNetFrameworks(frameworks); AppendDefaultMonoFramework(frameworks); // NYI //AppendMonoFrameworks(frameworks); availableFrameworks = frameworks.ToArray(); } return availableFrameworks; } } /// /// Returns true if the current RuntimeFramework is available. /// In the current implementation, only Mono and Microsoft .NET /// are supported. /// /// True if it's available, false if not public bool IsAvailable { get { foreach (RuntimeFramework framework in AvailableFrameworks) if (this.Supports(framework)) return true; return false; } } /// /// The type of this runtime framework /// public RuntimeType Runtime { get { return runtime; } } /// /// The framework version for this runtime framework /// public Version FrameworkVersion { get { return frameworkVersion; } } /// /// The CLR version for this runtime framework /// public Version ClrVersion { get { return clrVersion; } } /// /// Return true if any CLR version may be used in /// matching this RuntimeFramework object. /// public bool AllowAnyVersion { get { return this.clrVersion == DefaultVersion; } } /// /// Returns the Display name for this framework /// public string DisplayName { get { return displayName; } } #endregion #region Public Methods /// /// Parses a string representing a RuntimeFramework. /// The string may be just a RuntimeType name or just /// a Version or a hyphentated RuntimeType-Version or /// a Version prefixed by 'v'. /// /// /// public static RuntimeFramework Parse(string s) { RuntimeType runtime = RuntimeType.Any; Version version = DefaultVersion; string[] parts = s.Split(new char[] { '-' }); if (parts.Length == 2) { runtime = (RuntimeType)System.Enum.Parse(typeof(RuntimeType), parts[0], true); string vstring = parts[1]; if (vstring != "") version = new Version(vstring); } else if (char.ToLower(s[0]) == 'v') { version = new Version(s.Substring(1)); } else if (IsRuntimeTypeName(s)) { runtime = (RuntimeType)System.Enum.Parse(typeof(RuntimeType), s, true); } else { version = new Version(s); } return new RuntimeFramework(runtime, version); } /// /// Returns the best available framework that matches a target framework. /// If the target framework has a build number specified, then an exact /// match is needed. Otherwise, the matching framework with the highest /// build number is used. /// /// /// public static RuntimeFramework GetBestAvailableFramework(RuntimeFramework target) { RuntimeFramework result = target; if (target.ClrVersion.Build < 0) { foreach (RuntimeFramework framework in AvailableFrameworks) if (framework.Supports(target) && framework.ClrVersion.Build > result.ClrVersion.Build) { result = framework; } } return result; } /// /// Overridden to return the short name of the framework /// /// public override string ToString() { if (this.AllowAnyVersion) { return runtime.ToString().ToLower(); } else { string vstring = frameworkVersion.ToString(); if (runtime == RuntimeType.Any) return "v" + vstring; else return runtime.ToString().ToLower() + "-" + vstring; } } /// /// Returns true if this framework's supports executing under the /// requested target framework. The target is supported if /// /// 1. The runtime types are the same or either one is RuntimeType.Any /// /// 2. All specified (non-negative) components of the CLR version are equal. /// /// 3. The major and minor components of the current framework version are /// greater than or equal to the corresponding target components. /// /// The last provision allows tests requiring .NET 2.0 to run under the /// 3.0 and 3.5 platforms as well. /// /// The RuntimeFramework to be matched. /// True on match, otherwise false public bool Supports(RuntimeFramework target) { if (this.Runtime != RuntimeType.Any && target.Runtime != RuntimeType.Any && this.Runtime != target.Runtime) return false; if (this.AllowAnyVersion || target.AllowAnyVersion) return true; return VersionsMatch(this.ClrVersion, target.ClrVersion) && this.FrameworkVersion.Major >= target.FrameworkVersion.Major && this.FrameworkVersion.Minor >= target.FrameworkVersion.Minor; } #endregion #region Helper Methods private static bool IsRuntimeTypeName(string name) { foreach (string item in Enum.GetNames(typeof(RuntimeType))) if (item.ToLower() == name.ToLower()) return true; return false; } private static string GetDefaultDisplayName(RuntimeType runtime, Version version) { if (version == DefaultVersion) return runtime.ToString(); else if (runtime == RuntimeType.Any) return "v" + version.ToString(); else return runtime.ToString() + " " + version.ToString(); } private static bool VersionsMatch(Version v1, Version v2) { return v1.Major == v2.Major && v1.Minor == v2.Minor && (v1.Build < 0 || v2.Build < 0 || v1.Build == v2.Build) && (v1.Revision < 0 || v2.Revision < 0 || v1.Revision == v2.Revision); } private static void AppendMonoFrameworks(FrameworkCollection frameworks) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) AppendAllMonoFrameworks(frameworks); else AppendDefaultMonoFramework(frameworks); } private static void AppendAllMonoFrameworks(FrameworkCollection frameworks) { // TODO: Find multiple installed Mono versions under Linux if (Environment.OSVersion.Platform == PlatformID.Win32NT) { // Use registry to find alternate versions RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Novell\Mono"); if (key == null) return; foreach (string version in key.GetSubKeyNames()) { RegistryKey subKey = key.OpenSubKey(version); string monoPrefix = subKey.GetValue("SdkInstallRoot") as string; AppendMonoFramework(frameworks, monoPrefix, version); } } else AppendDefaultMonoFramework(frameworks); } // This method works for Windows and Linux but currently // is only called under Linux. private static void AppendDefaultMonoFramework(FrameworkCollection frameworks) { string monoPrefix = null; string version = null; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Novell\Mono"); if (key != null) { version = key.GetValue("DefaultCLR") as string; if (version != null && version != "") { key = key.OpenSubKey(version); if (key != null) monoPrefix = key.GetValue("SdkInstallRoot") as string; } } } else // Assuming we're currently running Mono - change if more runtimes are added { string libMonoDir = Path.GetDirectoryName(typeof(object).Assembly.Location); monoPrefix = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(libMonoDir))); } AppendMonoFramework(frameworks, monoPrefix, version); } private static void AppendMonoFramework(FrameworkCollection frameworks, string monoPrefix, string version) { if (monoPrefix != null) { string displayFmt = version != null ? "Mono " + version + " - {0} Profile" : "Mono {0} Profile"; if (File.Exists(Path.Combine(monoPrefix, "lib/mono/1.0/mscorlib.dll"))) { RuntimeFramework framework = new RuntimeFramework(RuntimeType.Mono, new Version(1, 1, 4322)); framework.displayName = string.Format(displayFmt, "1.0"); frameworks.Add(framework); } if (File.Exists(Path.Combine(monoPrefix, "lib/mono/2.0/mscorlib.dll"))) { RuntimeFramework framework = new RuntimeFramework(RuntimeType.Mono, new Version(2, 0, 50727)); framework.displayName = string.Format(displayFmt, "2.0"); frameworks.Add(framework); } if (File.Exists(Path.Combine(monoPrefix, "lib/mono/4.0/mscorlib.dll"))) { RuntimeFramework framework = new RuntimeFramework(RuntimeType.Mono, new Version(4, 0, 30319)); framework.displayName = string.Format(displayFmt, "4.0"); frameworks.Add(framework); } } } private static void AppendDotNetFrameworks(FrameworkCollection frameworks) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NETFramework\policy"); if (key != null) { foreach (string name in key.GetSubKeyNames()) { if (name.StartsWith("v")) { RegistryKey key2 = key.OpenSubKey(name); foreach (string build in key2.GetValueNames()) frameworks.Add(new RuntimeFramework(RuntimeType.Net, new Version(name.Substring(1) + "." + build))); } } } } } #if CLR_2_0 || CLR_4_0 private class FrameworkCollection : System.Collections.Generic.List { } #else private class FrameworkCollection : ArrayList { public new RuntimeFramework[] ToArray() { return (RuntimeFramework[])ToArray(typeof(RuntimeFramework)); } } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestPackage.cs0000664000175000017500000002114411713204220022453 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; using System.Collections.Specialized; namespace NUnit.Core { /// /// Represents the manner in which test assemblies are /// distributed across processes. /// public enum ProcessModel { /// /// Use the default setting, depending on the runner /// and the nature of the tests to be loaded. /// Default, /// /// Run tests directly in the NUnit process /// Single, /// /// Run tests in a single separate process /// Separate, /// /// Run tests in a separate process per assembly /// Multiple } /// /// Represents the manner in which test assemblies use /// AppDomains to provide isolation /// public enum DomainUsage { /// /// Use the default setting, depending on the runner /// and the nature of the tests to be loaded. /// Default, /// /// Don't create a test domain - run in the primary AppDomain /// None, /// /// Run tests in a single separate test domain /// Single, /// /// Run tests in a separate domain per assembly /// Multiple } /// /// TestPackage holds information about a set of tests to /// be loaded by a TestRunner. It may represent a single /// assembly or a set of assemblies. It supports selection /// of a single test fixture for loading. /// [Serializable] public class TestPackage { private string name; private string fullName; private ListDictionary settings = new ListDictionary(); private string basePath; private string configFile; private string binPath; private bool autoBinPath; private ArrayList assemblies; private string testName; private bool isSingleAssembly; /// /// Construct a package, specifying the name of the package. /// If the package name is an assembly file type (dll or exe) /// then the resulting package represents a single assembly. /// Otherwise it is a container for multiple assemblies. /// /// The name of the package public TestPackage( string name ) { this.fullName = name; this.name = Path.GetFileName( name ); this.assemblies = new ArrayList(); if ( IsAssemblyFileType( name ) ) { if (!Path.IsPathRooted(name)) throw new ArgumentException("Assembly in TestPackage must be specified as an absolute path", "name"); this.isSingleAssembly = true; this.assemblies.Add(name); } } /// /// Construct a package, specifying the name to be used /// and a list of assemblies. /// /// The package name, used to name the top-level test node /// The list of assemblies comprising the package public TestPackage( string name, IList assemblies ) { this.fullName = name; this.name = Path.GetFileName( name ); this.assemblies = new ArrayList(); foreach (string assembly in assemblies) { if (!Path.IsPathRooted(assembly)) throw new ArgumentException("Assembly in TestPackage must be specified as an absolute path", "assemblies"); this.assemblies.Add(assembly); } this.isSingleAssembly = false; } /// /// Gets the name of the package /// public string Name { get { return name; } } /// /// Gets the full name of the package, which is usually /// the path to the NUnit project used to create the it /// public string FullName { get { return fullName; } } /// /// The BasePath to be used in loading the assemblies /// public string BasePath { get { return basePath; } set { basePath = value; } } /// /// The configuration file to be used /// public string ConfigurationFile { get { return configFile; } set { configFile = value; } } /// /// Addditional directories to be probed when loading assemblies /// public string PrivateBinPath { get { return binPath; } set { binPath = value; } } /// /// Indicates whether the probing path should be generated /// automatically based on the list of assemblies. /// public bool AutoBinPath { get { return autoBinPath; } set { autoBinPath = value; } } /// /// Assemblies to be loaded. At least one must be specified. /// public IList Assemblies { get { return assemblies; } } /// /// Return true if the package represents a single assembly. /// No root node is displayed in that case. /// public bool IsSingleAssembly { get { return isSingleAssembly; } } /// /// Fully qualified name of test to be loaded. If not /// specified, all the tests in the assemblies are loaded. /// public string TestName { get { return testName; } set { testName = value; } } /// /// Gets the dictionary of settings for this TestPackage /// public IDictionary Settings { get { return settings; } } /// /// Return the value of a setting or a default. /// /// The name of the setting /// The default value /// public object GetSetting(string name, object defaultSetting) { object setting = settings[name]; return setting == null ? defaultSetting : setting; } /// /// Return the value of a string setting or a default. /// /// The name of the setting /// The default value /// public string GetSetting(string name, string defaultSetting) { object setting = settings[name]; return setting == null ? defaultSetting : (string)setting; } /// /// Return the value of a bool setting or a default. /// /// The name of the setting /// The default value /// public bool GetSetting(string name, bool defaultSetting) { object setting = settings[name]; return setting == null ? defaultSetting : (bool)setting; } /// /// Return the value of an int setting or a default. /// /// The name of the setting /// The default value /// public int GetSetting(string name, int defaultSetting) { object setting = settings[name]; return setting == null ? defaultSetting : (int)setting; } /// /// Return the value of a enum setting or a default. /// /// The name of the setting /// The default value /// public System.Enum GetSetting(string name, System.Enum defaultSetting) { object setting = settings[name]; return setting == null ? defaultSetting : (System.Enum)setting; } private static bool IsAssemblyFileType(string path) { string extension = Path.GetExtension( path ).ToLower(); return extension == ".dll" || extension == ".exe"; } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/0000775000175000017500000000000011742560362022601 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/TestFramework.cs0000664000175000017500000000220511504175260025717 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// Summary description for TestFramework. /// [Serializable] public class TestFramework { #region Instance Fields /// /// The name of the framework /// public string Name; /// /// The file name of the assembly that defines the framwork /// public string AssemblyName; #endregion #region Constructor /// /// Constructs a TestFramwork object given its name and assembly name. /// /// /// public TestFramework( string frameworkName, string assemblyName ) { this.Name = frameworkName; this.AssemblyName = assemblyName; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/Addin.cs0000664000175000017500000000637611543055572024164 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// The Addin class holds information about an addin. /// [Serializable] public class Addin { #region Private Fields private string typeName; private string name; private string description; private ExtensionType extensionType; private AddinStatus status; private string message; #endregion #region Constructor /// /// Construct an Addin for a type. /// /// The type to be used public Addin( Type type ) { this.typeName = type.AssemblyQualifiedName; object[] attrs = type.GetCustomAttributes( typeof(NUnitAddinAttribute), false ); if ( attrs.Length == 1 ) { NUnitAddinAttribute attr = (NUnitAddinAttribute)attrs[0]; this.name = attr.Name; this.description = attr.Description; this.extensionType = attr.Type; } if ( this.name == null ) this.name = type.Name; if ( this.extensionType == 0 ) this.extensionType = ExtensionType.Core; this.status = AddinStatus.Enabled; } #endregion #region Properties /// /// The name of the Addin /// public string Name { get { return name; } } /// /// Brief description of what the Addin does /// public string Description { get { return description; } } /// /// The type or types of extension provided, using /// one or more members of the ExtensionType enumeration. /// public ExtensionType ExtensionType { get { return extensionType; } } /// /// The AssemblyQualifiedName of the type that implements /// the addin. /// public string TypeName { get { return typeName; } } /// /// The status of the addin /// public AddinStatus Status { get { return status; } set { status = value; } } /// /// Any message that clarifies the status of the Addin, /// such as an error message or an explanation of why /// the addin is disabled. /// public string Message { get { return message; } set { message = value; } } #endregion #region Object Overrides /// /// Return true if two Addins have teh same type name /// /// The other addin to be compared public override bool Equals(object obj) { Addin addin = obj as Addin; if (addin == null) return false; return this.typeName.Equals(addin.typeName); } /// /// Return a hash code for this addin /// public override int GetHashCode() { return this.typeName.GetHashCode(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IAddinRegistry.cs0000664000175000017500000000300411504175260026001 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The IAddinRegistry interface allows registering addins /// and retrieving information about them. It is also used /// to record the load status of an addin. /// public interface IAddinRegistry { /// /// Gets a list of all addins as Addin objects /// System.Collections.IList Addins { get; } /// /// Registers an addin /// /// The addin to be registered void Register( Addin addin ); /// /// Returns true if an addin of a given name is registered /// /// The name of the addin /// True if an addin of that name is registered, otherwise false bool IsAddinRegistered(string name); /// /// Sets the load status of an addin /// /// The name of the addin /// The status to be set /// An optional message explaining the status void SetStatus( string name, AddinStatus status, string message ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IExtensionPoint.cs0000664000175000017500000000475611504175260026236 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// Represents a single point of extension for NUnit. Some extension /// points may accept only a single extension, while others may /// accept more than one at the same time. /// public interface IExtensionPoint { /// /// Get the name of this extension point /// string Name { get; } /// /// Get the host that provides this extension point /// IExtensionHost Host { get; } /// /// Install an extension at this extension point. If the /// extension object does not meet the requirements for /// this extension point, an exception is thrown. /// /// The extension to install void Install(object extension); /// /// Removes an extension from this extension point. If the /// extension object is not present, the method returns /// without error. /// /// void Remove( object extension ); } /// /// Represents a single point of extension for NUnit. Some extension /// points may accept only a single extension, while others may /// accept more than one at the same time. This interface enhances /// IExtensionPoint by allowing specification of a priority /// order for applying addins. /// public interface IExtensionPoint2 : IExtensionPoint { /// /// Install an extension at this extension point specifying /// an integer priority value for the extension.If the /// extension object does not meet the requirements for /// this extension point, or if the extension point does /// not support the requested priority level, an exception /// is thrown. /// /// The extension to install /// The priority level for this extension void Install(object extension, int priority); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ISuiteBuilder.cs0000664000175000017500000000255511504175260025643 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The ISuiteBuilder interface is exposed by a class that knows how to /// build a suite from one or more Types. /// public interface ISuiteBuilder { /// /// Examine the type and determine if it is suitable for /// this builder to use in building a TestSuite. /// /// Note that returning false will cause the type to be ignored /// in loading the tests. If it is desired to load the suite /// but label it as non-runnable, ignored, etc., then this /// method must return true. /// /// The type of the fixture to be used /// True if the type can be used to build a TestSuite bool CanBuildFrom( Type type ); /// /// Build a TestSuite from type provided. /// /// The type of the fixture to be used /// A TestSuite Test BuildFrom( Type type ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ITestCaseProvider.cs0000664000175000017500000000474011543055572026475 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.Collections; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// The ITestCaseProvider interface is used by extensions /// that provide data for parameterized tests, along with /// certain flags and other indicators used in the test. /// public interface ITestCaseProvider { /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// True if any cases are available, otherwise false. bool HasTestCasesFor(MethodInfo method); /// /// Return an IEnumerable providing test cases for use in /// running a paramterized test. /// /// /// IEnumerable GetTestCasesFor(MethodInfo method); } /// /// ITestCaseProvider2 extends ITestCaseProvider with methods /// that include the suite for which the test case is being /// built. TestCaseProviders not needing the suite can /// continue to implement ITestCaseBuilder. /// public interface ITestCaseProvider2 : ITestCaseProvider { /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// The suite for which the test case is being built /// True if any cases are available, otherwise false. bool HasTestCasesFor(MethodInfo method, Test suite); /// /// Return an IEnumerable providing test cases for use in /// running a paramterized test. /// /// /// The suite for which the test case is being built /// IEnumerable GetTestCasesFor(MethodInfo method, Test suite); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IFrameworkRegistry.cs0000664000175000017500000000150111543055572026725 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The IFrameworkRegistry allows extensions to register new /// frameworks or emulations of other frameworks. /// public interface IFrameworkRegistry { /// /// Register a framework /// /// The name of the framework /// The name of the assembly that the tests reference void Register( string frameworkName, string assemblyName ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ITestCaseBuilder.cs0000664000175000017500000000575611504175260026273 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Reflection; namespace NUnit.Core.Extensibility { /// /// The ITestCaseBuilder interface is exposed by a class that knows how to /// build a test case from certain methods. /// public interface ITestCaseBuilder { /// /// Examine the method and determine if it is suitable for /// this builder to use in building a TestCase. /// /// Note that returning false will cause the method to be ignored /// in loading the tests. If it is desired to load the method /// but label it as non-runnable, ignored, etc., then this /// method must return true. /// /// The test method to examine /// True is the builder can use this method bool CanBuildFrom(MethodInfo method); /// /// Build a TestCase from the provided MethodInfo. /// /// The method to be used as a test case /// A TestCase or null Test BuildFrom(MethodInfo method); } /// /// ITestCaseBuilder2 extends ITestCaseBuilder with methods /// that include the suite for which the test case is being /// built. Test case builders not needing the suite can /// continue to implement ITestCaseBuilder. /// public interface ITestCaseBuilder2 : ITestCaseBuilder { /// /// Examine the method and determine if it is suitable for /// this builder to use in building a TestCase to be /// included in the suite being populated. /// /// Note that returning false will cause the method to be ignored /// in loading the tests. If it is desired to load the method /// but label it as non-runnable, ignored, etc., then this /// method must return true. /// /// The test method to examine /// The suite being populated /// True is the builder can use this method bool CanBuildFrom(MethodInfo method, Test suite); /// /// Build a TestCase from the provided MethodInfo for /// inclusion in the suite being constructed. /// /// The method to be used as a test case /// The test suite being populated, or null /// A TestCase or null Test BuildFrom(MethodInfo method, Test suite); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ExtensionType.cs0000664000175000017500000000171111504175260025741 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The ExtensionType enumeration is used to indicate the /// kinds of extensions provided by an Addin. The addin /// is only installed by hosts supporting one of its /// extension types. /// [Flags] public enum ExtensionType { /// /// A Core extension is installed by the CoreExtensions /// host in each test domain. /// Core=1, /// /// A Client extension is installed by all clients /// Client=2, /// /// A Gui extension is installed by the gui client /// Gui=4 } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/AddinStatus.cs0000664000175000017500000000166211504175260025353 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The AddinStatus enum indicates the load status of an addin. /// public enum AddinStatus { /// /// Not known - default /// Unknown, /// /// The addin is enabled but not loaded /// Enabled, /// /// The addin is disabled /// Disabled, /// /// The addin was loaded successfully /// Loaded, /// /// An error was encountered loading the addin /// Error } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IAddin.cs0000664000175000017500000000216111504175260024253 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// Add-ins are used to extend NUnti. All add-ins must /// implement the IAddin interface. /// public interface IAddin { /// /// When called, the add-in installs itself into /// the host, if possible. Because NUnit uses separate /// hosts for the client and test domain environments, /// an add-in may be invited to istall itself more than /// once. The add-in is responsible for checking which /// extension points are supported by the host that is /// passed to it and taking the appropriate action. /// /// The host in which to install the add-in /// True if the add-in was installed, otehrwise false bool Install( IExtensionHost host ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IDataPointProvider.cs0000664000175000017500000000516411504175260026640 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System.Collections; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// The IDataPointProvider interface is used by extensions /// that provide data for a single test parameter. /// public interface IDataPointProvider { /// /// Determine whether any data is available for a parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// True if any data is available, otherwise false. bool HasDataFor(ParameterInfo parameter); /// /// Return an IEnumerable providing data for use with the /// supplied parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// An IEnumerable providing the required data IEnumerable GetDataFor(ParameterInfo parameter); } /// /// The IDataPointProvider2 interface extends IDataPointProvider /// by making the test fixture for which the test is being built /// available for use. /// public interface IDataPointProvider2 : IDataPointProvider { /// /// Determine whether any data is available for a parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// The test suite for which the test is being built /// True if any data is available, otherwise false. bool HasDataFor(ParameterInfo parameter, Test parentSuite); /// /// Return an IEnumerable providing data for use with the /// supplied parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// The test suite for which the test is being built /// An IEnumerable providing the required data IEnumerable GetDataFor(ParameterInfo parameter, Test parentSuite); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ITestDecorator.cs0000664000175000017500000000357111504175260026024 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// DecoratorPriority wraps constants that may be used /// to represent the relative priority of TestDecorators. /// Decorators with a lower priority are applied first /// so that higher priority decorators wrap them. /// /// NOTE: This feature is subject to change. /// public class DecoratorPriority { /// /// The default priority, equivalent to Normal /// public static readonly int Default = 0; /// /// Priority for Decorators that must apply first /// public static readonly int First = 1; /// /// Normal Decorator priority /// public static readonly int Normal = 5; /// /// Priority for Decorators that must apply last /// public static readonly int Last = 9; } /// /// The ITestDecorator interface is exposed by a class that knows how to /// enhance the functionality of a test case or suite by decorating it. /// public interface ITestDecorator { /// /// Examine the a Test and either return it as is, modify it /// or return a different TestCase. /// /// The Test to be decorated /// The MethodInfo used to construct the test /// The resulting Test Test Decorate( Test test, MemberInfo member ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/ParameterSet.cs0000664000175000017500000002721411720006750025522 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// ParameterSet encapsulates method arguments and /// other selected parameters needed for constructing /// a parameterized test case. /// public class ParameterSet : NUnit.Framework.ITestCaseData { #region Constants private static readonly string DESCRIPTION = "_DESCRIPTION"; //private static readonly string IGNOREREASON = "_IGNOREREASON"; private static readonly string CATEGORIES = "_CATEGORIES"; #endregion #region Instance Fields private RunState runState; private Exception providerException; private object[] arguments; private object[] originalArguments; private System.Type expectedExceptionType; private string expectedExceptionName; private string expectedMessage; private string matchType; private object expectedResult; private string testName; private string ignoreReason; private bool isIgnored; private bool isExplicit; private bool hasExpectedResult; /// /// A dictionary of properties, used to add information /// to tests without requiring the class to change. /// private IDictionary properties; #endregion #region Properties /// /// The RunState for this set of parameters. /// public RunState RunState { get { return runState; } set { runState = value; } } ///// ///// The reason for not running the test case ///// represented by this ParameterSet ///// //public string NotRunReason //{ // get { return (string) Properties[IGNOREREASON]; } //} /// /// Holds any exception thrown by the parameter provider /// public Exception ProviderException { get { return providerException; } } /// /// The arguments to be used in running the test, /// which must match the method signature. /// public object[] Arguments { get { return arguments; } set { arguments = value; if (originalArguments == null) originalArguments = value; } } /// /// The original arguments supplied by the user, /// used for display purposes. /// public object[] OriginalArguments { get { return originalArguments; } } /// /// The Type of any exception that is expected. /// public System.Type ExpectedException { get { return expectedExceptionType; } set { expectedExceptionType = value; } } /// /// The FullName of any exception that is expected /// public string ExpectedExceptionName { get { return expectedExceptionName; } set { expectedExceptionName = value; } } /// /// The Message of any exception that is expected /// public string ExpectedMessage { get { return expectedMessage; } set { expectedMessage = value; } } /// /// Gets or sets the type of match to be performed on the expected message /// public string MatchType { get { return matchType; } set { matchType = value; } } /// /// The expected result of the test, which /// must match the method return type. /// public object Result { get { return expectedResult; } set { expectedResult = value; hasExpectedResult = true; } } /// /// Returns true if an expected result has been /// specified for this parameter set. /// public bool HasExpectedResult { get { return hasExpectedResult; } } /// /// A description to be applied to this test case /// public string Description { get { return (string) Properties[DESCRIPTION]; } set { if (value != null) Properties[DESCRIPTION] = value; else Properties.Remove(DESCRIPTION); } } /// /// A name to be used for this test case in lieu /// of the standard generated name containing /// the argument list. /// public string TestName { get { return testName; } set { testName = value; } } /// /// Gets or sets a value indicating whether this is ignored. /// /// true if ignored; otherwise, false. public bool Ignored { get { return isIgnored; } set { isIgnored = value; } } /// /// Gets or sets a value indicating whether this is explicit. /// /// true if explicit; otherwise, false. public bool Explicit { get { return isExplicit; } set { isExplicit = value; } } /// /// Gets or sets the ignore reason. /// /// The ignore reason. public string IgnoreReason { get { return ignoreReason; } set { ignoreReason = value; } } /// /// Gets a list of categories associated with this test. /// public IList Categories { get { if (Properties[CATEGORIES] == null) Properties[CATEGORIES] = new ArrayList(); return (IList)Properties[CATEGORIES]; } } /// /// Gets the property dictionary for this test /// public IDictionary Properties { get { if (properties == null) properties = new ListDictionary(); return properties; } } #endregion #region Constructors /// /// Construct a non-runnable ParameterSet, specifying /// the provider excetpion that made it invalid. /// public ParameterSet(Exception exception) { this.runState = RunState.NotRunnable; this.providerException = exception; this.ignoreReason = exception.Message; } /// /// Construct an empty parameter set, which /// defaults to being Runnable. /// public ParameterSet() { this.runState = RunState.Runnable; } #endregion #region Static Methods /// /// Constructs a ParameterSet from another object, accessing properties /// by reflection. The object must expose at least an Arguments property /// in order for the test to be runnable. /// /// public static ParameterSet FromDataSource(object source) { ParameterSet parms = new ParameterSet(); parms.Arguments = GetParm(source, PropertyNames.Arguments) as object[]; parms.ExpectedException = GetParm(source, PropertyNames.ExpectedException) as Type; if (parms.ExpectedException != null) parms.ExpectedExceptionName = parms.ExpectedException.FullName; else parms.ExpectedExceptionName = GetParm(source, PropertyNames.ExpectedExceptionName) as string; parms.ExpectedMessage = GetParm(source, PropertyNames.ExpectedMessage) as string; object matchEnum = GetParm(source, PropertyNames.MatchType); if ( matchEnum != null ) parms.MatchType = matchEnum.ToString(); // Note: pre-2.6 versions of some attributes don't have the HasExpectedResult property object hasResult = GetParm(source, PropertyNames.HasExpectedResult); object expectedResult = GetParm(source, PropertyNames.ExpectedResult); if (hasResult != null && (bool)hasResult || expectedResult != null) parms.Result = expectedResult; parms.Description = GetParm(source, PropertyNames.Description) as string; parms.TestName = GetParm(source, PropertyNames.TestName) as string; object objIgnore = GetParm(source, PropertyNames.Ignored); if (objIgnore != null) parms.Ignored = (bool)objIgnore; parms.IgnoreReason = GetParm(source, PropertyNames.IgnoreReason) as string; object objExplicit = GetParm(source, PropertyNames.Explicit); if (objExplicit != null) parms.Explicit = (bool)objExplicit; // Some sources may also implement Properties and/or Categories bool gotCategories = false; IDictionary props = GetParm(source, PropertyNames.Properties) as IDictionary; if ( props != null ) foreach (string key in props.Keys) { parms.Properties.Add(key, props[key]); if (key == CATEGORIES) gotCategories = true; } // Some sources implement Categories. They may have been // provided as properties or they may be separate. if (!gotCategories) { IList categories = GetParm(source, PropertyNames.Categories) as IList; if (categories != null) foreach (string cat in categories) parms.Categories.Add(cat); } return parms; } private static object GetParm(object source, string name) { Type type = source.GetType(); PropertyInfo prop = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty); if (prop != null) return prop.GetValue(source, null); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField); if (field != null) return field.GetValue(source); return null; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/NUnitAddinAttribute.cs0000664000175000017500000000220011504175260026776 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// NUnitAddinAttribute is used to mark all add-ins. The marked class /// must implement the IAddin interface. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)] public sealed class NUnitAddinAttribute : Attribute { /// /// The name of this addin /// public string Name; /// /// A description for the addin /// public string Description; /// /// The type of extension provided /// public ExtensionType Type; /// /// Default Constructor /// public NUnitAddinAttribute() { this.Type = ExtensionType.Core; } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/Extensibility/IExtensionHost.cs0000664000175000017500000000305511504175260026051 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core.Extensibility { /// /// The IExtensionHost interface is implemented by each /// of NUnit's Extension hosts. Currently, there is /// only one host, which resides in the test domain. /// public interface IExtensionHost { /// /// Get a list of the ExtensionPoints provided by this host. /// IExtensionPoint[] ExtensionPoints { get; } /// /// Get an interface to the framework registry /// [Obsolete("Use the FrameworkRegistry extension point instead")] IFrameworkRegistry FrameworkRegistry { get; } /// /// Return an extension point by name, if present /// /// The name of the extension point /// The extension point, if found, otherwise null IExtensionPoint GetExtensionPoint( string name ); /// /// Gets the ExtensionTypes supported by this host /// /// An enum indicating the ExtensionTypes supported ExtensionType ExtensionTypes { get; } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/RunState.cs0000664000175000017500000000317211504175260022037 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// The RunState enum indicates whether a test /// can be executed. When used on a TestResult /// it may also indicate whether the test has /// been executed. See individual values for /// restrictions on use. /// public enum RunState { /// /// The test is not runnable. /// NotRunnable, /// /// The test is runnable. This value would /// normally not appear on a TestResult, since /// it would change to Executed. /// Runnable, /// /// The test can only be run explicitly. Would /// normally not appear on a TestResult, since /// it would change to Executed or Skipped. /// Explicit, /// /// The test has been skipped. This value may /// appear on a Test when certain attributes /// are used to skip the test. /// Skipped, /// /// The test has been ignored. May appear on /// a Test, when the IgnoreAttribute is used. /// Appears on a TestResult in that case or /// if the test is dynamically ignored. /// Ignored } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestAgent.cs0000664000175000017500000000564411504175260022176 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// Abstract base for all types of TestAgents. /// A TestAgent provides services of locating, /// loading and running tests in a particular /// context such as an AppDomain or Process. /// public abstract class TestAgent : MarshalByRefObject, IDisposable { #region Fields /// /// Reference to the TestAgency that controls this agent /// private IAgency agency; /// /// This agent's assigned id /// private Guid agentId; #endregion #region Constructors /// /// Constructs a TestAgent /// /// public TestAgent(Guid agentId) { this.agentId = agentId; } /// /// Consructor used by TestAgency when creating /// an agent. /// /// /// public TestAgent( Guid agentId, IAgency agency ) { this.agency = agency; this.agentId = agentId; } #endregion #region Properties /// /// The TestAgency with which this agent is asssociated, /// or null if the agent is not tied to an agency. /// public IAgency Agency { get { return agency; } } /// /// A Guid that uniquely identifies this agent. /// public Guid Id { get { return agentId; } } #endregion #region Absract Methods /// /// Starts the agent, performing any required initialization /// /// public abstract bool Start(); /// /// Stops the agent, releasing any resources /// public abstract void Stop(); /// /// Creates a runner using a given runner id /// public abstract TestRunner CreateRunner(int runnerId); #endregion #region IDisposable Members /// /// Dispose is overridden to stop the agent /// public void Dispose() { this.Stop(); } #endregion #region InitializeLifeTimeService /// /// Overridden to cause object to live indefinitely /// public override object InitializeLifetimeService() { return null; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/ITest.cs0000664000175000017500000000471611504175260021327 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Collections; namespace NUnit.Core { /// /// Common interface supported by all representations /// of a test. Only includes informational fields. /// The Run method is specifically excluded to allow /// for data-only representations of a test. /// public interface ITest { #region Properties /// /// Gets the completely specified name of the test /// encapsulated in a TestName object. /// TestName TestName { get; } /// /// Gets a string representing the type of test, e.g.: "Test Case" /// string TestType { get; } /// /// Indicates whether the test can be run using /// the RunState enum. /// RunState RunState { get; set; } /// /// Reason for not running the test, if applicable /// string IgnoreReason { get; set; } /// /// Count of the test cases ( 1 if this is a test case ) /// int TestCount { get; } /// /// Categories available for this test /// IList Categories { get; } /// /// Return the description field. /// string Description { get; set; } /// /// Return additional properties of the test /// IDictionary Properties { get; } /// /// True if this is a suite /// bool IsSuite { get; } /// /// Gets the parent test of this test /// ITest Parent { get; } /// /// For a test suite, the child tests or suites /// Null if this is not a test suite /// IList Tests { get; } #endregion #region Methods /// /// Count the test cases that pass a filter. The /// result should match those that would execute /// when passing the same filter to Run. /// /// The filter to apply /// The count of test cases int CountTestCases(ITestFilter filter); #endregion } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/ResultState.cs0000664000175000017500000000400711504175260022547 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// The ResultState enum indicates the result of running a test /// public enum ResultState { /// /// The result is inconclusive /// Inconclusive = 0, /// /// The test was not runnable. /// NotRunnable = 1, /// /// The test has been skipped. /// Skipped = 2, /// /// The test has been ignored. /// Ignored = 3, /// /// The test succeeded /// Success = 4, /// /// The test failed /// Failure = 5, /// /// The test encountered an unexpected exception /// Error = 6, /// /// The test was cancelled by the user /// Cancelled =7 } /// /// The FailureSite enum indicates the stage of a test /// in which an error or failure occured. /// public enum FailureSite { /// /// Failure in the test itself /// Test, /// /// Failure in the SetUp method /// SetUp, /// /// Failure in the TearDown method /// TearDown, /// /// Failure of a parent test /// Parent, /// /// Failure of a child test /// Child } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestAssemblyInfo.cs0000664000175000017500000001155311504175260023527 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Reflection; using System.Diagnostics; using System.IO; using System.Text; namespace NUnit.Core { /// /// TestAssemblyInfo holds information about a loaded test assembly /// [Serializable] public class TestAssemblyInfo { private string assemblyName; private Version imageRuntimeVersion; private RuntimeFramework runnerRuntimeFramework; private int processId; private string moduleName; private string domainName; private string appBase; private string binPath; private string configFile; private IList testFrameworks; /// /// Constructs a TestAssemblyInfo /// /// The name of the assembly /// The version of the runtime for which the assembly was built /// The runtime framework under which the assembly is loaded /// A list of test framework useds by the assembly public TestAssemblyInfo( string assemblyName, Version imageRuntimeVersion, RuntimeFramework runnerRuntimeFramework, IList testFrameworks ) { this.assemblyName = assemblyName; this.imageRuntimeVersion = imageRuntimeVersion; this.runnerRuntimeFramework = runnerRuntimeFramework; this.testFrameworks = testFrameworks; Process p = Process.GetCurrentProcess(); this.processId = p.Id; Assembly entryAssembly = Assembly.GetEntryAssembly(); this.moduleName = entryAssembly != null ? Path.GetFileName(Assembly.GetEntryAssembly().Location) : p.MainModule.ModuleName; this.domainName = AppDomain.CurrentDomain.FriendlyName; this.appBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; this.configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; this.binPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath; } /// /// Gets the name of the assembly /// public string Name { get { return assemblyName; } } /// /// Gets the runtime version for which the assembly was built /// public Version ImageRuntimeVersion { get { return imageRuntimeVersion; } } /// /// Gets the runtime framework under which the assembly is loaded /// public RuntimeFramework RunnerRuntimeFramework { get { return runnerRuntimeFramework; } } /// /// Gets the runtime version under which the assembly is loaded /// public Version RunnerRuntimeVersion { get { return runnerRuntimeFramework.ClrVersion; } } /// /// The Id of the process in which the assembly is loaded /// public int ProcessId { get { return processId; } } /// /// The friendly name of the AppDomain in which the assembly is loaded /// public string DomainName { get { return domainName; } } /// /// The Application Base of the AppDomain in which the assembly is loaded /// public string ApplicationBase { get { return appBase; } } /// /// The PrivateBinPath of the AppDomain in which the assembly is loaded /// public string PrivateBinPath { get { return binPath; } } /// /// The ConfigurationFile of the AppDomain in which the assembly is loaded /// public string ConfigurationFile { get { return configFile; } } /// /// The name of the main module of the process in which the assembly is loaded /// public string ModuleName { get { return moduleName; } set { moduleName = value; } } /// /// Gets a list of testframeworks referenced by the assembly /// public IList TestFrameworks { get { return testFrameworks; } } } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/nunit.core.interfaces.dll.csproj0000664000175000017500000001331511702530104026135 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {435428F8-5995-4CE4-8022-93D595A8CC0F} Debug AnyCPU nunit.core.interfaces JScript Grid IE50 false Library NUnit.Core OnBuildSuccess 2.0 v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 ..\..\..\bin\Debug\lib\nunit.core.interfaces.xml true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 ..\..\..\bin\Release\lib\nunit.core.interfaces.xml 4096 1699 true false false 4 none prompt System System.Data System.XML CommonAssemblyInfo.cs Extensibility\ITestCaseData.cs NUnit-2.6.0.12051/src/NUnitCore/interfaces/ITestFilter.cs0000664000175000017500000000266511504175260022476 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// Interface to be implemented by filters applied to tests. /// The filter applies when running the test, after it has been /// loaded, since this is the only time an ITest exists. /// public interface ITestFilter { /// /// Indicates whether this is the EmptyFilter /// bool IsEmpty { get; } /// /// Determine if a particular test passes the filter criteria. Pass /// may examine the parents and/or descendants of a test, depending /// on the semantics of the particular filter /// /// The test to which the filter is applied /// True if the test passes the filter, otherwise false bool Pass( ITest test ); /// /// Determine whether the test itself matches the filter criteria, /// without examining either parents or descendants. /// /// The test to which the filter is applied /// True if the filter matches the any parent of the test bool Match( ITest test ); } } NUnit-2.6.0.12051/src/NUnitCore/interfaces/TestID.cs0000664000175000017500000000717711504175260021437 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; namespace NUnit.Core { /// /// TestID encapsulates a unique identifier for tests. As /// currently implemented, this is an integer and is unique /// within the AppDomain. TestID is one component of a /// TestName. We use this object, rather than a raw int, /// for two reasons: (1) to hide the implementation so /// it may be changed later if necessary and (2) so that the /// id may be null in a "weak" TestName. /// [Serializable] public class TestID : ICloneable { #region Fields /// /// The int key that distinguishes this test from all others created /// by the same runner. /// private int id; /// /// Static value to seed ids. It's started at 1000 so any /// uninitialized ids will stand out. /// private static int nextID = 1000; #endregion #region Construction /// /// Construct a new TestID /// public TestID() { this.id = unchecked( nextID++ ); } /// /// Construct a TestID with a given value. /// Used in parsing test names and in order /// to construct an artificial test node for /// aggregating multiple test runners. /// /// public TestID( int id ) { this.id = id; } #endregion #region Static Methods /// /// Parse a TestID from it's string representation /// /// /// public static TestID Parse( string s ) { int id = Int32.Parse( s ); return new TestID( id ); } #endregion #region Object Overrides /// /// Override of Equals method to allow comparison of TestIDs /// /// /// public override bool Equals(object obj) { TestID other = obj as TestID; if ( other != null ) return this.id == other.id; return base.Equals (obj); } /// /// Override of GetHashCode for TestIDs /// /// public override int GetHashCode() { return id.GetHashCode(); } /// /// Override ToString() to display the int id /// /// public override string ToString() { return id.ToString(); } #endregion #region Operator Overrides /// /// Operator == override /// /// /// /// public static bool operator ==( TestID id1, TestID id2 ) { if ( Object.Equals( id1, null ) ) return Object.Equals( id2, null ); return id1.Equals( id2 ); } /// /// Operator != override /// /// /// /// public static bool operator !=( TestID id1, TestID id2 ) { return id1 == id2 ? false : true; } #endregion #region ICloneable Implementation /// /// Clone this TestID /// /// An identical TestID public object Clone() { return this.MemberwiseClone(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/tests/0000775000175000017500000000000011742560362016764 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/tests/AssemblyVersionFixture.cs0000664000175000017500000000326411504175260024007 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using System.Threading; using System.Reflection.Emit; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class AssemblyVersionFixture { [Test] // TODO: Figure out what we're testing here! Was there a bug? public void Version() { Version version = new Version("1.0.0.2002"); string nameString = "TestAssembly"; AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = nameString; assemblyName.Version = version; MakeDynamicAssembly(assemblyName); Assembly assembly = FindAssemblyByName(nameString); System.Version foundVersion = assembly.GetName().Version; Assert.AreEqual(version, foundVersion); } private Assembly FindAssemblyByName(string name) { // Get all the assemblies currently loaded in the application domain. Assembly[] myAssemblies = Thread.GetDomain().GetAssemblies(); Assembly assembly = null; for(int i = 0; i < myAssemblies.Length && assembly == null; i++) { if(String.Compare(myAssemblies[i].GetName().Name, name) == 0) assembly = myAssemblies[i]; } return assembly; } public static void MakeDynamicAssembly(AssemblyName myAssemblyName) { Thread.GetDomain().DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/PlatformDetectionTests.cs0000664000175000017500000002602111654223224023755 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// Summary description for PlatformHelperTests. /// [TestFixture] public class PlatformDetectionTests { private static readonly PlatformHelper win95Helper = new PlatformHelper( new OSPlatform( PlatformID.Win32Windows , new Version( 4, 0 ) ), new RuntimeFramework( RuntimeType.Net, new Version( 1, 1, 4322, 0 ) ) ); private static readonly PlatformHelper winXPHelper = new PlatformHelper( new OSPlatform( PlatformID.Win32NT , new Version( 5,1 ) ), new RuntimeFramework( RuntimeType.Net, new Version( 1, 1, 4322, 0 ) ) ); private void CheckOSPlatforms( OSPlatform os, string expectedPlatforms ) { CheckPlatforms( new PlatformHelper( os, RuntimeFramework.CurrentFramework ), expectedPlatforms, PlatformHelper.OSPlatforms ); } private void CheckRuntimePlatforms( RuntimeFramework runtimeFramework, string expectedPlatforms ) { CheckPlatforms( new PlatformHelper( OSPlatform.CurrentPlatform, runtimeFramework ), expectedPlatforms, PlatformHelper.RuntimePlatforms + ",NET-1.0,NET-1.1,NET-2.0,NET-3.0,NET-3.5,NET-4.0,MONO-1.0,MONO-2.0,MONO-3.0,MONO-3.5,MONO-4.0" ); } private void CheckPlatforms( PlatformHelper helper, string expectedPlatforms, string checkPlatforms ) { string[] expected = expectedPlatforms.Split( new char[] { ',' } ); string[] check = checkPlatforms.Split( new char[] { ',' } ); foreach( string testPlatform in check ) { bool shouldPass = false; foreach( string platform in expected ) if ( shouldPass = platform.ToLower() == testPlatform.ToLower() ) break; bool didPass = helper.IsPlatformSupported( testPlatform ); if ( shouldPass && !didPass ) Assert.Fail( "Failed to detect {0}", testPlatform ); else if ( didPass && !shouldPass ) Assert.Fail( "False positive on {0}", testPlatform ); else if ( !shouldPass && !didPass ) Assert.AreEqual( "Only supported on " + testPlatform, helper.Reason ); } } [Test] public void DetectWin95() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32Windows, new Version( 4, 0 ) ), "Win95,Win32Windows,Win32,Win" ); } [Test] public void DetectWin98() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32Windows, new Version( 4, 10 ) ), "Win98,Win32Windows,Win32,Win" ); } [Test] public void DetectWinMe() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32Windows, new Version( 4, 90 ) ), "WinMe,Win32Windows,Win32,Win" ); } // WinCE isn't defined in .NET 1.0. [Test, Platform(Exclude="Net-1.0")] public void DetectWinCE() { PlatformID winCE = (PlatformID)Enum.Parse(typeof(PlatformID), "WinCE"); CheckOSPlatforms( new OSPlatform(winCE, new Version(1, 0)), "WinCE,Win32,Win" ); } [Test] public void DetectNT3() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32NT, new Version( 3, 51 ) ), "NT3,Win32NT,Win32,Win" ); } [Test] public void DetectNT4() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32NT, new Version( 4, 0 ) ), "NT4,Win32NT,Win32,Win,Win-4.0" ); } [Test] public void DetectWin2K() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32NT, new Version( 5, 0 ) ), "Win2K,NT5,Win32NT,Win32,Win,Win-5.0" ); } [Test] public void DetectWinXP() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32NT, new Version( 5, 1 ) ), "WinXP,NT5,Win32NT,Win32,Win,Win-5.1" ); } [Test] public void DetectWinXPProfessionalX64() { CheckOSPlatforms( new OSPlatform( PlatformID.Win32NT, new Version( 5, 2 ), OSPlatform.ProductType.WorkStation ), "WinXP,NT5,Win32NT,Win32,Win,Win-5.1" ); } [Test] public void DetectWin2003Server() { CheckOSPlatforms( new OSPlatform(PlatformID.Win32NT, new Version(5, 2), OSPlatform.ProductType.Server), "Win2003Server,NT5,Win32NT,Win32,Win,Win-5.2"); } [Test] public void DetectVista() { CheckOSPlatforms( new OSPlatform(PlatformID.Win32NT, new Version(6, 0), OSPlatform.ProductType.WorkStation), "Vista,NT6,Win32NT,Win32,Win,Win-6.0"); } [Test] public void DetectWin2008ServerOriginal() { CheckOSPlatforms( new OSPlatform(PlatformID.Win32NT, new Version(6, 0), OSPlatform.ProductType.Server), "Win2008Server,NT6,Win32NT,Win32,Win,Win-6.0"); } [Test] public void DetectWin2008ServerR2() { CheckOSPlatforms( new OSPlatform(PlatformID.Win32NT, new Version(6, 1), OSPlatform.ProductType.Server), "Win2008Server,Win2008ServerR2,NT6,Win32NT,Win32,Win,Win-6.1"); } [Test] public void DetectWindows7() { CheckOSPlatforms( new OSPlatform(PlatformID.Win32NT, new Version(6, 1), OSPlatform.ProductType.WorkStation), "Windows7,NT6,Win32NT,Win32,Win,Win-6.1"); } [Test] public void DetectUnixUnderMicrosoftDotNet() { CheckOSPlatforms( new OSPlatform(OSPlatform.UnixPlatformID_Microsoft, new Version()), "UNIX,Linux"); } // This throws under Microsoft .Net due to the invlaid enumeration value of 128 [Test, Platform(Exclude="Net")] public void DetectUnixUnderMono() { CheckOSPlatforms( new OSPlatform(OSPlatform.UnixPlatformID_Mono, new Version()), "UNIX,Linux"); } [Test] public void DetectNet10() { CheckRuntimePlatforms( new RuntimeFramework( RuntimeType.Net, new Version( 1, 0, 3705, 0 ) ), "NET,NET-1.0" ); } [Test] public void DetectNet11() { CheckRuntimePlatforms( new RuntimeFramework( RuntimeType.Net, new Version( 1, 1, 4322, 0 ) ), "NET,NET-1.1" ); } [Test] public void DetectNet20() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Net, new Version(2, 0, 50727, 0)), "Net,Net-2.0"); } [Test] public void DetectNet30() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Net, new Version(3, 0)), "Net,Net-2.0,Net-3.0"); } [Test] public void DetectNet35() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Net, new Version(3, 5)), "Net,Net-2.0,Net-3.0,Net-3.5"); } [Test] public void DetectNet40() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Net, new Version(4, 0, 30319, 0)), "Net,Net-4.0"); } [Test] public void DetectNetCF() { CheckRuntimePlatforms( new RuntimeFramework( RuntimeType.NetCF, new Version( 1, 1, 4322, 0 ) ), "NetCF" ); } [Test] public void DetectSSCLI() { CheckRuntimePlatforms( new RuntimeFramework( RuntimeType.SSCLI, new Version( 1, 0, 3, 0 ) ), "SSCLI,Rotor" ); } [Test] public void DetectMono10() { CheckRuntimePlatforms( new RuntimeFramework( RuntimeType.Mono, new Version( 1, 1, 4322, 0 ) ), "Mono,Mono-1.0" ); } [Test] public void DetectMono20() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Mono, new Version(2, 0, 50727, 0)), "Mono,Mono-2.0"); } [Test] public void DetectMono30() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Mono, new Version(3, 0)), "Mono,Mono-2.0,Mono-3.0"); } [Test] public void DetectMono35() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Mono, new Version(3, 5)), "Mono,Mono-2.0,Mono-3.0,Mono-3.5"); } [Test] public void DetectMono40() { CheckRuntimePlatforms( new RuntimeFramework(RuntimeType.Mono, new Version(4, 0, 30319)), "Mono,Mono-4.0"); } [Test] public void DetectExactVersion() { Assert.IsTrue( winXPHelper.IsPlatformSupported( "net-1.1.4322" ) ); Assert.IsTrue( winXPHelper.IsPlatformSupported( "net-1.1.4322.0" ) ); Assert.IsFalse( winXPHelper.IsPlatformSupported( "net-1.1.4323.0" ) ); Assert.IsFalse( winXPHelper.IsPlatformSupported( "net-1.1.4322.1" ) ); } [Test] public void ArrayOfPlatforms() { string[] platforms = new string[] { "NT4", "Win2K", "WinXP" }; Assert.IsTrue( winXPHelper.IsPlatformSupported( platforms ) ); Assert.IsFalse( win95Helper.IsPlatformSupported( platforms ) ); } [Test] public void PlatformAttribute_Include() { PlatformAttribute attr = new PlatformAttribute( "Win2K,WinXP,NT4" ); Assert.IsTrue( winXPHelper.IsPlatformSupported( attr ) ); Assert.IsFalse( win95Helper.IsPlatformSupported( attr ) ); Assert.AreEqual("Only supported on Win2K,WinXP,NT4", win95Helper.Reason); } [Test] public void PlatformAttribute_Exclude() { PlatformAttribute attr = new PlatformAttribute(); attr.Exclude = "Win2K,WinXP,NT4"; Assert.IsFalse( winXPHelper.IsPlatformSupported( attr ) ); Assert.AreEqual( "Not supported on Win2K,WinXP,NT4", winXPHelper.Reason ); Assert.IsTrue( win95Helper.IsPlatformSupported( attr ) ); } [Test] public void PlatformAttribute_IncludeAndExclude() { PlatformAttribute attr = new PlatformAttribute( "Win2K,WinXP,NT4" ); attr.Exclude = "Mono"; Assert.IsFalse( win95Helper.IsPlatformSupported( attr ) ); Assert.AreEqual( "Only supported on Win2K,WinXP,NT4", win95Helper.Reason ); Assert.IsTrue( winXPHelper.IsPlatformSupported( attr ) ); attr.Exclude = "Net"; Assert.IsFalse( win95Helper.IsPlatformSupported( attr ) ); Assert.AreEqual( "Only supported on Win2K,WinXP,NT4", win95Helper.Reason ); Assert.IsFalse( winXPHelper.IsPlatformSupported( attr ) ); Assert.AreEqual( "Not supported on Net", winXPHelper.Reason ); } [Test] public void PlatformAttribute_InvalidPlatform() { PlatformAttribute attr = new PlatformAttribute( "Net-1.0,Net11,Mono" ); Assert.IsFalse( winXPHelper.IsPlatformSupported( attr ) ); Assert.AreEqual( "Invalid platform name: Net11", winXPHelper.Reason ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/MaxTimeTests.cs0000664000175000017500000000500411504175260021674 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.TestData; namespace NUnit.Core.Tests { /// /// Tests for MaxTime decoration. /// [TestFixture] public class MaxTimeTests { [Test,MaxTime(1000)] public void MaxTimeNotExceeded() { } // TODO: We need a way to simulate the clock reliably [Test] public void MaxTimeExceeded() { Test test = TestFixtureBuilder.BuildFrom(typeof(MaxTimeFixture)); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); result = (TestResult)result.Results[0]; StringAssert.IsMatch(@"Elapsed time of \d*ms exceeds maximum of 1ms", result.Message); } [Test, MaxTime(1000)] [ExpectedException(typeof(AssertionException), ExpectedMessage = "Intentional Failure")] public void FailureReport() { Assert.Fail("Intentional Failure"); } [Test] public void FailureReportHasPriorityOverMaxTime() { Test test = TestFixtureBuilder.BuildFrom(typeof(MaxTimeFixtureWithFailure)); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); result = (TestResult)result.Results[0]; Assert.AreEqual(ResultState.Failure, result.ResultState); StringAssert.IsMatch("Intentional Failure", result.Message); } [Test, MaxTime(1000), ExpectedException] public void ErrorReport() { throw new Exception(); } [Test] public void ErrorReportHasPriorityOverMaxTime() { Test test = TestFixtureBuilder.BuildFrom(typeof(MaxTimeFixtureWithError)); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); result = (TestResult)result.Results[0]; Assert.AreEqual(ResultState.Error, result.ResultState); StringAssert.IsMatch("Exception message", result.Message); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/CoreExtensionsTests.cs0000664000175000017500000001531311544451536023313 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Text; using System.Reflection; #if NET_3_5 || NET_4_0 using NSubstitute; #endif using NUnit.Framework; using NUnit.Core.Extensibility; namespace NUnit.Core.Tests { [TestFixture] public class CoreExtensionsTests { private CoreExtensions host; [SetUp] public void CreateHost() { host = new CoreExtensions(); } [Test] public void HasSuiteBuildersExtensionPoint() { IExtensionPoint ep = host.GetExtensionPoint( "SuiteBuilders" ); Assert.IsNotNull( ep ); Assert.AreEqual( "SuiteBuilders", ep.Name ); Assert.AreEqual( typeof( SuiteBuilderCollection ), ep.GetType() ); } [Test] public void HasTestCaseBuildersExtensionPoint() { IExtensionPoint ep = host.GetExtensionPoint( "TestCaseBuilders" ); Assert.IsNotNull( ep ); Assert.AreEqual( "TestCaseBuilders", ep.Name ); Assert.AreEqual( typeof( TestCaseBuilderCollection ), ep.GetType() ); } [Test] public void HasTestDecoratorsExtensionPoint() { IExtensionPoint ep = host.GetExtensionPoint( "TestDecorators" ); Assert.IsNotNull( ep ); Assert.AreEqual( "TestDecorators", ep.Name ); Assert.AreEqual( typeof( TestDecoratorCollection ), ep.GetType() ); } [Test] public void HasEventListenerExtensionPoint() { IExtensionPoint ep = host.GetExtensionPoint( "EventListeners" ); Assert.IsNotNull( ep ); Assert.AreEqual( "EventListeners", ep.Name ); Assert.AreEqual( typeof( EventListenerCollection ), ep.GetType() ); } [Test] public void HasTestFrameworkRegistry() { IExtensionPoint ep = host.GetExtensionPoint( "FrameworkRegistry" ); Assert.IsNotNull( ep ); Assert.AreEqual( "FrameworkRegistry", ep.Name ); Assert.AreEqual( typeof( FrameworkRegistry ), ep.GetType() ); } class MockDecorator : ITestDecorator { private string name; private StringBuilder sb; public MockDecorator(string name, StringBuilder sb) { this.name = name; this.sb = sb; } public Test Decorate(Test test, MemberInfo member) { sb.Append(name); return test; } } [Test] public void DecoratorsRunInOrderOfPriorities() { StringBuilder sb = new StringBuilder(); ITestDecorator mock0 = new MockDecorator("mock0", sb); ITestDecorator mock1 = new MockDecorator("mock1", sb); ITestDecorator mock3a = new MockDecorator("mock3a", sb); ITestDecorator mock3b = new MockDecorator("mock3b", sb); ITestDecorator mock3c = new MockDecorator("mock3c", sb); ITestDecorator mock5a = new MockDecorator("mock5a", sb); ITestDecorator mock5b = new MockDecorator("mock5b", sb); ITestDecorator mock8 = new MockDecorator("mock8", sb); ITestDecorator mock9 = new MockDecorator("mock9", sb); IExtensionPoint2 ep = (IExtensionPoint2)host.GetExtensionPoint("TestDecorators"); ep.Install(mock8, 8); ep.Install(mock5a, 5); ep.Install(mock1, 1); ep.Install(mock3a, 3); ep.Install(mock3b, 3); ep.Install(mock9, 9); ep.Install(mock3c, 3); ep.Install(mock0); ep.Install(mock5b, 5); ITestDecorator decorators = (ITestDecorator)ep; decorators.Decorate(null, null); Assert.AreEqual("mock0mock1mock3cmock3bmock3amock5bmock5amock8mock9", sb.ToString()); sb.Remove(0, sb.Length); decorators.Decorate(null, null); Assert.AreEqual("mock0mock1mock3cmock3bmock3amock5bmock5amock8mock9", sb.ToString()); } #if NET_3_5 || NET_4_0 [Test, Platform("Net-3.5,Mono-3.5,Net-4.0")] public void CanAddDecorator() { ITestDecorator mockDecorator = Substitute.For(); IExtensionPoint ep = host.GetExtensionPoint("TestDecorators"); ep.Install(mockDecorator); ITestDecorator decorators = (ITestDecorator)ep; decorators.Decorate(null, null); mockDecorator.Received().Decorate(null, null); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0")] public void CanAddSuiteBuilder() { ISuiteBuilder mockBuilder = Substitute.For(); mockBuilder.CanBuildFrom(Arg.Any()).Returns(true); IExtensionPoint ep = host.GetExtensionPoint("SuiteBuilders"); ep.Install(mockBuilder); ISuiteBuilder builders = (ISuiteBuilder)ep; builders.BuildFrom( null ); mockBuilder.Received().BuildFrom(null); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0")] public void CanAddTestCaseBuilder() { ITestCaseBuilder mockBuilder = Substitute.For(); mockBuilder.CanBuildFrom(null).Returns(true); IExtensionPoint ep = host.GetExtensionPoint("TestCaseBuilders"); ep.Install(mockBuilder); ITestCaseBuilder builders = (ITestCaseBuilder)ep; builders.BuildFrom(null); mockBuilder.Received().BuildFrom(null); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0")] public void CanAddTestCaseBuilder2() { ITestCaseBuilder2 mockBuilder = Substitute.For(); mockBuilder.CanBuildFrom(null, null).Returns(true); IExtensionPoint ep = host.GetExtensionPoint("TestCaseBuilders"); ep.Install(mockBuilder); ITestCaseBuilder2 builders = (ITestCaseBuilder2)ep; builders.BuildFrom(null, null); mockBuilder.Received().BuildFrom(null, null); } [Test, Platform("Net-3.5,Mono-3.5,Net-4.0")] public void CanAddEventListener() { EventListener mockListener = Substitute.For(); IExtensionPoint ep = host.GetExtensionPoint("EventListeners"); ep.Install( mockListener ); EventListener listeners = (EventListener)ep; listeners.RunStarted( "test", 0 ); mockListener.Received().RunStarted("test", 0); listeners.RunFinished( new TestResult( new TestInfo( new TestSuite( "test" ) ) ) ); mockListener.Received().RunFinished(Arg.Is(x=>x.Name=="test")); } #endif } } NUnit-2.6.0.12051/src/NUnitCore/tests/AssemblyHelperTests.cs0000664000175000017500000000626611720453120023254 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class AssemblyHelperTests { [Test] public void GetPathForAssembly() { string path = AssemblyHelper.GetAssemblyPath(this.GetType().Assembly); Assert.That(Path.GetFileName(path), Is.EqualTo("nunit.core.tests.dll").IgnoreCase); Assert.That(File.Exists(path)); } [Test] public void GetPathForType() { string path = AssemblyHelper.GetAssemblyPath(this.GetType()); Assert.That(Path.GetFileName(path), Is.EqualTo("nunit.core.tests.dll").IgnoreCase); Assert.That(File.Exists(path)); } [Platform("Win")] [TestCase(@"file:///C:/path/to/assembly.dll", Result=@"C:/path/to/assembly.dll")] [TestCase(@"file://C:/path/to/assembly.dll", Result=@"C:/path/to/assembly.dll")] [TestCase(@"file://C:/my path/to my/assembly.dll", Result = @"C:/my path/to my/assembly.dll")] [TestCase(@"file:///C:/dev/C#/assembly.dll", Result = @"C:/dev/C#/assembly.dll")] [TestCase(@"file:///C:/dev/funnychars?:=/assembly.dll", Result = @"C:/dev/funnychars?:=/assembly.dll")] [TestCase(@"file:///path/to/assembly.dll", Result = @"/path/to/assembly.dll")] [TestCase(@"file://path/to/assembly.dll", Result = @"path/to/assembly.dll")] [TestCase(@"file:///my path/to my/assembly.dll", Result = @"/my path/to my/assembly.dll")] [TestCase(@"file://my path/to my/assembly.dll", Result = @"my path/to my/assembly.dll")] [TestCase(@"file:///dev/C#/assembly.dll", Result = @"/dev/C#/assembly.dll")] [TestCase(@"file:///dev/funnychars?:=/assembly.dll", Result = @"/dev/funnychars?:=/assembly.dll")] //[TestCase(@"http://server/path/to/assembly.dll", Result="//server/path/to/assembly.dll")] public string GetAssemblyPathFromFileUri_Windows(string uri) { return AssemblyHelper.GetAssemblyPathFromFileUri(uri); } [Platform("Linux")] [TestCase(@"file:///path/to/assembly.dll", Result = @"/path/to/assembly.dll")] [TestCase(@"file://path/to/assembly.dll", Result = @"/path/to/assembly.dll")] [TestCase(@"file:///my path/to my/assembly.dll", Result = @"/my path/to my/assembly.dll")] [TestCase(@"file://my path/to my/assembly.dll", Result = @"/my path/to my/assembly.dll")] [TestCase(@"file:///dev/C#/assembly.dll", Result = @"/dev/C#/assembly.dll")] [TestCase(@"file:///dev/funnychars?:=/assembly.dll", Result = @"/dev/funnychars?:=/assembly.dll")] //[TestCase(@"http://server/path/to/assembly.dll", Result="//server/path/to/assembly.dll")] public string GetAssemblyPathFromFileUri_Linux(string uri) { return AssemblyHelper.GetAssemblyPathFromFileUri(uri); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestConsole.cs0000664000175000017500000000354611504175260021560 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// This test is designed to check that console output is being passed /// correctly accross the AppDomain boundry. Non-remotable objects should /// be converted to a string before being passed accross. /// [TestFixture] public class TestConsole { [Test] public void ConsoleWrite() { Console.Write("I am a 'String' object."); Console.WriteLine(); Console.Write(new TestSerialisable()); Console.WriteLine(); Console.Write(new TestMarshalByRefObject()); Console.WriteLine(); System.Diagnostics.Trace.WriteLine( "Output from Trace", "NUnit" ); Console.Write(new TestNonRemotableObject()); Console.WriteLine(); Console.Error.WriteLine( "This is from Console.Error" ); } [Test] public void ConsoleWriteLine() { Console.WriteLine("I am a 'String' object."); Console.WriteLine(new TestSerialisable()); Console.WriteLine(new TestMarshalByRefObject()); Console.WriteLine(new TestNonRemotableObject()); } [Serializable] public class TestSerialisable { override public string ToString() { return "I am a 'Serializable' object."; } } public class TestMarshalByRefObject : MarshalByRefObject { override public string ToString() { return "I am a 'MarshalByRefObject' object."; } } public class TestNonRemotableObject { override public string ToString() { return "I am a non-remotable object."; } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestIDTests.cs0000664000175000017500000000230711504175260021467 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class TestIDTests { [Test] public void ClonedTestIDsAreEqual() { TestID testID = new TestID(); TestID cloneID = (TestID)testID.Clone(); Assert.AreEqual( testID, cloneID ); Assert.IsTrue( testID == cloneID, "operator ==" ); Assert.IsFalse( testID != cloneID, "operator !=" ); } [Test] public void DifferentTestIDsAreNotEqual() { TestID testID1 = new TestID(); TestID testID2 = new TestID(); Assert.AreNotEqual( testID1, testID2 ); Assert.IsFalse( testID1 == testID2, "operator ==" ); Assert.IsTrue( testID1 != testID2, "operator !=" ); } [Test] public void DifferentTestIDsDisplayDifferentStrings() { TestID testID1 = new TestID(); TestID testID2 = new TestID(); Assert.AreNotEqual( testID1.ToString(), testID2.ToString() ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AssemblyReaderTests.cs0000664000175000017500000000355511715541364023251 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using System.IO; namespace NUnit.Core.Tests { [TestFixture] public class AssemblyReaderTests { private AssemblyReader rdr; [SetUp] public void CreateReader() { rdr = new AssemblyReader( this.GetType().Assembly ); } [TearDown] public void DisposeReader() { if ( rdr != null ) rdr.Dispose(); rdr = null; } [Test] public void CreateFromPath() { string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType())); Assert.AreEqual(path, new AssemblyReader(path).AssemblyPath); } [Test] public void CreateFromAssembly() { string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType())); Assert.AreEqual(path, rdr.AssemblyPath); } [Test] public void IsValidPeFile() { Assert.IsTrue( rdr.IsValidPeFile ); } [Test] public void IsValidPeFile_Fails() { string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Assert.IsFalse( new AssemblyReader( configFile ).IsValidPeFile ); } [Test] public void IsDotNetFile() { Assert.IsTrue( rdr.IsDotNetFile ); } [Test] public void ImageRuntimeVersion() { string runtimeVersion = rdr.ImageRuntimeVersion; StringAssert.StartsWith( "v", runtimeVersion ); new Version( runtimeVersion.Substring( 1 ) ); // This fails when we force running under a prior version // Assert.LessOrEqual( version, Environment.Version ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestFixtureBuilderTests.cs0000664000175000017500000000226111504175260024127 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using NUnit.Framework; using NUnit.Core; using NUnit.TestUtilities; using NUnit.TestData.TestFixtureBuilderTests; namespace NUnit.Core.Tests { // TODO: Figure out what this is really testing and eliminate if not needed [TestFixture] public class TestFixtureBuilderTests { [Test] public void GoodSignature() { string methodName = "TestVoid"; Test fixture = TestFixtureBuilder.BuildFrom( typeof( SignatureTestFixture ) ); Test foundTest = TestFinder.Find( methodName, fixture, true ); Assert.IsNotNull( foundTest ); Assert.AreEqual( RunState.Runnable, foundTest.RunState ); } [Test] public void LoadCategories() { Test fixture = TestFixtureBuilder.BuildFrom( typeof( HasCategories ) ); Assert.IsNotNull(fixture); Assert.AreEqual(2, fixture.Categories.Count); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AssemblyResolverTests.cs0000664000175000017500000000307411504175260023636 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** namespace NUnit.Core.Tests { using System; using NUnit.Framework; using System.IO; [TestFixture] public class AssemblyResolverTests { string appBasePath; [TestFixtureSetUp] public void TestFixtureSetUp() { this.appBasePath = Environment.ExpandEnvironmentVariables(@"%temp%\AssemblyResolver"); if (Directory.Exists(this.appBasePath)) { Directory.Delete(this.appBasePath, true); } Directory.CreateDirectory(this.appBasePath); } [TestFixtureTearDown] public void TestFixtureTearDown() { Directory.Delete(this.appBasePath, true); } [Test] public void AddFile() { AppDomain domain = null; try { domain = AppDomain.CreateDomain("AssemblyResolver", null, this.appBasePath, null, false); AssemblyResolver assemblyResolver = (AssemblyResolver)domain.CreateInstanceFromAndUnwrap(typeof(AssemblyResolver).Assembly.CodeBase, typeof(AssemblyResolver).FullName); using (assemblyResolver) { Type type = typeof(TestAttribute); // ensure that assembly containing type can be found assemblyResolver.AddFile(type.Assembly.CodeBase); domain.CreateInstance(type.Assembly.FullName, type.FullName); } } finally { AppDomain.Unload(domain); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestFrameworkTests.cs0000664000175000017500000000172111504175260023127 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Tests { /// /// Summary description for TestFrameworkTests. /// [TestFixture] public class TestFrameworkTests { [Test] public void NUnitFrameworkIsKnownAndReferenced() { FrameworkRegistry frameworks = (FrameworkRegistry)CoreExtensions.Host.GetExtensionPoint("FrameworkRegistry"); foreach( AssemblyName assemblyName in frameworks.GetReferencedFrameworks( Assembly.GetExecutingAssembly() ) ) if ( assemblyName.Name == "nunit.framework" ) return; Assert.Fail("Cannot find nunit.framework"); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/SimpleTestRunnerTests.cs0000664000175000017500000000167011504175260023620 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using NUnit.Framework; using NUnit.Tests.Assemblies; namespace NUnit.Core.Tests { /// /// Tests of BaseTestRunner /// [TestFixture] public class SimpleTestRunnerTests : BasicRunnerTests { private SimpleTestRunner myRunner; protected override TestRunner CreateRunner( int runnerID ) { myRunner = new SimpleTestRunner( runnerID ); return myRunner; } // [Test] // public void BeginRunIsSynchronous() // { // myRunner.Load( "mock-assembly.dll" ); // myRunner.BeginRun( NullListener.NULL ); // Assert.IsFalse( myRunner.Running ); // } } } NUnit-2.6.0.12051/src/NUnitCore/tests/Results.xsd0000664000175000017500000001235211504175260021143 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitCore/tests/XmlTest.cs0000664000175000017500000001301611543625326020715 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Globalization; using System.IO; using System.Text; using System.Threading; using System.Xml; using System.Xml.Schema; using NUnit.Framework; using NUnit.Util; using NUnit.TestUtilities; namespace NUnit.Core.Tests { /// /// Summary description for XmlTest. /// /// [TestFixture] public class XmlTest { public class SchemaValidator { private XmlValidatingReader myXmlValidatingReader; private bool success; public SchemaValidator(string xmlFile, string schemaFile) { XmlSchemaCollection myXmlSchemaCollection = new XmlSchemaCollection(); XmlTextReader xmlTextReader = new XmlTextReader(schemaFile); try { myXmlSchemaCollection.Add(XmlSchema.Read(xmlTextReader, null)); } finally { xmlTextReader.Close(); } // Validate the XML file with the schema XmlTextReader myXmlTextReader = new XmlTextReader (xmlFile); myXmlValidatingReader = new XmlValidatingReader(myXmlTextReader); myXmlValidatingReader.Schemas.Add(myXmlSchemaCollection); myXmlValidatingReader.ValidationType = ValidationType.Schema; } public bool Validate() { success = true; try { // Set the validation event handler myXmlValidatingReader.ValidationEventHandler += new ValidationEventHandler (this.ValidationEventHandle); // Read XML data while (myXmlValidatingReader.Read()){} } catch (Exception e) { throw new NUnitException(e.Message, e); } finally { myXmlValidatingReader.Close(); } return success; } public void ValidationEventHandle (object sender, ValidationEventArgs args) { success = false; Console.WriteLine("\tValidation error: " + args.Message); if (args.Severity == XmlSeverityType.Warning) { Console.WriteLine("No schema found to enforce validation."); } else if (args.Severity == XmlSeverityType.Error) { Console.WriteLine("validation error occurred when validating the instance document."); } if (args.Exception != null) // XSD schema validation error { Console.WriteLine(args.Exception.SourceUri + "," + args.Exception.LinePosition + "," + args.Exception.LineNumber); } } } private void runSchemaValidatorTest(string reportFileName) { string testsDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( testsDll ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); new XmlResultWriter(reportFileName).SaveTestResult(result); SchemaValidator validator = new SchemaValidator(reportFileName, schemaFile.Path); Assert.IsTrue(validator.Validate(), "validate failed"); } private void runSchemaValidatorTest(TextWriter writer) { string testsDll = NUnit.Tests.Assemblies.MockAssembly.AssemblyPath; TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( testsDll ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); new XmlResultWriter(writer).SaveTestResult(result); } private string tempFile; private TempResourceFile schemaFile; [SetUp] public void CreateTempFileName() { tempFile = Path.GetTempFileName(); schemaFile = new TempResourceFile( GetType(), "Results.xsd"); } [TearDown] public void RemoveTempFiles() { schemaFile.Dispose(); FileInfo info = new FileInfo(tempFile); if(info.Exists) info.Delete(); } [Test,SetCulture("")] public void TestSchemaValidatorInvariantCulture() { runSchemaValidatorTest(tempFile); } [Test,SetCulture("en-US")] public void TestSchemaValidatorUnitedStatesCulture() { runSchemaValidatorTest(tempFile); } [Test,SetCulture("en-US")] public void TestStream() { runSchemaValidatorTest(tempFile); StringBuilder builder = new StringBuilder(); StringWriter writer = new StringWriter(builder); runSchemaValidatorTest(writer); string second = builder.ToString(); StreamReader reader = new StreamReader(tempFile); string first = reader.ReadToEnd(); reader.Close(); Assert.AreEqual(removeTimeAndAssertAttributes(first), removeTimeAndAssertAttributes(second)); } [Test,SetCulture("fr-FR")] public void TestSchemaValidatorFrenchCulture() { runSchemaValidatorTest(tempFile); } [Test] public void removeTime() { string input = "foo time=\"123.745774xxx\" bar asserts=\"5\" time=\"0\""; string output = removeTimeAndAssertAttributes(input); Assert.AreEqual("foo bar ", output); } private string removeTimeAndAssertAttributes(string text) { int index = 0; while ((index = text.IndexOf("time=\"")) != -1) { int endQuote = text.IndexOf("\"", index + 7); text = text.Remove(index, endQuote - index + 1); } while ((index = text.IndexOf("asserts=\"")) != -1) { int endQuote = text.IndexOf("\"", index + 10); text = text.Remove(index, endQuote - index + 1); } return text; } } } NUnit-2.6.0.12051/src/NUnitCore/tests/NameFilterTest.cs0000664000175000017500000001121711504175260022176 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Tests.Assemblies; using NUnit.Core.Builders; using NUnit.Core.Filters; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class NameFilterTest { private TestSuite testSuite; private Test mock3; [SetUp] public void SetUp() { testSuite = new TestSuite("Mock Test Suite"); testSuite.Add( TestBuilder.MakeFixture( typeof( MockTestFixture ) ) ); mock3 = TestFinder.Find("MockTest3", testSuite, true); } [Test] public void SingleNameMatch() { string fullName = "NUnit.Tests.Assemblies.MockTestFixture.MockTest3"; Assert.AreEqual(fullName, mock3.TestName.FullName); NameFilter filter = new NameFilter(mock3.TestName); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.AreEqual("NUnit.Tests.Assemblies.MockTestFixture", ((TestSuite)testSuite.Tests[0]).TestName.FullName); Assert.IsTrue(filter.Pass((TestSuite)testSuite.Tests[0]), "Name Filter did not pass test suite"); } [Test] public void MultipleNameMatch() { Test mock1 = TestFinder.Find("MockTest1", testSuite, true); NameFilter filter = new NameFilter(); filter.Add(mock3.TestName); filter.Add(mock1.TestName); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass(mock1), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass((TestSuite)testSuite.Tests[0]), "Name Filter did not pass test suite"); } [Test] public void SuiteNameMatch() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite) TestFinder.Find("MockTestFixture", testSuite, true); NameFilter filter = new NameFilter(mockTest.TestName); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass(mockTest), "Suite did not pass test case"); Assert.IsTrue(filter.Pass(testSuite), "Suite did not pass test case"); } [Test] public void TestDoesNotMatch() { Test mock1 = TestFinder.Find("MockTest1", testSuite, true); NameFilter filter = new NameFilter(mock1.TestName); Assert.IsFalse(filter.Pass(mock3), "Name Filter did pass test case"); Assert.IsTrue(filter.Pass(testSuite), "Name Filter did not pass test suite"); } [Test] public void HighLevelSuite() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite) TestFinder.Find("MockTestFixture", testSuite, true); NameFilter filter = new NameFilter(testSuite.TestName); Assert.AreEqual( true, filter.Pass(mock3), "test case"); Assert.AreEqual( true, filter.Pass(mockTest), "middle suite"); Assert.AreEqual( true, filter.Pass(testSuite), "test suite"); } [Test] public void ExplicitTestCaseDoesNotMatchWhenNotSelectedDirectly() { Test explicitTest = TestFinder.Find("ExplicitlyRunTest", testSuite, true); NameFilter filter = new NameFilter( testSuite.TestName ); Assert.AreEqual( false, filter.Pass(explicitTest) ); } [Test] public void ExplicitTestCaseMatchesWhenSelectedDirectly() { Test explicitTest = TestFinder.Find("ExplicitlyRunTest", testSuite, true); NameFilter filter = new NameFilter( explicitTest.TestName ); Assert.IsTrue(filter.Pass(explicitTest), "Name Filter did not pass on test case" ); Assert.IsTrue(filter.Pass(testSuite), "Name Filter did not pass on test suite" ); } [Test] public void ExplicitTestSuiteDoesNotMatchWhenNotSelectedDirectly() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite) TestFinder.Find("MockTestFixture", testSuite, true); mockTest.RunState = RunState.Explicit; NameFilter filter = new NameFilter(testSuite.TestName); Assert.AreEqual( false, filter.Pass(mock3), "descendant of explicit suite should not match" ); Assert.AreEqual( false, filter.Pass(mockTest), "explicit suite should not match" ); } [Test] public void ExplicitTestSuiteMatchesWhenSelectedDirectly() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite) TestFinder.Find("MockTestFixture", testSuite, true); mockTest.RunState = RunState.Explicit; NameFilter filter = new NameFilter(mockTest.TestName); Assert.AreEqual( true, filter.Pass(mock3), "test case" ); Assert.AreEqual( true, filter.Pass(mockTest), "middle suite"); Assert.AreEqual( true, filter.Pass(testSuite), "test suite"); } } }NUnit-2.6.0.12051/src/NUnitCore/tests/CombinatorialTests.cs0000664000175000017500000000452311504175260023120 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class CombinatorialTests { [Test] public void SingleArgument( [Values(1.3, 1.7, 1.5)] double x) { Assert.That(x > 1.0 && x < 2.0); } [Test, Combinatorial] public void TwoArguments_Combinatorial( [Values(1, 2, 3)] int x, [Values(10, 20)] int y) { Assert.That(x > 0 && x < 4 && y % 10 == 0); } [Test, Sequential] public void TwoArguments_Sequential( [Values(1, 2, 3)] int x, [Values(10, 20)] int y) { Assert.That(x > 0 && x < 4 && y % 10 == 0); } [Test, Combinatorial] public void ThreeArguments_Combinatorial( [Values(1, 2, 3)] int x, [Values(10, 20)] int y, [Values("Charlie", "Joe", "Frank")] string name) { Assert.That(x > 0 && x < 4 && y % 10 == 0); Assert.That(name.Length >= 2); } [Test, Sequential] public void ThreeArguments_Sequential( [Values(1, 2, 3)] int x, [Values(10, 20)] int y, [Values("Charlie", "Joe", "Frank")] string name) { Assert.That(x > 0 && x < 4 && y % 10 == 0); Assert.That(name.Length >= 2); } [Test] public void RangeTest( [Range(0.2, 0.6, 0.2)] double a, [Range(10, 20, 5)] int b) { } [Test, Sequential] public void RandomTest( [Random(32, 212, 5)] int x, [Random(5)] double y) { Assert.That(x,Is.InRange(32,212)); Assert.That(y,Is.InRange(0.0,1.0)); } [Test, Sequential] public void RandomArgsAreIndependent( [Random(1)] double x, [Random(1)] double y) { Assert.AreNotEqual(x, y); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestCaseSourceTests.cs0000664000175000017500000003227211672336042023236 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.Util; using NUnit.TestData; using NUnit.TestUtilities; using System.Collections; namespace NUnit.Core.Tests { [TestFixture] public class TestCaseSourceTests { [Test, TestCaseSource("StaticProperty")] public void SourceCanBeStaticProperty(string source) { Assert.AreEqual("StaticProperty", source); } static IEnumerable StaticProperty { get { return new object[] { new object[] { "StaticProperty" } }; } } [Test, TestCaseSource("InstanceProperty")] public void SourceCanBeInstanceProperty(string source) { Assert.AreEqual("InstanceProperty", source); } IEnumerable InstanceProperty { get { return new object[] { new object[] { "InstanceProperty" } }; } } [Test, TestCaseSource("StaticMethod")] public void SourceCanBeStaticMethod(string source) { Assert.AreEqual("StaticMethod", source); } static IEnumerable StaticMethod() { return new object[] { new object[] { "StaticMethod" } }; } [Test, TestCaseSource("InstanceMethod")] public void SourceCanBeInstanceMethod(string source) { Assert.AreEqual("InstanceMethod", source); } IEnumerable InstanceMethod() { return new object[] { new object[] { "InstanceMethod" } }; } [Test, TestCaseSource("StaticField")] public void SourceCanBeStaticField(string source) { Assert.AreEqual("StaticField", source); } internal static object[] StaticField = { new object[] { "StaticField" } }; [Test, TestCaseSource("InstanceField")] public void SourceCanBeInstanceField(string source) { Assert.AreEqual("InstanceField", source); } internal static object[] InstanceField = { new object[] { "InstanceField" } }; [Test, TestCaseSource("CheckCurrentDirectory")] public void SourceIsInvokedWithCorrectCurrentDirectory(bool isOK) { Assert.That(isOK); } [Test, TestCaseSource("MyData")] public void SourceMayReturnArgumentsAsObjectArray(int n, int d, int q) { Assert.AreEqual(q, n / d); } [TestCaseSource("MyData")] public void TestAttributeIsOptional(int n, int d, int q) { Assert.AreEqual(q, n / d); } [Test, TestCaseSource("MyIntData")] public void SourceMayReturnArgumentsAsIntArray(int n, int d, int q) { Assert.AreEqual(q, n / d); } [Test, TestCaseSource("EvenNumbers")] public void SourceMayReturnSinglePrimitiveArgumentAlone(int n) { Assert.AreEqual(0, n % 2); } [Test, TestCaseSource("Params")] public int SourceMayReturnArgumentsAsParamSet(int n, int d) { return n / d; } [Test] [TestCaseSource("MyData")] [TestCaseSource("MoreData", Category="Extra")] [TestCase(12, 0, 0, ExpectedException = typeof(System.DivideByZeroException))] public void TestMayUseMultipleSourceAttributes(int n, int d, int q) { Assert.AreEqual(q, n / d); } [Test, TestCaseSource("FourArgs")] public void TestWithFourArguments(int n, int d, int q, int r) { Assert.AreEqual(q, n / d); Assert.AreEqual(r, n % d); } [Test, Category("Top"), TestCaseSource(typeof(DivideDataProvider), "HereIsTheData")] public void SourceMayBeInAnotherClass(int n, int d, int q) { Assert.AreEqual(q, n / d); } [Test, TestCaseSource(typeof(DivideDataProviderWithExpectedResult), "TestCases")] public int SourceMayBeInAnotherClassWithExpectedResult(int n, int d) { return n / d; } [TestCaseSource("ExpectNull")] public object ExpectedResultCanBeNull() { return null; } [Test] public void CanSpecifyExpectedException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodThrowsExpectedException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Success, result.ResultState); } [Test] public void CanSpecifyExpectedException_WrongException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodThrowsWrongException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); StringAssert.StartsWith("An unexpected exception type was thrown", result.Message); } [Test] public void CanSpecifyExpectedException_NoneThrown() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodThrowsNoException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); Assert.AreEqual("System.ArgumentNullException was expected", result.Message); } [Test] public void CanSpecifyExpectedException_NoneThrown_ExpectedResultReturned() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodThrowsNoExceptionButReturnsResult").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); Assert.AreEqual("System.ArgumentNullException was expected", result.Message); } [Test] public void IgnoreTakesPrecedenceOverExpectedException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodCallsIgnore").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Ignored, result.ResultState); Assert.AreEqual("Ignore this", result.Message); } [Test] public void CanIgnoreIndividualTestCases() { Test test = TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodWithIgnoredTestCases"); Test testCase = TestFinder.Find("MethodWithIgnoredTestCases(1)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Runnable)); testCase = TestFinder.Find("MethodWithIgnoredTestCases(2)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Ignored)); testCase = TestFinder.Find("MethodWithIgnoredTestCases(3)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Ignored)); Assert.That(testCase.IgnoreReason, Is.EqualTo("Don't Run Me!")); } [Test] public void CanMarkIndividualTestCasesExplicit() { Test test = TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodWithExplicitTestCases"); Test testCase = TestFinder.Find("MethodWithExplicitTestCases(1)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Runnable)); testCase = TestFinder.Find("MethodWithExplicitTestCases(2)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Explicit)); testCase = TestFinder.Find("MethodWithExplicitTestCases(3)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Explicit)); Assert.That(testCase.IgnoreReason, Is.EqualTo("Connection failing")); } [Test] public void HandlesExceptionInTestCaseSource() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseSourceAttributeFixture), "MethodWithSourceThrowingException").Tests[0]; Assert.AreEqual(RunState.NotRunnable, test.RunState); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.NotRunnable, result.ResultState); Assert.AreEqual("System.Exception : my message", result.Message); } [TestCaseSource("exception_source"), Explicit] public void HandlesExceptioninTestCaseSource_GuiDisplay(string lhs, string rhs) { Assert.AreEqual(lhs, rhs); } internal object[] testCases = { new TestCaseData( new string[] { "A" }, new string[] { "B" }) }; [Test, TestCaseSource("testCases")] public void MethodTakingTwoStringArrays(string[] a, string[] b) { Assert.That(a, Is.TypeOf(typeof(string[]))); Assert.That(b, Is.TypeOf(typeof(string[]))); } #region Sources used by the tests internal static object[] MyData = new object[] { new object[] { 12, 3, 4 }, new object[] { 12, 4, 3 }, new object[] { 12, 6, 2 } }; internal static object[] MyIntData = new object[] { new int[] { 12, 3, 4 }, new int[] { 12, 4, 3 }, new int[] { 12, 6, 2 } }; internal static object[] FourArgs = new object[] { new TestCaseData( 12, 3, 4, 0 ), new TestCaseData( 12, 4, 3, 0 ), new TestCaseData( 12, 5, 2, 2 ) }; internal static int[] EvenNumbers = new int[] { 2, 4, 6, 8 }; internal static object[] ExpectNull = new object[] { new TestCaseData().Returns(null) }; private static IEnumerable CheckCurrentDirectory { get { return new object[] { new object[] { System.IO.File.Exists("nunit.core.tests.dll") } }; } } internal static object[] MoreData = new object[] { new object[] { 12, 1, 12 }, new object[] { 12, 2, 6 } }; internal static object[] Params = new object[] { new TestCaseData(24, 3).Returns(8), new TestCaseData(24, 2).Returns(12) }; private class DivideDataProvider { public static IEnumerable HereIsTheData { get { #if CLR_2_0 || CLR_4_0 yield return new TestCaseData(0, 0, 0) .SetName("ThisOneShouldThrow") .SetDescription("Demonstrates use of ExpectedException") .SetCategory("Junk") .SetProperty("MyProp", "zip") .Throws(typeof(System.DivideByZeroException)); yield return new object[] { 100, 20, 5 }; yield return new object[] { 100, 4, 25 }; #else ArrayList list = new ArrayList(); list.Add( new TestCaseData( 0, 0, 0) .SetName("ThisOneShouldThrow") .SetDescription("Demonstrates use of ExpectedException") .SetCategory("Junk") .SetProperty("MyProp", "zip") .Throws( typeof (System.DivideByZeroException) )); list.Add(new object[] { 100, 20, 5 }); list.Add(new object[] {100, 4, 25}); return list; #endif } } } public class DivideDataProviderWithExpectedResult { public static IEnumerable TestCases { get { return new object[] { new TestCaseData(12, 0).Throws(typeof(System.DivideByZeroException)), new TestCaseData(12, 3).Returns(5).Throws(typeof(AssertionException)).SetName("TC1"), new TestCaseData(12, 2).Returns(6).SetName("TC2"), new TestCaseData(12, 4).Returns(3).SetName("TC3") }; } } } private static IEnumerable exception_source { get { #if CLR_2_0 || CLR_4_0 yield return new TestCaseData("a", "a"); yield return new TestCaseData("b", "b"); #endif throw new System.Exception("my message"); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/tests/SuiteBuilderTests_Multiple.cs0000664000175000017500000000323111504175260024603 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; namespace NUnit.Core.Tests { [TestFixture] public class SuiteBuilderTests_Multiple { private static readonly int totalTests = NoNamespaceTestFixture.Tests + MockAssembly.Tests; private TestSuiteBuilder builder; private static string[] assemblies = new string[] { NoNamespaceTestFixture.AssemblyPath, MockAssembly.AssemblyPath }; private Test loadedSuite; [SetUp] public void LoadSuite() { builder = new TestSuiteBuilder(); loadedSuite = builder.Build( new TestPackage( "TestSuite", assemblies ) ); } [Test] public void BuildSuite() { Assert.IsNotNull( loadedSuite ); } [Test] public void RootNode() { Assert.AreEqual( "TestSuite", loadedSuite.TestName.Name ); } [Test] public void TestCaseCount() { Assert.AreEqual( totalTests , loadedSuite.TestCount); } [Test] public void LoadFixture() { TestPackage package = new TestPackage( "Multiple Assemblies", assemblies ); package.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; TestSuite suite = builder.Build( package ); Assert.IsNotNull( suite ); Assert.AreEqual( MockTestFixture.Tests, suite.TestCount ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/BasicRunnerTests.cs0000664000175000017500000001370711702653276022564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; namespace NUnit.Core.Tests { /// /// Base class for tests of various kinds of runners. The derived /// class should use SetUp to create the runner and assign it to /// the protected field runner and perform any cleanup in TearDown. /// If creating the runner is resource intensive, it may be possible /// to use TestFixtureSetUp and TestFixtureTearDown instead. /// public abstract class BasicRunnerTests { private static readonly string testsDll = NoNamespaceTestFixture.AssemblyPath; private static readonly string mockDll = MockAssembly.AssemblyPath; private readonly string[] assemblies = new string[] { testsDll, mockDll }; private readonly RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; protected TestRunner runner; private TestPackage package1; private TestPackage package2; [TestFixtureSetUp] public void SetUpRunner() { runner = CreateRunner( 123 ); Assert.IsNotNull( runner, "Derived test class failed to set runner" ); } [TestFixtureTearDown] public void TearDownRunner() { DestroyRunner(); } [SetUp] public void CreatePackages() { package1 = new TestPackage(MockAssembly.AssemblyPath); package2 = new TestPackage("TestSuite", assemblies); // Set current framework explicitly to avoid running out of process // unless explicitly called for by derived test. package1.Settings["RuntimeFramework"] = currentFramework; package2.Settings["RuntimeFramework"] = currentFramework; } protected abstract TestRunner CreateRunner( int runnerID ); protected virtual void DestroyRunner() { if (runner != null) runner.Unload(); } [Test] public void CheckRunnerID() { Assert.AreEqual(123, runner.ID); } [Test] public virtual void LoadAndReloadAssembly() { Assert.IsTrue(runner.Load(package1), "Unable to load assembly"); runner.Unload(); Assert.IsTrue(runner.Load(package1), "Unable to reload assembly"); } [Test] public void LoadAssemblyWithoutNamespaces() { package1.Settings["AutoNamespaceSuites"] = false; Assert.IsTrue(runner.Load(package1), "Unable to load assembly"); ITest test = runner.Test; Assert.IsNotNull( test ); Assert.AreEqual( MockAssembly.Classes, test.Tests.Count ); Assert.AreEqual( "MockTestFixture", ((ITest)test.Tests[0]).TestName.Name ); } [Test] public void LoadAssemblyWithFixture() { package1.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; Assert.IsTrue( runner.Load( package1 ) ); } [Test] public void LoadAssemblyWithSuite() { package1.TestName = "NUnit.Tests.Assemblies.MockSuite"; runner.Load( package1 ); Assert.IsNotNull(runner.Test, "Unable to build suite"); } [Test] public void CountTestCases() { runner.Load(package1); Assert.AreEqual( MockAssembly.Tests, runner.Test.TestCount ); } [Test] public void LoadMultipleAssemblies() { runner.Load( package2 ); Assert.IsNotNull( runner.Test, "Unable to load assemblies" ); } [Test] public void LoadMultipleAssembliesWithFixture() { package2.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; runner.Load( package2 ); Assert.IsNotNull(runner.Test, "Unable to build suite"); } [Test] public void LoadMultipleAssembliesWithSuite() { package2.TestName = "NUnit.Tests.Assemblies.MockSuite"; runner.Load( package2 ); Assert.IsNotNull(runner.Test, "Unable to build suite"); } [Test] public void CountTestCasesAcrossMultipleAssemblies() { runner.Load(package2); Assert.AreEqual( NoNamespaceTestFixture.Tests + MockAssembly.Tests, runner.Test.TestCount ); } [Test] public void RunAssembly() { runner.Load(package1); TestResult result = runner.Run( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); ResultSummarizer summary = new ResultSummarizer(result); Assert.AreEqual( MockAssembly.Tests - MockAssembly.NotRun, summary.TestsRun ); } [Test] public void RunAssemblyUsingBeginAndEndRun() { runner.Load(package1); runner.BeginRun( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); TestResult result = runner.EndRun(); Assert.IsNotNull( result ); ResultSummarizer summary = new ResultSummarizer( result ); Assert.AreEqual( MockAssembly.Tests - MockAssembly.NotRun, summary.TestsRun ); } [Test] public void RunMultipleAssemblies() { runner.Load( package2 ); TestResult result = runner.Run( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); ResultSummarizer summary = new ResultSummarizer(result); Assert.AreEqual( NoNamespaceTestFixture.Tests + MockAssembly.Tests - MockAssembly.NotRun, summary.TestsRun); } [Test] public void RunMultipleAssembliesUsingBeginAndEndRun() { runner.Load( package2 ); runner.BeginRun( NullListener.NULL, TestFilter.Empty, false, LoggingThreshold.Off ); TestResult result = runner.EndRun(); Assert.IsNotNull( result ); ResultSummarizer summary = new ResultSummarizer( result ); Assert.AreEqual( NoNamespaceTestFixture.Tests + MockAssembly.Tests - MockAssembly.NotRun, summary.TestsRun); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ValueSourceTests.cs0000664000175000017500000001125411544454420022573 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using NUnit.Framework; using NUnit.TestData; using NUnit.TestUtilities; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Core.Tests { [TestFixture] public class ValueSourceTests { [Test] public void ValueSourceCanBeStaticProperty( [ValueSource("StaticProperty")] string source) { Assert.AreEqual("StaticProperty", source); } static IEnumerable StaticProperty { get { #if CLR_2_0 || CLR_4_0 yield return "StaticProperty"; #else return new object[] { "StaticProperty" }; #endif } } [Test] public void ValueSourceCanBeInstanceProperty( [ValueSource("InstanceProperty")] string source) { Assert.AreEqual("InstanceProperty", source); } IEnumerable InstanceProperty { get { return new object[] { "InstanceProperty" }; } } [Test] public void ValueSourceCanBeStaticMethod( [ValueSource("StaticMethod")] string source) { Assert.AreEqual("StaticMethod", source); } static IEnumerable StaticMethod() { return new object[] { "StaticMethod" }; } [Test] public void ValueSourceCanBeInstanceMethod( [ValueSource("InstanceMethod")] string source) { Assert.AreEqual("InstanceMethod", source); } IEnumerable InstanceMethod() { return new object[] { "InstanceMethod" }; } [Test] public void ValueSourceCanBeStaticField( [ValueSource("StaticField")] string source) { Assert.AreEqual("StaticField", source); } internal static object[] StaticField = { "StaticField" }; [Test] public void ValueSourceCanBeInstanceField( [ValueSource("InstanceField")] string source) { Assert.AreEqual("InstanceField", source); } internal static object[] InstanceField = { "InstanceField" }; [Test] public void ValueSourceIsInvokedWithCorrectCurrentDirectory( [ValueSource("CheckCurrentDirectory")] bool isOK) { Assert.That(isOK); } private static IEnumerable CheckCurrentDirectory { get { return new object[] { System.IO.File.Exists("nunit.core.tests.dll") }; } } [Test, Sequential] public void MultipleArguments( [ValueSource("Numerators")] int n, [ValueSource("Denominators")] int d, [ValueSource("Quotients")] int q) { Assert.AreEqual(q, n / d); } internal static int[] Numerators = new int[] { 12, 12, 12 }; internal static int[] Denominators = new int[] { 3, 4, 6 }; internal static int[] Quotients = new int[] { 4, 3, 2 }; [Test, Sequential] public void ValueSourceMayBeInAnotherClass( [ValueSource(typeof(DivideDataProvider), "Numerators")] int n, [ValueSource(typeof(DivideDataProvider), "Denominators")] int d, [ValueSource(typeof(DivideDataProvider), "Quotients")] int q) { Assert.AreEqual(q, n / d); } private class DivideDataProvider { internal static int[] Numerators = new int[] { 12, 12, 12 }; internal static int[] Denominators = new int[] { 3, 4, 6 }; internal static int[] Quotients = new int[] { 4, 3, 2 }; } #if CLR_2_0 || CLR_4_0 [Test] public void ValueSourceMayBeGeneric( [ValueSourceAttribute(typeof(ValueProvider), "IntegerProvider")] int val) { Assert.That(2 * val, Is.EqualTo(val + val)); } public class ValueProvider { public IEnumerable IntegerProvider() { List dataList = new List(); dataList.Add(1); dataList.Add(2); dataList.Add(4); dataList.Add(8); return dataList; } } #endif } } NUnit-2.6.0.12051/src/NUnitCore/tests/StackOverflowTestFixture.cs0000664000175000017500000000202011504175260024300 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using System.Runtime.InteropServices; namespace NUnit.Core.Tests { /// /// Summary description for StackOverflowTestFixture. /// [TestFixture, Platform(Exclude="Net-2.0,Net-4.0,Mono",Reason="Cannot handle StackOverflowException in managed code")] public class StackOverflowTestFixture { private void FunctionCallsSelf() { FunctionCallsSelf(); } [Test, ExpectedException] // StackOverflowException in .NET, NullReferenceExcepton in Mono [Platform(Exclude="Net-2.0,linux",Reason="Cannot handle StackOverflowException in managed code")] public void SimpleOverflow() { FunctionCallsSelf(); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ThreadingTests.cs0000664000175000017500000001356111675632520022252 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData; namespace NUnit.Core.Tests { public class ThreadingTests { Thread parentThread; ApartmentState parentThreadApartment; Thread setupThread; [TestFixtureSetUp] public void GetParentThreadInfo() { this.parentThread = Thread.CurrentThread; this.parentThreadApartment = parentThread.ApartmentState; } [SetUp] public void GetSetUpThreadInfo() { this.setupThread = Thread.CurrentThread; } [Test, Timeout(50)] public void TestWithTimeoutRunsOnSeparateThread() { Assert.That(Thread.CurrentThread, Is.Not.EqualTo(parentThread)); } [Test, Timeout(50)] public void TestWithTimeoutRunsSetUpAndTestOnSameThread() { Assert.That(Thread.CurrentThread, Is.EqualTo(setupThread)); } [Test] public void TestWithInfiniteLoopTimesOut() { ThreadingFixture fixture = new ThreadingFixture(); TestSuite suite = TestBuilder.MakeFixture(fixture); Test test = TestFinder.Find("InfiniteLoopWith50msTimeout", suite, false); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.That(result.ResultState, Is.EqualTo(ResultState.Failure)); Assert.That(result.Message, Text.Contains("50ms")); Assert.That(fixture.TearDownWasRun, "TearDown was not executed"); } [Test, STAThread] public void TestWithSTAThreadRunsInSTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.STA)); if (parentThreadApartment == ApartmentState.STA) Assert.That(Thread.CurrentThread, Is.EqualTo(parentThread)); } [Test, MTAThread] public void TestWithMTAThreadRunsInMTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.MTA)); if (parentThreadApartment == ApartmentState.MTA) Assert.That(Thread.CurrentThread, Is.EqualTo(parentThread)); } [Test, RequiresSTA] public void TestWithRequiresSTARunsInSTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.STA)); if (parentThreadApartment == ApartmentState.STA) Assert.That(Thread.CurrentThread, Is.EqualTo(parentThread)); } [Test, RequiresMTA] public void TestWithRequiresMTARunsInMTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.MTA)); if (parentThreadApartment == ApartmentState.MTA) Assert.That(Thread.CurrentThread, Is.EqualTo(parentThread)); } [Test, RequiresThread] public void TestWithRequiresThreadRunsInSeparateThread() { Assert.That(Thread.CurrentThread, Is.Not.EqualTo(parentThread)); } [Test, RequiresThread] public void TestWithRequiresThreadRunsSetUpAndTestOnSameThread() { Assert.That(Thread.CurrentThread, Is.EqualTo(setupThread)); } [Test, RequiresThread(ApartmentState.STA)] public void TestWithRequiresThreadWithSTAArgRunsOnSeparateThreadInSTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.STA)); Assert.That(Thread.CurrentThread, Is.Not.EqualTo(parentThread)); } [Test, RequiresThread(ApartmentState.MTA)] public void TestWithRequiresThreadWithMTAArgRunsOnSeparateThreadInMTA() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.MTA)); Assert.That(Thread.CurrentThread, Is.Not.EqualTo(parentThread)); } [Test] public void TestOnSeparateThreadReportsAssertCountCorrectly() { TestResult result = TestBuilder.RunTestCase(typeof(ThreadingFixture), "MethodWithThreeAsserts"); Assert.That(result.AssertCount, Is.EqualTo(3)); } [Test] public void TimeoutCanBeSetOnTestFixture() { TestResult result = TestBuilder.RunTestFixture(typeof(ThreadingFixtureWithTimeout)); Assert.That(result.ResultState, Is.EqualTo(ResultState.Failure)); result = TestFinder.Find("Test2WithInfiniteLoop", result, false); Assert.That(result.ResultState, Is.EqualTo(ResultState.Failure)); Assert.That(result.Message, Text.Contains("50ms")); } [TestFixture, RequiresSTA] class FixtureRequiresSTA { [Test] public void RequiresSTACanBeSetOnTestFixture() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.STA)); } } [TestFixture, RequiresMTA] class FixtureRequiresMTA { [Test] public void RequiresMTACanBeSetOnTestFixture() { Assert.That(Thread.CurrentThread.ApartmentState, Is.EqualTo(ApartmentState.MTA)); } } [TestFixture, RequiresThread] class FixtureRequiresThread { [Test] public void RequiresThreadCanBeSetOnTestFixture() { Assert.That(Environment.StackTrace, Text.Contains("TestThread.RunTestProc")); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AttributeInheritance.cs0000664000175000017500000000346211504175260023430 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Builders; namespace NUnit.Core.Tests { [TestFixture] public class AttributeInheritance { NUnitTestFixtureBuilder builder; [SetUp] public void CreateBuilder() { builder = new NUnitTestFixtureBuilder(); } [Test] public void InheritedFixtureAttributeIsRecognized() { Assert.That( builder.CanBuildFrom( typeof (TestData.When_collecting_test_fixtures) ) ); } [Test] public void InheritedTestAttributeIsRecognized() { Test fixture = builder.BuildFrom( typeof( TestData.When_collecting_test_fixtures ) ); Assert.AreEqual( 1, fixture.TestCount ); } [Test] public void InheritedExplicitAttributeIsRecognized() { Test fixture = builder.BuildFrom(typeof(TestData.AttributeInheritanceFixture)); Test test = TestUtilities.TestFinder.Find("ShouldBeExplicit", fixture, false); Assert.That(test.RunState, Is.EqualTo(RunState.Explicit)); Assert.That(test.IgnoreReason, Is.EqualTo("Work in progress")); } [Test] public void InheritedIgnoreAttributeIsRecognized() { Test fixture = builder.BuildFrom(typeof(TestData.AttributeInheritanceFixture)); Test test = TestUtilities.TestFinder.Find("ShouldBeIgnored", fixture, false); Assert.That(test.RunState, Is.EqualTo(RunState.Ignored)); Assert.That(test.IgnoreReason, Is.EqualTo("Not yet implemented")); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/Generic/0000775000175000017500000000000011742560362020340 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/tests/Generic/SimpleGenericMethods.cs0000664000175000017500000000316511544454420024743 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; using NUnit.Framework; namespace NUnit.Core.Tests.Generic { [TestFixture,Category("Generics")] class SimpleGenericMethods { [TestCase(5, 2, "ABC")] [TestCase(5.0, 2.0, "ABC")] [TestCase(5, 2.0, "ABC")] [TestCase(5.0, 2L, "ABC")] public void GenericTestMethodWithOneTypeParameter(T x, T y, string label) { Assert.AreEqual(5, x); Assert.AreEqual(2, y); Assert.AreEqual("ABC", label); } [TestCase(5, 2, "ABC")] [TestCase(5.0, 2.0, "ABC")] [TestCase(5, 2.0, "ABC")] [TestCase(5.0, 2L, "ABC")] public void GenericTestMethodWithTwoTypeParameters(T1 x, T2 y, string label) { Assert.AreEqual(5, x); Assert.AreEqual(2, y); Assert.AreEqual("ABC", label); } [TestCase(5, 2, "ABC")] [TestCase(5.0, 2.0, "ABC")] [TestCase(5, 2.0, "ABC")] [TestCase(5.0, 2L, "ABC")] public void GenericTestMethodWithTwoTypeParameters_Reversed(T2 x, T1 y, string label) { Assert.AreEqual(5, x); Assert.AreEqual(2, y); Assert.AreEqual("ABC", label); } } } #endifNUnit-2.6.0.12051/src/NUnitCore/tests/Generic/DeduceTypeArgsFromArgs.cs0000664000175000017500000000150311544454420025174 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using NUnit.Framework; namespace NUnit.Core.Tests.Generic { [Category("Generics")] [TestFixture(100.0, 42)] [TestFixture(42, 100.0)] public class DeduceTypeArgsFromArgs { public DeduceTypeArgsFromArgs(T1 t1, T2 t2) { } [TestCase(5, 7)] public void TestMyArgTypes(T1 t1, T2 t2) { Assert.That(t1, Is.TypeOf()); Assert.That(t2, Is.TypeOf()); } } } #endif NUnit-2.6.0.12051/src/NUnitCore/tests/Generic/TypeParameterUsedWithTestMethod.cs0000664000175000017500000000127711544454420027133 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using NUnit.Framework; namespace NUnit.Core.Tests.Generic { [Category("Generics")] [TestFixture(typeof(double))] public class TypeParameterUsedWithTestMethod { [TestCase(5)] [TestCase(1.23)] public void TestMyArgType(T x) { Assert.That(x, Is.TypeOf(typeof(T))); } } } #endifNUnit-2.6.0.12051/src/NUnitCore/tests/Generic/SimpleGenericFixture.cs0000664000175000017500000000176211544454420024767 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections; using System.Collections.Generic; using System.Text; using NUnit.Framework; namespace NUnit.Core.Tests.Generic { [Category("Generics")] [TestFixture(typeof(List))] [TestFixture(TypeArgs=new Type[] {typeof(ArrayList)} )] public class SimpleGenericFixture where TList : IList, new() { [Test] public void TestCollectionCount() { Console.WriteLine("TList is {0}", typeof(TList)); IList list = new TList(); list.Add(1); list.Add(2); list.Add(3); Assert.AreEqual(3, list.Count); } } } #endifNUnit-2.6.0.12051/src/NUnitCore/tests/TestContextTests.cs0000664000175000017500000000746011720453244022625 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; using NUnit.TestData.TestContextData; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class TestContextTests { [Test] public void TestCanAccessItsOwnName() { Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("TestCanAccessItsOwnName")); } [Test] public void TestCanAccessItsOwnFullName() { Assert.That(TestContext.CurrentContext.Test.FullName, Is.EqualTo("NUnit.Core.Tests.TestContextTests.TestCanAccessItsOwnFullName")); } [Test] [Property("Answer", 42)] public void TestCanAccessItsOwnProperties() { Assert.That(TestContext.CurrentContext.Test.Properties["Answer"], Is.EqualTo(42)); } [Test] public void TestCanAccessTestDirectory() { string testDirectory = TestContext.CurrentContext.TestDirectory; Assert.NotNull(testDirectory); Assert.That(Directory.Exists(testDirectory)); Assert.That(File.Exists(Path.Combine(testDirectory, "nunit.core.tests.dll"))); } [Test] public void TestCanAccessWorkDirectory() { string workDirectory = TestContext.CurrentContext.WorkDirectory; Assert.NotNull(workDirectory); Assert.That(Directory.Exists(workDirectory), string.Format("Directory {0} does not exist", workDirectory)); } [Test] public void TestCanAccessTestState_PassingTest() { TestStateRecordingFixture fixture = new TestStateRecordingFixture(); TestBuilder.RunTestFixture(fixture); Assert.That(fixture.stateList, Is.EqualTo("Inconclusive=>Inconclusive=>Success")); Assert.That(fixture.statusList, Is.EqualTo("Inconclusive=>Inconclusive=>Passed")); } [Test] public void TestCanAccessTestState_FailureInSetUp() { TestStateRecordingFixture fixture = new TestStateRecordingFixture(); fixture.setUpFailure = true; TestBuilder.RunTestFixture(fixture); Assert.That(fixture.stateList, Is.EqualTo("Inconclusive=>=>Failure")); Assert.That(fixture.statusList, Is.EqualTo("Inconclusive=>=>Failed")); } [Test] public void TestCanAccessTestState_FailingTest() { TestStateRecordingFixture fixture = new TestStateRecordingFixture(); fixture.testFailure = true; TestBuilder.RunTestFixture(fixture); Assert.That(fixture.stateList, Is.EqualTo("Inconclusive=>Inconclusive=>Failure")); Assert.That(fixture.statusList, Is.EqualTo("Inconclusive=>Inconclusive=>Failed")); } [Test] public void TestCanAccessTestState_IgnoredInSetUp() { TestStateRecordingFixture fixture = new TestStateRecordingFixture(); fixture.setUpIgnore = true; TestBuilder.RunTestFixture(fixture); Assert.That(fixture.stateList, Is.EqualTo("Inconclusive=>=>Ignored")); Assert.That(fixture.statusList, Is.EqualTo("Inconclusive=>=>Skipped")); } [Test, RequiresThread] public void CanAccessTestContextOnSeparateThread() { Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("CanAccessTestContextOnSeparateThread")); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestMethodSignatureTests.cs0000664000175000017500000001574111504175260024303 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Util; using NUnit.TestUtilities; using NUnit.TestData; namespace NUnit.Core.Tests { [TestFixture] public class TestMethodSignatureTests { private static Type fixtureType = typeof(TestMethodSignatureFixture); private Test fixture; [SetUp] public void CreateFixture() { fixture = TestBuilder.MakeFixture( typeof( TestMethodSignatureFixture ) ); } [Test] public void InstanceTestMethodIsRunnable() { TestAssert.IsRunnable( fixtureType, "InstanceTestMethod" ); } [Test] public void StaticTestMethodIsRunnable() { TestAssert.IsRunnable( fixtureType, "StaticTestMethod" ); } [Test] public void TestMethodWithoutParametersWithArgumentsProvidedIsNotRunnable() { TestAssert.ChildNotRunnable(fixtureType, "TestMethodWithoutParametersWithArgumentsProvided"); } [Test] public void TestMethodWithArgumentsNotProvidedIsNotRunnable() { TestAssert.IsNotRunnable(fixtureType, "TestMethodWithArgumentsNotProvided"); } [Test] public void TestMethodWithArgumentsProvidedIsRunnable() { TestAssert.IsRunnable(fixtureType, "TestMethodWithArgumentsProvided"); } [Test] public void TestMethodWithWrongNumberOfArgumentsProvidedIsNotRunnable() { TestAssert.ChildNotRunnable(fixtureType, "TestMethodWithWrongNumberOfArgumentsProvided"); } [Test] public void TestMethodWithWrongArgumentTypesProvidedGivesError() { TestAssert.IsRunnable(fixtureType, "TestMethodWithWrongArgumentTypesProvided", ResultState.Error); } [Test] public void StaticTestMethodWithArgumentsNotProvidedIsNotRunnable() { TestAssert.IsNotRunnable(fixtureType, "StaticTestMethodWithArgumentsNotProvided"); } [Test] public void StaticTestMethodWithArgumentsProvidedIsRunnable() { TestAssert.IsRunnable(fixtureType, "StaticTestMethodWithArgumentsProvided"); } [Test] public void StaticTestMethodWithWrongNumberOfArgumentsProvidedIsNotRunnable() { TestAssert.ChildNotRunnable(fixtureType, "StaticTestMethodWithWrongNumberOfArgumentsProvided"); } [Test] public void StaticTestMethodWithWrongArgumentTypesProvidedGivesError() { TestAssert.IsRunnable(fixtureType, "StaticTestMethodWithWrongArgumentTypesProvided", ResultState.Error); } [Test] public void TestMethodWithConvertibleArgumentsIsRunnable() { TestAssert.IsRunnable(fixtureType, "TestMethodWithConvertibleArguments"); } [Test] public void TestMethodWithNonConvertibleArgumentsGivesError() { TestAssert.IsRunnable(fixtureType, "TestMethodWithNonConvertibleArguments", ResultState.Error); } [Test] public void ProtectedTestMethodIsNotRunnable() { TestAssert.IsNotRunnable( fixtureType, "ProtectedTestMethod" ); } [Test] public void PrivateTestMethodIsNotRunnable() { TestAssert.IsNotRunnable( fixtureType, "PrivateTestMethod" ); } [Test] public void TestMethodWithReturnTypeIsNotRunnable() { TestAssert.IsNotRunnable( fixtureType, "TestMethodWithReturnType" ); } [Test] public void TestMethodWithMultipleTestCasesExecutesMultipleTimes() { Test test = TestFinder.Find( "TestMethodWithMultipleTestCases", fixture, false ); Assert.That( test.RunState, Is.EqualTo( RunState.Runnable ) ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.That( result.ResultState, Is.EqualTo(ResultState.Success) ); ResultSummarizer summary = new ResultSummarizer(result); Assert.That(summary.TestsRun, Is.EqualTo(3)); } [Test] public void TestMethodWithMultipleTestCasesUsesCorrectNames() { string name = "TestMethodWithMultipleTestCases"; string fullName = typeof (TestMethodSignatureFixture).FullName + "." + name; TestSuite suite = (TestSuite)TestFinder.Find(name, fixture, false); Assert.That(suite.TestCount, Is.EqualTo(3)); ArrayList names = new ArrayList(); ArrayList fullNames = new ArrayList(); foreach (Test test in suite.Tests) { names.Add(test.TestName.Name); fullNames.Add(test.TestName.FullName); } Assert.That(names, Has.Member(name + "(12,3,4)")); Assert.That(names, Has.Member(name + "(12,2,6)")); Assert.That(names, Has.Member(name + "(12,4,3)")); Assert.That(fullNames, Has.Member(fullName + "(12,3,4)")); Assert.That(fullNames, Has.Member(fullName + "(12,2,6)")); Assert.That(fullNames, Has.Member(fullName + "(12,4,3)")); } [Test] public void TestMethodWithParamsArgumentIsRunnable() { TestAssert.IsRunnable(fixtureType, "TestMethodWithParamsArgument"); } // TODO: Make this work in a later release //[Test] public void TestMethodWithParamsArgumentUsesCorrectName() { string name = "TestMethodWithParamsArgument"; string fullName = typeof(TestMethodSignatureFixture).FullName + "." + name; TestSuite suite = (TestSuite)TestFinder.Find(name, fixture, false); Test test = suite.Tests[0] as Test; Assert.That(test.TestName.Name, Is.EqualTo(name + "(1, 2, 3)")); Assert.That(test.TestName.FullName, Is.EqualTo(fullName + "(1, 2, 3)")); } [Test] public void RunningTestsThroughFixtureGivesCorrectResults() { TestResult result = fixture.Run(NullListener.NULL, TestFilter.Empty); ResultSummarizer summary = new ResultSummarizer( result ); Assert.That( summary.ResultCount, Is.EqualTo( TestMethodSignatureFixture.Tests ) ); Assert.That( summary.TestsRun, Is.EqualTo( TestMethodSignatureFixture.Runnable ) ); Assert.That( summary.NotRunnable, Is.EqualTo( TestMethodSignatureFixture.NotRunnable ) ); Assert.That( summary.Errors, Is.EqualTo(TestMethodSignatureFixture.Errors)); Assert.That( summary.Failures, Is.EqualTo(TestMethodSignatureFixture.Failures)); Assert.That( summary.TestsNotRun, Is.EqualTo( TestMethodSignatureFixture.NotRunnable ) ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestFixtureTests.cs0000664000175000017500000003165511652213662022634 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Core; using NUnit.TestUtilities; using NUnit.TestData.TestFixtureData; namespace NUnit.Core.Tests { /// /// Tests of the NUnitTestFixture class /// [TestFixture] public class TestFixtureTests { [Test] public void ConstructFromType() { TestSuite fixture = TestBuilder.MakeFixture( typeof( NUnit.Tests.Assemblies.MockTestFixture ) ); Assert.AreEqual( "MockTestFixture", fixture.TestName.Name ); Assert.AreEqual( "NUnit.Tests.Assemblies.MockTestFixture", fixture.TestName.FullName ); } [Test] public void ConstructFromTypeWithoutNamespace() { TestSuite fixture = TestBuilder.MakeFixture( typeof( NoNamespaceTestFixture ) ); Assert.AreEqual( "NoNamespaceTestFixture", fixture.TestName.Name ); Assert.AreEqual( "NoNamespaceTestFixture", fixture.TestName.FullName ); } [Test] public void ConstructFromNestedType() { TestSuite fixture = TestBuilder.MakeFixture( typeof( OuterClass.NestedTestFixture ) ); Assert.AreEqual( "OuterClass+NestedTestFixture", fixture.TestName.Name ); Assert.AreEqual( "NUnit.TestData.TestFixtureData.OuterClass+NestedTestFixture", fixture.TestName.FullName ); } [Test] public void ConstructFromDoublyNestedType() { TestSuite fixture = TestBuilder.MakeFixture( typeof( OuterClass.NestedTestFixture.DoublyNestedTestFixture ) ); Assert.AreEqual( "OuterClass+NestedTestFixture+DoublyNestedTestFixture", fixture.TestName.Name ); Assert.AreEqual( "NUnit.TestData.TestFixtureData.OuterClass+NestedTestFixture+DoublyNestedTestFixture", fixture.TestName.FullName ); } [Test] public void ConstructFromTypeWithoutTestFixtureAttributeContainingTest() { TestSuite fixture = TestBuilder.MakeFixture(typeof(FixtureWithoutTestFixtureAttributeContainingTest)); Assert.NotNull(fixture, "Unable to construct fixture"); Assert.AreEqual("FixtureWithoutTestFixtureAttributeContainingTest", fixture.TestName.Name); Assert.AreEqual("NUnit.TestData.TestFixtureData.FixtureWithoutTestFixtureAttributeContainingTest", fixture.TestName.FullName); } [Test] public void ConstructFromTypeWithoutTestFixtureAttributeContainingTestCase() { TestSuite fixture = TestBuilder.MakeFixture(typeof(FixtureWithoutTestFixtureAttributeContainingTestCase)); Assert.NotNull(fixture, "Unable to construct fixture"); Assert.AreEqual("FixtureWithoutTestFixtureAttributeContainingTestCase", fixture.TestName.Name); Assert.AreEqual("NUnit.TestData.TestFixtureData.FixtureWithoutTestFixtureAttributeContainingTestCase", fixture.TestName.FullName); } [Test] public void ConstructFromTypeWithoutTestFixtureAttributeContainingTestCaseSource() { TestSuite fixture = TestBuilder.MakeFixture(typeof(FixtureWithoutTestFixtureAttributeContainingTestCaseSource)); Assert.NotNull(fixture, "Unable to construct fixture"); Assert.AreEqual("FixtureWithoutTestFixtureAttributeContainingTestCaseSource", fixture.TestName.Name); Assert.AreEqual("NUnit.TestData.TestFixtureData.FixtureWithoutTestFixtureAttributeContainingTestCaseSource", fixture.TestName.FullName); } [Test] public void ConstructFromTypeWithoutTestFixtureAttributeContainingTheory() { TestSuite fixture = TestBuilder.MakeFixture(typeof(FixtureWithoutTestFixtureAttributeContainingTheory)); Assert.NotNull(fixture, "Unable to construct fixture"); Assert.AreEqual("FixtureWithoutTestFixtureAttributeContainingTheory", fixture.TestName.Name); Assert.AreEqual("NUnit.TestData.TestFixtureData.FixtureWithoutTestFixtureAttributeContainingTheory", fixture.TestName.FullName); } [Test] public void CannotRunConstructorWithArgsNotSupplied() { TestAssert.IsNotRunnable(typeof(NoDefaultCtorFixture)); } [Test] public void CanRunConstructorWithArgsSupplied() { TestAssert.IsRunnable(typeof(FixtureWithArgsSupplied)); } [Test] public void CannotRunBadConstructor() { TestAssert.IsNotRunnable(typeof(BadCtorFixture)); } [Test] public void CanRunMultipleSetUp() { TestAssert.IsRunnable(typeof(MultipleSetUpAttributes)); } [Test] public void CanRunMultipleTearDown() { TestAssert.IsRunnable(typeof(MultipleTearDownAttributes)); } [Test] public void CannotRunIgnoredFixture() { TestSuite suite = TestBuilder.MakeFixture( typeof( IgnoredFixture ) ); Assert.AreEqual( RunState.Ignored, suite.RunState ); Assert.AreEqual( "testing ignore a fixture", suite.IgnoreReason ); } [Test] public void CanRunFixtureDerivedFromAbstractFixture() { TestAssert.IsRunnable(typeof(DerivedFromAbstractTestFixture)); } [Test] public void CanRunFixtureDerivedFromAbstractDerivedTestFixture() { TestAssert.IsRunnable(typeof(DerivedFromAbstractDerivedTestFixture)); } [Test] public void FixtureInheritingTwoTestFixtureAttributesIsLoadedOnlyOnce() { TestSuite suite = TestBuilder.MakeFixture(typeof(DoubleDerivedClassWithTwoInheritedAttributes)); Assert.That(suite, Is.TypeOf(typeof(NUnitTestFixture))); Assert.That(suite.Tests.Count, Is.EqualTo(0)); } [Test] public void CanRunMultipleTestFixtureSetUp() { TestAssert.IsRunnable(typeof(MultipleFixtureSetUpAttributes)); } [Test] public void CanRunMultipleTestFixtureTearDown() { TestAssert.IsRunnable(typeof(MultipleFixtureTearDownAttributes)); } #if CLR_2_0 || CLR_4_0 [Test] public void ConstructFromStaticTypeWithoutTestFixtureAttribute() { TestSuite fixture = TestBuilder.MakeFixture(typeof(StaticFixtureWithoutTestFixtureAttribute)); Assert.NotNull(fixture, "Unable to construct fixture"); Assert.AreEqual("StaticFixtureWithoutTestFixtureAttribute", fixture.TestName.Name); Assert.AreEqual("NUnit.TestData.TestFixtureData.StaticFixtureWithoutTestFixtureAttribute", fixture.TestName.FullName); } [Test] public void CanRunStaticFixture() { TestAssert.IsRunnable(typeof(StaticFixtureWithoutTestFixtureAttribute)); } [Test] public void CanRunGenericFixtureWithProperArgsProvided() { TestSuite suite = TestBuilder.MakeFixture( Type.GetType("NUnit.TestData.TestFixtureData.GenericFixtureWithProperArgsProvided`1,test-assembly")); Assert.That(suite.RunState, Is.EqualTo(RunState.Runnable)); Assert.That(suite is ParameterizedFixtureSuite); Assert.That(suite.Tests.Count, Is.EqualTo(2)); } [Test] public void CannotRunGenericFixtureWithNoTestFixtureAttribute() { TestAssert.IsNotRunnable( Type.GetType("NUnit.TestData.TestFixtureData.GenericFixtureWithNoTestFixtureAttribute`1,test-assembly")); } [Test] public void CannotRunGenericFixtureWithNoArgsProvided() { Test suite = TestBuilder.MakeFixture( Type.GetType("NUnit.TestData.TestFixtureData.GenericFixtureWithNoArgsProvided`1,test-assembly")); TestAssert.IsNotRunnable((Test)suite.Tests[0]); } [Test] public void CannotRunGenericFixtureDerivedFromAbstractFixtureWithNoArgsProvided() { Test suite = TestBuilder.MakeFixture( Type.GetType("NUnit.TestData.TestFixtureData.GenericFixtureDerivedFromAbstractFixtureWithNoArgsProvided`1,test-assembly")); TestAssert.IsNotRunnable((Test)suite.Tests[0]); } [Test] public void CanRunGenericFixtureDerivedFromAbstractFixtureWithArgsProvided() { Test suite = TestBuilder.MakeFixture( Type.GetType("NUnit.TestData.TestFixtureData.GenericFixtureDerivedFromAbstractFixtureWithArgsProvided`1,test-assembly")); Assert.That(suite.RunState, Is.EqualTo(RunState.Runnable)); Assert.That(suite is ParameterizedFixtureSuite); Assert.That(suite.Tests.Count, Is.EqualTo(2)); } #endif #region SetUp Signature [Test] public void CannotRunPrivateSetUp() { TestAssert.IsNotRunnable(typeof(PrivateSetUp)); } [Test] public void CanRunProtectedSetUp() { TestAssert.IsRunnable(typeof(ProtectedSetUp)); } /// /// Determines whether this instance [can run static set up]. /// [Test] public void CanRunStaticSetUp() { TestAssert.IsRunnable(typeof(StaticSetUp)); } [Test] public void CannotRunSetupWithReturnValue() { TestAssert.IsNotRunnable(typeof(SetUpWithReturnValue)); } [Test] public void CannotRunSetupWithParameters() { TestAssert.IsNotRunnable(typeof(SetUpWithParameters)); } #endregion #region TearDown Signature [Test] public void CannotRunPrivateTearDown() { TestAssert.IsNotRunnable(typeof(PrivateTearDown)); } [Test] public void CanRunProtectedTearDown() { TestAssert.IsRunnable(typeof(ProtectedTearDown)); } [Test] public void CanRunStaticTearDown() { TestAssert.IsRunnable(typeof(StaticTearDown)); } [Test] public void CannotRunTearDownWithReturnValue() { TestAssert.IsNotRunnable(typeof(TearDownWithReturnValue)); } [Test] public void CannotRunTearDownWithParameters() { TestAssert.IsNotRunnable(typeof(TearDownWithParameters)); } #endregion #region TestFixtureSetUp Signature [Test] public void CannotRunPrivateFixtureSetUp() { TestAssert.IsNotRunnable(typeof(PrivateFixtureSetUp)); } [Test] public void CanRunProtectedFixtureSetUp() { TestAssert.IsRunnable(typeof(ProtectedFixtureSetUp)); } [Test] public void CanRunStaticFixtureSetUp() { TestAssert.IsRunnable(typeof(StaticFixtureSetUp)); } [Test] public void CannotRunFixtureSetupWithReturnValue() { TestAssert.IsNotRunnable(typeof(FixtureSetUpWithReturnValue)); } [Test] public void CannotRunFixtureSetupWithParameters() { TestAssert.IsNotRunnable(typeof(FixtureSetUpWithParameters)); } #endregion #region TestFixtureTearDown Signature [Test] public void CannotRunPrivateFixtureTearDown() { TestAssert.IsNotRunnable(typeof(PrivateFixtureTearDown)); } [Test] public void CanRunProtectedFixtureTearDown() { TestAssert.IsRunnable(typeof(ProtectedFixtureTearDown)); } [Test] public void CanRunStaticFixtureTearDown() { TestAssert.IsRunnable(typeof(StaticFixtureTearDown)); } // [TestFixture] // [Category("fixture category")] // [Category("second")] // private class HasCategories // { // [Test] public void OneTest() // {} // } // // [Test] // public void LoadCategories() // { // TestSuite fixture = LoadFixture("NUnit.Core.Tests.TestFixtureBuilderTests+HasCategories"); // Assert.IsNotNull(fixture); // Assert.AreEqual(2, fixture.Categories.Count); // } [Test] public void CannotRunFixtureTearDownWithReturnValue() { TestAssert.IsNotRunnable(typeof(FixtureTearDownWithReturnValue)); } [Test] public void CannotRunFixtureTearDownWithParameters() { TestAssert.IsNotRunnable(typeof(FixtureTearDownWithParameters)); } #endregion #region Nested Fixtures [TestFixture] private class PrivateTestFixture { [Test] public void CanRunTestInPrivateTestFixture() { Assert.True(true); } } [TestFixture] protected class ProtectedTestFixture { [Test] public void CanRunTestInProtectedTestFixture() { Assert.True(true); } } [TestFixture] internal class InternalTestFixture { [Test] public void CanRunTestInInternalTestFixture() { Assert.True(true); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/tests/SimpleNameFilterTests.cs0000664000175000017500000001304711537111504023533 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Tests.Assemblies; using NUnit.Core.Builders; using NUnit.Core.Filters; using NUnit.Tests.Singletons; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class SimpleNameFilterTests { private TestSuite testSuite; private Test mock3; [SetUp] public void SetUp() { testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(TestBuilder.MakeFixture(typeof(MockTestFixture))); mock3 = TestFinder.Find("MockTest3", testSuite, true); } [Test] public void SingleNameMatch() { string fullName = "NUnit.Tests.Assemblies.MockTestFixture.MockTest3"; Assert.AreEqual(fullName, mock3.TestName.FullName); SimpleNameFilter filter = new SimpleNameFilter(fullName); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.AreEqual("NUnit.Tests.Assemblies.MockTestFixture", ((TestSuite)testSuite.Tests[0]).TestName.FullName); Assert.IsTrue(filter.Pass((TestSuite)testSuite.Tests[0]), "Name Filter did not pass test suite"); } [Test] public void MultipleNameMatch() { Test mock1 = TestFinder.Find("MockTest1", testSuite, true); SimpleNameFilter filter = new SimpleNameFilter(); filter.Add("NUnit.Tests.Assemblies.MockTestFixture.MockTest3"); filter.Add("NUnit.Tests.Assemblies.MockTestFixture.MockTest1"); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass(mock1), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass((TestSuite)testSuite.Tests[0]), "Name Filter did not pass test suite"); } [Test] public void SuiteNameMatch() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite)TestFinder.Find("MockTestFixture", testSuite, true); SimpleNameFilter filter = new SimpleNameFilter("NUnit.Tests.Assemblies.MockTestFixture"); Assert.IsTrue(filter.Pass(mock3), "Name Filter did not pass test case"); Assert.IsTrue(filter.Pass(mockTest), "Fixture did not pass test case"); Assert.IsTrue(filter.Pass(testSuite), "Suite did not pass test case"); } [Test] public void TestDoesNotMatch() { SimpleNameFilter filter = new SimpleNameFilter("NUnit.Tests.Assemblies.MockTestFixture.MockTest1"); Assert.IsFalse(filter.Pass(mock3), "Name Filter did pass test case"); Assert.IsTrue(filter.Pass(testSuite), "Name Filter did not pass test suite"); } [Test] public void HighLevelSuite() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite)TestFinder.Find("MockTestFixture", testSuite, true); SimpleNameFilter filter = new SimpleNameFilter("NUnit.Tests.Assemblies.MockTestFixture"); Assert.AreEqual(true, filter.Pass(mock3), "test case"); Assert.AreEqual(true, filter.Pass(mockTest), "fixture"); Assert.AreEqual(true, filter.Pass(testSuite), "test suite"); } [Test] public void ExplicitTestCaseDoesNotMatchWhenNotSelectedDirectly() { Test explicitTest = TestFinder.Find("ExplicitlyRunTest", testSuite, true); SimpleNameFilter filter = new SimpleNameFilter("Mock Test Suite"); Assert.AreEqual(false, filter.Pass(explicitTest)); } [Test] public void ExplicitTestCaseMatchesWhenSelectedDirectly() { Test explicitTest = TestFinder.Find("ExplicitlyRunTest", testSuite, true); SimpleNameFilter filter = new SimpleNameFilter("NUnit.Tests.Assemblies.MockTestFixture.ExplicitlyRunTest"); Assert.IsTrue(filter.Pass(explicitTest), "Name Filter did not pass on test case"); Assert.IsTrue(filter.Pass(testSuite), "Name Filter did not pass on test suite"); } [Test] public void ExplicitTestSuiteDoesNotMatchWhenNotSelectedDirectly() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite)TestFinder.Find("MockTestFixture", testSuite, true); mockTest.RunState = RunState.Explicit; SimpleNameFilter filter = new SimpleNameFilter("Mock Test Suite"); Assert.AreEqual(false, filter.Pass(mock3), "descendant of explicit suite should not match"); Assert.AreEqual(false, filter.Pass(mockTest), "explicit suite should not match"); } [Test] public void ExplicitTestSuiteMatchesWhenSelectedDirectly() { NUnit.Core.TestSuite mockTest = (NUnit.Core.TestSuite)TestFinder.Find("MockTestFixture", testSuite, true); mockTest.RunState = RunState.Explicit; SimpleNameFilter filter = new SimpleNameFilter("NUnit.Tests.Assemblies.MockTestFixture"); Assert.AreEqual(true, filter.Pass(mock3), "test case"); Assert.AreEqual(true, filter.Pass(mockTest), "middle suite"); Assert.AreEqual(true, filter.Pass(testSuite), "test suite"); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestExecutionContextTests.cs0000664000175000017500000001420211650462712024503 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Security.Principal; using System.Threading; using System.Globalization; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// Summary description for TestExecutionContextTests. /// [TestFixture] public class TestExecutionContextTests { string currentDirectory; CultureInfo currentCulture; CultureInfo currentUICulture; IPrincipal currentPrincipal; /// /// Since we are testing the mechanism that saves and /// restores contexts, we save manually here /// [SetUp] public void SaveContext() { currentDirectory = Environment.CurrentDirectory; currentCulture = CultureInfo.CurrentCulture; currentUICulture = CultureInfo.CurrentUICulture; currentPrincipal = Thread.CurrentPrincipal; } [TearDown] public void RestoreContext() { Environment.CurrentDirectory = currentDirectory; Thread.CurrentThread.CurrentCulture = currentCulture; Thread.CurrentThread.CurrentUICulture = currentUICulture; Thread.CurrentPrincipal = currentPrincipal; } [Test] public void SetAndRestoreCurrentDirectory() { Assert.AreEqual(currentDirectory, TestExecutionContext.CurrentContext.CurrentDirectory, "Directory not in initial context"); TestExecutionContext.Save(); try { string otherDirectory = System.IO.Path.GetTempPath(); if (otherDirectory[otherDirectory.Length - 1] == System.IO.Path.DirectorySeparatorChar) otherDirectory = otherDirectory.Substring(0, otherDirectory.Length - 1); TestExecutionContext.CurrentContext.CurrentDirectory = otherDirectory; Assert.AreEqual(otherDirectory, Environment.CurrentDirectory, "Directory was not set"); Assert.AreEqual(otherDirectory, TestExecutionContext.CurrentContext.CurrentDirectory, "Directory not in new context"); } finally { TestExecutionContext.Restore(); } Assert.AreEqual( currentDirectory, Environment.CurrentDirectory, "Directory was not restored" ); Assert.AreEqual(currentDirectory, TestExecutionContext.CurrentContext.CurrentDirectory, "Directory not in final context"); } [Test] public void SetAndRestoreCurrentCulture() { Assert.AreEqual(currentCulture, TestExecutionContext.CurrentContext.CurrentCulture, "Culture not in initial context"); TestExecutionContext.Save(); try { CultureInfo otherCulture = new CultureInfo(currentCulture.Name == "fr-FR" ? "en-GB" : "fr-FR"); TestExecutionContext.CurrentContext.CurrentCulture = otherCulture; Assert.AreEqual(otherCulture, CultureInfo.CurrentCulture, "Culture was not set"); Assert.AreEqual(otherCulture, TestExecutionContext.CurrentContext.CurrentCulture, "Culture not in new context"); } finally { TestExecutionContext.Restore(); } Assert.AreEqual( currentCulture, CultureInfo.CurrentCulture, "Culture was not restored" ); Assert.AreEqual(currentCulture, TestExecutionContext.CurrentContext.CurrentCulture, "Culture not in final context"); } [Test] public void SetAndRestoreCurrentUICulture() { Assert.AreEqual(currentUICulture, TestExecutionContext.CurrentContext.CurrentUICulture, "UICulture not in initial context"); TestExecutionContext.Save(); try { CultureInfo otherCulture = new CultureInfo(currentUICulture.Name == "fr-FR" ? "en-GB" : "fr-FR"); TestExecutionContext.CurrentContext.CurrentUICulture = otherCulture; Assert.AreEqual(otherCulture, CultureInfo.CurrentUICulture, "UICulture was not set"); Assert.AreEqual(otherCulture, TestExecutionContext.CurrentContext.CurrentUICulture, "UICulture not in new context"); } finally { TestExecutionContext.Restore(); } Assert.AreEqual(currentUICulture, CultureInfo.CurrentUICulture, "UICulture was not restored"); Assert.AreEqual(currentUICulture, TestExecutionContext.CurrentContext.CurrentUICulture, "UICulture not in final context"); } [Test] public void SetAndRestoreCurrentPrincipal() { Assert.AreEqual(currentPrincipal, TestExecutionContext.CurrentContext.CurrentPrincipal, "Principal not in initial context"); TestExecutionContext.Save(); try { GenericIdentity identity = new GenericIdentity("foo"); TestExecutionContext.CurrentContext.CurrentPrincipal = new GenericPrincipal(identity, new string[0]); Assert.AreEqual("foo", Thread.CurrentPrincipal.Identity.Name, "Principal was not set"); Assert.AreEqual("foo", TestExecutionContext.CurrentContext.CurrentPrincipal.Identity.Name, "Principal not in new context"); } finally { TestExecutionContext.Restore(); } Assert.AreEqual(currentPrincipal, Thread.CurrentPrincipal, "Principal was not restored"); Assert.AreEqual(currentPrincipal, TestExecutionContext.CurrentContext.CurrentPrincipal, "Principal not in final context"); } [Test, Explicit("Run this test manually with PrincipalPolicy set to WindowsPrincipal in the advanced loader settings")] public void CanSetPrincipalPolicy() { Assert.That(Thread.CurrentPrincipal is WindowsPrincipal); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AttributeDescriptionFixture.cs0000664000175000017500000000650011504175260025025 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using System.Collections; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.TestUtilities; using NUnit.TestData.AttributeDescriptionFixture; namespace NUnit.Core.Tests { // TODO: Review to see if we need these tests [TestFixture] public class TestAttributeFixture { static readonly Type FixtureType = typeof( MockFixture ); [Test] public void ReflectionTest() { Test testCase = TestBuilder.MakeTestCase( FixtureType, "Method" ); Assert.AreEqual( RunState.Runnable, testCase.RunState ); } [Test] public void Description() { Test testCase = TestBuilder.MakeTestCase(FixtureType, "Method"); Assert.AreEqual("Test Description", testCase.Description); } [Test] public void DescriptionInResult() { TestSuite suite = new TestSuite("Mock Fixture"); suite.Add(TestBuilder.MakeFixture(typeof(MockFixture))); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); TestResult caseResult = TestFinder.Find("Method", result, true); Assert.AreEqual("Test Description", caseResult.Description); caseResult = TestFinder.Find("NoDescriptionMethod", result, true); Assert.IsNull(caseResult.Description); } [Test] public void NoDescription() { Test testCase = TestBuilder.MakeTestCase( FixtureType, "NoDescriptionMethod" ); Assert.IsNull(testCase.Description); } [Test] public void FixtureDescription() { TestSuite suite = new TestSuite("suite"); suite.Add( TestBuilder.MakeFixture( typeof( MockFixture ) ) ); IList tests = suite.Tests; TestSuite mockFixtureSuite = (TestSuite)tests[0]; Assert.AreEqual("Fixture Description", mockFixtureSuite.Description); } [Test] public void FixtureDescriptionInResult() { TestSuite suite = new TestSuite("Mock Fixture"); suite.Add( TestBuilder.MakeFixture( typeof( MockFixture ) ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); TestResult fixtureResult = TestFinder.Find("MockFixture", result, true); Assert.AreEqual("Fixture Description", fixtureResult.Description); } [Test] public void SeparateDescriptionAttribute() { Test testCase = TestBuilder.MakeTestCase(FixtureType, "SeparateDescriptionMethod"); Assert.AreEqual("Separate Description", testCase.Description); } [Test] public void SeparateDescriptionInResult() { TestSuite suite = new TestSuite("Mock Fixture"); suite.Add(TestBuilder.MakeFixture(typeof(MockFixture))); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); TestResult caseResult = TestFinder.Find("SeparateDescriptionMethod", result, true); Assert.AreEqual("Separate Description", caseResult.Description); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ExpectExceptionTest.cs0000664000175000017500000004310411652020542023253 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Runtime.Serialization; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData.ExpectExceptionTest; namespace NUnit.Core.Tests { /// /// /// [TestFixture] public class ExpectExceptionTest { [Test, ExpectedException] public void CanExpectUnspecifiedException() { throw new ArgumentException(); } [Test] [ExpectedException(typeof(ArgumentException))] public void TestSucceedsWithSpecifiedExceptionType() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException(ExpectedException=typeof(ArgumentException))] public void TestSucceedsWithSpecifiedExceptionTypeAsNamedParameter() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException("System.ArgumentException")] public void TestSucceedsWithSpecifiedExceptionName() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException(ExpectedExceptionName="System.ArgumentException")] public void TestSucceedsWithSpecifiedExceptionNameAsNamedParameter() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException(typeof(ArgumentException),ExpectedMessage="argument exception")] public void TestSucceedsWithSpecifiedExceptionTypeAndMessage() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage="argument exception", MatchType=MessageMatch.Exact)] public void TestSucceedsWithSpecifiedExceptionTypeAndExactMatch() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException(typeof(ArgumentException),ExpectedMessage="invalid", MatchType=MessageMatch.Contains)] public void TestSucceedsWithSpecifiedExceptionTypeAndContainsMatch() { throw new ArgumentException("argument invalid exception"); } [Test] [ExpectedException(typeof(ArgumentException),ExpectedMessage="exception$", MatchType=MessageMatch.Regex)] public void TestSucceedsWithSpecifiedExceptionTypeAndRegexMatch() { throw new ArgumentException("argument invalid exception"); } [Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "argument invalid", MatchType = MessageMatch.StartsWith)] public void TestSucceedsWithSpecifiedExceptionTypeAndStartsWithMatch() { throw new ArgumentException("argument invalid exception"); } // [Test] // [ExpectedException("System.ArgumentException", "argument exception")] // public void TestSucceedsWithSpecifiedExceptionNameAndMessage_OldFormat() // { // throw new ArgumentException("argument exception"); // } [Test] [ExpectedException("System.ArgumentException", ExpectedMessage = "argument exception")] public void TestSucceedsWithSpecifiedExceptionNameAndMessage_NewFormat() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException("System.ArgumentException",ExpectedMessage="argument exception",MatchType=MessageMatch.Exact)] public void TestSucceedsWithSpecifiedExceptionNameAndExactMatch() { throw new ArgumentException("argument exception"); } [Test] [ExpectedException("System.ArgumentException",ExpectedMessage="invalid", MatchType=MessageMatch.Contains)] public void TestSucceedsWhenSpecifiedExceptionNameAndContainsMatch() { throw new ArgumentException("argument invalid exception"); } [Test] [ExpectedException("System.ArgumentException",ExpectedMessage="exception$", MatchType=MessageMatch.Regex)] public void TestSucceedsWhenSpecifiedExceptionNameAndRegexMatch() { throw new ArgumentException("argument invalid exception"); } [Test] public void TestFailsWhenBaseExceptionIsThrown() { Type fixtureType = typeof(BaseException); Test test = TestBuilder.MakeTestCase( fixtureType, "BaseExceptionTest" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "BaseExceptionTest should have failed"); StringAssert.StartsWith( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.Exception", result.Message); } [Test] public void TestFailsWhenDerivedExceptionIsThrown() { Type fixtureType = typeof(DerivedException); Test test = TestBuilder.MakeTestCase( fixtureType, "DerivedExceptionTest" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "DerivedExceptionTest should have failed"); StringAssert.StartsWith( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.Exception" + Environment.NewLine + " but was: System.ArgumentException", result.Message); } [Test] public void TestMismatchedExceptionType() { Type fixtureType = typeof(MismatchedException); Test test = TestBuilder.MakeTestCase(fixtureType, "MismatchedExceptionType"); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "MismatchedExceptionType should have failed"); StringAssert.StartsWith( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.ArgumentOutOfRangeException", result.Message); } [Test] public void TestMismatchedExceptionTypeAsNamedParameter() { Type fixtureType = typeof(MismatchedException); Test test = TestBuilder.MakeTestCase(fixtureType, "MismatchedExceptionTypeAsNamedParameter"); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "MismatchedExceptionType should have failed"); StringAssert.StartsWith( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.ArgumentOutOfRangeException", result.Message); } [Test] public void TestMismatchedExceptionTypeWithUserMessage() { Type fixtureType = typeof(MismatchedException); Test test = TestBuilder.MakeTestCase( fixtureType, "MismatchedExceptionTypeWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); StringAssert.StartsWith( "custom message" + Environment.NewLine + "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.ArgumentOutOfRangeException", result.Message); } [Test] public void TestMismatchedExceptionName() { Type fixtureType = typeof(MismatchedException); Test test = TestBuilder.MakeTestCase( fixtureType, "MismatchedExceptionName" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "MismatchedExceptionName should have failed"); StringAssert.StartsWith( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.ArgumentOutOfRangeException", result.Message); } [Test] public void TestMismatchedExceptionNameWithUserMessage() { Type fixtureType = typeof(MismatchedException); Test test = TestBuilder.MakeTestCase( fixtureType, "MismatchedExceptionNameWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); StringAssert.StartsWith( "custom message" + Environment.NewLine + "An unexpected exception type was thrown" + Environment.NewLine + "Expected: System.ArgumentException" + Environment.NewLine + " but was: System.ArgumentOutOfRangeException", result.Message); } [Test] public void TestMismatchedExceptionMessage() { Type fixtureType = typeof(TestThrowsExceptionWithWrongMessage); Test test = TestBuilder.MakeTestCase( fixtureType, "TestThrow" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "TestThrow should have failed"); Assert.AreEqual( "The exception message text was incorrect" + Environment.NewLine + "Expected: not the message" + Environment.NewLine + " but was: the message", result.Message); } [Test] public void TestMismatchedExceptionMessageWithUserMessage() { Type fixtureType = typeof(TestThrowsExceptionWithWrongMessage); Test test = TestBuilder.MakeTestCase( fixtureType, "TestThrowWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "TestThrow should have failed"); Assert.AreEqual( "custom message" + Environment.NewLine + "The exception message text was incorrect" + Environment.NewLine + "Expected: not the message" + Environment.NewLine + " but was: the message", result.Message); } [Test] public void TestUnspecifiedExceptionNotThrown() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowUnspecifiedException" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("An Exception was expected", result.Message); } [Test] public void TestUnspecifiedExceptionNotThrownWithUserMessage() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowUnspecifiedExceptionWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("custom message" + Environment.NewLine + "An Exception was expected", result.Message); } [Test] public void TestExceptionTypeNotThrown() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowExceptionType" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("System.ArgumentException was expected", result.Message); } [Test] public void TestExceptionTypeNotThrownWithUserMessage() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowExceptionTypeWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("custom message" + Environment.NewLine + "System.ArgumentException was expected", result.Message); } [Test] public void TestExceptionNameNotThrown() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowExceptionName" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("System.ArgumentException was expected", result.Message); } [Test] public void TestExceptionNameNotThrownWithUserMessage() { Type fixtureType = typeof(TestDoesNotThrowExceptionFixture); Test test = TestBuilder.MakeTestCase( fixtureType, "TestDoesNotThrowExceptionNameWithUserMessage" ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsFailure, "Test method should have failed"); Assert.AreEqual("custom message" + Environment.NewLine + "System.ArgumentException was expected", result.Message); } [Test] public void MethodThrowsException() { TestResult result = TestBuilder.RunTestFixture( typeof( TestThrowsExceptionFixture ) ); Assert.AreEqual(true, result.IsFailure); } [Test] public void MethodThrowsRightExceptionMessage() { TestResult result = TestBuilder.RunTestFixture( typeof( TestThrowsExceptionWithRightMessage ) ); Assert.AreEqual(true, result.IsSuccess); } [Test] public void MethodThrowsArgumentOutOfRange() { TestResult result = TestBuilder.RunTestFixture( typeof( TestThrowsArgumentOutOfRangeException ) ); Assert.AreEqual(true, result.IsSuccess ); } [Test] public void MethodThrowsWrongExceptionMessage() { TestResult result = TestBuilder.RunTestFixture( typeof( TestThrowsExceptionWithWrongMessage ) ); Assert.AreEqual(true, result.IsFailure); } [Test] public void SetUpThrowsSameException() { TestResult result = TestBuilder.RunTestFixture( typeof( SetUpExceptionTests ) ); Assert.AreEqual(true, result.IsFailure); } [Test] public void TearDownThrowsSameException() { TestResult result = TestBuilder.RunTestFixture( typeof( TearDownExceptionTests ) ); Assert.AreEqual(true, result.IsFailure); } [Test] public void AssertFailBeforeException() { TestResult suiteResult = TestBuilder.RunTestFixture( typeof (TestAssertsBeforeThrowingException) ); Assert.AreEqual( ResultState.Failure, suiteResult.ResultState ); TestResult result = (TestResult)suiteResult.Results[0]; Assert.AreEqual( "private message", result.Message ); } internal class MyAppException : System.Exception { public MyAppException (string message) : base(message) {} public MyAppException(string message, Exception inner) : base(message, inner) {} protected MyAppException(SerializationInfo info, StreamingContext context) : base(info,context) {} } [Test] [ExpectedException(typeof(MyAppException))] public void ThrowingMyAppException() { throw new MyAppException("my app"); } [Test] [ExpectedException(typeof(MyAppException), ExpectedMessage="my app")] public void ThrowingMyAppExceptionWithMessage() { throw new MyAppException("my app"); } [Test] [ExpectedException(typeof(NUnitException))] public void ThrowNUnitException() { throw new NUnitException("Nunit exception"); } [Test] public void ExceptionHandlerIsCalledWhenExceptionMatches_AlternateHandler() { ExceptionHandlerCalledClass fixture = new ExceptionHandlerCalledClass(); Test test = TestBuilder.MakeTestCase( fixture, "ThrowsArgumentException_AlternateHandler" ); test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse(fixture.HandlerCalled, "Base Handler should not be called" ); Assert.IsTrue(fixture.AlternateHandlerCalled, "Alternate Handler should be called" ); } [Test] public void ExceptionHandlerIsCalledWhenExceptionMatches() { ExceptionHandlerCalledClass fixture = new ExceptionHandlerCalledClass(); Test test = TestBuilder.MakeTestCase( fixture, "ThrowsArgumentException" ); test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(fixture.HandlerCalled, "Base Handler should be called"); Assert.IsFalse(fixture.AlternateHandlerCalled, "Alternate Handler should not be called"); } [Test] public void ExceptionHandlerIsNotCalledWhenExceptionDoesNotMatch() { ExceptionHandlerCalledClass fixture = new ExceptionHandlerCalledClass(); Test test = TestBuilder.MakeTestCase( fixture, "ThrowsApplicationException" ); test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse( fixture.HandlerCalled, "Base Handler should not be called" ); Assert.IsFalse( fixture.AlternateHandlerCalled, "Alternate Handler should not be called" ); } [Test] public void ExceptionHandlerIsNotCalledWhenExceptionDoesNotMatch_AlternateHandler() { ExceptionHandlerCalledClass fixture = new ExceptionHandlerCalledClass(); Test test = TestBuilder.MakeTestCase( fixture, "ThrowsApplicationException_AlternateHandler" ); test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse(fixture.HandlerCalled, "Base Handler should not be called"); Assert.IsFalse(fixture.AlternateHandlerCalled, "Alternate Handler should not be called"); } [Test] public void TestIsNotRunnableWhenAlternateHandlerIsNotFound() { ExceptionHandlerCalledClass fixture = new ExceptionHandlerCalledClass(); Test test = TestBuilder.MakeTestCase( fixture, "MethodWithBadHandler" ); Assert.AreEqual( RunState.NotRunnable, test.RunState ); Assert.AreEqual( "The specified exception handler DeliberatelyMissingHandler was not found", test.IgnoreReason ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/IgnoreFixture.cs0000664000175000017500000000750611655721126022115 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.TestUtilities; using NUnit.TestData.IgnoreFixture; namespace NUnit.Core.Tests { /// /// Tests of IgnoreException and Assert.Ignore /// [TestFixture] public class IgnoreFixture { [Test] public void IgnoreThrowsIgnoreException() { //Note that we can't use ExpectedException here because //Assert.Ignore takes precedence and the test is ignored. try { Assert.Ignore("I threw this!"); } catch(IgnoreException ex) { Assert.AreEqual("I threw this!", ex.Message); } } [Test] public void IgnoreWorksForTestCase() { Type fixtureType = typeof(IgnoredTestCaseFixture); Test test = TestBuilder.MakeTestCase(fixtureType, "CallsIgnore"); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse(result.Executed, "Test should not run"); Assert.AreEqual("Ignore me", result.Message); } [Test] public void IgnoreTakesPrecedenceOverExpectedException() { Type fixtureType = typeof(IgnoredTestCaseFixture); Test test = TestBuilder.MakeTestCase(fixtureType, "CallsIgnoreWithExpectedException"); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse(result.Executed, "Test should not run"); Assert.AreEqual("Ignore me", result.Message); } [Test] public void IgnoreWorksForTestSuite() { //IgnoredTestSuiteFixture testFixture = new IgnoredTestSuiteFixture(); TestSuite suite = new TestSuite("IgnoredTestFixture"); suite.Add( TestBuilder.MakeFixture( typeof( IgnoredTestSuiteFixture ) ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); TestResult fixtureResult = (TestResult)result.Results[0]; Assert.IsFalse( fixtureResult.Executed, "Fixture should not have been executed" ); foreach( TestResult testResult in fixtureResult.Results ) Assert.IsFalse( testResult.Executed, "Test case should not have been executed" ); } [Test] public void IgnoreWorksFromSetUp() { TestSuite testFixture = TestBuilder.MakeFixture( typeof( IgnoreInSetUpFixture ) ); TestResult fixtureResult = testFixture.Run(NullListener.NULL, TestFilter.Empty); foreach( TestResult testResult in fixtureResult.Results ) Assert.IsFalse( testResult.Executed, "Test case should not have been executed" ); } [Test] public void IgnoreWithUserMessage() { try { Assert.Ignore( "my message" ); } catch( IgnoreException ex ) { Assert.AreEqual( "my message", ex.Message ); } } [Test] public void IgnoreWithUserMessage_OneArg() { try { Assert.Ignore( "The number is {0}", 5 ); } catch( IgnoreException ex ) { Assert.AreEqual( "The number is 5", ex.Message ); } } [Test] public void IgnoreWithUserMessage_ThreeArgs() { try { Assert.Ignore( "The numbers are {0}, {1} and {2}", 1, 2, 3 ); } catch( IgnoreException ex ) { Assert.AreEqual( "The numbers are 1, 2 and 3", ex.Message ); } } [Test] public void IgnoreWithUserMessage_ArrayOfArgs() { try { Assert.Ignore( "The numbers are {0}, {1} and {2}", new object[] { 1, 2, 3 } ); } catch( IgnoreException ex ) { Assert.AreEqual( "The numbers are 1, 2 and 3", ex.Message ); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/DatapointTests.cs0000664000175000017500000000455711720453070022265 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using NUnit.Framework; using NUnit.TestData.DatapointFixture; using NUnit.TestUtilities; namespace NUnit.Core.Tests { public class DatapointTests { private void RunTestOnFixture(Type fixtureType) { TestResult result = TestBuilder.RunTestFixture(fixtureType); NUnit.Util.ResultSummarizer summary = new NUnit.Util.ResultSummarizer(result); Assert.That(summary.Passed, Is.EqualTo(2)); Assert.That(summary.Inconclusive, Is.EqualTo(3)); Assert.That(result.ResultState, Is.EqualTo(ResultState.Success)); } [Test] public void WorksOnField() { RunTestOnFixture(typeof(SquareRootTest_Field_Double)); } [Test] public void WorksOnArray() { RunTestOnFixture(typeof(SquareRootTest_Field_ArrayOfDouble)); } [Test] public void WorksOnPropertyReturningArray() { RunTestOnFixture(typeof(SquareRootTest_Property_ArrayOfDouble)); } [Test] public void WorksOnMethodReturningArray() { RunTestOnFixture(typeof(SquareRootTest_Method_ArrayOfDouble)); } #if CLR_2_0 || CLR_4_0 #if CS_3_0 || CS_4_0 [Test] public void WorksOnIEnumerableOfT() { RunTestOnFixture(typeof(SquareRootTest_Field_IEnumerableOfDouble)); } [Test] public void WorksOnPropertyReturningIEnumerableOfT() { RunTestOnFixture(typeof(SquareRootTest_Property_IEnumerableOfDouble)); } [Test] public void WorksOnMethodReturningIEnumerableOfT() { RunTestOnFixture(typeof(SquareRootTest_Method_IEnumerableOfDouble)); } [Test] public void WorksOnIteratorReturningIEnumerableOfT() { RunTestOnFixture(typeof(SquareRootTest_Iterator_IEnumerableOfDouble)); } #endif #endif } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestAssemblyBuilderTests.cs0000664000175000017500000000314011543055572024263 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; using NUnit.Core.Builders; namespace NUnit.Core.Tests { // It's no longer possible to load assemblies at a relative // location to the current directory. // TODO: Create other tests //[TestFixture] //public class TestAssemblyBuilderTests //{ // [Test] // public void CanLoadAssemblyInCurrentDirectory() // { // TestAssemblyBuilder builder = new TestAssemblyBuilder(); // Assert.IsNotNull( builder.Build( "mock-assembly.dll", false ) ); // } // [Test] // public void CanLoadAssemblyAtRelativeDirectoryLocation() // { // DirectoryInfo current = new DirectoryInfo( Environment.CurrentDirectory ); // string dir = current.Name; // string parentDir = current.Parent.FullName; // try // { // Environment.CurrentDirectory = parentDir; // TestAssemblyBuilder builder = new TestAssemblyBuilder(); // Assert.IsNotNull( builder.Build( dir + Path.DirectorySeparatorChar + "mock-assembly.dll", false ) ); // } // finally // { // Environment.CurrentDirectory = current.FullName; // } // } //} } NUnit-2.6.0.12051/src/NUnitCore/tests/TestCaseAttributeTests.cs0000664000175000017500000002664311676162570023755 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Util; using NUnit.TestData; using NUnit.TestUtilities; using System.Collections; namespace NUnit.Core.Tests { [TestFixture] public class TestCaseAttributeTests { [TestCase(12, 3, 4)] [TestCase(12, 2, 6)] [TestCase(12, 4, 3)] [TestCase(12, 0, 0, ExpectedException = typeof(System.DivideByZeroException))] [TestCase(12, 0, 0, ExpectedExceptionName = "System.DivideByZeroException")] public void IntegerDivisionWithResultPassedToTest(int n, int d, int q) { Assert.AreEqual(q, n / d); } [TestCase(12, 3, Result = 4)] [TestCase(12, 2, Result = 6)] [TestCase(12, 4, Result = 3)] [TestCase(12, 0, ExpectedException = typeof(System.DivideByZeroException))] [TestCase(12, 0, ExpectedExceptionName = "System.DivideByZeroException", TestName = "DivisionByZeroThrowsException")] public int IntegerDivisionWithResultCheckedByNUnit(int n, int d) { return n / d; } [TestCase(2, 2, Result=4)] public double CanConvertIntToDouble(double x, double y) { return x + y; } [TestCase("2.2", "3.3", Result = 5.5)] public decimal CanConvertStringToDecimal(decimal x, decimal y) { return x + y; } [TestCase(2.2, 3.3, Result = 5.5)] public decimal CanConvertDoubleToDecimal(decimal x, decimal y) { return x + y; } [TestCase(5, 2, Result = 7)] public decimal CanConvertIntToDecimal(decimal x, decimal y) { return x + y; } [TestCase(5, 2, Result = 7)] public short CanConvertSmallIntsToShort(short x, short y) { return (short)(x + y); } [TestCase(5, 2, Result = 7)] public byte CanConvertSmallIntsToByte(byte x, byte y) { return (byte)(x + y); } [TestCase(5, 2, Result = 7)] public sbyte CanConvertSmallIntsToSByte(sbyte x, sbyte y) { return (sbyte)(x + y); } #if CLR_2_0 || CLR_4_0 [TestCase(Result = null)] public object ExpectedResultCanBeNull() { return null; } #endif [Test] public void ConversionOverflowMakesTestNonRunnable() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodCausesConversionOverflow").Tests[0]; Assert.AreEqual(RunState.NotRunnable, test.RunState); } [TestCase("ABCD\u0019"), Explicit("For display purposes only")] public void UnicodeCharInStringArgument(string arg) { } [TestCase("12-October-1942")] public void CanConvertStringToDateTime(DateTime dt) { Assert.AreEqual(1942, dt.Year); } [TestCase(42, ExpectedException = typeof(System.Exception), ExpectedMessage = "Test Exception")] public void CanSpecifyExceptionMessage(int a) { throw new System.Exception("Test Exception"); } [TestCase(42, ExpectedException = typeof(System.Exception), ExpectedMessage = "Test Exception", MatchType=MessageMatch.StartsWith)] public void CanSpecifyExceptionMessageAndMatchType(int a) { throw new System.Exception("Test Exception thrown here"); } #if CLR_2_0 || CLR_4_0 [TestCase(null, null)] public void CanPassNullAsArgument(object a, string b) { Assert.IsNull(a); Assert.IsNull(b); } [TestCase(null)] public void CanPassNullAsSoleArgument(object a) { Assert.IsNull(a); } #endif [TestCase(new object[] { 1, "two", 3.0 })] [TestCase(new object[] { "zip" })] public void CanPassObjectArrayAsFirstArgument(object[] a) { } [TestCase(new object[] { "a", "b" })] public void CanPassArrayAsArgument(object[] array) { Assert.AreEqual("a", array[0]); Assert.AreEqual("b", array[1]); } [TestCase("a", "b")] public void ArgumentsAreCoalescedInObjectArray(object[] array) { Assert.AreEqual("a", array[0]); Assert.AreEqual("b", array[1]); } [TestCase(1, "b")] public void ArgumentsOfDifferentTypeAreCoalescedInObjectArray(object[] array) { Assert.AreEqual(1, array[0]); Assert.AreEqual("b", array[1]); } [TestCase("a", "b")] public void HandlesParamsArrayAsSoleArgument(params string[] array) { Assert.AreEqual("a", array[0]); Assert.AreEqual("b", array[1]); } [TestCase("a")] public void HandlesParamsArrayWithOneItemAsSoleArgument(params string[] array) { Assert.AreEqual("a", array[0]); } [TestCase("a", "b", "c", "d")] public void HandlesParamsArrayAsLastArgument(string s1, string s2, params object[] array) { Assert.AreEqual("a", s1); Assert.AreEqual("b", s2); Assert.AreEqual("c", array[0]); Assert.AreEqual("d", array[1]); } [TestCase("a", "b")] public void HandlesParamsArrayAsLastArgumentWithNoValues(string s1, string s2, params object[] array) { Assert.AreEqual("a", s1); Assert.AreEqual("b", s2); Assert.AreEqual(0, array.Length); } [TestCase("a", "b", "c")] public void HandlesParamsArrayWithOneItemAsLastArgument(string s1, string s2, params object[] array) { Assert.AreEqual("a", s1); Assert.AreEqual("b", s2); Assert.AreEqual("c", array[0]); } [Test] public void CanSpecifyDescription() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodHasDescriptionSpecified").Tests[0]; Assert.AreEqual("My Description", test.Description); } [Test] public void CanSpecifyTestName() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodHasTestNameSpecified").Tests[0]; Assert.AreEqual("XYZ", test.TestName.Name); Assert.AreEqual("NUnit.TestData.TestCaseAttributeFixture.XYZ", test.TestName.FullName); } [Test] public void CanSpecifyCategory() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodHasSingleCategory").Tests[0]; Assert.AreEqual(new string[] { "XYZ" }, test.Categories); } [Test] public void CanSpecifyMultipleCategories() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodHasMultipleCategories").Tests[0]; Assert.AreEqual(new string[] { "X", "Y", "Z" }, test.Categories); } [Test] public void CanSpecifyExpectedException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodThrowsExpectedException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Success, result.ResultState); } [Test] public void CanSpecifyExpectedException_WrongException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodThrowsWrongException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); StringAssert.StartsWith("An unexpected exception type was thrown", result.Message); } [Test] public void CanSpecifyExpectedException_WrongMessage() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodThrowsExpectedExceptionWithWrongMessage").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); StringAssert.StartsWith("The exception message text was incorrect", result.Message); } [Test] public void CanSpecifyExpectedException_NoneThrown() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodThrowsNoException").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Failure, result.ResultState); Assert.AreEqual("System.ArgumentNullException was expected", result.Message); } [Test] public void IgnoreTakesPrecedenceOverExpectedException() { Test test = (Test)TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodCallsIgnore").Tests[0]; TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual(ResultState.Ignored, result.ResultState); Assert.AreEqual("Ignore this", result.Message); } [Test] public void CanIgnoreIndividualTestCases() { Test test = TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodWithIgnoredTestCases"); Test testCase = TestFinder.Find("MethodWithIgnoredTestCases(1)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Runnable)); testCase = TestFinder.Find("MethodWithIgnoredTestCases(2)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Ignored)); testCase = TestFinder.Find("MethodWithIgnoredTestCases(3)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Ignored)); Assert.That(testCase.IgnoreReason, Is.EqualTo("Don't Run Me!")); } [Test] public void CanMarkIndividualTestCasesExplicit() { Test test = TestBuilder.MakeTestCase( typeof(TestCaseAttributeFixture), "MethodWithExplicitTestCases"); Test testCase = TestFinder.Find("MethodWithExplicitTestCases(1)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Runnable)); testCase = TestFinder.Find("MethodWithExplicitTestCases(2)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Explicit)); testCase = TestFinder.Find("MethodWithExplicitTestCases(3)", test, false); Assert.That(testCase.RunState, Is.EqualTo(RunState.Explicit)); Assert.That(testCase.IgnoreReason, Is.EqualTo("Connection failing")); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestCaseTest.cs0000664000175000017500000000341611504175260021665 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using NUnit.Framework; using NUnit.Tests.Assemblies; using NUnit.Util; using NUnit.TestUtilities; using NUnit.TestData.TestCaseTest; namespace NUnit.Core.Tests { /// /// Summary description for TestCaseTest. /// /// [TestFixture] public class TestCaseTest { [Test] public void CreateIgnoredTestCase() { Type fixtureType = typeof(MockTestFixture); Test testCase = TestBuilder.MakeTestCase( fixtureType, "MockTest4" ); Assert.AreEqual(1, testCase.TestCount); Assert.AreEqual( RunState.Ignored, testCase.RunState ); Assert.AreEqual("ignoring this test method for now", testCase.IgnoreReason); } [Test] public void RunIgnoredTestCase() { Type fixtureType = typeof(MockTestFixture); Test testCase = TestBuilder.MakeTestCase( fixtureType, "MockTest4" ); Assert.AreEqual(1, testCase.TestCount); TestResult result = testCase.Run(NullListener.NULL, TestFilter.Empty); ResultSummarizer summarizer = new ResultSummarizer(result); Assert.AreEqual(0, summarizer.TestsRun); Assert.AreEqual(1, summarizer.TestsNotRun); } [Test] public void LoadMethodCategories() { Type fixtureType = typeof(HasCategories); Test testCase = TestBuilder.MakeTestCase( fixtureType, "ATest" ); Assert.IsNotNull(testCase); Assert.IsNotNull(testCase.Categories); Assert.AreEqual(2, testCase.Categories.Count); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ActionAttributeTests.cs0000664000175000017500000001724211713202002023423 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** //#define DEFAULT_APPLIES_TO_TESTCASE #if CLR_2_0 || CLR_4_0 using System; using System.Collections; using System.Collections.Generic; using NUnit.Framework; using NUnit.TestData.ActionAttributeTests; namespace NUnit.Core.Tests { [TestFixture] public class ActionAttributeTests { private class ActionAttributeFixtureFilter : TestFilter { public override bool Match(ITest test) { return test.TestName.FullName.StartsWith(typeof(ActionAttributeFixture).FullName); } } private TestResult _result = null; private readonly string[] _suiteSites = new string[] { "Assembly", "BaseSetupFixture", "SetupFixture", "BaseInterface", "BaseFixture", "Interface", "Fixture" }; private readonly string[] _parameterizedTestOutput = new string[] { "SomeTest-Case1", "SomeTest-Case2" }; private readonly string[] _testOutput = new string[] { "SomeTestNotParameterized", }; [TestFixtureSetUp] public void Setup() { ActionAttributeFixture.Results = new List(); TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage(AssemblyHelper.GetAssemblyPath(typeof(ActionAttributeFixture))); package.TestName = typeof(ActionAttributeFixture).Namespace; Test suite = builder.Build(package); _result = suite.Run(new NullListener(), new ActionAttributeFixtureFilter()); } [Test] public void TestsRunsSuccessfully() { Assert.IsTrue(_result.IsSuccess, "Test run was not successful."); Console.WriteLine("{prefix}.{phase}.{hasFixture}.{hasMethod}"); foreach(string message in ActionAttributeFixture.Results) Console.WriteLine(message); } private void AssertResultEquals(List input, int index, string expected) { Assert.IsTrue(input[index].Equals(expected), string.Format("Did not find '{0}' at index {1}; instead '{2}'", expected, index, input[index])); } [Test] public void ExpectedOutput_InCorrectOrder() { string[] expectedResults = new string[] { "AssemblySuite.Before.false.false", "AssemblySite.Before.false.false", "BaseSetupFixtureSuite.Before.true.false", "BaseSetupFixtureSite.Before.true.false", "SetupFixtureSuite.Before.true.false", "SetupFixtureSite.Before.true.false", "BaseInterfaceSuite.Before.true.false", "BaseInterfaceSite.Before.true.false", "BaseFixtureSuite.Before.true.false", "BaseFixtureSite.Before.true.false", "InterfaceSuite.Before.true.false", "InterfaceSite.Before.true.false", "FixtureSuite.Before.true.false", "FixtureSite.Before.true.false", "ParameterizedSuite.Before.true.false", #if DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.Before.true.false", #endif "AssemblyTest.Before.true.true", "BaseSetupFixtureTest.Before.true.true", "SetupFixtureTest.Before.true.true", "BaseInterfaceTest.Before.true.true", "BaseFixtureTest.Before.true.true", "InterfaceTest.Before.true.true", "FixtureTest.Before.true.true", "ParameterizedTest.Before.true.true", #if !DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.Before.true.true", #endif "SomeTest", #if !DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.After.true.true", #endif "ParameterizedTest.After.true.true", "FixtureTest.After.true.true", "InterfaceTest.After.true.true", "BaseFixtureTest.After.true.true", "BaseInterfaceTest.After.true.true", "SetupFixtureTest.After.true.true", "BaseSetupFixtureTest.After.true.true", "AssemblyTest.After.true.true", "AssemblyTest.Before.true.true", "BaseSetupFixtureTest.Before.true.true", "SetupFixtureTest.Before.true.true", "BaseInterfaceTest.Before.true.true", "BaseFixtureTest.Before.true.true", "InterfaceTest.Before.true.true", "FixtureTest.Before.true.true", "ParameterizedTest.Before.true.true", #if !DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.Before.true.true", #endif "SomeTest", #if !DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.After.true.true", #endif "ParameterizedTest.After.true.true", "FixtureTest.After.true.true", "InterfaceTest.After.true.true", "BaseFixtureTest.After.true.true", "BaseInterfaceTest.After.true.true", "SetupFixtureTest.After.true.true", "BaseSetupFixtureTest.After.true.true", "AssemblyTest.After.true.true", #if DEFAULT_APPLIES_TO_TESTCASE "ParameterizedSite.After.true.false", #endif "ParameterizedSuite.After.true.false", "AssemblyTest.Before.true.true", "BaseSetupFixtureTest.Before.true.true", "SetupFixtureTest.Before.true.true", "BaseInterfaceTest.Before.true.true", "BaseFixtureTest.Before.true.true", "InterfaceTest.Before.true.true", "FixtureTest.Before.true.true", "MethodTest.Before.true.true", "MethodSite.Before.true.true", "SomeTestNotParameterized", "MethodSite.After.true.true", "MethodTest.After.true.true", "FixtureTest.After.true.true", "InterfaceTest.After.true.true", "BaseFixtureTest.After.true.true", "BaseInterfaceTest.After.true.true", "SetupFixtureTest.After.true.true", "BaseSetupFixtureTest.After.true.true", "AssemblyTest.After.true.true", "FixtureSite.After.true.false", "FixtureSuite.After.true.false", "InterfaceSite.After.true.false", "InterfaceSuite.After.true.false", "BaseFixtureSite.After.true.false", "BaseFixtureSuite.After.true.false", "BaseInterfaceSite.After.true.false", "BaseInterfaceSuite.After.true.false", "SetupFixtureSite.After.true.false", "SetupFixtureSuite.After.true.false", "BaseSetupFixtureSite.After.true.false", "BaseSetupFixtureSuite.After.true.false", "AssemblySite.After.false.false", "AssemblySuite.After.false.false" }; Assert.AreEqual(expectedResults, ActionAttributeFixture.Results); } } } #endifNUnit-2.6.0.12051/src/NUnitCore/tests/EventTestFixture.cs0000664000175000017500000000442311504175260022601 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Tests.Assemblies; namespace NUnit.Core.Tests { /// /// Summary description for EventTestFixture. /// /// [TestFixture(Description="Tests that proper events are generated when running test")] public class EventTestFixture { private string testsDll = MockAssembly.AssemblyPath; internal class EventCounter : EventListener { internal int runStarted = 0; internal int runFinished = 0; internal int testCaseStart = 0; internal int testCaseFinished = 0; internal int suiteStarted = 0; internal int suiteFinished = 0; public void RunStarted(string name, int testCount) { runStarted++; } public void RunFinished(NUnit.Core.TestResult result) { runFinished++; } public void RunFinished(Exception exception) { runFinished++; } public void TestStarted(TestName testName) { testCaseStart++; } public void TestFinished(TestResult result) { testCaseFinished++; } public void SuiteStarted(TestName suiteName) { suiteStarted++; } public void SuiteFinished(TestResult result) { suiteFinished++; } public void UnhandledException( Exception exception ) { } public void TestOutput(TestOutput testOutput) { } } [Test] public void CheckEventListening() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test testSuite = builder.Build( new TestPackage( testsDll ) ); EventCounter counter = new EventCounter(); testSuite.Run(counter, TestFilter.Empty); Assert.AreEqual(testSuite.CountTestCases(TestFilter.Empty), counter.testCaseStart); Assert.AreEqual(testSuite.CountTestCases(TestFilter.Empty), counter.testCaseFinished); Assert.AreEqual(MockAssembly.SuitesRun, counter.suiteStarted); Assert.AreEqual(MockAssembly.SuitesRun, counter.suiteFinished); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/nunit.core.tests.build0000664000175000017500000001315711532545536023244 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitCore/tests/TestCaseResultFixture.cs0000664000175000017500000000310311504175260023564 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core.Tests { using System; using NUnit.Framework; using NUnit.Core; using NUnit.TestUtilities; /// /// Summary description for TestResultTests. /// [TestFixture] public class TestCaseResultFixture { private TestResult caseResult; [SetUp] public void SetUp() { caseResult = new TestResult( new TestInfo(new NUnitTestMethod(Reflect.GetNamedMethod( this.GetType(), "DummyMethod" ) ) ) ); } public void DummyMethod() { } [Test] public void TestCaseDefault() { Assert.AreEqual( ResultState.Inconclusive, caseResult.ResultState ); } [Test] public void TestCaseSuccess() { caseResult.Success(); Assert.IsTrue(caseResult.IsSuccess, "result should be success"); } [Test] public void TestCaseNotRun() { caseResult.Ignore( "because" ); Assert.AreEqual( false, caseResult.Executed ); Assert.AreEqual( "because", caseResult.Message ); } [Test] public void TestCaseFailure() { caseResult.Failure("message", "stack trace"); Assert.IsTrue(caseResult.IsFailure); Assert.IsFalse(caseResult.IsSuccess); Assert.AreEqual("message",caseResult.Message); Assert.AreEqual("stack trace",caseResult.StackTrace); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TypeHelperTests.cs0000664000175000017500000000561311720453214022415 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using NUnit.Framework; using NUnit.TestData.TypeHelperFixture; namespace NUnit.Core.Tests { [TestFixture] public class TypeHelperTests { [TestCase(typeof(int), "Int32")] [TestCase(typeof(SimpleClass), "SimpleClass")] [TestCase(typeof(MyNoNamespaceClass), "MyNoNamespaceClass")] #if CLR_2_0 || CLR_4_0 [TestCase(typeof(GenericClass), "GenericClass")] [TestCase(typeof(GenericClass), "GenericClass")] [TestCase(typeof(ContainerClass.NestedClass), "ContainerClass+NestedClass")] [TestCase(typeof(ContainerClass.NestedClass.DoublyNestedClass), "ContainerClass+NestedClass+DoublyNestedClass")] [TestCase(typeof(ContainerClass.NestedClass.DoublyNestedGeneric), "ContainerClass+NestedClass+DoublyNestedGeneric")] [TestCase(typeof(ContainerClass.NestedGeneric), "ContainerClass+NestedGeneric")] [TestCase(typeof(ContainerClass.NestedGeneric.DoublyNestedClass), "ContainerClass+NestedGeneric+DoublyNestedClass")] [TestCase(typeof(ContainerClass.NestedGeneric.DoublyNestedGeneric), "ContainerClass+NestedGeneric+DoublyNestedGeneric")] [TestCase(typeof(GenericContainerClass.NestedClass), "GenericContainerClass+NestedClass")] [TestCase(typeof(GenericContainerClass.NestedClass.DoublyNestedClass), "GenericContainerClass+NestedClass+DoublyNestedClass")] [TestCase(typeof(GenericContainerClass.NestedClass.DoublyNestedGeneric), "GenericContainerClass+NestedClass+DoublyNestedGeneric")] [TestCase(typeof(GenericContainerClass.NestedGeneric), "GenericContainerClass+NestedGeneric")] [TestCase(typeof(GenericContainerClass.NestedGeneric.DoublyNestedClass), "GenericContainerClass+NestedGeneric+DoublyNestedClass")] [TestCase(typeof(GenericContainerClass.NestedGeneric.DoublyNestedGeneric), "GenericContainerClass+NestedGeneric+DoublyNestedGeneric")] [TestCase(typeof(ListTester>), "ListTester>")] [TestCase(typeof(ListTester>>), "ListTester>>")] #endif public void GetDisplayName(Type type, string name) { Assert.That(TypeHelper.GetDisplayName(type), Is.EqualTo(name)); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestNodeTests.cs0000664000175000017500000000474011504175260022063 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Tests.Assemblies; using NUnit.Core.Builders; using NUnit.TestUtilities; namespace NUnit.Core.Tests { /// /// TestNode construction tests. Does not repeat tests /// for the TestInfo base class. /// [TestFixture] public class TestNodeTests { TestSuite testSuite; TestSuite testFixture; Test testCase1; [SetUp] public void SetUp() { testSuite = new TestSuite("MyTestSuite"); testFixture = TestBuilder.MakeFixture( typeof( MockTestFixture ) ); testSuite.Add( testFixture ); testCase1 = (Test)testFixture.Tests[0]; } [Test] public void ConstructFromSuite() { TestNode test = new TestNode( testSuite ); Assert.IsNotNull( test.Tests ); Assert.AreEqual( test.TestCount, CountTests( test ) ); Assert.AreSame( test, ((TestNode)test.Tests[0]).Parent ); } private int CountTests( TestNode node ) { if ( !node.IsSuite ) return 1; int count = 0; if ( node.Tests != null ) foreach( TestNode child in node.Tests ) count += CountTests( child ); return count; } [Test] public void ConstructFromTestCase() { TestNode test = new TestNode( testCase1 ); Assert.IsNull( test.Tests ); } [Test] public void ConstructFromMultipleTests() { ITest[] tests = new ITest[testFixture.Tests.Count]; for( int index = 0; index < tests.Length; index++ ) tests[index] = (ITest)testFixture.Tests[index]; TestName testName = new TestName(); testName.FullName = testName.Name = "Combined"; testName.TestID = new TestID( 1000 ); TestNode test = new TestNode( testName, tests ); Assert.AreEqual( "Combined", test.TestName.Name ); Assert.AreEqual( "Combined", test.TestName.FullName ); Assert.AreEqual( RunState.Runnable, test.RunState ); Assert.IsTrue( test.IsSuite, "IsSuite" ); Assert.AreEqual( tests.Length, test.Tests.Count ); Assert.AreEqual( MockTestFixture.Tests, test.TestCount ); Assert.AreEqual( 0, test.Categories.Count, "Categories"); Assert.AreNotEqual( testFixture.TestName.Name, test.TestName.Name, "TestName" ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/nunit.core.tests.csproj0000664000175000017500000002505211707326342023436 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {DD758D21-E5D5-4D40-9450-5F65A32F359C} Debug AnyCPU nunit.core.tests JScript Grid IE50 false Library NUnit.Core.Tests OnBuildSuccess 2.0 http://localhost/nunit.core.tests/ true Web true Foreground 7 Days false false true 0 1.0.0.%2a true false true v3.5 ..\..\..\bin\Debug\tests\ 285212672 TRACE;DEBUG;CLR_2_0,NET_3_5,CS_3_0 true 4096 618 false false false 4 full prompt ..\..\..\bin\Release\tests\ 285212672 TRACE;CLR_2_0,NET_3_5,CS_3_0 4096 618 true false false 4 none prompt System 3.5 System.Data System.XML nunit.util.dll {61CE9CE5-943E-44D4-A381-814DC1406767} False nunit.framework.dll {83DD7E12-A705-4DBA-9D71-09C8973D9382} mock-assembly {2E368281-3BA8-4050-B05E-0E0E43F8F446} False nonamespace-assembly {5110F0D2-8E50-46F8-9E17-7C8EBFECCA9D} False test-assembly {1960CAC4-9A82-47C5-A9B3-55BC37572C3C} test-utilities {3E63AD0F-24D4-46BE-BEE4-5A3299847D86} nunit.core.dll {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} False nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False ..\..\..\lib\3.5\NSubstitute.dll CommonAssemblyInfo.cs False .NET Framework 2.0 %28x86%29 true False .NET Framework 3.0 %28x86%29 false False .NET Framework 3.5 false NUnit-2.6.0.12051/src/NUnitCore/tests/SetUpTest.cs0000664000175000017500000001277711504175260021224 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.TestUtilities; using NUnit.TestData.SetUpTest; namespace NUnit.Core.Tests { [TestFixture] public class SetUpTest { [Test] public void SetUpAndTearDownCounter() { SetUpAndTearDownCounterFixture fixture = new SetUpAndTearDownCounterFixture(); TestBuilder.RunTestFixture( fixture ); Assert.AreEqual(3, fixture.setUpCounter); Assert.AreEqual(3, fixture.tearDownCounter); } [Test] public void MakeSureSetUpAndTearDownAreCalled() { SetUpAndTearDownFixture fixture = new SetUpAndTearDownFixture(); TestBuilder.RunTestFixture( fixture ); Assert.IsTrue(fixture.wasSetUpCalled); Assert.IsTrue(fixture.wasTearDownCalled); } [Test] public void CheckInheritedSetUpAndTearDownAreCalled() { InheritSetUpAndTearDown fixture = new InheritSetUpAndTearDown(); TestBuilder.RunTestFixture( fixture ); Assert.IsTrue(fixture.wasSetUpCalled); Assert.IsTrue(fixture.wasTearDownCalled); } [Test] public void CheckOverriddenSetUpAndTearDownAreNotCalled() { DefineInheritSetUpAndTearDown fixture = new DefineInheritSetUpAndTearDown(); TestBuilder.RunTestFixture( fixture ); Assert.IsFalse(fixture.wasSetUpCalled); Assert.IsFalse(fixture.wasTearDownCalled); Assert.IsTrue(fixture.derivedSetUpCalled); Assert.IsTrue(fixture.derivedTearDownCalled); } [Test] public void MultipleSetUpAndTearDownMethodsAreCalled() { MultipleSetUpTearDownFixture fixture = new MultipleSetUpTearDownFixture(); TestBuilder.RunTestFixture(fixture); Assert.IsTrue(fixture.wasSetUp1Called, "SetUp1"); Assert.IsTrue(fixture.wasSetUp2Called, "SetUp2"); Assert.IsTrue(fixture.wasSetUp3Called, "SetUp3"); Assert.IsTrue(fixture.wasTearDown1Called, "TearDown1"); Assert.IsTrue(fixture.wasTearDown2Called, "TearDown2"); } [Test] public void BaseSetUpIsCalledFirstTearDownLast() { DerivedClassWithSeparateSetUp fixture = new DerivedClassWithSeparateSetUp(); TestBuilder.RunTestFixture(fixture); Assert.IsTrue(fixture.wasSetUpCalled, "Base SetUp Called"); Assert.IsTrue(fixture.wasTearDownCalled, "Base TearDown Called"); Assert.IsTrue(fixture.wasDerivedSetUpCalled, "Derived SetUp Called"); Assert.IsTrue(fixture.wasDerivedTearDownCalled, "Derived TearDown Called"); Assert.IsTrue(fixture.wasBaseSetUpCalledFirst, "SetUp Order"); Assert.IsTrue(fixture.wasBaseTearDownCalledLast, "TearDown Order"); } [Test] public void SetupRecordsOriginalExceptionThownByTestCase() { Exception e = new Exception("Test message for exception thrown from setup"); SetupAndTearDownExceptionFixture fixture = new SetupAndTearDownExceptionFixture(); fixture.setupException = e; TestResult result = TestBuilder.RunTestFixture(fixture); Assert.IsTrue(result.HasResults, "Fixture test should have child result."); result = (TestResult)result.Results[0]; Assert.AreEqual(result.ResultState, ResultState.Error, "Test should be in error state"); Assert.AreEqual(result.FailureSite, FailureSite.SetUp, "Test should be failed at setup site"); string expected = string.Format("SetUp : {0} : {1}", e.GetType().FullName, e.Message); Assert.AreEqual(expected, result.Message); } [Test] public void TearDownRecordsOriginalExceptionThownByTestCase() { Exception e = new Exception("Test message for exception thrown from tear down"); SetupAndTearDownExceptionFixture fixture = new SetupAndTearDownExceptionFixture(); fixture.tearDownException = e; TestResult result = TestBuilder.RunTestFixture(fixture); Assert.IsTrue(result.HasResults, "Fixture test should have child result."); result = (TestResult)result.Results[0]; Assert.AreEqual(result.ResultState, ResultState.Error, "Test should be in error state"); Assert.AreEqual(result.FailureSite, FailureSite.TearDown, "Test should be failed at tear down site"); string expected = string.Format("TearDown : {0} : {1}", e.GetType().FullName, e.Message); Assert.AreEqual(expected, result.Message); } public class SetupCallBase { protected int setupCount = 0; public virtual void Init() { setupCount++; } public virtual void AssertCount() { } } [TestFixture] // Test for bug 441022 public class SetupCallDerived : SetupCallBase { [SetUp] public override void Init() { setupCount++; base.Init(); } [Test] public override void AssertCount() { Assert.AreEqual(2, setupCount); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ReflectTests.cs0000664000175000017500000001230311504175260021714 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class ReflectTests { private readonly Type myType = typeof( Colors.MyClass ); private readonly BindingFlags BF = BindingFlags.Public | BindingFlags.Instance; [Test] public void CanDetectAttributes() { Assert.IsFalse( Reflect.HasAttribute( myType, "Colors.RedAttribute", false ), "Red" ); Assert.IsTrue( Reflect.HasAttribute( myType, "Colors.GreenAttribute", false ), "Green" ); Assert.IsFalse( Reflect.HasAttribute( myType, "Colors.BlueAttribute", false ), "Blue" ); } [Test] public void CanDetectInheritedAttributes() { Assert.IsTrue( Reflect.HasAttribute( myType, "Colors.RedAttribute", true ), "Red" ); Assert.IsTrue( Reflect.HasAttribute( myType, "Colors.GreenAttribute", true ), "Green" ); Assert.IsFalse( Reflect.HasAttribute( myType, "Colors.BlueAttribute", true ), "Blue" ); } [Test] public void GetAttribute() { Assert.IsNull( Reflect.GetAttribute( myType, "Colors.RedAttribute", false ), "Red" ); Assert.AreEqual( "GreenAttribute", Reflect.GetAttribute( myType, "Colors.GreenAttribute", false ).GetType().Name ); Assert.IsNull( Reflect.GetAttribute( myType, "Colors.BlueAttribute", false ), "Blue" ); } [Test] public void GetAttributes() { Assert.AreEqual( 1, Reflect.GetAttributes( myType, false ).Length ); Assert.AreEqual( 0, Reflect.GetAttributes( myType, "Colors.RedAttribute", false ).Length, "Red" ); Assert.AreEqual( 1, Reflect.GetAttributes( myType, "Colors.GreenAttribute", false ).Length, "Green" ); Assert.AreEqual( 0, Reflect.GetAttributes( myType, "Colors.BlueAttribute", false ).Length, "Blue" ); } [Test] public void GetInheritedAttribute() { Assert.AreEqual( "RedAttribute", Reflect.GetAttribute( myType, "Colors.RedAttribute", true ).GetType().Name ); Assert.AreEqual( "GreenAttribute", Reflect.GetAttribute( myType, "Colors.GreenAttribute", true ).GetType().Name ); Assert.IsNull( Reflect.GetAttribute( myType, "Colors.BlueAttribute", true ), "Blue" ); } [Test] public void GetInheritedAttributes() { Assert.AreEqual( 2, Reflect.GetAttributes( myType, true ).Length ); Assert.AreEqual( 1, Reflect.GetAttributes( myType, "Colors.RedAttribute", true ).Length, "Red" ); Assert.AreEqual( 1, Reflect.GetAttributes( myType, "Colors.GreenAttribute", true ).Length, "Green" ); Assert.AreEqual( 0, Reflect.GetAttributes( myType, "Colors.BlueAttribute", true ).Length , "Blue" ); } [Test] public void InheritsFrom() { Assert.IsTrue( Reflect.InheritsFrom( myType, "Colors.BaseClass" ) ); } [Test] public void HasInterface() { Assert.IsTrue( Reflect.HasInterface( myType, "Colors.MyInterface" ) ); } [Test] public void GetConstructor() { Assert.IsNotNull( Reflect.GetConstructor( myType ) ); } [Test] public void GetMethodsWithAttribute() { MethodInfo[] methods = Reflect.GetMethodsWithAttribute(myType, "Colors.BlueAttribute", false); Assert.That( List.Map(methods).Property("Name"), Is.EqualTo(new string[] {"BaseBlueMethod", "BlueMethod"} )); } [Test] public void GetNamedMethod() { Assert.IsNotNull( Reflect.GetNamedMethod( myType, "BlueMethod" ) ); } [Test] public void GetNamedMethodWithArgs() { Assert.IsNotNull( Reflect.GetNamedMethod( myType, "TwoArgs", new string[] { "System.Int32", "System.String" } ) ); } [Test] public void GetPropertyWithAttribute() { Assert.IsNotNull( Reflect.GetPropertyWithAttribute( myType, "Colors.RedAttribute" ) ); } [Test] public void GetNamedProperty() { Assert.IsNotNull( Reflect.GetNamedProperty( myType, "RedProperty", BF ) ); } [Test] public void GetPropertyValue() { Assert.AreEqual( 42, Reflect.GetPropertyValue( new Colors.MyClass(), "RedProperty", BF ) ); } [Test] public void Construct() { Assert.IsNotNull( Reflect.Construct( myType ) ); } [Test] public void InvokeMethod() { Colors.MyClass myClass = new Colors.MyClass(); MethodInfo method = Reflect.GetNamedMethod( myType, "BlueMethod" ); Reflect.InvokeMethod( method, myClass ); Assert.IsTrue( myClass.BlueInvoked ); } } } namespace Colors { class RedAttribute : Attribute { } class GreenAttribute : Attribute { } class BlueAttribute : Attribute { } class BrightRedAttribute : RedAttribute { } interface MyInterface { } [Red] class BaseClass : MyInterface { [Blue] public void BaseBlueMethod() { } } [Green] class MyClass : BaseClass { public bool BlueInvoked = false; [Blue] public void BlueMethod() { BlueInvoked = true; } [Red] public int RedProperty { get { return 42; } } public void TwoArgs( int i, string s ) { } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestRunnerThreadTests.cs0000664000175000017500000000405411702654456023606 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if NET_3_5 || NET_4_0 using System; using System.Threading; using NSubstitute; using NUnit.Framework; using NUnit.Core; using NUnit.Core.Filters; namespace NUnit.Core.Tests { [TestFixture, Platform("Net-3.5,Mono-3.5,Net-4.0")] public class TestRunnerThreadTests { private TestRunner mockRunner; private TestRunnerThread runnerThread; private EventListener listener; [SetUp] public void CreateRunnerThread() { mockRunner = Substitute.For(); runnerThread = new TestRunnerThread( mockRunner, ApartmentState.Unknown, ThreadPriority.Normal ); listener = NullListener.NULL; } [Test] public void RunTestSuite() { runnerThread.StartRun(listener, TestFilter.Empty, false, LoggingThreshold.Off); runnerThread.Wait(); mockRunner.Received().Run(listener, TestFilter.Empty, false, LoggingThreshold.Off); } [Test] public void RunNamedTest() { runnerThread.StartRun(listener, new NameFilter(TestName.Parse("SomeTest")), false, LoggingThreshold.Off); runnerThread.Wait(); mockRunner.Received().Run(listener, Arg.Any(), false, LoggingThreshold.Off); } [Test] public void RunMultipleTests() { NUnit.Core.Filters.NameFilter filter = new NUnit.Core.Filters.NameFilter(); filter.Add(TestName.Parse("Test1")); filter.Add(TestName.Parse("Test2")); filter.Add(TestName.Parse("Test3")); runnerThread.StartRun(listener, filter, false, LoggingThreshold.Off); runnerThread.Wait(); mockRunner.Received().Run(listener, filter, false, LoggingThreshold.Off); } } } #endif NUnit-2.6.0.12051/src/NUnitCore/tests/RepeatedTestFixture.cs0000664000175000017500000000624011504175260023250 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using NUnit.Framework; using NUnit.TestData.RepeatedTestFixture; namespace NUnit.Core.Tests { [TestFixture] public class RepeatedTestFixture { private MethodInfo successMethod; private MethodInfo failOnFirstMethod; private MethodInfo failOnThirdMethod; [SetUp] public void SetUp() { Type testType = typeof(RepeatSuccessFixture); successMethod = testType.GetMethod ("RepeatSuccess"); testType = typeof(RepeatFailOnFirstFixture); failOnFirstMethod = testType.GetMethod("RepeatFailOnFirst"); testType = typeof(RepeatFailOnThirdFixture); failOnThirdMethod = testType.GetMethod("RepeatFailOnThird"); } private TestResult RunTestOnFixture( object fixture ) { Test suite = TestFixtureBuilder.BuildFrom( fixture ); Assert.AreEqual( 1, suite.Tests.Count, "Test case count" ); return suite.Run(NullListener.NULL, TestFilter.Empty); } [Test] public void RepeatSuccess() { Assert.IsNotNull (successMethod); RepeatSuccessFixture fixture = new RepeatSuccessFixture(); TestResult result = RunTestOnFixture( fixture ); Assert.IsTrue(result.IsSuccess); Assert.AreEqual(1, fixture.FixtureSetupCount); Assert.AreEqual(1, fixture.FixtureTeardownCount); Assert.AreEqual(3, fixture.SetupCount); Assert.AreEqual(3, fixture.TeardownCount); Assert.AreEqual(3, fixture.Count); } [Test] public void RepeatFailOnFirst() { Assert.IsNotNull (failOnFirstMethod); RepeatFailOnFirstFixture fixture = new RepeatFailOnFirstFixture(); TestResult result = RunTestOnFixture( fixture ); Assert.IsFalse(result.IsSuccess); Assert.AreEqual(1, fixture.SetupCount); Assert.AreEqual(1, fixture.TeardownCount); Assert.AreEqual(1, fixture.Count); } [Test] public void RepeatFailOnThird() { Assert.IsNotNull (failOnThirdMethod); RepeatFailOnThirdFixture fixture = new RepeatFailOnThirdFixture(); TestResult result = RunTestOnFixture( fixture ); Assert.IsFalse(result.IsSuccess); Assert.AreEqual(3, fixture.SetupCount); Assert.AreEqual(3, fixture.TeardownCount); Assert.AreEqual(3, fixture.Count); } [Test] public void IgnoreWorksWithRepeatedTest() { RepeatedTestWithIgnore fixture = new RepeatedTestWithIgnore(); RunTestOnFixture( fixture ); Assert.AreEqual( 0, fixture.SetupCount ); Assert.AreEqual( 0, fixture.TeardownCount ); Assert.AreEqual( 0, fixture.Count ); } [Test] public void CategoryWorksWithRepeatedTest() { Test suite = TestFixtureBuilder.BuildFrom(typeof(RepeatedTestWithCategory)); Test test = suite.Tests[0] as Test; Assert.IsNotNull(test.Categories); Assert.AreEqual(1, test.Categories.Count); Assert.AreEqual("SAMPLE", test.Categories[0]); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/NamespaceAssemblyTests.cs0000664000175000017500000000523311504175260023730 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Framework; using NUnit.Core; using NUnit.Tests.Assemblies; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class NamespaceAssemblyTests { private string testsDll = MockAssembly.AssemblyPath; private string nonamespaceDLL = NoNamespaceTestFixture.AssemblyPath; [Test] public void LoadTestFixtureFromAssembly() { TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage( testsDll ); package.TestName = "NUnit.Tests.Assemblies.MockTestFixture"; Test suite= builder.Build( package ); Assert.IsNotNull(suite); } [Test] public void TestRoot() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( testsDll ) ); Assert.AreEqual(testsDll, suite.TestName.Name); } [Test] public void Hierarchy() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( testsDll ) ); suite = (Test)suite.Tests[0]; Assert.AreEqual("NUnit", suite.TestName.Name); suite = (Test)suite.Tests[0]; Assert.AreEqual("Tests", suite.TestName.Name); Assert.AreEqual(MockAssembly.Classes, suite.Tests.Count); Test singletonSuite = TestFinder.Find("Singletons", suite, false); Assert.AreEqual(1, singletonSuite.Tests.Count); Test mockSuite = TestFinder.Find("Assemblies", suite, false); Assert.AreEqual(1, mockSuite.Tests.Count); Test mockFixtureSuite = TestFinder.Find("MockTestFixture", mockSuite, false); Assert.AreEqual(MockTestFixture.Tests, mockFixtureSuite.Tests.Count); foreach(Test t in mockFixtureSuite.Tests) { Assert.IsFalse(t.IsSuite, "Should not be a suite"); } } [Test] public void NoNamespaceInAssembly() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( nonamespaceDLL ) ); Assert.IsNotNull(suite); Assert.AreEqual( NoNamespaceTestFixture.Tests, suite.TestCount ); suite = (TestSuite)suite.Tests[0]; Assert.IsNotNull(suite); Assert.AreEqual( "NoNamespaceTestFixture", suite.TestName.Name ); Assert.AreEqual( "NoNamespaceTestFixture", suite.TestName.FullName ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/SetUpFixtureTests.cs0000664000175000017500000001556011504175260022747 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Util; namespace NUnit.Core.Tests { [TestFixture] public class SetUpFixtureTests { private static readonly string testAssembly = AssemblyHelper.GetAssemblyPath(typeof(NUnit.TestData.EmptyFixture)); #region SetUp [SetUp] public void SetUp() { TestUtilities.SimpleEventRecorder.Clear(); } #endregion SetUp private TestResult runTests(string nameSpace) { return runTests(nameSpace, TestFilter.Empty); } private TestResult runTests(string nameSpace, TestFilter filter) { TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage( testAssembly ); package.TestName = nameSpace; Test suite = builder.Build( package ); return suite.Run(new NullListener(),filter); } #region Builder /// /// Tests that the TestSuiteBuilder correctly interperets a SetupFixture class as a 'virtual namespace' into which /// all it's sibling classes are inserted. /// [NUnit.Framework.Test] public void NamespaceSetUpFixtureReplacesNamespaceNodeInTree() { string nameSpace = "NUnit.TestData.SetupFixture.Namespace1"; TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage( testAssembly ); package.TestName = nameSpace; Test suite= builder.Build( package ); Assert.IsNotNull(suite); Assert.AreEqual(testAssembly, suite.TestName.Name); Assert.AreEqual(1, suite.Tests.Count); string[] nameSpaceBits = nameSpace.Split('.'); for (int i = 0; i < nameSpaceBits.Length; i++) { suite = suite.Tests[0] as TestSuite; Assert.AreEqual(nameSpaceBits[i], suite.TestName.Name); Assert.AreEqual(1, suite.Tests.Count); } Assert.IsInstanceOf(typeof(SetUpFixture), suite); suite = suite.Tests[0] as TestSuite; Assert.AreEqual("SomeTestFixture", suite.TestName.Name); Assert.AreEqual(1, suite.Tests.Count); } #endregion Builder #region NoNamespaceBuilder /// /// Tests that the TestSuiteBuilder correctly interperets a SetupFixture class with no parent namespace /// as a 'virtual assembly' into which all it's sibling fixtures are inserted. /// [NUnit.Framework.Test] public void AssemblySetUpFixtureReplacesAssemblyNodeInTree() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( testAssembly ) ); Assert.IsNotNull(suite); Assert.IsInstanceOf(typeof(SetUpFixture), suite); suite = suite.Tests[1] as TestSuite; Assert.AreEqual("SomeTestFixture", suite.TestName.Name); Assert.AreEqual(1, suite.TestCount); } #endregion NoNamespaceBuilder #region Simple [NUnit.Framework.Test] public void NamespaceSetUpFixtureWrapsExecutionOfSingleTest() { Assert.IsTrue(runTests("NUnit.TestData.SetupFixture.Namespace1").IsSuccess); TestUtilities.SimpleEventRecorder.Verify("NamespaceSetup", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "NamespaceTearDown"); } #endregion Simple #region Static [Test] public void NamespaceSetUpMethodsMayBeStatic() { Assert.IsTrue(runTests("NUnit.TestData.SetupFixture.Namespace5").IsSuccess); TestUtilities.SimpleEventRecorder.Verify("NamespaceSetup", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "NamespaceTearDown"); } #endregion #region TwoTestFixtures [NUnit.Framework.Test] public void NamespaceSetUpFixtureWrapsExecutionOfTwoTests() { Assert.IsTrue(runTests("NUnit.TestData.SetupFixture.Namespace2").IsSuccess); TestUtilities.SimpleEventRecorder.Verify("NamespaceSetup", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "NamespaceTearDown"); } #endregion TwoTestFixtures #region SubNamespace [NUnit.Framework.Test] public void NamespaceSetUpFixtureWrapsNestedNamespaceSetUpFixture() { Assert.IsTrue(runTests("NUnit.TestData.SetupFixture.Namespace3").IsSuccess); TestUtilities.SimpleEventRecorder.Verify("NamespaceSetup", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "SubNamespaceSetup", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "SubNamespaceTearDown", "NamespaceTearDown"); } #endregion SubNamespace #region TwoSetUpFixtures [NUnit.Framework.Test] public void WithTwoSetUpFixtuesOnlyOneIsUsed() { Assert.IsTrue(runTests("NUnit.TestData.SetupFixture.Namespace4").IsSuccess); TestUtilities.SimpleEventRecorder.Verify("NamespaceSetup2", "FixtureSetup", "Setup", "Test", "TearDown", "FixtureTearDown", "NamespaceTearDown2"); } #endregion TwoSetUpFixtures #region NoNamespaceSetupFixture [NUnit.Framework.Test] public void AssemblySetupFixtureWrapsExecutionOfTest() { TestResult result = runTests(null, new Filters.SimpleNameFilter("SomeTestFixture")); ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.IsTrue(result.IsSuccess); TestUtilities.SimpleEventRecorder.Verify("RootNamespaceSetup", "Test", "RootNamespaceTearDown"); } #endregion NoNamespaceSetupFixture } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestSuiteTest.cs0000664000175000017500000002515511504175260022107 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.Util; using NUnit.Tests.Assemblies; using System.Collections; using NUnit.Core.Filters; using NUnit.TestUtilities; using NUnit.TestData; namespace NUnit.Core.Tests { [TestFixture] public class TestSuiteTest { TestSuite mockTestFixture; TestSuite noTestSuite; [SetUp] public void SetUp() { mockTestFixture = TestBuilder.MakeFixture( typeof( MockTestFixture ) ); TestSuite noTestFixture = TestBuilder.MakeFixture( typeof( EmptyFixture ) ); noTestSuite = new TestSuite("No Tests"); noTestSuite.Add( noTestFixture); } [Test] public void RunTestsInFixture() { TestResult result = mockTestFixture.Run(NullListener.NULL, TestFilter.Empty); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( MockTestFixture.TestsRun, summarizer.TestsRun, "TestsRun" ); Assert.AreEqual( MockTestFixture.NotRunnable, summarizer.NotRunnable, "NotRunnable"); Assert.AreEqual(MockTestFixture.Ignored, summarizer.Ignored, "Ignored"); Assert.AreEqual(MockTestFixture.Errors, summarizer.Errors, "Errors"); Assert.AreEqual(MockTestFixture.Failures, summarizer.Failures, "Failures"); result = TestFinder.Find( "ExplicitlyRunTest", result, true ); Assert.IsNull( result, "ExplicitlyRunTest should not be in results" ); // TODO: Decide if we want to include Explicit tests that are not run in results // Assert.IsNotNull( result, "Cannot find ExplicitlyRunTest result" ); // Assert.IsFalse( result.Executed, "ExplicitlyRunTest should not be executed" ); // Assert.AreEqual( "Explicit selection required", result.Message ); } [Test] public void RunExplicitTestDirectly() { Test test = TestFinder.Find( "ExplicitlyRunTest", mockTestFixture, true ); Assert.IsNotNull( test, "Cannot find ExplicitlyRunTest" ); Assert.AreEqual( RunState.Explicit, test.RunState ); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( 1, summarizer.TestsRun ); } [Test] public void RunExplicitTestByName() { Test test = TestFinder.Find( "ExplicitlyRunTest", mockTestFixture, true ); Assert.IsNotNull( test, "Cannot find ExplicitlyRunTest" ); Assert.AreEqual( RunState.Explicit, test.RunState ); NameFilter filter = new NameFilter( test.TestName ); TestResult result = mockTestFixture.Run( NullListener.NULL, filter ); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( 1, summarizer.TestsRun ); } [Test] public void RunExplicitTestByCategory() { CategoryFilter filter = new CategoryFilter( "Special" ); TestResult result = mockTestFixture.Run( NullListener.NULL, filter ); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( 1, summarizer.TestsRun ); } [Test] public void ExcludingCategoryDoesNotRunExplicitTestCases() { NotFilter filter = new NotFilter( new CategoryFilter( "MockCategory" ) ); filter.TopLevel = true; TestResult result = mockTestFixture.Run( NullListener.NULL, filter ); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( MockTestFixture.TestsRun - MockTestFixture.MockCategoryTests, summarizer.TestsRun ); } [Test] public void ExcludingCategoryDoesNotRunExplicitTestFixtures() { NotFilter filter = new NotFilter( new CategoryFilter( "MockCategory" ) ); filter.TopLevel = true; TestAssemblyBuilder builder = new TestAssemblyBuilder(); TestSuite suite = builder.Build( MockAssembly.AssemblyPath, true ); TestResult result = suite.Run( NullListener.NULL, filter ); ResultSummarizer summarizer = new ResultSummarizer( result ); Assert.AreEqual( MockAssembly.TestsRun - 2, summarizer.TestsRun ); } [Test] public void InheritedTestCount() { TestSuite suite = TestBuilder.MakeFixture( typeof( InheritedTestFixture ) ); Assert.AreEqual(InheritedTestFixture.Tests, suite.TestCount); } [Test] public void SuiteRunInitialized() { Assert.AreEqual( RunState.Runnable, mockTestFixture.RunState ); } [Test] public void SuiteWithNoTests() { IList tests = noTestSuite.Tests; Assert.AreEqual(1, tests.Count); TestSuite testSuite = (TestSuite)tests[0]; // NOTE: Beginning with NUnit 2.5.3, a suite with no tests is now runnable Assert.AreEqual( RunState.Runnable, testSuite.RunState ); //Assert.AreEqual(testSuite.TestName.Name + " does not have any tests", testSuite.IgnoreReason); } [Test] public void RunNoTestSuite() { Assert.AreEqual(0, noTestSuite.TestCount); TestResult result = noTestSuite.Run(NullListener.NULL, TestFilter.Empty); ResultSummarizer summarizer = new ResultSummarizer(result); Assert.AreEqual(0, summarizer.TestsRun); Assert.AreEqual(0, summarizer.TestsNotRun); } [Test] public void RunTestByName() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); Assert.IsNull(testSuite.Parent); Test firstTest = (Test)testSuite.Tests[0]; Assert.AreEqual(testSuite, firstTest.Parent); Test bottom = (Test)firstTest.Tests[2]; RecordingListener listener = new RecordingListener(); NameFilter filter = new NameFilter(bottom.TestName); testSuite.Run(listener, filter); Assert.AreEqual(1, listener.testStarted.Count); Assert.AreEqual("MockTest3", (string)listener.testStarted[0]); } [Test] public void RunSuiteByName() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); RecordingListener listener = new RecordingListener(); testSuite.Run(listener, TestFilter.Empty); Assert.AreEqual(MockTestFixture.ResultCount, listener.testStarted.Count); Assert.AreEqual(2, listener.suiteStarted.Count); } [Test] public void CountTestCasesFilteredByName() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); Assert.AreEqual(MockTestFixture.Tests, testSuite.TestCount); Test mock3 = TestFinder.Find("MockTest3", testSuite, true); Test mock1 = TestFinder.Find("MockTest1", testSuite, true); NameFilter filter = new NameFilter(mock3.TestName); Assert.AreEqual(1, testSuite.CountTestCases(filter)); filter = new NameFilter(); filter.Add(mock3.TestName); filter.Add(mock1.TestName); Assert.AreEqual(2, testSuite.CountTestCases(filter)); filter = new NameFilter(testSuite.TestName); Assert.AreEqual(MockTestFixture.ResultCount, testSuite.CountTestCases(filter)); } [Test] public void RunTestByCategory() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); CategoryFilter filter = new CategoryFilter(); filter.AddCategory("MockCategory"); RecordingListener listener = new RecordingListener(); testSuite.Run(listener, filter); CollectionAssert.AreEquivalent( new string[] { "MockTest2", "MockTest3" }, listener.testStarted ); } [Test] public void RunTestExcludingCategory() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); CategoryFilter filter = new CategoryFilter(); filter.AddCategory("MockCategory"); RecordingListener listener = new RecordingListener(); NotFilter notFilter = new NotFilter(filter); notFilter.TopLevel = true; testSuite.Run(listener, notFilter); CollectionAssert.AreEquivalent( new string[] { "MockTest1", "MockTest4", "MockTest5", "TestWithManyProperties", "NotRunnableTest", "FailingTest", "TestWithException", "InconclusiveTest" }, listener.testStarted ); } [Test] public void RunSuiteByCategory() { TestSuite testSuite = new TestSuite("Mock Test Suite"); testSuite.Add(mockTestFixture); CategoryFilter filter = new CategoryFilter(); filter.AddCategory("FixtureCategory"); RecordingListener listener = new RecordingListener(); testSuite.Run(listener, filter); Assert.AreEqual(MockTestFixture.ResultCount, listener.testStarted.Count); } [Test] public void RunSingleTest() { TestSuite fixture = TestBuilder.MakeFixture( typeof( NUnit.Tests.Assemblies.MockTestFixture ) ); Test test = (Test) fixture.Tests[0]; RecordingListener listener = new RecordingListener(); test.Run(listener, null); Assert.IsFalse(listener.lastResult.IsFailure); } [Test] public void DefaultSortIsByName() { mockTestFixture.Sort(); Assert.AreEqual( "ExplicitlyRunTest", ((Test)mockTestFixture.Tests[0]).TestName.Name ); } [Test] public void CanSortUsingExternalComparer() { IComparer comparer = new ReverseSortComparer(); mockTestFixture.Sort(comparer); Assert.AreEqual( "TestWithManyProperties", ((Test)mockTestFixture.Tests[0]).TestName.Name ); } private class ReverseSortComparer : IComparer { public int Compare(object t1, object t2) { int result = Comparer.Default.Compare( t1, t2 ); return -result; } } } [Serializable] public class RecordingListener : EventListener { public ArrayList testStarted = new ArrayList(); public ArrayList testFinished = new ArrayList(); public ArrayList suiteStarted = new ArrayList(); public ArrayList suiteFinished = new ArrayList(); public TestResult lastResult = null; public void RunStarted(string name, int testCount) { } public void RunFinished(NUnit.Core.TestResult result) { } public void RunFinished(Exception exception) { } public void TestStarted(TestName testName) { testStarted.Add(testName.Name); } public void TestFinished(TestResult result) { testFinished.Add(result.Name); lastResult = result; } public void SuiteStarted(TestName suiteName) { suiteStarted.Add(suiteName.Name); } public void SuiteFinished(TestResult result) { suiteFinished.Add(result.Name); } public void UnhandledException(Exception exception ) { } public void TestOutput(TestOutput testOutput) { } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestDelegateFixture.cs0000664000175000017500000000217311504175260023232 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Threading; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// Summary description for TestDelegate. /// /// [TestFixture] public class TestDelegateFixture { internal class TestDelegate { public bool delegateCalled = false; public System.IAsyncResult ar; public delegate void CallBackFunction(); public TestDelegate() { ar = new CallBackFunction (DoSomething).BeginInvoke (null,null); } public void DoSomething() { delegateCalled = true; } } [Test] public void DelegateTest() { TestDelegate testDelegate = new TestDelegate(); testDelegate.ar.AsyncWaitHandle.WaitOne(1000, false ); Assert.IsTrue(testDelegate.delegateCalled); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/CategoryAttributeTests.cs0000664000175000017500000000341611504175260023776 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData.CategoryAttributeTests; namespace NUnit.Core.Tests { /// /// Summary description for CategoryAttributeTests. /// [TestFixture] public class CategoryAttributeTests { TestSuite fixture; [SetUp] public void CreateFixture() { fixture = TestBuilder.MakeFixture( typeof( FixtureWithCategories ) ); } [Test] public void CategoryOnFixture() { Assert.Contains( "DataBase", fixture.Categories ); } [Test] public void CategoryOnTestCase() { Test test1 = (Test)fixture.Tests[0]; Assert.Contains( "Long", test1.Categories ); } [Test] public void CanDeriveFromCategoryAttribute() { Test test2 = (Test)fixture.Tests[1]; Assert.Contains( "Critical", test2.Categories ); } [Test] public void DerivedCategoryMayBeInherited() { Assert.Contains("MyCategory", fixture.Categories); } [Test] public void CountTestsWithoutCategoryFilter() { Assert.That(fixture.CountTestCases(TestFilter.Empty), Is.EqualTo(2)); } [TestCase("Database", Result = 0)] [TestCase("Long", Result = 1)] [TestCase("Critical", Result = 1)] public int CountTestsUsingCategoryFilter(string name) { TestFilter filter = new Filters.CategoryFilter(name); return fixture.CountTestCases(filter); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ThreadedTestRunnerTests.cs0000664000175000017500000000136511700127000024073 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// Summary description for ThreadedTestRunnerTests. /// [TestFixture] public class ThreadedTestRunnerTests : BasicRunnerTests { protected override TestRunner CreateRunner( int runnerID ) { return new ThreadedTestRunner( new SimpleTestRunner( runnerID ), ApartmentState.Unknown, ThreadPriority.Normal ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ActionAttributeExceptionTests.cs0000664000175000017500000000507311712475522025323 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using NUnit.Framework; using NUnit.TestData; using NUnit.TestData.ActionAttributeTests; namespace NUnit.Core.Tests { [TestFixture] public class ActionAttributeExceptionTests { private class Filter : TestFilter { public override bool Match(ITest test) { return test.TestName.FullName.StartsWith(typeof(ActionAttributeExceptionFixture).FullName); } } private TestSuite _Suite = null; [TestFixtureSetUp] public void Setup() { TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage(AssemblyHelper.GetAssemblyPath(typeof(ActionAttributeExceptionFixture))); package.TestName = typeof(ActionAttributeExceptionFixture).Namespace; _Suite = builder.Build(package); } public TestResult RunTest() { return _Suite.Run(new NullListener(), new Filter()); } private TestResult FindFailureTestResult(TestResult result) { while (result.FailureSite == FailureSite.Child && result.Results != null && result.Results.Count > 0) result = (TestResult)result.Results[0]; return result; } [Test] public void BeforeTestException() { ExceptionThrowingActionAttribute.Reset(); ExceptionThrowingActionAttribute.ThrowBeforeException = true; ActionAttributeExceptionFixture.Reset(); TestResult result = FindFailureTestResult(RunTest()); Assert.IsTrue(result.FailureSite == FailureSite.SetUp); Assert.IsFalse(ActionAttributeExceptionFixture.TestRun); } [Test] public void AfterTestException() { ExceptionThrowingActionAttribute.Reset(); ExceptionThrowingActionAttribute.ThrowAfterException = true; ActionAttributeExceptionFixture.Reset(); TestResult result = FindFailureTestResult(RunTest()); Assert.IsTrue(result.FailureSite == FailureSite.TearDown); Assert.IsTrue(ActionAttributeExceptionFixture.TestRun); } } } #endif NUnit-2.6.0.12051/src/NUnitCore/tests/FixtureSetUpTearDownTest.cs0000664000175000017500000003437411544454420024236 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Security.Principal; using System.Threading; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.Util; using NUnit.TestUtilities; using NUnit.TestData.FixtureSetUpTearDown; namespace NUnit.Core.Tests { [TestFixture] public class FixtureSetupTearDownTest { private TestResult RunTestOnFixture( object fixture ) { TestSuite suite = TestBuilder.MakeFixture( fixture.GetType() ); suite.Fixture = fixture; return suite.Run(NullListener.NULL, TestFilter.Empty); } [Test] public void MakeSureSetUpAndTearDownAreCalled() { SetUpAndTearDownFixture fixture = new SetUpAndTearDownFixture(); RunTestOnFixture( fixture ); Assert.AreEqual(1, fixture.setUpCount, "SetUp"); Assert.AreEqual(1, fixture.tearDownCount, "TearDown"); } [Test] public void MakeSureSetUpAndTearDownAreCalledOnExplicitFixture() { ExplicitSetUpAndTearDownFixture fixture = new ExplicitSetUpAndTearDownFixture(); RunTestOnFixture( fixture ); Assert.AreEqual(1, fixture.setUpCount, "SetUp"); Assert.AreEqual(1, fixture.tearDownCount, "TearDown"); } [Test] public void CheckInheritedSetUpAndTearDownAreCalled() { InheritSetUpAndTearDown fixture = new InheritSetUpAndTearDown(); RunTestOnFixture( fixture ); Assert.AreEqual(1, fixture.setUpCount); Assert.AreEqual(1, fixture.tearDownCount); } [Test] public static void StaticSetUpAndTearDownAreCalled() { StaticSetUpAndTearDownFixture.setUpCount = 0; StaticSetUpAndTearDownFixture.tearDownCount = 0; TestBuilder.RunTestFixture(typeof(StaticSetUpAndTearDownFixture)); Assert.AreEqual(1, StaticSetUpAndTearDownFixture.setUpCount); Assert.AreEqual(1, StaticSetUpAndTearDownFixture.tearDownCount); } #if CLR_2_0 || CLR_4_0 [Test] public static void StaticClassSetUpAndTearDownAreCalled() { StaticClassSetUpAndTearDownFixture.setUpCount = 0; StaticClassSetUpAndTearDownFixture.tearDownCount = 0; TestBuilder.RunTestFixture(typeof(StaticClassSetUpAndTearDownFixture)); Assert.AreEqual(1, StaticClassSetUpAndTearDownFixture.setUpCount); Assert.AreEqual(1, StaticClassSetUpAndTearDownFixture.tearDownCount); } #endif [Test] public void OverriddenSetUpAndTearDownAreNotCalled() { DefineInheritSetUpAndTearDown fixture = new DefineInheritSetUpAndTearDown(); RunTestOnFixture(fixture); Assert.AreEqual(0, fixture.setUpCount); Assert.AreEqual(0, fixture.tearDownCount); Assert.AreEqual(1, fixture.derivedSetUpCount); Assert.AreEqual(1, fixture.derivedTearDownCount); } [Test] public void BaseSetUpCalledFirstAndTearDownCalledLast() { DerivedSetUpAndTearDownFixture fixture = new DerivedSetUpAndTearDownFixture(); RunTestOnFixture(fixture); Assert.AreEqual(1, fixture.setUpCount); Assert.AreEqual(1, fixture.tearDownCount); Assert.AreEqual(1, fixture.derivedSetUpCount); Assert.AreEqual(1, fixture.derivedTearDownCount); Assert.That(fixture.baseSetUpCalledFirst, "Base SetUp called first"); Assert.That(fixture.baseTearDownCalledLast, "Base TearDown called last"); } [Test] public void StaticBaseSetUpCalledFirstAndTearDownCalledLast() { StaticSetUpAndTearDownFixture.setUpCount = 0; StaticSetUpAndTearDownFixture.tearDownCount = 0; DerivedStaticSetUpAndTearDownFixture.derivedSetUpCount = 0; DerivedStaticSetUpAndTearDownFixture.derivedTearDownCount = 0; DerivedStaticSetUpAndTearDownFixture fixture = new DerivedStaticSetUpAndTearDownFixture(); RunTestOnFixture(fixture); Assert.AreEqual(1, DerivedStaticSetUpAndTearDownFixture.setUpCount); Assert.AreEqual(1, DerivedStaticSetUpAndTearDownFixture.tearDownCount); Assert.AreEqual(1, DerivedStaticSetUpAndTearDownFixture.derivedSetUpCount); Assert.AreEqual(1, DerivedStaticSetUpAndTearDownFixture.derivedTearDownCount); Assert.That(DerivedStaticSetUpAndTearDownFixture.baseSetUpCalledFirst, "Base SetUp called first"); Assert.That(DerivedStaticSetUpAndTearDownFixture.baseTearDownCalledLast, "Base TearDown called last"); } [Test] public void HandleErrorInFixtureSetup() { MisbehavingFixture fixture = new MisbehavingFixture(); fixture.blowUpInSetUp = true; TestResult result = RunTestOnFixture( fixture ); Assert.AreEqual( 1, fixture.setUpCount, "setUpCount" ); Assert.AreEqual( 0, fixture.tearDownCount, "tearDownCOunt" ); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); Assert.AreEqual(ResultState.Error, result.ResultState); Assert.AreEqual("SetUp : System.Exception : This was thrown from fixture setup", result.Message, "TestSuite Message"); Assert.IsNotNull(result.StackTrace, "TestSuite StackTrace should not be null"); TestResult testResult = ((TestResult)result.Results[0]); Assert.IsTrue(testResult.Executed, "Test should have executed"); Assert.AreEqual("TestFixtureSetUp failed in MisbehavingFixture", testResult.Message, "TestSuite Message"); Assert.AreEqual(FailureSite.Parent, testResult.FailureSite); Assert.AreEqual(testResult.StackTrace, testResult.StackTrace, "Test stackTrace should match TestSuite stackTrace" ); } [Test] public void RerunFixtureAfterSetUpFixed() { MisbehavingFixture fixture = new MisbehavingFixture(); fixture.blowUpInSetUp = true; TestResult result = RunTestOnFixture( fixture ); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); Assert.IsTrue(result.Executed, "Suite should have executed"); //fix the blow up in setup fixture.Reinitialize(); result = RunTestOnFixture( fixture ); Assert.AreEqual( 1, fixture.setUpCount, "setUpCount" ); Assert.AreEqual( 1, fixture.tearDownCount, "tearDownCOunt" ); // should have one suite and one fixture summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); } [Test] public void HandleIgnoreInFixtureSetup() { IgnoreInFixtureSetUp fixture = new IgnoreInFixtureSetUp(); TestResult result = RunTestOnFixture( fixture ); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(0, summ.TestsRun); Assert.AreEqual(1, summ.TestsNotRun); Assert.IsFalse(result.Executed, "Suite should not have executed"); Assert.AreEqual("TestFixtureSetUp called Ignore", result.Message); Assert.IsNotNull(result.StackTrace, "StackTrace should not be null"); TestResult testResult = ((TestResult)result.Results[0]); Assert.IsFalse(testResult.Executed, "Testcase should not have executed"); Assert.AreEqual("TestFixtureSetUp called Ignore", testResult.Message ); } [Test] public void HandleErrorInFixtureTearDown() { MisbehavingFixture fixture = new MisbehavingFixture(); fixture.blowUpInTearDown = true; TestResult result = RunTestOnFixture( fixture ); Assert.AreEqual(1, result.Results.Count); Assert.IsTrue(result.Executed, "Suite should have executed"); Assert.IsTrue(result.IsFailure, "Suite should have failed" ); Assert.AreEqual( 1, fixture.setUpCount, "setUpCount" ); Assert.AreEqual( 1, fixture.tearDownCount, "tearDownCOunt" ); Assert.AreEqual("This was thrown from fixture teardown", result.Message); Assert.IsNotNull(result.StackTrace, "StackTrace should not be null"); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); } [Test] public void HandleExceptionInFixtureConstructor() { TestSuite suite = TestBuilder.MakeFixture( typeof( ExceptionInConstructor ) ); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); Assert.AreEqual(ResultState.Error, result.ResultState); Assert.AreEqual("SetUp : System.Exception : This was thrown in constructor", result.Message, "TestSuite Message"); Assert.IsNotNull(result.StackTrace, "TestSuite StackTrace should not be null"); TestResult testResult = ((TestResult)result.Results[0]); Assert.IsTrue(testResult.Executed, "Testcase should have executed"); Assert.AreEqual("TestFixtureSetUp failed in ExceptionInConstructor", testResult.Message, "TestSuite Message"); Assert.AreEqual(FailureSite.Parent, testResult.FailureSite); Assert.AreEqual(testResult.StackTrace, testResult.StackTrace, "Test stackTrace should match TestSuite stackTrace" ); } [Test] public void RerunFixtureAfterTearDownFixed() { MisbehavingFixture fixture = new MisbehavingFixture(); fixture.blowUpInTearDown = true; TestResult result = RunTestOnFixture( fixture ); Assert.AreEqual(1, result.Results.Count); // should have one suite and one fixture ResultSummarizer summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); fixture.Reinitialize(); result = RunTestOnFixture( fixture ); Assert.AreEqual( 1, fixture.setUpCount, "setUpCount" ); Assert.AreEqual( 1, fixture.tearDownCount, "tearDownCOunt" ); summ = new ResultSummarizer(result); Assert.AreEqual(1, summ.TestsRun); Assert.AreEqual(0, summ.TestsNotRun); } [Test] public void HandleSetUpAndTearDownWithTestInName() { SetUpAndTearDownWithTestInName fixture = new SetUpAndTearDownWithTestInName(); RunTestOnFixture( fixture ); Assert.AreEqual(1, fixture.setUpCount); Assert.AreEqual(1, fixture.tearDownCount); } [Test] public void RunningSingleMethodCallsSetUpAndTearDown() { SetUpAndTearDownFixture fixture = new SetUpAndTearDownFixture(); TestSuite suite = TestBuilder.MakeFixture( fixture.GetType() ); suite.Fixture = fixture; Test test = (Test)suite.Tests[0]; suite.Run(NullListener.NULL, new Filters.NameFilter( test.TestName ) ); Assert.AreEqual(1, fixture.setUpCount); Assert.AreEqual(1, fixture.tearDownCount); } [Test] public void IgnoredFixtureShouldNotCallFixtureSetUpOrTearDown() { IgnoredFixture fixture = new IgnoredFixture(); TestSuite suite = new TestSuite("IgnoredFixtureSuite"); TestSuite fixtureSuite = TestBuilder.MakeFixture( fixture.GetType() ); suite.Fixture = fixture; Test test = (Test)fixtureSuite.Tests[0]; suite.Add( fixtureSuite ); fixtureSuite.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse( fixture.setupCalled, "TestFixtureSetUp called running fixture" ); Assert.IsFalse( fixture.teardownCalled, "TestFixtureTearDown called running fixture" ); suite.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse( fixture.setupCalled, "TestFixtureSetUp called running enclosing suite" ); Assert.IsFalse( fixture.teardownCalled, "TestFixtureTearDown called running enclosing suite" ); test.Run(NullListener.NULL, TestFilter.Empty); Assert.IsFalse( fixture.setupCalled, "TestFixtureSetUp called running a test case" ); Assert.IsFalse( fixture.teardownCalled, "TestFixtureTearDown called running a test case" ); } [Test] public void FixtureWithNoTestsCallsFixtureSetUpAndTearDown() { // NOTE: Beginning with NUnit 2.5.3, FixtureSetUp and TearDown // are called even if the fixture contains no tests. FixtureWithNoTests fixture = new FixtureWithNoTests(); RunTestOnFixture( fixture ); Assert.IsTrue( fixture.setupCalled, "TestFixtureSetUp not called" ); Assert.IsTrue( fixture.teardownCalled, "TestFixtureTearDown not called" ); } [Test] public void DisposeCalledWhenFixtureImplementsIDisposable() { DisposableFixture fixture = new DisposableFixture(); RunTestOnFixture(fixture); Assert.IsTrue(fixture.disposeCalled); } [TestFixture] class ChangesMadeInFixtureSetUp { [TestFixtureSetUp] public void TestFixtureSetUp() { GenericIdentity identity = new GenericIdentity("foo"); Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[0]); System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-GB"); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; } [Test] public void TestThatChangesPersistUsingSameThread() { Assert.AreEqual("foo", Thread.CurrentPrincipal.Identity.Name); Assert.AreEqual("en-GB", Thread.CurrentThread.CurrentCulture.Name); Assert.AreEqual("en-GB", Thread.CurrentThread.CurrentUICulture.Name); } [Test, RequiresThread] public void TestThatChangesPersistUsingSeparateThread() { Assert.AreEqual("foo", Thread.CurrentPrincipal.Identity.Name); Assert.AreEqual("en-GB", Thread.CurrentThread.CurrentCulture.Name); Assert.AreEqual("en-GB", Thread.CurrentThread.CurrentUICulture.Name); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/SuiteBuilderTests.cs0000664000175000017500000001006611504175260022734 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using NUnit.Framework; using NUnit.Core; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class SuiteBuilderTests { private string testsDll = AssemblyHelper.GetAssemblyPath(typeof(SuiteBuilderTests)); private string testData = AssemblyHelper.GetAssemblyPath(typeof(NUnit.TestData.EmptyFixture)); private string tempFile; private TestSuiteBuilder builder; [SetUp] public void CreateBuilder() { builder = new TestSuiteBuilder(); tempFile = Path.ChangeExtension(Path.GetTempFileName(), ".dll"); } [TearDown] public void TearDown() { FileInfo info = new FileInfo(tempFile); if(info.Exists) info.Delete(); } [Test] public void LoadAssembly() { Test suite = builder.Build( new TestPackage( testsDll ) ); Assert.IsNotNull(suite, "Unable to build suite" ); Assert.AreEqual( 1, suite.Tests.Count ); Assert.AreEqual( "NUnit", ((ITest)suite.Tests[0]).TestName.Name ); } [Test] public void LoadAssemblyWithoutNamespaces() { TestPackage package = new TestPackage( testsDll ); package.Settings["AutoNamespaceSuites"] = false; Test suite = builder.Build( package ); Assert.IsNotNull(suite, "Unable to build suite" ); Assert.Greater( suite.Tests.Count, 1 ); Assert.AreEqual( "TestFixture", ((ITest)suite.Tests[0]).TestType ); } [Test] public void LoadFixture() { TestPackage package = new TestPackage( testsDll ); package.TestName = "NUnit.Core.Tests.SuiteBuilderTests"; Test suite= builder.Build( package ); Assert.IsNotNull(suite, "Unable to build suite"); } [Test] public void LoadSuite() { TestPackage package = new TestPackage( testsDll ); package.TestName = "NUnit.Core.Tests.AllTests"; Test suite= builder.Build( package ); Assert.IsNotNull(suite, "Unable to build suite"); Assert.AreEqual( 3, suite.Tests.Count ); } [Test] public void LoadNamespaceAsSuite() { TestPackage package = new TestPackage( testsDll ); package.TestName = "NUnit.Core.Tests"; Test suite= builder.Build( package ); Assert.IsNotNull( suite ); Assert.AreEqual( testsDll, suite.TestName.Name ); Assert.AreEqual( "NUnit", ((Test)suite.Tests[0]).TestName.Name ); } [Test] public void DiscoverSuite() { TestPackage package = new TestPackage( testData ); package.TestName = "NUnit.TestData.LegacySuiteData.Suite"; Test suite = builder.Build( package ); Assert.IsNotNull(suite, "Could not discover suite attribute"); } [Test] public void WrongReturnTypeSuite() { TestPackage package = new TestPackage( testData ); package.TestName = "NUnit.TestData.LegacySuiteData.NonConformingSuite"; Test suite = builder.Build( package ); Assert.AreEqual(RunState.NotRunnable, suite.RunState); Assert.AreEqual("Suite property must return either TestSuite or IEnumerable", suite.IgnoreReason); } [Test] [ExpectedException(typeof(FileNotFoundException))] public void FileNotFound() { builder.Build( new TestPackage( "/xxxx.dll" ) ); } // Gives FileNotFoundException on Mono [Test, ExpectedException(typeof(BadImageFormatException))] public void InvalidAssembly() { FileInfo file = new FileInfo( tempFile ); StreamWriter sw = file.AppendText(); sw.WriteLine("This is a new entry to add to the file"); sw.WriteLine("This is yet another line to add..."); sw.Flush(); sw.Close(); builder.Build( new TestPackage( tempFile ) ); } [Test] public void FixtureNotFound() { TestPackage package = new TestPackage( testsDll ); package.TestName = "NUnit.Tests.Junk"; Assert.IsNull( builder.Build( package ) ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/CallContextTests.cs0000664000175000017500000000655511543055572022572 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Runtime.Remoting.Messaging; using System.Security.Principal; using NUnit.Framework; namespace NUnit.Core.Tests { // TODO: Make this work for .NET 2.0 [TestFixture] public class CallContextTests { const string CONTEXT_DATA = "MyContextData"; // IPrincipal savedPrincipal; // [SetUp] // public void SaveCurrentPrincipal() // { // savedPrincipal = System.Threading.Thread.CurrentPrincipal; // } // // [TearDown] // public void RestoreCurrentPrincipal() // { // System.Threading.Thread.CurrentPrincipal = savedPrincipal; // CallContext.FreeNamedDataSlot(CONTEXT_DATA); // } [TestFixtureTearDown] public void FreeCallContextDataSlot() { // NOTE: We don't want possible side effects on other cross context tests. CallContext.FreeNamedDataSlot(CONTEXT_DATA); } [Test] public void ILogicalThreadAffinativeTest() { CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() ); } [Test] public void ILogicalThreadAffinativeTestConsole() { CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() ); // TODO: make this Assertable //Console.WriteLine("ILogicalThreadAffinativeTest"); Console.Out.Flush(); } [Test] public void GenericPrincipalTest() { GenericIdentity ident = new GenericIdentity("Bob"); GenericPrincipal prpal = new GenericPrincipal(ident, new string[] {"Level1"}); CallContext.SetData( CONTEXT_DATA, new PrincipalCallContextData( prpal ) ); } [Test] public void SetGenericPrincipalOnThread() { GenericIdentity ident = new GenericIdentity("Bob"); GenericPrincipal prpal = new GenericPrincipal(ident, new string[] {"Level1"}); System.Threading.Thread.CurrentPrincipal = prpal; } [Test] public void SetCustomPrincipalOnThread() { MyPrincipal prpal = new MyPrincipal(); System.Threading.Thread.CurrentPrincipal = prpal; } [Test] public void UseCustomIdentity() { TestIdentity ident = new TestIdentity( "test" ); GenericPrincipal principal = new GenericPrincipal( ident, new string[] { "Level1" } ); System.Threading.Thread.CurrentPrincipal = principal; } } /// /// Helper class that implements ILogicalThreadAffinative /// but holds no data at all /// [Serializable] public class EmptyCallContextData : ILogicalThreadAffinative { } [Serializable] public class PrincipalCallContextData : ILogicalThreadAffinative { public PrincipalCallContextData( IPrincipal principal ) { } } [Serializable] public class MyPrincipal : IPrincipal { public IIdentity Identity { get { // TODO: Add MyPrincipal.Identity getter implementation return null; } } public bool IsInRole(string role) { // TODO: Add MyPrincipal.IsInRole implementation return false; } } [Serializable] public class TestIdentity : GenericIdentity { public TestIdentity( string name ) : base( name ) { } } } NUnit-2.6.0.12051/src/NUnitCore/tests/CultureSettingAndDetectionTests.cs0000664000175000017500000001304411666226674025615 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Globalization; using NUnit.Framework; using NUnit.TestData.CultureAttributeTests; using NUnit.TestUtilities; namespace NUnit.Core.Tests { /// /// Summary description for CultureDetectionTests. /// [TestFixture] public class CultureSettingAndDetectionTests { private CultureDetector detector = new CultureDetector("fr-FR"); private void ExpectMatch( string culture ) { if ( !detector.IsCultureSupported( culture ) ) Assert.Fail( string.Format( "Failed to match \"{0}\"" , culture ) ); } private void ExpectMatch( CultureAttribute attr ) { if ( !detector.IsCultureSupported( attr ) ) Assert.Fail( string.Format( "Failed to match attribute with Include=\"{0}\",Exclude=\"{1}\"", attr.Include, attr.Exclude ) ); } private void ExpectFailure( string culture ) { if ( detector.IsCultureSupported( culture ) ) Assert.Fail( string.Format( "Should not match \"{0}\"" , culture ) ); Assert.AreEqual( "Only supported under culture " + culture, detector.Reason ); } private void ExpectFailure( CultureAttribute attr, string msg ) { if ( detector.IsCultureSupported( attr ) ) Assert.Fail( string.Format( "Should not match attribute with Include=\"{0}\",Exclude=\"{1}\"", attr.Include, attr.Exclude ) ); Assert.AreEqual( msg, detector.Reason ); } [Test] public void CanMatchStrings() { ExpectMatch( "fr-FR" ); ExpectMatch( "fr" ); ExpectMatch( "fr-FR,fr-BE,fr-CA" ); ExpectMatch( "en,de,fr,it" ); ExpectFailure( "en-GB" ); ExpectFailure( "en" ); ExpectFailure( "fr-CA" ); ExpectFailure( "fr-BE,fr-CA" ); ExpectFailure( "en,de,it" ); } [Test] public void CanMatchAttributeWithInclude() { ExpectMatch( new CultureAttribute( "fr-FR" ) ); ExpectMatch( new CultureAttribute( "fr-FR,fr-BE,fr-CA" ) ); ExpectFailure( new CultureAttribute( "en" ), "Only supported under culture en" ); ExpectFailure( new CultureAttribute( "en,de,it" ), "Only supported under culture en,de,it" ); } [Test] public void CanMatchAttributeWithExclude() { CultureAttribute attr = new CultureAttribute(); attr.Exclude = "en"; ExpectMatch( attr ); attr.Exclude = "en,de,it"; ExpectMatch( attr ); attr.Exclude = "fr"; ExpectFailure( attr, "Not supported under culture fr"); attr.Exclude = "fr-FR,fr-BE,fr-CA"; ExpectFailure( attr, "Not supported under culture fr-FR,fr-BE,fr-CA" ); } [Test] public void CanMatchAttributeWithIncludeAndExclude() { CultureAttribute attr = new CultureAttribute( "en,fr,de,it" ); attr.Exclude="fr-CA,fr-BE"; ExpectMatch( attr ); attr.Exclude = "fr-FR"; ExpectFailure( attr, "Not supported under culture fr-FR" ); } [Test,SetCulture("fr-FR")] public void LoadWithFrenchCulture() { Assert.AreEqual( "fr-FR", CultureInfo.CurrentCulture.Name, "Culture not set correctly" ); TestSuite fixture = TestBuilder.MakeFixture( typeof( FixtureWithCultureAttribute ) ); Assert.AreEqual( RunState.Runnable, fixture.RunState, "Fixture" ); foreach( Test test in fixture.Tests ) { RunState expected = test.TestName.Name == "FrenchTest" ? RunState.Runnable : RunState.Skipped; Assert.AreEqual( expected, test.RunState, test.TestName.Name ); } } [Test,SetCulture("fr-CA")] public void LoadWithFrenchCanadianCulture() { Assert.AreEqual( "fr-CA", CultureInfo.CurrentCulture.Name, "Culture not set correctly" ); TestSuite fixture = TestBuilder.MakeFixture( typeof( FixtureWithCultureAttribute ) ); Assert.AreEqual( RunState.Runnable, fixture.RunState, "Fixture" ); foreach( Test test in fixture.Tests ) { RunState expected = test.TestName.Name.StartsWith( "French" ) ? RunState.Runnable : RunState.Skipped; Assert.AreEqual( expected, test.RunState, test.TestName.Name ); } } [Test,SetCulture("ru-RU")] public void LoadWithRussianCulture() { Assert.AreEqual( "ru-RU", CultureInfo.CurrentCulture.Name, "Culture not set correctly" ); TestSuite fixture = TestBuilder.MakeFixture( typeof( FixtureWithCultureAttribute ) ); Assert.AreEqual( RunState.Skipped, fixture.RunState, "Fixture" ); foreach( Test test in fixture.Tests ) Assert.AreEqual( RunState.Skipped, test.RunState, test.TestName.Name ); } [Test] public void SettingInvalidCultureGivesError() { TestResult result = TestBuilder.RunTestCase( typeof( InvalidCultureFixture ), "InvalidCultureSet" ); Assert.AreEqual( ResultState.Error, result.ResultState ); Assert.That(result.Message, Text.StartsWith("System.ArgumentException").Or.StartsWith("System.Globalization.CultureNotFoundException")); Assert.That(result.Message, Text.Contains("xx-XX").IgnoreCase); } [TestFixture, SetCulture("en-GB")] public class NestedFixture { [Test] public void CanSetCultureOnFixture() { Assert.AreEqual( "en-GB", CultureInfo.CurrentCulture.Name ); } } #if CLR_2_0 || CLR_4_0 [Test, SetCulture("de-DE")] [TestCase(Result="01.06.2010 00:00:00")] public string UseWithParameterizedTest() { return new DateTime(2010, 6, 1).ToString(); } #endif } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestNameTests.cs0000664000175000017500000001061711504175260022056 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class TestNameTests { private TestName weakName1; private TestName weakName2; private TestName strongName1; private TestName strongName2; [SetUp] public void CreateTestNames() { weakName1 = new TestName(); weakName2 = new TestName(); weakName1.FullName = weakName2.FullName = "Name.Of.This.Test"; strongName1 = new TestName(); strongName2 = new TestName(); strongName1.FullName = strongName2.FullName = "Name.Of.This.Test"; strongName1.TestID = new TestID(); strongName2.TestID = new TestID(); } [Test] public void CanCompareWeakTestNames() { Assert.AreEqual( weakName1, weakName2 ); Assert.IsTrue( weakName1 == weakName2, "operator =="); Assert.IsFalse( weakName1 != weakName2, "operator !="); weakName2.FullName = "A.Different.Name"; Assert.AreNotEqual( weakName1, weakName2 ); Assert.IsFalse( weakName1 == weakName2, "operator =="); Assert.IsTrue( weakName1 != weakName2, "operator !="); } [Test] public void CanCompareStrongTestNames() { Assert.AreNotEqual( strongName1, strongName2 ); Assert.IsFalse( strongName1 == strongName2, "operator ==" ); Assert.IsTrue( strongName1 != strongName2, "operator !=" ); strongName2.TestID = strongName1.TestID; Assert.AreEqual( strongName1, strongName2 ); Assert.IsTrue( strongName1 == strongName2, "operator ==" ); Assert.IsFalse( strongName1 != strongName2, "operator !=" ); strongName2.FullName = "A.Different.Name"; Assert.AreNotEqual( strongName1, strongName2 ); Assert.IsFalse( strongName1 == strongName2, "operator ==" ); Assert.IsTrue( strongName1 != strongName2, "operator !=" ); } [Test] public void CanCompareWeakAndStrongTestNames() { Assert.AreNotEqual( weakName1, strongName1 ); Assert.IsFalse( weakName1 == strongName1, "operator ==" ); Assert.IsTrue( weakName1 != strongName1, "operator !=" ); } [Test] public void TestNamesWithDifferentRunnerIDsAreNotEqual() { weakName2.RunnerID = 7; Assert.AreEqual( 0, weakName1.RunnerID ); Assert.AreNotEqual( weakName1, weakName2 ); Assert.IsFalse( weakName1 == weakName2, "operator ==" ); Assert.IsTrue( weakName1 != weakName2, "operator !=" ); strongName1.RunnerID = 3; strongName2.RunnerID = 5; strongName2.TestID = strongName1.TestID; Assert.AreNotEqual( strongName1, strongName2 ); Assert.IsFalse( strongName1 == strongName2, "operator ==" ); Assert.IsTrue( strongName1 != strongName2, "operator !=" ); } [Test] public void ClonedTestNamesAreEqual() { TestName clonedName = (TestName)weakName1.Clone(); Assert.AreEqual( weakName1, clonedName ); Assert.IsTrue( weakName1 == clonedName, "operator ==" ); Assert.IsFalse( weakName1 != clonedName, "operator !=" ); clonedName = (TestName)strongName1.Clone(); Assert.AreEqual( strongName1, clonedName ); Assert.IsTrue( strongName1 == clonedName, "operator ==" ); Assert.IsFalse( strongName1 != clonedName, "operator !=" ); } [Test] public void CanDisplayUniqueNames() { Assert.AreEqual( "[0]Name.Of.This.Test", weakName1.UniqueName ); Assert.AreEqual( "[0-" + strongName1.TestID.ToString() + "]Name.Of.This.Test", strongName1.UniqueName ); } [Test] public void CanParseSimpleTestNames() { TestName tn = TestName.Parse( "Name.Of.This.Test" ); Assert.AreEqual( "Name.Of.This.Test", tn.FullName ); } [Test] public void CanParseWeakTestNames() { TestName testName = TestName.Parse( weakName1.UniqueName ); Assert.AreEqual( weakName1, testName ); weakName1.RunnerID = 7; testName = TestName.Parse( weakName1.UniqueName ); Assert.AreEqual( weakName1, testName ); } [Test] public void CanParseStrongTestNames() { TestName testName = TestName.Parse( strongName1.UniqueName ); Assert.AreEqual( strongName1, testName ); strongName1.RunnerID = 7; testName = TestName.Parse( strongName1.UniqueName ); Assert.AreEqual( strongName1, testName ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/ParameterizedTestFixtureTests.cs0000664000175000017500000001430511544454420025341 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture("hello", "hello", "goodbye")] [TestFixture("zip", "zip")] [TestFixture(42, 42, 99)] public class ParameterizedTestFixture { private string eq1; private string eq2; private string neq; public ParameterizedTestFixture(string eq1, string eq2, string neq) { this.eq1 = eq1; this.eq2 = eq2; this.neq = neq; } public ParameterizedTestFixture(string eq1, string eq2) : this(eq1, eq2, null) { } public ParameterizedTestFixture(int eq1, int eq2, int neq) { this.eq1 = eq1.ToString(); this.eq2 = eq2.ToString(); this.neq = neq.ToString(); } [Test] public void TestEquality() { Assert.AreEqual(eq1, eq2); if (eq1 != null && eq2 != null) Assert.AreEqual(eq1.GetHashCode(), eq2.GetHashCode()); } [Test] public void TestInequality() { Assert.AreNotEqual(eq1, neq); if (eq1 != null && neq != null) Assert.AreNotEqual(eq1.GetHashCode(), neq.GetHashCode()); } } #if CLR_2_0 || CLR_4_0 [TestFixture("A", null)] [TestFixture(null, "A")] [TestFixture(null, null)] public class ParameterizedTestFixtureWithNullArguments { string a; string b; public ParameterizedTestFixtureWithNullArguments(string a, string b) { this.a = a; this.b = b; } [Test] public void TestMethod() { Assert.That(a == null || b == null); } } #endif [TestFixture(42)] public class ParameterizedTestFixtureWithDataSources { private int answer; internal object[] myData = { new int[] { 6, 7 }, new int[] { 3, 14 } }; public ParameterizedTestFixtureWithDataSources(int val) { this.answer = val; } [Test, TestCaseSource("myData")] public void CanAccessTestCaseSource(int x, int y) { Assert.That(x * y, Is.EqualTo(answer)); } #if CLR_2_0 || CLR_4_0 IEnumerable GenerateData() { for(int i = 1; i <= answer; i++) if ( answer%i == 0 ) yield return new int[] { i, answer/i }; } [Test, TestCaseSource("GenerateData")] public void CanGenerateDataFromParameter(int x, int y) { Assert.That(x * y, Is.EqualTo(answer)); } #endif internal int[] intvals = new int[] { 1, 2, 3 }; [Test] public void CanAccessValueSource( [ValueSource("intvals")] int x) { Assert.That(answer % x == 0); } } public class ParameterizedTestFixtureNamingTests { Test fixture; [SetUp] public void MakeFixture() { fixture = TestBuilder.MakeFixture(typeof(NUnit.TestData.ParameterizedTestFixture)); } [Test] public void TopLevelSuiteIsNamedCorrectly() { Assert.That(fixture.TestName.Name, Is.EqualTo("ParameterizedTestFixture")); Assert.That(fixture.TestName.FullName, Is.EqualTo("NUnit.TestData.ParameterizedTestFixture")); } [Test] public void SuiteHasCorrectNumberOfInstances() { Assert.That(fixture.Tests.Count, Is.EqualTo(2)); } [Test] public void FixtureInstancesAreNamedCorrectly() { ArrayList names = new ArrayList(); ArrayList fullnames = new ArrayList(); foreach (Test test in fixture.Tests) { names.Add(test.TestName.Name); fullnames.Add(test.TestName.FullName); } Assert.That(names, Is.EquivalentTo(new string[] { "ParameterizedTestFixture(1)", "ParameterizedTestFixture(2)" })); Assert.That(fullnames, Is.EquivalentTo(new string[] { "NUnit.TestData.ParameterizedTestFixture(1)", "NUnit.TestData.ParameterizedTestFixture(2)" })); } [Test] public void MethodWithoutParamsIsNamedCorrectly() { Test instance = (Test)fixture.Tests[0]; Test method = TestFinder.Find("MethodWithoutParams", instance, false); Assert.That(method, Is.Not.Null ); Assert.That(method.TestName.FullName, Is.EqualTo(instance.TestName.FullName + ".MethodWithoutParams")); } [Test] public void MethodWithParamsIsNamedCorrectly() { Test instance = (Test)fixture.Tests[0]; Test method = TestFinder.Find("MethodWithParams", instance, false); Assert.That(method, Is.Not.Null); Test testcase = (Test)method.Tests[0]; Assert.That(testcase.TestName.Name, Is.EqualTo("MethodWithParams(10,20)")); Assert.That(testcase.TestName.FullName, Is.EqualTo(instance.TestName.FullName + ".MethodWithParams(10,20)")); } } public class ParameterizedTestFixtureTests { [Test] public void CanSpecifyCategory() { Test fixture = TestBuilder.MakeFixture(typeof(NUnit.TestData.TestFixtureWithSingleCategory)); Assert.AreEqual(new string[] { "XYZ" }, fixture.Categories); } [Test] public void CanSpecifyMultipleCategories() { Test fixture = TestBuilder.MakeFixture(typeof(NUnit.TestData.TestFixtureWithMultipleCategories)); Assert.AreEqual(new string[] { "X", "Y", "Z" }, fixture.Categories); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/DirectorySwapperTests.cs0000664000175000017500000000263411504175260023644 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using NUnit.Framework; namespace NUnit.Core.Tests { /// /// Tests of the DirectorySwapper class /// [TestFixture] public class DirectorySwapperTests { private string thisDirectory; private string driveRoot; [SetUp] public void Init() { thisDirectory = Environment.CurrentDirectory; driveRoot = Path.GetPathRoot( thisDirectory ); } [TearDown] public void Cleanup() { Environment.CurrentDirectory = thisDirectory; } [Test] public void ChangeAndRestore() { using( new DirectorySwapper() ) { Assert.AreEqual( thisDirectory, Environment.CurrentDirectory ); Environment.CurrentDirectory = driveRoot; Assert.AreEqual( driveRoot, Environment.CurrentDirectory ); } Assert.AreEqual( thisDirectory, Environment.CurrentDirectory ); } [Test] public void SwapAndRestore() { using( new DirectorySwapper( driveRoot ) ) { Assert.AreEqual( driveRoot, Environment.CurrentDirectory ); } Assert.AreEqual( thisDirectory, Environment.CurrentDirectory ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/PropertyAttributeTests.cs0000664000175000017500000000247011504175260024044 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData.PropertyAttributeTests; namespace NUnit.Core.Tests { [TestFixture] public class PropertyAttributeTests { TestSuite fixture; [SetUp] public void CreateFixture() { fixture = TestBuilder.MakeFixture( typeof( FixtureWithProperties ) ); } [Test] public void PropertyWithStringValue() { Test test1 = (Test)fixture.Tests[0]; Assert.AreEqual( "Charlie", test1.Properties["user"] ); } [Test] public void PropertiesWithNumericValues() { Test test2 = (Test)fixture.Tests[1]; Assert.AreEqual( 10.0, test2.Properties["X"] ); Assert.AreEqual( 17.0, test2.Properties["Y"] ); } [Test] public void PropertyWorksOnFixtures() { Assert.AreEqual( "SomeClass", fixture.Properties["ClassUnderTest"] ); } [Test] public void CanDeriveFromPropertyAttribute() { Test test3 = (Test)fixture.Tests[2]; Assert.AreEqual( 5, test3.Properties["Priority"] ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestFixtureExtension.cs0000664000175000017500000000370611504175260023477 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.TestUtilities; using NUnit.TestData.TestFixtureExtension; namespace NUnit.Core.Tests { /// /// Summary description for TestFixtureExtension. /// /// [TestFixture] public class TestFixtureExtension { private Test suite; private void RunTestOnFixture( object fixture ) { Test suite = TestBuilder.MakeFixture( fixture ); suite.Run(NullListener.NULL, TestFilter.Empty); } [SetUp] public void LoadFixture() { string testsDll = AssemblyHelper.GetAssemblyPath(typeof(DerivedTestFixture)); TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage( testsDll ); package.TestName = typeof(DerivedTestFixture).FullName; suite= builder.Build( package ); } [Test] public void CheckMultipleSetUp() { SetUpDerivedTestFixture fixture = new SetUpDerivedTestFixture(); RunTestOnFixture( fixture ); Assert.AreEqual(true, fixture.baseSetup); } [Test] public void DerivedTest() { Assert.IsNotNull(suite); TestResult result = suite.Run(NullListener.NULL, TestFilter.Empty); Assert.IsTrue(result.IsSuccess); } [Test] public void InheritSetup() { DerivedTestFixture fixture = new DerivedTestFixture(); RunTestOnFixture( fixture ); Assert.AreEqual(true, fixture.baseSetup); } [Test] public void InheritTearDown() { DerivedTestFixture fixture = new DerivedTestFixture(); RunTestOnFixture( fixture ); Assert.AreEqual(true, fixture.baseTeardown); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/UnhandledExceptionTests.cs0000664000175000017500000000445611504175260024123 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Text; using NUnit.Framework; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture, Explicit("These tests fail by design")] public class UnhandledExceptionTests { #region Normal [NUnit.Framework.Test] public void Normal() { testDummy("Normal", false); } private static void testDummy(string dummyName, bool shouldPass) { Type fixtureType = typeof(NUnit.TestData.UnhandledExceptions); Test test = TestBuilder.MakeTestCase(fixtureType, dummyName); TestResult result = test.Run(NullListener.NULL, TestFilter.Empty); if (shouldPass) Assert.IsTrue(result.IsSuccess, "{0} test should have passed", dummyName); else { Assert.IsTrue(result.IsFailure, "{0} test should have failed", dummyName); Assert.AreEqual("System.ApplicationException : Test exception", result.Message); } } #endregion Normal #region Threaded [NUnit.Framework.Test] public void Threaded() { // TODO: Make this fail testDummy("Threaded", true); } #endregion Threaded #region ThreadedAndWait [NUnit.Framework.Test] public void ThreadedAndWait() { // TODO: Make this fail testDummy("ThreadedAndWait", true); } #endregion ThreadedAndWait #region ThreadedAndForget [NUnit.Framework.Test] public void ThreadedAndForget() { // TODO: Make this fail testDummy("ThreadedAndForget", true); } #endregion ThreadedAndForget #region ThreadedAssert [NUnit.Framework.Test] public void ThreadedAssert() { testDummy("ThreadedAssert", true); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/tests/SerializationBug.cs0000664000175000017500000000337111543625326022573 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Runtime.Serialization; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class SerializationBug { private static readonly string fileName = Path.GetTempFileName(); [Serializable] public class Perob { public int i; public int j; public Perob(int ii,int jj) { i = ii; j = jj; } public void Serialize(string filename) { StreamWriter stm = new StreamWriter(File.OpenWrite( filename )); BinaryFormatter bf=new BinaryFormatter(); bf.Serialize(stm.BaseStream,this); stm.Close(); } public static Perob Deserialize(string filename) { Perob rv; using (StreamReader stm = new StreamReader(File.OpenRead( filename ))) { BinaryFormatter bf=new BinaryFormatter(); object obj = bf.Deserialize(stm.BaseStream); rv = obj as Perob; } return rv; } } [TearDown] public void CleanUp() { FileInfo file = new FileInfo(fileName); if(file.Exists) file.Delete(); } [Test] public void SaveAndLoad() { Perob p = new Perob(3,4); p.Serialize( fileName ); Perob np = Perob.Deserialize( fileName ); Assert.IsNotNull(np, "np != null"); Assert.AreEqual(p.i, np.i, "i neq" ); Assert.AreEqual(p.j, np.j, "j neq" ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/SetCultureAttributeTests.cs0000664000175000017500000001040011504175260024307 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Threading; using System.Globalization; using NUnit.Framework; using NUnit.TestData.CultureAttributeTests; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class SetCultureAttributeTests { private CultureInfo originalCulture; // private CultureInfo originalUICulture; [SetUp] public void Setup() { originalCulture = CultureInfo.CurrentCulture; // originalUICulture = CultureInfo.CurrentUICulture; } [Test, SetUICulture("fr-FR")] public void SetUICultureOnlyToFrench() { Assert.AreEqual(CultureInfo.CurrentCulture, originalCulture, "Culture should not change"); Assert.AreEqual("fr-FR", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetUICulture("fr-CA")] public void SetUICultureOnlyToFrenchCanadian() { Assert.AreEqual(CultureInfo.CurrentCulture, originalCulture, "Culture should not change"); Assert.AreEqual("fr-CA", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetUICulture("ru-RU")] public void SetUICultureOnlyToRussian() { Assert.AreEqual(CultureInfo.CurrentCulture, originalCulture, "Culture should not change"); Assert.AreEqual("ru-RU", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetCulture("fr-FR"), SetUICulture("fr-FR")] public void SetBothCulturesToFrench() { Assert.AreEqual("fr-FR", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("fr-FR", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetCulture("fr-CA"), SetUICulture("fr-CA")] public void SetBothCulturesToFrenchCanadian() { Assert.AreEqual("fr-CA", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("fr-CA", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetCulture("ru-RU"), SetUICulture("ru-RU")] public void SetBothCulturesToRussian() { Assert.AreEqual("ru-RU", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("ru-RU", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetCulture("fr-FR"), SetUICulture("fr-CA")] public void SetMixedCulturesToFrenchAndUIFrenchCanadian() { Assert.AreEqual("fr-FR", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("fr-CA", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetCulture("ru-RU"), SetUICulture("en-US")] public void SetMixedCulturesToRussianAndUIEnglishUS() { Assert.AreEqual("ru-RU", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("en-US", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [TestFixture, SetCulture("ru-RU"), SetUICulture("ru-RU")] class NestedBehavior { [Test] public void InheritedRussian() { Assert.AreEqual("ru-RU", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("ru-RU", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } [Test, SetUICulture("fr-FR")] public void InheritedRussianWithUIFrench() { Assert.AreEqual("ru-RU", CultureInfo.CurrentCulture.Name, "Culture not set correctly"); Assert.AreEqual("fr-FR", CultureInfo.CurrentUICulture.Name, "UICulture not set correctly"); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/RuntimeFrameworkTests.cs0000664000175000017500000002715111720453302023634 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class RuntimeFrameworkTests { static RuntimeType currentRuntime = Type.GetType("Mono.Runtime", false) != null ? RuntimeType.Mono : RuntimeType.Net; [Test] public void CanGetCurrentFramework() { RuntimeFramework framework = RuntimeFramework.CurrentFramework; Assert.That(framework.Runtime, Is.EqualTo(currentRuntime)); Assert.That(framework.ClrVersion, Is.EqualTo(Environment.Version)); } [Test] public void CurrentFrameworkHasBuildSpecified() { Assert.That(RuntimeFramework.CurrentFramework.ClrVersion.Build, Is.GreaterThan(0)); } [Test] public void CurrentFrameworkMustBeAvailable() { Assert.That(RuntimeFramework.CurrentFramework.IsAvailable); } [Test] public void CanListAvailableFrameworks() { RuntimeFramework[] available = RuntimeFramework.AvailableFrameworks; Assert.That(available, Has.Length.GreaterThan(0) ); bool foundCurrent = false; foreach (RuntimeFramework framework in available) { Console.WriteLine("Available: {0}", framework.DisplayName); foundCurrent |= RuntimeFramework.CurrentFramework.Supports(framework); } Assert.That(foundCurrent, "CurrentFramework not listed"); } [TestCaseSource("frameworkData")] public void CanCreateUsingFrameworkVersion(FrameworkData data) { RuntimeFramework framework = new RuntimeFramework(data.runtime, data.frameworkVersion); Assert.AreEqual(data.runtime, framework.Runtime); Assert.AreEqual(data.frameworkVersion, framework.FrameworkVersion); Assert.AreEqual(data.clrVersion, framework.ClrVersion); } [TestCaseSource("frameworkData")] public void CanCreateUsingClrVersion(FrameworkData data) { Assume.That(data.frameworkVersion.Major != 3); RuntimeFramework framework = new RuntimeFramework(data.runtime, data.clrVersion); Assert.AreEqual(data.runtime, framework.Runtime); Assert.AreEqual(data.frameworkVersion, framework.FrameworkVersion); Assert.AreEqual(data.clrVersion, framework.ClrVersion); } [TestCaseSource("frameworkData")] public void CanParseRuntimeFramework(FrameworkData data) { RuntimeFramework framework = RuntimeFramework.Parse(data.representation); Assert.AreEqual(data.runtime, framework.Runtime); Assert.AreEqual(data.clrVersion, framework.ClrVersion); } [TestCaseSource("frameworkData")] public void CanDisplayFrameworkAsString(FrameworkData data) { RuntimeFramework framework = new RuntimeFramework(data.runtime, data.frameworkVersion); Assert.AreEqual(data.representation, framework.ToString()); Assert.AreEqual(data.displayName, framework.DisplayName); } [TestCaseSource("matchData")] public bool CanMatchRuntimes(RuntimeFramework f1, RuntimeFramework f2) { return f1.Supports(f2); } internal static TestCaseData[] matchData = new TestCaseData[] { new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(3,5)), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Net, new Version(3,5))) .Returns(false), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(3,5)), new RuntimeFramework(RuntimeType.Net, new Version(3,5))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Net, new Version(2,0,50727))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0,50727)), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0,50727)), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Mono, new Version(2,0))) .Returns(false), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Net, new Version(1,1))) .Returns(false), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0,50727)), new RuntimeFramework(RuntimeType.Net, new Version(2,0,40607))) .Returns(false), new TestCaseData( new RuntimeFramework(RuntimeType.Mono, new Version(1,1)), // non-existent version but it works new RuntimeFramework(RuntimeType.Mono, new Version(1,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Mono, new Version(2,0)), new RuntimeFramework(RuntimeType.Any, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Any, new Version(2,0)), new RuntimeFramework(RuntimeType.Mono, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Any, new Version(2,0)), new RuntimeFramework(RuntimeType.Any, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Any, new Version(2,0)), new RuntimeFramework(RuntimeType.Any, new Version(4,0))) .Returns(false), new TestCaseData( new RuntimeFramework(RuntimeType.Net, RuntimeFramework.DefaultVersion), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Net, RuntimeFramework.DefaultVersion)) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Any, RuntimeFramework.DefaultVersion), new RuntimeFramework(RuntimeType.Net, new Version(2,0))) .Returns(true), new TestCaseData( new RuntimeFramework(RuntimeType.Net, new Version(2,0)), new RuntimeFramework(RuntimeType.Any, RuntimeFramework.DefaultVersion)) .Returns(true) }; public struct FrameworkData { public RuntimeType runtime; public Version frameworkVersion; public Version clrVersion; public string representation; public string displayName; public FrameworkData(RuntimeType runtime, Version frameworkVersion, Version clrVersion, string representation, string displayName) { this.runtime = runtime; this.frameworkVersion = frameworkVersion; this.clrVersion = clrVersion; this.representation = representation; this.displayName = displayName; } public override string ToString() { return string.Format("<{0},{1},{2}>", this.runtime, this.frameworkVersion, this.clrVersion); } } internal FrameworkData[] frameworkData = new FrameworkData[] { new FrameworkData(RuntimeType.Net, new Version(1,0), new Version(1,0,3705), "net-1.0", "Net 1.0"), //new FrameworkData(RuntimeType.Net, new Version(1,0,3705), new Version(1,0,3705), "net-1.0.3705", "Net 1.0.3705"), //new FrameworkData(RuntimeType.Net, new Version(1,0), new Version(1,0,3705), "net-1.0.3705", "Net 1.0.3705"), new FrameworkData(RuntimeType.Net, new Version(1,1), new Version(1,1,4322), "net-1.1", "Net 1.1"), //new FrameworkData(RuntimeType.Net, new Version(1,1,4322), new Version(1,1,4322), "net-1.1.4322", "Net 1.1.4322"), new FrameworkData(RuntimeType.Net, new Version(2,0), new Version(2,0,50727), "net-2.0", "Net 2.0"), //new FrameworkData(RuntimeType.Net, new Version(2,0,40607), new Version(2,0,40607), "net-2.0.40607", "Net 2.0.40607"), //new FrameworkData(RuntimeType.Net, new Version(2,0,50727), new Version(2,0,50727), "net-2.0.50727", "Net 2.0.50727"), new FrameworkData(RuntimeType.Net, new Version(3,0), new Version(2,0,50727), "net-3.0", "Net 3.0"), new FrameworkData(RuntimeType.Net, new Version(3,5), new Version(2,0,50727), "net-3.5", "Net 3.5"), new FrameworkData(RuntimeType.Net, new Version(4,0), new Version(4,0,30319), "net-4.0", "Net 4.0"), new FrameworkData(RuntimeType.Net, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "net", "Net"), new FrameworkData(RuntimeType.Mono, new Version(1,0), new Version(1,1,4322), "mono-1.0", "Mono 1.0"), new FrameworkData(RuntimeType.Mono, new Version(2,0), new Version(2,0,50727), "mono-2.0", "Mono 2.0"), //new FrameworkData(RuntimeType.Mono, new Version(2,0,50727), new Version(2,0,50727), "mono-2.0.50727", "Mono 2.0.50727"), new FrameworkData(RuntimeType.Mono, new Version(3,5), new Version(2,0,50727), "mono-3.5", "Mono 3.5"), new FrameworkData(RuntimeType.Mono, new Version(4,0), new Version(4,0,30319), "mono-4.0", "Mono 4.0"), new FrameworkData(RuntimeType.Mono, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "mono", "Mono"), new FrameworkData(RuntimeType.Any, new Version(1,1), new Version(1,1,4322), "v1.1", "v1.1"), new FrameworkData(RuntimeType.Any, new Version(2,0), new Version(2,0,50727), "v2.0", "v2.0"), //new FrameworkData(RuntimeType.Any, new Version(2,0,50727), new Version(2,0,50727), "v2.0.50727", "v2.0.50727"), new FrameworkData(RuntimeType.Any, new Version(3,5), new Version(2,0,50727), "v3.5", "v3.5"), new FrameworkData(RuntimeType.Any, new Version(4,0), new Version(4,0,30319), "v4.0", "v4.0"), new FrameworkData(RuntimeType.Any, RuntimeFramework.DefaultVersion, RuntimeFramework.DefaultVersion, "any", "Any") }; } } NUnit-2.6.0.12051/src/NUnitCore/tests/DirectoryChangeTests.cs0000664000175000017500000000145111504175260023404 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2010, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.TestData; using NUnit.TestUtilities; namespace NUnit.Core.Tests { [TestFixture] public class DirectoryChangeTests { [Test] public void ChangingCurrentDirectoryGivesWarning() { TestResult result = TestBuilder.RunTestCase(typeof(DirectoryChangeFixture), "ChangeCurrentDirectory"); Assert.AreEqual(ResultState.Success, result.ResultState); Assert.AreEqual("Warning: Test changed the CurrentDirectory", result.Message); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AssertPassFixture.cs0000664000175000017500000000235711504175260022754 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; namespace NUnit.Core.Tests { [TestFixture] public class AssertPassFixture { [Test] public void AssertPassReturnsSuccess() { Assert.Pass("This test is OK!"); } [Test] public void SubsequentFailureIsIrrelevant() { Assert.Pass("This test is OK!"); Assert.Fail("No it's NOT!"); } } [TestFixture] public class AssertInconclusiveFixture { [Test] public void AssertInconclusiveThrowsException() { Exception ex = Assert.Throws( typeof(InconclusiveException), new TestDelegate(InconclusiveTest)); Assert.AreEqual("Unable to run test", ex.Message); } private static void InconclusiveTest() { Assert.Inconclusive("Unable to run test"); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/RemoteRunnerTests.cs0000664000175000017500000000127711504175260022765 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.Util; using NUnit.Tests.Assemblies; namespace NUnit.Core.Tests { [TestFixture] public class RemoteRunnerTests : BasicRunnerTests { protected override TestRunner CreateRunner( int runnerID ) { return new RemoteTestRunner( runnerID ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/EventQueueTests.cs0000664000175000017500000005312011676062546022434 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using System.Diagnostics; using System.IO; using System.Threading; using NUnit.Core.Extensibility; using NUnit.Framework; using ThreadState = System.Threading.ThreadState; namespace NUnit.Core.Tests { /// /// Summary description for EventQueueTests. /// [TestFixture] public class EventQueueTests { static readonly Event[] events = { new RunStartedEvent( string.Empty, 0 ), new SuiteStartedEvent( null ), new OutputEvent( new TestOutput( string.Empty, TestOutputType.Log )), new TestStartedEvent( null ), new OutputEvent( new TestOutput( string.Empty, TestOutputType.Out )), new TestFinishedEvent( null ), new OutputEvent( new TestOutput( string.Empty, TestOutputType.Trace )), new SuiteFinishedEvent( null ), new RunFinishedEvent( (TestResult)null ) }; private static void EnqueueEvents(EventQueue q) { foreach (Event e in events) q.Enqueue(e); } private static void SendEvents(EventListener el) { foreach (Event e in events) e.Send(el); } private static void VerifyQueue(EventQueue q) { for (int index = 0; index < events.Length; index++) { Event e = q.Dequeue(false); Assert.AreEqual(events[index].GetType(), e.GetType(), string.Format("Event {0}", index)); } } private static void StartPump(EventPump pump, int waitTime) { pump.Start(); WaitForPumpToStart(pump, waitTime); } private static void StopPump(EventPump pump, int waitTime) { pump.Stop(); WaitForPumpToStop(pump, waitTime); } private static void WaitForPumpToStart(EventPump pump, int waitTime) { while (waitTime > 0 && pump.PumpState != EventPumpState.Pumping) { Thread.Sleep(100); waitTime -= 100; } } private static void WaitForPumpToStop(EventPump pump, int waitTime) { while (waitTime > 0 && pump.PumpState != EventPumpState.Stopped) { Thread.Sleep(100); waitTime -= 100; } } #region EventQueue tests [Test] public void QueueEvents() { EventQueue q = new EventQueue(); EnqueueEvents(q); VerifyQueue(q); } [Test] public void DequeueEmpty() { EventQueue q = new EventQueue(); Assert.IsNull(q.Dequeue(false)); } [TestFixture] public class DequeueBlocking_StopTest : ProducerConsumerTest { private EventQueue q; private volatile int receivedEvents; [Test] [Timeout(1000)] public void DequeueBlocking_Stop() { this.q = new EventQueue(); this.receivedEvents = 0; this.RunProducerConsumer(); Assert.AreEqual(events.Length + 1, this.receivedEvents); } protected override void Producer() { EnqueueEvents(this.q); while (this.receivedEvents < events.Length) { Thread.Sleep(30); } this.q.Stop(); } protected override void Consumer() { Event e; do { e = this.q.Dequeue(true); this.receivedEvents++; Thread.MemoryBarrier(); } while (e != null); } } [TestFixture] public class SetWaitHandle_Enqueue_SynchronousTest : ProducerConsumerTest { private EventQueue q; private AutoResetEvent waitHandle; private volatile bool afterEnqueue; [Test] [Timeout(1000)] public void SetWaitHandle_Enqueue_Synchronous() { using (this.waitHandle = new AutoResetEvent(false)) { this.q = new EventQueue(); this.q.SetWaitHandleForSynchronizedEvents(this.waitHandle); this.afterEnqueue = false; this.RunProducerConsumer(); } } protected override void Producer() { Event synchronousEvent = new RunStartedEvent(string.Empty, 0); Assert.IsTrue(synchronousEvent.IsSynchronous); this.q.Enqueue(synchronousEvent); this.afterEnqueue = true; Thread.MemoryBarrier(); } protected override void Consumer() { this.q.Dequeue(true); Thread.Sleep(30); Assert.IsFalse(this.afterEnqueue); this.waitHandle.Set(); Thread.Sleep(30); Assert.IsTrue(this.afterEnqueue); } } [TestFixture] public class SetWaitHandle_Enqueue_AsynchronousTest : ProducerConsumerTest { private EventQueue q; private volatile bool afterEnqueue; [Test] [Timeout(1000)] public void SetWaitHandle_Enqueue_Asynchronous() { using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { this.q = new EventQueue(); this.q.SetWaitHandleForSynchronizedEvents(waitHandle); this.afterEnqueue = false; this.RunProducerConsumer(); } } protected override void Producer() { Event asynchronousEvent = new OutputEvent(new TestOutput(string.Empty, TestOutputType.Trace)); Assert.IsFalse(asynchronousEvent.IsSynchronous); this.q.Enqueue(asynchronousEvent); this.afterEnqueue = true; Thread.MemoryBarrier(); } protected override void Consumer() { this.q.Dequeue(true); Thread.Sleep(30); Assert.IsTrue(this.afterEnqueue); } } #endregion EventQueue tests #region QueuingEventListener tests [Test] public void SendEvents() { QueuingEventListener el = new QueuingEventListener(); SendEvents(el); VerifyQueue(el.Events); } #endregion #region EventPump tests [Test] public void StartAndStopPumpOnEmptyQueue() { EventQueue q = new EventQueue(); using (EventPump pump = new EventPump(NullListener.NULL, q, false)) { pump.Name = "StartAndStopPumpOnEmptyQueue"; StartPump(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Pumping)); StopPump(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); } } [Test] public void PumpAutoStopsOnRunFinished() { EventQueue q = new EventQueue(); using (EventPump pump = new EventPump(NullListener.NULL, q, true)) { pump.Name = "PumpAutoStopsOnRunFinished"; Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); StartPump(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Pumping)); q.Enqueue(new RunFinishedEvent(new Exception())); WaitForPumpToStop(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); } } [Test] [Timeout(3000)] public void PumpEvents() { EventQueue q = new EventQueue(); QueuingEventListener el = new QueuingEventListener(); using (EventPump pump = new EventPump(el, q, false)) { pump.Name = "PumpEvents"; Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); StartPump(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Pumping)); EnqueueEvents(q); StopPump(pump, 1000); Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); } VerifyQueue(el.Events); } [Test] [Timeout(2000)] public void PumpEventsWithAutoStop() { EventQueue q = new EventQueue(); QueuingEventListener el = new QueuingEventListener(); using (EventPump pump = new EventPump(el, q, true)) { pump.Name = "PumpEventsWithAutoStop"; pump.Start(); EnqueueEvents(q); int tries = 10; while (--tries > 0 && q.Count > 0) { Thread.Sleep(100); } Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); } } [Test] [Timeout(2000)] public void PumpPendingEventsAfterAutoStop() { EventQueue q = new EventQueue(); EnqueueEvents(q); Event[] eventsAfterStop = { new OutputEvent(new TestOutput("foo", TestOutputType.Out)), new OutputEvent(new TestOutput("bar", TestOutputType.Trace)), }; foreach (Event e in eventsAfterStop) { q.Enqueue(e); } QueuingEventListener el = new QueuingEventListener(); using (EventPump pump = new EventPump(el, q, true)) { pump.Name = "PumpPendingEventsAfterAutoStop"; pump.Start(); int tries = 10; while (--tries > 0 && q.Count > 0) { Thread.Sleep(100); } Assert.That(pump.PumpState, Is.EqualTo(EventPumpState.Stopped)); } Assert.That(el.Events.Count, Is.EqualTo(events.Length + eventsAfterStop.Length)); } [Test] [Timeout(1000)] public void PumpSynchronousAndAsynchronousEvents() { EventQueue q = new EventQueue(); using (EventPump pump = new EventPump(NullListener.NULL, q, false)) { pump.Name = "PumpSynchronousAndAsynchronousEvents"; pump.Start(); int numberOfAsynchronousEvents = 0; int sumOfAsynchronousQueueLength = 0; const int Repetitions = 2; for (int i = 0; i < Repetitions; i++) { foreach (Event e in events) { q.Enqueue(e); if (e.IsSynchronous) { Assert.That(q.Count, Is.EqualTo(0)); } else { sumOfAsynchronousQueueLength += q.Count; numberOfAsynchronousEvents++; } } } Console.WriteLine("Average queue length: {0}", (float)sumOfAsynchronousQueueLength / numberOfAsynchronousEvents); } } /// /// Verifies that when /// (1) Traces are captured and fed into the EventListeners, and /// (2) an EventListener writes Traces, /// the Trace / EventPump / EventListener do not deadlock. /// /// /// This mainly simulates the object structure created by RemoteTestRunner.Run. /// [Test] [Timeout(1000)] public void TracingEventListenerDoesNotDeadlock() { QueuingEventListener upstreamListener = new QueuingEventListener(); EventQueue upstreamListenerQueue = upstreamListener.Events; // Install a TraceListener sending TestOutput events to the upstreamListener. // This simulates RemoteTestRunner.StartTextCapture, where TestContext installs such a TraceListener. TextWriter traceWriter = new EventListenerTextWriter(upstreamListener, TestOutputType.Trace); const string TraceListenerName = "TracingEventListenerDoesNotDeadlock"; TraceListener feedingTraceToUpstreamListener = new TextWriterTraceListener(traceWriter, TraceListenerName); try { Trace.Listeners.Add(feedingTraceToUpstreamListener); // downstreamListenerToTrace simulates an EventListener installed e.g. by an Addin, // which may call Trace within the EventListener methods: TracingEventListener downstreamListenerToTrace = new TracingEventListener(); using (EventPump pump = new EventPump(downstreamListenerToTrace, upstreamListenerQueue, false)) { pump.Name = "TracingEventListenerDoesNotDeadlock"; pump.Start(); const int Repetitions = 10; for (int i = 0; i < Repetitions; i++) { foreach (Event e in events) { Trace.WriteLine("Before sending {0} event.", e.GetType().Name); e.Send(upstreamListener); Trace.WriteLine("After sending {0} event.", e.GetType().Name); } } } } finally { Trace.Listeners.Remove(TraceListenerName); feedingTraceToUpstreamListener.Dispose(); } } /// /// Floods the queue of an EventPump with multiple concurrent event producers. /// Prints the maximum queue length to Console, but does not implement an /// oracle on what the maximum queue length should be. /// /// The number of concurrent producer threads. /// /// If true, the producer threads slow down by adding a short delay time. /// [TestCase(1, false)] [TestCase(5, true)] [TestCase(5, false)] [Explicit("Takes several seconds. Just prints the queue length of the EventPump to Console, but has no oracle regarding this.")] public void EventPumpQueueLength(int numberOfProducers, bool producerDelay) { EventQueue q = new EventQueue(); EventProducer[] producers = new EventProducer[numberOfProducers]; for (int i = 0; i < numberOfProducers; i++) { producers[i] = new EventProducer(q, i, producerDelay); } using (EventPump pump = new EventPump(NullListener.NULL, q, false)) { pump.Name = "EventPumpQueueLength"; pump.Start(); foreach (EventProducer p in producers) { p.ProducerThread.Start(); } foreach (EventProducer p in producers) { p.ProducerThread.Join(); } pump.Stop(); } Assert.That(q.Count, Is.EqualTo(0)); foreach (EventProducer p in producers) { Console.WriteLine( "#Events: {0}, MaxQueueLength: {1}", p.SentEventsCount, p.MaxQueueLength); Assert.IsNull(p.Exception, "{0}", p.Exception); } } #endregion public abstract class ProducerConsumerTest { private volatile Exception myConsumerException; protected void RunProducerConsumer() { this.myConsumerException = null; Thread consumerThread = new Thread(new ThreadStart(this.ConsumerThreadWrapper)); try { consumerThread.Start(); this.Producer(); bool consumerStopped = consumerThread.Join(1000); Assert.IsTrue(consumerStopped); } finally { ThreadUtility.Kill(consumerThread); } Assert.IsNull(this.myConsumerException); } protected abstract void Producer(); protected abstract void Consumer(); private void ConsumerThreadWrapper() { try { this.Consumer(); } catch (ThreadAbortException) { Thread.ResetAbort(); } catch (Exception ex) { this.myConsumerException = ex; } } } private class EventProducer { public readonly Thread ProducerThread; public int SentEventsCount; public int MaxQueueLength; public Exception Exception; private readonly EventQueue queue; private readonly bool delay; public EventProducer(EventQueue q, int id, bool delay) { this.queue = q; this.ProducerThread = new Thread(new ThreadStart(this.Produce)); this.ProducerThread.Name = this.GetType().FullName + id; this.delay = delay; } private void Produce() { try { Event e = new OutputEvent(new TestOutput(this.ProducerThread.Name, TestOutputType.Log)); DateTime start = DateTime.Now; while (DateTime.Now - start <= TimeSpan.FromSeconds(3)) { this.queue.Enqueue(e); this.SentEventsCount++; this.MaxQueueLength = Math.Max(this.queue.Count, this.MaxQueueLength); // without Sleep or with just a Sleep(0), the EventPump thread does not keep up and the queue gets very long if (this.delay) { Thread.Sleep(1); } } } catch (Exception ex) { this.Exception = ex; } } } private class TracingEventListener : EventListener { #region EventListener Members public void RunStarted(string name, int testCount) { WriteTrace("RunStarted({0},{1})", name, testCount); } public void RunFinished(TestResult result) { WriteTrace("RunFinished({0})", result); } public void RunFinished(Exception exception) { WriteTrace("RunFinished({0})", exception); } public void TestStarted(TestName testName) { WriteTrace("TestStarted({0})", testName); } public void TestFinished(TestResult result) { WriteTrace("TestFinished({0})", result); } public void SuiteStarted(TestName testName) { WriteTrace("SuiteStarted({0})", testName); } public void SuiteFinished(TestResult result) { WriteTrace("SuiteFinished({0})", result); } public void UnhandledException(Exception exception) { WriteTrace("UnhandledException({0})", exception); } public void TestOutput(TestOutput testOutput) { if (testOutput.Type != TestOutputType.Trace) { WriteTrace("TestOutput {0}: '{1}'", testOutput.Type, testOutput.Text); } } #endregion #if CLR_2_0 || CLR_4_0 private static void WriteTrace(string message, params object[] args) { Trace.TraceInformation(message, args); } #else private static void WriteTrace(string message, params object[] args) { Trace.WriteLine(string.Format(message, args)); } #endif } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TheoryTests.cs0000664000175000017500000001006611504175260021606 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData; namespace NUnit.Core.Tests { public class TheoryTests { static Type fixtureType = typeof(TheoryFixture); [Test] public void TheoryWithNoArgumentsIsTreatedAsTest() { TestAssert.IsRunnable(fixtureType, "TheoryWithNoArguments"); } [Test] public void TheoryWithNoDatapointsIsNotRunnable() { TestAssert.IsNotRunnable(fixtureType, "TheoryWithArgumentsButNoDatapoints"); } [Test] public void BooleanArgumentsAreSuppliedAutomatically() { Test test = TestBuilder.MakeTestCase(fixtureType, "TestWithBooleanArguments"); TestAssert.IsRunnable(test); Assert.That(test.TestCount, Is.EqualTo(4)); } [Theory] public void NullDatapointIsOK(object o) { } [Datapoint] internal object objData = null; [Test] public void EnumArgumentsAreSuppliedAutomatically() { Test test = TestBuilder.MakeTestCase(fixtureType, "TestWithEnumAsArgument"); TestAssert.IsRunnable(test); Assert.That(test.TestCount, Is.EqualTo(3)); } [Test] public void TheoryWithDatapointsIsRunnable() { Test test = TestBuilder.MakeTestCase(fixtureType, "TheoryWithArgumentsAndDatapoints"); TestAssert.IsRunnable(test); Assert.That(test.TestCount, Is.EqualTo(9)); } [Theory] public void SquareRootWithAllGoodValues( [Values(12.0, 4.0, 9.0)] double d) { SquareRootTest(d); } [Theory] public void SquareRootWithOneBadValue( [Values(12.0, -4.0, 9.0)] double d) { SquareRootTest(d); } [Datapoints] internal string[] vals = new string[] { "xyz1", "xyz2", "xyz3" }; [Theory] public void ArrayWithDatapointsAttributeIsUsed(string s) { Assert.That(s.StartsWith("xyz")); } //[Datapoint] //public double[,] Array2X2 = new double[,] { { 1, 0 }, { 0, 1 } }; //[Theory] //public void TestForArbitraryArray(T[,] array) //{ //} private void SquareRootTest(double d) { Assume.That(d > 0); double root = Math.Sqrt(d); Assert.That(root * root, Is.EqualTo(d).Within(0.000001)); Assert.That(root > 0); } [Test] public void SimpleTestIgnoresDataPoints() { Test test = TestBuilder.MakeTestCase(fixtureType, "TestWithArguments"); Assert.That(test.TestCount, Is.EqualTo(2)); } [Theory] public void TheoryFailsIfAllTestsAreInconclusive() { TestResult result = TestBuilder.RunTestCase(fixtureType, "TestWithAllBadValues"); Assert.That(result.ResultState, Is.EqualTo(ResultState.Failure)); Assert.That(result.Message, Is.EqualTo("All test cases were inconclusive")); } public class SqrtTests_DisplayResults { [Datapoints] public double[] values = new double[] { 0.0, 1.0, -1.0, double.MaxValue, double.PositiveInfinity }; [Theory] public void SqrtTimesItselfGivesOriginal(double num) { Assume.That(num >= 0.0 && num < double.MaxValue); double sqrt = Math.Sqrt(num); Assert.That(sqrt >= 0.0); Assert.That(sqrt * sqrt, Is.EqualTo(num).Within(0.000001)); } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/FailFixture.cs0000664000175000017500000000463211504175260021535 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.TestUtilities; using NUnit.TestData.FailFixture; namespace NUnit.Core.Tests { [TestFixture] public class FailFixture { [Test] public void VerifyFailWorks() { TestResult result = TestBuilder.RunTestCase( typeof(VerifyFailThrowsException), "CallAssertFail" ); Assert.IsTrue(result.IsFailure, "Should have failed"); Assert.AreEqual( VerifyFailThrowsException.failureMessage, result.Message); } [Test] [ExpectedException(typeof(AssertionException))] public void FailThrowsAssertionException() { Assert.Fail(String.Empty); } [Test] public void FailInheritsFromSystemException() { try { Assert.Fail(); } catch (System.Exception) { return; } throw new AssertionException("fail"); // You can't call fail() here } [Test] public void FailRecordsInnerException() { Type fixtureType = typeof(VerifyTestResultRecordsInnerExceptions); string expectedMessage ="System.Exception : Outer Exception" + Environment.NewLine + " ----> System.Exception : Inner Exception"; NUnit.Core.TestResult result = TestBuilder.RunTestCase(fixtureType, "ThrowInnerException"); Assert.AreEqual(ResultState.Error, result.ResultState ); Assert.AreEqual(expectedMessage, result.Message); } [Test] public void BadStackTraceIsHandled() { TestResult result = TestBuilder.RunTestCase( typeof( BadStackTraceFixture ), "TestFailure" ); Assert.AreEqual( ResultState.Error, result.ResultState ); Assert.AreEqual( "NUnit.TestData.FailFixture.ExceptionWithBadStackTrace : thrown by me", result.Message ); Assert.AreEqual( "No stack trace available", result.StackTrace ); } [Test] public void CustomExceptionIsHandled() { TestResult result = TestBuilder.RunTestCase( typeof( CustomExceptionFixture ), "ThrowCustomException" ); Assert.AreEqual( ResultState.Error, result.ResultState ); Assert.AreEqual( "NUnit.TestData.FailFixture.CustomExceptionFixture+CustomException : message", result.Message ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/TestInfoTests.cs0000664000175000017500000000405111504175260022064 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using NUnit.Framework; using NUnit.Tests.Assemblies; using NUnit.TestUtilities; namespace NUnit.Core.Tests { /// /// Summary description for TestInfoTests. /// [TestFixture] public class TestInfoTests { TestSuite testSuite; TestSuite testFixture; Test testCase1; [SetUp] public void SetUp() { testSuite = new TestSuite("MyTestSuite"); testFixture = TestBuilder.MakeFixture( typeof( MockTestFixture ) ); testSuite.Add( testFixture ); testCase1 = (Test)testFixture.Tests[0]; } private void CheckConstructionFromTest( ITest expected ) { TestInfo actual = new TestInfo( expected ); Assert.AreEqual( expected.TestName, actual.TestName ); Assert.AreEqual( expected.TestType, actual.TestType ); Assert.AreEqual( expected.RunState, actual.RunState ); Assert.AreEqual( expected.IsSuite, actual.IsSuite, "IsSuite" ); Assert.AreEqual( expected.TestCount, actual.TestCount, "TestCount" ); if ( expected.Categories == null ) Assert.AreEqual( 0, actual.Categories.Count, "Categories" ); else { Assert.AreEqual( expected.Categories.Count, actual.Categories.Count, "Categories" ); for ( int index = 0; index < expected.Categories.Count; index++ ) Assert.AreEqual( expected.Categories[index], actual.Categories[index], "Category {0}", index ); } Assert.AreEqual( expected.TestName, actual.TestName, "TestName" ); } [Test] public void ConstructFromFixture() { CheckConstructionFromTest( testFixture ); } [Test] public void ConstructFromSuite() { CheckConstructionFromTest( testSuite ); } [Test] public void ConstructFromTestCase() { CheckConstructionFromTest( testCase1 ); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/PairwiseTests.cs0000664000175000017500000001202411504175260022113 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2009, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core.Builders; namespace NUnit.Core.Tests { [TestFixture] public class PairwiseTest { [TestFixture] public class LiveTest { public Hashtable pairsTested = new Hashtable(); [TestFixtureSetUp] public void TestFixtureSetUp() { pairsTested = new Hashtable(); } [TestFixtureTearDown] public void TestFixtureTearDown() { Assert.That(pairsTested.Count, Is.EqualTo(16)); } [Test, Pairwise] public void Test( [Values("a", "b", "c")] string a, [Values("+", "-")] string b, [Values("x", "y")] string c) { Console.WriteLine("Pairwise: {0} {1} {2}", a, b, c); pairsTested[a + b] = null; pairsTested[a + c] = null; pairsTested[b + c] = null; } } // Test data is taken from various sources. See "Lessons Learned // in Software Testing" pp 53-59, for example. For orthogonal cases, see // http://www.freequality.org/sites/www_freequality_org/documents/tools/Tagarray_files/tamatrix.htm internal static object[] cases = new object[] { #if ORIGINAL new TestCaseData( new int[] { 2, 4 }, 8, 8 ).SetName("Test 2x4"), new TestCaseData( new int[] { 2, 2, 2 }, 5, 4 ).SetName("Test 2x2x2"), new TestCaseData( new int[] { 3, 2, 2 }, 6, 6 ).SetName("Test 3x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2 }, 7, 6 ).SetName("Test 3x2x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2, 2 }, 8, 6 ).SetName("Test 3x2x2x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2, 2, 2 }, 9, 8 ).SetName("Test 3x2x2x2x2x2"), new TestCaseData( new int[] { 3, 3, 3 }, 12, 9 ).SetName("Test 3x3x3"), new TestCaseData( new int[] { 4, 4, 4 }, 22, 16 ).SetName("Test 4x4x4"), new TestCaseData( new int[] { 5, 5, 5 }, 34, 25 ).SetName("Test 5x5x5") #else new TestCaseData( new int[] { 2, 4 }, 8, 8 ).SetName("Test 2x4"), new TestCaseData( new int[] { 2, 2, 2 }, 5, 4 ).SetName("Test 2x2x2"), new TestCaseData( new int[] { 3, 2, 2 }, 7, 6 ).SetName("Test 3x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2 }, 8, 6 ).SetName("Test 3x2x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2, 2 }, 9, 6 ).SetName("Test 3x2x2x2x2"), new TestCaseData( new int[] { 3, 2, 2, 2, 2, 2 }, 9, 8 ).SetName("Test 3x2x2x2x2x2"), new TestCaseData( new int[] { 3, 3, 3 }, 9, 9 ).SetName("Test 3x3x3"), new TestCaseData( new int[] { 4, 4, 4 }, 17, 16 ).SetName("Test 4x4x4"), new TestCaseData( new int[] { 5, 5, 5 }, 27, 25 ).SetName("Test 5x5x5") #endif }; [Test, TestCaseSource("cases")] public void Test(int[] dimensions, int bestSoFar, int targetCases) { int features = dimensions.Length; string[][] sources = new string[features][]; for (int i = 0; i < features; i++) { string featureName = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Substring(i, 1); int n = dimensions[i]; sources[i] = new string[n]; for (int j = 0; j < n; j++) sources[i][j] = featureName + j.ToString(); } CombiningStrategy strategy = new PairwiseStrategy(sources); Hashtable pairs = new Hashtable(); int cases = 0; foreach (NUnit.Core.Extensibility.ParameterSet testcase in strategy.GetTestCases()) { for (int i = 1; i < features; i++) for (int j = 0; j < i; j++) { string a = testcase.Arguments[i] as string; string b = testcase.Arguments[j] as string; pairs[a + b] = null; } ++cases; } int expectedPairs = 0; for (int i = 1; i < features; i++) for (int j = 0; j < i; j++) expectedPairs += dimensions[i] * dimensions[j]; Assert.That(pairs.Count, Is.EqualTo(expectedPairs), "Number of pairs is incorrect"); Assert.That(cases, Is.AtMost(bestSoFar), "Regression: Number of test cases exceeded target previously reached"); #if DEBUG //Assert.That(cases, Is.AtMost(targetCases), "Number of test cases exceeded target"); #endif } } } NUnit-2.6.0.12051/src/NUnitCore/tests/LegacySuiteTests.cs0000664000175000017500000001036611677400604022561 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; using NUnit.Framework; using NUnit.Core; using NUnit.TestData; using NUnit.TestData.LegacySuiteData; namespace NUnit.Core.Tests { /// /// Summary description for LegacySuiteTests. /// [TestFixture] public class LegacySuiteTests { static int setupCount = 0; static int teardownCount = 0; private Builders.LegacySuiteBuilder builder = new Builders.LegacySuiteBuilder(); [Test] public void SuiteReturningTestSuite() { Test suite = builder.BuildFrom(typeof(NUnit.Core.Tests.AllTests)); Assert.AreEqual(RunState.Runnable, suite.RunState); Assert.AreEqual(3, suite.Tests.Count); Assert.AreEqual(10, suite.TestCount); } [Test] public void SuiteReturningFixtures() { Test suite = builder.BuildFrom(typeof(LegacySuiteReturningFixtures)); Assert.AreEqual(RunState.Runnable, suite.RunState); Assert.AreEqual(3, suite.Tests.Count); Assert.AreEqual(10, suite.TestCount); } private class LegacySuiteReturningFixtures { [Suite] public static IEnumerable Suite { get { ArrayList suite = new ArrayList(); suite.Add(new OneTestCase()); suite.Add(new AssemblyTests()); suite.Add(new NoNamespaceTestFixture()); return suite; } } } [Test] public void SuiteReturningFixtureWithArguments() { Test suite = builder.BuildFrom(typeof(LegacySuiteReturningFixtureWithArguments)); Assert.AreEqual(RunState.Runnable, suite.RunState); Assert.AreEqual(1, suite.Tests.Count); Assert.AreEqual(0, suite.TestCount); } [Test] public void SuiteReturningTypes() { Test suite = builder.BuildFrom(typeof(LegacySuiteReturningTypes)); Assert.AreEqual(RunState.Runnable, suite.RunState); Assert.AreEqual(3, suite.Tests.Count); Assert.AreEqual(10, suite.TestCount); } private class LegacySuiteReturningTypes { [Suite] public static IEnumerable Suite { get { ArrayList suite = new ArrayList(); suite.Add(typeof(OneTestCase)); suite.Add(typeof(AssemblyTests)); suite.Add(typeof(NoNamespaceTestFixture)); return suite; } } } [Test] public void SetUpAndTearDownAreCalled() { setupCount = teardownCount = 0; Test suite = builder.BuildFrom( typeof( LegacySuiteWithSetUpAndTearDown ) ); Assert.AreEqual(RunState.Runnable, suite.RunState); suite.Run(NullListener.NULL, TestFilter.Empty); Assert.AreEqual( 1, setupCount ); Assert.AreEqual( 1, teardownCount ); } private class LegacySuiteWithSetUpAndTearDown { [Suite] public static TestSuite TheSuite { get { return new TestSuite( "EmptySuite" ); } } [TestFixtureSetUp] public void SetUpMethod() { setupCount++; } [TestFixtureTearDown] public void TearDownMethod() { teardownCount++; } } [Test] public void SuitePropertyWithInvalidType() { Test suite = builder.BuildFrom(typeof(LegacySuiteWithInvalidPropertyType)); Assert.AreEqual(RunState.NotRunnable, suite.RunState); } private class LegacySuiteWithInvalidPropertyType { [Suite] public static object TheSuite { get { return null; } } } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AssemblyTests.cs0000664000175000017500000000552611677376474022145 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core.Tests { using System; using System.Configuration; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Threading; using NUnit.Framework; [TestFixture] public class AssemblyTests { private string thisDll; private string noTestFixturesDll; [SetUp] public void InitStrings() { thisDll = AssemblyHelper.GetAssemblyPath(this.GetType()); noTestFixturesDll = AssemblyHelper.GetAssemblyPath(typeof(NUnit.TestUtilities.TestBuilder)); } // TODO: Review and remove unnecessary tests [Test] public void RunSetsCurrentDirectory() { Assert.IsTrue( File.Exists( thisDll ), "Run does not set current directory" ); } //[Test] //public void NUnitTraceIsEnabled() //{ // Assert.IsNotNull( Trace.Listeners["NUnit"] ); //} [Test] public void LoadAssembly() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( thisDll ) ); Assert.IsNotNull(suite, "Unable to load " + thisDll); Assert.IsTrue( File.Exists( thisDll ), "Load does not set current Directory" ); } [Test] [ExpectedException(typeof(FileNotFoundException))] public void LoadAssemblyNotFound() { TestSuiteBuilder builder = new TestSuiteBuilder(); builder.Build( new TestPackage( "/XXXX.dll" ) ); } [Test] public void LoadAssemblyWithoutTestFixtures() { TestSuiteBuilder builder = new TestSuiteBuilder(); Test suite = builder.Build( new TestPackage( noTestFixturesDll ) ); Assert.IsNotNull(suite, "Unable to load " + noTestFixturesDll); Assert.AreEqual(RunState.Runnable, suite.RunState); Assert.AreEqual( 0, suite.Tests.Count ); } [Test] public void LoadTestFixtureFromAssembly() { TestSuiteBuilder builder = new TestSuiteBuilder(); TestPackage package = new TestPackage( thisDll ); package.TestName = this.GetType().FullName; Test suite= builder.Build( package ); Assert.IsNotNull(suite, "Should not be Null"); } [Test] public void AppSettingsLoaded() { string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Assert.IsTrue( File.Exists( configFile ), string.Format( "{0} does not exist", configFile ) ); Assert.IsNull(ConfigurationSettings.AppSettings["tooltip.ShowAlways"]); Assert.AreEqual("54321",ConfigurationSettings.AppSettings["test.setting"]); } } } NUnit-2.6.0.12051/src/NUnitCore/tests/AllTests.cs0000664000175000017500000000135211504175260021042 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using NUnit.Framework; using NUnit.Core.Builders; using NUnit.TestData; namespace NUnit.Core.Tests { public class AllTests { [Suite] public static TestSuite Suite { get { TestSuite suite = new TestSuite("All Tests"); suite.Add( new OneTestCase() ); suite.Add( new AssemblyTests() ); suite.Add( new NoNamespaceTestFixture() ); return suite; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/0000775000175000017500000000000011742560362016552 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/core/ExtensionPoint.cs0000664000175000017500000001277311504175260022074 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core { public class ExtensionsCollection : IEnumerable { private static readonly int DEFAULT_LEVEL = 0; private static readonly int MAX_LEVELS = 10; private ArrayList[] lists; public ExtensionsCollection() : this(1) {} public ExtensionsCollection( int levels ) { if ( levels < 1 ) levels = 1; else if ( levels > MAX_LEVELS ) levels = MAX_LEVELS; lists = new ArrayList[levels]; } public int Levels { get { return lists.Length; } } public void Add( object extension ) { Add( extension, DEFAULT_LEVEL ); } public void Add( object extension, int level ) { if ( level < 0 || level >= lists.Length ) throw new ArgumentOutOfRangeException("level", level, "Value must be between 0 and " + lists.Length ); if ( lists[level] == null ) lists[level] = new ArrayList(); lists[level].Insert( 0, extension ); } public void Remove( object extension ) { foreach( IList list in lists ) list.Remove( extension ); } #region IEnumerable Members public IEnumerator GetEnumerator() { return new ExtensionsEnumerator( lists ); } public class ExtensionsEnumerator : IEnumerator { private ArrayList[] lists; private IEnumerator listEnum; private int currentLevel; public ExtensionsEnumerator( ArrayList[] lists ) { this.lists = lists; Reset(); } #region IEnumerator Members public void Reset() { this.listEnum = null; this.currentLevel = -1; } public object Current { get { return listEnum.Current; } } public bool MoveNext() { if ( listEnum != null && listEnum.MoveNext() ) return true; while ( ++currentLevel < lists.Length ) { IList list = lists[currentLevel]; if ( list != null ) { listEnum = list.GetEnumerator(); if ( listEnum.MoveNext() ) return true; } } return false; } #endregion } #endregion } /// /// ExtensionPoint is used as a base class for all /// extension points. /// public abstract class ExtensionPoint : IExtensionPoint { private readonly string name; private readonly IExtensionHost host; private readonly ExtensionsCollection extensions; protected IEnumerable Extensions { get { return extensions; } } #region Constructor public ExtensionPoint(string name, IExtensionHost host) : this( name, host, 0) { } public ExtensionPoint(string name, IExtensionHost host, int priorityLevels) { this.name = name; this.host = host; extensions = new ExtensionsCollection(priorityLevels); } #endregion #region IExtensionPoint Members /// /// Get the name of this extension point /// public string Name { get { return this.name; } } /// /// Get the host that provides this extension point /// public IExtensionHost Host { get { return this.host; } } /// /// Install an extension at this extension point. If the /// extension object does not meet the requirements for /// this extension point, an exception is thrown. /// /// The extension to install public void Install(object extension) { if (!IsValidExtension(extension)) throw new ArgumentException( extension.GetType().FullName + " is not {0} extension point", "extension"); extensions.Add(extension); } /// /// Install an extension at this extension point specifying /// an integer priority value for the extension.If the /// extension object does not meet the requirements for /// this extension point, or if the extension point does /// not support the requested priority level, an exception /// is thrown. /// /// The extension to install /// The priority level for this extension public void Install(object extension, int priority ) { if (!IsValidExtension(extension)) throw new ArgumentException( extension.GetType().FullName + " is not {0} extension point", "extension"); if (priority < 0 || priority >= extensions.Levels) throw new ArgumentException("Priority value not supported", "priority"); extensions.Add(extension, priority); } /// /// Removes an extension from this extension point. If the /// extension object is not present, the method returns /// without error. /// /// public void Remove(object extension) { extensions.Remove( extension ); } #endregion #region Abstract Members protected abstract bool IsValidExtension(object extension); #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/RemoteTestRunner.cs0000664000175000017500000001266511703133302022363 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Threading; /// /// RemoteTestRunner is tailored for use as the initial runner to /// receive control in a remote domain. It provides isolation for the return /// value by using a ThreadedTestRunner and for the events through use of /// an EventPump. /// public class RemoteTestRunner : ProxyTestRunner { /// /// Returns a RemoteTestRunner in the target domain. This method /// is used in the domain that wants to get a reference to /// a RemoteTestRunnner and not in the test domain itself. /// /// AppDomain in which to create the runner /// Id for the new runner to use /// public static RemoteTestRunner CreateInstance(AppDomain targetDomain, int ID) { #if CLR_2_0 || CLR_4_0 System.Runtime.Remoting.ObjectHandle oh = Activator.CreateInstance( targetDomain, #else System.Runtime.Remoting.ObjectHandle oh = targetDomain.CreateInstance( #endif Assembly.GetExecutingAssembly().FullName, typeof(RemoteTestRunner).FullName, false, BindingFlags.Default, null, new object[] { ID }, null, null, null); object obj = oh.Unwrap(); return (RemoteTestRunner)obj; } static Logger log = InternalTrace.GetLogger("RemoteTestRunner"); #region Constructors public RemoteTestRunner() : this( 0 ) { } public RemoteTestRunner( int runnerID ) : base( runnerID ) { } #endregion #region Method Overrides public override bool Load(TestPackage package) { log.Info("Loading Test Package " + package.Name ); // Initialize ExtensionHost if not already done if ( !CoreExtensions.Host.Initialized ) CoreExtensions.Host.InitializeService(); // Delayed creation of downstream runner allows us to // use a different runner type based on the package bool useThreadedRunner = package.GetSetting( "UseThreadedRunner", true ); TestRunner runner = new SimpleTestRunner( this.runnerID ); if (useThreadedRunner) { ApartmentState apartmentState = (ApartmentState)package.GetSetting("ApartmentState", ApartmentState.Unknown); ThreadPriority priority = (ThreadPriority)package.GetSetting("ThreadPriority", ThreadPriority.Normal); runner = new ThreadedTestRunner(runner, apartmentState, priority); } this.TestRunner = runner; if( base.Load (package) ) { log.Info("Loaded package successfully" ); return true; } else { log.Info("Package load failed" ); return false; } } public override void Unload() { log.Info("Unloading test package"); base.Unload(); } public override TestResult Run( EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel ) { log.Debug("Run"); QueuingEventListener queue = new QueuingEventListener(); StartTextCapture( queue, tracing, logLevel ); using( EventPump pump = new EventPump( listener, queue.Events, true ) ) { pump.Start(); return base.Run( queue, filter, tracing, logLevel ); } } public override void BeginRun( EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel ) { log.Debug("BeginRun"); QueuingEventListener queue = new QueuingEventListener(); StartTextCapture( queue, tracing, logLevel ); EventPump pump = new EventPump( listener, queue.Events, true); pump.Start(); // Will run till RunFinished is received // TODO: Make sure the thread is cleaned up if we abort the run base.BeginRun( queue, filter, tracing, logLevel ); } private void StartTextCapture( EventListener queue, bool tracing, LoggingThreshold logLevel ) { TestExecutionContext.CurrentContext.Out = new EventListenerTextWriter(queue, TestOutputType.Out); TestExecutionContext.CurrentContext.Error = new EventListenerTextWriter(queue, TestOutputType.Error); TestExecutionContext.CurrentContext.Tracing = false; if (tracing) { TestExecutionContext.CurrentContext.TraceWriter = new EventListenerTextWriter(queue, TestOutputType.Trace); TestExecutionContext.CurrentContext.Tracing = true; } TestExecutionContext.CurrentContext.LogLevel = LoggingThreshold.Off; if (logLevel != LoggingThreshold.Off) { TestExecutionContext.CurrentContext.LogWriter = new EventListenerTextWriter(queue, TestOutputType.Log); TestExecutionContext.CurrentContext.LogLevel = logLevel; } } #endregion private void CurrentDomain_DomainUnload(object sender, EventArgs e) { log.Debug(AppDomain.CurrentDomain.FriendlyName + " unloaded"); InternalTrace.Flush(); } } } NUnit-2.6.0.12051/src/NUnitCore/core/nunit.core.build0000664000175000017500000001215311713171472021657 0ustar jtaylorjtaylor NUnit-2.6.0.12051/src/NUnitCore/core/TestAction.cs0000664000175000017500000000603611720452566021165 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections.Generic; using System.Reflection; using System.Text; namespace NUnit.Core { public class TestAction { public static readonly int TargetsDefault = 0; public static readonly int TargetsTest = 1; public static readonly int TargetsSuite = 2; private static readonly Type _ActionInterfaceType = null; private static readonly Type _TestDetailsClassType = null; static TestAction() { _ActionInterfaceType = Type.GetType(NUnitFramework.TestActionInterface); _TestDetailsClassType = Type.GetType(NUnitFramework.TestDetailsClass); } private readonly object _Action; private readonly int _Targets; public TestAction(object action) { if (action == null) throw new ArgumentNullException("action"); _Action = action; _Targets = (int) Reflect.GetPropertyValue(action, "Targets"); } public void ExecuteBefore(ITest test) { Execute(test, "Before"); } public void ExecuteAfter(ITest test) { Execute(test, "After"); } private void Execute(ITest test, string methodPrefix) { var method = Reflect.GetNamedMethod(_ActionInterfaceType, methodPrefix + "Test"); var details = CreateTestDetails(test); Reflect.InvokeMethod(method, _Action, details); } private static object CreateTestDetails(ITest test) { object fixture = null; MethodInfo method = null; var testMethod = test as TestMethod; if (testMethod != null) method = testMethod.Method; var testObject = test as Test; if(testObject != null) fixture = testObject.Fixture; return Activator.CreateInstance(_TestDetailsClassType, fixture, method, test.TestName.FullName, test.TestType, test.IsSuite); } public bool DoesTarget(int target) { if(target < 0) throw new ArgumentOutOfRangeException("target", "Target must be a positive integer."); if(target == 0) return _Targets == 0; uint self = Convert.ToUInt32(target); return (_Targets & self) == self; } public int Targets { get { return _Targets; } } } } #endifNUnit-2.6.0.12051/src/NUnitCore/core/StringTextWriter.cs0000664000175000017500000000537411504175260022415 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.IO; using System.Text; namespace NUnit.Core { // TODO: This class is not currently being used. Review to // see if we will use it again, otherwise drop it. #region StringTextWriter /// /// Use this wrapper to ensure that only strings get passed accross the AppDomain /// boundary. Otherwise tests will break when non-remotable objects are passed to /// Console.Write/WriteLine. /// public class StringTextWriter : TextWriter { public StringTextWriter( TextWriter aTextWriter ) { theTextWriter = aTextWriter; } protected TextWriter theTextWriter; override public void Write(char aChar) { theTextWriter.Write(aChar); } override public void Write(string aString) { theTextWriter.Write(aString); } override public void WriteLine(string aString) { theTextWriter.WriteLine(aString); } override public System.Text.Encoding Encoding { get { return theTextWriter.Encoding; } } public override void Close() { this.Flush(); theTextWriter.Close (); } public override void Flush() { theTextWriter.Flush (); } } #endregion #region BufferedStringTextWriter /// /// This wrapper derives from StringTextWriter and adds buffering /// to improve cross-domain performance. The buffer is flushed whenever /// it reaches or exceeds a maximum size or when Flush is called. /// public class BufferedStringTextWriter : StringTextWriter { public BufferedStringTextWriter( TextWriter aTextWriter ) : base( aTextWriter ){ } private static readonly int MAX_BUFFER = 1000; private StringBuilder sb = new StringBuilder( MAX_BUFFER ); override public void Write(char aChar) { lock( sb ) { sb.Append( aChar ); this.CheckBuffer(); } } override public void Write(string aString) { lock( sb ) { sb.Append( aString ); this.CheckBuffer(); } } override public void WriteLine(string aString) { lock( sb ) { sb.Append( aString ); sb.Append( '\n' ); this.CheckBuffer(); } } override public void Flush() { if ( sb.Length > 0 ) { lock( sb ) { theTextWriter.Write( sb.ToString() ); sb.Length = 0; } } theTextWriter.Flush(); } private void CheckBuffer() { if ( sb.Length >= MAX_BUFFER ) this.Flush(); } } #endregion } NUnit-2.6.0.12051/src/NUnitCore/core/EventQueue.cs0000664000175000017500000002212111543337362021166 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Globalization; using System.Runtime.Serialization; using System.Threading; namespace NUnit.Core { #region Individual Event Classes /// /// NUnit.Core.Event is the abstract base for all stored events. /// An Event is the stored representation of a call to the /// EventListener interface and is used to record such calls /// or to queue them for forwarding on another thread or at /// a later time. /// public abstract class Event { abstract public void Send( EventListener listener ); /// /// Gets a value indicating whether this event is delivered synchronously by the NUnit . /// /// If true, and if has been used to /// set a WaitHandle, blocks its calling thread until the /// thread has delivered the event and sets the WaitHandle. /// /// public virtual bool IsSynchronous { get { return false; } } protected static Exception WrapUnserializableException(Exception ex) { string message = string.Format( CultureInfo.InvariantCulture, "(failed to serialize original Exception - original Exception follows){0}{1}", Environment.NewLine, ex); return new Exception(message); } } public class RunStartedEvent : Event { string name; int testCount; public RunStartedEvent( string name, int testCount ) { this.name = name; this.testCount = testCount; } public override bool IsSynchronous { get { return true; } } public override void Send( EventListener listener ) { listener.RunStarted(name, testCount); } } public class RunFinishedEvent : Event { TestResult result; Exception exception; public RunFinishedEvent( TestResult result ) { this.result = result; } public RunFinishedEvent( Exception exception ) { this.exception = exception; } public override void Send( EventListener listener ) { if ( this.exception != null ) { try { listener.RunFinished( this.exception ); } catch (SerializationException) { Exception wrapped = WrapUnserializableException(this.exception); listener.RunFinished(wrapped); } } else listener.RunFinished( this.result ); } } public class TestStartedEvent : Event { TestName testName; public TestStartedEvent( TestName testName ) { this.testName = testName; } public override bool IsSynchronous { get { return true; } } public override void Send( EventListener listener ) { listener.TestStarted( this.testName ); } } public class TestFinishedEvent : Event { TestResult result; public TestFinishedEvent( TestResult result ) { this.result = result; } public override void Send( EventListener listener ) { listener.TestFinished( this.result ); } } public class SuiteStartedEvent : Event { TestName suiteName; public SuiteStartedEvent( TestName suiteName ) { this.suiteName = suiteName; } public override bool IsSynchronous { get { return true; } } public override void Send( EventListener listener ) { listener.SuiteStarted( this.suiteName ); } } public class SuiteFinishedEvent : Event { TestResult result; public SuiteFinishedEvent( TestResult result ) { this.result = result; } public override void Send( EventListener listener ) { listener.SuiteFinished( this.result ); } } public class UnhandledExceptionEvent : Event { Exception exception; public UnhandledExceptionEvent( Exception exception ) { this.exception = exception; } public override void Send( EventListener listener ) { try { listener.UnhandledException( this.exception ); } catch (SerializationException) { Exception wrapped = WrapUnserializableException(this.exception); listener.UnhandledException(wrapped); } } } public class OutputEvent : Event { TestOutput output; public OutputEvent( TestOutput output ) { this.output = output; } public override void Send( EventListener listener ) { listener.TestOutput( this.output ); } } #endregion /// /// Implements a queue of work items each of which /// is queued as a WaitCallback. /// public class EventQueue { private readonly Queue queue = new Queue(); private readonly object syncRoot; private bool stopped; /// /// WaitHandle for synchronous event delivery in . /// /// Having just one handle for the whole implies that /// there may be only one producer (the test thread) for synchronous events. /// If there can be multiple producers for synchronous events, one would have /// to introduce one WaitHandle per event. /// /// private AutoResetEvent synchronousEventSent; public int Count { get { lock( this.syncRoot ) { return this.queue.Count; } } } public EventQueue() { this.syncRoot = queue.SyncRoot; } /// /// Sets a handle on which to wait, when is called /// for an with == true. /// /// /// The wait handle on which to wait, when is called /// for an with == true. /// The caller is responsible for disposing this wait handle. /// public void SetWaitHandleForSynchronizedEvents( AutoResetEvent synchronousEventWaitHandle ) { this.synchronousEventSent = synchronousEventWaitHandle; } public void Enqueue( Event e ) { lock( this.syncRoot ) { this.queue.Enqueue( e ); Monitor.Pulse( this.syncRoot ); } if ( this.synchronousEventSent != null && e.IsSynchronous ) { this.synchronousEventSent.WaitOne(); } else { Thread.Sleep( 0 ); // give EventPump thread a chance to process the event } } /// /// Removes the first element from the queue and returns it (or null). /// /// /// If true and the queue is empty, the calling thread is blocked until /// either an element is enqueued, or is called. /// /// /// /// /// If the queue not empty /// the first element. /// /// /// otherwise, if ==false /// or has been called /// null. /// /// /// public Event Dequeue( bool blockWhenEmpty ) { lock( this.syncRoot ) { while ( this.queue.Count == 0 ) { if ( blockWhenEmpty && !this.stopped ) { Monitor.Wait( this.syncRoot ); } else { return null; } } return (Event)this.queue.Dequeue(); } } public void Stop() { lock( this.syncRoot ) { if ( !this.stopped ) { this.stopped = true; Monitor.Pulse( this.syncRoot ); } } } } } NUnit-2.6.0.12051/src/NUnitCore/core/NoTestFixturesException.cs0000664000175000017500000000162011504175260023720 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Runtime.Serialization; /// /// Summary description for NoTestFixtureException. /// [Serializable] public class NoTestFixturesException : ApplicationException { public NoTestFixturesException() : base () {} public NoTestFixturesException(string message) : base(message) {} public NoTestFixturesException(string message, Exception inner) : base(message, inner) {} protected NoTestFixturesException(SerializationInfo info, StreamingContext context) : base(info, context) {} } } NUnit-2.6.0.12051/src/NUnitCore/core/TestThread.cs0000664000175000017500000001462411676062546021166 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Runtime.Remoting.Messaging; using System.Threading; namespace NUnit.Core { /// /// Represents a thread of test execution and runs a test /// on a thread, implementing timeout and setting the /// apartment state appropriately. /// public abstract class TestThread { static Logger log = InternalTrace.GetLogger(typeof(TestThread)); private Test test; #region Protected Fields /// /// The Thread object used to run tests /// protected Thread thread; /// /// The result of running the test, which must be kept /// separate from the returned TestResult while the thread /// is running to avoid race conditions. /// protected TestResult threadResult; protected EventListener listener; protected ITestFilter filter; protected ContextDictionary contextDictionary; /// /// Unexpected exception thrown by test thread /// protected Exception thrownException; #endregion #region Constructor protected TestThread(Test test) { this.test = test; this.thread = new Thread(new ThreadStart(RunTestProc)); thread.CurrentCulture = Thread.CurrentThread.CurrentCulture; thread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture; // Setting to Unknown causes an error under the Mono 1.0 profile if ( test.ApartmentState != ApartmentState.Unknown ) this.ApartmentState = test.ApartmentState; } #endregion #region Properties public ApartmentState ApartmentState { #if CLR_2_0 || CLR_4_0 get { return thread.GetApartmentState(); } set { thread.SetApartmentState(value); } #else get { return thread.ApartmentState; } set { thread.ApartmentState = value; } #endif } #endregion /// /// Run the test, honoring any timeout value provided. If the /// timeout is exceeded, set the testresult as a failure. As /// currently implemented, the thread proc calls test.doRun, /// which handles all exceptions itself. However, for safety, /// any exception thrown is rethrown upwards. /// /// TODO: It would be cleaner to call test.Run, since that's /// part of the pubic interface, but it would require some /// restructuring of the Test hierarchy. /// public TestResult Run(EventListener listener, ITestFilter filter) { TestResult testResult = new TestResult(test); this.thrownException = null; this.listener = listener; this.filter = filter; this.contextDictionary = (ContextDictionary)CallContext.GetData("NUnit.Framework.TestContext"); log.Debug("Starting test in separate thread"); thread.Start(); thread.Join(this.Timeout); // Timeout? if (thread.IsAlive) { log.Debug("Test timed out - aborting thread"); ThreadUtility.Kill(thread); // NOTE: Without the use of Join, there is a race condition here. // The thread sets the result to Cancelled and our code below sets // it to Failure. In order for the result to be shown as a failure, // we need to ensure that the following code executes after the // thread has terminated. There is a risk here: the test code might // refuse to terminate. However, it's more important to deal with // the normal rather than a pathological case. thread.Join(); testResult.Failure(string.Format("Test exceeded Timeout value of {0}ms", Timeout), null); } else if (thrownException != null) { log.Debug("Test threw " + thrownException.GetType().Name); throw thrownException; } else { log.Debug("Test completed normally"); testResult = threadResult; } return testResult; } /// /// This is the engine of this class; the actual call to test.doRun! /// Note that any thrown exception is saved for later use! /// private void RunTestProc() { CallContext.SetData("NUnit.Framework.TestContext", contextDictionary); try { RunTest(); } catch (Exception e) { thrownException = e; } finally { CallContext.FreeNamedDataSlot("NUnit.Framework.TestContext"); } } protected abstract int Timeout { get; } protected abstract void RunTest(); } public class TestMethodThread : TestThread { private TestMethod testMethod; public TestMethodThread(TestMethod testMethod) : base(testMethod) { this.testMethod = testMethod; } protected override int Timeout { get { return testMethod.Timeout == 0 //|| System.Diagnostics.Debugger.IsAttached ? System.Threading.Timeout.Infinite : testMethod.Timeout; } } protected override void RunTest() { this.threadResult = testMethod.RunTest(); } } public class TestSuiteThread : TestThread { private TestSuite suite; public TestSuiteThread(TestSuite suite) : base(suite) { this.suite = suite; } protected override int Timeout { get { return System.Threading.Timeout.Infinite; } } protected override void RunTest() { this.threadResult = suite.RunSuite(listener, filter); } } } NUnit-2.6.0.12051/src/NUnitCore/core/TestSuiteBuilder.cs0000664000175000017500000000740211543055572022345 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using NUnit.Core.Builders; using System.Collections; using System.Reflection; /// /// This is the master suite builder for NUnit. It builds a test suite from /// one or more assemblies using a list of internal and external suite builders /// to create fixtures from the qualified types in each assembly. It implements /// the ISuiteBuilder interface itself, allowing it to be used by other classes /// for queries and suite construction. /// D:\Dev\NUnit\nunit20\src\NUnitFramework\core\TestBuilderAttribute.cs public class TestSuiteBuilder { #region Instance Variables private ArrayList builders = new ArrayList(); #endregion #region Properties public IList Assemblies { get { ArrayList assemblies = new ArrayList(); foreach( TestAssemblyBuilder builder in builders ) assemblies.Add( builder.Assembly ); return assemblies; } } public IList AssemblyInfo { get { ArrayList info = new ArrayList(); foreach( TestAssemblyBuilder builder in this.builders ) info.Add( builder.AssemblyInfo ); return info; } } #endregion #region Build Methods /// /// Build a suite based on a TestPackage /// /// The TestPackage /// A TestSuite public TestSuite Build( TestPackage package ) { bool autoNamespaceSuites = package.GetSetting( "AutoNamespaceSuites", true ); bool mergeAssemblies = package.GetSetting( "MergeAssemblies", false ); TestExecutionContext.CurrentContext.TestCaseTimeout = package.GetSetting("DefaultTimeout", 0); if ( package.IsSingleAssembly ) return BuildSingleAssembly( package ); string targetAssemblyName = null; if( package.TestName != null && package.Assemblies.Contains( package.TestName ) ) { targetAssemblyName = package.TestName; package.TestName = null; } TestSuite rootSuite = new ProjectRootSuite( package.FullName ); NamespaceTreeBuilder namespaceTree = new NamespaceTreeBuilder( rootSuite ); builders.Clear(); foreach(string assemblyName in package.Assemblies) { if ( targetAssemblyName == null || targetAssemblyName == assemblyName ) { TestAssemblyBuilder builder = new TestAssemblyBuilder(); builders.Add( builder ); Test testAssembly = builder.Build( assemblyName, package.TestName, autoNamespaceSuites && !mergeAssemblies ); if ( testAssembly != null ) { if (!mergeAssemblies) { rootSuite.Add(testAssembly); } else if (autoNamespaceSuites) { namespaceTree.Add(testAssembly.Tests); rootSuite = namespaceTree.RootSuite; } else { foreach (Test test in testAssembly.Tests) rootSuite.Add(test); } } } } ProviderCache.Clear(); if (rootSuite.Tests.Count == 0) return null; return rootSuite; } private TestSuite BuildSingleAssembly( TestPackage package ) { TestAssemblyBuilder builder = new TestAssemblyBuilder(); builders.Clear(); builders.Add( builder ); TestSuite suite = (TestSuite)builder.Build( package.FullName, package.TestName, package.GetSetting( "AutoNamespaceSuites", true ) ); ProviderCache.Clear(); return suite; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/NUnitTestMethod.cs0000664000175000017500000000201411504175260022127 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { /// /// Class to implement an NUnit test method /// public class NUnitTestMethod : TestMethod { #region Constructor public NUnitTestMethod(MethodInfo method) : base(method) { } #endregion #region TestMethod Overrides /// /// Run a test returning the result. Overrides TestMethod /// to count assertions. /// /// public override TestResult RunTest() { TestResult testResult = base.RunTest(); testResult.AssertCount = NUnitFramework.Assert.GetAssertCount(); return testResult; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ExtensionHost.cs0000664000175000017500000000301411504175260021704 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core { /// /// ExtensionHost is the abstract base class used for /// all extension hosts. It provides an array of /// extension points and a FrameworkRegistry and /// implements the IExtensionHost interface. Derived /// classes must initialize the extension points. /// public abstract class ExtensionHost : IExtensionHost { #region Protected Fields protected ArrayList extensions; protected ExtensionType supportedTypes; #endregion #region IExtensionHost Interface public IExtensionPoint[] ExtensionPoints { get { return (IExtensionPoint[])extensions.ToArray(typeof(IExtensionPoint)); } } public IFrameworkRegistry FrameworkRegistry { get { return (IFrameworkRegistry)GetExtensionPoint("FrameworkRegistry"); } } public IExtensionPoint GetExtensionPoint( string name ) { foreach ( IExtensionPoint extensionPoint in extensions ) if ( extensionPoint.Name == name ) return extensionPoint; return null; } public ExtensionType ExtensionTypes { get { return supportedTypes; } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/NamespaceTreeBuilder.cs0000664000175000017500000001206511504175260023123 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System.Collections; namespace NUnit.Core { /// /// Class that can build a tree of automatic namespace /// suites from a group of fixtures. /// public class NamespaceTreeBuilder { #region Instance Variables /// /// Hashtable of all test suites we have created to represent namespaces. /// Used to locate namespace parent suites for fixtures. /// Hashtable namespaceSuites = new Hashtable(); /// /// The root of the test suite being created by this builder. /// TestSuite rootSuite; #endregion #region Constructor public NamespaceTreeBuilder( TestSuite rootSuite ) { this.rootSuite = rootSuite; } #endregion #region Properties public TestSuite RootSuite { get { return rootSuite; } } #endregion #region Public Methods public void Add( IList fixtures ) { foreach (TestSuite fixture in fixtures) //if (fixture is SetUpFixture) // Add(fixture as SetUpFixture); //else Add( fixture ); } public void Add( TestSuite fixture ) { if (fixture != null) { string ns = fixture.TestName.FullName; int index = ns.IndexOf("["); if (index >= 0) ns = ns.Substring(0, index); index = ns.LastIndexOf('.'); ns = index > 0 ? ns.Substring(0, index) : string.Empty; TestSuite containingSuite = BuildFromNameSpace(ns); if (fixture is SetUpFixture) { // The SetUpFixture must replace the namespace suite // in which it is "contained". // // First, add the old suite's children foreach (TestSuite child in containingSuite.Tests) fixture.Add(child); // Make the parent of the containing suite point to this // fixture instead // TODO: Get rid of this somehow? TestSuite parent = (TestSuite)containingSuite.Parent; if (parent == null) { fixture.TestName.Name = rootSuite.TestName.Name; rootSuite = fixture; } else { parent.Tests.Remove(containingSuite); parent.Add(fixture); } // Update the hashtable namespaceSuites[ns] = fixture; } else containingSuite.Add(fixture); } } //public void Add( SetUpFixture fixture ) //{ // string ns = fixture.FullName; // int index = ns.LastIndexOf( '.' ); // ns = index > 0 ? ns.Substring( 0, index ) : string.Empty; // TestSuite suite = BuildFromNameSpace( ns ); // // Make the parent point to this instead // // TODO: Get rid of this somehow? // TestSuite parent = suite.Parent; // if ( parent != null ) // { // parent.Tests.Remove( suite ); // parent.Add( fixture ); // } // // Add the old suite's children // foreach( TestSuite child in suite.Tests ) // fixture.Add( child ); // if (parent == null && fixture is SetUpFixture) // { // suite.Tests.Clear(); // suite.Add(fixture); // } // // Update the hashtable // namespaceSuites[ns] = fixture; //} #endregion #region Helper Method private TestSuite BuildFromNameSpace( string nameSpace ) { if( nameSpace == null || nameSpace == "" ) return rootSuite; TestSuite suite = (TestSuite)namespaceSuites[nameSpace]; if(suite!=null) return suite; int index = nameSpace.LastIndexOf("."); //string prefix = string.Format( "[{0}]" ); if( index == -1 ) { suite = new NamespaceSuite( nameSpace ); if ( rootSuite == null ) rootSuite = suite; else rootSuite.Add(suite); namespaceSuites[nameSpace]=suite; } else { string parentNameSpace = nameSpace.Substring( 0,index ); TestSuite parent = BuildFromNameSpace( parentNameSpace ); string suiteName = nameSpace.Substring( index+1 ); suite = new NamespaceSuite( parentNameSpace, suiteName ); parent.Add( suite ); namespaceSuites[nameSpace] = suite; } return suite; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/InternalTrace.cs0000664000175000017500000000674011656150726021646 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// InternalTraceLevel is an enumeration controlling the /// level of detailed presented in the internal log. /// public enum InternalTraceLevel { Default, Off, Error, Warning, Info, Verbose } /// /// Summary description for Logger. /// public class InternalTrace { private readonly static string TIME_FMT = "HH:mm:ss.fff"; private static bool initialized; private static InternalTraceLevel level; private static string logName; private static InternalTraceWriter writer; public static InternalTraceWriter Writer { get { return writer; } } private static string LogName { get { return logName; } set { logName = value; } } public static InternalTraceLevel Level { get { return level; } set { if (level != value) { level = value; if (writer == null && Level > InternalTraceLevel.Off) { writer = new InternalTraceWriter(logName); writer.WriteLine("InternalTrace: Initializing at level " + Level.ToString()); } } } } //public static void Initialize(string logName) //{ // int lev = (int) new System.Diagnostics.TraceSwitch("NTrace", "NUnit internal trace").Level; // Initialize(logName, (InternalTraceLevel)lev); //} public static void Initialize(string logName, InternalTraceLevel level) { if (!initialized) { LogName = logName; Level = level; initialized = true; } } public static void Flush() { if (writer != null) writer.Flush(); } public static void Close() { if (writer != null) writer.Close(); writer = null; } public static Logger GetLogger(string name) { return new Logger( name ); } public static Logger GetLogger( Type type ) { return new Logger( type.FullName ); } public static void Log(InternalTraceLevel level, string message, string category) { Log(level, message, category, null); } public static void Log(InternalTraceLevel level, string message, string category, Exception ex) { Writer.WriteLine("{0} {1,-5} [{2,2}] {3}: {4}", DateTime.Now.ToString(TIME_FMT), level == InternalTraceLevel.Verbose ? "Debug" : level.ToString(), #if CLR_2_0 || CLR_4_0 System.Threading.Thread.CurrentThread.ManagedThreadId, #else AppDomain.GetCurrentThreadId(), #endif category, message); if (ex != null) Writer.WriteLine(ex.ToString()); } } } NUnit-2.6.0.12051/src/NUnitCore/core/DirectorySwapper.cs0000664000175000017500000000247411504175260022411 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// Utility class that allows changing the current directory /// for the duration of some lexical scope and guaranteeing /// that it will be restored upon exit. /// /// Use it as follows: /// using( new DirectorySwapper( @"X:\New\Path" ) /// { /// // Code that operates in the new current directory /// } /// /// Instantiating DirectorySwapper without a path merely /// saves the current directory, but does not change it. /// public class DirectorySwapper : IDisposable { private string savedDirectoryName; public DirectorySwapper() : this( null ) { } public DirectorySwapper( string directoryName ) { savedDirectoryName = Environment.CurrentDirectory; if ( directoryName != null && directoryName != string.Empty ) Environment.CurrentDirectory = directoryName; } public void Dispose() { Environment.CurrentDirectory = savedDirectoryName; } } } NUnit-2.6.0.12051/src/NUnitCore/core/TestExecutionContext.cs0000664000175000017500000003202411702530164023243 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections.Specialized; using System.Configuration; using System.IO; using System.Diagnostics; using System.Globalization; using System.Security.Principal; using System.Threading; namespace NUnit.Core { /// /// Helper class used to save and restore certain static or /// singleton settings in the environment that affect tests /// or which might be changed by the user tests. /// /// An internal class is used to hold settings and a stack /// of these objects is pushed and popped as Save and Restore /// are called. /// /// Static methods for each setting forward to the internal /// object on the top of the stack. /// public class TestExecutionContext { #region Static Fields /// /// The current context, head of the list of saved contexts. /// private static TestExecutionContext current = new TestExecutionContext(); #endregion #region Instance Fields /// /// Indicates whether trace is enabled /// private bool tracing; /// /// Indicates whether logging is enabled /// //private bool logging; /// /// Destination for standard output /// private TextWriter outWriter; /// /// Destination for standard error /// private TextWriter errorWriter; /// /// Destination for Trace output /// private TextWriter traceWriter; /// /// Default timeout for test cases /// private int testCaseTimeout; private Log4NetCapture logCapture; /// /// The current working directory /// private string currentDirectory; /// /// The current culture /// private CultureInfo currentCulture; /// /// The current UI culture /// private CultureInfo currentUICulture; /// /// The current Principal. /// private IPrincipal currentPrincipal; /// /// The currently executing test /// private Test currentTest; /// /// The active TestResult for the current test /// private TestResult currentResult; /// /// The TestPackage being executed /// private TestPackage testPackage; /// /// Link to a prior saved context /// public TestExecutionContext prior; #endregion #region Constructors /// /// Initializes a new instance of the class. /// public TestExecutionContext() { this.prior = null; this.tracing = false; //this.logging = false; this.outWriter = Console.Out; this.errorWriter = Console.Error; this.traceWriter = null; this.logCapture = new Log4NetCapture(); this.testCaseTimeout = 0; this.currentDirectory = Environment.CurrentDirectory; this.currentCulture = CultureInfo.CurrentCulture; this.currentUICulture = CultureInfo.CurrentUICulture; this.currentPrincipal = Thread.CurrentPrincipal; } /// /// Initializes a new instance of the class. /// /// An existing instance of TestExecutionContext. public TestExecutionContext(TestExecutionContext other) { this.prior = other; this.tracing = other.tracing; //this.logging = other.logging; this.outWriter = other.outWriter; this.errorWriter = other.errorWriter; this.traceWriter = other.traceWriter; this.logCapture = other.logCapture; this.testCaseTimeout = other.testCaseTimeout; this.currentTest = other.currentTest; this.currentResult = other.currentResult; this.testPackage = other.testPackage; this.currentDirectory = Environment.CurrentDirectory; this.currentCulture = CultureInfo.CurrentCulture; this.currentUICulture = CultureInfo.CurrentUICulture; this.currentPrincipal = Thread.CurrentPrincipal; } #endregion #region Static Singleton Instance /// /// Gets the current context. /// /// The current context. public static TestExecutionContext CurrentContext { get { return current; } } #endregion #region Properties /// /// Controls whether trace and debug output are written /// to the standard output. /// public bool Tracing { get { return tracing; } set { if (tracing != value) { if (traceWriter != null && tracing) StopTracing(); tracing = value; if (traceWriter != null && tracing) StartTracing(); } } } /// /// Controls where Console.Out is directed /// public TextWriter Out { get { return outWriter; } set { if (outWriter != value) { outWriter = value; Console.Out.Flush(); Console.SetOut(outWriter); } } } /// /// Controls where Console.Error is directed /// public TextWriter Error { get { return errorWriter; } set { if (errorWriter != value) { errorWriter = value; Console.Error.Flush(); Console.SetError(errorWriter); } } } /// /// Controls where Trace output is directed /// public TextWriter TraceWriter { get { return traceWriter; } set { if (traceWriter != value) { if (traceWriter != null && tracing) StopTracing(); traceWriter = value; if (traceWriter != null && tracing) StartTracing(); } } } /// /// Gets or sets the Log writer, which is actually held by a log4net /// TextWriterAppender. When first set, the appender will be created /// and will thereafter send any log events to the writer. /// /// In normal operation, LogWriter is set to an EventListenerTextWriter /// connected to the EventQueue in the test domain. The events are /// subsequently captured in the Gui an the output displayed in /// the Log tab. The application under test does not need to define /// any additional appenders. /// public TextWriter LogWriter { get { return logCapture.Writer; } set { logCapture.Writer = value; } } public LoggingThreshold LogLevel { get { return logCapture.Threshold; } set { logCapture.Threshold = value; } } private void StopTracing() { traceWriter.Close(); System.Diagnostics.Trace.Listeners.Remove("NUnit"); } private void StartTracing() { System.Diagnostics.Trace.Listeners.Add(new TextWriterTraceListener(traceWriter, "NUnit")); } /// /// Saves and restores the CurrentDirectory /// public string CurrentDirectory { get { return currentDirectory; } set { currentDirectory = value; Environment.CurrentDirectory = currentDirectory; } } /// /// Saves or restores the CurrentCulture /// public CultureInfo CurrentCulture { get { return currentCulture; } set { currentCulture = value; Thread.CurrentThread.CurrentCulture = currentCulture; } } /// /// Saves or restores the CurrentUICulture /// public CultureInfo CurrentUICulture { get { return currentUICulture; } set { currentUICulture = value; Thread.CurrentThread.CurrentUICulture = currentUICulture; } } /// /// Gets or sets the current for the Thread. /// public IPrincipal CurrentPrincipal { get { return this.currentPrincipal; } set { this.currentPrincipal = value; Thread.CurrentPrincipal = this.currentPrincipal; } } /// /// Gets or sets the test case timeout value /// public int TestCaseTimeout { get { return testCaseTimeout; } set { testCaseTimeout = value; } } /// /// Gets or sets the current test /// public Test CurrentTest { get { return currentTest; } set { currentTest = value; } } /// /// Gets or sets the current test result /// public TestResult CurrentResult { get { return currentResult; } set { currentResult = value; } } /// /// Gets the test package currently being run /// public TestPackage TestPackage { get { return testPackage; } set { testPackage = value; } } #endregion #region Static Methods /// /// Saves the old context and makes a fresh one /// current without changing any settings. /// public static void Save() { TestExecutionContext.current = new TestExecutionContext(current); } /// /// Restores the last saved context and puts /// any saved settings back into effect. /// public static void Restore() { current.ReverseChanges(); current = current.prior; } #endregion #region Instance Methods /// /// Used to restore settings to their prior /// values before reverting to a prior context. /// public void ReverseChanges() { if (prior == null) throw new InvalidOperationException("TestContext: too many Restores"); this.Tracing = prior.Tracing; this.Out = prior.Out; this.Error = prior.Error; this.CurrentDirectory = prior.CurrentDirectory; this.CurrentCulture = prior.CurrentCulture; this.CurrentUICulture = prior.CurrentUICulture; this.TestCaseTimeout = prior.TestCaseTimeout; this.CurrentPrincipal = prior.CurrentPrincipal; } /// /// Record any changed values in the current context /// public void Update() { this.currentDirectory = Environment.CurrentDirectory; this.currentCulture = CultureInfo.CurrentCulture; this.currentUICulture = CultureInfo.CurrentUICulture; this.currentPrincipal = System.Threading.Thread.CurrentPrincipal; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TextCapture.cs0000664000175000017500000000250611702546154021353 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System.IO; namespace NUnit.Core { /// /// Abstract base for classes that capture text output /// and redirect it to a TextWriter. /// public abstract class TextCapture { #region Abstract Members /// /// Gets or sets the TextWriter to which text is redirected /// when captured. The value may only be changed when the /// logging threshold is set to "Off" /// public abstract TextWriter Writer { get; set; } /// /// Gets or sets the capture threshold value, which represents /// the degree of verbosity of the output text stream. Derived /// classes will need to translate the LoggingThreshold into /// the appropriate levels supported by the logging software. /// public abstract LoggingThreshold Threshold { get; set; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/LegacySuite.cs0000664000175000017500000000170411504175260021314 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Core { /// /// Represents a test suite constructed from a type that has a static Suite property /// public class LegacySuite : TestSuite { public LegacySuite( Type fixtureType ) : base( fixtureType ) { this.fixtureSetUpMethods = Reflect.GetMethodsWithAttribute(fixtureType, NUnitFramework.FixtureSetUpAttribute, true); this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute(fixtureType, NUnitFramework.FixtureTearDownAttribute, true); } } } NUnit-2.6.0.12051/src/NUnitCore/core/AssemblyInfo.cs0000664000175000017500000000100111504175260021457 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; [assembly: CLSCompliant(true)] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../nunit.snk")] [assembly: AssemblyKeyName("")] NUnit-2.6.0.12051/src/NUnitCore/core/EventPump.cs0000664000175000017500000001404211543342270021020 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Threading; /// /// The EventPumpState enum represents the state of an /// EventPump. /// public enum EventPumpState { Stopped, Pumping, Stopping } /// /// EventPump pulls events out of an EventQueue and sends /// them to a listener. It is used to send events back to /// the client without using the CallContext of the test /// runner thread. /// public class EventPump : IDisposable { private static Logger log = InternalTrace.GetLogger(typeof(EventPump)); #region Instance Variables /// /// The handle on which a thread enqueuing an event with == true /// waits, until the EventPump has sent the event to its listeners. /// private readonly AutoResetEvent synchronousEventSent = new AutoResetEvent(false); /// /// The downstream listener to which we send events /// private EventListener eventListener; /// /// The queue that holds our events /// private EventQueue events; /// /// Thread to do the pumping /// private Thread pumpThread; /// /// The current state of the eventpump /// private volatile EventPumpState pumpState = EventPumpState.Stopped; /// /// If true, stop after sending RunFinished /// private bool autostop; private string name; #endregion #region Constructor /// /// Constructor /// /// The EventListener to receive events /// The event queue to pull events from /// Set to true to stop pump after RunFinished public EventPump( EventListener eventListener, EventQueue events, bool autostop) { this.eventListener = eventListener; this.events = events; this.events.SetWaitHandleForSynchronizedEvents(this.synchronousEventSent); this.autostop = autostop; } #endregion #region Properties /// /// Gets or sets the current state of the pump /// /// /// On volatile and , see /// "http://www.albahari.com/threading/part4.aspx". /// public EventPumpState PumpState { get { Thread.MemoryBarrier(); return pumpState; } set { this.pumpState = value; Thread.MemoryBarrier(); } } /// /// Gets or sets the name of this EventPump /// (used only internally and for testing). /// public string Name { get { return this.name; } set { this.name = value; } } #endregion #region Public Methods /// /// Disposes and stops the pump. /// Disposes the used WaitHandle, too. /// public void Dispose() { Stop(); ((IDisposable)this.synchronousEventSent).Dispose(); } /// /// Start the pump /// public void Start() { if ( this.PumpState == EventPumpState.Stopped ) // Ignore if already started { this.pumpThread = new Thread( new ThreadStart( PumpThreadProc ) ); this.pumpThread.Name = "EventPumpThread" + this.Name; this.pumpThread.Priority = ThreadPriority.Highest; this.PumpState = EventPumpState.Pumping; this.pumpThread.Start(); } } /// /// Tell the pump to stop after emptying the queue. /// public void Stop() { if ( this.PumpState == EventPumpState.Pumping ) // Ignore extra calls { this.PumpState = EventPumpState.Stopping; this.events.Stop(); this.pumpThread.Join(); } } #endregion #region PumpThreadProc /// /// Our thread proc for removing items from the event /// queue and sending them on. Note that this would /// need to do more locking if any other thread were /// removing events from the queue. /// private void PumpThreadProc() { EventListener hostListeners = CoreExtensions.Host.Listeners; try { while (true) { Event e = this.events.Dequeue( this.PumpState == EventPumpState.Pumping ); if ( e == null ) break; try { e.Send(this.eventListener); e.Send(hostListeners); } catch (Exception ex) { log.Error( "Exception in event handler", ex ); } finally { if ( e.IsSynchronous ) this.synchronousEventSent.Set(); } if ( this.autostop && e is RunFinishedEvent ) this.PumpState = EventPumpState.Stopping; } } catch (Exception ex) { log.Error( "Exception in pump thread", ex ); } finally { this.PumpState = EventPumpState.Stopped; //pumpThread = null; } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TestMethod.cs0000664000175000017500000003720211712475522021165 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** //#define DEFAULT_APPLIES_TO_TESTCASE namespace NUnit.Core { using System; using System.Collections; using System.Runtime.Remoting.Messaging; using System.Threading; using System.Text; using System.Text.RegularExpressions; using System.Reflection; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif /// /// The TestMethod class represents a Test implemented as a method. /// /// Because of how exceptions are handled internally, this class /// must incorporate processing of expected exceptions. A change to /// the Test interface might make it easier to process exceptions /// in an object that aggregates a TestMethod in the future. /// public abstract class TestMethod : Test { static Logger log = InternalTrace.GetLogger(typeof(TestMethod)); static ContextDictionary context; #region Fields /// /// The test method /// internal MethodInfo method; /// /// The SetUp method. /// protected MethodInfo[] setUpMethods; /// /// The teardown method /// protected MethodInfo[] tearDownMethods; #if CLR_2_0 || CLR_4_0 /// /// The actions /// protected TestAction[] actions; /// /// The parent suite's actions /// protected TestAction[] suiteActions; #endif /// /// The ExpectedExceptionProcessor for this test, if any /// internal ExpectedExceptionProcessor exceptionProcessor; /// /// Arguments to be used in invoking the method /// internal object[] arguments; /// /// The expected result of the method return value /// internal object expectedResult; /// /// Indicates whether expectedResult was set - thereby allowing null as a value /// internal bool hasExpectedResult; /// /// The fixture object, if it has been created /// private object fixture; private Exception builderException; #endregion #region Constructors public TestMethod( MethodInfo method ) : base( method.ReflectedType.FullName, method.Name ) { if( method.DeclaringType != method.ReflectedType) this.TestName.Name = method.DeclaringType.Name + "." + method.Name; this.method = method; } #endregion #region Static Properties private static ContextDictionary Context { get { if (context==null) { context = new ContextDictionary(); } return context; } } #endregion #region Properties public override string TestType { get { return "TestMethod"; } } public MethodInfo Method { get { return method; } } public override Type FixtureType { get { return method.ReflectedType; } } public ExpectedExceptionProcessor ExceptionProcessor { get { return exceptionProcessor; } set { exceptionProcessor = value; } } public bool ExceptionExpected { get { return exceptionProcessor != null; } } public override object Fixture { get { return fixture; } set { fixture = value; } } public int Timeout { get { return Properties.Contains("Timeout") ? (int)Properties["Timeout"] : TestExecutionContext.CurrentContext.TestCaseTimeout; } } protected override bool ShouldRunOnOwnThread { get { return base.ShouldRunOnOwnThread || Timeout > 0; } } public Exception BuilderException { get { return builderException; } set { builderException = value; } } #endregion #region Run Methods public override TestResult Run(EventListener listener, ITestFilter filter) { log.Debug("Test Starting: " + this.TestName.FullName); listener.TestStarted(this.TestName); long startTime = DateTime.Now.Ticks; TestResult testResult = this.RunState == RunState.Runnable || this.RunState == RunState.Explicit ? RunTestInContext() : SkipTest(); log.Debug("Test result = " + testResult.ResultState); long stopTime = DateTime.Now.Ticks; double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond; testResult.Time = time; listener.TestFinished(testResult); return testResult; } private TestResult SkipTest() { TestResult testResult = new TestResult(this); switch (this.RunState) { case RunState.Skipped: default: testResult.Skip(IgnoreReason); break; case RunState.NotRunnable: if (BuilderException != null) testResult.Invalid(BuilderException); else testResult.Invalid(IgnoreReason); break; case RunState.Ignored: testResult.Ignore(IgnoreReason); break; } return testResult; } private TestResult RunTestInContext() { TestExecutionContext.Save(); TestExecutionContext.CurrentContext.CurrentTest = this; ContextDictionary context = Context; context._ec = TestExecutionContext.CurrentContext; CallContext.SetData("NUnit.Framework.TestContext", context); if (this.Parent != null) { this.Fixture = this.Parent.Fixture; TestSuite suite = this.Parent as TestSuite; if (suite != null) { this.setUpMethods = suite.GetSetUpMethods(); this.tearDownMethods = suite.GetTearDownMethods(); #if CLR_2_0 || CLR_4_0 this.suiteActions = suite.GetTestActions(); #endif } } try { #if CLR_2_0 || CLR_4_0 this.actions = ActionsHelper.GetActionsFromAttributeProvider(method); #endif // Temporary... to allow for tests that directly execute a test case); if (Fixture == null && !method.IsStatic) Fixture = Reflect.Construct(this.FixtureType); if (this.Properties["_SETCULTURE"] != null) TestExecutionContext.CurrentContext.CurrentCulture = new System.Globalization.CultureInfo((string)Properties["_SETCULTURE"]); if (this.Properties["_SETUICULTURE"] != null) TestExecutionContext.CurrentContext.CurrentUICulture = new System.Globalization.CultureInfo((string)Properties["_SETUICULTURE"]); return RunRepeatedTest(); } catch (Exception ex) { log.Debug("TestMethod: Caught " + ex.GetType().Name); if (ex is ThreadAbortException) Thread.ResetAbort(); TestResult testResult = new TestResult(this); RecordException(ex, testResult, FailureSite.Test); return testResult; } finally { Fixture = null; TestExecutionContext.Restore(); } } // TODO: Repeated tests need to be implemented as separate tests // in the tree of tests. Once that is done, this method will no // longer be needed and RunTest can be called directly. private TestResult RunRepeatedTest() { TestResult testResult = null; int repeatCount = this.Properties.Contains("Repeat") ? (int)this.Properties["Repeat"] : 1; while (repeatCount-- > 0) { testResult = ShouldRunOnOwnThread ? new TestMethodThread(this).Run(NullListener.NULL, TestFilter.Empty) : RunTest(); if (testResult.ResultState == ResultState.Failure || testResult.ResultState == ResultState.Error || testResult.ResultState == ResultState.Cancelled) { break; } } return testResult; } /// /// The doRun method is used to run a test internally. /// It assumes that the caller is taking care of any /// TestFixtureSetUp and TestFixtureTearDown needed. /// /// The result in which to record success or failure public virtual TestResult RunTest() { DateTime start = DateTime.Now; TestResult testResult = new TestResult(this); TestExecutionContext.CurrentContext.CurrentResult = testResult; try { RunSetUp(); #if CLR_2_0 || CLR_4_0 RunBeforeActions(testResult); #endif RunTestCase( testResult ); } catch(Exception ex) { // doTestCase handles its own exceptions so // if we're here it's a setup exception if (ex is ThreadAbortException) Thread.ResetAbort(); RecordException(ex, testResult, FailureSite.SetUp); } finally { #if CLR_2_0 || CLR_4_0 RunAfterActions(testResult); #endif RunTearDown( testResult ); DateTime stop = DateTime.Now; TimeSpan span = stop.Subtract(start); testResult.Time = (double)span.Ticks / (double)TimeSpan.TicksPerSecond; if (testResult.IsSuccess) { if (this.Properties.Contains("MaxTime")) { int elapsedTime = (int)Math.Round(testResult.Time * 1000.0); int maxTime = (int)this.Properties["MaxTime"]; if (maxTime > 0 && elapsedTime > maxTime) testResult.Failure( string.Format("Elapsed time of {0}ms exceeds maximum of {1}ms", elapsedTime, maxTime), null); } if (testResult.IsSuccess && testResult.Message == null && Environment.CurrentDirectory != TestExecutionContext.CurrentContext.prior.CurrentDirectory) { // TODO: Introduce a warning result state in NUnit 3.0 testResult.SetResult(ResultState.Success, "Warning: Test changed the CurrentDirectory", null); } } } log.Debug("Test result = " + testResult.ResultState); return testResult; } #endregion #region Invoke Methods by Reflection, Recording Errors #if CLR_2_0 || CLR_4_0 protected virtual void ExecuteActions(ActionPhase phase) { List targetActions = new List(); if (this.suiteActions != null) { foreach (var action in this.suiteActions) { if(action.DoesTarget(TestAction.TargetsTest)) targetActions.Add(action); } } if (this.actions != null) { foreach (var action in this.actions) { #if DEFAULT_APPLIES_TO_TESTCASE if (!(Parent is ParameterizedMethodSuite) && (action.DoesTarget(TestAction.TargetsDefault) || action.DoesTarget(TestAction.TargetsTest))) #else if (action.DoesTarget(TestAction.TargetsDefault) || (!(Parent is ParameterizedMethodSuite) && action.DoesTarget(TestAction.TargetsTest))) #endif targetActions.Add(action); } } ActionsHelper.ExecuteActions(phase, targetActions, this); } private void RunBeforeActions(TestResult testResult) { ExecuteActions(ActionPhase.Before); } private void RunAfterActions(TestResult testResult) { try { ExecuteActions(ActionPhase.After); } catch (Exception ex) { if (ex is NUnitException) ex = ex.InnerException; // TODO: What about ignore exceptions in teardown? testResult.Error(ex, FailureSite.TearDown); } } #endif private void RunSetUp() { if (setUpMethods != null) foreach( MethodInfo setUpMethod in setUpMethods ) Reflect.InvokeMethod(setUpMethod, setUpMethod.IsStatic ? null : this.Fixture); } private void RunTearDown( TestResult testResult ) { try { if (tearDownMethods != null) { int index = tearDownMethods.Length; while (--index >= 0) Reflect.InvokeMethod(tearDownMethods[index], tearDownMethods[index].IsStatic ? null : this.Fixture); } } catch(Exception ex) { if ( ex is NUnitException ) ex = ex.InnerException; RecordException(ex, testResult, FailureSite.TearDown); } } private void RunTestCase( TestResult testResult ) { try { RunTestMethod(testResult); if (testResult.IsSuccess && exceptionProcessor != null) exceptionProcessor.ProcessNoException(testResult); } catch (Exception ex) { if (ex is ThreadAbortException) Thread.ResetAbort(); if (exceptionProcessor == null) RecordException(ex, testResult, FailureSite.Test); else exceptionProcessor.ProcessException(ex, testResult); } } private void RunTestMethod(TestResult testResult) { object fixture = this.method.IsStatic ? null : this.Fixture; object result = Reflect.InvokeMethod( this.method, fixture, this.arguments ); if (this.hasExpectedResult) NUnitFramework.Assert.AreEqual(expectedResult, result); testResult.Success(); } #endregion #region Record Info About An Exception protected virtual void RecordException( Exception exception, TestResult testResult, FailureSite failureSite ) { if (exception is NUnitException) exception = exception.InnerException; // Ensure that once a test is cancelled, it stays cancelled ResultState finalResultState = testResult.ResultState == ResultState.Cancelled ? ResultState.Cancelled : NUnitFramework.GetResultState(exception); testResult.SetResult(finalResultState, exception, failureSite); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Summary.xslt0000664000175000017500000000354211504175260021122 0ustar jtaylorjtaylort Tests run: , Errors: , Failures: , Time: seconds Not run: , Invalid: , Ignored: , Skipped: Test Fixture SetUp Failures: Test Case Failures: Tests not run: ) : NUnit-2.6.0.12051/src/NUnitCore/core/ContextDictionary.cs0000664000175000017500000000336211652457452022564 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2011, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Collections; namespace NUnit.Core { public class ContextDictionary : Hashtable { internal TestExecutionContext _ec; public override object this[object key] { get { // Get Result values dynamically, since // they may change as execution proceeds switch (key as string) { case "Test.Name": return _ec.CurrentTest.TestName.Name; case "Test.FullName": return _ec.CurrentTest.TestName.FullName; case "Test.Properties": return _ec.CurrentTest.Properties; case "Result.State": return (int)_ec.CurrentResult.ResultState; case "TestDirectory": return AssemblyHelper.GetDirectoryName(_ec.CurrentTest.FixtureType.Assembly); case "WorkDirectory": return _ec.TestPackage.Settings.Contains("WorkDirectory") ? _ec.TestPackage.Settings["WorkDirectory"] : Environment.CurrentDirectory; default: return base[key]; } } set { base[key] = value; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/Logger.cs0000664000175000017500000000516111504175260020316 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { public class Logger { private string name; private string fullname; public Logger(string name) { this.fullname = this.name = name; int index = fullname.LastIndexOf('.'); if (index >= 0) this.name = fullname.Substring(index + 1); } #region Error public void Error(string message) { Log(InternalTraceLevel.Error, message); } public void Error(string message, params object[] args) { Log(InternalTraceLevel.Error, message, args); } public void Error(string message, Exception ex) { if (InternalTrace.Level >= InternalTraceLevel.Error) { InternalTrace.Log(InternalTraceLevel.Error, message, name, ex); } } #endregion #region Warning public void Warning(string message) { Log(InternalTraceLevel.Warning, message); } public void Warning(string message, params object[] args) { Log(InternalTraceLevel.Warning, message, args); } #endregion #region Info public void Info(string message) { Log(InternalTraceLevel.Info, message); } public void Info(string message, params object[] args) { Log(InternalTraceLevel.Info, message, args); } #endregion #region Debug public void Debug(string message) { Log(InternalTraceLevel.Verbose, message); } public void Debug(string message, params object[] args) { Log(InternalTraceLevel.Verbose, message, args); } #endregion #region Helper Methods public void Log(InternalTraceLevel level, string message) { if (InternalTrace.Level >= level) InternalTrace.Log(level, message, name); } private void Log(InternalTraceLevel level, string format, params object[] args) { if (InternalTrace.Level >= level) Log(level, string.Format( format, args ) ); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/AssemblyReader.cs0000664000175000017500000001221711504175260022001 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Text; using System.IO; namespace NUnit.Core { /// /// AssemblyReader knows how to find various things in an assembly header /// public class AssemblyReader : IDisposable { private string assemblyPath; private BinaryReader rdr; private FileStream fs; UInt16 dos_magic = 0xffff; UInt32 pe_signature = 0xffffffff; UInt16 numberOfSections; UInt16 optionalHeaderSize; UInt16 peType; UInt32 numDataDirectoryEntries; private uint peHeader = 0; private uint fileHeader = 0; private uint optionalHeader = 0; private uint dataDirectory = 0; private uint dataSections = 0; private struct DataSection { public uint virtualAddress; public uint virtualSize; public uint fileOffset; }; private DataSection[] sections; public AssemblyReader( string assemblyPath ) { this.assemblyPath = assemblyPath; CalcHeaderOffsets(); } public AssemblyReader( Assembly assembly ) { this.assemblyPath = AssemblyHelper.GetAssemblyPath( assembly ); CalcHeaderOffsets(); } private void CalcHeaderOffsets() { this.fs = new FileStream( assemblyPath, FileMode.Open, FileAccess.Read ); this.rdr = new BinaryReader( fs ); dos_magic = rdr.ReadUInt16(); if ( dos_magic == 0x5a4d ) { fs.Position = 0x3c; peHeader = rdr.ReadUInt32(); fileHeader = peHeader + 4; optionalHeader = fileHeader + 20; fs.Position = optionalHeader; peType = rdr.ReadUInt16(); dataDirectory = peType == 0x20b ? optionalHeader + 112 : optionalHeader + 96; fs.Position = dataDirectory - 4; numDataDirectoryEntries = rdr.ReadUInt32(); fs.Position = peHeader; pe_signature = rdr.ReadUInt32(); rdr.ReadUInt16(); // machine numberOfSections = rdr.ReadUInt16(); fs.Position += 12; optionalHeaderSize = rdr.ReadUInt16(); dataSections = optionalHeader + optionalHeaderSize; sections = new DataSection[numberOfSections]; fs.Position = dataSections; for( int i = 0; i < numberOfSections; i++ ) { fs.Position += 8; sections[i].virtualSize = rdr.ReadUInt32(); sections[i].virtualAddress = rdr.ReadUInt32(); uint rawDataSize = rdr.ReadUInt32(); sections[i].fileOffset = rdr.ReadUInt32(); if ( sections[i].virtualSize == 0 ) sections[i].virtualSize = rawDataSize; fs.Position += 16; } } } private uint DataDirectoryRva( int n ) { fs.Position = dataDirectory + n * 8; return rdr.ReadUInt32(); } private uint RvaToLfa( uint rva ) { for( int i = 0; i < numberOfSections; i++ ) if ( rva >= sections[i].virtualAddress && rva < sections[i].virtualAddress + sections[i].virtualSize ) return rva - sections[i].virtualAddress + sections[i].fileOffset; return 0; } public string AssemblyPath { get { return assemblyPath; } } public bool IsValidPeFile { get { return dos_magic == 0x5a4d && pe_signature == 0x00004550; } } public bool IsDotNetFile { get { return IsValidPeFile && numDataDirectoryEntries > 14 && DataDirectoryRva(14) != 0; } } public bool Is64BitImage { get { return peType == 0x20b; } } public string ImageRuntimeVersion { get { string runtimeVersion = string.Empty; if (this.IsDotNetFile) { uint rva = DataDirectoryRva(14); if (rva != 0) { fs.Position = RvaToLfa(rva) + 8; uint metadata = rdr.ReadUInt32(); fs.Position = RvaToLfa(metadata); if (rdr.ReadUInt32() == 0x424a5342) { // Copy string representing runtime version fs.Position += 12; StringBuilder sb = new StringBuilder(); char c; while ((c = rdr.ReadChar()) != '\0') sb.Append(c); if (sb[0] == 'v') // Last sanity check runtimeVersion = sb.ToString(); // Could do fixups here for bad values in older files // like 1.x86, 1.build, etc. But we are only using // the major version anyway } } } return runtimeVersion; } } public void Dispose() { if ( fs != null ) fs.Close(); if ( rdr != null ) rdr.Close(); fs = null; rdr = null; } } } NUnit-2.6.0.12051/src/NUnitCore/core/NamespaceSuite.cs0000664000175000017500000000255411504175260022010 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// TestAssembly is a TestSuite that represents the execution /// of tests in a managed assembly. /// public class NamespaceSuite : TestSuite { /// /// Initializes a new instance of the class. /// /// The path. public NamespaceSuite(string path) : base(path) { } /// /// Initializes a new instance of the class. /// /// The parent namespace. /// Name of the suite. public NamespaceSuite(string parentNamespace, string suiteName) : base(parentNamespace, suiteName) { } /// /// Gets the type of the test. /// public override string TestType { get { return "Namespace"; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/CoreExtensions.cs0000664000175000017500000001630011543055572022052 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using System.Reflection; using NUnit.Core.Builders; using NUnit.Core.Extensibility; namespace NUnit.Core { /// /// CoreExtensions is a singleton class that groups together all /// the extension points that are supported in the test domain. /// It also provides access to the test builders and decorators /// by other parts of the NUnit core. /// public class CoreExtensions : ExtensionHost, IService { static Logger log = InternalTrace.GetLogger("CoreExtensions"); #region Instance Fields private IAddinRegistry addinRegistry; private bool initialized; private SuiteBuilderCollection suiteBuilders; private TestCaseBuilderCollection testBuilders; private TestDecoratorCollection testDecorators; private EventListenerCollection listeners; private FrameworkRegistry frameworks; private TestCaseProviders testcaseProviders; private DataPointProviders dataPointProviders; #endregion #region CoreExtensions Singleton private static CoreExtensions host; public static CoreExtensions Host { get { if (host == null) host = new CoreExtensions(); return host; } } #endregion #region Constructors public CoreExtensions() { this.suiteBuilders = new SuiteBuilderCollection(this); this.testBuilders = new TestCaseBuilderCollection(this); this.testDecorators = new TestDecoratorCollection(this); this.listeners = new EventListenerCollection(this); this.frameworks = new FrameworkRegistry(this); this.testcaseProviders = new TestCaseProviders(this); this.dataPointProviders = new DataPointProviders(this); this.extensions = new ArrayList(); extensions.Add(suiteBuilders); extensions.Add(testBuilders); extensions.Add(testDecorators); extensions.Add(listeners); extensions.Add(frameworks); extensions.Add(testcaseProviders); extensions.Add(dataPointProviders); this.supportedTypes = ExtensionType.Core; // TODO: This should be somewhere central // string logfile = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData ); // logfile = Path.Combine( logfile, "NUnit" ); // logfile = Path.Combine( logfile, "NUnitTest.log" ); // // appender = new log4net.Appender.ConsoleAppender(); //// appender.File = logfile; //// appender.AppendToFile = true; //// appender.LockingModel = new log4net.Appender.FileAppender.MinimalLock(); // appender.Layout = new log4net.Layout.PatternLayout( // "%date{ABSOLUTE} %-5level [%4thread] %logger{1}: PID=%property{PID} %message%newline" ); // appender.Threshold = log4net.Core.Level.All; // log4net.Config.BasicConfigurator.Configure(appender); } #endregion #region Public Properties public bool Initialized { get { return initialized; } } /// /// Our AddinRegistry may be set from outside or passed into the domain /// public IAddinRegistry AddinRegistry { get { if ( addinRegistry == null ) addinRegistry = AppDomain.CurrentDomain.GetData( "AddinRegistry" ) as IAddinRegistry; return addinRegistry; } set { addinRegistry = value; } } #endregion #region Internal Properties internal ISuiteBuilder SuiteBuilders { get { return suiteBuilders; } } internal ITestCaseBuilder2 TestBuilders { get { return testBuilders; } } internal ITestDecorator TestDecorators { get { return testDecorators; } } internal EventListener Listeners { get { return listeners; } } internal FrameworkRegistry TestFrameworks { get { return frameworks; } } internal TestCaseProviders TestCaseProviders { get { return testcaseProviders; } } #endregion #region Public Methods public void InstallBuiltins() { log.Info( "Installing Builtins" ); // Define NUnit Frameworks frameworks.Register( "NUnit", "nunit.framework" ); frameworks.Register("NUnitLite", "NUnitLite"); // Install builtin SuiteBuilders suiteBuilders.Install( new NUnitTestFixtureBuilder() ); suiteBuilders.Install( new SetUpFixtureBuilder() ); // Install builtin TestCaseBuilder testBuilders.Install( new NUnitTestCaseBuilder() ); //testBuilders.Install(new TheoryBuilder()); // Install builtin TestCaseProviders testcaseProviders.Install(new TestCaseParameterProvider()); testcaseProviders.Install(new TestCaseSourceProvider()); testcaseProviders.Install(new CombinatorialTestCaseProvider()); // Install builtin DataPointProvider dataPointProviders.Install(new InlineDataPointProvider()); dataPointProviders.Install(new ValueSourceProvider()); dataPointProviders.Install(new DatapointProvider()); } public void InstallAddins() { log.Info( "Installing Addins" ); if( AddinRegistry != null ) { foreach (Addin addin in AddinRegistry.Addins) { if ( (this.ExtensionTypes & addin.ExtensionType) != 0 ) { AddinStatus status = AddinStatus.Unknown; string message = null; try { Type type = Type.GetType(addin.TypeName); if ( type == null ) { status = AddinStatus.Error; message = string.Format( "Unable to locate {0} Type", addin.TypeName ); } else if ( !InstallAddin( type ) ) { status = AddinStatus.Error; message = "Install method returned false"; } else { status = AddinStatus.Loaded; } } catch( Exception ex ) { status = AddinStatus.Error; message = ex.ToString(); } AddinRegistry.SetStatus( addin.Name, status, message ); if ( status != AddinStatus.Loaded ) { log.Error( "Failed to load {0}", addin.Name ); log.Error( message ); } } } } } public void InstallAdhocExtensions( Assembly assembly ) { foreach ( Type type in assembly.GetExportedTypes() ) { if ( type.GetCustomAttributes(typeof(NUnitAddinAttribute), false).Length == 1 ) InstallAddin( type ); } } #endregion #region Helper Methods private bool InstallAddin( Type type ) { ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes); object obj = ctor.Invoke( new object[0] ); IAddin theAddin = (IAddin)obj; return theAddin.Install(this); } #endregion #region IService Members public void UnloadService() { // TODO: Add CoreExtensions.UnloadService implementation } public void InitializeService() { InstallBuiltins(); InstallAddins(); initialized = true; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/EventListenerTextWriter.cs0000664000175000017500000000501211504175260023723 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.IO; using System.Text; public class EventListenerTextWriter : TextWriter { private EventListener eventListener; private TestOutputType type; public EventListenerTextWriter( EventListener eventListener, TestOutputType type ) { this.eventListener = eventListener; this.type = type; } override public void Write(char aChar) { this.eventListener.TestOutput( new TestOutput( aChar.ToString(), this.type ) ); } override public void Write(string aString) { this.eventListener.TestOutput( new TestOutput( aString, this.type ) ); } override public void WriteLine(string aString) { this.eventListener.TestOutput( new TestOutput( aString + this.NewLine, this.type ) ); } override public System.Text.Encoding Encoding { get { return Encoding.Default; } } } /// /// This wrapper adds buffering to improve cross-domain performance. /// public class BufferedEventListenerTextWriter : TextWriter { private EventListener eventListener; private TestOutputType type; private const int MAX_BUFFER = 1024; private StringBuilder sb = new StringBuilder( MAX_BUFFER ); public BufferedEventListenerTextWriter( EventListener eventListener, TestOutputType type ) { this.eventListener = eventListener; this.type = type; } public override Encoding Encoding { get { return Encoding.Default; } } override public void Write(char ch) { lock( sb ) { sb.Append( ch ); this.CheckBuffer(); } } override public void Write(string str) { lock( sb ) { sb.Append( str ); this.CheckBuffer(); } } override public void WriteLine(string str) { lock( sb ) { sb.Append( str ); sb.Append( base.NewLine ); this.CheckBuffer(); } } override public void Flush() { if ( sb.Length > 0 ) { lock( sb ) { TestOutput output = new TestOutput(sb.ToString(), this.type); this.eventListener.TestOutput( output ); sb.Length = 0; } } } private void CheckBuffer() { if ( sb.Length >= MAX_BUFFER ) this.Flush(); } } } NUnit-2.6.0.12051/src/NUnitCore/core/TestSuite.cs0000664000175000017500000005127511712475522021044 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Text; using System.Threading; using System.Collections; using System.Reflection; using NUnit.Core.Filters; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif /// /// Summary description for TestSuite. /// /// [Serializable] public class TestSuite : Test { #region Fields static Logger log = InternalTrace.GetLogger(typeof(TestSuite)); /// /// Our collection of child tests /// private ArrayList tests = new ArrayList(); /// /// The fixture setup methods for this suite /// protected MethodInfo[] fixtureSetUpMethods; /// /// The fixture teardown methods for this suite /// protected MethodInfo[] fixtureTearDownMethods; /// /// The setup methods for this suite /// protected MethodInfo[] setUpMethods; /// /// The teardown methods for this suite /// protected MethodInfo[] tearDownMethods; #if CLR_2_0 || CLR_4_0 /// /// The actions for this suite /// protected TestAction[] actions; #endif /// /// Set to true to suppress sorting this suite's contents /// protected bool maintainTestOrder; /// /// Arguments for use in creating a parameterized fixture /// internal object[] arguments; /// /// The System.Type of the fixture for this test suite, if there is one /// private Type fixtureType; /// /// The fixture object, if it has been created /// private object fixture; #endregion #region Constructors public TestSuite( string name ) : base( name ) { } public TestSuite( string parentSuiteName, string name ) : base( parentSuiteName, name ) { } public TestSuite(Type fixtureType) : this(fixtureType, null) { } public TestSuite(Type fixtureType, object[] arguments) : base(fixtureType.FullName) { string name = TypeHelper.GetDisplayName(fixtureType, arguments); this.TestName.Name = name; this.TestName.FullName = name; string nspace = fixtureType.Namespace; if (nspace != null && nspace != "") this.TestName.FullName = nspace + "." + name; this.fixtureType = fixtureType; this.arguments = arguments; } #endregion #region Public Methods public void Sort() { if (!maintainTestOrder) { this.tests.Sort(); foreach (Test test in Tests) { TestSuite suite = test as TestSuite; if (suite != null) suite.Sort(); } } } public void Sort(IComparer comparer) { this.tests.Sort(comparer); foreach( Test test in Tests ) { TestSuite suite = test as TestSuite; if ( suite != null ) suite.Sort(comparer); } } public void Add( Test test ) { // if( test.RunState == RunState.Runnable ) // { // test.RunState = this.RunState; // test.IgnoreReason = this.IgnoreReason; // } test.Parent = this; tests.Add(test); } public void Add( object fixture ) { Test test = TestFixtureBuilder.BuildFrom( fixture ); if ( test != null ) Add( test ); } #endregion #region Properties public override IList Tests { get { return tests; } } public override bool IsSuite { get { return true; } } public override int TestCount { get { int count = 0; foreach(Test test in Tests) { count += test.TestCount; } return count; } } public override Type FixtureType { get { return fixtureType; } } public override object Fixture { get { return fixture; } set { fixture = value; } } public MethodInfo[] GetSetUpMethods() { return setUpMethods; } public MethodInfo[] GetTearDownMethods() { return tearDownMethods; } #if CLR_2_0 || CLR_4_0 internal virtual TestAction[] GetTestActions() { List allActions = new List(); if (this.Parent != null && this.Parent is TestSuite) { TestAction[] parentActions = ((TestSuite)this.Parent).GetTestActions(); if (parentActions != null) allActions.AddRange(parentActions); } if (this.actions != null) allActions.AddRange(this.actions); return allActions.ToArray(); } #endif #endregion #region Test Overrides public override string TestType { get { return "TestSuite"; } } public override int CountTestCases(ITestFilter filter) { int count = 0; if(filter.Pass(this)) { foreach(Test test in Tests) { count += test.CountTestCases(filter); } } return count; } public override TestResult Run(EventListener listener, ITestFilter filter) { listener.SuiteStarted(this.TestName); long startTime = DateTime.Now.Ticks; TestResult suiteResult = this.RunState == RunState.Runnable || this.RunState == RunState.Explicit ? RunSuiteInContext(listener, filter) : SkipSuite(listener, filter); long stopTime = DateTime.Now.Ticks; double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond; suiteResult.Time = time; listener.SuiteFinished(suiteResult); return suiteResult; } private TestResult SkipSuite(EventListener listener, ITestFilter filter) { TestResult suiteResult = new TestResult(this); switch (this.RunState) { default: case RunState.Skipped: SkipAllTests(suiteResult, listener, filter); break; case RunState.NotRunnable: MarkAllTestsInvalid(suiteResult, listener, filter); break; case RunState.Ignored: IgnoreAllTests(suiteResult, listener, filter); break; } return suiteResult; } private TestResult RunSuiteInContext(EventListener listener, ITestFilter filter) { TestExecutionContext.Save(); try { return ShouldRunOnOwnThread ? new TestSuiteThread(this).Run(listener, filter) : RunSuite(listener, filter); } finally { TestExecutionContext.Restore(); } } public TestResult RunSuite(EventListener listener, ITestFilter filter) { TestResult suiteResult = new TestResult(this); DoOneTimeSetUp(suiteResult); #if CLR_2_0 || CLR_4_0 DoOneTimeBeforeTestSuiteActions(suiteResult); #endif if (this.Properties["_SETCULTURE"] != null) TestExecutionContext.CurrentContext.CurrentCulture = new System.Globalization.CultureInfo((string)Properties["_SETCULTURE"]); if (this.Properties["_SETUICULTURE"] != null) TestExecutionContext.CurrentContext.CurrentUICulture = new System.Globalization.CultureInfo((string)Properties["_SETUICULTURE"]); switch (suiteResult.ResultState) { case ResultState.Failure: case ResultState.Error: MarkTestsFailed(Tests, suiteResult, listener, filter); break; case ResultState.NotRunnable: MarkTestsNotRun(this.Tests, ResultState.NotRunnable, suiteResult.Message, suiteResult, listener, filter); break; default: try { RunAllTests(suiteResult, listener, filter); } finally { #if CLR_2_0 || CLR_4_0 DoOneTimeAfterTestSuiteActions(suiteResult); #endif DoOneTimeTearDown(suiteResult); } break; } return suiteResult; } #endregion #region Virtual Methods protected virtual void DoOneTimeSetUp(TestResult suiteResult) { if (FixtureType != null) { try { // In case TestFixture was created with fixture object if (Fixture == null && !IsStaticClass( FixtureType ) ) CreateUserFixture(); if (this.fixtureSetUpMethods != null) foreach( MethodInfo fixtureSetUp in fixtureSetUpMethods ) Reflect.InvokeMethod(fixtureSetUp, fixtureSetUp.IsStatic ? null : Fixture); TestExecutionContext.CurrentContext.Update(); } catch (Exception ex) { if (ex is NUnitException || ex is System.Reflection.TargetInvocationException) ex = ex.InnerException; if (ex is InvalidTestFixtureException) suiteResult.Invalid(ex.Message); else if (IsIgnoreException(ex)) { this.RunState = RunState.Ignored; suiteResult.Ignore(ex.Message); suiteResult.StackTrace = ex.StackTrace; this.IgnoreReason = ex.Message; } else if (IsAssertException(ex)) suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.SetUp); else suiteResult.Error(ex, FailureSite.SetUp); } } } #if CLR_2_0 || CLR_4_0 protected virtual void ExecuteActions(ActionPhase phase) { List targetActions = new List(); if (this.actions != null) { foreach (var action in this.actions) { if (action.DoesTarget(TestAction.TargetsSuite) || action.DoesTarget(TestAction.TargetsDefault)) targetActions.Add(action); } } ActionsHelper.ExecuteActions(phase, targetActions, this); } protected virtual void DoOneTimeBeforeTestSuiteActions(TestResult suiteResult) { try { ExecuteActions(ActionPhase.Before); TestExecutionContext.CurrentContext.Update(); } catch (Exception ex) { if (ex is NUnitException || ex is System.Reflection.TargetInvocationException) ex = ex.InnerException; if (ex is InvalidTestFixtureException) suiteResult.Invalid(ex.Message); else if (IsIgnoreException(ex)) { this.RunState = RunState.Ignored; suiteResult.Ignore(ex.Message); suiteResult.StackTrace = ex.StackTrace; this.IgnoreReason = ex.Message; } else if (IsAssertException(ex)) suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.SetUp); else suiteResult.Error(ex, FailureSite.SetUp); } } #endif protected virtual void CreateUserFixture() { if (arguments != null && arguments.Length > 0) Fixture = Reflect.Construct(FixtureType, arguments); else Fixture = Reflect.Construct(FixtureType); } protected virtual void DoOneTimeTearDown(TestResult suiteResult) { if ( this.FixtureType != null) { try { if (this.fixtureTearDownMethods != null) { int index = fixtureTearDownMethods.Length; while (--index >= 0 ) { MethodInfo fixtureTearDown = fixtureTearDownMethods[index]; Reflect.InvokeMethod(fixtureTearDown, fixtureTearDown.IsStatic ? null : Fixture); } } IDisposable disposable = Fixture as IDisposable; if (disposable != null) disposable.Dispose(); } catch (Exception ex) { // Error in TestFixtureTearDown or Dispose causes the // suite to be marked as a failure, even if // all the contained tests passed. NUnitException nex = ex as NUnitException; if (nex != null) ex = nex.InnerException; suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.TearDown); } this.Fixture = null; } } #if CLR_2_0 || CLR_4_0 protected virtual void DoOneTimeAfterTestSuiteActions(TestResult suiteResult) { try { ExecuteActions(ActionPhase.After); } catch (Exception ex) { // Error in TestFixtureTearDown or Dispose causes the // suite to be marked as a failure, even if // all the contained tests passed. NUnitException nex = ex as NUnitException; if (nex != null) ex = nex.InnerException; suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.TearDown); } } #endif protected virtual bool IsAssertException(Exception ex) { return ex.GetType().FullName == NUnitFramework.AssertException; } protected virtual bool IsIgnoreException(Exception ex) { return ex.GetType().FullName == NUnitFramework.IgnoreException; } #endregion #region Helper Methods private bool IsStaticClass(Type type) { return type.IsAbstract && type.IsSealed; } private void RunAllTests( TestResult suiteResult, EventListener listener, ITestFilter filter ) { if (Properties.Contains("Timeout")) TestExecutionContext.CurrentContext.TestCaseTimeout = (int)Properties["Timeout"]; IDictionary settings = TestExecutionContext.CurrentContext.TestPackage.Settings; bool stopOnError = settings.Contains("StopOnError") && (bool)settings["StopOnError"]; foreach (Test test in ArrayList.Synchronized(Tests)) { if (filter.Pass(test)) { RunState saveRunState = test.RunState; if (test.RunState == RunState.Runnable && this.RunState != RunState.Runnable && this.RunState != RunState.Explicit ) { test.RunState = this.RunState; test.IgnoreReason = this.IgnoreReason; } TestResult result = test.Run(listener, filter); log.Debug("Test result = " + result.ResultState); suiteResult.AddResult(result); log.Debug("Suite result = " + suiteResult.ResultState); if (saveRunState != test.RunState) { test.RunState = saveRunState; test.IgnoreReason = null; } if (result.ResultState == ResultState.Cancelled) break; if ((result.IsError || result.IsFailure) && stopOnError) break; } } } private void SkipAllTests(TestResult suiteResult, EventListener listener, ITestFilter filter) { suiteResult.Skip(this.IgnoreReason); MarkTestsNotRun(this.Tests, ResultState.Skipped, this.IgnoreReason, suiteResult, listener, filter); } private void IgnoreAllTests(TestResult suiteResult, EventListener listener, ITestFilter filter) { suiteResult.Ignore(this.IgnoreReason); MarkTestsNotRun(this.Tests, ResultState.Ignored, this.IgnoreReason, suiteResult, listener, filter); } private void MarkAllTestsInvalid(TestResult suiteResult, EventListener listener, ITestFilter filter) { suiteResult.Invalid(this.IgnoreReason); MarkTestsNotRun(this.Tests, ResultState.NotRunnable, this.IgnoreReason, suiteResult, listener, filter); } private void MarkTestsNotRun( IList tests, ResultState resultState, string ignoreReason, TestResult suiteResult, EventListener listener, ITestFilter filter) { foreach (Test test in ArrayList.Synchronized(tests)) { if (filter.Pass(test)) MarkTestNotRun(test, resultState, ignoreReason, suiteResult, listener, filter); } } private void MarkTestNotRun( Test test, ResultState resultState, string ignoreReason, TestResult suiteResult, EventListener listener, ITestFilter filter) { if (test is TestSuite) { listener.SuiteStarted(test.TestName); TestResult result = new TestResult( new TestInfo(test) ); result.SetResult( resultState, ignoreReason, null ); MarkTestsNotRun(test.Tests, resultState, ignoreReason, result, listener, filter); suiteResult.AddResult(result); listener.SuiteFinished(result); } else { listener.TestStarted(test.TestName); TestResult result = new TestResult( new TestInfo(test) ); result.SetResult( resultState, ignoreReason, null ); suiteResult.AddResult(result); listener.TestFinished(result); } } private void MarkTestsFailed( IList tests, TestResult suiteResult, EventListener listener, ITestFilter filter) { foreach (Test test in ArrayList.Synchronized(tests)) if (filter.Pass(test)) MarkTestFailed(test, suiteResult, listener, filter); } private void MarkTestFailed( Test test, TestResult suiteResult, EventListener listener, ITestFilter filter) { if (test is TestSuite) { listener.SuiteStarted(test.TestName); TestResult result = new TestResult( new TestInfo(test) ); string msg = this.FixtureType == null ? "Parent SetUp failed" : string.Format( "Parent SetUp failed in {0}", this.FixtureType.Name ); result.Failure(msg, null, FailureSite.Parent); MarkTestsFailed(test.Tests, result, listener, filter); suiteResult.AddResult(result); listener.SuiteFinished(result); } else { listener.TestStarted(test.TestName); TestResult result = new TestResult( new TestInfo(test) ); string msg = this.FixtureType == null ? "TestFixtureSetUp failed" : string.Format( "TestFixtureSetUp failed in {0}", this.FixtureType.Name ); result.Failure(msg, null, FailureSite.Parent); suiteResult.AddResult(result); listener.TestFinished(result); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/MethodHelper.cs0000664000175000017500000001417611544454420021467 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Text; namespace NUnit.Core { public class MethodHelper { public static string GetDisplayName(MethodInfo method, object[] arglist) { StringBuilder sb = new StringBuilder(method.Name); #if CLR_2_0 || CLR_4_0 if (method.IsGenericMethod) { sb.Append("<"); int cnt = 0; foreach (Type t in method.GetGenericArguments()) { if (cnt++ > 0) sb.Append(","); sb.Append(t.Name); } sb.Append(">"); } #endif if (arglist != null) { sb.Append("("); for (int i = 0; i < arglist.Length; i++) { if (i > 0) sb.Append(","); sb.Append(GetDisplayString(arglist[i])); } sb.Append(")"); } return sb.ToString(); } private static string GetDisplayString(object arg) { string display = arg == null ? "null" : Convert.ToString( arg, System.Globalization.CultureInfo.InvariantCulture); if (arg is double) { double d = (double)arg; if (double.IsNaN(d)) display = "double.NaN"; else if (double.IsPositiveInfinity(d)) display = "double.PositiveInfinity"; else if (double.IsNegativeInfinity(d)) display = "double.NegativeInfinity"; else if (d == double.MaxValue) display = "double.MaxValue"; else if (d == double.MinValue) display = "double.MinValue"; else { if (display.IndexOf('.') == -1) display += ".0"; display += "d"; } } else if (arg is float) { float f = (float)arg; if (float.IsNaN(f)) display = "float.NaN"; else if (float.IsPositiveInfinity(f)) display = "float.PositiveInfinity"; else if (float.IsNegativeInfinity(f)) display = "float.NegativeInfinity"; else if (f == float.MaxValue) display = "float.MaxValue"; else if (f == float.MinValue) display = "float.MinValue"; else { if (display.IndexOf('.') == -1) display += ".0"; display += "f"; } } else if (arg is decimal) { decimal d = (decimal)arg; if (d == decimal.MinValue) display = "decimal.MinValue"; else if (d == decimal.MaxValue) display = "decimal.MaxValue"; else display += "m"; } else if (arg is long) { long l = (long)arg; if (l == long.MinValue) display = "long.MinValue"; else if (l == long.MinValue) display = "long.MaxValue"; else display += "L"; } else if (arg is ulong) { ulong ul = (ulong)arg; if (ul == ulong.MinValue) display = "ulong.MinValue"; else if (ul == ulong.MinValue) display = "ulong.MaxValue"; else display += "UL"; } else if (arg is string) { StringBuilder sb = new StringBuilder(); sb.Append("\""); foreach (char c in (string)arg) sb.Append(EscapeControlChar(c)); sb.Append("\""); display = sb.ToString(); } else if (arg is char) { display = "\'" + EscapeControlChar((char)arg) + "\'"; } else if (arg is int) { int ival = (int)arg; if (ival == int.MaxValue) display = "int.MaxValue"; else if (ival == int.MinValue) display = "int.MinValue"; } return display; } private static string EscapeControlChar(char c) { switch (c) { case '\'': return "\\\'"; case '\"': return "\\\""; case '\\': return "\\\\"; case '\0': return "\\0"; case '\a': return "\\a"; case '\b': return "\\b"; case '\f': return "\\f"; case '\n': return "\\n"; case '\r': return "\\r"; case '\t': return "\\t"; case '\v': return "\\v"; case '\x0085': case '\x2028': case '\x2029': return string.Format("\\x{0:X4}", (int)c); default: return char.IsControl(c) || (int)c > 128 ? string.Format("\\x{0:X4}", (int)c) : c.ToString(); } } } } NUnit-2.6.0.12051/src/NUnitCore/core/InternalTraceWriter.cs0000664000175000017500000000350611647652254023043 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Diagnostics; using System.IO; namespace NUnit.Core { /// /// A trace listener that writes to a separate file per domain /// and process using it. /// public class InternalTraceWriter : TextWriter { StreamWriter writer; public InternalTraceWriter(string logName) { int pId = Process.GetCurrentProcess().Id; string domainName = AppDomain.CurrentDomain.FriendlyName; string fileName = logName .Replace("%p", pId.ToString() ) .Replace("%a", domainName ); string logPath = Path.Combine(NUnitConfiguration.LogDirectory, fileName); this.writer = new StreamWriter(logPath, true); this.writer.AutoFlush = true; } public override System.Text.Encoding Encoding { get { return writer.Encoding; } } public override void Write(char value) { writer.Write(value); } public override void Write(string value) { base.Write(value); } public override void WriteLine(string value) { writer.WriteLine(value); } public override void Close() { if (writer != null) { writer.Flush(); writer.Close(); writer = null; } } public override void Flush() { if ( writer != null ) writer.Flush(); } } } NUnit-2.6.0.12051/src/NUnitCore/core/TestBuilderAttribute.cs0000664000175000017500000000125111504175260023205 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public class TestBuilderAttribute : Attribute { private Type builderType; public TestBuilderAttribute(Type builderType) { this.builderType = builderType; } public Type BuilderType { get { return builderType; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/ExpectedExceptionProcessor.cs0000664000175000017500000002343611504175260024424 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Text.RegularExpressions; namespace NUnit.Core { public class ExpectedExceptionProcessor { #region Fields /// /// The TestMethod to which this exception processor applies /// internal TestMethod testMethod; /// /// The exception handler method /// internal MethodInfo exceptionHandler; /// /// The type of any expected exception /// internal Type expectedExceptionType; /// /// The full name of any expected exception type /// internal string expectedExceptionName; /// /// The value of any message associated with an expected exception /// internal string expectedMessage; /// /// A string indicating how to match the expected message /// internal string matchType; /// /// A string containing any user message specified for the expected exception /// internal string userMessage; #endregion #region Constructor public ExpectedExceptionProcessor( TestMethod testMethod ) { this.testMethod = testMethod; } public ExpectedExceptionProcessor(TestMethod testMethod, object source) { this.testMethod = testMethod; this.expectedExceptionType = GetExceptionType(source); this.expectedExceptionName = GetExceptionName(source); this.expectedMessage = GetExpectedMessage(source); this.matchType = GetMatchType(source); this.userMessage = GetUserMessage(source); string handlerName = GetHandler(source); if (handlerName == null) this.exceptionHandler = GetDefaultExceptionHandler(testMethod.FixtureType); else { MethodInfo handler = GetExceptionHandler(testMethod.FixtureType, handlerName); if (handler != null) this.exceptionHandler = handler; else { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = string.Format( "The specified exception handler {0} was not found", handlerName); } } } #endregion #region Public Methods public void ProcessNoException(TestResult testResult) { testResult.Failure(NoExceptionMessage(), null); } public void ProcessException(Exception exception, TestResult testResult) { if (exception is NUnitException) exception = exception.InnerException; if (IsExpectedExceptionType(exception)) { if (IsExpectedMessageMatch(exception)) { if (exceptionHandler != null) Reflect.InvokeMethod(exceptionHandler, testMethod.Fixture, exception); testResult.Success(); } else { testResult.Failure(WrongTextMessage(exception), GetStackTrace(exception)); } } else { switch (NUnitFramework.GetResultState(exception)) { case ResultState.Failure: testResult.Failure(exception.Message, exception.StackTrace); break; case ResultState.Ignored: testResult.Ignore(exception); break; case ResultState.Inconclusive: testResult.SetResult(ResultState.Inconclusive, exception, FailureSite.Test); break; case ResultState.Success: testResult.Success(exception.Message); break; default: testResult.Failure(WrongTypeMessage(exception), GetStackTrace(exception)); break; } } } #endregion #region Helper Methods private bool IsExpectedExceptionType(Exception exception) { return expectedExceptionName == null || expectedExceptionName.Equals(exception.GetType().FullName); } private bool IsExpectedMessageMatch(Exception exception) { if (expectedMessage == null) return true; switch (matchType) { case "Exact": default: return expectedMessage.Equals(exception.Message); case "Contains": return exception.Message.IndexOf(expectedMessage) >= 0; case "Regex": return Regex.IsMatch(exception.Message, expectedMessage); case "StartsWith": return exception.Message.StartsWith(expectedMessage); } } private string NoExceptionMessage() { string expectedType = expectedExceptionName == null ? "An Exception" : expectedExceptionName; return CombineWithUserMessage(expectedType + " was expected"); } private string WrongTypeMessage(Exception exception) { return CombineWithUserMessage( "An unexpected exception type was thrown" + Environment.NewLine + "Expected: " + expectedExceptionName + Environment.NewLine + " but was: " + exception.GetType().FullName + " : " + exception.Message); } private string WrongTextMessage(Exception exception) { string expectedText; switch (matchType) { default: case "Exact": expectedText = "Expected: "; break; case "Contains": expectedText = "Expected message containing: "; break; case "Regex": expectedText = "Expected message matching: "; break; case "StartsWith": expectedText = "Expected message starting: "; break; } return CombineWithUserMessage( "The exception message text was incorrect" + Environment.NewLine + expectedText + expectedMessage + Environment.NewLine + " but was: " + exception.Message); } private string CombineWithUserMessage(string message) { if (userMessage == null) return message; return userMessage + Environment.NewLine + message; } private string GetStackTrace(Exception exception) { try { return exception.StackTrace; } catch (Exception) { return "No stack trace available"; } } private static MethodInfo GetDefaultExceptionHandler(Type fixtureType) { return Reflect.HasInterface(fixtureType, NUnitFramework.ExpectExceptionInterface) ? GetExceptionHandler(fixtureType, "HandleException") : null; } private static MethodInfo GetExceptionHandler(Type fixtureType, string name) { return Reflect.GetNamedMethod( fixtureType, name, new string[] { "System.Exception" }); } private static string GetHandler(object source) { return Reflect.GetPropertyValue(source, "Handler") as string; } private static Type GetExceptionType(object source) { Type type = Reflect.GetPropertyValue(source, PropertyNames.ExpectedException) as Type; // Prior to 2.5, NUnit used an 'ExceptionType' property if (type == null) type = Reflect.GetPropertyValue(source, PropertyNames.LegacyExceptionType) as Type; return type; } private static string GetExceptionName(object source) { string name = Reflect.GetPropertyValue(source, PropertyNames.ExpectedExceptionName) as string; // Prior to 2.5, NUnit used an 'ExceptionName' property if (name == null) name = Reflect.GetPropertyValue(source, PropertyNames.LegacyExceptionName) as string; return name; } private static string GetExpectedMessage(object source) { return Reflect.GetPropertyValue(source, PropertyNames.ExpectedMessage) as string; } private static string GetMatchType(object source) { object matchEnum = Reflect.GetPropertyValue(source, "MatchType"); return matchEnum != null ? matchEnum.ToString() : null; } private static string GetUserMessage(object source) { return Reflect.GetPropertyValue(source, "UserMessage") as string; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TestRunnerThread.cs0000664000175000017500000000714711702656442022354 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Threading; using System.Configuration; using System.Collections.Specialized; namespace NUnit.Core { /// /// TestRunnerThread encapsulates running a test on a thread. /// It knows how to create the thread based on configuration /// settings and can cancel abort the test if necessary. /// public class TestRunnerThread { #region Private Fields /// /// The Test runner to be used in running tests on the thread /// private TestRunner runner; /// /// The System.Threading.Thread created by the object /// private Thread thread; /// /// The EventListener interface to receive test events /// private NUnit.Core.EventListener listener; /// /// The Test filter used in selecting the tests //private string[] testNames; private ITestFilter filter; /// /// Indicates whether trace output should be captured /// private bool tracing; /// /// The logging threshold for which output should be captured /// private LoggingThreshold logLevel; /// /// Array of returned results /// private TestResult[] results; #endregion #region Properties /// /// True if the thread is executing /// public bool IsAlive { get { return this.thread.IsAlive; } } /// /// Array of returned results /// public TestResult[] Results { get { return results; } } #endregion #region Constructor public TestRunnerThread( TestRunner runner, ApartmentState apartmentState, ThreadPriority priority ) { this.runner = runner; this.thread = new Thread( new ThreadStart( TestRunnerThreadProc ) ); thread.IsBackground = true; thread.Name = "TestRunnerThread"; thread.Priority = priority; if (apartmentState != ApartmentState.Unknown) #if CLR_2_0 || CLR_4_0 thread.SetApartmentState(apartmentState); #else thread.ApartmentState = apartmentState; #endif } #endregion #region Public Methods public void Wait() { if ( this.thread.IsAlive ) this.thread.Join(); } public void Cancel() { ThreadUtility.Kill(this.thread); } public void StartRun(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { this.listener = listener; this.filter = filter; this.tracing = tracing; this.logLevel = logLevel; thread.Start(); } #endregion #region Thread Proc /// /// The thread proc for our actual test run /// private void TestRunnerThreadProc() { try { results = new TestResult[] { runner.Run(this.listener, this.filter, this.tracing, this.logLevel) }; } catch (Exception ex) { if ( !(ex is ThreadAbortException) ) throw new ApplicationException("Exception in TestRunnerThread", ex); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/NUnitFramework.cs0000664000175000017500000004604411712475522022024 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using NUnit.Core.Extensibility; namespace NUnit.Core { /// /// Static methods that implement aspects of the NUnit framework that cut /// across individual test types, extensions, etc. Some of these use the /// methods of the Reflect class to implement operations specific to the /// NUnit Framework. /// public class NUnitFramework { #region Constants #region Attribute Names // NOTE: Attributes used in switch statements must be const // Attributes that apply to Assemblies, Classes and Methods public const string IgnoreAttribute = "NUnit.Framework.IgnoreAttribute"; public const string PlatformAttribute = "NUnit.Framework.PlatformAttribute"; public const string CultureAttribute = "NUnit.Framework.CultureAttribute"; public const string ExplicitAttribute = "NUnit.Framework.ExplicitAttribute"; public const string CategoryAttribute = "NUnit.Framework.CategoryAttribute"; public const string PropertyAttribute = "NUnit.Framework.PropertyAttribute"; public const string DescriptionAttribute = "NUnit.Framework.DescriptionAttribute"; public const string RequiredAddinAttribute = "NUnit.Framework.RequiredAddinAttribute"; // Attributes that apply only to Classes public const string TestFixtureAttribute = "NUnit.Framework.TestFixtureAttribute"; public const string SetUpFixtureAttribute = "NUnit.Framework.SetUpFixtureAttribute"; // Attributes that apply only to Methods public const string TestAttribute = "NUnit.Framework.TestAttribute"; public const string TestCaseAttribute = "NUnit.Framework.TestCaseAttribute"; public const string TestCaseSourceAttribute = "NUnit.Framework.TestCaseSourceAttribute"; public const string TheoryAttribute = "NUnit.Framework.TheoryAttribute"; public static readonly string SetUpAttribute = "NUnit.Framework.SetUpAttribute"; public static readonly string TearDownAttribute = "NUnit.Framework.TearDownAttribute"; public static readonly string FixtureSetUpAttribute = "NUnit.Framework.TestFixtureSetUpAttribute"; public static readonly string FixtureTearDownAttribute = "NUnit.Framework.TestFixtureTearDownAttribute"; public static readonly string ExpectedExceptionAttribute = "NUnit.Framework.ExpectedExceptionAttribute"; // Attributes that apply only to Properties public static readonly string SuiteAttribute = "NUnit.Framework.SuiteAttribute"; #endregion #region Other Framework Types public static readonly string TestActionInterface = "NUnit.Framework.ITestAction, nunit.framework"; public static readonly string TestDetailsClass = "NUnit.Framework.TestDetails, nunit.framework"; public static readonly string AssertException = "NUnit.Framework.AssertionException"; public static readonly string IgnoreException = "NUnit.Framework.IgnoreException"; public static readonly string InconclusiveException = "NUnit.Framework.InconclusiveException"; public static readonly string SuccessException = "NUnit.Framework.SuccessException"; public static readonly string AssertType = "NUnit.Framework.Assert"; public static readonly string ExpectExceptionInterface = "NUnit.Framework.IExpectException"; #endregion #region Core Types public static readonly string SuiteBuilderAttribute = typeof(SuiteBuilderAttribute).FullName; public static readonly string SuiteBuilderInterface = typeof(ISuiteBuilder).FullName; public static readonly string TestCaseBuilderAttributeName = typeof(TestCaseBuilderAttribute).FullName; public static readonly string TestCaseBuilderInterfaceName = typeof(ITestCaseBuilder).FullName; public static readonly string TestDecoratorAttributeName = typeof(TestDecoratorAttribute).FullName; public static readonly string TestDecoratorInterfaceName = typeof(ITestDecorator).FullName; #endregion #endregion #region Properties private static Assembly frameworkAssembly; private static bool frameworkAssemblyInitialized; private static Assembly FrameworkAssembly { get { if (!frameworkAssemblyInitialized) foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) if (assembly.GetName().Name == "nunit.framework" || assembly.GetName().Name == "NUnitLite") { frameworkAssembly = assembly; break; } frameworkAssemblyInitialized = true; return frameworkAssembly; } } #endregion #region Check SetUp and TearDown methods public static bool CheckSetUpTearDownMethods(Type fixtureType, string attributeName, ref string reason) { foreach( MethodInfo theMethod in Reflect.GetMethodsWithAttribute(fixtureType, attributeName, true )) if ( theMethod.IsAbstract || !theMethod.IsPublic && !theMethod.IsFamily || theMethod.GetParameters().Length > 0 || !theMethod.ReturnType.Equals(typeof(void))) { reason = string.Format( "Invalid signature for SetUp or TearDown method: {0}", theMethod.Name ); return false; } return true; } #endregion #region Get Special Properties of Attributes #region IgnoreReason public static string GetIgnoreReason( System.Attribute attribute ) { return Reflect.GetPropertyValue(attribute, PropertyNames.Reason) as string; } #endregion #region Description /// /// Method to return the description from an source /// /// The source to check /// The description, if any, or null public static string GetDescription(System.Attribute attribute) { return Reflect.GetPropertyValue(attribute, PropertyNames.Description) as string; } #endregion #endregion #region ApplyCommonAttributes /// /// Modify a newly constructed test based on a type or method by /// applying any of NUnit's common attributes. /// /// The type or method from which the test was constructed /// The test to which the attributes apply public static void ApplyCommonAttributes(MemberInfo member, Test test) { ApplyCommonAttributes( Reflect.GetAttributes( member, true ), test ); } /// /// Modify a newly constructed test based on an assembly by applying /// any of NUnit's common attributes. /// /// The assembly from which the test was constructed /// The test to which the attributes apply public static void ApplyCommonAttributes(Assembly assembly, Test test) { ApplyCommonAttributes( Reflect.GetAttributes( assembly, false ), test ); } /// /// Modify a newly constructed test by applying any of NUnit's common /// attributes, based on an input array of attributes. This method checks /// for all attributes, relying on the fact that specific attributes can only /// occur on those constructs on which they are allowed. /// /// An array of attributes possibly including NUnit attributes /// The test to which the attributes apply public static void ApplyCommonAttributes(Attribute[] attributes, Test test) { foreach (Attribute attribute in attributes) { Type attributeType = attribute.GetType(); string attributeName = attributeType.FullName; bool isValid = test.RunState != RunState.NotRunnable; switch (attributeName) { case TestFixtureAttribute: case TestAttribute: if ( test.Description == null ) test.Description = GetDescription( attribute ); break; case DescriptionAttribute: test.Description = GetDescription( attribute ); break; case PlatformAttribute: PlatformHelper pHelper = new PlatformHelper(); if (isValid && !pHelper.IsPlatformSupported(attribute)) { test.RunState = RunState.Skipped; test.IgnoreReason = GetIgnoreReason(attribute); if ( test.IgnoreReason == null ) test.IgnoreReason = pHelper.Reason; } break; case CultureAttribute: CultureDetector cultureDetector = new CultureDetector(); if (isValid && !cultureDetector.IsCultureSupported(attribute)) { test.RunState = RunState.Skipped; test.IgnoreReason = cultureDetector.Reason; } break; case RequiredAddinAttribute: string required = (string)Reflect.GetPropertyValue(attribute, PropertyNames.RequiredAddin); if (!IsAddinAvailable(required)) { test.RunState = RunState.NotRunnable; test.IgnoreReason = string.Format("Required addin {0} not available", required); } break; case "System.STAThreadAttribute": test.Properties.Add("APARTMENT_STATE", System.Threading.ApartmentState.STA); break; case "System.MTAThreadAttribute": test.Properties.Add("APARTMENT_STATE", System.Threading.ApartmentState.MTA); break; default: if ( Reflect.InheritsFrom( attributeType, CategoryAttribute ) ) { string categoryName = (string)Reflect.GetPropertyValue(attribute, PropertyNames.CategoryName); test.Categories.Add(categoryName); if (!IsValidCategoryName(categoryName)) { test.RunState = RunState.NotRunnable; test.IgnoreReason = "Category name must not contain ',', '!', '+' or '-'"; } } else if ( Reflect.InheritsFrom( attributeType, PropertyAttribute ) ) { IDictionary props = (IDictionary)Reflect.GetPropertyValue( attribute, PropertyNames.Properties ); if ( props != null ) foreach( DictionaryEntry entry in props ) test.Properties.Add(entry.Key, entry.Value); } else if ( Reflect.InheritsFrom( attributeType, ExplicitAttribute ) ) { if (isValid) { test.RunState = RunState.Explicit; test.IgnoreReason = GetIgnoreReason(attribute); } } else if (Reflect.InheritsFrom(attributeType, IgnoreAttribute)) { if (isValid) { test.RunState = RunState.Ignored; test.IgnoreReason = GetIgnoreReason(attribute); } } break; } } } #endregion #region ApplyExpectedExceptionAttribute /// /// Modify a newly constructed test by checking for ExpectedExceptionAttribute /// and setting properties on the test accordingly. /// /// An array of attributes possibly including NUnit attributes /// The test to which the attributes apply public static void ApplyExpectedExceptionAttribute(MethodInfo method, TestMethod testMethod) { Attribute attribute = Reflect.GetAttribute( method, NUnitFramework.ExpectedExceptionAttribute, false); if (attribute != null) testMethod.ExceptionProcessor = new ExpectedExceptionProcessor(testMethod, attribute); } #endregion #region IsSuiteBuilder public static bool IsSuiteBuilder( Type type ) { return Reflect.HasAttribute( type, SuiteBuilderAttribute, false ) && Reflect.HasInterface( type, SuiteBuilderInterface ); } #endregion #region IsTestCaseBuilder public static bool IsTestCaseBuilder( Type type ) { return Reflect.HasAttribute( type, TestCaseBuilderAttributeName, false ) && Reflect.HasInterface( type, TestCaseBuilderInterfaceName ); } #endregion #region IsTestDecorator public static bool IsTestDecorator( Type type ) { return Reflect.HasAttribute( type, TestDecoratorAttributeName, false ) && Reflect.HasInterface( type, TestDecoratorInterfaceName ); } #endregion #region IsAddinAvailable public static bool IsAddinAvailable(string name) { foreach (Addin addin in CoreExtensions.Host.AddinRegistry.Addins) if (addin.Name == name && addin.Status == AddinStatus.Loaded) return true; return false; } #endregion #region Framework Assert Access /// /// NUnitFramework.Assert is a nested class that implements /// a few of the framework operations by reflection, /// using whatever framework version is available. /// public class Assert { #region Properties private static Type assertType; private static Type AssertType { get { if (assertType == null && FrameworkAssembly != null) assertType = FrameworkAssembly.GetType(NUnitFramework.AssertType); return assertType; } } private static MethodInfo areEqualMethod; private static MethodInfo AreEqualMethod { get { if (areEqualMethod == null && AssertType != null) areEqualMethod = AssertType.GetMethod( "AreEqual", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(object), typeof(object) }, null ); return areEqualMethod; } } private static PropertyInfo counterProperty; private static PropertyInfo CounterProperty { get { if (counterProperty == null && AssertType != null) counterProperty = Reflect.GetNamedProperty( AssertType, "Counter", BindingFlags.Public | BindingFlags.Static); return counterProperty; } } #endregion /// /// Invoke Assert.AreEqual by reflection /// /// The expected value /// The actual value public static void AreEqual(object expected, object actual) { if (AreEqualMethod != null) try { AreEqualMethod.Invoke(null, new object[] { expected, actual }); } catch (TargetInvocationException e) { Exception inner = e.InnerException; throw new NUnitException("Rethrown", inner); } } /// /// Get the assertion counter. It clears itself automatically /// on each call. /// /// Count of number of asserts since last call public static int GetAssertCount() { return CounterProperty == null ? 0 : (int)CounterProperty.GetValue(null, new object[0]); } } #endregion #region GetResultState /// /// Returns a result state for a special exception. /// If the exception is not handled specially, returns /// ResultState.Error. /// /// The exception to be examined /// A ResultState public static ResultState GetResultState(Exception ex) { if (ex is System.Threading.ThreadAbortException) return ResultState.Cancelled; string name = ex.GetType().FullName; if (name == NUnitFramework.AssertException) return ResultState.Failure; else if (name == NUnitFramework.IgnoreException) return ResultState.Ignored; else if (name == NUnitFramework.InconclusiveException) return ResultState.Inconclusive; else if (name == NUnitFramework.SuccessException) return ResultState.Success; else return ResultState.Error; } #endregion #region IsValidCategoryName /// /// Returns true if the category name is valid /// public static bool IsValidCategoryName(string name) { return name.IndexOfAny(new char[] { ',', '!', '+', '-' }) < 0; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ProjectRootSuite.cs0000664000175000017500000000176311504175260022367 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// TestAssembly is a TestSuite that represents the execution /// of tests in a managed assembly. /// public class ProjectRootSuite : TestSuite { /// /// Initializes a new instance of the class. /// /// The path. public ProjectRootSuite(string path) : base(path) { } /// /// Gets the type of the test. /// public override string TestType { get { return "Project"; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/TestFixture.cs0000664000175000017500000000256711504175260021374 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// TestFixture is a surrogate for a user test fixture class, /// containing one or more tests. /// public class TestFixture : TestSuite { #region Constructors public TestFixture(Type fixtureType) : base(fixtureType) { } public TestFixture(Type fixtureType, object[] arguments) : base(fixtureType, arguments) { } #endregion #region TestSuite Overrides /// /// Gets a string representing the kind of test /// that this object represents, for use in display. /// public override string TestType { get { return "TestFixture"; } } public override TestResult Run(EventListener listener, ITestFilter filter) { using ( new DirectorySwapper( AssemblyHelper.GetDirectoryName( FixtureType.Assembly ) ) ) { return base.Run(listener, filter); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TypeHelper.cs0000664000175000017500000001606511544454420021167 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Text; using System.Text.RegularExpressions; namespace NUnit.Core { public class TypeHelper { public static string GetDisplayName(Type type) { #if CLR_2_0 || CLR_4_0 if (type.IsGenericParameter) return type.Name; if (type.IsGenericType) { string name = type.FullName; int index = name.IndexOf("[["); if (index > 0) { int index2 = name.LastIndexOf("]]"); if (index2 > index) name = name.Substring(0, index) + name.Substring(index2 + 2); } index = name.LastIndexOf('.'); if (index >= 0) name = name.Substring(index + 1); index = name.IndexOf('`'); while (index >= 0) { int index2 = name.IndexOf('+', index); if (index2 >= 0) name = name.Substring(0, index) + name.Substring(index2); else name = name.Substring(0, index); index = name.IndexOf('`'); } StringBuilder sb = new StringBuilder(name); sb.Append("<"); int cnt = 0; foreach (Type t in type.GetGenericArguments()) { if (cnt++ > 0) sb.Append(","); sb.Append(GetDisplayName(t)); } sb.Append(">"); return sb.ToString(); } #endif int lastdot = type.FullName.LastIndexOf('.'); return lastdot >= 0 ? type.FullName.Substring(lastdot + 1) : type.FullName; } public static string GetDisplayName(Type type, object[] arglist) { string baseName = GetDisplayName(type); if (arglist == null || arglist.Length == 0) return baseName; StringBuilder sb = new StringBuilder( baseName ); sb.Append("("); for (int i = 0; i < arglist.Length; i++) { if (i > 0) sb.Append(","); object arg = arglist[i]; string display = arg == null ? "null" : arg.ToString(); if (arg is double || arg is float) { if (display.IndexOf('.') == -1) display += ".0"; display += arg is double ? "d" : "f"; } else if (arg is decimal) display += "m"; else if (arg is long) display += "L"; else if (arg is ulong) display += "UL"; else if (arg is string) display = "\"" + display + "\""; sb.Append(display); } sb.Append(")"); return sb.ToString(); } public static Type BestCommonType(Type type1, Type type2) { if (type1 == type2) return type1; if (type1 == null) return type2; if (type2 == null) return type1; if (TypeHelper.IsNumeric(type1) && TypeHelper.IsNumeric(type2)) { if (type1 == typeof(double)) return type1; if (type2 == typeof(double)) return type2; if (type1 == typeof(float)) return type1; if (type2 == typeof(float)) return type2; if (type1 == typeof(decimal)) return type1; if (type2 == typeof(decimal)) return type2; if (type1 == typeof(UInt64)) return type1; if (type2 == typeof(UInt64)) return type2; if (type1 == typeof(Int64)) return type1; if (type2 == typeof(Int64)) return type2; if (type1 == typeof(UInt32)) return type1; if (type2 == typeof(UInt32)) return type2; if (type1 == typeof(Int32)) return type1; if (type2 == typeof(Int32)) return type2; if (type1 == typeof(UInt16)) return type1; if (type2 == typeof(UInt16)) return type2; if (type1 == typeof(Int16)) return type1; if (type2 == typeof(Int16)) return type2; if (type1 == typeof(byte)) return type1; if (type2 == typeof(byte)) return type2; if (type1 == typeof(sbyte)) return type1; if (type2 == typeof(sbyte)) return type2; } return type1; } public static bool IsNumeric(Type type) { return type == typeof(double) || type == typeof(float) || type == typeof(decimal) || type == typeof(Int64) || type == typeof(Int32) || type == typeof(Int16) || type == typeof(UInt64) || type == typeof(UInt32) || type == typeof(UInt16) || type == typeof(byte) || type == typeof(sbyte); } #if CLR_2_0 || CLR_4_0 public static Type MakeGenericType(Type type, Type[] typeArgs) { // TODO: Add error handling return type.MakeGenericType(typeArgs); } public static bool CanDeduceTypeArgsFromArgs(Type type, object[] arglist, ref Type[] typeArgsOut) { Type[] typeParameters = type.GetGenericArguments(); foreach (ConstructorInfo ctor in type.GetConstructors()) { ParameterInfo[] parameters = ctor.GetParameters(); if (parameters.Length != arglist.Length) continue; Type[] typeArgs = new Type[typeParameters.Length]; for (int i = 0; i < typeArgs.Length; i++) { for (int j = 0; j < arglist.Length; j++) { if (parameters[j].ParameterType.Equals(typeParameters[i])) typeArgs[i] = TypeHelper.BestCommonType( typeArgs[i], arglist[j].GetType()); } if (typeArgs[i] == null) { typeArgs = null; break; } } if (typeArgs != null) { typeArgsOut = typeArgs; return true; } } return false; } #endif } } NUnit-2.6.0.12051/src/NUnitCore/core/SimpleTestRunner.cs0000664000175000017500000001261611702656442022373 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Threading; using System.Collections; using System.Collections.Specialized; using NUnit.Core.Filters; using System.Reflection; namespace NUnit.Core { /// /// SimpleTestRunner is the simplest direct-running TestRunner. It /// passes the event listener interface that is provided on to the tests /// to use directly and does nothing to redirect text output. Both /// Run and BeginRun are actually synchronous, although the client /// can usually ignore this. BeginRun + EndRun operates as expected. /// public class SimpleTestRunner : MarshalByRefObject, TestRunner { static Logger log = InternalTrace.GetLogger(typeof(SimpleTestRunner)); #region Instance Variables /// /// Identifier for this runner. Must be unique among all /// active runners in order to locate tests. Default /// value of 0 is adequate in applications with a single /// runner or a non-branching chain of runners. /// private int runnerID = 0; /// /// The loaded test suite /// private Test test; /// /// The builder we use to load tests, created for each load /// private TestSuiteBuilder builder; /// /// Results from the last test run /// private TestResult testResult; /// /// The thread on which Run was called. Set to the /// current thread while a run is in process. /// private Thread runThread; #endregion #region Constructor public SimpleTestRunner() : this( 0 ) { } public SimpleTestRunner( int runnerID ) { this.runnerID = runnerID; } #endregion #region Properties public virtual int ID { get { return runnerID; } } public IList AssemblyInfo { get { return builder.AssemblyInfo; } } public ITest Test { get { return test == null ? null : new TestNode( test ); } } /// /// Results from the last test run /// public TestResult TestResult { get { return testResult; } } public virtual bool Running { get { return runThread != null && runThread.IsAlive; } } #endregion #region Methods for Loading Tests /// /// Load a TestPackage /// /// The package to be loaded /// True on success, false on failure public bool Load( TestPackage package ) { log.Debug("Loading package " + package.Name); this.builder = new TestSuiteBuilder(); this.test = builder.Build( package ); if ( test == null ) return false; test.SetRunnerID( this.runnerID, true ); TestExecutionContext.CurrentContext.TestPackage = package; return true; } /// /// Unload all tests previously loaded /// public void Unload() { log.Debug("Unloading"); this.test = null; // All for now } #endregion #region CountTestCases public int CountTestCases( ITestFilter filter ) { return test.CountTestCases( filter ); } #endregion #region Methods for Running Tests public virtual TestResult Run( EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel ) { try { log.Debug("Starting test run"); // Take note of the fact that we are running this.runThread = Thread.CurrentThread; listener.RunStarted( this.Test.TestName.FullName, test.CountTestCases( filter ) ); testResult = test.Run( listener, filter ); // Signal that we are done listener.RunFinished( testResult ); log.Debug("Test run complete"); // Return result array return testResult; } catch( Exception exception ) { // Signal that we finished with an exception listener.RunFinished( exception ); // Rethrow - should we do this? throw; } finally { runThread = null; } } public void BeginRun(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { testResult = this.Run(listener, filter, tracing, logLevel); } public virtual TestResult EndRun() { return TestResult; } /// /// Wait is a NOP for SimpleTestRunner /// public virtual void Wait() { } public virtual void CancelRun() { if (this.runThread != null) { // Cancel Synchronous run only if on another thread if ( this.runThread == Thread.CurrentThread ) throw new InvalidOperationException( "May not CancelRun on same thread that is running the test" ); ThreadUtility.Kill(this.runThread); } } #endregion #region InitializeLifetimeService Override public override object InitializeLifetimeService() { return null; } #endregion #region IDisposable Members public void Dispose() { Unload(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/SuiteBuilderAttribute.cs0000664000175000017500000000122311504175260023356 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// SuiteBuilderAttribute is used to mark custom suite builders. /// The class so marked must implement the ISuiteBuilder interface. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public sealed class SuiteBuilderAttribute : Attribute {} } NUnit-2.6.0.12051/src/NUnitCore/core/Log4NetCapture.cs0000664000175000017500000001660411702550410021675 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using BF = System.Reflection.BindingFlags; namespace NUnit.Core { /// /// Proxy class for operations on a real log4net appender, /// allowing NUnit to work with multiple versions of log4net /// and to fail gracefully if no log4net assembly is present. /// public class Log4NetCapture : TextCapture { /// /// The TextWriter to which text is redirected /// private TextWriter writer; /// /// The threshold for capturing text. A value of "Off" /// means that no text is captured. A value of "All" /// should be taken to mean the highest possible level /// of verbosity supported by the derived class. The /// meaning of any other values is determined by the /// derived class. /// private LoggingThreshold threshold = LoggingThreshold.Off; private Assembly log4netAssembly; private Type appenderType; private Type basicConfiguratorType; private object appender; private bool isInitialized; // Layout codes that work for versions from // log4net 1.2.0.30714 to 1.2.10: // // %a = domain friendly name // %c = logger name (%c{1} = last component ) // %d = date and time // %d{ABSOLUTE} = time only // %l = source location of the error // %m = message // %n = newline // %p = level // %r = elapsed milliseconds since program start // %t = thread // %x = nested diagnostic content (NDC) private static readonly string logFormat = "%d{ABSOLUTE} %-5p [%4t] %c{1} [%x]- %m%n"; /// /// Gets or sets the TextWriter to which text is redirected /// when captured. The value may only be changed when the /// logging threshold is set to "Off" /// public override TextWriter Writer { get { return writer; } set { if (threshold != LoggingThreshold.Off) throw new System.InvalidOperationException( "Writer may not be changed while capture is enabled"); writer = value; } } /// /// Gets or sets the capture threshold value, which represents /// the degree of verbosity of the output text stream. /// Derived classes may supply multiple levels of capture but /// must retain the use of the "Off" setting to represent /// no logging. /// public override LoggingThreshold Threshold { get { return threshold; } set { if (value != threshold) { bool turnOff = value == LoggingThreshold.Off; //bool turnOn = threshold == LoggingThreshold.Off; //if (turnOff) StopCapture(); threshold = value; if (!turnOff) StartCapture(); } } } private void StartCapture() { if (IsLog4netAvailable) { string threshold = Threshold.ToString(); if ( !SetLoggingThreshold( threshold ) ) SetLoggingThreshold( "Error" ); SetAppenderTextWriter( this.Writer ); ConfigureAppender(); } } private void ResumeCapture() { if (IsLog4netAvailable) { SetLoggingThreshold(Threshold.ToString()); ConfigureAppender(); } } private void StopCapture() { if ( writer != null ) writer.Flush(); if ( appender != null ) { SetLoggingThreshold( "Off" ); //SetAppenderTextWriter( null ); } } #region Private Properties and Methods private bool IsLog4netAvailable { get { if (!isInitialized) InitializeTypes(); return log4netAssembly != null && basicConfiguratorType != null && appenderType != null; } } private void InitializeTypes() { try { log4netAssembly = Assembly.Load("log4net"); if (log4netAssembly != null) { appenderType = log4netAssembly.GetType( "log4net.Appender.TextWriterAppender", false, false); basicConfiguratorType = log4netAssembly.GetType( "log4net.Config.BasicConfigurator", false, false); appender = TryCreateAppender(); if (appender != null) SetAppenderLogFormat(logFormat); } } catch { } finally { isInitialized = true; } } /// /// Attempt to create a TextWriterAppender using reflection, /// failing silently if it is not possible. /// private object TryCreateAppender() { ConstructorInfo ctor = appenderType.GetConstructor( Type.EmptyTypes ); object appender = ctor.Invoke( new object[0] ); return appender; } private void SetAppenderLogFormat( string logFormat ) { Type patternLayoutType = log4netAssembly.GetType( "log4net.Layout.PatternLayout", false, false ); if ( patternLayoutType == null ) return; ConstructorInfo ctor = patternLayoutType.GetConstructor( new Type[] { typeof(string) } ); if ( ctor != null ) { object patternLayout = ctor.Invoke( new object[] { logFormat } ); if ( patternLayout != null ) { PropertyInfo prop = appenderType.GetProperty( "Layout", BF.Public | BF.Instance | BF.SetProperty ); if ( prop != null ) prop.SetValue( appender, patternLayout, null ); } } } private bool SetLoggingThreshold( string threshold ) { PropertyInfo prop = appenderType.GetProperty( "Threshold", BF.Public | BF.Instance | BF.SetProperty ); if ( prop == null ) return false; Type levelType = prop.PropertyType; FieldInfo levelField = levelType.GetField( threshold, BF.Public | BF.Static | BF.IgnoreCase ); if ( levelField == null ) return false; object level = levelField.GetValue( null ); prop.SetValue( appender, level, null ); return true; } private void SetAppenderTextWriter( TextWriter writer ) { PropertyInfo prop = appenderType.GetProperty( "Writer", BF.Instance | BF.Public | BF.SetProperty ); if ( prop != null ) prop.SetValue( appender, writer, null ); } private void ConfigureAppender() { MethodInfo configureMethod = basicConfiguratorType.GetMethod( "Configure", new Type[] { appenderType } ); if ( configureMethod != null ) configureMethod.Invoke( null, new object[] { appender } ); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/NUnitConfiguration.cs0000664000175000017500000001776311700546716022705 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; using System.Configuration; using System.Collections.Specialized; using System.Threading; using Microsoft.Win32; namespace NUnit.Core { /// /// Provides static methods for accessing the NUnit config /// file /// public class NUnitConfiguration { #region Public Properties #region BuildConfiguration public static string BuildConfiguration { get { #if DEBUG return "Debug"; #else return "Release"; #endif } } #endregion #region NUnitLibDirectory private static string nunitLibDirectory; /// /// Gets the path to the lib directory for the version and build /// of NUnit currently executing. /// public static string NUnitLibDirectory { get { if (nunitLibDirectory == null) { nunitLibDirectory = AssemblyHelper.GetDirectoryName(Assembly.GetExecutingAssembly()); } return nunitLibDirectory; } } #endregion #region NUnitBinDirectory private static string nunitBinDirectory; public static string NUnitBinDirectory { get { if (nunitBinDirectory == null) { nunitBinDirectory = NUnitLibDirectory; if (Path.GetFileName(nunitBinDirectory).ToLower() == "lib") nunitBinDirectory = Path.GetDirectoryName(nunitBinDirectory); } return nunitBinDirectory; } } #endregion #region NUnitDocDirectory private static string nunitDocDirectory; private static string NUnitDocDirectory { get { if (nunitDocDirectory == null) { string dir = Path.GetDirectoryName(NUnitBinDirectory); nunitDocDirectory = Path.Combine(dir, "doc"); if (!Directory.Exists(nunitDocDirectory)) { dir = Path.GetDirectoryName(dir); nunitDocDirectory = Path.Combine(dir, "doc"); } } return nunitDocDirectory; } } #endregion #region AddinDirectory private static string addinDirectory; public static string AddinDirectory { get { if (addinDirectory == null) { addinDirectory = Path.Combine(NUnitBinDirectory, "addins"); } return addinDirectory; } } #endregion #region TestAgentExePath //private static string testAgentExePath; //private static string TestAgentExePath //{ // get // { // if (testAgentExePath == null) // testAgentExePath = Path.Combine(NUnitBinDirectory, "nunit-agent.exe"); // return testAgentExePath; // } //} #endregion #region MonoExePath private static string monoExePath; public static string MonoExePath { get { if (monoExePath == null) { string[] searchNames = IsWindows() ? new string[] { "mono.bat", "mono.cmd", "mono.exe" } : new string[] { "mono", "mono.exe" }; monoExePath = FindOneOnPath(searchNames); if (monoExePath == null && IsWindows()) { RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Novell\Mono"); if (key != null) { string version = key.GetValue("DefaultCLR") as string; if (version != null) { key = key.OpenSubKey(version); if (key != null) { string installDir = key.GetValue("SdkInstallRoot") as string; if (installDir != null) monoExePath = Path.Combine(installDir, @"bin\mono.exe"); } } } } if (monoExePath == null) return "mono"; } return monoExePath; } } private static string FindOneOnPath(string[] names) { //foreach (string dir in Environment.GetEnvironmentVariable("path").Split(new char[] { Path.PathSeparator })) // foreach (string name in names) // { // string fullPath = Path.Combine(dir, name); // if (File.Exists(fullPath)) // return name; // } return null; } private static bool IsWindows() { return Environment.OSVersion.Platform == PlatformID.Win32NT; } #endregion #region ApplicationDataDirectory private static string applicationDirectory; public static string ApplicationDirectory { get { if (applicationDirectory == null) { applicationDirectory = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NUnit"); } return applicationDirectory; } } #endregion #region LogDirectory private static string logDirectory; public static string LogDirectory { get { if (logDirectory == null) { logDirectory = Path.Combine(ApplicationDirectory, "logs"); } return logDirectory; } } #endregion #region HelpUrl public static string HelpUrl { get { string helpUrl = "http://nunit.org"; string dir = Path.GetDirectoryName(NUnitBinDirectory); string docDir = null; while (dir != null) { docDir = Path.Combine(dir, "doc"); if (Directory.Exists(docDir)) break; dir = Path.GetDirectoryName(dir); } if (docDir != null) { string localPath = Path.Combine(docDir, "index.html"); if (File.Exists(localPath)) { UriBuilder uri = new UriBuilder(); uri.Scheme = "file"; uri.Host = "localhost"; uri.Path = localPath; helpUrl = uri.ToString(); } } return helpUrl; } } #endregion #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TestDecoratorAttribute.cs0000664000175000017500000000117411504175260023545 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// TestDecoratorAttribute is used to mark custom suite builders. /// The class so marked must implement the ISuiteBuilder interface. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public sealed class TestDecoratorAttribute : Attribute {} } NUnit-2.6.0.12051/src/NUnitCore/core/AbstractTestCaseDecoration.cs0000664000175000017500000000247711504175260024315 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Collections.Specialized; namespace NUnit.Core { /// /// TestDecorator is used to add functionality to /// another Test, which it aggregates. /// public abstract class TestDecorator : TestMethod { protected TestMethod test; public TestDecorator( TestMethod test ) //: base( (TestName)test.TestName.Clone() ) : base( test.Method ) { this.test = test; this.RunState = test.RunState; this.IgnoreReason = test.IgnoreReason; this.Description = test.Description; this.Categories = new System.Collections.ArrayList( test.Categories ); if ( test.Properties != null ) { this.Properties = new ListDictionary(); foreach (DictionaryEntry entry in test.Properties) this.Properties.Add(entry.Key, entry.Value); } } public override int TestCount { get { return test.TestCount; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/AssemblyResolver.cs0000664000175000017500000000673611504175260022411 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.IO; using System.Reflection; using System.Collections; /// /// Class adapted from NUnitAddin for use in handling assemblies that are not /// found in the test AppDomain. /// public class AssemblyResolver : MarshalByRefObject, IDisposable { static Logger log = InternalTrace.GetLogger(typeof(AssemblyResolver)); private class AssemblyCache { private Hashtable _resolved = new Hashtable(); public bool Contains( string name ) { return _resolved.ContainsKey( name ); } public Assembly Resolve( string name ) { if ( _resolved.ContainsKey( name ) ) return (Assembly)_resolved[name]; return null; } public void Add( string name, Assembly assembly ) { _resolved[name] = assembly; } } private AssemblyCache _cache = new AssemblyCache(); private ArrayList _dirs = new ArrayList(); public AssemblyResolver() { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } public void Dispose() { AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve); } public void AddFile( string file ) { Assembly assembly = Assembly.LoadFrom( file ); _cache.Add(assembly.GetName().FullName, assembly); } public void AddFiles( string directory, string pattern ) { if ( Directory.Exists( directory ) ) foreach( string file in Directory.GetFiles( directory, pattern ) ) AddFile( file ); } public void AddDirectory( string directory ) { if ( Directory.Exists( directory ) ) _dirs.Add( directory ); } private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string fullName = args.Name; int index = fullName.IndexOf(','); if(index == -1) // Only resolve using full name. { log.Debug( string.Format("Not a strong name: {0}", fullName ) ); return null; } if ( _cache.Contains( fullName ) ) { log.Info( string.Format( "Resolved from Cache: {0}", fullName ) ); return _cache.Resolve(fullName); } foreach( string dir in _dirs ) { foreach( string file in Directory.GetFiles( dir, "*.dll" ) ) { string fullFile = Path.Combine( dir, file ); AssemblyReader rdr = new AssemblyReader(fullFile); try { if (rdr.IsDotNetFile) { if (AssemblyName.GetAssemblyName(fullFile).FullName == fullName) { log.Info(string.Format("Added to Cache: {0}", fullFile)); AddFile(fullFile); return _cache.Resolve(fullName); } } } catch(Exception ex) { log.Error( "Unable to load addin assembly", ex ); throw; } } } log.Debug( string.Format( "Not in Cache: {0}", fullName) ); return null; } } } NUnit-2.6.0.12051/src/NUnitCore/core/ThreadedTestRunner.cs0000664000175000017500000000450111702656442022654 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Threading; using System.Collections.Specialized; /// /// ThreadedTestRunner overrides the Run and BeginRun methods /// so that they are always run on a separate thread. The actual /// public class ThreadedTestRunner : ProxyTestRunner { static Logger log = InternalTrace.GetLogger(typeof(ThreadedTestRunner)); #region Instance Variables private TestRunnerThread testRunnerThread; private ApartmentState apartmentState; private ThreadPriority priority; #endregion #region Constructor public ThreadedTestRunner(TestRunner testRunner) : this(testRunner, ApartmentState.Unknown, ThreadPriority.Normal) { } public ThreadedTestRunner(TestRunner testRunner, ApartmentState apartmentState, ThreadPriority priority) : base(testRunner) { this.apartmentState = apartmentState; this.priority = priority; } #endregion #region Overrides public override TestResult Run(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { BeginRun(listener, filter, tracing, logLevel); return EndRun(); } public override void BeginRun(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { log.Info("BeginRun"); testRunnerThread = new TestRunnerThread(this.TestRunner, this.apartmentState, this.priority); testRunnerThread.StartRun(listener, filter, tracing, logLevel); } public override TestResult EndRun() { log.Info("EndRun"); this.Wait(); return this.TestRunner.TestResult; } public override void Wait() { if ( testRunnerThread != null ) testRunnerThread.Wait(); } public override void CancelRun() { if ( testRunnerThread != null ) testRunnerThread.Cancel(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ParameterizedFixtureSuite.cs0000664000175000017500000000321711544454420024256 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// ParameterizedFixtureSuite serves as a container for the set of test /// fixtures created from a given Type using various parameters. /// public class ParameterizedFixtureSuite : TestSuite { private Type type; /// /// Initializes a new instance of the class. /// /// The type. public ParameterizedFixtureSuite(Type type) : base(type.Namespace, TypeHelper.GetDisplayName(type)) { this.type = type; } /// /// Gets the type of the test. /// /// The type of the test. public override string TestType { get { #if CLR_2_0 || CLR_4_0 if (type.IsGenericType) return "GenericFixture"; #endif return "ParameterizedFixture"; } } /// /// Gets the Type represented by this suite. /// /// A Sysetm.Type. public Type ParameterizedType { get { return type; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/NUnitException.cs0000664000175000017500000000265011504175260022013 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Runtime.Serialization; /// /// Thrown when an assertion failed. Here to preserve the inner /// exception and hence its stack trace. /// /// [Serializable] public class NUnitException : ApplicationException { public NUnitException () : base() {} /// /// Standard constructor /// /// The error message that explains /// the reason for the exception public NUnitException(string message) : base (message) {} /// /// Standard constructor /// /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public NUnitException(string message, Exception inner) : base(message, inner) {} /// /// Serialization Constructor /// protected NUnitException(SerializationInfo info, StreamingContext context) : base(info,context){} } } NUnit-2.6.0.12051/src/NUnitCore/core/SetUpFixture.cs0000664000175000017500000000354611712475522021520 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Reflection; namespace NUnit.Core { /// /// SetUpFixture extends TestSuite and supports /// Setup and TearDown methods. /// public class SetUpFixture : TestSuite { #region Constructor public SetUpFixture( Type type ) : base( type ) { this.TestName.Name = type.Namespace; if (this.TestName.Name == null) this.TestName.Name = "[default namespace]"; int index = TestName.Name.LastIndexOf('.'); if (index > 0) this.TestName.Name = this.TestName.Name.Substring(index + 1); this.fixtureSetUpMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.SetUpAttribute, true ); this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.TearDownAttribute, true ); #if CLR_2_0 || CLR_4_0 this.actions = ActionsHelper.GetActionsFromTypesAttributes(type); #endif } #endregion #region TestSuite Overrides /// /// Gets a string representing the kind of test /// that this object represents, for use in display. /// public override string TestType { get { return "SetUpFixture"; } } public override TestResult Run(EventListener listener, ITestFilter filter) { using ( new DirectorySwapper( AssemblyHelper.GetDirectoryName( FixtureType.Assembly ) ) ) { return base.Run(listener, filter); } } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ThreadUtility.cs0000664000175000017500000000327711703130526021675 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Threading; namespace NUnit.Core { public class ThreadUtility { /// /// Do our best to Kill a thread /// /// The thread to kill public static void Kill(Thread thread) { Kill(thread, null); } /// /// Do our best to kill a thread, passing state info /// /// The thread to kill /// Info for the ThreadAbortException handler public static void Kill(Thread thread, object stateInfo) { try { if (stateInfo == null) thread.Abort(); else thread.Abort(stateInfo); } catch (ThreadStateException) { // This is deprecated but still needed in this case // in order to kill the thread. The warning can't // be disabled because the #pragma directive is not // recognized by the .NET 1.1 compiler. thread.Resume(); } if ( (thread.ThreadState & ThreadState.WaitSleepJoin) != 0 ) thread.Interrupt(); } private ThreadUtility() { } } } NUnit-2.6.0.12051/src/NUnitCore/core/ActionsHelper.cs0000664000175000017500000000775211712475522021654 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2012, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** #if CLR_2_0 || CLR_4_0 using System; using System.Collections; using System.Collections.Generic; using System.Reflection; namespace NUnit.Core { internal class ActionsHelper { private static Type _ActionInterfaceType = null; static ActionsHelper() { _ActionInterfaceType = Type.GetType(NUnitFramework.TestActionInterface); } public static void ExecuteActions(ActionPhase phase, IEnumerable actions, ITest test) { if (actions == null) return; TestAction[] filteredActions = GetFilteredAndSortedActions(actions, phase); foreach (TestAction action in filteredActions) { if(phase == ActionPhase.Before) action.ExecuteBefore(test); else action.ExecuteAfter(test); } } public static TestAction[] GetActionsFromAttributeProvider(ICustomAttributeProvider attributeProvider) { if (attributeProvider == null || _ActionInterfaceType == null) return new TestAction[0]; object[] targets = attributeProvider.GetCustomAttributes(_ActionInterfaceType, false); List actions = new List(); foreach (var target in targets) actions.Add(new TestAction(target)); actions.Sort(SortByTargetDescending); return actions.ToArray(); } public static TestAction[] GetActionsFromTypesAttributes(Type type) { if(type == null) return new TestAction[0]; if(type == typeof(object)) return new TestAction[0]; List actions = new List(); actions.AddRange(GetActionsFromTypesAttributes(type.BaseType)); Type[] declaredInterfaces = GetDeclaredInterfaces(type); foreach(Type interfaceType in declaredInterfaces) actions.AddRange(GetActionsFromAttributeProvider(interfaceType)); actions.AddRange(GetActionsFromAttributeProvider(type)); return actions.ToArray(); } private static Type[] GetDeclaredInterfaces(Type type) { List interfaces = new List(type.GetInterfaces()); if (type.BaseType == typeof(object)) return interfaces.ToArray(); List baseInterfaces = new List(type.BaseType.GetInterfaces()); List declaredInterfaces = new List(); foreach (Type interfaceType in interfaces) { if (!baseInterfaces.Contains(interfaceType)) declaredInterfaces.Add(interfaceType); } return declaredInterfaces.ToArray(); } private static TestAction[] GetFilteredAndSortedActions(IEnumerable actions, ActionPhase phase) { List filteredActions = new List(); foreach (TestAction actionItem in actions) { if (filteredActions.Contains(actionItem) != true) filteredActions.Add(actionItem); } if(phase == ActionPhase.After) filteredActions.Reverse(); return filteredActions.ToArray(); } private static int SortByTargetDescending(TestAction x, TestAction y) { return y.Targets.CompareTo(x.Targets); } } public enum ActionPhase { Before, After } } #endif NUnit-2.6.0.12051/src/NUnitCore/core/PlatformHelper.cs0000664000175000017500000002010111710344414022010 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { public class PlatformHelper { private OSPlatform os; private RuntimeFramework rt; // Set whenever we fail to support a list of platforms private string reason = string.Empty; /// /// Comma-delimited list of all supported OS platform constants /// public static readonly string OSPlatforms = "Win,Win32,Win32S,Win32NT,Win32Windows,WinCE,Win95,Win98,WinMe,NT3,NT4,NT5,NT6,Win2K,WinXP,Win2003Server,Vista,Win2008Server,Win2008ServerR2,Win2012Server,Windows7,Windows8,Unix,Linux"; /// /// Comma-delimited list of all supported Runtime platform constants /// public static readonly string RuntimePlatforms = "Net,NetCF,SSCLI,Rotor,Mono"; /// /// Default constructor uses the operating system and /// common language runtime of the system. /// public PlatformHelper() { this.os = OSPlatform.CurrentPlatform; this.rt = RuntimeFramework.CurrentFramework; } /// /// Contruct a PlatformHelper for a particular operating /// system and common language runtime. Used in testing. /// /// OperatingSystem to be used public PlatformHelper( OSPlatform os, RuntimeFramework rt ) { this.os = os; this.rt = rt; } /// /// Test to determine if one of a collection of platforms /// is being used currently. /// /// /// public bool IsPlatformSupported( string[] platforms ) { foreach( string platform in platforms ) if ( IsPlatformSupported( platform ) ) return true; return false; } /// /// Tests to determine if the current platform is supported /// based on a platform attribute. /// /// The attribute to examine /// public bool IsPlatformSupported( Attribute platformAttribute ) { //Use reflection to avoid dependency on a particular framework version string include = (string)Reflect.GetPropertyValue( platformAttribute, "Include", BindingFlags.Public | BindingFlags.Instance ); string exclude = (string)Reflect.GetPropertyValue( platformAttribute, "Exclude", BindingFlags.Public | BindingFlags.Instance ); try { if (include != null && !IsPlatformSupported(include)) { reason = string.Format("Only supported on {0}", include); return false; } if (exclude != null && IsPlatformSupported(exclude)) { reason = string.Format("Not supported on {0}", exclude); return false; } } catch( ArgumentException ex ) { reason = string.Format( "Invalid platform name: {0}", ex.ParamName ); return false; } return true; } /// /// Test to determine if the a particular platform or comma- /// delimited set of platforms is in use. /// /// Name of the platform or comma-separated list of platform names /// True if the platform is in use on the system public bool IsPlatformSupported( string platform ) { if ( platform.IndexOf( ',' ) >= 0 ) return IsPlatformSupported( platform.Split( new char[] { ',' } ) ); string platformName = platform.Trim(); bool isSupported = false; //string versionSpecification = null; //string[] parts = platformName.Split( new char[] { '-' } ); //if ( parts.Length == 2 ) //{ // platformName = parts[0]; // versionSpecification = parts[1]; //} switch( platformName.ToUpper() ) { case "WIN": case "WIN32": isSupported = os.IsWindows; break; case "WIN32S": isSupported = os.IsWin32S; break; case "WIN32WINDOWS": isSupported = os.IsWin32Windows; break; case "WIN32NT": isSupported = os.IsWin32NT; break; case "WINCE": isSupported = os.IsWinCE; break; case "WIN95": isSupported = os.IsWin95; break; case "WIN98": isSupported = os.IsWin98; break; case "WINME": isSupported = os.IsWinME; break; case "NT3": isSupported = os.IsNT3; break; case "NT4": isSupported = os.IsNT4; break; case "NT5": isSupported = os.IsNT5; break; case "WIN2K": isSupported = os.IsWin2K; break; case "WINXP": isSupported = os.IsWinXP; break; case "WIN2003SERVER": isSupported = os.IsWin2003Server; break; case "NT6": isSupported = os.IsNT6; break; case "VISTA": isSupported = os.IsVista; break; case "WIN2008SERVER": isSupported = os.IsWin2008Server; break; case "WIN2008SERVERR2": isSupported = os.IsWin2008ServerR2; break; case "WIN2012SERVER": isSupported = os.IsWin2012Server; break; case "WINDOWS7": isSupported = os.IsWindows7; break; case "WINDOWS8": isSupported = os.IsWindows8; break; case "UNIX": case "LINUX": isSupported = os.IsUnix; break; default: isSupported = IsRuntimeSupported(platformName); break; } if (!isSupported) this.reason = "Only supported on " + platform; return isSupported; } /// /// Return the last failure reason. Results are not /// defined if called before IsSupported( Attribute ) /// is called. /// public string Reason { get { return reason; } } private bool IsRuntimeSupported(string platformName) { string versionSpecification = null; string[] parts = platformName.Split(new char[] { '-' }); if (parts.Length == 2) { platformName = parts[0]; versionSpecification = parts[1]; } switch (platformName.ToUpper()) { case "NET": return IsRuntimeSupported(RuntimeType.Net, versionSpecification); case "NETCF": return IsRuntimeSupported(RuntimeType.NetCF, versionSpecification); case "SSCLI": case "ROTOR": return IsRuntimeSupported(RuntimeType.SSCLI, versionSpecification); case "MONO": return IsRuntimeSupported(RuntimeType.Mono, versionSpecification); default: throw new ArgumentException("Invalid platform name", platformName); } } private bool IsRuntimeSupported(RuntimeType runtime, string versionSpecification) { Version version = versionSpecification == null ? RuntimeFramework.DefaultVersion : new Version(versionSpecification); RuntimeFramework target = new RuntimeFramework(runtime, version); return rt.Supports(target); } } } NUnit-2.6.0.12051/src/NUnitCore/core/IgnoreDecorator.cs0000664000175000017500000000213511504175260022163 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { /// /// Ignore Decorator is an alternative method of marking tests to /// be ignored. It is currently not used, since the test builders /// take care of the ignore attribute. /// public class IgnoreDecorator : Extensibility.ITestDecorator { public IgnoreDecorator( string ignoreAttributeType ) { } #region ITestDecorator Members public Test Decorate( Test test, MemberInfo member ) { Attribute ignoreAttribute = Reflect.GetAttribute( member, NUnitFramework.IgnoreAttribute, false ); if ( ignoreAttribute != null ) { test.RunState = RunState.Ignored; test.IgnoreReason = NUnitFramework.GetIgnoreReason( ignoreAttribute ); } return test; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/DomainAgent.cs0000664000175000017500000001352111713202614021260 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.IO; using System.Reflection; namespace NUnit.Core { /// /// Represesents an agent that controls running of tests in /// an application domain. /// public class DomainAgent : TestAgent { static Logger log = InternalTrace.GetLogger(typeof(DomainAgent)); /// /// Factory method used to create a DomainAgent in an AppDomain. /// /// The domain in which to create the agent /// The level of internal tracing to use /// A proxy for the DomainAgent in the other domain static public DomainAgent CreateInstance(AppDomain targetDomain) { #if CLR_2_0 || CLR_4_0 System.Runtime.Remoting.ObjectHandle oh = Activator.CreateInstance( targetDomain, #else System.Runtime.Remoting.ObjectHandle oh = targetDomain.CreateInstance( #endif Assembly.GetExecutingAssembly().FullName, typeof(DomainAgent).FullName, false, BindingFlags.Default, null, null, null, null, null); object obj = oh.Unwrap(); return (DomainAgent)obj; } private bool isActive; /// /// Constructs a DomainAgent specifying the trace level. /// /// The level of internal tracing to use public DomainAgent() : base( Guid.NewGuid() ) { } #region Public Methods /// /// Creates a TestRunner for use in loading and running /// tests in this domain. DomainAgent always creates /// a RemoteTestRunner. /// /// Runner ID to be used /// A TestRunner public override TestRunner CreateRunner(int runnerID) { log.Info("Creating RemoteTestRunner"); return new RemoteTestRunner(runnerID); } /// /// Starts the agent if it is no aready started. /// /// public override bool Start() { if (!this.isActive) { log.Info("Starting"); this.isActive = true; } return true; } /// /// Stops the agent if it is running /// public override void Stop() { if (this.isActive) { log.Info("Stopping"); this.isActive = false; } } public AppDomain AppDomain { get { return AppDomain.CurrentDomain; } } #endregion } public class DomainInitializer : MarshalByRefObject { static Logger log; /// /// Factory method used to create a DomainInitializer in an AppDomain. /// /// The domain in which to create the agent /// The level of internal tracing to use /// A proxy for the DomainAgent in the other domain static public DomainInitializer CreateInstance(AppDomain targetDomain) { #if CLR_2_0 || CLR_4_0 System.Runtime.Remoting.ObjectHandle oh = Activator.CreateInstanceFrom( targetDomain, #else System.Runtime.Remoting.ObjectHandle oh = targetDomain.CreateInstanceFrom( #endif typeof(DomainInitializer).Assembly.CodeBase, typeof(DomainInitializer).FullName, false, BindingFlags.Default, null, null, null, null, null); object obj = oh.Unwrap(); return (DomainInitializer)obj; } public void InitializeDomain(int level) { InternalTraceLevel traceLevel = (InternalTraceLevel)level; InternalTrace.Initialize("%a_%p.log", traceLevel); log = InternalTrace.GetLogger(typeof(DomainInitializer)); AppDomain domain = AppDomain.CurrentDomain; log.Info("Initializing domain {0}", domain.FriendlyName); log.Debug(" Base Directory: {0}", domain.BaseDirectory); log.Debug(" Probing Path: {0}", domain.SetupInformation.PrivateBinPath); domain.DomainUnload += new EventHandler(OnDomainUnload); AssemblyResolver resolver = new AssemblyResolver(); resolver.AddDirectory(NUnitConfiguration.NUnitLibDirectory); resolver.AddDirectory(NUnitConfiguration.AddinDirectory); // TODO: Temporary additions till we resolve a problem with pnunit // Test for existence is needed to avoid messing when the installation // does not include pnunit. string binDir = NUnitConfiguration.NUnitBinDirectory; string pnunitFrameworkPath = Path.Combine(binDir, "pnunit.framework.dll"); if (File.Exists(pnunitFrameworkPath)) resolver.AddFile(pnunitFrameworkPath); string pnunitAgentPath = Path.Combine(binDir, "pnunit-agent.exe"); if (File.Exists(pnunitAgentPath)) resolver.AddFile(pnunitAgentPath); } void OnDomainUnload(object sender, EventArgs e) { log.Info("Unloading domain " + AppDomain.CurrentDomain.FriendlyName); InternalTrace.Flush(); } } } NUnit-2.6.0.12051/src/NUnitCore/core/NUnitTestFixture.cs0000664000175000017500000000363111712475522022350 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; namespace NUnit.Core { /// /// Class to implement an NUnit test fixture /// public class NUnitTestFixture : TestFixture { public NUnitTestFixture(Type fixtureType) : this(fixtureType, null) { } public NUnitTestFixture(Type fixtureType, object[] arguments) : base(fixtureType, arguments) { this.fixtureSetUpMethods = Reflect.GetMethodsWithAttribute(fixtureType, NUnitFramework.FixtureSetUpAttribute, true); this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute(fixtureType, NUnitFramework.FixtureTearDownAttribute, true); this.setUpMethods = Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.SetUpAttribute, true); this.tearDownMethods = Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.TearDownAttribute, true); #if CLR_2_0 || CLR_4_0 this.actions = ActionsHelper.GetActionsFromTypesAttributes(fixtureType); #endif } protected override void DoOneTimeSetUp(TestResult suiteResult) { base.DoOneTimeSetUp(suiteResult); suiteResult.AssertCount = NUnitFramework.Assert.GetAssertCount(); ; } protected override void DoOneTimeTearDown(TestResult suiteResult) { base.DoOneTimeTearDown(suiteResult); suiteResult.AssertCount += NUnitFramework.Assert.GetAssertCount(); } } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/0000775000175000017500000000000011742560362021406 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/SuiteBuilderCollection.cs0000664000175000017500000000407411504175260026351 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Core.Extensibility { /// /// SuiteBuilderCollection is an ExtensionPoint for SuiteBuilders and /// implements the ISuiteBuilder interface itself, passing calls /// on to the individual builders. /// /// The builders are added to the collection by inserting them at /// the start, as to take precedence over those added earlier. /// public class SuiteBuilderCollection : ExtensionPoint, ISuiteBuilder { #region Constructor /// /// Default constructor /// public SuiteBuilderCollection(IExtensionHost host) : base("SuiteBuilders", host ) { } #endregion #region ISuiteBuilder Members /// /// Examine the type and determine if it is suitable for /// any SuiteBuilder to use in building a TestSuite /// /// The type of the fixture to be used /// True if the type can be used to build a TestSuite public bool CanBuildFrom(Type type) { foreach( ISuiteBuilder builder in Extensions ) if ( builder.CanBuildFrom( type ) ) return true; return false; } /// /// Build a TestSuite from type provided. /// /// The type of the fixture to be used /// A TestSuite or null public Test BuildFrom(Type type) { foreach( ISuiteBuilder builder in Extensions ) if ( builder.CanBuildFrom( type ) ) return builder.BuildFrom( type ); return null; } #endregion #region ExtensionPoint Overrides protected override bool IsValidExtension(object extension) { return extension is ISuiteBuilder; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/DataPointProviders.cs0000664000175000017500000001034711504175260025516 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; namespace NUnit.Core.Extensibility { class DataPointProviders : ExtensionPoint, IDataPointProvider2 { public DataPointProviders(ExtensionHost host) : base("DataPointProviders", host) { } #region IDataPointProvider Members /// /// Determine whether any data is available for a parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// True if any data is available, otherwise false. public bool HasDataFor(ParameterInfo parameter) { foreach (IDataPointProvider provider in Extensions) if (provider.HasDataFor(parameter)) return true; return false; } /// /// Return an IEnumerable providing data for use with the /// supplied parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// An IEnumerable providing the required data public IEnumerable GetDataFor(ParameterInfo parameter) { ArrayList list = new ArrayList(); foreach (IDataPointProvider provider in Extensions) if (provider.HasDataFor(parameter)) foreach (object o in provider.GetDataFor(parameter)) list.Add(o); return list; } #endregion #region IDataPointProvider2 Members /// /// Determine whether any data is available for a parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// True if any data is available, otherwise false. public bool HasDataFor(ParameterInfo parameter, Test suite) { foreach (IDataPointProvider provider in Extensions) { if (provider is IDataPointProvider2) { IDataPointProvider2 provider2 = (IDataPointProvider2)provider; if (provider2.HasDataFor(parameter, suite)) return true; } else if (provider.HasDataFor(parameter)) return true; } return false; } /// /// Return an IEnumerable providing data for use with the /// supplied parameter. /// /// A ParameterInfo representing one /// argument to a parameterized test /// An IEnumerable providing the required data public IEnumerable GetDataFor(ParameterInfo parameter, Test suite) { ArrayList list = new ArrayList(); foreach (IDataPointProvider provider in Extensions) { if (provider is IDataPointProvider2) { IDataPointProvider2 provider2 = (IDataPointProvider2)provider; if (provider2.HasDataFor(parameter, suite)) foreach (object o in provider2.GetDataFor(parameter, suite)) list.Add(o); } else if (provider.HasDataFor(parameter)) foreach (object o in provider.GetDataFor(parameter)) list.Add(o); } return list; } #endregion #region ExtensionPoint Overrides protected override bool IsValidExtension(object extension) { return extension is IDataPointProvider; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/FrameworkRegistry.cs0000664000175000017500000000506311504175260025422 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; namespace NUnit.Core.Extensibility { public class FrameworkRegistry : ExtensionPoint, IFrameworkRegistry { #region Constructor public FrameworkRegistry( IExtensionHost host ) : base( "FrameworkRegistry", host ) { } #endregion Constructor #region Instance Fields /// /// List of FrameworkInfo structs for supported frameworks /// private Hashtable testFrameworks = new Hashtable(); #endregion #region IFrameworkRegistry Members /// /// Register a framework. NUnit registers itself using this method. Add-ins that /// work with or emulate a different framework may register themselves as well. /// /// The name of the framework /// The name of the assembly that framework users reference public void Register(string frameworkName, string assemblyName) { testFrameworks[frameworkName] = new TestFramework(frameworkName, assemblyName); } #endregion #region ExtensionPoint overrides protected override bool IsValidExtension(object extension) { return extension is TestFramework; } #endregion #region Other Methods /// /// Get a list of known frameworks referenced by an assembly /// /// The assembly to be examined /// A list of AssemblyNames public IList GetReferencedFrameworks(Assembly assembly) { ArrayList referencedAssemblies = new ArrayList(); foreach (AssemblyName assemblyRef in assembly.GetReferencedAssemblies()) { foreach (TestFramework info in testFrameworks.Values) { if (assemblyRef.Name == info.AssemblyName) { referencedAssemblies.Add(assemblyRef); break; } } } return referencedAssemblies; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/TestDecoratorCollection.cs0000664000175000017500000000244611504175260026534 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// TestDecoratorCollection is an ExtensionPoint for TestDecorators and /// implements the ITestDecorator interface itself, passing calls /// on to the individual decorators. /// public class TestDecoratorCollection : ExtensionPoint, IExtensionPoint2, ITestDecorator { #region Constructor public TestDecoratorCollection(IExtensionHost host) : base( "TestDecorators", host, 10 ) { } #endregion #region ITestDecorator Members public Test Decorate(Test test, MemberInfo member) { Test decoratedTest = test; foreach( ITestDecorator decorator in Extensions ) decoratedTest = decorator.Decorate( decoratedTest, member ); return decoratedTest; } #endregion #region ExtensionPoint Overrides protected override bool IsValidExtension(object extension) { return extension is ITestDecorator; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/EventListenerCollection.cs0000664000175000017500000000443411504175260026540 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; namespace NUnit.Core.Extensibility { /// /// EventListenerCollection holds multiple event listeners /// and relays all event calls to each of them. /// public class EventListenerCollection : ExtensionPoint, EventListener { #region Constructor public EventListenerCollection( IExtensionHost host ) : base( "EventListeners", host ) { } #endregion #region EventListener Members public void RunStarted(string name, int testCount) { foreach( EventListener listener in Extensions ) listener.RunStarted( name, testCount ); } public void RunFinished(TestResult result) { foreach( EventListener listener in Extensions ) listener.RunFinished( result ); } public void RunFinished(Exception exception) { foreach( EventListener listener in Extensions ) listener.RunFinished( exception ); } public void SuiteStarted(TestName testName) { foreach( EventListener listener in Extensions ) listener.SuiteStarted( testName ); } public void SuiteFinished(TestResult result) { foreach( EventListener listener in Extensions ) listener.SuiteFinished( result ); } public void TestStarted(TestName testName) { foreach( EventListener listener in Extensions ) listener.TestStarted( testName ); } public void TestFinished(TestResult result) { foreach( EventListener listener in Extensions ) listener.TestFinished( result ); } public void UnhandledException(Exception exception) { foreach( EventListener listener in Extensions ) listener.UnhandledException( exception ); } public void TestOutput(TestOutput testOutput) { foreach( EventListener listener in Extensions ) listener.TestOutput( testOutput ); } #endregion #region ExtensionPoint Overrides protected override bool IsValidExtension(object extension) { return extension is EventListener; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/TestCaseBuilderCollection.cs0000664000175000017500000001002411504175260026763 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Core.Extensibility { /// /// TestCaseBuilderCollection is an ExtensionPoint for TestCaseBuilders /// and implements the ITestCaseBuilder interface itself, passing calls /// on to the individual builders. /// /// The builders are added to the collection by inserting them at /// the start, as to take precedence over those added earlier. /// public class TestCaseBuilderCollection : ExtensionPoint, ITestCaseBuilder2 { #region Constructor public TestCaseBuilderCollection(IExtensionHost host) : base("TestCaseBuilders", host) { } #endregion #region ITestCaseBuilder Members /// /// Examine the method and determine if it is suitable for /// any TestCaseBuilder to use in building a Test /// /// The method to be used as a test case /// True if the method can be used to build a Test public bool CanBuildFrom(MethodInfo method) { foreach (ITestCaseBuilder builder in Extensions) if (builder.CanBuildFrom(method)) return true; return false; } /// /// Build a Test from the method provided. /// /// The method to be used /// A Test or null public Test BuildFrom(MethodInfo method) { foreach (ITestCaseBuilder builder in Extensions) { if (builder.CanBuildFrom(method)) return builder.BuildFrom(method); } return null; } #endregion #region ITestCaseBuilder2 Members /// /// Examine the method and determine if it is suitable for /// any TestCaseBuilder to use in building a Test /// /// The method to be used as a test case /// True if the method can be used to build a Test public bool CanBuildFrom(MethodInfo method, Test suite) { foreach (ITestCaseBuilder builder in Extensions) { if (builder is ITestCaseBuilder2) { ITestCaseBuilder2 builder2 = (ITestCaseBuilder2)builder; if (builder2.CanBuildFrom(method, suite)) return true; } else if (builder.CanBuildFrom(method)) return true; } return false; } /// /// Build a Test from the method provided. /// /// The method to be used /// A Test or null public Test BuildFrom(MethodInfo method, Test suite) { foreach (ITestCaseBuilder builder in Extensions) { if (builder is ITestCaseBuilder2) { ITestCaseBuilder2 builder2 = (ITestCaseBuilder2)builder; if (builder2.CanBuildFrom(method, suite)) return builder2.BuildFrom(method, suite); } else if (builder.CanBuildFrom(method)) return builder.BuildFrom(method); } return null; } #endregion #region ExtensionPoint Overrides protected override bool IsValidExtension(object extension) { return extension is ITestCaseBuilder; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Extensibility/TestCaseProviders.cs0000664000175000017500000001173411504175260025347 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System.Collections; using System.Reflection; namespace NUnit.Core.Extensibility { class TestCaseProviders : ExtensionPoint, ITestCaseProvider2 { public TestCaseProviders(IExtensionHost host) : base( "TestCaseProviders", host ) { } #region ITestCaseProvider Members /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// True if any cases are available, otherwise false. public bool HasTestCasesFor(MethodInfo method) { foreach (ITestCaseProvider provider in Extensions) if (provider.HasTestCasesFor(method)) return true; return false; } /// /// Return an enumeration providing test cases for use in /// running a paramterized test. /// /// /// public IEnumerable GetTestCasesFor(MethodInfo method) { ArrayList testcases = new ArrayList(); foreach (ITestCaseProvider provider in Extensions) try { if (provider.HasTestCasesFor(method)) foreach (object o in provider.GetTestCasesFor(method)) testcases.Add(o); } catch (System.Reflection.TargetInvocationException ex) { testcases.Add(new ParameterSet(ex.InnerException)); } catch (System.Exception ex) { testcases.Add(new ParameterSet(ex)); } return testcases; } #endregion #region ITestCaseProvider2 Members /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// The suite for which the test case is being built /// True if any cases are available, otherwise false. public bool HasTestCasesFor(MethodInfo method, Test suite) { foreach (ITestCaseProvider provider in Extensions) { if (provider is ITestCaseProvider2) { ITestCaseProvider2 provider2 = (ITestCaseProvider2)provider; if (provider2.HasTestCasesFor(method, suite)) return true; } else if (provider.HasTestCasesFor(method)) return true; } return false; } /// /// Return an enumeration providing test cases for use in /// running a paramterized test. /// /// A MethodInfo representing a parameterized test /// The suite for which the test case is being built /// public IEnumerable GetTestCasesFor(MethodInfo method, Test suite) { ArrayList testcases = new ArrayList(); foreach (ITestCaseProvider provider in Extensions) try { if (provider is ITestCaseProvider2) { ITestCaseProvider2 provider2 = (ITestCaseProvider2)provider; if (provider2.HasTestCasesFor(method, suite)) foreach (object o in provider2.GetTestCasesFor(method, suite)) testcases.Add(o); } else if (provider.HasTestCasesFor(method)) foreach (object o in provider.GetTestCasesFor(method)) testcases.Add(o); } catch (System.Reflection.TargetInvocationException ex) { testcases.Add(new ParameterSet(ex.InnerException)); } catch (System.Exception ex) { testcases.Add(new ParameterSet(ex)); } return testcases; } #endregion #region IsValidExtension protected override bool IsValidExtension(object extension) { return extension is ITestCaseProvider; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ProxyTestRunner.cs0000664000175000017500000001061011717225004022243 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Collections; using System.IO; /// /// DelegatingTestRUnner is the abstract base for core TestRunner /// implementations that operate by controlling a downstream /// TestRunner. All calls are simply passed on to the /// TestRunner that is provided to the constructor. /// /// Although the class is abstract, it has no abstract /// methods specified because each implementation will /// need to override different methods. All methods are /// specified using interface syntax and the derived class /// must explicitly implement TestRunner in order to /// redefine the selected methods. /// public abstract class ProxyTestRunner : MarshalByRefObject, TestRunner { #region Instance Variables /// /// Our runner ID /// protected int runnerID; /// /// The downstream TestRunner /// private TestRunner testRunner; /// /// The event listener for the currently running test /// protected EventListener listener; #endregion #region Construction public ProxyTestRunner(TestRunner testRunner) { this.testRunner = testRunner; this.runnerID = testRunner.ID; } /// /// Protected constructor for runners that delay creation /// of their downstream runner. /// protected ProxyTestRunner( int runnerID ) { this.runnerID = runnerID; } #endregion #region Properties public virtual int ID { get { return runnerID; } } public virtual bool Running { get { return testRunner != null && testRunner.Running; } } public virtual IList AssemblyInfo { get { return testRunner == null ? null : testRunner.AssemblyInfo; } } public virtual ITest Test { get { return testRunner == null ? null : testRunner.Test; } } public virtual TestResult TestResult { get { return testRunner == null ? null : testRunner.TestResult; } } /// /// Protected property copies any settings to the downstream test runner /// when it is set. Derived runners overriding this should call the base /// or copy the settings themselves. /// protected virtual TestRunner TestRunner { get { return testRunner; } set { testRunner = value; } } #endregion #region Load and Unload Methods public virtual bool Load( TestPackage package ) { return this.testRunner.Load( package ); } public virtual void Unload() { if ( this.testRunner != null ) this.testRunner.Unload(); } #endregion #region CountTestCases public virtual int CountTestCases( ITestFilter filter ) { return this.testRunner.CountTestCases( filter ); } #endregion #region Methods for Running Tests public virtual TestResult Run(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { // Save active listener for derived classes this.listener = listener; return this.testRunner.Run(listener, filter, tracing, logLevel); } public virtual void BeginRun(EventListener listener, ITestFilter filter, bool tracing, LoggingThreshold logLevel) { // Save active listener for derived classes this.listener = listener; this.testRunner.BeginRun(listener, filter, tracing, logLevel); } public virtual TestResult EndRun() { return this.testRunner.EndRun(); } public virtual void CancelRun() { this.testRunner.CancelRun(); } public virtual void Wait() { this.testRunner.Wait(); } #endregion #region InitializeLifetimeService Override public override object InitializeLifetimeService() { return null; } #endregion #region IDisposable Implementation public virtual void Dispose() { if (testRunner != null) testRunner.Dispose(); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/nunit.core.dll.csproj0000664000175000017500000002244611712475522022642 0ustar jtaylorjtaylor Local 9.0.30729 2.0 {EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} Debug AnyCPU nunit.core JScript Grid IE50 false Library NUnit.Core OnBuildSuccess 2.0 http://localhost/nunit.core/ true Web true Foreground 7 Days false false true 0 1.0.0.%2a true false true v2.0 ..\..\..\bin\Debug\lib\ 285212672 TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0 true 4096 1699 false false false 4 full prompt ..\..\..\bin\Release\lib\ 285212672 TRACE;CLR_2_0,NET_2_0,CS_3_0 4096 1699 true false false 4 none prompt System System.Data System.XML nunit.core.interfaces.dll {435428F8-5995-4CE4-8022-93D595A8CC0F} False False .NET Framework 2.0 %28x86%29 true False .NET Framework 3.0 %28x86%29 false False .NET Framework 3.5 false CommonAssemblyInfo.cs NUnit-2.6.0.12051/src/NUnitCore/core/TestCaseBuilderAttribute.cs0000664000175000017500000000124311504175260024002 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// TestBuilderAttribute is used to mark custom test case builders. /// The class so marked must implement the ITestCaseBuilder interface. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public sealed class TestCaseBuilderAttribute : System.Attribute {} } NUnit-2.6.0.12051/src/NUnitCore/core/TestFixtureBuilder.cs0000664000175000017500000000404111504175260022670 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { /// /// TestFixtureBuilder contains static methods for building /// TestFixtures from types. It uses builtin SuiteBuilders /// and any installed extensions to do it. /// public class TestFixtureBuilder { public static bool CanBuildFrom( Type type ) { return CoreExtensions.Host.SuiteBuilders.CanBuildFrom( type ); } /// /// Build a test fixture from a given type. /// /// The type to be used for the fixture /// A TestSuite if the fixture can be built, null if not public static Test BuildFrom( Type type ) { Test suite = CoreExtensions.Host.SuiteBuilders.BuildFrom( type ); if ( suite != null ) suite = CoreExtensions.Host.TestDecorators.Decorate( suite, type ); return suite; } /// /// Build a fixture from an object. /// /// The object to be used for the fixture /// A TestSuite if fixture type can be built, null if not public static Test BuildFrom( object fixture ) { Test suite = BuildFrom( fixture.GetType() ); if( suite != null) { suite.Fixture = fixture; // TODO: Integrate building from an object as part of NUnitTestFixtureBuilder if (suite.RunState == RunState.NotRunnable && Reflect.GetConstructor(fixture.GetType()) == null) { suite.RunState = RunState.Runnable; suite.IgnoreReason = null; } } return suite; } /// /// Private constructor to prevent instantiation /// private TestFixtureBuilder() { } } } NUnit-2.6.0.12051/src/NUnitCore/core/NullListener.cs0000664000175000017500000000210711504175260021514 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// Summary description for NullListener. /// /// [Serializable] public class NullListener : EventListener { public void RunStarted( string name, int testCount ){ } public void RunFinished( TestResult result ) { } public void RunFinished( Exception exception ) { } public void TestStarted(TestName testName){} public void TestFinished(TestResult result){} public void SuiteStarted(TestName testName){} public void SuiteFinished(TestResult result){} public void UnhandledException( Exception exception ) {} public void TestOutput(TestOutput testOutput) {} public static EventListener NULL { get { return new NullListener();} } } } NUnit-2.6.0.12051/src/NUnitCore/core/CultureDetector.cs0000664000175000017500000000707711537117336022232 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Globalization; namespace NUnit.Core { public class CultureDetector { private CultureInfo currentCulture; // Set whenever we fail to support a list of platforms private string reason = string.Empty; /// /// Default constructor uses the current culutre. /// public CultureDetector() { this.currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; } /// /// Contruct a CultureHelper for a particular culture for testing. /// /// The culture to be used public CultureDetector( string culture ) { this.currentCulture = new CultureInfo( culture ); } /// /// Test to determine if one of a collection of culturess /// is being used currently. /// /// /// public bool IsCultureSupported( string[] cultures ) { foreach( string culture in cultures ) if ( IsCultureSupported( culture ) ) return true; return false; } /// /// Tests to determine if the current culture is supported /// based on a culture attribute. /// /// The attribute to examine /// public bool IsCultureSupported( Attribute cultureAttribute ) { //Use reflection to avoid dependency on a particular framework version string include = (string)Reflect.GetPropertyValue( cultureAttribute, "Include", BindingFlags.Public | BindingFlags.Instance ); string exclude = (string)Reflect.GetPropertyValue( cultureAttribute, "Exclude", BindingFlags.Public | BindingFlags.Instance ); try { if (include != null && !IsCultureSupported(include)) { reason = string.Format("Only supported under culture {0}", include); return false; } if (exclude != null && IsCultureSupported(exclude)) { reason = string.Format("Not supported under culture {0}", exclude); return false; } } catch( ArgumentException ex ) { reason = string.Format( "Invalid culture: {0}", ex.ParamName ); return false; } return true; } /// /// Test to determine if the a particular culture or comma- /// delimited set of cultures is in use. /// /// Name of the culture or comma-separated list of culture names /// True if the culture is in use on the system public bool IsCultureSupported( string culture ) { culture = culture.Trim(); if ( culture.IndexOf( ',' ) >= 0 ) { if ( IsCultureSupported( culture.Split( new char[] { ',' } ) ) ) return true; } else { if( this.currentCulture.Name == culture || this.currentCulture.TwoLetterISOLanguageName == culture) return true; } this.reason = "Only supported under culture " + culture; return false; } /// /// Return the last failure reason. Results are not /// defined if called before IsSupported( Attribute ) /// is called. /// public string Reason { get { return reason; } } } } NUnit-2.6.0.12051/src/NUnitCore/core/QueuingEventListener.cs0000664000175000017500000000576311504175260023234 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core { /// /// QueuingEventListener uses an EventQueue to store any /// events received on its EventListener interface. /// public class QueuingEventListener : EventListener { private EventQueue events = new EventQueue(); /// /// The EvenQueue created and filled by this listener /// public EventQueue Events { get { return events; } } #region EventListener Methods /// /// Run is starting /// /// Array of tests to be run public void RunStarted( string name, int testCount ) { events.Enqueue( new RunStartedEvent( name, testCount ) ); } /// /// Run finished successfully /// /// Array of test results public void RunFinished( TestResult result ) { events.Enqueue( new RunFinishedEvent( result ) ); } /// /// Run was terminated due to an exception /// /// Exception that was thrown public void RunFinished( Exception exception ) { events.Enqueue( new RunFinishedEvent( exception ) ); } /// /// A single test case is starting /// /// The test case public void TestStarted(TestName testName) { events.Enqueue( new TestStartedEvent( testName ) ); } /// /// A test case finished /// /// Result of the test case public void TestFinished(TestResult result) { events.Enqueue( new TestFinishedEvent( result ) ); } /// /// A suite is starting /// /// The suite that is starting public void SuiteStarted(TestName testName) { events.Enqueue( new SuiteStartedEvent( testName ) ); } /// /// A suite finished /// /// Result of the suite public void SuiteFinished(TestResult result) { events.Enqueue( new SuiteFinishedEvent( result ) ); } /// /// An unhandled exception occured while running a test, /// but the test was not terminated. /// /// public void UnhandledException( Exception exception ) { events.Enqueue( new UnhandledExceptionEvent( exception ) ); } /// /// A message has been output to the console. /// /// A console message public void TestOutput( TestOutput output ) { events.Enqueue( new OutputEvent( output ) ); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/InvalidSuiteException.cs0000664000175000017500000000245711504175260023363 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Runtime.Serialization; [Serializable] public class InvalidSuiteException : ApplicationException { public InvalidSuiteException () : base() {} /// /// Standard constructor /// /// The error message that explains /// the reason for the exception public InvalidSuiteException(string message) : base (message) {} /// /// Standard constructor /// /// The error message that explains /// the reason for the exception /// The exception that caused the /// current exception public InvalidSuiteException(string message, Exception inner) : base(message, inner) {} /// /// Serialization Constructor /// protected InvalidSuiteException(SerializationInfo info, StreamingContext context) : base(info,context){} } }NUnit-2.6.0.12051/src/NUnitCore/core/AssemblyHelper.cs0000664000175000017500000000404311663720222022014 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { public class AssemblyHelper { #region GetAssemblyPath public static string GetAssemblyPath(Type type) { return GetAssemblyPath(type.Assembly); } public static string GetAssemblyPath(Assembly assembly) { string uri = assembly.CodeBase; if (IsFileUri(uri)) return GetAssemblyPathFromFileUri(uri); else return assembly.Location; } #endregion #region // Public for testing purposes public static string GetAssemblyPathFromFileUri(string uri) { // Skip over the file:// int start = Uri.UriSchemeFile.Length + Uri.SchemeDelimiter.Length; if (System.IO.Path.DirectorySeparatorChar == '\\') { // Handle Windows Drive specifications if (uri[start] == '/' && uri[start + 2] == ':') ++start; } else { // Assume all Linux paths are absolute if (uri[start] != '/') --start; } return uri.Substring(start); } #endregion #region GetDirectoryName public static string GetDirectoryName( Assembly assembly ) { return System.IO.Path.GetDirectoryName(GetAssemblyPath(assembly)); } #endregion #region Helper Methods private static bool IsFileUri(string uri) { return uri.ToLower().StartsWith(Uri.UriSchemeFile); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/ParameterizedTestMethodSuite.cs0000664000175000017500000001046011712475522024711 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** //#define DEFAULT_APPLIES_TO_TESTCASE using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using System.Reflection; using System.Text; namespace NUnit.Core { /// /// ParameterizedMethodSuite holds a collection of individual /// TestMethods with their arguments applied. /// public class ParameterizedMethodSuite : TestSuite { private bool isTheory; private MethodInfo method; /// /// Construct from a MethodInfo /// /// public ParameterizedMethodSuite(MethodInfo method) : base(method.ReflectedType.FullName, method.Name) { this.maintainTestOrder = true; this.isTheory = Reflect.HasAttribute(method, NUnitFramework.TheoryAttribute, true); this.method = method; } /// /// Gets a string representing the kind of test /// that this object represents, for use in display. /// public override string TestType { get { return this.isTheory ? "Theory" : "ParameterizedTest"; } } /// /// Override Run, setting Fixture to that of the Parent. /// /// /// /// public override TestResult Run(EventListener listener, ITestFilter filter) { if (this.Parent != null) { this.Fixture = this.Parent.Fixture; TestSuite suite = this.Parent as TestSuite; if (suite != null) { this.setUpMethods = suite.GetSetUpMethods(); this.tearDownMethods = suite.GetTearDownMethods(); } } #if CLR_2_0 || CLR_4_0 this.actions = ActionsHelper.GetActionsFromAttributeProvider(this.method); #endif // DYNAMIC: Get the parameters, and add the methods here. TestResult result = base.Run(listener, filter); if (this.isTheory && result.ResultState == ResultState.Inconclusive) result.SetResult( ResultState.Failure, this.TestCount == 0 ? "No test cases were provided" : "All test cases were inconclusive", null); this.Fixture = null; this.setUpMethods = null; this.tearDownMethods = null; #if CLR_2_0 || CLR_4_0 this.actions = null; #endif return result; } /// /// Override DoOneTimeSetUp to avoid executing any /// TestFixtureSetUp method for this suite /// /// protected override void DoOneTimeSetUp(TestResult suiteResult) { } /// /// Override DoOneTimeTearDown to avoid executing any /// TestFixtureTearDown method for this suite. /// /// protected override void DoOneTimeTearDown(TestResult suiteResult) { } #if CLR_2_0 || CLR_4_0 #if !DEFAULT_APPLIES_TO_TESTCASE protected override void ExecuteActions(ActionPhase phase) { List targetActions = new List(); if (this.actions != null) { foreach (var action in this.actions) { if (action.DoesTarget(TestAction.TargetsSuite)) targetActions.Add(action); } } ActionsHelper.ExecuteActions(phase, targetActions, this); } #endif #endif } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/0000775000175000017500000000000011742560362020323 5ustar jtaylorjtaylorNUnit-2.6.0.12051/src/NUnitCore/core/Builders/ProviderCache.cs0000664000175000017500000000336211504175260023367 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Text; namespace NUnit.Core.Builders { class ProviderCache { private static IDictionary instances = new Hashtable(); public static object GetInstanceOf(Type providerType) { CacheEntry entry = new CacheEntry(providerType); object instance = instances[entry]; return instance == null ? instances[entry] = Reflect.Construct(providerType) : instance; } public static void Clear() { foreach (object key in instances.Keys) { IDisposable provider = instances[key] as IDisposable; if (provider != null) provider.Dispose(); } instances.Clear(); } class CacheEntry { private Type providerType; public CacheEntry(Type providerType) { this.providerType = providerType; } public override bool Equals(object obj) { CacheEntry other = obj as CacheEntry; if (other == null) return false; return this.providerType == other.providerType; } public override int GetHashCode() { return providerType.GetHashCode(); } } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/CombinatorialStrategy.cs0000664000175000017500000000341511544454420025160 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Core.Extensibility; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif namespace NUnit.Core.Builders { public class CombinatorialStrategy : CombiningStrategy { public CombinatorialStrategy(IEnumerable[] sources) : base(sources) { } public override IEnumerable GetTestCases() { IEnumerator[] enumerators = new IEnumerator[Sources.Length]; int index = -1; #if CLR_2_0 || CLR_4_0 List testCases = new List(); #else ArrayList testCases = new ArrayList(); #endif for (; ; ) { while (++index < Sources.Length) { enumerators[index] = Sources[index].GetEnumerator(); if (!enumerators[index].MoveNext()) return testCases; } object[] testdata = new object[Sources.Length]; for (int i = 0; i < Sources.Length; i++) testdata[i] = enumerators[i].Current; ParameterSet testCase = new ParameterSet(); testCase.Arguments = testdata; testCases.Add(testCase); index = Sources.Length; while (--index >= 0 && !enumerators[index].MoveNext()) ; if (index < 0) break; } return testCases; } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/TestCaseSourceProvider.cs0000664000175000017500000001425311650231470025257 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { /// /// TestCaseSourceProvider provides data for methods /// annotated with the TestCaseSourceAttribute. /// public class TestCaseSourceProvider : ITestCaseProvider2 { #region Constants public const string SourceTypeProperty = "SourceType"; public const string SourceNameProperty = "SourceName"; #endregion #region ITestCaseProvider Members /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// True if any cases are available, otherwise false. public bool HasTestCasesFor(MethodInfo method) { return Reflect.HasAttribute(method, NUnitFramework.TestCaseSourceAttribute, false); } /// /// Return an IEnumerable providing test cases for use in /// running a parameterized test. /// /// /// public IEnumerable GetTestCasesFor(MethodInfo method) { return GetTestCasesFor(method, null); } #endregion #region ITestCaseProvider2 Members /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// True if any cases are available, otherwise false. public bool HasTestCasesFor(MethodInfo method, Test suite) { return HasTestCasesFor(method); } /// /// Return an IEnumerable providing test cases for use in /// running a parameterized test. /// /// /// public IEnumerable GetTestCasesFor(MethodInfo method, Test parentSuite) { ArrayList parameterList = new ArrayList(); foreach (ProviderReference info in GetSourcesFor(method, parentSuite)) { foreach (object source in info.GetInstance()) { ParameterSet parms; if (source == null) { parms = new ParameterSet(); parms.Arguments = new object[] { null }; } else parms = source as ParameterSet; if (parms == null) { if (source.GetType().GetInterface("NUnit.Framework.ITestCaseData") != null) parms = ParameterSet.FromDataSource(source); else { parms = new ParameterSet(); ParameterInfo[] parameters = method.GetParameters(); Type sourceType = source.GetType(); if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(sourceType)) parms.Arguments = new object[] { source }; else if (source is object[]) parms.Arguments = (object[])source; else if (source is Array) { Array array = (Array)source; if (array.Rank == 1) { parms.Arguments = new object[array.Length]; for (int i = 0; i < array.Length; i++) parms.Arguments[i] = (object)array.GetValue(i); } } else parms.Arguments = new object[] { source }; } } if (info.Category != null) foreach (string cat in info.Category.Split(new char[] { ',' })) parms.Categories.Add(cat); parameterList.Add(parms); } } return parameterList; } #endregion #region Helper Methods private static IList GetSourcesFor(MethodInfo method, Test parent) { ArrayList sources = new ArrayList(); TestFixture parentSuite = parent as TestFixture; foreach (Attribute sourceAttr in Reflect.GetAttributes(method, NUnitFramework.TestCaseSourceAttribute, false)) { Type sourceType = Reflect.GetPropertyValue(sourceAttr, SourceTypeProperty) as Type; string sourceName = Reflect.GetPropertyValue(sourceAttr, SourceNameProperty) as string; string category = Reflect.GetPropertyValue(sourceAttr, "Category") as string; if (sourceType == null) { if (parentSuite != null) sources.Add(new ProviderReference(parentSuite.FixtureType, parentSuite.arguments, sourceName, category)); else sources.Add(new ProviderReference(method.ReflectedType, sourceName, category)); } else { sources.Add(new ProviderReference(sourceType, sourceName, category)); } } return sources; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/TestAssemblyBuilder.cs0000664000175000017500000001663311665763262024621 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.IO; using System.Collections; using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { /// /// Class that builds a TestSuite from an assembly /// public class TestAssemblyBuilder { static Logger log = InternalTrace.GetLogger("TestAssemblyBuilder"); #region Instance Fields /// /// The loaded assembly /// Assembly assembly; /// /// Our LegacySuite builder, which is only used when a /// fixture has been passed by name on the command line. /// ISuiteBuilder legacySuiteBuilder; private TestAssemblyInfo assemblyInfo = null; #endregion #region Properties public Assembly Assembly { get { return assembly; } } public TestAssemblyInfo AssemblyInfo { get { if ( assemblyInfo == null && assembly != null ) { AssemblyReader rdr = new AssemblyReader( assembly ); Version imageRuntimeVersion = new Version( rdr.ImageRuntimeVersion.Substring( 1 ) ); IList frameworks = CoreExtensions.Host.TestFrameworks.GetReferencedFrameworks( assembly ); assemblyInfo = new TestAssemblyInfo( rdr.AssemblyPath, imageRuntimeVersion, RuntimeFramework.CurrentFramework, frameworks ); } return assemblyInfo; } } #endregion #region Constructor public TestAssemblyBuilder() { // TODO: Keeping this separate till we can make //it work in all situations. legacySuiteBuilder = new NUnit.Core.Builders.LegacySuiteBuilder(); } #endregion #region Build Methods public Test Build( string assemblyName, string testName, bool autoSuites ) { if ( testName == null || testName == string.Empty ) return Build( assemblyName, autoSuites ); // Change currentDirectory in case assembly references unmanaged dlls // and so that any addins are able to access the directory easily. using (new DirectorySwapper(Path.GetDirectoryName(assemblyName))) { this.assembly = Load(assemblyName); if (assembly == null) return null; // If provided test name is actually the name of // a type, we handle it specially Type testType = assembly.GetType(testName); if (testType != null) return Build(assembly, assemblyName, testType, autoSuites); // Assume that testName is a namespace and get all fixtures in it IList fixtures = GetFixtures(assembly, testName); if (fixtures.Count > 0) return BuildTestAssembly(this.assembly, assemblyName, fixtures, autoSuites); return null; } } public TestSuite Build( string assemblyName, bool autoSuites ) { // Change currentDirectory in case assembly references unmanaged dlls // and so that any addins are able to access the directory easily. using (new DirectorySwapper(Path.GetDirectoryName(assemblyName))) { this.assembly = Load(assemblyName); if (this.assembly == null) return null; IList fixtures = GetFixtures(assembly, null); return BuildTestAssembly(this.assembly, assemblyName, fixtures, autoSuites); } } private Test Build( Assembly assembly, string assemblyName, Type testType, bool autoSuites ) { // TODO: This is the only situation in which we currently // recognize and load legacy suites. We need to determine // whether to allow them in more places. if ( legacySuiteBuilder.CanBuildFrom( testType ) ) return legacySuiteBuilder.BuildFrom( testType ); else if ( TestFixtureBuilder.CanBuildFrom( testType ) ) return BuildTestAssembly( assembly, assemblyName, new Test[] { TestFixtureBuilder.BuildFrom( testType ) }, autoSuites ); return null; } private TestSuite BuildTestAssembly( Assembly assembly, string assemblyName, IList fixtures, bool autoSuites ) { TestSuite testAssembly = new TestAssembly( assembly, assemblyName ); if ( autoSuites ) { NamespaceTreeBuilder treeBuilder = new NamespaceTreeBuilder( testAssembly ); treeBuilder.Add( fixtures ); testAssembly = treeBuilder.RootSuite; } else foreach( TestSuite fixture in fixtures ) { if (fixture != null) { if (fixture is SetUpFixture) { fixture.RunState = RunState.NotRunnable; fixture.IgnoreReason = "SetUpFixture cannot be used when loading tests as a flat list of fixtures"; } testAssembly.Add(fixture); } } NUnitFramework.ApplyCommonAttributes( assembly, testAssembly ); testAssembly.Properties["_PID"] = System.Diagnostics.Process.GetCurrentProcess().Id; testAssembly.Properties["_APPDOMAIN"] = AppDomain.CurrentDomain.FriendlyName; // TODO: Make this an option? Add Option to sort assemblies as well? testAssembly.Sort(); return testAssembly; } #endregion #region Helper Methods private Assembly Load(string path) { Assembly assembly = null; // Throws if this isn't a managed assembly or if it was built // with a later version of the same assembly. AssemblyName assemblyName = AssemblyName.GetAssemblyName( Path.GetFileName( path ) ); assembly = Assembly.Load(assemblyName); if ( assembly != null ) CoreExtensions.Host.InstallAdhocExtensions( assembly ); log.Info( "Loaded assembly " + assembly.FullName ); return assembly; } private IList GetFixtures( Assembly assembly, string ns ) { ArrayList fixtures = new ArrayList(); log.Debug("Examining assembly for test fixtures"); IList testTypes = GetCandidateFixtureTypes( assembly, ns ); log.Debug("Found {0} classes to examine", testTypes.Count); #if CLR_2_0 || CLR_4_0 System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); #endif foreach(Type testType in testTypes) { if( TestFixtureBuilder.CanBuildFrom( testType ) ) fixtures.Add( TestFixtureBuilder.BuildFrom( testType ) ); } #if CLR_2_0 || CLR_4_0 log.Debug("Found {0} fixtures in {1} seconds", fixtures.Count, timer.Elapsed); #else log.Debug("Found {0} fixtures", fixtures.Count); #endif return fixtures; } private IList GetCandidateFixtureTypes( Assembly assembly, string ns ) { IList types = assembly.GetTypes(); if ( ns == null || ns == string.Empty || types.Count == 0 ) return types; string prefix = ns + "." ; ArrayList result = new ArrayList(); foreach( Type type in types ) if ( type.FullName.StartsWith( prefix ) ) result.Add( type ); return result; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/LegacySuiteBuilder.cs0000664000175000017500000001041011504175260024366 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Core.Builders { /// /// Built-in SuiteBuilder for LegacySuite /// public class LegacySuiteBuilder : Extensibility.ISuiteBuilder { #region ISuiteBuilderMembers /// /// Checks to see if the fixture type has the a property /// with the SuiteAttribute. /// /// The fixture type to check /// True if the fixture can be built, false if not public bool CanBuildFrom(Type type) { return GetSuiteProperty( type ) != null; } public Test BuildFrom( Type type ) { TestSuite suite = new LegacySuite( type ); string reason = null; if (!IsValidFixtureType(type, ref reason)) { suite.RunState = RunState.NotRunnable; suite.IgnoreReason = reason; } PropertyInfo suiteProperty = GetSuiteProperty(type); MethodInfo method = suiteProperty.GetGetMethod(true); if (method.GetParameters().Length > 0) { suite.RunState = RunState.NotRunnable; suite.IgnoreReason = "Suite property may not be indexed"; } else if (method.ReturnType.FullName == "NUnit.Core.TestSuite") { TestSuite s = (TestSuite)suiteProperty.GetValue(null, new Object[0]); foreach (Test test in s.Tests) suite.Add(test); } else if (typeof(IEnumerable).IsAssignableFrom(method.ReturnType)) { foreach (object obj in (IEnumerable)suiteProperty.GetValue(null, new object[0])) { Type objType = obj as Type; if (objType != null && TestFixtureBuilder.CanBuildFrom(objType)) suite.Add(TestFixtureBuilder.BuildFrom(objType)); else suite.Add(obj); } } else { suite.RunState = RunState.NotRunnable; suite.IgnoreReason = "Suite property must return either TestSuite or IEnumerable"; } return suite; } #endregion #region Helper Methods private bool IsValidFixtureType(Type type, ref string reason) { if (type.IsAbstract) { reason = string.Format("{0} is an abstract class", type.FullName); return false; } if (Reflect.GetConstructor(type) == null) { reason = string.Format("{0} does not have a valid constructor", type.FullName); return false; } if (!NUnitFramework.CheckSetUpTearDownMethods(type, NUnitFramework.FixtureSetUpAttribute, ref reason) ) return false; if (!NUnitFramework.CheckSetUpTearDownMethods(type, NUnitFramework.FixtureTearDownAttribute, ref reason)) return false; if (Reflect.HasMethodWithAttribute(type, NUnitFramework.SetUpAttribute, true)) { reason = "SetUp method not allowed on a legacy suite"; return false; } if (Reflect.HasMethodWithAttribute(type, NUnitFramework.TearDownAttribute, true)) { reason = "TearDown method not allowed on a legacy suite"; return false; } return true; } public static PropertyInfo GetSuiteProperty(Type testClass) { //if (testClass == null) // return null; return Reflect.GetPropertyWithAttribute(testClass, NUnitFramework.SuiteAttribute); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/PairwiseStrategy.cs0000664000175000017500000003545511544454420024171 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using System.Reflection; using System.Text; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public class PairwiseStrategy : CombiningStrategy { internal class FleaRand { private const int FleaRandSize = 256; private uint b; private uint c; private uint d; private uint z; private uint[] m = new uint[FleaRandSize]; private uint[] r = new uint[FleaRandSize]; private uint q; public FleaRand(uint seed) { this.b = seed; this.c = seed; this.d = seed; this.z = seed; for (int i = 0; i < this.m.Length; i++) { this.m[i] = seed; } for (int i = 0; i < 10; i++) { this.Batch(); } this.q = 0; } public uint Next() { if (this.q == 0) { this.Batch(); this.q = (uint)this.r.Length - 1; } else { this.q--; } return this.r[this.q]; } private void Batch() { uint a; uint b = this.b; uint c = this.c + (++this.z); uint d = this.d; for (int i = 0; i < this.r.Length; i++) { a = this.m[b % this.m.Length]; this.m[b % this.m.Length] = d; d = (c << 19) + (c >> 13) + b; c = b ^ this.m[i]; b = a + d; this.r[i] = c; } this.b = b; this.c = c; this.d = d; } } internal class FeatureInfo { public const string Names = "abcdefghijklmnopqrstuvwxyz"; public readonly int Dimension; public readonly int Feature; public FeatureInfo(int dimension, int feature) { this.Dimension = dimension; this.Feature = feature; } #if DEBUG public override string ToString() { return (this.Dimension + 1).ToString() + FeatureInfo.Names[this.Feature]; } #endif } internal class Tuple { private readonly ArrayList features = new ArrayList(); public int Count { get { return this.features.Count; } } public FeatureInfo this[int index] { get { return (FeatureInfo)this.features[index]; } } public void Add(FeatureInfo feature) { this.features.Add(feature); } #if DEBUG public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append('('); for (int i = 0; i < this.features.Count; i++) { if (i > 0) { sb.Append(' '); } sb.Append(this.features[i].ToString()); } sb.Append(')'); return sb.ToString(); } #endif } internal class TupleCollection { private readonly ArrayList tuples = new ArrayList(); public int Count { get { return this.tuples.Count; } } public Tuple this[int index] { get { return (Tuple)this.tuples[index]; } } public void Add(Tuple tuple) { this.tuples.Add(tuple); } public void RemoveAt(int index) { this.tuples.RemoveAt(index); } } internal class TestCase { public readonly int[] Features; public TestCase(int numberOfDimensions) { this.Features = new int[numberOfDimensions]; } public bool IsTupleCovered(Tuple tuple) { for (int i = 0; i < tuple.Count; i++) { if (this.Features[tuple[i].Dimension] != tuple[i].Feature) { return false; } } return true; } #if DEBUG public override string ToString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < this.Features.Length; i++) { if (i > 0) { sb.Append(' '); } sb.Append(i + 1); sb.Append(FeatureInfo.Names[this.Features[i]]); } return sb.ToString(); } #endif } internal class TestCaseCollection : IEnumerable { private readonly ArrayList testCases = new ArrayList(); public void Add(TestCase testCase) { this.testCases.Add(testCase); } public IEnumerator GetEnumerator() { return this.testCases.GetEnumerator(); } public bool IsTupleCovered(Tuple tuple) { foreach (TestCase testCase in this.testCases) { if (testCase.IsTupleCovered(tuple)) { return true; } } return false; } } internal class PairwiseTestCaseGenerator { private const int MaxTupleLength = 2; private readonly FleaRand random = new FleaRand(0); private readonly int[] dimensions; private readonly TupleCollection[][] uncoveredTuples; private readonly int[][] currentTupleLength; private readonly TestCaseCollection testCases = new TestCaseCollection(); public PairwiseTestCaseGenerator(int[] dimensions) { this.dimensions = dimensions; this.uncoveredTuples = new TupleCollection[this.dimensions.Length][]; for (int d = 0; d < this.uncoveredTuples.Length; d++) { this.uncoveredTuples[d] = new TupleCollection[this.dimensions[d]]; for (int f = 0; f < this.dimensions[d]; f++) { this.uncoveredTuples[d][f] = new TupleCollection(); } } this.currentTupleLength = new int[this.dimensions.Length][]; for (int d = 0; d < this.dimensions.Length; d++) { this.currentTupleLength[d] = new int[this.dimensions[d]]; } } public IEnumerable GetTestCases() { this.CreateTestCases(); this.SelfTest(); return this.testCases; } private void CreateTestCases() { while (true) { this.ExtendTupleSet(); Tuple tuple = this.FindTupleToCover(); if (tuple == null) { return; } TestCase testCase = this.FindGoodTestCase(tuple); this.RemoveTuplesCoveredBy(testCase); this.testCases.Add(testCase); } } private void ExtendTupleSet() { for (int d = 0; d < this.dimensions.Length; d++) { for (int f = 0; f < this.dimensions[d]; f++) { this.ExtendTupleSet(d, f); } } } private void ExtendTupleSet(int dimension, int feature) { // If tuples for [dimension][feature] already exists, it's no needs to add more tuples. if (this.uncoveredTuples[dimension][feature].Count > 0) { return; } // If maximum tuple length for [dimension][feature] is reached, it's no needs to add more tuples. if (this.currentTupleLength[dimension][feature] == MaxTupleLength) { return; } this.currentTupleLength[dimension][feature]++; int tupleLength = this.currentTupleLength[dimension][feature]; if (tupleLength == 1) { Tuple tuple = new Tuple(); tuple.Add(new FeatureInfo(dimension, feature)); if (this.testCases.IsTupleCovered(tuple)) { return; } this.uncoveredTuples[dimension][feature].Add(tuple); } else { for (int d = 0; d < this.dimensions.Length; d++) { for (int f = 0; f < this.dimensions[d]; f++) { Tuple tuple = new Tuple(); tuple.Add(new FeatureInfo(d, f)); if (tuple[0].Dimension == dimension) { continue; } tuple.Add(new FeatureInfo(dimension, feature)); if (this.testCases.IsTupleCovered(tuple)) { continue; } this.uncoveredTuples[dimension][feature].Add(tuple); } } } } private Tuple FindTupleToCover() { int tupleLength = MaxTupleLength; int tupleCount = 0; Tuple tuple = null; for (int d = 0; d < this.dimensions.Length; d++) { for (int f = 0; f < this.dimensions[d]; f++) { if (this.currentTupleLength[d][f] < tupleLength) { tupleLength = this.currentTupleLength[d][f]; tupleCount = this.uncoveredTuples[d][f].Count; tuple = this.uncoveredTuples[d][f][0]; } else { if (this.currentTupleLength[d][f] == tupleLength && this.uncoveredTuples[d][f].Count > tupleCount) { tupleCount = this.uncoveredTuples[d][f].Count; tuple = this.uncoveredTuples[d][f][0]; } } } } return tuple; } private TestCase FindGoodTestCase(Tuple tuple) { TestCase bestTest = null; int bestCoverage = -1; for (int i = 0; i < 5; i++) { TestCase test = new TestCase(this.dimensions.Length); int coverage = this.CreateTestCase(tuple, test); if (coverage > bestCoverage) { bestTest = test; bestCoverage = coverage; } } return bestTest; } private int CreateTestCase(Tuple tuple, TestCase test) { // Create a random test case... for (int i = 0; i < test.Features.Length; i++) { test.Features[i] = (int)(this.random.Next() % this.dimensions[i]); } // ...and inject the tuple into it! for (int i = 0; i < tuple.Count; i++) { test.Features[tuple[i].Dimension] = tuple[i].Feature; } return this.MaximizeCoverage(test, tuple); } private int MaximizeCoverage(TestCase test, Tuple tuple) { int[] dimensionOrder = this.GetMutableDimensions(tuple); while (true) { bool progress = false; int totalCoverage = 1; // Scramble dimensions. for (int i = dimensionOrder.Length; i > 1; i--) { int j = (int)(this.random.Next() % i); int t = dimensionOrder[i - 1]; dimensionOrder[i - 1] = dimensionOrder[j]; dimensionOrder[j] = t; } // For each dimension that can be modified... for (int i = 0; i < dimensionOrder.Length; i++) { int d = dimensionOrder[i]; ArrayList bestFeatures = new ArrayList(); int bestCoverage = this.CountTuplesCovered(test, d, test.Features[d]); int bestTupleLength = this.currentTupleLength[d][test.Features[d]]; // For each feature that can be modified, check if it can extend coverage. for (int f = 0; f < this.dimensions[d]; f++) { test.Features[d] = f; int coverage = this.CountTuplesCovered(test, d, f); if (this.currentTupleLength[d][f] < bestTupleLength) { progress = true; bestTupleLength = this.currentTupleLength[d][f]; bestCoverage = coverage; bestFeatures.Clear(); bestFeatures.Add(f); } else { if (this.currentTupleLength[d][f] == bestTupleLength && coverage >= bestCoverage) { if (coverage > bestCoverage) { progress = true; bestCoverage = coverage; bestFeatures.Clear(); } bestFeatures.Add(f); } } } if (bestFeatures.Count == 1) { test.Features[d] = (int)bestFeatures[0]; } else { test.Features[d] = (int)bestFeatures[(int)(this.random.Next() % bestFeatures.Count)]; } totalCoverage += bestCoverage; } if (!progress) { return totalCoverage; } } } private int[] GetMutableDimensions(Tuple tuple) { bool[] immutableDimensions = new bool[this.dimensions.Length]; for (int i = 0; i < tuple.Count; i++) { immutableDimensions[tuple[i].Dimension] = true; } ArrayList mutableDimensions = new ArrayList(); for (int i = 0; i < this.dimensions.Length; i++) { if (!immutableDimensions[i]) { mutableDimensions.Add(i); } } return (int[])mutableDimensions.ToArray(typeof(int)); } private int CountTuplesCovered(TestCase test, int dimension, int feature) { int tuplesCovered = 0; TupleCollection tuples = this.uncoveredTuples[dimension][feature]; for (int i = 0; i < tuples.Count; i++) { if (test.IsTupleCovered(tuples[i])) { tuplesCovered++; } } return tuplesCovered; } private void RemoveTuplesCoveredBy(TestCase testCase) { for (int d = 0; d < this.uncoveredTuples.Length; d++) { for (int f = 0; f < this.uncoveredTuples[d].Length; f++) { TupleCollection tuples = this.uncoveredTuples[d][f]; for (int i = tuples.Count - 1; i >= 0; i--) { if (testCase.IsTupleCovered(tuples[i])) { tuples.RemoveAt(i); } } } } } private void SelfTest() { for (int d1 = 0; d1 < this.dimensions.Length - 1; d1++) { for (int d2 = d1 + 1; d2 < this.dimensions.Length; d2++) { for (int f1 = 0; f1 < this.dimensions[d1]; f1++) { for (int f2 = 0; f2 < this.dimensions[d2]; f2++) { Tuple tuple = new Tuple(); tuple.Add(new FeatureInfo(d1, f1)); tuple.Add(new FeatureInfo(d2, f2)); if (!this.testCases.IsTupleCovered(tuple)) { throw new ApplicationException("PairwiseStrategy self-test failed : Not all pairs are covered!"); } } } } } } } public PairwiseStrategy(IEnumerable[] sources) : base(sources) { } public override IEnumerable GetTestCases() { ArrayList[] valueSet = CreateValueSet(); int[] dimensions = CreateDimensions(valueSet); IEnumerable pairwiseTestCases = new PairwiseTestCaseGenerator(dimensions).GetTestCases(); #if CLR_2_0 || CLR_4_0 List testCases = new List(); #else ArrayList testCases = new ArrayList(); #endif foreach (TestCase pairwiseTestCase in pairwiseTestCases) { object[] testData = new object[pairwiseTestCase.Features.Length]; for (int i = 0; i < pairwiseTestCase.Features.Length; i++) { testData[i] = valueSet[i][pairwiseTestCase.Features[i]]; } ParameterSet testCase = new ParameterSet(); testCase.Arguments = testData; testCases.Add(testCase); } return testCases; } private ArrayList[] CreateValueSet() { ArrayList[] valueSet = new ArrayList[Sources.Length]; for (int i = 0; i < valueSet.Length; i++) { ArrayList values = new ArrayList(); foreach (object value in Sources[i]) { values.Add(value); } valueSet[i] = values; } return valueSet; } private int[] CreateDimensions(ArrayList[] valueSet) { int[] dimensions = new int[valueSet.Length]; for (int i = 0; i < valueSet.Length; i++) { dimensions[i] = valueSet[i].Count; } return dimensions; } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/NUnitTestFixtureBuilder.cs0000664000175000017500000002675011652213740025432 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using System.Text.RegularExpressions; using System.Text; namespace NUnit.Core.Builders { /// /// Built-in SuiteBuilder for NUnit TestFixture /// public class NUnitTestFixtureBuilder : Extensibility.ISuiteBuilder { #region Instance Fields /// /// The NUnitTestFixture being constructed; /// private NUnitTestFixture fixture; private Extensibility.ITestCaseBuilder2 testBuilders = CoreExtensions.Host.TestBuilders; private Extensibility.ITestDecorator testDecorators = CoreExtensions.Host.TestDecorators; #endregion #region ISuiteBuilder Methods /// /// Checks to see if the fixture type has the TestFixtureAttribute /// /// The fixture type to check /// True if the fixture can be built, false if not public bool CanBuildFrom(Type type) { if (type.IsAbstract && !type.IsSealed) return false; return Reflect.HasAttribute( type, NUnitFramework.TestFixtureAttribute, true ) || Reflect.HasMethodWithAttribute(type, NUnitFramework.TestAttribute, true) || Reflect.HasMethodWithAttribute(type, NUnitFramework.TestCaseAttribute, true) || Reflect.HasMethodWithAttribute(type, NUnitFramework.TestCaseSourceAttribute, true) || Reflect.HasMethodWithAttribute(type, NUnitFramework.TheoryAttribute, true); } /// /// Build a TestSuite from type provided. /// /// /// public Test BuildFrom(Type type) { Attribute[] attrs = GetTestFixtureAttributes(type); #if CLR_2_0 || CLR_4_0 if (type.IsGenericType) return BuildMultipleFixtures(type, attrs); #endif switch (attrs.Length) { case 0: return BuildSingleFixture(type, null); case 1: object[] args = (object[])Reflect.GetPropertyValue(attrs[0], "Arguments"); return args == null || args.Length == 0 ? BuildSingleFixture(type, attrs[0]) : BuildMultipleFixtures(type, attrs); default: return BuildMultipleFixtures(type, attrs); } } #endregion #region Helper Methods private Test BuildMultipleFixtures(Type type, Attribute[] attrs) { TestSuite suite = new ParameterizedFixtureSuite(type); if (attrs.Length > 0) { foreach (Attribute attr in attrs) suite.Add(BuildSingleFixture(type, attr)); } else { suite.RunState = RunState.NotRunnable; suite.IgnoreReason = "Generic fixture has no type arguments provided"; } return suite; } private Test BuildSingleFixture(Type type, Attribute attr) { object[] arguments = null; IList categories = null; if (attr != null) { arguments = (object[])Reflect.GetPropertyValue(attr, "Arguments"); categories = Reflect.GetPropertyValue(attr, "Categories") as IList; #if CLR_2_0 || CLR_4_0 if (type.ContainsGenericParameters) { Type[] typeArgs = (Type[])Reflect.GetPropertyValue(attr, "TypeArgs"); if( typeArgs.Length > 0 || TypeHelper.CanDeduceTypeArgsFromArgs(type, arguments, ref typeArgs)) { type = TypeHelper.MakeGenericType(type, typeArgs); } } #endif } this.fixture = new NUnitTestFixture(type, arguments); CheckTestFixtureIsValid(fixture); NUnitFramework.ApplyCommonAttributes(type, fixture); if (categories != null) foreach (string category in categories) fixture.Categories.Add(category); if (fixture.RunState == RunState.Runnable && attr != null) { object objIgnore = Reflect.GetPropertyValue(attr, "Ignore"); if (objIgnore != null && (bool)objIgnore == true) { fixture.RunState = RunState.Ignored; fixture.IgnoreReason = (string)Reflect.GetPropertyValue(attr, "IgnoreReason"); } } AddTestCases(type); return this.fixture; } /// /// Method to add test cases to the newly constructed fixture. /// The default implementation looks at each candidate method /// and tries to build a test case from it. It will only need /// to be overridden if some other approach, such as reading a /// datafile is used to generate test cases. /// /// protected virtual void AddTestCases( Type fixtureType ) { IList methods = fixtureType.GetMethods( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static ); foreach(MethodInfo method in methods) { Test test = BuildTestCase(method, this.fixture); if(test != null) { this.fixture.Add( test ); } } } /// /// Method to create a test case from a MethodInfo and add /// it to the fixture being built. It first checks to see if /// any global TestCaseBuilder addin wants to build the /// test case. If not, it uses the internal builder /// collection maintained by this fixture builder. After /// building the test case, it applies any decorators /// that have been installed. /// /// The default implementation has no test case builders. /// Derived classes should add builders to the collection /// in their constructor. /// /// /// private Test BuildTestCase( MethodInfo method, TestSuite suite ) { Test test = testBuilders.BuildFrom( method, suite ); if ( test != null ) test = testDecorators.Decorate( test, method ); return test; } private void CheckTestFixtureIsValid(TestFixture fixture) { Type fixtureType = fixture.FixtureType; string reason = null; if (!IsValidFixtureType(fixtureType, ref reason)) { fixture.RunState = RunState.NotRunnable; fixture.IgnoreReason = reason; } else if( !IsStaticClass( fixtureType ) ) { // Postpone checking for constructor with arguments till we invoke it // since Type.GetConstructor doesn't handle null arguments well. if ( fixture.arguments == null || fixture.arguments.Length == 0 ) if (Reflect.GetConstructor(fixtureType) == null) { fixture.RunState = RunState.NotRunnable; fixture.IgnoreReason = "No suitable constructor was found"; } } } private static bool IsStaticClass(Type type) { return type.IsAbstract && type.IsSealed; } /// /// Check that the fixture type is valid. This method ensures that /// the type is not abstract and that there is no more than one of /// each setup or teardown method and that their signatures are correct. /// /// The type of the fixture to check /// A message indicating why the fixture is invalid /// True if the fixture is valid, false if not private bool IsValidFixtureType(Type fixtureType, ref string reason) { //if (fixtureType.IsAbstract && !fixtureType.IsSealed) //{ // reason = string.Format("{0} is an abstract class", fixtureType.FullName); // return false; //} #if CLR_2_0 || CLR_4_0 if ( fixtureType.ContainsGenericParameters ) { reason = "Fixture type contains generic parameters. You must either provide " + "Type arguments or specify constructor arguments that allow NUnit " + "to deduce the Type arguments."; return false; } #endif return NUnitFramework.CheckSetUpTearDownMethods(fixtureType, NUnitFramework.SetUpAttribute, ref reason) && NUnitFramework.CheckSetUpTearDownMethods(fixtureType, NUnitFramework.TearDownAttribute, ref reason) && NUnitFramework.CheckSetUpTearDownMethods(fixtureType, NUnitFramework.FixtureSetUpAttribute, ref reason) && NUnitFramework.CheckSetUpTearDownMethods(fixtureType, NUnitFramework.FixtureTearDownAttribute, ref reason); } /// /// Get TestFixtureAttributes following a somewhat obscure /// set of rules to eliminate spurious duplication of fixtures. /// 1. If there are any attributes with args, they are the only /// ones returned and those without args are ignored. /// 2. No more than one attribute without args is ever returned. /// private static Attribute[] GetTestFixtureAttributes(Type type) { Attribute[] attrs = Reflect.GetAttributes(type, NUnitFramework.TestFixtureAttribute, true); // Just return - no possibility of duplication if (attrs.Length <= 1) return attrs; int withArgs = 0; bool[] hasArgs = new bool[attrs.Length]; // Count and record those attrs with arguments for (int i = 0; i < attrs.Length; i++) { object[] args = (object[])Reflect.GetPropertyValue(attrs[i], "Arguments"); object[] typeArgs = (object[])Reflect.GetPropertyValue(attrs[i], "TypeArgs"); if (args.Length > 0 || typeArgs != null && typeArgs.Length > 0) { withArgs++; hasArgs[i] = true; } } // If all attributes have args, just return them if (withArgs == attrs.Length) return attrs; // If all attributes are without args, just return the first found if (withArgs == 0) return new Attribute[] { attrs[0] }; // Some of each type, so extract those with args int count = 0; Attribute[] result = new Attribute[withArgs]; for (int i = 0; i < attrs.Length; i++) if (hasArgs[i]) result[count++] = attrs[i]; return result; } #endregion } }NUnit-2.6.0.12051/src/NUnitCore/core/Builders/CombiningStrategy.cs0000664000175000017500000000264011504175260024277 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public abstract class CombiningStrategy { protected IDataPointProvider dataPointProvider = (IDataPointProvider)CoreExtensions.Host.GetExtensionPoint("DataPointProviders"); private IEnumerable[] sources; private IEnumerator[] enumerators; public CombiningStrategy(IEnumerable[] sources) { this.sources = sources; } public IEnumerable[] Sources { get { return sources; } } public IEnumerator[] Enumerators { get { if (enumerators == null) { enumerators = new IEnumerator[Sources.Length]; for (int i = 0; i < Sources.Length; i++) enumerators[i] = Sources[i].GetEnumerator(); } return enumerators; } } public abstract IEnumerable GetTestCases(); } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/ProviderInfo.cs0000664000175000017500000000730711650231470023260 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; namespace NUnit.Core.Builders { class ProviderReference { private Type providerType; private string providerName; private object[] providerArgs; private string category; public ProviderReference(Type providerType, string providerName, string category) { if (providerType == null) throw new ArgumentNullException("providerType"); if (providerName == null) throw new ArgumentNullException("providerName"); this.providerType = providerType; this.providerName = providerName; this.category = category; } public ProviderReference(Type providerType, object[] args, string providerName, string category) : this(providerType, providerName, category) { this.providerArgs = args; } public string Name { get { return this.providerName; } } public string Category { get { return this.category; } } public IEnumerable GetInstance() { MemberInfo[] members = providerType.GetMember( providerName, MemberTypes.Field | MemberTypes.Method | MemberTypes.Property, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (members.Length == 0) throw new Exception(string.Format( "Unable to locate {0}.{1}", providerType.FullName, providerName)); return (IEnumerable)GetProviderObjectFromMember(members[0]); } private object GetProviderObjectFromMember(MemberInfo member) { object providerObject = null; object instance = null; switch (member.MemberType) { case MemberTypes.Property: PropertyInfo providerProperty = member as PropertyInfo; MethodInfo getMethod = providerProperty.GetGetMethod(true); if (!getMethod.IsStatic) //instance = ProviderCache.GetInstanceOf(providerType); instance = Reflect.Construct(providerType, providerArgs); providerObject = providerProperty.GetValue(instance, null); break; case MemberTypes.Method: MethodInfo providerMethod = member as MethodInfo; if (!providerMethod.IsStatic) //instance = ProviderCache.GetInstanceOf(providerType); instance = Reflect.Construct(providerType, providerArgs); providerObject = providerMethod.Invoke(instance, null); break; case MemberTypes.Field: FieldInfo providerField = member as FieldInfo; if (!providerField.IsStatic) //instance = ProviderCache.GetInstanceOf(providerType); instance = Reflect.Construct(providerType, providerArgs); providerObject = providerField.GetValue(instance); break; } return providerObject; } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/TestCaseParameterProvider.cs0000664000175000017500000001557711676163674025773 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; using System.Reflection; using System.Text; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public class TestCaseParameterProvider : ITestCaseProvider { /// /// Determine whether any test cases are available for a parameterized method. /// /// A MethodInfo representing a parameterized test /// True if any cases are available, otherwise false. public bool HasTestCasesFor(MethodInfo method) { return Reflect.HasAttribute(method, NUnitFramework.TestCaseAttribute, false); } /// /// Return an IEnumerable providing test cases for use in /// running a parameterized test. /// /// /// public IEnumerable GetTestCasesFor(MethodInfo method) { ArrayList list = new ArrayList(); Attribute[] attrs = Reflect.GetAttributes(method, NUnitFramework.TestCaseAttribute, false); ParameterInfo[] parameters = method.GetParameters(); int argsNeeded = parameters.Length; foreach (Attribute attr in attrs) { ParameterSet parms; try { parms = ParameterSet.FromDataSource(attr); int argsProvided = parms.Arguments.Length; // Special handling for params arguments if (argsNeeded > 0 && argsProvided >= argsNeeded - 1) { ParameterInfo lastParameter = parameters[argsNeeded - 1]; Type lastParameterType = lastParameter.ParameterType; Type elementType = lastParameterType.GetElementType(); if (lastParameterType.IsArray && lastParameter.IsDefined(typeof(ParamArrayAttribute), false)) { if (argsProvided == argsNeeded) { Type lastArgumentType = parms.Arguments[argsProvided - 1].GetType(); if (!lastParameterType.IsAssignableFrom(lastArgumentType)) { Array array = Array.CreateInstance(elementType, 1); array.SetValue(parms.Arguments[argsProvided - 1], 0); parms.Arguments[argsProvided - 1] = array; } } else { object[] newArglist = new object[argsNeeded]; for (int i = 0; i < argsNeeded && i < argsProvided; i++) newArglist[i] = parms.Arguments[i]; int length = argsProvided - argsNeeded + 1; Array array = Array.CreateInstance(elementType, length); for (int i = 0; i < length; i++) array.SetValue(parms.Arguments[argsNeeded + i - 1], i); newArglist[argsNeeded - 1] = array; parms.Arguments = newArglist; argsProvided = argsNeeded; } } } //if (method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(object[])) // parms.Arguments = new object[]{parms.Arguments}; // Special handling when sole argument is an object[] if (argsNeeded == 1 && method.GetParameters()[0].ParameterType == typeof(object[])) { if (argsProvided > 1 || argsProvided == 1 && parms.Arguments[0].GetType() != typeof(object[])) { parms.Arguments = new object[] { parms.Arguments }; } } if (argsProvided == argsNeeded) PerformSpecialConversions(parms.Arguments, parameters); } catch (Exception ex) { parms = new ParameterSet( ex ); } list.Add( parms ); } return list; } /// /// Performs several special conversions allowed by NUnit in order to /// permit arguments with types that cannot be used in the constructor /// of an Attribute such as TestCaseAttribute or to simplify their use. /// /// The arguments to be converted /// The ParameterInfo array for the method private static void PerformSpecialConversions(object[] arglist, ParameterInfo[] parameters) { for (int i = 0; i < arglist.Length; i++) { object arg = arglist[i]; Type targetType = parameters[i].ParameterType; if (arg == null) continue; if (arg.GetType().FullName == "NUnit.Framework.SpecialValue" && arg.ToString() == "Null" ) { arglist[i] = null; continue; } if (targetType.IsAssignableFrom(arg.GetType())) continue; if (arg is DBNull) { arglist[i] = null; continue; } bool convert = false; if (targetType == typeof(short) || targetType == typeof(byte) || targetType == typeof(sbyte)) convert = arg is int; else if (targetType == typeof(decimal)) convert = arg is double || arg is string || arg is int; else if (targetType == typeof(DateTime) || targetType == typeof(TimeSpan)) convert = arg is string; if (convert) arglist[i] = Convert.ChangeType(arg, targetType, System.Globalization.CultureInfo.InvariantCulture); } } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/NUnitTestCaseBuilder.cs0000664000175000017500000004405011720007056024645 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { /// /// Class to build ether a parameterized or a normal NUnitTestMethod. /// There are four cases that the builder must deal with: /// 1. The method needs no params and none are provided /// 2. The method needs params and they are provided /// 3. The method needs no params but they are provided in error /// 4. The method needs params but they are not provided /// This could have been done using two different builders, but it /// turned out to be simpler to have just one. The BuildFrom method /// takes a different branch depending on whether any parameters are /// provided, but all four cases are dealt with in lower-level methods /// public class NUnitTestCaseBuilder : ITestCaseBuilder2 { #region ITestCaseBuilder Methods /// /// Determines if the method can be used to build an NUnit test /// test method of some kind. The method must normally be marked /// with an identifying attriute for this to be true. If the test /// config file sets AllowOldStyleTests to true, then any method beginning /// "test..." (case-insensitive) is treated as a test unless /// it is also marked as a setup or teardown method. /// /// Note that this method does not check that the signature /// of the method for validity. If we did that here, any /// test methods with invalid signatures would be passed /// over in silence in the test run. Since we want such /// methods to be reported, the check for validity is made /// in BuildFrom rather than here. /// /// A MethodInfo for the method being used as a test method /// The test suite being built, to which the new test would be added /// True if the builder can create a test case from this method public bool CanBuildFrom(MethodInfo method) { return Reflect.HasAttribute(method, NUnitFramework.TestAttribute, false) || Reflect.HasAttribute(method, NUnitFramework.TestCaseAttribute, false) || Reflect.HasAttribute(method, NUnitFramework.TestCaseSourceAttribute, false) || Reflect.HasAttribute(method, NUnitFramework.TheoryAttribute, false); } /// /// Build a Test from the provided MethodInfo. Depending on /// whether the method takes arguments and on the availability /// of test case data, this method may return a single test /// or a group of tests contained in a ParameterizedMethodSuite. /// /// The MethodInfo for which a test is to be built /// The test fixture being populated, or null /// A Test representing one or more method invocations public Test BuildFrom(MethodInfo method) { return BuildFrom(method, null); } #region ITestCaseBuilder2 Members public bool CanBuildFrom(MethodInfo method, Test parentSuite) { return CanBuildFrom(method); } public Test BuildFrom(MethodInfo method, Test parentSuite) { return CoreExtensions.Host.TestCaseProviders.HasTestCasesFor(method) ? BuildParameterizedMethodSuite(method, parentSuite) : BuildSingleTestMethod(method, parentSuite, null); } #endregion /// /// Builds a ParameterizedMetodSuite containing individual /// test cases for each set of parameters provided for /// this method. /// /// The MethodInfo for which a test is to be built /// A ParameterizedMethodSuite populated with test cases public static Test BuildParameterizedMethodSuite(MethodInfo method, Test parentSuite) { ParameterizedMethodSuite methodSuite = new ParameterizedMethodSuite(method); NUnitFramework.ApplyCommonAttributes(method, methodSuite); if (parentSuite != null) { if (parentSuite.RunState == RunState.NotRunnable && methodSuite.RunState != RunState.NotRunnable) { methodSuite.RunState = RunState.NotRunnable; methodSuite.IgnoreReason = parentSuite.IgnoreReason; } if (parentSuite.RunState == RunState.Ignored && methodSuite.RunState != RunState.Ignored && methodSuite.RunState != RunState.NotRunnable) { methodSuite.RunState = RunState.Ignored; methodSuite.IgnoreReason = parentSuite.IgnoreReason; } } foreach (object source in CoreExtensions.Host.TestCaseProviders.GetTestCasesFor(method, parentSuite)) { ParameterSet parms; if (source == null) { parms = new ParameterSet(); parms.Arguments = new object[] { null }; } else parms = source as ParameterSet; if (parms == null) { if (source.GetType().GetInterface("NUnit.Framework.ITestCaseData") != null) parms = ParameterSet.FromDataSource(source); else { parms = new ParameterSet(); ParameterInfo[] parameters = method.GetParameters(); Type sourceType = source.GetType(); if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(sourceType)) parms.Arguments = new object[] { source }; else if (source is object[]) parms.Arguments = (object[])source; else if (source is Array) { Array array = (Array)source; if (array.Rank == 1) { parms.Arguments = new object[array.Length]; for (int i = 0; i < array.Length; i++) parms.Arguments[i] = (object)array.GetValue(i); } } else parms.Arguments = new object[] { source }; } } TestMethod test = BuildSingleTestMethod(method, parentSuite, parms); methodSuite.Add(test); } return methodSuite; } /// /// Builds a single NUnitTestMethod, either as a child of the fixture /// or as one of a set of test cases under a ParameterizedTestMethodSuite. /// /// The MethodInfo from which to construct the TestMethod /// The ParameterSet to be used, or null /// public static NUnitTestMethod BuildSingleTestMethod(MethodInfo method, Test parentSuite, ParameterSet parms) { NUnitTestMethod testMethod = new NUnitTestMethod(method); string prefix = method.ReflectedType.FullName; if (parentSuite != null) { prefix = parentSuite.TestName.FullName; testMethod.TestName.FullName = prefix + "." + testMethod.TestName.Name; } if (CheckTestMethodSignature(testMethod, parms)) { if (parms == null) NUnitFramework.ApplyCommonAttributes(method, testMethod); NUnitFramework.ApplyExpectedExceptionAttribute(method, testMethod); } if (parms != null) { // NOTE: After the call to CheckTestMethodSignature, the Method // property of testMethod may no longer be the same as the // original MethodInfo, so we reassign it here. method = testMethod.Method; if (parms.TestName != null) { testMethod.TestName.Name = parms.TestName; testMethod.TestName.FullName = prefix + "." + parms.TestName; } else if (parms.OriginalArguments != null) { string name = MethodHelper.GetDisplayName(method, parms.OriginalArguments); testMethod.TestName.Name = name; testMethod.TestName.FullName = prefix + "." + name; } if (parms.Ignored) { testMethod.RunState = RunState.Ignored; testMethod.IgnoreReason = parms.IgnoreReason; } else if (parms.Explicit) { testMethod.RunState = RunState.Explicit; } if (parms.ExpectedExceptionName != null) testMethod.exceptionProcessor = new ExpectedExceptionProcessor(testMethod, parms); foreach (string key in parms.Properties.Keys) testMethod.Properties[key] = parms.Properties[key]; // Description is stored in parms.Properties if (parms.Description != null) testMethod.Description = parms.Description; } //if (testMethod.BuilderException != null && testMethod.RunState != RunState.NotRunnable) //{ // testMethod.RunState = RunState.NotRunnable; // testMethod.IgnoreReason = testMethod.BuilderException.Message; //} if (parentSuite != null) { if (parentSuite.RunState == RunState.NotRunnable && testMethod.RunState != RunState.NotRunnable) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = parentSuite.IgnoreReason; } if (parentSuite.RunState == RunState.Ignored && testMethod.RunState != RunState.Ignored && testMethod.RunState != RunState.NotRunnable) { testMethod.RunState = RunState.Ignored; testMethod.IgnoreReason = parentSuite.IgnoreReason; } } return testMethod; } #endregion #region Helper Methods /// /// Helper method that checks the signature of a TestMethod and /// any supplied parameters to determine if the test is valid. /// /// Currently, NUnitTestMethods are required to be public, /// non-abstract methods, either static or instance, /// returning void. They may take arguments but the values must /// be provided or the TestMethod is not considered runnable. /// /// Methods not meeting these criteria will be marked as /// non-runnable and the method will return false in that case. /// /// The TestMethod to be checked. If it /// is found to be non-runnable, it will be modified. /// Parameters to be used for this test, or null /// True if the method signature is valid, false if not private static bool CheckTestMethodSignature(TestMethod testMethod, ParameterSet parms) { if (testMethod.Method.IsAbstract) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Method is abstract"; return false; } if (!testMethod.Method.IsPublic) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Method is not public"; return false; } ParameterInfo[] parameters = testMethod.Method.GetParameters(); int argsNeeded = parameters.Length; object[] arglist = null; int argsProvided = 0; if (parms != null) { testMethod.arguments = parms.Arguments; testMethod.hasExpectedResult = parms.HasExpectedResult; if (testMethod.hasExpectedResult) testMethod.expectedResult = parms.Result; testMethod.RunState = parms.RunState; testMethod.IgnoreReason = parms.IgnoreReason; testMethod.BuilderException = parms.ProviderException; arglist = parms.Arguments; if (arglist != null) argsProvided = arglist.Length; if (testMethod.RunState != RunState.Runnable) return false; } if (!testMethod.Method.ReturnType.Equals(typeof(void)) && (parms == null || !parms.HasExpectedResult && parms.ExpectedExceptionName == null)) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Method has non-void return value"; return false; } if (argsProvided > 0 && argsNeeded == 0) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Arguments provided for method not taking any"; return false; } if (argsProvided == 0 && argsNeeded > 0) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "No arguments were provided"; return false; } //if (argsProvided > argsNeeded) //{ // ParameterInfo lastParameter = parameters[argsNeeded - 1]; // Type lastParameterType = lastParameter.ParameterType; // if (lastParameterType.IsArray && lastParameter.IsDefined(typeof(ParamArrayAttribute), false)) // { // object[] newArglist = new object[argsNeeded]; // for (int i = 0; i < argsNeeded; i++) // newArglist[i] = arglist[i]; // int length = argsProvided - argsNeeded + 1; // Array array = Array.CreateInstance(lastParameterType.GetElementType(), length); // for (int i = 0; i < length; i++) // array.SetValue(arglist[argsNeeded + i - 1], i); // newArglist[argsNeeded - 1] = array; // testMethod.arguments = arglist = newArglist; // argsProvided = argsNeeded; // } //} if (argsProvided != argsNeeded ) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Wrong number of arguments provided"; return false; } #if CLR_2_0 || CLR_4_0 if (testMethod.Method.IsGenericMethodDefinition) { Type[] typeArguments = GetTypeArgumentsForMethod(testMethod.Method, arglist); foreach (object o in typeArguments) if (o == null) { testMethod.RunState = RunState.NotRunnable; testMethod.IgnoreReason = "Unable to determine type arguments for fixture"; return false; } testMethod.method = testMethod.Method.MakeGenericMethod(typeArguments); parameters = testMethod.Method.GetParameters(); for (int i = 0; i < parameters.Length; i++) { if (arglist[i].GetType() != parameters[i].ParameterType && arglist[i] is IConvertible) { try { arglist[i] = Convert.ChangeType(arglist[i], parameters[i].ParameterType); } catch (Exception) { // Do nothing - the incompatible argument will be reported below } } } } #endif return true; } #if CLR_2_0 || CLR_4_0 private static Type[] GetTypeArgumentsForMethod(MethodInfo method, object[] arglist) { Type[] typeParameters = method.GetGenericArguments(); Type[] typeArguments = new Type[typeParameters.Length]; ParameterInfo[] parameters = method.GetParameters(); for (int typeIndex = 0; typeIndex < typeArguments.Length; typeIndex++) { Type typeParameter = typeParameters[typeIndex]; for (int argIndex = 0; argIndex < parameters.Length; argIndex++) { if (parameters[argIndex].ParameterType.Equals(typeParameter)) typeArguments[typeIndex] = TypeHelper.BestCommonType( typeArguments[typeIndex], arglist[argIndex].GetType()); } } return typeArguments; } #endif #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/CombinatorialTestCaseProvider.cs0000664000175000017500000000535011504175260026602 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public class CombinatorialTestCaseProvider : ITestCaseProvider2 { #region Static Members static IDataPointProvider2 dataPointProvider = (IDataPointProvider2)CoreExtensions.Host.GetExtensionPoint("DataPointProviders"); //static readonly string CombinatorialAttribute = "NUnit.Framework.CombinatorialAttribute"; static readonly string PairwiseAttribute = "NUnit.Framework.PairwiseAttribute"; static readonly string SequentialAttribute = "NUnit.Framework.SequentialAttribute"; #endregion #region ITestCaseProvider Members public bool HasTestCasesFor(System.Reflection.MethodInfo method) { if (method.GetParameters().Length == 0) return false; foreach (ParameterInfo parameter in method.GetParameters()) if (!dataPointProvider.HasDataFor(parameter)) return false; return true; } public IEnumerable GetTestCasesFor(MethodInfo method) { return GetStrategy(method, null).GetTestCases(); } #endregion #region ITestCaseProvider2 Members public bool HasTestCasesFor(System.Reflection.MethodInfo method, Test suite) { return HasTestCasesFor(method); } public IEnumerable GetTestCasesFor(MethodInfo method, Test suite) { return GetStrategy(method, suite).GetTestCases(); } #endregion #region GetStrategy private CombiningStrategy GetStrategy(MethodInfo method, Test suite) { ParameterInfo[] parameters = method.GetParameters(); IEnumerable[] sources = new IEnumerable[parameters.Length]; for (int i = 0; i < parameters.Length; i++) sources[i] = dataPointProvider.GetDataFor(parameters[i], suite); if (Reflect.HasAttribute(method, SequentialAttribute, false)) return new SequentialStrategy(sources); if (Reflect.HasAttribute(method, PairwiseAttribute, false) && method.GetParameters().Length > 2) return new PairwiseStrategy(sources); return new CombinatorialStrategy(sources); } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/DatapointProvider.cs0000664000175000017500000001437011665722104024313 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { /// /// Provides data from fields marked with the DatapointAttribute or the /// DatapointsAttribute. /// public class DatapointProvider : IDataPointProvider { private static readonly string DatapointAttribute = "NUnit.Framework.DatapointAttribute"; private static readonly string DatapointsAttribute = "NUnit.Framework.DatapointsAttribute"; #region IDataPointProvider Members public bool HasDataFor(System.Reflection.ParameterInfo parameter) { Type parameterType = parameter.ParameterType; MemberInfo method = parameter.Member; Type fixtureType = method.ReflectedType; if (!Reflect.HasAttribute(method, NUnitFramework.TheoryAttribute, true)) return false; if (parameterType == typeof(bool) || parameterType.IsEnum) return true; foreach (MemberInfo member in fixtureType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (Reflect.HasAttribute(member, DatapointAttribute, true) && GetTypeFromMemberInfo(member) == parameterType) return true; else if (Reflect.HasAttribute(member, DatapointsAttribute, true) && GetElementTypeFromMemberInfo(member) == parameterType) return true; } return false; } public System.Collections.IEnumerable GetDataFor(System.Reflection.ParameterInfo parameter) { ArrayList datapoints = new ArrayList(); Type parameterType = parameter.ParameterType; Type fixtureType = parameter.Member.ReflectedType; foreach (MemberInfo member in fixtureType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (Reflect.HasAttribute(member, DatapointAttribute, true)) { if (GetTypeFromMemberInfo(member) == parameterType && member.MemberType == MemberTypes.Field) { FieldInfo field = member as FieldInfo; if (field.IsStatic) datapoints.Add(field.GetValue(null)); else datapoints.Add(field.GetValue(ProviderCache.GetInstanceOf(fixtureType))); } } else if (Reflect.HasAttribute(member, DatapointsAttribute, true)) { if (GetElementTypeFromMemberInfo(member) == parameterType) { object instance; switch(member.MemberType) { case MemberTypes.Field: FieldInfo field = member as FieldInfo; instance = field.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType); foreach (object data in (IEnumerable)field.GetValue(instance)) datapoints.Add(data); break; case MemberTypes.Property: PropertyInfo property = member as PropertyInfo; MethodInfo getMethod = property.GetGetMethod(true); instance = getMethod.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType); foreach (object data in (IEnumerable)property.GetValue(instance, null)) datapoints.Add(data); break; case MemberTypes.Method: MethodInfo method = member as MethodInfo; instance = method.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType); foreach (object data in (IEnumerable)method.Invoke(instance, Type.EmptyTypes)) datapoints.Add(data); break; } } } } if (datapoints.Count == 0) { if (parameterType == typeof(bool)) { datapoints.Add(true); datapoints.Add(false); } else if (parameterType.IsEnum) { datapoints.AddRange(System.Enum.GetValues(parameterType)); } } return datapoints; } private Type GetTypeFromMemberInfo(MemberInfo member) { switch (member.MemberType) { case MemberTypes.Field: return ((FieldInfo)member).FieldType; case MemberTypes.Property: return ((PropertyInfo)member).PropertyType; case MemberTypes.Method: return ((MethodInfo)member).ReturnType; default: return null; } } private Type GetElementTypeFromMemberInfo(MemberInfo member) { Type type = GetTypeFromMemberInfo(member); if (type == null) return null; if (type.IsArray) return type.GetElementType(); #if CLR_2_0 || CLR_4_0 if (type.IsGenericType && type.Name == "IEnumerable`1") return type.GetGenericArguments()[0]; #endif return null; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/InlineDataPointProvider.cs0000664000175000017500000000265111504175260025406 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public class InlineDataPointProvider : IDataPointProvider { private static readonly string ParameterDataAttribute = "NUnit.Framework.ParameterDataAttribute"; private static readonly string GetDataMethod = "GetData"; #region IDataPointProvider Members public bool HasDataFor(ParameterInfo parameter) { return Reflect.HasAttribute(parameter, ParameterDataAttribute, false); } public IEnumerable GetDataFor(ParameterInfo parameter) { Attribute attr = Reflect.GetAttribute(parameter, ParameterDataAttribute, false); if (attr == null) return null; MethodInfo getData = attr.GetType().GetMethod( GetDataMethod, new Type[] { typeof(ParameterInfo) }); if ( getData == null) return null; return getData.Invoke(attr, new object[] { parameter }) as IEnumerable; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/ValueSourceProvider.cs0000664000175000017500000001043511650230404024612 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org // **************************************************************** using System; using System.Reflection; using System.Collections; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { /// /// ValueSourceProvider supplies data items for individual parameters /// from named data sources in the test class or a separate class. /// public class ValueSourceProvider : IDataPointProvider2 { #region Constants public const string SourcesAttribute = "NUnit.Framework.ValueSourceAttribute"; public const string SourceTypeProperty = "SourceType"; public const string SourceNameProperty = "SourceName"; #endregion #region IDataPointProvider Members /// /// Determine whether any data sources are available for a parameter. /// /// A ParameterInfo test parameter /// True if any data is available, otherwise false. public bool HasDataFor(ParameterInfo parameter) { return Reflect.HasAttribute(parameter, SourcesAttribute, false); } /// /// Return an IEnumerable providing test data for use with /// one parameter of a parameterized test. /// /// /// public IEnumerable GetDataFor(ParameterInfo parameter) { return GetDataFor(parameter, null); } #endregion #region IDataPointProvider2 Members /// /// Determine whether any data sources are available for a parameter. /// /// A ParameterInfo test parameter /// The test suite for which the test is being built /// True if any data is available, otherwise false. public bool HasDataFor(ParameterInfo parameter, Test parentSuite) { return HasDataFor(parameter); } /// /// Return an IEnumerable providing test data for use with /// one parameter of a parameterized test. /// /// /// The test suite for which the test is being built /// public IEnumerable GetDataFor(ParameterInfo parameter, Test parentSuite) { ArrayList parameterList = new ArrayList(); foreach (ProviderReference providerRef in GetSourcesFor(parameter, parentSuite)) { IEnumerable instance = providerRef.GetInstance(); if (instance != null) foreach (object o in instance) parameterList.Add(o); } return parameterList; } #endregion #region Helper Methods private static IList GetSourcesFor(ParameterInfo parameter, Test parent) { ArrayList sources = new ArrayList(); TestFixture parentSuite = parent as TestFixture; foreach (Attribute sourceAttr in Reflect.GetAttributes(parameter, SourcesAttribute, false)) { Type sourceType = Reflect.GetPropertyValue(sourceAttr, SourceTypeProperty) as Type; string sourceName = Reflect.GetPropertyValue(sourceAttr, SourceNameProperty) as string; if (sourceType != null) sources.Add(new ProviderReference(sourceType, sourceName, null)); else if (parentSuite != null) sources.Add(new ProviderReference(parentSuite.FixtureType, parentSuite.arguments, sourceName, null)); else sources.Add(new ProviderReference(parameter.Member.ReflectedType, sourceName, null)); } return sources; } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/SetUpFixtureBuilder.cs0000664000175000017500000000447211504175260024572 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; namespace NUnit.Core.Builders { /// /// SetUpFixtureBuilder knows how to build a SetUpFixture. /// public class SetUpFixtureBuilder : Extensibility.ISuiteBuilder { #region ISuiteBuilder Members public Test BuildFrom(Type type) { SetUpFixture fixture = new SetUpFixture( type ); string reason = null; if (!IsValidFixtureType(type, ref reason)) { fixture.RunState = RunState.NotRunnable; fixture.IgnoreReason = reason; } return fixture; } public bool CanBuildFrom(Type type) { return Reflect.HasAttribute( type, NUnitFramework.SetUpFixtureAttribute, false ); } #endregion private bool IsValidFixtureType(Type type, ref string reason) { if (type.IsAbstract) { reason = string.Format("{0} is an abstract class", type.FullName); return false; } if (Reflect.GetConstructor(type) == null) { reason = string.Format("{0} does not have a valid constructor", type.FullName); return false; } if (!NUnitFramework.CheckSetUpTearDownMethods(type, NUnitFramework.SetUpAttribute, ref reason) || !NUnitFramework.CheckSetUpTearDownMethods(type, NUnitFramework.TearDownAttribute, ref reason) ) return false; if ( Reflect.HasMethodWithAttribute(type, NUnitFramework.FixtureSetUpAttribute, true) ) { reason = "TestFixtureSetUp method not allowed on a SetUpFixture"; return false; } if ( Reflect.HasMethodWithAttribute(type, NUnitFramework.FixtureTearDownAttribute, true) ) { reason = "TestFixtureTearDown method not allowed on a SetUpFixture"; return false; } return true; } } } NUnit-2.6.0.12051/src/NUnitCore/core/Builders/SequentialStrategy.cs0000664000175000017500000000314211544454420024504 0ustar jtaylorjtaylor// **************************************************************** // Copyright 2008, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org. // **************************************************************** using System; using System.Collections; #if CLR_2_0 || CLR_4_0 using System.Collections.Generic; #endif using System.Reflection; using NUnit.Core.Extensibility; namespace NUnit.Core.Builders { public class SequentialStrategy : CombiningStrategy { public SequentialStrategy(IEnumerable[] sources) : base(sources) { } public override IEnumerable GetTestCases() { #if CLR_2_0 || CLR_4_0 List testCases = new List(); #else ArrayList testCases = new ArrayList(); #endif for (; ; ) { bool gotData = false; object[] testdata = new object[Sources.Length]; for (int i = 0; i < Sources.Length; i++) if (Enumerators[i].MoveNext()) { testdata[i] = Enumerators[i].Current; gotData = true; } else testdata[i] = null; if (!gotData) break; ParameterSet testcase = new ParameterSet(); testcase.Arguments = testdata; testCases.Add(testcase); } return testCases; } } } NUnit-2.6.0.12051/src/NUnitCore/core/InvalidTestFixtureException.cs0000664000175000017500000000176111504175260024555 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** namespace NUnit.Core { using System; using System.Runtime.Serialization; /// /// Summary description for NoTestMethodsException. /// /// [Serializable] public class InvalidTestFixtureException : ApplicationException { public InvalidTestFixtureException() : base() {} public InvalidTestFixtureException(string message) : base(message) {} public InvalidTestFixtureException(string message, Exception inner) : base(message, inner) {} /// /// Serialization Constructor /// protected InvalidTestFixtureException(SerializationInfo info, StreamingContext context) : base(info,context){} } }NUnit-2.6.0.12051/src/NUnitCore/core/Reflect.cs0000664000175000017500000004070011504175260020461 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; using System.Collections; namespace NUnit.Core { /// /// Helper methods for inspecting a type by reflection. /// /// Many of these methods take ICustomAttributeProvider as an /// argument to avoid duplication, even though certain attributes can /// only appear on specific types of members, like MethodInfo or Type. /// /// In the case where a type is being examined for the presence of /// an attribute, interface or named member, the Reflect methods /// operate with the full name of the member being sought. This /// removes the necessity of the caller having a reference to the /// assembly that defines the item being sought and allows the /// NUnit core to inspect assemblies that reference an older /// version of the NUnit framework. /// public class Reflect { private static readonly BindingFlags AllMembers = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy; #region Attributes /// /// Check presence of attribute of a given type on a member. /// /// The member to examine /// The FullName of the attribute type to look for /// True to include inherited attributes /// True if the attribute is present public static bool HasAttribute( ICustomAttributeProvider member, string attrName, bool inherit ) { foreach( Attribute attribute in GetAttributes( member, inherit ) ) if ( IsInstanceOfType( attrName, attribute ) ) return true; return false; } /// /// Get attribute of a given type on a member. If multiple attributes /// of a type are present, the first one found is returned. /// /// The member to examine /// The FullName of the attribute type to look for /// True to include inherited attributes /// The attribute or null public static System.Attribute GetAttribute(ICustomAttributeProvider member, string attrName, bool inherit) { foreach (Attribute attribute in GetAttributes( member, inherit ) ) if ( IsInstanceOfType( attrName, attribute ) ) return attribute; return null; } /// /// Get all attributes of a given type on a member. /// /// The member to examine /// The FullName of the attribute type to look for /// True to include inherited attributes /// The attribute or null public static System.Attribute[] GetAttributes( ICustomAttributeProvider member, string attrName, bool inherit) { ArrayList result = new ArrayList(); foreach( Attribute attribute in GetAttributes( member, inherit ) ) if ( IsInstanceOfType( attrName, attribute ) ) result.Add( attribute ); return (System.Attribute[])result.ToArray( typeof( System.Attribute ) ); } /// /// Get all attributes on a member. /// /// The member to examine /// True to include inherited attributes /// The attribute or null public static System.Attribute[] GetAttributes( ICustomAttributeProvider member, bool inherit) { object[] attributes = member.GetCustomAttributes(inherit); System.Attribute[] result = new System.Attribute[attributes.Length]; int n = 0; foreach (Attribute attribute in attributes) result[n++] = attribute; return result; } #endregion #region Interfaces /// /// Check to see if a type implements a named interface. /// /// The type to examine /// The FullName of the interface to check for /// True if the interface is implemented by the type public static bool HasInterface( Type fixtureType, string interfaceName ) { foreach( Type type in fixtureType.GetInterfaces() ) if ( type.FullName == interfaceName ) return true; return false; } #endregion #region Inheritance //SHMARYA: [ 10/12/2005 ] /// /// Checks to see if a type inherits from a named type. /// /// The type to examine /// The FullName of the inherited type to look for /// True if the type inherits from the named type. public static bool InheritsFrom( Type type, string typeName ) { for( Type current = type; current != typeof( object ); current = current.BaseType ) if( current.FullName == typeName ) return true; return false; } public static bool InheritsFrom( object obj, string typeName ) { return InheritsFrom( obj.GetType(), typeName ); } public static bool IsInstanceOfType( string typeName, Attribute attr ) { Type type = attr.GetType(); return type.FullName == typeName || InheritsFrom( type, typeName ); } #endregion #region Get Methods of a type /// /// Find the default constructor on a type /// /// /// public static ConstructorInfo GetConstructor( Type fixtureType ) { return fixtureType.GetConstructor( Type.EmptyTypes ); } /// /// Examine a fixture type and return an array of methods having a /// particular attribute. The array is order with base methods first. /// /// The type to examine /// The FullName of the attribute to look for /// The array of methods found public static MethodInfo[] GetMethodsWithAttribute(Type fixtureType, string attributeName, bool inherit) { ArrayList list = new ArrayList(); foreach (MethodInfo method in GetMethods(fixtureType)) { if (HasAttribute(method, attributeName, inherit)) list.Add(method); } list.Sort(new BaseTypesFirstComparer()); return (MethodInfo[])list.ToArray(typeof(MethodInfo)); } private static MethodInfo[] GetMethods(Type fixtureType) { MethodInfo[] result = fixtureType.GetMethods(AllMembers); return result; } private class BaseTypesFirstComparer : IComparer { #region IComparer Members public int Compare(object x, object y) { MethodInfo m1 = x as MethodInfo; MethodInfo m2 = y as MethodInfo; if (m1 == null || m2 == null) return 0; Type m1Type = m1.DeclaringType; Type m2Type = m2.DeclaringType; if ( m1Type == m2Type ) return 0; if ( m1Type.IsAssignableFrom(m2Type) ) return -1; return 1; } #endregion } /// /// Examine a fixture type and return true if it has a method with /// a particular attribute. /// /// The type to examine /// The FullName of the attribute to look for /// True if found, otherwise false public static bool HasMethodWithAttribute(Type fixtureType, string attributeName, bool inherit) { foreach (MethodInfo method in GetMethods( fixtureType )) { if (HasAttribute(method, attributeName, inherit)) return true; } return false; } /// /// Examine a fixture type and get a method with a particular name. /// In the case of overloads, the first one found is returned. /// /// The type to examine /// The name of the method /// A MethodInfo or null public static MethodInfo GetNamedMethod(Type fixtureType, string methodName) { foreach (MethodInfo method in GetMethods( fixtureType )) { if (method.Name == methodName) return method; } return null; } /// /// Examine a fixture type and get a method with a particular name and list /// of arguments. In the case of overloads, the first one found is returned. /// /// The type to examine /// The name of the method /// The full names of the argument types to search for /// A MethodInfo or null public static MethodInfo GetNamedMethod(Type fixtureType, string methodName, string[] argTypes) { foreach (MethodInfo method in GetMethods(fixtureType) ) { if (method.Name == methodName) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == argTypes.Length) { bool match = true; for (int i = 0; i < argTypes.Length; i++) if (parameters[i].ParameterType.FullName != argTypes[i]) { match = false; break; } if (match) return method; } } } return null; } #endregion #region Get Properties of a type /// /// Examine a type and return a property having a particular attribute. /// In the case of multiple methods, the first one found is returned. /// /// The type to examine /// The FullName of the attribute to look for /// A PropertyInfo or null public static PropertyInfo GetPropertyWithAttribute( Type fixtureType, string attributeName ) { foreach(PropertyInfo property in fixtureType.GetProperties( AllMembers ) ) { if( HasAttribute( property, attributeName, true ) ) return property; } return null; } /// /// Examine a type and get a property with a particular name. /// In the case of overloads, the first one found is returned. /// /// The type to examine /// BindingFlags to use /// A PropertyInfo or null public static PropertyInfo GetNamedProperty( Type type, string name, BindingFlags bindingFlags ) { return type.GetProperty( name, bindingFlags ); } /// /// Get the value of a named property on an object using binding flags of Public and Instance /// /// The object for which the property value is needed /// The name of a non-indexed property of the object /// public static object GetPropertyValue( object obj, string name ) { return GetPropertyValue( obj, name, BindingFlags.Public | BindingFlags.Instance ); } /// /// Get the value of a named property on an object /// /// The object for which the property value is needed /// The name of a non-indexed property of the object /// BindingFlags for use in determining which properties are neededparam> /// public static object GetPropertyValue( object obj, string name, BindingFlags bindingFlags ) { PropertyInfo property = GetNamedProperty( obj.GetType(), name, bindingFlags ); if ( property != null ) return property.GetValue( obj, null ); return null; } #endregion #region Invoke Methods /// /// Invoke the default constructor on a Type /// /// The Type to be constructed /// An instance of the Type public static object Construct(Type type) { ConstructorInfo ctor = GetConstructor(type); if (ctor == null) throw new InvalidTestFixtureException(type.FullName + " does not have a default constructor"); return ctor.Invoke(null); } /// /// Invoke a constructor on a Type with arguments /// /// The Type to be constructed /// Arguments to the constructor /// An instance of the Type public static object Construct(Type type, object[] arguments) { if (arguments == null) return Construct(type); //Type[] argTypes = GetTypeArray(arguments); //ConstructorInfo ctor = GetConstructor(type, argTypes); //if (ctor == null) // throw new InvalidTestFixtureException(type.FullName + " does not have a suitable constructor"); try { return type.InvokeMember(type.Name, BindingFlags.CreateInstance, null, null, arguments); } catch (Exception ex) { throw new InvalidTestFixtureException(type.FullName + " does not have a suitable constructor", ex); } } /// /// Returns an array of types from an array of objects. /// Used because the compact framework doesn't support /// Type.GetTypeArray() /// /// An array of objects /// An array of Types public static Type[] GetTypeArray(object[] objects) { Type[] types = new Type[objects.Length]; int index = 0; foreach (object o in objects) types[index++] = o == null ? null : o.GetType(); return types; } /// /// Invoke a parameterless method returning void on an object. /// /// A MethodInfo for the method to be invoked /// The object on which to invoke the method public static object InvokeMethod( MethodInfo method, object fixture ) { return InvokeMethod( method, fixture, null ); } /// /// Invoke a method returning void, converting any TargetInvocationException /// to an NUnitException /// /// A MethodInfo for the method to be invoked /// The object on which to invoke the method public static object InvokeMethod( MethodInfo method, object fixture, params object[] args ) { if(method != null) { try { return method.Invoke( fixture, args ); } catch(TargetInvocationException e) { Exception inner = e.InnerException; throw new NUnitException("Rethrown",inner); } } return null; } #endregion #region Private Constructor for static-only class private Reflect() { } #endregion } } NUnit-2.6.0.12051/src/NUnitCore/core/TestAssembly.cs0000664000175000017500000000223411712475522021521 0ustar jtaylorjtaylor// **************************************************************** // This is free software licensed under the NUnit license. You // may obtain a copy of the license as well as information regarding // copyright ownership at http://nunit.org. // **************************************************************** using System; using System.Reflection; namespace NUnit.Core { /// /// TestAssembly is a TestSuite that represents the execution /// of tests in a managed assembly. /// public class TestAssembly : TestSuite { /// /// Initializes a new instance of the class. /// /// The path. public TestAssembly(Assembly assembly, string path) : base(path) { #if CLR_2_0 || CLR_4_0 this.actions = ActionsHelper.GetActionsFromAttributeProvider(assembly); #endif } /// /// Gets the type of the test. /// public override string TestType { get { return "Assembly"; } } } } NUnit-2.6.0.12051/NUnitTests.v1.nunit0000664000175000017500000000061711543625326016656 0ustar jtaylorjtaylor