Created
February 28, 2024 15:05
-
-
Save kant2002/5c716d6a4aab1dd5de3c7cdb1f3a2913 to your computer and use it in GitHub Desktop.
Тестування на базі властивостей
This file contains hidden or 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
#r "nuget: FsCheck, 3.0.0-rc2" | |
#r "nuget: FSharp.Core.Ukrainian, 0.0.6" | |
open FsCheck | |
open FsCheck.FSharp | |
type ТипПалива = Дизель | Бензін | Електрика | Гибрид | REXГибрид | |
type НапрямокПродаж = Казахстан | Киргизстан | |
type Авто = { | |
Паливо:ТипПалива | |
РікВиробництва :int | |
Об'ємДвигуна: int option | |
МодельнийРік :int | |
ЦінаEXW :int option | |
ЗаводськаЦіна: int | |
} | |
let розрахуватиЦіну (авто: Авто) напрямокПродаж = | |
let yuanДоUsd = 0.1369 | |
let kztДоUsd = 0.002096 | |
let типПалива = авто.Паливо | |
let рікВиробництва = авто.РікВиробництва | |
let цінаExw = | |
авто.ЦінаEXW | |
|> Option.map float | |
|> Option.defaultValue ((авто.ЗаводськаЦіна |> float) * yuanДоUsd + 1500.0) | |
match напрямокПродаж with | |
| Киргизстан -> | |
{| ЦінаEXW = цінаExw; МРП = None; ЦінаЕТТ = None; ЦінаВТО = None; НДВ = None; ЛьготнаЦіна = None; СбориКомпанії = None; ПервинаРеєстрация = None; УтильЗбір = None |} | |
| Казахстан -> | |
let рік = System.DateTime.Now.Year | |
let мрп = kztДоUsd * if рік = 2023 then 3450.0 else 3692.0 | |
let первиннаРеєстрация = | |
мрп * | |
match рік - рікВиробництва with | |
| x when x <= 0 -> 0.25 | |
| x when x > 0 && x < 3 -> 50. | |
| _ -> 500.0 | |
let митнийЗбір = 20_000.0 * kztДоUsd | |
let сбір_компанії = 500.0 | |
let утильЗбір = | |
50. * мрп * | |
match типПалива with | |
| Дизель | Бензін | Гибрид | REXГибрид -> | |
match авто.Об'ємДвигуна with | |
| Some об'ємДвигуна when об'ємДвигуна < 1000 -> 1.5 | |
| Some об'ємДвигуна when об'ємДвигуна >= 1000 && об'ємДвигуна < 2000 -> 3.5 | |
| Some об'ємДвигуна when об'ємДвигуна >= 2000 && об'ємДвигуна < 3000 -> 5. | |
| Some об'ємДвигуна when об'ємДвигуна >= 3000 -> 11.5 | |
| _ -> 0. | |
| _ -> 0. | |
match типПалива with | |
| Дизель | Бензін | Гибрид -> | |
let митнаЦіна = цінаExw + митнийЗбір | |
let митнийПлатіж = митнаЦіна * 0.15 | |
let НДС = митнаЦіна * 0.12 | |
let цінаЕТТ = митнаЦіна + митнийПлатіж + НДС + утильЗбір + сбір_компанії + первиннаРеєстрация | |
{| ЦінаEXW = цінаExw; МРП = Some(мрп); ЦінаЕТТ = Some цінаЕТТ; ЦінаВТО = None; НДВ = None; СбориКомпанії = Some сбір_компанії; ЛьготнаЦіна = None; ПервинаРеєстрация = Some первиннаРеєстрация; УтильЗбір = Some утильЗбір |} | |
| _ -> | |
let льготнаЦіна = цінаExw + сбір_компанії + первиннаРеєстрация + утильЗбір | |
let митнаЦіна = цінаExw + митнийЗбір | |
let НДВ = митнаЦіна * 0.12 | |
let цінаВТО = митнаЦіна + НДВ + утильЗбір + сбір_компанії + первиннаРеєстрация | |
let митнийПлатіж = митнаЦіна * 0.15 | |
let цінаЕТТ = митнаЦіна + митнийПлатіж + НДВ + утильЗбір + сбір_компанії + первиннаРеєстрация | |
{| ЦінаEXW = цінаExw; МРП = Some(мрп); ЦінаЕТТ = Some цінаЕТТ; ЦінаВТО = Some цінаВТО; НДВ = Some НДВ; ЛьготнаЦіна = Some льготнаЦіна; СбориКомпанії = Some сбір_компанії; ПервинаРеєстрация = Some первиннаРеєстрация; УтильЗбір = Some утильЗбір |} | |
// =========================================== Тесты ========================================= | |
let потрібен_НДВ авто = | |
авто.Паливо = Електрика || авто.Паливо = REXГибрид | |
let ``НДВ для Киргизстану не потрібен`` авто напрямокПродаж = | |
(напрямокПродаж = Киргизстан) ==> | |
(lazy ((розрахуватиЦіну авто напрямокПродаж).НДВ = None)) | |
Check.Quick ("НДВ для Киргизстану не потрібен", ``НДВ для Киргизстану не потрібен``) | |
let построительАвто паливо об'ємДвигуна рікВипуску = | |
{ | |
Паливо = паливо | |
РікВиробництва = рікВипуску | |
Об'ємДвигуна = Some(об'ємДвигуна) | |
МодельнийРік = 2022 | |
ЦінаEXW = None | |
ЗаводськаЦіна = 0 | |
} | |
let генераторТипаПалива = ArbMap.defaults |> ArbMap.generate<ТипПалива> | |
let генераторОб'ємаДвигуна = Gen.choose (0, 50) |> Gen.map (fun x -> x * 100) | |
let генераторРокуВиробництва = Gen.choose (0, 10) |> Gen.map (fun x -> System.DateTime.Now.Year - x) | |
let генераторАвто = Gen.map3 построительАвто генераторТипаПалива генераторОб'ємаДвигуна генераторРокуВиробництва | |
type ГенераториАвто = | |
static member Авто() = | |
{new Arbitrary<Авто>() with | |
override _.Generator = генераторАвто | |
override _.Shrinker _ = Seq.empty } | |
let конфигурація = | |
Config.Quick | |
.WithArbitrary([typeof<ГенераториАвто>]) | |
.WithMaxRejected(20_000) | |
let утильЗбірУМРП авто напрямПродаж пропорції = | |
let ціна = розрахуватиЦіну авто напрямПродаж | |
match(ціна.УтильЗбір, ціна.МРП) with | |
| Some(утильЗбір), Some(мрп) when мрп * пропорції - утильЗбір < 1. -> true | |
| _ -> false | |
|@ (sprintf "Утиль збір = %A, МРП = %A" ціна.УтильЗбір ціна.МРП) | |
type ``Правила Казахстана`` = | |
static member ``Утильзбір для електромобілей не збирається`` авто = | |
(авто.Паливо = Електрика) ==> | |
(lazy ((розрахуватиЦіну авто Казахстан).УтильЗбір = Some(0.))) | |
static member ``Утильзбір для авто меньш 1000 мл`` авто = | |
((авто.Паливо <> Електрика) && авто.Об'ємДвигуна |> Option.map(fun x -> x < 1000) = Some(true)) ==> | |
(lazy утильЗбірУМРП авто Казахстан 75.) | |
static member ``Утильзбір для авто від 1000 мл до 2000 мл`` авто = | |
((авто.Паливо <> Електрика) && авто.Об'ємДвигуна |> Option.map(fun x -> x < 2000 && x >= 1000) = Some(true)) ==> | |
(lazy утильЗбірУМРП авто Казахстан 175.) | |
static member ``Утильзбір для авто від 2000 мл до 3000 мл`` авто = | |
((авто.Паливо <> Електрика) && авто.Об'ємДвигуна |> Option.map(fun x -> x < 3000 && x >= 2000) = Some(true)) ==> | |
(lazy утильЗбірУМРП авто Казахстан 250.) | |
static member ``Утильзбір для авто від 3000 мл та вище`` авто = | |
((авто.Паливо <> Електрика) && авто.Об'ємДвигуна |> Option.map(fun x -> x >= 3000) = Some(true)) ==> | |
(lazy утильЗбірУМРП авто Казахстан 575.) | |
static member ``НДВ збирається для електромобілей та REX-гибридів`` авто = | |
(потрібен_НДВ авто) ==> | |
(lazy ((розрахуватиЦіну авто Казахстан).НДВ <> None)) | |
static member ``НДВ не собирается для звичайних гибридів та звичайних авто`` авто = | |
не (потрібен_НДВ авто) ==> | |
(lazy ((розрахуватиЦіну авто Казахстан).НДВ = None)) | |
Check.All<``Правила Казахстана``>(конфигурація) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment