diff --git a/module-1/classification.js b/module-1/classification.js index 9f85b22..0a78d9d 100644 --- a/module-1/classification.js +++ b/module-1/classification.js @@ -22,7 +22,23 @@ function grade(score) { */ // PLACE YOUR CODE BETWEEN THIS... - // ...AND THIS COMMENT LINE! + if (score < 0 || score > 100) { + gradeOfStudent = 0; + } + else { + gradeOfStudent = Math.ceil(Math.max(((score - 59) / 41) * 4, 0)) + 1; + } + + // ...AND THIS COMMENT LINE! + return gradeOfStudent; } -module.exports = grade; \ No newline at end of file + + + + + + + + +module.exports = grade; diff --git a/module-1/euclidean.js b/module-1/euclidean.js index 3d33d00..25b782a 100644 --- a/module-1/euclidean.js +++ b/module-1/euclidean.js @@ -16,9 +16,21 @@ function euclidean(a, b) { * Also take into consideration the documentation of the function! */ // PLACE YOUR CODE BETWEEN THIS... - + if (a > 0 && b > 0) { + while (a !== b) { + if (a > b) { + a = a - b; + } else { + b = b - a; + } + } + gcd = a; + } else { + gcd = 0; + } // ...AND THIS COMMENT LINE! return gcd; } -module.exports = euclidean; \ No newline at end of file +module.exports = euclidean; + diff --git a/module-1/fibonacci.js b/module-1/fibonacci.js index 14ec907..0aa904f 100644 --- a/module-1/fibonacci.js +++ b/module-1/fibonacci.js @@ -15,8 +15,25 @@ function fibonacci(n) { * Also take into consideration the documentation of the function! */ // PLACE YOUR CODE BETWEEN THIS... - + if (n >= 0) { + if (n < 2) { + nThFibonacci = n; + } else { + let f0 = 0; + let f1 = 1; + for (let i = 2; i <= n; ++i) { + const sum = f0 + f1; + f0 = f1; + f1 = sum; + } + nThFibonacci = f1; + } + } else { + nThFibonacci = 0; + } // ...AND THIS COMMENT LINE! return nThFibonacci; } -module.exports = fibonacci; \ No newline at end of file + +module.exports = fibonacci; + diff --git a/module-2/test/calc.spec.js b/module-2/test/calc.spec.js index c6fc7c7..6907f6f 100644 --- a/module-2/test/calc.spec.js +++ b/module-2/test/calc.spec.js @@ -1,3 +1,4 @@ +const { Then } = require('cucumber'); const calc = require('../calc'); const expect = require('chai').expect; @@ -17,5 +18,144 @@ describe.only('calc', () => { * .times(6).v // 24 */ // TODO: write test cases to test calculator + it("should have proper value", () => { + //Given + const c = calc(3); + //When + //Then + expect(c.v).to.equal(3); + }); -}); \ No newline at end of file + describe("add", () => { + it("should exist", () => { + //Given + const c = calc(3); + //When + //Then + expect(c.add).not.to.undefined; + }); + it("should be able to add a number to the current value", () => { + //Given + const c = calc(3); + //When + const result = calc(3).add(5); + //Then + expect(result.v).to.equal(8); + }); + }); + + describe("minus", () => { + it("should exist", () => { + //Given + const c = calc(3); + //When + //Then + expect(c.minus).not.to.undefined; + }); + it("should be able to subtract a number from the current value", () => { + //Given + const c = calc(3); + //When + const result = calc(3).minus(2); + //Then + expect(result.v).to.equal(1); + }); + }); + + describe("divide", () => { + it("should exist", () => { + //Given + const c = calc(42); + //When + //THen + expect(c.divide).not.to.undefined; + }); + it("should be able to perform a valid division", () => { + //Given + const c = calc(10); + //When + const result = c.divide(2).v; + //Then + expect(result).to.be.equal(5); + }); + it("should handle division by 0", () => { + //Given + const c = calc(5); + //When + //Then + expect(() => c.divide(0)).to.throw("Division by 0 is not possible!"); + }); + }); + + describe("sqrt", () => { + it("should exist", () => { + //Given + const c = calc(4); + //When + //THen + expect(c.sqrt).not.to.undefined; + }); + it("should be able to square a number", () => { + //Given + const c = calc(4); + //When + const result = calc(4).sqrt().v; + //Then + expect(result).to.equal(2); + }); + it ("should handle negative numbers", () => { + //Given + const c = calc(-3); + //When + //Then + expect(() => c.sqrt()).to.throw("Square root of negative value cannot be determined!"); + }); + }); + + describe("times", () => { + it("should exist", () => { + //Given + const c = calc(4); + //When + //THen + expect(c.times).not.to.undefined; + }); + it("should be able to multiply numbers", () => { + //Given + const c = calc(3); + //When + const result = calc(3).times(10).v; + //Then + expect(result).to.equal(30); + }); + }); + + describe("modulo", () => { + it("should exist", () => { + //Given + const c = calc(10); + //When + //THen + expect(c.modulo).not.to.undefined; + }); + it("should be able to perform modulo operation", () => { + //Given + const c = calc(10); + //When + const result = c.modulo(5).v; + //Then + expect(result).to.equal(0); + }); + }); + + describe("multiply operations", () => { + it("should be able to perform multiply operations", () => { + //Given + const c = calc(3); + //When + const result = c.add(4).minus(3).times(6).v; + //THen + expect(result).to.equal(24); + }); + }); +}); diff --git a/module-3/pop/Element.js b/module-3/pop/Element.js index 85e594c..3198069 100644 --- a/module-3/pop/Element.js +++ b/module-3/pop/Element.js @@ -14,4 +14,66 @@ * in it's children (recursively) the Element with * the given name or throws an Erorr if it cannot * find the element - */ \ No newline at end of file + */ + + +const ElementFinder = require("../test/mock/ElementFinder"); + + +class Element { + constructor(name, locator) { + this.locator = locator; + this.name = name; + + this.parent = null; + this.children = {}; + } + + setParent(parent) { + this.parent = parent; + } + + addChildren(child) { + if (this.children.hasOwnProperty(child.name)) { + throw new Error(child.name + " is already added"); + } + this.children[child.name] = child; + } + + get(name) { + + if (name === undefined) { + + const rootName = Object.values(this.locator)[0]; + + const rootSelector = Object.keys(this.locator)[0]; + + let rootElementFinder= new ElementFinder({ [rootSelector]: rootName }); + + return rootElementFinder; + } + + else { + + if (this.children.hasOwnProperty(name)) { + + const selectedName = Object.values(this.children[name].locator)[0]; + + const selector = Object.keys(this.children[name].locator)[0]; + + let selectedElement = new ElementFinder({ [selector]: selectedName }); + + return selectedElement; + + + + } + else { + throw new Error("The " + name + " is not a valid child element"); + } + } + } +} + +module.exports = Element; + diff --git a/module-3/pop/Elements.js b/module-3/pop/Elements.js index f1ed38d..eb1ba53 100644 --- a/module-3/pop/Elements.js +++ b/module-3/pop/Elements.js @@ -12,4 +12,40 @@ * in the collection by the locator (.all()) in it's context * 6. It has a method to retrieve one element from the collection * by the locator (.get(n)) in it's context - */ \ No newline at end of file + */ +const Element = require("./Element"); +const ElementArrayFinder = require('../test/mock/ElementArrayFinder'); + +class Elements extends Element { + + constructor(name, locator) { + + super(name, locator); + this.children = null; + this.parent = null; + } + + addChildren() { + + throw new Error("Elements cannot have children"); + + } + all() { + + let elementarrayfinder = new ElementArrayFinder; + return elementarrayfinder.all(this.locator); + + } + + get(n) { + + let elementarrayfinder = new ElementArrayFinder; + return elementarrayfinder.get(n); + + } + + +} + + +module.exports = Elements; diff --git a/module-3/pop/HomePage.js b/module-3/pop/HomePage.js index 694d6a6..0aeadeb 100644 --- a/module-3/pop/HomePage.js +++ b/module-3/pop/HomePage.js @@ -2,4 +2,93 @@ * Create HomePage class representing the EPAM.com home page. * Add main widgets and element of the page and write tests * for it (test/pop/HomePage.spec.js). - */ \ No newline at end of file + */ + +const Layout = require("./Layout"); +const ElementFinder = require("../test/mock/ElementFinder"); + +class HomePage extends Layout { + + constructor(name, url, locator) { + super(name, url, locator); + + } + + getHeader() { + + const header = "Header"; + + if (this.children.hasOwnProperty(header)) { + + const selectedName = Object.values(this.children[header].locator)[0]; + + const selector = Object.keys(this.children[header].locator)[0]; + + let selectedElement = new ElementFinder; + + selectedElement._locator = { [selector]: selectedName }; + + return selectedElement; + + + } else { + + throw new Error("Header is not set"); + } + + + } + + getFooter() { + + const footer = "Footer"; + + if (this.children.hasOwnProperty(footer)) { + + const selectedName = Object.values(this.children[footer].locator)[0]; + + const selector = Object.keys(this.children[footer].locator)[0]; + + let selectedElement = new ElementFinder; + + selectedElement._locator = { [selector]: selectedName }; + + return selectedElement; + } + else { + + throw new Error("Footer is not set"); + + + } + } + + + getMain() { + + const main = "Main"; + + if (this.children.hasOwnProperty(main)) { + + const selectedName = Object.values(this.children[main].locator)[0]; + + const selector = Object.keys(this.children[main].locator)[0]; + + let selectedElement = new ElementFinder; + + selectedElement._locator = { [selector]: selectedName }; + + return selectedElement; + } + else { + + throw new Error("Main is not set"); + + + } + } + + } + + +module.exports = HomePage; diff --git a/module-3/pop/Layout.js b/module-3/pop/Layout.js index 324bae9..b7a0bc6 100644 --- a/module-3/pop/Layout.js +++ b/module-3/pop/Layout.js @@ -13,4 +13,33 @@ * by name in any depth * 7. It has a method to load the page, i.e. Navigates to * the URL of it (.load()) - */ \ No newline at end of file + */ + +const Element = require("./Element"); +const Browser = require('../test/mock/Browser'); + +class Layout extends Element { + + constructor(name, url, locator) { + super(name, locator); + this.url = url; + + } + setParent(parent) { + + throw new Error("Parent can not be set"); + } + + load() { + + let browser = new Browser; + return browser.get(this.url); + + } + + +} + +module.exports = Layout; + + diff --git a/module-3/test/pop/HomePage.spec.js b/module-3/test/pop/HomePage.spec.js index 307b783..235b8a6 100644 --- a/module-3/test/pop/HomePage.spec.js +++ b/module-3/test/pop/HomePage.spec.js @@ -1,3 +1,185 @@ +const ElementFinder = require('../mock/ElementFinder'); +const HomePage = require('../../pop/HomePage'); +const Element = require('../../pop/Element'); +const expect = require('chai').expect; + + + describe('HomePage Class', () => { - // TODO: write tests + + it('should be defined', () => { + expect(HomePage).to.be.instanceOf(Function); + }); + + it('should have stored locator', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.locator).not.to.be.undefined; + expect(page.locator.css).to.equal('body'); + }); + + it('should have stored name', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.name).not.to.be.undefined; + expect(page.name).to.equal('Home'); + }); + + it('should have stored URL', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.url).not.to.be.undefined; + expect(page.url).to.equal('http://epam.com'); + }); + + describe('Load', () => { + it('should have method to load the page by URL', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.load).not.to.be.undefined; + expect(page.load()).to.equal('http://epam.com'); + }); + }); + + describe('Parent', () => { + it('should not have parent by default', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.parent).not.to.be.undefined; + expect(page.parent).to.be.null; + }); + + it('should throw error if parent is set', () => { + const element = new HomePage('Title', {css: 'h1'}); + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.setParent).not.to.be.undefined; + expect(() => page.setParent(element)).to.throw(); + }); + }); + + describe('Children', () => { + it('should not have children by default', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + + expect(page.children).not.to.be.undefined; + expect(page.children).to.eql({}); + }); + + it('should have method to add children', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const child = new Element('Title', {css: 'h1'}); + + expect(page.addChildren).not.to.be.undefined; + + page.addChildren(child); + + expect(page.children.Title).to.eql(child); + }); + + it('should not add children twice', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const child = new Element('Title', {css: 'h1'}); + + page.addChildren(child); + expect(() => page.addChildren(child)).to.throw(); + }); + }); + + describe('Header', () => { + + it('GetHeader method should return error if Header root element does not exist', () => { + + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childMain = new Element('Main', {css: '#main'}); + + expect(page.getHeader).not.to.be.undefined; + expect(() => page.getHeader(childMain)).to.throw(); + }); + + + it('GetHeader method should return Header element if it was added to HomePage', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childHeader = new Element('Header', {css: '.header__content'}); + const childMain = new Element('Main', {css: '#main'}); + const childFooter = new Element('Footer', {css: '.footer_section'}); + + page.addChildren(childFooter); + page.addChildren(childMain); + page.addChildren(childHeader); + + + const pElement = page.getHeader(); + + expect(pElement).to.be.instanceOf(ElementFinder); + expect(pElement.locator().css).to.equal('.header__content'); + }); + }); + + describe('Main', () => { + + it('GetMain method should return error if Main root element does not exist', () => { + + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childHeader = new Element('Header', {css: '.header__content'}); + + + expect(page.getHeader).not.to.be.undefined; + expect(() => page.getHeader(childHeader)).to.throw(); + }); + + + it('GetMain method should return Main element if it was added to HomePage', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childHeader = new Element('Header', {css: '.header__content'}); + const childMain = new Element('Main', {css: '#main'}); + const childFooter = new Element('Footer', {css: '.footer_section'}); + + page.addChildren(childFooter); + page.addChildren(childMain); + page.addChildren(childHeader); + + + const pElement = page.getMain(); + + expect(pElement).to.be.instanceOf(ElementFinder); + expect(pElement.locator().css).to.equal('#main'); + }); + }); + + describe('Footer', () => { + + it('GetFooter method should return error if Main root element does not exist', () => { + + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childHeader = new Element('Header', {css: '.header__content'}); + + + expect(page.getHeader).not.to.be.undefined; + expect(() => page.getHeader(childHeader)).to.throw(); + }); + + + it('GetFooter method should return Footer element if it was added to HomePage', () => { + const page = new HomePage('Home', 'http://epam.com', {css: 'body'}); + const childHeader = new Element('Header', {css: '.header__content'}); + const childMain = new Element('Main', {css: '#main'}); + const childFooter = new Element('Footer', {css: '.footer_section'}); + + page.addChildren(childFooter); + page.addChildren(childMain); + page.addChildren(childHeader); + + + const pElement = page.getFooter(); + + expect(pElement).to.be.instanceOf(ElementFinder); + expect(pElement.locator().css).to.equal('.footer_section'); + }); + }); + + + + + }); \ No newline at end of file diff --git a/module-3/test/pop/Layout.spec.js b/module-3/test/pop/Layout.spec.js index f996c06..554059f 100644 --- a/module-3/test/pop/Layout.spec.js +++ b/module-3/test/pop/Layout.spec.js @@ -1,5 +1,6 @@ const ElementFinder = require('../mock/ElementFinder'); const Browser = require('../mock/Browser'); +const Element = require('../../pop/Element'); const Layout = require('../../pop/Layout'); const expect = require('chai').expect;