diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..701fe1f --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs +/OnScreenKeyboardScripter/.vs/OnScreenKeyboardScripter/v15 +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/bin/Debug +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/obj +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/bin/Debug +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/obj +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/bin/Debug +/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/obj +/OnScreenKeyboardScripter/packages diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/App.config b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/App.config new file mode 100644 index 0000000..731f6de --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/OnScreenKeyboardScripter.Demo.csproj b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/OnScreenKeyboardScripter.Demo.csproj new file mode 100644 index 0000000..56c4e78 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/OnScreenKeyboardScripter.Demo.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {DBA825CE-715D-4F3A-BD08-BDD8A3490CAA} + Exe + OnScreenKeyboardScripter.Demo + OnScreenKeyboardScripter.Demo + v4.6.1 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + Always + + + + + {67c25f06-53a5-4536-8fe2-c8c92795b95a} + OnScreenKeyboardScripter.Lib + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Program.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Program.cs new file mode 100644 index 0000000..2cd5b6c --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Program.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using lib = OnScreenKeyboardScripter.Lib; + +namespace OnScreenKeyboardScripter.Demo +{ + class Program + { + static void Main(string[] args) + { + if (System.IO.File.Exists("sample.txt")) + { + lib.IKeyboard keyboard = lib.Factory.GetKeyboard(); + lib.IScripter scripter = lib.Factory.GetScripter(); + + System.IO.File.ReadAllLines("sample.txt") + .ToList() + .ForEach(line => + { + string output = string.Empty; + try + { + output = scripter.GetPath(keyboard, line); + } + catch (Exception e) + { + output = string.Format("ERROR - unable to translate input:\n\t'{0}'\n{1}", line, e.Message); + } + Console.WriteLine(output); + }); + } + + Console.Write("Press key to exit"); + Console.ReadKey(); + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Properties/AssemblyInfo.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..809eefd --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using 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("OnScreenKeyboardScripter.Demo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OnScreenKeyboardScripter.Demo")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("dba825ce-715d-4f3a-bd08-bdd8a3490caa")] + +// 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")] diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/sample.txt b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/sample.txt new file mode 100644 index 0000000..8d1ca5a --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Demo/sample.txt @@ -0,0 +1,2 @@ +IT Crowd +This has s*me b@d input diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Factory.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Factory.cs new file mode 100644 index 0000000..909d389 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Factory.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OnScreenKeyboardScripter.Lib +{ + /// + /// Single source for keyboards and scripters + /// + public sealed class Factory + { + static StructureMap.IContainer container = null; + + /// + /// Gets the currently-registered class. + /// + /// + static public IKeyboard GetKeyboard() { return container.GetInstance(); } + /// + /// Gets the currently-registered class. + /// + /// + static public IScripter GetScripter() { return container.GetInstance(); } + + /// + /// Initializes the class. + /// + static Factory() + { + container = new StructureMap.Container(cfg => + { + cfg.For().Use(); + cfg.For().Use(); + }); + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IKeyboard.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IKeyboard.cs new file mode 100644 index 0000000..6bd1bce --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IKeyboard.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OnScreenKeyboardScripter.Lib +{ + public enum MoveCursor + { + Up, + Down, + Left, + Right + } + + public interface IKeyboard + { + List GetCursorPath(char fromKey, char toKey); + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IScripter.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IScripter.cs new file mode 100644 index 0000000..9f1653b --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/IScripter.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OnScreenKeyboardScripter.Lib +{ + public interface IScripter + { + string GetPath(IKeyboard keyboard, string input); + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Keyboard.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Keyboard.cs new file mode 100644 index 0000000..220f016 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Keyboard.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OnScreenKeyboardScripter.Lib +{ + /// + /// Represents the on-screen keyboard layout and cursor-movement behavior. + /// + /// + public class Keyboard : IKeyboard + { + public bool CursorWrapsHorizontally { get; set; } = true; + public bool CursorWrapsVertically { get; set; } = true; + + const int rowWidth = 6; + const int rows = 6; + + const string layout = + "ABCDEF" + + "GHIJKL" + + "MNOPQR" + + "STUVWX" + + "YZ0123" + + "456789"; + + /// + /// Gets the cursor path from current key-location on keyboard to next key-location + /// + /// Starting key (cursor position) on keyboard + /// Destination key (cursor position) on keyboard + /// + /// Unrecognized keyboard key + public List GetCursorPath(char fromKey, char toKey) + { + int idxFrom = layout.IndexOf(fromKey), + idxTo = layout.IndexOf(toKey); + + if (idxFrom < 0 || idxTo < 0) + { + throw new NotImplementedException("Unrecognized keyboard key"); + } + + List cursorMovements = new List(); + + int fromY = (int)Math.Floor((double)idxFrom / (double)rowWidth), + fromX = idxFrom - (fromY * rowWidth), + toY = (int)Math.Floor((double)idxTo / (double)rowWidth), + toX = idxTo - (toY * rowWidth); + + while (fromKey != toKey) + { + // go up instead of down if wrapping? + var upOverDown = (CursorWrapsVertically && ((fromY + rows - toY) < toY - fromY)); + // go down instead of up if wrapping? + var downOverUp = (CursorWrapsVertically && (toY + rows - fromY) < fromY - toY); + // go left instead of right if wrapping + var leftOverRight = (CursorWrapsHorizontally && ((fromX + rowWidth - toX) < toX - fromX)); + // go right instead of left if wrapping + var rightOverLeft = (CursorWrapsHorizontally && ((toX + rowWidth - fromX) < fromX - toX)); + + if ((toY < fromY && !downOverUp) || upOverDown) + { + cursorMovements.Add(MoveCursor.Up); + fromY = (fromY + rows - 1) % rows; + } + // go down? + else if (fromY < toY || downOverUp) + { + cursorMovements.Add(MoveCursor.Down); + fromY = (fromY + 1) % rows; + } + // go left? toX < fromX + else if ((fromX > toX && !rightOverLeft) || leftOverRight) + { + cursorMovements.Add(MoveCursor.Left); + fromX = (fromX + rowWidth - 1) % rowWidth; + } + // go right? toX > fromX + else if ((toX > fromX) || rightOverLeft) + { + cursorMovements.Add(MoveCursor.Right); + fromX = (fromX + 1) % rowWidth; + } + + fromKey = layout[(fromY * rowWidth) + fromX]; + } + + return cursorMovements; + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/OnScreenKeyboardScripter.Lib.csproj b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/OnScreenKeyboardScripter.Lib.csproj new file mode 100644 index 0000000..f52e045 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/OnScreenKeyboardScripter.Lib.csproj @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {67C25F06-53A5-4536-8FE2-C8C92795B95A} + Library + Properties + OnScreenKeyboardScripter.Lib + OnScreenKeyboardScripter.Lib + v4.6.1 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\StructureMap.4.6.1\lib\net45\StructureMap.dll + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Properties/AssemblyInfo.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b9bd70e --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using 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("OnScreenKeyboardScripter.Lib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OnScreenKeyboardScripter.Lib")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("67c25f06-53a5-4536-8fe2-c8c92795b95a")] + +// 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")] diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Scripter.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Scripter.cs new file mode 100644 index 0000000..6eb6d64 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/Scripter.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OnScreenKeyboardScripter.Lib +{ + /// + /// Translates keyboard cursor movements and DVR actions into comma-separated "action" sequence of characters + /// + /// + public class Scripter : IScripter + { + /// + /// Gets the comma-separated "action" sequence of characters from + /// + /// The on-screen keyboard representation + /// The text input to translate + /// + /// + public string GetPath(IKeyboard keyboard, string input) + { + List path = new List(); + + if (keyboard == null) + { + throw new ArgumentNullException(); + } + + if (!string.IsNullOrEmpty(input)) + { + char lastkey = 'A'; + foreach(var nextkey in input.ToUpper()) + { + if (nextkey == ' ') + { + path.Add('S'); + } + else + { + var cursorPath = keyboard.GetCursorPath(lastkey, nextkey) + .Select(mc => Enum.GetName(typeof(MoveCursor), mc)[0]) + .ToArray(); + if (cursorPath.Length > 0) + { + path.AddRange(cursorPath); + path.Add('#'); + } + lastkey = nextkey; + } + } + } + + return string.Join(",", path); + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/packages.config b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/packages.config new file mode 100644 index 0000000..58ae58e --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Lib/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/KeyboardTests.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/KeyboardTests.cs new file mode 100644 index 0000000..a1b621b --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/KeyboardTests.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace OnScreenKeyboardScripter.Test +{ + [TestClass] + public class KeyboardTests + { + [TestMethod] + public void GetCursorPath_fromKeyNotRecognized_Fail_NotImplementedException() + { + Assert.ThrowsException( + () => + { + new OnScreenKeyboardScripter.Lib.Keyboard().GetCursorPath('\0', 'A'); + }); + } + [TestMethod] + public void GetCursorPath_toKeyNotRecognized_Fail_NotImplementedException() + { + Assert.ThrowsException( + () => + { + new OnScreenKeyboardScripter.Lib.Keyboard().GetCursorPath('A', '\0'); + }); + } + [TestMethod] + public void GetCursorPath_fromGtoA_Success_Up() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('G', 'A'); + + var expected = new List() + { Lib.MoveCursor.Up }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_fromAto4_Success_Up() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('A', '4'); + + var expected = new List() + { Lib.MoveCursor.Up }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_from5toB_Success_Down() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('5', 'B'); + + var expected = new List() + { Lib.MoveCursor.Down }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_fromBtoH_Success_Down() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('B', 'H'); + + var expected = new List() + { Lib.MoveCursor.Down }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + + [TestMethod] + public void GetCursorPath_fromGtoL_Success_Left() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('G', 'L'); + + var expected = new List() + { Lib.MoveCursor.Left }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_fromLtoK_Success_Left() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('L', 'K'); + + var expected = new List() + { Lib.MoveCursor.Left }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_fromRtoM_Success_Right() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('R', 'M'); + + var expected = new List() + { Lib.MoveCursor.Right }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + [TestMethod] + public void GetCursorPath_fromMtoN_Success_Right() + { + var path = new OnScreenKeyboardScripter.Lib.Keyboard() + .GetCursorPath('M', 'N'); + + var expected = new List() + { Lib.MoveCursor.Right }; + Assert.IsTrue(expected.SequenceEqual(path)); + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/OnScreenKeyboardScripter.Test.csproj b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/OnScreenKeyboardScripter.Test.csproj new file mode 100644 index 0000000..3411b5e --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/OnScreenKeyboardScripter.Test.csproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + {35A77BDB-46AE-40CC-A750-CB57157DA6B3} + Library + Properties + OnScreenKeyboardScripter.Test + OnScreenKeyboardScripter.Test + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll + + + ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\packages\Moq.4.8.2\lib\net45\Moq.dll + + + + + + ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll + + + + + + + + + + + + + {67c25f06-53a5-4536-8fe2-c8c92795b95a} + OnScreenKeyboardScripter.Lib + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/Properties/AssemblyInfo.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1f4a31c --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("OnScreenKeyboardScripter.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OnScreenKeyboardScripter.Test")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("35a77bdb-46ae-40cc-a750-cb57157da6b3")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/ScripterTests.cs b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/ScripterTests.cs new file mode 100644 index 0000000..5dba490 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/ScripterTests.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace OnScreenKeyboardScripter.Test +{ + [TestClass] + public class ScripterTests + { + [TestMethod] + public void GetPath_keyboardParamNull_Fail_ArgumentNullException() + { + Assert.ThrowsException( + () => + { + new OnScreenKeyboardScripter.Lib.Scripter().GetPath(null, "splat"); + }); + } + + [TestMethod] + public void GetPath_inputNullOrEmpty_Success_EmptyString() + { + var moqKeyboard = new Moq.Mock(); + var result = new OnScreenKeyboardScripter.Lib.Scripter().GetPath(moqKeyboard.Object, ""); + Assert.AreEqual(string.Empty, result); + } + + [TestMethod] + public void GetPath_keyboardGetCursorPathException_Fail_AllowExceptionToBubbleThrough() + { + var moqKeyboard = new Moq.Mock(); + + // pick and exception that won't be thrown from library + moqKeyboard.Setup(fn => fn.GetCursorPath(Moq.It.IsAny(), Moq.It.IsAny())) + .Throws(new DuplicateWaitObjectException("splat")); + + // make sure we get THAT exception + Assert.ThrowsException( + () => + { + new OnScreenKeyboardScripter.Lib.Scripter().GetPath(moqKeyboard.Object, "splat"); + }); + } + } +} diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/packages.config b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/packages.config new file mode 100644 index 0000000..de82217 --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.Test/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/OnScreenKeyboardScripter/OnScreenKeyboardScripter.sln b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.sln new file mode 100644 index 0000000..b788d0b --- /dev/null +++ b/OnScreenKeyboardScripter/OnScreenKeyboardScripter.sln @@ -0,0 +1,42 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2002 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnScreenKeyboardScripter.Lib", "OnScreenKeyboardScripter.Lib\OnScreenKeyboardScripter.Lib.csproj", "{67C25F06-53A5-4536-8FE2-C8C92795B95A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnScreenKeyboardScripter.Demo", "OnScreenKeyboardScripter.Demo\OnScreenKeyboardScripter.Demo.csproj", "{DBA825CE-715D-4F3A-BD08-BDD8A3490CAA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnScreenKeyboardScripter.Test", "OnScreenKeyboardScripter.Test\OnScreenKeyboardScripter.Test.csproj", "{35A77BDB-46AE-40CC-A750-CB57157DA6B3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2F6C9256-F13A-43B8-AB14-726587EDFE24}" + ProjectSection(SolutionItems) = preProject + ..\README.md = ..\README.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {67C25F06-53A5-4536-8FE2-C8C92795B95A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67C25F06-53A5-4536-8FE2-C8C92795B95A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67C25F06-53A5-4536-8FE2-C8C92795B95A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67C25F06-53A5-4536-8FE2-C8C92795B95A}.Release|Any CPU.Build.0 = Release|Any CPU + {DBA825CE-715D-4F3A-BD08-BDD8A3490CAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBA825CE-715D-4F3A-BD08-BDD8A3490CAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBA825CE-715D-4F3A-BD08-BDD8A3490CAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBA825CE-715D-4F3A-BD08-BDD8A3490CAA}.Release|Any CPU.Build.0 = Release|Any CPU + {35A77BDB-46AE-40CC-A750-CB57157DA6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35A77BDB-46AE-40CC-A750-CB57157DA6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35A77BDB-46AE-40CC-A750-CB57157DA6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35A77BDB-46AE-40CC-A750-CB57157DA6B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B8391A64-9B34-4907-ADFD-71CBE4DBEC57} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md index 2c16e5c..8854f06 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,26 @@ On Screen Keyboard ================== +The Solution +------------ +There are three source folders to the solution: + +##### OnScreenKeyboardScripter.Demo + +Simple console application built off OnScreenKeyboardScripter.Lib that reads in a text file and writes out screen keyboard action "path" per line. + +##### OnScreenKeyboardScripter.Lib + +The library for transforming an input into keyboard actions. Keyboard and scripting are decoupled so other keyboard and scripting algorithms can be used. + +NOTE: exceptions are not handled here - they are allowed to bubble out of OnScreenKeyboardScripter.Lib. An example of handling exceptions from there can be seen in the OnScreenKeyboardScripter.Demo project. + +##### OnScreenKeyboardScripter.Test + +Unit tests for OnScreenKeyboardScripter.Lib. + + + The Problem ----------- On screen keyboards are the bane of DVR users. To help alleviate the pain, one local company is asking you to implement part of a voice to text search for their DVR by developing an algorithm to script the on screen keyboard.