рд╢реБрд░реБрдЖрддреА рдХреЗ рд▓рд┐рдП Xcode 4.5 рдореЗрдВ OCUnit

рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВ рдердХ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдлрд┐рдХреНрд╕рд┐рдВрдЧ рдмрдЧ рдореБрдЭреЗ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрд╛, рдФрд░ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдореЗрдВ рдореИрдВ рдЯреАрдбреАрдбреА - рдЯреЗрд╕реНрдЯ-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд┐рдХрд╛рд╕ рдЖрдпрд╛ред

рдпрд╣ рд▓реЗрдЦ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ iOS рдХреЗ рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Xcode 4.5 рдореЗрдВ рдкрд╣рд▓рд╛ рдХрджрдо рдХреИрд╕реЗ рдЙрдард╛рдпрд╛ рдЬрд╛рдПред

рдпрд╣ рд▓реЗрдЦ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рд╣реИ, рдЗрд╕рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдмрд╛рдпрд╕рди рдХреА рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред


рдкрд░рд┐рдЪрдп


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

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

"OcuTests.m" рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓реЗрдВ рдФрд░ "testExample" рд╡рд┐рдзрд┐ рдвреВрдВрдвреЗрдВред
OcuTests.m
#import "OcuTests.h" @implementation OcuTests - (void)setUp { [super setUp]; // Set-up code here. } - (void)tearDown { // Tear-down code here. [super tearDown]; } - (void)testExample { STFail(@"Unit tests are not implemented yet in OcuTests"); } @end 

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

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

рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдПрдБ ("cmd + U" рджрдмрд╛рдХрд░ рдпрд╛ "рд░рди" рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдФрд░ рдЗрд╕реЗ рджрдмрд╛рдХрд░, рдбреНрд░реЙрдк-рдбрд╛рдЙрди рд╕реВрдЪреА рд╕реЗ "рдкрд░реАрдХреНрд╖рдг" рдЪреБрдиреЗрдВ) рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдбрд┐рдмрдЧрд░ рд╣рдореЗрдВ рдХреНрдпрд╛ рд▓рд┐рдЦрддрд╛ рд╣реИред
 Test Suite 'OcuTests' started at 2012-11-22 22:27:01 +0000. Test Case '-[OcuTests testExample]' started. /Ocu/OcuTests/OcuTests.m:29: error: -[OcuTests testExample] : Unit tests are not implemented yet in OcuTests Test Case '-[OcuTests testExample]' failed (0.000 seconds). Test Suite 'OcuTests' finished at 2012-11-22 22:27:01 +0000. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds 

рдбреАрдмрдЧрд░ рдиреЗ рд▓рд┐рдЦрд╛ рдХрд┐ 1 рдкрд░реАрдХреНрд╖рдг рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛, рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдпрд╛, рдФрд░ рд╣рдореЗрдВ рд╡рд╣ рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЬреЛ рд╣рдордиреЗ рд╕реНрдереВрд▓ рдореЗрдВ рд░рдЦрд╛ рдерд╛ред

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

рдЙрджрд╛рд╣рд░рдг 1 - рд╕рддреНрдпрд╛рдкрди рдЬреЛрдбрд╝реЗрдВ


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ 2 рдЪрд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреЗ рдЬреЛрдбрд╝ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред

рд╣рдо 2 рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рдФрд░ рдЬрд┐рд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ рд╣рдорд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛ред
OcuTests.h
 #import <SenTestingKit/SenTestingKit.h> @interface OcuTests : SenTestCase { float foo; float bar; } - (void) testMathAdd; @end 


рд╕реЗрдЯрдЕрдк рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╡реИрд▓реНрдпреВ рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЯреЗрд╕реНрдЯрдореИрдердбрд╛рдЙрди рд╡рд┐рдзрд┐ рдореЗрдВ рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВред
OcuTests.m
 - (void)setUp { [super setUp]; foo = 2.0; bar = 5.0; } - (void)tearDown { // Tear-down code here. [super tearDown]; } - (void) testMathAdd { STAssertTrue (foo + bar == 6.0, @"%f + %f should be 7.0", foo, bar); } 


рдкрд░реАрдХреНрд╖рдг "cmd + U" рдЪрд▓рд╛рдПрдВ рдФрд░ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд╕рд╛рде рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджреЗрдЦреЗрдВред
 Test Suite 'OcuTests' started at 2012-11-23 12:26:14 +0000 Test Case '-[OcuTests testMathAdd]' started. /Ocu/OcuTests/OcuTests.m:30: error: -[OcuTests testMathAdd] : "foo + bar == 6.0" should be true. 2.000000 + 5.000000 should be 7.0 Test Case '-[OcuTests testMathAdd]' failed (0.000 seconds). Test Suite 'OcuTests' finished at 2012-11-23 12:20:42 +0000. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds 


рдЯрд┐рдкреНрдкрдгреА рдХрд╣рддреА рд╣реИ рдХрд┐ рдЬреЛрдбрд╝ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдЙрдореНрдореАрдж рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рд╣рдо рддреНрд░реБрдЯрд┐ рдХреЛ рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗред
OcuTests.m
 - (void) testMathAdd { STAssertTrue (foo + bar == 7.0, @"%f + %f should be 7.0", foo, bar); } 


рд╣рдо рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рдПрдХ рд╕рдВрджреЗрд╢ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдкрд╛рд╕ рд╣реЛ рдЧрдпрд╛ рд╣реИред
 Test Suite 'OcuTests' started at 2012-11-23 12:26:14 +0000 Test Case '-[OcuTests testMathAdd]' started. Test Case '-[OcuTests testMathAdd]' passed (0.000 seconds). Test Suite 'OcuTests' finished at 2012-11-23 12:26:14 +0000. Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.000) seconds 


рдЙрджрд╛рд╣рд░рдг 2 - рдПрдХ рд╡рд╕реНрддреБ рд╕рдВрдкрддреНрддрд┐ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛


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

рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ - "рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдХреНрд▓рд╛рд╕" рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЪреБрдиреЗрдВ рдФрд░ "NSObject рдХрд╛ рдЙрдкрд╡рд░реНрдЧ" рдЪреБрдиреЗрдВ, рдирд╛рдо "рддреНрд░рд┐рднреБрдЬ" рджрд░реНрдЬ рдХрд░реЗрдВ, рдФрд░ рд╕рд╣реЗрдЬрддреЗ рд╕рдордп, рдмреЙрдХреНрд╕ "рд▓рдХреНрд╖реНрдп OcuTests" рдЬрд╛рдВрдЪреЗрдВред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, OcuTests рд╕рдореВрд╣ рдореЗрдВ рд╣рдореЗрдВ 2 рдирдИ рдлрд╛рдЗрд▓реЗрдВ "Triangle.h" рдФрд░ "Triangle.m" рдорд┐рд▓рддреА рд╣реИрдВред
рд╣рдо рдЙрдирдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рддрд░реАрдХреЗ рдмрдирд╛рддреЗ рд╣реИрдВред

Triangle.h
 #import <Foundation/Foundation.h> @interface Triangle : NSObject { float cathetus1; float cathetus2; } - (id)initWithCathetus1:(float)cat1 andCathetus2:(float)cat2; - (float)getHypotenuse; @end 


Triangle.m
 #import "Triangle.h" @implementation Triangle - (id)initWithCathetus1:(float)cat1 andCathetus2:(float)cat2 { cathetus1 = cat1; cathetus2 = cat2; return self; } - (float)getHypotenuse { float hypotenuse = hypotf(cathetus1, cathetus2); return hypotenuse; } @end 


рдФрд░ рддрджрдиреБрд╕рд╛рд░, рд╣рдо рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рддреЗ рд╣реИрдВред
OcuTests.h
 #import <SenTestingKit/SenTestingKit.h> @interface OcuTests : SenTestCase - (void)testTriangleHypotenuse; @end 


OcuTests.m
 #import "OcuTests.h" #import "Triangle.h" //   ,    @implementation OcuTests - (void)setUp { [super setUp]; } - (void)tearDown { [super tearDown]; } - (void)testTriangleHypotenuse { float cat1 = 3.0; float cat2 = 4.0; Triangle *tri = [[Triangle alloc] initWithCathetus1:cat1 andCathetus2:cat2]; STAssertTrue([tri getHypotenuse]==5.0, @"Hypotenuse should be 5.0 with catheti: %f, %f", cat1, cat2); [tri release]; } 


рд╣рдо рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддреЗ рд╣реИрдВ рдФрд░ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
 Test Suite 'OcuTests' started at 2012-11-23 14:25:39 +0000 Test Case '-[OcuTests testTriangleHypotenuse]' started. Test Case '-[OcuTests testTriangleHypotenuse]' passed (0.000 seconds). Test Suite 'OcuTests' finished at 2012-11-23 14:25:39 +0000. Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.000) seconds 


рдкреБрдирд╢реНрдЪ:
рдпрджрд┐ рдЖрдк рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рд▓рд┐рдЦреЗрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдЖрдк рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

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


All Articles