<commit_before>chai        = require 'chai'
should      = chai.should()
expect      = chai.expect
after       = require('fluent-time').after
lies        = require '../src/beautiful-lies'
createLiar = lies.createLiar

# TODO: Add support for simultaneous calls of another (of) callback
# and the handler callback

describe 'Runs callback', ->

  liar = createLiar [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value: 'connected'
    ]
  ]

  it 'should run callback', (done) ->

    liar.connect (err, status) ->
      status.should.equal 'connected'
      done()

describe 'Runs callback (result object instead of array of result object)', ->

  liar = createLiar [
    function_name: 'connect'
    run_callback:
      argument_2:
        value: 'connected'
  ]

  it 'should run callback', (done) ->

    liar.connect (err, status) ->
      status.should.equal 'connected'
      done()

describe 'Runs callback with error arguments', ->

  liar = createLiar [
    function_name: 'query'
    run_callback: [
      argument_1:
        value:
          message: 'Your query was malformed!'
    ]
  ]

  it 'should run callback with correct arguments', (done) ->

    liar.query (err, status) ->
      err.message.should.equal 'Your query was malformed!'
      done()

describe 'Runs callback with dual arguments', ->

  liar = createLiar [
    function_name: 'query'
    run_callback: [
      argument_2:
        value: 3
      argument_3:
        value: [ 'Smith', 'Johnson', 'Jackson' ]
    ]
  ]

  it 'should run callback with correct arguments', (done) ->

    liar.query (err, pages, result) ->
      expect(err).to.be.null
      pages.should.equal 3
      result.should.deep.equal [ 'Smith', 'Johnson', 'Jackson' ]
      done()

describe 'run_callback defined with no_arguments', ->

  passedToCallback = null

  beforeEach (done) ->
    liar = createLiar [
      function_name: 'query',
      run_callback: [
        no_arguments: true
      ]
    ]
    liar.query () ->
      passedToCallback = arguments

    after(50).milliseconds -> done()

  it 'runs callback without arguments', ->
    passedToCallback.length.should.equal 0



describe 'Runs callback order', ->

  it 'should call callbacks in turn', ->

    liar = createLiar [
      function_name: 'query'
      run_callback: [
        {
          argument_3:
            value: 'ninjas'
        },
        {
          argument_2:
            value: 'pirates'
        }
      ]
    ]

    arr = []
    liar.query (dummy1, dummy2, str) ->
      arr.push str

    arr.length.should.equal 0
    after(60).milliseconds ->

      arr[0].should.equal 'ninjas'
      arr.length.should.equal 1

      liar.query (dummy1, str) ->
        arr.push str

      after(60).milliseconds ->
        arr[1].should.equal 'pirates'


  it 'should work with multiple expectations', (done) ->

    liar = createLiar [
      {
        function_name: 'count'
        run_callback: [
          {
            argument_1:
              value: 'one'
          },
          {
            argument_1:
              value: 'two'
          }
        ]
      },{
        function_name: 'bark',
        run_callback: [
          {
            argument_1:
              value: 'woof!'
          },
          {
            argument_1:
              value: 'ruff!'
          }
        ]
      }
    ]

    liar.count (result) ->
      result.should.equal 'one'
      liar.bark (result) ->
        result.should.equal 'woof!'
        liar.count (result) ->
          result.should.equal 'two'
          liar.bark (result) ->
            result.should.equal 'ruff!'
            done()



  describe 'yeild delay', ->

    describe 'when running callback without any delay specified', ->

      result = null

      beforeEach (done) ->
        liar = createLiar [
          function_name: 'query'
          run_callback: [
            {
              argument_1:
                value: '47 ninjas'
            }
          ]
        ]
        liar.query (r) -> result = r
        done()

      it 'should not have called back after 49ms', (done) ->

        after(10).milliseconds ->
          should.not.exist result
          done()

      it 'should have callbed back after 50ms', (done) ->

        after(50).milliseconds ->
          result.should.equal '47 ninjas'
          done()

    describe 'when calling back with a delay of 237 ms', () ->
      result = null
      beforeEach (done) ->
        liar = createLiar [
          function_name: 'query'
          run_callback: [
            {
              argument_1:
                value: '49 ninjas'
              delay: 237
            }
          ]
        ]
        liar.query (r) ->
          result = r
        done()

      it 'should not have called back after 236ms', (done) ->
        after(236).milliseconds ->
          should.not.exist result
          done()

      it 'should have called back after 237ms', (done) ->
        after(237).milliseconds ->
          result.should.equal '49 ninjas'
          done()

describe 'run_callback has an "of" property', (done) ->

  onLoadResult = null
  onErrorResult = null
  liar = null

  describe 'and has one event listener', ->
    liar = null
    yielded = null

    beforeEach (done) ->

      liar = createLiar [
        {
          function_name: 'addEventListener'
        }, {
          function_name: 'loadStuff'
          run_callback:
            of:
              function_name: 'addEventListener'
              arguments: [ 'onLoad' ]
            argument_2:
              value: 'This is a result!'
        }
      ]



      liar.addEventListener 'onLoad', (error, result) ->
        yielded = result
      liar.loadStuff()

      after(100).milliseconds -> done()

    it 'executes addEventListener callback', ->
      yielded.should.equal 'This is a result!'

  describe 'and has multiple event listeners', ->



    beforeEach ->
      liar = createLiar [
        {
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]
        }, {
          function_name: 'addEventListener'
          arguments: [ 'onError' ]
        }, {
          function_name: 'loadStuff'
          run_callback: [
            {
              of:
                function_name: 'addEventListener'
                arguments: [ 'onLoad' ]
              argument_1:
                value: 'This is a result!'
            },{
              of:
                function_name: 'addEventListener'
                arguments: [ 'onError' ]
              argument_1:
                value: 'This is an error!'
            }
          ]
        }
      ]

      liar.addEventListener 'onLoad', (result) -> onLoadResult = result
      liar.addEventListener 'onError', (result) -> onErrorResult = result

    describe 'when calling loadStuff the first time', ->
      beforeEach (done) ->
        liar.loadStuff()
        after(60).milliseconds -> done()

      it 'gets the result', ->
        onLoadResult.should.equal 'This is a result!'

      it 'and does not get an error', ->
        expect(onErrorResult).to.equal null

      describe 'but when calling it a second time', ->
        beforeEach (done) ->
          liar.loadStuff()
          after(100).milliseconds -> done()

        it 'gets the error', ->
          onErrorResult.should.equal 'This is an error!'

  describe 'and defines a single argument (as opposed to array)', ->
    beforeEach ->
      liar = createLiar [
        {
          function_name: 'addEventListener'
          arguments: [ 'onResult' ]
        },{
          function_name: 'loadThings'
          run_callback: {
            of:
              function_name: 'addEventListener'
              arguments: 'onResult' # <- Look ma, no []!
            argument_1:
              value: 'This is a result!'
          }
        }
      ]

    describe 'and loads things', ->
      beforeEach (done) ->
        liar.addEventListener 'onResult', (result) -> onLoadResult = result
        liar.loadThings()
        after(51).milliseconds -> done()

      it 'should get the correct result', ->
        onLoadResult.should.equal 'This is a result!'




  # TODO certain arguments

it 'should support on_value for callback arguments', (done) ->

  liar = createLiar [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value:
          status: 'open'
        on_value: [
          function_name: 'query'
          returns:
            value:
              size: 72
        ]
    ]
  ]

  liar.connect (err, connection) ->
    connection.status.should.equal 'open'
    connection.query().size.should.equal 72
    done()

it 'should treat simple objects to on_value the same way as an array with 1 item', (done) ->

  liar = createLiar [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value:
          status: 'open'
        on_value: # Same as the above test, but with no array
                  # passed to on_value.
          function_name: 'query'
          returns:
            value:
              size: 72
    ]
  ]

  liar.connect (err, connection) ->
    connection.status.should.equal 'open'
    connection.query().size.should.equal 72
    done()

describe 'Syntax checking', ->

  it 'should have a nice warning when too few callbacks', ->
    (->
      liar = createLiar [
        function_name: 'kaboom'
        run_callback: [
          {
            argument_1:
              value: 'bam!'
          },
          {
            argument_1:
              value: 'boom!'
          }
        ]
      ]
      liar.kaboom(()->)
      liar.kaboom() # Doesn't have a callback, but should still count.
      liar.kaboom(()->)
    ).should.throw 'kaboom was called 3 times, but only defined 2 run_callback.'

  it 'should not display the nice warning when there is only a single callback result', (done) ->
    liar = createLiar [
      function_name: 'shoot',
      run_callback: [{
        argument_1:
          value: 'pew!'
      }]
    ]

    liar.shoot (res) ->
      res.should.equal 'pew!'
      liar.shoot (res) ->
        res.should.equal 'pew!'
        done()

  it 'should validate that arguments is an array (on_value)', ->
    (->
      liar = createLiar [
        function_name: 'birth'
        returns:
          value: {}
          on_value: [
            function_name: 'bark'
            arguments: 7
            returns:
              value: 'Yiff!'
          ]
      ]
      liar.birth().bark(7)
    ).should.throw 'arguments must be of type Array.'

  it 'should validate function_name of on_value', ->
    (->
      liar = createLiar [
        function_name: 'do_stuff'
        returns:
          value: {}
          on_value: [
            functionn_name: "do_something_else"  # misspelled
          ]
      ]
      liar.do_stuff()
    ).should.throw 'expectation must have property "function_name"'

  it 'should verify that of is an object (string)', ->
    (->
      liar = createLiar [
        function_name: 'do_things'
        run_callback:
          of: 'otherFunction'
      ]
      liar.do_things()
    ).should.throw 'run_callback.of property was set to "otherFunction" - must be an object.'

  it 'should verify that of is an object (number)', ->
    (->
      liar = createLiar [
        function_name: 'hello'
        run_callback:
          of: 871
      ]
      liar.hello()
    ).should.throw 'run_callback.of property was set to "871" - must be an object.'

  it 'should throw pretty error message if an of command does\'nt match any callback', ->
    (->
      liar = createLiar [{
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]
        },{
          function_name: 'runLoader'
          run_callback:
            of:
              function_name: 'addEventListener'
              arguments: ['onload'] # <- OOPS, a misspelling!
        }
      ]
      liar.addEventListener 'onLoad', ->
      liar.runLoader()
    ).should.throw 'Tried to run callback provided to addEventListener along with arguments [ onload ], but didn\'t find any. Did you misspell function_name or arguments, or perhaps the callback was never passed to addEventListener?'

  it 'should throw a nice error message if too broad a match', ->
    (->
      liar = createLiar [
        {
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]<commit_msg>Updated callback_ordered to new expect syntax<commit_after>chai        = require 'chai'
should      = chai.should()
expect      = chai.expect
after       = require('fluent-time').after
lies        = require '../src/beautiful-lies'

lies.init()

# TODO: Add support for simultaneous calls of another (of) callback
# and the handler callback

describe 'Runs callback', ->

  liar = {}

  liar.expect [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value: 'connected'
    ]
  ]

  it 'should run callback', (done) ->

    liar.connect (err, status) ->
      status.should.equal 'connected'
      done()

describe 'Runs callback (result object instead of array of result object)', ->

  liar = {}

  liar.expect [
    function_name: 'connect'
    run_callback:
      argument_2:
        value: 'connected'
  ]

  it 'should run callback', (done) ->

    liar.connect (err, status) ->
      status.should.equal 'connected'
      done()

describe 'Runs callback with error arguments', ->
  liar = {}
  liar.expect [
    function_name: 'query'
    run_callback: [
      argument_1:
        value:
          message: 'Your query was malformed!'
    ]
  ]

  it 'should run callback with correct arguments', (done) ->

    liar.query (err, status) ->
      err.message.should.equal 'Your query was malformed!'
      done()

describe 'Runs callback with dual arguments', ->
  liar = {}
  liar.expect [
    function_name: 'query'
    run_callback: [
      argument_2:
        value: 3
      argument_3:
        value: [ 'Smith', 'Johnson', 'Jackson' ]
    ]
  ]

  it 'should run callback with correct arguments', (done) ->

    liar.query (err, pages, result) ->
      expect(err).to.be.null
      pages.should.equal 3
      result.should.deep.equal [ 'Smith', 'Johnson', 'Jackson' ]
      done()

describe 'run_callback defined with no_arguments', ->
  liar = {}
  passedToCallback = null

  beforeEach (done) ->
    liar.expect [
      function_name: 'query',
      run_callback: [
        no_arguments: true
      ]
    ]
    liar.query () ->
      passedToCallback = arguments

    after(50).milliseconds -> done()

  it 'runs callback without arguments', ->
    passedToCallback.length.should.equal 0



describe 'Runs callback order', ->


  it 'should call callbacks in turn', ->
    liar = {}
    liar.expect [
      function_name: 'query'
      run_callback: [
        {
          argument_3:
            value: 'ninjas'
        },
        {
          argument_2:
            value: 'pirates'
        }
      ]
    ]

    arr = []
    liar.query (dummy1, dummy2, str) ->
      arr.push str

    arr.length.should.equal 0
    after(60).milliseconds ->

      arr[0].should.equal 'ninjas'
      arr.length.should.equal 1

      liar.query (dummy1, str) ->
        arr.push str

      after(60).milliseconds ->
        arr[1].should.equal 'pirates'


  it 'should work with multiple expectations', (done) ->
    liar = {}
    liar.expect [
      {
        function_name: 'count'
        run_callback: [
          {
            argument_1:
              value: 'one'
          },
          {
            argument_1:
              value: 'two'
          }
        ]
      },{
        function_name: 'bark',
        run_callback: [
          {
            argument_1:
              value: 'woof!'
          },
          {
            argument_1:
              value: 'ruff!'
          }
        ]
      }
    ]

    liar.count (result) ->
      result.should.equal 'one'
      liar.bark (result) ->
        result.should.equal 'woof!'
        liar.count (result) ->
          result.should.equal 'two'
          liar.bark (result) ->
            result.should.equal 'ruff!'
            done()



  describe 'yeild delay', ->


    describe 'when running callback without any delay specified', ->
      liar = null
      result = null

      beforeEach (done) ->
        liar = {}

        liar.expect [
          function_name: 'query'
          run_callback: [
            {
              argument_1:
                value: '47 ninjas'
            }
          ]
        ]
        liar.query (r) -> result = r
        done()

      it 'should not have called back after 49ms', (done) ->

        after(10).milliseconds ->
          should.not.exist result
          done()

      it 'should have callbed back after 50ms', (done) ->

        after(50).milliseconds ->
          result.should.equal '47 ninjas'
          done()

    describe 'when calling back with a delay of 237 ms', () ->
      liar = null
      result = null
      beforeEach (done) ->
        liar = {}
        liar.expect [
          function_name: 'query'
          run_callback: [
            {
              argument_1:
                value: '49 ninjas'
              delay: 237
            }
          ]
        ]
        liar.query (r) ->
          result = r
        done()

      it 'should not have called back after 236ms', (done) ->
        after(236).milliseconds ->
          should.not.exist result
          done()

      it 'should have called back after 237ms', (done) ->
        after(237).milliseconds ->
          result.should.equal '49 ninjas'
          done()

describe 'run_callback has an "of" property', (done) ->

  onLoadResult = null
  onErrorResult = null
  yielded = null
  liar = null

  beforeEach ->
    onLoadResult = null
    onErrorResult = null
    yielded = null
    liar = {}


  describe 'and has one event listener', ->

    beforeEach (done) ->

      liar.expect [
        {
          function_name: 'addEventListener'
        }, {
          function_name: 'loadStuff'
          run_callback:
            of:
              function_name: 'addEventListener'
              arguments: [ 'onLoad' ]
            argument_2:
              value: 'This is a result!'
        }
      ]

      liar.addEventListener 'onLoad', (error, result) ->
        yielded = result
      liar.loadStuff()

      after(100).milliseconds -> done()

    it 'executes addEventListener callback', ->
      yielded.should.equal 'This is a result!'

  describe 'and has multiple event listeners', ->

    beforeEach ->
      liar.expect [
        {
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]
        }, {
          function_name: 'addEventListener'
          arguments: [ 'onError' ]
        }, {
          function_name: 'loadStuff'
          run_callback: [
            {
              of:
                function_name: 'addEventListener'
                arguments: [ 'onLoad' ]
              argument_1:
                value: 'This is a result!'
            },{
              of:
                function_name: 'addEventListener'
                arguments: [ 'onError' ]
              argument_1:
                value: 'This is an error!'
            }
          ]
        }
      ]

      liar.addEventListener 'onLoad', (result) -> onLoadResult = result
      liar.addEventListener 'onError', (result) -> onErrorResult = result

    describe 'when calling loadStuff the first time', ->
      beforeEach (done) ->
        liar.loadStuff()
        after(60).milliseconds -> done()

      it 'gets the result', ->
        onLoadResult.should.equal 'This is a result!'

      it 'and does not get an error', ->
        expect(onErrorResult).to.equal null

      describe 'but when calling it a second time', ->
        beforeEach (done) ->
          liar.loadStuff()
          after(100).milliseconds -> done()

        it 'gets the error', ->
          onErrorResult.should.equal 'This is an error!'

  describe 'and defines a single argument (as opposed to array)', ->
    beforeEach ->
      liar.expect [
        {
          function_name: 'addEventListener'
          arguments: [ 'onResult' ]
        },{
          function_name: 'loadThings'
          run_callback: {
            of:
              function_name: 'addEventListener'
              arguments: 'onResult' # <- Look ma, no []!
            argument_1:
              value: 'This is a result!'
          }
        }
      ]

    describe 'and loads things', ->
      beforeEach (done) ->
        liar.addEventListener 'onResult', (result) -> onLoadResult = result
        liar.loadThings()
        after(51).milliseconds -> done()

      it 'should get the correct result', ->
        onLoadResult.should.equal 'This is a result!'




  # TODO certain arguments

it 'should support on_value for callback arguments', (done) ->
  liar = {}
  liar.expect [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value:
          status: 'open'
        on_value: [
          function_name: 'query'
          returns:
            value:
              size: 72
        ]
    ]
  ]

  liar.connect (err, connection) ->
    connection.status.should.equal 'open'
    connection.query().size.should.equal 72
    done()

it 'should treat simple objects to on_value the same way as an array with 1 item', (done) ->
  liar = {}
  liar.expect [
    function_name: 'connect'
    run_callback: [
      argument_2:
        value:
          status: 'open'
        on_value: # Same as the above test, but with no array
                  # passed to on_value.
          function_name: 'query'
          returns:
            value:
              size: 72
    ]
  ]

  liar.connect (err, connection) ->
    connection.status.should.equal 'open'
    connection.query().size.should.equal 72
    done()

describe 'Syntax checking', ->
  liar = null
  beforeEach -> liar = {}
  it 'should have a nice warning when too few callbacks', ->
    (->
      liar.expect [
        function_name: 'kaboom'
        run_callback: [
          {
            argument_1:
              value: 'bam!'
          },
          {
            argument_1:
              value: 'boom!'
          }
        ]
      ]
      liar.kaboom(()->)
      liar.kaboom() # Doesn't have a callback, but should still count.
      liar.kaboom(()->)
    ).should.throw 'kaboom was called 3 times, but only defined 2 run_callback.'

  it 'should not display the nice warning when there is only a single callback result', (done) ->
    liar.expect [
      function_name: 'shoot',
      run_callback: [{
        argument_1:
          value: 'pew!'
      }]
    ]

    liar.shoot (res) ->
      res.should.equal 'pew!'
      liar.shoot (res) ->
        res.should.equal 'pew!'
        done()

  it 'should validate that arguments is an array (on_value)', ->
    (->
      liar.expect [
        function_name: 'birth'
        returns:
          value: {}
          on_value: [
            function_name: 'bark'
            arguments: 7
            returns:
              value: 'Yiff!'
          ]
      ]
      liar.birth().bark(7)
    ).should.throw 'arguments must be of type Array.'

  it 'should validate function_name of on_value', ->
    (->
      liar.expect [
        function_name: 'do_stuff'
        returns:
          value: {}
          on_value: [
            functionn_name: "do_something_else"  # misspelled
          ]
      ]
      liar.do_stuff()
    ).should.throw 'expectation must have property "function_name"'

  it 'should verify that of is an object (string)', ->
    (->
      liar.expect [
        function_name: 'do_things'
        run_callback:
          of: 'otherFunction'
      ]
      liar.do_things()
    ).should.throw 'run_callback.of property was set to "otherFunction" - must be an object.'

  it 'should verify that of is an object (number)', ->
    (->
      liar.expect [
        function_name: 'hello'
        run_callback:
          of: 871
      ]
      liar.hello()
    ).should.throw 'run_callback.of property was set to "871" - must be an object.'

  it 'should throw pretty error message if an of command does\'nt match any callback', ->
    (->
      liar.expect [{
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]
        },{
          function_name: 'runLoader'
          run_callback:
            of:
              function_name: 'addEventListener'
              arguments: ['onload'] # <- OOPS, a misspelling!
        }
      ]
      liar.addEventListener 'onLoad', ->
      liar.runLoader()
    ).should.throw 'Tried to run callback provided to addEventListener along with arguments [ onload ], but didn\'t find any. Did you misspell function_name or arguments, or perhaps the callback was never passed to addEventListener?'

  it 'should throw a nice error message if too broad a match', ->
    (->
      liar.expect [
        {
          function_name: 'addEventListener'
          arguments: [ 'onLoad' ]
{'fraction_non_alphanumeric': 0.10937750681854645, 'fraction_numerical': 0.008102037542114552, 'mean_word_length': 1.6623598505072077, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 193, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7221740', 'n_tokens_mistral': 7427, 'n_tokens_neox': 7058, 'n_words': 1935}