рд╣рдореЗрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдЬрдВрдЧрд▓ рд╕реЗ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИ: рд╣рдо рдЬреБрдбрд╝рдирд╛рд░ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рддрдХ рдПрдХ рдЫреЛрдЯрд╛ рд░рд╛рд╕реНрддрд╛ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВ


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рд╕реНрдХрд╛рд▓рд╛ рдХреА рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рд░рдВрдкрд░рд┐рдХ рдкрд░реАрдХреНрд╖рдг рдбрд┐рдЬрд╛рдЗрди рд╢реИрд▓реА рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рджреГрд╖реНрдЯрд┐рдХреЛрдг рджрд░реНрдЬрдиреЛрдВ рдФрд░ рд╕реИрдХрдбрд╝реЛрдВ рдЧрд┐рд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЖрд╕рд╛рди рдФрд░ рдЕрдзрд┐рдХ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрд▓рддреА рд╣реБрдИ рдЗрдЪреНрдЫрд╛ рд╕реЗ рдХрдИ рдорд╣реАрдиреЛрдВ рдХреЗ рджрд░реНрдж рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛ред


рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдХреЛрдб рдХреЛ рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рдЪрд╛рд░ рд╕рднреА рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдФрд░ рдкрд░реАрдХреНрд╖рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реЛрдЧрд╛ рдЬреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкреНрд░рддрд┐рдорд╛рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдПрдХ рд╕рдВрдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдЬреАрдердм рдХрд╛ рд▓рд┐рдВрдХ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╕рдорд╕реНрдпрд╛


рдпрджрд┐ рдЖрдкрдиреЗ рдХрднреА рднреА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рд╣реИ (рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ - рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг, рдПрдХреАрдХрд░рдг рдпрд╛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ), рддреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:


//     .     //  ,      ,  //     . "   = 'customer'" - { import TestHelper._ "    < 250    -  " in { val db: Database = Database.forURL(TestConfig.generateNewUrl()) migrateDb(db) insertUser(db, id = 1, name = "test", role = "customer") insertPackage(db, id = 1, name = "test", userId = 1, status = "new") insertPackageItems(db, id = 1, packageId = 1, name = "test", price = 30) insertPackageItems(db, id = 2, packageId = 1, name = "test", price = 20) insertPackageItems(db, id = 3, packageId = 1, name = "test", price = 40) val svc = new SomeProductionLogic(db) val result = svc.calculatePrice(packageId = 1) result shouldBe 90 } "    >= 250    -  10%" in { val db: Database = Database.forURL(TestConfig.generateNewUrl()) migrateDb(db) insertUser(db, id = 1, name = "test", role = "customer") insertPackage(db, id = 1, name = "test", userId = 1, status = "new") insertPackageItems(db, id = 1, packageId = 1, name = "test", price = 100) insertPackageItems(db, id = 2, packageId = 1, name = "test", price = 120) insertPackageItems(db, id = 3, packageId = 1, name = "test", price = 130) insertBonus(db, id = 1, packageId = 1, bonusAmount = 40) val svc = new SomeProductionLogic(db) val result = svc.calculatePrice(packageId = 1) result shouldBe 279 } } "   = 'vip'" - {/*...*/} 

рдпрд╣ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЗ рд▓рд┐рдП рдкрд╕рдВрджреАрджрд╛ рд╣реИ, рд╡рд┐рдХрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╕реНрддрд░реЛрдВ (рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг, рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг, рдПрдВрдб-рдЯреВ-рдПрдВрдб) рдХреЗ рд▓рдЧрднрдЧ 1000 рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ, рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рд╕рднреА, рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╕рдорд╛рди рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдереЗред рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдврд╝рддреА рдЧрдИ, рд╣рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛рдУрдВ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рдордВрджреА рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рд╢реБрд░реВ рд╣реБрдЖ: рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХреНрд░рдо рдореЗрдВ рд░рдЦрдирд╛ рд╡реНрдпрд╡рд╕рд╛рдп-рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдХрдо рд╕рдордп рдирд╣реАрдВ рд▓рдЧрд╛ред


рдирдП рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╕рдордп, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдЦрд░реЛрдВрдЪ рд╕реЗ рд╕реЛрдЪрдирд╛ рдкрдбрд╝рддрд╛ рдерд╛ рдХрд┐ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЕрдХреНрд╕рд░ рдкрдбрд╝реЛрд╕реА рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХрджрдоред рдирддреАрдЬрддрди, рдЬрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдбреЗрдЯрд╛ рдореЙрдбрд▓ рдмрджрд▓ рдЧрдпрд╛, рдХрд╛рд░реНрдб рдХрд╛ рдШрд░ рдЯреВрдЯ рдЧрдпрд╛ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдПрдХ рдирдП рддрд░реАрдХреЗ рд╕реЗ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдерд╛: рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛, рдмрд╕ рд╕рд╣рд╛рдпрдХреЛрдВ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдмрджрд▓рд╛рд╡, рд╕рдмрд╕реЗ рдЦрд░рд╛рдм - рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдПрдХ рдЧрд╣рд░рд╛ рд╡рд┐рд╕рд░реНрдЬрди рдФрд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ред


рдЬрдм рдкрд░реАрдХреНрд╖рдг рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЧрдпрд╛ - рдЕрд░реНрдерд╛рдд, рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдореЗрдВ рдмрдЧ рдХреЗ рдХрд╛рд░рдг, рдФрд░ рди рд╣реА рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг - рдпрд╣ рд╕рдордЭрдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛ рдХрд┐ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ рдХреБрдЫ рдЧрд▓рдд рдХрд╣рд╛рдВ рд╣реБрдЖред рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдПрдХ рд▓рдВрдмрд╛ рд╕рдордп рд▓рдЧрд╛, рдХрд┐рд╕реА рдХреЛ рднреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рдЬреНрдЮрд╛рди рдирд╣реАрдВ рдерд╛ - рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдХреБрдЫ рд╢рд░реНрддреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдпрд╣ рд╕рдм рджрд░реНрдж рдЗрд╕ рдбрд┐рдЬрд╛рдЗрди рдХреА рджреЛ рдЧрд╣рд░реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд▓рдХреНрд╖рдг рд╣реИ:


  1. рдкрд░реАрдХреНрд╖рдг рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрд╣реБрдд рдвреАрд▓реЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рддреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдЕрджреНрд╡рд┐рддреАрдп рд╣реИ, рдмрд░реНрдл рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХреА рддрд░рд╣ред рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдбрд┐рдореЛрдЯрд┐рд╡реЗрдЯреНрд╕ рд╣реЛрддрд╛ рд╣реИред рдореБрдЦреНрдп рдмрд╛рдд рд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╡рд░рдг рд╡рд┐рдЪрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ - рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░рд╛ рд╕рддреНрдпрд╛рдкрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВред рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдирдП рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдореБрдЦреНрдп рддрд░реАрдХрд╛ рдмрди рд░рд╣рд╛ рд╣реИред
  2. рдЯреЗрд╕реНрдЯ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реНрдерд╛рдиреАрдпрдХреГрдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВред рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЗрд╕реЗ рдЕрдкрдиреЗ рд╕рд┐рд░ рдореЗрдВ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдпрд╛ рдбреАрдмрдЧрд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдореЛрдбрд▓рд┐рдВрдЧ


рдХреНрдпрд╛ рд╣рдо рдмреЗрд╣рддрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? (рд╕реНрдкреЙрдпрд▓рд░: рд╣рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред) рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдХреНрдпрд╛ рд╣реИрдВред


 val db: Database = Database.forURL(TestConfig.generateNewUrl()) migrateDb(db) insertUser(db, id = 1, name = "test", role = "customer") insertPackage(db, id = 1, name = "test", userId = 1, status = "new") insertPackageItems(db, id = 1, packageId = 1, name = "test", price = 30) insertPackageItems(db, id = 2, packageId = 1, name = "test", price = 20) insertPackageItems(db, id = 3, packageId = 1, name = "test", price = 40) 

рдкрд░реАрдХреНрд╖рдг рдХреЛрдб, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛ - рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛, рдЖрдХрд╛рд░, рд╡реЙрд▓реНрдпреВрдо, рдлрд╝рд┐рд▓реНрдЯрд░ рдЖрджрд┐ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕реЗ рдЕрдХреНрд╕рд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА - рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдиреВ рдФрд░ рдореЗрдиреВ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ рдбреЗрдЯрд╛рдмреЗрд╕ред рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╕реНрдерд┐рд░рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ - рд╡рд╣ рд╕реНрдерд┐рддрд┐ рдЬрд┐рд╕рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдФрд░ / рдпрд╛ рдбреЗрдЯрд╛ рдкреНрд░рджрд╛рддрд╛ рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░, рдЕрдХреНрд╕рд░ рд░рд╛рдЬреНрдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрддреЗ рд╣реИрдВред


рд╣рдо рдЗрд╕ рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрднрд░рддрд╛ рддреИрдпрд╛рд░ рдХрд░реЗрдВрдЧреЗ - рдбреЗрдЯрд╛рдмреЗрд╕ (рдХрддрд╛рд░, рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛, рдЖрджрд┐) рднрд░реЗрдВред рддреИрдпрд╛рд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде, рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рд╡рд░реНрдЧ (рд╕реЗрд╡рд╛рдУрдВ, рдореЙрдбреНрдпреВрд▓, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА, рдЖрджрд┐) рдХреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХрд░рддреЗ рд╣реИрдВред


 val svc = new SomeProductionLogic(db) val result = svc.calculatePrice(packageId = 1) 

рдХреБрдЫ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ, рд╣рдореЗрдВ рдПрдХ рд╡реНрдпрд╛рдкрд╛рд░-рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрд░рд┐рдгрд╛рдо ( рдЖрдЙрдЯрдкреБрдЯ ) рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ - рджреЛрдиреЛрдВ рд╕реНрдкрд╖реНрдЯ (рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛) рдФрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд - рдХреБрдЦреНрдпрд╛рдд рд░рд╛рдЬреНрдп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди: рдбреЗрдЯрд╛рдмреЗрд╕, рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛, рдЖрджрд┐ред


 result shouldBe 90 

рдЕрдВрдд рдореЗрдВ, рд╣рдо рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рд╡рд╣реА рд╣реИрдВ рдЬреЛ рд╡реЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдереЗ, рдкрд░реАрдХреНрд╖рдг рдХреЛ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рдЕрднрд┐рдХрдерди рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝ рджреЗрдВ ред



рдпрд╣ рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐, рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ, рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕рдорд╛рди рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВ: рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рддреИрдпрд╛рд░ рдХрд░рдирд╛, рдЙрди рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдФрд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рд▓реЛрдЧреЛрдВ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ред рд╣рдо рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдмрд╣реБрдд рдвреАрд▓реЗ рд░реВрдк, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ред рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдирдпрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдмреАрдбреАрдбреА-рд╢реИрд▓реА ( рд╡реНрдпрд╡рд╣рд╛рд░-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕ ) рдореЗрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд┐рд▓рд┐рдЯреА рдХрд╛ рдХреНрдпрд╛? рдкрд░реАрдХреНрд╖рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдХрд┐рд╕реА рднреА рдЪрд░рдг рдореЗрдВ рдЖрдкрдХреА рдкрд╕рдВрдж рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрдИ рдордзреНрдпрд╡рд░реНрддреА рдЪрд░рдг рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдПрдХ рд╕реНрдерд┐рд░рддрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рдПрдХ рддрд░рд╣ рдХреА рдорд╛рдирд╡-рдкрдардиреАрдп рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рднрд░рдиреЗ рд╡рд╛рд▓реА рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрд╕реАрдо рд░реВрдк рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рдпреЛрдЧреНрдп рд╣реИ, рд▓реЗрдХрд┐рди, рдЕрдВрддрддрдГ, рдпрд╣ рд╣рдореЗрд╢рд╛ рдореБрдЦреНрдп рдЪрд░рдгреЛрдВ рдореЗрдВ рдЖрддрд╛ рд╣реИред



рдкрд░реАрдХреНрд╖рдг рдЪрд▓ рд░рд╣рд╛ рд╣реИ


рдЖрдЗрдП рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдХреИрд╕реЗ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╣рдо рд▓реЗрдЦрди рдФрд░ рд╕рд╣рд╛рдпрдХ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХрдо рд╢реНрд░рдо-рдЧрд╣рди рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдЦрдж рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдХрдо рд╕реНрдкрд╖реНрдЯ рдЧреИрд░-рдЕрджреНрд╡рд┐рддреАрдп (рдмрд╛рд░-рдмрд╛рд░ рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛) рдирд┐рд░реНрджреЗрд╢, рдЕрдиреБрдмрдВрдзреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдпрд╛ рдлрд┐рд░ рд╕реЗ рднрд░рдиреЗ рдХреЗ рдмрд╛рдж рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдХрдо рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрдо рд╕рдордп рд▓рдЧреЗрдЧрд╛ред рдкрд░реАрдХреНрд╖рдг рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдХреЛ рдХреЛрдб рдХреЗ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдЯреБрдХрдбрд╝реЛрдВ рдХреЗ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЛ рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рд╡рд┐рдЪрд╛рд░рд╣реАрди рдирдХрд▓ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдирдЬрд╝рд░ рдЖрдПред рдкреНрд░рд┐рдбрд┐рдХреНрдЯрд┐рдмрд┐рд▓рд┐рдЯреА рдкрдардиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддреА рд╣реИ рдФрд░ рд╕рдордп рдХреА рдмрдЪрдд рдХрд░рддреА рд╣реИ - рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рднреМрддрд┐рдХреА рдХреЗ рдЫрд╛рддреНрд░реЛрдВ рдХреЛ рдЧрдгрд┐рддреАрдп рднрд╛рд╖рд╛ рдХреЗ рдмрдЬрд╛рдп рдлрд╝реНрд░реА-рдлрд╝реЙрд░реНрдо рд╢рдмреНрджреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдирдП рдлреЙрд░реНрдореВрд▓реЗ рдХреЛ рдорд╛рд╕реНрдЯрд░ рдХрд░рдиреЗ рдореЗрдВ рдХрд┐рддрдирд╛ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдзреНрдпрд╛рди рднрдЯрдХрд╛рдиреЗ рд╡рд╛рд▓реА рдФрд░ рд╕реВрдЪрдирд╛рдУрдВ рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рдХреЗрд╡рд▓ рдЖрд╡реЗрджрди рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ: рдХреНрдпрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрдирдкреБрдЯ рдкрд░ рдХреНрдпрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ, рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдХреНрдпрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред



рдЖрдЗрдП рдкрд░реАрдХреНрд╖рдг рдЙрдкрдХрд░рдг рдХреЗ рдореЙрдбрд▓ рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВред рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ, рдЗрд╕ рдЧреНрд░рд╛рдлрд╝ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдХреЛ рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░, рдФрд░ рдПрдХ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди - рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЕрдВрддрд┐рдо рдПрдХ рддрдХ рдЖ рд╕рдХрддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреА рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ : рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ (рдЪрд▓реЛ рдЗрд╕реЗ prepare рдХрд╣рддреЗ рд╣реИрдВ), рдкрд░реАрдХреНрд╖рдг рдХреЛрдб execute ( execute ) рдФрд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо ( check ) рдХреА check ред рд╣рдо рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдЪрд╛рд░реНрдЯ, рд╕реНрдерд┐рд░рддрд╛ рдХрд╛ рдкрд╣рд▓рд╛ рдмрд┐рдВрджреБ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рдкрд░рд┐рдгрд╛рдореА рдЙрдЪреНрдЪ-рдХреНрд░рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░реАрдХреНрд╖рдг рдЬреАрд╡рди рдЪрдХреНрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред


рдЬреАрд╡рди рдЪрдХреНрд░ рд╕рдорд╛рд░реЛрд╣
 def runTestCycle[FX, DEP, OUT, F[_]]( fixture: FX, prepare: FX => DEP, execute: DEP => OUT, check: OUT => F[Assertion] ): F[Assertion] = //  Scala  ,   check(execute(prepare(fixture))) //        andThen: (prepare andThen execute andThen check) (fixture) 

рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдп рдХрд╣рд╛рдВ рд╕реЗ рдЖрддреЗ рд╣реИрдВ? рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд╕реАрдорд┐рдд рддрд░реАрдХреЗ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░реЗрдВрдЧреЗ - рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЧреАрд▓реЗ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрддреНрдпрд╛рджрд┐ - рдЗрд╕рд▓рд┐рдП, рддреИрдпрд╛рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдк рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрдВрдЧреЗред рдирддреАрдЬрддрди, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЬреАрд╡рди-рдЪрдХреНрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬреЛ рдбреЗрдЯрд╛ рддреИрдпрд╛рд░реА рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВред рдЪреВрдБрдХрд┐ рдХреЛрдб рдХреА рдЬрд╛рдБрдЪ execute рдФрд░ check рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЕрдиреЛрдЦреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП execute рдФрд░ check рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рдПрдЧреАред


рдЬреАрд╡рдирдЪрдХреНрд░ рд╕рдорд╛рд░реЛрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд
 //    тАФ     def prepareDatabase[DB](db: Database): DbFixture => DB def testInDb[DB, OUT]( fixture: DbFixture, execute: DB => OUT, check: OUT => Future[Assertion], db: Database = getDatabaseHandleFromSomewhere(), ): Future[Assertion] = runTestCycle(fixture, prepareDatabase(db), execute, check) 

рд╕рднреА рдкреНрд░рд╢рд╛рд╕рдирд┐рдХ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдХреЗ, рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реБрдП рдмрд┐рдирд╛ рдкрд░реАрдХреНрд╖рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред рд░рдЪрдирд╛ рдХреЗ рдХрд╛рд░рдг, рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╣реАрдВ рднреА рдШреБрд╕рдкреИрда рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╡рд╣рд╛рдВ рдбреЗрдЯрд╛ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрд░реАрдХреНрд╖рдг рдХреА рджреВрд╕рд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ - рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╕реНрдерд╛рдиреАрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХреА рдХрдореАред рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдкрд░ рд▓реЙрдЧрд┐рдВрдЧ рдЬреЛрдбрд╝реЗрдВред рд╣рдорд╛рд░рд╛ рд▓реЙрдЧрд┐рдВрдЧ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдкреИрджрд╛ рдХрд░реЗрдЧрд╛ - рдХрдВрд╕реЛрд▓ рдкрд░ рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ред рдЗрд╕рд▓рд┐рдП, рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдВрдЧреЗред


рд▓реЙрдЧрд┐рдВрдЧ рдЬреАрд╡рдирдЪрдХреНрд░ рд╕рдорд╛рд░реЛрд╣
 def logged[T](implicit loggedT: Logged[T]): T => T = (that: T) => { //       Logged  T, //    тАЬтАЭ  that  log(). //    - . loggedT.log(that) //    : that.log() that //    } def runTestCycle[FX, DEP, OUT, F[_]]( fixture: FX, prepare: FX => DEP, execute: DEP => OUT, check: OUT => F[Assertion] )(implicit loggedOut: Logged[OUT]): F[Assertion] = //  logged     -  execute (prepare andThen execute andThen logged andThen check) (fixture) 

рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд░рд▓ рдЖрдВрджреЛрд▓рди рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рд╛ рдореЗрдВ рд▓реМрдЯреЗ рдкрд░рд┐рдгрд╛рдо рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓реЙрдЧрд┐рдВрдЧ рдХреЛ рдЬреЛрдбрд╝рд╛ред рдЗрди рдЫреЛрдЯреЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд░рдЪрдирд╛ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдФрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рдЕрдм рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИред



рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:


 val fixture: SomeMagicalFixture = ??? //  -    def runProductionCode(id: Int): Database => Double = (db: Database) => new SomeProductionLogic(db).calculatePrice(id) def checkResult(expected: Double): Double => Future[Assertion] = (result: Double) => result shouldBe expected //    Database   testInDb "   = 'customer'" in testInDb( state = fixture, execute = runProductionCode(id = 1), check = checkResult(90) ) 

рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╢рд░реАрд░ рдЙрд▓рдЯрд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЬреБрдбрд╝рдирд╛рд░ рдФрд░ рдЬрд╛рдВрдЪ рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╣реАрдВ рдФрд░ рддреИрдпрд╛рд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдмрдиреА рд╣реБрдИ рд╣реИ ...


рд╕реНрдерд┐рд░рддрд╛ рддреИрдпрд╛рд░реА


рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдореЗрдВ, рд╣рдордиреЗ рдЗрд╕ рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдХрд┐ рд╕реНрдерд┐рд░рддрд╛ рдХрд╣реАрдВ-рди-рдХрд╣реАрдВ рд░реЗрдбреА-рдореЗрдб рд╕реЗ рдЖрдПрдЧреА рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдЬреАрд╡рди рдЪрдХреНрд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЪреВрдВрдХрд┐ рдбреЗрдЯрд╛ рд╕рд░рд▓ рдФрд░ рд╕рдорд░реНрдерд┐рдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдШрдЯрдХ рд╣реИ, рд╣рдо рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рд╕реНрдкрд░реНрд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рд╕реНрдЯреЛрд░ рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдордзреНрдпрдо рдЖрдХрд╛рд░ рдХрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ (рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, 4 рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрджрд╛рд╣рд░рдг, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реИрдХрдбрд╝реЛрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ)ред рднрд╛рдЧ рдореЗрдВ рдкреГрд╖реНрдарднреВрдорд┐ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИ, рднрд╛рдЧ - рд╕реАрдзреЗ рд╡реНрдпрд╛рдкрд╛рд░, рдФрд░ рд╕рднреА рдПрдХ рд╕рд╛рде рдЗрд╕реЗ рдХрдИ рдкреВрд░реНрдг-рддрд╛рд░реНрдХрд┐рдХ рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрд╕реНрдерд╛рдУрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддрд╛рд▓рд┐рдХрд╛рдПрдБ рдХреБрдВрдЬреА ( рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬреА ) рджреНрд╡рд╛рд░рд╛ рдкрд░рд╕реНрдкрд░ рдЬреБрдбрд╝реА рд╣реЛрддреА рд╣реИрдВ - рдПрдХ Bonus рдЗрдХрд╛рдИ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ Package рдЗрдХрд╛рдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдпрд╣ рдмрджрд▓реЗ рдореЗрдВ, User ред рдФрд░ рдЗрд╕реА рддрд░рд╣ред



рд╕рд░реНрдХрд┐рдЯ рд╕реАрдорд╛рдУрдВ рдФрд░ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реИрдХреНрд╕ рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдЕрд╕рдВрдЧрддрд┐ рд╣реЛрддреА рд╣реИ рдФрд░, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЕрд╕реНрдерд┐рд░рддрд╛ рдФрд░ рд░реЛрдорд╛рдВрдЪрдХ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдШрдВрдЯреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ, рд╣рдо рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рднрд░ рджреЗрдВрдЧреЗред


рд╣рдо рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реИрдиреНрдп рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреА рдПрдХ рд╕рддрд╣реА рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рднреА, рдХрдИ рдХрдард┐рди рд╕рд╡рд╛рд▓ рдЙрдарддреЗ рд╣реИрдВред рдЗрди рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдЦреБрдж рддреИрдпрд╛рд░ рдХрд░реЗрдЧрд╛ рдХреНрдпрд╛? рдХреНрдпрд╛ рдЕрдиреБрдмрдВрдз рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╣реЛрдиреЗ рдкрд░ рдореБрдЭреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛? рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдбреЗрдЯрд╛ рдПрдХ рдЧреИрд░-рдкрд░реАрдХреНрд╖рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдФрд░ рджреНрд╡рд╛рд░рд╛ рдЖрдпрд╛рдд) рджреНрд╡рд╛рд░рд╛ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдХрдИ рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдЗрдХрд╛рдИ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдиреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рд╢реНрди рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ?


рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЖрдзрд╛рд░ рднрд░рдирд╛
 insertUser(db, id = 1, name = "test", role = "customer") insertPackage(db, id = 1, name = "test", userId = 1, status = "new") insertPackageItems(db, id = 1, packageId = 1, name = "test", price = 30) insertPackageItems(db, id = 2, packageId = 1, name = "test", price = 20) insertPackageItems(db, id = 3, packageId = 1, name = "test", price = 40) 

рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрд┐рдЦрд░реЗ рд╣реБрдП рд╕рд╣рд╛рдпрдХ рддрд░реАрдХреЗ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдЕрд▓рдЧ рд╕реЙрд╕ рдХреЗ рд╕рд╛рдеред рд╡реЗ рдЖрд╢реНрд░рд┐рдд рд╡рд╕реНрддреБрдУрдВ рдФрд░ рдЙрдирдХреЗ рд░рд┐рд╢реНрддреЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕реМрдВрдкрддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдЗрд╕рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред


рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдореИрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдбреЗрдЯрд╛ рд░рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдПрдХ рдирдЬрд╝рд░ рдЬрд┐рд╕ рдкрд░ рд╕рд╛рдорд╛рдиреНрдп рд╢рдмреНрджреЛрдВ рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рд╕рд┐рд╕реНрдЯрдо рдХрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реЛрдЧрд╛ред рд░рд╛рдЬреНрдп рдХреЗ рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреЗ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ (PHP рдФрд░ рдкрд╛рдпрдерди рдореЗрдВ рд▓рд╛ рдбреЗрдЯрд╛рд╕реЗрдЯ ) рд╣реИ, рдЬрд╣рд╛рдВ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рд╡реНрдпрд╡рд╕рд╛рдп рддрд░реНрдХ рдПрдХ рд╕реБрд╡рд┐рдзрд╛ рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ рдбреЗрдЯрд╛рд╕реЗрдЯ рдореЗрдВ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╕рдорд░реНрдерди рдХрдо рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:


 val dataTable: Seq[DataRow] = Table( ("Package ID", "Customer's role", "Item prices", "Bonus value", "Expected final price") , (1, "customer", Vector(40, 20, 30) , Vector.empty , 90.0) , (2, "customer", Vector(250) , Vector.empty , 225.0) , (3, "customer", Vector(100, 120, 30) , Vector(40) , 210.0) , (4, "customer", Vector(100, 120, 30, 100) , Vector(20, 20) , 279.0) , (5, "vip" , Vector(100, 120, 30, 100, 50), Vector(10, 20, 10), 252.0) ) 


рд╣рдорд╛рд░реА рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ, рд╣рдо рдЖрдИрдбреА рджреНрд╡рд╛рд░рд╛ рдХреБрдВрдЬреА - рдЗрдХрд╛рдИ рд╕рдВрдмрдВрдз рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрджрд┐ рдЗрдХрд╛рдИ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рддреЛ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреБрдВрдЬреА рдмрдирд╛рдИ рдЬрд╛рдПрдЧреАред рдРрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрд╕реНрдерд╛рдПрдВ рд╕рдорд╛рди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддреА рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА ( рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА ) рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдбреЗрдЯрд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рдж рд╕рд╕реНрддрд╛ рд╣реИ - рдЪреВрдВрдХрд┐ рдХреБрдВрдЬрд┐рдпреЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реЛрддреЗ рд╣реИрдВ, рд╣рдо рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдбрд┐рдбреБрдкреНрд▓реАрдХреЗрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Set ред рдпрджрд┐ рдпрд╣ рдЕрдкрд░реНрдпрд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╣рдореЗрд╢рд╛ рдЬреАрд╡рди рдЪрдХреНрд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рд╣реЛрд╢рд┐рдпрд╛рд░ рд╕рдорд░реНрдкрдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдореБрдЦреНрдп рдЙрджрд╛рд╣рд░рдг
 sealed trait Key case class PackageKey(id: Int, userId: Int) extends Key case class PackageItemKey(id: Int, packageId: Int) extends Key case class UserKey(id: Int) extends Key case class BonusKey(id: Int, packageId: Int) extends Key 

рд╣рдо рдирдХрд▓реА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреАрдврд╝реА рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдбреНрд╕ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд╛рдо) рдореЗрдВ рд╕реМрдВрдкрддреЗ рд╣реИрдВред рдлрд┐рд░, рдЗрд╕ рд╡рд░реНрдЧ рдХреА рд╕рд╣рд╛рдпрддрд╛ рдФрд░ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рдирд┐рдпрдореЛрдВ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗрддреЗ рд╣реБрдП, рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рд╕реАрдзреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред


рд▓рд╛рдЗрди рдЙрджрд╛рд╣рд░рдг
 object SampleData { def name: String = "test name" def role: String = "customer" def price: Int = 1000 def bonusAmount: Int = 0 def status: String = "new" } sealed trait Row case class PackageRow(id: Int, name: String, userId: Int, status: String) extends Row case class PackageItemRow(id: Int, packageId: Int, name: String, price: Int) extends Row case class UserRow(id: Int, name: String, role: String) extends Row case class BonusRow(id: Int, packageId: Int, bonusAmount: Int) extends Row 

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдирдХрд▓реА рдбреЗрдЯрд╛, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╣рдо рд▓реЗрдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдмрдирд╛рдИ рдЧрдИ рд╕рднреА рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреЗрд╡рд▓ рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдЕрдВрдд рдореЗрдВ рд▓реЗрдВрд╕ рд╕рд╛рдзрд╛рд░рдг рдХрд╛рд░реНрдп рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдХрдВрдкреЛрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЙрдирдХреА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╣реИред


рдЙрджрд╛рд╣рд░рдг рджреЗрддреЗ рд╣реИрдВ
 def changeUserRole(userId: Int, newRole: String): Set[Row] => Set[Row] = (rows: Set[Row]) => rows.modifyAll(_.each.when[UserRow]) .using(r => if (r.id == userId) r.modify(_.role).setTo(newRole) else r) 

рд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рднреАрддрд░ рд╣рдо рд╡рд┐рднрд┐рдиреНрди рдЕрдиреБрдХреВрд▓рди рдФрд░ рд╕реБрдзрд╛рд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рд╕рдореВрд╣ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд╕рд╛рде рдбрд╛рд▓рд╛ рдЬрд╛ рд╕рдХреЗ, рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рдордп рдХреЛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдпрд╛ рдкрдХрдбрд╝рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред


рд╕реНрдерд┐рд░рддрд╛ рдЖрдХрд╛рд░ рджреЗрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп
 def makeFixture[STATE, FX, ROW, F[_]]( state: STATE, applyOverrides: F[ROW] => F[ROW] = x => x ): FX = (extractKeys andThen deduplicateKeys andThen enrichWithSampleData andThen applyOverrides andThen logged andThen buildFixture) (state) 

рд╕рднреА рдПрдХ рд╕рд╛рде рд╣рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рддрддрд╛ рджреЗрдВрдЧреЗ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рднрд░рддрд╛ рд╣реИ - рдбреЗрдЯрд╛рдмреЗрд╕ред рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╣реА, рдореВрд▓ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рдЕрддрд┐рд╢реНрдпреЛрдХреНрддрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛рдПрдЧрд╛ - рд╕рднреА рд╡рд┐рд╡рд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЕрдВрджрд░ рдЫрд┐рдкрд╛рдП рдЬрд╛рдПрдВрдЧреЗред



рд╣рдорд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:


 val dataTable: Seq[DataRow] = Table( ("Package ID", "Customer's role", "Item prices", "Bonus value", "Expected final price") , (1, "customer", Vector(40, 20, 30) , Vector.empty , 90.0) , (2, "customer", Vector(250) , Vector.empty , 225.0) , (3, "customer", Vector(100, 120, 30) , Vector(40) , 210.0) , (4, "customer", Vector(100, 120, 30, 100) , Vector(20, 20) , 279.0) , (5, "vip" , Vector(100, 120, 30, 100, 50), Vector(10, 20, 10), 252.0) ) "   -" - { "'customer'" - { "   " - { "< 250    -  " - { "(:  )" in calculatePriceFor(dataTable, 1) "(:  )" in calculatePriceFor(dataTable, 3) } ">= 250   " - { "   -  10%  " in calculatePriceFor(dataTable, 2) "   -  10%     " in calculatePriceFor(dataTable, 4) } } } "'vip' -    20%      ,       " in calculatePriceFor(dataTable, 5) } 

рдПрдХ рд╕рд╣рд╛рдпрдХ рдХреЛрдб:


рдХреЛрдб
 //    def calculatePriceFor(table: Seq[DataRow], idx: Int) = testInDb( state = makeState(table.row(idx)), execute = runProductionCode(table.row(idx)._1), check = checkResult(table.row(idx)._5) ) def makeState(row: DataRow): Logger => DbFixture = { val items: Map[Int, Int] = ((1 to row._3.length) zip row._3).toMap val bonuses: Map[Int, Int] = ((1 to row._4.length) zip row._4).toMap MyFixtures.makeFixture( state = PackageRelationships .minimal(id = row._1, userId = 1) .withItems(items.keys) .withBonuses(bonuses.keys), overrides = changeRole(userId = 1, newRole = row._2) andThen items.map { case (id, newPrice) => changePrice(id, newPrice) }.foldPls andThen bonuses.map { case (id, newBonus) => changeBonus(id, newBonus) }.foldPls ) } def runProductionCode(id: Int): Database => Double = (db: Database) => new SomeProductionLogic(db).calculatePrice(id) def checkResult(expected: Double): Double => Future[Assertion] = (result: Double) => result shouldBe expected 

рдЯреЗрдмрд▓ рдкрд░ рдирдП рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдПрдХ рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рдмрди рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рдмрдЬрд╛рдп рдЕрдзрд┐рдХрддрдо рд╕реАрдорд╛ рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред


рдЕрдиреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдкрд░ рдкреБрди: рдирд┐рд░реНрдзрд╛рд░рдг рддреИрдпрд╛рд░реА рдХреЛрдб


рдЦреИрд░, рд╣рдордиреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЬреБрдбрд╝рдирд╛рд░ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд▓рд┐рдЦреЗ, рдЗрд╕ рдкрд░ рдмрд╣реБрдд рд╕рдордп рдмрд┐рддрд╛рдпрд╛ред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдХреНрдпрд╛ рд╣рдо рд╣рд░ рдмрд╛рд░ рдкрд╣рд┐рдпрд╛ рдФрд░ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд░реНрдмрд╛рдж рд╣реЛрддреЗ рд╣реИрдВ?


рд╣рдо рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбреЛрдореЗрди рдореЙрдбрд▓ рд╕реЗ рдЬреБрдбрд╝рдирд╛рд░ рдХреА рддреИрдпрд╛рд░реА рдХреЛ рд╕рд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдлрдкреА рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ, рдПрдХ рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯреЗрд╕ рдУрдУрдкреА рд╕реЗ рдХрдХреНрд╖рд╛рдПрдВ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрдВрдЯрд░рдлреЗрд╕ рдЬреИрд╕реЗ рдХреБрдЫ, рд╡реЗ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдореВрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдореВрд▓рднреВрдд рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдореВрд╣ рдХреЛ рд╡рд░реНрдЧреАрдп рд╡рд┐рд░рд╛рд╕рдд рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рд╕рд╛рдзрд╛рд░рдг рдЪрд░ рдХреА рддрд░рд╣ рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рдХреЗ рд╕рд╛рде, рд╕рдВрдХрд▓рд┐рдд рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ, рдкреНрд░рдХрд╛рд░ рдХреА рдХрдХреНрд╖рд╛рдУрдВ (рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ) рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рд╣реЛрддрд╛ рд╣реИред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рдХреЛ рдХреЛрдЯрд▓рд┐рди рдФрд░ рд╕реА # рд╕реЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЛрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЛ рдЧрд┐рд░рд╡реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╕реНрддреБ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдкрд╛рд╕ рдХреНрдпрд╛ рдХреНрд╖реЗрддреНрд░ рдФрд░ рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВред рдпрд╣ рдХреЗрд╡рд▓ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╡рд╛рд▓реЗ log рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдкреНрд░рддреНрдпреЗрдХ рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд Logged рдЗрди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ Logged рд╣реЛрдЧрд╛, рдФрд░ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреБрд╕реНрддрдХрд╛рд▓рдп рдпрд╛ рдорд╛рдирдХ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВред рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯреЗрд╕ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рд╣рдо рд▓реЙрдЧ Logged рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬреБрдбрд╝рдирд╛рд░ рдХреЗ рд▓рд┐рдП, рдФрд░ рдЗрд╕реЗ рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдЕрдиреНрдп рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП, Any рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдФрд░ рдХрд┐рд╕реА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдореБрдлреНрдд рдореЗрдВ рдЙрдирдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ toString рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред


рдЯреИрдЧ рдХреА рдЧрдИ рдХрдХреНрд╖рд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ
 trait Logged[A] { def log(a: A)(implicit logger: Logger): A } //   Future implicit def futureLogged[T]: Logged[Future[T]] = new Logged[Future[T]] { override def log(futureT: Future[T])(implicit logger: Logger): Future[T] = { futureT.map { t => // map  Future       ,   //  logger.info(t.toString()) t } } } // ,        implicit def anyNoLogged[T]: Logged[T] = new Logged[T] { override def log(t: T)(implicit logger: Logger): T = { logger.info(t.toString()) t } } 

рд▓реЙрдЧрд┐рдВрдЧ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЬреБрдбрд╝рдирд╛рд░ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреА рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рд╕рдорд╛рдзрд╛рди рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЯрд╛рдЗрдордХреНрд▓рд╕ рдФрд░ рдЙрди рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрдореВрд░реНрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдкреЗрд╢рдХрд╢ рдХрд░реЗрдЧрд╛ред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╣реИ рдХрд┐ рд╡рд╣ рдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рдХреЗ рдЕрдкрдиреЗ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦреЗрдВред


 //    def makeFixture[STATE, FX, ROW, F[_]]( state: STATE, applyOverrides: F[ROW] => F[ROW] = x => x ): FX = (extractKeys andThen deduplicateKeys andThen enrichWithSampleData andThen applyOverrides andThen logged andThen buildFixture) (state) override def extractKeys(implicit toKeys: ToKeys[DbState]): DbState => Set[Key] = (db: DbState) => db.toKeys() override def enrichWithSampleData(implicit enrich: Enrich[Key]): Key => Set[Row] = (key: Key) => key.enrich() override def buildFixture(implicit insert: Insertable[Set[Row]]): Set[Row] => DbFixture = (rows: Set[Row]) => rows.insert() // ,   - (, )   trait ToKeys[A] { def toKeys(a: A): Set[Key] // Something => Set[Key] } // ...    trait Enrich[A] { def enrich(a: A): Set[Row] // Set[Key] => Set[Row] } // ...     trait Insertable[A] { def insert(a: A): DbFixture // Set[Row] => DbFixture } //      (.     ) implicit val toKeys: ToKeys[DbState] = ??? implicit val enrich: Enrich[Key] = ??? implicit val insert: Insertable[Set[Row]] = ??? 

рд╕реНрдерд┐рд░рддрд╛ рдЬрдирд░реЗрдЯрд░ рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рддреЗ рд╕рдордп, рдореИрдВрдиреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рдПрд╕рдУрдПрд▓рдЖрдИрдбреА рдбрд┐рдЬрд╛рдЗрди рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕рдХреА рд╕реНрдерд┐рд░рддрд╛ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рдирд╢реАрд▓рддрд╛ рдХреЗ рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ:


  • рд╕рд┐рдВрдЧрд▓ рд░рд┐рд╕реНрдкрд╛рдВрд╕рд┐рдмрд┐рд▓рд┐рдЯреА рдкреНрд░рд┐рдВрд╕рд┐рдкрд▓ : рдкреНрд░рддреНрдпреЗрдХ рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рдЯрд╛рдЗрдк рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдПрдХ рдкрд╣рд▓реВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
  • рдУрдкрди рдХреНрд▓реЛрдЬреНрдб рд╕рд┐рджреНрдзрд╛рдВрдд : рд╣рдо рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рд▓рдбрд╝рд╛рдХреВ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЯрд┐рдХреНрд╕реЗрд╕ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд░рддреЗ рд╣реИрдВред
  • Liskov рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╕рд┐рджреНрдзрд╛рдВрдд рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╡рд┐рд░рд╛рд╕рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
  • рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЕрд▓рдЧрд╛рд╡ рд╕рд┐рджреНрдзрд╛рдВрдд : рд╣рдо рдПрдХ рдПрдХрд▓ рд╡реИрд╢реНрд╡рд┐рдХ рдХреЗ рдмрдЬрд╛рдп рдХрдИ рд╡рд┐рд╢реЗрд╖ рдЯрд╛рдЗрдордХреНрд▓рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
  • рдирд┐рд░реНрднрд░рддрд╛ рдЙрд▓рдЯрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд : рд╕реНрдерд┐рд░рддрд╛ рдЬрдирд░реЗрдЯрд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореБрдХрд╛рдмрд▓рд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдореВрд░реНрдд timeclasses рдкрд░ред

рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдХрд┐ рд╕рднреА рд╕рд┐рджреНрдзрд╛рдВрдд рдкреВрд░реЗ рд╣реЛ рдЧрдП рд╣реИрдВ, рдпрд╣ рддрд░реНрдХ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рд╕рдорд╛рдзрд╛рди рд╡рд┐рднрд┐рдиреНрди рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рд╕рдорд░реНрдерд┐рдд рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдпреЛрдЧреНрдп рд╣реИред


рдЬреАрд╡рди рдЪрдХреНрд░, рдЬреБрдбрд╝рдирд╛рд░ рдХреА рдкреАрдврд╝реА, рдФрд░ рдЬреБрдбрд╝рдирд╛рд░ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбреЛрдореЗрди рдореЙрдбрд▓ рд╕реЗ рдЕрдореВрд░реНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдВрдд рдореЗрдВ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред


рдкрд░рд┐рдгрд╛рдо


рд╣рдо рдкрд░реАрдХреНрд╖рдг рдбрд┐рдЬрд╛рдЗрди рдХреА рдкрд╛рд░рдВрдкрд░рд┐рдХ (рдЪрд░рдг-рджрд░-рдЪрд░рдг) рд╢реИрд▓реА рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдПрдХ рдореЗрдВ рдЪрд▓реЗ рдЧрдПред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЪрд░рдг рдФрд░ рдЫреЛрдЯреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдПрдХ рдХрджрдо-рджрд░-рдЪрд░рдг рд╢реИрд▓реА рдЕрдЪреНрдЫреА рд╣реЛрддреА рд╣реИ, рдЗрд╕рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╢реНрд░рдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдФрд░ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реАрдорд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЦреЛрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИред рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рдХреЛ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕рднреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЙрди рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдФрд░ рд╕рдорд░реНрдерди рдХреА рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реИрдХрдбрд╝реЛрдВ рдпрд╛ рд╣рдЬрд╛рд░реЛрдВ рдореЗрдВ рд╣реИред рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рдкрд░реАрдХреНрд╖рдг рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реИрдВ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг (рдбреЗрдЯрд╛, рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдФрд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо) рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдордзреНрдпрд╡рд░реНрддреА рдЪрд░рдгреЛрдВ рдкрд░ рдирд╣реАрдВред


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдордиреЗ рдПрдХ рдЬреАрд╡рд┐рдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рдЧреМрд░ рдХрд┐рдпрд╛ рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рд░рдЪрдирд╛ рдФрд░ рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдВ рдХрд┐рддрдиреА рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИрдВред рдЙрдирдХреА рдорджрдж рд╕реЗ, рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдПрдХ рдЕрднрд┐рдиреНрди рд╣рд┐рд╕реНрд╕рд╛ рд╡рд┐рд▓реБрдкреНрддрд┐ рдФрд░ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рд╣реИред


, , , . , , , -. , . !




: Github

Source: https://habr.com/ru/post/hi463623/


All Articles