From 1e1af922fe4ea79be44b28faec27d87a0a22077b Mon Sep 17 00:00:00 2001 From: Don Cross Date: Sat, 2 May 2020 13:33:25 -0400 Subject: [PATCH] Constellations: Added C unit test. Fixed bugs in C code. This unit test only exercises 8 different points. I want to add a more thorough unit test soon, before moving on to implementing the constellation finder in the other supported programming languages. --- generate/codegen.c | 15 +++++- generate/constellation/test_input.txt | 1 - generate/ctest.c | 69 +++++++++++++++++++++++++++ generate/template/astronomy.c | 18 ++++--- generate/unit_test_c | 1 + source/c/astronomy.c | 20 +++++--- 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/generate/codegen.c b/generate/codegen.c index dc462624..8eec0b10 100644 --- a/generate/codegen.c +++ b/generate/codegen.c @@ -1381,7 +1381,20 @@ static int ConstellationData(cg_context_t *context) } } - fprintf(context->outfile, "};\n\n"); + switch (context->language) + { + case CODEGEN_LANGUAGE_C: + fprintf(context->outfile, "};\n\n"); + fprintf(context->outfile, "#define NUM_CONSTEL_BOUNDARIES %d\n\n", lnum); + break; + + case CODEGEN_LANGUAGE_CSHARP: + case CODEGEN_LANGUAGE_JS: + case CODEGEN_LANGUAGE_PYTHON: + default: + CHECK(LogError(context, "ConstellationData(4): Unsupported language %d", context->language)); + } + error = 0; fail: if (infile) fclose(infile); diff --git a/generate/constellation/test_input.txt b/generate/constellation/test_input.txt index 3621127e..6a8d7618 100644 --- a/generate/constellation/test_input.txt +++ b/generate/constellation/test_input.txt @@ -1,4 +1,3 @@ -1950. 9.0000 +65.0000 UMa 23.5000 -20.0000 Aqr 5.1200 +09.1200 Ori diff --git a/generate/ctest.c b/generate/ctest.c index f8c74b70..1e2d1f06 100644 --- a/generate/ctest.c +++ b/generate/ctest.c @@ -69,6 +69,7 @@ static int TestMaxMag(astro_body_t body, const char *filename); static const char *ParseJplHorizonsDateTime(const char *text, astro_time_t *time); static int VectorDiff(astro_vector_t a, astro_vector_t b, double *diff); static int RefractionTest(void); +static int ConstellationTest(void); int main(int argc, const char *argv[]) { @@ -131,6 +132,12 @@ int main(int argc, const char *argv[]) CHECK(Issue48()); goto success; } + + if (!strcmp(verb, "constellation")) + { + CHECK(ConstellationTest()); + goto success; + } } if (argc == 3) @@ -2829,3 +2836,65 @@ static int RefractionTest(void) } /*-----------------------------------------------------------------------------------------------------------*/ + +static int ConstellationTest(void) +{ + int error = 1; + FILE *infile = NULL; + const char *inFileName = "constellation/test_input.txt"; + char line[100]; + double ra, dec; + char symbol[4]; + int lnum; + astro_constellation_t constel; + + infile = fopen(inFileName, "rt"); + if (infile == NULL) + { + fprintf(stderr, "ConstellationTest: Cannot open input file: %s\n", inFileName); + error = 1; + goto fail; + } + + lnum = 0; + while (fgets(line, sizeof(line), infile)) + { + ++lnum; + if (3 != sscanf(line, "%lf %lf %3s", &ra, &dec, symbol) || 3 != strlen(symbol)) + { + fprintf(stderr, "ConstellationTest: Invalid test data in %s line %d\n", inFileName, lnum); + error = 1; + goto fail; + } + + constel = Astronomy_FindConstellation(ra, dec); + if (constel.status != ASTRO_SUCCESS) + { + fprintf(stderr, "ConstellationTest: FAILED with status %d: %s line %d\n", constel.status, inFileName, lnum); + error = 1; + goto fail; + } + + if (constel.symbol == NULL || constel.name == NULL) + { + fprintf(stderr, "ConstellationTest: UNEXPECTED NULL name/symbol: %s line %d\n", inFileName, lnum); + error = 1; + goto fail; + } + + if (strcmp(constel.symbol, symbol)) + { + fprintf(stderr, "ConstellationTest: %s line %d: expected '%s', found '%s'\n", inFileName, lnum, symbol, constel.symbol); + error = 1; + goto fail; + } + } + + printf("ConstellationTest: PASS (verified %d)\n", lnum); + error = 0; +fail: + if (infile != NULL) fclose(infile); + return error; +} + +/*-----------------------------------------------------------------------------------------------------------*/ diff --git a/generate/template/astronomy.c b/generate/template/astronomy.c index 1bfdebba..f5255306 100644 --- a/generate/template/astronomy.c +++ b/generate/template/astronomy.c @@ -5244,10 +5244,10 @@ constel_info_t; typedef struct { - double dec_lo; + int index; double ra_lo; double ra_hi; - int index; + double dec_lo; } constel_boundary_t; /** @endcond */ @@ -5279,7 +5279,7 @@ astro_constellation_t Astronomy_FindConstellation(double ra, double dec) astro_constellation_t constel; astro_equatorial_t j2000, b1875; astro_vector_t vec2000, vec1875; - int i; + int i, c; if (dec < -90.0 || dec > +90.0) return ConstelErr(ASTRO_INVALID_PARAMETER); @@ -5318,19 +5318,23 @@ astro_constellation_t Astronomy_FindConstellation(double ra, double dec) return ConstelErr(b1875.status); /* Search for the constellation using the B1875 coordinates. */ - for (i=0; i < NUM_CONSTELLATIONS; ++i) + c = -1; /* constellation not (yet) found */ + for (i=0; i < NUM_CONSTEL_BOUNDARIES; ++i) { const constel_boundary_t *b = &ConstelBounds[i]; if ((b->dec_lo <= b1875.dec) && (b->ra_hi > b1875.ra) && (b->ra_lo <= b1875.ra)) + { + c = b->index; break; + } } - if (i == NUM_CONSTELLATIONS) + if (c < 0 || c >= NUM_CONSTELLATIONS) return ConstelErr(ASTRO_INTERNAL_ERROR); /* should have been able to find the constellation */ constel.status = ASTRO_SUCCESS; - constel.symbol = ConstelInfo[i].symbol; - constel.name = ConstelInfo[i].name; + constel.symbol = ConstelInfo[c].symbol; + constel.name = ConstelInfo[c].name; return constel; } diff --git a/generate/unit_test_c b/generate/unit_test_c index b7e4c04e..5e185f08 100755 --- a/generate/unit_test_c +++ b/generate/unit_test_c @@ -8,6 +8,7 @@ Fail() ./ctest refraction || Fail "Failure in ctest refraction" ./ctest rotation || Fail "Failure in ctest rotation" ./ctest moon || Fail "Failure in ctest moon" +./ctest constellation || Fail "Failure in ctest constellation" time ./ctest check || Fail "Failure in ctest check" ./generate check temp/c_check.txt || Fail "Verification failure for C unit test output." ./ctest diff temp/c_check.txt temp/js_check.txt || Fail "Diff(C,JS) failure." diff --git a/source/c/astronomy.c b/source/c/astronomy.c index ae65f2c5..0d366a7e 100644 --- a/source/c/astronomy.c +++ b/source/c/astronomy.c @@ -6535,10 +6535,10 @@ constel_info_t; typedef struct { - double dec_lo; + int index; double ra_lo; double ra_hi; - int index; + double dec_lo; } constel_boundary_t; /** @endcond */ @@ -6996,6 +6996,8 @@ static const constel_boundary_t ConstelBounds[] = { , { 57, 0.0000, 24.0000, -90.0000 } /* Oct */ }; +#define NUM_CONSTEL_BOUNDARIES 357 + /** @@ -7023,7 +7025,7 @@ astro_constellation_t Astronomy_FindConstellation(double ra, double dec) astro_constellation_t constel; astro_equatorial_t j2000, b1875; astro_vector_t vec2000, vec1875; - int i; + int i, c; if (dec < -90.0 || dec > +90.0) return ConstelErr(ASTRO_INVALID_PARAMETER); @@ -7062,19 +7064,23 @@ astro_constellation_t Astronomy_FindConstellation(double ra, double dec) return ConstelErr(b1875.status); /* Search for the constellation using the B1875 coordinates. */ - for (i=0; i < NUM_CONSTELLATIONS; ++i) + c = -1; /* constellation not (yet) found */ + for (i=0; i < NUM_CONSTEL_BOUNDARIES; ++i) { const constel_boundary_t *b = &ConstelBounds[i]; if ((b->dec_lo <= b1875.dec) && (b->ra_hi > b1875.ra) && (b->ra_lo <= b1875.ra)) + { + c = b->index; break; + } } - if (i == NUM_CONSTELLATIONS) + if (c < 0 || c >= NUM_CONSTELLATIONS) return ConstelErr(ASTRO_INTERNAL_ERROR); /* should have been able to find the constellation */ constel.status = ASTRO_SUCCESS; - constel.symbol = ConstelInfo[i].symbol; - constel.name = ConstelInfo[i].name; + constel.symbol = ConstelInfo[c].symbol; + constel.name = ConstelInfo[c].name; return constel; }