Skip to content

Commit b6a2242

Browse files
committed
Merge branch 'next' of https://github.com/vuejs/vuepress into next
2 parents af95037 + fb6e8d4 commit b6a2242

File tree

99 files changed

+1484
-701
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+1484
-701
lines changed

babel.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module.exports = {
22
'env': {
33
'test': {
44
'presets': [
5-
['@babel/preset-env', { 'targets': { 'node': 8 }}]
5+
['@babel/preset-env', { 'targets': { 'node': 'current' }}]
66
]
77
}
88
}

packages/@vuepress/core/__test__/app/Content.spec.js

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const AsyncOption = require('../../lib/plugin-api/abstract/AsyncOption')
2+
3+
describe('AsyncOption', () => {
4+
test('parallelApply', async () => {
5+
const option = new AsyncOption('option')
6+
const handler1 = jest.fn()
7+
const handler2 = jest.fn()
8+
9+
option.add('plugin-a', handler1)
10+
option.add('plugin-b', handler2)
11+
12+
// TODO for now, if a class extends from another class.
13+
// the original methods in that class will be lost.
14+
15+
await option.parallelApply(1, 2)
16+
// expect(handler1.mock.calls).toHaveLength(1)
17+
// expect(handler2.mock.calls).toHaveLength(1)
18+
// expect(handler1.mock.calls[0][0]).toBe(1)
19+
// expect(handler1.mock.calls[0][1]).toBe(2)
20+
// expect(handler2.mock.calls[0][0]).toBe(1)
21+
// expect(handler2.mock.calls[0][1]).toBe(2)
22+
})
23+
})
24+
Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,90 @@
1-
import Option from '../../lib/plugin-api/Option'
1+
import Option from '../../lib/plugin-api/abstract/Option'
22

33
describe('Option', () => {
4-
test('shoould option record the key', () => {
4+
test('key', () => {
55
const option = new Option('option')
66
expect(option.key).toBe('option')
77
})
88

9-
test('should \'tap\' work', () => {
9+
test('add', () => {
1010
const option = new Option('option')
11-
option.tap('plugin-a', 'a')
12-
option.tap('plugin-b', 'b')
11+
option.add('plugin-a', 'a')
12+
option.add('plugin-b', 'b')
13+
1314
expect(option.items).toEqual([
1415
{ value: 'a', name: 'plugin-a' },
1516
{ value: 'b', name: 'plugin-b' }
1617
])
18+
1719
expect(option.values).toEqual(['a', 'b'])
1820
})
1921

20-
test('should \'tap\' resolve array value', () => {
22+
test('add - resolve array', () => {
2123
const option = new Option('option')
22-
option.tap('plugin-a', ['a-1', 'a-2'])
23-
option.tap('plugin-b', 'b')
24+
option.add('plugin-a', ['a-1', 'a-2'])
25+
option.add('plugin-b', 'b')
26+
2427
expect(option.items).toEqual([
2528
{ value: 'a-1', name: 'plugin-a' },
2629
{ value: 'a-2', name: 'plugin-a' },
2730
{ value: 'b', name: 'plugin-b' }
2831
])
29-
expect(option.values).toEqual(['a-1', 'a-2', 'b'])
3032
})
3133

32-
test('should \'apply\' work', async () => {
34+
test('delete', () => {
3335
const option = new Option('option')
34-
const handler1 = jest.fn()
35-
const handler2 = jest.fn()
36+
option.add('plugin-a', ['a-1', 'a-2'])
37+
option.add('plugin-b', 'b')
3638

37-
option.tap('plugin-a', handler1)
38-
option.tap('plugin-b', handler2)
39+
option.delete('plugin-a')
3940

40-
await option.apply(1, 2)
41-
expect(handler1.mock.calls).toHaveLength(1)
42-
expect(handler2.mock.calls).toHaveLength(1)
43-
expect(handler1.mock.calls[0][0]).toBe(1)
44-
expect(handler1.mock.calls[0][1]).toBe(2)
45-
expect(handler2.mock.calls[0][0]).toBe(1)
46-
expect(handler2.mock.calls[0][1]).toBe(2)
41+
expect(option.items).toEqual([
42+
{ value: 'b', name: 'plugin-b' }
43+
])
44+
})
45+
46+
test('clear', () => {
47+
const option = new Option('option')
48+
option.add('plugin-a', ['a-1', 'a-2'])
49+
50+
option.clear()
51+
52+
expect(option.items).toEqual([])
4753
})
4854

49-
test('should \'parallelApply\' work', async () => {
55+
test('syncApply', () => {
5056
const option = new Option('option')
5157
const handler1 = jest.fn()
5258
const handler2 = jest.fn()
5359

54-
option.tap('plugin-a', handler1)
55-
option.tap('plugin-b', handler2)
60+
option.add('plugin-a', handler1)
61+
option.add('plugin-b', handler2)
5662

57-
await option.parallelApply(1, 2)
63+
option.syncApply('p1', 'p2')
5864
expect(handler1.mock.calls).toHaveLength(1)
5965
expect(handler2.mock.calls).toHaveLength(1)
60-
expect(handler1.mock.calls[0][0]).toBe(1)
61-
expect(handler1.mock.calls[0][1]).toBe(2)
62-
expect(handler2.mock.calls[0][0]).toBe(1)
63-
expect(handler2.mock.calls[0][1]).toBe(2)
66+
expect(handler1.mock.calls[0][0]).toBe('p1')
67+
expect(handler1.mock.calls[0][1]).toBe('p2')
68+
expect(handler2.mock.calls[0][0]).toBe('p1')
69+
expect(handler2.mock.calls[0][1]).toBe('p2')
70+
})
71+
72+
test('appliedItems', () => {
73+
const option = new Option('option')
74+
const fn1 = () => 'fn1'
75+
const fn2 = () => 'fn2'
76+
const handler1 = jest.fn(fn1)
77+
const handler2 = jest.fn(fn2)
78+
79+
option.add('plugin-a', handler1)
80+
option.add('plugin-b', handler2)
81+
82+
option.syncApply(1, 2)
83+
84+
expect(option.appliedItems).toEqual([
85+
{ value: 'fn1', name: 'plugin-a' },
86+
{ value: 'fn2', name: 'plugin-b' }
87+
])
6488
})
6589
})
6690

packages/@vuepress/core/__test__/plugin-api/PluginAPI.spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import PluginAPI from '../../lib/plugin-api/index'
66
import { PLUGIN_OPTION_MAP } from '../../lib/plugin-api/constants'
77

88
describe('Plugin', () => {
9-
test('should \'registerOption\' work.', () => {
9+
test('registerOption', () => {
1010
const api = new PluginAPI()
1111
const readyHandler = () => {}
1212
api.registerOption(PLUGIN_OPTION_MAP.READY.key, readyHandler)
1313
expect(api.options.ready.values).toHaveLength(1)
1414
expect(api.options.ready.values[0]).toBe(readyHandler)
1515
})
1616

17-
test('should \'useByPluginsConfig\' work.', () => {
17+
test('useByPluginsConfig', () => {
1818
[
1919
['a'],
2020
[['a']],
@@ -29,7 +29,7 @@ describe('Plugin', () => {
2929
})
3030
})
3131

32-
test('should \'useByPluginsConfig\' work. - disable plugin', () => {
32+
test('useByPluginsConfig - disable plugin', () => {
3333
[
3434
[['a', false]],
3535
{ a: false }
@@ -42,7 +42,7 @@ describe('Plugin', () => {
4242
})
4343
})
4444

45-
test('should \'useByPluginsConfig\' work. - get options', () => {
45+
test('useByPluginsConfig - get options', () => {
4646
const pluginOptions = {};
4747
[
4848
[['a', pluginOptions]],
@@ -54,7 +54,7 @@ describe('Plugin', () => {
5454
})
5555
})
5656

57-
test('make sure the namesake plugin is only executed once.', () => {
57+
test('ensure the namesake plugin is only executed once.', () => {
5858
const pluginOptions1 = {}
5959
const pluginOptions2 = {}
6060
const pluginOptions3 = {}
@@ -70,7 +70,7 @@ describe('Plugin', () => {
7070
expect(api.enabledPlugins[0].$$options).toBe(pluginOptions3)
7171
})
7272

73-
test('a "multuple" plugin can be applied multuple times.', () => {
73+
test('ensure a "multuple" plugin can be applied multuple times.', () => {
7474
const pluginOptions1 = { a: 1 }
7575
const pluginOptions2 = { b: 1 }
7676
const pluginsConfig = [

packages/@vuepress/core/__test__/plugin-api/PluginUtil.spec.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
import { hydratePlugin } from '../../lib/plugin-api/util'
1+
import { flattenPlugin } from '../../lib/plugin-api/util'
22

3-
describe('hydratePlugin', () => {
3+
describe('flattenPlugin', () => {
44
test('shoould hydrate plugin correctly', () => {
5-
const plugin = { name: 'a', shortcut: 'a', config: { enhanceAppFiles: 'file' }}
6-
const hydratedPlugin = hydratePlugin(plugin, {}, {})
5+
const plugin = { name: 'a', shortcut: 'a', module: { enhanceAppFiles: 'file' }}
6+
const hydratedPlugin = flattenPlugin(plugin, {}, {})
77
expect(hydratedPlugin.name).toBe('a')
88
expect(hydratedPlugin.shortcut).toBe('a')
99
expect(hydratedPlugin.enabled).toBe(true)
1010
expect(hydratedPlugin.enhanceAppFiles).toBe('file')
1111
})
1212

1313
test('shoould set \'enabled\' to false when \'pluginOptions\' is set to false.', () => {
14-
const plugin = { name: 'a', shortcut: 'a', config: {}}
15-
const hydratedPlugin = hydratePlugin(plugin, false, {})
14+
const plugin = { name: 'a', shortcut: 'a', module: {}}
15+
const hydratedPlugin = flattenPlugin(plugin, false, {})
1616
expect(hydratedPlugin.name).toBe('a')
1717
expect(hydratedPlugin.shortcut).toBe('a')
1818
expect(hydratedPlugin.enabled).toBe(false)
1919
})
2020

21-
test('shoould hydrate functional plugin correctly.', () => {
21+
test('shoould flatten functional plugin correctly.', () => {
2222
const config = jest.fn(() => ({ enhanceAppFiles: 'file' }))
23-
const plugin = { name: 'a', shortcut: 'a', config }
23+
const plugin = { name: 'a', shortcut: 'a', module: config }
2424
const pluginOptions = {}
2525
const pluginContext = {}
26-
const hydratedPlugin = hydratePlugin(plugin, pluginOptions, pluginContext)
26+
const hydratedPlugin = flattenPlugin(plugin, pluginOptions, pluginContext)
2727
expect(hydratedPlugin.name).toBe('a')
2828
expect(hydratedPlugin.shortcut).toBe('a')
2929
expect(hydratedPlugin.enabled).toBe(true)
@@ -33,12 +33,12 @@ describe('hydratePlugin', () => {
3333
expect(Object.getPrototypeOf(config.mock.calls[0][1])).toBe(pluginContext)
3434
})
3535

36-
test('shoould hydrate functional plugin correctly - options defaults to \'{}\'.', () => {
36+
test('shoould flatten functional plugin correctly - options defaults to \'{}\'.', () => {
3737
const config = jest.fn(() => ({ enhanceAppFiles: 'file' }))
38-
const plugin = { name: 'a', shortcut: 'a', config }
38+
const plugin = { name: 'a', shortcut: 'a', module: config }
3939
const pluginOptions = undefined
4040
const pluginContext = {}
41-
hydratePlugin(plugin, pluginOptions, pluginContext)
41+
flattenPlugin(plugin, pluginOptions, pluginContext)
4242
expect(config.mock.calls[0][0]).toEqual({})
4343
expect(Object.getPrototypeOf(config.mock.calls[0][1])).toBe(pluginContext)
4444
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { fs } = require('@vuepress/shared-utils')
2+
const path = require('path')
3+
const prepare = require('../../lib/prepare')
4+
5+
const docsBaseDir = path.resolve(__dirname, 'fixtures')
6+
const docsModeNames = fs.readdirSync(docsBaseDir)
7+
const docsModes = docsModeNames.map(name => {
8+
const docsPath = path.resolve(docsBaseDir, name)
9+
const docsTempPath = path.resolve(docsPath, '.vuepress/.temp')
10+
return { name, docsPath, docsTempPath }
11+
})
12+
13+
describe('prepare', () => {
14+
test('should not throw error', async () => {
15+
await Promise.all(docsModes.map(async ({ name, docsPath, docsTempPath }) => {
16+
await fs.ensureDir(docsTempPath)
17+
const context = await prepare(docsPath, { theme: '@vuepress/default', temp: docsTempPath })
18+
expect(context.sourceDir).toBe(docsPath)
19+
}))
20+
})
21+
})
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Vue from 'vue'
2+
3+
export default class Store {
4+
constructor () {
5+
this.store = new Vue({
6+
data: {
7+
ob: {}
8+
}
9+
})
10+
}
11+
12+
get (key) {
13+
return this.store.ob[key]
14+
}
15+
16+
set (key, value) {
17+
Vue.set(this.store.ob, key, value)
18+
}
19+
}

packages/@vuepress/core/lib/app/app.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { routes } from '@internal/routes'
66
import { siteData } from '@internal/siteData'
77
import appEnhancers from '@internal/app-enhancers'
88
import globalUIComponents from '@internal/global-ui'
9-
import I18n from '@internal/i18n'
9+
import ClientComputedMixin from '../prepare/ClientComputedMixin'
10+
import Store from './Store'
1011

1112
// generated from user config
1213
import('@temp/style.styl')
@@ -30,9 +31,12 @@ if (module.hot) {
3031
}
3132

3233
Vue.config.productionTip = false
34+
35+
Vue.$store = new Store()
36+
3337
Vue.use(Router)
3438
// mixin for exposing $site and $page
35-
Vue.mixin(dataMixin(I18n, siteData))
39+
Vue.mixin(dataMixin(ClientComputedMixin, siteData))
3640
// component for rendering markdown content and setting title etc.
3741
Vue.component('Content', Content)
3842
Vue.component('OutboundLink', OutboundLink)
@@ -59,7 +63,7 @@ export function createApp (isServer) {
5963
if (saved) {
6064
return saved
6165
} else if (to.hash) {
62-
if (Vue.$store.disableScrollBehavior) {
66+
if (Vue.$store.get('disableScrollBehavior')) {
6367
return false
6468
}
6569
return {

packages/@vuepress/core/lib/app/dataMixin.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,16 @@ import Vue from 'vue'
44

55
export default function dataMixin (I18n, siteData) {
66
prepare(siteData)
7-
const store = new Vue({
8-
data: {
9-
siteData,
10-
disableScrollBehavior: false
11-
}
12-
})
13-
Vue.$store = store
7+
Vue.$store.set('siteData', siteData)
148

159
if (module.hot) {
1610
module.hot.accept(VUEPRESS_TEMP_PATH + '/internal/siteData.js', () => {
1711
prepare(siteData)
18-
store.siteData = siteData
12+
Vue.$store.set('siteData', siteData)
1913
})
2014
}
2115

22-
const I18nConstructor = I18n(store)
16+
const I18nConstructor = I18n(Vue.$store.get('siteData'))
2317
const i18n = new I18nConstructor()
2418
const descriptors = Object.getOwnPropertyDescriptors(Object.getPrototypeOf(i18n))
2519
const computed = {}

0 commit comments

Comments
 (0)