// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.ClearScript.V8;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.ClearScript.Test
{
[TestClass]
[SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Test classes use TestCleanupAttribute for deterministic teardown.")]
public class HostListTest : ClearScriptTest
{
#region setup / teardown
private ScriptEngine engine;
[TestInitialize]
public void TestInitialize()
{
engine = new V8ScriptEngine(V8ScriptEngineFlags.EnableDebugging);
}
[TestCleanup]
public void TestCleanup()
{
engine.Dispose();
BaseTestCleanup();
}
#endregion
#region test methods
// ReSharper disable InconsistentNaming
[TestMethod, TestCategory("HostList")]
public void HostList_ArrayList()
{
var list = new ArrayList { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
engine.Execute("list[1] = list[2]");
Assert.AreEqual(DayOfWeek.Wednesday, engine.Evaluate("list[1]"));
}
[TestMethod, TestCategory("HostList")]
public void HostList_List()
{
var list = new List { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
engine.Execute("list[1] = list[2]");
Assert.AreEqual(DayOfWeek.Wednesday, engine.Evaluate("list[1]"));
}
[TestMethod, TestCategory("HostList")]
public void HostList_Custom()
{
var list = new BogusCustomList { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
engine.Execute("list[1] = list[2]");
Assert.AreEqual(DayOfWeek.Wednesday, engine.Evaluate("list[1]"));
}
[TestMethod, TestCategory("HostList")]
public void HostList_CustomGeneric()
{
var list = new BogusCustomList { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
engine.Execute("list[1] = list[2]");
Assert.AreEqual(DayOfWeek.Wednesday, engine.Evaluate("list[1]"));
}
[TestMethod, TestCategory("HostList")]
public void HostList_TypeRestriction()
{
var list = new List { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableListIndexTypeRestriction = true;
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableListIndexTypeRestriction = false;
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableTypeRestriction = true;
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list.Item(2)"));
}
[TestMethod, TestCategory("ReadOnlyHostList")]
public void ReadOnlyHostList_List()
{
IReadOnlyList list = new List { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday };
engine.AddRestrictedHostObject("list", list);
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
TestUtil.AssertException(() => engine.Execute("list[1] = list[2]"));
}
[TestMethod, TestCategory("ReadOnlyHostList")]
public void ReadOnlyHostList_Custom()
{
var list = new BogusReadOnlyCustomList(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday);
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual(DayOfWeek.Tuesday, engine.Evaluate("list[1]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
TestUtil.AssertException(() => engine.Execute("list[1] = list[2]"));
}
[TestMethod, TestCategory("ReadOnlyHostList")]
public void ReadOnlyHostList_TypeRestriction()
{
var list = new BogusReadOnlyCustomList(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday);
engine.Script.list = list;
Assert.AreEqual(3, engine.Evaluate("list.Count"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableListIndexTypeRestriction = true;
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableListIndexTypeRestriction = false;
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:IConvertible]", engine.ExecuteCommand("list.Item(2)"));
engine.DisableTypeRestriction = true;
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list[2]"));
Assert.AreEqual("[HostObject:DayOfWeek]", engine.ExecuteCommand("list.Item(2)"));
}
// ReSharper restore InconsistentNaming
#endregion
#region miscellaneous
public interface IBogus
{
}
public interface ICustomList : IList
{
}
public interface ICustomList : IList
{
}
public interface IReadOnlyCustomList : IReadOnlyList
{
}
public interface IBogusCustomList : IBogus, ICustomList
{
}
public interface IBogusCustomList : IBogus, ICustomList
{
}
public interface IBogusReadOnlyCustomList : IBogus, IReadOnlyCustomList
{
}
public class BogusCustomListBase : IBogusCustomList
{
private readonly IList list = new ArrayList();
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
public void CopyTo(Array array, int index)
{
list.CopyTo(array, index);
}
public int Count => list.Count;
public object SyncRoot => list.SyncRoot;
public bool IsSynchronized => list.IsSynchronized;
public int Add(object value)
{
return list.Add(value);
}
public bool Contains(object value)
{
return list.Contains(value);
}
public void Clear()
{
list.Clear();
}
public int IndexOf(object value)
{
return list.IndexOf(value);
}
public void Insert(int index, object value)
{
list.Insert(index, value);
}
public void Remove(object value)
{
list.Remove(value);
}
public void RemoveAt(int index)
{
list.RemoveAt(index);
}
public object this[int index]
{
get => list[index];
set => list[index] = value;
}
public bool IsReadOnly => list.IsReadOnly;
public bool IsFixedSize => list.IsFixedSize;
}
public class BogusCustomListBase : IBogusCustomList
{
private readonly IList list = new List();
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
list.Add(item);
}
public void Clear()
{
list.Clear();
}
public bool Contains(T item)
{
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
return list.Remove(item);
}
public int Count => list.Count;
public bool IsReadOnly => list.IsReadOnly;
public int IndexOf(T item)
{
return list.IndexOf(item);
}
public void Insert(int index, T item)
{
list.Insert(index, item);
}
public void RemoveAt(int index)
{
list.RemoveAt(index);
}
public T this[int index]
{
get => list[index];
set => list[index] = value;
}
}
public class BogusReadOnlyCustomListBase : IBogusReadOnlyCustomList
{
private readonly IReadOnlyList list;
public BogusReadOnlyCustomListBase(params T[] items)
{
list = new List(items);
}
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count => list.Count;
public T this[int index] => list[index];
}
public class BogusCustomList : BogusCustomListBase
{
}
public class BogusCustomList : BogusCustomListBase
{
}
public class BogusReadOnlyCustomList : BogusReadOnlyCustomListBase
{
public BogusReadOnlyCustomList(params T[] items)
: base(items)
{
}
}
#endregion
}
}