From 21b0aa0ce0d1eca031f27497503c9888d5c51653 Mon Sep 17 00:00:00 2001 From: Ann Yuan Date: Fri, 25 Jan 2019 08:55:58 -0500 Subject: [PATCH 1/4] change spies --- src/models_test.ts | 238 ++++++++++++++++++++++++++++----------------- 1 file changed, 147 insertions(+), 91 deletions(-) diff --git a/src/models_test.ts b/src/models_test.ts index ecf82ea63..32c98d28f 100644 --- a/src/models_test.ts +++ b/src/models_test.ts @@ -8,19 +8,21 @@ * ============================================================================= */ -import {DataType, io, ones, randomNormal, Scalar, scalar, serialization, sum, Tensor, tensor1d, tensor2d, zeros, tensor3d} from '@tensorflow/tfjs-core'; +import {DataType, io, ones, randomNormal, Scalar, scalar, serialization, sum, Tensor, tensor1d, tensor2d, tensor3d, zeros} from '@tensorflow/tfjs-core'; import {ConfigDict} from '@tensorflow/tfjs-core/dist/serialization'; import {Model} from './engine/training'; import * as tfl from './index'; +import {PyJsonDict} from './keras_format/types'; import {Reshape} from './layers/core'; import {deserialize} from './layers/serialization'; import {loadModelInternal, ModelAndWeightsConfig, modelFromJSON} from './models'; import {convertPythonicToTs, convertTsToPythonic} from './utils/serialization_utils'; import {describeMathCPU, describeMathCPUAndGPU, expectTensorsClose} from './utils/test_utils'; import {version as layersVersion} from './version'; -import {PyJsonDict} from './keras_format/types'; +const OCTET_STREAM_TYPE = 'application/octet-stream'; +const JSON_TYPE = 'application/json'; describeMathCPU('Nested model topology', () => { it('Nested Sequential model: Sequential as first layer', done => { @@ -215,7 +217,8 @@ describeMathCPU('Nested model topology', () => { const outerModel = tfl.sequential({ layers: [ innerModel, - tfl.layers.dense({units: 1, kernelInitializer: 'zeros', useBias: false}) + tfl.layers.dense( + {units: 1, kernelInitializer: 'zeros', useBias: false}) ] }); @@ -546,8 +549,12 @@ describeMathCPU('loadModel from URL', () => { (fileBufferMap: {[filename: string]: Float32Array|Int32Array|ArrayBuffer}) => { spyOn(window, 'fetch').and.callFake((path: string) => { - return new Response(fileBufferMap[path]); - }); + return new Promise((res, rej) => { + res(new Response( + fileBufferMap[path], + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + }); + }) }; const isModelConfigNestedValues = [false, true]; @@ -623,20 +630,28 @@ describeMathCPU('loadModel from URL', () => { [{'name': `dense_6/bias`, 'dtype': 'float32', 'shape': [32]}], } ]; + spyOn(window, 'fetch').and.callFake((path: string) => { - if (path === 'model/model.json') { - return new Response(JSON.stringify({ - modelTopology, - weightsManifest, - })); - } else if (path === 'model/weight_0') { - return new Response( - ones([32, 32], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_1') { - return new Response(zeros([32], 'float32').dataSync() as Float32Array); - } else { - throw new Error(`Invalid path: ${path}`); - } + return new Promise((res, rej) => { + if (path === 'model/model.json') { + res(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + res(new Response( + ones([32, 32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + res(new Response( + zeros([32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + rej(new Error(`Invalid path: ${path}`)); + } + }); }); const model = await loadModelInternal('model/model.json'); @@ -681,25 +696,34 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - if (path === 'model/model.json') { - return new Response(JSON.stringify({ - modelTopology, - weightsManifest, - })); - } else if (path === 'model/weight_0') { - return new Response( - ones([10, 2], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_1') { - return new Response( - zeros([2], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_2') { - return new Response( - zeros([2, 1], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_3') { - return new Response(ones([1], 'float32').dataSync() as Float32Array); - } else { - throw new Error(`Invalid path: ${path}`); - } + return new Promise((res, rej) => { + if (path === 'model/model.json') { + res(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + res(new Response( + ones([10, 2], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + res(new Response( + zeros([2], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_2') { + res(new Response( + zeros([2, 1], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_3') { + res(new Response( + ones([1], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + rej(new Error(`Invalid path: ${path}`)); + } + }); }); const model = await loadModelInternal('model/model.json'); @@ -741,24 +765,34 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - if (path === 'model/model.json') { - return new Response(JSON.stringify({ - modelTopology, - weightsManifest, - })); - } else if (path === 'model/weight_0') { - return new Response( - ones([10, 2], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_1') { - return new Response(zeros([2], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_2') { - return new Response( - zeros([2, 1], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_3') { - return new Response(ones([1], 'float32').dataSync() as Float32Array); - } else { - throw new Error(`Invalid path: ${path}`); - } + return new Promise((res, rej) => { + if (path === 'model/model.json') { + res(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + res(new Response( + ones([10, 2], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + res(new Response( + zeros([2], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_2') { + res(new Response( + zeros([2, 1], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_3') { + res(new Response( + ones([1], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + rej(new Error(`Invalid path: ${path}`)); + } + }); }); const model = await loadModelInternal('model/model.json'); @@ -803,20 +837,26 @@ describeMathCPU('loadModel from URL', () => { requestHeaders.push(requestInit.headers); requestCredentials.push(requestInit.credentials); } - if (path === 'model/model.json') { - return new Response(JSON.stringify({ - modelTopology, - weightsManifest, - })); - } else if (path === 'model/weight_0') { - return new Response( - ones([32, 32], 'float32').dataSync() as Float32Array); - } else if (path === 'model/weight_1') { - return new Response( - zeros([32], 'float32').dataSync() as Float32Array); - } else { - throw new Error(`Invalid path: ${path}`); - } + return new Promise((res, rej) => { + if (path === 'model/model.json') { + res(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + res(new Response( + ones([32, 32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + res(new Response( + zeros([32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + rej(new Error(`Invalid path: ${path}`)); + } + }); }); const model = @@ -837,8 +877,14 @@ describeMathCPU('loadModel from URL', () => { // Verify that the headers and credentials are sent via // `fetch` properly. expect(requestHeaders).toEqual([ - {'header_key_1': 'header_value_1'}, {'header_key_1': 'header_value_1'}, - {'header_key_1': 'header_value_1'} + {'header_key_1': 'header_value_1', 'Accept': 'application/json'}, { + 'header_key_1': 'header_value_1', + 'Accept': 'application/octet-stream' + }, + { + 'header_key_1': 'header_value_1', + 'Accept': 'application/octet-stream' + } ]); expect(requestCredentials).toEqual(['include', 'include', 'include']); }); @@ -852,9 +898,11 @@ describeMathCPU('loadModel from URL', () => { const weightsManifest: io.WeightsManifestConfig = [ { 'paths': ['weight_0'], - 'weights': [ - {'name': `dense_6/kernel`, 'dtype': 'float32', 'shape': [32, 32]} - ], + 'weights': [{ + 'name': `dense_6/kernel`, + 'dtype': 'float32', + 'shape': [32, 32] + }], }, { 'paths': ['weight_1'], @@ -863,20 +911,26 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - if (path === `${protocol}localhost:8888/models/model.json`) { - return new Response(JSON.stringify({ - modelTopology, - weightsManifest, - })); - } else if (path === `${protocol}localhost:8888/models/weight_0`) { - return new Response( - ones([32, 32], 'float32').dataSync() as Float32Array); - } else if (path === `${protocol}localhost:8888/models/weight_1`) { - return new Response( - zeros([32], 'float32').dataSync() as Float32Array); - } else { - throw new Error(`Invalid path: ${path}`); - } + return new Promise((res, rej) => { + if (path === `${protocol}localhost:8888/models/model.json`) { + res(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === `${protocol}localhost:8888/models/weight_0`) { + res(new Response( + ones([32, 32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === `${protocol}localhost:8888/models/weight_1`) { + res(new Response( + zeros([32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + rej(new Error(`Invalid path: ${path}`)); + } + }); }); const model = await loadModelInternal( @@ -937,9 +991,11 @@ describeMathCPU('loadModel from URL', () => { }, { 'paths': ['weight_1'], - 'weights': [ - {'name': `${denseLayerName}/bias`, 'dtype': 'float32', 'shape': [32]} - ], + 'weights': [{ + 'name': `${denseLayerName}/bias`, + 'dtype': 'float32', + 'shape': [32] + }], } ]; // JSON.parse and stringify to deep copy fakeSequentialModel. From 3e926c49fd720633bcaedf8b58dd7503dff9429a Mon Sep 17 00:00:00 2001 From: Ann Yuan Date: Fri, 25 Jan 2019 09:04:33 -0500 Subject: [PATCH 2/4] lint --- src/models_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models_test.ts b/src/models_test.ts index 32c98d28f..0a8d3efb7 100644 --- a/src/models_test.ts +++ b/src/models_test.ts @@ -554,7 +554,7 @@ describeMathCPU('loadModel from URL', () => { fileBufferMap[path], {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); }); - }) + }); }; const isModelConfigNestedValues = [false, true]; From 017c0fe790195616c9db97d937d04763a3baea6b Mon Sep 17 00:00:00 2001 From: Ann Yuan Date: Fri, 25 Jan 2019 10:11:32 -0500 Subject: [PATCH 3/4] fix test --- src/models_test.ts | 229 ++++++++++++++++++++++++--------------------- 1 file changed, 122 insertions(+), 107 deletions(-) diff --git a/src/models_test.ts b/src/models_test.ts index 0a8d3efb7..cc32c1ea9 100644 --- a/src/models_test.ts +++ b/src/models_test.ts @@ -548,13 +548,12 @@ describeMathCPU('loadModel from URL', () => { const setupFakeWeightFiles = (fileBufferMap: {[filename: string]: Float32Array|Int32Array|ArrayBuffer}) => { - spyOn(window, 'fetch').and.callFake((path: string) => { - return new Promise((res, rej) => { - res(new Response( - fileBufferMap[path], - {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); - }); - }); + spyOn(window, 'fetch') + .and.callFake( + (path: string) => new Promise( + resolve => {resolve(new Response( + fileBufferMap[path], + {'headers': {'Content-Type': OCTET_STREAM_TYPE}}))})); }; const isModelConfigNestedValues = [false, true]; @@ -632,24 +631,24 @@ describeMathCPU('loadModel from URL', () => { ]; spyOn(window, 'fetch').and.callFake((path: string) => { - return new Promise((res, rej) => { + return new Promise((resolve, reject) => { if (path === 'model/model.json') { - res(new Response( + resolve(new Response( JSON.stringify({ modelTopology, weightsManifest, }), {'headers': {'Content-Type': JSON_TYPE}})); } else if (path === 'model/weight_0') { - res(new Response( + resolve(new Response( ones([32, 32], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_1') { - res(new Response( + resolve(new Response( zeros([32], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else { - rej(new Error(`Invalid path: ${path}`)); + reject(new Error(`Invalid path: ${path}`)); } }); }); @@ -696,32 +695,32 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - return new Promise((res, rej) => { + return new Promise((resolve, reject) => { if (path === 'model/model.json') { - res(new Response( + resolve(new Response( JSON.stringify({ modelTopology, weightsManifest, }), {'headers': {'Content-Type': JSON_TYPE}})); } else if (path === 'model/weight_0') { - res(new Response( + resolve(new Response( ones([10, 2], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_1') { - res(new Response( + resolve(new Response( zeros([2], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_2') { - res(new Response( + resolve(new Response( zeros([2, 1], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_3') { - res(new Response( + resolve(new Response( ones([1], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else { - rej(new Error(`Invalid path: ${path}`)); + reject(new Error(`Invalid path: ${path}`)); } }); }); @@ -765,32 +764,32 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - return new Promise((res, rej) => { + return new Promise((resolve, reject) => { if (path === 'model/model.json') { - res(new Response( + resolve(new Response( JSON.stringify({ modelTopology, weightsManifest, }), {'headers': {'Content-Type': JSON_TYPE}})); } else if (path === 'model/weight_0') { - res(new Response( + resolve(new Response( ones([10, 2], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_1') { - res(new Response( + resolve(new Response( zeros([2], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_2') { - res(new Response( + resolve(new Response( zeros([2, 1], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === 'model/weight_3') { - res(new Response( + resolve(new Response( ones([1], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else { - rej(new Error(`Invalid path: ${path}`)); + reject(new Error(`Invalid path: ${path}`)); } }); }); @@ -811,83 +810,99 @@ describeMathCPU('loadModel from URL', () => { }); - it('load topology and weights with browserHTTPRequest with requestInit', - async () => { - const modelTopology = - JSON.parse(JSON.stringify(fakeSequentialModel)).modelTopology; - const weightsManifest: io.WeightsManifestConfig = [ - { - 'paths': ['weight_0'], - 'weights': [ - {'name': `dense_6/kernel`, 'dtype': 'float32', 'shape': [32, 32]} - ], - }, - { - 'paths': ['weight_1'], - 'weights': - [{'name': `dense_6/bias`, 'dtype': 'float32', 'shape': [32]}], - } - ]; - - const requestHeaders: Array<{}> = []; - const requestCredentials: string[] = []; - spyOn(window, 'fetch') - .and.callFake((path: string, requestInit?: RequestInit) => { - if (requestInit != null) { - requestHeaders.push(requestInit.headers); - requestCredentials.push(requestInit.credentials); - } - return new Promise((res, rej) => { - if (path === 'model/model.json') { - res(new Response( - JSON.stringify({ - modelTopology, - weightsManifest, - }), - {'headers': {'Content-Type': JSON_TYPE}})); - } else if (path === 'model/weight_0') { - res(new Response( - ones([32, 32], 'float32').dataSync() as Float32Array, - {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); - } else if (path === 'model/weight_1') { - res(new Response( - zeros([32], 'float32').dataSync() as Float32Array, - {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); - } else { - rej(new Error(`Invalid path: ${path}`)); - } - }); - }); + fit('load topology and weights with browserHTTPRequest with requestInit', + async () => { + const modelTopology = + JSON.parse(JSON.stringify(fakeSequentialModel)).modelTopology; + const weightsManifest: io.WeightsManifestConfig = [ + { + 'paths': ['weight_0'], + 'weights': [{ + 'name': `dense_6/kernel`, + 'dtype': 'float32', + 'shape': [32, 32] + }], + }, + { + 'paths': ['weight_1'], + 'weights': + [{'name': `dense_6/bias`, 'dtype': 'float32', 'shape': [32]}], + } + ]; - const model = - await loadModelInternal(io.browserHTTPRequest('model/model.json', { - headers: {'header_key_1': 'header_value_1'}, - credentials: 'include', - })); - expect(model.layers.length).toEqual(2); - expect(model.inputs.length).toEqual(1); - expect(model.inputs[0].shape).toEqual([null, 32]); - expect(model.outputs.length).toEqual(1); - expect(model.outputs[0].shape).toEqual([null, 32]); - const weightValues = model.getWeights(); - expect(weightValues.length).toEqual(2); - expectTensorsClose(weightValues[0], ones([32, 32])); - expectTensorsClose(weightValues[1], zeros([32])); - - // Verify that the headers and credentials are sent via - // `fetch` properly. - expect(requestHeaders).toEqual([ - {'header_key_1': 'header_value_1', 'Accept': 'application/json'}, { - 'header_key_1': 'header_value_1', - 'Accept': 'application/octet-stream' - }, - { - 'header_key_1': 'header_value_1', - 'Accept': 'application/octet-stream' - } - ]); - expect(requestCredentials).toEqual(['include', 'include', 'include']); - }); + const requestHeaders: Array<{[key: string]: string | {}}> = []; + const requestCredentials: string[] = []; + spyOn(window, 'fetch') + .and.callFake((path: string, requestInit?: RequestInit) => { + if (requestInit != null) { + requestHeaders.push(requestInit.headers as {}); + requestCredentials.push(requestInit.credentials); + } + return new Promise((resolve, reject) => { + if (path === 'model/model.json') { + resolve(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + resolve(new Response( + ones([32, 32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + resolve(new Response( + zeros([32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + reject(new Error(`Invalid path: ${path}`)); + } + }); + }); + + const model = + await loadModelInternal(io.browserHTTPRequest('model/model.json', { + headers: {'header_key_1': 'header_value_1'}, + credentials: 'include', + })); + expect(model.layers.length).toEqual(2); + expect(model.inputs.length).toEqual(1); + expect(model.inputs[0].shape).toEqual([null, 32]); + expect(model.outputs.length).toEqual(1); + expect(model.outputs[0].shape).toEqual([null, 32]); + const weightValues = model.getWeights(); + expect(weightValues.length).toEqual(2); + expectTensorsClose(weightValues[0], ones([32, 32])); + expectTensorsClose(weightValues[1], zeros([32])); + + // Verify that the headers and credentials are sent via + // `fetch` properly. + expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[0]['Accept']) { + expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/json' + })); + } + expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[1]['Accept']) { + expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/octet-stream' + })); + } + expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[2]['Accept']) { + expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/octet-stream' + })); + } + expect(requestCredentials).toEqual(['include', 'include', 'include']); + }); const httpProtocols = ['http://', 'https://']; for (const protocol of httpProtocols) { @@ -911,24 +926,24 @@ describeMathCPU('loadModel from URL', () => { } ]; spyOn(window, 'fetch').and.callFake((path: string) => { - return new Promise((res, rej) => { + return new Promise((resolve, reject) => { if (path === `${protocol}localhost:8888/models/model.json`) { - res(new Response( + resolve(new Response( JSON.stringify({ modelTopology, weightsManifest, }), {'headers': {'Content-Type': JSON_TYPE}})); } else if (path === `${protocol}localhost:8888/models/weight_0`) { - res(new Response( + resolve(new Response( ones([32, 32], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else if (path === `${protocol}localhost:8888/models/weight_1`) { - res(new Response( + resolve(new Response( zeros([32], 'float32').dataSync() as Float32Array, {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); } else { - rej(new Error(`Invalid path: ${path}`)); + reject(new Error(`Invalid path: ${path}`)); } }); }); From 1e7f2c3df51ad18e913948752487e463129af18d Mon Sep 17 00:00:00 2001 From: Ann Yuan Date: Fri, 25 Jan 2019 10:23:06 -0500 Subject: [PATCH 4/4] lint --- src/models_test.ts | 192 ++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 97 deletions(-) diff --git a/src/models_test.ts b/src/models_test.ts index cc32c1ea9..bb81c8650 100644 --- a/src/models_test.ts +++ b/src/models_test.ts @@ -549,11 +549,11 @@ describeMathCPU('loadModel from URL', () => { (fileBufferMap: {[filename: string]: Float32Array|Int32Array|ArrayBuffer}) => { spyOn(window, 'fetch') - .and.callFake( - (path: string) => new Promise( - resolve => {resolve(new Response( - fileBufferMap[path], - {'headers': {'Content-Type': OCTET_STREAM_TYPE}}))})); + .and.callFake((path: string) => new Promise(resolve => { + resolve(new Response(fileBufferMap[path], { + 'headers': {'Content-Type': OCTET_STREAM_TYPE} + })); + })); }; const isModelConfigNestedValues = [false, true]; @@ -810,99 +810,97 @@ describeMathCPU('loadModel from URL', () => { }); - fit('load topology and weights with browserHTTPRequest with requestInit', - async () => { - const modelTopology = - JSON.parse(JSON.stringify(fakeSequentialModel)).modelTopology; - const weightsManifest: io.WeightsManifestConfig = [ - { - 'paths': ['weight_0'], - 'weights': [{ - 'name': `dense_6/kernel`, - 'dtype': 'float32', - 'shape': [32, 32] - }], - }, - { - 'paths': ['weight_1'], - 'weights': - [{'name': `dense_6/bias`, 'dtype': 'float32', 'shape': [32]}], - } - ]; + it('load topology and weights with browserHTTPRequest with requestInit', + async () => { + const modelTopology = + JSON.parse(JSON.stringify(fakeSequentialModel)).modelTopology; + const weightsManifest: io.WeightsManifestConfig = [ + { + 'paths': ['weight_0'], + 'weights': [ + {'name': `dense_6/kernel`, 'dtype': 'float32', 'shape': [32, 32]} + ], + }, + { + 'paths': ['weight_1'], + 'weights': + [{'name': `dense_6/bias`, 'dtype': 'float32', 'shape': [32]}], + } + ]; - const requestHeaders: Array<{[key: string]: string | {}}> = []; - const requestCredentials: string[] = []; - spyOn(window, 'fetch') - .and.callFake((path: string, requestInit?: RequestInit) => { - if (requestInit != null) { - requestHeaders.push(requestInit.headers as {}); - requestCredentials.push(requestInit.credentials); - } - return new Promise((resolve, reject) => { - if (path === 'model/model.json') { - resolve(new Response( - JSON.stringify({ - modelTopology, - weightsManifest, - }), - {'headers': {'Content-Type': JSON_TYPE}})); - } else if (path === 'model/weight_0') { - resolve(new Response( - ones([32, 32], 'float32').dataSync() as Float32Array, - {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); - } else if (path === 'model/weight_1') { - resolve(new Response( - zeros([32], 'float32').dataSync() as Float32Array, - {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); - } else { - reject(new Error(`Invalid path: ${path}`)); - } - }); - }); - - const model = - await loadModelInternal(io.browserHTTPRequest('model/model.json', { - headers: {'header_key_1': 'header_value_1'}, - credentials: 'include', - })); - expect(model.layers.length).toEqual(2); - expect(model.inputs.length).toEqual(1); - expect(model.inputs[0].shape).toEqual([null, 32]); - expect(model.outputs.length).toEqual(1); - expect(model.outputs[0].shape).toEqual([null, 32]); - const weightValues = model.getWeights(); - expect(weightValues.length).toEqual(2); - expectTensorsClose(weightValues[0], ones([32, 32])); - expectTensorsClose(weightValues[1], zeros([32])); - - // Verify that the headers and credentials are sent via - // `fetch` properly. - expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ - 'header_key_1': 'header_value_1' - })); - if (requestHeaders[0]['Accept']) { - expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ - 'Accept': 'application/json' - })); - } - expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ - 'header_key_1': 'header_value_1' - })); - if (requestHeaders[1]['Accept']) { - expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ - 'Accept': 'application/octet-stream' - })); - } - expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ - 'header_key_1': 'header_value_1' - })); - if (requestHeaders[2]['Accept']) { - expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ - 'Accept': 'application/octet-stream' - })); - } - expect(requestCredentials).toEqual(['include', 'include', 'include']); - }); + const requestHeaders: Array<{[key: string]: string | {}}> = []; + const requestCredentials: string[] = []; + spyOn(window, 'fetch') + .and.callFake((path: string, requestInit?: RequestInit) => { + if (requestInit != null) { + requestHeaders.push(requestInit.headers as {}); + requestCredentials.push(requestInit.credentials); + } + return new Promise((resolve, reject) => { + if (path === 'model/model.json') { + resolve(new Response( + JSON.stringify({ + modelTopology, + weightsManifest, + }), + {'headers': {'Content-Type': JSON_TYPE}})); + } else if (path === 'model/weight_0') { + resolve(new Response( + ones([32, 32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else if (path === 'model/weight_1') { + resolve(new Response( + zeros([32], 'float32').dataSync() as Float32Array, + {'headers': {'Content-Type': OCTET_STREAM_TYPE}})); + } else { + reject(new Error(`Invalid path: ${path}`)); + } + }); + }); + + const model = + await loadModelInternal(io.browserHTTPRequest('model/model.json', { + headers: {'header_key_1': 'header_value_1'}, + credentials: 'include', + })); + expect(model.layers.length).toEqual(2); + expect(model.inputs.length).toEqual(1); + expect(model.inputs[0].shape).toEqual([null, 32]); + expect(model.outputs.length).toEqual(1); + expect(model.outputs[0].shape).toEqual([null, 32]); + const weightValues = model.getWeights(); + expect(weightValues.length).toEqual(2); + expectTensorsClose(weightValues[0], ones([32, 32])); + expectTensorsClose(weightValues[1], zeros([32])); + + // Verify that the headers and credentials are sent via + // `fetch` properly. + expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[0]['Accept']) { + expect(requestHeaders[0]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/json' + })); + } + expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[1]['Accept']) { + expect(requestHeaders[1]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/octet-stream' + })); + } + expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ + 'header_key_1': 'header_value_1' + })); + if (requestHeaders[2]['Accept']) { + expect(requestHeaders[2]).toEqual(jasmine.objectContaining({ + 'Accept': 'application/octet-stream' + })); + } + expect(requestCredentials).toEqual(['include', 'include', 'include']); + }); const httpProtocols = ['http://', 'https://']; for (const protocol of httpProtocols) {