 #
 # The Element common methods section unit tests
 #
-# Copyright (C) 2011 Nikolay Nemshilov
+# Copyright (C) 2011-2012 Nikolay Nemshilov
 #
-{describe, assert, server, load_element} = require('../../test_helper')
-
-server.respond "/commons.html": """
+{Browser} = require('../../test_helper')
+
+Browser.respond "/commons.html": """
   <html>
     <head>
       <script src="/core.js"></script>

  </html>
  """

test_element = ->
  load_element("/commons.html", this, 'test')


describe 'Element Commons', module,
  "#attr":

    "\b('name')":
      topic: test_element

      "should read a property attribute": (element) ->
        assert.equal element.attr('id'), 'test'

      "should read the 'data-test' attribute": (element) ->
        assert.equal element.attr('data-test'), 'test'

      "should return 'null' for non existing attributes": (element) ->
        assert.isNull element.attr('nonexistent')


    "\b('name', 'value')":
      topic: test_element

      "should return the element back": (element) ->
        assert.same element.attr('title', 'text'), element

      "should set property attributes": (element) ->
        element.attr('title', 'new value')
        assert.equal element._.title, 'new value'

      "should set non-property attributes": (element) ->
        element.attr('data-new', 'something')
        assert.equal element._.getAttribute('data-new'), 'something'


    "\b({name: 'value'})":
      topic: test_element

      "should return the element back afterwards": (element) ->
        assert.same element.attr(smth: 'value'), element

      "should set all the attributes from the hash": (element) ->
        element.attr
          test_attr1: 'value1'
          test_attr2: 'value2'

        assert.equal element._.getAttribute('test_attr1'), 'value1'
        assert.equal element._.getAttribute('test_attr2'), 'value2'


    "\b('name', null)":
      topic: test_element

      "should remove the attribute": (element) ->
        element.attr('something', 'something')
        assert.equal element.attr('something'), 'something'

        element.attr('something', null)
        assert.isNull element.attr('something')


  "#hidden()":
    topic: test_element

    "should say 'true' when the element is hidden": (element)->
      element._.style.display = 'none'
      assert.isTrue element.hidden()

    "should say 'false' when the element is visible": (element)->
      element._.style.display = 'block'
      assert.isFalse element.hidden()

  "#visible()":
    topic: test_element

    "should say 'false' when the element is hidden": (element)->
      element._.style.display = 'none'
      assert.isFalse element.visible()

    "should say 'true' when the element is visible": (element)->
      element._.style.display = 'block'
      assert.isTrue element.visible()

  "#hide()":
    topic: test_element

    "should hide the element when it is visible": (element)->
      element._.style.display = 'block'
      element.hide()
      assert.equal element._.style.display, 'none'

    "should leave element hidden when it is not visible": (element)->
      element._.style.display = 'none'
      element.hide()
      assert.equal element._.style.display, 'none'

    "should return the element reference back": (element)->
      assert.same element.hide(), element

  "#show()":
    topic: test_element

    "should show an element if it's hidden": (element)->
      element._.style.display = 'none'
      element.show()
      assert.equal element._.style.display, 'block'

    "should leave a visible element visible": (element)->
      element._.style.display = 'inline'
      element.show()
      assert.equal element._.style.display, 'inline'

    "should return the element reference back": (element)->
      assert.same element.show(), element

  "#toggle()":
    topic: test_element

    "should show an element if it is hidden": (element)->
      element._.style.display = 'none'
      element.toggle()
      assert.equal element._.style.display, 'block'

    "should hide an element if it's visible": (element)->
      element._.style.display = 'block'
      element.toggle()
      assert.equal element._.style.display, 'none'

    "should return back a reference to the element": (element)->
      assert.same element.toggle(), element


  "#document()":
    topic: test_element

    "should return the owner document wrapper": (element)->
      document = element.document()

      assert.instanceOf document, this.Document
      assert.same       document._, this.document

    "should return the same wrapper all the time": (element)->
      assert.same element.document(), element.document()

  "#window()":
    topic: test_element

    "should return the owner window wrapper": (element)->
      window = element.window()

      assert.instanceOf window,          this.Window
      assert.same       window._.window, this.window.window

  "#data()":
    topic: test_element

    "should read data- attributes": (element)->
      element.attr({
        'data-false':  'false'
        'data-true':   'true'

        'data-plain':  'plain text'
      })

      element.data('false').should.equal  false
      element.data('true').should.equal   true
      element.data('number').should.equal 1.23
      element.data('string').should.equal 'string'
      element.data('array').should.eql    [1,2,3]
      element.data('object').should.eql   {boo: "hoo"}
      element.data('plain').should.equal  'plain text'
      (element.data('non-existing') is null).should.be.true

    it "should read nested attributes", get (element)->
      element.attr({
        'data-thing-one': '1'
        'data-thing-two': '2'
        'data-thing-three-one': '3.1'
      })

      element.data('thing').should.eql {
        one: 1, two: 2, threeOne: 3.1
      }

    it "should write data- attributes", get (element)->
      element.data('string', 'string').should.equal element
      element._.getAttribute('data-string').should.equal 'string'
      (element['data-string'] is undefined).should.be.true

      element.data('false', false)._.getAttribute('data-false').should.equal   'false'
      element.data('true', true)._.getAttribute('data-true').should.equal      'true'
      element.data('number', 1.23)._.getAttribute('data-number').should.equal  '1.23'
      element.data('array', [1,2,3])._.getAttribute('data-array').should.equal '[1,2,3]'

    it "should allow to write data as a plain hash", get (element)->
      element.data({
        one: 1, two: 2, three: 3
      }).should.equal element

      element._.getAttribute('data-one').should.equal   '1'
      element._.getAttribute('data-two').should.equal   '2'
      element._.getAttribute('data-three').should.equal '3'

    it "should allow to write data as a nested hash", get (element)->
      element.data('test', {
        'one': 1, two: 2, 'three-one': 3.1, 'threeTwo': 3.2
      }).should.equal element

      element._.getAttribute('data-test-one').should.equal       '1'
      element._.getAttribute('data-test-two').should.equal       '2'
      element._.getAttribute('data-test-three-one').should.equal '3.1'
      element._.getAttribute('data-test-three-two').should.equal '3.2'

    it "should allow to remove data- attributes", get (element)->
      element.attr {'data-something': 'something'}

      element.data('something', null).should.equal          element
      (element._.getAttribute('data-something') is null).should.be.true
