1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20'use strict'; 21 22const fs = require('fs'); 23const path =require('path'); 24 25const chai = require('chai'); 26const sinon = require('sinon'); 27const sinonChai = require('sinon-chai'); 28const expect = chai.expect; 29chai.use(sinonChai); 30 31const Base64 = require('js-base64').Base64; 32const SourceMap = require('source-map'); 33 34function getActualString(name) { 35 const filepath = path.resolve(__dirname, 'actual', `${name}.js`); 36 const result = fs.readFileSync(filepath, 'utf-8'); 37 return result.toString(); 38} 39 40function getExpectJSON(name) { 41 const filepath = path.resolve(__dirname, 'expect', `${name}.js`); 42 const result = fs.readFileSync(filepath, 'utf-8'); 43 return JSON.parse(result.toString()); 44} 45 46function stringifyActual(json) { 47 return JSON.stringify(json, function(key, value) { 48 if (typeof value === 'function') { 49 value = value.toString(); 50 } 51 return value; 52 }, ' '); 53} 54 55function extractMap(actualStr) { 56 const mapStr = actualStr.match(/\/\/\# sourceMappingURL=data:application\/json;charset=utf-8;base64,([0-9a-zA-Z=+\/]+)/) 57 if (mapStr) { 58 return JSON.parse(Base64.decode(mapStr[1])); 59 } 60} 61 62describe('build', () => { 63 let __weex_define__; 64 let __weex_bootstrap__; 65 let components; 66 let requireStub; 67 let bootstrapStub; 68 69 function expectActual(name) { 70 const actualStr = getActualString(name); 71 const fn = new Function('__weex_define__', '__weex_bootstrap__', actualStr); 72 fn(__weex_define__, __weex_bootstrap__); 73 74 // const filepath = path.resolve(__dirname, 'expect', `${name}.js`); 75 // fs.writeFileSync(filepath, stringifyActual(components), 'utf-8'); 76 77 const expectJSON = getExpectJSON(name); 78 expect(JSON.parse(stringifyActual(components))).eql(expectJSON); 79 expect(components).to.include.keys(__weex_bootstrap__.firstCall.args[0]); 80 81 return actualStr; 82 } 83 84 beforeEach(() => { 85 components = {}; 86 requireStub = sinon.stub(); 87 bootstrapStub = sinon.stub(); 88 89 __weex_define__ = function(componentName, deps, factory) { 90 if (components[componentName]) { 91 throw new Error(`${componentName} is defined repeatly`); 92 } 93 94 var __weex_require__ = requireStub; 95 var __weex_exports__ = {}; 96 var __weex_module__ = {exports : __weex_exports__} 97 98 factory(__weex_require__, __weex_exports__, __weex_module__) 99 components[componentName] = __weex_module__.exports 100 } 101 102 __weex_bootstrap__ = bootstrapStub; 103 104 }); 105 106 it('single template', () => { 107 expectActual('a'); 108 }); 109 110 it('template with style', () => { 111 expectActual('b'); 112 }); 113 114 it('template with style and script', () => { 115 expectActual('c'); 116 }); 117 118 it('template with single inline element', () => { 119 expectActual('d'); 120 }); 121 122 it('template with multiple inline elements', () => { 123 expectActual('e'); 124 }); 125 126 it('parted files specifed in src', () => { 127 expectActual('f'); 128 }); 129 130 it('component by requiring src and specifing alias', () => { 131 expectActual('g'); 132 expect(requireStub.callCount).eql(0); 133 }); 134 135 it('component under same folder', () => { 136 expectActual('h'); 137 }); 138 139 it('template with config and data', () => { 140 expectActual('i'); 141 expect(bootstrapStub.firstCall.args[1]).is.not.undefined; 142 expect(bootstrapStub.firstCall.args[2]).is.not.undefined; 143 }); 144 145 it('template and use weex module', () => { 146 expectActual('j'); 147 expect(requireStub.callCount).eql(1); 148 expect(requireStub.firstCall.args).eql(['@weex-module/modal']); 149 }); 150 151 it('template by using custom language', () => { 152 expectActual('k'); 153 expect(requireStub.callCount).eql(1); 154 expect(requireStub.firstCall.args).eql(['@weex-module/modal']); 155 }); 156 157 it('template and require commonjs module', () => { 158 expectActual('l'); 159 expect(requireStub.callCount).eql(1); 160 expect(requireStub.firstCall.args).eql(['@weex-module/modal']); 161 }); 162 163 it('template and use weex module in commonjs module', () => { 164 expectActual('m'); 165 expect(requireStub.callCount).eql(1); 166 expect(requireStub.firstCall.args).eql(['@weex-module/modal']); 167 }); 168 169 it.skip('template with sourcemap', () => { 170 const actualStr = expectActual('n'); 171 const map = extractMap(actualStr); 172 const smc = new SourceMap.SourceMapConsumer(map); 173 174 // new Array(276).fill(0).forEach((n, i) => { 175 // i = i + 1 176 // const original = smc.originalPositionFor({ 177 // line: i, 178 // column: 0 179 // }) 180 // if (original.source) { 181 // console.log(i, original.line, original.source) 182 // } 183 // }) 184 }); 185 186 it('weex examples', () => { 187 expectActual('o'); 188 }); 189}); 190