File: test_util.c

package info (click to toggle)
xastir 2.2.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 22,860 kB
  • sloc: ansic: 126,160; perl: 7,792; makefile: 448; sh: 228; sql: 102
file content (329 lines) | stat: -rw-r--r-- 12,085 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*
 *
 * XASTIR, Amateur Station Tracking and Information Reporting
 * Copyright (C) 2025-2026 The Xastir Group
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Look at the README for more information on the program.
 */

/*
 * Test program for object_utils.c functions
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>

#include "tests/test_framework.h"

#include "util.h"
#include "globals.h"

extern long scale_x, scale_y;
extern long center_longitude, center_latitude;
extern long NW_corner_longitude, NW_corner_latitude;
extern long SE_corner_longitude, SE_corner_latitude;
extern long screen_height, screen_width;

int test_convert_lat_l2s_basic(void)
{
  long lat;
  char lat_str[20];
  // Compute Xastir coordinates for 35d01.631'N
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lat = 90*60*60*100-(35*60+1.631)*60*100;
  convert_lat_l2s(lat,lat_str, sizeof(lat_str),CONVERT_HP_NOSP);
  TEST_ASSERT_STR_EQ("3501.631N",lat_str,"xastir y value correctly converted to string");
  TEST_PASS("convert_lat_l2s: correct");
}
int test_convert_lon_l2s_basic(void)
{
  long lon;
  char lon_str[20];
  // Compute Xastir coordinates for 106d12.385'W
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lon = 180*60*60*100-(106*60+12.385)*60*100;
  convert_lon_l2s(lon,lon_str, sizeof(lon_str),CONVERT_HP_NOSP);
  TEST_ASSERT_STR_EQ("10612.385W",lon_str,"xastir x value correctly converted to string");
  TEST_PASS("convert_lon_l2s: correct");
}
int test_convert_lat_l2s_basic_s(void)
{
  long lat;
  char lat_str[20];
  // Compute Xastir coordinates for 35d01.631'S
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lat = 90*60*60*100+(35*60+1.631)*60*100;
  convert_lat_l2s(lat,lat_str, sizeof(lat_str),CONVERT_HP_NOSP);
  TEST_ASSERT_STR_EQ("3501.631S",lat_str,"xastir y value correctly converted to string");
  TEST_PASS("convert_lat_l2s: correct");
}
int test_convert_lon_l2s_basic_e(void)
{
  long lon;
  char lon_str[20];
  // Compute Xastir coordinates for 106d12.385'E
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lon = 180*60*60*100+(106*60+12.385)*60*100;
  convert_lon_l2s(lon,lon_str, sizeof(lon_str),CONVERT_HP_NOSP);
  TEST_ASSERT_STR_EQ("10612.385E",lon_str,"xastir x value correctly converted to string");
  TEST_PASS("convert_lon_l2s: correct");
}
int test_convert_lat_l2s_lp(void)
{
  long lat;
  char lat_str[20];
  // Compute Xastir coordinates for 35d01.631'N
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lat = 90*60*60*100-(35*60+1.631)*60*100;
  convert_lat_l2s(lat,lat_str, sizeof(lat_str),CONVERT_LP_NOSP);
  TEST_ASSERT_STR_EQ("3501.63N",lat_str,"xastir y value correctly converted to string");
  TEST_PASS("convert_lat_l2s: correct");
}
int test_convert_lon_l2s_lp(void)
{
  long lon;
  char lon_str[20];
  // Compute Xastir coordinates for 106d12.384'W
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  // we're using ".384" here because ".385" would get rounded up, not truncated.
  lon = 180*60*60*100-(106*60+12.384)*60*100;
  convert_lon_l2s(lon,lon_str, sizeof(lon_str),CONVERT_LP_NOSP);
  TEST_ASSERT_STR_EQ("10612.38W",lon_str,"xastir x value correctly converted to string");
  TEST_PASS("convert_lon_l2s: correct");
}
int test_convert_lat_s2l_basic(void)
{
  long lat;
  long lat_expect;
  // Compute Xastir coordinates for 35d01.631'N
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lat_expect = 90*60*60*100-(35*60+1.631)*60*100;
  lat = convert_lat_s2l("3501.631N");
  TEST_ASSERT(lat==lat_expect,"xastir y value correctly converted from string");
  TEST_PASS("convert_lat_s2l: correct");
}
int test_convert_lon_s2l_basic(void)
{
  long lon;
  long lon_expect;
  // Compute Xastir coordinates for 106d12.385'W
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lon_expect = 180*60*60*100-(106*60+12.385)*60*100;
  lon = convert_lon_s2l("10612.385W");
  TEST_ASSERT(lon==lon_expect,"xastir x value correctly converted from string");
  TEST_PASS("convert_lon_s2l: correct");
}
int test_convert_lat_s2l_basic_s(void)
{
  long lat;
  long lat_expect;
  // Compute Xastir coordinates for 35d01.631'S
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lat_expect = 90*60*60*100+(35*60+1.631)*60*100;
  lat = convert_lat_s2l("3501.631S");
  TEST_ASSERT(lat==lat_expect,"xastir y value correctly converted from string");
  TEST_PASS("convert_lat_s2l: correct");
}
int test_convert_lon_s2l_basic_e(void)
{
  long lon;
  long lon_expect;
  // Compute Xastir coordinates for 106d12.385'E
  // Xastir coordinates are in hundredths of seconds, with 0 being 90d N
  lon_expect = 180*60*60*100+(106*60+12.385)*60*100;
  lon = convert_lon_s2l("10612.385E");
  TEST_ASSERT(lon==lon_expect,"xastir x value correctly converted from string");
  TEST_PASS("convert_lon_s2l: correct");
}

// Check that s2l->l2s gives back what we started with.
int test_s2l_l2s_consistency(void)
{
  long lon;
  long lat;
  char lon_s[10+1];
  char lat_s[9+1];
  lon=convert_lon_s2l("10612.385W");
  lat=convert_lat_s2l("3501.631N");
  convert_lon_l2s(lon,lon_s,sizeof(lon_s),CONVERT_HP_NOSP);
  convert_lat_l2s(lat,lat_s,sizeof(lat_s),CONVERT_HP_NOSP);

  TEST_ASSERT_STR_EQ("3501.631N",lat_s,"Round-trip latitude consistent");
  TEST_ASSERT_STR_EQ("10612.385W",lon_s,"Round-trip longitude consistent");
  TEST_PASS("convert_lon_s2l and back: correct");
}
// Check that l2s->s2l gives back what we started with.
int test_l2s_s2l_consistency(void)
{
  long lon;
  long lat;
  long lon_return;
  long lat_return;
  char lon_s[10+1];
  char lat_s[9+1];
  lon = 180*60*60*100-(106*60+12.385)*60*100;
  lat = 90*60*60*100-(35*60+1.631)*60*100;
  convert_lon_l2s(lon,lon_s,sizeof(lon_s),CONVERT_HP_NOSP);
  convert_lat_l2s(lat,lat_s,sizeof(lat_s),CONVERT_HP_NOSP);
  lat_return = convert_lat_s2l(lat_s);
  lon_return = convert_lon_s2l(lon_s);
  TEST_ASSERT(lat==lat_return,"Round-trip latitude consistent");
  TEST_ASSERT(lon==lon_return,"Round-trip longitude consistent");
  TEST_PASS("convert_lon_s2l and back: correct");
}

// Note that this is *identical* to the previous function except it
// calls convert_xastir_to_screen_coordinates instead of having hard-coded
// junk in it.
int test_convert_xastir_to_screen_coordinates(void)
{
  // presume screen to be 1900x712 pixels
  // NW corner 3515.704N 10706.340W
  // SW corner 3454.727N 10548.923W
  // the "long" coords are in centi-seconds (1/100 second)
  // scale_x and scale_y are centi-seconds per pixel
  long screen_x, screen_y;

  screen_width=1900;
  screen_height=712;
  NW_corner_longitude = convert_lon_s2l("10706.340W");
  NW_corner_latitude  = convert_lat_s2l("3515.704N");
  SE_corner_longitude = convert_lon_s2l("10548.923W");
  SE_corner_latitude  = convert_lat_s2l("3454.727N");
  // Remember that Xastir coords are 0,0 at 90N 180W and increase as we
  // go east and south.
  scale_x = (SE_corner_longitude - NW_corner_longitude)/screen_width;
  scale_y = (SE_corner_latitude - NW_corner_latitude)/screen_height;
  center_latitude = (NW_corner_latitude + SE_corner_latitude)/2;
  center_longitude = (NW_corner_longitude + SE_corner_longitude)/2;

  // Now, Xastir itself actually makes the center lat/lon the primary
  // variable, and recomputes NW and SW based on that and the scale.  Let's
  // do that ourselves now.  Otherwise we get rounding problems later.

  NW_corner_longitude = center_longitude - (screen_width*scale_x)/2;
  NW_corner_latitude  = center_latitude  - (screen_height*scale_y)/2;
  SE_corner_longitude = center_longitude + (screen_width*scale_x)/2;
  SE_corner_latitude  = center_latitude  + (screen_height*scale_y)/2;

  // Now try to convert this back to screen coords using the
  // utility function
  convert_xastir_to_screen_coordinates(center_longitude, center_latitude, &screen_x, &screen_y);

  // We expect these screen coords to be screen_width/2, screen_height/2
  TEST_ASSERT(screen_x == screen_width/2, "center lon maps onto center pixel");
  TEST_ASSERT(screen_y == screen_height/2, "center lat maps onto center pixel.");

  // Now what about NW and SE corners?

  convert_xastir_to_screen_coordinates(NW_corner_longitude, NW_corner_latitude, &screen_x, &screen_y);
  // We expect these screen coords to be 0,0
  TEST_ASSERT(screen_x == 0, "NW corner lon maps onto top left pixel");
  TEST_ASSERT(screen_y == 0, "NW corner lat maps onto top left pixel.");

  // now the SE corner

  convert_xastir_to_screen_coordinates(SE_corner_longitude, SE_corner_latitude, &screen_x, &screen_y);

  // We expect these screen coords to be screen_width, screen_height
  TEST_ASSERT(screen_x == screen_width, "SE corner lon maps onto bot right pixel");
  TEST_ASSERT(screen_y == screen_height, "SE corner lat maps onto bot right pixel.");

  TEST_PASS("convert_xastir_to_screen_coordinates: works as expected");
}

int test_short_filename_for_status_notrunc(void)
{
  char filename[MAX_FILENAME]="this_is_short.shp";
  char short_filename[MAX_FILENAME];

  short_filename_for_status(filename, short_filename, sizeof(short_filename));

  TEST_ASSERT_STR_EQ("this_is_short.shp", short_filename, "Name not truncated if already short enough");
  TEST_PASS("short_filename_for_status");
}
int test_short_filename_for_status_trunc(void)
{
  char filename[MAX_FILENAME]="/a/long/path/with/lots/of/components/basename.shp";
  char short_filename[MAX_FILENAME];

  short_filename_for_status(filename, short_filename, sizeof(short_filename));

  TEST_ASSERT_STR_EQ("..ots/of/components/basename.shp", short_filename, "Name truncated if long");
  TEST_PASS("short_filename_for_status");
}

/* Test runner */
typedef struct {
    const char *name;
    int (*func)(void);
} test_case_t;

int main(int argc, char *argv[])
{
  test_case_t tests[] = {
    {"convert_lat_l2s_basic",test_convert_lat_l2s_basic},
    {"convert_lon_l2s_basic",test_convert_lon_l2s_basic},
    {"convert_lat_l2s_basic_s",test_convert_lat_l2s_basic_s},
    {"convert_lon_l2s_basic_e",test_convert_lon_l2s_basic_e},
    {"convert_lat_l2s_lp",test_convert_lat_l2s_lp},
    {"convert_lon_l2s_lp",test_convert_lon_l2s_lp},
    {"convert_lat_s2l_basic",test_convert_lat_s2l_basic},
    {"convert_lon_s2l_basic",test_convert_lon_s2l_basic},
    {"convert_lat_s2l_basic_s",test_convert_lat_s2l_basic_s},
    {"convert_lon_s2l_basic_e",test_convert_lon_s2l_basic_e},
    {"s2l_l2s_consistency",test_s2l_l2s_consistency},
    {"l2s_s2l_consistency",test_l2s_s2l_consistency},
    {"convert_xastir_to_screen_coordinates", test_convert_xastir_to_screen_coordinates},
    {"short_filename_for_status_notrunc",test_short_filename_for_status_notrunc},
    {"short_filename_for_status_trunc",test_short_filename_for_status_trunc},
    {NULL,NULL}
  };


  if (argc < 2)
  {
    fprintf(stderr, "Usage: %s <test name>\n", argv[0]);
    fprintf(stderr, "Available tests: \n");
    for (int i = 0; tests[i].name != NULL; i++)
    {
      fprintf(stderr, "  %s\n", tests[i].name);
    }
    return 1;
  }

  const char *test_name = argv[1];

  /* Run the requested test */
  for (int i = 0; tests[i].name != NULL; i++)
  {
    if (strcmp(test_name, tests[i].name) == 0)
    {
      return tests[i].func();
    }
  }

  fprintf(stderr, "Unknown test: %s\n", test_name);
  return 1;
}