@@ -64,10 +64,8 @@ private void setComponentText(String text, int caretOffset) throws BadLocationEx
6464 when (mockComponent .getCaretPosition ()).thenReturn (caretOffset );
6565 }
6666
67- // --- Core Test Case: 1. Tag Completion ---
68-
6967 @ Test
70- void testCompletion_StartTag_SuggestsAllUIElements () throws BadLocationException {
68+ void testAllUiElements () throws BadLocationException {
7169 // Simulate typing '<' to trigger tag completion (caret at offset 1)
7270 setComponentText ("<" , 1 );
7371
@@ -96,10 +94,8 @@ void testCompletion_StartTag_SuggestsAllUIElements() throws BadLocationException
9694 }
9795 }
9896
99- // --- Core Test Case: 2. Attribute Completion for <button> ---
100-
10197 @ Test
102- void testCompletion_InsideButtonTag_SuggestsCoreAttributes () throws BadLocationException {
98+ void testButtonAttributes () throws BadLocationException {
10399 var text = "<button " ;
104100 var caretOffset = text .length (); // Caret is right after the space in "<button "
105101
@@ -114,7 +110,7 @@ void testCompletion_InsideButtonTag_SuggestsCoreAttributes() throws BadLocationE
114110 .collect (Collectors .toSet ());
115111
116112 assertTrue (attributeNames .contains ("name" ), "Should suggest the mandatory 'name' attribute." );
117- // assertTrue(attributeNames.contains("text"), "Should suggest the mandatory 'text' attribute.");
113+ assertTrue (attributeNames .contains ("text" ), "Should suggest the mandatory 'text' attribute." );
118114
119115 // Verify other essential attributes are present (from the DTD)
120116 assertTrue (attributeNames .contains ("background" ), "Should also suggest the 'background' attribute." );
@@ -127,8 +123,8 @@ void testCompletion_InsideButtonTag_SuggestsCoreAttributes() throws BadLocationE
127123 }
128124 }
129125
130- @ Test
131- void testCompletion_InsideTextAreaTag_SuggestsCoreAttributes () throws BadLocationException {
126+ @ Test
127+ void testTextAreaAtttributes () throws BadLocationException {
132128 var text = "<text-area " ;
133129 var caretOffset = text .length ();
134130
@@ -143,7 +139,7 @@ void testCompletion_InsideTextAreaTag_SuggestsCoreAttributes() throws BadLocatio
143139 .collect (Collectors .toSet ());
144140
145141 assertTrue (attributeNames .contains ("name" ), "Should suggest the mandatory 'name' attribute." );
146- // assertTrue(attributeNames.contains("text"), "Should suggest the mandatory 'text' attribute.");
142+ assertTrue (attributeNames .contains ("text" ), "Should suggest the mandatory 'text' attribute." );
147143
148144 // specific to text area
149145 assertTrue (attributeNames .contains ("lineWrap" ), "Should suggest the mandatory 'lineWrap' attribute." );
@@ -158,4 +154,76 @@ void testCompletion_InsideTextAreaTag_SuggestsCoreAttributes() throws BadLocatio
158154 assertTrue (current .compareTo (next ) <= 0 , "Suggestions should be sorted alphabetically." );
159155 }
160156 }
157+
158+ @ Test
159+ void testAttributeNarrowing () throws BadLocationException {
160+ // Start with just '<button ' (caret after space)
161+ var base = "<button " ;
162+ setComponentText (base , base .length ());
163+
164+ var suggestionsAll = provider .getCompletions (mockComponent );
165+ assertFalse (suggestionsAll .isEmpty (), "Should suggest attributes when inside a tag." );
166+ assertTrue (suggestionsAll .stream ().anyMatch (c -> c .getInputText ().equals ("name" )),
167+ "Suggestions should include 'name' initially." );
168+
169+ // Type one character: 'n'
170+ var oneChar = "<button n" ;
171+ setComponentText (oneChar , oneChar .length ());
172+
173+ var suggestionsN = provider .getCompletions (mockComponent );
174+ assertFalse (suggestionsN .isEmpty (), "Should still suggest attributes after typing 'n'." );
175+ for (var c : suggestionsN ) {
176+ assertTrue (c .getInputText ().toLowerCase ().startsWith ("n" ),
177+ "All suggestions after typing 'n' should start with 'n'." );
178+ }
179+
180+ // Type a second character: 'a' -> prefix 'na'
181+ var twoChar = "<button na" ;
182+ setComponentText (twoChar , twoChar .length ());
183+
184+ var suggestionsNA = provider .getCompletions (mockComponent );
185+ assertFalse (suggestionsNA .isEmpty (), "Should still suggest attributes after typing 'na'." );
186+ for (var c : suggestionsNA ) {
187+ assertTrue (c .getInputText ().toLowerCase ().startsWith ("na" ),
188+ "All suggestions after typing 'na' should start with 'na'." );
189+ }
190+ assertTrue (suggestionsNA .stream ().anyMatch (c -> c .getInputText ().equals ("name" )),
191+ "Suggestions after 'na' should include the 'name' attribute." );
192+ }
193+
194+ @ Test
195+ void testTagNarrowing () throws BadLocationException {
196+ // Start with just '<' (caret after '<')
197+ var base = "<" ;
198+ setComponentText (base , base .length ());
199+
200+ var suggestionsAll = provider .getCompletions (mockComponent );
201+ assertFalse (suggestionsAll .isEmpty (), "Should suggest tags when starting a tag." );
202+ assertTrue (suggestionsAll .stream ().anyMatch (c -> c .getInputText ().equals ("button" )),
203+ "Suggestions should include 'button' initially." );
204+
205+ // Type one character: 'b'
206+ var oneChar = "<b" ;
207+ setComponentText (oneChar , oneChar .length ());
208+
209+ var suggestionsB = provider .getCompletions (mockComponent );
210+ assertFalse (suggestionsB .isEmpty (), "Should still suggest tags after typing 'b'." );
211+ for (var c : suggestionsB ) {
212+ assertTrue (c .getInputText ().toLowerCase ().startsWith ("b" ),
213+ "All tag suggestions after typing 'b' should start with 'b'." );
214+ }
215+
216+ // Type a second character: 'u' -> prefix 'bu'
217+ var twoChar = "<bu" ;
218+ setComponentText (twoChar , twoChar .length ());
219+
220+ var suggestionsBU = provider .getCompletions (mockComponent );
221+ assertFalse (suggestionsBU .isEmpty (), "Should still suggest tags after typing 'bu'." );
222+ for (var c : suggestionsBU ) {
223+ assertTrue (c .getInputText ().toLowerCase ().startsWith ("bu" ),
224+ "All tag suggestions after typing 'bu' should start with 'bu'." );
225+ }
226+ assertTrue (suggestionsBU .stream ().anyMatch (c -> c .getInputText ().equals ("button" )),
227+ "Suggestions after 'bu' should include the 'button' tag." );
228+ }
161229}
0 commit comments