From 1f5b74a4648640a1f431f87524f636a30df7d8a8 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 3 Aug 2015 19:20:32 +0700 Subject: [PATCH 1/4] feat(scintillator): use PIXI v3 and (game): move BG image out of scintillator --- config/webpack.js | 9 +++++ package.json | 5 ++- public/skins/default/skin_screen.xml | 6 --- public/skins/default/skin_template.jade | 5 --- src/game/display/background/default.jpg | Bin 0 -> 60049 bytes src/game/display/game-display.scss | 36 ++++++++++++++++++ src/game/display/index.js | 15 +++++++- src/game/game-scene.js | 16 ++++---- src/game/loaders/game-loader.js | 1 - src/progress/formatters.js | 6 ++- src/scintillator/context.js | 4 +- src/scintillator/loader.js | 25 ++++++++---- .../nodes/concerns/display-object.js | 4 +- src/scintillator/nodes/group.js | 2 +- src/scintillator/nodes/if.js | 2 +- src/scintillator/nodes/object.js | 2 +- src/scintillator/nodes/sprite.js | 2 +- src/scintillator/nodes/text.js | 6 +-- 18 files changed, 104 insertions(+), 42 deletions(-) create mode 100644 src/game/display/background/default.jpg create mode 100644 src/game/display/game-display.scss diff --git a/config/webpack.js b/config/webpack.js index e4c1e08ba..52dd1473c 100644 --- a/config/webpack.js +++ b/config/webpack.js @@ -38,6 +38,15 @@ let config = { include: [path('src'), path('spec')], loader: 'babel?modules=common&experimental=true', }, + { + test: /\.js$/, + include: [path('node_modules', 'pixi.js')], + loader: 'transform/cacheable?brfs', + }, + { + test: /\.json$/, + loader: 'json', + }, { test: /\.pegjs$/, loader: 'pegjs', diff --git a/package.json b/package.json index b5cb4148f..4a14c437c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "babel-eslint": "^3.0.1", "babel-loader": "^4.0.0", "body-parser": "^1.10.0", + "brfs": "^1.4.0", "browser-launcher": "^1.0.0", "bundle-loader": "^0.5.2", "chai": "^2.2.0", @@ -60,6 +61,7 @@ "jade-loader": "^0.7.0", "jasmine": "^2.1.1", "js-yaml": "^3.2.5", + "json-loader": "^0.5.2", "merge-stream": "^0.1.6", "mocha": "^2.1.0", "node-env": "^0.1.6", @@ -76,6 +78,7 @@ "sinon-chai": "^2.7.0", "style-loader": "^0.9.0", "through2": "^0.6.3", + "transform-loader": "^0.2.2", "url-loader": "^0.5.5", "val-loader": "^0.5.0", "web-audio-test-api": "^0.2.1", @@ -109,7 +112,7 @@ "lru-cache": "^2.6.5", "once": "^1.3.1", "parse": "^1.5.0", - "pixi.js": "^2.2.3", + "pixi.js": "^3.0.7", "react": "^0.13.2", "react-fa": "^3.2.0", "react-overlay-popup": "^1.0.2", diff --git a/public/skins/default/skin_screen.xml b/public/skins/default/skin_screen.xml index 1260da373..3dbb9970c 100644 --- a/public/skins/default/skin_screen.xml +++ b/public/skins/default/skin_screen.xml @@ -1935,12 +1935,6 @@ - - - - - - diff --git a/public/skins/default/skin_template.jade b/public/skins/default/skin_template.jade index ba5fb215c..7d3eeae5c 100644 --- a/public/skins/default/skin_template.jade +++ b/public/skins/default/skin_template.jade @@ -6,11 +6,6 @@ include _lib/common defs +all-note-area(id='note-area') - sprite(image='Background/Space.jpg' x='0' y='0') - animation - keyframe(t='0.0' y='0' alpha='0') - keyframe(t='1.0' y='-32' alpha='1' ease='quadOut') - // note panel (Left) #{'if'}(key='p1_placement' value='left') group diff --git a/src/game/display/background/default.jpg b/src/game/display/background/default.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87223292255fbb2ad233e80438d3aa3c5228ff5c GIT binary patch literal 60049 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 canvas { + position: relative; + z-index: 100; + } +} + +@keyframes game-display--bg-default { + from { + transform: translate(0, 0); + opacity: 0; + } + to { + transform: translate(0, -35px); + opacity: 1; + } +} diff --git a/src/game/display/index.js b/src/game/display/index.js index e2a0bc5af..1e549a747 100644 --- a/src/game/display/index.js +++ b/src/game/display/index.js @@ -1,14 +1,16 @@ import PlayerDisplay from './player-display' +import './game-display.scss' +import $ from 'jquery' export class GameDisplay { - constructor({ game, skin, context }) { + constructor({ game, context }) { this._game = game this._context = context this._players = new Map(game.players.map(player => [player, new PlayerDisplay(player)])) this._stateful = { } - void skin + this._wrapper = this._createWrapper() } start() { this._started = new Date().getTime() @@ -61,12 +63,21 @@ export class GameDisplay { let f = gameState.readyFraction return f > 0.5 ? Math.pow(1 - (f - 0.5) / 0.5, 2) : 0 } + _createWrapper() { + var $wrapper = $('
') + .append('
') + .append(this.view) + return $wrapper[0] + } get context() { return this._context } get view() { return this._context.view } + get wrapper() { + return this._wrapper + } _formatTime(seconds) { let s = Math.floor(seconds % 60) return Math.floor(seconds / 60) + ':' + (s < 10 ? '0' : '') + s diff --git a/src/game/game-scene.js b/src/game/game-scene.js index 90a065ec8..f66570035 100644 --- a/src/game/game-scene.js +++ b/src/game/game-scene.js @@ -5,7 +5,7 @@ export default function GameScene(display) { return function(container) { let handler = () => false $(window).on('touchstart', handler) - showCanvas(display.view, container) + showCanvas(display, container) return { teardown() { $(window).off('touchstart', handler) @@ -14,14 +14,12 @@ export default function GameScene(display) { } } -function showCanvas(view, container) { +function showCanvas(display, container) { + var { view, wrapper } = display var { width, height } = view + container.appendChild(wrapper) - view.style.display = 'block' - view.style.margin = '0 auto' - - container.appendChild(view) resize() $(window).on('resize', resize) @@ -32,8 +30,12 @@ function showCanvas(view, container) { ) view.style.width = Math.round(width * scale) + 'px' view.style.height = Math.round(height * scale) + 'px' + wrapper.style.width = Math.round(width * scale) + 'px' + wrapper.style.height = Math.round(height * scale) + 'px' var yOffset = (window.innerHeight - height * scale) / 2 - view.style.marginTop = Math.round(yOffset) + 'px' + wrapper.style.marginTop = Math.round(yOffset) + 'px' } + return wrapper + } diff --git a/src/game/loaders/game-loader.js b/src/game/loaders/game-loader.js index 85808bfe9..ddb480653 100644 --- a/src/game/loaders/game-loader.js +++ b/src/game/loaders/game-loader.js @@ -104,4 +104,3 @@ export function load(spec) { }) } - diff --git a/src/progress/formatters.js b/src/progress/formatters.js index 6eea601d5..e2eeb0832 100644 --- a/src/progress/formatters.js +++ b/src/progress/formatters.js @@ -7,6 +7,10 @@ let wrap = f => progress => progress.progress !== null ? f(progress) : '' export let BYTES_FORMATTER = wrap(progress => bytes(progress.current) + ' / ' + bytes(progress.total)) -// Formats the `Progress` simply bu using the value of `Progress#extra`. +// Formats the `Progress` as percentage. +export let PERCENTAGE_FORMATTER = wrap(progress => + (progress.current / progress.total * 100).toFixed(1) + '%') + +// Formats the `Progress` simply by using the value of `Progress#extra`. export let EXTRA_FORMATTER = wrap(progress => progress.extra + '') diff --git a/src/scintillator/context.js b/src/scintillator/context.js index dba8e4fe4..96d14e707 100644 --- a/src/scintillator/context.js +++ b/src/scintillator/context.js @@ -3,9 +3,9 @@ import PIXI from 'pixi.js' function createRenderer(w, h) { if (navigator.userAgent.match(/Gecko\//)) { - return new PIXI.autoDetectRenderer(w, h) + return new PIXI.autoDetectRenderer(w, h, { transparent: true }) } else { - return new PIXI.CanvasRenderer(w, h) + return new PIXI.CanvasRenderer(w, h, { transparent: true }) } } diff --git a/src/scintillator/loader.js b/src/scintillator/loader.js index 732f5d1be..f54a1e32f 100644 --- a/src/scintillator/loader.js +++ b/src/scintillator/loader.js @@ -6,7 +6,7 @@ import $ from 'jquery' import url from 'url' import co from 'co' import PIXI from 'pixi.js' -import * as ProgressUtils from 'bemuse/progress/utils' +import { PERCENTAGE_FORMATTER } from 'bemuse/progress/formatters' import Resources from './resources' import Compiler from './compiler' @@ -32,9 +32,7 @@ export function load(xmlPath, progress) { } // load all images + progress reporting - let onload = ProgressUtils.fixed(1 + paths.size, progress) - onload() - yield loadResources(resources, onload) + yield loadResources(resources, progress) // compile the skin log('compiling') @@ -50,16 +48,27 @@ function loadXml(xmlUrl) { .then(xml => $(xml.documentElement)) } -function loadResources(resources, onprogress) { +function loadResources(resources, progress) { log('loading resources') return new Promise(function(resolve) { if (resources.urls.length === 0) return resolve() - let loader = new PIXI.AssetLoader(resources.urls) - loader.on('onComplete', function() { + let loader = new PIXI.loaders.Loader() + for (let url of resources.urls) { + loader.add(url, url) + } + loader.once('complete', function() { log('resources finished loading') resolve() }) - if (onprogress) loader.on('onProgress', onprogress) + if (progress) { + progress.formatter = PERCENTAGE_FORMATTER + loader.once('complete', function() { + progress.report(100, 100) + }) + loader.on('progress', function() { + progress.report(loader.progress, 100) + }) + } loader.load() }) } diff --git a/src/scintillator/nodes/concerns/display-object.js b/src/scintillator/nodes/concerns/display-object.js index 72ce85ad1..8e4fd7cd5 100644 --- a/src/scintillator/nodes/concerns/display-object.js +++ b/src/scintillator/nodes/concerns/display-object.js @@ -57,8 +57,8 @@ export class DisplayObject extends SkinNode { } function parseBlendMode(text) { - if (text === 'normal') return PIXI.blendModes.NORMAL - if (text === 'screen') return PIXI.blendModes.SCREEN + if (text === 'normal') return PIXI.BLEND_MODES.NORMAL + if (text === 'screen') return PIXI.BLEND_MODES.SCREEN throw new Error('Invalid blend mode: ' + text) } diff --git a/src/scintillator/nodes/group.js b/src/scintillator/nodes/group.js index 42065efd6..4230d341c 100644 --- a/src/scintillator/nodes/group.js +++ b/src/scintillator/nodes/group.js @@ -33,7 +33,7 @@ export class GroupNode extends SkinNode { if (maskFrame) this.mask = new Mask(maskFrame) } instantiate(context, container) { - let object = new PIXI.DisplayObjectContainer() + let object = new PIXI.Container() let concerns = [ this.display ] if (this.mask) { concerns.push(this.mask) diff --git a/src/scintillator/nodes/if.js b/src/scintillator/nodes/if.js index 646e8e2f5..2844bc244 100644 --- a/src/scintillator/nodes/if.js +++ b/src/scintillator/nodes/if.js @@ -17,7 +17,7 @@ export class IfNode extends SkinNode { this.value = String($el.attr('value')) } instantiate(context, container) { - let object = new PIXI.DisplayObjectContainer() + let object = new PIXI.Container() let expr = this.key let value = this.value let childNode = this.child diff --git a/src/scintillator/nodes/object.js b/src/scintillator/nodes/object.js index e55391b55..2bb753b41 100644 --- a/src/scintillator/nodes/object.js +++ b/src/scintillator/nodes/object.js @@ -75,7 +75,7 @@ export class ObjectNode extends SkinNode { this.key = new Expression($el.attr('key')) } instantiate(context, container) { - let batch = new PIXI.SpriteBatch() + let batch = new PIXI.ParticleContainer() let manager = new ChildManager(this.key, this.children[0], this.pool) return new Instance({ context: context, diff --git a/src/scintillator/nodes/sprite.js b/src/scintillator/nodes/sprite.js index a33a0b2e6..1f444c184 100644 --- a/src/scintillator/nodes/sprite.js +++ b/src/scintillator/nodes/sprite.js @@ -24,7 +24,7 @@ export class SpriteNode extends SkinNode { } getTexture() { if (this._texture) return this._texture - let scaleMode = PIXI.scaleModes.NEAREST + let scaleMode = PIXI.SCALE_MODES.NEAREST let base = PIXI.BaseTexture.fromImage(this.url, undefined, scaleMode) let texture = new PIXI.Texture(base, this.frame) this._texture = texture diff --git a/src/scintillator/nodes/text.js b/src/scintillator/nodes/text.js index cf0160ab0..3396bc743 100644 --- a/src/scintillator/nodes/text.js +++ b/src/scintillator/nodes/text.js @@ -30,9 +30,9 @@ export class TextNode extends SkinNode { fill: this.fill, }) } else { - text = new PIXI.BitmapText(this.text, { font: this.font }) + text = new PIXI.extras.BitmapText(this.text, { font: this.font }) } - let object = new PIXI.DisplayObjectContainer() + let object = new PIXI.Container() object.addChild(text) return new Instance({ context: context, @@ -43,7 +43,7 @@ export class TextNode extends SkinNode { [ this.data, v => { - text.setText(this.text.replace('%s', v)) + text.text = this.text.replace('%s', v) text.updateText() text.x = text.width * -this.align }, From 058382701afc60487124cd31d95989f5a8a4b2e9 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 3 Aug 2015 20:35:16 +0700 Subject: [PATCH 2/4] feat(~): add support for 5keys --- package.json | 3 +- spec/game/notechart_spec.js | 45 ++++++++++++++++++++++ src/app/stores/music-select-store.js | 6 ++- src/app/ui/music-chart-selector-item.jsx | 1 + src/app/ui/music-chart-selector-item.scss | 47 +++++++++++------------ src/game/notechart.js | 42 ++++++++++++++++++-- 6 files changed, 112 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 4a14c437c..0c6006ded 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "dependencies": { "audio-context": "^0.1.0", "baconjs": "^0.7.53", - "bemuse-indexer": "^1.1.2", + "bemuse-indexer": "^1.3.0", "bluebird": "^2.9.10", "bms": "^0.11.1", "bytes": "^1.0.0", @@ -117,6 +117,7 @@ "react-fa": "^3.2.0", "react-overlay-popup": "^1.0.2", "remarkable": "^1.6.0", + "require-sdk": "0.0.2", "screenfull": "^2.0.0", "serviceworker-cache-polyfill": "^3.0.0", "throat": "^2.0.2", diff --git a/spec/game/notechart_spec.js b/spec/game/notechart_spec.js index c69c61f8d..6ec2c3821 100644 --- a/spec/game/notechart_spec.js +++ b/spec/game/notechart_spec.js @@ -26,6 +26,51 @@ describe('Notechart', function() { }) }) + describe('5K', function() { + const src = ` + #00116:01 + #00111:01 + #00112:01 + #00113:01 + #00114:01 + #00115:01 + ` + function byColumn(column) { + return note => note.column === column + } + describe('scratch left', function() { + it('should keep notes intact', function() { + var subject = notechart(src, { scratch: 'left' }) + expect(subject.notes).to.have.length(6) + void expect(subject.notes.filter(byColumn('1'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('2'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('3'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('4'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('5'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('6'))).to.be.empty + void expect(subject.notes.filter(byColumn('7'))).to.be.empty + }) + }) + describe('scratch off', function() { + it('should shift columns by 1', function() { + var subject = notechart(src, { scratch: 'off' }) + expect(subject.notes).to.have.length(5) + void expect(subject.notes.filter(byColumn('6'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('1'))).to.be.empty + }) + }) + describe('scratch right', function() { + it('should shift columns by 2', function() { + var subject = notechart(src, { scratch: 'right' }) + expect(subject.notes).to.have.length(6) + void expect(subject.notes.filter(byColumn('6'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('7'))).not.to.be.empty + void expect(subject.notes.filter(byColumn('1'))).to.be.empty + void expect(subject.notes.filter(byColumn('2'))).to.be.empty + }) + }) + }) + describe('#samples', function() { it('should return an array of all used samples', function() { var subject = notechart('#WAV0X wow.wav\n#00101:0x0x') diff --git a/src/app/stores/music-select-store.js b/src/app/stores/music-select-store.js index f7baa93ad..0a0cd3d2d 100644 --- a/src/app/stores/music-select-store.js +++ b/src/app/stores/music-select-store.js @@ -15,6 +15,8 @@ export function MusicSelectStoreFactory(CollectionStore) { const $unofficial = CollectionStore.map(state => state.unofficial) const $loading = $collection.map(({ loading }) => loading) + const playableChart = chart => chart.keys === '7K' || chart.keys === '5K' + const $grouping = Bacon.constant([ { title: 'Custom Song', criteria: song => song.custom }, { title: 'Tutorial', criteria: song => song.tutorial }, @@ -34,7 +36,7 @@ export function MusicSelectStoreFactory(CollectionStore) { .sortByAll([ song => { return _(song.charts) - .filter({ keys: '7K' }) + .filter(playableChart) .filter(chart => chart.info.difficulty < 5) .filter(chart => chart.info.level > 0) .map(chart => chart.info.level) @@ -65,7 +67,7 @@ export function MusicSelectStoreFactory(CollectionStore) { const $charts = $song.map(song => (song && song.charts) || [ ]) const $visibleCharts = $charts.map(charts => _(charts) - .filter({ keys: '7K' }) + .filter(playableChart) .sortByAll( chart => chart.info.difficulty >= 5 ? 1 : 0, chart => chart.info.level diff --git a/src/app/ui/music-chart-selector-item.jsx b/src/app/ui/music-chart-selector-item.jsx index acd81cc4c..d5f5309fb 100644 --- a/src/app/ui/music-chart-selector-item.jsx +++ b/src/app/ui/music-chart-selector-item.jsx @@ -12,6 +12,7 @@ export default React.createClass({ 'is-active': this.props.isSelected, 'is-tutorial': this.props.isTutorial, 'is-insane': this.props.chart.info.difficulty >= 5, + 'is-5keys': this.props.chart.keys === '5K', }) return
  • { if (note.column && note.column.column === 'SC') { - note.column = null + return Object.assign({ }, note, { column: null }) + } else { + return note } + }) + } + if (keys === '5K') { + const columnsToShift = ['1', '2', '3', '4', '5', '6', '7'] + const shiftNote = amount => note => { + if (note.column) { + let index = columnsToShift.indexOf(note.column.column) + if (index > -1) { + let newIndex = index + amount + invariant( + newIndex < columnsToShift.length, + 'Weird. Columns must not shift beyond available column' + ) + let newColumn = columnsToShift[newIndex] + return Object.assign({ }, note, { + column: Object.assign({ }, note.column, { column: newColumn }) + }) + } + } + return note + } + if (playerOptions.scratch === 'off') { + chain = chain.map(shiftNote(1)) + } else if (playerOptions.scratch === 'right') { + chain = chain.map(shiftNote(2)) } } + return chain.value() } _generatePlayableNotesFromBMS(bmsNotes) { From 01753e5853b5e06da60f6151e4ea31fafc1bdfa0 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 4 Aug 2015 23:30:53 +0700 Subject: [PATCH 3/4] chore(~): update outdated dependencies --- package.json | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 0c6006ded..7a0425398 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,14 @@ "description": "BEAT☆MUSIC☆SEQUENCE, a web-based music game of the future", "main": "index.js", "scripts": { - "code-review": "gulp code-review", + "build": "gulp build", "ci:code-review": "npm run code-review; ./bin/upload-code-review", - "test": "bash -c \"BEMUSE_COV=true gulp build && BEMUSE_COV=true gulp test:exit\"", + "code-review": "gulp code-review", "lint": "gulp lint", + "pre-commit": "gulp pre-commit", "start": "gulp server", - "build": "gulp build", - "travis": "gulp travis", - "pre-commit": "gulp pre-commit" + "test": "bash -c \"BEMUSE_COV=true gulp build && BEMUSE_COV=true gulp test:exit\"", + "travis": "gulp travis" }, "repository": { "type": "git", @@ -28,29 +28,29 @@ "homepage": "https://github.com/spacetme/bemuse", "devDependencies": { "artstep": "^5555.0.0", - "autoprefixer-loader": "^1.2.0", - "babel-core": "^4.3.0", - "babel-eslint": "^3.0.1", - "babel-loader": "^4.0.0", + "autoprefixer-loader": "^2.0.0", + "babel-core": "^5.8.20", + "babel-eslint": "^4.0.5", + "babel-loader": "^5.3.2", "body-parser": "^1.10.0", "brfs": "^1.4.0", "browser-launcher": "^1.0.0", "bundle-loader": "^0.5.2", - "chai": "^2.2.0", - "chai-as-promised": "^4.1.1", - "codeclimate-test-reporter": "0.0.4", + "chai": "^3.2.0", + "chai-as-promised": "^5.1.0", + "codeclimate-test-reporter": "^0.1.0", "connect": "^3.3.3", "coveralls": "^2.11.2", - "css-loader": "^0.9.0", + "css-loader": "^0.15.6", "dotenv": "^1.2.0", - "eslint": "^0.19.0", - "eslint-plugin-react": "^2.1.1", + "eslint": "^1.0.0", + "eslint-plugin-react": "^3.2.0", "exports-loader": "^0.6.2", "express": "^4.10.6", "file-loader": "^0.8.1", - "glob": "^4.3.2", + "glob": "^5.0.14", "gulp": "^3.8.10", - "gulp-eslint": "^0.9.0", + "gulp-eslint": "^1.0.0", "gulp-gh-pages": "git://github.com/dtinth/gulp-gh-pages", "gulp-mocha": "^2.0.1", "gulp-util": "^3.0.1", @@ -66,11 +66,10 @@ "mocha": "^2.1.0", "node-env": "^0.1.6", "node-notifier": "^4.0.3", - "node-sass": "^2.1.1", + "node-sass": "^3.2.0", "node-ssi": "^0.3.0", "pegjs-loader": "^0.1.1", - "ractive-loader": "^0.5.6", - "sass-loader": "^0.4.2", + "sass-loader": "^1.0.4", "script-loader": "^0.6.1", "selenium-webdriver": "^2.45.1", "serviceworker-loader": "^0.1.0", @@ -81,21 +80,20 @@ "transform-loader": "^0.2.2", "url-loader": "^0.5.5", "val-loader": "^0.5.0", - "web-audio-test-api": "^0.2.1", + "web-audio-test-api": "^0.3.6", "webpack": "^1.4.13", "webpack-dev-server": "^1.6.6", - "worker-loader": "^0.6.0", - "yadda": "^0.11.5" + "worker-loader": "^0.6.0" }, "dependencies": { "audio-context": "^0.1.0", "baconjs": "^0.7.53", "bemuse-indexer": "^1.3.0", "bluebird": "^2.9.10", - "bms": "^0.11.1", - "bytes": "^1.0.0", + "bms": "^0.12.0", + "bytes": "^2.1.0", "chance": "^0.7.3", - "classnames": "^1.2.0", + "classnames": "^2.1.3", "co": "^4.3.1", "data-structure": "^1.2.0", "debug": "^2.1.1", From 67e08335c9a8b451987a5d4181cd6d8199844500 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 4 Aug 2015 23:40:48 +0700 Subject: [PATCH 4/4] fix(ProgressFormatters): fix formatter specs --- spec/progress/formatters_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/progress/formatters_spec.js b/spec/progress/formatters_spec.js index 931b01b18..e3e31a245 100644 --- a/spec/progress/formatters_spec.js +++ b/spec/progress/formatters_spec.js @@ -12,7 +12,7 @@ describe('ProgressFormatters', function() { it('should format as human readable size', function() { let p = new Progress() p.report(1, 1024) - expect(Formatters.BYTES_FORMATTER(p)).to.equal('1b / 1kb') + expect(Formatters.BYTES_FORMATTER(p)).to.equal('1B / 1kB') }) })