 describe "A basic funnel", ->
 
+  count = 0
   funnel = {}
   rules =
     # in this case only one rule depends on our `input` - a reserved rule
     word: (input) ->
       # notice how we are returning multiple times in the same function
       @return word for word in input.split(' ')
+
+    # keep track of how many words have been passed into this funnel
+    $word_count: (self, word) ->
+      @return if self then self + 1 else 1
+
+    # keep track of how many times each word has been passed in to this funnel
+    $word_frequency: (self, $word) ->
+      @return if self then self + 1 else 1
 
     # `char` depends on `word`, returning charicters
     char: (word) ->

    # `word_has_vowel` depends on `input` and `word_has_vowel`
    # it is keyed on `input`
    not_english: (self, $input, word_has_vowel) ->
      @return self && word_has_vowel
  
  beforeEach ->
    # Create our funnel
    funnel = new Funnel(rules)
  
  describe "the basic dependency structure", ->

    it "calls a rule each time a new set of dependencies is satisfied", ->
      output1 = output2 = output3 = ""
      count = 0

      inputString = "The quick brown fox jumps over the lazy dog"


      funnel.input(inputString)
      
      expect(count).toEqual 45

  describe "keyed dependencies and the self keyword", ->

    xit "sets self to `undefined` if rule hasn't been run with the same key", ->
      
      funnel.listen( (self, $input) ->
        count += 1
        expect(self).toBeUndefined()
      )

      funnel.input('blarg')

      expect(count).toEqual 1

    xit "keys rules based on the `$` prefix", ->

  describe "persistence", ->

    describe "non-persisted rules", ->

      xit "initially sets `self` to `undefined` even if input is repeated", ->
        funnel.listen( (self, $input) ->
          count += 1
          expect(self).toBeUndefined()
          @return "Just listened to: #{$input}!"
        )

        funnel.input('blarg')
        funnel.input('blarg')

        expect(count).toEqual 2

      xit "properly reduces using the `self` keyword", ->

    describe "persisted rules", ->

      xit "keeps self the same if there are no keyed inputs", ->
        funnel.listen( (word_count) ->
          count += 1
          expect(word_count).toEqual count
        )

        funnel.input('hello world!')
        funnel.input('hello world!')

        expect(count).toEqual 2
      
      xit "keep self the same when keyed inputs match", ->
        funnel.listen( (word_frequency) ->
          expect(word_frequency).toEqual parseInt(count/4)+1
          count += 1
        )

        funnel.input('testing one two three')
        funnel.input('testing one two three')

        expect(count).toEqual 2
