Forráskód Böngészése

refactor and separate stuff before going TDD

Benoît Hubert 8 éve
szülő
commit
41db00fa9f
7 módosított fájl, 188 hozzáadás és 122 törlés
  1. 3 1
      js/editor.js
  2. 3 3
      lib/ExampleStore.js
  3. 50 0
      lib/fsio.js
  4. 93 0
      lib/indexHandlers.js
  5. 0 24
      lib/scandir.js
  6. 4 0
      package.json
  7. 35 94
      sandboxApp.js

+ 3 - 1
js/editor.js

@@ -73,13 +73,15 @@ $(document).ready(function() {
   }
 
 
+  /**
+   * File list tabs click handler
+   */
   $tabItems.click(function() {
     var clickedItem = $(this);
     var type = clickedItem.data('type');
     editorSession.setMode("ace/mode/" + mapTypes[type]);
     var name = clickedItem.html();
     var file = _webSandboxFiles.find(f => (f.name === name));
-    console.log(type, mapTypes[type], name, file);
     editorSession.setValue(file.content);
     // saveToLocalStorage();
     // var mode = $(this).prop('id').substr(5);

+ 3 - 3
lib/ExampleStore.js

@@ -1,4 +1,4 @@
-const scandir = require('./scandir');
+const { scandirAsync } = require('./fsio');
 var Promise   = require('bluebird');
 var _         = require('lodash');
 function ExampleStore(path) {
@@ -8,7 +8,7 @@ function ExampleStore(path) {
 
 ExampleStore.prototype.init = function() {
   const loadRepository = this.loadRepository.bind(this);
-  return scandir(this.rootPath, ['.gitkeep'])
+  return scandirAsync(this.rootPath, ['.gitkeep'])
   .then(repositories => Promise.map(
     repositories, loadRepository
   ));
@@ -24,7 +24,7 @@ ExampleStore.prototype.loadRepository = function(repoPath) {
     examples: []
   });
   this.repos.push(repoDescriptor);
-  return scandir(fullPath, ['.gitkeep', 'repo-config.json'])
+  return scandirAsync(fullPath, ['.gitkeep', 'repo-config.json'])
   .then(examples => Promise.map(
     examples, example => loadExample(repoDescriptor, example)
   ))

+ 50 - 0
lib/fsio.js

@@ -0,0 +1,50 @@
+/**
+ * This has to be required *after* using Bluebird's promisifyAll() on fs
+ */
+var fs      = require('fs');
+var path    = require('path');
+var Promise = require('bluebird');
+
+if(typeof fs.readdirAsync !== 'function') {
+  console.error("scandirAsync module requires promisifying fs with Bluebird's Promise.promisifyAll()");
+}
+
+function scandirAsync(path, excludes) {
+  excludes = excludes || [];
+  return fs.readdirAsync(path)
+  .then(dirContent => {
+    excludes.forEach(file => {
+      var idxInContent = dirContent.indexOf(file);
+      if(idxInContent !== -1) {
+        dirContent.splice(idxInContent, 1);
+      }
+    });
+    return dirContent;
+  });
+}
+
+function readFileAsync(file) {
+  return fs.readFileAsync(file)
+  .then(buf => (buf.toString()));
+}
+
+function readFilesAsync(fullPath, files) {
+  // console.log('reading files', files, 'from path', path);
+  return Promise.reduce(files,
+    (carry, f) => readFileAsync(fullPath + '/' + f)
+      .then(content => 
+        (carry.concat([{
+          type: path.extname(f).substr(1),
+          name: f,
+          content
+        }]))
+      ),
+    []
+  );
+}
+
+module.exports = {
+  scandirAsync,
+  readFileAsync,
+  readFilesAsync
+};

+ 93 - 0
lib/indexHandlers.js

@@ -0,0 +1,93 @@
+/* global __dirname */
+"use strict";
+var _             = require('lodash');
+var Mustache      = require('mustache');
+var path          = require('path');
+var fs            = require('fs');
+var indexTmplPath = path.normalize(__dirname + '/../html/index.mustache.html');
+var indexTpml     = fs.readFileSync(indexTmplPath).toString();
+var {
+  readFilesAsync
+}                 = require('../lib/fsio');
+
+function readExampleFiles(repoSlug, exampleSlug, config) {
+  const exampleDir = path.normalize(__dirname + '/../exemples/' + repoSlug + '/' + exampleSlug);
+  const libsCssDir = path.normalize(__dirname + '/../css/vendor');
+  const libsJsDir  = path.normalize(__dirname + '/../js/vendor');
+  const { html, js, css } = config; // libsCss, libsJs 
+  const files = [].concat(html, js, css);
+  return readFilesAsync(exampleDir, files);
+}
+
+
+module.exports = function(exStore) {
+
+  return {
+
+    /**
+     * Get bare index without repo or examples
+     */
+    getIndexBare: function(req, res) {
+      const menuRepo = exStore.getRepoMenu();
+      // const title    = 'Home';
+      console.log(menuRepo);
+      res.send(Mustache.render(indexTpml, {
+        // title,
+        menuRepo
+      }));
+    },
+
+
+    /**
+     * Get index with repo selected only
+     */
+    getIndexRepo: function getIndexRepo(req, res) {
+      const repo = exStore.getRepo(req.params.repoSlug);
+      if(! repo) {
+        return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
+      }
+      const menuRepo = exStore.getRepoMenu();
+      const menuExample = exStore.getExampleMenu(repo.path);
+      // const title    = 'Home';
+      console.log(menuExample);
+      res.send(Mustache.render(indexTpml, {
+        // title,
+        menuRepo,
+        menuExample
+      }));
+    },
+
+
+    /**
+     * Get index with selected repo&example
+     */
+    getIndexExample: function(req, res) {
+      const repo = exStore.getRepo(req.params.repoSlug);
+      if(! repo) {
+        return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
+      }
+      const menuRepo = exStore.getRepoMenu();
+      const menuExample = exStore.getExampleMenu(repo.path);
+      const example = _.find(repo.examples, { slug: req.params.exampleSlug });
+      if(! example) {
+        return res.status(404).send('Example ' + req.params.repoSlug + '/' + req.params.exampleSlug + ' not found');
+      }
+      // const title    = 'Home';
+      console.log(menuExample);
+      const { repoSlug, exampleSlug } = req.params;
+      readExampleFiles(repoSlug, exampleSlug, example)
+      .then(files => {
+        // console.log('example files', html, js, css);
+        res.send(Mustache.render(indexTpml, {
+          // title,
+          menuRepo,
+          menuExample,
+          files,
+          filesJSON: JSON.stringify(files)
+        }));
+      });
+    }
+
+  };
+
+};

+ 0 - 24
lib/scandir.js

@@ -1,24 +0,0 @@
-/**
- * This has to be required *after* using Bluebird's promisifyAll() on fs
- */
-var fs = require('fs');
-
-if(typeof fs.readdirAsync !== 'function') {
-  console.error("scandir module requires promisifying fs with Bluebird's Promise.promisifyAll()");
-}
-
-function scandir(path, excludes) {
-  excludes = excludes || [];
-  return fs.readdirAsync(path)
-  .then(dirContent => {
-    excludes.forEach(file => {
-      var idxInContent = dirContent.indexOf(file);
-      if(idxInContent !== -1) {
-        dirContent.splice(idxInContent, 1);
-      }
-    });
-    return dirContent;
-  })
-}
-
-module.exports = scandir;

+ 4 - 0
package.json

@@ -9,5 +9,9 @@
     "lodash": "^4.17.4",
     "mustache": "^2.3.0",
     "slug": "^0.9.1"
+  },
+  "devDependencies": {
+    "chai": "^4.1.2",
+    "mocha": "^4.0.1"
   }
 }

+ 35 - 94
sandboxApp.js

@@ -1,25 +1,40 @@
 /* global __dirname */
 /* jshint strict:false */
 "use strict";
-var express      = require('express');
-var bodyParser   = require('body-parser');
-var slug         = require('slug');
-var beautify     = require("json-beautify");
-var _            = require('lodash');
-var fs           = require('fs');
-var path         = require('path');
-var Promise      = require('bluebird');
-var Mustache     = require('mustache');
-var app          = express();
-var ExampleStore = require('./lib/ExampleStore');
-var indexTpml    = fs.readFileSync(__dirname + '/html/index.mustache.html').toString();
-var sandboxTpml  = fs.readFileSync(__dirname + '/html/template.mustache.html').toString();
-Promise.promisifyAll(fs);
-var exStore     = new ExampleStore(__dirname + '/exemples');
+var express       = require('express');
+var bodyParser    = require('body-parser');
+var slug          = require('slug');
+var beautify      = require("json-beautify");
+var _             = require('lodash');
+var path          = require('path');
+var Mustache      = require('mustache');
+var app           = express();
+var fs            = require('fs');
+var Promise       = require('bluebird'); Promise.promisifyAll(fs);
+var sandboxTpml   = fs.readFileSync(__dirname + '/html/template.mustache.html').toString();
+var ExampleStore  = require('./lib/ExampleStore');
+var exStore       = new ExampleStore(__dirname + '/exemples');
+var {
+  readFileAsync,
+  readFilesAsync
+}                 = require('./lib/fsio');
+var {
+  getIndexBare,
+  getIndexRepo,
+  getIndexExample
+}                 = require('./lib/indexHandlers')(exStore);
+
+
+/**
+ * Initialize example store
+ */
 exStore.init()
 .then(() => console.log(exStore.getMenu()));
 
-// Initialize Express app: root folder as static, body parsers
+
+/**
+ * Initialize Express app: root folder as static, body parsers
+ */
 app.use(express.static(__dirname));
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({ extended: true }));
@@ -35,100 +50,26 @@ function readConfigJson(exampleSlug) {
   return require('./exemples/jquery/' + exampleSlug + '/config.json');
 }
 
-function readFileAsync(file) {
-  return fs.readFileAsync(file)
-  .then(buf => (buf.toString()));
-}
 
-function readFilesAsync(fullPath, files) {
-  // console.log('reading files', files, 'from path', path);
-  return Promise.reduce(files,
-    (carry, f) => readFileAsync(fullPath + '/' + f)
-      .then(content => 
-        (carry.concat([{
-          type: path.extname(f).substr(1),
-          name: f,
-          content
-        }]))
-      ),
-    []
-  );
-}
 
-function readExampleFiles(repoSlug, exampleSlug, config) {
-  const exampleDir = __dirname + '/exemples/' + repoSlug + '/' + exampleSlug;
-  const libsCssDir = __dirname + '/css/vendor';
-  const libsJsDir  = __dirname + '/js/vendor';
-  const { html, js, css } = config; // libsCss, libsJs 
-  const files = [].concat(html, js, css);
-  return readFilesAsync(exampleDir, files);
-}
+
 
 
 /**
  * Index page: render with only repo list in menu
  */
-app.get('/', function(req, res) {
-  const menuRepo = exStore.getRepoMenu();
-  // const title    = 'Home';
-  console.log(menuRepo);
-  res.send(Mustache.render(indexTpml, {
-    title,
-    menuRepo
-  }));
-});
+app.get('/', getIndexBare);
 
 /**
  * Repo page: render with repo list and selected repo's example list in menu
  */
-app.get('/:repoSlug',
-  function(req, res) {
-    const repo = exStore.getRepo(req.params.repoSlug);
-    if(! repo) {
-      return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
-    }
-    const menuRepo = exStore.getRepoMenu();
-    const menuExample = exStore.getExampleMenu(repo.path);
-    // const title    = 'Home';
-    console.log(menuExample);
-    res.send(Mustache.render(indexTpml, {
-      // title,
-      menuRepo,
-      menuExample
-    }));
-});
+app.get('/:repoSlug', getIndexRepo);
 
 /**
  * Example page: render with repo list and selected repo's example list in menu,
  * and the editor with the selected example
  */
-app.get('/:repoSlug/:exampleSlug',
-  function(req, res) {
-    const repo = exStore.getRepo(req.params.repoSlug);
-    if(! repo) {
-      return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
-    }
-    const menuRepo = exStore.getRepoMenu();
-    const menuExample = exStore.getExampleMenu(repo.path);
-    const example = _.find(repo.examples, { slug: req.params.exampleSlug });
-    if(! example) {
-      return res.status(404).send('Example ' + req.params.repoSlug + '/' + req.params.exampleSlug + ' not found');
-    }
-    // const title    = 'Home';
-    console.log(menuExample);
-    const { repoSlug, exampleSlug } = req.params;
-    readExampleFiles(repoSlug, exampleSlug, example)
-    .then(files => {
-      // console.log('example files', html, js, css);
-      res.send(Mustache.render(indexTpml, {
-        // title,
-        menuRepo,
-        menuExample,
-        files,
-        filesJSON: JSON.stringify(files)
-      }));
-    });
-});
+app.get('/:repoSlug/:exampleSlug', getIndexExample);
 
 app.post('/examples', function(req, res) {
   var title = req.body.title;