var store;

function generate(name, config) {

  store = config.store;

  if (config.list) {
    testList.call(this, name);
  }
  if (config.create) {
    testCreate.call(this, name, config.create.data);
  }
  if (config.read) {
    testGet.call(this, name, config.read.source);
  }
  if (config.update) {
    testUpdate.call(this, name, config.update.source, config.update.data);
  }
  if (config.delete) {
    testDelete.call(this, name, config.delete.source);
  }
}

function getList(name) {
  return store.find(name);
}
function getRandomFromList(name) {
  return getList(name)
    .then(function(list) {
      var length = list.get('length'),
          rand = Math.floor(Math.random() * length),
          item = list.objectAt(rand);

      return item.reload();
    });
}

function createItem(name, data) {
  if (typeof data === 'function') {
    return createItem.bind(this)().save(); // TODO - detect if promise
  }

  var newObject = store.createRecord(name),
      key, val;

  for (key in data) {
    if (data.hasOwnProperty(key)) {
      val = data[key];

      if (typeof val === 'function') {
        val = val.call(this, newObject.get(key));
      }

      if (typeof val !== 'undefined') {
        newObject.set(key, val);
      }
    }
  }

  return newObject.save();
}

function fetchItem(name, source) {
  var fetchFn;

  if (source === 'listRandom') {
    fetchFn = getRandomFromList.bind(this, name);
  } else if (source === 'listFilter') {
    // TODO - handle listFilter
  } else if (source === 'create') {
    // TODO - handle create
  } else if (typeof source === 'number' || typeof source === 'string') {
    fetchFn = store.find.bind(store, name, source);
  } else if (typeof source === 'function') {
    fetchFn = source.bind(this);
  } else {
    Ember.assert("Improper source specified");
    return;
  }

  return fetchFn(); // TODO - promise wrap
}

function updateItem(item, data) {
  debugger;
}

function testUpdate(name, source, data) {
  async();
  return fetchItem(name, source)
    .then(function(item) {
      return updateItem(item, data);
    })
    .then(handleSuccess, handleFailure)
    .finally(asyncDone);
}

function testDelete(name, source) {
  async();
  return fetchItem(name, source)
    .then(function(item) {
      return item.destroyRecord();
    })
    .then(handleSuccess, handleFailure)
    .finally(asyncDone);
}

function testCreate(name, data) {
  async();
  return createItem(name, data)
    .then(handleSuccess, handleFailure)
    .finally(asyncDone);
}

function testList(name) {
  async();
  return getList.call(this, name)
    .then(handleSuccess, handleFailure)
    .finally(asyncDone);
}

function testGet(name, source) {
  async();
  return fetchItem(name, source)
    .then(handleSuccess, handleFailure)
    .finally(asyncDone);
}

function handleSuccess(arg) {
  ok(true, "Promise resolved successfully");
  return arg;
}
function handleFailure(arg) {
  ok(false, "Promise was rejected");
  return arg;
}
function async() {
  QUnit.stop();
}
function asyncDone(arg) {
  QUnit.start();
  return arg;
}


export { generate };

@@ -2083,32 +2083,39 @@
    %7D)%0A    .then(
+%0A      
 handleSuccess, h
@@ -2107,39 +2107,101 @@
 andleSuccess
-, handleFailure
+(name + %22 is updatable%22),%0A      handleFailure(name + %22 failed to be updated%22)
 )%0A    .final
@@ -2369,32 +2369,39 @@
    %7D)%0A    .then(
+%0A      
 handleSuccess, h
@@ -2393,39 +2393,101 @@
 andleSuccess
-, handleFailure
+(name + %22 is deletable%22),%0A      handleFailure(name + %22 failed to be deleted%22)
 )%0A    .final
@@ -2583,32 +2583,39 @@
 data)%0A    .then(
+%0A      
 handleSuccess, h
@@ -2607,39 +2607,101 @@
 andleSuccess
-, handleFailure
+(name + %22 is creatable%22),%0A      handleFailure(name + %22 failed to be created%22)
 )%0A    .final
@@ -2791,32 +2791,39 @@
 name)%0A    .then(
+%0A      
 handleSuccess, h
@@ -2815,39 +2815,99 @@
 andleSuccess
-, handleFailure
+(name + %22 is listable%22),%0A      handleFailure(name + %22 failed to be listed%22)
 )%0A    .final
@@ -3011,16 +3011,23 @@
   .then(
+%0A      
 handleSu
@@ -3035,23 +3035,84 @@
 cess
-, handleFailure
+(name + %22 is readable%22),%0A      handleFailure(name + %22 failed to be fetched%22)
 )%0A  
@@ -3160,16 +3160,45 @@
 Success(
+message) %7B%0A  return function(
 arg) %7B%0A 
@@ -3202,16 +3202,18 @@
 %7B%0A  
+ 
+ 
 ok(true,
  %22Pr
@@ -3208,16 +3208,27 @@
 ok(true,
+ message %7C%7C
  %22Promis
@@ -3250,24 +3250,26 @@
 essfully%22);%0A
+  
   return arg
@@ -3262,32 +3262,36 @@
     return arg;%0A
+  %7D%0A
 %7D%0Afunction handl
@@ -3299,23 +3299,54 @@
 Failure(
+message) %7B%0A  return function(
 arg) %7B%0A
+  
   ok(fal
@@ -3348,16 +3348,27 @@
 k(false,
+ message %7C%7C
  %22Promis
@@ -3385,16 +3385,18 @@
 cted%22);%0A
+  
   return
@@ -3401,16 +3401,20 @@
 rn arg;%0A
+  %7D%0A
 %7D%0Afuncti

Add custom messages to various assertions