Skip to content

Commit

Permalink
feat(loader): add file system loader
Browse files Browse the repository at this point in the history
loader will resolve templates from the file system
  • Loading branch information
thetutlage committed Jul 2, 2018
1 parent aa10de0 commit cc3aa63
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 3 deletions.
57 changes: 54 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"coveralls": "^3.0.2",
"cz-conventional-changelog": "^2.1.0",
"del-cli": "^1.1.0",
"fs-extra": "^6.0.1",
"japa": "^1.0.6",
"japa-cli": "^1.0.1",
"mrm": "^1.1.1",
Expand All @@ -57,5 +58,8 @@
"extension": [
".ts"
]
},
"dependencies": {
"edge-parser": "git+https://github.com/poppinss/edge-parser.git#develop"
}
}
Empty file added src/Compiler/index.ts
Empty file.
65 changes: 65 additions & 0 deletions src/Loader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { join } from 'path'
import { readFileSync } from 'fs'

export class Loader {
private mountedDirs: Map<string, string> = new Map()

/**
* Returns an object of mounted directories with their public
* names
*/
public get mounted (): object {
return Array.from(this.mountedDirs).reduce((obj, [key, value]) => {
obj[key] = value
return obj
}, {})
}

/**
* Mount a directory for resolving views
*/
public mount (name: string, dirPath: string): void {
this.mountedDirs.set(name, dirPath)
}

/**
* Remove directory from the list of directories
* for resolving views
*/
public unmount (name: string): void {
this.mountedDirs.delete(name)
}

/**
* Resolves a template from disk and returns it as a string
*/
public resolve (template: string, name: string = 'default'): string {
const mountedDir = this.mountedDirs.get(name)
if (!mountedDir) {
throw new Error(`Attempting to resolve ${template} template for unmounted ${name} location`)
}

/**
* Normalize template name by adding extension
*/
template = `${template.replace(/\.edge$/, '')}.edge`

try {
return readFileSync(join(mountedDir, template), 'utf-8')
} catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`Cannot resolve ${template}. Make sure file exists at ${mountedDir} location.`)
}
throw error
}
}
}
70 changes: 70 additions & 0 deletions test/loader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import * as test from 'japa'
import * as fs from 'fs-extra'

import { join } from 'path'
import { Loader } from '../src/Loader'

const viewsDir = join(__dirname, 'views')

test.group('Loader', (group) => {
group.afterEach(async () => {
await fs.remove(viewsDir)
})

test('mount path with a name', (assert) => {
const loader = new Loader()
loader.mount('default', viewsDir)
assert.deepEqual(loader.mounted, { default: join(__dirname, 'views') })
})

test('unmount path with a name', (assert) => {
const loader = new Loader()
loader.mount('default', viewsDir)
loader.unmount('default')

assert.deepEqual(loader.mounted, {})
})

test('throw exception when resolve path from undefined location', (assert) => {
const loader = new Loader()
const fn = () => loader.resolve('foo')
assert.throw(fn, 'Attempting to resolve foo template for unmounted default location')
})

test('resolve template for given location', async (assert) => {
await fs.outputFile(join(viewsDir, 'foo.edge'), 'Hello world')

const loader = new Loader()
loader.mount('default', viewsDir)

const template = loader.resolve('foo')
assert.equal(template.trim(), 'Hello world')
})

test('raise error when template is missing', async (assert) => {
const loader = new Loader()
loader.mount('default', viewsDir)

const fn = () => loader.resolve('foo')
assert.throw(fn, `Cannot resolve foo.edge. Make sure file exists at ${viewsDir} location.`)
})

test('resolve template with extension', async (assert) => {
await fs.outputFile(join(viewsDir, 'foo.edge'), 'Hello world')

const loader = new Loader()
loader.mount('default', viewsDir)

const template = loader.resolve('foo.edge')
assert.equal(template.trim(), 'Hello world')
})
})

0 comments on commit cc3aa63

Please sign in to comment.