Permalink
Browse files

[rant] ExtendObject

  • Loading branch information...
1 parent 8be66dd commit 43cf10f4f1d38b33d34c811b2f655bb53e029c5c @alejandro committed Apr 1, 2013
Showing 392 changed files with 30,313 additions and 4 deletions.
@@ -0,0 +1 @@
+# Extended Objects
View
@@ -0,0 +1,139 @@
+/**
+ * Object extended
+ * -------------------------
+ * Cuz' simple objects are main stream
+ * @author: Alejandro Morales <vamg008@gmail.com>
+ * @license: MIT 2013 <http://ale.mit-license.org>
+ * @date: date
+ */ 'use strict';
+
+// Is this a good idea? Hell no! But I like my objects with get/has and emitter
+module.exports = ExtendedObject
+
+/**
+ * ExtendedObject
+ * ------------
+ * Add a bunch of tools to raw objects
+ * - get
+ * - has
+ * - set / mixin
+ * Options: 'separator', the char used to separate levels (o.get('a:b:c'), separator -> ':')
+ *
+ */
+function ExtendedObject(options){
+ if (!(this instanceof ExtendedObject)) return new ExtendedObject(options)
+ if (!options.separator) options.separator = '.'
+ ExtendedObject.mix(options)
+}
+
+ExtendedObject.create = function(options){
+ return new ExtendedObject(options)
+}
+
+/**
+ * ExtendObject#mix
+ * ------------
+ * Mix the options with constructor into private properties
+ *
+ */
+ExtendedObject.mix = function (options){
+ Object.keys(options).forEach(function(key){
+ Object.defineProperty(ExtendedObject.prototype, '_' + key, {
+ get: function (){
+ // if (typeof options[key] == 'function') return options[key].call(this)
+ return options[key]
+ },
+ enumerable: false
+ })
+ })
+}
+
+/**
+ * ExtendObject#getElementsByTagName('')
+ * ------------
+ * Gets the value in the main object
+ *
+ * // o -> { a: 2, b: {c:{ f: 1, d: 2}}}
+ *
+ * o.get('a.b.c') // -> {f: 1, d: 2}
+ * o.get('a.b.c.d') // -> 2
+ */
+ExtendedObject.prototype.get = function (id){
+ var deep = destructure(id, this._separator)
+ var noexist = false
+ var found = deep.reduce(function (prev, next){
+ if (!prev) return this[next]
+ if (prev[next]) return prev[next]
+ else {
+ noexist = true
+ return prev
+ }
+ }, this)
+ if (noexist) return null
+ else return found
+}
+
+/**
+ * ExtendObject#mixin
+ * ------------
+ * Alias to ExtendObject#set
+ *
+ */
+ExtendedObject.prototype.mixin = function (newStuff){
+ return this.set(newStuff)
+}
+
+ExtendedObject.prototype.set = function (id, tng){
+ if (!tng && typeof id === 'object') {
+ return Object.keys(id).forEach(function(tn){ this.set(tn, id[tn]) }, this)
+ }
+ insertInto(this, id, tng, this._separator)
+ if (typeof this._change == 'function') this._change.call(this, id, tng)
+ return this
+}
+
+// Has a key? true/false
+ExtendedObject.prototype.has = function(id){
+ if (this.get(id)) return true
+ return false
+}
+
+// --- Helpers --
+function insertInto(o, id, tn, _separator) {
+ var steps = id
+ if (!Array.isArray(id)) steps = id.split(_separator)
+ if (steps.length === 1 && !o[id]) {
+ o[id] = tn
+ } else if (!o[id] && steps.length > 1){
+ id = steps.shift()
+ if (o[id] && typeof o[id] === 'object') o[id] = merge(o[id], insertInto({}, steps, tn, _separator))
+ else o[id] = insertInto({}, steps, tn, _separator)
+ } else {
+ id = steps.shift()
+ o[id] = insertInto(o[id], steps, tn, _separator)
+ }
+ return o
+}
+
+function merge(obj1, obj2) {
+ for (var prop in obj2) {
+ try {
+ if (obj2[prop].constructor == Object) {
+ obj1[prop] = merge(obj1[prop], obj2[prop])
+ } else {
+ obj1[prop] = obj2[prop]
+ }
+ } catch(e) {
+ obj1[prop] = obj2[prop]
+ }
+ }
+ return obj1
+}
+
+function destructure(obj, _separator) {
+ if (Array.isArray(obj)) return obj
+ return obj.split(_separator || '.')
+}
+
+// -- endHelpers --
+
@@ -0,0 +1,11 @@
+# contributors sorted by whether or not they're me
+Isaac Z. Schlueter <i@izs.me>
+baudehlo <helpme+github@gmail.com>
+James Halliday <mail@substack.net>
+Jason Smith (air) <jhs@iriscouch.com>
+Pedro P. Candel <kusorbox@gmail.com>
+Stein Martin Hustad <stein@hustad.com>
+Trent Mick <trentm@gmail.com>
+Corey Richardson <kb1pkl@aim.com>
+Raynos <raynos2@gmail.com>
+Siddharth Mahendraker <siddharth_mahen@me.com>
@@ -0,0 +1,23 @@
+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+All rights reserved.
+
+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,84 @@
+This is a mix-and-match set of utilities that you can use to write test
+harnesses and frameworks that communicate with one another using the
+Test Anything Protocol.
+
+If you don't yet know what TAP is, [you better ask
+somebody](http://testanything.org/).
+
+Default Usage:
+
+1. Make a directory. Maybe call it 'test'. That'd be nice and obvious.
+2. Put a bunch of test scripts in there. If they're node programs, then
+ they should be ".js". Anything else is assumed to be some kind of shell
+ script, which should have a shebang line.
+3. `npm install tap`
+4. Update package.json scripts.test to include `tap ./test` [example
+ gist](https://gist.github.com/4469613)
+5. `npm test`
+
+The output will be TAP-compliant.
+
+For extra special bonus points, you can do something like this:
+
+ var test = require("tap").test
+ test("make sure the thingie is a thing", function (t) {
+ t.equal(thingie, "thing", "thingie should be thing")
+ t.type(thingie, "string", "type of thingie is string")
+ t.ok(true, "this is always true")
+ t.notOk(false, "this is never true")
+ t.test("a child test", function (t) {
+ t.equal(this, superEasy, "right!?")
+ t.similar(7, 2, "ever notice 7 is kinda like 2?", {todo: true})
+ t.test("so skippable", {skip: true}, function (t) {
+ t.plan(1) // only one test in this block
+ t.ok(true, "but when the flag changes, it'll pass")
+ // no need to end, since we had a plan.
+ })
+ t.end()
+ })
+ t.ok(99, "can also skip individual assertions", {skip: true})
+ // end lets it know it's over.
+ t.end()
+ })
+ test("another one", function (t) {
+ t.plan(1)
+ t.ok(true, "It's ok to plan, and also end. Watch.")
+ t.end() // but it must match the plan!
+ })
+
+Node-tap is actually a collection of several modules, any of which may be
+mixed and matched however you please.
+
+If you don't like this test framework, and think you can do much much
+better, *I strongly encourage you to do so!* If you use this library,
+however, at least to output TAP-compliant results when `process.env.TAP`
+is set, then the data coming out of your framework will be much more
+consumable by machines.
+
+You can also use this to build programs that *consume* the TAP data, so
+this is very useful for CI systems and such.
+
+* tap-assert: A collection of assert functions that return TAP result
+ objects.
+* tap-consumer: A stream interface for consuming TAP data.
+* tap-producer: A class that produces a TAP stream by taking in result
+ objects.
+* tap-results: A class for keeping track of TAP result objects as they
+ pass by, counting up skips, passes, fails, and so on.
+* tap-runner: A program that runs through a directory running all the
+ tests in it. (Tests which may or may not be TAP-outputting tests. But
+ it's better if they are.)
+* tap-test: A class for actually running tests.
+* tap-harness: A class that runs tests. (Tests are also Harnesses,
+ which is how sub-tests run.)
+* tap-global-harness: A default harness that provides the top-level
+ support for running TAP tests.
+
+## Experimental Code Coverage with runforcover & bunker:
+
+```
+TAP_COV=1 tap ./test [--cover=./lib,foo.js] [--cover-dir=./coverage]
+```
+
+This feature is experimental, and will most likely change somewhat
+before being finalized. Feedback welcome.
@@ -0,0 +1,19 @@
+#!/usr/bin/env node
+
+// just an example, really
+// Run with `node tap-http.js path/to/tests/`
+
+var argv = process.argv.slice(2)
+ , path = require("path")
+ , Runner = require("../lib/tap-runner")
+
+ , http = require("http")
+ , server = http.createServer(function (req, res) {
+ // it'd be nice to return a non-200 if the tests fail, but we don't
+ // know the status until it's done, so that would mean not being able
+ // to pipe the output
+ res.writeHead(200, {'content-type': 'text/plain'})
+ new Runner(argv, null).pipe(res)
+ })
+
+server.listen(1337)
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+
+// read a tap stream from stdin.
+
+var TapConsumer = require("../lib/tap-consumer")
+ , TapProducer = require("../lib/tap-producer")
+
+var tc = new TapConsumer
+ , tp = new TapProducer
+
+//process.stdin.pipe(tc)
+process.stdin.on("data", function (c) {
+ c = c + ""
+ // console.error(JSON.stringify(c).substr(0, 100))
+ tc.write(c)
+})
+process.stdin.on("end", function () { tc.end() })
+process.stdin.resume()
+//tc.pipe(tp)
+tc.on("data", function (c) {
+ tp.write(c)
+})
+tc.on("end", function () { tp.end() })
+
+tp.on("data", function (c) {
+ console.error(["output write", c])
+ process.stdout.write(c)
+})
+
+tp.on("end", function (er, total, ok) {
+ if (er) throw er
+ process.exit(total - ok)
+})
Oops, something went wrong.

0 comments on commit 43cf10f

Please sign in to comment.