Passing tests.

This commit is contained in:
Elf M. Sternberg 2013-04-27 13:53:31 -07:00
parent 7d7bf35d63
commit 8c96acf0f0
5 changed files with 72 additions and 6 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
npm-debug.log npm-debug.log
node_modules/* node_modules/*
lib/ lib/
tmp/

View File

@ -13,11 +13,11 @@ lib:
lib/tumble.js: lib src/tumble.peg lib/tumble.js: lib src/tumble.peg
./node_modules/.bin/pegjs src/tumble.peg lib/tumble.js ./node_modules/.bin/pegjs src/tumble.peg lib/tumble.js
$(lib_objects): lib lib/%.js: src/%.coffee $(lib_objects): $(lib_sources)
@mkdir -p $(@D) @mkdir -p $(@D)
coffee -o $(@D) -c $< coffee -o $(@D) -c $<
test: test/[0-9]*_mocha.coffee lib/tumble.js test: test/[0-9]*_mocha.coffee lib/tumble.js lib/parser.js
./node_modules/.bin/mocha -R tap -C --compilers coffee:coffee-script -u tdd $< ./node_modules/.bin/mocha -R tap -C --compilers coffee:coffee-script -u tdd $<

63
src/parser.coffee Normal file
View File

@ -0,0 +1,63 @@
_ = require 'underscore'
util = require 'util'
class Contexter
constructor: (@content) ->
@stack = [@content]
@templates = {}
@depth = 0
has_any: (name) ->
_.find this.stack, (o) -> _.has(o, name)
has_any_one: (name) ->
p = @has_any(name)
if p then p[name] else null
has: (name) ->
if @stack[0][name]? then @stack[0][name] else null
get: (name, alt = '') ->
p = @has_any_one(name)
if p and (_.isString(p) or _.isNumber(p)) then p else alt
once: (obj, cb) ->
@stack.unshift obj
r = cb this
@stack.shift()
r
if: (name, cb) ->
p = @has_any_one(name)
if p then cb(this) else ''
block: (name, cb) ->
p = @has_any_one(name)
if p and _.isObject(p) then @once(p, cb) else ''
many: (name, cb) ->
ps = @has(name)
if not (ps and _.isArray(ps))
return ""
(_.map ps, (p) => @once(p, cb)).join('')
templatize: (name, cb) ->
@templates[name] = cb
""
render: (name) ->
if @templates[name]? and _.isfunction(@templates[name]) then @templates[name](@) else ""
module.exports = (ast, data) ->
context = new Contexter(data)
cmd = (o) ->
switch o.unit
when 'variable' then (context) -> context.get(o.name)
when 'text' then (context) -> o.content
when 'block' then (context) -> context[o.type] o.name, (context) ->
(cmd(p)(context) for p in o.content).join("")
(cmd(o)(context) for o in ast.content).join("")

View File

@ -2,7 +2,7 @@
document document
= ps:part* = ps:part*
{ return ps; } { return { unit: "block", name: "document", content: ps }; }
part part
= block / variable / text = block / variable / text

View File

@ -5,6 +5,7 @@ should = chai.should()
util = require 'util' util = require 'util'
tumble = require('../lib/tumble').parse; tumble = require('../lib/tumble').parse;
parse = require('../lib/parser');
test_data = [ test_data = [
{ {
@ -98,7 +99,7 @@ describe "Basic Functionality", ->
do (data) -> do (data) ->
it "should work with #{data.description}", -> it "should work with #{data.description}", ->
r = tumble(data.input) r = tumble(data.input)
r = r(data.data) r = parse(r, data.data)
r.should.equal data.output r.should.equal data.output
describe "Check for recursion", -> describe "Check for recursion", ->
@ -111,7 +112,8 @@ describe "Check for recursion", ->
do (data) -> do (data) ->
it "should catch an exception", -> it "should catch an exception", ->
try try
r = tumble(data.input)(data.data) r = tumble(data.input)
r = parse(r, data.data)
assert.ok false, "It did not throw the exception" assert.ok false, "It did not throw the exception"
catch err catch err
assert.ok true, "Recursion depth exeception thrown." assert.ok err.id == 'recursion-error', "Recursion depth exeception thrown."