Awaiting testing before releasing 1.1.2

This commit is contained in:
Jonathan Bernard 2010-02-18 20:45:20 -06:00
parent 9c2898729f
commit 1e5ebe89bf
12 changed files with 184 additions and 62 deletions

26
issues/libpit/0017c3.rst Normal file
View File

@ -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.

View File

@ -1,10 +1,10 @@
#Thu Feb 18 11:21:57 CST 2010 #Thu Feb 18 12:01:49 CST 2010
build.dir=build build.dir=build
src.dir=src src.dir=src
lib.shared.dir=../shared-libs lib.shared.dir=../shared-libs
test.dir=test test.dir=test
build.number=2 build.number=4
expected.application.version=1.1.1 expected.application.version=1.1.2
lib.dir=lib lib.dir=lib
release.dir=release release.dir=release
release.jar=pit-${application.version}.jar release.jar=pit-${application.version}.jar

Binary file not shown.

View File

@ -1,5 +1,7 @@
package com.jdbernard.pit package com.jdbernard.pit
import java.lang.IllegalArgumentException as IAE
public class Issue { public class Issue {
final String id final String id
@ -24,21 +26,38 @@ public class Issue {
text = file.text text = file.text
} }
/**
*/
void setCategory(Category c) { void setCategory(Category c) {
if (category == null)
throw new IAE("Category cannot be null.")
this.category = c this.category = c
source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) source.renameTo(new File(source.canonicalFile.parentFile, getFilename()))
} }
void setPriority(int p) { void setPriority(int p) {
if (p < 0) priority = 0
else if (p > 9) priority = 9 // bounds check priority
else priority = p priority = Math.min(9, Math.max(0, priority))
source.renameTo(new File(source.canonicalFile.parentFile, getFilename())) source.renameTo(new File(source.canonicalFile.parentFile, getFilename()))
} }
String getFilename() { return makeFilename(id, category, priority) } String getFilename() { return makeFilename(id, category, priority) }
static String makeFilename(String id, Category category, int 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"; return id + category.symbol + priority + ".rst";
} }

View File

@ -7,7 +7,7 @@ class Project {
Map<String, Project> projects = [:] Map<String, Project> projects = [:]
File source File source
Project(File dir, Filter filter = null) { Project(File dir) {
if (!dir.isDirectory()) if (!dir.isDirectory())
throw new IllegalArgumentException( throw new IllegalArgumentException(
"${dir.name} is not a directory.") "${dir.name} is not a directory.")
@ -19,20 +19,16 @@ class Project {
// add sub projects // add sub projects
if (child.isDirectory()) { if (child.isDirectory()) {
if ( child.name ==~ /\d{4}/ || // just an issue folder if ( child.name ==~ /\d{4}/) return // just an issue folder
(filter && !filter.accept(child.name)))
return
// otherwise build and add to list // otherwise build and add to list
projects[(child.name)] = new Project(child, filter) projects[(child.name)] = new Project(child)
} else if (child.isFile()) { } else if (child.isFile()) {
def issue def issue
// if exception, then not an issue // if exception, then not an issue
try { issue = new Issue(child) } catch (all) { return } try { issue = new Issue(child) } catch (all) { return }
if (filter && !filter.accept(issue)) return
issues[(issue.id)] = issue issues[(issue.id)] = issue
} }
} }
@ -47,15 +43,19 @@ class Project {
public void eachIssue(Filter filter = null, Closure c) { public void eachIssue(Filter filter = null, Closure c) {
def sorter = filter?.issueSorter ?: Filter.defaultIssueSorter 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) { public void eachProject(Filter filter = null, Closure c) {
def sorter = filter?.projectSorter ?: Filter.defaultProjectSorter 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 is = filter?.issueSorter ?: Filter.defaultIssueSorter
def ps = filter?.projectSorter ?: Filter.defaultProjectSorter def ps = filter?.projectSorter ?: Filter.defaultProjectSorter
@ -72,15 +72,19 @@ class Project {
c.call(project) c.call(project)
} }
} }*/
public Issue createNewIssue(Map options) { public Issue createNewIssue(Map options) {
if (!options.category) options.category = Category.TASK if (!options.category) options.category = Category.TASK
if (!options.priority) options.priority = 5 if (!options.priority) options.priority = 5
if (!options.text) options.text = "Default issue title.\n" + if (!options.text) options.text = "Default issue title.\n" +
"====================\n" "====================\n"
String id = (issues.values().max { it.id.toInteger() }).id String id
id = (id.toInteger() + 1).toString().padLeft(id.length(), '0') 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)) def issueFile = new File(source, Issue.makeFilename(id, options.category, options.priority))
assert !issueFile.exists() assert !issueFile.exists()

View File

@ -3,6 +3,7 @@ package com.jdbernard.pit
import org.junit.* import org.junit.*
import static org.junit.Assert.assertTrue import static org.junit.Assert.assertTrue
import static org.junit.Assert.assertFalse import static org.junit.Assert.assertFalse
import static org.junit.Assert.assertEquals
class IssueTest { class IssueTest {
@ -33,19 +34,19 @@ class IssueTest {
} }
@After void deleteIssueFiles() { @After void deleteIssueFiles() {
testDir.deleteDir() assert testDir.deleteDir()
} }
@Test void testSetCategory() { @Test void testSetCategory() {
assertTrue issues[0].category == Category.FEATURE assertEquals issues[0].category, Category.FEATURE
assertTrue issues[1].category == Category.TASK assertEquals issues[1].category, Category.TASK
issues[0].category = Category.CLOSED issues[0].category = Category.CLOSED
issues[1].category = Category.BUG issues[1].category = Category.BUG
assertTrue issues[0].category == Category.CLOSED assertEquals issues[0].category, Category.CLOSED
assertTrue issues[1].category == Category.BUG assertEquals issues[1].category, Category.BUG
assertTrue new File(testDir, '0001c1.rst').exists() assertTrue new File(testDir, '0001c1.rst').exists()
assertTrue new File(testDir, '0002b5.rst').exists() assertTrue new File(testDir, '0002b5.rst').exists()
@ -55,14 +56,14 @@ class IssueTest {
@Test void testSetPriority() { @Test void testSetPriority() {
assertTrue issues[0].priority == 1 assertEquals issues[0].priority, 1
assertTrue issues[1].priority == 5 assertEquals issues[1].priority, 5
issues[0].priority = 2 issues[0].priority = 2
issues[1].priority = 9 issues[1].priority = 9
assertTrue issues[0].priority == 2 assertEquals issues[0].priority, 2
assertTrue issues[1].priority == 9 assertEquals issues[1].priority, 9
assertTrue new File(testDir, '0001f2.rst').exists() assertTrue new File(testDir, '0001f2.rst').exists()
assertTrue new File(testDir, '0002t9.rst').exists() assertTrue new File(testDir, '0002t9.rst').exists()
@ -74,13 +75,32 @@ class IssueTest {
File issueFile = new File(testDir, '0001f1.rst') File issueFile = new File(testDir, '0001f1.rst')
Issue issue = new Issue(issueFile) Issue issue = new Issue(issueFile)
assertTrue issue.id == "0001" assertEquals issue.id , "0001"
assertTrue issue.category == Category.FEATURE assertEquals issue.category , Category.FEATURE
assertTrue issue.priority == 1 assertEquals issue.priority , 1
assertTrue issue.title == "Add the killer feature to the killer app." assertEquals issue.title , "Add the killer feature to the killer app."
assertTrue issue.text == "Add the killer feature to the killer app.\n" + assertEquals issue.text , "Add the killer feature to the killer app.\n" +
"=========================================\n\n" + "=========================================\n\n" +
"Make our killer app shine!." "Make our killer app shine!."
assertTrue issue.source == issueFile 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) {}
} }
} }

View File

@ -3,8 +3,10 @@ package com.jdbernard.pit
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test 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.assertFalse
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertTrue
class ProjectTest { class ProjectTest {
@ -12,9 +14,25 @@ class ProjectTest {
Project rootProj Project rootProj
@Before void createTestProjects() { @Before void createTestProjects() {
testDir = new File('testdir') testDir = new File('testdir')
assert !testDir.exists()
testDir.mkdirs() testDir.mkdirs()
/* TEST SUITE:
/testdir/
0001t5.rst
0002b5.rst
0003f2.rst
subproj1/
0001f3.rst
0002b4.rst
emptyproj/
*/
def issueFile = new File(testDir, '0001t5.rst') def issueFile = new File(testDir, '0001t5.rst')
issueFile.createNewFile() issueFile.createNewFile()
issueFile.write('Test Issue 1\n' + issueFile.write('Test Issue 1\n' +
@ -27,7 +45,7 @@ class ProjectTest {
'========\n\n' + '========\n\n' +
'Yeah, it is a test bug.') 'Yeah, it is a test bug.')
issueFile = new File(testDir, '0003f2.rst') issueFile = new File(testDir, '0003c2.rst')
issueFile.createNewFile() issueFile.createNewFile()
issueFile.write('Important Feature Request\n' + issueFile.write('Important Feature Request\n' +
'=========================\n\n' + '=========================\n\n' +
@ -48,40 +66,51 @@ class ProjectTest {
'==========================\n\n' + '==========================\n\n' +
'For some reason, the Zippners are bilperring, not zippning.') 'For some reason, the Zippners are bilperring, not zippning.')
subDir = new File(testDir, 'emptyproj')
subDir.mkdirs()
rootProj = new Project(testDir) rootProj = new Project(testDir)
} }
@After void deleteTestProjects() { @After void deleteTestProjects() {
testDir.delete() assert testDir.deleteDir()
if (rootProj.source.exists())
assert rootProj.source.deleteDir()
} }
@Test void testConstruction() { @Test void testConstruction() {
Project proj = new Project(testDir, null) Project proj = new Project(testDir)
assertTrue proj.name == 'testdir' assertEquals proj.name, 'testdir'
assertTrue proj.issues.size() == 3 assertEquals proj.issues.size(), 3
assertTrue proj.projects.size() == 1 assertEquals proj.projects.size(), 1
// Issue construction in general is under test in IssueTest // Issue construction in general is under test in IssueTest
// just check that the issues actually exists // just check that the issues actually exists
assertTrue proj.issues['0001'].id == '0001' assertEquals proj.issues['0001'].id, '0001'
assertTrue proj.issues['0001'].title == 'Test Issue 1' assertEquals proj.issues['0001'].title, 'Test Issue 1'
assertTrue proj.issues['0002'].id == '0002' assertEquals proj.issues['0002'].id, '0002'
assertTrue proj.issues['0002'].title == 'Test Bug' assertEquals proj.issues['0002'].title, 'Test Bug'
assertTrue proj.issues['0003'].id == '0003' assertEquals proj.issues['0003'].id, '0003'
assertTrue proj.issues['0003'].title == 'Important Feature Request' assertEquals proj.issues['0003'].title, 'Important Feature Request'
// check sub-project behaviour // check sub-project behaviour
assertTrue proj.projects.subproj1 != null assertNotNull proj.projects.subproj1
assertTrue proj.projects.subproj1.name == 'subproj1' assertEquals proj.projects.subproj1.name, 'subproj1'
assertTrue proj.projects.subproj1.issues.size() == 2 assertEquals proj.projects.subproj1.issues.size(), 2
assertTrue proj.projects.subproj1.projects.size() == 0 assertEquals proj.projects.subproj1.projects.size(), 0
assertTrue proj.projects.subproj1.issues['0001'].id == '0001' assertEquals proj.projects.subproj1.issues['0001'].id, '0001'
assertTrue proj.projects.subproj1.issues['0001'].title == 'First feature in subproject' assertEquals proj.projects.subproj1.issues['0002'].id, '0002'
assertTrue proj.projects.subproj1.issues['0002'].id == '0002' assertEquals proj.projects.subproj1.issues['0001'].title,
assertTrue proj.projects.subproj1.issues['0002'].title == 'Zippners are not zippning.' '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() { @Test void testRename() {
@ -89,10 +118,34 @@ class ProjectTest {
rootProj.rename('renamedTestDir') rootProj.rename('renamedTestDir')
assertTrue rootProj.name == 'renamedTestDir' assertEquals rootProj.name, 'renamedTestDir'
assertTrue new File('renamedTestDir').exists() 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() { /*@Test void testEachIssue() {
def expectedList = [rootProj.issues['0001'], def expectedList = [rootProj.issues['0001'],
rootProj.issues['0002'], rootProj.issues['0003']] rootProj.issues['0002'], rootProj.issues['0003']]

Binary file not shown.

View File

@ -1,9 +1,9 @@
#Thu Feb 18 11:10:29 CST 2010 #Thu Feb 18 11:26:18 CST 2010
build.dir=build build.dir=build
src.dir=src src.dir=src
build.jar=pit-cli-${application.version}.${build.number}.jar build.jar=pit-cli-${application.version}.${build.number}.jar
build.number=31 build.number=1
expected.application.version=1.1.0 expected.application.version=1.1.1
lib.dir=lib lib.dir=lib
release.dir=release release.dir=release
release.jar=pit-cli-${application.version}.jar release.jar=pit-cli-${application.version}.jar

View File

@ -1 +1 @@
application.version=1.1.1 application.version=1.1.2