diff --git a/spec/treeCompare.spec.js b/spec/treeCompare.spec.js index ecb6dbb0..9fa03173 100644 --- a/spec/treeCompare.spec.js +++ b/spec/treeCompare.spec.js @@ -9,10 +9,13 @@ var loadTree = function(treeString) { return TreeCompare.convertTreeSafe(treeString); }; -var testMethod = function(compareMethod, goalTreeString, cases) { +var testMethod = function(compareMethod, goalTreeString, cases, options) { cases = cases || {}; - // always expect the goal to compare to itself correctly - cases[goalTreeString] = true; + options = options || {}; + if (!options.dontCompareGoal) { + // always expect the goal to compare to itself correctly + cases[goalTreeString] = true; + } _.each(cases, function(value, actualTree) { var isEqual = TreeCompare.dispatch(compareMethod, goalTreeString, actualTree); @@ -26,6 +29,62 @@ var testMethod = function(compareMethod, goalTreeString, cases) { }; describe('Tree Compare', function() { + it('will return false early if goal missing origin', function() { + testMethod( + {}, // checked for all methods + '{}', // no origin tree + { + '{"originTree":{}}': false + }, { + dontCompareGoal: true + } + ); + }); + + it('will return false early if current missing origin', function() { + testMethod( + {}, // checked for all methods + '{"originTree":{}}', + { + '{}': false + }, { + dontCompareGoal: true + } + ); + }); + + it('deep compares on origin tree', function() { + testMethod( + {}, // checked for all methods so this doesnt matter + // state with originTree + '{"branches":{"master":{"target":"C1","id":"master"},"o/master":{"target":"C1","id":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C1","id":"master","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 09:58:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 09:58:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}', + { + // one extra commit in origin + '{"branches":{"master":{"target":"C1","id":"master"},"o/master":{"target":"C1","id":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C2","id":"master","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 10:24:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 10:24:50 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"},"C2":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 10:24:55 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C2"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}': false, + // extra commit local + '{"branches":{"master":{"target":"C2","id":"master"},"o/master":{"target":"C1","id":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C1","id":"master","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:31:20 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:31:20 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}': false + } + ); + }); + + it('uses originCompare for the origin comparison results', function() { + testMethod({ + // compare all branches and head locally, but only master remotely + originCompare: { + compareOnlyMaster: true + } + }, + // start with a local / origin with two branches + '{"branches":{"master":{"target":"C3","id":"master"},"side":{"target":"C2","id":"side"},"o/master":{"target":"C3","id":"o/master"},"o/side":{"target":"C2","id":"o/side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C3","id":"master","type":"branch"},"side":{"remoteTrackingBranch":null,"remote":false,"target":"C2","id":"side","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"},"C2":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C2"},"C3":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C3"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}', + { + // committing remotely on other branch is fine + '{"branches":{"master":{"target":"C3","id":"master"},"side":{"target":"C2","id":"side"},"o/master":{"target":"C3","id":"o/master"},"o/side":{"target":"C2","id":"o/side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C3","id":"master","type":"branch"},"side":{"remoteTrackingBranch":null,"remote":false,"target":"C4","id":"side","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"},"C2":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C2"},"C3":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C3"},"C4":{"type":"commit","parents":["C2"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:35:38 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C4"}},"HEAD":{"target":"side","id":"HEAD","type":"general ref"}}}': true, + // but committing on master is not ok + '{"branches":{"master":{"target":"C3","id":"master"},"side":{"target":"C2","id":"side"},"o/master":{"target":"C3","id":"o/master"},"o/side":{"target":"C2","id":"o/side"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"remoteTrackingBranch":null,"remote":false,"target":"C5","id":"master","type":"branch"},"side":{"remoteTrackingBranch":null,"remote":false,"target":"C4","id":"side","type":"branch"}},"commits":{"C0":{"type":"commit","parents":[],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C0","rootCommit":true},"C1":{"type":"commit","parents":["C0"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C1"},"C2":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C2"},"C3":{"type":"commit","parents":["C1"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:34:45 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C3"},"C4":{"type":"commit","parents":["C2"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:35:38 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C4"},"C5":{"type":"commit","parents":["C3"],"author":"Peter Cottle","createTime":"Wed Jul 24 2013 12:37:44 GMT-0700 (PDT)","commitMessage":"Quick commit. Go Bears!","id":"C5"}},"HEAD":{"target":"master","id":"HEAD","type":"general ref"}}}': false + } + ); + }); + it('has default behavior to check all branches and master', function() { testMethod( {}, // default method, which is compare all branches and HEAD diff --git a/src/js/git/treeCompare.js b/src/js/git/treeCompare.js index 91392b81..58144167 100644 --- a/src/js/git/treeCompare.js +++ b/src/js/git/treeCompare.js @@ -21,22 +21,56 @@ TreeCompare.onlyMasterCompared = function(levelBlob) { }; TreeCompare.dispatch = function(levelBlob, goalTreeString, treeToCompare) { + var goalTree = this.convertTreeSafe(goalTreeString); + treeToCompare = this.convertTreeSafe(treeToCompare); + if (typeof goalTree.originTree !== typeof treeToCompare.originTree) { + // origin status does not match + return false; + } + var shallowResult = this.dispatchShallow( + levelBlob, goalTree, treeToCompare + ); + if (!shallowResult || !goalTree.originTree) { + // we only have one level (or failed on shallow), punt + return shallowResult; + } + + var originBlob = (levelBlob.originCompare) ? + levelBlob.originCompare : levelBlob; + // compare origin trees + return shallowResult && this.dispatchShallow( + originBlob, goalTree.originTree, treeToCompare.originTree + ); +}; + +TreeCompare.dispatchShallow = function(levelBlob, goalTreeString, treeToCompare) { var getAroundLintTrue = true; // i actually prefer this to else if switch (getAroundLintTrue) { case !!levelBlob.compareOnlyMaster: - return TreeCompare.compareBranchWithinTrees(treeToCompare, goalTreeString, 'master'); + return TreeCompare.compareBranchWithinTrees( + treeToCompare, goalTreeString, 'master' + ); case !!levelBlob.compareOnlyBranches: - return TreeCompare.compareAllBranchesWithinTrees(treeToCompare, goalTreeString); + return TreeCompare.compareAllBranchesWithinTrees( + treeToCompare, goalTreeString + ); case !!levelBlob.compareAllBranchesHashAgnostic: - return TreeCompare.compareAllBranchesWithinTreesHashAgnostic(treeToCompare, goalTreeString); + return TreeCompare.compareAllBranchesWithinTreesHashAgnostic( + treeToCompare, goalTreeString + ); case !!levelBlob.compareOnlyMasterHashAgnostic: - return TreeCompare.compareBranchesWithinTreesHashAgnostic(treeToCompare, goalTreeString, ['master']); + return TreeCompare.compareBranchesWithinTreesHashAgnostic( + treeToCompare, goalTreeString, ['master'] + ); case !!levelBlob.compareOnlyMasterHashAgnosticWithAsserts: - return TreeCompare.compareBranchesWithinTreesHashAgnostic(treeToCompare, goalTreeString, ['master']) && - TreeCompare.evalAsserts(treeToCompare, levelBlob.goalAsserts); + return TreeCompare.compareBranchesWithinTreesHashAgnostic( + treeToCompare, goalTreeString, ['master'] + ) && TreeCompare.evalAsserts(treeToCompare, levelBlob.goalAsserts); default: - return TreeCompare.compareAllBranchesWithinTreesAndHEAD(treeToCompare, goalTreeString); + return TreeCompare.compareAllBranchesWithinTreesAndHEAD( + treeToCompare, goalTreeString + ); } }; diff --git a/todo.txt b/todo.txt index abed81cf..fa47be62 100644 --- a/todo.txt +++ b/todo.txt @@ -21,12 +21,10 @@ Easier origin things: - git push takes in an argument, and has to check if the remote branch exists, and makes it otherwise (after pushing) [ ] finally work on an upload / download animation -[ ] do a cute uploading thing Origin things: ~~~~~~~~~~~~~~~~~~~~~~~~~~ [ ] set checkout -b branch __remoteBranch to track the remote branch -[ ] tree comparison with origin.... sigh [ ] prototype visual layout (background change + header? maybe...) Medium things: @@ -50,6 +48,7 @@ Ideas for cleaning Done things: (I only started this on Dec 17th 2012 to get a better sense of what was done) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[x] tree comparison with origin.... done! not too bad [x] green refactor tree compare to have map [x] increase test coverage over everything - unit and integration, but mostly for git operations