 {TestStorageAdapter, AsyncTestStorageAdapter} = if typeof require isnt 'undefined' then require './model_helper' else window
 helpers = if typeof require is 'undefined' then window.viewHelpers else require '../view/view_helper'
 
-QUnit.module "Batman.Model One-To-One Associations"
+QUnit.module "belongsTo Associations"
   setup: ->
     class @App extends Batman.App
-    class @App.Store extends Batman.Model
-      @encode 'id', 'name'
-      @hasOne 'product'
-
     # Batman.currentApp exists under node and causes the adapters to explode
     Batman.currentApp = undefined
 
+    class @App.Store extends Batman.Model
+      @encode 'id', 'name'
     @storeAdapter = new AsyncTestStorageAdapter @App.Store
     @storeAdapter.storage =
       'stores1': {name: "Store One", id: 1}

  store.save (err, record) =>
    equal storeSaveSpy.callCount, 1
    equal product.get('store_id'), record.id
    storedJSON = @storeAdapter.storage["stores#{record.id}"]
    deepEqual storedJSON, store.toJSON()

    productJSON = store.get('product').toJSON()
    delete productJSON.store
    deepEqual storedJSON.product, productJSON
    QUnit.start()

asyncTest "hasOne associations can be destroyed safely", 2, ->

    deepEqual storedJSON.store, store.toJSON()
    QUnit.start()

asyncTest "belongsTo associations render", 1, ->
  @App.Product.find 1, (err, product) ->
    source = '<span data-bind="product.store.name"></span>'
    context = Batman(product: product)
    helpers.render source, context, (node) =>
      equal node[0].innerHTML, 'Store One'
      QUnit.start()

QUnit.module "hasOne Associations"
  setup: ->
    class @App extends Batman.App
    # Batman.currentApp exists under node and causes the adapters to explode
    Batman.currentApp = undefined

    class @App.Store extends Batman.Model
      @encode 'id', 'name'
      @hasOne 'product'
    @storeAdapter = new AsyncTestStorageAdapter @App.Store
    @storeAdapter.storage =
      'stores1': {name: "Store One", id: 1}
      'stores2': {name: "Store Two", id: 2, product: {id:3, name:"JSON Product"}}
    @App.Store.persist @storeAdapter

    class @App.Product extends Batman.Model
      @encode 'id', 'name'
    @productAdapter = new AsyncTestStorageAdapter @App.Product
    @productAdapter.storage = 'products1': {name: "Product One", id: 1, store_id: 1}
    @App.Product.persist @productAdapter

    @App.run()

asyncTest "should work with model classes that haven't been loaded yet", ->
  class @App.Blog extends Batman.Model
    @encode 'id', 'name'
    @hasOne 'customer'
  blogAdapter = new AsyncTestStorageAdapter @App.Blog
  blogAdapter.storage = 'blogs1': {name: "Blog One", id: 1}
  @App.Blog.persist blogAdapter

  setTimeout (=>
    class @App.Customer extends Batman.Model
      @encode 'id', 'name'
    customerAdapter = new AsyncTestStorageAdapter @App.Customer
    customerAdapter.storage =
      'customer1': {name: "Customer One", id: 1, blog_id: 1}
    @App.Customer.persist customerAdapter

    @App.Blog.find 1, (err, blog) =>
      customer = blog.get 'customer'
      ok customer instanceof @App.Customer
      equal customer.get('id'), 1
      equal customer.get('name'), 'Customer One'
      QUnit.start()
  ), ASYNC_TEST_DELAY

asyncTest "hasOne yields the related model when toJSON is called", 1, ->
  @App.Store.find 1, (err, store) =>
    deepEqual store.toJSON().product, @productAdapter.storage['products1']
    QUnit.start()

asyncTest "hasOne associations are loaded via ID", 2, ->
  @App.Store.find 1, (err, store) =>
    product = store.get 'product'
