Merge lp:~oppifjellet/cable/message-history into lp:cable
- message-history
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 128 | ||||
Proposed branch: | lp:~oppifjellet/cable/message-history | ||||
Merge into: | lp:cable | ||||
Diff against target: |
405 lines (+258/-10) 7 files modified
CMakeLists.txt (+22/-1) src/Utils/RRStringList.vala (+77/-0) src/Widgets/Room.vala (+31/-9) tests/TestCase.vala (+58/-0) tests/TestExample.vala (+22/-0) tests/TestMain.vala (+7/-0) tests/TestMessageHistory.vala (+41/-0) |
||||
To merge this branch: | bzr merge lp:~oppifjellet/cable/message-history | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eduard Gotwig | Pending | ||
Review via email: mp+182453@code.launchpad.net |
Commit message
Implemented message history
Description of the change
This branch fixes this bug https:/
Every channel now keeps an history of sent messages and commands that are navigable using arrow keys ( Up&Down )
For performance reasons the history capacity for each channel is 25 items. Old items are replaced with round robin logic.
Eduard Gotwig (gotwig) wrote : | # |
- 126. By Daniele "OpenNingia" Simonetti
-
improved history navigation behavior
Daniele "OpenNingia" Simonetti (oppifjellet) wrote : | # |
Revision 126 should fix the annoying behavior.
You're welcome, thank you for Cable.
982c80311320c1b (alexander-wilms) wrote : | # |
It doesn't work as expected for me.
When I type
1 <Enter>
2 <Enter>
3 <Enter>
and then browse through history with the <up> key, the following messages appear in this order: 2, 1. When I then press the <down> key, those messages appear: 1, 2, 3
If I _instead_ (not after browing them with <up> and <down>) press the <down> key, 3 appears in the text box.
Daniele "OpenNingia" Simonetti (oppifjellet) wrote : | # |
I admit it's a strange behavior. If it were you what's the best behavior?
Il giorno 30/ago/2013 00:57, "Alexander Wilms" <email address hidden>
ha scritto:
> It doesn't work as expected for me.
> When I type
> 1 <Enter>
> 2 <Enter>
> 3 <Enter>
>
> and then browse through history with the <up> key, the following messages
> appear in this order: 2, 1. When I then press the <down> key, those
> messages appear: 1, 2, 3
>
> If I _instead_ (not after browing them with <up> and <down>) press the
> <down> key, 3 appears in the text box.
> --
> https:/
> You are the owner of lp:~oppifjellet/cable/message-history.
>
Daniele "OpenNingia" Simonetti (oppifjellet) wrote : | # |
So I checked the implementation:
pressing <down><up> with the editbox empty ( or after sending a message ) is a shortcut to get the last typed message )
instead when navigating <up>/<down> will return the next and the previous message, with one exception:
. the history doesn't save duplicates
so if you write
1
2
3
2
the last "2" is ignored.
982c80311320c1b (alexander-wilms) wrote : | # |
I think the most intuitive implementation (and IMHO the most simple one) would be this:
After typing:
1
2
3
2
Pressing <down> doesn't do anything. <Up> shows the last history entry (2) and every press of <up> shows the previous message. <Down> returns the next message.
Duplicates should not be skipped, since users don't know the algorithm behind it and at least I would expect it to list the messages in the order in which I pyed them.
- 127. By Daniele "OpenNingia" Simonetti
-
permit duplicates
Daniele "OpenNingia" Simonetti (oppifjellet) wrote : | # |
Ok so, this revision implements your design. Duplicates are permitted, history default size has been increased to 50, and hitting <down> after typing an entry does nothing.
982c80311320c1b (alexander-wilms) wrote : | # |
Great :)
- 128. By Daniele "OpenNingia" Simonetti
-
add unit test using GLib.Test
Eduard Gotwig (gotwig) wrote : | # |
You shouldnt propose merge requests, which are based on other merge requests. Each merge request should be clean applied with it changes on trunk.
However, I am going to look today at the other merge request of you, which included this one.
Cheers,
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2013-08-06 15:32:12 +0000 | |||
3 | +++ CMakeLists.txt 2013-09-03 20:19:34 +0000 | |||
4 | @@ -55,6 +55,7 @@ | |||
5 | 55 | src/Utils/EmbeddedAlert.vala | 55 | src/Utils/EmbeddedAlert.vala |
6 | 56 | src/Utils/Identity.vala | 56 | src/Utils/Identity.vala |
7 | 57 | src/Utils/Network.vala | 57 | src/Utils/Network.vala |
8 | 58 | src/Utils/RRStringList.vala | ||
9 | 58 | 59 | ||
10 | 59 | src/Irc/Maki.vala | 60 | src/Irc/Maki.vala |
11 | 60 | src/Irc/Irc.vala | 61 | src/Irc/Irc.vala |
12 | @@ -90,7 +91,7 @@ | |||
13 | 90 | src/Dialogs/Preferences.vala | 91 | src/Dialogs/Preferences.vala |
14 | 91 | src/Dialogs/ManageIdentity.vala | 92 | src/Dialogs/ManageIdentity.vala |
15 | 92 | src/Dialogs/ManageNetwork.vala | 93 | src/Dialogs/ManageNetwork.vala |
17 | 93 | 94 | ||
18 | 94 | src/Tests/Tests.vala | 95 | src/Tests/Tests.vala |
19 | 95 | src/Tests/Utils.vala | 96 | src/Tests/Utils.vala |
20 | 96 | 97 | ||
21 | @@ -109,9 +110,29 @@ | |||
22 | 109 | --verbose | 110 | --verbose |
23 | 110 | ) | 111 | ) |
24 | 111 | 112 | ||
25 | 113 | vala_precompile(VALA_C_TESTS | ||
26 | 114 | tests/TestCase.vala | ||
27 | 115 | tests/TestMain.vala | ||
28 | 116 | tests/TestExample.vala | ||
29 | 117 | tests/TestMessageHistory.vala | ||
30 | 118 | src/Utils/RRStringList.vala | ||
31 | 119 | PACKAGES | ||
32 | 120 | gtk+-3.0 | ||
33 | 121 | granite | ||
34 | 122 | libnotify | ||
35 | 123 | unity | ||
36 | 124 | OPTIONS | ||
37 | 125 | --target-glib=2.32 | ||
38 | 126 | --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi/ | ||
39 | 127 | --enable-experimental | ||
40 | 128 | --fatal-warnings | ||
41 | 129 | --verbose | ||
42 | 130 | ) | ||
43 | 131 | |||
44 | 112 | add_subdirectory (po) | 132 | add_subdirectory (po) |
45 | 113 | add_subdirectory (data) | 133 | add_subdirectory (data) |
46 | 114 | 134 | ||
47 | 115 | add_executable(cable ${VALA_C}) | 135 | add_executable(cable ${VALA_C}) |
48 | 136 | add_executable(cable_tests ${VALA_C_TESTS}) | ||
49 | 116 | 137 | ||
50 | 117 | install(TARGETS cable RUNTIME DESTINATION bin) | 138 | install(TARGETS cable RUNTIME DESTINATION bin) |
51 | 118 | 139 | ||
52 | === added file 'src/Utils/RRStringList.vala' | |||
53 | --- src/Utils/RRStringList.vala 1970-01-01 00:00:00 +0000 | |||
54 | +++ src/Utils/RRStringList.vala 2013-09-03 20:19:34 +0000 | |||
55 | @@ -0,0 +1,77 @@ | |||
56 | 1 | /*** | ||
57 | 2 | Copyright (C) 2013 Cable Developers | ||
58 | 3 | |||
59 | 4 | This program or library is free software; you can redistribute it | ||
60 | 5 | and/or modify it under the terms of the GNU Lesser General Public | ||
61 | 6 | License as published by the Free Software Foundation; either | ||
62 | 7 | version 3 of the License, or (at your option) any later version. | ||
63 | 8 | |||
64 | 9 | This library is distributed in the hope that it will be useful, | ||
65 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
66 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
67 | 12 | Lesser General Public License for more details. | ||
68 | 13 | |||
69 | 14 | You should have received a copy of the GNU Lesser General | ||
70 | 15 | Public License along with this library; if not, write to the | ||
71 | 16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
72 | 17 | Boston, MA 02110-1301 USA. | ||
73 | 18 | ***/ | ||
74 | 19 | |||
75 | 20 | |||
76 | 21 | public class Cable.Collections.RRStringList { | ||
77 | 22 | |||
78 | 23 | internal int? current_; | ||
79 | 24 | internal Gee.List <string> data; | ||
80 | 25 | |||
81 | 26 | public int capacity { get; set; } | ||
82 | 27 | public int? current_index { get { return current_; } } | ||
83 | 28 | |||
84 | 29 | public RRStringList.with_capacity (int capacity_value) | ||
85 | 30 | requires (capacity_value > 0) { | ||
86 | 31 | capacity = capacity_value; | ||
87 | 32 | data = new Gee.ArrayList <string>(); | ||
88 | 33 | } | ||
89 | 34 | |||
90 | 35 | public RRStringList () { | ||
91 | 36 | this.with_capacity(50); // default capacity | ||
92 | 37 | } | ||
93 | 38 | |||
94 | 39 | public void add(string value) { | ||
95 | 40 | if ( data.size >= this.capacity ) | ||
96 | 41 | data.remove_at( 0 ); | ||
97 | 42 | data.add(value); | ||
98 | 43 | current_ = data.size/*-1*/; | ||
99 | 44 | } | ||
100 | 45 | |||
101 | 46 | public bool contains(string value) { | ||
102 | 47 | return data.contains(value); | ||
103 | 48 | } | ||
104 | 49 | |||
105 | 50 | public string current() { | ||
106 | 51 | if ( current_ == null ) return ""; | ||
107 | 52 | if ( current_ >= data.size ) current_ = data.size-1; | ||
108 | 53 | if ( current_ < 0 ) current_ = 0; | ||
109 | 54 | return data[current_]; | ||
110 | 55 | } | ||
111 | 56 | |||
112 | 57 | public bool previous() { | ||
113 | 58 | if ( current_ == null ) return false; | ||
114 | 59 | if ( current_ <= 0 ) return false; | ||
115 | 60 | current_ = current_ - 1; | ||
116 | 61 | return true; | ||
117 | 62 | } | ||
118 | 63 | |||
119 | 64 | public bool next() { | ||
120 | 65 | if ( current_ == null ) return false; | ||
121 | 66 | if ( current_+1 >= data.size ) return false; | ||
122 | 67 | current_ = current_ + 1; | ||
123 | 68 | return true; | ||
124 | 69 | } | ||
125 | 70 | |||
126 | 71 | public bool set_current_value(string value) { | ||
127 | 72 | if ( !(value in data) ) return false; | ||
128 | 73 | current_ = data.index_of(value)+1; | ||
129 | 74 | return true; | ||
130 | 75 | } | ||
131 | 76 | |||
132 | 77 | } | ||
133 | 0 | 78 | ||
134 | === modified file 'src/Widgets/Room.vala' | |||
135 | --- src/Widgets/Room.vala 2013-08-22 18:40:53 +0000 | |||
136 | +++ src/Widgets/Room.vala 2013-09-03 20:19:34 +0000 | |||
137 | @@ -51,6 +51,8 @@ | |||
138 | 51 | internal Gtk.Entry text_entry; | 51 | internal Gtk.Entry text_entry; |
139 | 52 | Utils.AutoScrolled left_scrolled; | 52 | Utils.AutoScrolled left_scrolled; |
140 | 53 | 53 | ||
141 | 54 | internal Cable.Collections.RRStringList history_set; | ||
142 | 55 | |||
143 | 54 | Gtk.Box user_box; | 56 | Gtk.Box user_box; |
144 | 55 | 57 | ||
145 | 56 | public Widgets.Topic topic_bar; | 58 | public Widgets.Topic topic_bar; |
146 | @@ -62,17 +64,21 @@ | |||
147 | 62 | public signal void rejoin (); | 64 | public signal void rejoin (); |
148 | 63 | 65 | ||
149 | 64 | public string channel { get; set; } | 66 | public string channel { get; set; } |
151 | 65 | 67 | ||
152 | 66 | public string nick { | 68 | public string nick { |
153 | 67 | get { return pseudo_label.label; } | 69 | get { return pseudo_label.label; } |
154 | 68 | set { pseudo_label.label = value; } | 70 | set { pseudo_label.label = value; } |
155 | 69 | } | 71 | } |
157 | 70 | 72 | ||
158 | 71 | public string entry { | 73 | public string entry { |
159 | 72 | get { return text_entry.text; } | 74 | get { return text_entry.text; } |
160 | 73 | set { text_entry.text = value; } | 75 | set { text_entry.text = value; } |
161 | 74 | } | 76 | } |
162 | 75 | 77 | ||
163 | 78 | public Cable.Collections.RRStringList history { | ||
164 | 79 | get { return history_set; } | ||
165 | 80 | } | ||
166 | 81 | |||
167 | 76 | State _state; | 82 | State _state; |
168 | 77 | public State state { | 83 | public State state { |
169 | 78 | get { return _state; } | 84 | get { return _state; } |
170 | @@ -104,7 +110,7 @@ | |||
171 | 104 | show_all (); | 110 | show_all (); |
172 | 105 | } | 111 | } |
173 | 106 | } | 112 | } |
175 | 107 | 113 | ||
176 | 108 | private Gee.Set <string> nicks { | 114 | private Gee.Set <string> nicks { |
177 | 109 | owned get { | 115 | owned get { |
178 | 110 | var _nicks = new Gee.HashSet <string> (); | 116 | var _nicks = new Gee.HashSet <string> (); |
179 | @@ -119,6 +125,8 @@ | |||
180 | 119 | public Room (string channel, string nick="") { | 125 | public Room (string channel, string nick="") { |
181 | 120 | this.channel = channel; | 126 | this.channel = channel; |
182 | 121 | 127 | ||
183 | 128 | history_set = new Cable.Collections.RRStringList(); | ||
184 | 129 | |||
185 | 122 | init_layout (); | 130 | init_layout (); |
186 | 123 | connect_callbacks (); | 131 | connect_callbacks (); |
187 | 124 | } | 132 | } |
188 | @@ -227,7 +235,7 @@ | |||
189 | 227 | return true; | 235 | return true; |
190 | 228 | } else { | 236 | } else { |
191 | 229 | text_entry.buffer.delete_text (text_entry.cursor_position - word.length, word.length); | 237 | text_entry.buffer.delete_text (text_entry.cursor_position - word.length, word.length); |
193 | 230 | 238 | ||
194 | 231 | if( text_entry.text != "" ){ | 239 | if( text_entry.text != "" ){ |
195 | 232 | text_entry.insert_at_cursor (completion[0] + " "); | 240 | text_entry.insert_at_cursor (completion[0] + " "); |
196 | 233 | } else { | 241 | } else { |
197 | @@ -236,12 +244,26 @@ | |||
198 | 236 | return true; | 244 | return true; |
199 | 237 | } | 245 | } |
200 | 238 | } | 246 | } |
201 | 247 | else if ( ev.keyval == Gdk.Key.Up ) { | ||
202 | 248 | if ( history.previous() ) | ||
203 | 249 | text_entry.text = history.current(); | ||
204 | 250 | return true; | ||
205 | 251 | } | ||
206 | 252 | else if ( ev.keyval == Gdk.Key.Down ) { | ||
207 | 253 | if ( history.next() ) | ||
208 | 254 | text_entry.text = history.current(); | ||
209 | 255 | return true; | ||
210 | 256 | } | ||
211 | 239 | return false; | 257 | return false; |
212 | 240 | }); | 258 | }); |
214 | 241 | 259 | ||
215 | 242 | text_entry.activate.connect (() => { | 260 | text_entry.activate.connect (() => { |
217 | 243 | if (text_entry.text != "") | 261 | if (text_entry.text != "") { |
218 | 262 | |||
219 | 263 | // permit duplicates | ||
220 | 264 | history.add(text_entry.text); | ||
221 | 244 | send_message (text_entry.text); // signal | 265 | send_message (text_entry.text); // signal |
222 | 266 | } | ||
223 | 245 | }); | 267 | }); |
224 | 246 | 268 | ||
225 | 247 | action_join.activate.connect (() => { | 269 | action_join.activate.connect (() => { |
226 | @@ -281,7 +303,7 @@ | |||
227 | 281 | requires (!has_user (new_name)) | 303 | requires (!has_user (new_name)) |
228 | 282 | ensures (!has_user (old_name)) | 304 | ensures (!has_user (old_name)) |
229 | 283 | ensures (has_user (new_name)) { | 305 | ensures (has_user (new_name)) { |
231 | 284 | 306 | ||
232 | 285 | if (old_name == null) { | 307 | if (old_name == null) { |
233 | 286 | add_user (new_name, type, true); | 308 | add_user (new_name, type, true); |
234 | 287 | return; | 309 | return; |
235 | @@ -300,7 +322,7 @@ | |||
236 | 300 | 322 | ||
237 | 301 | var user = new User (name); | 323 | var user = new User (name); |
238 | 302 | user.selectable = false; | 324 | user.selectable = false; |
240 | 303 | 325 | ||
241 | 304 | switch (type) { | 326 | switch (type) { |
242 | 305 | case UserType.OPERATOR: | 327 | case UserType.OPERATOR: |
243 | 306 | operators.add (user); | 328 | operators.add (user); |
244 | @@ -324,7 +346,7 @@ | |||
245 | 324 | public bool remove_user (string name, string message, bool silent = false) | 346 | public bool remove_user (string name, string message, bool silent = false) |
246 | 325 | requires (has_user (name)) | 347 | requires (has_user (name)) |
247 | 326 | ensures (!has_user (name)) { | 348 | ensures (!has_user (name)) { |
249 | 327 | 349 | ||
250 | 328 | Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; | 350 | Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
251 | 329 | foreach (var list in lists) { | 351 | foreach (var list in lists) { |
252 | 330 | foreach (var child in list.children) { | 352 | foreach (var child in list.children) { |
253 | 331 | 353 | ||
254 | === added directory 'tests' | |||
255 | === added file 'tests/TestCase.vala' | |||
256 | --- tests/TestCase.vala 1970-01-01 00:00:00 +0000 | |||
257 | +++ tests/TestCase.vala 2013-09-03 20:19:34 +0000 | |||
258 | @@ -0,0 +1,58 @@ | |||
259 | 1 | public abstract class Gee.TestCase : Object { | ||
260 | 2 | |||
261 | 3 | private GLib.TestSuite suite; | ||
262 | 4 | private Adaptor[] adaptors = new Adaptor[0]; | ||
263 | 5 | |||
264 | 6 | public delegate void TestMethod (); | ||
265 | 7 | |||
266 | 8 | public TestCase (string name) { | ||
267 | 9 | this.suite = new GLib.TestSuite (name); | ||
268 | 10 | } | ||
269 | 11 | |||
270 | 12 | public void add_test (string name, owned TestMethod test) { | ||
271 | 13 | var adaptor = new Adaptor (name, (owned)test, this); | ||
272 | 14 | this.adaptors += adaptor; | ||
273 | 15 | |||
274 | 16 | this.suite.add (new GLib.TestCase (adaptor.name, | ||
275 | 17 | adaptor.set_up, | ||
276 | 18 | adaptor.run, | ||
277 | 19 | adaptor.tear_down )); | ||
278 | 20 | } | ||
279 | 21 | |||
280 | 22 | public virtual void set_up () { | ||
281 | 23 | } | ||
282 | 24 | |||
283 | 25 | public virtual void tear_down () { | ||
284 | 26 | } | ||
285 | 27 | |||
286 | 28 | public GLib.TestSuite get_suite () { | ||
287 | 29 | return this.suite; | ||
288 | 30 | } | ||
289 | 31 | |||
290 | 32 | private class Adaptor { | ||
291 | 33 | |||
292 | 34 | public string name { get; private set; } | ||
293 | 35 | private TestMethod test; | ||
294 | 36 | private TestCase test_case; | ||
295 | 37 | |||
296 | 38 | public Adaptor (string name, | ||
297 | 39 | owned TestMethod test, | ||
298 | 40 | TestCase test_case) { | ||
299 | 41 | this.name = name; | ||
300 | 42 | this.test = (owned)test; | ||
301 | 43 | this.test_case = test_case; | ||
302 | 44 | } | ||
303 | 45 | |||
304 | 46 | public void set_up (void* fixture) { | ||
305 | 47 | this.test_case.set_up (); | ||
306 | 48 | } | ||
307 | 49 | |||
308 | 50 | public void run (void* fixture) { | ||
309 | 51 | this.test (); | ||
310 | 52 | } | ||
311 | 53 | |||
312 | 54 | public void tear_down (void* fixture) { | ||
313 | 55 | this.test_case.tear_down (); | ||
314 | 56 | } | ||
315 | 57 | } | ||
316 | 58 | } | ||
317 | 0 | \ No newline at end of file | 59 | \ No newline at end of file |
318 | 1 | 60 | ||
319 | === added file 'tests/TestExample.vala' | |||
320 | --- tests/TestExample.vala 1970-01-01 00:00:00 +0000 | |||
321 | +++ tests/TestExample.vala 2013-09-03 20:19:34 +0000 | |||
322 | @@ -0,0 +1,22 @@ | |||
323 | 1 | class TestExample : Gee.TestCase { | ||
324 | 2 | |||
325 | 3 | public TestExample() { | ||
326 | 4 | // assign a name for this class | ||
327 | 5 | base("TestExample"); | ||
328 | 6 | // add test methods | ||
329 | 7 | add_test("test_example", test_example); | ||
330 | 8 | } | ||
331 | 9 | |||
332 | 10 | public override void set_up () { | ||
333 | 11 | // setup your test | ||
334 | 12 | } | ||
335 | 13 | |||
336 | 14 | public void test_example() { | ||
337 | 15 | // add your expressions | ||
338 | 16 | // assert(expression); | ||
339 | 17 | } | ||
340 | 18 | |||
341 | 19 | public override void tear_down () { | ||
342 | 20 | // tear down your test | ||
343 | 21 | } | ||
344 | 22 | } | ||
345 | 0 | \ No newline at end of file | 23 | \ No newline at end of file |
346 | 1 | 24 | ||
347 | === added file 'tests/TestMain.vala' | |||
348 | --- tests/TestMain.vala 1970-01-01 00:00:00 +0000 | |||
349 | +++ tests/TestMain.vala 2013-09-03 20:19:34 +0000 | |||
350 | @@ -0,0 +1,7 @@ | |||
351 | 1 | public static int main(string[] args) { | ||
352 | 2 | Test.init (ref args); | ||
353 | 3 | // add any of your test cases here | ||
354 | 4 | TestSuite.get_root().add_suite(new TestExample().get_suite()); | ||
355 | 5 | TestSuite.get_root().add_suite(new TestMessageHistory().get_suite()); | ||
356 | 6 | return Test.run (); | ||
357 | 7 | } | ||
358 | 0 | \ No newline at end of file | 8 | \ No newline at end of file |
359 | 1 | 9 | ||
360 | === added file 'tests/TestMessageHistory.vala' | |||
361 | --- tests/TestMessageHistory.vala 1970-01-01 00:00:00 +0000 | |||
362 | +++ tests/TestMessageHistory.vala 2013-09-03 20:19:34 +0000 | |||
363 | @@ -0,0 +1,41 @@ | |||
364 | 1 | class TestMessageHistory : Gee.TestCase { | ||
365 | 2 | |||
366 | 3 | public TestMessageHistory() { | ||
367 | 4 | // assign a name for this class | ||
368 | 5 | base("TestMessageHistory"); | ||
369 | 6 | // add test methods | ||
370 | 7 | add_test("[History] Navigate history", test_navigate); | ||
371 | 8 | add_test("[History] Limited capacity", test_capacity); | ||
372 | 9 | } | ||
373 | 10 | |||
374 | 11 | public override void set_up () { | ||
375 | 12 | // setup your test | ||
376 | 13 | } | ||
377 | 14 | |||
378 | 15 | public void test_navigate() { | ||
379 | 16 | var history = new Cable.Collections.RRStringList(); | ||
380 | 17 | history.add("one"); | ||
381 | 18 | history.add("two"); | ||
382 | 19 | history.add("three"); | ||
383 | 20 | assert(history.current() == "three"); | ||
384 | 21 | assert(history.next() == false); | ||
385 | 22 | assert(history.current() == "three"); | ||
386 | 23 | assert(history.previous() == true); | ||
387 | 24 | assert(history.current() == "two"); | ||
388 | 25 | } | ||
389 | 26 | |||
390 | 27 | public void test_capacity() { | ||
391 | 28 | var history = new Cable.Collections.RRStringList.with_capacity(2); | ||
392 | 29 | history.add("one"); | ||
393 | 30 | history.add("two"); | ||
394 | 31 | history.add("three"); | ||
395 | 32 | assert(history.current() == "three"); | ||
396 | 33 | assert(history.previous() == true); | ||
397 | 34 | assert(history.previous() == false); | ||
398 | 35 | assert(history.current() == "two"); | ||
399 | 36 | } | ||
400 | 37 | |||
401 | 38 | public override void tear_down () { | ||
402 | 39 | // tear down your test | ||
403 | 40 | } | ||
404 | 41 | } | ||
405 | 0 | \ No newline at end of file | 42 | \ No newline at end of file |
sometimes I have to double press up or down, for it to work. Can this be fixed?
Thanks for your work.