Skip to content

Commit

Permalink
Merge pull request #1 from dmitriichernykh/homework_1-1
Browse files Browse the repository at this point in the history
implement scala homework 1-1 tasks
  • Loading branch information
dmitr2 authored Oct 4, 2020
2 parents 4f7cb9a + b526bd3 commit 2bd1de4
Show file tree
Hide file tree
Showing 37 changed files with 354 additions and 0 deletions.
3 changes: 3 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
scalaVersion := "2.13.3"

libraryDependencies += "org.scalactic" %% "scalactic" % "3.2.0"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.0" % "test"
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/caesar/model/CipherRequest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.caesar.model

case class CipherRequest(text: String, shift: Int = 10)
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/caesar/model/CipherResponse.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.caesar.model

case class CipherResponse(text: String)
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/caesar/model/DecipherRequest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.caesar.model

case class DecipherRequest(text: String, shift: Int = 10)
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/caesar/model/DecipherResponse.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.caesar.model

case class DecipherResponse(text: String)
8 changes: 8 additions & 0 deletions src/main/scala/ru/otus/sc/caesar/service/CaesarCipher.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.otus.sc.caesar.service

import ru.otus.sc.caesar.model._

trait CaesarCipher {
def cipher(request: CipherRequest): CipherResponse
def decipher(request: DecipherRequest): DecipherResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.otus.sc.caesar.service.impl

import ru.otus.sc.caesar.model.{CipherRequest, CipherResponse, DecipherRequest, DecipherResponse}
import ru.otus.sc.caesar.service.CaesarCipher

class CaesarCipherImpl extends CaesarCipher {
private val cardinality = 128

/** Enciphers a text using Caesar cipher
* @param request a text to be enciphered
* @return cipher text
*/
def cipher(request: CipherRequest): CipherResponse =
CipherResponse(
request.text.map(c => ((c + request.shift) % cardinality).toChar)
)

/** Deciphers a cipher text using Caesar cipher
*
* @param request a cipher text to be deciphered
* @return a deciphered text
*/
def decipher(request: DecipherRequest): DecipherResponse =
DecipherResponse(
request.text.map(c => ((c - request.shift) % cardinality).toChar)
)
}
5 changes: 5 additions & 0 deletions src/main/scala/ru/otus/sc/counter/dao/CounterDao.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ru.otus.sc.counter.dao

trait CounterDao {
var counter: Int
}
12 changes: 12 additions & 0 deletions src/main/scala/ru/otus/sc/counter/dao/impl/CounterDaoImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ru.otus.sc.counter.dao.impl

import ru.otus.sc.counter.dao.CounterDao

class CounterDaoImpl extends CounterDao {
private var _storage = 0

def counter: Int = _storage
def counter_=(value: Int): Unit = {
_storage = value
}
}
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/counter/model/CounterRequest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.counter.model

case object CounterRequest
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/counter/model/CounterResponse.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.counter.model

case class CounterResponse(value: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.sc.counter.service

import ru.otus.sc.counter.model.{CounterRequest, CounterResponse}

trait CounterService {
def count(request: CounterRequest): CounterResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.otus.sc.counter.service.impl

import ru.otus.sc.counter.dao.CounterDao
import ru.otus.sc.counter.model.{CounterRequest, CounterResponse}
import ru.otus.sc.counter.service.CounterService

class CounterServiceImpl(dao: CounterDao) extends CounterService {

/** Counts how many times the method was called
*
* @param request request with no parameters
* @return number representing total count of the method calls
*/
override def count(request: CounterRequest): CounterResponse = {
val result = dao.counter + 1
dao.counter = result
CounterResponse(result)
}
}
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/echo/model/EchoRequest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.echo.model

case class EchoRequest(value: String)
3 changes: 3 additions & 0 deletions src/main/scala/ru/otus/sc/echo/model/EchoResponse.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.echo.model

case class EchoResponse(value: String)
7 changes: 7 additions & 0 deletions src/main/scala/ru/otus/sc/echo/service/EchoService.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.sc.echo.service

import ru.otus.sc.echo.model.{EchoRequest, EchoResponse}

trait EchoService {
def echo(request: EchoRequest): EchoResponse
}
14 changes: 14 additions & 0 deletions src/main/scala/ru/otus/sc/echo/service/impl/EchoServiceImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.otus.sc.echo.service.impl

import ru.otus.sc.echo.model.{EchoRequest, EchoResponse}
import ru.otus.sc.echo.service.EchoService

class EchoServiceImpl extends EchoService {

/** Returns the same value as it is in the input
*
* @param request request with the input value
* @return response containing the input value
*/
override def echo(request: EchoRequest): EchoResponse = EchoResponse(request.value)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ru.otus.sc.factorial.dao

trait Factorial2020Dao {
def nthDigit(n: Int): Char
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.otus.sc.factorial.dao.impl

import ru.otus.sc.factorial.dao.Factorial2020Dao

import scala.math.BigInt

class Factorial2020DaoImpl extends Factorial2020Dao {
private val k = 2020
private lazy val factorial =
(1 to k).foldLeft(BigInt(1))((acc, term) => acc * term).toString.toVector

def nthDigit(n: Int): Char = if (0 < n && n <= factorial.length) factorial(n - 1) else '?'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.factorial.model

case class Factorial2020Request(position: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.factorial.model

case class Factorial2020Response(digit: Char)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.sc.factorial.service

import ru.otus.sc.factorial.model.{Factorial2020Request, Factorial2020Response}

trait Factorial2020Service {
def nthDigit(request: Factorial2020Request): Factorial2020Response
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.otus.sc.factorial.service.impl

import ru.otus.sc.factorial.dao.impl.Factorial2020DaoImpl
import ru.otus.sc.factorial.model.{Factorial2020Request, Factorial2020Response}
import ru.otus.sc.factorial.service.Factorial2020Service

class Factorial2020ServiceImpl(dao: Factorial2020DaoImpl) extends Factorial2020Service {

/** Returns n-th digit of number 2020!
*
* @param request request with the position number
* @return the requested digit of 2020! or ? if the requested position is incorrect
*/
def nthDigit(request: Factorial2020Request): Factorial2020Response = {
Factorial2020Response(dao.nthDigit(request.position))
}
}
5 changes: 5 additions & 0 deletions src/main/scala/ru/otus/sc/fifa/dao/WorldChampionDao.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ru.otus.sc.fifa.dao

trait WorldChampionDao {
def winCount(year: String): Int
}
13 changes: 13 additions & 0 deletions src/main/scala/ru/otus/sc/fifa/dao/impl/WorldChampionDaoImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.otus.sc.fifa.dao.impl

import ru.otus.sc.fifa.dao.WorldChampionDao

class WorldChampionDaoImpl extends WorldChampionDao {
def winCount(country: String): Int = {
if (country == "Brazil") 5
else if (country == "Germany" || country == "Italy") 4
else if (country == "Argentina" || country == "France" || country == "Uruguay") 2
else if (country == "England" || country == "Spain") 1
else 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.fifa.model

case class WorldChampionRequest(country: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.sc.fifa.model

case class WorldChampionResponse(winsCount: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.sc.fifa.service

import ru.otus.sc.fifa.model.{WorldChampionRequest, WorldChampionResponse}

trait WorldChampionService {
def totalWinCount(request: WorldChampionRequest): WorldChampionResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.otus.sc.fifa.service.impl

import ru.otus.sc.fifa.dao.WorldChampionDao
import ru.otus.sc.fifa.model.{WorldChampionRequest, WorldChampionResponse}
import ru.otus.sc.fifa.service.WorldChampionService

class WorldChampionServiceImpl(dao: WorldChampionDao) extends WorldChampionService {

/** Answers how many times a country won FIFA World Cup
*
* @param request request with a country name
* @return response with a total wins count
*/
def totalWinCount(request: WorldChampionRequest): WorldChampionResponse = {
WorldChampionResponse(dao.winCount(request.country))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import ru.otus.sc.greet.model.{GreetRequest, GreetResponse}
import ru.otus.sc.greet.service.GreetingService

class GreetingServiceImpl(dao: GreetingDao) extends GreetingService {

/** Greets a human by name with prefix and postfix added. Screams if a request is not from a human.
*
* @param request name and an indication of a human
* @return a greeting or a scream
*/
def greet(request: GreetRequest): GreetResponse =
if (request.isHuman)
GreetResponse(s"${dao.greetingPrefix} ${request.name} ${dao.greetingPostfix}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.otus.sc.caesar.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.caesar.model.{CipherRequest, DecipherRequest}

class TestCaesarCipherImpl extends AnyFreeSpec {
"round trip should get equivalent input and output" in {
val service = new CaesarCipherImpl
val input = "Hello World!"
assert(
service.decipher(DecipherRequest(service.cipher(CipherRequest(input)).text)).text === input
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.otus.sc.counter.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.counter.dao.impl.CounterDaoImpl
import ru.otus.sc.counter.model.{CounterRequest, CounterResponse}

class TestCounterServiceImpl extends AnyFreeSpec {
"CounterServiceImpl" - {
"should increment a counter" in {
val counterServiceImpl = new CounterServiceImpl(new CounterDaoImpl)
val counter = counterServiceImpl.count(CounterRequest()).value
val actual = counterServiceImpl.count(CounterRequest())
val expected = CounterResponse(1 + counter)
assert(expected === actual)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.otus.sc.echo.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.echo.model.{EchoRequest, EchoResponse}

class TestEchoServiceImpl extends AnyFreeSpec {
"EchoServiceImpl" - {
"should return an input value as an output" in {
val echoServiceImpl = new EchoServiceImpl
val input = "hello"
val actual = echoServiceImpl.echo(EchoRequest(input))
assert(EchoResponse(input) === actual)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.otus.sc.factorial.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.factorial.dao.impl.Factorial2020DaoImpl
import ru.otus.sc.factorial.model.{Factorial2020Request, Factorial2020Response}

class TestFactorial2020ServiceImpl extends AnyFreeSpec {
"2020!" - {
val service = new Factorial2020ServiceImpl(new Factorial2020DaoImpl)
"should have digit 0 in the last position" in {
val result = service.nthDigit(Factorial2020Request(5802))
assert(result === Factorial2020Response('0'))
}
"should return '?' for negative position" in {
val result = service.nthDigit(Factorial2020Request(-5))
assert(result === Factorial2020Response('?'))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ru.otus.sc.fifa.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.fifa.dao.impl.WorldChampionDaoImpl
import ru.otus.sc.fifa.model.WorldChampionRequest

class TestWorldChampionServiceImpl extends AnyFreeSpec {
"WorldChampionService" - {
"should return a positive integer for a world champion" in {
val worldChampionServiceImpl = new WorldChampionServiceImpl(new WorldChampionDaoImpl)
val result = worldChampionServiceImpl.totalWinCount(WorldChampionRequest("France"))
assert(result.winsCount > 0)
}
"should return zero if a country did not win FIFA World Cup" in {
val worldChampionServiceImpl = new WorldChampionServiceImpl(new WorldChampionDaoImpl)
val result = worldChampionServiceImpl.totalWinCount(WorldChampionRequest("Russia"))
assert(result.winsCount === 0)
}
}
}
16 changes: 16 additions & 0 deletions src/test/scala/ru/otus/sc/greet/dao/impl/TestGreetingDaoImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ru.otus.sc.greet.dao.impl

import org.scalatest.freespec.AnyFreeSpec

class TestGreetingDaoImpl extends AnyFreeSpec {
"GreetingDaoImpl" - {
"should have prefix 'Hi'" in {
val greetingDao = new GreetingDaoImpl
assert(greetingDao.greetingPrefix === "Hi")
}
"should have postfix '!'" in {
val greetingDao = new GreetingDaoImpl
assert(greetingDao.greetingPostfix === "!")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.otus.sc.greet.service.impl

import org.scalatest.freespec.AnyFreeSpec
import ru.otus.sc.greet.dao.impl.GreetingDaoImpl
import ru.otus.sc.greet.model.{GreetRequest, GreetResponse}

class TestGreetingServiceImpl extends AnyFreeSpec {
"GreetingServiceImpl" - {
"when a request" - {
"is not from a human should scream" in {
val greetingServiceImpl = new GreetingServiceImpl(new GreetingDaoImpl)
val expected = GreetResponse("AAAAAAAAAA!!!!!!")
val actual = greetingServiceImpl.greet(GreetRequest("Legolas", isHuman = false))
assert(expected === actual)
}

"is a human should greet the human" in {
val greetingServiceImpl = new GreetingServiceImpl(new GreetingDaoImpl)
val humanName = "Aragorn"
val actual = greetingServiceImpl.greet(GreetRequest(humanName))
assert(actual.greeting contains humanName)
}
}
}
}

0 comments on commit 2bd1de4

Please sign in to comment.