Giter Club home page Giter Club logo

es-feature-tests's Introduction

ES Feature Tests

Feature Tests for JavaScript. This is the library used by the FeatureTests.io service.

If you're looking for the repository for the site itself, not this library, go here instead.

Why

Load the library, request feature test results for the current browser, use those results to determine what code to deliver for your application!

If all the JavaScript features/syntax your code uses are supported natively by the browser, why would you load up the ugly transpiled code? Why would you load dozens of kb of polyfills/shims if all (or most of) those APIs are already built-in?

Just use the original authored ES6+ code in newest browsers! Only use transpiled code and polyfills/shims for browsers which are missing the features/syntax you need.

Don't rely on stale caniuse data baked into build tools that matches a browser based on brittle UserAgent string parsing. Feature Test! That's the most reliable and sensible approach.

For much more detail about the why motivations and sanity checking the risks/concerns about scalability/reliability, see ES6: Features By Testing.

Documentation

The updated and detailed documentation for how this library works and what test results are available can be found on FeatureTests.io/details.

Hosting vs. Hosted

Hosting this package locally on your server is mostly useful if you want to use the feature tests in your Node/iojs programs (see "Node/iojs" below).

You can install this package locally and web host your own copy of the library files if you prefer. You'll need to modify the URLs ("https://featuretests.io") in several places to get them to load correctly. Hosting the files also means the test results won't be shareable with other sites, which puts more testing burden on users' machines.

Another concern that only applies if you're self-hosting and running your own tests is that all of the syntax-realted tests require using new Function(..) (or, ugh, eval(..)). If your site has a restrictive CSP, you will not be able to run those tests unless you relax it to allow unsafe-eval. By allowing the service to run the tests, that CSP policy is contained to the "featuretests.io" domain instead of polluting your site's domain.

It's probably a much better idea to use the "https://featuretests.io" service's hosted versions of the files for web usage.

Web

Using this library on the web:

<script src="https://featuretests.io/rs.js"></script>
<script>
window["Reflect.supports"]( "all", function(results,timestamp){
	console.log( results );
	// {
	//    ..
	// }
});
</script>

Node/iojs

Using this library in Node/iojs:

npm install es-feature-tests

Then:

var ReflectSupports = require("es-feature-tests");

ReflectSupports( "all", function(results,timestamp){
	console.log( results );
	// {
	//    ..
	// }
});

Testify CLI

This package also includes a testify CLI tool, which scans files for ES6 features and produces the code for a JS function called checkFeatureTests(..). For example:

function checkFeatureTests(testResults){return testResults.letConst&&testResults.templateString}

As shown, checkFeatureTests(..) receives the feature test results (as provided by this es-feature-tests library), and returns true or false indicating if the test results are sufficient or not. This test tells you if your ES6-authored files can be loaded directly into the environment in question, or if you need to load the transpiled version of your code.

In the preceding example, both the letConst test result and the templateString test result must pass for checkFeatureTests(..) to pass.

By letting testify scan your files, you won't need to manually maintain a list of checks for your code base. Just simply run testify during your build process, and include the code it produces (like shown above) into your initial bootstrapped code that will run the feature tests. Use the generated checkFeatureTests(..) with the es-feature-tests library like so:

var supports = window["Reflect.supports"];

// or in Node:
// var supports = require("es-feature-tests");

supports( "all", function(results){
	if (checkFeatureTests(results)) {
		// load ES6 code
	}
	else {
		// load transpiled code instead
	}
});

The testify CLI tool has the following options:

usage: testify [--file|--dir]=path [opt ...]

options:
--help                    show this help

--file=file               scan a single file
--dir=directory           scan all files in a directory
--exclude=pattern         exclude any included paths that match pattern (JS regex)
-C, --input               scan file contents from STDIN

--output=[simple|json|babel|traceur]
                          control output format (see docs)
                          (default: simple)
--enable=test-name        force inclusion of a test by name
--disable=test-name       force exclusion of a test by name

-R, --recursive           directory scan is recursive
                          (default: off)
-M, --ignore-missing      ignore missing dependency files
                          (default: off)
-I, --ignore-invalid      ignore JS parsing issues
                          (default: off)

Specify file(s) to scan by using one or more --file and/or --dir flags, and/or import text contents via STDIN by specifying --input (-C).

If you use --dir, that directory's contents will be examined (non-recursively), and all found JS files will be scanned. Use --recursive (-R) to recursively examine sub-directories. To exclude any files/paths from this processing, use one or more --exclude flags, specifying a JS-style regular expression to match for exclusion (note: to avoid shell escaping issues, surround your regex in ' ' quotes).

The default (--output=simple) output of the testify CLI tool is the code for the checkFeatureTests(..) function, as described above. If you'd prefer to receive a JSON string holding the array of tests needed by name, specify --output=json. If you want to produce a Babel config with tests needed mapped to the whitelist option, use --output=babel. To produce the configuration for Traceur, use --output=traceur.

To force the inclusion of a specific test check, use --enable and specify the name (matching the test result name from this es-feature-tests library). To exclude a specific test check, use --disable and specify the matching name.

Suppress errors for missing scan files with --ignore-missing and for invalid files (failure to parse the JS) with --ignore-invalid.

Testify Library

testify can also be used programmatically in JS:

var testify = require("es-feature-tests/testify"),
	code = testify.scan({ ..options.. });

// (Optional) To use the function inside Node:
var checkFeatureTests = new Function(
	"res",
	code + ";return checkFeatureTests(res)"
);

The options correspond similarly to the CLI parameters described above:

  • files (string, array): specifies file(s) to scan

  • dirs (string, array): specifies director(ies) of file(s) to scan

  • excludes (string, array): specifies exclusion pattern(s)

  • content (string): specifies text to scan as if it was already read from a file

  • output (string: "simple", "json", "babel", "traceur"): controls the output formatting of the list of tests needed

    Note: The CLI --output option defaults to "simple" (the code for checkFeatureTests(..)), but the default value for the library option is "json", which *actually produces the array object itself, since that will likely be more useful when used programmatically.

  • enabled (string, array): specifies test(s) that should always be included

  • disabled (string, array): specifies test(s) that should never be included

  • recursive (boolean, default: false): make directory scans recursive

  • ignore (object, boolean): if true/false, will set all sub-properties accordingly; otherwise, should be an object with one or more of these:

    • ignore.missing (boolean): ignore files or directories not found
    • ignore.invalid (boolean): ignore files where the scan fails

Note: files, dirs, and excludes all have the -s suffix, and enabled and disabled both have the -d suffix. However, the associated CLI parameter names do not have these suffixes.

GitHub

If you install this package from GitHub instead of npm, you won't have the deploy/* files for deployment. Run these commands from the main repo directory to build them:

npm install
npm run build

License

The code and all the documentation are all (c) 2015 Kyle Simpson and released under the MIT license.

http://getify.mit-license.org/

es-feature-tests's People

Contributors

getify 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

es-feature-tests's Issues

Possible bug in parser

The code below is informing my I have a concise method property. Messing with the whitespace next to request = makes it go away sometimes. Also, killing the foo() call makes it go away.

javascript
'use strict';

define([], function () {
_createClass(x, [{
value: function bulkShare(vm, evt) {
var y = this.ssr().map(function (item) {
return item.id;
}),
request = {
resourceIds: y.join(','),
contactId: ko.unwrap(this.a()),
contactType: ko.unwrap(this.b())
};
foo();
}
}]);

return null;

});

Test results persist in localStorage after browser is updated

I just updated from Chrome 49 to 50 and expected that the unicodeRegExp test would now pass, but it didn't. Clearing localStorage fixed it:

screen shot 2016-04-14 at 11 00 07 am

I'd expected that the stored results would include the user agent string (or something?) so that they could be invalidated following an update – what do you reckon?

ES2016 testing?

Now that ES2016 is out, are there plans for including these feature in your browser tests?

Module tests don't make sense

The module tests don't make sense. They will always fail, even in environments supporting ES6 modules:

  1. import/export statements are allowed only in top-level scope so new Function('export var a = 1') will always fail.
  2. import/export are only allowed in modules, not scripts; in browsers JS code will be able to be loaded as a module via <script type="module" src="path.js"><script>, in Node it's not fully clear yet. In any case, those tests will need to be run in a different way then every other one.
  3. For import {a} from 'b' to not fail the environment needs to first be able to resolve the module 'b'.

To sum up, the tests in their current form don't really make any sense, they will always fail for multiple reasons so they should be removed.

Functionality (implementation details) of each future

Hi,

First of all, great project, really appreciate your work and hope babeljs to implement it on some level so we can exclude from transpiling some of the language features which are widely supported already.

What is missing here though is that usually we need to not just know existence of a feature, but some implementation details — like is there anything is missing or are there any differences with the spec, etc. Take @kangax ECMAScript compatibility table for instance — there are several tests for each future so you can see how fully each one of them is supported on different platforms. I understand that it's an early stage of the project, so maybe you considered this already, but anyway.

Support CSP `script-src 'self';`

Due to the use of Function(…) this library cannot be used with CSP script-src 'self';. Switching to a getter-based approach that executes the feature test once and then caches the result would solve this problem.

More granular test results

ArrayMethods isn't particularly useful to me. However, an exact report of which methods passed and failed would be wonderful.

The design I think would be amazing is (using "supports" as the root report object):
supports.Array.prototype = true = all tested Array.prototype methods pass
supports.Array.prototype.fill = true = Array.prototype.fill passes
supports.Array = all tested Array methods pass
supports.Array.of = Array.of passes
… and so forth.

For everything that's an API method, this would be very clean. You could then do supports.syntax.arrowFunctions etc if there was concern about namespace overlapping. Alternatively, the above could be supports.api.Array etc.

(filed per https://twitter.com/getify/status/596773738277785600)

Document supported browsers version

Judging by the use of Object.keys and foreach I believe IE8 is not supported. Or at least requires polyfills. I'm not sure about old Opera. These still need to be supported by some projects or at least produce meaningful error messages instead of just quietly crashing. FeatureTest is an external dependency so it would be good to know what to expect from it.

How convert to babel/traceur options list to defer to browser's features

[We had a short twitter chat .. you mentioned it'd be good to have longer one.]

Both babel and traceur have two workflows: static & dynamic. Static transpiles the es6 to es5 before use, while dynamic uses in-browser transpilation.

Both modes have options to include/exclude features of the transpilers, mainly to defer to the browser if it has the given feature.

This issue is to use es-feature-tests to create the options file appropriate to the browser being used, to build the options file for babel/traceur to defer to the browser. This would primarily be useful in the dynamic workflow.

It need not be a direct part of the project/repo .. but simply to document how to convert from the es-feature-tests results to an options file which exclude options already available in the browser.

Store and check version against user agent

How about storing the user-agent and checking against this (at least more often than a couple weeks) when reading the cached data? If the browser gets updated then the user agent will change and we'll catch that.

Thanks!

Update Babel Transformers mapping

Some transformers are merged since babel 5.8.2 c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1

Looks like is not a good suggestion to use only one.

But for now I only have some warning messages:
[BABEL] The transformer es6.parameters.default has been renamed to es6.parameters
[BABEL] The transformer es6.parameters.rest has been renamed to es6.parameters

ES5 Testing

Would you be open to having ES5 features tested too? Ones that can't be polyfilled that is, like Object.defineProperty.

letConst should be false in IE11 & Edge

IE11 & Edge don't follow the ES6-mandated rule that a const/let fresh binding is created for each iteration of the for loop. The following is valid ES6 but will throw a SyntaxError:

for (const i in {a: 2, b: 3}) {
    setTimeout(function () {
        console.log(i);
    });
}

Even worse, the following will parse correctly:

for (let i in {a: 2, b: 3}) {
    setTimeout(function () {
        console.log(i);
    });
}

but will print b twice instead of a b.

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.