diff --git a/admin/rehash.php b/admin/rehash.php --- a/admin/rehash.php +++ b/admin/rehash.php @@ -35,6 +35,14 @@ return main($argc, $argv); function main($argc, $argv) { + $n = test(); + if ($n) + { + fprintf(STDERR, "%d tests failed; exiting\n", + $n); + return 1; + } + $crawl = TRUE; $crawl_semester_year = '2011'; $crawl_semester_season = Semester::SEASON_SPRING; @@ -335,3 +343,104 @@ function usage($progname) . " data. Cached data from schools not listed is preserved\n", $progname); } + +/** + * \brief + * A small testsuite to help developers. + * + * \return + * Number of failures. + */ +function test() +{ + $ideal = array('department' => 'CS', + 'course' => '262', + 'section' => 'A'); + $ideal_c = $ideal; + unset($ideal_c['section']); + $n = 0; + + $t1 = 'CS-262-A'; + $n += assert_equal($t1, Section::parse($t1), $ideal); + $n += assert_equal($t1 . '_class', Classes::parse($t1), $ideal_c); + $t2 = 'cs262 a'; + $n += assert_equal($t2, Section::parse($t2), $ideal); + $n += assert_equal($t2 . '_class', Classes::parse($t2), $ideal_c); + $t3 = 'cs 262 a'; + $n += assert_equal($t3, Section::parse($t2), $ideal); + $n += assert_equal($t3 . '_class', Classes::parse($t3), $ideal_c); + + $ideal['course'] .= 'L'; + $ideal_c['course'] = $ideal['course']; + + $t1 = 'CS-262L-A'; + $n += assert_equal($t1, Section::parse($t1), $ideal); + $n += assert_equal($t1 . '_class', Classes::parse($t1), $ideal_c); + $t2 = 'cs262l a'; + $n += assert_equal($t2, Section::parse($t2), $ideal); + $n += assert_equal($t2 . '_class', Classes::parse($t2), $ideal_c); + $t3 = 'cs 262l a'; + $n += assert_equal($t3, Section::parse($t2), $ideal); + $n += assert_equal($t3 . '_class', Classes::parse($t3), $ideal_c); + + return $n; +} + +/** + * \brief + * A reimplementation of a standard testsuite utility. + * + * \return + * TRUE if the test failed. + */ +function assert_equal($name, $a, $b) +{ + if (is_array($a)) + { + $bad = FALSE; + if (!is_array($b)) + { + fprintf(STDERR, "Test ``%s'' failed: \$a is an array while \$b isn't.\n", + $name); + return TRUE; + } + + foreach ($a as $key => $val) + if (!$bad && isset($b[$key])) + $bad = assert_equal($name . '[' . $key . ']', $a[$key], $b[$key]); + else + $bad = TRUE; + foreach ($b as $key => $val) + if (!$bad && isset($a[$key])) + $bad = assert_equal($name . '[' . $key . ']', $a[$key], $b[$key]); + else + $bad = TRUE; + + if ($bad) + { + fprintf(STDERR, "Test ``%s'' failed, see previous error message\n", + $name); + return TRUE; + } + + return FALSE; + } + elseif (is_array($b)) + { + fprintf(STDERR, "Test ``%s'' failed: \$b is an array; \$a isn't.\n", + $name); + return TRUE; + } + elseif ($a === $b + && !strcmp($a, $b)) + { + return FALSE; + } + else + { + fprintf(STDERR, "Test ``%s'' failed: `%s' !== `%s', strcmp() == %d\n", + $name, $a, $b, strcmp($a, $b)); + return TRUE; + } + return TRUE; +} diff --git a/class.section.php b/class.section.php --- a/class.section.php +++ b/class.section.php @@ -206,9 +206,17 @@ class Section * section. * * For example, will return array('CS', '262', 'A') for 'CS-262-A' - * or 'CS262A' or 'cs-262a'. This function is not for dealing with + * or 'CS262 A' or 'cs-262,a'. This function is not for dealing with * course synonyms. * + * Note: Section specifiers where the section numeral/letter is + * directly adjacent to the course number is not valid. Calvin + * College distinguishes between normal courses and their labs by + * appending an `L' to the course number. Thus, 'CS262A' is not a + * valid specifier for 'CS-262-A' because there may exist another + * course called 'CS-262L-A' (which is likely the lab for the + * 'CS-262-A' class ;-)). + * * \param $section_spec * A string starting with a section specifier. If only the * department is found, an array of size one is returned. If the @@ -239,12 +247,12 @@ class Section $section_spec = trim(substr($section_spec, strlen($dept_matches[0]))); $ret['department'] = strtoupper($dept_matches[1]); - if (!preg_match(';([0-9]+)[^a-zA-Z0-9]*;', $section_spec, $course_matches)) + if (!preg_match(';([0-9a-zA-Z]+)[^a-zA-Z0-9]*;', $section_spec, $course_matches)) return $ret; /* skip gunk */ $section_spec = trim(substr($section_spec, strlen($course_matches[0]))); - $ret['course'] = $course_matches[1]; + $ret['course'] = strtoupper($course_matches[1]); /* * we accept _either_ alphabetic section _or_ numeric section (the