Add most of components and prepare for V1 Release

This commit is contained in:
Fawad Mirzad
2021-02-13 16:09:48 +01:00
parent 1a5cf0b075
commit decca38b67
47 changed files with 2556 additions and 0 deletions

26
test/.eslintrc.json Normal file
View File

@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "standard",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"comma-dangle": 0
},
"globals": {
"google": true,
"Vue": true,
"VueGoogleMaps": true
},
"plugins": [
"html"
],
"settings": {
"html/html-extensions": [".html", ".vue"]
}
}

95
test/basic.js Normal file
View File

@@ -0,0 +1,95 @@
import Lab from 'lab'
import assert from 'assert'
import fs from 'fs'
import path from 'path'
import {getPage, loadFile} from './test-setup/test-common'
export const lab = Lab.script()
lab.experiment('Basic tests', {timeout: 15000}, function () {
let page = null
async function loadPage () {
return loadFile(page, './test-pages/test-plain-map.html', {
waitUntil: 'domcontentloaded'
})
}
async function mountVue () {
return page.evaluateHandle(() =>
new Promise((resolve) => {
new Vue({
created () {
resolve(this)
},
}).$mount('#test1')
}))
}
lab.before({timeout: 15000}, getPage(p => { page = p }))
lab.test('Maps API is loaded', async function () {
await loadPage()
const vue = await mountVue()
assert(await page.evaluate(
(vue) =>
vue.$refs.map.$mapPromise
.then(() => vue.$refs.map.$mapObject instanceof google.maps.Map),
vue), '$mapPromise is defined')
assert(await page.evaluate(
(vue) =>
vue.$refs.map.$mapObject
.getDiv().parentNode.classList.contains('map-container'),
vue),
'Parent of $mapObject.div is a .map-container')
})
lab.test('Panning of map works', {timeout: 30000}, async function () {
await loadPage()
const vue = await mountVue()
const [top, right, bottom, left] = await page.evaluate(() => {
const el = document.querySelector('.map-container')
const top = el.offsetTop
const right = el.offsetLeft + el.offsetWidth
const bottom = el.offsetTop + el.offsetHeight
const left = el.offsetLeft
return [top, right, bottom, left]
})
// Wait for map to load first...
await page.evaluate((vue) =>
vue.$refs.map.$mapPromise
.then(() => new Promise(resolve => setTimeout(resolve, 500))),
vue)
// Then try to pan the page
await page.mouse.move(right - 4, top + 4)
await page.mouse.down()
await page.mouse.move(left + 4, bottom - 4, {steps: 20})
await new Promise(resolve => setTimeout(resolve, 100))
await page.mouse.up()
const {lat, lng} = await page.evaluate((vue) => {
const c = vue.$refs.map.$mapObject.getCenter()
return {lat: c.lat(), lng: c.lng()}
}, vue)
assert(lat > 1.45, 'Lat greater than 1.45')
assert(lng > 103.9, 'Lng greater than 103.9')
})
lab.test('Lodash library is not bloating up the library', async () => {
const libraryOutput = fs.readFileSync(
path.join(__dirname, '../dist/vue-google-maps.js'),
'utf-8'
)
if (/Lodash <http(.*)>/.test(libraryOutput)) {
assert(false,
'Lodash found! This is bad because you are bloating up the library')
}
})
})

38
test/gmapApi-guard.js Normal file
View File

@@ -0,0 +1,38 @@
import Lab from 'lab'
import assert from 'assert'
import {getPage, loadFile} from './test-setup/test-common'
export const lab = Lab.script()
lab.experiment('Effectiveness of gmapApi guard', {timeout: 15000}, function () {
let page = null
let isError = false
async function loadPage () {
return loadFile(page, './test-pages/test-gmapApi.html', {
waitUntil: 'networkidle0'
})
}
lab.before({timeout: 15000}, getPage(p => {
isError = false
page = p
page.on('error', (err) => {
isError = err
})
page.on('pageerror', (err) => {
isError = err
})
return p
}))
lab.test('gmapGuard prevents errors', async function () {
await loadPage()
assert(!isError)
assert(await page.evaluate(() => {
return google && (window.vue.$refs.myMarker.position instanceof google.maps.LatLng)
}), 'Marker is loaded with a position')
})
})

65
test/maps-not-loaded.js Normal file
View File

@@ -0,0 +1,65 @@
import Lab from 'lab'
import assert from 'assert'
import {getPage, loadFile} from './test-setup/test-common'
export const lab = Lab.script()
lab.experiment('On-demand API loading', {timeout: 15000}, function () {
let page = null
async function loadPage () {
return loadFile(page, './test-pages/test-page-without-maps.html', {
waitUntil: 'networkidle0'
})
}
async function mountVue () {
return page.evaluateHandle(() =>
new Promise((resolve) => {
new Vue({
data: {
loadMap: false,
},
mounted () {
resolve(this)
},
}).$mount('#test1')
}))
}
lab.before({timeout: 15000}, getPage(p => { page = p }))
lab.test('Maps API is loaded only on demand', async function () {
await loadPage()
const vue = await mountVue()
assert(await page.evaluate(
(vue) => {
const allScriptElements = Array.prototype.slice.call(document.getElementsByTagName('SCRIPT'), 0)
return (
allScriptElements.every(s => !s.src.toLowerCase().includes('maps.googleapis.com')) &&
!window.google
)
},
vue), 'Google APIs are not loaded')
assert(await page.evaluate(
(vue) => {
return Promise.resolve(null)
.then(() => {
vue.loadMap = true
return new Promise((resolve) => setTimeout(resolve, 100))
})
.then(() => vue.$refs.gmap.$mapPromise.then(() => !!window.google))
.then((isGoogleLoaded) => {
const allScriptElements = Array.prototype.slice.call(document.getElementsByTagName('SCRIPT'), 0)
return (
isGoogleLoaded &&
allScriptElements.some(s => s.src.toLowerCase().includes('maps.googleapis.com'))
)
})
},
vue), 'Google APIs are loaded')
})
})

View File

@@ -0,0 +1,84 @@
import Lab from 'lab'
import assert from 'assert'
import {getPage, loadFile} from './test-setup/test-common'
export const lab = Lab.script()
lab.experiment('Marker / Infowindow tests', {timeout: 15000}, function () {
let page = null
async function loadPage () {
return loadFile(page, './test-pages/test-marker-with-infowindow.html', {
waitUntil: 'domcontentloaded'
})
}
lab.before({timeout: 15000}, getPage(p => { page = p }))
lab.test('Clicking the marker triggers the infowindow', async function () {
await loadPage()
await page.evaluate(() => {
// Ensure that the map has been created
return window.theVue.$refs.map.$mapPromise
.then(() => {
// Give some more time for the marker to initialize
return new Promise(resolve => setTimeout(resolve, 100))
})
})
// Is the infowindow hidden?
assert(await page.evaluate(() => {
return !document.getElementById('thediv') || (
document.getElementById('thediv').offsetWidth === 0 &&
document.getElementById('thediv').offsetHeight === 0
)
}),
'infowindow is hidden')
// Clicked is false
assert(await page.evaluate(() => {
return !window.theVue.clicked
}),
'marker is not clicked')
// Obtain the center
const [x, y] = await page.evaluate(() => {
const el = window.theVue.$refs.map.$el
return Promise.resolve([
el.offsetLeft + 0.5 * el.offsetWidth,
el.offsetTop + 0.5 * el.offsetHeight,
])
})
await page.mouse.click(x, y - 20)
// Clicked is now true!
assert(await page.evaluate(() => {
return new Promise(resolve => setTimeout(resolve, 100))
.then(() => {
return window.theVue.clicked
})
}),
'marker is clicked')
// Infowindow is now open!
assert(await page.evaluate(() => {
return document.getElementById('thediv').offsetWidth > 10
}),
'#thediv is visible')
// shut the infowindow
assert(await page.evaluate(() => {
window.theVue.infoWindow.open = false
return new Promise(resolve => setTimeout(resolve, 100))
.then(() => {
return !document.getElementById('thediv') || (
document.getElementById('thediv').offsetWidth === 0 &&
document.getElementById('thediv').offsetHeight === 0
)
})
}), 'setting open=false closes #thediv')
})
})

40
test/test-all-examples.js Normal file
View File

@@ -0,0 +1,40 @@
import Lab from 'lab'
import assert from 'assert'
import fs from 'fs'
import path from 'path'
import {getPage, loadFile} from './test-setup/test-common'
export const lab = Lab.script()
lab.experiment('Examples test', {timeout: 15000}, function () {
let page = null
async function loadPage (f) {
return loadFile(page, f, {
waitUntil: 'networkidle0'
})
}
lab.before({timeout: 15000}, getPage(p => { page = p }))
lab.test('Test all examples pages load without errors (does not test functionality)', {timeout: 50000}, async function () {
const files = fs.readdirSync(path.join(__dirname, '../examples')).filter(f => f.endsWith('.html'))
let isErrored = false
page.on('error', (err) => {
isErrored = err
})
page.on('pageerror', (err) => {
isErrored = err
})
assert(!isErrored)
for (let file of files) {
await loadPage('../examples/' + file)
if (isErrored) {
throw new Error(`The example file ../examples/${file} threw an error ${isErrored}`)
}
}
})
})

View File

@@ -0,0 +1,39 @@
<head>
<style>
.map-container {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div id="test">
<h2>Test 1</h2>
<gmap-map
:center="{lat: 1.38, lng: 103.8}"
:zoom="12"
class="map-container"
ref="map">
<gmap-marker ref="myMarker" :position="google && new google.maps.LatLng(1.38, 103.8)"></gmap-marker>
</gmap-map>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<script src="../../dist/vue-google-maps.js"></script>
<script>
Vue.use(VueGoogleMaps, {
load: {
key: 'AIzaSyDf43lPdwlF98RCBsJOFNKOkoEjkwxb5Sc',
}
})
document.addEventListener('DOMContentLoaded', () => {
window.vue = new Vue({
computed: {
google: VueGoogleMaps.gmapApi
},
el: '#test',
})
})
</script>
</body>

View File

@@ -0,0 +1,71 @@
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<gmap-map
:center="randomInitialLatLng"
:zoom="7"
style="height: 400px; width: 100%;"
ref="map"
id="themap">
<gmap-marker
:position="randomInitialLatLng"
:clickable="true"
@click="openInfoWindowTemplate(randomInitialLatLng)"
ref="markers">
</gmap-marker>
<gmap-info-window
:options="{maxWidth: 300}"
:position="infoWindow.position"
:opened="infoWindow.open"
@closeclick="infoWindow.open = false">
<div id="thediv">hello</div>
</gmap-info-window>
</gmap-map>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<script src="../../dist/vue-google-maps.js"></script>
<script>
Vue.use(VueGoogleMaps, {
load: {
key: 'AIzaSyDf43lPdwlF98RCBsJOFNKOkoEjkwxb5Sc',
}
})
document.addEventListener('DOMContentLoaded', () => {
window.theVue = new Vue({
el: '#app',
data () {
return {
infoWindow: {
position: {lat: 50, lng: 90},
open: false,
template: ''
},
clicked: false,
}
},
computed: {
randomInitialLatLng () {
return ({lat: 50 + Math.random(), lng: 90 + Math.random()})
}
},
methods: {
openInfoWindowTemplate (pos) {
this.infoWindow.position = pos
this.infoWindow.open = true
this.clicked = true
}
}
})
})
</script>
</body>
</html>

View File

@@ -0,0 +1,28 @@
<head>
<style>
.map-container {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div id="test1">
<h2>Test 1</h2>
<gmap-map v-if="loadMap" ref="gmap"></gmap-map>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<script src="../../dist/vue-google-maps.js"></script>
<script>
// This page does not have maps, but we use Vue2-google-maps
// Must ensure that Google Maps library is NEVER loaded
Vue.use(VueGoogleMaps, {
load: {
key: 'AIzaSyDf43lPdwlF98RCBsJOFNKOkoEjkwxb5Sc',
}
})
</script>
</body>

View File

@@ -0,0 +1,30 @@
<head>
<style>
.map-container {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div id="test1">
<h2>Test 1</h2>
<gmap-map
:center="{lat: 1.38, lng: 103.8}"
:zoom="12"
class="map-container"
ref="map">
</gmap-map>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<script src="../../dist/vue-google-maps.js"></script>
<script>
Vue.use(VueGoogleMaps, {
load: {
key: 'AIzaSyDf43lPdwlF98RCBsJOFNKOkoEjkwxb5Sc',
}
})
</script>
</body>

View File

@@ -0,0 +1,30 @@
// Adapted from https://github.com/nlf/lab-babel/blob/master/lib/index.js
require('babel-polyfill')
var Babel = require('babel-core')
var internals = {}
internals.transform = function (content, filename) {
if (/^node_modules/.test(filename)) {
return content
}
var transformed = Babel.transform(content, {
filename: filename,
sourceMap: 'inline',
sourceFileName: filename,
auxiliaryCommentBefore: '$lab:coverage:off$',
auxiliaryCommentAfter: '$lab:coverage:on$',
presets: ['es2015'],
plugins: ['transform-object-rest-spread'],
})
return transformed.code
}
internals.extensions = ['js', 'jsx', 'es', 'es6']
internals.methods = []
for (var i = 0, il = internals.extensions.length; i < il; ++i) {
internals.methods.push({ ext: internals.extensions[i], transform: internals.transform })
}
module.exports = internals.methods

View File

@@ -0,0 +1,25 @@
import webpack from 'webpack'
import * as shell from 'shelljs'
import path from 'path'
export default new Promise((resolve, reject) => {
const webpackConfig = require('../../webpack.config.js')[0]
webpack(
{
...webpackConfig,
mode: 'development',
},
(err, status) => {
if (!err) {
shell.cp(
path.resolve(__dirname, '../../dist/vue-google-maps.js'),
path.resolve(__dirname, '../../examples/vue-google-maps.js')
)
resolve()
} else {
reject(err)
}
}
)
})

View File

@@ -0,0 +1,23 @@
import Puppeteer from 'puppeteer'
import CompileStandalone from './compile-standalone'
import path from 'path'
const puppeteerPromise = CompileStandalone.then(() => {
let options = {}
if (process.env['THIS_IS_ON_TRAVIS_AND_SANDBOX_IS_NOT_ALLOWED'] === 'true') {
options.args = ['--no-sandbox', '--disable-setuid-sandbox']
}
return Puppeteer.launch(options)
})
export function getPage (p) {
return async () => {
p(await puppeteerPromise.then(browser => browser.newPage()))
}
}
export async function loadFile (page, relpath, options) {
return page.goto('file:///' + path.join(__dirname, '../', relpath), options)
}