attempt to fix unit tests.
This commit is contained in:
@ -1,24 +1,24 @@
|
||||
import { length } from "enheter";
|
||||
import { AreaProduct, LengthProduct, price } from "../product";
|
||||
import { Product } from "../product";
|
||||
|
||||
describe("Product tests", () => {
|
||||
|
||||
it(`Length product gives correct price for a shorter length`, () => {
|
||||
const standard = new LengthProduct(price("USD", 20), length("foot", 4));
|
||||
const standard = new Product(20, length("foot", 4));
|
||||
const comparison = standard.priceFor(length("foot", 2));
|
||||
expect(comparison.value).toEqual(10);
|
||||
expect(comparison).toEqual(10);
|
||||
});
|
||||
|
||||
it(`Length product gives correct price for a longer length`, () => {
|
||||
const standard = new LengthProduct(price("USD", 20), length("foot", 4));
|
||||
const standard = new Product(20, length("foot", 4));
|
||||
const comparison = standard.priceFor(length("foot", 8));
|
||||
expect(comparison.value).toEqual(40);
|
||||
expect(comparison).toEqual(40);
|
||||
});
|
||||
|
||||
it(`Length product gives correct price if different units`, () => {
|
||||
const standard = new LengthProduct(price("USD", 10), length("foot", 1));
|
||||
const standard = new Product(10, length("foot", 1));
|
||||
const comparison = standard.priceFor(length("inch", 24));
|
||||
expect(comparison.value).toEqual(20);
|
||||
expect(comparison).toEqual(20);
|
||||
});
|
||||
|
||||
});
|
@ -1,63 +1,58 @@
|
||||
import {length as en_length, area as en_area} from "enheter"
|
||||
import {Measure, LengthUnit, AreaUnit, } from "enheter"
|
||||
import uuid from "react-native-uuid";
|
||||
export type Id = string;
|
||||
|
||||
export type Currency = "USD";
|
||||
|
||||
export class Price<C extends Currency> {
|
||||
constructor(public value : number) {}
|
||||
}
|
||||
export const CURRENCY_SYMBOLS : Map<"USD", string> = {
|
||||
"USD": "$",
|
||||
};
|
||||
|
||||
export function price(c : Currency, value : number) {
|
||||
return new Price<typeof c>(value);
|
||||
export class Price {
|
||||
constructor(public currency : Currency, public value : number) {}
|
||||
public toString() {
|
||||
const sym = CURRENCY_SYMBOLS.get(this.currency);
|
||||
return `${sym} ${Math.round(this.value)}`;
|
||||
}
|
||||
}
|
||||
|
||||
export type ProductAttributes = {
|
||||
id?: string,
|
||||
name?: string,
|
||||
image?: string,
|
||||
description?: string,
|
||||
depth?: string,
|
||||
currency?: Currency,
|
||||
[key:string]: any,
|
||||
}
|
||||
|
||||
|
||||
export abstract class Product {
|
||||
id?: Id
|
||||
constructor(public pricePerUnit : Price<Currency>, public attributes : ProductAttributes = {}) {}
|
||||
public abstract priceFor(measure : Measure<"length"> | Measure<"area">) : Price<Currency>;
|
||||
}
|
||||
|
||||
|
||||
interface ILength {
|
||||
length : Measure<"length">
|
||||
}
|
||||
|
||||
interface IArea {
|
||||
area: Measure<"area">
|
||||
}
|
||||
|
||||
export class LengthProduct extends Product implements ILength {
|
||||
constructor(public pricePerUnit : Price<Currency>, public length: Measure<"length">, public attributes : ProductAttributes = {}) {
|
||||
super(pricePerUnit, attributes);
|
||||
export class Product {
|
||||
public id : string;
|
||||
constructor(public pricePerUnit : number, public measurement : Measure<"length" | "area">, public attributes : ProductAttributes = {}) {
|
||||
this.id = attributes.id || uuid.v4().toString();
|
||||
}
|
||||
|
||||
public priceFor(length : Measure<"length">): Price<Currency> {
|
||||
const ratio = length.convertTo(this.length.unit).divideBy(this.length).value;
|
||||
return {
|
||||
value: this.pricePerUnit.value * ratio,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class AreaProduct extends Product implements IArea {
|
||||
constructor(public pricePerUnit : Price<Currency>, public area : Measure<"area">, public attributes : ProductAttributes = {}) {
|
||||
super(pricePerUnit, attributes);
|
||||
public priceFor(measurement : Measure<"length" | "area">): number {
|
||||
const ratio = measurement.convertTo(this.measurement.unit).divideBy(this.measurement).value;
|
||||
return this.pricePerUnit * ratio
|
||||
}
|
||||
|
||||
public priceFor(area : Measure<"area">): Price<Currency> {
|
||||
const ratio = area.convertTo(this.area.unit).divideBy(this.area).value;
|
||||
return {
|
||||
value: this.pricePerUnit.value * ratio,
|
||||
};
|
||||
get isArea() {
|
||||
return this.measurement.unit.dimension.length === 2;
|
||||
}
|
||||
|
||||
get isLength() {
|
||||
return this.measurement.unit.dimension.length === 1;
|
||||
}
|
||||
|
||||
get attributesAsList() {
|
||||
return Object.entries(this.attributes).map(([key, value]) => {
|
||||
return {key, value}
|
||||
})
|
||||
}
|
||||
|
||||
public removeAttribute(key : string) {
|
||||
delete this.attributes[key]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user