Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bsltf_testvaluesarray
[Package bsltf]

Provide a container for values used for testing. More...

Namespaces

namespace  bsltf

Detailed Description

Outline
Purpose:
Provide a container for values used for testing.
Classes:
bsltf::TestValuesArray container for values used for testing
bsltf::TestValuesArrayIterator iterator for the container
See also:
Component bsltf_templatetestfacility
Description:
This component defines a class bsltf::TestValuesArray providing a uniform interface for creating and accessing a sequence of test values of a type that has a copy constructor, and may or may not have a default constructor.
This component also defines an iterator class bsltf::TestValuesArrayIterator providing access to elements in a TestValuesArray object. TestValuesArrayIterator is designed to satisfies the minimal requirement of an input iterator as defined by the C++11 standard [24.2.3]. It uses the BSLS_ASSERT macro to detect undefined behavior.
The sequence described by this container is an input-range, that may be traversed exactly once. Once an iterator is incremented, any other iterator at the same position in the sequence is invalidated. The TestValuesArray object provides a resetIterators method that restores the ability to iterate the container.
Iterator:
The requirements of the input iterators as defined by the C++11 standard may not be as tight as the users of the input iterators expected. Incorrect assumptions about the properties of the input iterator may result in undefined behavior. TestValuesArrayIterator is designed to detect possible incorrect usages. Specifically, TestValuesArrayIterator put restriction on when it can be dereferenced or compared. A TestValuesArrayIterator is considered to be dereferenceable if it satisfies all of the following:
  1. The iterator refers to a valid element (not end).
  2. The iterator has not been dereferenced. (*)
  3. The iterator is not a copy of another iterator of which operator++ have been invoked. (see [table 107] of the C++11 standard)
*note: An input iterator may not be dereferenced more than once is a common requirement of a container method that takes input iterators as arguments. Other standard algorithms may allow the iterator to be dereferenced more than once, in which case, TestValuesArrayIterator is not suitable to be used to with those algorithms.
TestValuesArrayIterator is comparable if the iterator is not a copy of another iterator of which operator++ have been invoked.
Thread Safety:
This component is not thread-safe, by any definition of the term, and should not be used in test scenarios concerned with concurrent code.
Usage:
This section illustrates intended use of this component.
Example 1: Testing a Simple Template Function:
Suppose that we have a function that we would like to test. This function take in a range defined by two input iterators and returns the largest value in that range.
First, we define the function we would like to test:
  template <class VALUE, class INPUT_ITERATOR>
  VALUE myMaxValue(INPUT_ITERATOR first, INPUT_ITERATOR last)
      // Return the largest value referred to by the iterators in the range
      // beginning at the specified 'first' and up to, but not including, the
      // specified 'last'.  The behavior is undefined unless [first, last)
      // specifies a valid range and 'first != last'.
  {
      assert(first != last);

      VALUE largestValue(*first);
      ++first;
      for(;first != last; ++first) {
          // Store in temporary variable to avoid dereferencing twice.

          const VALUE& temp = *first;
          if (largestValue < temp) {
              largestValue = temp;
          }
      }
      return largestValue;
  }
Next, we implement a test function runTest that allows the function to be tested with different types:
  template <class VALUE>
  void runTest()
      // Test driver.
  {
Then, we define a set of test values and expected results:
      struct {
          const char *d_spec;
          const char  d_result;
      } DATA[] = {
          { "A",     'A' },
          { "ABC",   'C' },
          { "ADCB",  'D' },
          { "EDCBA", 'E' }
      };
      const size_t NUM_DATA = sizeof DATA / sizeof *DATA;
Now, for each set of test values, verify that the function return the expected result.
      for (size_t i = 0; i < NUM_DATA; ++i) {
          const char *const SPEC = DATA[i].d_spec;
          const VALUE       EXP  =
                bsltf::TemplateTestFacility::create<VALUE>(DATA[i].d_result);

          bsltf::TestValuesArray<VALUE> values(SPEC);
          assert(EXP == myMaxValue<VALUE>(values.begin(), values.end()));
      }
  }
Finally, we invoke the test function to verify our function is implemented correctly. The test function to run without triggering the assert statement:
  runTest<char>();