'use strict';

const assert = require('assert');
const Stack = require('./index.js');

describe('Check type of every function', function () {
    it('stack should use expected API', function() {
        assert.strictEqual(typeof Stack, 'function', 'Stack is not a function');

        const stack = new Stack;
        assert.strictEqual(typeof stack.push, 'function', 'stack.push is not a function');
        assert.strictEqual(typeof stack.pop, 'function', 'stack.pop is not a function');
        assert.strictEqual(typeof stack.peek, 'function', 'stack.peek is not a function');
        assert.strictEqual(typeof stack.isEmpty, 'function', 'stack.isEmpty is not a function');
        assert.strictEqual(typeof stack.isEmptyAssert, 'function', 'stack.isEmptyAssert is not a function');
    });
});
    
describe('push() testsuite', function () {
    it('push() dont throw errors', function () {
        const stack = new Stack;

        assert.doesNotThrow(function () {
            stack.push(1);
        }, 'stack.push() throws instead of adding item on top of stack');
    });


    it('should add items on top of stack with push()', function () {
        const stack = new Stack;
        stack.push(1);

        assert.deepStrictEqual(stack.stack.length, 1, 'stack.length <> 1');
    });

});
    
describe('peek() testsuite', function () {
    it('should return the first element in stack with peek()', function() {
        const stack = new Stack;
        stack.push(1);
        stack.peek();

        assert.deepStrictEqual(stack.peek(), 1);
    });
});

describe('pop() testsuite', function () {
    it('pop() dont throw errors', function() {
        const stack = new Stack;

        assert.doesNotThrow(function () {
            stack.push(1);
            stack.pop();
        }, 'stack.stack.pop() throws instead of adding item on top of stack');
    });

    it('should remove the first element from stack with pop()', function() {
        const stack = new Stack;
        stack.push(1);
        stack.pop();

        assert.deepStrictEqual(stack.stack.length, 0, 'stack.stack.length <> 0');
    });     

    it('should act like FIFO data structure', function () {
        const stack = new Stack;
        stack.push(1);
        stack.push(2);
        stack.push(3);
        assert.strictEqual(stack.pop(), 3);
    });
});

describe('isEmpty() testsuite', function() {
    it('should check if stack is not empty with isEmpty()', function() {
        const stack = new Stack;
        stack.push(1);

        assert.deepStrictEqual(stack.isEmpty(), true);
    });

    it('should check if stack is empty with isEmpty()', function() {
        const stack = new Stack;

        assert.deepStrictEqual(stack.isEmpty(), false);
    });
});

describe('isEmptyAssert() testsuite', function() {
    it('should throw error if stack is empty with isEmptyAssert()', function() {
        const stack = new Stack;

        assert.throws(function() {
            stack.isEmptyAssert();
        }, /The stack is empty/, 'isEmptyAssert throw when stack is not empty');
    });

    it('dont throw error if stack is empty with isEmptyAssert()', function() {
        const stack = new Stack;
 
        assert.doesNotThrow(function() {
            stack.push(123);
        }, 'isEmptyAssert() dont throw when stack is empty');
    });
});

describe('Tests with several elements in stack', function() {
    it('first element should be correct', function() {
        const stack = new Stack;
        stack.push(1);
        stack.push(2);
        stack.push(3);

        assert.deepStrictEqual(stack.stack[0], 1, 'first element in stack is wrong');
    });

     it('second element should be correct', function() {
        const stack = new Stack;
        stack.push(1);
        stack.push(2);
        stack.push(3);

        assert.deepStrictEqual(stack.stack[1], 2, 'second element in stack is wrong');
    });

     it('third element should be correct', function() {
        const stack = new Stack;
        stack.push(1);
        stack.push(2);
        stack.push(3);

        assert.deepStrictEqual(stack.stack[2], 3, 'third element in stack is wrong');
    });

    it('stack length should be correct', function() {
        const stack = new Stack;
        stack.push(1);
        stack.push(2);
        stack.push(3);

        assert.deepStrictEqual(stack.stack.length, 3, 'stack length is wrong');
});
});
@@ -143,22 +143,16 @@
     it('
-stack 
 should u
@@ -846,18 +846,17 @@
 it('
-push() don
+shoudl no
 t th
@@ -1603,17 +1603,17 @@
 it('
-pop() don
+should no
 t th
@@ -2547,19 +2547,20 @@
 mpty(), 
-tru
+fals
 e);%0A    
@@ -2707,36 +2707,35 @@
 tack.isEmpty(), 
-fals
+tru
 e);%0A    %7D);%0A%7D);%0A
@@ -3069,19 +3069,25 @@
     it('
-don
+should no
 t throw 
@@ -3396,16 +3396,27 @@
     it('
+should add 
 first el
@@ -3421,33 +3421,25 @@
 element 
-should be 
 correct
+ly
 ', funct
@@ -3596,17 +3596,17 @@
 ack%5B0%5D, 
-1
+3
 , 'first
@@ -3653,16 +3653,27 @@
     it('
+should add 
 second e
@@ -3679,33 +3679,25 @@
 element 
-should be 
 correct
+ly
 ', funct
@@ -3912,16 +3912,27 @@
     it('
+should add 
 third el
@@ -3937,33 +3937,25 @@
 element 
-should be 
 correct
+ly
 ', funct
@@ -4112,17 +4112,17 @@
 ack%5B2%5D, 
-3
+1
 , 'third
@@ -4274,107 +4274,37 @@
 1);%0A
-        stack.push(2);%0A        stack.push(3);%0A%0A        assert.deepStrictEqual(stack.stack.length, 3
+%0A        assert(stack.isEmpty
 , 's

fix crashing tests