public void TestInheritedOnEventGotoStateDeclaration() { var test = @" namespace Foo { machine M { abstract state BaseState { on e goto BaseDest; } start state Init : BaseState { on e goto InitDest; } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [OnEventGotoState(typeof(e), typeof(BaseDest))] abstract class BaseState : MachineState { } [Microsoft.PSharp.Start] [OnEventGotoState(typeof(e), typeof(InitDest))] class Init : BaseState { } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineExitDeclaration() { var test = @" namespace Foo { machine M { group G { start state S { exit{} } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnExit(nameof(psharp_G_S_on_exit_action))] public class S : MachineState { } } protected void psharp_G_S_on_exit_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineOnSimpleGenericEventDoActionDeclarationWithBody() { var test = @" namespace Foo { machine M { group G { start state S1 { on e<int> do {} } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventDoAction(typeof(e<int>), nameof(psharp_G_S1_e_type_0_action))] public class S1 : MachineState { } } protected void psharp_G_S1_e_type_0_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineOnEventGotoStateDeclarationWithBody() { var test = @" namespace Foo { machine M { group G { start state S1 { on e goto S2 with {} } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventGotoState(typeof(e), typeof(S2), nameof(psharp_G_S1_e_action))] public class S1 : MachineState { } } protected void psharp_G_S1_e_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMonitorOnEventDoActionDeclarationWithBody() { var test = @" namespace Foo { monitor M { group G { start state S1 { on e do {} } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Monitor { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventDoAction(typeof(e), nameof(psharp_G_S1_e_action))] public class S1 : MonitorState { } } protected void psharp_G_S1_e_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineInheritanceDeclarationWithGenerics2() { var test = @" namespace Foo { machine M1: M2<int,int> { start state S { } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M1 : M2<int, int> { [Microsoft.PSharp.Start] class S : MachineState { } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineDeclaration() { var test = @" namespace Foo { machine M { start state S { } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] class S : MachineState { } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestAsyncEntryAndExitDeclaration() { var test = @" namespace Foo { machine M { start state S { async entry { await Task.Delay(42); } async exit { await Task.Delay(42); } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S_on_entry_action_async))] [OnExit(nameof(psharp_S_on_exit_action_async))] class S : MachineState { } protected async System.Threading.Tasks.Task psharp_S_on_entry_action_async() { await Task.Delay(42); } protected async System.Threading.Tasks.Task psharp_S_on_exit_action_async() { await Task.Delay(42); } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestEntryAndExitDeclaration() { var test = @" namespace Foo { machine M { start state S { entry {} exit {} } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S_on_entry_action))] [OnExit(nameof(psharp_S_on_exit_action))] class S : MachineState { } protected void psharp_S_on_entry_action() {} protected void psharp_S_on_exit_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMonitorEntryDeclaration() { var test = @" namespace Foo { monitor M { group G { start state S { entry{} } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Monitor { class G : StateGroup { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_G_S_on_entry_action))] public class S : MonitorState { } } protected void psharp_G_S_on_entry_action() {} } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMachineOnEventGotoStateAndDoActionDeclaration() { var test = @" namespace Foo { machine M { group G { start state S1 { on e1 goto S2; on e2 do Bar; } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventGotoState(typeof(e1), typeof(S2))] [OnEventDoAction(typeof(e2), nameof(Bar))] public class S1 : MachineState { } } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestEventRaiseStatementWithPSharpAPI() { var test = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public e1() : base() { } } class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] [OnEventGotoState(typeof(e1), typeof(S2))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { this.Raise(new e1()); } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public e1() : base() { } } class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] [OnEventGotoState(typeof(e1), typeof(S2))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { this.Raise(new e1()); } } }"; LanguageTestUtilities.AssertRewritten(expected, test, isPSharpProgram: false); }
public void TestMachineMultipleGroups2() { var test = @" namespace Foo { machine M { group G1 { start state S1 { entry { jump(S2); } } state S2 { entry { jump(S1); } } } group G2 { state S1 { entry { jump(S2); } } state S2 { entry { jump(S1); } } state S3 { entry { jump(G1.S1); } } } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G1 : StateGroup { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_G1_S1_on_entry_action))] public class S1 : MachineState { } [OnEntry(nameof(psharp_G1_S2_on_entry_action))] public class S2 : MachineState { } } class G2 : StateGroup { [OnEntry(nameof(psharp_G2_S1_on_entry_action))] public class S1 : MachineState { } [OnEntry(nameof(psharp_G2_S2_on_entry_action))] public class S2 : MachineState { } [OnEntry(nameof(psharp_G2_S3_on_entry_action))] public class S3 : MachineState { } } protected void psharp_G1_S1_on_entry_action() { this.Goto<G1.S2>(); } protected void psharp_G1_S2_on_entry_action() { this.Goto<G1.S1>(); } protected void psharp_G2_S1_on_entry_action() { this.Goto<G2.S2>(); } protected void psharp_G2_S2_on_entry_action() { this.Goto<G2.S1>(); } protected void psharp_G2_S3_on_entry_action() { this.Goto<G1.S1>(); } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
private void AssertWithEntryExitReplacement(string expected, string test) { // Test both Entry and Exit combination LanguageTestUtilities.AssertRewritten(expected, test); LanguageTestUtilities.AssertRewritten(ReplaceEntryWithExitInExpected(expected), ReplaceEntryWithExitInTest(test)); }
public void TestIncorrectUsingDeclaration() { var test = "using System.Text"; LanguageTestUtilities.AssertFailedTestLog("Expected \";\".", test); }
public void TestUsingDeclarationWithoutIdentifier() { var test = "using;"; LanguageTestUtilities.AssertFailedTestLog("Expected identifier.", test); }
public void TestMultiPayloadMultiLevelGeneric() { // Some generic type params in derived classes are not specified in the same order // as in the base class, to verify correct handling. var test = @" namespace Foo { extern event E1x0<Te1x0> (ax0:char, bx0:string); extern event E1x<Te1x0, Te1x> : E1x0<Te1x0> (a1x:float, b1x:double); internal event E10 <Te10> (a10:short, b10:ushort); internal event E1 <Te10, Te1>: E10<Te10> (a1:byte, b1:bool); internal event E2 <Te2, Te1, Te10>: E1<Te10, Te1> (a2:int, b2:uint); internal event E2x <Te1x0, Te1x, Te2x> : E1x<Te1x0, Te1x> (a2x:long, b2x:ulong); }"; var expected = @" using Microsoft.PSharp; namespace Foo { internal class E10<Te10> : Event { public short a10; public ushort b10; public E10(short a10, ushort b10) : base() { this.a10 = a10; this.b10 = b10; } } internal class E1<Te10, Te1> : E10<Te10> { public byte a1; public bool b1; public E1(short a10, ushort b10, byte a1, bool b1) : base(a10, b10) { this.a1 = a1; this.b1 = b1; base.SetCardinalityConstraints(-1, -1); } } internal class E2<Te2, Te1, Te10> : E1<Te10, Te1> { public int a2; public uint b2; public E2(short a10, ushort b10, byte a1, bool b1, int a2, uint b2) : base(a10, b10, a1, b1) { this.a2 = a2; this.b2 = b2; base.SetCardinalityConstraints(-1, -1); } } internal class E2x<Te1x0, Te1x, Te2x> : E1x<Te1x0, Te1x> { public long a2x; public ulong b2x; public E2x(char ax0, string bx0, float a1x, double b1x, long a2x, ulong b2x) : base(ax0, bx0, a1x, b1x) { this.a2x = a2x; this.b2x = b2x; base.SetCardinalityConstraints(-1, -1); } } } "; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestAssumeAssertInheritance() { var test = @" namespace Foo { internal event E1 assert 1; internal event E2: E1 assert 2; internal event E3 assume 3; internal event E4: E3 assume 4; internal event E5 assert 5; internal event E6: E5 assume 6; internal event E7: E6; }"; var expected = @" using Microsoft.PSharp; namespace Foo { internal class E1 : Event { public E1() : base(1, -1) { } } internal class E2 : E1 { public E2() : base() { base.SetCardinalityConstraints(2, -1); } } internal class E3 : Event { public E3() : base(-1, 3) { } } internal class E4 : E3 { public E4() : base() { base.SetCardinalityConstraints(-1, 4); } } internal class E5 : Event { public E5() : base(5, -1) { } } internal class E6 : E5 { public E6() : base() { base.SetCardinalityConstraints(-1, 6); } } internal class E7 : E6 { public E7() : base() { base.SetCardinalityConstraints(-1, -1); } } } "; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestMultiPayloadMultiLevel() { var test = @" namespace Foo { extern event E1x0 (ax0:char, bx0:string); extern event E1x : E1x0 (a1x:float, b1x:double); internal event E10 (a10:short, b10:ushort); internal event E1 : E10 (a1:byte, b1:bool); internal event E2 : E1 (a2:int, b2:uint); internal event E2x : E1x (a2x:long, b2x:ulong); }"; var expected = @" using Microsoft.PSharp; namespace Foo { internal class E10 : Event { public short a10; public ushort b10; public E10(short a10, ushort b10) : base() { this.a10 = a10; this.b10 = b10; } } internal class E1 : E10 { public byte a1; public bool b1; public E1(short a10, ushort b10, byte a1, bool b1) : base(a10, b10) { this.a1 = a1; this.b1 = b1; base.SetCardinalityConstraints(-1, -1); } } internal class E2 : E1 { public int a2; public uint b2; public E2(short a10, ushort b10, byte a1, bool b1, int a2, uint b2) : base(a10, b10, a1, b1) { this.a2 = a2; this.b2 = b2; base.SetCardinalityConstraints(-1, -1); } } internal class E2x : E1x { public long a2x; public ulong b2x; public E2x(char ax0, string bx0, float a1x, double b1x, long a2x, ulong b2x) : base(ax0, bx0, a1x, b1x) { this.a2x = a2x; this.b2x = b2x; base.SetCardinalityConstraints(-1, -1); } } } "; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestNamespaceDeclarationWithoutIdentifier() { var test = "namespace { }"; LanguageTestUtilities.AssertFailedTestLog("Expected namespace identifier.", test); }
public void TestUnexpectedTokenWithoutNamespace() { var test = "private"; LanguageTestUtilities.AssertFailedTestLog("Unexpected token.", test); }
public void TestEventInMachineDeclaration() { var test = @" namespace Foo { machine M { public event e1<T>; internal event e2; public event e3<T, K> (m:K, n:T); internal event e4 (m:string); start state S { } } }"; var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { public class e1<T> : Event { public e1() : base() { } } internal class e2 : Event { public e2() : base() { } } public class e3<T, K> : Event { public K m; public T n; public e3(K m, T n) : base() { this.m = m; this.n = n; } } internal class e4 : Event { public string m; public e4(string m) : base() { this.m = m; } } [Microsoft.PSharp.Start] class S : MachineState { } } }"; LanguageTestUtilities.AssertRewritten(expected, test); }
public void TestEventDeclarationWithoutNamespace() { var test = "event e;"; LanguageTestUtilities.AssertFailedTestLog("Must be declared inside a namespace or machine.", test); }