Example #1
0
  /**
   * Test the functions getXxxMinimum() and getXxxMaximum() by marching a test calendar 'cal'
   * through 'numberOfDays' sequential days starting with 'startDate'. For each date, read a field
   * value along with its reported actual minimum and actual maximum. These values are checked
   * against one another as well as against getMinimum(), getGreatestMinimum(), getLeastMaximum(),
   * and getMaximum(). We expect to see:
   *
   * <p>1. minimum <= actualMinimum <= greatestMinimum <= leastMaximum <= actualMaximum <= maximum
   *
   * <p>2. actualMinimum <= value <= actualMaximum
   *
   * <p>Note: In addition to outright failures, this test reports some results as warnings. These
   * are not generally of concern, but they should be evaluated by a human. To see these, run this
   * test in verbose mode.
   *
   * @param cal the calendar to be tested
   * @param fieldsToTest an array of field values to be tested, e.g., new int[] { Calendar.MONTH,
   *     Calendar.DAY_OF_MONTH }. It only makes sense to test the day fields; the time fields are
   *     not tested by this method. If null, then test all standard fields.
   * @param startDate the first date to test
   * @param testDuration if positive, the number of days to be tested. If negative, the number of
   *     seconds to run the test.
   */
  public void doLimitsTest(Calendar cal, int[] fieldsToTest, Date startDate, int testDuration) {
    GregorianCalendar greg = new GregorianCalendar();
    greg.setTime(startDate);
    logln("Start: " + startDate);

    if (fieldsToTest == null) {
      fieldsToTest =
          new int[] {
            Calendar.ERA,
            Calendar.YEAR,
            Calendar.MONTH,
            Calendar.WEEK_OF_YEAR,
            Calendar.WEEK_OF_MONTH,
            Calendar.DAY_OF_MONTH,
            Calendar.DAY_OF_YEAR,
            Calendar.DAY_OF_WEEK_IN_MONTH,
            Calendar.YEAR_WOY,
            Calendar.EXTENDED_YEAR
          };
    }

    // Keep a record of minima and maxima that we actually see.
    // These are kept in an array of arrays of hashes.
    Map[][] limits = new Map[fieldsToTest.length][2];
    Object nub = new Object(); // Meaningless placeholder

    // This test can run for a long time; show progress.
    long millis = System.currentTimeMillis();
    long mark = millis + 5000; // 5 sec
    millis -= testDuration * 1000; // stop time if testDuration<0

    for (int i = 0;
        testDuration > 0 ? i < testDuration : System.currentTimeMillis() < millis;
        ++i) {
      if (System.currentTimeMillis() >= mark) {
        logln("(" + i + " days)");
        mark += 5000; // 5 sec
      }
      cal.setTimeInMillis(greg.getTimeInMillis());
      for (int j = 0; j < fieldsToTest.length; ++j) {
        int f = fieldsToTest[j];
        int v = cal.get(f);
        int minActual = cal.getActualMinimum(f);
        int maxActual = cal.getActualMaximum(f);
        int minLow = cal.getMinimum(f);
        int minHigh = cal.getGreatestMinimum(f);
        int maxLow = cal.getLeastMaximum(f);
        int maxHigh = cal.getMaximum(f);

        // Fetch the hash for this field and keep track of the
        // minima and maxima.
        Map[] h = limits[j];
        if (h[0] == null) {
          h[0] = new HashMap();
          h[1] = new HashMap();
        }
        h[0].put(new Integer(minActual), nub);
        h[1].put(new Integer(maxActual), nub);

        if (minActual < minLow || minActual > minHigh) {
          errln(
              "Fail: "
                  + ymdToString(cal)
                  + " Range for min of "
                  + FIELD_NAME[f]
                  + "("
                  + f
                  + ")="
                  + minLow
                  + ".."
                  + minHigh
                  + ", actual_min="
                  + minActual);
        }
        if (maxActual < maxLow || maxActual > maxHigh) {
          errln(
              "Fail: "
                  + ymdToString(cal)
                  + " Range for max of "
                  + FIELD_NAME[f]
                  + "("
                  + f
                  + ")="
                  + maxLow
                  + ".."
                  + maxHigh
                  + ", actual_max="
                  + maxActual);
        }
        if (v < minActual || v > maxActual) {
          errln(
              "Fail: "
                  + ymdToString(cal)
                  + " "
                  + FIELD_NAME[f]
                  + "("
                  + f
                  + ")="
                  + v
                  + ", actual range="
                  + minActual
                  + ".."
                  + maxActual
                  + ", allowed=("
                  + minLow
                  + ".."
                  + minHigh
                  + ")..("
                  + maxLow
                  + ".."
                  + maxHigh
                  + ")");
        }
      }
      greg.add(Calendar.DAY_OF_YEAR, 1);
    }

    // Check actual maxima and minima seen against ranges returned
    // by API.
    StringBuffer buf = new StringBuffer();
    for (int j = 0; j < fieldsToTest.length; ++j) {
      int f = fieldsToTest[j];
      buf.setLength(0);
      buf.append(FIELD_NAME[f]);
      Map[] h = limits[j];
      boolean fullRangeSeen = true;
      for (int k = 0; k < 2; ++k) {
        int rangeLow = (k == 0) ? cal.getMinimum(f) : cal.getLeastMaximum(f);
        int rangeHigh = (k == 0) ? cal.getGreatestMinimum(f) : cal.getMaximum(f);
        // If either the top of the range or the bottom was never
        // seen, then there may be a problem.
        if (h[k].get(new Integer(rangeLow)) == null || h[k].get(new Integer(rangeHigh)) == null) {
          fullRangeSeen = false;
        }
        buf.append(k == 0 ? " minima seen=(" : "; maxima seen=(");
        for (Object v : h[k].keySet()) {
          buf.append(" " + v);
        }
        buf.append(") range=" + rangeLow + ".." + rangeHigh);
      }
      if (fullRangeSeen) {
        logln("OK: " + buf.toString());
      } else {
        // This may or may not be an error -- if the range of dates
        // we scan over doesn't happen to contain a minimum or
        // maximum, it doesn't mean some other range won't.
        logln("Warning: " + buf.toString());
      }
    }

    logln("End: " + greg.getTime());
  }