Improve tests & validate FSEntry names #4
@@ -10,15 +10,21 @@ class FSCreator {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Create entry, leaving existing folders' contents, but overwriting existing files.
 | 
					     * Create entry, leaving existing folders' contents, but overwriting existing files.
 | 
				
			||||||
     * @throws CyclicFolderException Cyclic folders cannot be created.
 | 
					     * @throws CyclicFolderException Cyclic folders cannot be created.
 | 
				
			||||||
 | 
					     * @throws DuplicateEntryNameException A folder or sub-folder contains entries with duplicate names.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Throws(CyclicFolderException::class)
 | 
					    @Throws(CyclicFolderException::class, DuplicateEntryNameException::class)
 | 
				
			||||||
    fun create(
 | 
					    fun create(
 | 
				
			||||||
        entryToCreate: FSEntry,
 | 
					        entryToCreate: FSEntry,
 | 
				
			||||||
        destination: String,
 | 
					        destination: String,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        // No point in running anything if we know the input is invalid.
 | 
					        // No point in running anything if we know the input is invalid.
 | 
				
			||||||
        if (entryToCreate is FSFolder && entryToCreate.isCyclic()) {
 | 
					        if (entryToCreate is FSFolder) {
 | 
				
			||||||
            throw CyclicFolderException()
 | 
					            if (entryToCreate.isCyclic()) {
 | 
				
			||||||
 | 
					                throw CyclicFolderException()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (entryToCreate.deepHasDuplicateNames()) {
 | 
				
			||||||
 | 
					                throw DuplicateEntryNameException()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val queue =
 | 
					        val queue =
 | 
				
			||||||
@@ -47,3 +53,4 @@ class FSCreator {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CyclicFolderException : Exception("Cyclic FSFolders are not supported")
 | 
					class CyclicFolderException : Exception("Cyclic FSFolders are not supported")
 | 
				
			||||||
 | 
					class DuplicateEntryNameException : Exception("Folder contains entries with duplicate names")
 | 
				
			||||||
@@ -34,6 +34,26 @@ class FSFolder(name: String, val entries: List<FSEntry>) : FSEntry(name) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return false
 | 
					        return false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check whether a folder contains multiple entries with the same name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    fun hasDuplicateNames(): Boolean {
 | 
				
			||||||
 | 
					        val seen = HashSet<String>()
 | 
				
			||||||
 | 
					        return entries.any { !seen.add(it.name) }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    internal fun deepHasDuplicateNames(): Boolean {
 | 
				
			||||||
 | 
					        val queue = ArrayDeque(listOf(this))
 | 
				
			||||||
 | 
					        while (queue.isNotEmpty()) {
 | 
				
			||||||
 | 
					            val entry = queue.removeFirst()
 | 
				
			||||||
 | 
					            if (entry.hasDuplicateNames()) {
 | 
				
			||||||
 | 
					                return true
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            queue.addAll(entry.entries.mapNotNull { it as? FSFolder })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InvalidEntryNameException(name: String) : Exception("Invalid FSEntry name: '$name'")
 | 
					class InvalidEntryNameException(name: String) : Exception("Invalid FSEntry name: '$name'")
 | 
				
			||||||
		Reference in New Issue
	
	Block a user