diff options
author | Soreine <nicolas@gitbook.com> | 2016-05-09 19:51:54 +0200 |
---|---|---|
committer | Soreine <nicolas@gitbook.com> | 2016-05-11 13:11:32 +0200 |
commit | 2fef898a1e13dc6b3f2627ed83af2865f51d2ffa (patch) | |
tree | 61d3b98e7f80a1883462eb8da4dbb694ac91fc31 | |
parent | 0945807184907d4aac47d370d05b39d4029d07fa (diff) | |
download | gitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.zip gitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.tar.gz gitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.tar.bz2 |
Modifier moveArticleAfter
-rw-r--r-- | lib/modifiers/summary/__tests__/moveArticleAfter.js | 82 | ||||
-rw-r--r-- | lib/modifiers/summary/index.js | 1 | ||||
-rw-r--r-- | lib/modifiers/summary/moveArticleAfter.js | 58 |
3 files changed, 141 insertions, 0 deletions
diff --git a/lib/modifiers/summary/__tests__/moveArticleAfter.js b/lib/modifiers/summary/__tests__/moveArticleAfter.js new file mode 100644 index 0000000..c380575 --- /dev/null +++ b/lib/modifiers/summary/__tests__/moveArticleAfter.js @@ -0,0 +1,82 @@ +var Immutable = require('immutable'); +var Summary = require('../../../models/summary'); +var File = require('../../../models/file'); + +describe('moveArticleAfter', function() { + var moveArticleAfter = require('../moveArticleAfter'); + var summary = Summary.createFromParts(File(), [ + { + articles: [ + { + title: '1.1', + path: '1.1' + }, + { + title: '1.2', + path: '1.2' + } + ] + }, + { + title: 'Part I', + articles: [ + { + title: '2.1', + path: '2.1', + articles: [ + { + title: '2.1.1', + path: '2.1.1' + }, + { + title: '2.1.2', + path: '2.1.2' + } + ] + }, + { + title: '2.2', + path: '2.2' + } + ] + } + ]); + + it('moving right after itself should be invariant', function() { + var newSummary = moveArticleAfter(summary, '2.1', '2.1'); + + expect(Immutable.is(summary, newSummary)).toBe(true); + }); + + it('moving after previous one should be invariant too', function() { + var newSummary = moveArticleAfter(summary, '2.1', '2.0'); + + expect(Immutable.is(summary, newSummary)).toBe(true); + }); + + it('should move an article after a previous level', function() { + var newSummary = moveArticleAfter(summary, '2.2', '2.0'); + var moved = newSummary.getByLevel('2.1'); + + expect(moved.getTitle()).toBe('2.2'); + expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1'); + }); + + it('should move an article after a previous and less deep level', function() { + var newSummary = moveArticleAfter(summary, '2.1.1', '2.0'); + var moved = newSummary.getByLevel('2.1'); + + expect(moved.getTitle()).toBe('2.1.1'); + expect(newSummary.getByLevel('2.2.1').getTitle()).toBe('2.1.2'); + expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1'); + }); + + it('should move an article after a next level', function() { + var newSummary = moveArticleAfter(summary, '2.1', '2.2'); + var moved = newSummary.getByLevel('2.2'); + + expect(moved.getTitle()).toBe('2.1'); + expect(newSummary.getByLevel('2.1').getTitle()).toBe('2.2'); + }); + +}); diff --git a/lib/modifiers/summary/index.js b/lib/modifiers/summary/index.js index 2b84f66..3ee0367 100644 --- a/lib/modifiers/summary/index.js +++ b/lib/modifiers/summary/index.js @@ -1,6 +1,7 @@ module.exports = { insertArticle: require('./insertArticle'), moveArticle: require('./moveArticle'), + moveArticleAfter: require('./moveArticleAfter'), removeArticle: require('./removeArticle'), unshiftArticle: require('./unshiftArticle'), editArticleTitle: require('./editArticleTitle'), diff --git a/lib/modifiers/summary/moveArticleAfter.js b/lib/modifiers/summary/moveArticleAfter.js new file mode 100644 index 0000000..e03eae9 --- /dev/null +++ b/lib/modifiers/summary/moveArticleAfter.js @@ -0,0 +1,58 @@ +var is = require('is'); +var removeArticle = require('./removeArticle'); +var insertArticle = require('./insertArticle'); + +/** + Returns a new summary, with the an article moved after another article. + + @param {Summary} summary + @param {String|SummaryArticle} origin + @param {String|SummaryArticle} afterTarget + @return {Summary} +*/ +function moveArticleAfter(summary, origin, afterTarget) { + // Coerce to level + var originLevel = is.string(origin)? origin : origin.getLevel(); + var afterTargetLevel = is.string(afterTarget)? afterTarget : afterTarget.getLevel(); + var article = summary.getByLevel(originLevel); + + var targetLevel = increment(afterTargetLevel); + + if (targetLevel < origin) { + // Remove first + var removed = removeArticle(summary, originLevel); + // Insert then + return insertArticle(removed, article, targetLevel); + } else { + // Insert right after first + var inserted = insertArticle(summary, article, targetLevel); + // Remove old one + return removeArticle(inserted, originLevel); + } +} + +/** + @param {String} + @return {Array<Number>} + */ +function levelToArray(l) { + return l.split('.').map(function (char) { + return parseInt(char, 10); + }); +} + +/** + @param {Array<Number>} + @return {String} + */ +function arrayToLevel(a) { + return a.join('.'); +} + +function increment(level) { + level = levelToArray(level); + level[level.length - 1]++; + return arrayToLevel(level); +} + +module.exports = moveArticleAfter; |