Giter Site home page Giter Site logo

type-assert's People

Contributors

alexeyt avatar aloiret avatar aloiret-ed avatar atry avatar azjezz avatar dlreeves avatar fredemmott avatar jjergus avatar joshrai avatar kmeht avatar lexidor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

type-assert's Issues

[ RFC ] Do we want to open up using custom TypeSpec<T>'s for the reified API's?

With the current capabilities of TypeAssert, we can derive from Facebook\TypeSpec\TypeSpec<T> to implement validation for custom newtypes. These specs compose just like the built-in specs.

__Private\from_type_structure<T>() (and its friends like TypeSpec\of<T>()) will however not know how to find our custom TypeSpecs. This means that you need to manually build the complex TypeSpec object via TypeSpec\xxx() calls in practice.

Do we want to offer the capability to supply your own TypeSpecs for your own newtypes and have them be recognized by TypeSpec\of<T>() and friends?

This has the major downside of revealing how TypeSpec\of<T>() works and will prevent us from changing our implementation away from TypeStrucuture<T>. The fact that we use TypeStrucuture<T> is an implementation detail of this library.

I have created a PR which demonstrates how something like this may work.
I am not suggesting that this is the PR that adds this feature.
I just need to be able to point to some example code.

3.18 Breaks things :(

File "/builds/HRMWEB/easyEMPLOYER/vendor/fredemmott/type-assert/src/TypeAssert.php", line 81, characters 9-30:
'instanceof' cannot be used on a generic classname because types are erased at runtime (Typing[4162])

I just added // UNSAFE in the method, but you may have a nicer way of doing it (like a FIXME, I was just lazy). Was hoping that Hack would've been fixed before the release, but apparently not.

Add support for complex types without type aliases

eg

<?hh

$typed = TypeAssert::matchesTypeSpec(
  TypeSpec::arrayOf(TypeSpec::string()),
  $untyped,
);

Ideally the type_structure implementation should be changed to be a wrapper on top of this, as this isn't tied to undocumented/unsupported HHVM features

TypeSpec\of() doesn't take inner reified generics of arbitrary classes into account.

example:

final class A<reify T> {}

class B<reify T> {}
final class C<reify Ti, reify To> extends B<Ti> {}

<<__EntryPoint>>
function m(): void {

  require_once __DIR__.'/vendor/autoload.hack';
  \Facebook\AutoloadMap\initialize();

  echo \Facebook\TypeSpec\of<C<string, A<int>>>()->toString();
}

expected output: C<string, A<int>>
actual output: C

Evaluates empty arrays as NULL causing unexpected exceptions

use \FredEmmott\TypeAssert\TypeAssert;

type my_shape_t = shape(
		'one' => bool,
		'two' => array
	);

$my_array = array ('one' => true, 'two' => array());

$shape = new ReflectionTypeAlias('my_shape_t');
$type_structure = $shape->getResolvedTypeStructure();

$assertion = TypeAssert::matchesTypeStructure($type_structure, $my_array);

#
# Throws this exception
# Fatal error: Uncaught exception 'FredEmmott\TypeAssert\IncorrectTypeException' with message 'Expected not-null, got null' in ~/code/include/type-assert/TypeAssert.php:72
#

The above example, I think, should evaluate correctly but the 'two' field gets read as null even though it is an empty array.

Clean up references to varray and darray

VarraySpec and DarraySpec are now nearly the same as VecSpec and DictSpec. There are some small differences in the traces that are generated on failure, and there's some redundant logic in the legacy specs (e.g. VarraySpec doesn't trust that a varray's keys are consecutive integers).

Let's get rid of VarraySpec and DarraySpec, and rename VarrayOrDarraySpec to VecOrDictSpec. We should also eliminate any other references to varray or darray in other types, like tuples.

This change will introduce some backwards incompatibility. It looks to me like assertType and coerceType are okay for these specs, but the type name will change, and maybe people are depending on that.

One warning, though: while varray and darray are gone, it is still possible to distinguish varray and vec typehints via reflection... That means that the TypeStructure kinds for varray, darray, and varray_or_darray still exist. It will be some time before we can clean that up, but treating the kinds homogeneously to vec, dict, and vec_or_dict will help us with that.

[BC broken] Exception type for `DictSpec::assertType()` changed between 3.6.1 and 3.6.2

In my attempt to allow slackhq/hack-json-schema to run on hhvm 4.27, I found that the newer hhvm versions failed the test suite. After hours of debugging I pinned it down on this concept.

use namespace Facebook\TypeSpec;
use namespace Facebook\TypeAssert;

<<__EntryPoint>>
async function main_async(): Awaitable<void> {
  require_once __DIR__.'/vendor/autoload.hack';
  Facebook\AutoloadMap\initialize();

  try {
    $spec = TypeSpec\dict(TypeSpec\string(), TypeSpec\mixed());
    $spec->assertType([1, 2, 3, 4]);
  } catch (TypeAssert\TypeCoercionException $t) {
    echo "You are running TypeAssert 3.6.1\n";
  } catch (TypeAssert\IncorrectTypeException $t) {
    echo "You are running TypeAssert 3.6.2\n";
  }
}

In ObjectConstraint::check() they catch TypeCoercionException to detect and fallback to an array check instead. This exception is now no longer caught. This caused a handful of test failures.

Use directly with a shape

Hello,

It's a great lib! I'm wondering if it would be possible to use it directly with a shape, here is my usecase:

$result = $db->table->find([
  'id' => 1,
], shape(
  'id' => int,
  'data' => string,
));

and $result would be typed with the projection. (more exactly array<T>)

Thanks a lot :)

Negative numbers don't coerce to ints

=hphpd> =Facebook\TypeCoerce\int('100');
=Facebook\TypeCoerce\int('100');
100
hphpd> =Facebook\TypeCoerce\int('-100');
=Facebook\TypeCoerce\int('-100');
Hit a php exception : exception 'Facebook\TypeAssert\TypeCoercionException' with message 'Could not coerce string to type int' ...

This is due to the use of ctype_digit() which returns false for negative numbers.

Remove tuple/shape coercion from assert path

We allow either arrays or vecs for tuples, and arrays or dicts for shapes. We should require they match the current runtime.

This makes migration slightly harder, but the 'typeassert may return a different value' thing it creates leads to more problems.

TypeAssert::matches_type_structure can't check collections of shapes

Asserts that a variable matches the given type structure; these can be arbitrary nested shapes. This is particular useful for dealing with JSON responses.

Test:

<?hh

require_once(__DIR__.'/../../../vendor/hh_autoload.php');

class X
{
    const type Inner = shape('a' => int);
    const type Outer = Container<self::Inner>;

    public static function test(): mixed
    {
        $subj = [
            ['a' => 'completely normal int'],
        ];
        return \Facebook\TypeAssert\matches_type_structure(type_structure(self::class, 'Outer'), $subj);
    }
}

X::test();

Returns array but should throw IncorrectTypeException because of type mismatch (string instead of int). (Like Fred Emmott's typeassert: FredEmmott\TypeAssert\IncorrectTypeException' with message 'Expected type 'int', got type 'string'' in…)

Fatal on matches_type_structure() with container in shape in TS, but not value

Basic example:

class A
{
    const type Something = shape('ints' => Container<int>);
}

\FredEmmott\TypeAssert\TypeAssert::matchesTypeStructure(
    type_structure(A::class, 'Something'), []);

Result:

Catchable fatal error: Argument 2 passed to FredEmmott\TypeAssert\PrivateImpl\TypeStructureImpl::assertValueTypes() must implement interface HH\KeyedTraversable, null given in …/vendor/fredemmott/type-assert/src/PrivateImpl/TypeStructureImpl.php on line 179

HipHop VM 3.12.0-dev

matches_type_structure() too restrictive on HH\Container with arrays

Hi

Another issue with matches_type_structure() (\TypeCoerce\match_type_structure as well):

class X
{
  const type Arr = Container<mixed>;
}

\Facebook\TypeAssert\matches_type_structure(type_structure(X::class, 'Arr'), []);

Throws Facebook\TypeAssert\IncorrectTypeException' with message 'Expected type 'HH\Container<T>', got type 'array'

But it shouldn't, right? In addition to Hack collections, PHP arrays are Containers (https://docs.hhvm.com/hack/reference/interface/HH.Container/)

type_structure vs ReflectionTypeAlias::getTypeStructures()

Hi,

I noticed a difference between the return from type_structure and ReflectionTypeAlias::getTypeStructures(). Am I using it correctly ?

Thanks,

type_structure

array(2) {
  ["kind"]=>
  int(14)
  ["fields"]=>
  array(3) {
    ["a"]=>
    array(1) {
      ["kind"]=>
      int(4)
    }
  }
}

getTypeStructures

array(2) {
  ["kind"]=>
  int(14)
  ["fields"]=>
  array(3) {
    ["a"]=>
    array(1) {
      ["value"]=>
      array(1) {
        ["kind"]=>
        int(4)
      }
    }
  }
}

Remove all dict/vec/varray/darray/shape/tuple implicit conversions in assert path

Related: #48, #18

We're expecting to make darray an alias for dict, varray an alias for vec, and swap the backing store for shapes and tuples to dict/vec respectively in the next 2-8 weeks. Once that has happened in HHVM:

  • this implicit conversion should be removed
  • we should start asserting that a successful assert returns exactly the same value, just with a different type

Missing support for Hack arrays

Probably not coming out until 3.17, but is in the nightlies already.

vendor/fredemmott/type-assert/src/PrivateImpl/TypeStructureImpl.php:25:13,23: Switch statement nonexhaustive; the following cases are missing: OF_VEC, OF_KEYSET, OF_DICT (Typing[4019])
  /tmp/hh_server/hhi_c9b76cf/typestructure.hhi:16:6,22: Enum declared here

Include key name in exceptions?

Is this on the roadmap? When a type doesn't match is it possible to emit the field name? Or maybe I am missing something on this lib. Thanks!

[BugReport] Automatic dict to shape coercion doesn't work inside of a KeyedContainer spec.

Expected behavior

$shape_typespec->assertType(dict['a' => 0]); // shape('a' => 0)

Actual behavior

$with_kc = TypeSpec\of<KeyedContainer<arraykey, shape('a' => int)>>();
$with_vec = TypeSpec\of<vec<shape('a' => int)>>();
$data = vec[dict['a' => 0]];
$with_kc->assertType($data)[0] is shape(...); // false
$with_vec->assertType($data)[0] is shape(...); // true

Automatic coercion should apply to varrays, darrays, vecs, and dicts

The next release of HHVM will eliminate "plain" PHP arrays. After this release:

  • vec assertions should accept both vecs and varrays, coercing both to vecs
  • varray assertions should accept both vecs and varrays, coercing both to varrays
  • similarly for dict and darray assertions

We can use the HH\is_vec_or_varray and HH\is_dict_or_darray helpers to implement this logic. These helpers don't log, like type tests that distinguish PHP and Hack arrays do, since they're safe for the next steps of Hack Array Migration.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.