 utils = require "../utils"
 
 HasProperties = utils.require "common/has_properties"
-{Document, ModelChangedEvent} = utils.require "common/document"
+{Document, ModelChangedEvent, TitleChangedEvent, RootAddedEvent, RootRemovedEvent, DEFAULT_TITLE} = utils.require "common/document"
 base = utils.require "common/base"
 Collection = utils.require "common/collection"
 


    expect(child1.get('foo')).to.equal 67

  # TODO copy the following tests from test_document.py here
  # TODO(havocp) test_patch_reference_property
  # TODO(havocp) test_patch_two_properties_at_once

  it "sets proper document on models added during construction", ->
    d = new Document()

      expect(e.message).to.include('Multiple models')
    expect(got_error).to.equal(true)

  it "can have all_models with multiple references", ->
    d = new Document()
    expect(d.roots().length).to.equal 0
    expect(_.size(d._all_models)).to.equal 0

    root1 = new SomeModel()
    root2 = new SomeModel()
    child1 = new AnotherModel()
    root1.set('child', child1)
    root2.set('child', child1)
    d.add_root(root1)
    d.add_root(root2)
    expect(d.roots().length).to.equal 2
    expect(_.size(d._all_models)).to.equal 3

    root1.set('child', null)
    expect(_.size(d._all_models)).to.equal 3

    root2.set('child', null)
    expect(_.size(d._all_models)).to.equal 2

    root1.set('child', child1)
    expect(_.size(d._all_models)).to.equal 3

    root2.set('child', child1)
    expect(_.size(d._all_models)).to.equal 3

    d.remove_root(root1)
    expect(_.size(d._all_models)).to.equal 2

    d.remove_root(root2)
    expect(_.size(d._all_models)).to.equal 0

  it "can have all_models with cycles", ->
    d = new Document()
    expect(d.roots().length).to.equal 0
    expect(_.size(d._all_models)).to.equal 0

    root1 = new SomeModel()
    root2 = new SomeModel()
    child1 = new SomeModel()
    root1.set('child', child1)
    root2.set('child', child1)
    child1.set('child', root1)
    d.add_root(root1)
    d.add_root(root2)
    expect(d.roots().length).to.equal 2
    expect(_.size(d._all_models)).to.equal 3

    root1.set('child', null)
    expect(_.size(d._all_models)).to.equal 3

    root2.set('child', null)
    expect(_.size(d._all_models)).to.equal 2

    root1.set('child', child1)
    expect(_.size(d._all_models)).to.equal 3

  it "can notify on changes", ->
    d = new Document()
    expect(d.roots().length).to.equal 0

    m = new AnotherModel()

    d.add_root(m)
    expect(d.roots().length).to.equal 1
    expect(m.get('bar')).to.equal 1

    events = []
    curdoc_from_listener = []
    listener = (event) ->
      events.push(event)
    d.on_change(listener)

    m.set('bar', 42)
    expect(events.length).to.equal 1
    expect(events[0]).is.instanceof ModelChangedEvent
    expect(events[0].document).to.equal d
    expect(events[0].model).to.equal m
    expect(events[0].attr).to.equal 'bar'
    expect(events[0].old).to.equal 1
    expect(events[0].new_).to.equal 42

  it "can remove notification changes", ->
    d = new Document()
    expect(d.roots().length).to.equal 0

    m = new AnotherModel()

    d.add_root(m)
    expect(d.roots().length).to.equal 1
    expect(m.get('bar')).to.equal 1

    events = []
    listener = (event) ->
      events.push(event)
    d.on_change(listener)

    m.set('bar', 42)

    expect(events.length).to.equal 1
    expect(events[0].new_).to.equal 42

    d.remove_on_change(listener)
    m.set('bar', 43)

    expect(events.length).to.equal 1

  it "should notify on roots change", ->
    d = new Document()
    expect(d.roots().length).to.equal 0

    events = []
    listener = (event) ->
      events.push(event)
    d.on_change(listener)

    m = new AnotherModel({bar:1})
    d.add_root(m)
    expect(d.roots().length).to.equal 1
    expect(events.length).to.equal 1
    expect(events[0]).is.instanceof RootAddedEvent
    expect(events[0].model).to.equal m

    m2 = new AnotherModel({bar:2})
    d.add_root(m2)
    expect(d.roots().length).to.equal 2
    expect(events.length).to.equal 2
    expect(events[1]).is.instanceof RootAddedEvent
    expect(events[1].model).to.equal m2

    d.remove_root(m)
    expect(d.roots().length).to.equal 1
    expect(events.length).to.equal 3
    expect(events[2]).is.instanceof RootRemovedEvent
    expect(events[2].model).to.equal m

    d.remove_root(m2)
    expect(d.roots().length).to.equal 0
    expect(events.length).to.equal 4
    expect(events[3]).is.instanceof RootRemovedEvent
    expect(events[3].model).to.equal m2

  it "should notify on title change", ->
    d = new Document()
    expect(d.roots().length).to.equal 0
    expect(d.title()).to.equal DEFAULT_TITLE

    events = []
    listener = (event) ->
      events.push(event)
    d.on_change(listener)

    d.set_title('Foo')
    expect(d.title()).to.equal 'Foo'
    expect(events.length).to.equal 1
    expect(events[0]).is.instanceof TitleChangedEvent
    expect(events[0].document).to.equal d
    expect(events[0].title).to.equal 'Foo'

  it "can clear", ->
    d = new Document()
    expect(d.roots().length).to.equal 0
    expect(d.title()).to.equal DEFAULT_TITLE
    d.add_root(new AnotherModel())
    d.add_root(new AnotherModel())
    d.set_title('Foo')
    expect(d.roots().length).to.equal 2
    expect(d.title()).to.equal 'Foo'
    d.clear()
    expect(d.roots().length).to.equal 0
    expect(_.size(d._all_models)).to.equal 0
    # does not reset title
    expect(d.title()).to.equal 'Foo'

  it "can serialize with one model in it", ->
    d = new Document()
