/**
  * Tests PFXUtils::testSettingTypes().
  *
  * @runInSeparateProcess
  * @preserveGlobalState disabled
  */
 public function testTestSettingTypes()
 {
     define('PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_1', 'foo');
     define('PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_2', '  foo ');
     define('PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_3', 'Foobar');
     define('PFXUTILS_TEST_SETTING_REGEX_MATCH_FAIL_1', 'bar ');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_REGEX_MATCH_PASS_1', ' foo');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_REGEX_MATCH_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_BOOLEAN_PASS_1', true);
     define('PFXUTILS_TEST_SETTING_BOOLEAN_PASS_2', false);
     define('PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_1', 0);
     define('PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_2', '');
     define('PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_3', 1);
     define('PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_4', 'true');
     define('PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_5', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_BOOLEAN_PASS_1', false);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_BOOLEAN_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_STRING_PASS_1', '');
     define('PFXUTILS_TEST_SETTING_STRING_PASS_2', 'asdf');
     define('PFXUTILS_TEST_SETTING_STRING_FAIL_1', null);
     define('PFXUTILS_TEST_SETTING_STRING_FAIL_2', 72);
     define('PFXUTILS_TEST_SETTING_STRING_FAIL_3', true);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_STRING_PASS_1', 'ao dsoigra 0a428h7 ');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_STRING_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_INTEGER_PASS_1', 0);
     define('PFXUTILS_TEST_SETTING_INTEGER_PASS_2', 293834);
     define('PFXUTILS_TEST_SETTING_INTEGER_PASS_3', '-2398034');
     define('PFXUTILS_TEST_SETTING_INTEGER_FAIL_1', 0.1);
     define('PFXUTILS_TEST_SETTING_INTEGER_FAIL_2', '0.1');
     define('PFXUTILS_TEST_SETTING_INTEGER_FAIL_3', 'a8924h898hrwga');
     define('PFXUTILS_TEST_SETTING_INTEGER_FAIL_4', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_INTEGER_PASS_1', 1);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_INTEGER_PASS_2', null);
     /* Make sure all the tests that are meant to pass the integer tests
        pass the numeric tests as well. */
     define('PFXUTILS_TEST_SETTING_NUM_PASS_1', 0.1);
     define('PFXUTILS_TEST_SETTING_NUM_PASS_2', '0.1');
     define('PFXUTILS_TEST_SETTING_NUM_PASS_3', 0x1ff);
     define('PFXUTILS_TEST_SETTING_NUM_PASS_4', '1.2345e5');
     define('PFXUTILS_TEST_SETTING_NUM_FAIL_1', 'zero');
     define('PFXUTILS_TEST_SETTING_NUM_FAIL_2', true);
     define('PFXUTILS_TEST_SETTING_NUM_FAIL_3', null);
     define('PFXUTILS_TEST_SETTING_NUM_FAIL_4', 'dsiapin op98ae9 8ba9d');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_NUM_PASS_1', '23');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_NUM_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_RATIO_PASS_1', 0);
     define('PFXUTILS_TEST_SETTING_RATIO_PASS_2', 1);
     define('PFXUTILS_TEST_SETTING_RATIO_PASS_3', 2 / 3);
     define('PFXUTILS_TEST_SETTING_RATIO_PASS_4', '0.7');
     define('PFXUTILS_TEST_SETTING_RATIO_FAIL_1', -1);
     define('PFXUTILS_TEST_SETTING_RATIO_FAIL_2', '1.1');
     define('PFXUTILS_TEST_SETTING_RATIO_FAIL_3', '1/2');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_RATIO_PASS_1', 0.234);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_RATIO_PASS_2', null);
     $tempFile = self::_createTempFile();
     self::$_tempFiles[] = $tempLink = self::$_tempDir . DIRECTORY_SEPARATOR . uniqid();
     symlink($tempFile, $tempLink);
     define('PFXUTILS_TEST_SETTING_FILE_PASS_1', $tempFile);
     define('PFXUTILS_TEST_SETTING_FILE_PASS_2', $tempLink);
     define('PFXUTILS_TEST_SETTING_FILE_FAIL_1', dirname($tempFile));
     define('PFXUTILS_TEST_SETTING_FILE_FAIL_2', 'asdofijasdf');
     define('PFXUTILS_TEST_SETTING_FILE_FAIL_3', null);
     define('PFXUTILS_TEST_SETTING_FILE_FAIL_4', true);
     define('PFXUTILS_TEST_SETTING_FILE_FAIL_5', 3);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_FILE_PASS_1', $tempFile);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_FILE_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_DIR_PASS_1', dirname($tempFile));
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_1', dirname($tempFile) . DIRECTORY_SEPARATOR);
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_2', null);
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_3', $tempFile);
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_4', 'asdf');
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_5', true);
     define('PFXUTILS_TEST_SETTING_DIR_FAIL_6', 98027);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_DIR_PASS_1', __DIR__);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_DIR_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_WRITABLE_PASS_1', $tempFile);
     define('PFXUTILS_TEST_SETTING_WRITABLE_PASS_2', self::_createTempFile());
     define('PFXUTILS_TEST_SETTING_WRITABLE_FAIL_1', '/some/path/that/does/not/exist');
     define('PFXUTILS_TEST_SETTING_WRITABLE_FAIL_2', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_WRITABLE_PASS_1', $tempFile);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_WRITABLE_PASS_2', null);
     define('PFXUTILS_TEST_SETTING_EMAIL_PASS_1', '*****@*****.**');
     define('PFXUTILS_TEST_SETTING_EMAIL_PASS_2', 'me@website.com,you@other-website.com');
     define('PFXUTILS_TEST_SETTING_EMAIL_FAIL_1', 'me@');
     define('PFXUTILS_TEST_SETTING_EMAIL_FAIL_2', false);
     define('PFXUTILS_TEST_SETTING_EMAIL_FAIL_3', 3);
     define('PFXUTILS_TEST_SETTING_EMAIL_FAIL_4', 'sadfoij');
     define('PFXUTILS_TEST_SETTING_EMAIL_FAIL_5', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_EMAIL_PASS_1', '*****@*****.**');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_EMAIL_PASS_2', null);
     // I hope this isn't too brittle of an assumption
     define('PFXUTILS_TEST_SETTING_EXECUTABLE_PASS_1', '/usr/bin/php');
     define('PFXUTILS_TEST_SETTING_EXECUTABLE_FAIL_1', 'oisajdf');
     define('PFXUTILS_TEST_SETTING_EXECUTABLE_FAIL_2', true);
     define('PFXUTILS_TEST_SETTING_EXECUTABLE_FAIL_3', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_EXECUTABLE_PASS_1', '/usr/bin/php');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_EXECUTABLE_PASS_2', null);
     /* Since this validation is actually done by the URL class under the
        hood and that is pretty thoroughly covered with unit tests, I'm not
        going to go nuts testing multiple URL variants here. */
     define('PFXUTILS_TEST_SETTING_URL_PASS_1', 'http://www.foo.bar/?a=1');
     define('PFXUTILS_TEST_SETTING_URL_PASS_2', 'http://asdf');
     define('PFXUTILS_TEST_SETTING_URL_FAIL_1', 'www.foo.bar');
     define('PFXUTILS_TEST_SETTING_URL_FAIL_2', 'asdf');
     define('PFXUTILS_TEST_SETTING_URL_FAIL_3', 29376);
     define('PFXUTILS_TEST_SETTING_URL_FAIL_4', false);
     define('PFXUTILS_TEST_SETTING_URL_FAIL_5', null);
     define('PFXUTILS_TEST_SETTING_OPTIONAL_URL_PASS_1', 'http://www.foo.bar/?a=1');
     define('PFXUTILS_TEST_SETTING_OPTIONAL_URL_PASS_2', null);
     $tests = array('boolean', 'string', 'integer', 'num', 'ratio', 'file', 'dir', 'writable', 'email', 'executable', 'url');
     // Build a settings array containing one setting of each type
     $settings = array();
     foreach ($tests as $test) {
         $settings['PFXUTILS_TEST_SETTING_' . strtoupper($test) . '_PASS_1'] = $test;
     }
     // Add some regex tests
     $settings['PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_1'] = '/foo/';
     $settings['PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_2'] = '/foo/';
     $settings['PFXUTILS_TEST_SETTING_REGEX_MATCH_PASS_3'] = '/^foo/i';
     PFXUtils::testSettingTypes($settings);
     // Try with a mixture of passing and failing settings
     $settings = array('PFXUTILS_TEST_SETTING_REGEX_MATCH_FAIL_1' => '/foo/', 'PFXUTILS_TEST_SETTING_STRING_PASS_2' => 'str', 'PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_1' => 'bool', 'PFXUTILS_TEST_SETTING_INTEGER_FAIL_1' => 'int', 'PFXUTILS_TEST_SETTING_NUM_PASS_2' => 'number');
     $this->assertThrows('SettingException', array('PFXUtils', 'testSettingTypes'), array($settings));
     // Remove the failing ones and try again
     unset($settings['PFXUTILS_TEST_SETTING_REGEX_MATCH_FAIL_1']);
     unset($settings['PFXUTILS_TEST_SETTING_BOOLEAN_FAIL_1']);
     unset($settings['PFXUTILS_TEST_SETTING_INTEGER_FAIL_1']);
     PFXUtils::testSettingTypes($settings);
     /* Try a mix of normal settings, ones that are optional and set
        correctly, and ones that are optional and not set. */
     $settings = array('PFXUTILS_TEST_SETTING_BOOLEAN_PASS_2' => 'boolean', 'PFXUTILS_TEST_SETTING_INTEGER_PASS_3' => 'integer', 'PFXUTILS_TEST_SETTING_OPTIONAL_REGEX_MATCH_PASS_1' => '?/foo$/', 'PFXUTILS_TEST_SETTING_OPTIONAL_BOOLEAN_PASS_2' => '?bool');
     PFXUtils::testSettingTypes($settings);
     /* Now try the same thing, including one that is optional but set to
        something inappropriate. */
     $settings = array('PFXUTILS_TEST_SETTING_NUM_PASS_3' => 'numeric', 'PFXUTILS_TEST_SETTING_OPTIONAL_NUM_PASS_1' => '?num', 'PFXUTILS_TEST_SETTING_NUM_FAIL_4' => '?number', 'PFXUTILS_TEST_SETTING_OPTIONAL_REGEX_MATCH_PASS_2' => '?/foo/', 'PFXUTILS_TEST_SETTING_OPTIONAL_DIR_PASS_1' => '?directory');
     $this->assertThrows('SettingException', array('PFXUtils', 'testSettingTypes'), array($settings));
     unset($settings['PFXUTILS_TEST_SETTING_NUM_FAIL_4']);
     PFXUtils::testSettingTypes($settings);
     // Now make sure all the test constants get tested
     foreach ($tests as $test) {
         $i = 0;
         while (true) {
             $constName = 'PFXUTILS_TEST_SETTING_' . strtoupper($test) . '_PASS_' . ++$i;
             if (!defined($constName)) {
                 break;
             }
             PFXUtils::testSettingTypes(array($constName => $test));
         }
     }
     foreach ($tests as $test) {
         $i = 0;
         while (true) {
             $constName = 'PFXUTILS_TEST_SETTING_' . strtoupper($test) . '_FAIL_' . ++$i;
             if (!defined($constName)) {
                 break;
             }
             $this->assertThrows('SettingException', array('PFXUtils', 'testSettingTypes'), array(array($constName => $test)), 'Failed to throw expected exception when testing ' . $constName . '.');
         }
     }
 }