From 7e22efde3f3be8d9f39856eb704d438feae8eb0f Mon Sep 17 00:00:00 2001 From: Serghei Cebotari Date: Fri, 29 Dec 2023 11:24:23 +0300 Subject: Implement Data driven tests --- RhSolutions.ML.Tests/DatasetBase.cs | 22 +++ RhSolutions.ML.Tests/RaupianoTests.cs | 16 -- RhSolutions.ML.Tests/RautitanFittingsTests.cs | 168 ---------------- RhSolutions.ML.Tests/RautitanPipesTests.cs | 32 --- RhSolutions.ML.Tests/RautitanTests.cs | 172 ++++++++++++++++ RhSolutions.ML.Tests/RhSolutionsDataset.cs | 6 + RhSolutions.ML.Tests/RhSolutionsTests.cs | 29 --- RhSolutions.ML.Tests/TestBase.cs | 39 ++++ RhSolutions.ML.Tests/TestData/Rautitan.csv | 273 ++++++++++++++++++++++++++ 9 files changed, 512 insertions(+), 245 deletions(-) create mode 100644 RhSolutions.ML.Tests/DatasetBase.cs delete mode 100644 RhSolutions.ML.Tests/RaupianoTests.cs delete mode 100644 RhSolutions.ML.Tests/RautitanFittingsTests.cs delete mode 100644 RhSolutions.ML.Tests/RautitanPipesTests.cs create mode 100644 RhSolutions.ML.Tests/RautitanTests.cs create mode 100644 RhSolutions.ML.Tests/RhSolutionsDataset.cs delete mode 100644 RhSolutions.ML.Tests/RhSolutionsTests.cs create mode 100644 RhSolutions.ML.Tests/TestBase.cs create mode 100644 RhSolutions.ML.Tests/TestData/Rautitan.csv diff --git a/RhSolutions.ML.Tests/DatasetBase.cs b/RhSolutions.ML.Tests/DatasetBase.cs new file mode 100644 index 0000000..904bab3 --- /dev/null +++ b/RhSolutions.ML.Tests/DatasetBase.cs @@ -0,0 +1,22 @@ +using System.Collections; + +namespace RhSolutions.ML.Tests; +public abstract class DatasetBase : IEnumerable +{ + protected virtual string FileName {get;set;} = string.Empty; + public IEnumerator GetEnumerator() + { + string path = Path.Combine("..", "..", "..", "TestData", $"{FileName}.csv"); + using FileStream stream = new(path, FileMode.Open, FileAccess.Read); + StreamReader reader = new(stream); + string? inputLine = reader.ReadLine(); + while (inputLine != null) + { + var data = inputLine.Split(';'); + yield return new Product { Name = data[0], Type = data[1] }; + inputLine = reader.ReadLine(); + } + reader.Close(); + stream.Close(); + } +} diff --git a/RhSolutions.ML.Tests/RaupianoTests.cs b/RhSolutions.ML.Tests/RaupianoTests.cs deleted file mode 100644 index 57abcfa..0000000 --- a/RhSolutions.ML.Tests/RaupianoTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// namespace RhSolutions.ML.Tests; - -// public class RaupianoTests : RhSolutionsTests -// { -// [TestCase("Труба канализационная")] -// [TestCase("Труба 110")] -// [TestCase("Труба 110 500")] -// public void WastePipeTest(string name) -// => Execute(name, expectedGroup: "Труба RAUPIANO"); - -// [TestCase("Тройник 50/50/45")] -// [TestCase("Тройник 50/50/45°")] -// [TestCase("Тройник 50 50 45")] -// public void WastePipeBranchTest(string name) -// => Execute(name, expectedGroup: "Тройник RAUPIANO"); -// } diff --git a/RhSolutions.ML.Tests/RautitanFittingsTests.cs b/RhSolutions.ML.Tests/RautitanFittingsTests.cs deleted file mode 100644 index a33d2fe..0000000 --- a/RhSolutions.ML.Tests/RautitanFittingsTests.cs +++ /dev/null @@ -1,168 +0,0 @@ -namespace RhSolutions.ML.Tests; -public class RautitanFittingsTests : RhSolutionsTests -{ - [TestCase("Гильза 16")] - [TestCase("Пресс-втулка")] - [TestCase("UPONOR Q&E EVOLUTION КОЛЬЦО БЕЛОЕ 16 '900Ф")] - public void SleevesTest(string name) - => Execute(name, expectedGroup: "Монтажная гильза"); - - [TestCase("Тройник 20")] - [TestCase("Тройник 20-16-16")] - [TestCase("Тройник 20х20х20")] - [TestCase("Тройник 32*32*32")] - [TestCase("Тройник 50-50-32")] - [TestCase("Тройник, 40 - 20 - 40")] - [TestCase("Тройник, 50 - 32 - 50")] - public void TPieceTest(string name) - => Execute(name, expectedGroup: "Тройник RAUTITAN"); - - [TestCase("Муфта соединительная равнопроходная 16 PX")] - [TestCase("Муфта соединительная переходная 25-16")] - [TestCase("Муфта 16")] - [TestCase("Переход 20-16")] - [TestCase("Переходник 20-16")] - [TestCase("Соединение труба-труба 50/50")] - [TestCase("Соединение труба-труба редукционное, 25 х 16")] - public void CouplingTest(string name) - => Execute(name, expectedGroup: "Муфта соединительная"); - - [TestCase("Переходник с наружной резьбой 20-R 3/4 RX+")] - [TestCase("Переходник с наружн. резьбой 20 1/2")] - [TestCase("Переходник 16 1/2 НР")] - [TestCase("ПНР 16")] - [TestCase("Переход НР 16 1/2")] - [TestCase("Муфта НР 16 1/2")] - [TestCase("Соединение прямое с ниппелем")] - [TestCase("Переходник на резьбу 20 1/2")] - [TestCase("переходник наружная резьба 16 1/2")] - public void AdapterExternalTest(string name) - => Execute(name, expectedGroup: "Переходник на наружную резьбу"); - - [TestCase("Переходник с внутренней резьбой 20-Rp 3/4 RX+")] - [TestCase("Переходник с внутр. резьбой 20 1/2")] - [TestCase("Переходник 16 1/2 ВР")] - [TestCase("ПВР 16")] - [TestCase("Переход ВР 16 1/2")] - [TestCase("Муфта ВР 16 1/2")] - [TestCase("Переходник с внутренней резьбой 16xG 3/4\" для труб из сшитого полиэтилена аксиальный")] - public void AdapterInternalTest(string name) - => Execute(name, expectedGroup: "Переходник на внутреннюю резьбу"); - - [TestCase("Переходник с накидной гайкой 16-G 1/2 RX+")] - [TestCase("Переходник с накидн. гайкой 16 1/2")] - [TestCase("Переходник 16 1/2 НГ")] - [TestCase("ПНГ 16")] - [TestCase("Переход НГ 16 1/2")] - [TestCase("Муфта НГ 16 1/2")] - [TestCase("штуцер с накидной гайкой")] - public void AdapterScrewcapTest(string name) - => Execute(name, expectedGroup: "Переходник с накидной гайкой"); - - [TestCase("Угольник 16")] - [TestCase("Угольник 16 90")] - [TestCase("Угольник 50 45")] - [TestCase("угольник 20/90")] - public void ElbowTest(string name) - => Execute(name, expectedGroup: "Угольник RAUTITAN"); - - [TestCase("Угольник-переходник с наружной резьбой 16-R 1/2 RX+")] - [TestCase("Уголок соединительный с ниппелем 20 х 1/2'', бронза")] - public void ThreadElbowExternalTest(string name) - => Execute(name, expectedGroup: "Угольник с наружной резьбой"); - - [TestCase("Угольник-переходник с внутренней резьбой 16-Rp 1/2 RX+")] - [TestCase("Уголок соединительный с муфтой 16 х 1/2\", бронза")] - public void ThreadElbowInternalTest(string name) - => Execute(name, expectedGroup: "Угольник с внутренней резьбой"); - - [TestCase("Угольник настенный с длинным патрубком, внутр. резьба 16-Rp 1/2 RX+")] - [TestCase("Угольник настенный с внутр. резьбой 16-Rp 1/2 RX+")] - [TestCase("Настенный угольник с внутренней резьбой (водорозетка), 16 - G 1/2\"")] - public void ThreadElbowWallInternalTest(string name) - => Execute(name, expectedGroup: "Угольник настенный внутренний"); - - - [TestCase("Проточный настенный угольник 16/16-Rp 1/2 длинный RX+")] - [TestCase("Проточный настенный угольник 16/20-Rp 1/2 короткий RX+")] - [TestCase("Проточный угольник 16")] - public void ThreadElbowDoubleWallInternalTest(string name) - => Execute(name, expectedGroup: "Проточный настенный угольник"); - - [TestCase("Угольник настенный с наружной резьбой 16-R 1/2 RX+")] - public void ThreadElbowWallExternalTest(string name) - => Execute(name, expectedGroup: "Угольник настенный наружный"); - - [TestCase("Угольник-переходник с накидной гайкой 16-G 1/2 RX+")] - [TestCase("Соединение угловое с накидной гайкой 16 х 1/2\", латунь")] - public void ScrewcapElbowTest(string name) - => Execute(name, expectedGroup: "Угольник с накидной гайкой"); - - [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 16-16-R 1/2")] - [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 1/2")] - public void ThreadTPieceExternal(string name) - => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой наружный"); - - [TestCase("Тройник настенный с внутренней резьбой 16-Rp1/2-16 RX+")] - [TestCase("Тройник с внутр. резьбой на боков. проходе 25-Rp 1/2-25 RX+")] - [TestCase("Тройник-переходник с внутренней резьбой 25xR 3/4\" для труб из сшитого полиэтилена аксиальный")] - public void ThreadTPieceInternal(string name) - => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой внутренний"); - - [TestCase("Фиксатор поворота трубы 20/90°, без колец (оцинк. сталь)")] - [TestCase("Фиксатор поворота трубы 32/90°, с кольцами (оцинк. сталь)")] - [TestCase("Дуга 90° 25")] - public void BendFormerHeating(string name) - => Execute(name, expectedGroup: "Фиксатор поворота отопление"); - - [TestCase("Фиксатор поворота с кольцами 90°, 32")] - [TestCase("Фиксатор поворота с кольцами 45°, 16")] - public void BendFormerDrinking(string name) - => Execute(name, expectedGroup: "Фиксатор поворота водоснабжение"); - - [TestCase("Трубка из. нерж. стали для подкл. радиатора, Г-образная 16/250")] - [TestCase("Трубка L-образная - D15 16х15 для подключения радиатора, 250 мм")] - [TestCase("Трубка L-образная")] - [TestCase("Монтажная трубка для радиатора, конечная, 16 х 15 х 1100 мм")] - public void ConnectionBendTest(string name) - => Execute(name, expectedGroup: "Трубка Г-образная"); - - [TestCase("Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/250")] - [TestCase("Монтажная трубка для радиатора, проходная 16 х 15 х 300 мм")] - [TestCase("Трубка T-образная - D15 16х15х16 для подключения радиатора")] - public void ConnectionTeeTest(string name) - => Execute(name, expectedGroup: "Трубка Т-образная"); - - [TestCase("Заглушка, 16, латунь")] - [TestCase("Заглушка 16")] - [TestCase("Заглушка для полимерн. трубы 16 RX+")] - public void DummyPlugTest(string name) - => Execute(name, expectedGroup: "Заглушка труб RAUTITAN"); - - [TestCase("Концовка разб. 3/4'' (еврок) для универс. трубы 16")] - [TestCase("Переходник компрессионный PEX 20х2.8-G 3/4\" Евроконус")] - [TestCase("Резьбозажимное соединение flex/pink 20х2,8xG3/4")] - public void EuroconeFlexTest(string name) - => Execute(name, expectedGroup: "Резьбозажимное flex"); - - [TestCase("Резьбозажимное соединение stabil 16,2x2,6xG3/4")] - [TestCase("Концовка разб.3/4''(еврок.) для PE-Xc и PE-MDXс 16")] - public void EuroconeStabilTest(string name) - => Execute(name, expectedGroup: "Резьбозажимное stabil"); - - [TestCase("Переходник на евроконус 16-G 3/4")] - [TestCase("Соед.прям. с вн.резьбой (н.гайка, еврок.) 16 ник.")] - [TestCase("Переходник с накидной гайкой 16x2.2 -G 3/4\" Евроконус, c гильзой в комплекте")] - public void EuroconeAdapterTest(string name) - => Execute(name, expectedGroup: "Переходник на евроконус"); - - [TestCase("Резьбозажимное соединение для металлической трубки G 3/4 -15")] - [TestCase("Концовка для монтажной трубы 15 х 1/2''")] - [TestCase("Фитинг подключения L и T-образной медной трубки - D15 - G 3/4")] - public void EuroconeConnectionBendTest(string name) - => Execute(name, expectedGroup: "Резьбозажимное для трубки"); - - [TestCase("К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4")] - public void NippelTest(string name) - => Execute(name, expectedGroup: "Ниппель"); -} \ No newline at end of file diff --git a/RhSolutions.ML.Tests/RautitanPipesTests.cs b/RhSolutions.ML.Tests/RautitanPipesTests.cs deleted file mode 100644 index 77a0147..0000000 --- a/RhSolutions.ML.Tests/RautitanPipesTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace RhSolutions.ML.Tests; - -public class RautitanPipesTests : RhSolutionsTests -{ - [TestCase("Труба stabil 16")] - [TestCase("Труба stabil")] - public void StabilPipeTest(string name) - => Execute(name, expectedGroup: "Stabil"); - - [TestCase("Труба flex 16")] - [TestCase("Труба flex")] - public void FlexPipeTest(string name) - => Execute(name, expectedGroup: "Flex"); - - [TestCase("Труба pink 16")] - [TestCase("Труба pink")] - [TestCase("Унив. труба RAUTITAN pink+ 16х2,2 мм, бухта 120 м")] - [TestCase("Унив. труба RAUTITAN pink+ 63х8,7 мм, прямые отрезки 6 м")] - public void PinkPipeTest(string name) - => Execute(name, expectedGroup: "Pink"); - - [TestCase("Труба black 16")] - [TestCase("Труба black")] - [TestCase("Отоп. труба RAUTITAN black 20х2,8 мм, бухта 180 м")] - public void BlackPipeTest(string name) - => Execute(name, expectedGroup: "Black"); - - [TestCase("Фиксирующий желоб 16")] - [TestCase("Желоб 16")] - public void SupportingClipTest(string name) - => Execute(name, expectedGroup: "Желоб"); -} diff --git a/RhSolutions.ML.Tests/RautitanTests.cs b/RhSolutions.ML.Tests/RautitanTests.cs new file mode 100644 index 0000000..1f51d8b --- /dev/null +++ b/RhSolutions.ML.Tests/RautitanTests.cs @@ -0,0 +1,172 @@ +namespace RhSolutions.ML.Tests; +public class RautitanTests : TestBase +{ + [TestCaseSource(typeof(RautitanDataset))] + public void RhSolutionsTests(Product expected) + => Execute(expected); + + [TestCase("Гильза 16")] + [TestCase("Пресс-втулка")] + [TestCase("UPONOR Q&E EVOLUTION КОЛЬЦО БЕЛОЕ 16 '900Ф")] + public void SleevesTest(string name) + => Execute(name, expectedGroup: "Монтажная гильза"); + + [TestCase("Тройник 20")] + [TestCase("Тройник 20-16-16")] + [TestCase("Тройник 20х20х20")] + [TestCase("Тройник 32*32*32")] + [TestCase("Тройник 50-50-32")] + [TestCase("Тройник, 40 - 20 - 40")] + [TestCase("Тройник, 50 - 32 - 50")] + public void TPieceTest(string name) + => Execute(name, expectedGroup: "Тройник RAUTITAN"); + + [TestCase("Муфта соединительная равнопроходная 16 PX")] + [TestCase("Муфта соединительная переходная 25-16")] + [TestCase("Муфта 16")] + [TestCase("Переход 20-16")] + [TestCase("Переходник 20-16")] + [TestCase("Соединение труба-труба 50/50")] + [TestCase("Соединение труба-труба редукционное, 25 х 16")] + public void CouplingTest(string name) + => Execute(name, expectedGroup: "Муфта соединительная"); + + [TestCase("Переходник с наружной резьбой 20-R 3/4 RX+")] + [TestCase("Переходник с наружн. резьбой 20 1/2")] + [TestCase("Переходник 16 1/2 НР")] + [TestCase("ПНР 16")] + [TestCase("Переход НР 16 1/2")] + [TestCase("Муфта НР 16 1/2")] + [TestCase("Соединение прямое с ниппелем")] + [TestCase("Переходник на резьбу 20 1/2")] + [TestCase("переходник наружная резьба 16 1/2")] + public void AdapterExternalTest(string name) + => Execute(name, expectedGroup: "Переходник на наружную резьбу"); + + [TestCase("Переходник с внутренней резьбой 20-Rp 3/4 RX+")] + [TestCase("Переходник с внутр. резьбой 20 1/2")] + [TestCase("Переходник 16 1/2 ВР")] + [TestCase("ПВР 16")] + [TestCase("Переход ВР 16 1/2")] + [TestCase("Муфта ВР 16 1/2")] + [TestCase("Переходник с внутренней резьбой 16xG 3/4\" для труб из сшитого полиэтилена аксиальный")] + public void AdapterInternalTest(string name) + => Execute(name, expectedGroup: "Переходник на внутреннюю резьбу"); + + [TestCase("Переходник с накидной гайкой 16-G 1/2 RX+")] + [TestCase("Переходник с накидн. гайкой 16 1/2")] + [TestCase("Переходник 16 1/2 НГ")] + [TestCase("ПНГ 16")] + [TestCase("Переход НГ 16 1/2")] + [TestCase("Муфта НГ 16 1/2")] + [TestCase("штуцер с накидной гайкой")] + public void AdapterScrewcapTest(string name) + => Execute(name, expectedGroup: "Переходник с накидной гайкой"); + + [TestCase("Угольник 16")] + [TestCase("Угольник 16 90")] + [TestCase("Угольник 50 45")] + [TestCase("угольник 20/90")] + public void ElbowTest(string name) + => Execute(name, expectedGroup: "Угольник RAUTITAN"); + + [TestCase("Угольник-переходник с наружной резьбой 16-R 1/2 RX+")] + [TestCase("Уголок соединительный с ниппелем 20 х 1/2'', бронза")] + public void ThreadElbowExternalTest(string name) + => Execute(name, expectedGroup: "Угольник с наружной резьбой"); + + [TestCase("Угольник-переходник с внутренней резьбой 16-Rp 1/2 RX+")] + [TestCase("Уголок соединительный с муфтой 16 х 1/2\", бронза")] + public void ThreadElbowInternalTest(string name) + => Execute(name, expectedGroup: "Угольник с внутренней резьбой"); + + [TestCase("Угольник настенный с длинным патрубком, внутр. резьба 16-Rp 1/2 RX+")] + [TestCase("Угольник настенный с внутр. резьбой 16-Rp 1/2 RX+")] + [TestCase("Настенный угольник с внутренней резьбой (водорозетка), 16 - G 1/2\"")] + public void ThreadElbowWallInternalTest(string name) + => Execute(name, expectedGroup: "Угольник настенный внутренний"); + + + [TestCase("Проточный настенный угольник 16/16-Rp 1/2 длинный RX+")] + [TestCase("Проточный настенный угольник 16/20-Rp 1/2 короткий RX+")] + [TestCase("Проточный угольник 16")] + public void ThreadElbowDoubleWallInternalTest(string name) + => Execute(name, expectedGroup: "Проточный настенный угольник"); + + [TestCase("Угольник настенный с наружной резьбой 16-R 1/2 RX+")] + public void ThreadElbowWallExternalTest(string name) + => Execute(name, expectedGroup: "Угольник настенный наружный"); + + [TestCase("Угольник-переходник с накидной гайкой 16-G 1/2 RX+")] + [TestCase("Соединение угловое с накидной гайкой 16 х 1/2\", латунь")] + public void ScrewcapElbowTest(string name) + => Execute(name, expectedGroup: "Угольник с накидной гайкой"); + + [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 16-16-R 1/2")] + [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 1/2")] + public void ThreadTPieceExternal(string name) + => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой наружный"); + + [TestCase("Тройник настенный с внутренней резьбой 16-Rp1/2-16 RX+")] + [TestCase("Тройник с внутр. резьбой на боков. проходе 25-Rp 1/2-25 RX+")] + [TestCase("Тройник-переходник с внутренней резьбой 25xR 3/4\" для труб из сшитого полиэтилена аксиальный")] + public void ThreadTPieceInternal(string name) + => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой внутренний"); + + [TestCase("Фиксатор поворота трубы 20/90°, без колец (оцинк. сталь)")] + [TestCase("Фиксатор поворота трубы 32/90°, с кольцами (оцинк. сталь)")] + [TestCase("Дуга 90° 25")] + public void BendFormerHeating(string name) + => Execute(name, expectedGroup: "Фиксатор поворота отопление"); + + [TestCase("Фиксатор поворота с кольцами 90°, 32")] + [TestCase("Фиксатор поворота с кольцами 45°, 16")] + public void BendFormerDrinking(string name) + => Execute(name, expectedGroup: "Фиксатор поворота водоснабжение"); + + [TestCase("Трубка из. нерж. стали для подкл. радиатора, Г-образная 16/250")] + [TestCase("Трубка L-образная - D15 16х15 для подключения радиатора, 250 мм")] + [TestCase("Трубка L-образная")] + [TestCase("Монтажная трубка для радиатора, конечная, 16 х 15 х 1100 мм")] + public void ConnectionBendTest(string name) + => Execute(name, expectedGroup: "Трубка Г-образная"); + + [TestCase("Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/250")] + [TestCase("Монтажная трубка для радиатора, проходная 16 х 15 х 300 мм")] + [TestCase("Трубка T-образная - D15 16х15х16 для подключения радиатора")] + public void ConnectionTeeTest(string name) + => Execute(name, expectedGroup: "Трубка Т-образная"); + + [TestCase("Заглушка, 16, латунь")] + [TestCase("Заглушка 16")] + [TestCase("Заглушка для полимерн. трубы 16 RX+")] + public void DummyPlugTest(string name) + => Execute(name, expectedGroup: "Заглушка труб RAUTITAN"); + + [TestCase("Концовка разб. 3/4'' (еврок) для универс. трубы 16")] + [TestCase("Переходник компрессионный PEX 20х2.8-G 3/4\" Евроконус")] + [TestCase("Резьбозажимное соединение flex/pink 20х2,8xG3/4")] + public void EuroconeFlexTest(string name) + => Execute(name, expectedGroup: "Резьбозажимное flex"); + + [TestCase("Резьбозажимное соединение stabil 16,2x2,6xG3/4")] + [TestCase("Концовка разб.3/4''(еврок.) для PE-Xc и PE-MDXс 16")] + public void EuroconeStabilTest(string name) + => Execute(name, expectedGroup: "Резьбозажимное stabil"); + + [TestCase("Переходник на евроконус 16-G 3/4")] + [TestCase("Соед.прям. с вн.резьбой (н.гайка, еврок.) 16 ник.")] + [TestCase("Переходник с накидной гайкой 16x2.2 -G 3/4\" Евроконус, c гильзой в комплекте")] + public void EuroconeAdapterTest(string name) + => Execute(name, expectedGroup: "Переходник на евроконус"); + + [TestCase("Резьбозажимное соединение для металлической трубки G 3/4 -15")] + [TestCase("Концовка для монтажной трубы 15 х 1/2''")] + [TestCase("Фитинг подключения L и T-образной медной трубки - D15 - G 3/4")] + public void EuroconeConnectionBendTest(string name) + => Execute(name, expectedGroup: "Резьбозажимное для трубки"); + + [TestCase("К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4")] + public void NippelTest(string name) + => Execute(name, expectedGroup: "Ниппель"); +} \ No newline at end of file diff --git a/RhSolutions.ML.Tests/RhSolutionsDataset.cs b/RhSolutions.ML.Tests/RhSolutionsDataset.cs new file mode 100644 index 0000000..0abe55f --- /dev/null +++ b/RhSolutions.ML.Tests/RhSolutionsDataset.cs @@ -0,0 +1,6 @@ +namespace RhSolutions.ML.Tests; + +public class RautitanDataset : DatasetBase +{ + protected override string FileName => "Rautitan"; +} diff --git a/RhSolutions.ML.Tests/RhSolutionsTests.cs b/RhSolutions.ML.Tests/RhSolutionsTests.cs deleted file mode 100644 index 4e91342..0000000 --- a/RhSolutions.ML.Tests/RhSolutionsTests.cs +++ /dev/null @@ -1,29 +0,0 @@ -using RhSolutions.ML.Lib; - -namespace RhSolutions.ML.Tests; - -public abstract class RhSolutionsTests -{ - protected static string _appPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) ?? "."; - protected static string _dataPath = Path.Combine(_appPath, "..", "..", "..", "..", "Models", "model.zip"); - protected MLContext _mlContext; - protected PredictionEngine _predEngine; - - public RhSolutionsTests() - { - RhSolutionsMLBuilder.RebuildModel(); - _mlContext = new MLContext(seed: 0); - ITransformer loadedNodel = _mlContext.Model.Load(_dataPath, out var _); - _predEngine = _mlContext.Model.CreatePredictionEngine(loadedNodel); - } - - public void Execute(string name, string expectedGroup) - { - Product p = new() - { - Name = name - }; - var prediction = _predEngine.Predict(p); - Assert.That(prediction.Type, Is.EqualTo(expectedGroup)); - } -} \ No newline at end of file diff --git a/RhSolutions.ML.Tests/TestBase.cs b/RhSolutions.ML.Tests/TestBase.cs new file mode 100644 index 0000000..679d9d3 --- /dev/null +++ b/RhSolutions.ML.Tests/TestBase.cs @@ -0,0 +1,39 @@ +using RhSolutions.ML.Lib; + +namespace RhSolutions.ML.Tests; + +public abstract class TestBase +{ + protected static string _appPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) ?? "."; + protected static string _dataPath = Path.Combine(_appPath, "..", "..", "..", "..", "Models", "model.zip"); + protected MLContext _mlContext; + protected PredictionEngine _predEngine; + + public TestBase() + { + RhSolutionsMLBuilder.RebuildModel(); + _mlContext = new MLContext(seed: 0); + ITransformer loadedNodel = _mlContext.Model.Load(_dataPath, out var _); + _predEngine = _mlContext.Model.CreatePredictionEngine(loadedNodel); + } + + public void Execute(string name, string expectedGroup) + { + Product p = new() + { + Name = name + }; + var prediction = _predEngine.Predict(p); + Assert.That(prediction.Type, Is.EqualTo(expectedGroup)); + } + + public void Execute(Product expected) + { + Product actual = new() + { + Name = expected.Name + }; + var prediction = _predEngine.Predict(actual); + Assert.That(prediction.Type, Is.EqualTo(expected.Type)); + } +} \ No newline at end of file diff --git a/RhSolutions.ML.Tests/TestData/Rautitan.csv b/RhSolutions.ML.Tests/TestData/Rautitan.csv new file mode 100644 index 0000000..7e78a6a --- /dev/null +++ b/RhSolutions.ML.Tests/TestData/Rautitan.csv @@ -0,0 +1,273 @@ +Универсальн.труба RAUTITAN stabil PLATINUM 16,2х2,6 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 20х2,9 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 25х3,7 мм, бухта 50 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 32х4,7 мм, прям. отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, бухта 300 м;Stabil +Универсальн.труба RAUTITAN stabil 20х2,9 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil 25х3,7 мм, бухта 50 м;Stabil +Универсальн.труба RAUTITAN stabil 32х4,7 мм, бухта 25 м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 20х2,9 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 25х3,7 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 32х4,7 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 40х6,0 мм, прям.отрезки 5м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, прямоуг. изол. 9 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, прямоуг. изол. 9 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, прямоуг., изол.26 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, прямоуг., изол. 26 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, кругл., изол. 4 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, кругл., изол. 4 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 4 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, кругл., изол. 9 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, кругл., изол. 9 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 9 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 16x2,6, кругл., изол. 13 мм, бухта 25 м.;Stabil +Унив.труба RAUTITAN stabil 20x2,9, кругл., изол. 13 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 13 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stаbil 16,2х2,6мм в гофротрубе, бухта 50м;Stabil +Унив.труба RAUTITAN stabil 20х2,9мм в гофротрубе, бухта 50 м;Stabil +Унив.труба РЕХАУ FLEX 16x2,2, бухта 100м;Flex +Унив.труба РЕХАУ FLEX 20x2,8, бухта 100м;Flex +Унив.труба РЕХАУ FLEX 25x3,5, бухта 50м;Flex +Унив.труба РЕХАУ FLEX 32x4,4, бухта 50м;Flex +Унив.труба РЕХАУ FLEX 40x5,5, прям.отрезки 6м;Flex +Унив.труба РЕХАУ FLEX 50x6,9, прям.отрезки 6м;Flex +Унив.труба РЕХАУ FLEX 63x8,6, прям.отрезки 6м;Flex +Отоп. труба РЕХАУ PINK 16х2,2 мм, бухта 120 м;Pink +Отоп. труба РЕХАУ PINK 20х2,8 мм, бухта 120 м;Pink +Отоп. труба РЕХАУ PINK 25х3,5 мм, бухта 50 м;Pink +Отоп. труба РЕХАУ PINK 32х4,4 мм, бухта 50 м;Pink +Отоп.труба РЕХАУ BLACK 16х2,2 мм, бухта 200 м;Black +Отоп.труба РЕХАУ BLACK 20х2,8 мм, бухта 180 м;Black +Отоп.труба РЕХАУ BLACK 25х3,5 мм, бухта 100 м;Black +Фиксирующий желоб для ПЭ-трубы 16/17;Желоб +Фиксирующий желоб для ПЭ-трубы 20;Желоб +Фиксирующий желоб для ПЭ-трубы 25;Желоб +Фиксирующий желоб для ПЭ-трубы 32;Желоб +Фиксирующий желоб для ПЭ-трубы 40;Желоб +Фиксирующий желоб для ПЭ-трубы 50;Желоб +Фиксирующий желоб для ПЭ-трубы 63;Желоб +Монтажная гильза 16 PX;Монтажная гильза +Монтажная гильза 20 PX;Монтажная гильза +Монтажная гильза 25 PX;Монтажная гильза +Монтажная гильза 32 PX;Монтажная гильза +Монтажная гильза 40 PX;Монтажная гильза +Монтажная гильза 50 MX;Монтажная гильза +Монтажная гильза 63 MX;Монтажная гильза +Тройник равнопроходный 16-16-16 PX;Тройник RAUTITAN +Тройник равнопроходный 20-20-20 PX;Тройник RAUTITAN +Тройник равнопроходный 25-25-25 PX;Тройник RAUTITAN +Тройник равнопроходный 32-32-32 PX;Тройник RAUTITAN +Тройник равнопроходный 40-40-40 PX;Тройник RAUTITAN +Тройник равнопроходный 50-50-50 RX+;Тройник RAUTITAN +Тройник равнопроходный 63-63-63 RX+;Тройник RAUTITAN +Тройник равнопроходный 16-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник равнопроходный 20-20-20 PLATINUM RX;Тройник RAUTITAN +Тройник равнопроходный 25-25-25 PLATINUM RX+;Тройник RAUTITAN +Тройник равнопроходный 32-32-32 PLATINUM RX+;Тройник RAUTITAN +Проточный настенный угольник 16/16-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 20/20-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 25/25-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 16/16-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 20/20-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 16/20-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 20/16-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 25/25-Rp 1/2 короткий RX+;Проточный настенный угольник +Тройник RAUTITAN RX+ с наружной резьбой 16-16-R 1/2;Тройник RAUTITAN резьбовой наружный +Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 1/2;Тройник RAUTITAN резьбовой наружный +Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 3/4;Тройник RAUTITAN резьбовой наружный +Тройник с уменьшенным боковым проходом 20-16-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-16-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-20-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-16-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-20-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-25-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-20-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-25-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-32-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-20-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-25-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-32-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-40-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-25-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-32-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-40-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-50-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 20-16-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-16-25 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-20-25 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-20-32 PLATINUM RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-25-32 PLATINUM RX+;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 20-20-16 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-16 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-20 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 32-32-20 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 32-32-25 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 20-20-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 20-16-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-20-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-20-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 40-32-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 50-32-40 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 20-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-25 PLATINUM RX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-20-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-25-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 20-25-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 20-25-20 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 25-32-25 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-20-16 PLATINUM RX;Тройник RAUTITAN +Тройник настенный с внутренней резьбой 16-Rp1/2-16 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник настенный с внутренней резьбой 20-Rp1/2-16 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник настенный с внутренней резьбой 20-Rp1/2-20 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 25-Rp 1/2-25 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 25-Rp 3/4-25 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 3/4-25 RX+ ;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 3/4-32 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 1-32 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 40-Rp 1-40 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 50-Rp 1-50 RX+;Тройник RAUTITAN резьбовой внутренний +Муфта соединительная равнопроходная 16 PX;Муфта соединительная +Муфта соединительная равнопроходная 20 PX;Муфта соединительная +Муфта соединительная равнопроходная 25 PX;Муфта соединительная +Муфта соединительная равнопроходная 32 PX;Муфта соединительная +Муфта соединительная равнопроходная 40 PX;Муфта соединительная +Муфта соединительная равнопроходная 50 RХ+;Муфта соединительная +Муфта соединительная равнопроходная 63 RХ +;Муфта соединительная +Муфта соединительная равнопроходная 16 PLATINUM RX;Муфта соединительная +Муфта соединительная равнопроходная 25 PLATINUM RX;Муфта соединительная +Муфта соединительная равнопроходная 32 PLATINUM RX+;Муфта соединительная +Муфта соединительная переходная 20-16 PX;Муфта соединительная +Муфта соединительная переходная 25-16 PX;Муфта соединительная +Муфта соединительная переходная 25-20 PX;Муфта соединительная +Муфта соединительная переходная 32-25 PX;Муфта соединительная +Муфта соединительная переходная 40-32 PX;Муфта соединительная +Муфта соединительная переходная 40-25 RX+;Муфта соединительная +Муфта соединительная переходная 50-32 RX+;Муфта соединительная +Муфта соединительная переходная 50-40 RX+;Муфта соединительная +Муфта соединительная переходная 63-50 RX+;Муфта соединительная +Муфта соединительная переходная 20-16 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 25-16 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 25-20 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 32-25 PLATINUM RX;Муфта соединительная +Переходник с наружной резьбой 16-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 16-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 16-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 40-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 50-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 50-R 1 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 63-R 2 RX+;Переходник на наружную резьбу +Переходник с внутренней резьбой 16-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 20-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 20-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 1 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 32-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 32-Rр 1 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 40-Rр 1 1/4 RX+;Переходник на внутреннюю резьбу +Переходник с накидной гайкой 16-G 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 16-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 20-G 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 20-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 25-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 25-G 1 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 1/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 40-G 1 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 50-G 1 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 63-G 2 3/8 RX+;Переходник с накидной гайкой +Переходник на евроконус 20-G 3/4 ;Переходник на евроконус +Угольник-переходник с накидной гайкой 16-G 1/2 RX+;Угольник с накидной гайкой +Угольник-переходник с накидной гайкой 20-G 1/2 RX+;Угольник с накидной гайкой +Угольник 90°, 50 RX+;Угольник RAUTITAN +Угольник 90°, 63 RX+;Угольник RAUTITAN +Угольник 90°, 16 PX;Угольник RAUTITAN +Угольник 90°, 20 PX;Угольник RAUTITAN +Угольник 90°, 25 PX;Угольник RAUTITAN +Угольник 90°, 32 PX;Угольник RAUTITAN +Угольник 90°, 40 PX;Угольник RAUTITAN +Угольник 90° 16 PLATINUM RX;Угольник RAUTITAN +Угольник 90° 20 PLATINUM RX;Угольник RAUTITAN +Угольник 90° 32 PLATINUM RX+;Угольник RAUTITAN +Угольник 45°, 50 RX+;Угольник RAUTITAN +Угольник 45°, 63 RX+;Угольник RAUTITAN +Угольник 45°, 20 PX;Угольник RAUTITAN +Угольник 45°, 25 PX;Угольник RAUTITAN +Угольник 45°, 32 PX;Угольник RAUTITAN +Угольник 45°, 40 PX;Угольник RAUTITAN +Фиксатор поворота с кольцами 90°, 16;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 20;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 25;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 32;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 16;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 20;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 25;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 32;Фиксатор поворота водоснабжение +Угольник-переходник с наружной резьбой 16-R 1/2 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 20-R 1/2 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 20-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 25-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 32-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 32-R 1 RX+;Угольник с наружной резьбой +Угольник-переходник с внутренней резьбой 16-Rp 1/2 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 16-Rp 3/4 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 20-Rp 1/2 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 20-Rp 3/4 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 25-Rp 1 RX+;Угольник с внутренней резьбой +Угольник настенный с внутр. резьбой 16-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 3/4 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 25-Rp 3/4 RX+;Угольник настенный внутренний +Угольник настенный с длинным патрубком, внутр. резьба 16-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с длинным патрубком, внутр. резьба 20-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с наружной резьбой 16-R 1/2 RX+;Угольник настенный наружный +Угольник настенный с наружной резьбой 20-R 1/2 RX+;Угольник настенный наружный +Угольник настенный с наружной резьбой 20-R 3/4 RX+;Угольник настенный наружный +Угольник настенный с внутр. резьбой 16-Rp 1/2 длинный, 59 мм RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 1/2 длинный, 59 мм RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 16-Rp 1/2 длинный, 70 мм RX+;Угольник настенный внутренний +Угольник настенный с внутренней резьбой 20-Rp1/2 70мм RX+;Угольник настенный внутренний +Заглушка для полимерн. трубы 16 RX+;Заглушка труб RAUTITAN +Заглушка для полимерн. трубы 20 RX+;Заглушка труб RAUTITAN +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/250 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/500 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/1000 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 20/250 ;Трубка Г-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/250 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/500 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/1000 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/250 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/500 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/1000 ;Трубка Т-образная +К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4 (латунь);Ниппель +Резьбозажимное соединение для металлической трубки G 3/4 -15;Резьбозажимное для трубки +Резьбозажимное соединение flex/pink 16х2,2xG3/4 ;Резьбозажимное flex +Резьбозажимное соединение flex/pink 20х2,8xG3/4 ;Резьбозажимное flex +Резьбозажимное соединение stabil 16,2x2,6xG3/4 ;Резьбозажимное stabil +Резьбозажимное соединение stabil 20x2,9xG3/4 ;Резьбозажимное stabil +Фиксатор поворота трубы 16/17/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 20/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 25/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 32/90°, с кольцами (оцинк. сталь);Фиксатор поворота отопление -- cgit v1.2.3