text: define('ember-test-helpers/test-module', ['exports', 'ember', 'ember-test-helpers/test-context', 'ember-test-helpers/abstract-test-module', 'ember-test-helpers/test-resolver', 'ember-test-helpers/build-registry', 'ember-test-helpers/has-ember-version'], function (exports, _ember, _emberTestHelpersTestContext, _emberTestHelpersAbstractTestModule, _emberTestHelpersTestResolver, _emberTestHelpersBuildRegistry, _emberTestHelpersHasEmberVersion) {
    'use strict';
  
    exports['default'] = _emberTestHelpersAbstractTestModule['default'].extend({
      init: function init(subjectName, description, callbacks) {
        // Allow `description` to be omitted, in which case it should
        // default to `subjectName`
        if (!callbacks && typeof description === 'object') {
          callbacks = description;
          description = subjectName;
        }
  
        this.subjectName = subjectName;
        this.description = description || subjectName;
        this.name = description || subjectName;
        this.callbacks = callbacks || {};
  
        if (this.callbacks.integration && this.callbacks.needs) {
          throw new Error("cannot declare 'integration: true' and 'needs' in the same module");
        }
  
        if (this.callbacks.integration) {
          if (this.isComponentTestModule) {
            this.isLegacy = callbacks.integration === 'legacy';
            this.isIntegration = callbacks.integration !== 'legacy';
          } else {
            if (callbacks.integration === 'legacy') {
              throw new Error('`integration: \'legacy\'` is only valid for component tests.');
            }
            this.isIntegration = true;
          }
  
          delete callbacks.integration;
        }
  
        this.initSubject();
        this.initNeeds();
        this.initSetupSteps();
        this.initTeardownSteps();
      },
  
      initSubject: function initSubject() {
        this.callbacks.subject = this.callbacks.subject || this.defaultSubject;
      },
  
      initNeeds: function initNeeds() {
        this.needs = [this.subjectName];
        if (this.callbacks.needs) {
          this.needs = this.needs.concat(this.callbacks.needs);
          delete this.callbacks.needs;
        }
      },
  
      initSetupSteps: function initSetupSteps() {
        this.setupSteps = [];
        this.contextualizedSetupSteps = [];
  
        if (this.callbacks.beforeSetup) {
          this.setupSteps.push(this.callbacks.beforeSetup);
          delete this.callbacks.beforeSetup;
        }
  
        this.setupSteps.push(this.setupContainer);
        this.setupSteps.push(this.setupContext);
        this.setupSteps.push(this.setupTestElements);
        this.setupSteps.push(this.setupAJAXListeners);
  
        if (this.callbacks.setup) {
          this.contextualizedSetupSteps.push(this.callbacks.setup);
          delete this.callbacks.setup;
        }
      },
  
      initTeardownSteps: function initTeardownSteps() {
        this.teardownSteps = [];
        this.contextualizedTeardownSteps = [];
  
        if (this.callbacks.teardown) {
          this.contextualizedTeardownSteps.push(this.callbacks.teardown);
          delete this.callbacks.teardown;
        }
  
        this.teardownSteps.push(this.teardownSubject);
        this.teardownSteps.push(this.teardownContainer);
        this.teardownSteps.push(this.teardownContext);
        this.teardownSteps.push(this.teardownTestElements);
        this.teardownSteps.push(this.teardownAJAXListeners);
  
        if (this.callbacks.afterTeardown) {
          this.teardownSteps.push(this.callbacks.afterTeardown);
          delete this.callbacks.afterTeardown;
        }
      },
  
      setupContainer: function setupContainer() {
        if (this.isIntegration || this.isLegacy) {
          this._setupIntegratedContainer();
        } else {
          this._setupIsolatedContainer();
        }
      },
  
      setupContext: function setupContext() {
        var subjectName = this.subjectName;
        var container = this.container;
  
        var factory = function factory() {
          return container.lookupFactory(subjectName);
        };
  
        this._super({
          container: this.container,
          registry: this.registry,
          factory: factory,
          register: function register() {
            var target = this.registry || this.container;
            return target.register.apply(target, arguments);
          }
        });
  
        var context = this.context = (0, _emberTestHelpersTestContext.getContext)();
  
        if (_ember['default'].setOwner) {
          _ember['default'].setOwner(context, this.container.owner);
        }
  
        if (_ember['default'].inject) {
          var keys = (Object.keys || _ember['default'].keys)(_ember['default'].inject);
          keys.forEach(function (typeName) {
            context.inject[typeName] = function (name, opts) {
              var alias = opts && opts.as || name;
              _ember['default'].set(context, alias, context.container.lookup(typeName + ':' + name));
            };
          });
        }
      },
  
      teardownSubject: function teardownSubject() {
        var subject = this.cache.subject;
  
        if (subject) {
          _ember['default'].run(function () {
            _ember['default'].tryInvoke(subject, 'destroy');
          });
        }
      },
  
      teardownContainer: function teardownContainer() {
        var container = this.container;
        _ember['default'].run(function () {
          container.destroy();
        });
      },
  
      defaultSubject: function defaultSubject(options, factory) {
        return factory.create(options);
      },
  
      // allow arbitrary named factories, like rspec let
      contextualizeCallbacks: function contextualizeCallbacks() {
        var callbacks = this.callbacks;
        var context = this.context;
  
        this.cache = this.cache || {};
        this.cachedCalls = this.cachedCalls || {};
  
        var keys = (Object.keys || _ember['default'].keys)(callbacks);
        var keysLength = keys.length;
  
        if (keysLength) {
          var deprecatedContext = this._buildDeprecatedContext(this, context);
          for (var i = 0; i < keysLength; i++) {
            this._contextualizeCallback(context, keys[i], deprecatedContext);
          }
        }
      },
  
      _contextualizeCallback: function _contextualizeCallback(context, key, callbackContext) {
        var _this = this;
        var callbacks = this.callbacks;
        var factory = context.factory;
  
        context[key] = function (options) {
          if (_this.cachedCalls[key]) {
            return _this.cache[key];
          }
  
          var result = callbacks[key].call(callbackContext, options, factory());
  
          _this.cache[key] = result;
          _this.cachedCalls[key] = true;
  
          return result;
        };
      },
  
      /*
        Builds a version of the passed in context that contains deprecation warnings
        for accessing properties that exist on the module.
      */
      _buildDeprecatedContext: function _buildDeprecatedContext(module, context) {
        var deprecatedContext = Object.create(context);
  
        var keysForDeprecation = Object.keys(module);
  
        for (var i = 0, l = keysForDeprecation.length; i < l; i++) {
          this._proxyDeprecation(module, deprecatedContext, keysForDeprecation[i]);
        }
  
        return deprecatedContext;
      },
  
      /*
        Defines a key on an object to act as a proxy for deprecating the original.
      */
      _proxyDeprecation: function _proxyDeprecation(obj, proxy, key) {
        if (typeof proxy[key] === 'undefined') {
          Object.defineProperty(proxy, key, {
            get: function get() {
              _ember['default'].deprecate('Accessing the test module property "' + key + '" from a callback is deprecated.', false, { id: 'ember-test-helpers.test-module.callback-context', until: '0.6.0' });
              return obj[key];
            }
          });
        }
      },
  
      _setupContainer: function _setupContainer(isolated) {
        var resolver = (0, _emberTestHelpersTestResolver.getResolver)();
  
        var items = (0, _emberTestHelpersBuildRegistry['default'])(!isolated ? resolver : Object.create(resolver, {
          resolve: {
            value: function value() {}
          }
        }));
  
        this.container = items.container;
        this.registry = items.registry;
  
        if ((0, _emberTestHelpersHasEmberVersion['default'])(1, 13)) {
          var thingToRegisterWith = this.registry || this.container;
          var router = resolver.resolve('router:main');
          router = router || _ember['default'].Router.extend();
          thingToRegisterWith.register('router:main', router);
        }
      },
  
      _setupIsolatedContainer: function _setupIsolatedContainer() {
        var resolver = (0, _emberTestHelpersTestResolver.getResolver)();
        this._setupContainer(true);
  
        var thingToRegisterWith = this.registry || this.container;
  
        for (var i = this.needs.length; i > 0; i--) {
          var fullName = this.needs[i - 1];
          var normalizedFullName = resolver.normalize(fullName);
          thingToRegisterWith.register(fullName, resolver.resolve(normalizedFullName));
        }
  
        if (!this.registry) {
          this.container.resolver = function () {};
        }
      },
  
      _setupIntegratedContainer: function _setupIntegratedContainer() {
        this._setupContainer();
      }
  
    });
  });