Commit 75aebf05 authored by pablososa's avatar pablososa

Entrega 12-04-2021 - Problemas en tests ARS

parents
Pipeline #44 failed with stages
in 9 seconds
node_modules
module.exports = createStatementData = function createStatementData(invoice, plays) {
const statementData = {}
statementData.customer = invoice.customer;
statementData.performances = invoice.performances.map(enrichPerformance);
statementData.totalAmount = totalAmount(statementData.performances);
statementData.totalVolumeCredits = totalVolumeCredits(statementData.performances);
return statementData;
function enrichPerformance(aPerformance) {
const calculator = new PerformanceCalculatorFactory(aPerformance,playFor(aPerformance));
const result = Object.assign({}, aPerformance);
result.play = playFor(result);
result.amount = calculator.amount;
result.volumeCredits = calculator.volumeCredits;
return result;
}
function playFor(aPerformance){
return plays[aPerformance.playID];
}
function totalAmount(somePerformance){
return somePerformance.reduce((result,aPerformance)=> result + aPerformance.amount, 0);
}
function totalVolumeCredits(somePerformance) {
let result = 0;
for (let perf of somePerformance) {
// add volume credits
result += perf.volumeCredits;
}
return result;
}
}
class PerformanceCalculator {
constructor(){
this.performance = null;
this.play = null;
}
get amount(){
throw new Error(`No se puede llamar a amount de la clase abstracta`);
}
}
class PerformanceCalculatorFactory{
constructor(aPerformance, aPlay){
switch (aPlay.type) {
case "tragedy": return new PerformanceCalculatorTragedy(aPerformance,aPlay);
case "comedy": return new PerformanceCalculatorComedy(aPerformance,aPlay);
default: throw new Error(`unknown type: ${aPlay.type}`);
}
}
}
class PerformanceCalculatorTragedy extends PerformanceCalculator{
constructor(aPerformance,aPlay) {
super();
this.performance = aPerformance;
this.play = aPlay;
}
get amount(){
var thisAmount = 40000;
if(this.performance.audience > 30)
thisAmount += 1000 * (this.performance.audience - 30);
return thisAmount;
}
get volumeCredits(){
return volumeCreditsComposer(this.performance.audience);
}
}
class PerformanceCalculatorComedy extends PerformanceCalculator{
constructor(aPerformance,aPlay) {
super();
this.performance = aPerformance;
this.play = aPlay;
}
get amount(){
let thisAmount = 30000;
if (this.performance.audience > 20) {
thisAmount += 10000 + 500 * (this.performance.audience - 20);
}
thisAmount += 300 * this.performance.audience;
return thisAmount;
}
get volumeCredits(){
return volumeCreditsComposer(this.performance.audience) + Math.floor(this.performance.audience / 5);
}
}
function volumeCreditsComposer(aAudience){
return Math.max(aAudience - 30, 0);
}
module.exports = {
default: `--format-options '{"snippetInterface": "synchronous"}' --publish-quiet`
}
# language: es
Característica: Imprimir la factura de una compañía teatral
Necesaria para liquidar el borderau
Escenario: imprimr la factura de BigCo en texto plano USD
Dado el listado de la facturación de espectáculos
"""
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}
"""
Y la lista de obras
"""
{
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
}
"""
Y tipo de renderizado
"""
{
"renderType": "text",
"currencyFormat":"usd"
}
"""
Cuando mando a imprimir el borderau texto Plano USD
Entonces debería imprimir el borderau texto Plano USD
"""
Statement for BigCo
Hamlet: $650.00 (55 seats)
As You Like It: $580.00 (35 seats)
Othello: $500.00 (40 seats)
Amount owed is $1,730.00
You earned 47 credits
"""
Escenario: imprimr la factura de BigCo en HTML USD
Dado el listado de la facturación de espectáculos
"""
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}
"""
Y la lista de obras
"""
{
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
}
"""
Y tipo de renderizado
"""
{
"renderType": "html",
"currencyFormat":"usd"
}
"""
Cuando mando a imprimir el borderau en HTML USD
Entonces debería imprimir el borderau en HTML USD
"""
<h1>Statement for BigCo</h1>
<table>
<tr><th>play</th><th>seats</th><th>cost</th></tr>
<tr><td>Hamlet</td><td>55</td><td>$650.00</td></tr>
<tr><td>As You Like It</td><td>35</td><td>$580.00</td></tr>
<tr><td>Othello</td><td>40</td><td>$500.00</td></tr>
</table>
<p>Amount owed is <em>$1,730.00</em></p>
<p>You earned <em>47</em> credits</p>
"""
Escenario: imprimr la factura de BigCo en texto plano ARS
Dado el listado de la facturación de espectáculos
"""
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}
"""
Y la lista de obras
"""
{
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
}
"""
Y tipo de renderizado
"""
{
"renderType": "text",
"currencyFormat":"ars"
}
"""
Cuando mando a imprimir el borderau texto Plano ARS
Entonces debería imprimir el borderau texto Plano ARS
"""
Statement for BigCo
Hamlet: $ 650,00 (55 seats)
As You Like It: $ 580,00 (35 seats)
Othello: $ 500,00 (40 seats)
Amount owed is $ 1730,00
You earned 47 credits
"""
Escenario: imprimr la factura de BigCo en HTML ARS
Dado el listado de la facturación de espectáculos
"""
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}
"""
Y la lista de obras
"""
{
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
}
"""
Y tipo de renderizado
"""
{
"renderType": "html",
"currencyFormat":"ars"
}
"""
Cuando mando a imprimir el borderau en HTML ARS
Entonces debería imprimir el borderau en HTML ARS
"""
<h1>Statement for BigCo</h1>
<table>
<tr><th>play</th><th>seats</th><th>cost</th></tr>
<tr><td>Hamlet</td><td>55</td><td>$ 650,00</td></tr>
<tr><td>As You Like It</td><td>35</td><td>$ 580,00</td></tr>
<tr><td>Othello</td><td>40</td><td>$ 500,00</td></tr>
</table>
<p>Amount owed is <em>$ 1730,00</em></p>
<p>You earned <em>47</em> credits</p>
"""
const assert = require('assert');
const { Given, When, Then } = require('cucumber');
const print_the_bill = require('../../statement');
Given('el listado de la facturación de espectáculos', function (espectaculos) {
this.invoice = JSON.parse(espectaculos);
});
Given('la lista de obras', function (obras) {
this.play = JSON.parse(obras);
});
Given('tipo de renderizado', function (renderType) {
this.render= JSON.parse(renderType);
});
When('mando a imprimir el borderau texto Plano USD', function () {
this.actualAnswer = print_the_bill.render(this.invoice,this.play,this.render.renderType,this.render.currencyFormat);
});
Then('debería imprimir el borderau texto Plano USD', function (expectedAnswer) {
assert.equal(this.actualAnswer.trim(), expectedAnswer.trim());;
});
When('mando a imprimir el borderau en HTML USD', function () {
this.actualAnswer = print_the_bill.render(this.invoice,this.play,this.render.renderType,this.render.currencyFormat);
});
Then('debería imprimir el borderau en HTML USD', function (expectedAnswer) {
assert.equal(this.actualAnswer.trim(), expectedAnswer.trim());;
});
When('mando a imprimir el borderau texto Plano ARS', function () {
this.actualAnswer = print_the_bill.render(this.invoice,this.play,this.render.renderType,this.render.currencyFormat);
});
Then('debería imprimir el borderau texto Plano ARS', function (expectedAnswer) {
assert.equal(this.actualAnswer.trim(), expectedAnswer.trim());;
});
When('mando a imprimir el borderau en HTML ARS', function () {
this.actualAnswer = print_the_bill.render(this.invoice,this.play,this.render.renderType,this.render.currencyFormat);
});
Then('debería imprimir el borderau en HTML ARS', function (expectedAnswer) {
assert.equal(this.actualAnswer.trim(), expectedAnswer.trim());;
});
[
{
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
}
]
\ No newline at end of file
var fs = require('fs');
var dataPlays = fs.readFileSync('plays.json', 'utf8');
var plays = JSON.parse(dataPlays);
var dataInvoices = fs.readFileSync('invoices.json', 'utf8');
var invoices = JSON.parse(dataInvoices);
var print_the_bill = require('./statement.js');
// main ????
for (let invoice of invoices) {
console.log(print_the_bill.statement(invoice, plays));
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "refactoring-solid",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "cucumber-js"
},
"repository": {
"type": "git",
"url": "https://git.fi.mdn.unp.edu.ar/labprog/talleres/refactoring-solid.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"cucumber": "^7.0.0-rc.0"
},
"dependencies": {
"tern": "^0.24.3"
}
}
{
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
}
\ No newline at end of file
module.exports = statement = function statement(invoice, plays) {
var renderPlainText = require('./render-plain-text.js');
return renderPlainText(statementData);
function enrichPerformance(aPerformance) {
const result = Object.assign({}, aPerformance);
result.name = playFor(result).name;
result.type = playFor(result).type;
result.amount = amountFor(result);
result.volumeCredits = volumeCreditsFor(result);
return result;
}
function playFor(aPerformance){
return plays[aPerformance.playID];
}
function amountFor(aPerformance) {
let thisAmount = 0;
switch (aPerformance.type) {
case "tragedy":
thisAmount = 40000;
if (aPerformance.audience > 30) {
thisAmount += 1000 * (aPerformance.audience - 30);
}
break;
case "comedy":
thisAmount = 30000;
if (aPerformance.audience > 20) {
thisAmount += 10000 + 500 * (aPerformance.audience - 20);
}
thisAmount += 300 * aPerformance.audience;
break;
default:
throw new Error(`unknown type: ${aPerformance.type}`);
}
return thisAmount;
}
function totalAmount(somePerformance){
return somePerformance.reduce((result,aPerformance)=> result + aPerformance.amount, 0);
}
function volumeCreditsFor(aPerformance){
let volumeCredits = 0;
volumeCredits += Math.max(aPerformance.audience - 30, 0);
if ("comedy" === aPerformance.type) volumeCredits += Math.floor(aPerformance.audience / 5);
return volumeCredits;
}
function totalVolumeCredits(somePerformance) {
let result = 0;
for (let perf of somePerformance) {
// add volume credits
result += volumeCreditsFor(perf);
}
return result;
}
}
// function usd(aNumber){
// return new Intl.NumberFormat("en-US",
// {
// style: "currency", currency: "USD",
// minimumFractionDigits: 2
// }).format(aNumber/100);
// }
// function renderPlainText(statementData) {
// let result = `Statement for ${statementData.customer}\n`;
// for (let perf of statementData.performances) {
// result += ` ${perf.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
// }
// result += `Amount owed is ${usd(statementData.totalAmount)}\n`;
// result += `You earned ${statementData.totalVolumeCredits} credits\n`;
// return result;
// }
const createStatementData = require('./createStatementData.js');
exports.render = render = function render(aInvoice,aPlays,aRender,aCurrency){
return new RenderFactory(aInvoice,aPlays,aRender,aCurrency).print;
}
/*
* Formatos de salida de statement
* */
class RenderFactory{
constructor(aInvoice,aPlays,aRenderType,aCurrency){
switch (aRenderType) {
case "html": return new RenderHtml(aInvoice,aPlays,aCurrency);
case "text": return new RenderPlainText(aInvoice,aPlays,aCurrency);
default: return new Error(`${aRenderType} output format not supported`);
}
}
}
class Render{
constructor(aInvoice,aPlays,aCurrency){
this.statementData = new createStatementData(aInvoice,aPlays);
this.currencyFormat = aCurrency;
}
get print(){
throw new Error("this is an abstract class");
}
get getCurrency(){
return this.currencyFormat;
}
set setCurrency(aCurrency){
this.currencyFormat = aCurrency;
}
}
class RenderHtml extends Render{
constructor(aInvoice,aPlays,aCurrency){
super(aInvoice,aPlays,aCurrency);
this.statementData = new createStatementData(aInvoice,aPlays);
this.currencyFormat = aCurrency;
}
get print(){
let result = `<h1>Statement for ${this.statementData.customer}</h1>\n`;
result += "<table>\n";
result += "<tr><th>play</th><th>seats</th><th>cost</th></tr>\n";
for (let perf of this.statementData.performances) {
result += `<tr><td>${perf.play.name}</td><td>${perf.audience}</td>`;
result += `<td>${new CurrencyFactory(this.currencyFormat,perf.amount).cFormat}</td></tr>\n`;
}
result += "</table>\n";
result += `<p>Amount owed is <em>${new CurrencyFactory(this.currencyFormat,this.statementData.totalAmount).cFormat}</em></p>\n`;
result += `<p>You earned <em>${this.statementData.totalVolumeCredits}</em> credits</p>\n`;
return result;
}
}
class RenderPlainText extends Render{
constructor(aInvoice,aPlays,aCurrency){
super(aInvoice,aPlays,aCurrency);
}
get print(){
let result = `Statement for ${this.statementData.customer}\n`;
for (let perf of this.statementData.performances) {
result += ` ${perf.play.name}: ${new CurrencyFactory(this.currencyFormat,perf.amount).cFormat} (${perf.audience} seats)\n`;
}
result += `Amount owed is ${new CurrencyFactory(this.currencyFormat,this.statementData.totalAmount).cFormat}\n`;
result += `You earned ${this.statementData.totalVolumeCredits} credits\n`;
return result;
}
}
class CurrencyFactory {
constructor(aCurrencyType,aNumber){
switch(aCurrencyType){
case "usd": return new Usd(aNumber);
case "ars": return new Ars(aNumber);
default: throw new Error(`${aCurrencyType} format not supported`);
}
}
}
/*
* Tipos de monedas soportadas
* */
class Currency{
constructor(){
this.cFormat = null;
}
}
class Usd extends Currency{
constructor(aNumber){
super();
this.cFormat = new Intl.NumberFormat("en-US",
{
style: "currency", currency: "USD",
minimumFractionDigits: 2
}).format(aNumber/100);
}
}
class Ars extends Currency{
constructor(aNumber){
super();
this.cFormat = new Intl.NumberFormat('es-AR',
{
style: 'currency', currency: 'ARS',
minimumFractionDigits: 2
}).format(aNumber/100);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment