public function testMe()
 {
     $rules = '{"subscription_id" : "/([0-9]{1,15})/",
               "!asset_type"     :"/([a-z]{1,15})/",
               "*@coins"         :"/^([0-9]{1,15})$/",
               "*#offer_meta_data"  : {"*PRD_ID":"/^([0-9]{0,15})$/"},
               "@#subscription_meta_foo" : [{"*SOME_PRD_ID":"/([A-Z0-9]{0,2})/"}],
               "@#subscription_meta_data" : [{"*SOME_PRD_ID":"/([A-Z0-9]{0,2})/"}],
               "*views"         :"/([0-9]{1,10})/",
               "*does_expire"   :"/(true|false)/",
               "*offer_chain_id":"/([0-9]{1,15})/",
               "*expires_on"    :"/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/",
               "*expires"       :"/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/",
               "*starts"        :"/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/",
               "*!ignore"       :""}';
     $rules = json_decode($rules, true);
     $params = array('subscription_id' => 12345, 'views' => 'yes', 'coins' => array(12, 25, 21), 'subscription_meta_foo' => array(array('SOME_PRD_ID' => 12345)));
     $res = Validator::validate($rules, $params);
     $this->assertArrayHasKey('400', $res);
     fwrite(STDOUT, "We got back: " . print_r($res, true) . "\n");
     $params = array('subscription_id' => 12345, 'views' => 'yes', 'coins' => array(-12, 25, 21));
     $res = Validator::validate($rules, $params);
     $this->assertArrayHasKey('400', $res);
     fwrite(STDOUT, "We got back: " . print_r($res, true) . "\n");
     $params = 12;
     $fail = Validator::validate($rules, $params);
     $this->assertNotNull($fail, 'We should get an array back failure becuase we did not pass an array to the validator');
 }
 /**
  * The run function normally expects no parameters, adding url and params
  * to support testing with simple test.
  * @codeCoverageIgnore
  * @param $routes  - the routes supported, intended to be sent from classes extending this class
  * @param $path    - support unit tests
  * @param $params  - support unit tests
  * @return hash    - e.g. array(200=>$result) or array(404=>'NOT FOUND');
  */
 public function run(&$routes, $path = null, $params = array())
 {
     $notfound = array(ResponseCodes::NOTFOUND => 'NOT FOUND.');
     $notsupported = array(ResponseCodes::NOTSUPPORTED => 'NOT SUPPORTED.');
     $found = false;
     $out = empty($routes['std_out']) ? null : $routes['std_out'];
     $err = empty($routes['std_err']) ? null : $routes['std_err'];
     $filters = empty($routes['filters']) ? array() : $routes['filters'];
     $this->routes = $routes;
     if (empty($path) && !empty($_SERVER['SCRIPT_NAME'])) {
         $path = $_SERVER['SCRIPT_NAME'];
     }
     if (!empty($params)) {
         $this->params = $params;
     } elseif (empty($this->params)) {
         $this->params = array();
     }
     if (!empty($routes['routes'])) {
         $allroutes = array_merge($routes['routes'], self::$docs);
         $this->routes['routes'] = array_merge($routes['routes'], self::$docs);
     } else {
         $allroutes = array_merge($routes, self::$docs);
         $this->routes = array_merge($routes, self::$docs);
     }
     foreach ($allroutes as $route) {
         if (empty($route['rule'])) {
             continue;
         }
         /*
          * only execute if the uri matches the rule and the action
          */
         if (preg_match($route['rule'], $path, $matches)) {
             $found = true;
             if (1 != $this->matchAction($this->action, $route['action'])) {
                 continue;
             }
             $out = empty($route['std_out']) ? $out : $route['std_out'];
             $err = empty($route['std_err']) ? $err : $route['std_err'];
             if (!empty($route['filters'])) {
                 $filters = array_merge($filters, $route['filters']);
             }
             /*
              * Run any filters. Filters support pre-processing such as
              * validating the cookies. Passing in $this->params permits
              * the filters to set variables, like getting the id from a
              * cookie.
              */
             if (!empty($filters)) {
                 // class is a reserved word
                 foreach ($filters as $clazz) {
                     $filter = new $clazz();
                     $ok = $filter->filter($this->params);
                     /*
                      * a filter will return TRUE, nothing if all went well
                      */
                     if ($ok !== TRUE) {
                         return self::handleOut($ok, $out, $err);
                     }
                 }
             }
             /*
              * Add name/value pairs for the parameters passed in the URL,
              * but don't override existing params.
              */
             $index = 0;
             if (!empty($route['params'])) {
                 foreach ($route['params'] as $param) {
                     if (isset($this->params[$param])) {
                         $index++;
                     } else {
                         $this->params[$param] = $matches[$index++];
                     }
                 }
             }
             /*
              * The validator returns TRUE if ok, otherwise an array
              */
             if (!empty($route['pcheck'])) {
                 $valid = Validator::validate($route['pcheck'], $this->params);
                 if (is_array($valid)) {
                     return self::handleOut($valid, $out, $err);
                 }
             }
             /*
              * Call the handler function
              */
             $hclass = $route['class'];
             $method = $route['method'];
             $handler = new $hclass();
             if (($method == 'help' || $method == 'iodoc') && $hclass == 'Rust\\Service\\Controller') {
                 /*
                  * a special case to spit out the route data sharing what services are provided
                  */
                 $result = $handler->{$method}($this->routes);
             } else {
                 $result = $handler->{$method}($this->params);
             }
             return self::handleOut($result, $out, $err);
         }
     }
     /*
      * If we found a matching URL but no supported method, send 405 else 404
      */
     if ($found) {
         return self::handleOut($notsupported, $out, $err);
     }
     $out = 'Rust\\Output\\JsonOutput';
     $err = 'Rust\\Output\\JsonError';
     return self::handleOut($notfound, $out, $err);
 }