public function testCheckWithFailedConstraints() { $spec = TypedSpec::define()->withFieldType('first_name', Boa::string())->withFieldConstraints('first_name', new StringLengthConstraint(4))->withFieldType('age', Boa::integer()); $result = $spec->check(['first_name' => 'Ed', 'age' => 23]); $this->assertTrue($result->failed()); $this->assertEquals(['first_name'], array_keys($result->getFailed())); }
/** * Construct an instance of a Flick. * * @param array|ArrayAccess|Traversable $functions * @param string $default * * @throws InvalidArgumentException * @throws \Chromabits\Nucleus\Exceptions\LackOfCoffeeException */ public function __construct($functions, $default = 'default') { parent::__construct(); Arguments::define(Boa::lst(), Boa::either(Boa::string(), Boa::integer()))->check($functions, $default); $this->functions = $functions; $this->default = $default; }
/** * Construct an instance of a StringLengthConstraint. * * @param int $min * @param int $max * * @throws InvalidArgumentException */ public function __construct($min = 0, $max = -1) { parent::__construct(); Arguments::define(Boa::integer(), Boa::integer())->check($min, $max); if ($min < 0) { throw new InvalidArgumentException('The minimum length is expected to be >= 0.'); } if ($max != -1 && $max < $min || $max < -1) { throw new InvalidArgumentException(' The maximum length is expected to be: (== -1 || >= minimum) &&' . ' >= -1.'); } $this->min = $min; $this->max = $max; }
public function testCheckNested() { $instance = Spec::define(['name' => Boa::string(), 'count' => Boa::integer(), 'address' => Spec::define(['street' => Spec::define(['first_line' => Boa::string(), 'second_line' => Boa::either(Boa::string(), Boa::integer())], [], ['first_line']), 'state' => [Boa::string(), new StringLengthConstraint(2, 2)], 'zip' => Boa::integer()], [], ['street', 'zip'])]); $resultOne = $instance->check(['name' => 'Doge', 'count' => 7, 'address' => []]); $this->assertTrue($resultOne->failed()); $resultTwo = $instance->check(['name' => 'Doge', 'count' => 7, 'address' => ['street' => [], 'state' => 90]]); $failed = $resultTwo->getFailed(); $missing = $resultTwo->getMissing(); $this->assertTrue($resultTwo->failed()); $this->assertArrayHasKey('address.state', $failed); $this->assertTrue(in_array('address.street.first_line', $missing)); $resultThree = $instance->check(['name' => 'Doge', 'count' => 7, 'address' => ['street' => ['first_line' => '1337 Hacker Way'], 'state' => 'GA', 'zip' => 13370]]); $this->assertTrue($resultThree->passed()); }
public function testComplexSpec() { $graph = new SpecGraph(); $graph->add('input', [], Spec::define(['sleepy' => Boa::boolean(), 'tennis_balls' => Boa::integer(), 'message' => Boa::either(Boa::string(), Boa::integer())], [], ['message'])); $graph->add('allowedMessage', ['input'], Spec::define(['message' => [Boa::in(['hi', 'how are you?', 'you dumb']), Boa::in(['hi', 'how are you?', 'you are smart'])]], [], ['message'])); $graph->add('validBallCount', ['input'], Spec::define(['tennis_balls' => Boa::between(1, 10)])); $graph->add('additionalBallProps', ['validBallCount'], Spec::define(['ball_color' => [Boa::string(), Boa::in(['blue', 'red', 'yellow'])]], [], ['ball_color'])); $result = $graph->check(['sleepy' => true, 'tennis_balls' => 3, 'message' => 'hi', 'ball_color' => 'blue']); $this->assertTrue($result->passed()); $result2 = $graph->check(['sleepy' => 1, 'tennis_balls' => 3]); $this->assertEqualsMatrix([[true, $result2->failed()], [1, count($result2->getFailed())], [['message'], $result2->getMissing()]]); $result3 = $graph->check(['sleepy' => true, 'tennis_balls' => -30, 'message' => 'hello']); $this->assertEqualsMatrix([[true, $result3->failed()], [2, count($result3->getFailed())], [[], $result3->getMissing()]]); $result4 = $graph->check(['sleepy' => true, 'tennis_balls' => 3, 'message' => 'how are you?']); $this->assertEqualsMatrix([[true, $result4->failed()], [0, count($result4->getFailed())], [['ball_color'], $result4->getMissing()]]); $result5 = $graph->check(['sleepy' => true, 'tennis_balls' => 3, 'message' => 'how are you?', 'ball_color' => 'liquid_gold']); $this->assertEqualsMatrix([[true, $result5->failed()], [1, count($result5->getFailed())], [[], $result5->getMissing()]]); }
/** * Get an array with only the specified keys of the provided array. * * @param array|null $included * * @return static */ public function only($included = []) { Arguments::define(Boa::either(Boa::arrOf(Boa::either(Boa::string(), Boa::integer())), Boa::null()))->check($included); if (is_null($included)) { return $this; } if (count($included) == 0) { return static::zero(); } return static::of(array_intersect_key($this->value, array_flip($included))); }
/** * Generate an authorization code for the Research API server. * * @param null|integer $timestamp * * @return string */ public function generateCode($timestamp = null) { Arguments::contain(Boa::either(Boa::null(), Boa::integer()))->check($timestamp); $timestamp = Std::coalesce($timestamp, time() + 3600 * 3); $signature = md5(implode('', [$timestamp, $this->clientId, $this->secret])); return vsprintf('%s|%s|%s', [$timestamp, $this->clientId, $signature]); }
/** * The inverse operation of calling toResponse. * * This function will attempt to parse a Response object into an * ApiResponse object, which can be useful for introspection and testing. * * @param Response $response * * @throws CoreException * @return static */ public static function fromResponse(Response $response) { $body = Std::jsonDecode($response->getContent()); $result = Spec::define(['messages' => Boa::arrOf(Boa::string()), 'status' => Boa::in(static::getValidStatuses()), 'code' => Boa::integer()])->check($body); if ($result->failed()) { throw new CoreException('Unable to parse an ApiResponse out of the content of a' . ' Response object. Make sure that the Response object was' . ' actually generated by an ApiResponse or a compatible' . ' implementation.'); } return new static(Arr::except($body, static::getReservedKeys()), $body['status'], $body['messages']); }
/** * Get a copy of the provided array excluding the specified values. * * @param array $input * @param array $excluded * * @return array * @throws InvalidArgumentException */ public static function exceptValues(array $input, $excluded = []) { Arguments::define(Boa::arrOf(Boa::either(Boa::string(), Boa::integer())))->check($excluded); return Std::filter(function ($value, $_) use($excluded) { return !in_array($value, $excluded); }, $input); }
/** * @inheritDoc */ public function getSpec() { return Spec::define(['days' => Boa::integer(), 'repeat_in' => Boa::integer(), 'expire_after' => Boa::integer()], ['days' => 30, 'repeat_in' => -1, 'expire_after' => 1440]); }
/** * @return PrimitiveTypeConstraint */ public function getKeyType() { return Boa::integer(); }
/** * Attempt call the provided function a number of times until it no longer * throws an exception. * * @param callable $function * @param int $attempts * * @return mixed|null * @throws InvalidArgumentException */ public static function retry(callable $function, $attempts) { Arguments::define(Boa::func(), Boa::integer())->check($function, $attempts); for ($ii = 0; $ii < $attempts; $ii++) { try { $result = static::call($function, $ii); return $result; } catch (Exception $e) { continue; } } return null; }
/** * Get a model by its id. * * @param int $id * @param array $columns * @param array $with * * @throws InvalidArgumentException * @throws LackOfCoffeeException * @return Model */ public function getById($id, array $columns = ['*'], array $with = []) { Arguments::contain(Boa::integer(), Boa::arrOf(Boa::string()), Boa::arrOf(Boa::string()))->check($id, $columns, $with); $query = $this->makeModelInstance()->query()->where('id', $id); $this->applyWith($query, $with); return $query->firstOrFail($columns); }