Skip to content

Commit

Permalink
feat(preview): initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveVanOpstal committed Apr 16, 2016
1 parent eb0e7df commit ead2acc
Show file tree
Hide file tree
Showing 16 changed files with 599 additions and 261 deletions.
56 changes: 56 additions & 0 deletions src/app/build/items/item-slot.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//import {spyOn} from 'jasmine';
import {it, inject, beforeEachProviders, beforeEach} from 'angular2/testing';

import {ItemsComponent} from './items.component';
import {ItemSlotComponent} from './item-slot.component';

describe('ItemSlotComponent', () => {
beforeEachProviders(() => [
ItemsComponent,

ItemSlotComponent
]);

let item1;
let item2;

beforeEach(inject([ItemSlotComponent], (component) => {
item1 = {
'id': 3341,
'gold': { 'total': 0 }
};

item2 = {
'id': 2003,
'gold': { 'total': 50 }
};

component.config = { g: [0, 100, 200, 300], gameTime: 200, sampleSize: 20 };
component.items = [item1, item2, item2, item2];
}));

it('should add an item', inject([ItemSlotComponent], (component) => {
spyOn(component, 'addTime');
spyOn(component, 'addBundle');
expect(component.addTime).not.toHaveBeenCalled();
expect(component.addBundle).not.toHaveBeenCalled();
component.addItem(item1);
expect(component.addTime).toHaveBeenCalled();
expect(component.addBundle).toHaveBeenCalled();
expect(component.items[4]).toHaveEqualContent(item1);
}));

it('should calculate time', inject([ItemSlotComponent], (component) => {
component.addTime(item1);
expect(item1['time']).toBe(0);
component.addTime(item2);
expect(item2['time']).toBe(5);
}));

it('should bundle', inject([ItemSlotComponent], (component) => {
component.addTime(item2);
component.addBundle(item2);
expect(component.items.length).toBe(2);
expect(component.items[1].bundle).toBe(3);
}));
});
112 changes: 112 additions & 0 deletions src/app/build/items/item-slot.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {Component, Input, Inject, forwardRef, OnInit} from 'angular2/core';
import {NgClass} from 'angular2/common';
import {Observable} from 'rxjs/Observable';

import {ItemsComponent} from './items.component';
import {ItemComponent} from './item.component';
import {Config} from '../config';

import * as d3 from 'd3'; //TODO: remove test

@Component({
selector: 'item-slot',
directives: [NgClass, ItemComponent],
template: `
<template ngFor #item [ngForOf]="items">
<item [item]="item" [ngClass]="{disabled: item.disabled}" style="left: {{xScaleTime(item.time)}}px" (contextmenu)="rightClicked(item)"></item>
</template>`
})

export class ItemSlotComponent implements OnInit {
@Input() id: number;
@Input() config: Config;
private items: Array<Object> = new Array<Object>();

// TODO: move to itemComponent when angular allows attributes on <template>
// TODO: get this scale from shopComponent
private xScaleTime = d3.scale.linear()
.domain([0, 3600000])
.range([0, 1460]);

constructor( @Inject(forwardRef(() => ItemsComponent)) private itemsComponent: ItemsComponent) {
}

ngOnInit() {
this.itemsComponent.addItemSlotComponent(this);
}

addItem(item: Object) {
this.addTime(item);
this.addBundle(item);
this.items.push(item);
}

removeItem(item: Object) {
this.items.splice(this.items.indexOf(item), 1);
}

compatible(item: Object) {
if (!this.items.length) {
return true;
}
let from = this.items[this.items.length - 1]['from'];
if (!from) {
return true;
}
return from.indexOf(item['id']) > -1;
}

private addTime(item: Object) {
item['time'] = this.getTime(this.config.g, item['gold']['total'], this.config.gameTime, this.config.sampleSize);
}

private addBundle(item: Object) {
if (!this.items || !this.items.length) {
return;
}

item['bundle'] = 1;
for (let index = 0; index < this.items.length - 1; index++) {
if (item['id'] === this.items[index]['id'] && item['time'] === this.items[index]['time']) {
item['bundle']++;
this.items.splice(index + 1, 1);
index--;
}
}
}

private getTime(frames: Array<number>, value: number, totalTime: number, sampleSize: number) {
let index = this.getUpperIndex(frames, value);
if (index <= -1) {
return -1;
}

let lowerFrame = frames[index];
let upperFrame = frames[index + 1];

let ratio = (value - lowerFrame) / (upperFrame - lowerFrame);

let sampleTime = totalTime / sampleSize;
let lowerTime = index * sampleTime;
let upperTime = (index + 1) * sampleTime;

let time = lowerTime + ((upperTime - lowerTime) * ratio);
time = isFinite(time) ? time : lowerTime;
return time > 0 ? time : 0;
}

private getUpperIndex(frames: Array<number>, gold: number) {
for (var j = 0; j < frames.length; j++) {
if (frames[j] > gold) {
return j;
}
}
return -1;
}

// TODO: move to itemComponent when angular allows events on <template>
private rightClicked(item: Object) {
this.removeItem(item);
return false; // stop context menu from appearing
}
}
2 changes: 1 addition & 1 deletion src/app/build/items/item.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ import {DDragonDirective} from '../../misc/ddragon.directive';
})

export class ItemComponent {
@Input() item;
@Input() item: Object;
}
104 changes: 36 additions & 68 deletions src/app/build/items/items.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,46 @@
import {it, inject, beforeEachProviders, beforeEach} from 'angular2/testing';

import {ItemsComponent} from './items.component';
import {ItemSlotComponent} from './item-slot.component';

// class MockItemSlotComponent implements ItemSlotComponent {

// }

describe('ItemsComponent', () => {
beforeEachProviders(() => [
ItemsComponent
]);

beforeEach(inject([ItemsComponent], (component) => {
component.config = { g: [100, 200, 300], gameTime: 200, sampleSize: 20 };
component.items = [
{
'id': 3341,
'gold': { 'total': 0 }
},
{
'id': 2003,
'gold': { 'total': 50 }
},
{
'id': 2003,
'gold': { 'total': 50 }
},
{
'id': 2003,
'gold': { 'total': 50 }
}
];
}));

it('should update on changes', inject([ItemsComponent], (component) => {
spyOn(component, 'addTime');
spyOn(component, 'addBundle');
expect(component.addTime).not.toHaveBeenCalled();
expect(component.addBundle).not.toHaveBeenCalled();
component.ngDoCheck();
expect(component.addTime).toHaveBeenCalled();
expect(component.addBundle).toHaveBeenCalled();
}));

it('should calculate time', inject([ItemsComponent], (component) => {
component.addTime();
expect(component.items[0].time).toBe(0);
expect(component.items[1].time).toBe(0);
expect(component.items[2].time).toBe(0);
expect(component.items[3].time).toBe(5);
}));

it('should not calculate time', inject([ItemsComponent], (component) => {
component.items = [
{
'id': 123,
'gold': { 'total': 400 }
}
];
component.addTime();
component.addBundle();
expect(component.items[0].time).toBe(-1);
}));

it('should bundle', inject([ItemsComponent], (component) => {
component.addTime();
component.addBundle();
expect(component.items.length).toBe(3);
expect(component.items[1].bundle).toBe(2);
}));

it('should not bundle', inject([ItemsComponent], (component) => {
component.items = [];
component.addBundle();
expect(component.items).toHaveEqualContent([]);

component.items = [{ id: 1, bundle: 1 }, { id: 2, bundle: 1 }];
component.addBundle();
expect(component.items[0].bundle).toBe(1);
}));
// beforeEach(inject([ItemsComponent], (component) => {
// component.config = { g: [100, 200, 300], gameTime: 200, sampleSize: 20 };
// component.itemSlotComponents = [
// {
// 'id': 3341,
// 'gold': { 'total': 0 }
// },
// {
// 'id': 2003,
// 'gold': { 'total': 50 }
// },
// {
// 'id': 2003,
// 'gold': { 'total': 50 }
// },
// {
// 'id': 2003,
// 'gold': { 'total': 50 }
// }
// ];
// }));

// it('should add item', inject([ItemsComponent], (component) => {
// spyOn(component, 'addTime');
// spyOn(component, 'addBundle');
// expect(component.addTime).not.toHaveBeenCalled();
// expect(component.addBundle).not.toHaveBeenCalled();
// component.ngDoCheck();
// expect(component.addTime).toHaveBeenCalled();
// expect(component.addBundle).toHaveBeenCalled();
// }));
});
Loading

0 comments on commit ead2acc

Please sign in to comment.