Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit a7da8311b414f9140a06f8e50f7de1b9607a5648 @mathiasbynens committed Nov 28, 2013
Showing with 252 additions and 0 deletions.
  1. +2 −0 .gitattributes
  2. +17 −0 .gitignore
  3. +3 −0 .travis.yml
  4. +20 −0 LICENSE-MIT.txt
  5. +59 −0 README.md
  6. +52 −0 package.json
  7. +36 −0 tests/tests.js
  8. +63 −0 tpyo.js
@@ -0,0 +1,2 @@
+# Automatically normalize line endings for all text-based files
+* text=auto
@@ -0,0 +1,17 @@
+# Coverage report
+coverage
+
+# Installed npm modules
+node_modules
+
+# Folder view configuration files
+.DS_Store
+Desktop.ini
+
+# Thumbnail cache files
+._*
+Thumbs.db
+
+# Files that might appear on external disks
+.Spotlight-V100
+.Trashes
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - "0.10"
@@ -0,0 +1,20 @@
+Copyright Mathias Bynens <http://mathiasbynens.be/>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
+# tpyo [![Build status](https://travis-ci.org/mathiasbynens/tpyo.png?branch=master)](https://travis-ci.org/mathiasbynens/tpyo) [![Dependency status](https://gemnasium.com/mathiasbynens/tpyo.png)](https://gemnasium.com/mathiasbynens/tpyo)
+
+Ever wanted to use `Math.SQUIRTLE` instead of `Math.SQRT2`? Think `Function.prototype.apple` looks shinier than `apply`? Or do you prefer `Array.prototype.faReech` over `forEach`? Look no further — _tpyo_’s got your back.
+
+_tpyo_ is the result of combining the power of ES6 proxies with [Levenshtein string distance](https://github.com/gf3/Levenshtein). It’s a small script that enables you to make typos in JavaScript property names.
+
+## Installation
+
+Via [npm](http://npmjs.org/):
+
+```bash
+npm install tpyo
+```
+
+In [Node.js](http://nodejs.org/):
+
+```js
+var tpyo = require('tpyo');
+```
+
+Make sure to run node with the `--harmony` flag:
+
+```bash
+node --harmony your-script-using-tpyo.js
+```
+
+## Examples
+
+```js
+var array = typo(['a', 'b', 'c']);
+array.lnegth;
+// → `3`
+array.tosTr1ng();
+// → `'a,b,c'`
+array.fap(function(item) {
+ return item + item;
+});
+// → `['aa', 'bb', 'cc']`
+```
+
+## Should I use this?
+
+**Nope.** It’s just a fun example of what’s possible with ECMAScript 6 proxies.
+
+## Acknowledgements
+
+* Kudos to @gf3, whose [excellent implementation of the Levenshtein string difference algorithm](http://gf3.github.com/Levenshtein/) is being used in _tpyo_.
+* Thanks to @tvcutsem for his work on ES6 proxies and for [his harmony-reflect shim](https://github.com/tvcutsem/harmony-reflect).
+* Shout-out to [-ot](http://ot-crew.com/). ♥
+
+## Author
+
+| [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](http://twitter.com/mathias "Follow @mathias on Twitter") |
+|---|
+| [Mathias Bynens](http://mathiasbynens.be/) |
+
+## License
+
+_tpyo_ is available under the [MIT](http://mths.be/mit) license.
@@ -0,0 +1,52 @@
+{
+ "name": "tpyo",
+ "version": "0.1.0",
+ "description": "A simple ES6 proxy wrapper that enables you to make typos in property names.",
+ "homepage": "http://mths.be/tpyo",
+ "main": "tpyo.js",
+ "keywords": [
+ "es6",
+ "proxy",
+ "proxies",
+ "levenshtein",
+ "levenshtein-distance",
+ "string",
+ "property",
+ "property-names",
+ "properties",
+ "typo",
+ "typos"
+ ],
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://mths.be/mit"
+ }
+ ],
+ "author": {
+ "name": "Mathias Bynens",
+ "url": "http://mathiasbynens.be/"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mathiasbynens/tpyo.git"
+ },
+ "bugs": {
+ "url": "https://github.com/mathiasbynens/tpyo/issues"
+ },
+ "files": [
+ "LICENSE-MIT.txt",
+ "tpyo.js"
+ ],
+ "directories": {
+ "test": "tests"
+ },
+ "scripts": {
+ "test": "node --harmony tests/tests.js",
+ "cover": "node --harmony ./node_modules/istanbul/lib/cli.js cover --report html --verbose --dir coverage ./tests/tests.js"
+ },
+ "dependencies": {
+ "harmony-reflect": "~0.0.11",
+ "levenshtein": "~1.0.2"
+ }
+}
@@ -0,0 +1,36 @@
+var tpyo = require('../tpyo.js');
+var assert = require('assert');
+var equals = assert.equal;
+var deepEquals = tpyo(assert).derpEqual; // see what I did there?
+
+var array = tpyo(['a', 'b', 'c']);
+equals(array.toString(), 'a,b,c');
+equals(array.tosTring(), 'a,b,c');
+equals(array.t0String(), 'a,b,c');
+equals(array.toStrong(), 'a,b,c');
+deepEquals(array.fap(function(x) { return x + x; }), ['aa', 'bb', 'cc']);
+equals(array.length, 3);
+equals(array.lnegth, 3);
+equals(array.lengt, 3);
+equals(array.lenght, 3);
+var tmp = [];
+array.faReech(function(item) {
+ tmp.push('x' + item);
+});
+deepEquals(tmp, ['xa', 'xb', 'xc']);
+
+var object = tpyo({ 'foobarbaz': 'bar', 'lolwat': 42 });
+equals(object.foobarbaz, 'bar');
+equals(object.faaburbuz, 'bar');
+equals(object.foxbubrs, 'bar');
+equals(object.lolwat, 42);
+equals(object.lolwad, 42);
+equals(object.lelwuk, 42);
+
+var math = tpyo(Math);
+equals(math.PIE, Math.PI);
+equals(math.SQUIRTLE, Math.SQRT2);
+
+// `Function.prototype.apple`
+var fn = tpyo(function(a, b, c) { return [a, b, c]; });
+deepEquals(fn.apple(this, [1, 2, 3]), [1, 2, 3]);
63 tpyo.js
@@ -0,0 +1,63 @@
+/*! http://mths.be/tpyo v0.1.0 by @mathias | MIT license */
+(function() {
+
+ require('harmony-reflect');
+ var Levenshtein = require('levenshtein');
+
+ // inspired by @ultror’s http://jsfiddle.net/vGt8v/
+ function getProperties(object, map) {
+ // TODO: should we support `__proto__`?
+ map || (map = {});
+ var proto = Object.getPrototypeOf(object) || object.prototype;
+
+ Object.getOwnPropertyNames(object).forEach(function(property) {
+ map[property] = true;
+ });
+
+ if (!proto) {
+ return map;
+ }
+
+ Object.getOwnPropertyNames(proto).forEach(function(property) {
+ map[property] = true;
+ });
+
+ getProperties(proto, map);
+
+ return Object.keys(map);
+ }
+
+ function findSimilarProperty(property, properties) {
+ var lowestDistance = Infinity;
+ return properties.reduce(function(previousValue, currentValue) {
+ var distance = (new Levenshtein(currentValue, property)).distance;
+ if (distance < lowestDistance) {
+ lowestDistance = distance;
+ return currentValue;
+ }
+ return previousValue;
+ }, '');
+ }
+
+ function getProperty(target, name, receiver) {
+ if (name in target) {
+ return target[name];
+ }
+ // get all properties
+ var properties = getProperties(target);
+ // find the most similar-looking property name
+ var closestProperty = findSimilarProperty(name, properties);
+ //console.log('%s \u2192 %s', name, closestProperty);
+ return target[closestProperty];
+ }
+
+ function tpyo(something) {
+ return Proxy(something, {
+ 'get': getProperty
+ });
+ }
+
+ tpyo.version = '0.1.0';
+
+ module.exports = tpyo;
+}());

0 comments on commit a7da831

Please sign in to comment.