diff --git a/issues/libpit/0017c3.rst b/issues/libpit/0017c3.rst new file mode 100644 index 0000000..292a7ee --- /dev/null +++ b/issues/libpit/0017c3.rst @@ -0,0 +1,26 @@ +Creating a new issue bases the next id only on the filtered issues. +=================================================================== + +Problem +------- + +This represents a more systematic error. Filtering should be applied when +viewing the data only, not when loading the data. It is possible that +operations may need the full data to modify parts of it. + +Solution +-------- + +Remove filtering fromt he project and issue construction. Double check that +filtering is correctly applied during all the access methods (eachIssue, +eachProject, each) + +Testing +------- + +Updated ProjectTest.testConstruction() to reflect changes. + +Added a test to ProjectTest.testCreateNewIssue() that needs to count a closed +task to correctly generate a new id. + +TODO: Need to create filter tests. diff --git a/libpit/project.properties b/libpit/project.properties index 727c44f..154977a 100644 --- a/libpit/project.properties +++ b/libpit/project.properties @@ -1,10 +1,10 @@ -#Thu Feb 18 11:21:57 CST 2010 +#Thu Feb 18 12:01:49 CST 2010 build.dir=build src.dir=src lib.shared.dir=../shared-libs test.dir=test -build.number=2 -expected.application.version=1.1.1 +build.number=4 +expected.application.version=1.1.2 lib.dir=lib release.dir=release release.jar=pit-${application.version}.jar diff --git a/libpit/release/pit-1.1.2.jar b/libpit/release/pit-1.1.2.jar new file mode 100644 index 0000000..195548b Binary files /dev/null and b/libpit/release/pit-1.1.2.jar differ diff --git a/libpit/src/com/jdbernard/pit/Issue.groovy b/libpit/src/com/jdbernard/pit/Issue.groovy index 8d21d9f..9e002ea 100644 --- a/libpit/src/com/jdbernard/pit/Issue.groovy +++ b/libpit/src/com/jdbernard/pit/Issue.groovy @@ -1,5 +1,7 @@ package com.jdbernard.pit +import java.lang.IllegalArgumentException as IAE + public class Issue { final String id @@ -24,21 +26,38 @@ public class Issue { text = file.text } + /** + */ void setCategory(Category c) { + + if (category == null) + throw new IAE("Category cannot be null.") + this.category = c source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) } void setPriority(int p) { - if (p < 0) priority = 0 - else if (p > 9) priority = 9 - else priority = p + + // bounds check priority + priority = Math.min(9, Math.max(0, priority)) + source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) } String getFilename() { return makeFilename(id, category, priority) } static String makeFilename(String id, Category category, int priority) { + + // bounds check priority + priority = Math.min(9, Math.max(0, priority)) + + //check for valid values of cateogry and id + if (category == null) + throw new IAE("Category must be non-null.") + if (!(/\d+/ ==~ id)) + throw new IAE( "'${id}' is not a legal value for id.") + return id + category.symbol + priority + ".rst"; } diff --git a/libpit/src/com/jdbernard/pit/Project.groovy b/libpit/src/com/jdbernard/pit/Project.groovy index 3f4e543..88d259b 100644 --- a/libpit/src/com/jdbernard/pit/Project.groovy +++ b/libpit/src/com/jdbernard/pit/Project.groovy @@ -7,7 +7,7 @@ class Project { Map projects = [:] File source - Project(File dir, Filter filter = null) { + Project(File dir) { if (!dir.isDirectory()) throw new IllegalArgumentException( "${dir.name} is not a directory.") @@ -19,20 +19,16 @@ class Project { // add sub projects if (child.isDirectory()) { - if ( child.name ==~ /\d{4}/ || // just an issue folder - (filter && !filter.accept(child.name))) - return + if ( child.name ==~ /\d{4}/) return // just an issue folder // otherwise build and add to list - projects[(child.name)] = new Project(child, filter) + projects[(child.name)] = new Project(child) } else if (child.isFile()) { def issue // if exception, then not an issue try { issue = new Issue(child) } catch (all) { return } - if (filter && !filter.accept(issue)) return - issues[(issue.id)] = issue } } @@ -47,15 +43,19 @@ class Project { public void eachIssue(Filter filter = null, Closure c) { def sorter = filter?.issueSorter ?: Filter.defaultIssueSorter - for (i in issues.values().sort(sorter)) c.call(i) + for (i in issues.values().sort(sorter)) + if (!filter || filter.accept(i)) + c.call(i) } public void eachProject(Filter filter = null, Closure c) { def sorter = filter?.projectSorter ?: Filter.defaultProjectSorter - for (p in projects.values().sort(sorter)) c.call(p) + for (p in projects.values().sort(sorter)) + if (!filter || filter.accept(p)) + c.call(p) } - public void each(Filter filter = null, Closure c) { + /*public void each(Filter filter = null, Closure c) { def is = filter?.issueSorter ?: Filter.defaultIssueSorter def ps = filter?.projectSorter ?: Filter.defaultProjectSorter @@ -72,15 +72,19 @@ class Project { c.call(project) } - } + }*/ public Issue createNewIssue(Map options) { if (!options.category) options.category = Category.TASK if (!options.priority) options.priority = 5 if (!options.text) options.text = "Default issue title.\n" + "====================\n" - String id = (issues.values().max { it.id.toInteger() }).id - id = (id.toInteger() + 1).toString().padLeft(id.length(), '0') + String id + if (issues.size() == 0) id = '0000' + else { + id = (issues.values().max { it.id.toInteger() }).id + id = (id.toInteger() + 1).toString().padLeft(id.length(), '0') + } def issueFile = new File(source, Issue.makeFilename(id, options.category, options.priority)) assert !issueFile.exists() diff --git a/libpit/test/com/jdbernard/pit/IssueTest.groovy b/libpit/test/com/jdbernard/pit/IssueTest.groovy index 2221e11..456e968 100644 --- a/libpit/test/com/jdbernard/pit/IssueTest.groovy +++ b/libpit/test/com/jdbernard/pit/IssueTest.groovy @@ -3,6 +3,7 @@ package com.jdbernard.pit import org.junit.* import static org.junit.Assert.assertTrue import static org.junit.Assert.assertFalse +import static org.junit.Assert.assertEquals class IssueTest { @@ -33,19 +34,19 @@ class IssueTest { } @After void deleteIssueFiles() { - testDir.deleteDir() + assert testDir.deleteDir() } @Test void testSetCategory() { - assertTrue issues[0].category == Category.FEATURE - assertTrue issues[1].category == Category.TASK + assertEquals issues[0].category, Category.FEATURE + assertEquals issues[1].category, Category.TASK issues[0].category = Category.CLOSED issues[1].category = Category.BUG - assertTrue issues[0].category == Category.CLOSED - assertTrue issues[1].category == Category.BUG + assertEquals issues[0].category, Category.CLOSED + assertEquals issues[1].category, Category.BUG assertTrue new File(testDir, '0001c1.rst').exists() assertTrue new File(testDir, '0002b5.rst').exists() @@ -55,14 +56,14 @@ class IssueTest { @Test void testSetPriority() { - assertTrue issues[0].priority == 1 - assertTrue issues[1].priority == 5 + assertEquals issues[0].priority, 1 + assertEquals issues[1].priority, 5 issues[0].priority = 2 issues[1].priority = 9 - assertTrue issues[0].priority == 2 - assertTrue issues[1].priority == 9 + assertEquals issues[0].priority, 2 + assertEquals issues[1].priority, 9 assertTrue new File(testDir, '0001f2.rst').exists() assertTrue new File(testDir, '0002t9.rst').exists() @@ -74,13 +75,32 @@ class IssueTest { File issueFile = new File(testDir, '0001f1.rst') Issue issue = new Issue(issueFile) - assertTrue issue.id == "0001" - assertTrue issue.category == Category.FEATURE - assertTrue issue.priority == 1 - assertTrue issue.title == "Add the killer feature to the killer app." - assertTrue issue.text == "Add the killer feature to the killer app.\n" + - "=========================================\n\n" + - "Make our killer app shine!." - assertTrue issue.source == issueFile + assertEquals issue.id , "0001" + assertEquals issue.category , Category.FEATURE + assertEquals issue.priority , 1 + assertEquals issue.title , "Add the killer feature to the killer app." + assertEquals issue.text , "Add the killer feature to the killer app.\n" + + "=========================================\n\n" + + "Make our killer app shine!." + assertEquals issue.source , issueFile + } + + @Test void testMakeFilename() { + assertEquals Issue.makeFilename('0001', Category.BUG, 5) , '0001b5.rst' + assertEquals Issue.makeFilename('0010', Category.FEATURE, 1), '0010f1.rst' + assertEquals Issue.makeFilename('0002', Category.CLOSED, 3) , '0002c3.rst' + assertEquals Issue.makeFilename('0001', Category.BUG, -2) , '0001b0.rst' + assertEquals Issue.makeFilename('0001', Category.TASK, 10) , '0001t9.rst' + assertEquals Issue.makeFilename('00101', Category.BUG, 5) , '00101b5.rst' + + try { + Issue.makeFilename('badid', Category.BUG, 5) + assertTrue 'Issue.makeFilename() succeeded with bad id input.', false + } catch (IllegalArgumentException iae) {} + + try { + Issue.makeFilename('0002', null, 5) + assertTrue 'Issue.makeFilename() succeeded given no Category.', false + } catch (IllegalArgumentException iae) {} } } diff --git a/libpit/test/com/jdbernard/pit/ProjectTest.groovy b/libpit/test/com/jdbernard/pit/ProjectTest.groovy index 044c474..f3627df 100644 --- a/libpit/test/com/jdbernard/pit/ProjectTest.groovy +++ b/libpit/test/com/jdbernard/pit/ProjectTest.groovy @@ -3,8 +3,10 @@ package com.jdbernard.pit import org.junit.After import org.junit.Before import org.junit.Test -import static org.junit.Assert.assertTrue +import static org.junit.Assert.assertEquals import static org.junit.Assert.assertFalse +import static org.junit.Assert.assertNotNull +import static org.junit.Assert.assertTrue class ProjectTest { @@ -12,9 +14,25 @@ class ProjectTest { Project rootProj @Before void createTestProjects() { + testDir = new File('testdir') + assert !testDir.exists() testDir.mkdirs() + /* TEST SUITE: + /testdir/ + 0001t5.rst + 0002b5.rst + 0003f2.rst + + subproj1/ + 0001f3.rst + 0002b4.rst + + emptyproj/ + + */ + def issueFile = new File(testDir, '0001t5.rst') issueFile.createNewFile() issueFile.write('Test Issue 1\n' + @@ -27,7 +45,7 @@ class ProjectTest { '========\n\n' + 'Yeah, it is a test bug.') - issueFile = new File(testDir, '0003f2.rst') + issueFile = new File(testDir, '0003c2.rst') issueFile.createNewFile() issueFile.write('Important Feature Request\n' + '=========================\n\n' + @@ -48,40 +66,51 @@ class ProjectTest { '==========================\n\n' + 'For some reason, the Zippners are bilperring, not zippning.') + subDir = new File(testDir, 'emptyproj') + subDir.mkdirs() + rootProj = new Project(testDir) } @After void deleteTestProjects() { - testDir.delete() + assert testDir.deleteDir() + + if (rootProj.source.exists()) + assert rootProj.source.deleteDir() } @Test void testConstruction() { - Project proj = new Project(testDir, null) + Project proj = new Project(testDir) - assertTrue proj.name == 'testdir' - assertTrue proj.issues.size() == 3 - assertTrue proj.projects.size() == 1 + assertEquals proj.name, 'testdir' + assertEquals proj.issues.size(), 3 + assertEquals proj.projects.size(), 1 // Issue construction in general is under test in IssueTest // just check that the issues actually exists - assertTrue proj.issues['0001'].id == '0001' - assertTrue proj.issues['0001'].title == 'Test Issue 1' + assertEquals proj.issues['0001'].id, '0001' + assertEquals proj.issues['0001'].title, 'Test Issue 1' - assertTrue proj.issues['0002'].id == '0002' - assertTrue proj.issues['0002'].title == 'Test Bug' + assertEquals proj.issues['0002'].id, '0002' + assertEquals proj.issues['0002'].title, 'Test Bug' - assertTrue proj.issues['0003'].id == '0003' - assertTrue proj.issues['0003'].title == 'Important Feature Request' + assertEquals proj.issues['0003'].id, '0003' + assertEquals proj.issues['0003'].title, 'Important Feature Request' // check sub-project behaviour - assertTrue proj.projects.subproj1 != null - assertTrue proj.projects.subproj1.name == 'subproj1' - assertTrue proj.projects.subproj1.issues.size() == 2 - assertTrue proj.projects.subproj1.projects.size() == 0 - assertTrue proj.projects.subproj1.issues['0001'].id == '0001' - assertTrue proj.projects.subproj1.issues['0001'].title == 'First feature in subproject' - assertTrue proj.projects.subproj1.issues['0002'].id == '0002' - assertTrue proj.projects.subproj1.issues['0002'].title == 'Zippners are not zippning.' + assertNotNull proj.projects.subproj1 + assertEquals proj.projects.subproj1.name, 'subproj1' + assertEquals proj.projects.subproj1.issues.size(), 2 + assertEquals proj.projects.subproj1.projects.size(), 0 + assertEquals proj.projects.subproj1.issues['0001'].id, '0001' + assertEquals proj.projects.subproj1.issues['0002'].id, '0002' + assertEquals proj.projects.subproj1.issues['0001'].title, + 'First feature in subproject' + assertEquals proj.projects.subproj1.issues['0002'].title, + 'Zippners are not zippning.' + + assertNotNull proj.projects.emptyproj + assertEquals proj.projects.emptyproj.size(), 0 } @Test void testRename() { @@ -89,10 +118,34 @@ class ProjectTest { rootProj.rename('renamedTestDir') - assertTrue rootProj.name == 'renamedTestDir' + assertEquals rootProj.name, 'renamedTestDir' assertTrue new File('renamedTestDir').exists() } + @Test void testCreateNewIssue() { + + // test correct increment of id, application of values + def newIssue = rootProj.createNewIssue(category: Category.BUG, + priority: 4, text: 'A newly made bug report.\n'+ + '========================\n\n' + + 'Testing the Project.createNewIssue() method.') + + assertEquals newIssue.id, '0004' + assertEquals newIssue.priority, 4 + assertEquals newIssue.text, 'A newly made bug report.\n'+ + '========================\n\n' + + 'Testing the Project.createNewIssue() method.' + + //test defaults and creation of issue in an empty project + newIssue = rootProj.projects.emptyproj.createNewIssue() + + assertEquals newIssue.id, '0000' + assertEquals newIssue.priority, 5 + assertEquals newIssue.text, 'Default issue title.\n' + + '====================\n' + + } + /*@Test void testEachIssue() { def expectedList = [rootProj.issues['0001'], rootProj.issues['0002'], rootProj.issues['0003']] diff --git a/pit-cli/lib/pit-1.1.0.jar b/pit-cli/lib/pit-1.1.0.jar deleted file mode 100644 index 885a6b6..0000000 Binary files a/pit-cli/lib/pit-1.1.0.jar and /dev/null differ diff --git a/libpit/release/pit-1.1.1.jar b/pit-cli/lib/pit-1.1.1.jar similarity index 100% rename from libpit/release/pit-1.1.1.jar rename to pit-cli/lib/pit-1.1.1.jar diff --git a/pit-cli/project.properties b/pit-cli/project.properties index afe8063..7918cdb 100644 --- a/pit-cli/project.properties +++ b/pit-cli/project.properties @@ -1,9 +1,9 @@ -#Thu Feb 18 11:10:29 CST 2010 +#Thu Feb 18 11:26:18 CST 2010 build.dir=build src.dir=src build.jar=pit-cli-${application.version}.${build.number}.jar -build.number=31 -expected.application.version=1.1.0 +build.number=1 +expected.application.version=1.1.1 lib.dir=lib release.dir=release release.jar=pit-cli-${application.version}.jar diff --git a/pit-cli/release/pit-cli-1.1.0.jar b/pit-cli/release/pit-cli-1.1.1.jar similarity index 95% rename from pit-cli/release/pit-cli-1.1.0.jar rename to pit-cli/release/pit-cli-1.1.1.jar index 73cfafd..d457464 100644 Binary files a/pit-cli/release/pit-cli-1.1.0.jar and b/pit-cli/release/pit-cli-1.1.1.jar differ diff --git a/version.properties b/version.properties index d7fcd50..b5db596 100644 --- a/version.properties +++ b/version.properties @@ -1 +1 @@ -application.version=1.1.1 +application.version=1.1.2