Git Product home page Git Product logo

bypass-finals's Introduction

bypass-finals

Downloads this Month Tests Latest Stable Version License

 

Introduction

BypassFinals effortlessly strips away final and readonly keywords from your PHP code on-the-fly. This handy tool makes it possible to mock final methods and classes, seamlessly integrating with popular testing frameworks like PHPUnit, Mockery, or Nette Tester.

 

Installation

The easiest way to install BypassFinals is via Composer. Just run the following command in your project directory:

composer require dg/bypass-finals --dev

It pretty much runs everywhere: PHP 7.1 through 8.3 are all supported!

 

Usage

To get BypassFinals up and running, just invoke:

DG\BypassFinals::enable();

Make sure to call this method early, preferably immediately after your vendor/autoload.php is loaded, to ensure all classes are processed before they are used.

Note that final internal PHP classes like Closure are not mockable.

To avoid removing readonly keywords, you can disable this feature by passing a parameter:

DG\BypassFinals::enable(bypassReadOnly: false);

To narrow down the application scope of BypassFinals, use a whitelist to specify directories or files:

DG\BypassFinals::allowPaths([
    '*/Nette/*',
]);

Or, conversely, you can specify which paths not to search using DG\BypassFinals::denyPaths(). This gives you finer control and can solve issues with certain frameworks and libraries.

Enhance performance by caching transformed files. Make sure the cache directory already exists:

DG\BypassFinals::setCacheDirectory(__DIR__ . '/cache');

For integration with PHPUnit 10 or newer, simply add BypassFinals as an extension in your PHPUnit XML configuration file:

<extensions>
	<bootstrap class="DG\BypassFinals\PHPUnitExtension"/>
</extensions>

 

Do you like this project?

Check out my other innovative open-source projects that might catch your interest:

Latte: The only safe and intuitive templating system for PHP
Tracy: An addictive debugging tool to enhance your development workflow
PhpGenerator: A robust library for generating PHP code with modern features
Nette Framework: A thoughtfully engineered and popular web framework.

 

Support Project

Donate

bypass-finals's People

Contributors

afilina avatar ammarpad avatar bzikarsky avatar dg avatar dmitryuk avatar fancsali avatar jorgsowa avatar milo avatar nightlinus avatar nyholm avatar oruborus avatar phcorp avatar sanmai avatar szepeviktor 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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

bypass-finals's Issues

Please release version 1.1.1

Hi @dg,

first of all, thanks for your wonderful work!

Just had one question: I ran into the issue that was fixed by 8a5b647, but I notice that it is only fixed in dev-master.

Would you please release version 1.1.1 (assuming you follow semver) that contains this bugfix? I rather not include dev-master as a dependency to the projects I am working on.

Thanks in advance and keep up the good work!

eX

Bypassing readonly properties without visibilty can change behavior

Reproduction example:

  1. composer require dg/bypass-finals --dev
  2. index.php:
<?php

require_once __DIR__ . '/vendor/autoload.php';

\DG\BypassFinals::enable();

require_once __DIR__ . '/include.php';

new A('A');
new B('B');
  1. include.php:
<?php

class A {
    public function __construct(
        readonly string $a
    ) {
        var_dump('A: ' . $this->a);
    }
}

class B {
    public function __construct(
        public readonly string $a
    ) {
        var_dump('B: ' . $this->a);
    }
}

Result:

php index.php
PHP Warning:  Undefined property: A::$a in /…/test-bypassfinals/include.php on line 7

Warning: Undefined property: A::$a in /…/test-bypassfinals/include.php on line 7
string(3) "A: "
string(4) "B: B"

The problem stems from the fact that readonly is just removed from the code thus changing the promoted property to a simple constructor argument and thus changing behavior.

Context: We use a third-party library that does uses this kind of code.


I am unsure whether this package can really fix this issue because at the moment, a "simple" replace logic without considering the context is used. Here, the context of being a promoted property would have to be known and readonly replaced with public.

The class \Closure is marked final and its methods cannot be replaced.

Other final classes mocked sucessfully. But \Closure from PHP core don't mocked =(

https://www.php.net/manual/en/class.closure.php

    public function test() {
       BypassFinals::enable(
       Mockery::mock(\Closure::class)
    }
Mockery\Exception: The class \Closure is marked final and its methods cannot be replaced. Classes marked final can be passed in to \Mockery::mock() as instantiated objects to create a partial mock, but only if the mock is not subject to type hinting checks.

/var/www/app/vendor/mockery/mockery/library/Mockery/Generator/MockConfiguration.php:332
/var/www/app/vendor/mockery/mockery/library/Mockery/Generator/MockConfiguration.php:434
/var/www/app/vendor/mockery/mockery/library/Mockery/Generator/StringManipulationGenerator.php:74
/var/www/app/vendor/mockery/mockery/library/Mockery/Generator/CachingGenerator.php:40
/var/www/app/vendor/mockery/mockery/library/Mockery/Container.php:221
/var/www/app/vendor/mockery/mockery/library/Mockery.php:114
    public function test() {
       BypassFinals::enable(
       $this->createMock(\Closure::class);
    }
Class "Closure" is declared "final" and cannot be mocked.
composer info | grep dg
dg/bypass-finals                                 v1.2.1                                Removes final keyword from source code on-the-fly and allows moc...
composer info | grep phpunit
phpunit/php-code-coverage                        8.0.2                                 Library that provides collection, processing, and rendering func...
phpunit/php-file-iterator                        3.0.4                                 FilterIterator implementation that filters files based on a list...
phpunit/php-invoker                              3.0.2                                 Invoke callables with a timeout
phpunit/php-text-template                        2.0.2                                 Simple template engine.
phpunit/php-timer                                3.1.4                                 Utility class for timing
phpunit/php-token-stream                         4.0.3                                 Wrapper around PHP's tokenizer extension.
phpunit/phpunit                                  9.1.5                                 The PHP Unit Testing framework.
rregeer/phpunit-coverage-check                   0.3.1                                 Check the code coverage using the clover report of phpunit
php -v
PHP 7.4.3 (cli) (built: Feb 18 2020 11:53:05) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
    with Xdebug v2.9.2, Copyright (c) 2002-2020, by Derick Rethans

stat(): stat failed for vendor/pestphp/pest/src/Plugins/../../.temp/only.lock

  Tests:    89 passed (249 assertions)
  Duration: 3.94s
  Parallel: 4 processes


   Pest\Exceptions\FatalException

  stat(): stat failed for /Users/erik/Sviluppo/www/encodia/edit-cli/vendor/pestphp/pest/src/Plugins/../../.temp/only.lock

  at vendor/dg/bypass-finals/src/NativeWrapper.php:206
    202▕ 	private function native(string $func)
    203▕ 	{
    204▕ 		stream_wrapper_restore(self::PROTOCOL);
    205▕ 		try {
  ➜ 206▕ 			return $func(...array_slice(func_get_args(), 1));
    207▕ 		} finally {
    208▕ 			stream_wrapper_unregister(self::PROTOCOL);
    209▕ 			stream_wrapper_register(self::PROTOCOL, self::$outerWrapper);
    210▕ 		}

Script XDEBUG_MODE=off ./vendor/bin/pest --parallel --bail --exclude-group=API,S3 --colors=always handling the test event returned with error code 1

I'm running Pest on a Laravel Zero application.

This is the same problem described here: pestphp/pest#1079

As far as I could understand, this error is happening only under these conditions:

  • Pest 2.33.0 is required
  • nunomaduro/mock-final-classes� is required
  • two or more tests running involving removal of final�(for example, running a single test of these doesn't trigger the error).

Thank you.

Unsure of the true cause, but enabling BypassFinals causes unrelated test to fail in our project

The test uses SplFireObject to get a line count from a .tsv file.

    $fileInfo = new \SplFileObject($fileName);
    $fileInfo->seek(\PHP_INT_MAX);
    $lineCount = $fileInfo->key();

The file in question returns (for example) 100 when not using BypassFinals::enable(), but when used the test returns 99 when using. I've tested this and it appears that BypassFinals is somehow trimming a trailing new line in our .tsv which causes the test to fail. Using a strict whitelist does not seem to alleviate this issue.

What I can't determine is the root cause, I can't tell if this is a BypassFinals issue, or if there's something about this project's setup that merely gets triggered by BypassFinals. Either way, feels like I should leave this issue in case anyone else wants to look deeper or runs into a similar issue.

Causes issues passing descriptors to subprocesses

I had an issue reported to my package donatj/mock-webserver that turned out to be caused by this package.

donatj/mock-webserver#59 (comment)

After poking @sigma-z's example a bit, I've determined there's some sort of problem with this using this library AND generating file descriptors that can be passed to sub processes with proc_open.

I've boiled an example of the problem down to:

<?php

require __DIR__ . '/vendor/autoload.php';

DG\BypassFinals::enable();

$stdin   = fopen('php://stdin', 'rb');
$stdoutf = tempnam(sys_get_temp_dir(), 'dgb.test');

$descriptorSpec = [
	0 => $stdin,
	1 => [ 'file', $stdoutf, 'a' ],
];

$fullCmd = 'echo "This should come LAST in the output"';
$process = proc_open($fullCmd, $descriptorSpec, $pipes);

sleep(1);

echo "=== Text should come AFTER this line not before... reading from {$stdoutf} ===\n";
echo file_get_contents($stdoutf);

If you run this, you get something like

dup2: Bad file descriptor
This should come LAST in the output
=== Text should come AFTER this line not before... reading from <path> ===

If you comment out the line DG\BypassFinals::enable(); though you get the expected

=== Text should come AFTER this line not before... reading from /private/var/folders/dr/cpm01_51333c1px2yzc8qr9xq1kth0/T/dgb.testx1XyaY ===
This should come LAST in the output

It's failing to either create or pass the file descriptor to the subprocess.

I seem to be able to solve it on my site by replacing the line

	1 => [ 'file', $stdoutf, 'a' ],

with

	1 => fopen($stdoutf, 'wb'),

and I very well might do that but I still think this likely calls for some investigation

stat(): stat failed for

Hello everyone,

I'm using this package in my Laravel project. But, after I did add this extension in the phpunit.xml file, all my tests is showing one warning:

stat(): stat failed for /var/www/html/

Should I make some configuration for that?

phpunit Depends attribute broken with BypassFinals and cache enabled

Q A
PHPUnit version 10.5.19
PHP version 8.2.18
Installation Method Composer
BypassFinals version 1.6.0

Summary

When using the #[Depends('xxx')] attribute, or @depends xxx annotation, tests are getting skipped when the original test fails, but are not getting executed when the test succeeds.

Current behavior

Tests are skipped when the origin function fails, but are not executed when it succeeds. It also does not appear in the "skipped" list

How to reproduce

<?php
// DependTest.php
declare(strict_types=1);

use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\TestCase;

final class DependTest extends TestCase
{
    public function testWorks(): void
    {
        self::assertTrue(true);
    }

    public function testDoesNotWork(): void
    {
        self::assertTrue(false);
    }

    #[Depends('testWorks')]
    public function testDependsOnWorks(): void
    {
        self::assertTrue(true);
    }

    #[Depends('testDoesNotWork')]
    public function testDependsOnDoesNotWorks(): void
    {
        self::assertTrue(true);
    }
}
<?php
// BypassFinalsExtension
declare(strict_types=1);

use DG\BypassFinals;
use PHPUnit\Runner\Extension\Extension;
use PHPUnit\Runner\Extension\Facade;
use PHPUnit\Runner\Extension\ParameterCollection;
use PHPUnit\TextUI\Configuration\Configuration;

final class BypassFinalsExtension implements Extension
{
    public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
    {
        BypassFinals::setCacheDirectory(__DIR__ . '/cache'); // with this line disabled, it works correctly
        BypassFinals::enable();
    }
}

execution:

vendor/bin/phpunit DependTest.php --display-skipped

output:

PHPUnit 10.5.19 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.18
Configuration: /Users/anna.damm/Projects/test/phpunit.xml.dist

.FS                                                                 3 / 3 (100%)

Time: 00:00.033, Memory: 10.00 MB

There was 1 failure:

1) DependTest::testDoesNotWork
Failed asserting that false is true.

/Users/anna.damm/Projects/test/DependTest.php:17

--

There was 1 skipped test:

1) DependTest::testDependsOnDoesNotWorks
This test depends on "DependTest::testDoesNotWork" to pass

FAILURES!
Tests: 3, Assertions: 2, Failures: 1, Skipped: 1.

With this test case, the "testDependsOnWorks" is not executed. Tests are:
testWorks -> gets executed successfully
testDoesNotWork -> fails
testDependsOnWorks -> is not executed
testDependsOnDoesNotWorks -> is skipped because of failed dependency

Expected behavior

Test functions with #[Depends(...)] or @depends xxx should be executed when the function they depend on are executed successfully

This refers to sebastianbergmann/phpunit#5826

Cannot bootstrap extension because class DG\BypassFinals\PHPUnitExtension does not exist

This is the WARNing message that you get after following the steps from master's README -- especially the part about "registering BypassFinals in PHPUnit 10" - it makes you think that that class is already in the Released version (which is not specified in "install is through Composer" part), but it actually exists only in the master branch.

Please, add it to the next Release or specify that one should add composer require dg/bypass-finals:dev-master --dev to use that extensions->bootstrap class. Thanks!

What happens when using an opcode cache?

I don't know if this is really an "issue" so much as a question. But it seems worth documenting either way, so I'll claim it's a documentation request.

How does this interact with opcode caches like APC? If on one request a PHP file gets cached with finals not removed, and then another request comes along and tries to load the file with finals removed, is the parsed file going to get served from cache with finals still in it? I.e., you'll get files randomly with or without final depending on which one got cached? Or is this avoided somehow?

I got a warning message from `composer validate -A`

When i run composer validate -A on my project i get the following message:

...
dg/bypass-finals is valid, but with a few warnings
# General warnings
- License "GPL-2.0" is a deprecated SPDX license identifier, use "GPL-2.0-only" or "GPL-2.0-or-later" instead
- License "GPL-3.0" is a deprecated SPDX license identifier, use "GPL-3.0-only" or "GPL-3.0-or-later" instead
...

`mkdir` method always uses non-recursive flag

The third parameter of mkdir is a boolean which indicates if the given folder path should be created recursively.

However, false is always given; so when some API tries to create a full path, it fails.

public function mkdir($path, $mode, $options)
{
return $this->native('mkdir', $path, $mode, false, $this->context);
}


My usecase is: I want to use Infection which needs to have access to PHPUnit's coverage files, which are created in a folder (which is itself created with the recursive parameter set to true); see php-code-coverage Facade file.

So when I try to run Infection, the coverage files creation fails because the folders can't be created.


I tried to look what value is given to the $options parameters of the method above. Documentation says it can contain STREAM_MKDIR_RECURSIVE, which would be a solution.

In my case it contains 9 which seems to be the equivalent of STREAM_NOTIFY_FAILURE.

I don't know how to fix it with these information, any idea? 🙂

Support bypass readonly in PHP 82

In PHP 82, it is now possible to mark classes "readonly". However, tests of such classes give an error: "Class "Password Hasher" is declared "readonly" and cannot be duplicated". I would like this library to be able to fix these errors as well.

Fixtures:

final readonly class FinalClass
{
}

Warnings converted to ErrorExceptions make url_stat fail on non-existent files

Within my setup (Symfony 6.3, PHP 8.2, phpunit 9.6) there is by default an error handler that changes all errors and warnings into ErrorExceptions. This causes current version of NativeWrapper::url_stat to let this exception bubble to framework's code which doesn't expect functions like file_exists to fail.

The error handler cannot be trivially turned off, and I suspect the codebase I maintain isn't the only one which has this default. The problem is not fixed by error silencing operator, as per the docs If a custom error handler function is set with set_error_handler(), it will still be called even though the diagnostic has been suppressed. (https://www.php.net/manual/en/language.operators.errorcontrol.php)

I propose to add another catch to the try added in #34 (see bug #31). I'll post a PR shortly.

Expected: file_exists to always return a boolean.
Current behaviour:

Test Name (Test\Path)
 ✘ 
   ┐
   ├ ErrorException: stat(): stat failed for /var/www/html/config/secrets/test/test.list.php
   │
   ╵ /var/www/html/vendor/dg/bypass-finals/src/NativeWrapper.php:206
   ╵ /var/www/html/vendor/dg/bypass-finals/src/NativeWrapper.php:193
   ╵ /var/www/html/vendor/dg/bypass-finals/src/BypassFinals.php:192
   ╵ /var/www/html/vendor/symfony/framework-bundle/Secrets/SodiumVault.php:153
...

TypeError : mkdir() expects parameter 4 to be resource, null given

I have included it inside a [email protected] project in order to mock a final class. Yet a test is now breaking due to:

TypeError : mkdir() expects parameter 4 to be resource, null given
 /opt/project/vendor/dg/bypass-finals/src/BypassFinals.php:220
 /opt/project/vendor/dg/bypass-finals/src/BypassFinals.php:71
	public function mkdir(string $path, int $mode, int $options): bool
	{
		$recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
		return $this->native('mkdir', $path, $mode, $recursive, $this->context);
	}

The project uses ZipARchive and it fails when trying to execute an zip folder via: extractTo.

Why would bypass-finals break here?

[BUG] Warning thrown by `url_stat` when file does not exist

When \DG\BypassFinals::url_stat is called with the path of a file that does not exist on the filesystem, a warning is thrown: stat(): stat failed for /path/to/my/unexisting/file.

A check should be done before calling the native method with an invalid path.

Bypassing finals does not work with PHPUnit's --order-by set to random

It seems that this library does not work when you use PHPUnit together with the --order-by random flag.

I have only confirmed this on one project (maybe someone else can confirm this by running $ phpunit --order-by random in a project using this library?

I am using PHP 8.1.6 with PHPUnit 9.5.24.

Getting this on running my tests.

Invalid callback Monolog\Handler\RotatingFileHandler::customErrorHandler, cannot access private method Monolog\Handler\RotatingFileHandler::customErrorHandler()

at vendor/dg/bypass-finals/src/NativeWrapper.php:206

Packagist is outdated

Packagist does not seem to update by itself (last update 2017-09-14 13:53 UTC), maybe the hook is broekn?

Could you update the package manually?

Thanks!

"final" is not case-sensitive

$ php -r 'FINAL class A {} class B extends A {}'
PHP Fatal error:  Class B may not inherit from final class (A) in Command line code on line 1

removeFinals does

if (strpos($code, 'final') !== false) {

This will skip a file where all the "final"s are not lowercase. I don't think anyone actually does this, but I think this should be stripos instead of strpos, anyway.

(Not tested, just code inspection.)

Phpunit 10 doesn't works with bypass-finals

`An error occurred inside PHPUnit.

Message: call_user_func(): Argument #1 ($callback) must be a valid callback, class "PHPUnit\Util\ErrorHandler" not found
Location: /Users/aleksandrsavin/norse/api/vendor/symfony/phpunit-bridge/DeprecationErrorHandler.php:126

#0 [internal function]: Symfony\Bridge\PhpUnit\DeprecationErrorHandler->handleError(2, 'stat(): stat fa...', '/Users/aleksand...', 206)
#1 /Users/aleksandrsavin/norse/api/vendor/dg/bypass-finals/src/NativeWrapper.php(206): stat('/Users/aleksand...')
#2 /Users/aleksandrsavin/norse/api/vendor/dg/bypass-finals/src/NativeWrapper.php(193): DG\NativeWrapper->native('stat', '/Users/aleksand...')
#3 /Users/aleksandrsavin/norse/api/vendor/dg/bypass-finals/src/BypassFinals.php(173): DG\NativeWrapper->url_stat('/Users/aleksand...', 6)
#4 [internal function]: DG\BypassFinals->__call('url_stat', Array)
#5 /Users/aleksandrsavin/norse/api/vendor/phpunit/phpunit/src/Runner/ResultCache/DefaultResultCache.php(56): is_dir('/Users/aleksand...')
#6 /Users/aleksandrsavin/norse/api/vendor/phpunit/phpunit/src/TextUI/Application.php(586): PHPUnit\Runner\ResultCache\DefaultResultCache->__construct('/Users/aleksand...')
#7 /Users/aleksandrsavin/norse/api/vendor/phpunit/phpunit/src/TextUI/Application.php(159): PHPUnit\TextUI\Application->initializeTestResultCache(Object(PHPUnit\TextUI\Configuration\Configuration))
#8 /Users/aleksandrsavin/norse/api/vendor/phpunit/phpunit/phpunit(99): PHPUnit\TextUI\Application->run(Array)
#9 /Users/aleksandrsavin/norse/api/vendor/bin/phpunit(123): include('/Users/aleksand...')
#10 /private/var/folders/fl/4xt09qyx6_g6c4s87yrq3vs80000gn/T/ide-phpunit.php(224): require_once('/Users/aleksand...')
#11 /private/var/folders/fl/4xt09qyx6_g6c4s87yrq3vs80000gn/T/ide-phpunit.php(173): IDE_PHPUnit_Loader::loadByAutoloader('/Users/aleksand...')
#12 /private/var/folders/fl/4xt09qyx6_g6c4s87yrq3vs80000gn/T/ide-phpunit.php(228): IDE_PHPUnit_Loader::init()
#13 {main}`

do you have in plans to adapt bypass for phpunit 10?

PHPUnit 11 incompatibility

I have set up PHPUnit 11 and started test:

PHP Fatal error:  Non-readonly class SebastianBergmann\CodeUnit\ClassUnit cannot extend readonly class SebastianBergmann\CodeUnit\CodeUnit in /Users/alm/code/api_client/vendor/sebastian/code-unit/src/ClassUnit.php on line 15

With PHPUnit 10.5.13 everything works fine.

Failed infection test if bypass-final is enabled

Hello, I am using the library for infection testing https://infection.github.io/guide/ and if the bypass-final library is enabled the infections are not working as expected - the coverage test is not working properly.
example;
the case where bypass is disabled;
100% coverage of infection

the case where the bypass is enabled;
20-30% coverage.

Could you please take a look at what might be wrong?

Class with __invoke cannot be mocked

Hello.

I ran across a problem when I use a class that only has a __invoke method. It complains that such class is marked final and cannot be mocked. If I use a normal method then the problem disappears.

Is there something I can do about that?

Using Infection library fails because of another stream wrapper

The library Infection uses its own stream wrapper, see \Infection\StreamWrapper\IncludeInterceptor.

Because of that, the mutants created by the library are not used and that makes the whole library unusable if the tests use bypass-finals, because the stream wrapper is overriden.

I tried to guess how both stream wrappers could be used alongside each other but as I have no expertise at all in this topic it got hard very fast.

Do you think this could be possible? How could it be done? Can I help 🙂 ?

New release

Could we please get a new release for the PHPUnitExtension? Thanks.

Using is_file() with PHP 8.0

Hi,
Is it possible that this package isn't ready for PHP 8.0 yet? I have problem using is_file() function. It executes url_stat(), which uses @$this->native(...), and when the file doesn't exist it throw some exception that is impossible to catch by try-catch block:
"stat(): stat failed for 'filename'"

setWhitelist() undefined

PHP Fatal error: Uncaught Error: Call to undefined method DG\BypassFinals::setWhitelist()

Running 1.1.2, the code sample in the README fails as the method doesn't exist.

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.