From f907351c0d8ee511ab62528e0b9f4ddb991ab9b4 Mon Sep 17 00:00:00 2001 From: Kral Date: Sat, 3 Oct 2026 06:02:59 +0200 Subject: [PATCH] Mutation check done on all accepted tasks; mutant fixes; dump filter in proxy - skip sy-subrc lines and CDS type lengths; CDS literal mutants; mutate helper classes - proxy: sap_short_dumps shows only dumps of the current run - 26/26 tasks pass; results in docs/faz1-tasarim.md 11g Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat --- CLAUDE.md | 10 +- docs/faz1-tasarim.md | 15 ++ docs/yol-haritasi.md | 2 +- harness/mutation.py | 22 ++- harness/proxy.py | 11 ++ tasks/T01/mutation.json | 77 +++++++++ tasks/T13/mutation.json | 59 +++++++ tasks/T14/mutation.json | 33 ++++ tasks/T15/mutation.json | 39 +++++ .../eval/G0004/faulty/m1_stock_age.clas.abap | 92 ++++++++++ .../eval/G0004/faulty/m2_stock_age.clas.abap | 92 ++++++++++ .../eval/G0004/faulty/m3_stock_age.clas.abap | 92 ++++++++++ .../eval/G0004/faulty/m4_stock_age.clas.abap | 92 ++++++++++ tasks_gen/eval/G0004/mutation.json | 59 +++++++ .../faulty/m0_loyalty_evaluator.clas.abap | 79 +++++++++ .../faulty/m1_loyalty_evaluator.clas.abap | 79 +++++++++ .../faulty/m2_loyalty_evaluator.clas.abap | 79 +++++++++ .../faulty/m3_loyalty_evaluator.clas.abap | 79 +++++++++ .../faulty/m4_loyalty_evaluator.clas.abap | 79 +++++++++ tasks_gen/eval/G0007/mutation.json | 65 +++++++ .../G0008/faulty/m0_freight_calc.clas.abap | 149 +++++++++++++++++ .../G0008/faulty/m1_freight_calc.clas.abap | 149 +++++++++++++++++ .../G0008/faulty/m2_freight_calc.clas.abap | 149 +++++++++++++++++ .../G0008/faulty/m3_freight_calc.clas.abap | 149 +++++++++++++++++ .../G0008/faulty/m4_freight_calc.clas.abap | 149 +++++++++++++++++ tasks_gen/eval/G0008/mutation.json | 65 +++++++ .../faulty/m0_shipping_cost_calc.clas.abap | 56 +++++++ .../faulty/m1_shipping_cost_calc.clas.abap | 56 +++++++ .../faulty/m2_shipping_cost_calc.clas.abap | 56 +++++++ .../faulty/m3_shipping_cost_calc.clas.abap | 56 +++++++ tasks_gen/eval/G0009/mutation.json | 72 ++++++++ .../faulty/m0_stock_cover_checker.clas.abap | 128 ++++++++++++++ .../faulty/m1_stock_cover_checker.clas.abap | 128 ++++++++++++++ .../faulty/m2_stock_cover_checker.clas.abap | 128 ++++++++++++++ .../faulty/m4_stock_cover_checker.clas.abap | 128 ++++++++++++++ tasks_gen/eval/G0010/mutation.json | 68 ++++++++ .../eval/G0012/faulty/m0_prd_scrap.func.abap | 41 +++++ .../eval/G0012/faulty/m1_prd_scrap.func.abap | 41 +++++ .../eval/G0012/faulty/m2_prd_scrap.func.abap | 41 +++++ .../eval/G0012/faulty/m3_prd_scrap.func.abap | 41 +++++ tasks_gen/eval/G0012/mutation.json | 73 ++++++++ .../eval/G0013/faulty/m0_repl_qty.func.abap | 38 +++++ .../eval/G0013/faulty/m1_repl_qty.func.abap | 38 +++++ .../eval/G0013/faulty/m2_repl_qty.func.abap | 38 +++++ .../eval/G0013/faulty/m3_repl_qty.func.abap | 38 +++++ .../eval/G0013/faulty/m4_repl_qty.func.abap | 38 +++++ tasks_gen/eval/G0013/mutation.json | 75 +++++++++ .../eval/G0014/faulty/m0_stock_bal.prog.abap | 127 ++++++++++++++ .../eval/G0014/faulty/m1_stock_bal.prog.abap | 127 ++++++++++++++ .../eval/G0014/faulty/m2_stock_bal.prog.abap | 127 ++++++++++++++ .../eval/G0014/faulty/m3_stock_bal.prog.abap | 127 ++++++++++++++ .../eval/G0014/faulty/m4_stock_bal.prog.abap | 127 ++++++++++++++ tasks_gen/eval/G0014/mutation.json | 76 +++++++++ .../eval/G0015/faulty/m0_bill_age.prog.abap | 95 +++++++++++ .../eval/G0015/faulty/m1_bill_age.prog.abap | 95 +++++++++++ .../eval/G0015/faulty/m2_bill_age.prog.abap | 95 +++++++++++ tasks_gen/eval/G0015/mutation.json | 48 ++++++ .../eval/G0016/faulty/m0_stock_net.prog.abap | 132 +++++++++++++++ .../eval/G0016/faulty/m1_stock_net.prog.abap | 132 +++++++++++++++ .../eval/G0016/faulty/m3_stock_net.prog.abap | 132 +++++++++++++++ .../eval/G0016/faulty/m4_stock_net.prog.abap | 132 +++++++++++++++ tasks_gen/eval/G0016/mutation.json | 67 ++++++++ .../G0017/faulty/m1_i_proj_effort.ddls.asddls | 22 +++ .../G0017/faulty/m2_i_proj_effort.ddls.asddls | 22 +++ .../G0017/faulty/m3_i_proj_effort.ddls.asddls | 22 +++ .../G0017/faulty/m4_i_proj_effort.ddls.asddls | 22 +++ tasks_gen/eval/G0017/mutation.json | 59 +++++++ .../eval/G0018/faulty/m0_i_order.ddls.asddls | 15 ++ .../eval/G0018/faulty/m1_i_order.ddls.asddls | 15 ++ tasks_gen/eval/G0018/mutation.json | 33 ++++ .../G0019/faulty/m0_i_sales_class.ddls.asddls | 14 ++ .../G0019/faulty/m1_i_sales_class.ddls.asddls | 14 ++ .../G0019/faulty/m2_i_sales_class.ddls.asddls | 14 ++ .../G0019/faulty/m4_i_sales_class.ddls.asddls | 14 ++ tasks_gen/eval/G0019/mutation.json | 61 +++++++ .../faulty/m1_i_book_revenue.ddls.asddls | 20 +++ .../faulty/m2_i_book_revenue.ddls.asddls | 20 +++ .../faulty/m3_i_book_revenue.ddls.asddls | 20 +++ tasks_gen/eval/G0020/mutation.json | 56 +++++++ .../G0021/faulty/m0_i_shipment.ddls.asddls | 23 +++ .../G0021/faulty/m1_i_shipment.ddls.asddls | 23 +++ tasks_gen/eval/G0021/mutation.json | 35 ++++ .../faulty/m0_expense_validator.clas.abap | 85 ++++++++++ .../faulty/m1_expense_validator.clas.abap | 85 ++++++++++ .../faulty/m2_expense_validator.clas.abap | 85 ++++++++++ .../faulty/m3_expense_validator.clas.abap | 85 ++++++++++ tasks_gen/eval/G0022/mutation.json | 80 +++++++++ .../faulty/m0_freight_calculator.clas.abap | 62 +++++++ .../faulty/m1_freight_calculator.clas.abap | 62 +++++++ .../faulty/m2_freight_calculator.clas.abap | 62 +++++++ .../faulty/m3_freight_calculator.clas.abap | 62 +++++++ .../faulty/m4_freight_calculator.clas.abap | 62 +++++++ tasks_gen/eval/G0023/mutation.json | 78 +++++++++ .../faulty/m0_i_sales_report.ddls.asddls | 15 ++ .../faulty/m1_i_sales_report.ddls.asddls | 15 ++ .../faulty/m2_i_sales_report.ddls.asddls | 15 ++ .../faulty/m3_i_sales_report.ddls.asddls | 15 ++ .../faulty/m4_i_sales_report.ddls.asddls | 15 ++ tasks_gen/eval/G0024/mutation.json | 68 ++++++++ .../G0025/faulty/m0_i_partner_all.ddls.asddls | 19 +++ .../G0025/faulty/m1_i_partner_all.ddls.asddls | 19 +++ tasks_gen/eval/G0025/mutation.json | 32 ++++ .../eval/G0026/faulty/m0_cl_rent.clas.abap | 158 ++++++++++++++++++ .../eval/G0026/faulty/m1_cl_rent.clas.abap | 158 ++++++++++++++++++ .../eval/G0026/faulty/m2_cl_rent.clas.abap | 158 ++++++++++++++++++ .../eval/G0026/faulty/m3_cl_rent.clas.abap | 158 ++++++++++++++++++ .../eval/G0026/faulty/m4_cl_rent.clas.abap | 158 ++++++++++++++++++ tasks_gen/eval/G0026/mutation.json | 75 +++++++++ 108 files changed, 7384 insertions(+), 8 deletions(-) create mode 100644 tasks/T01/mutation.json create mode 100644 tasks/T13/mutation.json create mode 100644 tasks/T14/mutation.json create mode 100644 tasks/T15/mutation.json create mode 100644 tasks_gen/eval/G0004/faulty/m1_stock_age.clas.abap create mode 100644 tasks_gen/eval/G0004/faulty/m2_stock_age.clas.abap create mode 100644 tasks_gen/eval/G0004/faulty/m3_stock_age.clas.abap create mode 100644 tasks_gen/eval/G0004/faulty/m4_stock_age.clas.abap create mode 100644 tasks_gen/eval/G0004/mutation.json create mode 100644 tasks_gen/eval/G0007/faulty/m0_loyalty_evaluator.clas.abap create mode 100644 tasks_gen/eval/G0007/faulty/m1_loyalty_evaluator.clas.abap create mode 100644 tasks_gen/eval/G0007/faulty/m2_loyalty_evaluator.clas.abap create mode 100644 tasks_gen/eval/G0007/faulty/m3_loyalty_evaluator.clas.abap create mode 100644 tasks_gen/eval/G0007/faulty/m4_loyalty_evaluator.clas.abap create mode 100644 tasks_gen/eval/G0007/mutation.json create mode 100644 tasks_gen/eval/G0008/faulty/m0_freight_calc.clas.abap create mode 100644 tasks_gen/eval/G0008/faulty/m1_freight_calc.clas.abap create mode 100644 tasks_gen/eval/G0008/faulty/m2_freight_calc.clas.abap create mode 100644 tasks_gen/eval/G0008/faulty/m3_freight_calc.clas.abap create mode 100644 tasks_gen/eval/G0008/faulty/m4_freight_calc.clas.abap create mode 100644 tasks_gen/eval/G0008/mutation.json create mode 100644 tasks_gen/eval/G0009/faulty/m0_shipping_cost_calc.clas.abap create mode 100644 tasks_gen/eval/G0009/faulty/m1_shipping_cost_calc.clas.abap create mode 100644 tasks_gen/eval/G0009/faulty/m2_shipping_cost_calc.clas.abap create mode 100644 tasks_gen/eval/G0009/faulty/m3_shipping_cost_calc.clas.abap create mode 100644 tasks_gen/eval/G0009/mutation.json create mode 100644 tasks_gen/eval/G0010/faulty/m0_stock_cover_checker.clas.abap create mode 100644 tasks_gen/eval/G0010/faulty/m1_stock_cover_checker.clas.abap create mode 100644 tasks_gen/eval/G0010/faulty/m2_stock_cover_checker.clas.abap create mode 100644 tasks_gen/eval/G0010/faulty/m4_stock_cover_checker.clas.abap create mode 100644 tasks_gen/eval/G0010/mutation.json create mode 100644 tasks_gen/eval/G0012/faulty/m0_prd_scrap.func.abap create mode 100644 tasks_gen/eval/G0012/faulty/m1_prd_scrap.func.abap create mode 100644 tasks_gen/eval/G0012/faulty/m2_prd_scrap.func.abap create mode 100644 tasks_gen/eval/G0012/faulty/m3_prd_scrap.func.abap create mode 100644 tasks_gen/eval/G0012/mutation.json create mode 100644 tasks_gen/eval/G0013/faulty/m0_repl_qty.func.abap create mode 100644 tasks_gen/eval/G0013/faulty/m1_repl_qty.func.abap create mode 100644 tasks_gen/eval/G0013/faulty/m2_repl_qty.func.abap create mode 100644 tasks_gen/eval/G0013/faulty/m3_repl_qty.func.abap create mode 100644 tasks_gen/eval/G0013/faulty/m4_repl_qty.func.abap create mode 100644 tasks_gen/eval/G0013/mutation.json create mode 100644 tasks_gen/eval/G0014/faulty/m0_stock_bal.prog.abap create mode 100644 tasks_gen/eval/G0014/faulty/m1_stock_bal.prog.abap create mode 100644 tasks_gen/eval/G0014/faulty/m2_stock_bal.prog.abap create mode 100644 tasks_gen/eval/G0014/faulty/m3_stock_bal.prog.abap create mode 100644 tasks_gen/eval/G0014/faulty/m4_stock_bal.prog.abap create mode 100644 tasks_gen/eval/G0014/mutation.json create mode 100644 tasks_gen/eval/G0015/faulty/m0_bill_age.prog.abap create mode 100644 tasks_gen/eval/G0015/faulty/m1_bill_age.prog.abap create mode 100644 tasks_gen/eval/G0015/faulty/m2_bill_age.prog.abap create mode 100644 tasks_gen/eval/G0015/mutation.json create mode 100644 tasks_gen/eval/G0016/faulty/m0_stock_net.prog.abap create mode 100644 tasks_gen/eval/G0016/faulty/m1_stock_net.prog.abap create mode 100644 tasks_gen/eval/G0016/faulty/m3_stock_net.prog.abap create mode 100644 tasks_gen/eval/G0016/faulty/m4_stock_net.prog.abap create mode 100644 tasks_gen/eval/G0016/mutation.json create mode 100644 tasks_gen/eval/G0017/faulty/m1_i_proj_effort.ddls.asddls create mode 100644 tasks_gen/eval/G0017/faulty/m2_i_proj_effort.ddls.asddls create mode 100644 tasks_gen/eval/G0017/faulty/m3_i_proj_effort.ddls.asddls create mode 100644 tasks_gen/eval/G0017/faulty/m4_i_proj_effort.ddls.asddls create mode 100644 tasks_gen/eval/G0017/mutation.json create mode 100644 tasks_gen/eval/G0018/faulty/m0_i_order.ddls.asddls create mode 100644 tasks_gen/eval/G0018/faulty/m1_i_order.ddls.asddls create mode 100644 tasks_gen/eval/G0018/mutation.json create mode 100644 tasks_gen/eval/G0019/faulty/m0_i_sales_class.ddls.asddls create mode 100644 tasks_gen/eval/G0019/faulty/m1_i_sales_class.ddls.asddls create mode 100644 tasks_gen/eval/G0019/faulty/m2_i_sales_class.ddls.asddls create mode 100644 tasks_gen/eval/G0019/faulty/m4_i_sales_class.ddls.asddls create mode 100644 tasks_gen/eval/G0019/mutation.json create mode 100644 tasks_gen/eval/G0020/faulty/m1_i_book_revenue.ddls.asddls create mode 100644 tasks_gen/eval/G0020/faulty/m2_i_book_revenue.ddls.asddls create mode 100644 tasks_gen/eval/G0020/faulty/m3_i_book_revenue.ddls.asddls create mode 100644 tasks_gen/eval/G0020/mutation.json create mode 100644 tasks_gen/eval/G0021/faulty/m0_i_shipment.ddls.asddls create mode 100644 tasks_gen/eval/G0021/faulty/m1_i_shipment.ddls.asddls create mode 100644 tasks_gen/eval/G0021/mutation.json create mode 100644 tasks_gen/eval/G0022/faulty/m0_expense_validator.clas.abap create mode 100644 tasks_gen/eval/G0022/faulty/m1_expense_validator.clas.abap create mode 100644 tasks_gen/eval/G0022/faulty/m2_expense_validator.clas.abap create mode 100644 tasks_gen/eval/G0022/faulty/m3_expense_validator.clas.abap create mode 100644 tasks_gen/eval/G0022/mutation.json create mode 100644 tasks_gen/eval/G0023/faulty/m0_freight_calculator.clas.abap create mode 100644 tasks_gen/eval/G0023/faulty/m1_freight_calculator.clas.abap create mode 100644 tasks_gen/eval/G0023/faulty/m2_freight_calculator.clas.abap create mode 100644 tasks_gen/eval/G0023/faulty/m3_freight_calculator.clas.abap create mode 100644 tasks_gen/eval/G0023/faulty/m4_freight_calculator.clas.abap create mode 100644 tasks_gen/eval/G0023/mutation.json create mode 100644 tasks_gen/eval/G0024/faulty/m0_i_sales_report.ddls.asddls create mode 100644 tasks_gen/eval/G0024/faulty/m1_i_sales_report.ddls.asddls create mode 100644 tasks_gen/eval/G0024/faulty/m2_i_sales_report.ddls.asddls create mode 100644 tasks_gen/eval/G0024/faulty/m3_i_sales_report.ddls.asddls create mode 100644 tasks_gen/eval/G0024/faulty/m4_i_sales_report.ddls.asddls create mode 100644 tasks_gen/eval/G0024/mutation.json create mode 100644 tasks_gen/eval/G0025/faulty/m0_i_partner_all.ddls.asddls create mode 100644 tasks_gen/eval/G0025/faulty/m1_i_partner_all.ddls.asddls create mode 100644 tasks_gen/eval/G0025/mutation.json create mode 100644 tasks_gen/eval/G0026/faulty/m0_cl_rent.clas.abap create mode 100644 tasks_gen/eval/G0026/faulty/m1_cl_rent.clas.abap create mode 100644 tasks_gen/eval/G0026/faulty/m2_cl_rent.clas.abap create mode 100644 tasks_gen/eval/G0026/faulty/m3_cl_rent.clas.abap create mode 100644 tasks_gen/eval/G0026/faulty/m4_cl_rent.clas.abap create mode 100644 tasks_gen/eval/G0026/mutation.json diff --git a/CLAUDE.md b/CLAUDE.md index 915e0bb..85dee06 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -96,12 +96,16 @@ python3 -c "from harness.ledger import spent; print(spent())" task, first-attempt 1/5 (`docs/faz1-tasarim.md` 11f). - Generator: static checks, local abaplint parser check, dependency order of seed/reference, budget floor, max_tokens 80k. Runner: G2 for CDS with parameters, G6 ignores unknown standard superclasses. -- Step D: `harness/mutation.py` (deterministic mutants of the reference, hidden tests must fail). +- Step D done: `harness/mutation.py`, part of generator acceptance. All 26 tasks pass (`docs/faz1-tasarim.md` 11g). + Killed mutants are kept in `/faulty/`. +- Step 5 code: H stop scoring (`judge.py`), K variants (`make_k_variant`), proxy tool schema `generic_v0` (draft). + Not yet run on SAP. +- Step F: `harness/evalset.py` (88 slots G0100–G0187). Not started. ## 7. Next steps -1. Step D: run the mutation check on all accepted tasks; integrate it into the generator. -2. Use killed mutants as faulty references for own-test scoring (component (a)). +1. Test one H slot (G0168) and one K slot (G0178); then run step F (`python3 -m harness.evalset run`). +2. Own-test scoring part (a): run the model's own tests against `faulty/` mutants. 3. Step F: eval set of 110 tasks: ~150 candidates, empirical filter (2–3 models), Claude review with a checklist, Kral spot-checks ~10 flagged tasks. 4. Scoring for stop tasks (category H) and category K (free-text input, other tool schema). diff --git a/docs/faz1-tasarim.md b/docs/faz1-tasarim.md index 481c5b1..7d338b7 100644 --- a/docs/faz1-tasarim.md +++ b/docs/faz1-tasarim.md @@ -605,6 +605,21 @@ Ek bulgu: G0022'nin bütçesi (12 aktivasyon) referansın kendisine (13) yetmiyo G0022 bundle'ı değiştirilmeden yeniden doğrulandı (harness düzeltmeleri + bütçe): oracle 100, null 0 → kabul. +## 11g. Mutasyon kontrolü (Adım D, 2026-10-03) + +`harness/mutation.py`: referansın (test sınıfları hariç tüm objeler) implementasyonunda deterministik küçük değişiklikler; her mutant için oracle + gizli testler. Yakalandı = referans aktif ve en az bir gizli test düşüyor. Kabul: en az 2 geçerli mutant ve yakalama oranı ≥ %75. Generator artık oracle 100 / null 0'dan sonra mutasyon kontrolü yapar; hayatta kalan mutantlar onarım geri bildirimi olur. Yakalanan mutantlar `/faulty/` altında saklanır (kendi testlerin (a) puanı için aday hatalı referans). + +Mutant türleri: ilişki operatörünü tersine çevirme (`<`→`>=`), koşul satırında `=`→`<>`, `AND`↔`OR`, `+`↔`-`, `*`→`/`, `abap_true`↔`abap_false`, tamsayı sabiti +1; CDS'te ayrıca `sum(`→`max(`, `inner join`→`left outer join`, literal değer. + +Ayarlar (deneyle): +- Sınır kaydırma (`<`→`<=`) kullanılmaz: sınıra sabitleme (clamp) kodunda eşdeğer olur (T13: `IF fee < 1. fee = 1.`). +- `WHILE`/`DO` blokları atlanır: G0002'de bir mutant sonsuz döngü yaptı, unit test RFC bağlantısını ~8 dk kilitledi. +- `sy-subrc`/`sy-tabix` satırları atlanır: çoğu davranış farkı değil short dump verir (`GETWA_NOT_ASSIGNED`). +- CDS tip uzunlukları (`abap.char(1)`) atlanır. +- Mantık yardımcı sınıfta olabilir (G0026: FM bir sınıfı çağırır) → hedef sözleşme değil, tüm referans objeleri. + +Sonuç: T01, T13, T14, T15 ve kabul edilen 22 üretilmiş görevin hepsi geçti. Hayatta kalan mutantlar gerçek test boşluğu gösterir: `inner join`→`left outer join` (G0017, G0020: test verisinde eşleşmeyen satır yok), `sum(`→`max(` (G0019: grup başına tek satır). Süre: mutant başına ~10–50 s. + ## 12. Açık sorular Cevaplananlar (Adım 1.2): diff --git a/docs/yol-haritasi.md b/docs/yol-haritasi.md index 303d087..0e79203 100644 --- a/docs/yol-haritasi.md +++ b/docs/yol-haritasi.md @@ -86,7 +86,7 @@ Adım 3 görev ister; görevler el ile yazılırsa darboğaz olur. Bu yüzden il | A | Önek şeması: koşu 4 karakter base36, görev 3 karakter base36 (`Z005P001_`) | ✓ | | B | Harness: FUGR/FUNC, PROG, DDLS desteği (G2 kontrat kontrolü, abaplint dışa aktarımı, silme sırası) | ✓ T13–T15 oracle 100 / null 0. Server eşzamanlılık sorunu bulundu (harness'te retry) | | C | Görev üreteci: DeepSeek görev yazar (spec, seed, gizli testler, referans + local testler); kategori ve obje tipi dağılımına göre | ✓ `harness/generator.py`: üretim → yapı + statik kontrol + yerel abaplint → oracle/null doğrulama → en fazla 3 onarım turu. Pilot sonrası iyileştirildi (faz1-tasarim 11e) | -| D | Otomatik görev doğrulama: oracle = 100, null = 0, gizli testler bozuk referansta düşmeli | oracle/null hazır; mutasyon kontrolü `harness/mutation.py` (2026-10-03) | +| D | Otomatik görev doğrulama: oracle = 100, null = 0, gizli testler bozuk referansta düşmeli | ✓ oracle/null + mutasyon kontrolü (`harness/mutation.py`, generator'a bağlı). 26/26 görev geçti (faz1-tasarim 11g) | | E | Pilot: ~20 görev, tüm obje tipleri; kabul oranı ve gerçek maliyet ölçümü | ✓ 16/20 kabul, 0,16 $ / kabul edilen görev (faz1-tasarim 11e). Zor parti (5 görev): 5/5 kabul, 0,097 $ / kabul edilen görev (11f) | | F | Eval seti: 110 görev; Kral incelemesi. Eğitim havuzu: otomatik doğrulanmış görevler, eval ile çakışmasız | | | G | Ölçüm (1.6) ve yörünge üretimi (3.2) paralel worker'larla (bulut model: en fazla 6) | | diff --git a/harness/mutation.py b/harness/mutation.py index 940a7bf..4d1ecab 100644 --- a/harness/mutation.py +++ b/harness/mutation.py @@ -115,10 +115,21 @@ def mutants(src, otype, seed, n=MAX_MUTANTS): continue if kind == "arith" and re.search(r"(\(|\bSELECT)\s*$", src[line_start:x.start()], re.I): continue # COUNT( * ), SELECT * - if _skip_line(line) or (kind == "const" and re.search(r"\bLENGTH\b|\bDECIMALS\b|\(\s*\d+\s*,", line, re.I)): + if re.search(r"\bsy-subrc\b|\bsy-tabix\b", line, re.I): + continue # mostly gives a short dump (unassigned field symbol), not a behavior change + if _skip_line(line) or (kind == "const" and (re.search(r"\bLENGTH\b|\bDECIMALS\b|\(\s*\d+\s*,", line, re.I) + or re.search(r"abap\.\w+\(\s*[\d\s,]*$", src[line_start:x.start()], re.I))): continue new = str(int(x.group(1)) + 1) if rep is None else rep sites.append((kind, x.start(), x.end(), new, src.count("\n", 0, x.start()) + 1, x.group(0))) + if cds: # literal values in the select list (G0025: source 'A' / 'B' was the only logic) + for x in re.finditer(r"'([^'\n]{1,20})'", src): + line_start = src.rfind("\n", 0, x.start()) + 1 + if not lo <= x.start() < hi or src[line_start:x.start()].lstrip().startswith(("@", "//")): + continue + v = x.group(1) + new = "'" + ("Z" if v[0] != "Z" else "Y") + v[1:] + "'" + sites.append(("lit", x.start(), x.end(), new, src.count("\n", 0, x.start()) + 1, x.group(0))) rnd = random.Random(seed) rnd.shuffle(sites) chosen, kinds, lines = [], set(), set() @@ -141,9 +152,12 @@ def check_task(pool_root, task_id, run_base, n=MAX_MUTANTS, keep=False): """Run the mutants of one task. Returns a summary dict; writes it to /mutation.json.""" task_dir = os.path.join(pool_root, task_id) meta = json.load(open(os.path.join(task_dir, "task.json"))) - contract = {c["name"].upper() for c in meta["contract"]} - targets = [o for o in meta["reference"] if o["name"].upper() in contract and o.get("file") - and o["type"] in ("CLAS", "FUNC", "PROG", "DDLS")] + # every reference object except test classes: the logic can sit in a helper (G0026: FM calls a class) + def is_test(o): + return o["type"] == "CLAS" and re.search(r"^\s*CLASS\s+\S+\s+DEFINITION[^.]*FOR\s+TESTING", + open(os.path.join(task_dir, o["file"])).read(), re.I | re.M) + targets = [o for o in meta["reference"] if o.get("file") and o["type"] in ("CLAS", "FUNC", "PROG", "DDLS") + and not is_test(o)] work = os.path.join(ROOT, "runs", "gen", "mut") os.makedirs(work, exist_ok=True) runner = Runner(os.path.join(work, "pool"), os.path.join(work, "runs")) diff --git a/harness/proxy.py b/harness/proxy.py index b0b13d8..6ce50e5 100644 --- a/harness/proxy.py +++ b/harness/proxy.py @@ -41,6 +41,7 @@ class ToolProxy: def __init__(self, mcp, prefix, budget, log_path, tool_schema=None): self.mcp = mcp self.variant = VARIANTS.get(tool_schema) if tool_schema else None + self.started = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) # dump times are UTC self.prefix = prefix.upper() self.max_calls = budget.get("max_tool_calls", 60) self.max_activations = budget.get("max_activations", 15) @@ -82,6 +83,16 @@ class ToolProxy: return bool(RUN_PREFIX.match(n)) and not n.startswith(self.prefix) def _filter(self, tool, text): + if tool == "sap_short_dumps": # only dumps of this run: other runs (and mutants) also write dumps + try: + data = json.loads(text) + except ValueError: + return text + if isinstance(data, dict) and isinstance(data.get("dumps"), list): + data["dumps"] = [d for d in data["dumps"] if str(d.get("updated", "")) >= self.started] + data["count"] = len(data["dumps"]) + return json.dumps(data) + return text if tool not in ("sap_search_object", "sap_usage_references"): return text try: diff --git a/tasks/T01/mutation.json b/tasks/T01/mutation.json new file mode 100644 index 0000000..443197f --- /dev/null +++ b/tasks/T01/mutation.json @@ -0,0 +1,77 @@ +{ + "task": "T01", + "mutants": [ + { + "object": "{{P}}IBAN_VALIDATOR", + "mutant": "line 34: = -> <> (eq)", + "status": "killed", + "hidden": "2/12", + "failed_tests": [ + "BAD_CHARS", + "DIGIT_IN_COUNTRY", + "LOWER_CASE_OK", + "ORDER_CHARS_BEFORE_COUNTRY", + "UNKNOWN_COUNTRY", + "VALID_ALL_COUNTRIES", + "VALID_DE", + "VALID_LETTERS_IN_BODY", + "WRONG_CHECKSUM", + "WRONG_LENGTH" + ] + }, + { + "object": "{{P}}IBAN_VALIDATOR", + "mutant": "line 44: <> -> = (rel)", + "status": "killed", + "hidden": "6/12", + "failed_tests": [ + "LOWER_CASE_OK", + "VALID_ALL_COUNTRIES", + "VALID_DE", + "VALID_LETTERS_IN_BODY", + "WRONG_CHECKSUM", + "WRONG_LENGTH" + ] + }, + { + "object": "{{P}}IBAN_VALIDATOR", + "mutant": "line 78: * -> / (arith)", + "status": "killed", + "hidden": "8/12", + "failed_tests": [ + "LOWER_CASE_OK", + "VALID_ALL_COUNTRIES", + "VALID_DE", + "VALID_LETTERS_IN_BODY" + ] + }, + { + "object": "{{P}}IBAN_VALIDATOR", + "mutant": "line 78: 10 -> 11 (const)", + "status": "killed", + "hidden": "8/12", + "failed_tests": [ + "LOWER_CASE_OK", + "VALID_ALL_COUNTRIES", + "VALID_DE", + "VALID_LETTERS_IN_BODY" + ] + }, + { + "object": "{{P}}IBAN_VALIDATOR", + "mutant": "line 80: 100 -> 101 (const)", + "status": "killed", + "hidden": "8/12", + "failed_tests": [ + "LOWER_CASE_OK", + "VALID_ALL_COUNTRIES", + "VALID_DE", + "VALID_LETTERS_IN_BODY" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks/T13/mutation.json b/tasks/T13/mutation.json new file mode 100644 index 0000000..ca80e63 --- /dev/null +++ b/tasks/T13/mutation.json @@ -0,0 +1,59 @@ +{ + "task": "T13", + "mutants": [ + { + "object": "{{P}}EVT_FEE", + "mutant": "line 18: * -> / (arith)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "INVOICE_PERCENT", + "INVOICE_ROUNDING" + ] + }, + { + "object": "{{P}}EVT_FEE", + "mutant": "line 18: 2 -> 3 (const)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "INVOICE_PERCENT", + "INVOICE_ROUNDING" + ] + }, + { + "object": "{{P}}EVT_FEE", + "mutant": "line 18: 100 -> 101 (const)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "INVOICE_PERCENT", + "INVOICE_ROUNDING" + ] + }, + { + "object": "{{P}}EVT_FEE", + "mutant": "line 21: > -> <= (rel)", + "status": "killed", + "hidden": "5/8", + "failed_tests": [ + "INVOICE_MAXIMUM", + "INVOICE_PERCENT", + "INVOICE_ROUNDING" + ] + }, + { + "object": "{{P}}EVT_FEE", + "mutant": "line 25: abap_true -> abap_false (bool)", + "status": "killed", + "hidden": "7/8", + "failed_tests": [ + "CREDIT_MEMO_SKIPS" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks/T14/mutation.json b/tasks/T14/mutation.json new file mode 100644 index 0000000..d931012 --- /dev/null +++ b/tasks/T14/mutation.json @@ -0,0 +1,33 @@ +{ + "task": "T14", + "mutants": [ + { + "object": "{{P}}SALES_SUM", + "mutant": "line 30: >= -> < (rel)", + "status": "killed", + "hidden": "0/5", + "failed_tests": [ + "ALL_REGIONS", + "DATE_FILTER", + "REGION_FILTER", + "SORTED_BY_TOTAL", + "TOTALS_AND_COUNTS" + ] + }, + { + "object": "{{P}}SALES_SUM", + "mutant": "line 31: AND -> OR (logic)", + "status": "killed", + "hidden": "2/5", + "failed_tests": [ + "DATE_FILTER", + "REGION_FILTER", + "TOTALS_AND_COUNTS" + ] + } + ], + "valid": 2, + "killed": 2, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks/T15/mutation.json b/tasks/T15/mutation.json new file mode 100644 index 0000000..0a9d946 --- /dev/null +++ b/tasks/T15/mutation.json @@ -0,0 +1,39 @@ +{ + "task": "T15", + "mutants": [ + { + "object": "{{P}}I_ORDER_TOTAL", + "mutant": "line 5: inner join -> left outer join (join)", + "status": "killed", + "hidden": "4/5", + "failed_tests": [ + "ORDER_WITHOUT_ITEMS" + ] + }, + { + "object": "{{P}}I_ORDER_TOTAL", + "mutant": "line 5: = -> <> (eq)", + "status": "killed", + "hidden": "1/5", + "failed_tests": [ + "DECIMALS", + "ITEM_COUNTS", + "ORDER_WITHOUT_ITEMS", + "TOTALS" + ] + }, + { + "object": "{{P}}I_ORDER_TOTAL", + "mutant": "line 10: sum( -> max( (agg)", + "status": "killed", + "hidden": "4/5", + "failed_tests": [ + "TOTALS" + ] + } + ], + "valid": 3, + "killed": 3, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0004/faulty/m1_stock_age.clas.abap b/tasks_gen/eval/G0004/faulty/m1_stock_age.clas.abap new file mode 100644 index 0000000..b484680 --- /dev/null +++ b/tasks_gen/eval/G0004/faulty/m1_stock_age.clas.abap @@ -0,0 +1,92 @@ +CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_age. + + PRIVATE SECTION. + TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row + WITH UNIQUE KEY material bucket. + TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total + WITH UNIQUE KEY material. + + METHODS age_in_days + IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch + iv_key_date TYPE dats + RETURNING VALUE(rv_age) TYPE i. + + METHODS bucket_of + IMPORTING iv_age TYPE i + RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket. +ENDCLASS. + + +CLASS {{p}}stock_age IMPLEMENTATION. + + METHOD {{p}}if_stock_age~analyze. + DATA lt_group TYPE tt_age_group. + + LOOP AT it_batch INTO DATA(ls_batch). + DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ). + IF lv_age < 0. + CONTINUE. + ENDIF. + + DATA(lv_bucket) = bucket_of( lv_age ). + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material bucket = lv_bucket ) + INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_age = lt_group. + SORT rt_age BY material bucket. + ENDMETHOD. + + METHOD {{p}}if_stock_age~total_by_material. + DATA lt_group TYPE tt_total_group. + + LOOP AT it_batch INTO DATA(ls_batch). + IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0. + CONTINUE. + ENDIF. + + ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count - 1. + ENDLOOP. + + rt_total = lt_group. + SORT rt_total BY material. + ENDMETHOD. + + METHOD age_in_days. + IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date. + rv_age = -1. + ELSE. + rv_age = iv_key_date - is_batch-gr_date. + ENDIF. + ENDMETHOD. + + METHOD bucket_of. + IF iv_age <= 30. + rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30. + ELSEIF iv_age <= 60. + rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60. + ELSEIF iv_age <= 90. + rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90. + ELSE. + rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0004/faulty/m2_stock_age.clas.abap b/tasks_gen/eval/G0004/faulty/m2_stock_age.clas.abap new file mode 100644 index 0000000..9f6809d --- /dev/null +++ b/tasks_gen/eval/G0004/faulty/m2_stock_age.clas.abap @@ -0,0 +1,92 @@ +CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_age. + + PRIVATE SECTION. + TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row + WITH UNIQUE KEY material bucket. + TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total + WITH UNIQUE KEY material. + + METHODS age_in_days + IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch + iv_key_date TYPE dats + RETURNING VALUE(rv_age) TYPE i. + + METHODS bucket_of + IMPORTING iv_age TYPE i + RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket. +ENDCLASS. + + +CLASS {{p}}stock_age IMPLEMENTATION. + + METHOD {{p}}if_stock_age~analyze. + DATA lt_group TYPE tt_age_group. + + LOOP AT it_batch INTO DATA(ls_batch). + DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ). + IF lv_age < 0. + CONTINUE. + ENDIF. + + DATA(lv_bucket) = bucket_of( lv_age ). + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material bucket = lv_bucket ) + INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_age = lt_group. + SORT rt_age BY material bucket. + ENDMETHOD. + + METHOD {{p}}if_stock_age~total_by_material. + DATA lt_group TYPE tt_total_group. + + LOOP AT it_batch INTO DATA(ls_batch). + IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0. + CONTINUE. + ENDIF. + + ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_total = lt_group. + SORT rt_total BY material. + ENDMETHOD. + + METHOD age_in_days. + IF is_batch-gr_date IS INITIAL AND is_batch-gr_date > iv_key_date. + rv_age = -1. + ELSE. + rv_age = iv_key_date - is_batch-gr_date. + ENDIF. + ENDMETHOD. + + METHOD bucket_of. + IF iv_age <= 30. + rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30. + ELSEIF iv_age <= 60. + rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60. + ELSEIF iv_age <= 90. + rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90. + ELSE. + rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0004/faulty/m3_stock_age.clas.abap b/tasks_gen/eval/G0004/faulty/m3_stock_age.clas.abap new file mode 100644 index 0000000..05e3662 --- /dev/null +++ b/tasks_gen/eval/G0004/faulty/m3_stock_age.clas.abap @@ -0,0 +1,92 @@ +CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_age. + + PRIVATE SECTION. + TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row + WITH UNIQUE KEY material bucket. + TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total + WITH UNIQUE KEY material. + + METHODS age_in_days + IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch + iv_key_date TYPE dats + RETURNING VALUE(rv_age) TYPE i. + + METHODS bucket_of + IMPORTING iv_age TYPE i + RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket. +ENDCLASS. + + +CLASS {{p}}stock_age IMPLEMENTATION. + + METHOD {{p}}if_stock_age~analyze. + DATA lt_group TYPE tt_age_group. + + LOOP AT it_batch INTO DATA(ls_batch). + DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ). + IF lv_age < 0. + CONTINUE. + ENDIF. + + DATA(lv_bucket) = bucket_of( lv_age ). + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material bucket = lv_bucket ) + INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_age = lt_group. + SORT rt_age BY material bucket. + ENDMETHOD. + + METHOD {{p}}if_stock_age~total_by_material. + DATA lt_group TYPE tt_total_group. + + LOOP AT it_batch INTO DATA(ls_batch). + IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0. + CONTINUE. + ENDIF. + + ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_total = lt_group. + SORT rt_total BY material. + ENDMETHOD. + + METHOD age_in_days. + IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date. + rv_age = -1. + ELSE. + rv_age = iv_key_date + is_batch-gr_date. + ENDIF. + ENDMETHOD. + + METHOD bucket_of. + IF iv_age <= 30. + rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30. + ELSEIF iv_age <= 60. + rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60. + ELSEIF iv_age <= 90. + rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90. + ELSE. + rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0004/faulty/m4_stock_age.clas.abap b/tasks_gen/eval/G0004/faulty/m4_stock_age.clas.abap new file mode 100644 index 0000000..9d938e6 --- /dev/null +++ b/tasks_gen/eval/G0004/faulty/m4_stock_age.clas.abap @@ -0,0 +1,92 @@ +CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_age. + + PRIVATE SECTION. + TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row + WITH UNIQUE KEY material bucket. + TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total + WITH UNIQUE KEY material. + + METHODS age_in_days + IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch + iv_key_date TYPE dats + RETURNING VALUE(rv_age) TYPE i. + + METHODS bucket_of + IMPORTING iv_age TYPE i + RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket. +ENDCLASS. + + +CLASS {{p}}stock_age IMPLEMENTATION. + + METHOD {{p}}if_stock_age~analyze. + DATA lt_group TYPE tt_age_group. + + LOOP AT it_batch INTO DATA(ls_batch). + DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ). + IF lv_age < 0. + CONTINUE. + ENDIF. + + DATA(lv_bucket) = bucket_of( lv_age ). + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material bucket = lv_bucket ) + INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material + bucket = lv_bucket ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_age = lt_group. + SORT rt_age BY material bucket. + ENDMETHOD. + + METHOD {{p}}if_stock_age~total_by_material. + DATA lt_group TYPE tt_total_group. + + LOOP AT it_batch INTO DATA(ls_batch). + IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0. + CONTINUE. + ENDIF. + + ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(). + IF sy-subrc <> 0. + INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group. + ASSIGN lt_group[ material = ls_batch-material ] TO . + ENDIF. + + -quantity = -quantity + ls_batch-quantity. + -batch_count = -batch_count + 1. + ENDLOOP. + + rt_total = lt_group. + SORT rt_total BY material. + ENDMETHOD. + + METHOD age_in_days. + IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date. + rv_age = -1. + ELSE. + rv_age = iv_key_date - is_batch-gr_date. + ENDIF. + ENDMETHOD. + + METHOD bucket_of. + IF iv_age > 30. + rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30. + ELSEIF iv_age <= 60. + rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60. + ELSEIF iv_age <= 90. + rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90. + ELSE. + rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0004/mutation.json b/tasks_gen/eval/G0004/mutation.json new file mode 100644 index 0000000..650c015 --- /dev/null +++ b/tasks_gen/eval/G0004/mutation.json @@ -0,0 +1,59 @@ +{ + "task": "G0004", + "mutants": [ + { + "object": "{{P}}STOCK_AGE", + "mutant": "line 55: = -> <> (eq)", + "status": "invalid", + "hidden": "0/0", + "failed_tests": [] + }, + { + "object": "{{P}}STOCK_AGE", + "mutant": "line 66: + -> - (arith)", + "status": "killed", + "hidden": "9/10", + "failed_tests": [ + "TOTAL_GROUPS_BY_MATERIAL" + ] + }, + { + "object": "{{P}}STOCK_AGE", + "mutant": "line 74: OR -> AND (logic)", + "status": "killed", + "hidden": "8/10", + "failed_tests": [ + "INVALID_ROWS_ARE_IGNORED", + "TOTAL_IGNORES_INVALID_ROWS" + ] + }, + { + "object": "{{P}}STOCK_AGE", + "mutant": "line 77: - -> + (arith)", + "status": "killed", + "hidden": "6/10", + "failed_tests": [ + "BUCKET_BOUNDARIES", + "GROUPS_SUM_QUANTITY_AND_COUNT", + "RESULT_IS_SORTED", + "SINGLE_BATCH_BUCKET_01" + ] + }, + { + "object": "{{P}}STOCK_AGE", + "mutant": "line 82: <= -> > (rel)", + "status": "killed", + "hidden": "6/10", + "failed_tests": [ + "BUCKET_BOUNDARIES", + "GROUPS_SUM_QUANTITY_AND_COUNT", + "RESULT_IS_SORTED", + "SINGLE_BATCH_BUCKET_01" + ] + } + ], + "valid": 4, + "killed": 4, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0007/faulty/m0_loyalty_evaluator.clas.abap b/tasks_gen/eval/G0007/faulty/m0_loyalty_evaluator.clas.abap new file mode 100644 index 0000000..2c6e684 --- /dev/null +++ b/tasks_gen/eval/G0007/faulty/m0_loyalty_evaluator.clas.abap @@ -0,0 +1,79 @@ +CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_loyalty_rules. + + PRIVATE SECTION. + CONSTANTS: + c_silver_threshold TYPE i VALUE 1000, + c_gold_threshold TYPE i VALUE 5000, + c_platinum_threshold TYPE i VALUE 20000. + + METHODS normalize_points + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_points) TYPE i. + + METHODS tier_of + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier. + + METHODS points_to_tier + IMPORTING iv_points TYPE i + iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier + RETURNING VALUE(rv_points) TYPE i. +ENDCLASS. + + +CLASS {{p}}loyalty_evaluator IMPLEMENTATION. + METHOD {{p}}if_loyalty_rules~get_tier. + rv_tier = tier_of( normalize_points( iv_points ) ). + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~get_discount. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_percent = 3. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_percent = 7. + WHEN {{p}}if_loyalty_rules=>c_tier-platinum. + rv_percent = 12. + WHEN OTHERS. + rv_percent = 0. + ENDCASE. + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~points_to_next_tier. + DATA(lv_points) = normalize_points( iv_points ). + DATA(lv_tier) = tier_of( lv_points ). + rv_points = points_to_tier( iv_points = lv_points + iv_tier = lv_tier ). + ENDMETHOD. + + METHOD normalize_points. + rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ). + ENDMETHOD. + + METHOD tier_of. + IF iv_points >= c_platinum_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum. + ELSEIF iv_points < c_gold_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-gold. + ELSEIF iv_points >= c_silver_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-silver. + ELSE. + rv_tier = {{p}}if_loyalty_rules=>c_tier-basic. + ENDIF. + ENDMETHOD. + + METHOD points_to_tier. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-basic. + rv_points = c_silver_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_points = c_gold_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_points = c_platinum_threshold - iv_points. + WHEN OTHERS. + rv_points = 0. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0007/faulty/m1_loyalty_evaluator.clas.abap b/tasks_gen/eval/G0007/faulty/m1_loyalty_evaluator.clas.abap new file mode 100644 index 0000000..0bc3373 --- /dev/null +++ b/tasks_gen/eval/G0007/faulty/m1_loyalty_evaluator.clas.abap @@ -0,0 +1,79 @@ +CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_loyalty_rules. + + PRIVATE SECTION. + CONSTANTS: + c_silver_threshold TYPE i VALUE 1000, + c_gold_threshold TYPE i VALUE 5000, + c_platinum_threshold TYPE i VALUE 20000. + + METHODS normalize_points + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_points) TYPE i. + + METHODS tier_of + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier. + + METHODS points_to_tier + IMPORTING iv_points TYPE i + iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier + RETURNING VALUE(rv_points) TYPE i. +ENDCLASS. + + +CLASS {{p}}loyalty_evaluator IMPLEMENTATION. + METHOD {{p}}if_loyalty_rules~get_tier. + rv_tier = tier_of( normalize_points( iv_points ) ). + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~get_discount. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_percent = 3. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_percent = 7. + WHEN {{p}}if_loyalty_rules=>c_tier-platinum. + rv_percent = 12. + WHEN OTHERS. + rv_percent = 0. + ENDCASE. + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~points_to_next_tier. + DATA(lv_points) = normalize_points( iv_points ). + DATA(lv_tier) = tier_of( lv_points ). + rv_points = points_to_tier( iv_points = lv_points + iv_tier = lv_tier ). + ENDMETHOD. + + METHOD normalize_points. + rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ). + ENDMETHOD. + + METHOD tier_of. + IF iv_points >= c_platinum_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum. + ELSEIF iv_points >= c_gold_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-gold. + ELSEIF iv_points < c_silver_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-silver. + ELSE. + rv_tier = {{p}}if_loyalty_rules=>c_tier-basic. + ENDIF. + ENDMETHOD. + + METHOD points_to_tier. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-basic. + rv_points = c_silver_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_points = c_gold_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_points = c_platinum_threshold - iv_points. + WHEN OTHERS. + rv_points = 0. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0007/faulty/m2_loyalty_evaluator.clas.abap b/tasks_gen/eval/G0007/faulty/m2_loyalty_evaluator.clas.abap new file mode 100644 index 0000000..cc9806e --- /dev/null +++ b/tasks_gen/eval/G0007/faulty/m2_loyalty_evaluator.clas.abap @@ -0,0 +1,79 @@ +CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_loyalty_rules. + + PRIVATE SECTION. + CONSTANTS: + c_silver_threshold TYPE i VALUE 1000, + c_gold_threshold TYPE i VALUE 5000, + c_platinum_threshold TYPE i VALUE 20000. + + METHODS normalize_points + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_points) TYPE i. + + METHODS tier_of + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier. + + METHODS points_to_tier + IMPORTING iv_points TYPE i + iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier + RETURNING VALUE(rv_points) TYPE i. +ENDCLASS. + + +CLASS {{p}}loyalty_evaluator IMPLEMENTATION. + METHOD {{p}}if_loyalty_rules~get_tier. + rv_tier = tier_of( normalize_points( iv_points ) ). + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~get_discount. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_percent = 3. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_percent = 7. + WHEN {{p}}if_loyalty_rules=>c_tier-platinum. + rv_percent = 12. + WHEN OTHERS. + rv_percent = 0. + ENDCASE. + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~points_to_next_tier. + DATA(lv_points) = normalize_points( iv_points ). + DATA(lv_tier) = tier_of( lv_points ). + rv_points = points_to_tier( iv_points = lv_points + iv_tier = lv_tier ). + ENDMETHOD. + + METHOD normalize_points. + rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ). + ENDMETHOD. + + METHOD tier_of. + IF iv_points >= c_platinum_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum. + ELSEIF iv_points >= c_gold_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-gold. + ELSEIF iv_points >= c_silver_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-silver. + ELSE. + rv_tier = {{p}}if_loyalty_rules=>c_tier-basic. + ENDIF. + ENDMETHOD. + + METHOD points_to_tier. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-basic. + rv_points = c_silver_threshold + iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_points = c_gold_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_points = c_platinum_threshold - iv_points. + WHEN OTHERS. + rv_points = 0. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0007/faulty/m3_loyalty_evaluator.clas.abap b/tasks_gen/eval/G0007/faulty/m3_loyalty_evaluator.clas.abap new file mode 100644 index 0000000..6d26116 --- /dev/null +++ b/tasks_gen/eval/G0007/faulty/m3_loyalty_evaluator.clas.abap @@ -0,0 +1,79 @@ +CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_loyalty_rules. + + PRIVATE SECTION. + CONSTANTS: + c_silver_threshold TYPE i VALUE 1000, + c_gold_threshold TYPE i VALUE 5000, + c_platinum_threshold TYPE i VALUE 20000. + + METHODS normalize_points + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_points) TYPE i. + + METHODS tier_of + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier. + + METHODS points_to_tier + IMPORTING iv_points TYPE i + iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier + RETURNING VALUE(rv_points) TYPE i. +ENDCLASS. + + +CLASS {{p}}loyalty_evaluator IMPLEMENTATION. + METHOD {{p}}if_loyalty_rules~get_tier. + rv_tier = tier_of( normalize_points( iv_points ) ). + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~get_discount. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_percent = 3. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_percent = 7. + WHEN {{p}}if_loyalty_rules=>c_tier-platinum. + rv_percent = 12. + WHEN OTHERS. + rv_percent = 0. + ENDCASE. + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~points_to_next_tier. + DATA(lv_points) = normalize_points( iv_points ). + DATA(lv_tier) = tier_of( lv_points ). + rv_points = points_to_tier( iv_points = lv_points + iv_tier = lv_tier ). + ENDMETHOD. + + METHOD normalize_points. + rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ). + ENDMETHOD. + + METHOD tier_of. + IF iv_points >= c_platinum_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum. + ELSEIF iv_points >= c_gold_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-gold. + ELSEIF iv_points >= c_silver_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-silver. + ELSE. + rv_tier = {{p}}if_loyalty_rules=>c_tier-basic. + ENDIF. + ENDMETHOD. + + METHOD points_to_tier. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-basic. + rv_points = c_silver_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_points = c_gold_threshold + iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_points = c_platinum_threshold - iv_points. + WHEN OTHERS. + rv_points = 0. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0007/faulty/m4_loyalty_evaluator.clas.abap b/tasks_gen/eval/G0007/faulty/m4_loyalty_evaluator.clas.abap new file mode 100644 index 0000000..dad498d --- /dev/null +++ b/tasks_gen/eval/G0007/faulty/m4_loyalty_evaluator.clas.abap @@ -0,0 +1,79 @@ +CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_loyalty_rules. + + PRIVATE SECTION. + CONSTANTS: + c_silver_threshold TYPE i VALUE 1000, + c_gold_threshold TYPE i VALUE 5000, + c_platinum_threshold TYPE i VALUE 20000. + + METHODS normalize_points + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_points) TYPE i. + + METHODS tier_of + IMPORTING iv_points TYPE i + RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier. + + METHODS points_to_tier + IMPORTING iv_points TYPE i + iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier + RETURNING VALUE(rv_points) TYPE i. +ENDCLASS. + + +CLASS {{p}}loyalty_evaluator IMPLEMENTATION. + METHOD {{p}}if_loyalty_rules~get_tier. + rv_tier = tier_of( normalize_points( iv_points ) ). + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~get_discount. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_percent = 3. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_percent = 7. + WHEN {{p}}if_loyalty_rules=>c_tier-platinum. + rv_percent = 12. + WHEN OTHERS. + rv_percent = 0. + ENDCASE. + ENDMETHOD. + + METHOD {{p}}if_loyalty_rules~points_to_next_tier. + DATA(lv_points) = normalize_points( iv_points ). + DATA(lv_tier) = tier_of( lv_points ). + rv_points = points_to_tier( iv_points = lv_points + iv_tier = lv_tier ). + ENDMETHOD. + + METHOD normalize_points. + rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ). + ENDMETHOD. + + METHOD tier_of. + IF iv_points >= c_platinum_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum. + ELSEIF iv_points >= c_gold_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-gold. + ELSEIF iv_points >= c_silver_threshold. + rv_tier = {{p}}if_loyalty_rules=>c_tier-silver. + ELSE. + rv_tier = {{p}}if_loyalty_rules=>c_tier-basic. + ENDIF. + ENDMETHOD. + + METHOD points_to_tier. + CASE iv_tier. + WHEN {{p}}if_loyalty_rules=>c_tier-basic. + rv_points = c_silver_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-silver. + rv_points = c_gold_threshold - iv_points. + WHEN {{p}}if_loyalty_rules=>c_tier-gold. + rv_points = c_platinum_threshold + iv_points. + WHEN OTHERS. + rv_points = 0. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0007/mutation.json b/tasks_gen/eval/G0007/mutation.json new file mode 100644 index 0000000..cf4f6fb --- /dev/null +++ b/tasks_gen/eval/G0007/mutation.json @@ -0,0 +1,65 @@ +{ + "task": "G0007", + "mutants": [ + { + "object": "{{P}}LOYALTY_EVALUATOR", + "mutant": "line 58: >= -> < (rel)", + "status": "killed", + "hidden": "3/10", + "failed_tests": [ + "NEXT_TIER_FROM_BASIC", + "NEXT_TIER_FROM_GOLD", + "NEXT_TIER_FROM_SILVER", + "NEXT_TIER_NEGATIVE_POINTS", + "TIER_BOUNDARIES", + "TIER_NEGATIVE", + "TIER_ZERO" + ] + }, + { + "object": "{{P}}LOYALTY_EVALUATOR", + "mutant": "line 60: >= -> < (rel)", + "status": "killed", + "hidden": "4/10", + "failed_tests": [ + "NEXT_TIER_FROM_BASIC", + "NEXT_TIER_FROM_SILVER", + "NEXT_TIER_NEGATIVE_POINTS", + "TIER_BOUNDARIES", + "TIER_NEGATIVE", + "TIER_ZERO" + ] + }, + { + "object": "{{P}}LOYALTY_EVALUATOR", + "mutant": "line 70: - -> + (arith)", + "status": "killed", + "hidden": "9/10", + "failed_tests": [ + "NEXT_TIER_FROM_BASIC" + ] + }, + { + "object": "{{P}}LOYALTY_EVALUATOR", + "mutant": "line 72: - -> + (arith)", + "status": "killed", + "hidden": "9/10", + "failed_tests": [ + "NEXT_TIER_FROM_SILVER" + ] + }, + { + "object": "{{P}}LOYALTY_EVALUATOR", + "mutant": "line 74: - -> + (arith)", + "status": "killed", + "hidden": "9/10", + "failed_tests": [ + "NEXT_TIER_FROM_GOLD" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0008/faulty/m0_freight_calc.clas.abap b/tasks_gen/eval/G0008/faulty/m0_freight_calc.clas.abap new file mode 100644 index 0000000..7b39c70 --- /dev/null +++ b/tasks_gen/eval/G0008/faulty/m0_freight_calc.clas.abap @@ -0,0 +1,149 @@ +CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. + + CONSTANTS: + c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', + c_base_weight TYPE ty_quantity VALUE '1000.000', + c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', + c_free_km TYPE i VALUE 100, + c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', + c_step TYPE ty_quantity VALUE '100.000', + c_volume_factor TYPE i VALUE 250, + c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. + + METHODS check_input + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. + + METHODS chargeable_weight + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + RETURNING VALUE(rv_weight) TYPE ty_quantity. + + METHODS base_freight + IMPORTING iv_weight_kg TYPE ty_quantity + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS distance_freight + IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS fuel_freight + IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS started_steps + IMPORTING iv_excess TYPE ty_quantity + RETURNING VALUE(rv_steps) TYPE i. +ENDCLASS. + + +CLASS {{p}}freight_calc IMPLEMENTATION. + + METHOD {{p}}if_freight_calc~calculate. + DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. + DATA lv_weight TYPE ty_quantity. + DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. + + CLEAR rs_result. + lv_reason = check_input( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 + iv_distance_km = iv_distance_km + iv_fuel_index = iv_fuel_index ). + IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. + rs_result-reason = lv_reason. + RETURN. + ENDIF. + + lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 ). + rs_result-chargeable_weight = lv_weight. + rs_result-base = base_freight( lv_weight ). + rs_result-distance = distance_freight( iv_distance_km ). + lv_net = rs_result-base - rs_result-distance. + rs_result-fuel = fuel_freight( iv_amount = lv_net + iv_fuel_index = iv_fuel_index ). + rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel. + rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. + ENDMETHOD. + + METHOD check_input. + IF iv_weight_kg <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-weight. + ELSEIF iv_volume_m3 < 0. + rv_reason = {{p}}if_freight_calc=>c_reason-volume. + ELSEIF iv_distance_km <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-distance. + ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100. + rv_reason = {{p}}if_freight_calc=>c_reason-fuel. + ELSE. + rv_reason = {{p}}if_freight_calc=>c_reason-ok. + ENDIF. + ENDMETHOD. + + METHOD chargeable_weight. + DATA lv_volumetric TYPE ty_quantity. + + lv_volumetric = iv_volume_m3 * c_volume_factor. + IF lv_volumetric > iv_weight_kg. + rv_weight = lv_volumetric. + ELSE. + rv_weight = iv_weight_kg. + ENDIF. + ENDMETHOD. + + METHOD base_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_weight_kg - c_base_weight. + IF lv_excess <= 0. + rv_amount = c_base_amount. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = c_base_amount + lv_steps * c_weight_rate. + ENDIF. + ENDMETHOD. + + METHOD distance_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_distance_km - c_free_km. + IF lv_excess <= 0. + rv_amount = 0. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = lv_steps * c_km_rate. + ENDIF. + ENDMETHOD. + + METHOD fuel_freight. + DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. + DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. + + lv_scaled = iv_amount * iv_fuel_index. + lv_fuel = lv_scaled * c_percent. + rv_amount = lv_fuel. + ENDMETHOD. + + METHOD started_steps. + DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. + DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. + + lv_excess_scaled = iv_excess * 1000. + lv_step_scaled = c_step * 1000. + rv_steps = lv_excess_scaled DIV lv_step_scaled. + IF lv_excess_scaled MOD lv_step_scaled > 0. + rv_steps = rv_steps + 1. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0008/faulty/m1_freight_calc.clas.abap b/tasks_gen/eval/G0008/faulty/m1_freight_calc.clas.abap new file mode 100644 index 0000000..dfca1be --- /dev/null +++ b/tasks_gen/eval/G0008/faulty/m1_freight_calc.clas.abap @@ -0,0 +1,149 @@ +CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. + + CONSTANTS: + c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', + c_base_weight TYPE ty_quantity VALUE '1000.000', + c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', + c_free_km TYPE i VALUE 100, + c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', + c_step TYPE ty_quantity VALUE '100.000', + c_volume_factor TYPE i VALUE 250, + c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. + + METHODS check_input + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. + + METHODS chargeable_weight + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + RETURNING VALUE(rv_weight) TYPE ty_quantity. + + METHODS base_freight + IMPORTING iv_weight_kg TYPE ty_quantity + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS distance_freight + IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS fuel_freight + IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS started_steps + IMPORTING iv_excess TYPE ty_quantity + RETURNING VALUE(rv_steps) TYPE i. +ENDCLASS. + + +CLASS {{p}}freight_calc IMPLEMENTATION. + + METHOD {{p}}if_freight_calc~calculate. + DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. + DATA lv_weight TYPE ty_quantity. + DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. + + CLEAR rs_result. + lv_reason = check_input( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 + iv_distance_km = iv_distance_km + iv_fuel_index = iv_fuel_index ). + IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. + rs_result-reason = lv_reason. + RETURN. + ENDIF. + + lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 ). + rs_result-chargeable_weight = lv_weight. + rs_result-base = base_freight( lv_weight ). + rs_result-distance = distance_freight( iv_distance_km ). + lv_net = rs_result-base + rs_result-distance. + rs_result-fuel = fuel_freight( iv_amount = lv_net + iv_fuel_index = iv_fuel_index ). + rs_result-total = rs_result-base + rs_result-distance - rs_result-fuel. + rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. + ENDMETHOD. + + METHOD check_input. + IF iv_weight_kg <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-weight. + ELSEIF iv_volume_m3 < 0. + rv_reason = {{p}}if_freight_calc=>c_reason-volume. + ELSEIF iv_distance_km <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-distance. + ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100. + rv_reason = {{p}}if_freight_calc=>c_reason-fuel. + ELSE. + rv_reason = {{p}}if_freight_calc=>c_reason-ok. + ENDIF. + ENDMETHOD. + + METHOD chargeable_weight. + DATA lv_volumetric TYPE ty_quantity. + + lv_volumetric = iv_volume_m3 * c_volume_factor. + IF lv_volumetric > iv_weight_kg. + rv_weight = lv_volumetric. + ELSE. + rv_weight = iv_weight_kg. + ENDIF. + ENDMETHOD. + + METHOD base_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_weight_kg - c_base_weight. + IF lv_excess <= 0. + rv_amount = c_base_amount. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = c_base_amount + lv_steps * c_weight_rate. + ENDIF. + ENDMETHOD. + + METHOD distance_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_distance_km - c_free_km. + IF lv_excess <= 0. + rv_amount = 0. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = lv_steps * c_km_rate. + ENDIF. + ENDMETHOD. + + METHOD fuel_freight. + DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. + DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. + + lv_scaled = iv_amount * iv_fuel_index. + lv_fuel = lv_scaled * c_percent. + rv_amount = lv_fuel. + ENDMETHOD. + + METHOD started_steps. + DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. + DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. + + lv_excess_scaled = iv_excess * 1000. + lv_step_scaled = c_step * 1000. + rv_steps = lv_excess_scaled DIV lv_step_scaled. + IF lv_excess_scaled MOD lv_step_scaled > 0. + rv_steps = rv_steps + 1. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0008/faulty/m2_freight_calc.clas.abap b/tasks_gen/eval/G0008/faulty/m2_freight_calc.clas.abap new file mode 100644 index 0000000..ebf2d53 --- /dev/null +++ b/tasks_gen/eval/G0008/faulty/m2_freight_calc.clas.abap @@ -0,0 +1,149 @@ +CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. + + CONSTANTS: + c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', + c_base_weight TYPE ty_quantity VALUE '1000.000', + c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', + c_free_km TYPE i VALUE 100, + c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', + c_step TYPE ty_quantity VALUE '100.000', + c_volume_factor TYPE i VALUE 250, + c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. + + METHODS check_input + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. + + METHODS chargeable_weight + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + RETURNING VALUE(rv_weight) TYPE ty_quantity. + + METHODS base_freight + IMPORTING iv_weight_kg TYPE ty_quantity + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS distance_freight + IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS fuel_freight + IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS started_steps + IMPORTING iv_excess TYPE ty_quantity + RETURNING VALUE(rv_steps) TYPE i. +ENDCLASS. + + +CLASS {{p}}freight_calc IMPLEMENTATION. + + METHOD {{p}}if_freight_calc~calculate. + DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. + DATA lv_weight TYPE ty_quantity. + DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. + + CLEAR rs_result. + lv_reason = check_input( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 + iv_distance_km = iv_distance_km + iv_fuel_index = iv_fuel_index ). + IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. + rs_result-reason = lv_reason. + RETURN. + ENDIF. + + lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 ). + rs_result-chargeable_weight = lv_weight. + rs_result-base = base_freight( lv_weight ). + rs_result-distance = distance_freight( iv_distance_km ). + lv_net = rs_result-base + rs_result-distance. + rs_result-fuel = fuel_freight( iv_amount = lv_net + iv_fuel_index = iv_fuel_index ). + rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel. + rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. + ENDMETHOD. + + METHOD check_input. + IF iv_weight_kg <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-weight. + ELSEIF iv_volume_m3 < 0. + rv_reason = {{p}}if_freight_calc=>c_reason-volume. + ELSEIF iv_distance_km <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-distance. + ELSEIF iv_fuel_index < 0 OR iv_fuel_index <= 100. + rv_reason = {{p}}if_freight_calc=>c_reason-fuel. + ELSE. + rv_reason = {{p}}if_freight_calc=>c_reason-ok. + ENDIF. + ENDMETHOD. + + METHOD chargeable_weight. + DATA lv_volumetric TYPE ty_quantity. + + lv_volumetric = iv_volume_m3 * c_volume_factor. + IF lv_volumetric > iv_weight_kg. + rv_weight = lv_volumetric. + ELSE. + rv_weight = iv_weight_kg. + ENDIF. + ENDMETHOD. + + METHOD base_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_weight_kg - c_base_weight. + IF lv_excess <= 0. + rv_amount = c_base_amount. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = c_base_amount + lv_steps * c_weight_rate. + ENDIF. + ENDMETHOD. + + METHOD distance_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_distance_km - c_free_km. + IF lv_excess <= 0. + rv_amount = 0. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = lv_steps * c_km_rate. + ENDIF. + ENDMETHOD. + + METHOD fuel_freight. + DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. + DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. + + lv_scaled = iv_amount * iv_fuel_index. + lv_fuel = lv_scaled * c_percent. + rv_amount = lv_fuel. + ENDMETHOD. + + METHOD started_steps. + DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. + DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. + + lv_excess_scaled = iv_excess * 1000. + lv_step_scaled = c_step * 1000. + rv_steps = lv_excess_scaled DIV lv_step_scaled. + IF lv_excess_scaled MOD lv_step_scaled > 0. + rv_steps = rv_steps + 1. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0008/faulty/m3_freight_calc.clas.abap b/tasks_gen/eval/G0008/faulty/m3_freight_calc.clas.abap new file mode 100644 index 0000000..463c644 --- /dev/null +++ b/tasks_gen/eval/G0008/faulty/m3_freight_calc.clas.abap @@ -0,0 +1,149 @@ +CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. + + CONSTANTS: + c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', + c_base_weight TYPE ty_quantity VALUE '1000.000', + c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', + c_free_km TYPE i VALUE 100, + c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', + c_step TYPE ty_quantity VALUE '100.000', + c_volume_factor TYPE i VALUE 250, + c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. + + METHODS check_input + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. + + METHODS chargeable_weight + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + RETURNING VALUE(rv_weight) TYPE ty_quantity. + + METHODS base_freight + IMPORTING iv_weight_kg TYPE ty_quantity + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS distance_freight + IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS fuel_freight + IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS started_steps + IMPORTING iv_excess TYPE ty_quantity + RETURNING VALUE(rv_steps) TYPE i. +ENDCLASS. + + +CLASS {{p}}freight_calc IMPLEMENTATION. + + METHOD {{p}}if_freight_calc~calculate. + DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. + DATA lv_weight TYPE ty_quantity. + DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. + + CLEAR rs_result. + lv_reason = check_input( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 + iv_distance_km = iv_distance_km + iv_fuel_index = iv_fuel_index ). + IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. + rs_result-reason = lv_reason. + RETURN. + ENDIF. + + lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 ). + rs_result-chargeable_weight = lv_weight. + rs_result-base = base_freight( lv_weight ). + rs_result-distance = distance_freight( iv_distance_km ). + lv_net = rs_result-base + rs_result-distance. + rs_result-fuel = fuel_freight( iv_amount = lv_net + iv_fuel_index = iv_fuel_index ). + rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel. + rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. + ENDMETHOD. + + METHOD check_input. + IF iv_weight_kg <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-weight. + ELSEIF iv_volume_m3 < 0. + rv_reason = {{p}}if_freight_calc=>c_reason-volume. + ELSEIF iv_distance_km <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-distance. + ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100. + rv_reason = {{p}}if_freight_calc=>c_reason-fuel. + ELSE. + rv_reason = {{p}}if_freight_calc=>c_reason-ok. + ENDIF. + ENDMETHOD. + + METHOD chargeable_weight. + DATA lv_volumetric TYPE ty_quantity. + + lv_volumetric = iv_volume_m3 * c_volume_factor. + IF lv_volumetric > iv_weight_kg. + rv_weight = lv_volumetric. + ELSE. + rv_weight = iv_weight_kg. + ENDIF. + ENDMETHOD. + + METHOD base_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_weight_kg - c_base_weight. + IF lv_excess > 0. + rv_amount = c_base_amount. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = c_base_amount + lv_steps * c_weight_rate. + ENDIF. + ENDMETHOD. + + METHOD distance_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_distance_km - c_free_km. + IF lv_excess <= 0. + rv_amount = 0. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = lv_steps * c_km_rate. + ENDIF. + ENDMETHOD. + + METHOD fuel_freight. + DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. + DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. + + lv_scaled = iv_amount * iv_fuel_index. + lv_fuel = lv_scaled * c_percent. + rv_amount = lv_fuel. + ENDMETHOD. + + METHOD started_steps. + DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. + DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. + + lv_excess_scaled = iv_excess * 1000. + lv_step_scaled = c_step * 1000. + rv_steps = lv_excess_scaled DIV lv_step_scaled. + IF lv_excess_scaled MOD lv_step_scaled > 0. + rv_steps = rv_steps + 1. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0008/faulty/m4_freight_calc.clas.abap b/tasks_gen/eval/G0008/faulty/m4_freight_calc.clas.abap new file mode 100644 index 0000000..bedd0db --- /dev/null +++ b/tasks_gen/eval/G0008/faulty/m4_freight_calc.clas.abap @@ -0,0 +1,149 @@ +CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. + + CONSTANTS: + c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', + c_base_weight TYPE ty_quantity VALUE '1000.000', + c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', + c_free_km TYPE i VALUE 100, + c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', + c_step TYPE ty_quantity VALUE '100.000', + c_volume_factor TYPE i VALUE 250, + c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. + + METHODS check_input + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. + + METHODS chargeable_weight + IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight + iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume + RETURNING VALUE(rv_weight) TYPE ty_quantity. + + METHODS base_freight + IMPORTING iv_weight_kg TYPE ty_quantity + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS distance_freight + IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS fuel_freight + IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount + iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel + RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. + + METHODS started_steps + IMPORTING iv_excess TYPE ty_quantity + RETURNING VALUE(rv_steps) TYPE i. +ENDCLASS. + + +CLASS {{p}}freight_calc IMPLEMENTATION. + + METHOD {{p}}if_freight_calc~calculate. + DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. + DATA lv_weight TYPE ty_quantity. + DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. + + CLEAR rs_result. + lv_reason = check_input( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 + iv_distance_km = iv_distance_km + iv_fuel_index = iv_fuel_index ). + IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. + rs_result-reason = lv_reason. + RETURN. + ENDIF. + + lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg + iv_volume_m3 = iv_volume_m3 ). + rs_result-chargeable_weight = lv_weight. + rs_result-base = base_freight( lv_weight ). + rs_result-distance = distance_freight( iv_distance_km ). + lv_net = rs_result-base + rs_result-distance. + rs_result-fuel = fuel_freight( iv_amount = lv_net + iv_fuel_index = iv_fuel_index ). + rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel. + rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. + ENDMETHOD. + + METHOD check_input. + IF iv_weight_kg <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-weight. + ELSEIF iv_volume_m3 < 0. + rv_reason = {{p}}if_freight_calc=>c_reason-volume. + ELSEIF iv_distance_km <= 0. + rv_reason = {{p}}if_freight_calc=>c_reason-distance. + ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100. + rv_reason = {{p}}if_freight_calc=>c_reason-fuel. + ELSE. + rv_reason = {{p}}if_freight_calc=>c_reason-ok. + ENDIF. + ENDMETHOD. + + METHOD chargeable_weight. + DATA lv_volumetric TYPE ty_quantity. + + lv_volumetric = iv_volume_m3 * c_volume_factor. + IF lv_volumetric > iv_weight_kg. + rv_weight = lv_volumetric. + ELSE. + rv_weight = iv_weight_kg. + ENDIF. + ENDMETHOD. + + METHOD base_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_weight_kg - c_base_weight. + IF lv_excess <= 0. + rv_amount = c_base_amount. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = c_base_amount - lv_steps * c_weight_rate. + ENDIF. + ENDMETHOD. + + METHOD distance_freight. + DATA lv_excess TYPE ty_quantity. + DATA lv_steps TYPE i. + + lv_excess = iv_distance_km - c_free_km. + IF lv_excess <= 0. + rv_amount = 0. + ELSE. + lv_steps = started_steps( lv_excess ). + rv_amount = lv_steps * c_km_rate. + ENDIF. + ENDMETHOD. + + METHOD fuel_freight. + DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. + DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. + + lv_scaled = iv_amount * iv_fuel_index. + lv_fuel = lv_scaled * c_percent. + rv_amount = lv_fuel. + ENDMETHOD. + + METHOD started_steps. + DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. + DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. + + lv_excess_scaled = iv_excess * 1000. + lv_step_scaled = c_step * 1000. + rv_steps = lv_excess_scaled DIV lv_step_scaled. + IF lv_excess_scaled MOD lv_step_scaled > 0. + rv_steps = rv_steps + 1. + ENDIF. + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0008/mutation.json b/tasks_gen/eval/G0008/mutation.json new file mode 100644 index 0000000..891bd90 --- /dev/null +++ b/tasks_gen/eval/G0008/mutation.json @@ -0,0 +1,65 @@ +{ + "task": "G0008", + "mutants": [ + { + "object": "{{P}}FREIGHT_CALC", + "mutant": "line 71: + -> - (arith)", + "status": "killed", + "hidden": "10/11", + "failed_tests": [ + "FULL_LOAD" + ] + }, + { + "object": "{{P}}FREIGHT_CALC", + "mutant": "line 74: + -> - (arith)", + "status": "killed", + "hidden": "9/11", + "failed_tests": [ + "FUEL_ROUNDS_HALF_UP", + "FULL_LOAD" + ] + }, + { + "object": "{{P}}FREIGHT_CALC", + "mutant": "line 85: > -> <= (rel)", + "status": "killed", + "hidden": "4/11", + "failed_tests": [ + "BASE_ABOVE_WEIGHT_LIMIT", + "BASE_AT_WEIGHT_LIMIT", + "DISTANCE_COMPONENT", + "FUEL_INDEX_TOO_HIGH", + "FUEL_ROUNDS_HALF_UP", + "FULL_LOAD", + "VOLUMETRIC_WEIGHT_WINS" + ] + }, + { + "object": "{{P}}FREIGHT_CALC", + "mutant": "line 108: <= -> > (rel)", + "status": "killed", + "hidden": "8/11", + "failed_tests": [ + "BASE_ABOVE_WEIGHT_LIMIT", + "FULL_LOAD", + "VOLUMETRIC_WEIGHT_WINS" + ] + }, + { + "object": "{{P}}FREIGHT_CALC", + "mutant": "line 112: + -> - (arith)", + "status": "killed", + "hidden": "8/11", + "failed_tests": [ + "BASE_ABOVE_WEIGHT_LIMIT", + "FULL_LOAD", + "VOLUMETRIC_WEIGHT_WINS" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0009/faulty/m0_shipping_cost_calc.clas.abap b/tasks_gen/eval/G0009/faulty/m0_shipping_cost_calc.clas.abap new file mode 100644 index 0000000..8a8c72c --- /dev/null +++ b/tasks_gen/eval/G0009/faulty/m0_shipping_cost_calc.clas.abap @@ -0,0 +1,56 @@ +CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_shipping_cost. + + PRIVATE SECTION. + METHODS base_rate + IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight + RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount. + + METHODS express_surcharge + IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount + RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount. +ENDCLASS. + + +CLASS {{p}}shipping_cost_calc IMPLEMENTATION. + METHOD {{p}}if_shipping_cost~calculate. + IF iv_weight <= 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA(lv_cost) = base_rate( iv_weight ). + + IF iv_express <> abap_true. + lv_cost = lv_cost + express_surcharge( lv_cost ). + ENDIF. + + IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge. + rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge. + ELSE. + rv_cost = lv_cost. + ENDIF. + ENDMETHOD. + + METHOD base_rate. + IF iv_weight <= 1. + rv_rate = '4.90'. + ELSEIF iv_weight <= 5. + rv_rate = '8.50'. + ELSEIF iv_weight <= 10. + rv_rate = '12.00'. + ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight. + rv_rate = '18.75'. + ELSE. + DATA(lv_started_kg) = CONV i( + ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ). + rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step. + ENDIF. + ENDMETHOD. + + METHOD express_surcharge. + rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100 + dec = 2 ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0009/faulty/m1_shipping_cost_calc.clas.abap b/tasks_gen/eval/G0009/faulty/m1_shipping_cost_calc.clas.abap new file mode 100644 index 0000000..45fe30c --- /dev/null +++ b/tasks_gen/eval/G0009/faulty/m1_shipping_cost_calc.clas.abap @@ -0,0 +1,56 @@ +CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_shipping_cost. + + PRIVATE SECTION. + METHODS base_rate + IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight + RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount. + + METHODS express_surcharge + IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount + RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount. +ENDCLASS. + + +CLASS {{p}}shipping_cost_calc IMPLEMENTATION. + METHOD {{p}}if_shipping_cost~calculate. + IF iv_weight <= 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA(lv_cost) = base_rate( iv_weight ). + + IF iv_express = abap_true. + lv_cost = lv_cost - express_surcharge( lv_cost ). + ENDIF. + + IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge. + rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge. + ELSE. + rv_cost = lv_cost. + ENDIF. + ENDMETHOD. + + METHOD base_rate. + IF iv_weight <= 1. + rv_rate = '4.90'. + ELSEIF iv_weight <= 5. + rv_rate = '8.50'. + ELSEIF iv_weight <= 10. + rv_rate = '12.00'. + ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight. + rv_rate = '18.75'. + ELSE. + DATA(lv_started_kg) = CONV i( + ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ). + rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step. + ENDIF. + ENDMETHOD. + + METHOD express_surcharge. + rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100 + dec = 2 ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0009/faulty/m2_shipping_cost_calc.clas.abap b/tasks_gen/eval/G0009/faulty/m2_shipping_cost_calc.clas.abap new file mode 100644 index 0000000..dec0706 --- /dev/null +++ b/tasks_gen/eval/G0009/faulty/m2_shipping_cost_calc.clas.abap @@ -0,0 +1,56 @@ +CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_shipping_cost. + + PRIVATE SECTION. + METHODS base_rate + IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight + RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount. + + METHODS express_surcharge + IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount + RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount. +ENDCLASS. + + +CLASS {{p}}shipping_cost_calc IMPLEMENTATION. + METHOD {{p}}if_shipping_cost~calculate. + IF iv_weight <= 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA(lv_cost) = base_rate( iv_weight ). + + IF iv_express = abap_true. + lv_cost = lv_cost + express_surcharge( lv_cost ). + ENDIF. + + IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge. + rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge. + ELSE. + rv_cost = lv_cost. + ENDIF. + ENDMETHOD. + + METHOD base_rate. + IF iv_weight > 1. + rv_rate = '4.90'. + ELSEIF iv_weight <= 5. + rv_rate = '8.50'. + ELSEIF iv_weight <= 10. + rv_rate = '12.00'. + ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight. + rv_rate = '18.75'. + ELSE. + DATA(lv_started_kg) = CONV i( + ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ). + rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step. + ENDIF. + ENDMETHOD. + + METHOD express_surcharge. + rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100 + dec = 2 ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0009/faulty/m3_shipping_cost_calc.clas.abap b/tasks_gen/eval/G0009/faulty/m3_shipping_cost_calc.clas.abap new file mode 100644 index 0000000..c4d82b3 --- /dev/null +++ b/tasks_gen/eval/G0009/faulty/m3_shipping_cost_calc.clas.abap @@ -0,0 +1,56 @@ +CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_shipping_cost. + + PRIVATE SECTION. + METHODS base_rate + IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight + RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount. + + METHODS express_surcharge + IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount + RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount. +ENDCLASS. + + +CLASS {{p}}shipping_cost_calc IMPLEMENTATION. + METHOD {{p}}if_shipping_cost~calculate. + IF iv_weight <= 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA(lv_cost) = base_rate( iv_weight ). + + IF iv_express = abap_true. + lv_cost = lv_cost + express_surcharge( lv_cost ). + ENDIF. + + IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge. + rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge. + ELSE. + rv_cost = lv_cost. + ENDIF. + ENDMETHOD. + + METHOD base_rate. + IF iv_weight <= 1. + rv_rate = '4.90'. + ELSEIF iv_weight <= 5. + rv_rate = '8.50'. + ELSEIF iv_weight <= 10. + rv_rate = '12.00'. + ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight. + rv_rate = '18.75'. + ELSE. + DATA(lv_started_kg) = CONV i( + ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ). + rv_rate = '18.75' - lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step. + ENDIF. + ENDMETHOD. + + METHOD express_surcharge. + rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100 + dec = 2 ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0009/mutation.json b/tasks_gen/eval/G0009/mutation.json new file mode 100644 index 0000000..6cd49cc --- /dev/null +++ b/tasks_gen/eval/G0009/mutation.json @@ -0,0 +1,72 @@ +{ + "task": "G0009", + "mutants": [ + { + "object": "{{P}}SHIPPING_COST_CALC", + "mutant": "line 25: = -> <> (eq)", + "status": "killed", + "hidden": "1/10", + "failed_tests": [ + "BULK_EXPRESS", + "BULK_WEIGHT_LIMIT", + "BULK_WEIGHT_STARTED_KG", + "EXPRESS_BELOW_MINIMUM", + "EXPRESS_SURCHARGE", + "LIGHT_PARCEL_GETS_MINIMUM", + "TIER_LIMIT_FIVE_KG", + "TIER_LIMIT_ONE_KG", + "TIER_LIMIT_TEN_KG" + ] + }, + { + "object": "{{P}}SHIPPING_COST_CALC", + "mutant": "line 26: + -> - (arith)", + "status": "killed", + "hidden": "7/10", + "failed_tests": [ + "BULK_EXPRESS", + "EXPRESS_BELOW_MINIMUM", + "EXPRESS_SURCHARGE" + ] + }, + { + "object": "{{P}}SHIPPING_COST_CALC", + "mutant": "line 37: <= -> > (rel)", + "status": "killed", + "hidden": "1/10", + "failed_tests": [ + "BULK_EXPRESS", + "BULK_WEIGHT_LIMIT", + "BULK_WEIGHT_STARTED_KG", + "EXPRESS_BELOW_MINIMUM", + "EXPRESS_SURCHARGE", + "LIGHT_PARCEL_GETS_MINIMUM", + "TIER_LIMIT_FIVE_KG", + "TIER_LIMIT_ONE_KG", + "TIER_LIMIT_TEN_KG" + ] + }, + { + "object": "{{P}}SHIPPING_COST_CALC", + "mutant": "line 48: + -> - (arith)", + "status": "killed", + "hidden": "7/10", + "failed_tests": [ + "BULK_EXPRESS", + "BULK_WEIGHT_LIMIT", + "BULK_WEIGHT_STARTED_KG" + ] + }, + { + "object": "{{P}}SHIPPING_COST_CALC", + "mutant": "line 54: 2 -> 3 (const)", + "status": "survived", + "hidden": "10/10", + "failed_tests": [] + } + ], + "valid": 5, + "killed": 4, + "kill_rate": 0.8, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0010/faulty/m0_stock_cover_checker.clas.abap b/tasks_gen/eval/G0010/faulty/m0_stock_cover_checker.clas.abap new file mode 100644 index 0000000..69f5983 --- /dev/null +++ b/tasks_gen/eval/G0010/faulty/m0_stock_cover_checker.clas.abap @@ -0,0 +1,128 @@ +CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_cover. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_stock, + material TYPE {{p}}if_stock_cover=>ty_material, + plant TYPE {{p}}if_stock_cover=>ty_plant, + remaining TYPE {{p}}if_stock_cover=>ty_quantity, + END OF ty_stock. + TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant. + + METHODS aggregate + IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item + RETURNING VALUE(rt_stock) TYPE tt_stock. + + METHODS free_quantity + IMPORTING it_stock TYPE tt_stock + iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity. + + METHODS consume + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity + CHANGING ct_stock TYPE tt_stock. + + METHODS normalize_material + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material. + + METHODS normalize_plant + IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant. +ENDCLASS. + + +CLASS {{p}}stock_cover_checker IMPLEMENTATION. + METHOD {{p}}if_stock_cover~check. + DATA(lt_stock) = aggregate( it_stock ). + + LOOP AT it_requirement INTO DATA(ls_requirement). + DATA(lv_free) = free_quantity( it_stock = lt_stock + iv_material = ls_requirement-material + iv_plant = ls_requirement-plant ). + DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result( + material = ls_requirement-material + plant = ls_requirement-plant + required = ls_requirement-required + available = lv_free ). + + IF ls_requirement-required > 0. + ls_result-status = {{p}}if_stock_cover=>c_status-invalid. + ELSEIF lv_free >= ls_requirement-required. + ls_result-status = {{p}}if_stock_cover=>c_status-ok. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = ls_requirement-required + CHANGING ct_stock = lt_stock ). + ELSE. + ls_result-status = {{p}}if_stock_cover=>c_status-short. + ls_result-shortage = ls_requirement-required - lv_free. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = lv_free + CHANGING ct_stock = lt_stock ). + ENDIF. + + APPEND ls_result TO rt_result. + ENDLOOP. + ENDMETHOD. + + METHOD {{p}}if_stock_cover~shortages. + rt_shortage = it_result. + DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short. + SORT rt_shortage BY material plant. + ENDMETHOD. + + METHOD aggregate. + LOOP AT it_stock INTO DATA(ls_stock). + IF ls_stock-quantity < 0. + CONTINUE. + ENDIF. + DATA(lv_material) = normalize_material( ls_stock-material ). + DATA(lv_plant) = normalize_plant( ls_stock-plant ). + ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining + ls_stock-quantity. + ELSE. + INSERT VALUE #( material = lv_material + plant = lv_plant + remaining = ls_stock-quantity ) INTO TABLE rt_stock. + ENDIF. + ENDLOOP. + ENDMETHOD. + + METHOD free_quantity. + ASSIGN it_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + rv_quantity = -remaining. + ENDIF. + ENDMETHOD. + + METHOD consume. + ASSIGN ct_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining - iv_quantity. + ENDIF. + ENDMETHOD. + + METHOD normalize_material. + DATA lv_text TYPE string. + lv_text = iv_material. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_material = to_upper( lv_text ). + ENDMETHOD. + + METHOD normalize_plant. + DATA lv_text TYPE string. + lv_text = iv_plant. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_plant = to_upper( lv_text ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0010/faulty/m1_stock_cover_checker.clas.abap b/tasks_gen/eval/G0010/faulty/m1_stock_cover_checker.clas.abap new file mode 100644 index 0000000..a35eced --- /dev/null +++ b/tasks_gen/eval/G0010/faulty/m1_stock_cover_checker.clas.abap @@ -0,0 +1,128 @@ +CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_cover. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_stock, + material TYPE {{p}}if_stock_cover=>ty_material, + plant TYPE {{p}}if_stock_cover=>ty_plant, + remaining TYPE {{p}}if_stock_cover=>ty_quantity, + END OF ty_stock. + TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant. + + METHODS aggregate + IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item + RETURNING VALUE(rt_stock) TYPE tt_stock. + + METHODS free_quantity + IMPORTING it_stock TYPE tt_stock + iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity. + + METHODS consume + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity + CHANGING ct_stock TYPE tt_stock. + + METHODS normalize_material + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material. + + METHODS normalize_plant + IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant. +ENDCLASS. + + +CLASS {{p}}stock_cover_checker IMPLEMENTATION. + METHOD {{p}}if_stock_cover~check. + DATA(lt_stock) = aggregate( it_stock ). + + LOOP AT it_requirement INTO DATA(ls_requirement). + DATA(lv_free) = free_quantity( it_stock = lt_stock + iv_material = ls_requirement-material + iv_plant = ls_requirement-plant ). + DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result( + material = ls_requirement-material + plant = ls_requirement-plant + required = ls_requirement-required + available = lv_free ). + + IF ls_requirement-required <= 0. + ls_result-status = {{p}}if_stock_cover=>c_status-invalid. + ELSEIF lv_free >= ls_requirement-required. + ls_result-status = {{p}}if_stock_cover=>c_status-ok. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = ls_requirement-required + CHANGING ct_stock = lt_stock ). + ELSE. + ls_result-status = {{p}}if_stock_cover=>c_status-short. + ls_result-shortage = ls_requirement-required - lv_free. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = lv_free + CHANGING ct_stock = lt_stock ). + ENDIF. + + APPEND ls_result TO rt_result. + ENDLOOP. + ENDMETHOD. + + METHOD {{p}}if_stock_cover~shortages. + rt_shortage = it_result. + DELETE rt_shortage WHERE status = {{p}}if_stock_cover=>c_status-short. + SORT rt_shortage BY material plant. + ENDMETHOD. + + METHOD aggregate. + LOOP AT it_stock INTO DATA(ls_stock). + IF ls_stock-quantity < 0. + CONTINUE. + ENDIF. + DATA(lv_material) = normalize_material( ls_stock-material ). + DATA(lv_plant) = normalize_plant( ls_stock-plant ). + ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining + ls_stock-quantity. + ELSE. + INSERT VALUE #( material = lv_material + plant = lv_plant + remaining = ls_stock-quantity ) INTO TABLE rt_stock. + ENDIF. + ENDLOOP. + ENDMETHOD. + + METHOD free_quantity. + ASSIGN it_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + rv_quantity = -remaining. + ENDIF. + ENDMETHOD. + + METHOD consume. + ASSIGN ct_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining - iv_quantity. + ENDIF. + ENDMETHOD. + + METHOD normalize_material. + DATA lv_text TYPE string. + lv_text = iv_material. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_material = to_upper( lv_text ). + ENDMETHOD. + + METHOD normalize_plant. + DATA lv_text TYPE string. + lv_text = iv_plant. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_plant = to_upper( lv_text ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0010/faulty/m2_stock_cover_checker.clas.abap b/tasks_gen/eval/G0010/faulty/m2_stock_cover_checker.clas.abap new file mode 100644 index 0000000..a4ded8e --- /dev/null +++ b/tasks_gen/eval/G0010/faulty/m2_stock_cover_checker.clas.abap @@ -0,0 +1,128 @@ +CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_cover. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_stock, + material TYPE {{p}}if_stock_cover=>ty_material, + plant TYPE {{p}}if_stock_cover=>ty_plant, + remaining TYPE {{p}}if_stock_cover=>ty_quantity, + END OF ty_stock. + TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant. + + METHODS aggregate + IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item + RETURNING VALUE(rt_stock) TYPE tt_stock. + + METHODS free_quantity + IMPORTING it_stock TYPE tt_stock + iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity. + + METHODS consume + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity + CHANGING ct_stock TYPE tt_stock. + + METHODS normalize_material + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material. + + METHODS normalize_plant + IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant. +ENDCLASS. + + +CLASS {{p}}stock_cover_checker IMPLEMENTATION. + METHOD {{p}}if_stock_cover~check. + DATA(lt_stock) = aggregate( it_stock ). + + LOOP AT it_requirement INTO DATA(ls_requirement). + DATA(lv_free) = free_quantity( it_stock = lt_stock + iv_material = ls_requirement-material + iv_plant = ls_requirement-plant ). + DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result( + material = ls_requirement-material + plant = ls_requirement-plant + required = ls_requirement-required + available = lv_free ). + + IF ls_requirement-required <= 0. + ls_result-status = {{p}}if_stock_cover=>c_status-invalid. + ELSEIF lv_free >= ls_requirement-required. + ls_result-status = {{p}}if_stock_cover=>c_status-ok. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = ls_requirement-required + CHANGING ct_stock = lt_stock ). + ELSE. + ls_result-status = {{p}}if_stock_cover=>c_status-short. + ls_result-shortage = ls_requirement-required - lv_free. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = lv_free + CHANGING ct_stock = lt_stock ). + ENDIF. + + APPEND ls_result TO rt_result. + ENDLOOP. + ENDMETHOD. + + METHOD {{p}}if_stock_cover~shortages. + rt_shortage = it_result. + DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short. + SORT rt_shortage BY material plant. + ENDMETHOD. + + METHOD aggregate. + LOOP AT it_stock INTO DATA(ls_stock). + IF ls_stock-quantity >= 0. + CONTINUE. + ENDIF. + DATA(lv_material) = normalize_material( ls_stock-material ). + DATA(lv_plant) = normalize_plant( ls_stock-plant ). + ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining + ls_stock-quantity. + ELSE. + INSERT VALUE #( material = lv_material + plant = lv_plant + remaining = ls_stock-quantity ) INTO TABLE rt_stock. + ENDIF. + ENDLOOP. + ENDMETHOD. + + METHOD free_quantity. + ASSIGN it_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + rv_quantity = -remaining. + ENDIF. + ENDMETHOD. + + METHOD consume. + ASSIGN ct_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining - iv_quantity. + ENDIF. + ENDMETHOD. + + METHOD normalize_material. + DATA lv_text TYPE string. + lv_text = iv_material. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_material = to_upper( lv_text ). + ENDMETHOD. + + METHOD normalize_plant. + DATA lv_text TYPE string. + lv_text = iv_plant. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_plant = to_upper( lv_text ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0010/faulty/m4_stock_cover_checker.clas.abap b/tasks_gen/eval/G0010/faulty/m4_stock_cover_checker.clas.abap new file mode 100644 index 0000000..b59d249 --- /dev/null +++ b/tasks_gen/eval/G0010/faulty/m4_stock_cover_checker.clas.abap @@ -0,0 +1,128 @@ +CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_stock_cover. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_stock, + material TYPE {{p}}if_stock_cover=>ty_material, + plant TYPE {{p}}if_stock_cover=>ty_plant, + remaining TYPE {{p}}if_stock_cover=>ty_quantity, + END OF ty_stock. + TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant. + + METHODS aggregate + IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item + RETURNING VALUE(rt_stock) TYPE tt_stock. + + METHODS free_quantity + IMPORTING it_stock TYPE tt_stock + iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity. + + METHODS consume + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + iv_plant TYPE {{p}}if_stock_cover=>ty_plant + iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity + CHANGING ct_stock TYPE tt_stock. + + METHODS normalize_material + IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material + RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material. + + METHODS normalize_plant + IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant + RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant. +ENDCLASS. + + +CLASS {{p}}stock_cover_checker IMPLEMENTATION. + METHOD {{p}}if_stock_cover~check. + DATA(lt_stock) = aggregate( it_stock ). + + LOOP AT it_requirement INTO DATA(ls_requirement). + DATA(lv_free) = free_quantity( it_stock = lt_stock + iv_material = ls_requirement-material + iv_plant = ls_requirement-plant ). + DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result( + material = ls_requirement-material + plant = ls_requirement-plant + required = ls_requirement-required + available = lv_free ). + + IF ls_requirement-required <= 0. + ls_result-status = {{p}}if_stock_cover=>c_status-invalid. + ELSEIF lv_free >= ls_requirement-required. + ls_result-status = {{p}}if_stock_cover=>c_status-ok. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = ls_requirement-required + CHANGING ct_stock = lt_stock ). + ELSE. + ls_result-status = {{p}}if_stock_cover=>c_status-short. + ls_result-shortage = ls_requirement-required - lv_free. + consume( EXPORTING iv_material = ls_requirement-material + iv_plant = ls_requirement-plant + iv_quantity = lv_free + CHANGING ct_stock = lt_stock ). + ENDIF. + + APPEND ls_result TO rt_result. + ENDLOOP. + ENDMETHOD. + + METHOD {{p}}if_stock_cover~shortages. + rt_shortage = it_result. + DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short. + SORT rt_shortage BY material plant. + ENDMETHOD. + + METHOD aggregate. + LOOP AT it_stock INTO DATA(ls_stock). + IF ls_stock-quantity < 0. + CONTINUE. + ENDIF. + DATA(lv_material) = normalize_material( ls_stock-material ). + DATA(lv_plant) = normalize_plant( ls_stock-plant ). + ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining + ls_stock-quantity. + ELSE. + INSERT VALUE #( material = lv_material + plant = lv_plant + remaining = ls_stock-quantity ) INTO TABLE rt_stock. + ENDIF. + ENDLOOP. + ENDMETHOD. + + METHOD free_quantity. + ASSIGN it_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + rv_quantity = -remaining. + ENDIF. + ENDMETHOD. + + METHOD consume. + ASSIGN ct_stock[ material = normalize_material( iv_material ) + plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(). + IF sy-subrc = 0. + -remaining = -remaining + iv_quantity. + ENDIF. + ENDMETHOD. + + METHOD normalize_material. + DATA lv_text TYPE string. + lv_text = iv_material. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_material = to_upper( lv_text ). + ENDMETHOD. + + METHOD normalize_plant. + DATA lv_text TYPE string. + lv_text = iv_plant. + REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``. + rv_plant = to_upper( lv_text ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0010/mutation.json b/tasks_gen/eval/G0010/mutation.json new file mode 100644 index 0000000..9780f2f --- /dev/null +++ b/tasks_gen/eval/G0010/mutation.json @@ -0,0 +1,68 @@ +{ + "task": "G0010", + "mutants": [ + { + "object": "{{P}}STOCK_COVER_CHECKER", + "mutant": "line 54: <= -> > (rel)", + "status": "killed", + "hidden": "3/12", + "failed_tests": [ + "ALL_OK", + "CASE_AND_BLANKS_IGNORED", + "MISSING_STOCK_IS_SHORT", + "NEGATIVE_REQ_INVALID", + "NEGATIVE_STOCK_IGNORED", + "SHORTAGE_IS_REPORTED", + "STOCK_ITEMS_ARE_SUMMED", + "STOCK_USED_IN_ORDER", + "ZERO_REQUIREMENT_INVALID" + ] + }, + { + "object": "{{P}}STOCK_COVER_CHECKER", + "mutant": "line 77: <> -> = (rel)", + "status": "killed", + "hidden": "10/12", + "failed_tests": [ + "SHORTAGES_EMPTY_ALL_OK", + "SHORTAGES_FILTER_SORT" + ] + }, + { + "object": "{{P}}STOCK_COVER_CHECKER", + "mutant": "line 83: < -> >= (rel)", + "status": "killed", + "hidden": "4/12", + "failed_tests": [ + "ALL_OK", + "CASE_AND_BLANKS_IGNORED", + "NEGATIVE_REQ_INVALID", + "NEGATIVE_STOCK_IGNORED", + "SHORTAGE_IS_REPORTED", + "STOCK_ITEMS_ARE_SUMMED", + "STOCK_USED_IN_ORDER", + "ZERO_REQUIREMENT_INVALID" + ] + }, + { + "object": "{{P}}STOCK_COVER_CHECKER", + "mutant": "line 89: = -> <> (eq)", + "status": "invalid", + "hidden": "0/0", + "failed_tests": [] + }, + { + "object": "{{P}}STOCK_COVER_CHECKER", + "mutant": "line 111: - -> + (arith)", + "status": "killed", + "hidden": "11/12", + "failed_tests": [ + "STOCK_USED_IN_ORDER" + ] + } + ], + "valid": 4, + "killed": 4, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0012/faulty/m0_prd_scrap.func.abap b/tasks_gen/eval/G0012/faulty/m0_prd_scrap.func.abap new file mode 100644 index 0000000..a04f6b5 --- /dev/null +++ b/tasks_gen/eval/G0012/faulty/m0_prd_scrap.func.abap @@ -0,0 +1,41 @@ +FUNCTION {{p}}prd_scrap + IMPORTING + iv_quantity TYPE decfloat34 + iv_scrap TYPE decfloat34 + EXPORTING + ev_scrap_pct TYPE decfloat34 + ev_severity TYPE string + CHANGING + cv_rework_qty TYPE decfloat34 + EXCEPTIONS + invalid_quantity + scrap_too_high. + + IF iv_quantity <= 0 OR iv_scrap < 0. + RAISE invalid_quantity. + ENDIF. + + IF iv_scrap <= iv_quantity. + RAISE scrap_too_high. + ENDIF. + + ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100 + dec = 1 + mode = cl_abap_math=>round_half_up ). + + IF ev_scrap_pct = 0. + ev_severity = 'OK'. + ELSEIF ev_scrap_pct <= 5. + ev_severity = 'LOW'. + ELSEIF ev_scrap_pct <= 20. + ev_severity = 'HIGH'. + ELSE. + ev_severity = 'CRITICAL'. + ENDIF. + + CASE ev_severity. + WHEN 'HIGH' OR 'CRITICAL'. + cv_rework_qty = iv_scrap. + ENDCASE. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0012/faulty/m1_prd_scrap.func.abap b/tasks_gen/eval/G0012/faulty/m1_prd_scrap.func.abap new file mode 100644 index 0000000..a059355 --- /dev/null +++ b/tasks_gen/eval/G0012/faulty/m1_prd_scrap.func.abap @@ -0,0 +1,41 @@ +FUNCTION {{p}}prd_scrap + IMPORTING + iv_quantity TYPE decfloat34 + iv_scrap TYPE decfloat34 + EXPORTING + ev_scrap_pct TYPE decfloat34 + ev_severity TYPE string + CHANGING + cv_rework_qty TYPE decfloat34 + EXCEPTIONS + invalid_quantity + scrap_too_high. + + IF iv_quantity <= 0 OR iv_scrap < 0. + RAISE invalid_quantity. + ENDIF. + + IF iv_scrap > iv_quantity. + RAISE scrap_too_high. + ENDIF. + + ev_scrap_pct = round( val = iv_scrap / iv_quantity / 100 + dec = 1 + mode = cl_abap_math=>round_half_up ). + + IF ev_scrap_pct = 0. + ev_severity = 'OK'. + ELSEIF ev_scrap_pct <= 5. + ev_severity = 'LOW'. + ELSEIF ev_scrap_pct <= 20. + ev_severity = 'HIGH'. + ELSE. + ev_severity = 'CRITICAL'. + ENDIF. + + CASE ev_severity. + WHEN 'HIGH' OR 'CRITICAL'. + cv_rework_qty = iv_scrap. + ENDCASE. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0012/faulty/m2_prd_scrap.func.abap b/tasks_gen/eval/G0012/faulty/m2_prd_scrap.func.abap new file mode 100644 index 0000000..73c5c48 --- /dev/null +++ b/tasks_gen/eval/G0012/faulty/m2_prd_scrap.func.abap @@ -0,0 +1,41 @@ +FUNCTION {{p}}prd_scrap + IMPORTING + iv_quantity TYPE decfloat34 + iv_scrap TYPE decfloat34 + EXPORTING + ev_scrap_pct TYPE decfloat34 + ev_severity TYPE string + CHANGING + cv_rework_qty TYPE decfloat34 + EXCEPTIONS + invalid_quantity + scrap_too_high. + + IF iv_quantity <= 0 OR iv_scrap < 0. + RAISE invalid_quantity. + ENDIF. + + IF iv_scrap > iv_quantity. + RAISE scrap_too_high. + ENDIF. + + ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100 + dec = 2 + mode = cl_abap_math=>round_half_up ). + + IF ev_scrap_pct = 0. + ev_severity = 'OK'. + ELSEIF ev_scrap_pct <= 5. + ev_severity = 'LOW'. + ELSEIF ev_scrap_pct <= 20. + ev_severity = 'HIGH'. + ELSE. + ev_severity = 'CRITICAL'. + ENDIF. + + CASE ev_severity. + WHEN 'HIGH' OR 'CRITICAL'. + cv_rework_qty = iv_scrap. + ENDCASE. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0012/faulty/m3_prd_scrap.func.abap b/tasks_gen/eval/G0012/faulty/m3_prd_scrap.func.abap new file mode 100644 index 0000000..8405002 --- /dev/null +++ b/tasks_gen/eval/G0012/faulty/m3_prd_scrap.func.abap @@ -0,0 +1,41 @@ +FUNCTION {{p}}prd_scrap + IMPORTING + iv_quantity TYPE decfloat34 + iv_scrap TYPE decfloat34 + EXPORTING + ev_scrap_pct TYPE decfloat34 + ev_severity TYPE string + CHANGING + cv_rework_qty TYPE decfloat34 + EXCEPTIONS + invalid_quantity + scrap_too_high. + + IF iv_quantity <= 0 OR iv_scrap < 0. + RAISE invalid_quantity. + ENDIF. + + IF iv_scrap > iv_quantity. + RAISE scrap_too_high. + ENDIF. + + ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100 + dec = 1 + mode = cl_abap_math=>round_half_up ). + + IF ev_scrap_pct <> 0. + ev_severity = 'OK'. + ELSEIF ev_scrap_pct <= 5. + ev_severity = 'LOW'. + ELSEIF ev_scrap_pct <= 20. + ev_severity = 'HIGH'. + ELSE. + ev_severity = 'CRITICAL'. + ENDIF. + + CASE ev_severity. + WHEN 'HIGH' OR 'CRITICAL'. + cv_rework_qty = iv_scrap. + ENDCASE. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0012/mutation.json b/tasks_gen/eval/G0012/mutation.json new file mode 100644 index 0000000..b4300de --- /dev/null +++ b/tasks_gen/eval/G0012/mutation.json @@ -0,0 +1,73 @@ +{ + "task": "G0012", + "mutants": [ + { + "object": "{{P}}PRD_SCRAP", + "mutant": "line 18: > -> <= (rel)", + "status": "killed", + "hidden": "2/11", + "failed_tests": [ + "CRITICAL_ABOVE_TWENTY", + "HIGH_LOWER_BOUNDARY", + "HIGH_UPPER_BOUNDARY", + "LOW_UPPER_BOUNDARY", + "PERCENT_ROUNDS_HALF_UP", + "REWORK_SET_FOR_HIGH", + "REWORK_UNCHANGED_FOR_LOW", + "SCRAP_ABOVE_QUANTITY_RAISES", + "ZERO_SCRAP_IS_OK" + ] + }, + { + "object": "{{P}}PRD_SCRAP", + "mutant": "line 22: * -> / (arith)", + "status": "killed", + "hidden": "4/11", + "failed_tests": [ + "CRITICAL_ABOVE_TWENTY", + "HIGH_LOWER_BOUNDARY", + "HIGH_UPPER_BOUNDARY", + "LOW_UPPER_BOUNDARY", + "PERCENT_ROUNDS_HALF_UP", + "REWORK_SET_FOR_HIGH", + "REWORK_UNCHANGED_FOR_LOW" + ] + }, + { + "object": "{{P}}PRD_SCRAP", + "mutant": "line 23: 1 -> 2 (const)", + "status": "killed", + "hidden": "10/11", + "failed_tests": [ + "PERCENT_ROUNDS_HALF_UP" + ] + }, + { + "object": "{{P}}PRD_SCRAP", + "mutant": "line 26: = -> <> (eq)", + "status": "killed", + "hidden": "3/11", + "failed_tests": [ + "CRITICAL_ABOVE_TWENTY", + "HIGH_LOWER_BOUNDARY", + "HIGH_UPPER_BOUNDARY", + "LOW_UPPER_BOUNDARY", + "PERCENT_ROUNDS_HALF_UP", + "REWORK_SET_FOR_HIGH", + "REWORK_UNCHANGED_FOR_LOW", + "ZERO_SCRAP_IS_OK" + ] + }, + { + "object": "{{P}}PRD_SCRAP", + "mutant": "line 37: OR -> AND (logic)", + "status": "invalid", + "hidden": "0/0", + "failed_tests": [] + } + ], + "valid": 4, + "killed": 4, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0013/faulty/m0_repl_qty.func.abap b/tasks_gen/eval/G0013/faulty/m0_repl_qty.func.abap new file mode 100644 index 0000000..2bb8585 --- /dev/null +++ b/tasks_gen/eval/G0013/faulty/m0_repl_qty.func.abap @@ -0,0 +1,38 @@ +FUNCTION {{p}}repl_qty + IMPORTING + iv_stock TYPE decfloat34 + iv_safety TYPE decfloat34 + iv_lot_size TYPE decfloat34 + iv_min_order TYPE decfloat34 + EXPORTING + ev_order_qty TYPE decfloat34 + ev_action TYPE string + EXCEPTIONS + invalid_input. + + IF iv_lot_size >= 0 OR iv_min_order < 0. + RAISE invalid_input. + ENDIF. + + DATA lv_required TYPE decfloat34. + lv_required = iv_safety - iv_stock. + + IF lv_required <= 0. + ev_order_qty = 0. + ev_action = 'NONE'. + RETURN. + ENDIF. + + IF iv_lot_size > 0. + ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size. + ELSE. + ev_order_qty = lv_required. + ENDIF. + + IF ev_order_qty < iv_min_order. + ev_order_qty = iv_min_order. + ENDIF. + + ev_action = 'ORDER'. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0013/faulty/m1_repl_qty.func.abap b/tasks_gen/eval/G0013/faulty/m1_repl_qty.func.abap new file mode 100644 index 0000000..09b85ed --- /dev/null +++ b/tasks_gen/eval/G0013/faulty/m1_repl_qty.func.abap @@ -0,0 +1,38 @@ +FUNCTION {{p}}repl_qty + IMPORTING + iv_stock TYPE decfloat34 + iv_safety TYPE decfloat34 + iv_lot_size TYPE decfloat34 + iv_min_order TYPE decfloat34 + EXPORTING + ev_order_qty TYPE decfloat34 + ev_action TYPE string + EXCEPTIONS + invalid_input. + + IF iv_lot_size < 0 AND iv_min_order < 0. + RAISE invalid_input. + ENDIF. + + DATA lv_required TYPE decfloat34. + lv_required = iv_safety - iv_stock. + + IF lv_required <= 0. + ev_order_qty = 0. + ev_action = 'NONE'. + RETURN. + ENDIF. + + IF iv_lot_size > 0. + ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size. + ELSE. + ev_order_qty = lv_required. + ENDIF. + + IF ev_order_qty < iv_min_order. + ev_order_qty = iv_min_order. + ENDIF. + + ev_action = 'ORDER'. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0013/faulty/m2_repl_qty.func.abap b/tasks_gen/eval/G0013/faulty/m2_repl_qty.func.abap new file mode 100644 index 0000000..6083bfc --- /dev/null +++ b/tasks_gen/eval/G0013/faulty/m2_repl_qty.func.abap @@ -0,0 +1,38 @@ +FUNCTION {{p}}repl_qty + IMPORTING + iv_stock TYPE decfloat34 + iv_safety TYPE decfloat34 + iv_lot_size TYPE decfloat34 + iv_min_order TYPE decfloat34 + EXPORTING + ev_order_qty TYPE decfloat34 + ev_action TYPE string + EXCEPTIONS + invalid_input. + + IF iv_lot_size < 0 OR iv_min_order < 0. + RAISE invalid_input. + ENDIF. + + DATA lv_required TYPE decfloat34. + lv_required = iv_safety - iv_stock. + + IF lv_required <= 0. + ev_order_qty = 0. + ev_action = 'NONE'. + RETURN. + ENDIF. + + IF iv_lot_size <= 0. + ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size. + ELSE. + ev_order_qty = lv_required. + ENDIF. + + IF ev_order_qty < iv_min_order. + ev_order_qty = iv_min_order. + ENDIF. + + ev_action = 'ORDER'. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0013/faulty/m3_repl_qty.func.abap b/tasks_gen/eval/G0013/faulty/m3_repl_qty.func.abap new file mode 100644 index 0000000..95da713 --- /dev/null +++ b/tasks_gen/eval/G0013/faulty/m3_repl_qty.func.abap @@ -0,0 +1,38 @@ +FUNCTION {{p}}repl_qty + IMPORTING + iv_stock TYPE decfloat34 + iv_safety TYPE decfloat34 + iv_lot_size TYPE decfloat34 + iv_min_order TYPE decfloat34 + EXPORTING + ev_order_qty TYPE decfloat34 + ev_action TYPE string + EXCEPTIONS + invalid_input. + + IF iv_lot_size < 0 OR iv_min_order < 0. + RAISE invalid_input. + ENDIF. + + DATA lv_required TYPE decfloat34. + lv_required = iv_safety - iv_stock. + + IF lv_required <= 0. + ev_order_qty = 0. + ev_action = 'NONE'. + RETURN. + ENDIF. + + IF iv_lot_size > 0. + ev_order_qty = ceil( lv_required / iv_lot_size ) / iv_lot_size. + ELSE. + ev_order_qty = lv_required. + ENDIF. + + IF ev_order_qty < iv_min_order. + ev_order_qty = iv_min_order. + ENDIF. + + ev_action = 'ORDER'. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0013/faulty/m4_repl_qty.func.abap b/tasks_gen/eval/G0013/faulty/m4_repl_qty.func.abap new file mode 100644 index 0000000..87386d1 --- /dev/null +++ b/tasks_gen/eval/G0013/faulty/m4_repl_qty.func.abap @@ -0,0 +1,38 @@ +FUNCTION {{p}}repl_qty + IMPORTING + iv_stock TYPE decfloat34 + iv_safety TYPE decfloat34 + iv_lot_size TYPE decfloat34 + iv_min_order TYPE decfloat34 + EXPORTING + ev_order_qty TYPE decfloat34 + ev_action TYPE string + EXCEPTIONS + invalid_input. + + IF iv_lot_size < 0 OR iv_min_order < 0. + RAISE invalid_input. + ENDIF. + + DATA lv_required TYPE decfloat34. + lv_required = iv_safety - iv_stock. + + IF lv_required <= 0. + ev_order_qty = 0. + ev_action = 'NONE'. + RETURN. + ENDIF. + + IF iv_lot_size > 0. + ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size. + ELSE. + ev_order_qty = lv_required. + ENDIF. + + IF ev_order_qty >= iv_min_order. + ev_order_qty = iv_min_order. + ENDIF. + + ev_action = 'ORDER'. + +ENDFUNCTION. diff --git a/tasks_gen/eval/G0013/mutation.json b/tasks_gen/eval/G0013/mutation.json new file mode 100644 index 0000000..b81fa36 --- /dev/null +++ b/tasks_gen/eval/G0013/mutation.json @@ -0,0 +1,75 @@ +{ + "task": "G0013", + "mutants": [ + { + "object": "{{P}}REPL_QTY", + "mutant": "line 13: < -> >= (rel)", + "status": "killed", + "hidden": "1/11", + "failed_tests": [ + "EXACT_MULTIPLE_LOT", + "EXACT_MULTIPLE_SINGLE_LOT", + "EXACT_MULTIPLE_WITH_MINIMUM", + "MINIMUM_ORDER_APPLIES", + "MINIMUM_ORDER_KEEPS_QUANTITY", + "NEGATIVE_LOT_SIZE", + "NO_LOT_SIZE_NO_ROUNDING", + "PARTIAL_LOT_ROUNDS_UP", + "STOCK_ABOVE_SAFETY", + "STOCK_EQUALS_SAFETY" + ] + }, + { + "object": "{{P}}REPL_QTY", + "mutant": "line 13: OR -> AND (logic)", + "status": "killed", + "hidden": "9/11", + "failed_tests": [ + "NEGATIVE_LOT_SIZE", + "NEGATIVE_MIN_ORDER" + ] + }, + { + "object": "{{P}}REPL_QTY", + "mutant": "line 26: > -> <= (rel)", + "status": "killed", + "hidden": "7/11", + "failed_tests": [ + "MINIMUM_ORDER_APPLIES", + "MINIMUM_ORDER_KEEPS_QUANTITY", + "NO_LOT_SIZE_NO_ROUNDING", + "PARTIAL_LOT_ROUNDS_UP" + ] + }, + { + "object": "{{P}}REPL_QTY", + "mutant": "line 27: * -> / (arith)", + "status": "killed", + "hidden": "8/11", + "failed_tests": [ + "EXACT_MULTIPLE_LOT", + "EXACT_MULTIPLE_SINGLE_LOT", + "PARTIAL_LOT_ROUNDS_UP" + ] + }, + { + "object": "{{P}}REPL_QTY", + "mutant": "line 32: < -> >= (rel)", + "status": "killed", + "hidden": "4/11", + "failed_tests": [ + "EXACT_MULTIPLE_LOT", + "EXACT_MULTIPLE_SINGLE_LOT", + "EXACT_MULTIPLE_WITH_MINIMUM", + "MINIMUM_ORDER_APPLIES", + "MINIMUM_ORDER_KEEPS_QUANTITY", + "NO_LOT_SIZE_NO_ROUNDING", + "PARTIAL_LOT_ROUNDS_UP" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0014/faulty/m0_stock_bal.prog.abap b/tasks_gen/eval/G0014/faulty/m0_stock_bal.prog.abap new file mode 100644 index 0000000..03ed088 --- /dev/null +++ b/tasks_gen/eval/G0014/faulty/m0_stock_bal.prog.abap @@ -0,0 +1,127 @@ +REPORT {{p}}stock_bal. + +DATA gv_plant TYPE {{p}}movmt-plant. + +PARAMETERS p_from TYPE d OBLIGATORY. +PARAMETERS p_to TYPE d OBLIGATORY. +SELECT-OPTIONS s_plant FOR gv_plant. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + material TYPE {{p}}movmt-material, + receipt_qty TYPE i, + issue_qty TYPE i, + balance TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_plant TYPE RANGE OF {{p}}movmt-plant. + METHODS select_balances + IMPORTING iv_from TYPE d + iv_to TYPE d + it_plant TYPE tt_plant + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_balances. + SELECT material, + SUM( CASE WHEN move_type = '101' OR move_type = '201' + THEN quantity + ELSE 0 END ) AS receipt_qty, + SUM( CASE WHEN move_type = '261' OR move_type = '262' + THEN quantity + ELSE 0 END ) AS issue_qty + FROM {{p}}movmt + WHERE move_date < @iv_from + AND move_date <= @iv_to + AND plant IN @it_plant + AND move_type IN ( '101', '201', '261', '262' ) + GROUP BY material + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + + LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(). + -balance = -receipt_qty - -issue_qty. + ENDLOOP. + + SORT rt_lines BY balance DESCENDING. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_balances( iv_from = p_from + iv_to = p_to + it_plant = s_plant[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS balances_per_material FOR TESTING. + METHODS plant_filter FOR TESTING. + METHODS negative_balance FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ). + DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY. + lt_movmt = VALUE #( + ( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 ) + ( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 ) + ( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 ) + ( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 ) + ( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ). + go_env->insert_test_data( lt_movmt ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD balances_per_material. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ). + ENDMETHOD. + + METHOD plant_filter. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ). + ENDMETHOD. + + METHOD negative_balance. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0014/faulty/m1_stock_bal.prog.abap b/tasks_gen/eval/G0014/faulty/m1_stock_bal.prog.abap new file mode 100644 index 0000000..cd5b41d --- /dev/null +++ b/tasks_gen/eval/G0014/faulty/m1_stock_bal.prog.abap @@ -0,0 +1,127 @@ +REPORT {{p}}stock_bal. + +DATA gv_plant TYPE {{p}}movmt-plant. + +PARAMETERS p_from TYPE d OBLIGATORY. +PARAMETERS p_to TYPE d OBLIGATORY. +SELECT-OPTIONS s_plant FOR gv_plant. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + material TYPE {{p}}movmt-material, + receipt_qty TYPE i, + issue_qty TYPE i, + balance TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_plant TYPE RANGE OF {{p}}movmt-plant. + METHODS select_balances + IMPORTING iv_from TYPE d + iv_to TYPE d + it_plant TYPE tt_plant + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_balances. + SELECT material, + SUM( CASE WHEN move_type = '101' OR move_type = '201' + THEN quantity + ELSE 0 END ) AS receipt_qty, + SUM( CASE WHEN move_type = '261' OR move_type = '262' + THEN quantity + ELSE 0 END ) AS issue_qty + FROM {{p}}movmt + WHERE move_date >= @iv_from + OR move_date <= @iv_to + AND plant IN @it_plant + AND move_type IN ( '101', '201', '261', '262' ) + GROUP BY material + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + + LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(). + -balance = -receipt_qty - -issue_qty. + ENDLOOP. + + SORT rt_lines BY balance DESCENDING. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_balances( iv_from = p_from + iv_to = p_to + it_plant = s_plant[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS balances_per_material FOR TESTING. + METHODS plant_filter FOR TESTING. + METHODS negative_balance FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ). + DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY. + lt_movmt = VALUE #( + ( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 ) + ( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 ) + ( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 ) + ( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 ) + ( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ). + go_env->insert_test_data( lt_movmt ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD balances_per_material. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ). + ENDMETHOD. + + METHOD plant_filter. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ). + ENDMETHOD. + + METHOD negative_balance. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0014/faulty/m2_stock_bal.prog.abap b/tasks_gen/eval/G0014/faulty/m2_stock_bal.prog.abap new file mode 100644 index 0000000..b615e44 --- /dev/null +++ b/tasks_gen/eval/G0014/faulty/m2_stock_bal.prog.abap @@ -0,0 +1,127 @@ +REPORT {{p}}stock_bal. + +DATA gv_plant TYPE {{p}}movmt-plant. + +PARAMETERS p_from TYPE d OBLIGATORY. +PARAMETERS p_to TYPE d OBLIGATORY. +SELECT-OPTIONS s_plant FOR gv_plant. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + material TYPE {{p}}movmt-material, + receipt_qty TYPE i, + issue_qty TYPE i, + balance TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_plant TYPE RANGE OF {{p}}movmt-plant. + METHODS select_balances + IMPORTING iv_from TYPE d + iv_to TYPE d + it_plant TYPE tt_plant + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_balances. + SELECT material, + SUM( CASE WHEN move_type = '101' OR move_type = '201' + THEN quantity + ELSE 0 END ) AS receipt_qty, + SUM( CASE WHEN move_type = '261' OR move_type = '262' + THEN quantity + ELSE 0 END ) AS issue_qty + FROM {{p}}movmt + WHERE move_date >= @iv_from + AND move_date > @iv_to + AND plant IN @it_plant + AND move_type IN ( '101', '201', '261', '262' ) + GROUP BY material + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + + LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(). + -balance = -receipt_qty - -issue_qty. + ENDLOOP. + + SORT rt_lines BY balance DESCENDING. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_balances( iv_from = p_from + iv_to = p_to + it_plant = s_plant[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS balances_per_material FOR TESTING. + METHODS plant_filter FOR TESTING. + METHODS negative_balance FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ). + DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY. + lt_movmt = VALUE #( + ( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 ) + ( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 ) + ( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 ) + ( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 ) + ( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ). + go_env->insert_test_data( lt_movmt ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD balances_per_material. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ). + ENDMETHOD. + + METHOD plant_filter. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ). + ENDMETHOD. + + METHOD negative_balance. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0014/faulty/m3_stock_bal.prog.abap b/tasks_gen/eval/G0014/faulty/m3_stock_bal.prog.abap new file mode 100644 index 0000000..555558a --- /dev/null +++ b/tasks_gen/eval/G0014/faulty/m3_stock_bal.prog.abap @@ -0,0 +1,127 @@ +REPORT {{p}}stock_bal. + +DATA gv_plant TYPE {{p}}movmt-plant. + +PARAMETERS p_from TYPE d OBLIGATORY. +PARAMETERS p_to TYPE d OBLIGATORY. +SELECT-OPTIONS s_plant FOR gv_plant. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + material TYPE {{p}}movmt-material, + receipt_qty TYPE i, + issue_qty TYPE i, + balance TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_plant TYPE RANGE OF {{p}}movmt-plant. + METHODS select_balances + IMPORTING iv_from TYPE d + iv_to TYPE d + it_plant TYPE tt_plant + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_balances. + SELECT material, + SUM( CASE WHEN move_type = '101' OR move_type = '201' + THEN quantity + ELSE 0 END ) AS receipt_qty, + SUM( CASE WHEN move_type = '261' OR move_type = '262' + THEN quantity + ELSE 0 END ) AS issue_qty + FROM {{p}}movmt + WHERE move_date >= @iv_from + AND move_date <= @iv_to + AND plant IN @it_plant + OR move_type IN ( '101', '201', '261', '262' ) + GROUP BY material + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + + LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(). + -balance = -receipt_qty - -issue_qty. + ENDLOOP. + + SORT rt_lines BY balance DESCENDING. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_balances( iv_from = p_from + iv_to = p_to + it_plant = s_plant[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS balances_per_material FOR TESTING. + METHODS plant_filter FOR TESTING. + METHODS negative_balance FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ). + DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY. + lt_movmt = VALUE #( + ( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 ) + ( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 ) + ( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 ) + ( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 ) + ( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ). + go_env->insert_test_data( lt_movmt ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD balances_per_material. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ). + ENDMETHOD. + + METHOD plant_filter. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ). + ENDMETHOD. + + METHOD negative_balance. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0014/faulty/m4_stock_bal.prog.abap b/tasks_gen/eval/G0014/faulty/m4_stock_bal.prog.abap new file mode 100644 index 0000000..20ba79a --- /dev/null +++ b/tasks_gen/eval/G0014/faulty/m4_stock_bal.prog.abap @@ -0,0 +1,127 @@ +REPORT {{p}}stock_bal. + +DATA gv_plant TYPE {{p}}movmt-plant. + +PARAMETERS p_from TYPE d OBLIGATORY. +PARAMETERS p_to TYPE d OBLIGATORY. +SELECT-OPTIONS s_plant FOR gv_plant. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + material TYPE {{p}}movmt-material, + receipt_qty TYPE i, + issue_qty TYPE i, + balance TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_plant TYPE RANGE OF {{p}}movmt-plant. + METHODS select_balances + IMPORTING iv_from TYPE d + iv_to TYPE d + it_plant TYPE tt_plant + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_balances. + SELECT material, + SUM( CASE WHEN move_type = '101' OR move_type = '201' + THEN quantity + ELSE 0 END ) AS receipt_qty, + SUM( CASE WHEN move_type = '261' OR move_type = '262' + THEN quantity + ELSE 0 END ) AS issue_qty + FROM {{p}}movmt + WHERE move_date >= @iv_from + AND move_date <= @iv_to + AND plant IN @it_plant + AND move_type IN ( '101', '201', '261', '262' ) + GROUP BY material + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + + LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(). + -balance = -receipt_qty + -issue_qty. + ENDLOOP. + + SORT rt_lines BY balance DESCENDING. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_balances( iv_from = p_from + iv_to = p_to + it_plant = s_plant[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS balances_per_material FOR TESTING. + METHODS plant_filter FOR TESTING. + METHODS negative_balance FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ). + DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY. + lt_movmt = VALUE #( + ( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 ) + ( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 ) + ( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 ) + ( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 ) + ( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ). + go_env->insert_test_data( lt_movmt ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD balances_per_material. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ). + ENDMETHOD. + + METHOD plant_filter. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ). + ENDMETHOD. + + METHOD negative_balance. + DATA(lt_lines) = NEW lcl_report( )->select_balances( + iv_from = '20260101' + iv_to = '20260131' + it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ). + cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0014/mutation.json b/tasks_gen/eval/G0014/mutation.json new file mode 100644 index 0000000..ed1130a --- /dev/null +++ b/tasks_gen/eval/G0014/mutation.json @@ -0,0 +1,76 @@ +{ + "task": "G0014", + "mutants": [ + { + "object": "{{P}}STOCK_BAL", + "mutant": "line 39: >= -> < (rel)", + "status": "killed", + "hidden": "0/6", + "failed_tests": [ + "ALL_MATERIALS_IN_RANGE", + "DATE_RANGE_FILTER", + "IGNORED_MOVE_TYPES", + "PLANT_FILTER", + "RECEIPT_AND_ISSUE_SPLIT", + "SORTED_BY_BALANCE" + ] + }, + { + "object": "{{P}}STOCK_BAL", + "mutant": "line 40: AND -> OR (logic)", + "status": "killed", + "hidden": "0/6", + "failed_tests": [ + "ALL_MATERIALS_IN_RANGE", + "DATE_RANGE_FILTER", + "IGNORED_MOVE_TYPES", + "PLANT_FILTER", + "RECEIPT_AND_ISSUE_SPLIT", + "SORTED_BY_BALANCE" + ] + }, + { + "object": "{{P}}STOCK_BAL", + "mutant": "line 40: <= -> > (rel)", + "status": "killed", + "hidden": "0/6", + "failed_tests": [ + "ALL_MATERIALS_IN_RANGE", + "DATE_RANGE_FILTER", + "IGNORED_MOVE_TYPES", + "PLANT_FILTER", + "RECEIPT_AND_ISSUE_SPLIT", + "SORTED_BY_BALANCE" + ] + }, + { + "object": "{{P}}STOCK_BAL", + "mutant": "line 42: AND -> OR (logic)", + "status": "killed", + "hidden": "0/6", + "failed_tests": [ + "ALL_MATERIALS_IN_RANGE", + "DATE_RANGE_FILTER", + "IGNORED_MOVE_TYPES", + "PLANT_FILTER", + "RECEIPT_AND_ISSUE_SPLIT", + "SORTED_BY_BALANCE" + ] + }, + { + "object": "{{P}}STOCK_BAL", + "mutant": "line 47: - -> + (arith)", + "status": "killed", + "hidden": "3/6", + "failed_tests": [ + "ALL_MATERIALS_IN_RANGE", + "PLANT_FILTER", + "SORTED_BY_BALANCE" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0015/faulty/m0_bill_age.prog.abap b/tasks_gen/eval/G0015/faulty/m0_bill_age.prog.abap new file mode 100644 index 0000000..81ad1f6 --- /dev/null +++ b/tasks_gen/eval/G0015/faulty/m0_bill_age.prog.abap @@ -0,0 +1,95 @@ +REPORT {{p}}bill_age. + +DATA gv_customer TYPE {{p}}bill-customer. + +PARAMETERS p_date TYPE d OBLIGATORY. +SELECT-OPTIONS s_cust FOR gv_customer. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + customer TYPE {{p}}bill-customer, + open_count TYPE i, + open_amount TYPE {{p}}bill-amount, + overdue_amount TYPE {{p}}bill-amount, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_customer TYPE RANGE OF {{p}}bill-customer. + METHODS select_open_items + IMPORTING iv_date TYPE d + it_customer TYPE tt_customer + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_open_items. + SELECT customer, + COUNT( * ) AS open_count, + SUM( amount ) AS open_amount, + SUM( CASE WHEN due_date >= @iv_date THEN amount ELSE 0 END ) AS overdue_amount + FROM {{p}}bill + WHERE paid <> 'X' + AND customer IN @it_customer + GROUP BY customer + ORDER BY open_amount DESCENDING + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS open_invoices_only FOR TESTING. + METHODS overdue_amount FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ). + DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY. + lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' ) + ( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' ) + ( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ). + go_env->insert_test_data( lt_bill ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD open_invoices_only. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ). + ENDMETHOD. + + METHOD overdue_amount. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 ) + act = lt_lines[ 1 ]-overdue_amount ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0015/faulty/m1_bill_age.prog.abap b/tasks_gen/eval/G0015/faulty/m1_bill_age.prog.abap new file mode 100644 index 0000000..f79c20b --- /dev/null +++ b/tasks_gen/eval/G0015/faulty/m1_bill_age.prog.abap @@ -0,0 +1,95 @@ +REPORT {{p}}bill_age. + +DATA gv_customer TYPE {{p}}bill-customer. + +PARAMETERS p_date TYPE d OBLIGATORY. +SELECT-OPTIONS s_cust FOR gv_customer. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + customer TYPE {{p}}bill-customer, + open_count TYPE i, + open_amount TYPE {{p}}bill-amount, + overdue_amount TYPE {{p}}bill-amount, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_customer TYPE RANGE OF {{p}}bill-customer. + METHODS select_open_items + IMPORTING iv_date TYPE d + it_customer TYPE tt_customer + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_open_items. + SELECT customer, + COUNT( * ) AS open_count, + SUM( amount ) AS open_amount, + SUM( CASE WHEN due_date < @iv_date THEN amount ELSE 0 END ) AS overdue_amount + FROM {{p}}bill + WHERE paid = 'X' + AND customer IN @it_customer + GROUP BY customer + ORDER BY open_amount DESCENDING + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS open_invoices_only FOR TESTING. + METHODS overdue_amount FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ). + DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY. + lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' ) + ( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' ) + ( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ). + go_env->insert_test_data( lt_bill ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD open_invoices_only. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ). + ENDMETHOD. + + METHOD overdue_amount. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 ) + act = lt_lines[ 1 ]-overdue_amount ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0015/faulty/m2_bill_age.prog.abap b/tasks_gen/eval/G0015/faulty/m2_bill_age.prog.abap new file mode 100644 index 0000000..3bbdbea --- /dev/null +++ b/tasks_gen/eval/G0015/faulty/m2_bill_age.prog.abap @@ -0,0 +1,95 @@ +REPORT {{p}}bill_age. + +DATA gv_customer TYPE {{p}}bill-customer. + +PARAMETERS p_date TYPE d OBLIGATORY. +SELECT-OPTIONS s_cust FOR gv_customer. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + TYPES: + BEGIN OF ty_line, + customer TYPE {{p}}bill-customer, + open_count TYPE i, + open_amount TYPE {{p}}bill-amount, + overdue_amount TYPE {{p}}bill-amount, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_customer TYPE RANGE OF {{p}}bill-customer. + METHODS select_open_items + IMPORTING iv_date TYPE d + it_customer TYPE tt_customer + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_open_items. + SELECT customer, + COUNT( * ) AS open_count, + SUM( amount ) AS open_amount, + SUM( CASE WHEN due_date < @iv_date THEN amount ELSE 0 END ) AS overdue_amount + FROM {{p}}bill + WHERE paid <> 'X' + OR customer IN @it_customer + GROUP BY customer + ORDER BY open_amount DESCENDING + INTO CORRESPONDING FIELDS OF TABLE @rt_lines. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_error). + MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS open_invoices_only FOR TESTING. + METHODS overdue_amount FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ). + DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY. + lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' ) + ( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' ) + ( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ). + go_env->insert_test_data( lt_bill ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD open_invoices_only. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ). + ENDMETHOD. + + METHOD overdue_amount. + DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201' + it_customer = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 ) + act = lt_lines[ 1 ]-overdue_amount ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0015/mutation.json b/tasks_gen/eval/G0015/mutation.json new file mode 100644 index 0000000..041e3d0 --- /dev/null +++ b/tasks_gen/eval/G0015/mutation.json @@ -0,0 +1,48 @@ +{ + "task": "G0015", + "mutants": [ + { + "object": "{{P}}BILL_AGE", + "mutant": "line 32: < -> >= (rel)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "NO_OVERDUE_AMOUNT", + "OVERDUE_AMOUNT" + ] + }, + { + "object": "{{P}}BILL_AGE", + "mutant": "line 34: <> -> = (rel)", + "status": "killed", + "hidden": "1/8", + "failed_tests": [ + "COUNT_AND_AMOUNT", + "CUSTOMER_FILTER", + "NO_OVERDUE_AMOUNT", + "ONLY_OPEN_INVOICES", + "OVERDUE_AMOUNT", + "PAID_INVOICES_EXCLUDED", + "SORTED_BY_OPEN_AMOUNT" + ] + }, + { + "object": "{{P}}BILL_AGE", + "mutant": "line 35: AND -> OR (logic)", + "status": "killed", + "hidden": "2/8", + "failed_tests": [ + "COUNT_AND_AMOUNT", + "CUSTOMER_FILTER", + "CUSTOMER_FILTER_MULTIPLE", + "OVERDUE_AMOUNT", + "PAID_INVOICES_EXCLUDED", + "SORTED_BY_OPEN_AMOUNT" + ] + } + ], + "valid": 3, + "killed": 3, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0016/faulty/m0_stock_net.prog.abap b/tasks_gen/eval/G0016/faulty/m0_stock_net.prog.abap new file mode 100644 index 0000000..aa0fb81 --- /dev/null +++ b/tasks_gen/eval/G0016/faulty/m0_stock_net.prog.abap @@ -0,0 +1,132 @@ +REPORT {{p}}stock_net. + +TYPES: BEGIN OF ty_line, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + net_qty TYPE {{p}}move-quantity, + move_count TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant, + tt_matnr TYPE RANGE OF {{p}}move-material. + +DATA gv_matnr TYPE {{p}}move-material. + +PARAMETERS: p_from TYPE d OBLIGATORY, + p_to TYPE d OBLIGATORY. +SELECT-OPTIONS: s_matnr FOR gv_matnr. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + METHODS select_totals + IMPORTING iv_from TYPE d + iv_to TYPE d + it_matnr TYPE tt_matnr + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_totals. + TYPES: BEGIN OF ty_group, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + move_type TYPE {{p}}move-move_type, + qty TYPE {{p}}move-quantity, + cnt TYPE i, + END OF ty_group. + DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY. + + SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt + FROM {{p}}move + WHERE move_date < @iv_from + AND move_date <= @iv_to + AND material IN @it_matnr + GROUP BY material, plant, move_type + INTO CORRESPONDING FIELDS OF TABLE @lt_group. + + DATA lt_acc TYPE tt_acc. + LOOP AT lt_group INTO DATA(ls_group). + READ TABLE lt_acc ASSIGNING FIELD-SYMBOL() + WITH TABLE KEY material = ls_group-material plant = ls_group-plant. + IF sy-subrc <> 0. + INSERT VALUE ty_line( material = ls_group-material + plant = ls_group-plant ) + INTO TABLE lt_acc ASSIGNING . + ENDIF. + IF ls_group-move_type = 'GR'. + -net_qty = -net_qty + ls_group-qty. + ELSE. + -net_qty = -net_qty - ls_group-qty. + ENDIF. + -move_count = -move_count + ls_group-cnt. + ENDLOOP. + rt_lines = lt_acc. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( + IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_msg). + MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_totals( iv_from = p_from + iv_to = p_to + it_matnr = s_matnr[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS net_quantity FOR TESTING. + METHODS material_filter FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ). + DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY. + lt_move = VALUE #( + ( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110' + move_type = 'GR' quantity = '100.000' ) + ( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115' + move_type = 'GI' quantity = '30.000' ) + ( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201' + move_type = 'GR' quantity = '200.000' ) ). + go_env->insert_test_data( lt_move ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD net_quantity. + DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ). + ENDMETHOD. + + METHOD material_filter. + DATA(lt_lines) = NEW lcl_report( )->select_totals( + iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0016/faulty/m1_stock_net.prog.abap b/tasks_gen/eval/G0016/faulty/m1_stock_net.prog.abap new file mode 100644 index 0000000..2514bd7 --- /dev/null +++ b/tasks_gen/eval/G0016/faulty/m1_stock_net.prog.abap @@ -0,0 +1,132 @@ +REPORT {{p}}stock_net. + +TYPES: BEGIN OF ty_line, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + net_qty TYPE {{p}}move-quantity, + move_count TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant, + tt_matnr TYPE RANGE OF {{p}}move-material. + +DATA gv_matnr TYPE {{p}}move-material. + +PARAMETERS: p_from TYPE d OBLIGATORY, + p_to TYPE d OBLIGATORY. +SELECT-OPTIONS: s_matnr FOR gv_matnr. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + METHODS select_totals + IMPORTING iv_from TYPE d + iv_to TYPE d + it_matnr TYPE tt_matnr + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_totals. + TYPES: BEGIN OF ty_group, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + move_type TYPE {{p}}move-move_type, + qty TYPE {{p}}move-quantity, + cnt TYPE i, + END OF ty_group. + DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY. + + SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt + FROM {{p}}move + WHERE move_date >= @iv_from + OR move_date <= @iv_to + AND material IN @it_matnr + GROUP BY material, plant, move_type + INTO CORRESPONDING FIELDS OF TABLE @lt_group. + + DATA lt_acc TYPE tt_acc. + LOOP AT lt_group INTO DATA(ls_group). + READ TABLE lt_acc ASSIGNING FIELD-SYMBOL() + WITH TABLE KEY material = ls_group-material plant = ls_group-plant. + IF sy-subrc <> 0. + INSERT VALUE ty_line( material = ls_group-material + plant = ls_group-plant ) + INTO TABLE lt_acc ASSIGNING . + ENDIF. + IF ls_group-move_type = 'GR'. + -net_qty = -net_qty + ls_group-qty. + ELSE. + -net_qty = -net_qty - ls_group-qty. + ENDIF. + -move_count = -move_count + ls_group-cnt. + ENDLOOP. + rt_lines = lt_acc. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( + IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_msg). + MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_totals( iv_from = p_from + iv_to = p_to + it_matnr = s_matnr[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS net_quantity FOR TESTING. + METHODS material_filter FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ). + DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY. + lt_move = VALUE #( + ( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110' + move_type = 'GR' quantity = '100.000' ) + ( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115' + move_type = 'GI' quantity = '30.000' ) + ( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201' + move_type = 'GR' quantity = '200.000' ) ). + go_env->insert_test_data( lt_move ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD net_quantity. + DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ). + ENDMETHOD. + + METHOD material_filter. + DATA(lt_lines) = NEW lcl_report( )->select_totals( + iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0016/faulty/m3_stock_net.prog.abap b/tasks_gen/eval/G0016/faulty/m3_stock_net.prog.abap new file mode 100644 index 0000000..7ef58af --- /dev/null +++ b/tasks_gen/eval/G0016/faulty/m3_stock_net.prog.abap @@ -0,0 +1,132 @@ +REPORT {{p}}stock_net. + +TYPES: BEGIN OF ty_line, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + net_qty TYPE {{p}}move-quantity, + move_count TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant, + tt_matnr TYPE RANGE OF {{p}}move-material. + +DATA gv_matnr TYPE {{p}}move-material. + +PARAMETERS: p_from TYPE d OBLIGATORY, + p_to TYPE d OBLIGATORY. +SELECT-OPTIONS: s_matnr FOR gv_matnr. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + METHODS select_totals + IMPORTING iv_from TYPE d + iv_to TYPE d + it_matnr TYPE tt_matnr + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_totals. + TYPES: BEGIN OF ty_group, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + move_type TYPE {{p}}move-move_type, + qty TYPE {{p}}move-quantity, + cnt TYPE i, + END OF ty_group. + DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY. + + SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt + FROM {{p}}move + WHERE move_date >= @iv_from + AND move_date <= @iv_to + AND material IN @it_matnr + GROUP BY material, plant, move_type + INTO CORRESPONDING FIELDS OF TABLE @lt_group. + + DATA lt_acc TYPE tt_acc. + LOOP AT lt_group INTO DATA(ls_group). + READ TABLE lt_acc ASSIGNING FIELD-SYMBOL() + WITH TABLE KEY material = ls_group-material plant = ls_group-plant. + IF sy-subrc <> 0. + INSERT VALUE ty_line( material = ls_group-material + plant = ls_group-plant ) + INTO TABLE lt_acc ASSIGNING . + ENDIF. + IF ls_group-move_type <> 'GR'. + -net_qty = -net_qty + ls_group-qty. + ELSE. + -net_qty = -net_qty - ls_group-qty. + ENDIF. + -move_count = -move_count + ls_group-cnt. + ENDLOOP. + rt_lines = lt_acc. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( + IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_msg). + MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_totals( iv_from = p_from + iv_to = p_to + it_matnr = s_matnr[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS net_quantity FOR TESTING. + METHODS material_filter FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ). + DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY. + lt_move = VALUE #( + ( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110' + move_type = 'GR' quantity = '100.000' ) + ( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115' + move_type = 'GI' quantity = '30.000' ) + ( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201' + move_type = 'GR' quantity = '200.000' ) ). + go_env->insert_test_data( lt_move ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD net_quantity. + DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ). + ENDMETHOD. + + METHOD material_filter. + DATA(lt_lines) = NEW lcl_report( )->select_totals( + iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0016/faulty/m4_stock_net.prog.abap b/tasks_gen/eval/G0016/faulty/m4_stock_net.prog.abap new file mode 100644 index 0000000..fc5d7cf --- /dev/null +++ b/tasks_gen/eval/G0016/faulty/m4_stock_net.prog.abap @@ -0,0 +1,132 @@ +REPORT {{p}}stock_net. + +TYPES: BEGIN OF ty_line, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + net_qty TYPE {{p}}move-quantity, + move_count TYPE i, + END OF ty_line, + tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY, + tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant, + tt_matnr TYPE RANGE OF {{p}}move-material. + +DATA gv_matnr TYPE {{p}}move-material. + +PARAMETERS: p_from TYPE d OBLIGATORY, + p_to TYPE d OBLIGATORY. +SELECT-OPTIONS: s_matnr FOR gv_matnr. + +CLASS lcl_report DEFINITION FINAL. + PUBLIC SECTION. + METHODS select_totals + IMPORTING iv_from TYPE d + iv_to TYPE d + it_matnr TYPE tt_matnr + RETURNING VALUE(rt_lines) TYPE tt_line. + METHODS display + CHANGING ct_lines TYPE tt_line. +ENDCLASS. + +CLASS lcl_report IMPLEMENTATION. + METHOD select_totals. + TYPES: BEGIN OF ty_group, + material TYPE {{p}}move-material, + plant TYPE {{p}}move-plant, + move_type TYPE {{p}}move-move_type, + qty TYPE {{p}}move-quantity, + cnt TYPE i, + END OF ty_group. + DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY. + + SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt + FROM {{p}}move + WHERE move_date >= @iv_from + AND move_date <= @iv_to + AND material IN @it_matnr + GROUP BY material, plant, move_type + INTO CORRESPONDING FIELDS OF TABLE @lt_group. + + DATA lt_acc TYPE tt_acc. + LOOP AT lt_group INTO DATA(ls_group). + READ TABLE lt_acc ASSIGNING FIELD-SYMBOL() + WITH TABLE KEY material = ls_group-material plant = ls_group-plant. + IF sy-subrc <> 0. + INSERT VALUE ty_line( material = ls_group-material + plant = ls_group-plant ) + INTO TABLE lt_acc ASSIGNING . + ENDIF. + IF ls_group-move_type = 'GR'. + -net_qty = -net_qty + ls_group-qty. + ELSE. + -net_qty = -net_qty + ls_group-qty. + ENDIF. + -move_count = -move_count + ls_group-cnt. + ENDLOOP. + rt_lines = lt_acc. + ENDMETHOD. + + METHOD display. + TRY. + cl_salv_table=>factory( + IMPORTING r_salv_table = DATA(lo_alv) + CHANGING t_table = ct_lines ). + lo_alv->display( ). + CATCH cx_salv_msg INTO DATA(lx_msg). + MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'. + ENDTRY. + ENDMETHOD. +ENDCLASS. + +START-OF-SELECTION. + DATA(go_report) = NEW lcl_report( ). + DATA(gt_lines) = go_report->select_totals( iv_from = p_from + iv_to = p_to + it_matnr = s_matnr[] ). + go_report->display( CHANGING ct_lines = gt_lines ). + +CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. + PRIVATE SECTION. + CLASS-DATA go_env TYPE REF TO if_osql_test_environment. + CLASS-METHODS class_setup. + CLASS-METHODS class_teardown. + METHODS net_quantity FOR TESTING. + METHODS material_filter FOR TESTING. +ENDCLASS. + +CLASS ltc_report IMPLEMENTATION. + METHOD class_setup. + go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ). + DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY. + lt_move = VALUE #( + ( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110' + move_type = 'GR' quantity = '100.000' ) + ( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115' + move_type = 'GI' quantity = '30.000' ) + ( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201' + move_type = 'GR' quantity = '200.000' ) ). + go_env->insert_test_data( lt_move ). + ENDMETHOD. + + METHOD class_teardown. + go_env->destroy( ). + ENDMETHOD. + + METHOD net_quantity. + DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ) ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ). + cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ). + ENDMETHOD. + + METHOD material_filter. + DATA(lt_lines) = NEW lcl_report( )->select_totals( + iv_from = '20260101' + iv_to = '20261231' + it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ). + cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ). + cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0016/mutation.json b/tasks_gen/eval/G0016/mutation.json new file mode 100644 index 0000000..c51d4f4 --- /dev/null +++ b/tasks_gen/eval/G0016/mutation.json @@ -0,0 +1,67 @@ +{ + "task": "G0016", + "mutants": [ + { + "object": "{{P}}STOCK_NET", + "mutant": "line 43: >= -> < (rel)", + "status": "killed", + "hidden": "0/8", + "failed_tests": [ + "ALL_GROUPS", + "DATE_FROM_FILTER", + "DATE_TO_FILTER", + "MATERIAL_FILTER", + "MOVE_COUNT", + "NET_QUANTITY", + "NO_MATCHING_DATA", + "SORT_ORDER" + ] + }, + { + "object": "{{P}}STOCK_NET", + "mutant": "line 44: AND -> OR (logic)", + "status": "killed", + "hidden": "3/8", + "failed_tests": [ + "ALL_GROUPS", + "DATE_FROM_FILTER", + "DATE_TO_FILTER", + "MATERIAL_FILTER", + "NO_MATCHING_DATA" + ] + }, + { + "object": "{{P}}STOCK_NET", + "mutant": "line 53: <> -> = (rel)", + "status": "invalid", + "hidden": "0/0", + "failed_tests": [] + }, + { + "object": "{{P}}STOCK_NET", + "mutant": "line 58: = -> <> (eq)", + "status": "killed", + "hidden": "4/8", + "failed_tests": [ + "DATE_FROM_FILTER", + "DATE_TO_FILTER", + "MATERIAL_FILTER", + "NET_QUANTITY" + ] + }, + { + "object": "{{P}}STOCK_NET", + "mutant": "line 61: - -> + (arith)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "DATE_TO_FILTER", + "NET_QUANTITY" + ] + } + ], + "valid": 4, + "killed": 4, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0017/faulty/m1_i_proj_effort.ddls.asddls b/tasks_gen/eval/G0017/faulty/m1_i_proj_effort.ddls.asddls new file mode 100644 index 0000000..2c71522 --- /dev/null +++ b/tasks_gen/eval/G0017/faulty/m1_i_proj_effort.ddls.asddls @@ -0,0 +1,22 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Project effort' +define view entity {{P}}I_PROJ_EFFORT + as select from {{p}}proj as proj + inner join {{p}}asgn as asgn on asgn.proj_id <> proj.proj_id +{ + key proj.proj_id as proj_id, + proj.proj_name as proj_name, + count( * ) as assign_count, + sum( asgn.work_hours ) as total_hours, + sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost, + case + when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget + then 'X' + else 'N' + end as over_budget +} +where asgn.status = 'A' +group by + proj.proj_id, + proj.proj_name, + proj.budget diff --git a/tasks_gen/eval/G0017/faulty/m2_i_proj_effort.ddls.asddls b/tasks_gen/eval/G0017/faulty/m2_i_proj_effort.ddls.asddls new file mode 100644 index 0000000..61fec43 --- /dev/null +++ b/tasks_gen/eval/G0017/faulty/m2_i_proj_effort.ddls.asddls @@ -0,0 +1,22 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Project effort' +define view entity {{P}}I_PROJ_EFFORT + as select from {{p}}proj as proj + inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id +{ + key proj.proj_id as proj_id, + proj.proj_name as proj_name, + count( * ) as assign_count, + max( asgn.work_hours ) as total_hours, + sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost, + case + when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget + then 'X' + else 'N' + end as over_budget +} +where asgn.status = 'A' +group by + proj.proj_id, + proj.proj_name, + proj.budget diff --git a/tasks_gen/eval/G0017/faulty/m3_i_proj_effort.ddls.asddls b/tasks_gen/eval/G0017/faulty/m3_i_proj_effort.ddls.asddls new file mode 100644 index 0000000..fb3362b --- /dev/null +++ b/tasks_gen/eval/G0017/faulty/m3_i_proj_effort.ddls.asddls @@ -0,0 +1,22 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Project effort' +define view entity {{P}}I_PROJ_EFFORT + as select from {{p}}proj as proj + inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id +{ + key proj.proj_id as proj_id, + proj.proj_name as proj_name, + count( * ) as assign_count, + sum( asgn.work_hours ) as total_hours, + max( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost, + case + when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget + then 'X' + else 'N' + end as over_budget +} +where asgn.status = 'A' +group by + proj.proj_id, + proj.proj_name, + proj.budget diff --git a/tasks_gen/eval/G0017/faulty/m4_i_proj_effort.ddls.asddls b/tasks_gen/eval/G0017/faulty/m4_i_proj_effort.ddls.asddls new file mode 100644 index 0000000..090abf8 --- /dev/null +++ b/tasks_gen/eval/G0017/faulty/m4_i_proj_effort.ddls.asddls @@ -0,0 +1,22 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Project effort' +define view entity {{P}}I_PROJ_EFFORT + as select from {{p}}proj as proj + inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id +{ + key proj.proj_id as proj_id, + proj.proj_name as proj_name, + count( * ) as assign_count, + sum( asgn.work_hours ) as total_hours, + sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost, + case + when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) <= proj.budget + then 'X' + else 'N' + end as over_budget +} +where asgn.status = 'A' +group by + proj.proj_id, + proj.proj_name, + proj.budget diff --git a/tasks_gen/eval/G0017/mutation.json b/tasks_gen/eval/G0017/mutation.json new file mode 100644 index 0000000..78751f5 --- /dev/null +++ b/tasks_gen/eval/G0017/mutation.json @@ -0,0 +1,59 @@ +{ + "task": "G0017", + "mutants": [ + { + "object": "{{P}}I_PROJ_EFFORT", + "mutant": "line 5: inner join -> left outer join (join)", + "status": "survived", + "hidden": "8/8", + "failed_tests": [] + }, + { + "object": "{{P}}I_PROJ_EFFORT", + "mutant": "line 5: = -> <> (eq)", + "status": "killed", + "hidden": "1/8", + "failed_tests": [ + "BUDGET_NOT_EXCEEDED", + "COST_OF_PROJECT_ONE", + "COUNT_OF_PROJECT_ONE", + "HOURS_OF_PROJECT_ONE", + "NO_ACTIVE_ASSIGNMENT", + "OVER_BUDGET_FLAG", + "ROW_COUNT" + ] + }, + { + "object": "{{P}}I_PROJ_EFFORT", + "mutant": "line 10: sum( -> max( (agg)", + "status": "killed", + "hidden": "7/8", + "failed_tests": [ + "HOURS_OF_PROJECT_ONE" + ] + }, + { + "object": "{{P}}I_PROJ_EFFORT", + "mutant": "line 11: sum( -> max( (agg)", + "status": "killed", + "hidden": "7/8", + "failed_tests": [ + "COST_OF_PROJECT_ONE" + ] + }, + { + "object": "{{P}}I_PROJ_EFFORT", + "mutant": "line 13: > -> <= (rel)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "BUDGET_NOT_EXCEEDED", + "OVER_BUDGET_FLAG" + ] + } + ], + "valid": 5, + "killed": 4, + "kill_rate": 0.8, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0018/faulty/m0_i_order.ddls.asddls b/tasks_gen/eval/G0018/faulty/m0_i_order.ddls.asddls new file mode 100644 index 0000000..1e6ad63 --- /dev/null +++ b/tasks_gen/eval/G0018/faulty/m0_i_order.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Open orders with customer data' +define view entity {{P}}I_ORDER + as select from {{p}}ord as ord + association [0..1] to {{p}}cust as _Customer + on $projection.cust_id <> _Customer.cust_id +{ + key ord.order_id, + ord.cust_id, + ord.order_date, + _Customer.cust_name as customer_name, + _Customer.country as country, + _Customer +} +where ord.status = 'O' diff --git a/tasks_gen/eval/G0018/faulty/m1_i_order.ddls.asddls b/tasks_gen/eval/G0018/faulty/m1_i_order.ddls.asddls new file mode 100644 index 0000000..64ab999 --- /dev/null +++ b/tasks_gen/eval/G0018/faulty/m1_i_order.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Open orders with customer data' +define view entity {{P}}I_ORDER + as select from {{p}}ord as ord + association [0..1] to {{p}}cust as _Customer + on $projection.cust_id = _Customer.cust_id +{ + key ord.order_id, + ord.cust_id, + ord.order_date, + _Customer.cust_name as customer_name, + _Customer.country as country, + _Customer +} +where ord.status <> 'O' diff --git a/tasks_gen/eval/G0018/mutation.json b/tasks_gen/eval/G0018/mutation.json new file mode 100644 index 0000000..f6d0127 --- /dev/null +++ b/tasks_gen/eval/G0018/mutation.json @@ -0,0 +1,33 @@ +{ + "task": "G0018", + "mutants": [ + { + "object": "{{P}}I_ORDER", + "mutant": "line 6: = -> <> (eq)", + "status": "killed", + "hidden": "3/6", + "failed_tests": [ + "ASSOCIATION_PATH", + "CUSTOMER_DATA_SHOWN", + "ORDER_WITHOUT_CUSTOMER" + ] + }, + { + "object": "{{P}}I_ORDER", + "mutant": "line 15: = -> <> (eq)", + "status": "killed", + "hidden": "1/6", + "failed_tests": [ + "ASSOCIATION_PATH", + "CLOSED_ORDER_HIDDEN", + "CUSTOMER_DATA_SHOWN", + "OPEN_ORDERS_ONLY", + "ORDER_KEY_DATA" + ] + } + ], + "valid": 2, + "killed": 2, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0019/faulty/m0_i_sales_class.ddls.asddls b/tasks_gen/eval/G0019/faulty/m0_i_sales_class.ddls.asddls new file mode 100644 index 0000000..df4089f --- /dev/null +++ b/tasks_gen/eval/G0019/faulty/m0_i_sales_class.ddls.asddls @@ -0,0 +1,14 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales items by region and size class' +define view entity {{P}}I_SALES_CLASS + as select from {{p}}sale +{ + key region as region, + count( * ) as item_count, + sum( case when amount < 101 then 1 else 0 end ) as small_count, + sum( case when amount >= 100 and amount < 1000 then 1 else 0 end ) as medium_count, + sum( case when amount >= 1000 then 1 else 0 end ) as large_count, + sum( amount ) as total_amount +} +where status <> 'X' +group by region diff --git a/tasks_gen/eval/G0019/faulty/m1_i_sales_class.ddls.asddls b/tasks_gen/eval/G0019/faulty/m1_i_sales_class.ddls.asddls new file mode 100644 index 0000000..6422f6a --- /dev/null +++ b/tasks_gen/eval/G0019/faulty/m1_i_sales_class.ddls.asddls @@ -0,0 +1,14 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales items by region and size class' +define view entity {{P}}I_SALES_CLASS + as select from {{p}}sale +{ + key region as region, + count( * ) as item_count, + sum( case when amount < 100 then 1 else 0 end ) as small_count, + sum( case when amount < 100 and amount < 1000 then 1 else 0 end ) as medium_count, + sum( case when amount >= 1000 then 1 else 0 end ) as large_count, + sum( amount ) as total_amount +} +where status <> 'X' +group by region diff --git a/tasks_gen/eval/G0019/faulty/m2_i_sales_class.ddls.asddls b/tasks_gen/eval/G0019/faulty/m2_i_sales_class.ddls.asddls new file mode 100644 index 0000000..6ec60a4 --- /dev/null +++ b/tasks_gen/eval/G0019/faulty/m2_i_sales_class.ddls.asddls @@ -0,0 +1,14 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales items by region and size class' +define view entity {{P}}I_SALES_CLASS + as select from {{p}}sale +{ + key region as region, + count( * ) as item_count, + sum( case when amount < 100 then 1 else 0 end ) as small_count, + sum( case when amount >= 100 and amount < 1001 then 1 else 0 end ) as medium_count, + sum( case when amount >= 1000 then 1 else 0 end ) as large_count, + sum( amount ) as total_amount +} +where status <> 'X' +group by region diff --git a/tasks_gen/eval/G0019/faulty/m4_i_sales_class.ddls.asddls b/tasks_gen/eval/G0019/faulty/m4_i_sales_class.ddls.asddls new file mode 100644 index 0000000..aa1979f --- /dev/null +++ b/tasks_gen/eval/G0019/faulty/m4_i_sales_class.ddls.asddls @@ -0,0 +1,14 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales items by region and size class' +define view entity {{P}}I_SALES_CLASS + as select from {{p}}sale +{ + key region as region, + count( * ) as item_count, + sum( case when amount < 100 then 1 else 0 end ) as small_count, + sum( case when amount >= 100 and amount < 1000 then 1 else 0 end ) as medium_count, + sum( case when amount >= 1000 then 1 else 0 end ) as large_count, + sum( amount ) as total_amount +} +where status = 'X' +group by region diff --git a/tasks_gen/eval/G0019/mutation.json b/tasks_gen/eval/G0019/mutation.json new file mode 100644 index 0000000..6520aaf --- /dev/null +++ b/tasks_gen/eval/G0019/mutation.json @@ -0,0 +1,61 @@ +{ + "task": "G0019", + "mutants": [ + { + "object": "{{P}}I_SALES_CLASS", + "mutant": "line 8: 100 -> 101 (const)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "CLASS_BOUNDARIES", + "SMALL_COUNT" + ] + }, + { + "object": "{{P}}I_SALES_CLASS", + "mutant": "line 9: >= -> < (rel)", + "status": "killed", + "hidden": "7/8", + "failed_tests": [ + "MEDIUM_COUNT" + ] + }, + { + "object": "{{P}}I_SALES_CLASS", + "mutant": "line 9: 1000 -> 1001 (const)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "CLASS_BOUNDARIES", + "MEDIUM_COUNT" + ] + }, + { + "object": "{{P}}I_SALES_CLASS", + "mutant": "line 10: sum( -> max( (agg)", + "status": "survived", + "hidden": "8/8", + "failed_tests": [] + }, + { + "object": "{{P}}I_SALES_CLASS", + "mutant": "line 13: <> -> = (rel)", + "status": "killed", + "hidden": "0/8", + "failed_tests": [ + "CANCELLED_ITEMS_IGNORED", + "CLASS_BOUNDARIES", + "ITEM_COUNT", + "LARGE_COUNT", + "MEDIUM_COUNT", + "REGIONS_IN_RESULT", + "SMALL_COUNT", + "TOTAL_AMOUNT" + ] + } + ], + "valid": 5, + "killed": 4, + "kill_rate": 0.8, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0020/faulty/m1_i_book_revenue.ddls.asddls b/tasks_gen/eval/G0020/faulty/m1_i_book_revenue.ddls.asddls new file mode 100644 index 0000000..ed27305 --- /dev/null +++ b/tasks_gen/eval/G0020/faulty/m1_i_book_revenue.ddls.asddls @@ -0,0 +1,20 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Book revenue in period' +define view entity {{P}}I_BOOK_REVENUE + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}book as bk + inner join {{p}}sale as sl on sl.book_id <> bk.book_id +{ + key bk.book_id as book_id, + bk.title as title, + bk.category as category, + sum( sl.quantity ) as sold_quantity, + sum( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue +} +where sl.sale_date between $parameters.p_from and $parameters.p_to +group by + bk.book_id, + bk.title, + bk.category diff --git a/tasks_gen/eval/G0020/faulty/m2_i_book_revenue.ddls.asddls b/tasks_gen/eval/G0020/faulty/m2_i_book_revenue.ddls.asddls new file mode 100644 index 0000000..b48b0d0 --- /dev/null +++ b/tasks_gen/eval/G0020/faulty/m2_i_book_revenue.ddls.asddls @@ -0,0 +1,20 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Book revenue in period' +define view entity {{P}}I_BOOK_REVENUE + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}book as bk + inner join {{p}}sale as sl on sl.book_id = bk.book_id +{ + key bk.book_id as book_id, + bk.title as title, + bk.category as category, + max( sl.quantity ) as sold_quantity, + sum( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue +} +where sl.sale_date between $parameters.p_from and $parameters.p_to +group by + bk.book_id, + bk.title, + bk.category diff --git a/tasks_gen/eval/G0020/faulty/m3_i_book_revenue.ddls.asddls b/tasks_gen/eval/G0020/faulty/m3_i_book_revenue.ddls.asddls new file mode 100644 index 0000000..b582661 --- /dev/null +++ b/tasks_gen/eval/G0020/faulty/m3_i_book_revenue.ddls.asddls @@ -0,0 +1,20 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Book revenue in period' +define view entity {{P}}I_BOOK_REVENUE + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}book as bk + inner join {{p}}sale as sl on sl.book_id = bk.book_id +{ + key bk.book_id as book_id, + bk.title as title, + bk.category as category, + sum( sl.quantity ) as sold_quantity, + max( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue +} +where sl.sale_date between $parameters.p_from and $parameters.p_to +group by + bk.book_id, + bk.title, + bk.category diff --git a/tasks_gen/eval/G0020/mutation.json b/tasks_gen/eval/G0020/mutation.json new file mode 100644 index 0000000..c8127f7 --- /dev/null +++ b/tasks_gen/eval/G0020/mutation.json @@ -0,0 +1,56 @@ +{ + "task": "G0020", + "mutants": [ + { + "object": "{{P}}I_BOOK_REVENUE", + "mutant": "line 8: inner join -> left outer join (join)", + "status": "survived", + "hidden": "8/8", + "failed_tests": [] + }, + { + "object": "{{P}}I_BOOK_REVENUE", + "mutant": "line 8: = -> <> (eq)", + "status": "killed", + "hidden": "2/8", + "failed_tests": [ + "BOOKS_IN_PERIOD", + "BOOK_OUTSIDE_PERIOD_HIDDEN", + "PERIOD_LIMITS_INCLUDED", + "REVENUE_HAS_TWO_DECIMALS", + "REVENUE_IN_PERIOD", + "SOLD_QUANTITY_IN_PERIOD" + ] + }, + { + "object": "{{P}}I_BOOK_REVENUE", + "mutant": "line 13: sum( -> max( (agg)", + "status": "killed", + "hidden": "7/8", + "failed_tests": [ + "SOLD_QUANTITY_IN_PERIOD" + ] + }, + { + "object": "{{P}}I_BOOK_REVENUE", + "mutant": "line 14: sum( -> max( (agg)", + "status": "killed", + "hidden": "6/8", + "failed_tests": [ + "REVENUE_HAS_TWO_DECIMALS", + "REVENUE_IN_PERIOD" + ] + }, + { + "object": "{{P}}I_BOOK_REVENUE", + "mutant": "line 16: and -> or (logic)", + "status": "invalid", + "hidden": "0/0", + "failed_tests": [] + } + ], + "valid": 4, + "killed": 3, + "kill_rate": 0.75, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0021/faulty/m0_i_shipment.ddls.asddls b/tasks_gen/eval/G0021/faulty/m0_i_shipment.ddls.asddls new file mode 100644 index 0000000..2edffdb --- /dev/null +++ b/tasks_gen/eval/G0021/faulty/m0_i_shipment.ddls.asddls @@ -0,0 +1,23 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@Metadata.ignorePropagatedAnnotations: true +@EndUserText.label: 'Shipment overview' +define view entity {{P}}I_SHIPMENT + as select from {{p}}road as road +{ + key road.ship_id as ship_id, + road.cust as customer, + 'ROAD' as ship_mode, + road.kg as weight, + road.cost as cost +} +where road.kg <= 0 +union all +select from {{p}}rail as rail +{ + key rail.ship_id as ship_id, + rail.customer as customer, + 'RAIL' as ship_mode, + rail.weight as weight, + rail.fee as cost +} +where rail.weight > 0 diff --git a/tasks_gen/eval/G0021/faulty/m1_i_shipment.ddls.asddls b/tasks_gen/eval/G0021/faulty/m1_i_shipment.ddls.asddls new file mode 100644 index 0000000..f51d5c5 --- /dev/null +++ b/tasks_gen/eval/G0021/faulty/m1_i_shipment.ddls.asddls @@ -0,0 +1,23 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@Metadata.ignorePropagatedAnnotations: true +@EndUserText.label: 'Shipment overview' +define view entity {{P}}I_SHIPMENT + as select from {{p}}road as road +{ + key road.ship_id as ship_id, + road.cust as customer, + 'ROAD' as ship_mode, + road.kg as weight, + road.cost as cost +} +where road.kg > 0 +union all +select from {{p}}rail as rail +{ + key rail.ship_id as ship_id, + rail.customer as customer, + 'RAIL' as ship_mode, + rail.weight as weight, + rail.fee as cost +} +where rail.weight <= 0 diff --git a/tasks_gen/eval/G0021/mutation.json b/tasks_gen/eval/G0021/mutation.json new file mode 100644 index 0000000..442da00 --- /dev/null +++ b/tasks_gen/eval/G0021/mutation.json @@ -0,0 +1,35 @@ +{ + "task": "G0021", + "mutants": [ + { + "object": "{{P}}I_SHIPMENT", + "mutant": "line 13: > -> <= (rel)", + "status": "killed", + "hidden": "3/8", + "failed_tests": [ + "LIGHT_SHIPMENTS_HIDDEN", + "ROAD_CUSTOMER", + "ROAD_ROWS", + "ROAD_WEIGHT", + "ROW_COUNT" + ] + }, + { + "object": "{{P}}I_SHIPMENT", + "mutant": "line 23: > -> <= (rel)", + "status": "killed", + "hidden": "3/8", + "failed_tests": [ + "LIGHT_SHIPMENTS_HIDDEN", + "RAIL_COST", + "RAIL_CUSTOMER", + "RAIL_ROWS", + "ROW_COUNT" + ] + } + ], + "valid": 2, + "killed": 2, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0022/faulty/m0_expense_validator.clas.abap b/tasks_gen/eval/G0022/faulty/m0_expense_validator.clas.abap new file mode 100644 index 0000000..df3043c --- /dev/null +++ b/tasks_gen/eval/G0022/faulty/m0_expense_validator.clas.abap @@ -0,0 +1,85 @@ +CLASS {{p}}expense_validator DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS validate + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + + PRIVATE SECTION. + CONSTANTS: + c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00', + c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'. + + METHODS check_amount + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_currency + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_date + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_receipt + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_cost_center + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS is_supported_currency + IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency + RETURNING VALUE(rv_supported) TYPE abap_bool. +ENDCLASS. + + +CLASS {{p}}expense_validator IMPLEMENTATION. + METHOD validate. + check_amount( is_claim ). + check_currency( is_claim ). + check_date( is_claim ). + check_receipt( is_claim ). + check_cost_center( is_claim ). + ENDMETHOD. + + METHOD check_amount. + IF is_claim-amount <= 0. + RAISE EXCEPTION TYPE {{p}}cx_claim_amount + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_currency. + IF is_supported_currency( is_claim-currency ) <> abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_currency + EXPORTING iv_currency = is_claim-currency. + ENDIF. + ENDMETHOD. + + METHOD check_date. + IF is_claim-claim_date > sy-datum. + RAISE EXCEPTION TYPE {{p}}cx_claim_date + EXPORTING iv_claim_date = is_claim-claim_date. + ENDIF. + ENDMETHOD. + + METHOD check_receipt. + IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_receipt + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_cost_center. + IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL. + RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD is_supported_currency. + rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD' + OR iv_currency = 'GBP' OR iv_currency = 'CHF' ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0022/faulty/m1_expense_validator.clas.abap b/tasks_gen/eval/G0022/faulty/m1_expense_validator.clas.abap new file mode 100644 index 0000000..b75449a --- /dev/null +++ b/tasks_gen/eval/G0022/faulty/m1_expense_validator.clas.abap @@ -0,0 +1,85 @@ +CLASS {{p}}expense_validator DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS validate + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + + PRIVATE SECTION. + CONSTANTS: + c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00', + c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'. + + METHODS check_amount + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_currency + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_date + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_receipt + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_cost_center + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS is_supported_currency + IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency + RETURNING VALUE(rv_supported) TYPE abap_bool. +ENDCLASS. + + +CLASS {{p}}expense_validator IMPLEMENTATION. + METHOD validate. + check_amount( is_claim ). + check_currency( is_claim ). + check_date( is_claim ). + check_receipt( is_claim ). + check_cost_center( is_claim ). + ENDMETHOD. + + METHOD check_amount. + IF is_claim-amount <= 0. + RAISE EXCEPTION TYPE {{p}}cx_claim_amount + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_currency. + IF is_supported_currency( is_claim-currency ) = abap_true. + RAISE EXCEPTION TYPE {{p}}cx_claim_currency + EXPORTING iv_currency = is_claim-currency. + ENDIF. + ENDMETHOD. + + METHOD check_date. + IF is_claim-claim_date > sy-datum. + RAISE EXCEPTION TYPE {{p}}cx_claim_date + EXPORTING iv_claim_date = is_claim-claim_date. + ENDIF. + ENDMETHOD. + + METHOD check_receipt. + IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_receipt + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_cost_center. + IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL. + RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD is_supported_currency. + rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD' + OR iv_currency = 'GBP' OR iv_currency = 'CHF' ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0022/faulty/m2_expense_validator.clas.abap b/tasks_gen/eval/G0022/faulty/m2_expense_validator.clas.abap new file mode 100644 index 0000000..8fd718f --- /dev/null +++ b/tasks_gen/eval/G0022/faulty/m2_expense_validator.clas.abap @@ -0,0 +1,85 @@ +CLASS {{p}}expense_validator DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS validate + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + + PRIVATE SECTION. + CONSTANTS: + c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00', + c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'. + + METHODS check_amount + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_currency + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_date + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_receipt + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_cost_center + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS is_supported_currency + IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency + RETURNING VALUE(rv_supported) TYPE abap_bool. +ENDCLASS. + + +CLASS {{p}}expense_validator IMPLEMENTATION. + METHOD validate. + check_amount( is_claim ). + check_currency( is_claim ). + check_date( is_claim ). + check_receipt( is_claim ). + check_cost_center( is_claim ). + ENDMETHOD. + + METHOD check_amount. + IF is_claim-amount <= 0. + RAISE EXCEPTION TYPE {{p}}cx_claim_amount + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_currency. + IF is_supported_currency( is_claim-currency ) = abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_currency + EXPORTING iv_currency = is_claim-currency. + ENDIF. + ENDMETHOD. + + METHOD check_date. + IF is_claim-claim_date <= sy-datum. + RAISE EXCEPTION TYPE {{p}}cx_claim_date + EXPORTING iv_claim_date = is_claim-claim_date. + ENDIF. + ENDMETHOD. + + METHOD check_receipt. + IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_receipt + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_cost_center. + IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL. + RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD is_supported_currency. + rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD' + OR iv_currency = 'GBP' OR iv_currency = 'CHF' ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0022/faulty/m3_expense_validator.clas.abap b/tasks_gen/eval/G0022/faulty/m3_expense_validator.clas.abap new file mode 100644 index 0000000..73429ee --- /dev/null +++ b/tasks_gen/eval/G0022/faulty/m3_expense_validator.clas.abap @@ -0,0 +1,85 @@ +CLASS {{p}}expense_validator DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS validate + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + + PRIVATE SECTION. + CONSTANTS: + c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00', + c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'. + + METHODS check_amount + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_currency + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_date + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_receipt + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS check_cost_center + IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim + RAISING {{p}}cx_claim_error. + METHODS is_supported_currency + IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency + RETURNING VALUE(rv_supported) TYPE abap_bool. +ENDCLASS. + + +CLASS {{p}}expense_validator IMPLEMENTATION. + METHOD validate. + check_amount( is_claim ). + check_currency( is_claim ). + check_date( is_claim ). + check_receipt( is_claim ). + check_cost_center( is_claim ). + ENDMETHOD. + + METHOD check_amount. + IF is_claim-amount <= 0. + RAISE EXCEPTION TYPE {{p}}cx_claim_amount + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_currency. + IF is_supported_currency( is_claim-currency ) = abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_currency + EXPORTING iv_currency = is_claim-currency. + ENDIF. + ENDMETHOD. + + METHOD check_date. + IF is_claim-claim_date > sy-datum. + RAISE EXCEPTION TYPE {{p}}cx_claim_date + EXPORTING iv_claim_date = is_claim-claim_date. + ENDIF. + ENDMETHOD. + + METHOD check_receipt. + IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt <> abap_false. + RAISE EXCEPTION TYPE {{p}}cx_claim_receipt + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD check_cost_center. + IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL. + RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter + EXPORTING iv_amount = is_claim-amount. + ENDIF. + ENDMETHOD. + + METHOD is_supported_currency. + rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD' + OR iv_currency = 'GBP' OR iv_currency = 'CHF' ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0022/mutation.json b/tasks_gen/eval/G0022/mutation.json new file mode 100644 index 0000000..ab34494 --- /dev/null +++ b/tasks_gen/eval/G0022/mutation.json @@ -0,0 +1,80 @@ +{ + "task": "G0022", + "mutants": [ + { + "object": "{{P}}EXPENSE_VALIDATOR", + "mutant": "line 54: = -> <> (eq)", + "status": "killed", + "hidden": "3/12", + "failed_tests": [ + "COST_CENTER_NOT_REQUIRED", + "COST_CENTER_REQUIRED", + "FUTURE_DATE_REJECTED", + "RECEIPT_NOT_REQUIRED_BELOW", + "RECEIPT_REQUIRED", + "RECEIPT_RULE_HAS_PRIORITY", + "TODAY_IS_ACCEPTED", + "UNKNOWN_CURRENCY_REJECTED", + "VALID_CLAIM_PASSES" + ] + }, + { + "object": "{{P}}EXPENSE_VALIDATOR", + "mutant": "line 54: abap_false -> abap_true (bool)", + "status": "killed", + "hidden": "3/12", + "failed_tests": [ + "COST_CENTER_NOT_REQUIRED", + "COST_CENTER_REQUIRED", + "FUTURE_DATE_REJECTED", + "RECEIPT_NOT_REQUIRED_BELOW", + "RECEIPT_REQUIRED", + "RECEIPT_RULE_HAS_PRIORITY", + "TODAY_IS_ACCEPTED", + "UNKNOWN_CURRENCY_REJECTED", + "VALID_CLAIM_PASSES" + ] + }, + { + "object": "{{P}}EXPENSE_VALIDATOR", + "mutant": "line 61: > -> <= (rel)", + "status": "killed", + "hidden": "4/12", + "failed_tests": [ + "COST_CENTER_NOT_REQUIRED", + "COST_CENTER_REQUIRED", + "FUTURE_DATE_REJECTED", + "RECEIPT_NOT_REQUIRED_BELOW", + "RECEIPT_REQUIRED", + "RECEIPT_RULE_HAS_PRIORITY", + "TODAY_IS_ACCEPTED", + "VALID_CLAIM_PASSES" + ] + }, + { + "object": "{{P}}EXPENSE_VALIDATOR", + "mutant": "line 68: = -> <> (eq)", + "status": "killed", + "hidden": "6/12", + "failed_tests": [ + "COST_CENTER_NOT_REQUIRED", + "COST_CENTER_REQUIRED", + "RECEIPT_REQUIRED", + "RECEIPT_RULE_HAS_PRIORITY", + "TODAY_IS_ACCEPTED", + "VALID_CLAIM_PASSES" + ] + }, + { + "object": "{{P}}EXPENSE_VALIDATOR", + "mutant": "line 83: OR -> AND (logic)", + "status": "survived", + "hidden": "12/12", + "failed_tests": [] + } + ], + "valid": 5, + "killed": 4, + "kill_rate": 0.8, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0023/faulty/m0_freight_calculator.clas.abap b/tasks_gen/eval/G0023/faulty/m0_freight_calculator.clas.abap new file mode 100644 index 0000000..c967d55 --- /dev/null +++ b/tasks_gen/eval/G0023/faulty/m0_freight_calculator.clas.abap @@ -0,0 +1,62 @@ +CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_rate, + zone TYPE {{p}}if_freight_calc=>ty_zone, + base TYPE {{p}}if_freight_calc=>ty_amount, + per_kg TYPE {{p}}if_freight_calc=>ty_amount, + minimum TYPE {{p}}if_freight_calc=>ty_amount, + surcharge TYPE p LENGTH 4 DECIMALS 3, + END OF ty_rate, + tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone. + + CONSTANTS: + c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000', + c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'. + + METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate. +ENDCLASS. + + +CLASS {{p}}freight_calculator IMPLEMENTATION. + METHOD {{p}}if_freight_calc~calculate. + DATA(lt_rate) = rates( ). + READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone. + IF sy-subrc <> 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount. + lv_charge = ls_rate-per_kg / iv_weight. + + DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount. + lv_freight = ls_rate-base + lv_charge. + IF lv_freight < ls_rate-minimum. + lv_freight = ls_rate-minimum. + ENDIF. + + DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount. + lv_surcharge = lv_freight * ls_rate-surcharge. + + DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount. + lv_total = lv_freight + lv_surcharge. + IF iv_weight > c_heavy_limit. + lv_total = lv_total * c_discount. + ENDIF. + + rv_cost = lv_total. + ENDMETHOD. + + METHOD rates. + rt_rate = VALUE #( + ( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' ) + ( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' ) + ( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' ) + ( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' ) + ( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0023/faulty/m1_freight_calculator.clas.abap b/tasks_gen/eval/G0023/faulty/m1_freight_calculator.clas.abap new file mode 100644 index 0000000..971ac00 --- /dev/null +++ b/tasks_gen/eval/G0023/faulty/m1_freight_calculator.clas.abap @@ -0,0 +1,62 @@ +CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_rate, + zone TYPE {{p}}if_freight_calc=>ty_zone, + base TYPE {{p}}if_freight_calc=>ty_amount, + per_kg TYPE {{p}}if_freight_calc=>ty_amount, + minimum TYPE {{p}}if_freight_calc=>ty_amount, + surcharge TYPE p LENGTH 4 DECIMALS 3, + END OF ty_rate, + tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone. + + CONSTANTS: + c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000', + c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'. + + METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate. +ENDCLASS. + + +CLASS {{p}}freight_calculator IMPLEMENTATION. + METHOD {{p}}if_freight_calc~calculate. + DATA(lt_rate) = rates( ). + READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone. + IF sy-subrc <> 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount. + lv_charge = ls_rate-per_kg * iv_weight. + + DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount. + lv_freight = ls_rate-base - lv_charge. + IF lv_freight < ls_rate-minimum. + lv_freight = ls_rate-minimum. + ENDIF. + + DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount. + lv_surcharge = lv_freight * ls_rate-surcharge. + + DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount. + lv_total = lv_freight + lv_surcharge. + IF iv_weight > c_heavy_limit. + lv_total = lv_total * c_discount. + ENDIF. + + rv_cost = lv_total. + ENDMETHOD. + + METHOD rates. + rt_rate = VALUE #( + ( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' ) + ( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' ) + ( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' ) + ( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' ) + ( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0023/faulty/m2_freight_calculator.clas.abap b/tasks_gen/eval/G0023/faulty/m2_freight_calculator.clas.abap new file mode 100644 index 0000000..c9acbf0 --- /dev/null +++ b/tasks_gen/eval/G0023/faulty/m2_freight_calculator.clas.abap @@ -0,0 +1,62 @@ +CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_rate, + zone TYPE {{p}}if_freight_calc=>ty_zone, + base TYPE {{p}}if_freight_calc=>ty_amount, + per_kg TYPE {{p}}if_freight_calc=>ty_amount, + minimum TYPE {{p}}if_freight_calc=>ty_amount, + surcharge TYPE p LENGTH 4 DECIMALS 3, + END OF ty_rate, + tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone. + + CONSTANTS: + c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000', + c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'. + + METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate. +ENDCLASS. + + +CLASS {{p}}freight_calculator IMPLEMENTATION. + METHOD {{p}}if_freight_calc~calculate. + DATA(lt_rate) = rates( ). + READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone. + IF sy-subrc <> 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount. + lv_charge = ls_rate-per_kg * iv_weight. + + DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount. + lv_freight = ls_rate-base + lv_charge. + IF lv_freight >= ls_rate-minimum. + lv_freight = ls_rate-minimum. + ENDIF. + + DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount. + lv_surcharge = lv_freight * ls_rate-surcharge. + + DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount. + lv_total = lv_freight + lv_surcharge. + IF iv_weight > c_heavy_limit. + lv_total = lv_total * c_discount. + ENDIF. + + rv_cost = lv_total. + ENDMETHOD. + + METHOD rates. + rt_rate = VALUE #( + ( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' ) + ( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' ) + ( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' ) + ( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' ) + ( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0023/faulty/m3_freight_calculator.clas.abap b/tasks_gen/eval/G0023/faulty/m3_freight_calculator.clas.abap new file mode 100644 index 0000000..3ce38ee --- /dev/null +++ b/tasks_gen/eval/G0023/faulty/m3_freight_calculator.clas.abap @@ -0,0 +1,62 @@ +CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_rate, + zone TYPE {{p}}if_freight_calc=>ty_zone, + base TYPE {{p}}if_freight_calc=>ty_amount, + per_kg TYPE {{p}}if_freight_calc=>ty_amount, + minimum TYPE {{p}}if_freight_calc=>ty_amount, + surcharge TYPE p LENGTH 4 DECIMALS 3, + END OF ty_rate, + tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone. + + CONSTANTS: + c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000', + c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'. + + METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate. +ENDCLASS. + + +CLASS {{p}}freight_calculator IMPLEMENTATION. + METHOD {{p}}if_freight_calc~calculate. + DATA(lt_rate) = rates( ). + READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone. + IF sy-subrc <> 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount. + lv_charge = ls_rate-per_kg * iv_weight. + + DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount. + lv_freight = ls_rate-base + lv_charge. + IF lv_freight < ls_rate-minimum. + lv_freight = ls_rate-minimum. + ENDIF. + + DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount. + lv_surcharge = lv_freight * ls_rate-surcharge. + + DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount. + lv_total = lv_freight - lv_surcharge. + IF iv_weight > c_heavy_limit. + lv_total = lv_total * c_discount. + ENDIF. + + rv_cost = lv_total. + ENDMETHOD. + + METHOD rates. + rt_rate = VALUE #( + ( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' ) + ( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' ) + ( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' ) + ( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' ) + ( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0023/faulty/m4_freight_calculator.clas.abap b/tasks_gen/eval/G0023/faulty/m4_freight_calculator.clas.abap new file mode 100644 index 0000000..12070aa --- /dev/null +++ b/tasks_gen/eval/G0023/faulty/m4_freight_calculator.clas.abap @@ -0,0 +1,62 @@ +CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES {{p}}if_freight_calc. + + PRIVATE SECTION. + TYPES: + BEGIN OF ty_rate, + zone TYPE {{p}}if_freight_calc=>ty_zone, + base TYPE {{p}}if_freight_calc=>ty_amount, + per_kg TYPE {{p}}if_freight_calc=>ty_amount, + minimum TYPE {{p}}if_freight_calc=>ty_amount, + surcharge TYPE p LENGTH 4 DECIMALS 3, + END OF ty_rate, + tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone. + + CONSTANTS: + c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000', + c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'. + + METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate. +ENDCLASS. + + +CLASS {{p}}freight_calculator IMPLEMENTATION. + METHOD {{p}}if_freight_calc~calculate. + DATA(lt_rate) = rates( ). + READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone. + IF sy-subrc <> 0. + rv_cost = 0. + RETURN. + ENDIF. + + DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount. + lv_charge = ls_rate-per_kg * iv_weight. + + DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount. + lv_freight = ls_rate-base + lv_charge. + IF lv_freight < ls_rate-minimum. + lv_freight = ls_rate-minimum. + ENDIF. + + DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount. + lv_surcharge = lv_freight * ls_rate-surcharge. + + DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount. + lv_total = lv_freight + lv_surcharge. + IF iv_weight > c_heavy_limit. + lv_total = lv_total / c_discount. + ENDIF. + + rv_cost = lv_total. + ENDMETHOD. + + METHOD rates. + rt_rate = VALUE #( + ( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' ) + ( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' ) + ( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' ) + ( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' ) + ( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0023/mutation.json b/tasks_gen/eval/G0023/mutation.json new file mode 100644 index 0000000..020079a --- /dev/null +++ b/tasks_gen/eval/G0023/mutation.json @@ -0,0 +1,78 @@ +{ + "task": "G0023", + "mutants": [ + { + "object": "{{P}}FREIGHT_CALCULATOR", + "mutant": "line 34: * -> / (arith)", + "status": "killed", + "hidden": "3/9", + "failed_tests": [ + "ALL_ZONES_ARE_RATED", + "DISCOUNT_ROUNDS_HALF_UP", + "HEAVY_DISCOUNT_ON_TOTAL", + "NO_DISCOUNT_AT_EXACTLY_1000", + "SURCHARGE_USES_MINIMUM", + "WEIGHT_CHARGE_ROUNDS_HALF_UP" + ] + }, + { + "object": "{{P}}FREIGHT_CALCULATOR", + "mutant": "line 37: + -> - (arith)", + "status": "killed", + "hidden": "4/9", + "failed_tests": [ + "ALL_ZONES_ARE_RATED", + "DISCOUNT_ROUNDS_HALF_UP", + "HEAVY_DISCOUNT_ON_TOTAL", + "NO_DISCOUNT_AT_EXACTLY_1000", + "WEIGHT_CHARGE_ROUNDS_HALF_UP" + ] + }, + { + "object": "{{P}}FREIGHT_CALCULATOR", + "mutant": "line 38: < -> >= (rel)", + "status": "killed", + "hidden": "1/9", + "failed_tests": [ + "ALL_ZONES_ARE_RATED", + "DISCOUNT_ROUNDS_HALF_UP", + "HEAVY_DISCOUNT_ON_TOTAL", + "MINIMUM_APPLIES_AFTER_CHARGE", + "NO_DISCOUNT_AT_EXACTLY_1000", + "SMALL_WEIGHT_USES_MINIMUM", + "SURCHARGE_USES_MINIMUM", + "WEIGHT_CHARGE_ROUNDS_HALF_UP" + ] + }, + { + "object": "{{P}}FREIGHT_CALCULATOR", + "mutant": "line 46: + -> - (arith)", + "status": "killed", + "hidden": "1/9", + "failed_tests": [ + "ALL_ZONES_ARE_RATED", + "DISCOUNT_ROUNDS_HALF_UP", + "HEAVY_DISCOUNT_ON_TOTAL", + "MINIMUM_APPLIES_AFTER_CHARGE", + "NO_DISCOUNT_AT_EXACTLY_1000", + "SMALL_WEIGHT_USES_MINIMUM", + "SURCHARGE_USES_MINIMUM", + "WEIGHT_CHARGE_ROUNDS_HALF_UP" + ] + }, + { + "object": "{{P}}FREIGHT_CALCULATOR", + "mutant": "line 48: * -> / (arith)", + "status": "killed", + "hidden": "7/9", + "failed_tests": [ + "DISCOUNT_ROUNDS_HALF_UP", + "HEAVY_DISCOUNT_ON_TOTAL" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0024/faulty/m0_i_sales_report.ddls.asddls b/tasks_gen/eval/G0024/faulty/m0_i_sales_report.ddls.asddls new file mode 100644 index 0000000..7ebdbc0 --- /dev/null +++ b/tasks_gen/eval/G0024/faulty/m0_i_sales_report.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales per product in a period' +define view entity {{P}}I_SALES_REPORT + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}sales as sale +{ + key sale.product as product, + max( sale.quantity ) as total_qty, + sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount +} +where sale.sold_on >= $parameters.p_from + and sale.sold_on <= $parameters.p_to +group by sale.product diff --git a/tasks_gen/eval/G0024/faulty/m1_i_sales_report.ddls.asddls b/tasks_gen/eval/G0024/faulty/m1_i_sales_report.ddls.asddls new file mode 100644 index 0000000..34a3460 --- /dev/null +++ b/tasks_gen/eval/G0024/faulty/m1_i_sales_report.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales per product in a period' +define view entity {{P}}I_SALES_REPORT + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}sales as sale +{ + key sale.product as product, + sum( sale.quantity ) as total_qty, + max( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount +} +where sale.sold_on >= $parameters.p_from + and sale.sold_on <= $parameters.p_to +group by sale.product diff --git a/tasks_gen/eval/G0024/faulty/m2_i_sales_report.ddls.asddls b/tasks_gen/eval/G0024/faulty/m2_i_sales_report.ddls.asddls new file mode 100644 index 0000000..99363d0 --- /dev/null +++ b/tasks_gen/eval/G0024/faulty/m2_i_sales_report.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales per product in a period' +define view entity {{P}}I_SALES_REPORT + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}sales as sale +{ + key sale.product as product, + sum( sale.quantity ) as total_qty, + sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount +} +where sale.sold_on < $parameters.p_from + and sale.sold_on <= $parameters.p_to +group by sale.product diff --git a/tasks_gen/eval/G0024/faulty/m3_i_sales_report.ddls.asddls b/tasks_gen/eval/G0024/faulty/m3_i_sales_report.ddls.asddls new file mode 100644 index 0000000..785a041 --- /dev/null +++ b/tasks_gen/eval/G0024/faulty/m3_i_sales_report.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales per product in a period' +define view entity {{P}}I_SALES_REPORT + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}sales as sale +{ + key sale.product as product, + sum( sale.quantity ) as total_qty, + sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount +} +where sale.sold_on >= $parameters.p_from + or sale.sold_on <= $parameters.p_to +group by sale.product diff --git a/tasks_gen/eval/G0024/faulty/m4_i_sales_report.ddls.asddls b/tasks_gen/eval/G0024/faulty/m4_i_sales_report.ddls.asddls new file mode 100644 index 0000000..a47ee5d --- /dev/null +++ b/tasks_gen/eval/G0024/faulty/m4_i_sales_report.ddls.asddls @@ -0,0 +1,15 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Sales per product in a period' +define view entity {{P}}I_SALES_REPORT + with parameters + p_from : abap.dats, + p_to : abap.dats + as select from {{p}}sales as sale +{ + key sale.product as product, + sum( sale.quantity ) as total_qty, + sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount +} +where sale.sold_on >= $parameters.p_from + and sale.sold_on > $parameters.p_to +group by sale.product diff --git a/tasks_gen/eval/G0024/mutation.json b/tasks_gen/eval/G0024/mutation.json new file mode 100644 index 0000000..f6269d4 --- /dev/null +++ b/tasks_gen/eval/G0024/mutation.json @@ -0,0 +1,68 @@ +{ + "task": "G0024", + "mutants": [ + { + "object": "{{P}}I_SALES_REPORT", + "mutant": "line 10: sum( -> max( (agg)", + "status": "killed", + "hidden": "6/7", + "failed_tests": [ + "SUMS_QUANTITY" + ] + }, + { + "object": "{{P}}I_SALES_REPORT", + "mutant": "line 11: sum( -> max( (agg)", + "status": "killed", + "hidden": "6/7", + "failed_tests": [ + "SUMS_AMOUNT" + ] + }, + { + "object": "{{P}}I_SALES_REPORT", + "mutant": "line 13: >= -> < (rel)", + "status": "killed", + "hidden": "2/7", + "failed_tests": [ + "BOUNDS_INCLUSIVE", + "EXCLUDES_BEFORE_FROM", + "ROW_PER_PRODUCT", + "SUMS_AMOUNT", + "SUMS_QUANTITY" + ] + }, + { + "object": "{{P}}I_SALES_REPORT", + "mutant": "line 14: and -> or (logic)", + "status": "killed", + "hidden": "2/7", + "failed_tests": [ + "BOUNDS_INCLUSIVE", + "EMPTY_PERIOD", + "EXCLUDES_AFTER_TO", + "EXCLUDES_BEFORE_FROM", + "ROW_PER_PRODUCT" + ] + }, + { + "object": "{{P}}I_SALES_REPORT", + "mutant": "line 14: <= -> > (rel)", + "status": "killed", + "hidden": "0/7", + "failed_tests": [ + "BOUNDS_INCLUSIVE", + "EMPTY_PERIOD", + "EXCLUDES_AFTER_TO", + "EXCLUDES_BEFORE_FROM", + "ROW_PER_PRODUCT", + "SUMS_AMOUNT", + "SUMS_QUANTITY" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0025/faulty/m0_i_partner_all.ddls.asddls b/tasks_gen/eval/G0025/faulty/m0_i_partner_all.ddls.asddls new file mode 100644 index 0000000..c12bb81 --- /dev/null +++ b/tasks_gen/eval/G0025/faulty/m0_i_partner_all.ddls.asddls @@ -0,0 +1,19 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'All partners' +@Metadata.ignorePropagatedAnnotations: true +define view entity {{P}}I_PARTNER_ALL + as select from {{p}}part_a as a +{ + key a.partner_id as partner_id, + a.name as name, + a.city as city, + cast('Z' as abap.char(1)) as source +} +union all +select from {{p}}part_b as b +{ + key b.partner_id as partner_id, + b.name as name, + b.city as city, + cast('B' as abap.char(1)) as source +} diff --git a/tasks_gen/eval/G0025/faulty/m1_i_partner_all.ddls.asddls b/tasks_gen/eval/G0025/faulty/m1_i_partner_all.ddls.asddls new file mode 100644 index 0000000..4dbcc83 --- /dev/null +++ b/tasks_gen/eval/G0025/faulty/m1_i_partner_all.ddls.asddls @@ -0,0 +1,19 @@ +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'All partners' +@Metadata.ignorePropagatedAnnotations: true +define view entity {{P}}I_PARTNER_ALL + as select from {{p}}part_a as a +{ + key a.partner_id as partner_id, + a.name as name, + a.city as city, + cast('A' as abap.char(1)) as source +} +union all +select from {{p}}part_b as b +{ + key b.partner_id as partner_id, + b.name as name, + b.city as city, + cast('Z' as abap.char(1)) as source +} diff --git a/tasks_gen/eval/G0025/mutation.json b/tasks_gen/eval/G0025/mutation.json new file mode 100644 index 0000000..f7e7c73 --- /dev/null +++ b/tasks_gen/eval/G0025/mutation.json @@ -0,0 +1,32 @@ +{ + "task": "G0025", + "mutants": [ + { + "object": "{{P}}I_PARTNER_ALL", + "mutant": "line 10: 'A' -> 'Z' (lit)", + "status": "killed", + "hidden": "4/7", + "failed_tests": [ + "ONLY_IN_A", + "SAME_ID_TWICE", + "SOURCE_A_ROWS" + ] + }, + { + "object": "{{P}}I_PARTNER_ALL", + "mutant": "line 18: 'B' -> 'Z' (lit)", + "status": "killed", + "hidden": "3/7", + "failed_tests": [ + "NAME_AND_CITY", + "ONLY_IN_B", + "SAME_ID_TWICE", + "SOURCE_B_ROWS" + ] + } + ], + "valid": 2, + "killed": 2, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file diff --git a/tasks_gen/eval/G0026/faulty/m0_cl_rent.clas.abap b/tasks_gen/eval/G0026/faulty/m0_cl_rent.clas.abap new file mode 100644 index 0000000..ef37ac0 --- /dev/null +++ b/tasks_gen/eval/G0026/faulty/m0_cl_rent.clas.abap @@ -0,0 +1,158 @@ +CLASS {{p}}cl_rent DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + TYPES ty_class TYPE string. + TYPES ty_money TYPE decfloat34. + TYPES ty_err_code TYPE c LENGTH 1. + + CONSTANTS: BEGIN OF c_err, + ok TYPE ty_err_code VALUE ' ', + duration TYPE ty_err_code VALUE 'D', + distance TYPE ty_err_code VALUE 'K', + bad_class TYPE ty_err_code VALUE 'C', + END OF c_err. + + TYPES: BEGIN OF ty_request, + vehicle_class TYPE ty_class, + minutes TYPE i, + km TYPE i, + member TYPE abap_bool, + weekend TYPE abap_bool, + END OF ty_request. + + TYPES: BEGIN OF ty_result, + err_code TYPE ty_err_code, + time_fee TYPE ty_money, + distance_fee TYPE ty_money, + surcharge TYPE ty_money, + discount TYPE ty_money, + total TYPE ty_money, + END OF ty_result. + + CLASS-METHODS calculate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rs_result) TYPE ty_result. + + PRIVATE SECTION. + CONSTANTS: BEGIN OF c_block_price, + small TYPE ty_money VALUE '3.00', + medium TYPE ty_money VALUE '5.00', + large TYPE ty_money VALUE '8.00', + END OF c_block_price. + CONSTANTS c_block_minutes TYPE i VALUE 15. + CONSTANTS c_free_km TYPE i VALUE 10. + CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. + CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. + CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. + CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. + CONSTANTS c_decimals TYPE i VALUE 2. + + CLASS-METHODS validate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_err_code) TYPE ty_err_code. + + CLASS-METHODS time_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS distance_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS block_price + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_price) TYPE ty_money. + + CLASS-METHODS block_count + IMPORTING iv_minutes TYPE i + RETURNING VALUE(rv_blocks) TYPE i. + + CLASS-METHODS round_money + IMPORTING iv_value TYPE ty_money + RETURNING VALUE(rv_value) TYPE ty_money. +ENDCLASS. + + +CLASS {{p}}cl_rent IMPLEMENTATION. + METHOD calculate. + rs_result-err_code = validate( is_request ). + IF rs_result-err_code <> c_err-ok. + RETURN. + ENDIF. + + rs_result-time_fee = time_fee( is_request ). + rs_result-distance_fee = distance_fee( is_request ). + + IF is_request-weekend <> abap_true. + rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). + ELSE. + rs_result-surcharge = 0. + ENDIF. + + DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. + + IF is_request-member = abap_true. + rs_result-discount = round_money( lv_gross * c_member_share ). + ELSE. + rs_result-discount = 0. + ENDIF. + + rs_result-total = round_money( lv_gross - rs_result-discount ). + IF rs_result-total < c_min_total. + rs_result-total = c_min_total. + ENDIF. + ENDMETHOD. + + METHOD validate. + IF is_request-minutes < 1. + rv_err_code = c_err-duration. + ELSEIF is_request-km < 0. + rv_err_code = c_err-distance. + ELSEIF is_request-vehicle_class <> 'S' + AND is_request-vehicle_class <> 'M' + AND is_request-vehicle_class <> 'L'. + rv_err_code = c_err-bad_class. + ELSE. + rv_err_code = c_err-ok. + ENDIF. + ENDMETHOD. + + METHOD time_fee. + rv_fee = block_count( is_request-minutes ) * block_price( is_request ). + ENDMETHOD. + + METHOD distance_fee. + DATA(lv_chargeable_km) = is_request-km - c_free_km. + IF lv_chargeable_km > 0. + rv_fee = lv_chargeable_km * c_km_price. + ELSE. + rv_fee = 0. + ENDIF. + ENDMETHOD. + + METHOD block_price. + CASE is_request-vehicle_class. + WHEN 'S'. + rv_price = c_block_price-small. + WHEN 'M'. + rv_price = c_block_price-medium. + WHEN 'L'. + rv_price = c_block_price-large. + WHEN OTHERS. + rv_price = 0. + ENDCASE. + ENDMETHOD. + + METHOD block_count. + rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes. + ENDMETHOD. + + METHOD round_money. + rv_value = round( val = iv_value + dec = c_decimals + mode = cl_abap_math=>round_half_up ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0026/faulty/m1_cl_rent.clas.abap b/tasks_gen/eval/G0026/faulty/m1_cl_rent.clas.abap new file mode 100644 index 0000000..172e0f5 --- /dev/null +++ b/tasks_gen/eval/G0026/faulty/m1_cl_rent.clas.abap @@ -0,0 +1,158 @@ +CLASS {{p}}cl_rent DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + TYPES ty_class TYPE string. + TYPES ty_money TYPE decfloat34. + TYPES ty_err_code TYPE c LENGTH 1. + + CONSTANTS: BEGIN OF c_err, + ok TYPE ty_err_code VALUE ' ', + duration TYPE ty_err_code VALUE 'D', + distance TYPE ty_err_code VALUE 'K', + bad_class TYPE ty_err_code VALUE 'C', + END OF c_err. + + TYPES: BEGIN OF ty_request, + vehicle_class TYPE ty_class, + minutes TYPE i, + km TYPE i, + member TYPE abap_bool, + weekend TYPE abap_bool, + END OF ty_request. + + TYPES: BEGIN OF ty_result, + err_code TYPE ty_err_code, + time_fee TYPE ty_money, + distance_fee TYPE ty_money, + surcharge TYPE ty_money, + discount TYPE ty_money, + total TYPE ty_money, + END OF ty_result. + + CLASS-METHODS calculate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rs_result) TYPE ty_result. + + PRIVATE SECTION. + CONSTANTS: BEGIN OF c_block_price, + small TYPE ty_money VALUE '3.00', + medium TYPE ty_money VALUE '5.00', + large TYPE ty_money VALUE '8.00', + END OF c_block_price. + CONSTANTS c_block_minutes TYPE i VALUE 15. + CONSTANTS c_free_km TYPE i VALUE 10. + CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. + CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. + CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. + CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. + CONSTANTS c_decimals TYPE i VALUE 2. + + CLASS-METHODS validate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_err_code) TYPE ty_err_code. + + CLASS-METHODS time_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS distance_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS block_price + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_price) TYPE ty_money. + + CLASS-METHODS block_count + IMPORTING iv_minutes TYPE i + RETURNING VALUE(rv_blocks) TYPE i. + + CLASS-METHODS round_money + IMPORTING iv_value TYPE ty_money + RETURNING VALUE(rv_value) TYPE ty_money. +ENDCLASS. + + +CLASS {{p}}cl_rent IMPLEMENTATION. + METHOD calculate. + rs_result-err_code = validate( is_request ). + IF rs_result-err_code <> c_err-ok. + RETURN. + ENDIF. + + rs_result-time_fee = time_fee( is_request ). + rs_result-distance_fee = distance_fee( is_request ). + + IF is_request-weekend = abap_true. + rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). + ELSE. + rs_result-surcharge = 0. + ENDIF. + + DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. + + IF is_request-member = abap_true. + rs_result-discount = round_money( lv_gross * c_member_share ). + ELSE. + rs_result-discount = 0. + ENDIF. + + rs_result-total = round_money( lv_gross - rs_result-discount ). + IF rs_result-total < c_min_total. + rs_result-total = c_min_total. + ENDIF. + ENDMETHOD. + + METHOD validate. + IF is_request-minutes < 1. + rv_err_code = c_err-duration. + ELSEIF is_request-km >= 0. + rv_err_code = c_err-distance. + ELSEIF is_request-vehicle_class <> 'S' + AND is_request-vehicle_class <> 'M' + AND is_request-vehicle_class <> 'L'. + rv_err_code = c_err-bad_class. + ELSE. + rv_err_code = c_err-ok. + ENDIF. + ENDMETHOD. + + METHOD time_fee. + rv_fee = block_count( is_request-minutes ) * block_price( is_request ). + ENDMETHOD. + + METHOD distance_fee. + DATA(lv_chargeable_km) = is_request-km - c_free_km. + IF lv_chargeable_km > 0. + rv_fee = lv_chargeable_km * c_km_price. + ELSE. + rv_fee = 0. + ENDIF. + ENDMETHOD. + + METHOD block_price. + CASE is_request-vehicle_class. + WHEN 'S'. + rv_price = c_block_price-small. + WHEN 'M'. + rv_price = c_block_price-medium. + WHEN 'L'. + rv_price = c_block_price-large. + WHEN OTHERS. + rv_price = 0. + ENDCASE. + ENDMETHOD. + + METHOD block_count. + rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes. + ENDMETHOD. + + METHOD round_money. + rv_value = round( val = iv_value + dec = c_decimals + mode = cl_abap_math=>round_half_up ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0026/faulty/m2_cl_rent.clas.abap b/tasks_gen/eval/G0026/faulty/m2_cl_rent.clas.abap new file mode 100644 index 0000000..9f70c2a --- /dev/null +++ b/tasks_gen/eval/G0026/faulty/m2_cl_rent.clas.abap @@ -0,0 +1,158 @@ +CLASS {{p}}cl_rent DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + TYPES ty_class TYPE string. + TYPES ty_money TYPE decfloat34. + TYPES ty_err_code TYPE c LENGTH 1. + + CONSTANTS: BEGIN OF c_err, + ok TYPE ty_err_code VALUE ' ', + duration TYPE ty_err_code VALUE 'D', + distance TYPE ty_err_code VALUE 'K', + bad_class TYPE ty_err_code VALUE 'C', + END OF c_err. + + TYPES: BEGIN OF ty_request, + vehicle_class TYPE ty_class, + minutes TYPE i, + km TYPE i, + member TYPE abap_bool, + weekend TYPE abap_bool, + END OF ty_request. + + TYPES: BEGIN OF ty_result, + err_code TYPE ty_err_code, + time_fee TYPE ty_money, + distance_fee TYPE ty_money, + surcharge TYPE ty_money, + discount TYPE ty_money, + total TYPE ty_money, + END OF ty_result. + + CLASS-METHODS calculate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rs_result) TYPE ty_result. + + PRIVATE SECTION. + CONSTANTS: BEGIN OF c_block_price, + small TYPE ty_money VALUE '3.00', + medium TYPE ty_money VALUE '5.00', + large TYPE ty_money VALUE '8.00', + END OF c_block_price. + CONSTANTS c_block_minutes TYPE i VALUE 15. + CONSTANTS c_free_km TYPE i VALUE 10. + CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. + CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. + CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. + CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. + CONSTANTS c_decimals TYPE i VALUE 2. + + CLASS-METHODS validate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_err_code) TYPE ty_err_code. + + CLASS-METHODS time_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS distance_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS block_price + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_price) TYPE ty_money. + + CLASS-METHODS block_count + IMPORTING iv_minutes TYPE i + RETURNING VALUE(rv_blocks) TYPE i. + + CLASS-METHODS round_money + IMPORTING iv_value TYPE ty_money + RETURNING VALUE(rv_value) TYPE ty_money. +ENDCLASS. + + +CLASS {{p}}cl_rent IMPLEMENTATION. + METHOD calculate. + rs_result-err_code = validate( is_request ). + IF rs_result-err_code <> c_err-ok. + RETURN. + ENDIF. + + rs_result-time_fee = time_fee( is_request ). + rs_result-distance_fee = distance_fee( is_request ). + + IF is_request-weekend = abap_true. + rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). + ELSE. + rs_result-surcharge = 0. + ENDIF. + + DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. + + IF is_request-member = abap_true. + rs_result-discount = round_money( lv_gross * c_member_share ). + ELSE. + rs_result-discount = 0. + ENDIF. + + rs_result-total = round_money( lv_gross - rs_result-discount ). + IF rs_result-total < c_min_total. + rs_result-total = c_min_total. + ENDIF. + ENDMETHOD. + + METHOD validate. + IF is_request-minutes < 1. + rv_err_code = c_err-duration. + ELSEIF is_request-km < 0. + rv_err_code = c_err-distance. + ELSEIF is_request-vehicle_class <> 'S' + OR is_request-vehicle_class <> 'M' + AND is_request-vehicle_class <> 'L'. + rv_err_code = c_err-bad_class. + ELSE. + rv_err_code = c_err-ok. + ENDIF. + ENDMETHOD. + + METHOD time_fee. + rv_fee = block_count( is_request-minutes ) * block_price( is_request ). + ENDMETHOD. + + METHOD distance_fee. + DATA(lv_chargeable_km) = is_request-km - c_free_km. + IF lv_chargeable_km > 0. + rv_fee = lv_chargeable_km * c_km_price. + ELSE. + rv_fee = 0. + ENDIF. + ENDMETHOD. + + METHOD block_price. + CASE is_request-vehicle_class. + WHEN 'S'. + rv_price = c_block_price-small. + WHEN 'M'. + rv_price = c_block_price-medium. + WHEN 'L'. + rv_price = c_block_price-large. + WHEN OTHERS. + rv_price = 0. + ENDCASE. + ENDMETHOD. + + METHOD block_count. + rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes. + ENDMETHOD. + + METHOD round_money. + rv_value = round( val = iv_value + dec = c_decimals + mode = cl_abap_math=>round_half_up ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0026/faulty/m3_cl_rent.clas.abap b/tasks_gen/eval/G0026/faulty/m3_cl_rent.clas.abap new file mode 100644 index 0000000..0d57a2c --- /dev/null +++ b/tasks_gen/eval/G0026/faulty/m3_cl_rent.clas.abap @@ -0,0 +1,158 @@ +CLASS {{p}}cl_rent DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + TYPES ty_class TYPE string. + TYPES ty_money TYPE decfloat34. + TYPES ty_err_code TYPE c LENGTH 1. + + CONSTANTS: BEGIN OF c_err, + ok TYPE ty_err_code VALUE ' ', + duration TYPE ty_err_code VALUE 'D', + distance TYPE ty_err_code VALUE 'K', + bad_class TYPE ty_err_code VALUE 'C', + END OF c_err. + + TYPES: BEGIN OF ty_request, + vehicle_class TYPE ty_class, + minutes TYPE i, + km TYPE i, + member TYPE abap_bool, + weekend TYPE abap_bool, + END OF ty_request. + + TYPES: BEGIN OF ty_result, + err_code TYPE ty_err_code, + time_fee TYPE ty_money, + distance_fee TYPE ty_money, + surcharge TYPE ty_money, + discount TYPE ty_money, + total TYPE ty_money, + END OF ty_result. + + CLASS-METHODS calculate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rs_result) TYPE ty_result. + + PRIVATE SECTION. + CONSTANTS: BEGIN OF c_block_price, + small TYPE ty_money VALUE '3.00', + medium TYPE ty_money VALUE '5.00', + large TYPE ty_money VALUE '8.00', + END OF c_block_price. + CONSTANTS c_block_minutes TYPE i VALUE 15. + CONSTANTS c_free_km TYPE i VALUE 10. + CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. + CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. + CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. + CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. + CONSTANTS c_decimals TYPE i VALUE 2. + + CLASS-METHODS validate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_err_code) TYPE ty_err_code. + + CLASS-METHODS time_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS distance_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS block_price + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_price) TYPE ty_money. + + CLASS-METHODS block_count + IMPORTING iv_minutes TYPE i + RETURNING VALUE(rv_blocks) TYPE i. + + CLASS-METHODS round_money + IMPORTING iv_value TYPE ty_money + RETURNING VALUE(rv_value) TYPE ty_money. +ENDCLASS. + + +CLASS {{p}}cl_rent IMPLEMENTATION. + METHOD calculate. + rs_result-err_code = validate( is_request ). + IF rs_result-err_code <> c_err-ok. + RETURN. + ENDIF. + + rs_result-time_fee = time_fee( is_request ). + rs_result-distance_fee = distance_fee( is_request ). + + IF is_request-weekend = abap_true. + rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). + ELSE. + rs_result-surcharge = 0. + ENDIF. + + DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. + + IF is_request-member = abap_true. + rs_result-discount = round_money( lv_gross * c_member_share ). + ELSE. + rs_result-discount = 0. + ENDIF. + + rs_result-total = round_money( lv_gross - rs_result-discount ). + IF rs_result-total < c_min_total. + rs_result-total = c_min_total. + ENDIF. + ENDMETHOD. + + METHOD validate. + IF is_request-minutes < 1. + rv_err_code = c_err-duration. + ELSEIF is_request-km < 0. + rv_err_code = c_err-distance. + ELSEIF is_request-vehicle_class <> 'S' + AND is_request-vehicle_class <> 'M' + AND is_request-vehicle_class <> 'L'. + rv_err_code = c_err-bad_class. + ELSE. + rv_err_code = c_err-ok. + ENDIF. + ENDMETHOD. + + METHOD time_fee. + rv_fee = block_count( is_request-minutes ) / block_price( is_request ). + ENDMETHOD. + + METHOD distance_fee. + DATA(lv_chargeable_km) = is_request-km - c_free_km. + IF lv_chargeable_km > 0. + rv_fee = lv_chargeable_km * c_km_price. + ELSE. + rv_fee = 0. + ENDIF. + ENDMETHOD. + + METHOD block_price. + CASE is_request-vehicle_class. + WHEN 'S'. + rv_price = c_block_price-small. + WHEN 'M'. + rv_price = c_block_price-medium. + WHEN 'L'. + rv_price = c_block_price-large. + WHEN OTHERS. + rv_price = 0. + ENDCASE. + ENDMETHOD. + + METHOD block_count. + rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes. + ENDMETHOD. + + METHOD round_money. + rv_value = round( val = iv_value + dec = c_decimals + mode = cl_abap_math=>round_half_up ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0026/faulty/m4_cl_rent.clas.abap b/tasks_gen/eval/G0026/faulty/m4_cl_rent.clas.abap new file mode 100644 index 0000000..9f7bfef --- /dev/null +++ b/tasks_gen/eval/G0026/faulty/m4_cl_rent.clas.abap @@ -0,0 +1,158 @@ +CLASS {{p}}cl_rent DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + TYPES ty_class TYPE string. + TYPES ty_money TYPE decfloat34. + TYPES ty_err_code TYPE c LENGTH 1. + + CONSTANTS: BEGIN OF c_err, + ok TYPE ty_err_code VALUE ' ', + duration TYPE ty_err_code VALUE 'D', + distance TYPE ty_err_code VALUE 'K', + bad_class TYPE ty_err_code VALUE 'C', + END OF c_err. + + TYPES: BEGIN OF ty_request, + vehicle_class TYPE ty_class, + minutes TYPE i, + km TYPE i, + member TYPE abap_bool, + weekend TYPE abap_bool, + END OF ty_request. + + TYPES: BEGIN OF ty_result, + err_code TYPE ty_err_code, + time_fee TYPE ty_money, + distance_fee TYPE ty_money, + surcharge TYPE ty_money, + discount TYPE ty_money, + total TYPE ty_money, + END OF ty_result. + + CLASS-METHODS calculate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rs_result) TYPE ty_result. + + PRIVATE SECTION. + CONSTANTS: BEGIN OF c_block_price, + small TYPE ty_money VALUE '3.00', + medium TYPE ty_money VALUE '5.00', + large TYPE ty_money VALUE '8.00', + END OF c_block_price. + CONSTANTS c_block_minutes TYPE i VALUE 15. + CONSTANTS c_free_km TYPE i VALUE 10. + CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. + CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. + CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. + CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. + CONSTANTS c_decimals TYPE i VALUE 2. + + CLASS-METHODS validate + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_err_code) TYPE ty_err_code. + + CLASS-METHODS time_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS distance_fee + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_fee) TYPE ty_money. + + CLASS-METHODS block_price + IMPORTING is_request TYPE ty_request + RETURNING VALUE(rv_price) TYPE ty_money. + + CLASS-METHODS block_count + IMPORTING iv_minutes TYPE i + RETURNING VALUE(rv_blocks) TYPE i. + + CLASS-METHODS round_money + IMPORTING iv_value TYPE ty_money + RETURNING VALUE(rv_value) TYPE ty_money. +ENDCLASS. + + +CLASS {{p}}cl_rent IMPLEMENTATION. + METHOD calculate. + rs_result-err_code = validate( is_request ). + IF rs_result-err_code <> c_err-ok. + RETURN. + ENDIF. + + rs_result-time_fee = time_fee( is_request ). + rs_result-distance_fee = distance_fee( is_request ). + + IF is_request-weekend = abap_true. + rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). + ELSE. + rs_result-surcharge = 0. + ENDIF. + + DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. + + IF is_request-member = abap_true. + rs_result-discount = round_money( lv_gross * c_member_share ). + ELSE. + rs_result-discount = 0. + ENDIF. + + rs_result-total = round_money( lv_gross - rs_result-discount ). + IF rs_result-total < c_min_total. + rs_result-total = c_min_total. + ENDIF. + ENDMETHOD. + + METHOD validate. + IF is_request-minutes < 1. + rv_err_code = c_err-duration. + ELSEIF is_request-km < 0. + rv_err_code = c_err-distance. + ELSEIF is_request-vehicle_class <> 'S' + AND is_request-vehicle_class <> 'M' + AND is_request-vehicle_class <> 'L'. + rv_err_code = c_err-bad_class. + ELSE. + rv_err_code = c_err-ok. + ENDIF. + ENDMETHOD. + + METHOD time_fee. + rv_fee = block_count( is_request-minutes ) * block_price( is_request ). + ENDMETHOD. + + METHOD distance_fee. + DATA(lv_chargeable_km) = is_request-km - c_free_km. + IF lv_chargeable_km > 0. + rv_fee = lv_chargeable_km * c_km_price. + ELSE. + rv_fee = 0. + ENDIF. + ENDMETHOD. + + METHOD block_price. + CASE is_request-vehicle_class. + WHEN 'S'. + rv_price = c_block_price-small. + WHEN 'M'. + rv_price = c_block_price-medium. + WHEN 'L'. + rv_price = c_block_price-large. + WHEN OTHERS. + rv_price = 0. + ENDCASE. + ENDMETHOD. + + METHOD block_count. + rv_blocks = ( iv_minutes + c_block_minutes - 2 ) DIV c_block_minutes. + ENDMETHOD. + + METHOD round_money. + rv_value = round( val = iv_value + dec = c_decimals + mode = cl_abap_math=>round_half_up ). + ENDMETHOD. +ENDCLASS. diff --git a/tasks_gen/eval/G0026/mutation.json b/tasks_gen/eval/G0026/mutation.json new file mode 100644 index 0000000..05f685c --- /dev/null +++ b/tasks_gen/eval/G0026/mutation.json @@ -0,0 +1,75 @@ +{ + "task": "G0026", + "mutants": [ + { + "object": "{{P}}CL_RENT", + "mutant": "line 89: = -> <> (eq)", + "status": "killed", + "hidden": "5/10", + "failed_tests": [ + "DISTANCE_FEE_FREE_KM", + "MEMBER_DISCOUNT", + "MINIMUM_TOTAL_MEMBER", + "WEEKDAY_NO_SURCHARGE", + "WEEKEND_SURCHARGE" + ] + }, + { + "object": "{{P}}CL_RENT", + "mutant": "line 112: < -> >= (rel)", + "status": "killed", + "hidden": "2/10", + "failed_tests": [ + "DISTANCE_FEE_FREE_KM", + "INVALID_CLASS", + "INVALID_DISTANCE", + "MEMBER_DISCOUNT", + "MINIMUM_TOTAL", + "MINIMUM_TOTAL_MEMBER", + "TIME_FEE_BLOCKS", + "WEEKEND_SURCHARGE" + ] + }, + { + "object": "{{P}}CL_RENT", + "mutant": "line 115: AND -> OR (logic)", + "status": "killed", + "hidden": "4/10", + "failed_tests": [ + "DISTANCE_FEE_FREE_KM", + "MEMBER_DISCOUNT", + "MINIMUM_TOTAL", + "MINIMUM_TOTAL_MEMBER", + "TIME_FEE_BLOCKS", + "WEEKEND_SURCHARGE" + ] + }, + { + "object": "{{P}}CL_RENT", + "mutant": "line 124: * -> / (arith)", + "status": "killed", + "hidden": "4/10", + "failed_tests": [ + "DISTANCE_FEE_FREE_KM", + "MEMBER_DISCOUNT", + "MINIMUM_TOTAL", + "MINIMUM_TOTAL_MEMBER", + "TIME_FEE_BLOCKS", + "WEEKEND_SURCHARGE" + ] + }, + { + "object": "{{P}}CL_RENT", + "mutant": "line 150: 1 -> 2 (const)", + "status": "killed", + "hidden": "9/10", + "failed_tests": [ + "TIME_FEE_BLOCKS" + ] + } + ], + "valid": 5, + "killed": 5, + "kill_rate": 1.0, + "ok": true +} \ No newline at end of file