OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 // SharedOptions=--package-root=sdk/lib/_internal/ | |
6 | |
7 // Test that cursor positions are correctly updated after adding new content. | |
8 | |
9 library trydart.cursor_position_test; | |
10 | |
11 import 'dart:html'; | |
12 import 'dart:async'; | |
13 | |
14 import '../../site/try/src/interaction_manager.dart' show | |
15 InteractionManager; | |
16 | |
17 import '../../site/try/src/ui.dart' show | |
18 hackDiv, | |
19 mainEditorPane, | |
20 observer; | |
21 | |
22 import '../../site/try/src/user_option.dart' show | |
23 UserOption; | |
24 | |
25 import '../../pkg/expect/lib/expect.dart'; | |
26 | |
27 import '../../pkg/async_helper/lib/async_helper.dart'; | |
28 | |
29 void main() { | |
30 InteractionManager interaction = mockTryDartInteraction(); | |
31 | |
32 List<TestCase> tests = <TestCase>[ | |
33 | |
34 new TestCase('Test adding two lines programmatically.', () { | |
35 clearEditorPaneWithoutNotifications(); | |
36 mainEditorPane.appendText('\n\n'); | |
37 Text text = mainEditorPane.firstChild; | |
38 window.getSelection().collapse(text, 1); | |
39 checkSelectionIsCollapsed(text, 1); | |
40 }, checkAtBeginningOfSecondLine), | |
41 | |
42 new TestCase('Test adding a new line with mock key event.', () { | |
43 clearEditorPaneWithoutNotifications(); | |
44 checkSelectionIsCollapsed(mainEditorPane, 0); | |
45 simulateEnterKeyDown(interaction); | |
46 }, checkAtBeginningOfSecondLine), | |
47 | |
48 ]; | |
49 | |
50 runTests(tests.iterator, completerForAsyncTest()); | |
51 } | |
52 | |
53 void simulateEnterKeyDown(Interaction interaction) { | |
54 interaction.onKeyUp( | |
55 new MockKeyboardEvent('keydown', keyCode: KeyCode.ENTER)); | |
56 } | |
57 | |
58 void clearEditorPaneWithoutNotifications() { | |
59 mainEditorPane.nodes.clear(); | |
60 observer.takeRecords(); | |
61 } | |
62 | |
63 void checkSelectionIsCollapsed(Node node, int offset) { | |
64 var selection = window.getSelection(); | |
65 Expect.isTrue(selection.isCollapsed, 'selection.isCollapsed'); | |
66 Expect.equals(node, selection.anchorNode, 'selection.anchorNode'); | |
67 Expect.equals(offset, selection.anchorOffset, 'selection.anchorOffset'); | |
68 } | |
69 | |
70 void checkLineCount(int expectedLineCount) { | |
71 Expect.equals( | |
72 expectedLineCount, mainEditorPane.nodes.length, | |
73 'mainEditorPane.nodes.length'); | |
74 } | |
75 | |
76 void checkAtBeginningOfSecondLine() { | |
77 checkLineCount(2); | |
78 checkSelectionIsCollapsed(mainEditorPane.nodes[1].firstChild, 0); | |
79 } | |
80 | |
81 runTests(Iterator<TestCase> iterator, Completer completer) { | |
82 if (iterator.moveNext()) { | |
83 TestCase test = iterator.current; | |
84 new Future(() { | |
85 print('${test.description}\nSetup.'); | |
86 test.setup(); | |
87 new Future(() { | |
88 test.validate(); | |
89 print('${test.description}\nDone.'); | |
90 runTests(iterator, completer); | |
91 }); | |
92 }); | |
93 } else { | |
94 completer.complete(null); | |
95 } | |
96 } | |
97 | |
98 Completer completerForAsyncTest() { | |
99 Completer completer = new Completer(); | |
100 asyncTest(() => completer.future.then((_) { | |
101 // Clear the DOM to work around a bug in test.dart. | |
102 document.body.nodes.clear(); | |
103 })); | |
104 return completer; | |
105 } | |
106 | |
107 InteractionManager mockTryDartInteraction() { | |
108 UserOption.storage = {}; | |
109 | |
110 InteractionManager interaction = new InteractionManager(); | |
111 | |
112 hackDiv = new DivElement(); | |
113 mainEditorPane = new DivElement() | |
114 ..style.whiteSpace = 'pre' | |
115 ..contentEditable = 'true'; | |
116 | |
117 observer = new MutationObserver(interaction.onMutation); | |
118 observer.observe( | |
119 mainEditorPane, childList: true, characterData: true, subtree: true); | |
120 | |
121 document.body.nodes.addAll([mainEditorPane, hackDiv]); | |
122 | |
123 return interaction; | |
124 } | |
125 | |
126 class MockKeyboardEvent extends KeyEvent { | |
127 final int keyCode; | |
128 | |
129 MockKeyboardEvent(String type, {int keyCode}) | |
130 : this.keyCode = keyCode, | |
131 super.wrap(new KeyEvent(type, keyCode: keyCode)); | |
132 | |
133 bool getModifierState(String keyArgument) => false; | |
134 } | |
135 | |
136 typedef void VoidFunction(); | |
kasperl
2014/05/06 04:51:06
Is this really so much better than just using Func
ahe
2014/05/06 12:54:02
I don't think Function serves much purpose, and I
| |
137 | |
138 class TestCase { | |
139 final String description; | |
140 final VoidFunction setup; | |
141 final VoidFunction validate; | |
142 | |
143 TestCase(this.description, this.setup, this.validate); | |
144 } | |
OLD | NEW |