public void SuggestionMultiCodePointToSingleCodePoint() { //Arrange var mockKeyStateService = new Mock<IKeyStateService>(); mockKeyStateService.Setup(x => x.KeyDownStates).Returns(new NotifyingConcurrentDictionary<KeyValue, KeyDownStates>()); var mockSuggestionService = new Mock<ISuggestionStateService>(); mockSuggestionService.Setup(x => x.Suggestions).Returns(new List<string> { singleCodePointString, multiCodePointString }); var mockPublishService = new Mock<IPublishService>(); var mockDictionaryService = new Mock<IDictionaryService>(); var keyboardOutputService = new KeyboardOutputService(mockKeyStateService.Object, mockSuggestionService.Object, mockPublishService.Object, mockDictionaryService.Object, x => { }); //Act keyboardOutputService.ProcessSingleKeyText("1"); keyboardOutputService.ProcessFunctionKey(FunctionKeys.Suggestion2); keyboardOutputService.ProcessFunctionKey(FunctionKeys.Suggestion1); //Assert Assert.AreEqual(singleCodePointString, keyboardOutputService.Text); }
private void App_OnStartup(object sender, StartupEventArgs e) { try { Log.Info("Boot strapping the services and UI."); //Apply theme applyTheme(); //Define MainViewModel before services so I can setup a delegate to call into the MainViewModel //This is to work around the fact that the MainViewModel is created after the services. MainViewModel mainViewModel = null; Action<KeyValue> fireKeySelectionEvent = kv => { if (mainViewModel != null) //Access to modified closure is a good thing here, for once! { mainViewModel.FireKeySelectionEvent(kv); } }; //Create services var errorNotifyingServices = new List<INotifyErrors>(); IAudioService audioService = new AudioService(); IDictionaryService dictionaryService = new DictionaryService(Settings.Default.AutoCompleteMethod); IPublishService publishService = new PublishService(); ISuggestionStateService suggestionService = new SuggestionStateService(); ICalibrationService calibrationService = CreateCalibrationService(); ICapturingStateManager capturingStateManager = new CapturingStateManager(audioService); ILastMouseActionStateManager lastMouseActionStateManager = new LastMouseActionStateManager(); IKeyStateService keyStateService = new KeyStateService(suggestionService, capturingStateManager, lastMouseActionStateManager, calibrationService, fireKeySelectionEvent); IInputService inputService = CreateInputService(keyStateService, dictionaryService, audioService, calibrationService, capturingStateManager, errorNotifyingServices); IKeyboardOutputService keyboardOutputService = new KeyboardOutputService(keyStateService, suggestionService, publishService, dictionaryService, fireKeySelectionEvent); IMouseOutputService mouseOutputService = new MouseOutputService(publishService); errorNotifyingServices.Add(audioService); errorNotifyingServices.Add(dictionaryService); errorNotifyingServices.Add(publishService); errorNotifyingServices.Add(inputService); //Release keys on application exit ReleaseKeysOnApplicationExit(keyStateService, publishService); //Compose UI var mainWindow = new MainWindow(audioService, dictionaryService, inputService, keyStateService); IWindowManipulationService mainWindowManipulationService = new WindowManipulationService( mainWindow, () => Settings.Default.MainWindowOpacity, () => Settings.Default.MainWindowState, () => Settings.Default.MainWindowPreviousState, () => Settings.Default.MainWindowFloatingSizeAndPosition, () => Settings.Default.MainWindowDockPosition, () => Settings.Default.MainWindowDockSize, () => Settings.Default.MainWindowFullDockThicknessAsPercentageOfScreen, () => Settings.Default.MainWindowCollapsedDockThicknessAsPercentageOfFullDockThickness, () => Settings.Default.MainWindowMinimisedPosition, o => Settings.Default.MainWindowOpacity = o, state => Settings.Default.MainWindowState = state, state => Settings.Default.MainWindowPreviousState = state, rect => Settings.Default.MainWindowFloatingSizeAndPosition = rect, pos => Settings.Default.MainWindowDockPosition = pos, size => Settings.Default.MainWindowDockSize = size, t => Settings.Default.MainWindowFullDockThicknessAsPercentageOfScreen = t, t => Settings.Default.MainWindowCollapsedDockThicknessAsPercentageOfFullDockThickness = t); errorNotifyingServices.Add(mainWindowManipulationService); mainWindow.WindowManipulationService = mainWindowManipulationService; mainViewModel = new MainViewModel( audioService, calibrationService, dictionaryService, keyStateService, suggestionService, capturingStateManager, lastMouseActionStateManager, inputService, keyboardOutputService, mouseOutputService, mainWindowManipulationService, errorNotifyingServices); mainWindow.MainView.DataContext = mainViewModel; //Setup actions to take once main view is loaded (i.e. the view is ready, so hook up the services which kicks everything off) Action postMainViewLoaded = mainViewModel.AttachServiceEventHandlers; if(mainWindow.MainView.IsLoaded) { postMainViewLoaded(); } else { RoutedEventHandler loadedHandler = null; loadedHandler = (s, a) => { postMainViewLoaded(); mainWindow.MainView.Loaded -= loadedHandler; //Ensure this handler only triggers once }; mainWindow.MainView.Loaded += loadedHandler; } //Show the main window mainWindow.Show(); //Display splash screen and check for updates (and display message) after the window has been sized and positioned for the 1st time EventHandler sizeAndPositionInitialised = null; sizeAndPositionInitialised = async (_, __) => { mainWindowManipulationService.SizeAndPositionInitialised -= sizeAndPositionInitialised; //Ensure this handler only triggers once await ShowSplashScreen(inputService, audioService, mainViewModel); inputService.RequestResume(); //Start the input service await CheckForUpdates(inputService, audioService, mainViewModel); }; if (mainWindowManipulationService.SizeAndPositionIsInitialised) { sizeAndPositionInitialised(null, null); } else { mainWindowManipulationService.SizeAndPositionInitialised += sizeAndPositionInitialised; } } catch (Exception ex) { Log.Error("Error starting up application", ex); throw; } }