LCOV - code coverage report
Current view: top level - calculator - CalculatorApp.java (source / functions) Coverage Total Hit
Test: Documentation coverage (linux) Lines: 80.0 % 5 4
Test Date: 2026-09-30 03:11:16 Functions: - 0 0
Legend: Lines: hit not hit

            Line data    Source code
       1            1 : /**
       2              : 
       3              : @file CalculatorApp.java
       4              : @brief This file serves as the main application file for the Calculator App.
       5              : @details This file contains the entry point of the application, which is the main method. It initializes the necessary components and executes the Calculator App.
       6              : */
       7              : /**
       8              : 
       9              : @package com.ucoruh.calculator
      10              : @brief The com.ucoruh.calculator package contains all the classes and files related to the Calculator App.
      11              : */
      12              : package com.ucoruh.calculator;
      13              : 
      14              : import org.slf4j.LoggerFactory;
      15              : 
      16              : import ch.qos.logback.classic.Logger;
      17              : 
      18              : /**
      19              :  *
      20              :  * @class CalculatorApp
      21              :  * @brief This class represents the main application class for the Calculator
      22              :  *        App.
      23              :  * @details The CalculatorApp class provides the entry point for the Calculator
      24              :  *          App. It parses three command-line arguments (operand, operator,
      25              :  *          operand), computes the result with {@link Calculator} and prints
      26              :  *          it. It never reads from standard input, so it is safe to run from
      27              :  *          a non-interactive script and to unit test directly.
      28              :  * @author ugur.coruh
      29              :  */
      30            1 : public class CalculatorApp {
      31              :   /**
      32              :    * @brief Logger for the CalculatorApp class.
      33              :    */
      34            1 :   private static final Logger logger = (Logger) LoggerFactory.getLogger(CalculatorApp.class);
      35              : 
      36              :   /**
      37              :    * @brief Usage message shown when the arguments do not describe a single
      38              :    *        binary operation.
      39              :    */
      40              :   static final String USAGE = "Usage: CalculatorApp <number> <+|-|*|/> <number>";
      41              : 
      42            0 :   private CalculatorApp() {
      43              :     // Utility/entry-point class: not meant to be instantiated.
      44              :   }
      45              : 
      46              :   /**
      47              :    * @brief The main entry point of the Calculator App.
      48              :    *
      49              :    * @details Delegates all the work to {@link #run(String[])} and prints its
      50              :    *          result. Kept deliberately thin so that the parsing/calculation
      51              :    *          logic in `run` can be unit tested without touching the console.
      52              :    *
      53              :    * @param args The command-line arguments passed to the application:
      54              :    *             `<number> <operator> <number>`.
      55              :    */
      56            1 :   public static void main(String[] args) {
      57              :     System.out.println(run(args));
      58              :   }
      59              : 
      60              :   /**
      61              :    * @brief Parses `args` as `<number> <operator> <number>` and computes the
      62              :    *        result.
      63              :    *
      64              :    * @details This is the testable core of the application: it performs no
      65              :    *          I/O (it neither reads from `System.in` nor writes to
      66              :    *          `System.out`) and never blocks, so it can be called directly
      67              :    *          from tests and from scripts alike. Recognized operators are
      68              :    *          `+`, `-`, `*` and `/`. Invalid input (wrong argument count,
      69              :    *          non-numeric operand, unknown operator, division by zero) is
      70              :    *          reported as a descriptive `"Error: ..."` string instead of an
      71              :    *          uncaught exception, so the process always exits cleanly with a
      72              :    *          printable message.
      73              :    *
      74              :    * @param args The command-line arguments.
      75              :    * @return A human-readable result or error message.
      76              :    */
      77              :   static String run(String[] args) {
      78              :     if (args == null || args.length != 3) {
      79              :       logger.warn("Expected 3 arguments, got {}", args == null ? 0 : args.length);
      80              :       return USAGE;
      81              :     }
      82              : 
      83              :     final int left;
      84              :     final int right;
      85              : 
      86              :     try {
      87              :       left = Integer.parseInt(args[0]);
      88              :       right = Integer.parseInt(args[2]);
      89              :     } catch (NumberFormatException e) {
      90              :       logger.error("Invalid operand: {}", e.toString());
      91              :       return "Error: operands must be integers. " + USAGE;
      92              :     }
      93              : 
      94              :     String operator = args[1];
      95              :     Calculator calculator = new Calculator();
      96              : 
      97              :     switch (operator) {
      98              :       case "+":
      99              :         return String.valueOf(calculator.add(left, right));
     100              : 
     101              :       case "-":
     102              :         return String.valueOf(calculator.subtract(left, right));
     103              : 
     104              :       case "*":
     105              :         return String.valueOf(calculator.multiply(left, right));
     106              : 
     107              :       case "/":
     108              :         try {
     109              :           return String.valueOf(calculator.divide(left, right));
     110              :         } catch (ArithmeticException e) {
     111              :           logger.error("Division by zero requested");
     112              :           return "Error: division by zero";
     113              :         }
     114              : 
     115              :       default:
     116              :         logger.warn("Unknown operator: {}", operator);
     117              :         return "Error: unknown operator '" + operator + "'. " + USAGE;
     118              :     }
     119              :   }
     120              : }
        

Generated by: LCOV version 2.0-1