import assert from 'assert';
import { App } from '../src';

const fetch = (url) => Promise.resolve({ url });

describe('Usage Example', () => {

    class Foo {

        constructor (plah, data) {
            this.plah = plah;
            this.data = data;
        }

    }

    App.Component(Foo, {  // a Component is like an ordinary class, you can create multiple entities from it
                          // (an entity is a instance of a Component)

        construct: ['plah', 'data!'],  // specify the arguments for the Foo constructor
                                       // data has an exclamation mark, so the construction of Foo will be delayed
                                       // until 'data' is resolved

        inject: ['bar', 'fooBar!'],  // after object creation, add more properties to our new object

        provider: {  // our component has some extra providers which are not defined in the App
                     // providers are hierachical so they can override providers with same name from the App

            data: fetch('https://example.com/123.json')   // every Promise can be used as provider!

        }

    });


    class Plah { }
    // no annotations here!
    // without any annotations a class will be act as Service (which is a Component singelton)

    class Bar {
        constructor () {
            return new Promise(resolve => setTimeout(resolve(this), 4));
        }
        // ooops, our constructor returns a Promise!
        // this will tell our App to wait for the Service initialization until the Promise
        // is resolved (with an instance of Bar as value)
    }

    App.Component(Bar);


    class FooBar {
        constructor (parent) {
            this.foo = parent;
        }
    }

    App.Component(FooBar, { construct: ['parent'] });   // Foo asks for 'fooBar' after object creation,
                                                        // so *parent* will be an instance of Foo in this case.

    const app = new App({
        provider: {
            foo: Foo,
            plah: Plah,
            bar: Bar,
            fooBar: FooBar,
        }
    });

    it('create entity foo', () => app.createEntity('foo')
        .then(foo => {

            assert(foo instanceof Foo);

            return foo;
        })
        .then(foo => {

            assert.equal(typeof foo.plah, 'function');

            return foo.plah().then(plah => {

                assert(plah instanceof Plah);

                return foo;
            });
        })
        .then(foo => {

            assert.equal(foo.data && foo.data.url, 'https://example.com/123.json');

            return foo;
        })
        .then(foo => {

            assert.equal(typeof foo.bar, 'function');

            return foo.bar().then(bar => {

                assert(bar instanceof Bar);

                return foo;
            });
        })
        .then(foo => {

            assert(foo.fooBar instanceof FooBar);
            assert.equal(foo.fooBar.foo, foo);

        })
    );

    it('create entity fooBar', () => app.createEntity('fooBar')
        .then(fooBar => {
            assert.equal(fooBar.foo, null);
        })
    );

});

@@ -2123,24 +2123,275 @@
  %7D%0A    %7D);%0A%0A
+%0A    const check = cb =%3E %7B%0A        return value =%3E %7B%0A            let res = cb(value);%0A            if (res && res.then) %7B%0A                return res.then(() =%3E value);%0A            %7D else %7B%0A                return value;%0A            %7D%0A        %7D;%0A    %7D;%0A%0A
     it('crea
@@ -2442,32 +2442,38 @@
 )%0A        .then(
+check(
 foo =%3E %7B%0A%0A      
@@ -2519,33 +2519,10 @@
     
-    return foo;%0A        
 %7D
+)
 )%0A  
@@ -2525,32 +2525,38 @@
 )%0A        .then(
+check(
 foo =%3E %7B%0A%0A      
@@ -2702,36 +2702,8 @@
 );%0A%0A
-                return foo;%0A
     
@@ -2716,32 +2716,33 @@
   %7D);%0A        %7D)
+)
 %0A        .then(f
@@ -2732,32 +2732,38 @@
 )%0A        .then(
+check(
 foo =%3E %7B%0A%0A      
@@ -2853,33 +2853,10 @@
     
-    return foo;%0A        
 %7D
+)
 )%0A  
@@ -2859,32 +2859,38 @@
 )%0A        .then(
+check(
 foo =%3E %7B%0A%0A      
@@ -3031,36 +3031,8 @@
 );%0A%0A
-                return foo;%0A
     
@@ -3049,24 +3049,25 @@
 ;%0A        %7D)
+)
 %0A        .th
@@ -3069,16 +3069,22 @@
   .then(
+check(
 foo =%3E %7B
@@ -3185,32 +3185,33 @@
 oo);%0A%0A        %7D)
+)
 %0A    );%0A%0A    it(

refactor test code