From b0da3ee8d43f7a32aaf0fade9f36dede0965e786 Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Wed, 10 Jul 2019 14:44:39 +0300 Subject: [PATCH 1/6] initial for HW04 --- .gitignore | 4 +- src/ArrayStorage.java | 85 ------------------- src/Resume.java | 21 ----- .../javawebinar/basejava}/MainArray.java | 22 +++-- .../javawebinar/basejava/MainReflection.java | 19 +++++ src/ru/javawebinar/basejava/MainString.java | 18 ++++ .../basejava}/MainTestArrayStorage.java | 37 +++----- .../exception/ExistStorageException.java | 7 ++ .../exception/NotExistStorageException.java | 7 ++ .../basejava/exception/StorageException.java | 14 +++ src/ru/javawebinar/basejava/model/Resume.java | 49 +++++++++++ .../storage/AbstractArrayStorage.java | 80 +++++++++++++++++ .../javawebinar/basejava/storage/Storage.java | 20 +++++ .../basejava/storage/impl/ArrayStorage.java | 30 +++++++ .../storage/impl/SortedArrayStorage.java | 31 +++++++ .../storage/AbstractArrayStorageTest.java | 63 ++++++++++++++ .../storage/impl/ArrayStorageTest.java | 7 ++ 17 files changed, 369 insertions(+), 145 deletions(-) delete mode 100644 src/ArrayStorage.java delete mode 100644 src/Resume.java rename src/{ => ru/javawebinar/basejava}/MainArray.java (80%) create mode 100644 src/ru/javawebinar/basejava/MainReflection.java create mode 100644 src/ru/javawebinar/basejava/MainString.java rename src/{ => ru/javawebinar/basejava}/MainTestArrayStorage.java (50%) create mode 100644 src/ru/javawebinar/basejava/exception/ExistStorageException.java create mode 100644 src/ru/javawebinar/basejava/exception/NotExistStorageException.java create mode 100644 src/ru/javawebinar/basejava/exception/StorageException.java create mode 100644 src/ru/javawebinar/basejava/model/Resume.java create mode 100644 src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java create mode 100644 src/ru/javawebinar/basejava/storage/Storage.java create mode 100644 src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java create mode 100644 src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java create mode 100644 test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java create mode 100644 test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java diff --git a/.gitignore b/.gitignore index 188fae8..ba9ea56 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,4 @@ out *.iml log - - - +lib diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java deleted file mode 100644 index cefa261..0000000 --- a/src/ArrayStorage.java +++ /dev/null @@ -1,85 +0,0 @@ -import java.util.Arrays; -import java.util.Objects; - -/** - * Array based storage for Resumes - */ -public class ArrayStorage { - private Resume[] storage = new Resume[10_000]; - - private int size; - - public void clear() { - Arrays.fill(storage, 0, size, null); - size = 0; - } - - public void update(Resume resume) { - int index = getIndex(resume.getUuid()); - - if (index >= 0) { - storage[index] = resume; - } else { - System.out.println("ERROR in method 'update' :" + resume.getUuid()); - } - } - - public void save(Resume resume) { - int index = getIndex(resume.getUuid()); - - if (index >= 0) { - System.out.println("ERROR in method 'save' :" + resume.getUuid()); - } else { - if (size < storage.length) { - storage[size] = resume; - size++; - } else { - System.out.println("ERROR in method 'save' :" + resume.getUuid() + " (storage backing array boundary has been reached)"); - } - } - } - - public Resume get(String uuid) { - int index = getIndex(uuid); - - if (index >= 0) { - return storage[index]; - } else { - System.out.println("Invalid uuid in method 'get': " + uuid); - return null; - } - } - - - public void delete(String uuid) { - int index = getIndex(uuid); - - if (index >= 0) { - storage[index] = storage[size - 1]; - storage[size - 1] = null; - size--; - } else { - System.out.println("Invalid uuid in method 'delete': " + uuid); - } - } - - /** - * @return array, contains only Resumes in storage (without null) - */ - public Resume[] getAll() { - return Arrays.copyOf(storage, size); - } - - public int size() { - return size; - } - - private int getIndex(String uuid) { - for (int i = 0; i < size; i++) { - if (Objects.equals(storage[i].getUuid(), uuid)) { - return i; - } - } - return -1; - } -} diff --git a/src/Resume.java b/src/Resume.java deleted file mode 100644 index ef673e6..0000000 --- a/src/Resume.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Initial resume class - */ -public class Resume { - - // Unique identifier - private String uuid; - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - @Override - public String toString() { - return uuid; - } -} diff --git a/src/MainArray.java b/src/ru/javawebinar/basejava/MainArray.java similarity index 80% rename from src/MainArray.java rename to src/ru/javawebinar/basejava/MainArray.java index cc060cf..2f812b8 100644 --- a/src/MainArray.java +++ b/src/ru/javawebinar/basejava/MainArray.java @@ -1,19 +1,24 @@ +package ru.javawebinar.basejava; + +import ru.javawebinar.basejava.model.Resume; +import ru.javawebinar.basejava.storage.impl.ArrayStorage; +import ru.javawebinar.basejava.storage.Storage; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** - * Interactive test for ArrayStorage implementation - * (just run, no need to understand) + * Test for ru.javawebinar.basejava.storage.impl.ArrayStorage */ public class MainArray { - private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + private final static Storage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Resume r; while (true) { - System.out.print("Введите одну из команд - (list | save uuid | update uuid | delete uuid | get uuid | clear | exit): "); + System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | update uuid | clear | exit): "); String[] params = reader.readLine().trim().toLowerCase().split(" "); if (params.length < 1 || params.length > 2) { System.out.println("Неверная команда."); @@ -31,15 +36,14 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(); - r.setUuid(uuid); + r = new Resume(uuid); ARRAY_STORAGE.save(r); printAll(); break; case "update": - Resume rNew = new Resume(); - rNew.setUuid(uuid); - ARRAY_STORAGE.update(rNew); + r = new Resume(uuid); + ARRAY_STORAGE.update(r); + printAll(); break; case "delete": ARRAY_STORAGE.delete(uuid); diff --git a/src/ru/javawebinar/basejava/MainReflection.java b/src/ru/javawebinar/basejava/MainReflection.java new file mode 100644 index 0000000..d37690a --- /dev/null +++ b/src/ru/javawebinar/basejava/MainReflection.java @@ -0,0 +1,19 @@ +package ru.javawebinar.basejava; + +import ru.javawebinar.basejava.model.Resume; + +import java.lang.reflect.Field; + +public class MainReflection { + + public static void main(String[] args) throws IllegalAccessException { + Resume r = new Resume(); + Field field = r.getClass().getDeclaredFields()[0]; + field.setAccessible(true); + System.out.println(field.getName()); + System.out.println(field.get(r)); + field.set(r, "new_uuid"); + // TODO : invoke r.toString via reflection + System.out.println(r); + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/MainString.java b/src/ru/javawebinar/basejava/MainString.java new file mode 100644 index 0000000..681b189 --- /dev/null +++ b/src/ru/javawebinar/basejava/MainString.java @@ -0,0 +1,18 @@ +package ru.javawebinar.basejava; + +public class MainString { + public static void main(String[] args) { + String[] strArray = new String[]{"1", "2", "3", "4", "5"}; +// String result = ""; + StringBuilder sb = new StringBuilder(); + for (String str : strArray) { + sb.append(str).append(", "); + } + System.out.println(sb.toString()); + + String str1 = "abc"; + String str3 = "c"; + String str2 = ("ab" + str3).intern(); + System.out.println(str1 == str2); + } +} \ No newline at end of file diff --git a/src/MainTestArrayStorage.java b/src/ru/javawebinar/basejava/MainTestArrayStorage.java similarity index 50% rename from src/MainTestArrayStorage.java rename to src/ru/javawebinar/basejava/MainTestArrayStorage.java index 7683807..dad5b1b 100644 --- a/src/MainTestArrayStorage.java +++ b/src/ru/javawebinar/basejava/MainTestArrayStorage.java @@ -1,19 +1,18 @@ +package ru.javawebinar.basejava; + +import ru.javawebinar.basejava.model.Resume; +import ru.javawebinar.basejava.storage.impl.ArrayStorage; + /** - * Test for your ArrayStorage implementation + * Test ru.javawebinar.basejava.storage.impl.ArrayStorage */ public class MainTestArrayStorage { static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); - static int ARRAY_STORAGE_LIMIT = 10_000; public static void main(String[] args) { - Resume r1 = new Resume(); - r1.setUuid("uuid1"); - Resume r2 = new Resume(); - r2.setUuid("uuid2"); - Resume r3 = new Resume(); - r3.setUuid("uuid3"); - Resume r2new = new Resume(); - r2new.setUuid("uuid2"); + Resume r1 = new Resume("uuid1"); + Resume r2 = new Resume("uuid2"); + Resume r3 = new Resume("uuid3"); ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); @@ -24,14 +23,6 @@ public static void main(String[] args) { System.out.println("Get dummy: " + ARRAY_STORAGE.get("dummy")); - ARRAY_STORAGE.save(r2new); - - ARRAY_STORAGE.update(r2new); - System.out.println("Get r2new: " + ARRAY_STORAGE.get(r2new.getUuid())); - - ARRAY_STORAGE.get("uuid111"); - ARRAY_STORAGE.delete("uuid111"); - printAll(); ARRAY_STORAGE.delete(r1.getUuid()); printAll(); @@ -39,14 +30,6 @@ public static void main(String[] args) { printAll(); System.out.println("Size: " + ARRAY_STORAGE.size()); - - for (int i = 0; i <= ARRAY_STORAGE_LIMIT; i++) { - Resume r = new Resume(); - r.setUuid("uuid" + i); - ARRAY_STORAGE.save(r); - } - - System.out.println("Size: " + ARRAY_STORAGE.size()); } static void printAll() { @@ -55,4 +38,4 @@ static void printAll() { System.out.println(r); } } -} +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/exception/ExistStorageException.java b/src/ru/javawebinar/basejava/exception/ExistStorageException.java new file mode 100644 index 0000000..33d98be --- /dev/null +++ b/src/ru/javawebinar/basejava/exception/ExistStorageException.java @@ -0,0 +1,7 @@ +package ru.javawebinar.basejava.exception; + +public class ExistStorageException extends StorageException { + public ExistStorageException(String uuid) { + super("Resume " + uuid + " already exist", uuid); + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/exception/NotExistStorageException.java b/src/ru/javawebinar/basejava/exception/NotExistStorageException.java new file mode 100644 index 0000000..9a9b867 --- /dev/null +++ b/src/ru/javawebinar/basejava/exception/NotExistStorageException.java @@ -0,0 +1,7 @@ +package ru.javawebinar.basejava.exception; + +public class NotExistStorageException extends StorageException { + public NotExistStorageException(String uuid) { + super("Resume " + uuid + " not exist", uuid); + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/exception/StorageException.java b/src/ru/javawebinar/basejava/exception/StorageException.java new file mode 100644 index 0000000..dbd1be0 --- /dev/null +++ b/src/ru/javawebinar/basejava/exception/StorageException.java @@ -0,0 +1,14 @@ +package ru.javawebinar.basejava.exception; + +public class StorageException extends RuntimeException { + private final String uuid; + + public StorageException(String message, String uuid) { + super(message); + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/model/Resume.java b/src/ru/javawebinar/basejava/model/Resume.java new file mode 100644 index 0000000..508cc20 --- /dev/null +++ b/src/ru/javawebinar/basejava/model/Resume.java @@ -0,0 +1,49 @@ +package ru.javawebinar.basejava.model; + +import java.util.UUID; + +/** + * ru.javawebinar.basejava.model.Resume class + */ +public class Resume implements Comparable { + + // Unique identifier + private final String uuid; + + public Resume() { + this(UUID.randomUUID().toString()); + } + + public Resume(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Resume resume = (Resume) o; + + return uuid.equals(resume.uuid); + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + + @Override + public String toString() { + return uuid; + } + + @Override + public int compareTo(Resume o) { + return uuid.compareTo(o.uuid); + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java b/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java new file mode 100644 index 0000000..098f9f1 --- /dev/null +++ b/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java @@ -0,0 +1,80 @@ +package ru.javawebinar.basejava.storage; + +import ru.javawebinar.basejava.exception.ExistStorageException; +import ru.javawebinar.basejava.exception.NotExistStorageException; +import ru.javawebinar.basejava.exception.StorageException; +import ru.javawebinar.basejava.model.Resume; + +import java.util.Arrays; + +/** + * Array based storage for Resumes + */ +public abstract class AbstractArrayStorage implements Storage { + protected static final int STORAGE_LIMIT = 10000; + + protected Resume[] storage = new Resume[STORAGE_LIMIT]; + protected int size = 0; + + public int size() { + return size; + } + + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; + } + + public void update(Resume r) { + int index = getIndex(r.getUuid()); + if (index < 0) { + throw new NotExistStorageException(r.getUuid()); + } else { + storage[index] = r; + } + } + + /** + * @return array, contains only Resumes in storage (without null) + */ + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); + } + + public void save(Resume r) { + int index = getIndex(r.getUuid()); + if (index >= 0) { + throw new ExistStorageException(r.getUuid()); + } else if (size == STORAGE_LIMIT) { + throw new StorageException("Storage overflow", r.getUuid()); + } else { + insertElement(r, index); + size++; + } + } + + public void delete(String uuid) { + int index = getIndex(uuid); + if (index < 0) { + throw new NotExistStorageException(uuid); + } else { + fillDeletedElement(index); + storage[size - 1] = null; + size--; + } + } + + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index < 0) { + throw new NotExistStorageException(uuid); + } + return storage[index]; + } + + protected abstract void fillDeletedElement(int index); + + protected abstract void insertElement(Resume r, int index); + + protected abstract int getIndex(String uuid); +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/storage/Storage.java b/src/ru/javawebinar/basejava/storage/Storage.java new file mode 100644 index 0000000..2f7a1d9 --- /dev/null +++ b/src/ru/javawebinar/basejava/storage/Storage.java @@ -0,0 +1,20 @@ +package ru.javawebinar.basejava.storage; + +import ru.javawebinar.basejava.model.Resume; + +public interface Storage { + + void clear(); + + void update(Resume r); + + void save(Resume r); + + Resume get(String uuid); + + void delete(String uuid); + + Resume[] getAll(); + + int size(); +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java b/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java new file mode 100644 index 0000000..37663ba --- /dev/null +++ b/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java @@ -0,0 +1,30 @@ +package ru.javawebinar.basejava.storage.impl; + +import ru.javawebinar.basejava.model.Resume; +import ru.javawebinar.basejava.storage.AbstractArrayStorage; + +/** + * Array based storage for Resumes + */ +public class ArrayStorage extends AbstractArrayStorage { + + @Override + protected void fillDeletedElement(int index) { + storage[index] = storage[size - 1]; + } + + @Override + protected void insertElement(Resume r, int index) { + storage[size] = r; + } + + @Override + protected int getIndex(String uuid) { + for (int i = 0; i < size; i++) { + if (uuid.equals(storage[i].getUuid())) { + return i; + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java b/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java new file mode 100644 index 0000000..befd2f6 --- /dev/null +++ b/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java @@ -0,0 +1,31 @@ +package ru.javawebinar.basejava.storage.impl; + +import ru.javawebinar.basejava.model.Resume; +import ru.javawebinar.basejava.storage.AbstractArrayStorage; + +import java.util.Arrays; + +public class SortedArrayStorage extends AbstractArrayStorage { + + @Override + protected void fillDeletedElement(int index) { + int numMoved = size - index - 1; + if (numMoved > 0) { + System.arraycopy(storage, index + 1, storage, index, numMoved); + } + } + + @Override + protected void insertElement(Resume r, int index) { +// http://codereview.stackexchange.com/questions/36221/binary-search-for-inserting-in-array#answer-36239 + int insertIdx = -index - 1; + System.arraycopy(storage, insertIdx, storage, insertIdx + 1, size - insertIdx); + storage[insertIdx] = r; + } + + @Override + protected int getIndex(String uuid) { + Resume searchKey = new Resume(uuid); + return Arrays.binarySearch(storage, 0, size, searchKey); + } +} \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java new file mode 100644 index 0000000..dce9722 --- /dev/null +++ b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java @@ -0,0 +1,63 @@ +package ru.javawebinar.basejava.storage; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import ru.javawebinar.basejava.exception.NotExistStorageException; +import ru.javawebinar.basejava.model.Resume; + +public abstract class AbstractArrayStorageTest { + private Storage storage; + + private static final String UUID_1 = "uuid1"; + private static final String UUID_2 = "uuid2"; + private static final String UUID_3 = "uuid3"; + + @Before + public void setUp() throws Exception { + storage.clear(); + storage.save(new Resume(UUID_1)); + storage.save(new Resume(UUID_2)); + storage.save(new Resume(UUID_3)); + } + + @Test + public void size() throws Exception { + Assert.assertEquals(3, storage.size()); + } + + @Test + public void clear() throws Exception { + + } + + @Test + public void update() throws Exception { + + } + + @Test + public void getAll() throws Exception { + + } + + @Test + public void save() throws Exception { + + } + + @Test + public void delete() throws Exception { + + } + + @Test + public void get() throws Exception { + + } + + @Test(expected = NotExistStorageException.class) + public void getNotExist() throws Exception { + storage.get("dummy"); + } +} \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java new file mode 100644 index 0000000..ef07e36 --- /dev/null +++ b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java @@ -0,0 +1,7 @@ +package ru.javawebinar.basejava.storage.impl; + +import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; + +public class ArrayStorageTest extends AbstractArrayStorageTest { + +} \ No newline at end of file From d288d7113119f3a7919c93b7083da69875c0a122 Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Wed, 10 Jul 2019 15:07:32 +0300 Subject: [PATCH 2/6] invoke via reflection --- .../javawebinar/basejava/MainReflection.java | 21 +++++++++++++++++++ .../storage/impl/SortedArrayStorageTest.java | 20 ++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java diff --git a/src/ru/javawebinar/basejava/MainReflection.java b/src/ru/javawebinar/basejava/MainReflection.java index d37690a..7652fd8 100644 --- a/src/ru/javawebinar/basejava/MainReflection.java +++ b/src/ru/javawebinar/basejava/MainReflection.java @@ -3,6 +3,8 @@ import ru.javawebinar.basejava.model.Resume; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; public class MainReflection { @@ -15,5 +17,24 @@ public static void main(String[] args) throws IllegalAccessException { field.set(r, "new_uuid"); // TODO : invoke r.toString via reflection System.out.println(r); + + System.out.println(field.get(r)); + + try { + Method toString = r.getClass().getMethod("toString"); + + try { + Object invoke = toString.invoke(r); + System.out.println(invoke); + + } catch (IllegalArgumentException e) { } + catch (IllegalAccessException e) { } + catch (InvocationTargetException e) { } + + } catch (SecurityException e) { } + catch (NoSuchMethodException e) { } + + + } } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java new file mode 100644 index 0000000..90c4b09 --- /dev/null +++ b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java @@ -0,0 +1,20 @@ +package ru.javawebinar.basejava.storage.impl; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class SortedArrayStorageTest { + + @Test + public void fillDeletedElement() { + } + + @Test + public void insertElement() { + } + + @Test + public void getIndex() { + } +} \ No newline at end of file From 86217926ef25c6a90ae1335e9bd264b74e93ad8b Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Sat, 3 Aug 2019 23:13:31 +0300 Subject: [PATCH 3/6] ready to review --- .../storage/AbstractArrayStorage.java | 8 +- .../basejava/storage/impl/ArrayStorage.java | 4 +- .../storage/impl/SortedArrayStorage.java | 11 +- .../storage/AbstractArrayStorageTest.java | 127 +++++++++++++++--- .../storage/impl/ArrayStorageTest.java | 3 + .../storage/impl/SortedArrayStorageTest.java | 18 +-- 6 files changed, 129 insertions(+), 42 deletions(-) diff --git a/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java b/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java index 098f9f1..3971b8d 100644 --- a/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java +++ b/src/ru/javawebinar/basejava/storage/AbstractArrayStorage.java @@ -48,7 +48,7 @@ public void save(Resume r) { } else if (size == STORAGE_LIMIT) { throw new StorageException("Storage overflow", r.getUuid()); } else { - insertElement(r, index); + doSave(r, index); size++; } } @@ -58,7 +58,7 @@ public void delete(String uuid) { if (index < 0) { throw new NotExistStorageException(uuid); } else { - fillDeletedElement(index); + doDelete(index); storage[size - 1] = null; size--; } @@ -72,9 +72,9 @@ public Resume get(String uuid) { return storage[index]; } - protected abstract void fillDeletedElement(int index); + protected abstract void doDelete(int index); - protected abstract void insertElement(Resume r, int index); + protected abstract void doSave(Resume r, int index); protected abstract int getIndex(String uuid); } \ No newline at end of file diff --git a/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java b/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java index 37663ba..981e3bd 100644 --- a/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java +++ b/src/ru/javawebinar/basejava/storage/impl/ArrayStorage.java @@ -9,12 +9,12 @@ public class ArrayStorage extends AbstractArrayStorage { @Override - protected void fillDeletedElement(int index) { + protected void doDelete(int index) { storage[index] = storage[size - 1]; } @Override - protected void insertElement(Resume r, int index) { + protected void doSave(Resume r, int index) { storage[size] = r; } diff --git a/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java b/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java index befd2f6..aef2646 100644 --- a/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java +++ b/src/ru/javawebinar/basejava/storage/impl/SortedArrayStorage.java @@ -8,7 +8,7 @@ public class SortedArrayStorage extends AbstractArrayStorage { @Override - protected void fillDeletedElement(int index) { + protected void doDelete(int index) { int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(storage, index + 1, storage, index, numMoved); @@ -16,11 +16,10 @@ protected void fillDeletedElement(int index) { } @Override - protected void insertElement(Resume r, int index) { -// http://codereview.stackexchange.com/questions/36221/binary-search-for-inserting-in-array#answer-36239 - int insertIdx = -index - 1; - System.arraycopy(storage, insertIdx, storage, insertIdx + 1, size - insertIdx); - storage[insertIdx] = r; + protected void doSave(Resume r, int index) { + int insert = -index - 1; + System.arraycopy(storage, insert, storage, insert + 1, size - insert); + storage[insert] = r; } @Override diff --git a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java index dce9722..a8f2536 100644 --- a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java @@ -1,63 +1,158 @@ package ru.javawebinar.basejava.storage; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.function.Executable; +import ru.javawebinar.basejava.exception.ExistStorageException; import ru.javawebinar.basejava.exception.NotExistStorageException; +import ru.javawebinar.basejava.exception.StorageException; import ru.javawebinar.basejava.model.Resume; +import java.util.Optional; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + + +@DisplayName("JUnit 5 Example") public abstract class AbstractArrayStorageTest { - private Storage storage; + protected Storage storage; - private static final String UUID_1 = "uuid1"; - private static final String UUID_2 = "uuid2"; - private static final String UUID_3 = "uuid3"; + protected static final String UUID_1 = "uuid1"; + protected static final String UUID_2 = "uuid2"; + protected static final String UUID_3 = "uuid3"; - @Before - public void setUp() throws Exception { - storage.clear(); + public AbstractArrayStorageTest(Storage storage) { + this.storage = storage; + } + + @BeforeEach + void beforeEach() { storage.save(new Resume(UUID_1)); storage.save(new Resume(UUID_2)); storage.save(new Resume(UUID_3)); } + @AfterEach + void afterEach() { + storage.clear(); + } + + @Nested + @DisplayName("When overflow") + class WhenOverflow { + + @BeforeEach + void setUp() { + storage.clear(); + + IntStream.iterate(0, n -> n + 1). + limit(AbstractArrayStorage.STORAGE_LIMIT). + mapToObj(i -> new Resume("Name" + i)). + forEach(storage::save); + } + + + @Test + @DisplayName("Should not throw within size limit") + void shouldNotThrow() { + String uuid = "New item"; + if (storage.size() < AbstractArrayStorage.STORAGE_LIMIT) { + storage.save(new Resume(uuid)); + assertDoesNotThrow(() -> { + }); + } + } + + @Test + @DisplayName("Should throw correct exception if overflown") + void shouldThrowCorrectException() { + + // arrange + String uuid = "New item"; + Executable throwingExecutable = () -> { + storage.save(new Resume(uuid)); + }; + + // act and assert + RuntimeException thrown = assertThrows( + StorageException.class, throwingExecutable::execute, "Should throw non specialized StorageException" + ); + + assertEquals("Storage overflow", thrown.getMessage()); + } + } + @Test public void size() throws Exception { - Assert.assertEquals(3, storage.size()); + assertEquals(3, storage.size()); } @Test public void clear() throws Exception { - + storage.clear(); + assertEquals(0, storage.size()); } @Test public void update() throws Exception { + Resume r2new = new Resume(UUID_2); + storage.update(r2new); + assertEquals(UUID_2, storage.get(UUID_2).getUuid()); } @Test public void getAll() throws Exception { + Resume[] all = storage.getAll(); + + assertEquals(UUID_1, all[0].getUuid()); + assertEquals(UUID_2, all[1].getUuid()); + assertEquals(UUID_3, all[2].getUuid()); } @Test public void save() throws Exception { + String newUuid = "uuid4"; + Resume r4 = new Resume(newUuid); + storage.save(r4); + assertEquals(newUuid, storage.get(newUuid).getUuid()); + } + + @Test + public void saveExisting() throws Exception { + assertThrows(ExistStorageException.class, + () -> storage.save(new Resume(UUID_1))); } @Test public void delete() throws Exception { + storage.delete(UUID_2); + Resume[] all = storage.getAll(); + Optional first = Stream.of(all) + .filter(r -> r.getUuid() == UUID_2) + .findFirst(); + assertEquals(Optional.empty(), first); } @Test public void get() throws Exception { - + assertEquals(UUID_1, storage.get("uuid1").getUuid()); } - @Test(expected = NotExistStorageException.class) - public void getNotExist() throws Exception { - storage.get("dummy"); + @Test + public void getNonExisting() { + String dummy = "dummy"; + + final StorageException thrown = assertThrows( + NotExistStorageException.class, + () -> { + storage.get(dummy); + } + ); + assertEquals(dummy, thrown.getUuid()); } } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java index ef07e36..51d79df 100644 --- a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java @@ -4,4 +4,7 @@ public class ArrayStorageTest extends AbstractArrayStorageTest { + public ArrayStorageTest() { + super(new ArrayStorage()); + } } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java index 90c4b09..8f53414 100644 --- a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java @@ -1,20 +1,10 @@ package ru.javawebinar.basejava.storage.impl; -import org.junit.Test; +import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; -import static org.junit.Assert.*; +public class SortedArrayStorageTest extends AbstractArrayStorageTest { -public class SortedArrayStorageTest { - - @Test - public void fillDeletedElement() { - } - - @Test - public void insertElement() { - } - - @Test - public void getIndex() { + public SortedArrayStorageTest() { + super(new SortedArrayStorage()); } } \ No newline at end of file From 2ae77cf8ee629a9f7cca2462c514de0ddce81f72 Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Mon, 5 Aug 2019 15:27:19 +0300 Subject: [PATCH 4/6] rev2 --- .../storage/AbstractArrayStorageTest.java | 80 +++++++++++-------- .../ru/javawebinar/basejava/storage/Util.java | 24 ++++++ .../storage/impl/ArrayStorageTest.java | 2 + .../storage/impl/SortedArrayStorageTest.java | 2 + 4 files changed, 74 insertions(+), 34 deletions(-) create mode 100644 test/ru/javawebinar/basejava/storage/Util.java diff --git a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java index a8f2536..27824c7 100644 --- a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java @@ -7,30 +7,29 @@ import ru.javawebinar.basejava.exception.StorageException; import ru.javawebinar.basejava.model.Resume; -import java.util.Optional; import java.util.stream.IntStream; -import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; +import static ru.javawebinar.basejava.storage.Util.*; -@DisplayName("JUnit 5 Example") public abstract class AbstractArrayStorageTest { - protected Storage storage; - protected static final String UUID_1 = "uuid1"; - protected static final String UUID_2 = "uuid2"; - protected static final String UUID_3 = "uuid3"; + private Storage storage; - public AbstractArrayStorageTest(Storage storage) { + protected AbstractArrayStorageTest(Storage storage) { this.storage = storage; } + @BeforeAll + static void beforeAll() { + } + @BeforeEach void beforeEach() { - storage.save(new Resume(UUID_1)); - storage.save(new Resume(UUID_2)); - storage.save(new Resume(UUID_3)); + storage.save(r1); + storage.save(r2); + storage.save(r3); } @AfterEach @@ -39,8 +38,7 @@ void afterEach() { } @Nested - @DisplayName("When overflow") - class WhenOverflow { + class SaveOverflow { @BeforeEach void setUp() { @@ -96,26 +94,33 @@ public void clear() throws Exception { @Test public void update() throws Exception { - Resume r2new = new Resume(UUID_2); - + Resume r2new = makeResume(UUID_2); storage.update(r2new); - assertEquals(UUID_2, storage.get(UUID_2).getUuid()); + + assertSame(storage.get(UUID_2), r2new); } @Test - public void getAll() throws Exception { + public void updateNonExisting() { + assertThrows( + NotExistStorageException.class, + () -> { + storage.update(makeResume("dummy")); + } + ); + } - Resume[] all = storage.getAll(); - assertEquals(UUID_1, all[0].getUuid()); - assertEquals(UUID_2, all[1].getUuid()); - assertEquals(UUID_3, all[2].getUuid()); + @Test + public void getAll() throws Exception { + Resume[] test = new Resume[]{r1, r2, r3}; + assertArrayEquals(test, storage.getAll()); } @Test public void save() throws Exception { - String newUuid = "uuid4"; - Resume r4 = new Resume(newUuid); + String newUuid = UUID_4; + Resume r4 = makeResume(newUuid); storage.save(r4); assertEquals(newUuid, storage.get(newUuid).getUuid()); @@ -130,29 +135,36 @@ public void saveExisting() throws Exception { @Test public void delete() throws Exception { storage.delete(UUID_2); - Resume[] all = storage.getAll(); - Optional first = Stream.of(all) - .filter(r -> r.getUuid() == UUID_2) - .findFirst(); - assertEquals(Optional.empty(), first); + assertAll("storage size is decreased, and access to deleted item correctly throws", + () -> assertEquals(2, storage.size()), + () -> assertThrows(NotExistStorageException.class, + () -> storage.get(UUID_2)) + ); + } + + @Test + public void deleteNonExisting() { + assertThrows( + NotExistStorageException.class, + () -> { + storage.delete("dummy"); + } + ); } @Test public void get() throws Exception { - assertEquals(UUID_1, storage.get("uuid1").getUuid()); + assertSame(r1, storage.get(UUID_1)); } @Test public void getNonExisting() { - String dummy = "dummy"; - - final StorageException thrown = assertThrows( + assertThrows( NotExistStorageException.class, () -> { - storage.get(dummy); + storage.get("dummy"); } ); - assertEquals(dummy, thrown.getUuid()); } } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/Util.java b/test/ru/javawebinar/basejava/storage/Util.java new file mode 100644 index 0000000..8e5c658 --- /dev/null +++ b/test/ru/javawebinar/basejava/storage/Util.java @@ -0,0 +1,24 @@ +package ru.javawebinar.basejava.storage; + +import ru.javawebinar.basejava.model.Resume; + +class Util { + static final String UUID_1 = "uuid1"; + static final String UUID_2 = "uuid2"; + static final String UUID_3 = "uuid3"; + static final String UUID_4 = "uuid4"; + + static final Resume r1; + static final Resume r2; + static final Resume r3; + + static Resume makeResume(String uuid){ + return new Resume(uuid); + } + + static { + r1 = makeResume(UUID_1); + r2 = makeResume(UUID_2); + r3 = makeResume(UUID_3); + } +} diff --git a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java index 51d79df..4d9bcdb 100644 --- a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java @@ -1,7 +1,9 @@ package ru.javawebinar.basejava.storage.impl; +import org.junit.jupiter.api.DisplayName; import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; +@DisplayName("ArrayStorage implementstion") public class ArrayStorageTest extends AbstractArrayStorageTest { public ArrayStorageTest() { diff --git a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java index 8f53414..384a34b 100644 --- a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java @@ -1,7 +1,9 @@ package ru.javawebinar.basejava.storage.impl; +import org.junit.jupiter.api.DisplayName; import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; +@DisplayName("SortedArrayStorage implementstion") public class SortedArrayStorageTest extends AbstractArrayStorageTest { public SortedArrayStorageTest() { From eb1d904005dbd0eec43a7b8a7c2ca245877a8e4a Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Mon, 5 Aug 2019 15:41:29 +0300 Subject: [PATCH 5/6] rev2 --- .../storage/AbstractArrayStorageTest.java | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java index 27824c7..175a797 100644 --- a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java @@ -43,29 +43,12 @@ class SaveOverflow { @BeforeEach void setUp() { storage.clear(); - - IntStream.iterate(0, n -> n + 1). - limit(AbstractArrayStorage.STORAGE_LIMIT). - mapToObj(i -> new Resume("Name" + i)). - forEach(storage::save); } @Test - @DisplayName("Should not throw within size limit") - void shouldNotThrow() { - String uuid = "New item"; - if (storage.size() < AbstractArrayStorage.STORAGE_LIMIT) { - storage.save(new Resume(uuid)); - assertDoesNotThrow(() -> { - }); - } - } - - @Test - @DisplayName("Should throw correct exception if overflown") - void shouldThrowCorrectException() { - + @DisplayName("Should not throw within size limit, then throws when overflow") + void fill() { // arrange String uuid = "New item"; Executable throwingExecutable = () -> { @@ -73,6 +56,13 @@ void shouldThrowCorrectException() { }; // act and assert + assertDoesNotThrow(() -> { + IntStream.iterate(0, n -> n + 1). + limit(AbstractArrayStorage.STORAGE_LIMIT). + mapToObj(i -> new Resume("Name" + i)). + forEach(storage::save); + }); + RuntimeException thrown = assertThrows( StorageException.class, throwingExecutable::execute, "Should throw non specialized StorageException" ); From 0a31ed879257eacfebfc289fa308bbd2d1fbb6ed Mon Sep 17 00:00:00 2001 From: Lev Tikhonov Date: Mon, 5 Aug 2019 22:46:22 +0300 Subject: [PATCH 6/6] rev3 --- .../storage/AbstractArrayStorageTest.java | 70 ++++++++----------- .../ru/javawebinar/basejava/storage/Util.java | 16 ++--- .../storage/impl/ArrayStorageTest.java | 2 +- .../storage/impl/SortedArrayStorageTest.java | 2 +- 4 files changed, 38 insertions(+), 52 deletions(-) diff --git a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java index 175a797..6d5ab9e 100644 --- a/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/AbstractArrayStorageTest.java @@ -21,15 +21,11 @@ protected AbstractArrayStorageTest(Storage storage) { this.storage = storage; } - @BeforeAll - static void beforeAll() { - } - @BeforeEach void beforeEach() { - storage.save(r1); - storage.save(r2); - storage.save(r3); + storage.save(R1); + storage.save(R2); + storage.save(R3); } @AfterEach @@ -45,7 +41,6 @@ void setUp() { storage.clear(); } - @Test @DisplayName("Should not throw within size limit, then throws when overflow") void fill() { @@ -64,7 +59,7 @@ void fill() { }); RuntimeException thrown = assertThrows( - StorageException.class, throwingExecutable::execute, "Should throw non specialized StorageException" + StorageException.class, throwingExecutable::execute, "Should throw generic StorageException" ); assertEquals("Storage overflow", thrown.getMessage()); @@ -72,60 +67,59 @@ void fill() { } @Test - public void size() throws Exception { + void size() throws Exception { assertEquals(3, storage.size()); } @Test - public void clear() throws Exception { + void clear() throws Exception { storage.clear(); assertEquals(0, storage.size()); } @Test - public void update() throws Exception { - Resume r2new = makeResume(UUID_2); - storage.update(r2new); + void update() throws Exception { + Resume r2New = new Resume(UUID_2); + storage.update(r2New); - assertSame(storage.get(UUID_2), r2new); + assertSame(r2New, storage.get(UUID_2)); } @Test - public void updateNonExisting() { + void updateNonExisting() { assertThrows( NotExistStorageException.class, - () -> { - storage.update(makeResume("dummy")); - } + () -> storage.update(new Resume("dummy")) ); } @Test - public void getAll() throws Exception { - Resume[] test = new Resume[]{r1, r2, r3}; + void getAll() throws Exception { + Resume[] test = new Resume[]{R1, R2, R3}; + assertEquals(3, storage.getAll().length); assertArrayEquals(test, storage.getAll()); } @Test - public void save() throws Exception { - String newUuid = UUID_4; - Resume r4 = makeResume(newUuid); - + void save() throws Exception { + Resume r4 = new Resume(UUID_4); storage.save(r4); - assertEquals(newUuid, storage.get(newUuid).getUuid()); + + assertEquals(4, storage.getAll().length); + assertSame(r4, storage.get(UUID_4)); } @Test - public void saveExisting() throws Exception { + void saveExisting() throws Exception { assertThrows(ExistStorageException.class, - () -> storage.save(new Resume(UUID_1))); + () -> storage.save(R1)); } + @Test - public void delete() throws Exception { + void delete() throws Exception { storage.delete(UUID_2); - assertAll("storage size is decreased, and access to deleted item correctly throws", () -> assertEquals(2, storage.size()), () -> assertThrows(NotExistStorageException.class, @@ -134,27 +128,23 @@ public void delete() throws Exception { } @Test - public void deleteNonExisting() { + void deleteNonExisting() { assertThrows( NotExistStorageException.class, - () -> { - storage.delete("dummy"); - } + () -> storage.delete("dummy") ); } @Test - public void get() throws Exception { - assertSame(r1, storage.get(UUID_1)); + void get() throws Exception { + assertSame(R1, storage.get(UUID_1)); } @Test - public void getNonExisting() { + void getNonExisting() { assertThrows( NotExistStorageException.class, - () -> { - storage.get("dummy"); - } + () -> storage.get("dummy") ); } } \ No newline at end of file diff --git a/test/ru/javawebinar/basejava/storage/Util.java b/test/ru/javawebinar/basejava/storage/Util.java index 8e5c658..e4587c3 100644 --- a/test/ru/javawebinar/basejava/storage/Util.java +++ b/test/ru/javawebinar/basejava/storage/Util.java @@ -8,17 +8,13 @@ class Util { static final String UUID_3 = "uuid3"; static final String UUID_4 = "uuid4"; - static final Resume r1; - static final Resume r2; - static final Resume r3; - - static Resume makeResume(String uuid){ - return new Resume(uuid); - } + static final Resume R1; + static final Resume R2; + static final Resume R3; static { - r1 = makeResume(UUID_1); - r2 = makeResume(UUID_2); - r3 = makeResume(UUID_3); + R1 = new Resume(UUID_1); + R2 = new Resume(UUID_2); + R3 = new Resume(UUID_3); } } diff --git a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java index 4d9bcdb..2430475 100644 --- a/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/ArrayStorageTest.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.DisplayName; import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; -@DisplayName("ArrayStorage implementstion") +@DisplayName("Test ArrayStorage implementation") public class ArrayStorageTest extends AbstractArrayStorageTest { public ArrayStorageTest() { diff --git a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java index 384a34b..269dd2d 100644 --- a/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java +++ b/test/ru/javawebinar/basejava/storage/impl/SortedArrayStorageTest.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.DisplayName; import ru.javawebinar.basejava.storage.AbstractArrayStorageTest; -@DisplayName("SortedArrayStorage implementstion") +@DisplayName("Test SortedArrayStorage implementation") public class SortedArrayStorageTest extends AbstractArrayStorageTest { public SortedArrayStorageTest() {