-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
MQ67DG
committed
Apr 15, 2021
1 parent
b0405cf
commit 71386dd
Showing
6 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
src/main/java/net/example/fizzbuzz/FizzbuzzApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package net.example.fizzbuzz; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
@SpringBootApplication | ||
public class FizzbuzzApplication { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(FizzbuzzApplication.class, args); | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/net/example/fizzbuzz/controller/FizzBuzzController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package net.example.fizzbuzz.controller; | ||
|
||
import net.example.fizzbuzz.service.FizzBuzzService; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
public class FizzBuzzController { | ||
|
||
public static final String FIZZBUZZ_RESOURCE = "/fizzbuzz-resource"; | ||
private final FizzBuzzService fizzBuzzService; | ||
|
||
public FizzBuzzController(FizzBuzzService fizzBuzzService) { | ||
this.fizzBuzzService = fizzBuzzService; | ||
} | ||
|
||
@GetMapping(path = FIZZBUZZ_RESOURCE) | ||
public ResponseEntity<String> getFizzBuzzResource(@RequestParam final int startFrom, @RequestParam final int endAt) { | ||
|
||
try { | ||
final String result = fizzBuzzService.step3FizzBuzz(startFrom, endAt); | ||
return ResponseEntity.status(HttpStatus.OK).body(result); | ||
} catch (Exception e) { | ||
return ResponseEntity.status(HttpStatus.PRECONDITION_FAILED).body(e.getMessage()); | ||
} | ||
|
||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
src/main/java/net/example/fizzbuzz/service/FizzBuzzService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package net.example.fizzbuzz.service; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
@Service | ||
public class FizzBuzzService { | ||
|
||
static final String BUZZ = "buzz"; | ||
static final String FIZZ = "fizz"; | ||
static final String ALFRESCO = "alfresco"; | ||
static final String INTEGER = "integer"; | ||
static final String DELIMITER = ": "; | ||
static final String SPACE = " "; | ||
|
||
public String step1FizzBuzz(final int startFrom, final int endAt) { | ||
checkArgumentsCondition(startFrom, endAt); | ||
|
||
final StringBuilder builder = buildResultString(startFrom, endAt, 1); | ||
|
||
return builder.toString().stripTrailing(); | ||
} | ||
|
||
public String step2FizzBuzz(final int startFrom, final int endAt) { | ||
checkArgumentsCondition(startFrom, endAt); | ||
|
||
final StringBuilder builder = buildResultString(startFrom, endAt, 2); | ||
|
||
return builder.toString().stripTrailing(); | ||
} | ||
|
||
public String step3FizzBuzz(final int startFrom, final int endAt) { | ||
checkArgumentsCondition(startFrom, endAt); | ||
|
||
final StringBuilder builder = new StringBuilder(); | ||
String step2Results = step2FizzBuzz(startFrom, endAt); | ||
builder.append(step2Results); | ||
final int itemsCount = endAt - startFrom + 1; | ||
builder.append("\n"); | ||
builder.append(countItemsAndWriteToString(step2Results, itemsCount)); | ||
|
||
return builder.toString().stripTrailing(); | ||
} | ||
|
||
private String countItemsAndWriteToString(final String input, final int itemsCount) { | ||
final StringBuilder countBuilder = new StringBuilder(); | ||
final List<String> stringList = List.of(input.split(SPACE)); | ||
final int fizzOccurrences = Collections.frequency(stringList, FIZZ); | ||
final int buzzOccurrences = Collections.frequency(stringList, BUZZ); | ||
final int fizzBuzzOccurrences = Collections.frequency(stringList, FIZZ + BUZZ); | ||
final int alfrescoOccurrences = Collections.frequency(stringList, ALFRESCO); | ||
final int integerOccurrences = | ||
itemsCount - (fizzBuzzOccurrences + fizzOccurrences + buzzOccurrences + alfrescoOccurrences); | ||
countBuilder.append(FIZZ).append(": ").append(fizzOccurrences).append(SPACE); | ||
countBuilder.append(BUZZ).append(": ").append(buzzOccurrences).append(SPACE); | ||
countBuilder.append(FIZZ + BUZZ).append(": ").append(fizzBuzzOccurrences).append(SPACE); | ||
countBuilder.append(ALFRESCO).append(": ").append(alfrescoOccurrences).append(SPACE); | ||
countBuilder.append(INTEGER).append(DELIMITER).append(integerOccurrences); | ||
return countBuilder.toString(); | ||
} | ||
|
||
private StringBuilder buildResultString(int startFrom, int endAt, int stepNumber) { | ||
final StringBuilder builder = new StringBuilder(); | ||
|
||
for (int i = startFrom; i <= endAt; i++) { | ||
if (shouldPutAlfresco(stepNumber, i)) { | ||
builder.append(ALFRESCO).append(SPACE); | ||
continue; | ||
} | ||
if (isDivisibleBy(i, 3)) { | ||
builder.append(FIZZ); | ||
} | ||
if (isDivisibleBy(i, 5)) { | ||
builder.append(BUZZ); | ||
} | ||
if (!isDivisibleBy(i, 3) && !isDivisibleBy(i, 5)) { | ||
builder.append(i); | ||
} | ||
builder.append(SPACE); | ||
|
||
} | ||
return builder; | ||
} | ||
|
||
private boolean shouldPutAlfresco(int stepNumber, int number) { | ||
return stepNumber == 2 && String.valueOf(number).contains("3"); | ||
} | ||
|
||
private void checkArgumentsCondition(int startFrom, int endAt) { | ||
if (endAt < startFrom) { | ||
throw new IllegalArgumentException( | ||
String.format("End of loop (%s) smaller than beggining (%s)", endAt, startFrom)); | ||
} | ||
} | ||
|
||
private boolean isDivisibleBy(final int number, final int divisor) { | ||
return number % divisor == 0; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
59 changes: 59 additions & 0 deletions
59
src/test/java/net/example/fizzbuzz/integration/FizzBuzzIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package net.example.fizzbuzz.integration; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.MvcResult; | ||
|
||
import static net.example.fizzbuzz.controller.FizzBuzzController.FIZZBUZZ_RESOURCE; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
@SpringBootTest | ||
@AutoConfigureMockMvc | ||
public class FizzBuzzIntegrationTest { | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@Test | ||
void whenProperParamsPassed_thenExpectProperFizzBuzzResult() throws Exception { | ||
|
||
final MvcResult mvcResult = mockMvc.perform(get(FIZZBUZZ_RESOURCE) | ||
.param("startFrom", "1") | ||
.param("endAt", "20") | ||
) | ||
.andExpect(status().isOk()) | ||
.andReturn(); | ||
|
||
final String result = mvcResult.getResponse().getContentAsString(); | ||
assertEquals("1 2 alfresco 4 buzz fizz 7 8 fizz buzz 11 fizz alfresco 14 fizzbuzz 16 17 fizz 19 buzz\n" + | ||
"fizz: 4 buzz: 3 fizzbuzz: 1 alfresco: 2 integer: 10", result); | ||
} | ||
|
||
@Test | ||
void whenNotProperParamsPassed_thenExpect4xx() throws Exception { | ||
|
||
final MvcResult mvcResult = mockMvc.perform(get(FIZZBUZZ_RESOURCE) | ||
.param("startFrom", "1") | ||
.param("endAt", "0") | ||
) | ||
.andExpect(status().is4xxClientError()) | ||
.andReturn(); | ||
} | ||
|
||
@Test | ||
void whenNotStringParamsPassed_thenExpect4xx() throws Exception { | ||
|
||
final MvcResult mvcResult = mockMvc.perform(get(FIZZBUZZ_RESOURCE) | ||
.param("startFrom", "b") | ||
.param("endAt", "b") | ||
) | ||
.andExpect(status().is4xxClientError()) | ||
.andReturn(); | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
src/test/java/net/example/fizzbuzz/service/FizzBuzzServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package net.example.fizzbuzz.service; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
class FizzBuzzServiceTest { | ||
|
||
private FizzBuzzService objectUnderTest = new FizzBuzzService(); | ||
|
||
@Test | ||
void shouldProperlyTestStep1() { | ||
final String result = objectUnderTest.step1FizzBuzz(1, 20); | ||
assertEquals("1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz", result); | ||
} | ||
|
||
@Test | ||
void shouldFailTestStep1() { | ||
assertThrows(IllegalArgumentException.class, () -> {objectUnderTest.step1FizzBuzz(1, 0);}); | ||
} | ||
|
||
@Test | ||
void shouldProperlyTestStep2() { | ||
final String result = objectUnderTest.step2FizzBuzz(1, 20); | ||
assertEquals("1 2 alfresco 4 buzz fizz 7 8 fizz buzz 11 fizz alfresco 14 fizzbuzz 16 17 fizz 19 buzz", result); | ||
} | ||
|
||
@Test | ||
void shouldFailTestStep2() { | ||
assertThrows(IllegalArgumentException.class, () -> {objectUnderTest.step2FizzBuzz(1, 0);}); | ||
} | ||
|
||
@Test | ||
void shouldProperlyTestStep3() { | ||
final String result = objectUnderTest.step3FizzBuzz(1, 20); | ||
assertEquals("1 2 alfresco 4 buzz fizz 7 8 fizz buzz 11 fizz alfresco 14 fizzbuzz 16 17 fizz 19 buzz\n" + | ||
"fizz: 4 buzz: 3 fizzbuzz: 1 alfresco: 2 integer: 10", result); | ||
} | ||
|
||
@Test | ||
void shouldFailTestStep3() { | ||
assertThrows(IllegalArgumentException.class, () -> {objectUnderTest.step3FizzBuzz(1, 0);}); | ||
} | ||
|
||
|
||
} |