diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24d524c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node/node_modules/ +php/vendor/ \ No newline at end of file diff --git a/node/arrayClass.js b/node/arrayClass.js new file mode 100644 index 0000000..4de786e --- /dev/null +++ b/node/arrayClass.js @@ -0,0 +1,173 @@ +"use strict" + +class Array { + + constructor( elements ) { + + this.setElements( elements ) + } + + setElements( elements ) + { + if( elements != null ) { + this.elements = elements + }else { + this.elements = [] + } + } + + last( ) { + + if( this.elements.length > 0 ) { + return this.elements[ this.elements.length - 1 ] + } else { + return undefined; + } + } +} + +let ar1 = new Array( ) +let ar2 = new Array( [1, 2, 3, 4, 5] ) + +console.log( ar1.last( ) ) //undefined +console.log( ar2.last( ) ) //5 + +function getTransactions() { + return new Promise((resolve, reject) => { + fetch(BASE_URL + '/api/transacoes') + .then(result => { + result.json().then(transactions_result => { + const transactions = [] + + for (let i in transactions_result) { + if (transactions_result[i].realizada) { + transactions.push({ + id: transactions_result[i].id, + value: transactions_result[i].valor, + type: transactions_result[i].valor < 0 ? 'transference' : 'deposit', + }) + } + } + + return resolve(transactions) + }) + }) + .catch(e => { + return reject(e) + }) + }) +} + + + +class ResponseTransaction { + + constructor( elements ) { + + this.json( ) + } + + json( ) { + + this.elements = + + [ + { id: 1, valor: -1, realizada: true }, + { id: 1, valor: 50, realizada: true }, + { id: 1, valor: 181, realizada: false } + ] + + return this.elements + + } + +} + + +const BASE_URL = 'http://teste.desenvolvimento.nodejs'; + +function fetch( url ) { + + console.log( url ) + return new Promise((resolve, reject) => { + + const response_transaction = new ResponseTransaction( ); + //console.log( response_transaction.json( ) ) + return resolve(response_transaction); + + }); + +} + +function resolvePromiseFetchResult( result ) { + + + return new Promise((resolve, reject) => { + + if( !result ) { + + return reject( "Invalid result" ) + } + + return resolve( result.json() ) + }); +} + +function buildArraySuccessfully( arrayTransactionsResult ) { + + + + return new Promise((resolve, reject) => { + + if( !arrayTransactionsResult ) { + + return reject( "Invalid array transaction result" ) + + } + + let transactions = [] + + for (let i in arrayTransactionsResult) { + + if (arrayTransactionsResult[i].realizada) { + transactions.push({ + id: arrayTransactionsResult[i].id, + value: arrayTransactionsResult[i].valor, + type: arrayTransactionsResult[i].valor < 0 ? 'transference' : 'deposit', + }) + } + } + + return resolve(transactions) + + }); + +} + + + +function getTransactions2( ) { + + return new Promise((resolve, reject) => { + + const url = BASE_URL + '/api/transacoes'; + + return resolve( url ) + + }); + +} + + +getTransactions2( ) + .then( fetch ) + .then( resolvePromiseFetchResult ) + .then( buildArraySuccessfully ) + .then( + (result) => { + console.log(result); + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + }); diff --git a/node/index.js b/node/index.js index e69de29..ff8fde6 100644 --- a/node/index.js +++ b/node/index.js @@ -0,0 +1,14 @@ +const express = require( 'express' ) +const bodyParser = require( 'body-parser' ) +const morgan = require( 'morgan' ) +const app = express( ) + +app.use( bodyParser.urlencoded( { extended : false } ) ) +app.use( bodyParser.json( ) ) +app.use( morgan( 'dev' ) ) + +require( './src/index' )( app ) + +app.listen( 9000, ( ) => { + console.log( 'Express has been started' ) +} ) \ No newline at end of file diff --git a/node/package.json b/node/package.json new file mode 100644 index 0000000..531f639 --- /dev/null +++ b/node/package.json @@ -0,0 +1,17 @@ +{ + "name": "node", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.18.3", + "express": "^4.16.3", + "morgan": "^1.9.0", + "node-cache": "^4.2.0" + } +} diff --git a/node/src/business/cache-manager.js b/node/src/business/cache-manager.js new file mode 100644 index 0000000..e52b2b1 --- /dev/null +++ b/node/src/business/cache-manager.js @@ -0,0 +1,144 @@ +"use strict" + +const nodeCache = require( "node-cache" ) +const cacheManager = new nodeCache( ) + +class CacheManager { + + + constructor( dollarQuotation ) { + + this.dollarQuotation = dollarQuotation + + } + + recoverDataDollarQuotation( ) { + + + return new Promise((resolve, reject) => { + + cacheManager.get( "dollar_quotation", ( err, value ) => { + + if( !err ){ + + return resolve( value ) + + }else { + + return reject ( err ) + + } + + } ) + + }); + + } + getDataDollarQuotation( value ) { + + + return new Promise((resolve, reject) => { + + + cacheManager.get( "dollar_quotation", ( err, value ) => { + + if( !err ){ + + if(value == undefined){ + + this.dollarQuotation.requestQuotationBcb( ) + .then( this.dollarQuotation.proccessDataQuotation ) + .then( this.dollarQuotation.calculateDollarQuotation ) + .then( + (result) => { + + cacheManager.set( "dollar_quotation", result, 14400, ( err, success) => { + if( !err && success ){ + + return resolve( result ) + } + }); + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + }) + + }else{ + + return resolve( value ) + } + + }else { + + return reject ( err ) + + } + + } ) + + + + + }); + + } + + getDataOrdersCache( ) { + + return new Promise((resolve, reject) => { + + + cacheManager.get( "orders", ( err, value ) => { + + if( !err ){ + + if(value == undefined){ + + return resolve( [ ] ) + + }else{ + + return resolve( value ) + } + + }else { + + return reject ( err ) + + } + + } ) + + + + + }); + + } + + recordDataOrdersCache( dataOrders ) { + + return new Promise((resolve, reject) => { + cacheManager.set( "orders", dataOrders, 14400, ( err, success) => { + if( !err && success ){ + + return resolve( success ) + }else { + reject( "Error to record orders" ) + } + + }); + + + + + } ) + + + + + } +} + +module.exports = CacheManager \ No newline at end of file diff --git a/node/src/business/dollar-quotation.js b/node/src/business/dollar-quotation.js new file mode 100644 index 0000000..477f3bf --- /dev/null +++ b/node/src/business/dollar-quotation.js @@ -0,0 +1,97 @@ +"use strict" + +const https = require( 'https' ) + +class DollarQuotation { + + + requestQuotationBcb( ) { + + let options = { + host: 'olinda.bcb.gov.br', + path: "/olinda/servico/PTAX/versao/v1/odata/CotacaoDolarDia(dataCotacao=@dataCotacao)?@dataCotacao='07-20-2018'&$top=100&$format=json" + }; + + + return new Promise((resolve, reject) => { + let req = https.get(options, ( response_https ) => { + + if( response_https.statusCode != 200) { + + return reject( "Invalid status code response of request" ) + + } + + return resolve( response_https ); + + }) + + req.on('error', function(e) { + return reject( e ) + }); + + }); + + } + + proccessDataQuotation ( response_https ) { + + return new Promise( ( resolve, reject ) => { + + if( !response_https ) { + + return reject( "Invalid response" ) + + } + + let bodyChunks = []; + + response_https.on('data', function(chunk) { + + bodyChunks.push(chunk); + + }).on('end', function() { + + return resolve( JSON.parse( bodyChunks ) ) + + }) + + } ) + + } + + calculateDollarQuotation( dataQuotation ) { + + + return new Promise( ( resolve, reject ) => { + + if( !dataQuotation ) { + + return reject( "Invalid data quotation" ) + + } + + if( !dataQuotation.value ) { + + return reject( "Invalid data quotation" ) + + } + + let cotation = 0 + if( dataQuotation.value[ 0 ].cotacaoCompra != 0 ) { + cotation = 1 / dataQuotation.value[ 0 ].cotacaoCompra + cotation = Number(( cotation ).toFixed(2)) + } + + return resolve( cotation ) + + + + } ) + + } + + +} + +module.exports = DollarQuotation \ No newline at end of file diff --git a/node/src/business/order.js b/node/src/business/order.js new file mode 100644 index 0000000..510fe55 --- /dev/null +++ b/node/src/business/order.js @@ -0,0 +1,94 @@ +"use strict" + + +class Order { + + + constructor( cacheManager ) { + + this.cacheManager = cacheManager + + } + + getOrders( ) { + + + return new Promise((resolve, reject) => { + + let orders = this.cacheManager.getDataOrdersCache( ) + + return resolve( orders ) + + }); + + } + + findInfoOrderId( orders ) { + + return new Promise((resolve, reject) => { + + let orderIds= [ ]; + let maxOrderId = 1; + + for ( let i in orders ) { + orderIds.push( orders[ i ].id ) + } + + if( orderIds.length > 0 ) { + + maxOrderId = Math.max.apply(null, orderIds ); + maxOrderId = maxOrderId + 1 + + } + + let order_info = { orders : orders, maxOrderId : maxOrderId } + + return resolve( order_info ) + + + }); + + + } + + + insertOrder( req_params, cotation_brl ) { + + return new Promise((resolve, reject) => { + + if( !req_params.items ) { + + reject( "params items is invalid. Check the headers content type of requests" ) + } + let items = req_params.items + let total_items = items.reduce((x, y) => x + y) + let createdAt = new Date() + let total_usd = total_items * cotation_brl + + this.getOrders( ) + .then( this.findInfoOrderId ) + .then( + (result) => { + + let orders = result.orders + let info_order_record = { id : result.maxOrderId, createdAt : createdAt, totalBRL: total_items, totalUSD : total_usd } + + orders.push( info_order_record ) + + this.cacheManager.recordDataOrdersCache( orders ) + + return resolve( info_order_record ) + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + }) + + }); + + } + + +} + +module.exports = Order \ No newline at end of file diff --git a/node/src/index.js b/node/src/index.js new file mode 100644 index 0000000..4f7b367 --- /dev/null +++ b/node/src/index.js @@ -0,0 +1,6 @@ +module.exports = ( app ) => { + + app.use( '/', require( './routes/main/' ) ) + app.use( '/api', require( './routes/api/' ) ) + +} \ No newline at end of file diff --git a/node/src/routes/api/brl_usd.js b/node/src/routes/api/brl_usd.js new file mode 100644 index 0000000..894812c --- /dev/null +++ b/node/src/routes/api/brl_usd.js @@ -0,0 +1,24 @@ +const https = require( 'https' ) +const dollarQuotation = require( "./../../business/dollar-quotation" ) +const cacheManager = require( "./../../business/cache-manager" ) + +module.exports = ( req, res ) => { + + let dollar_quotation = new dollarQuotation( ) + + let cache_manager = new cacheManager( dollar_quotation ) + + cache_manager.getDataDollarQuotation( ) + .then( + (result) => { + + return res.json( { brl: 1, usd : result } ) + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + } + ) + + +} diff --git a/node/src/routes/api/index.js b/node/src/routes/api/index.js new file mode 100644 index 0000000..a65f253 --- /dev/null +++ b/node/src/routes/api/index.js @@ -0,0 +1,9 @@ +const express = require( 'express' ) +const router = express.Router( ) + + +router.get( '/brl-usd', require( './brl_usd' ) ) +router.post( '/orders', require( './order-add' ) ) +router.get( '/orders', require( './order-list' ) ) + +module.exports = router \ No newline at end of file diff --git a/node/src/routes/api/order-add.js b/node/src/routes/api/order-add.js new file mode 100644 index 0000000..41b4ce2 --- /dev/null +++ b/node/src/routes/api/order-add.js @@ -0,0 +1,41 @@ +const https = require( 'https' ) +const dollarQuotation = require( "./../../business/dollar-quotation" ) +const cacheManager = require( "./../../business/cache-manager" ) +const order = require( "./../../business/order" ) + +module.exports = ( req, res ) => { + + let dollar_quotation = new dollarQuotation( ) + + let cache_manager = new cacheManager( dollar_quotation ) + + let order_manager = new order( cache_manager ) + + cache_manager.getDataDollarQuotation( ) + .then( + ( cotation_brl ) => { + + order_manager.insertOrder( req.body, cotation_brl ) + .then( + ( result ) => { + + return res.json( result ) + + }, + + ( error ) => { + + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + + } + ) + + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + } + ) + + +} diff --git a/node/src/routes/api/order-list.js b/node/src/routes/api/order-list.js new file mode 100644 index 0000000..02e3781 --- /dev/null +++ b/node/src/routes/api/order-list.js @@ -0,0 +1,30 @@ +const https = require( 'https' ) +const dollarQuotation = require( "./../../business/dollar-quotation" ) +const cacheManager = require( "./../../business/cache-manager" ) +const order = require( "./../../business/order" ) + +module.exports = ( req, res ) => { + + let dollar_quotation = new dollarQuotation( ) + + let cache_manager = new cacheManager( dollar_quotation ) + + let order_manager = new order( cache_manager ) + + order_manager.getOrders( ) + .then( + ( result ) => { + + return res.json( result ) + + }, + + ( error ) => { + + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + + } + ) + + +} diff --git a/node/src/routes/main/index.js b/node/src/routes/main/index.js new file mode 100644 index 0000000..7990f5d --- /dev/null +++ b/node/src/routes/main/index.js @@ -0,0 +1,7 @@ +const express = require( 'express' ) +const router = express.Router( ) + + +router.get( '/', require( './main' ) ) + +module.exports = router \ No newline at end of file diff --git a/node/src/routes/main/main.js b/node/src/routes/main/main.js new file mode 100644 index 0000000..0beac84 --- /dev/null +++ b/node/src/routes/main/main.js @@ -0,0 +1,5 @@ +module.exports = ( req, res ) => { + + return res.json( { msg : "Welcome to test developer nodejs" } ) + +} \ No newline at end of file diff --git a/php/brl-usd.php b/php/brl-usd.php index e69de29..3eeca5f 100644 --- a/php/brl-usd.php +++ b/php/brl-usd.php @@ -0,0 +1,17 @@ +getInstanceDependencyOfContainer( "Desenvolvimento/Dispatcher" ); + $dispatcher->dispatch( ); + +}catch( \RuntimeException $e ) { + + echo json_encode( $e->getMessage() ); +} \ No newline at end of file diff --git a/php/cache/dollar_quotation.cache b/php/cache/dollar_quotation.cache new file mode 100644 index 0000000..78aa9c2 --- /dev/null +++ b/php/cache/dollar_quotation.cache @@ -0,0 +1 @@ +O:20:"FileSystemCacheValue":5:{s:3:"key";O:18:"FileSystemCacheKey":2:{s:3:"key";s:16:"dollar_quotation";s:5:"group";N;}s:5:"value";a:2:{s:3:"brl";i:1;s:3:"usd";d:0.26000000000000001;}s:3:"ttl";i:14400;s:7:"expires";i:1533314147;s:7:"created";i:1533299747;} \ No newline at end of file diff --git a/php/composer.json b/php/composer.json new file mode 100644 index 0000000..5e8dcd8 --- /dev/null +++ b/php/composer.json @@ -0,0 +1,26 @@ +{ + "name": "node-php-test-middle/php", + "authors": [ + { + "name": "Erico de oliveira leandro", + "email": "erico.autocad@gmail.com" + } + ], + "require": { + "pimple/pimple": "^3.2", + "jdorn/file-system-cache": "dev-master" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "autoload" : { + "psr-4" : { + "Desenvolvimento\\" : "oop/Desenvolvimento/" + } + }, + "autoload-dev" : { + "psr-4" : { + "Desenvolvimento\\" : "tests/" + } + } +} diff --git a/php/composer.lock b/php/composer.lock new file mode 100644 index 0000000..0084a52 --- /dev/null +++ b/php/composer.lock @@ -0,0 +1,1542 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "de2d01658306fd87f8734c793f99945e", + "packages": [ + { + "name": "jdorn/file-system-cache", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/jdorn/FileSystemCache.git", + "reference": "08f33ff840ec4728a0bd28e4d68d97635584952e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jdorn/FileSystemCache/zipball/08f33ff840ec4728a0bd28e4d68d97635584952e", + "reference": "08f33ff840ec4728a0bd28e4d68d97635584952e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "lib" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "http://jeremydorn.com/" + } + ], + "description": "an easy way to cache data in the file system", + "homepage": "https://github.com/jdorn/FileSystemCache/", + "keywords": [ + "cache", + "file system" + ], + "time": "2013-07-05T13:28:27+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/container": "^1.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2018-01-21T07:42:36+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-10T14:09:06+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-12-04T08:55:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-02-01T05:50:59+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "810af2d35fc72b6cf5c01116806d2b65ccaaf2e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/810af2d35fc72b6cf5c01116806d2b65ccaaf2e2", + "reference": "810af2d35fc72b6cf5c01116806d2b65ccaaf2e2", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T11:19:56+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "jdorn/file-system-cache": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/php/oop/Desenvolvimento/ClientRequest.php b/php/oop/Desenvolvimento/ClientRequest.php new file mode 100644 index 0000000..4d23374 --- /dev/null +++ b/php/oop/Desenvolvimento/ClientRequest.php @@ -0,0 +1,47 @@ +getUrlRequestCotation( $date ); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url_request); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE ); + $output = curl_exec($ch); + $output = json_decode( $output, true ); + + $status_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE); + + if( $status_code !== 200 ) { + curl_close( $ch ); + return false; + } else { + curl_close( $ch ); + return $output; + } + + return $result; + + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/DependencyManager.php b/php/oop/Desenvolvimento/DependencyManager.php new file mode 100644 index 0000000..bf3f909 --- /dev/null +++ b/php/oop/Desenvolvimento/DependencyManager.php @@ -0,0 +1,62 @@ +dependencyContainer = $dependencyContainer; + $this->setDependencies( ); + + } + + public function setDependencies( ) + { + $this->dependencyContainer["Desenvolvimento/ClientRequest"] = function ( $recipient ) { + return new \Desenvolvimento\ClientRequest( ); + }; + $this->dependencyContainer["Desenvolvimento/DollarQuotation"] = function ( $recipient ) { + return new \Desenvolvimento\DollarQuotation( $recipient["Desenvolvimento/ClientRequest"] ); + }; + $this->dependencyContainer["Desenvolvimento/DependencyManager"] = function ( $recipient ) { + return new \Desenvolvimento\DependencyManager( $recipient ); + }; + $this->dependencyContainer["Desenvolvimento/Dispatcher"] = function ( $recipient ) { + return new \Desenvolvimento\Dispatcher( $recipient["Desenvolvimento/DependencyManager"] ); + }; + $this->dependencyContainer["FileSystemCache"] = function ( $recipient ) { + return new \FileSystemCache( ); + }; + $this->dependencyContainer["Desenvolvimento/Order"] = function ( $recipient ) { + return new \Desenvolvimento\Order( $recipient["FileSystemCache"] ); + }; + + $this->dependencyContainer["Desenvolvimento/Route/Get/Php/Brlusd"] = function ( $recipient ) { + return new \Desenvolvimento\Route\Get\Php\Brlusd( $recipient["Desenvolvimento/DollarQuotation"] ); + }; + $this->dependencyContainer["Desenvolvimento/Route/Post/Php/Orders"] = function ( $recipient ) { + return new \Desenvolvimento\Route\Post\Php\Orders( $recipient["Desenvolvimento/Order"], $recipient["Desenvolvimento/DollarQuotation"] ); + }; + $this->dependencyContainer["Desenvolvimento/Route/Get/Php/Orders"] = function ( $recipient ) { + return new \Desenvolvimento\Route\Get\Php\Orders( $recipient["Desenvolvimento/Order"] ); + }; + + } + + public function getInstanceDependencyOfContainer( $nameDependencyRecipient ) + { + if( empty( $this->dependencyContainer[$nameDependencyRecipient] ) ) { + + throw new \RuntimeException( "the dependency `$nameDependencyRecipient` is invalid" ); + + } + + return $this->dependencyContainer[$nameDependencyRecipient]; + + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/Dispatcher.php b/php/oop/Desenvolvimento/Dispatcher.php new file mode 100644 index 0000000..e9621b7 --- /dev/null +++ b/php/oop/Desenvolvimento/Dispatcher.php @@ -0,0 +1,82 @@ +dependencyManager = $dependencyManager; + + } + + public function getRoutes( ) + { + + return [ + "GET" => [ + "/php/brl-usd.php", + "/php/orders.php", + ], + "POST" => [ "/php/orders.php" ] + ]; + + + } + + public function getPathResource( $path_root_request, $request_method ) + { + + $path_root_request = str_replace( "-", "", $path_root_request ); + $path_root_request = strtolower( $path_root_request ); + $request_method = strtolower( $request_method ); + $path_root_request = preg_replace_callback('~(/)([a-z])~', function ($match) { + + return $match[1] . ucfirst( $match[2] ); + }, $path_root_request ); + $controller_class_name = ucfirst( $request_method ) . ucfirst( $path_root_request ); + $controller_class_name = str_replace( ".php", "", $controller_class_name ); + $controller_class_name = "Desenvolvimento/Route/" . $controller_class_name ; + + return $controller_class_name; + + } + + public function dispatch( $path_root_request = null, $request_method = null ) + { + + if( is_null( $path_root_request ) ) { + $path_root_request = $_SERVER[ "PHP_SELF" ]; + } + if( is_null( $request_method ) ) { + $request_method = $_SERVER[ "REQUEST_METHOD" ]; + } + $routes = $this->getRoutes( ); + + if( !empty( $routes [ $request_method ] ) ) { + + if( in_array( $path_root_request, $routes [ $request_method ] ) ) { + + $controller_class_name = $this->getPathResource( $path_root_request, $request_method ); + $instance_controller = $this->dependencyManager->getInstanceDependencyOfContainer( $controller_class_name ); + $instance_controller->run( ); + + return $instance_controller; + + } else { + + throw new \RuntimeException( "the requested resource is not valid" ); + + } + + }else { + + throw new \RuntimeException( "the requested resource is not valid" ); + + } + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/DollarQuotation.php b/php/oop/Desenvolvimento/DollarQuotation.php new file mode 100644 index 0000000..c3c882c --- /dev/null +++ b/php/oop/Desenvolvimento/DollarQuotation.php @@ -0,0 +1,70 @@ +clientRequest = $clientRequest; + + } + + public function getClientRequest( ) + { + + return $this->clientRequest; + + } + + public function getDollarCotation( $date = "07-20-2018" ) + { + + $info_cotation = $this->getADollarQuotationPerDay( $date ); + + return $info_cotation[ "usd" ]; + + } + + public function getADollarQuotationPerDay( $date = "07-20-2018" ) + { + + $client = $this->clientRequest; + + $keycache = \FileSystemCache::generateCacheKey('dollar_quotation'); + $datacache = \FileSystemCache::retrieve($keycache); + + // If there was a cache miss + if($datacache === false) { + + $datacache = $client->processRequest( $date ); + + if( !empty( $datacache[ "value" ] ) ) { + + $info_first_cotation = $datacache[ "value" ] [ 0 ]; + $value_usd = round( ( 1 / $info_first_cotation[ "cotacaoCompra" ] ) , 2 ); + + $datacache = [ "brl" => 1, "usd" => $value_usd ]; + \FileSystemCache::store( $keycache, $datacache, 14400 ); + + return $datacache; + + }else { + + return [ "brl" => 0, "usd" => 0 ]; + + } + + }else { + + return $datacache; + + } + + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/Order.php b/php/oop/Desenvolvimento/Order.php new file mode 100644 index 0000000..50b5ed6 --- /dev/null +++ b/php/oop/Desenvolvimento/Order.php @@ -0,0 +1,95 @@ +fileSystemCache = $fileSystemCache; + + } + + public function getFileSystemCache( ) + { + + return $this->fileSystemCache; + + } + + public function findLastOrderId( ) + { + + $orderIds= [ ]; + $maxOrderId = 1; + + $orders = $this->getOrders( ); + + $orderIds = array_column( $orders, "id" ); + + if( !empty( $orderIds ) ) { + + $maxOrderId = max( $orderIds ); + + $maxOrderId += 1; + + } + + return $maxOrderId; + + } + + public function insertOrder( array $items, $cotation_usd ) + { + + $data_insert = [ ]; + $data_insert ["id"] = $this->findLastOrderId( ); + $data_insert ["created_at"] = ( new \DateTime( "now", new \DateTimeZone( "America/Sao_Paulo" ) ) )->format( "Y-m-d H:i:s" ); + $data_insert ["total_brl"] = array_sum( $items ); + $data_insert ["total_usd"] = $data_insert ["total_brl"] * $cotation_usd ; + + $keycache = $this->fileSystemCache->generateCacheKey('orders'); + $orders = $this->fileSystemCache->retrieve($keycache); + + if($orders === false) { + + $orders = [ ]; + + } + + array_push( $orders, $data_insert); + $this->fileSystemCache->store( $keycache, $orders, 14400 ); + + + return $data_insert; + + + } + + public function getOrders( ) + { + + $keycache = $this->fileSystemCache->generateCacheKey('orders'); + $datacache = $this->fileSystemCache->retrieve($keycache); + + if($datacache === false) { + + $datacache = [ ]; + $this->fileSystemCache->store( $keycache, $datacache, 14400 ); + + return $datacache; + + }else { + + return $datacache; + + } + + } + + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/Park/Customer.php b/php/oop/Desenvolvimento/Park/Customer.php new file mode 100644 index 0000000..12dfc8b --- /dev/null +++ b/php/oop/Desenvolvimento/Park/Customer.php @@ -0,0 +1,14 @@ +dollarQuotation = $dollarQuotation; + + } + + public function run( ) + { + echo json_encode( $this->dollarQuotation->getADollarQuotationPerDay( "07-20-2018" ) ); + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/Route/Get/Php/Orders.php b/php/oop/Desenvolvimento/Route/Get/Php/Orders.php new file mode 100644 index 0000000..0e78b74 --- /dev/null +++ b/php/oop/Desenvolvimento/Route/Get/Php/Orders.php @@ -0,0 +1,23 @@ +order = $order; + + } + + public function run( ) + { + + $orders = $this->order->getOrders( ); + echo json_encode( $orders ); + } + +} \ No newline at end of file diff --git a/php/oop/Desenvolvimento/Route/Post/Php/Orders.php b/php/oop/Desenvolvimento/Route/Post/Php/Orders.php new file mode 100644 index 0000000..e2dfb1c --- /dev/null +++ b/php/oop/Desenvolvimento/Route/Post/Php/Orders.php @@ -0,0 +1,28 @@ +dollarQuotation = $dollarQuotation; + $this->order = $order; + + } + + public function run( ) + { + $date = "07-20-2018"; + $cotation_usd = $this->dollarQuotation->getDollarCotation( $date ); + $items = $_POST[ "items" ]; + $insert_result = $this->order->insertOrder( $items, $cotation_usd ); + echo json_encode( $insert_result ); + } + +} \ No newline at end of file diff --git a/php/orders.php b/php/orders.php index e69de29..3eeca5f 100644 --- a/php/orders.php +++ b/php/orders.php @@ -0,0 +1,17 @@ +getInstanceDependencyOfContainer( "Desenvolvimento/Dispatcher" ); + $dispatcher->dispatch( ); + +}catch( \RuntimeException $e ) { + + echo json_encode( $e->getMessage() ); +} \ No newline at end of file diff --git a/php/tests/ClientRequestTest.php b/php/tests/ClientRequestTest.php new file mode 100644 index 0000000..4f37c07 --- /dev/null +++ b/php/tests/ClientRequestTest.php @@ -0,0 +1,46 @@ +assertEquals( false, $clientRequest->processRequest( $date ) ); + + } + + public function testGetUrlRequestCotation( ) + { + + $clientRequest = new ClientRequest( ); + $url_request = 'https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/CotacaoDolarDia(dataCotacao=@dataCotacao)'; + $url_request .= "?@dataCotacao='07-20-2018'"; + $url_request .= '&$top=100&$format=json'; + + $date = "07-20-2018"; + $url_request_cotation = $clientRequest->getUrlRequestCotation( $date ); + $this->assertEquals( $url_request, $url_request_cotation ); + + } + + public function testProcessRequestSuccess( ) + { + + $clientRequest = new ClientRequest( ); + $url_request = 'https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/CotacaoDolarDia(dataCotacao=@dataCotacao)'; + $url_request .= "?@dataCotacao='07-20-2018'"; + $url_request .= '&$top=100&$format=json'; + + $date = "07-20-2018"; + $response = $clientRequest->processRequest( $date ); + $this->assertNotEmpty( $response ); + $this->assertArrayHasKey( "value", $response ); + + } + +} \ No newline at end of file diff --git a/php/tests/DispatcherTest.php b/php/tests/DispatcherTest.php new file mode 100644 index 0000000..51b41a1 --- /dev/null +++ b/php/tests/DispatcherTest.php @@ -0,0 +1,67 @@ +dependencyManager = new DependencyManager( $dependencyContainer ); + $this->dispatcher = new Dispatcher( $this->dependencyManager ); + + + } + + + public function testGetRoutes( ) + { + + $info_routes = [ + "GET" => [ + "/php/brl-usd.php", + "/php/orders.php", + ], + "POST" => [ "/php/orders.php" ] + ]; + + + $this->assertEquals( $info_routes, $this->dispatcher->getRoutes( ) ); + + } + + public function testGetPathResource( ) + { + $path_root_request = "/php/brl-usd.php"; + $request_method = "get"; + $path_resource = "Desenvolvimento/Route/Get/Php/Brlusd"; + + $this->assertEquals( $path_resource, $this->dispatcher->getPathResource( $path_root_request, $request_method ) ); + + } + + public function testDispatch( ) + { + $path_root_request = "/php/brl-usd.php"; + $request_method = "GET"; + $path_resource = "Desenvolvimento/Route/Get/Php/Brlusd"; + $client_request = new ClientRequest( ); + $dollar_quotation = new DollarQuotation( $client_request ); + $instance_controller = new Brlusd( $dollar_quotation ); + $this->assertEquals( $instance_controller, $this->dispatcher->dispatch( $path_root_request, $request_method ) ); + + } + + +} \ No newline at end of file diff --git a/php/tests/DollarQuotationTest.php b/php/tests/DollarQuotationTest.php new file mode 100644 index 0000000..34a0d65 --- /dev/null +++ b/php/tests/DollarQuotationTest.php @@ -0,0 +1,64 @@ +clientRequest = new ClientRequest( ); + } + + public function testGetClientRequest( ) + { + + $dollarQuotation = new DollarQuotation( $this->clientRequest ); + $this->assertEquals( $this->clientRequest, $dollarQuotation->getClientRequest( ) ); + + } + + + public function testGetADollarQuotationPerDayIn07202018Fail( ) + { + + $dollarQuotation = new DollarQuotation( $this->clientRequest ); + $date = "0000000000"; + + $result_cotation = $dollarQuotation->getADollarQuotationPerDay( $date ); + $this->assertArrayHasKey( "usd", $result_cotation ); + $this->assertEmpty( 0, $result_cotation[ "usd" ] ); + + + } + + public function testGetADollarQuotationPerDayIn07202018Success( ) + { + + $dollarQuotation = new DollarQuotation( $this->clientRequest ); + $date = "07-20-2018"; + + $result_cotation = $dollarQuotation->getADollarQuotationPerDay( $date ); + $this->assertTrue( is_array( $result_cotation ) ); + + $this->assertTrue( is_array( $dollarQuotation->getADollarQuotationPerDay( $date ) ) ); + + } + + public function testGetDollarCotation( ) + { + $dollarQuotation = new DollarQuotation( $this->clientRequest ); + $date = "07-20-2018"; + + $result_cotation = $dollarQuotation->getDollarCotation( $date ); + $this->assertEquals( 0.26, $result_cotation ); + } + + + +} \ No newline at end of file diff --git a/php/tests/OrderTest.php b/php/tests/OrderTest.php new file mode 100644 index 0000000..69b25c0 --- /dev/null +++ b/php/tests/OrderTest.php @@ -0,0 +1,82 @@ +fileSystemCache = new \FileSystemCache( ); + $this->order = new Order( $this->fileSystemCache ); + $this->clientRequest = new ClientRequest( ); + $this->dollarQuotation = new DollarQuotation( $this->clientRequest ); + $key = $this->fileSystemCache->generateCacheKey('orders'); + $this->fileSystemCache->invalidate( $key ); + } + + public function testGetFileSystemCache( ) + { + + $this->assertEquals( $this->fileSystemCache, $this->order->getFileSystemCache( ) ); + + } + + public function testInsertOrder( ) + { + $date_time = ( new \DateTime( "now", new \DateTimeZone( "America/Sao_Paulo" ) ) )->format( "Y-m-d H:i:s" ); + $data_order = [ "id" => 1, "created_at" => $date_time, "total_brl" => 1650, "total_usd" => 429 ]; + $items = [ 1000, 500, 150 ]; + $date = "07-20-2018"; + + + $cotation_usd = $this->dollarQuotation->getDollarCotation( $date ); + $this->assertEquals( $data_order, $this->order->insertOrder( $items, $cotation_usd ) ); + + } + + + public function testGetOrdersEmpty( ) + { + + $orders = [ ]; + $this->assertEquals( $orders, $this->order->getOrders( ) ); + + } + + public function testGetOrders( ) + { + $date_time = ( new \DateTime( "now", new \DateTimeZone( "America/Sao_Paulo" ) ) )->format( "Y-m-d H:i:s" ); + $data_order1 = [ "id" => 1, "created_at" => $date_time, "total_brl" => 1650, "total_usd" => 429 ]; + $data_order2 = [ "id" => 2, "created_at" => $date_time, "total_brl" => 1650, "total_usd" => 429 ]; + $items = [ 1000, 500, 150 ]; + $date = "07-20-2018"; + $orders = [ $data_order1, $data_order2 ]; + + + $cotation_usd = $this->dollarQuotation->getDollarCotation( $date ); + $this->order->insertOrder( $items, $cotation_usd ); + $this->order->insertOrder( $items, $cotation_usd ); + + $this->assertEquals( $orders, $this->order->getOrders() ); + } + + public function testFindLastOrderId( ) + { + + $this->assertEquals( 1, $this->order->findLastOrderId( ) ); + + } + + +} \ No newline at end of file diff --git a/pratico.md b/pratico.md index bf801f2..d713bfa 100644 --- a/pratico.md +++ b/pratico.md @@ -5,6 +5,39 @@ ```js // Resposta +"use strict" + +class Array { + + constructor( elements ) { + + this.setElements( elements ) + } + + setElements( elements ) + { + if( elements != null ) { + this.elements = elements + }else { + this.elements = [] + } + } + + last( ) { + + if( this.elements.length > 0 ) { + return this.elements[ this.elements.length - 1 ] + } else { + return undefined; + } + } +} + +let ar1 = new Array( ) +let ar2 = new Array( [1, 2, 3, 4, 5] ) + +console.log( ar1.last( ) ) //undefined +console.log( ar2.last( ) ) //5 // Teste/Exemplos const array1 = [1,2,3,4,5,6,7,8,9] @@ -46,6 +79,108 @@ function getTransactions() { ```js // Resposta + +function getTransactions() { + return new Promise((resolve, reject) => { + fetch(BASE_URL + '/api/transacoes') + .then(result => { + result.json().then(transactions_result => { + const transactions = [] + + for (let i in transactions_result) { + if (transactions_result[i].realizada) { + transactions.push({ + id: transactions_result[i].id, + value: transactions_result[i].valor, + type: transactions_result[i].valor < 0 ? 'transference' : 'deposit', + }) + } + } + + return resolve(transactions) + }) + }) + .catch(e => { + return reject(e) + }) + }) +} + +// ou + +function resolvePromiseFetchResult( result ) { + + + return new Promise((resolve, reject) => { + + if( !result ) { + + return reject( "Invalid result" ) + } + + return resolve( result.json() ) + }); +} + +function buildArraySuccessfully( arrayTransactionsResult ) { + + + + return new Promise((resolve, reject) => { + + if( !arrayTransactionsResult ) { + + return reject( "Invalid array transaction result" ) + + } + + let transactions = [] + + for (let i in arrayTransactionsResult) { + + if (arrayTransactionsResult[i].realizada) { + transactions.push({ + id: arrayTransactionsResult[i].id, + value: arrayTransactionsResult[i].valor, + type: arrayTransactionsResult[i].valor < 0 ? 'transference' : 'deposit', + }) + } + } + + return resolve(transactions) + + }); + +} + + + +function getTransactions2( ) { + + return new Promise((resolve, reject) => { + + const url = BASE_URL + '/api/transacoes'; + + return resolve( url ) + + }); + +} + + +getTransactions2( ) + .then( fetch ) + .then( resolvePromiseFetchResult ) + .then( buildArraySuccessfully ) + .then( + (result) => { + console.log(result); + }, + + (error) => { + console.log(`ocorreu o seguinte erro: [ ${error} ]`); + }); + ``` --- @@ -158,6 +293,22 @@ function login($username, $password) { ```php // Resposta + +function login($username, $password) { + + $sql = " + select * + from users + where username = :username AND password = :password + "; + + $sth = $dbh->prepare( $sql ); + $sth->execute(array(':username' => $username, ':password' => $password)); + $user = $sth->fetch(PDO::FETCH_ASSOC); + + return $user; + +} ``` --- @@ -240,4 +391,4 @@ Content-Type: applicaton/json "totalBRL": 1650, "totalUSD": 435.84 }] -``` \ No newline at end of file +``` diff --git a/teorico.md b/teorico.md index 8900235..fb5c032 100644 --- a/teorico.md +++ b/teorico.md @@ -2,33 +2,62 @@ 1\) Qual a diferença do operador `==` para o operador `===` em JavaScript? -[Resposta] +[O operador `==` avalia se dois elementos em comparação contem um mesmo valor enquanto que o operador `===` avalia alem de se dois elementos em comparação possuem o mesmo valor e o mesmo tipo.] 1.1) Dê 2 exemplos de quando os operadores produziriam resultados diferentes ```js // Resposta + +//Exemplo1: +let first_element = 20 +let second_element = "20" + +console.log( first_element == second_element ) +// irá imprimir `true` pois ambos os elementos comparativos tem o mesmo valor +console.log( first_element === second_element ) +// irá imprimir `false` pois ambos os elementos comparativos tem o mesmo valor, mas não tem o mesmo tipo + +//Exemplo2: +let first_element = 50 +let second_element = "50" + +console.log( first_element == second_element ) +// irá imprimir `true` pois ambos os elementos comparativos tem o mesmo valor +console.log( first_element === second_element ) +// irá imprimir `false` pois ambos os elementos comparativos tem o mesmo valor, mas não tem o mesmo tipo + ``` --- -2\) Qual recurso javascript é mais recomendado para tratar chamadas asíncronas? +2\) Qual recurso javascript é mais recomendado para tratar chamadas assíncronas? -[Resposta] +[Promises] 2.1) Justifique -[Resposta] +[Existem dois recursos bem famosos para tratrar chamadas assíncronas em javascript, são eles callbacks e promises, porém +os promises são mais recomendados para o tratamento de chamadas assíncrona, pois permite escrever o código como se fosse +síncrono diferente dos callbacks que geram chamadas dentro funções para utilizar o valor processado de uma função em +outra chamada interna, e isso pode torna dificil o entendimento e manutenção, e testabilidade. +Com promises o fluxo de chamadas é controlado após a resulução das promessas com o metodo then, e ainda podemos tratar +o fluxo de execução através dos parametros resolve e reject da promises.] --- 3\) Existem threads em Node? -[Resposta] +[Sim] 3.1) Explique -[Resposta] +[O node é single thread, porem utiliza de uma arquitetura conhecida como event drive, para fazer um enfileiramento de tarefas, +que são pequenos processamentos ou seja execuções de callbacks ou resolução de promises através de um fluxo controlado pelo +elemento conhecido como event loop. Este fluxo quebra o processamento de determinada rotina, script ou requisição em tasks +que são enfileiradas em uma task queue e são executas uma a uma dentro de uma unica stack ou seja ao final da execução de +uma task a proxima task na fila é adicionada na pilha de execução e o event loop segue seu fluxo executando varias de tasks, +utilizando-se de uma single thread sem a necessida de grande capacidade computacional do servidor.] --- @@ -51,7 +80,9 @@ getUserByName('jonh doe') .then(user => console.log(user)) ``` -[Resposta] +[O resultado é `undefined`, pois o fluxo de execução assincrono do javascript impede que um valor seja utiliza antes da +resolução de uma função, ou seja para que fosse possível utilizar o userId, seria necessário realizar mudanças no +código. ] 4.2) ```js @@ -76,9 +107,10 @@ getData() }) ``` -``` -[Resposta] -``` + +[O resultado é `second`, pois a promise resultante do método getData é reijada, pelo fato da chamada do método não passar, + o parametro como é definido no ato da assinatura do método `getData(id)`. ] + --- @@ -86,29 +118,51 @@ getData() 1\) Qual a diferença do operador `==` para o operador `===` em PHP? -[Resposta] +[O operador `==` avalia se dois elementos em comparação contem um mesmo valor enquanto que o operador `===` avalia alem de se dois elementos em comparação possuem o mesmo valor e o mesmo tipo.] 1.1) Dê 2 exemplos de quando os operadores produziriam resultados diferentes ```php // Resposta +//Exemplo1: +$first_element = 20; +$second_element = "20"; + +var_dump( $first_element == $second_element ) ; +// irá imprimir `true` pois ambos os elementos comparativos tem o mesmo valor +var_dump( $first_element === $second_element ) ; +// irá imprimir `false` pois ambos os elementos comparativos tem o mesmo valor, mas não tem o mesmo tipo + +//Exemplo2: +$first_element = 50; +$second_element = "50"; + +var_dump( $first_element == $second_element ) ; +// irá imprimir `true` pois ambos os elementos comparativos tem o mesmo valor +var_dump( $first_element === $second_element ) ; +// irá imprimir `false` pois ambos os elementos comparativos tem o mesmo valor, mas não tem o mesmo tipo ``` --- 2\) Qual a função do apache ou nginx em uma aplicação PHP? -[Resposta] +[O apache ou nginx são servidores web, que tratam requisições e respostas de scripts de uma aplicação construída +em alguma linguagem como php, por exemplo. Além disso o apache e nginx, permitem realiza configurações +no servidor que roda uma aplicação web.] --- 3\) Existem threads em PHP? -[Resposta] +[Sim] 3.1) Explique -[Resposta] +[Para utilizar o recurso de threads no php é necessário instalar um modulo chamado pthreads, este módulo +possibilita criar classes que extendem a classe abstrata Thread, para ter suas próprias classes de manipulação de +threads personalizadas é necessários implementas o método principal `run`, dentre outros para utilzar os recursos + de threads em php.] --- @@ -123,7 +177,8 @@ class Test { echo Test::prop; ``` -[Resposta] +[1337, pois constantes declaradas utilizando chave `const` permitem o uso de expressoes que produzem valores +escalares como um inteiro por exemplo, seja armazenado em seu conteúdo. ] 4.2) ```js @@ -146,4 +201,6 @@ class B extends A { B::test(); ``` -[Resposta] \ No newline at end of file +[O resuldado será a impressao da string `bar` pois a chamada do metodo estático `test` chama o método `foo` + utilizando a palavra chave `self` associado ao operador de resolução de escopo `::`, se fosse utilizado a + a palavra chave `static` associado ao operador de resolução de escopo `::`, o resultado seria: `baz`]