1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-11-25 01:40:10 +00:00

Merge pull request #25 from fluentdesk/v0.11.0

v0.11.0
This commit is contained in:
hacksalot 2015-12-19 08:58:59 -05:00
commit 786b3fd3b2
14 changed files with 276 additions and 140 deletions

View File

@ -17,6 +17,8 @@ module.exports = function (grunt) {
all: { src: ['tests/*.js'] } all: { src: ['tests/*.js'] }
}, },
clean: ['tests/sandbox'],
yuidoc: { yuidoc: {
compile: { compile: {
name: '<%= pkg.name %>', name: '<%= pkg.name %>',
@ -46,9 +48,10 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-simple-mocha'); grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-contrib-yuidoc'); grunt.loadNpmTasks('grunt-contrib-yuidoc');
grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('test', 'Test the FluentCV library.', grunt.registerTask('test', 'Test the FluentCV library.',
function( config ) { grunt.task.run( ['simplemocha:all'] ); }); function( config ) { grunt.task.run( ['clean','simplemocha:all'] ); });
grunt.registerTask('document', 'Generate FluentCV library documentation.', grunt.registerTask('document', 'Generate FluentCV library documentation.',
function( config ) { grunt.task.run( ['yuidoc'] ); }); function( config ) { grunt.task.run( ['yuidoc'] ); });
grunt.registerTask('default', [ 'jshint', 'test', 'yuidoc' ]); grunt.registerTask('default', [ 'jshint', 'test', 'yuidoc' ]);

View File

@ -1,12 +1,13 @@
fluentCV fluentCV
======== ========
*Create polished technical résumés and CVs in multiple formats from your command *Create polished résumés and CVs in multiple formats from your command line or
line or shell. See [FluentCV Desktop][7] for the desktop version. OS X ~ Windows shell. Author in clean Markdown and JSON, export to Word, HTML, PDF, LaTeX,
~ Linux.* plain text, and other arbitrary formats.*
![](assets/fluentcv_cli_ubuntu.png) ![](assets/resume-bouqet.png)
FluentCV is a dev-friendly Swiss Army knife for resumes and CVs. Use it to: FluentCV is a dev-friendly, local-only Swiss Army knife for resumes and CVs. Use
it to:
1. **Generate** HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, 1. **Generate** HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML,
YAML, print, smoke signal, carrier pigeon, and other arbitrary-format resumes YAML, print, smoke signal, carrier pigeon, and other arbitrary-format resumes
@ -14,7 +15,10 @@ and CVs, from a single source of truth&mdash;without violating DRY.
2. **Convert** resumes between [FRESH][fresca] and [JSON Resume][6] formats. 2. **Convert** resumes between [FRESH][fresca] and [JSON Resume][6] formats.
3. **Validate** resumes against either format. 3. **Validate** resumes against either format.
FluentCV supports both the [FRESH][fresca] and [JSON Resume][6] source formats. FluentCV is built with Node.js and runs on recent versions of OS X, Linux, or
Windows.
![](assets/fluentcv_cli_ubuntu.png)
## Features ## Features

BIN
assets/resume-bouqet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@ -1,6 +1,6 @@
{ {
"name": "fluentcv", "name": "fluentcv",
"version": "0.10.3", "version": "0.11.0",
"description": "Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.", "description": "Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.",
"repository": { "repository": {
"type": "git", "type": "git",
@ -20,7 +20,7 @@
"HTML", "HTML",
"CLI" "CLI"
], ],
"author": "James M. Devlin", "author": "hacksalot <hacksalot@fluentdesk.com> (https://github.com/hacksalot)",
"license": "MIT", "license": "MIT",
"preferGlobal": "true", "preferGlobal": "true",
"bugs": { "bugs": {
@ -33,8 +33,8 @@
"homepage": "https://github.com/fluentdesk/fluentcv", "homepage": "https://github.com/fluentdesk/fluentcv",
"dependencies": { "dependencies": {
"colors": "^1.1.2", "colors": "^1.1.2",
"fluent-themes": "~0.6.3-beta", "fluent-themes": "~0.7.0-beta",
"fresca": "~0.2.1", "fresca": "~0.2.2",
"fs-extra": "^0.24.0", "fs-extra": "^0.24.0",
"handlebars": "^4.0.5", "handlebars": "^4.0.5",
"html": "0.0.10", "html": "0.0.10",
@ -54,10 +54,11 @@
"devDependencies": { "devDependencies": {
"chai": "*", "chai": "*",
"grunt": "*", "grunt": "*",
"grunt-contrib-clean": "^0.7.0",
"grunt-contrib-jshint": "^0.11.3", "grunt-contrib-jshint": "^0.11.3",
"grunt-contrib-yuidoc": "^0.10.0", "grunt-contrib-yuidoc": "^0.10.0",
"grunt-simple-mocha": "*", "grunt-simple-mocha": "*",
"is-my-json-valid": "^2.12.2", "jane-q-fullstacker": "fluentdesk/jane-q-fullstacker",
"mocha": "*", "mocha": "*",
"resample": "fluentdesk/resample" "resample": "fluentdesk/resample"
} }

View File

@ -100,6 +100,7 @@ Definition of the Theme class.
var outFmt = '', isMajor = false; var outFmt = '', isMajor = false;
var portion = pathInfo.dir.replace(tplFolder,''); var portion = pathInfo.dir.replace(tplFolder,'');
if( portion && portion.trim() ) { if( portion && portion.trim() ) {
if( portion[1] === '_' ) return;
var reg = /^(?:\/|\\)(html|latex|doc|pdf|partials)(?:\/|\\)?/ig; var reg = /^(?:\/|\\)(html|latex|doc|pdf|partials)(?:\/|\\)?/ig;
var res = reg.exec( portion ); var res = reg.exec( portion );
if( res ) { if( res ) {
@ -152,7 +153,7 @@ Definition of the Theme class.
.forEach(function( cssf ) { .forEach(function( cssf ) {
// For each CSS file, get its corresponding HTML file // For each CSS file, get its corresponding HTML file
var idx = _.findIndex(fmts, function( fmt ) { var idx = _.findIndex(fmts, function( fmt ) {
return fmt.pre === cssf.pre && fmt.ext === 'html'; return fmt && fmt.pre === cssf.pre && fmt.ext === 'html';
}); });
cssf.action = null; cssf.action = null;
fmts[ idx ].css = cssf.data; fmts[ idx ].css = cssf.data;

View File

@ -11,93 +11,40 @@ Definition of the HandlebarsGenerator class.
var _ = require('underscore') var _ = require('underscore')
, HANDLEBARS = require('handlebars') , HANDLEBARS = require('handlebars')
, FS = require('fs') , FS = require('fs')
, moment = require('moment') , registerHelpers = require('./handlebars-helpers');
, MD = require('marked')
, H2W = require('../utils/html-to-wpml');
/** /**
Perform template-based resume generation using Handlebars.js. Perform template-based resume generation using Handlebars.js.
@method generate @class HandlebarsGenerator
*/ */
module.exports = function( json, jst, format, cssInfo, opts, theme ) { var HandlebarsGenerator = module.exports = {
// Pre-compile any partials present in the theme. generate: function( json, jst, format, cssInfo, opts, theme ) {
_.each( theme.partials, function( el ) {
var tplData = FS.readFileSync( el.path, 'utf8' );
var compiledTemplate = HANDLEBARS.compile( tplData );
HANDLEBARS.registerPartial( el.name, compiledTemplate );
});
// Register necessary helpers. // Pre-compile any partials present in the theme.
registerHelpers(); _.each( theme.partials, function( el ) {
var tplData = FS.readFileSync( el.path, 'utf8' );
var compiledTemplate = HANDLEBARS.compile( tplData );
HANDLEBARS.registerPartial( el.name, compiledTemplate );
});
// Compile and run the Handlebars template. // Register necessary helpers.
var template = HANDLEBARS.compile(jst); registerHelpers();
return template({
r: json, // Compile and run the Handlebars template.
filt: opts.filters, var template = HANDLEBARS.compile(jst);
cssInfo: cssInfo, return template({
headFragment: opts.headFragment || '' r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
}); RAW: json,
filt: opts.filters,
cssInfo: cssInfo,
headFragment: opts.headFragment || ''
});
}
}; };
/**
Register useful Handlebars helpers.
@method registerHelpers
*/
function registerHelpers() {
// Set up a date formatting helper so we can do:
// {{#formatDate val 'YYYY-MM'}}
HANDLEBARS.registerHelper("formatDate", function(datetime, format) {
if( moment ) {
return moment( datetime ).format( format );
}
else {
return datetime;
}
});
// Set up a Markdown-to-WordProcessingML helper so we can do:
// {{#wmpl val [true|false]}}
HANDLEBARS.registerHelper("wpml", function( txt, inline ) {
inline = (inline && !inline.hash) || false;
txt = inline ?
MD(txt.trim()).replace(/^\s*<p>|<\/p>\s*$/gi, '') :
MD(txt.trim());
txt = H2W( txt.trim() );
return txt;
});
// Set up a generic conditional helper so we can do:
// {{#compare val otherVal operator="<"}}
// http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/
HANDLEBARS.registerHelper('compare', function(lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
var operator = options.hash.operator || "==";
var operators = {
'==': function(l,r) { return l == r; },
'===': function(l,r) { return l === r; },
'!=': function(l,r) { return l != r; },
'<': function(l,r) { return l < r; },
'>': function(l,r) { return l > r; },
'<=': function(l,r) { return l <= r; },
'>=': function(l,r) { return l >= r; },
'typeof': function(l,r) { return typeof l == r; }
};
if (!operators[operator])
throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
var result = operators[operator](lvalue,rvalue);
return result ? options.fn(this) : options.inverse(this);
});
}
}()); }());

View File

@ -0,0 +1,124 @@
/**
Template helper definitions for Handlebars.
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
@module handlebars-helpers.js
*/
(function() {
var HANDLEBARS = require('handlebars')
, MD = require('marked')
, H2W = require('../utils/html-to-wpml')
, moment = require('moment')
, _ = require('underscore');
/**
Register useful Handlebars helpers.
@method registerHelpers
*/
module.exports = function() {
// Set up a date formatting helper so we can do:
// {{formatDate val 'YYYY-MM'}}
HANDLEBARS.registerHelper("formatDate", function(datetime, format) {
return moment ? moment( datetime ).format( format ) : datetime;
});
// Set up a Markdown-to-WordProcessingML helper so we can do:
// {{wmpl val [true|false]}}
HANDLEBARS.registerHelper("wpml", function( txt, inline ) {
if(!txt) return '';
inline = (inline && !inline.hash) || false;
txt = inline ?
MD(txt.trim()).replace(/^\s*<p>|<\/p>\s*$/gi, '') :
MD(txt.trim());
txt = H2W( txt.trim() );
return txt;
});
// Set up a last-word helper so we can do:
// {{lastWord val [true|false]}}
HANDLEBARS.registerHelper("link", function( text, url ) {
return url && url.trim() ?
('<a href="' + url + '">' + text + '</a>') : text;
});
// Set up a last-word helper so we can do:
// {{lastWord val [true|false]}}
HANDLEBARS.registerHelper("lastWord", function( txt ) {
return txt && txt.trim() ? _.last( txt.split(' ') ) : '';
});
// Set up a skill colorizing helper:
// {{skillColor val}}
HANDLEBARS.registerHelper("skillColor", function( lvl ) {
switch(lvl) {
case 'beginner': return '#5CB85C';
case 'intermediate': return '#F1C40F';
case 'advanced': return '#428BCA';
case 'master': return '#C00000';
}
});
// Set up a skill colorizing helper:
// {{skillColor val}}
HANDLEBARS.registerHelper("skillHeight", function( lvl ) {
switch(lvl) {
case 'beginner': return '30';
case 'intermediate': return '16';
case 'advanced': return '8';
case 'master': return '0';
}
});
// Set up a Markdown-to-WordProcessingML helper so we can do:
// {{initialWords val [true|false]}}
HANDLEBARS.registerHelper("initialWords", function( txt ) {
return txt && txt.trim() ? _.initial( txt.split(' ') ).join(' ') : '';
});
// Set up a URL-trimming helper to drop the protocol so we can do:
// {{trimURL url}}
HANDLEBARS.registerHelper("trimURL", function( url ) {
return url && url.trim() ? url.trim().replace(/^https?:\/\//i, '') : '';
});
// Set up a URL-trimming helper to drop the protocol so we can do:
// {{trimURL url}}
HANDLEBARS.registerHelper("toLower", function( txt ) {
return txt && txt.trim() ? txt.toLowerCase() : '';
});
// Set up a Markdown-to-WordProcessingML helper so we can do:
// {{either A B}}
HANDLEBARS.registerHelper("either", function( lhs, rhs, options ) {
if (lhs || rhs) return options.fn(this);
});
// Set up a generic conditional helper so we can do:
// {{compare val otherVal operator="<"}}
// http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/
HANDLEBARS.registerHelper('compare', function(lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
var operator = options.hash.operator || "==";
var operators = {
'==': function(l,r) { return l == r; },
'===': function(l,r) { return l === r; },
'!=': function(l,r) { return l != r; },
'<': function(l,r) { return l < r; },
'>': function(l,r) { return l > r; },
'<=': function(l,r) { return l <= r; },
'>=': function(l,r) { return l >= r; },
'typeof': function(l,r) { return typeof l == r; }
};
if (!operators[operator])
throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
var result = operators[operator](lvalue,rvalue);
return result ? options.fn(this) : options.inverse(this);
});
};
}());

View File

@ -1,37 +1,52 @@
/** /**
Definition of the UnderscoreGenerator class. Definition of the UnderscoreGenerator class.
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk. @license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
@module underscore-generator.js
*/ */
(function() { (function() {
var _ = require('underscore'); var _ = require('underscore');
module.exports = function( json, jst, format, cssInfo, opts, theme ) {
// Tweak underscore's default template delimeters
var delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template; /**
if( opts.themeObj && opts.themeObj.delimeters ) { Perform template-based resume generation using Underscore.js.
delims = _.mapObject( delims, function(val,key) { @class UnderscoreGenerator
return new RegExp( val, "ig"); */
var UnderscoreGenerator = module.exports = {
generate: function( json, jst, format, cssInfo, opts, theme ) {
// Tweak underscore's default template delimeters
var delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
if( opts.themeObj && opts.themeObj.delimeters ) {
delims = _.mapObject( delims, function(val,key) {
return new RegExp( val, "ig");
});
}
_.templateSettings = delims;
// Strip {# comments #}
jst = jst.replace( delims.comment, '');
// Compile and run the template. TODO: avoid unnecessary recompiles.
var compiled = _.template(jst);
var ret = compiled({
r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
filt: opts.filters,
XML: require('xml-escape'),
RAW: json,
cssInfo: cssInfo,
headFragment: opts.headFragment || ''
}); });
return ret;
} }
_.templateSettings = delims;
// Strip {# comments #}
jst = jst.replace( delims.comment, '');
// Compile and run the template. TODO: avoid unnecessary recompiles.
var compiled = _.template(jst);
var ret = compiled({
r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
filt: opts.filters,
XML: require('xml-escape'),
RAW: json,
cssInfo: cssInfo,
headFragment: opts.headFragment || ''
});
return ret;
}; };
}()); }());

View File

@ -142,9 +142,8 @@ Definition of the TemplateGenerator class.
*/ */
single: function( json, jst, format, cssInfo, opts, theme ) { single: function( json, jst, format, cssInfo, opts, theme ) {
this.opts.freezeBreaks && ( jst = freeze(jst) ); this.opts.freezeBreaks && ( jst = freeze(jst) );
var eng = require( '../eng/' + ((opts.themeObj && opts.themeObj.engine) || var eng = require( '../eng/' + theme.engine + '-generator' );
opts.engine) + '-generator' ); var result = eng.generate( json, jst, format, cssInfo, opts, theme );
var result = eng( json, jst, format, cssInfo, opts, theme );
this.opts.freezeBreaks && ( result = unfreeze(result) ); this.opts.freezeBreaks && ( result = unfreeze(result) );
return result; return result;
} }

View File

@ -1,14 +1,14 @@
{ {
"basics": { "basics": {
"name": "Jane Doe", "name": "Jane Q. Fullstacker",
"label": "Senior Developer / Code Ninja", "label": "Senior Developer",
"summary": "**Full-stack software developer with 6+ years industry experience** specializing in scalable cloud architectures for this, that, and the other. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two-year-old beagle.", "summary": "**Full-stack software developer with 6+ years industry experience** specializing in scalable cloud architectures for this, that, and the other. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two-year-old beagle.",
"website": "http://jane-doe.me", "website": "http://janef.me/blog",
"phone": "1-650-999-7777", "phone": "1-650-999-7777",
"email": "jdoe@onecoolstartup.io", "email": "jdoe@onecoolstartup.io",
"picture": "jane_doe.png", "picture": "jane_doe.png",
"location": { "location": {
"address": "Jane Doe\n123 Somewhere Rd.\nMountain View, CA 94035", "address": "Jane Fullstacker\n123 Somewhere Rd.\nMountain View, CA 94035",
"postalCode": "94035", "postalCode": "94035",
"city": "Mountain View", "city": "Mountain View",
"countryCode": "US", "countryCode": "US",
@ -17,13 +17,13 @@
"profiles": [ "profiles": [
{ {
"network": "GitHub", "network": "GitHub",
"username": "jane-doe-was-here", "username": "janef-was-here",
"url": "https://github.com/jane-doe-was-here" "url": "https://github.com/janef-was-here"
}, },
{ {
"network": "Twitter", "network": "Twitter",
"username": "jane-doe-was-here", "username": "janef-was-here",
"url": "https://twitter.com/jane-doe-was-here" "url": "https://twitter.com/janef-was-here"
} }
] ]
}, },
@ -104,17 +104,55 @@
], ],
"skills": [ "skills": [
{ {
"name": "Programming", "name": "Web Dev",
"keywords": [ "keywords": [
"C++", "JavaScript",
"Ruby", "HTML 5",
"Xcode" "CSS",
"LAMP",
"MVC",
"REST"
] ]
}, },
{ {
"name": "Project Management", "name": "JavaScript",
"keywords": [ "keywords": [
"Agile" "Node.js",
"Angular.js",
"jQuery",
"Bootstrap",
"React.js",
"Backbone.js"
]
},
{
"name": "Database",
"keywords": [
"MySQL",
"PostgreSQL",
"NoSQL",
"ORM",
"Hibernate"
]
},
{
"name": "Cloud",
"keywords": [
"AWS",
"EC2",
"RDS",
"S3",
"Azure",
"Dropbox"
]
},
{
"name": "Project",
"keywords": [
"Agile",
"TFS",
"Unified Process",
"MS Project"
] ]
} }
], ],
@ -166,10 +204,10 @@
"website": "http://codeproject.com/build-ui-electron-atom.aspx" "website": "http://codeproject.com/build-ui-electron-atom.aspx"
}, },
{ {
"name": "Jane Doe Unplugged", "name": "Jane Fullstacker's Blog",
"publisher": "self", "publisher": "self",
"releaseDate": "2011", "releaseDate": "2011",
"website": "http://jane-doe.me" "website": "http://janef.me"
}, },
{ {
"name": "Teach Yourself GORFF in 21 Days", "name": "Teach Yourself GORFF in 21 Days",
@ -218,7 +256,8 @@
}, },
{ {
"language": "Spanish", "language": "Spanish",
"level": "Moderate" "level": "Moderate",
"years": 10
} }
] ]
} }

View File

@ -7,6 +7,7 @@ var chai = require('chai')
, FRESHResume = require('../src/core/fresh-resume') , FRESHResume = require('../src/core/fresh-resume')
, CONVERTER = require('../src/core/convert') , CONVERTER = require('../src/core/convert')
, FS = require('fs') , FS = require('fs')
, MKDIRP = require('mkdirp')
, _ = require('underscore'); , _ = require('underscore');
chai.config.includeStack = false; chai.config.includeStack = false;
@ -21,6 +22,7 @@ describe('FRESH/JRS converter', function () {
var fileB = path.join( __dirname, 'sandbox/richard-hendriks.json' ); var fileB = path.join( __dirname, 'sandbox/richard-hendriks.json' );
_sheet = new FRESHResume().open( fileA ); _sheet = new FRESHResume().open( fileA );
MKDIRP.sync( path.parse(fileB).dir );
_sheet.saveAs( fileB, 'JRS' ); _sheet.saveAs( fileB, 'JRS' );
var rawA = FS.readFileSync( fileA, 'utf8' ); var rawA = FS.readFileSync( fileA, 'utf8' );

View File

@ -16,7 +16,7 @@ describe('jane-doe.json (FRESH)', function () {
it('should open without throwing an exception', function () { it('should open without throwing an exception', function () {
function tryOpen() { function tryOpen() {
_sheet = new FRESHResume().open( _sheet = new FRESHResume().open(
'node_modules/FRESCA/exemplar/jane-doe.json' ); 'node_modules/jane-q-fullstacker/resume/jane-resume.json' );
} }
tryOpen.should.not.Throw(); tryOpen.should.not.Throw();
}); });
@ -43,13 +43,13 @@ describe('jane-doe.json (FRESH)', function () {
it('should save without throwing an exception', function(){ it('should save without throwing an exception', function(){
function trySave() { function trySave() {
_sheet.save( 'tests/sandbox/jane-doe.json' ); _sheet.save( 'tests/sandbox/jane-q-fullstacker.json' );
} }
trySave.should.not.Throw(); trySave.should.not.Throw();
}); });
it('should not be modified after saving', function() { it('should not be modified after saving', function() {
var savedSheet = new FRESHResume().open('tests/sandbox/jane-doe.json'); var savedSheet = new FRESHResume().open('tests/sandbox/jane-q-fullstacker.json');
_sheet.stringify().should.equal( savedSheet.stringify() ) _sheet.stringify().should.equal( savedSheet.stringify() )
}); });

View File

@ -16,7 +16,7 @@ describe('jane-doe.json (JRS)', function () {
it('should open without throwing an exception', function () { it('should open without throwing an exception', function () {
function tryOpen() { function tryOpen() {
_sheet = new JRSResume().open( _sheet = new JRSResume().open(
path.join( __dirname, 'resumes/jrs/jane-doe.json' ) ); path.join( __dirname, 'resumes/jrs/jane-q-fullstacker.json' ) );
} }
tryOpen.should.not.Throw(); tryOpen.should.not.Throw();
}); });
@ -39,13 +39,13 @@ describe('jane-doe.json (JRS)', function () {
it('should save without throwing an exception', function(){ it('should save without throwing an exception', function(){
function trySave() { function trySave() {
_sheet.save( 'tests/sandbox/jane-doe.json' ); _sheet.save( 'tests/sandbox/jane-q-fullstacker.json' );
} }
trySave.should.not.Throw(); trySave.should.not.Throw();
}); });
it('should not be modified after saving', function() { it('should not be modified after saving', function() {
var savedSheet = new JRSResume().open( 'tests/sandbox/jane-doe.json' ); var savedSheet = new JRSResume().open( 'tests/sandbox/jane-q-fullstacker.json' );
_sheet.stringify().should.equal( savedSheet.stringify() ) _sheet.stringify().should.equal( savedSheet.stringify() )
}); });

View File

@ -29,8 +29,8 @@ describe('Testing themes', function () {
function genTheme( themeName ) { function genTheme( themeName ) {
it( themeName.toUpperCase() + ' theme should generate without throwing an exception', function () { it( themeName.toUpperCase() + ' theme should generate without throwing an exception', function () {
function tryOpen() { function tryOpen() {
var src = ['node_modules/FRESCA/exemplar/jane-doe.json']; var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
var dst = ['tests/sandbox/hello-world/resume.all']; var dst = ['tests/sandbox/' + themeName + '/resume.all'];
var opts = { var opts = {
theme: themeName, theme: themeName,
format: 'FRESH', format: 'FRESH',
@ -48,5 +48,6 @@ describe('Testing themes', function () {
genTheme('modern'); genTheme('modern');
genTheme('minimist'); genTheme('minimist');
genTheme('awesome'); genTheme('awesome');
genTheme('positive');
}); });