~ubuntu-branches/ubuntu/maverick/libchamplain/maverick

« back to all changes in this revision

Viewing changes to bindings/perl/Champlain/t/ChamplainView.t

  • Committer: Bazaar Package Importer
  • Author(s): Sjoerd Simons, Laurent Bigonville, Sjoerd Simons
  • Date: 2009-09-15 00:01:41 UTC
  • mfrom: (1.1.3 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090915000141-i8fg5n1t02zxo79m
Tags: 0.4.0-1
[ Laurent Bigonville ]
* debian/control: Add libchamplain-0.3-dev dependency to
  libchamplain-gtk-0.3-dev

[ Sjoerd Simons ]
* New upstream release (0.4.0)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
 
 
3
use strict;
 
4
use warnings;
 
5
 
 
6
use Clutter::TestHelper tests => 82;
 
7
 
 
8
use Champlain ':coords';
 
9
 
 
10
 
 
11
exit tests();
 
12
 
 
13
 
 
14
sub tests {
 
15
        test_go_to();
 
16
        test_ensure_visible();
 
17
        test_ensure_markers_visible();
 
18
        test_generic();
 
19
        test_zoom();
 
20
        test_event();
 
21
        test_polygons();
 
22
        return 0;
 
23
}
 
24
 
 
25
 
 
26
#
 
27
# Test some default functionality.
 
28
#
 
29
sub test_generic {
 
30
        my $view = Champlain::View->new();
 
31
        isa_ok($view, 'Champlain::View');
 
32
        
 
33
        # center_on() can be tested by checking the properties latitude and longitude.
 
34
        # And even then, the values set are not the ones returned
 
35
        my $latitude = $view->get('latitude');
 
36
        my $longitude = $view->get('longitude');
 
37
        $view->center_on(48.144722, 17.112778);
 
38
        ok($view->get('latitude') != $latitude, "center_on() changed latitude");
 
39
        ok($view->get('longitude') != $longitude, "center_on() changed longitude");
 
40
        
 
41
        # NOTE: In recent versions of libchamplain the view requests the first tile
 
42
        #       (0, 0 at zoom level 0). If the tile is already in the cache then it
 
43
        #       will be loaded and the view's initial size will be of the tile's size.
 
44
        #       If the tile is not in the cache then it will be downloaded
 
45
        #       asynchronously and the view will have a size of (0, 0).
 
46
        #
 
47
        #       For the moment there's no mechanism for disabling the cache nor for
 
48
        #       finding out if the view has a tile loaded. This is why the test for
 
49
        #       both.
 
50
        # 
 
51
        #
 
52
        my $source_original = $view->get('map-source');
 
53
        ok($view->get('width') == 0 || $view->get('width') == $source_original->get_tile_size, "original width");
 
54
        ok($view->get('height') == 0 || $view->get('height') == $source_original->get_tile_size, "original height");
 
55
 
 
56
        # set_size() can be tested by checking the properties width and height
 
57
        $view->set_size(600, 400);
 
58
        is($view->get('width'), 600, "set_size() changed width");
 
59
        is($view->get('height'), 400, "set_size() changed height");
 
60
 
 
61
        
 
62
        # Can't be tested but at least we check that it doesn't crash when invoked
 
63
        my $layer = Champlain::Layer->new();
 
64
        $view->add_layer($layer);
 
65
        
 
66
        
 
67
        # Change the map source (get a different map source)
 
68
        my $factory = Champlain::MapSourceFactory->dup_default();
 
69
        my $source_new = $factory->create(Champlain::MapSourceFactory->OSM_MAPNIK);
 
70
        if ($source_original->get_id eq $source_new->get_id) {
 
71
                # Same kind of map source, take another one
 
72
                $source_new = $factory->create(Champlain::MapSourceFactory->OAM);
 
73
        }
 
74
        $view->set_map_source($source_new);
 
75
        is($view->get('map-source'), $source_new, "set_map_source()");
 
76
        is($view->get_map_source, $source_new, "get_map_source()");
 
77
 
 
78
        
 
79
        # Change the decel rate
 
80
        $view->set_decel_rate(0.5);
 
81
        is($view->get('decel-rate'), 0.5, "set_decel_rate()");
 
82
        $view->set_decel_rate(1.5);
 
83
        is($view->get('decel-rate'), 1.5, "set_decel_rate()");
 
84
        is($view->get_decel_rate, 1.5, "get_decel_rate()");
 
85
 
 
86
        
 
87
        # Change the scroll mode
 
88
        $view->set_scroll_mode('push');
 
89
        is($view->get('scroll-mode'), 'push', "set_scroll_mode('push')");
 
90
        $view->set_scroll_mode('kinetic');
 
91
        is($view->get('scroll-mode'), 'kinetic', "set_scroll_mode('kinetic')");
 
92
        is($view->get_scroll_mode, 'kinetic', "get_scroll_mode()");
 
93
 
 
94
        
 
95
        # Change the show license property
 
96
        $view->set_show_license(TRUE);
 
97
        ok($view->get('show-license'), "set_show_license(TRUE)");
 
98
        $view->set_show_license(FALSE);
 
99
        ok(!$view->get('show-license'), "set_show_license(FALSE)");
 
100
        ok(!$view->get_show_license, "get_show_license");
 
101
        
 
102
        
 
103
        # Change the set zoom on double click property
 
104
        $view->set_zoom_on_double_click(TRUE);
 
105
        ok($view->get('zoom-on-double-click'), "set_zoom_on_double_click(TRUE)");
 
106
        $view->set_zoom_on_double_click(FALSE);
 
107
        ok(!$view->get('zoom-on-double-click'), "set_zoom_on_double_click(FALSE)");
 
108
        ok(!$view->get_zoom_on_double_click, "get_zoom_on_double_click()");
 
109
        
 
110
        
 
111
        # Change the keep center on resize property
 
112
        $view->set_keep_center_on_resize(TRUE);
 
113
        ok($view->get('keep-center-on-resize'), "set_keep_center_on_resize(TRUE)");
 
114
        $view->set_keep_center_on_resize(FALSE);
 
115
        ok(!$view->get('keep-center-on-resize'), "set_keep_center_on_resize(FALSE)");
 
116
        ok(!$view->get_keep_center_on_resize, "get_keep_center_on_resize()");
 
117
        
 
118
        
 
119
        # Call ensure_visible(), it's to test, but at least we test that it doesn't crash
 
120
        $view->ensure_visible(10, 10, 30, 30, TRUE);
 
121
}
 
122
 
 
123
 
 
124
#
 
125
# Test the zoom functionality.
 
126
#
 
127
sub test_zoom {
 
128
        my $view = Champlain::View->new();
 
129
        isa_ok($view, 'Champlain::View');
 
130
        
 
131
        
 
132
        # Zoom in
 
133
        is($view->get('zoom-level'), 0, "original zoom-level");
 
134
        $view->zoom_in();
 
135
        is($view->get('zoom-level'), 1, "zoom-in once");
 
136
        $view->zoom_in();
 
137
        is($view->get('zoom-level'), 2, "zoom-in twice");
 
138
        
 
139
        # Zoom out
 
140
        $view->zoom_out();
 
141
        is($view->get('zoom-level'), 1, "zoom-out once");
 
142
        $view->zoom_out();
 
143
        is($view->get('zoom-level'), 0, "zoom-out twice");
 
144
        
 
145
        my $map_source = $view->get('map-source');
 
146
        
 
147
        # Zoom out past the min zoom level
 
148
        my $min = $map_source->get_min_zoom_level;
 
149
        $view->set_zoom_level($min);
 
150
        is($view->get('zoom-level'), $min, "zoom-out to the minimal level");
 
151
        is($view->get_zoom_level, $min, "get_zoom_level()");
 
152
 
 
153
        $view->set("zoom-level", $min);
 
154
        is($view->get('zoom-level'), $min, "set('zoom-level') to the minimal level");
 
155
 
 
156
        $view->zoom_out();
 
157
        is($view->get('zoom-level'), $min, "zoom-out past minimal level has no effect");
 
158
        
 
159
        
 
160
        # Zoom in after the max zoom level
 
161
        my $max = $map_source->get_max_zoom_level;
 
162
        $view->set_zoom_level($max);
 
163
        is($view->get('zoom-level'), $max, "zoom-in to the maximal level");
 
164
 
 
165
        $view->set("zoom-level", $max);
 
166
        is($view->get('zoom-level'), $max, "set('zoom-level') to the maximal level");
 
167
 
 
168
        $view->zoom_in();
 
169
        is($view->get('zoom-level'), $max, "zoom-in past maximal level has no effect");
 
170
        
 
171
        # Go to the middle zoom level
 
172
        my $middle = int( ($max - $min) / 2 );
 
173
        $view->set_zoom_level($middle);
 
174
        is($view->get('zoom-level'), $middle, "set zoom to the middle level");
 
175
 
 
176
        $view->set("zoom-level", $middle);
 
177
        is($view->get('zoom-level'), $middle, "set('zoom-level', (max-min)/2) to the middle level");
 
178
        
 
179
        
 
180
        # Try to set directly the zoom level to a value inferior to min level
 
181
        $view->set_zoom_level($min - 1);
 
182
        is($view->get('zoom-level'), $middle, "set zoom (min - 1) has no effect");
 
183
 
 
184
        # NOTE: This gives a warning because -1 out of range for property `zoom-level'
 
185
        #$view->set("zoom-level", $min - 1);
 
186
        #is($view->get('zoom-level'), $middle, "set('zoom-level', min - 1) has no effect");
 
187
        
 
188
        # Try to set directly the zoom level to a valu superior to max level
 
189
        $view->set_zoom_level($max + 1);
 
190
        is($view->get('zoom-level'), $middle, "set zoom (max + 1) has no effect");
 
191
 
 
192
        $view->set("zoom-level", $max + 1);
 
193
        is($view->get('zoom-level'), $middle, "set('zoom-level', max + 1) has no effect");
 
194
 
 
195
        
 
196
        # Limit the application's zoom levels
 
197
        $view->set_zoom_level(1);
 
198
        is($view->get('zoom-level'), 1, "set('zoom-level', 1)");
 
199
        is($view->get('min-zoom-level'), $min, "defaullt min-zoom-level");
 
200
        is($view->get_min_zoom_level, $min, "get_min_zoom_level()");
 
201
        $view->set_min_zoom_level(3);
 
202
        is($view->get('min-zoom-level'), 3, "set_min_zoom_level(3)");
 
203
        is($view->get('zoom-level'), 3, "zoom-level level is 3 after setting min-zoom-level to 3");
 
204
        
 
205
        $view->set_zoom_level(6);
 
206
        is($view->get('zoom-level'), 6, "set('zoom-level', 6)");
 
207
        is($view->get('max-zoom-level'), $max, "defaullt max-zoom-level");
 
208
        is($view->get_max_zoom_level, $max, "get_max_zoom_level()");
 
209
        $view->set_max_zoom_level(4);
 
210
        is($view->get('max-zoom-level'), 4, "set_mx_zoom_level(4)");
 
211
        is($view->get('zoom-level'), 4, "zoom-level level is 4 after setting min-zoom-level to 4");
 
212
}
 
213
 
 
214
 
 
215
#
 
216
# Test getting the coordinates from an event.
 
217
#
 
218
# This tests simulates that the user clicked at the coordinate (0, 0) (where
 
219
# Greenwich meets the Equator). In order to simulate this, the test sets the
 
220
# view to be as big as the first tile and will simulate a click in the middle of
 
221
# the tile. Because the computations are made with a projection a slight error
 
222
# threshold will be accepted.
 
223
#
 
224
sub test_event {
 
225
        my $view = Champlain::View->new();
 
226
        isa_ok($view, 'Champlain::View');
 
227
        
 
228
        my $map_source = $view->get('map-source');
 
229
        my $size = $map_source->get_tile_size;
 
230
        ok($size > 0, "Tile has a decent size");
 
231
        
 
232
        # NOTE: At the moment this works only if the view is in a stage and if
 
233
        # show_all() was called
 
234
        my $stage = Clutter::Stage->get_default();
 
235
        $view->set_size($size, $size);
 
236
        $view->center_on(0, 0);
 
237
        $stage->add($view);
 
238
        
 
239
        # Create a fake event in the middle of the tile
 
240
        my $event = Clutter::Event->new('button_press');
 
241
        my $middle = int($size/2);
 
242
        $event->x($middle);
 
243
        $event->y($middle);
 
244
        is($event->x, $middle, "Fake event is in the middle (x)");
 
245
        is($event->y, $middle, "Fake event is in the middle (y)");
 
246
 
 
247
        my ($latitude, $longitude) = $view->get_coords_from_event($event);
 
248
        ok($latitude >= -2.0 && $latitude <= 2.0, "get_coords_from_event() latitude");
 
249
        ok($longitude >= -2.0 && $longitude <= 2.0, "get_coords_from_event() longitude");
 
250
 
 
251
        ($latitude, $longitude) = $view->get_coords_at($event->x, $event->y);
 
252
        ok($latitude >= -2.0 && $latitude <= 2.0, "get_coords_at() latitude");
 
253
        ok($longitude >= -2.0 && $longitude <= 2.0, "get_coords_at() longitude");
 
254
}
 
255
 
 
256
 
 
257
#
 
258
# Test going to a different location with go_to().
 
259
#
 
260
sub test_go_to {
 
261
        my $view = Champlain::View->new();
 
262
        isa_ok($view, 'Champlain::View');
 
263
 
 
264
        # Place the view in the center
 
265
        $view->center_on(0, 0);
 
266
        is($view->get('latitude'), 0, "center_on() reset latitude");
 
267
        is($view->get('longitude'), 0, "center_on() reset longitude");
 
268
        
 
269
        
 
270
        # Go to a different place
 
271
        my ($latitude, $longitude) = (48.218611, 17.146397);
 
272
        $view->go_to($latitude, $longitude);
 
273
 
 
274
        run_animation_loop($view);
 
275
        
 
276
        # Check if we got somewhere close to desired location
 
277
        is_view_near($view, $latitude, $longitude);
 
278
        
 
279
        
 
280
        # Replace the view in the center
 
281
        $view->center_on(0, 0);
 
282
        is($view->get('latitude'), 0, "center_on() reset latitude");
 
283
        is($view->get('longitude'), 0, "center_on() reset longitude");
 
284
        
 
285
        # Go to a different place. This is too fast and can't be tested properly.
 
286
        $view->go_to($latitude, $longitude);
 
287
        Glib::Idle->add(sub {$view->stop_go_to()});
 
288
        run_animation_loop($view);
 
289
 
 
290
        is($view->get('latitude'), 0, "stop_go_to() at latitude 0");
 
291
        is($view->get('longitude'), 0, "stop_go_to() at longitude 0");
 
292
}
 
293
 
 
294
 
 
295
#
 
296
# Test the polygons
 
297
#
 
298
sub test_polygons {
 
299
        my $view = Champlain::View->new();
 
300
        isa_ok($view, 'Champlain::View');
 
301
 
 
302
        my $line = Champlain::Polygon->new();
 
303
        my $triangle = Champlain::Polygon->new();
 
304
        my $square = Champlain::Polygon->new();
 
305
        
 
306
        # Note these can't be tested as the API provides no way for querying the polygons
 
307
        $view->add_polygon($line);
 
308
        $view->add_polygon($triangle);
 
309
        $view->add_polygon($square);
 
310
        
 
311
        $view->remove_polygon($line);
 
312
        $view->remove_polygon($square);
 
313
}
 
314
 
 
315
 
 
316
#
 
317
# Test ensure_visible().
 
318
#
 
319
sub test_ensure_visible {
 
320
        my $view = Champlain::View->new();
 
321
        isa_ok($view, 'Champlain::View');
 
322
 
 
323
        # Place the view in the center and zoomed
 
324
        $view->center_on(0, 0);
 
325
        $view->set_zoom_level(6);
 
326
        is($view->get('latitude'), 0);
 
327
        is($view->get('longitude'), 0);
 
328
        is($view->get('zoom-level'), 6);
 
329
 
 
330
        # Must add the view to a stage for this test
 
331
        my $stage = Clutter::Stage->get_default();
 
332
        $view->set_size(400, 400);
 
333
        $stage->add($view);
 
334
 
 
335
        # Ensure that 2 points are visible
 
336
        my (@marker1) = (48.218611, 17.146397);
 
337
        my (@marker2) = (48.21066, 16.31476);
 
338
        $view->ensure_visible(@marker1, @marker2, TRUE);
 
339
 
 
340
        run_animation_loop($view);
 
341
        
 
342
        # Check if we got somewhere close to the middle of the markers
 
343
        my $middle_latitude = ($marker1[0] + $marker2[0]) / 2;
 
344
        my $middle_longitude = ($marker1[1] + $marker2[1]) / 2;
 
345
        is_view_near($view, $middle_latitude, $middle_longitude);
 
346
}
 
347
 
 
348
 
 
349
#
 
350
# Test ensure_markers_visible().
 
351
#
 
352
sub test_ensure_markers_visible {
 
353
        my $view = Champlain::View->new();
 
354
        isa_ok($view, 'Champlain::View');
 
355
 
 
356
        # Place the view in the center and zoomed
 
357
        $view->center_on(0, 0);
 
358
        $view->set_zoom_level(6);
 
359
        is($view->get('latitude'), 0);
 
360
        is($view->get('longitude'), 0);
 
361
        is($view->get('zoom-level'), 6);
 
362
 
 
363
        # Ensure that some markers are visible
 
364
        my @markers = (
 
365
                create_marker('A', 48.218611, 17.146397),
 
366
                create_marker('B', 48.14838,  17.10791),
 
367
                create_marker('C', 48.21066,  16.31476),
 
368
        );
 
369
        
 
370
        my $layer = Champlain::Layer->new();
 
371
        foreach my $marker (@markers) {
 
372
                $layer->add($marker);
 
373
        }
 
374
        $view->add_layer($layer);
 
375
 
 
376
        # Must add the view to a stage and give a size for this test
 
377
        my $stage = Clutter::Stage->get_default();
 
378
        $stage->add($view);
 
379
        $view->set_size(400, 400);
 
380
 
 
381
        $view->ensure_markers_visible(\@markers, TRUE);
 
382
 
 
383
        run_animation_loop($view);
 
384
        
 
385
        # Check if we got somewhere close to the middle of the markers
 
386
        is_view_near($view, 48.0, 16.5, 5.0);
 
387
}
 
388
 
 
389
 
 
390
#
 
391
# Test if the view is near the given (latitude, longitude). This function checks
 
392
# if the cordinate is close to the given point by accepting an error margin. If
 
393
# no margin is given then one degree is assumed.
 
394
#
 
395
sub is_view_near {
 
396
        my ($view, $latitude, $longitude, $delta) = @_;
 
397
        $delta = 1.0 unless defined $delta;
 
398
        
 
399
        # Check if the view is close to the given position
 
400
        my ($current_latitude, $current_longitude) = $view->get('latitude', 'longitude');
 
401
        my $delta_latitude = $current_latitude - $latitude;
 
402
        my $delta_longitude = $current_longitude - $longitude;
 
403
        my $tester = Test::Builder->new();
 
404
        $tester->ok($delta_latitude >= -$delta && $delta_latitude <= $delta, "ensure_visible() changed latitude close enough (delta: $delta_latitude)");
 
405
        $tester->ok($delta_longitude >= -$delta && $delta_longitude <= $delta, "ensure_visible() changed longitude close enough (delta: $delta_longitude)");
 
406
}
 
407
 
 
408
 
 
409
sub create_marker {
 
410
        my ($label, $latitude, $longitude) = @_;
 
411
        my $marker = Champlain::Marker->new_with_text($label);
 
412
        $marker->set_position($latitude, $longitude);
 
413
        return $marker;
 
414
}
 
415
 
 
416
 
 
417
#
 
418
# Runs a main loop for the purpose of executing one animation. The main loop is
 
419
# timed in case where the test doesn't work.
 
420
#
 
421
sub run_animation_loop {
 
422
        my ($view) = @_;
 
423
 
 
424
#       if (my $stage = $view->get_stage) {
 
425
#               $stage->show_all();
 
426
#       }
 
427
 
 
428
 
 
429
        # Give us a bit of time to get there since this is an animation and it
 
430
        # requires an event loop. We add an idle timeout in order to make sure that we
 
431
        # don't wait forever.
 
432
        $view->signal_connect('animation-completed' => sub {
 
433
                Clutter->main_quit();
 
434
        });
 
435
        Glib::Timeout->add(10_000, sub {
 
436
                diag("Event loop timeout, perhaps the animation needs more time?");
 
437
                Clutter->main_quit();
 
438
                return FALSE;
 
439
        });
 
440
        Clutter->main();
 
441
}