private void TestWriteClientCode_Works(bool withNamespace, bool enableClientCreate, bool generateImplementationsAsOverride) { CodeBuilder cb = new CodeBuilder(); var tpl = new Template(); tpl.ClassName = "TestClass"; tpl.Nmspace = withNamespace ? "TestNamespace" : null; tpl.EnableClientCreate = enableClientCreate; tpl.AddClientUsingDirective("AddedNamespace.Client"); tpl.AddServerUsingDirective("AddedNamespace.Server"); tpl.GenerateImplementationsAsOverrides = generateImplementationsAsOverride; var m1 = mocks.StrictMock<IMember>(); var m2 = mocks.StrictMock<IMember>(); Expect.Call(m1.Name).Return("m1").Repeat.Any(); Expect.Call(m2.Name).Return("m2").Repeat.Any(); Expect.Call(m1.Dependencies).Return(new string[] { }); Expect.Call(m2.Dependencies).Return(new string[] { "m1" }); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ClientDefinition, cb)).Do((Action<ITemplate, MemberCodePoint, CodeBuilder>)((_, __, x) => x.AppendLine("[a]"))); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ClientDefinition, cb)).Do((Action<ITemplate, MemberCodePoint, CodeBuilder>)((_, __, x) => x.AppendLine("[b]"))); if (enableClientCreate) { Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ClientConstructor, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ClientConstructor, cb)); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.Attach, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.Attach, cb)); } Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.TransferConstructor, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.TransferConstructor, cb)); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ClientIdChanging, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ClientIdChanging, cb)); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.AttachSelf, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.AttachSelf, cb)); mocks.ReplayAll(); string maybeOverride = generateImplementationsAsOverride ? "override " : ""; string p = (withNamespace ? "\t" : ""); string expected = "using System;" + Environment.NewLine + "using System.Collections;" + Environment.NewLine + "using System.Collections.Generic;" + Environment.NewLine + "using System.Html;" + Environment.NewLine + "using Saltarelle;" + Environment.NewLine + "using Saltarelle.Ioc;" + Environment.NewLine + "using AddedNamespace.Client;" + Environment.NewLine + Environment.NewLine + (withNamespace ? "namespace TestNamespace {" + Environment.NewLine : "") + p + "public partial class TestClass : IControl, INotifyCreated" + (enableClientCreate ? ", IClientCreateControl" : "") + " {" + Environment.NewLine + p + " partial void Constructed();" + Environment.NewLine + p + " partial void Attached();" + Environment.NewLine + Environment.NewLine + p + " private Dictionary<string, IControl> controls = new Dictionary<string, IControl>();" + Environment.NewLine + p + " private JsDictionary __cfg;" + Environment.NewLine + Environment.NewLine + p + " private Position position;" + Environment.NewLine + p + " public " + maybeOverride + "Position Position {" + Environment.NewLine + p + " get { return isAttached ? PositionHelper.GetPosition(GetElement()) : position; }" + Environment.NewLine + p + " set {" + Environment.NewLine + p + " position = value;" + Environment.NewLine + p + " if (isAttached)" + Environment.NewLine + p + " PositionHelper.ApplyPosition(GetElement(), value);" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " private bool isAttached = false;" + Environment.NewLine + p + " public " + maybeOverride + "Element GetElement() { return isAttached ? Document.GetElementById(id) : null; }" + Environment.NewLine + Environment.NewLine + p + " private string id;" + Environment.NewLine + p + " public " + maybeOverride + "string Id {" + Environment.NewLine + p + " get { return id; }" + Environment.NewLine + p + " set {" + Environment.NewLine + p + " foreach (var kvp in controls)" + Environment.NewLine + p + " kvp.Value.Id = value + \"_\" + kvp.Key;" + Environment.NewLine + p + " if (isAttached)" + Environment.NewLine + p + " GetElement().ID = value;" + Environment.NewLine + p + " this.id = value;" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + (enableClientCreate ? p + " private string GetHtml() {" + Environment.NewLine + p + " StringBuilder sb = new StringBuilder();" + Environment.NewLine + p + " return sb.ToString();" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine : "") + p + " [a]" + Environment.NewLine + p + " [b]" + Environment.NewLine + p + " private void AttachSelf() {" + Environment.NewLine + p + " this.isAttached = true;" + Environment.NewLine + p + " Attached();" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + (enableClientCreate ? p + " public void Attach() {" + Environment.NewLine + p + " if (Script.IsNullOrEmpty(id) || isAttached) throw new Exception(\"Must set id before attach and can only attach once.\");" + Environment.NewLine + p + " AttachSelf();" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " public " + maybeOverride + "string Html {" + Environment.NewLine + p + " get {" + Environment.NewLine + p + " if (string.IsNullOrEmpty(id))" + Environment.NewLine + p + " throw new InvalidOperationException(\"Must assign Id before rendering.\");" + Environment.NewLine + p + " return GetHtml();" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " [AlternateSignature]" + Environment.NewLine + p + " public TestClass() {}" + Environment.NewLine : "") + p + " [Obsolete(@\"" + Template.DoNotCallConstructorMessage.Replace("\"", "\"\"") + "\")]" + Environment.NewLine + p + " public TestClass(object config) {" + Environment.NewLine + p + " __cfg = (!Script.IsUndefined(config) ? JsDictionary.GetDictionary(config) : null);" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " public void DependenciesAvailable() {" + Environment.NewLine + p + " if (__cfg != null) {" + Environment.NewLine + p + " this.id = (string)__cfg[\"id\"];" + Environment.NewLine + p + " Constructed();" + Environment.NewLine + p + " AttachSelf();" + Environment.NewLine + p + " }" + Environment.NewLine + p + " else {" + Environment.NewLine + (enableClientCreate ? p + " this.position = PositionHelper.NotPositioned;" + Environment.NewLine + p + " Constructed();" + Environment.NewLine : p + " throw new Exception(\"This control must be created server-side\");" + Environment.NewLine ) + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + p + "}" + Environment.NewLine + (withNamespace ? "}" + Environment.NewLine : ""); tpl.AddMember(m1); tpl.AddMember(m2); tpl.WriteClientCode(cb); Assert.AreEqual(expected, cb.ToString()); Assert.AreEqual(0, cb.IndentLevel); mocks.VerifyAll(); }
public void TestInstantiate() { var tpl = new Template(); IInstantiatedTemplateControl ctl = null; var m1 = mocks.StrictMock<IMember>(); var m2 = mocks.StrictMock<IMember>(); var container = mocks.StrictMock<IContainer>(); Expect.Call(m1.Name).Return("m1").Repeat.Any(); Expect.Call(m2.Name).Return("m2").Repeat.Any(); Expect.Call(m1.Dependencies).Return(new string[] { }); Expect.Call(m2.Dependencies).Return(new string[] { "m1" }); Expect.Call(() => m1.Instantiate(null, null, container)).IgnoreArguments().Constraints(Is.Same(tpl), Is.NotNull(), Is.Same(container)).Do((Action<ITemplate, IInstantiatedTemplateControl, IContainer>)((_, c, __) => { ctl = c; } )); Expect.Call(() => m2.Instantiate(null, null, container)).IgnoreArguments().Constraints(Is.Same(tpl), Is.Matching((IInstantiatedTemplateControl x) => object.ReferenceEquals(x, ctl)), Is.Same(container)); tpl.MainRenderFunction.AddFragment(new LiteralFragment("X")); mocks.ReplayAll(); tpl.AddMember(m1); tpl.AddMember(m2); var actual = tpl.Instantiate(container); Assert.AreSame(ctl, actual); actual.Id = "SomeId"; Assert.AreEqual("X", actual.Html); mocks.VerifyAll(); }
private void TestWriteServerCode_Works(bool withNamespace, bool enableClientCreate, bool generateImplementationsAsOverride) { CodeBuilder cb = new CodeBuilder(); var tpl = new Template(); tpl.ClassName = "TestClass"; tpl.Nmspace = withNamespace ? "TestNamespace" : null; tpl.EnableClientCreate = enableClientCreate; tpl.AddClientUsingDirective("AddedNamespace.Client"); tpl.AddServerUsingDirective("AddedNamespace.Server"); tpl.GenerateImplementationsAsOverrides = generateImplementationsAsOverride; var m1 = mocks.StrictMock<IMember>(); var m2 = mocks.StrictMock<IMember>(); Expect.Call(m1.Name).Return("m1").Repeat.Any(); Expect.Call(m2.Name).Return("m2").Repeat.Any(); Expect.Call(m1.Dependencies).Return(new string[] { }); Expect.Call(m2.Dependencies).Return(new string[] { "m1" }); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ServerIdChanging, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ServerIdChanging, cb)); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ConfigObjectInit, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ConfigObjectInit, cb)); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ServerDefinition, cb)).Do((Action<ITemplate, MemberCodePoint, CodeBuilder>)((_, __, x) => x.AppendLine("[a]"))); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ServerDefinition, cb)).Do((Action<ITemplate, MemberCodePoint, CodeBuilder>)((_, __, x) => x.AppendLine("[b]"))); Expect.Call(() => m1.WriteCode(tpl, MemberCodePoint.ServerConstructor, cb)); Expect.Call(() => m2.WriteCode(tpl, MemberCodePoint.ServerConstructor, cb)); mocks.ReplayAll(); string maybeOverride = generateImplementationsAsOverride ? "override " : ""; string p = (withNamespace ? "\t" : ""); string expected = "using System;" + Environment.NewLine + "using System.Collections.Generic;" + Environment.NewLine + "using System.Text;" + Environment.NewLine + "using Saltarelle;" + Environment.NewLine + "using Saltarelle.Ioc;" + Environment.NewLine + "using AddedNamespace.Server;" + Environment.NewLine + Environment.NewLine + (withNamespace ? "namespace TestNamespace {" + Environment.NewLine : "") + p + "public partial class TestClass : IControl, INotifyCreated" + (enableClientCreate ? ", IClientCreateControl" : "") + " {" + Environment.NewLine + p + " partial void Constructed();" + Environment.NewLine + Environment.NewLine + p + " private Dictionary<string, IControl> controls = new Dictionary<string, IControl>();" + Environment.NewLine + Environment.NewLine + p + " private Position position = PositionHelper.NotPositioned;" + Environment.NewLine + p + " public " + maybeOverride + "Position Position { get { return position; } set { position = value; } }" + Environment.NewLine + Environment.NewLine + p + " private string id;" + Environment.NewLine + p + " public " + maybeOverride + "string Id {" + Environment.NewLine + p + " get { return id; }" + Environment.NewLine + p + " set {" + Environment.NewLine + p + " foreach (var kvp in controls)" + Environment.NewLine + p + " kvp.Value.Id = value + \"_\" + kvp.Key;" + Environment.NewLine + p + " this.id = value;" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " public " + maybeOverride + "object ConfigObject {" + Environment.NewLine + p + " get {" + Environment.NewLine + p + " Dictionary<string, object> __cfg = new Dictionary<string, object>();" + Environment.NewLine + p + " __cfg[\"id\"] = id;" + Environment.NewLine + p + " return __cfg;" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " private string GetHtml() {" + Environment.NewLine + p + " StringBuilder sb = new StringBuilder();" + Environment.NewLine + p + " return sb.ToString();" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " [a]" + Environment.NewLine + p + " [b]" + Environment.NewLine + p + " public " + maybeOverride + "string Html {" + Environment.NewLine + p + " get {" + Environment.NewLine + p + " if (string.IsNullOrEmpty(id))" + Environment.NewLine + p + " throw new InvalidOperationException(\"Must assign Id before rendering.\");" + Environment.NewLine + p + " return GetHtml();" + Environment.NewLine + p + " }" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " [Obsolete(@\"" + Template.DoNotCallConstructorMessage.Replace("\"", "\"\"") + "\")]" + Environment.NewLine + p + " public TestClass() {" + Environment.NewLine + p + " }" + Environment.NewLine + Environment.NewLine + p + " public void DependenciesAvailable() {" + Environment.NewLine + p + " Constructed();" + Environment.NewLine + p + " }" + Environment.NewLine + p + "}" + Environment.NewLine + (withNamespace ? "}" + Environment.NewLine : ""); tpl.AddMember(m1); tpl.AddMember(m2); tpl.WriteServerCode(cb); Assert.AreEqual(expected, cb.ToString()); Assert.AreEqual(0, cb.IndentLevel); mocks.VerifyAll(); }