<commit_before>#include "calc.h"
#include "sevensegment.h"
#include "pocketcalculator.h"

#include "cute.h"
#include "ide_listener.h"
#include "xml_listener.h"
#include "cute_runner.h"

#include <string>
#include <sstream>
#include <limits>
#include <algorithm>

namespace calc_tests {
	constexpr int max { std::numeric_limits<int>::max() },
				  min { std::numeric_limits<int>::min() };
	void multiplies_positive_numbers() {
		ASSERT_EQUAL(20, calc(4, 5, '*'));
	}
	void multiplies_negative_with_positive_number() {
		ASSERT_EQUAL(-30, calc(-6, 5, '*'));
	}
	void multiplies_negative_numbers() {
		ASSERT_EQUAL(20, calc(-4, -5, '*'));
	}
	void recognizes_overflows_when_multiplying() {
		calc(1, max, '*');
		calc(1, min, '*');
		calc(-1, max, '*');
		calc(-1, min+1, '*');
		calc(2, max/2, '*');
		calc(2, min/2, '*');
		calc(-2, max/2, '*');
		calc(-2, min/2+1, '*');

		ASSERT_THROWS(calc(4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(4, min/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, min/3, '*'), std::overflow_error);
	}
	void divides() {
		ASSERT_EQUAL(5, calc(60, 12, '/'));
		ASSERT_EQUAL(-3, calc(9, -3, '/'));
	}
	void throws_when_dividing_by_zero() {
		ASSERT_THROWS(calc(1, 0, '/'), std::domain_error);
	}
	void adds() {
		ASSERT_EQUAL(5, calc(2, 3, '+'));
		ASSERT_EQUAL(-10, calc(-6, -4, '+'));
	}
	void recognizes_overflows_when_adding() {
		calc(max, 0, '+'); // must not throw
		ASSERT_THROWS(calc(max, 1, '+'), std::overflow_error);
		calc(min, 0, '+'); // must not throw
		ASSERT_THROWS(calc(min, -1, '+'), std::overflow_error);
	}
	void subtracts() {
		ASSERT_EQUAL(17, calc(20, 3, '-'));
		ASSERT_EQUAL(-5, calc(-2, 3, '-'));
	}
	void recognizes_overflows_when_subtracting() {
		calc(max, 0, '-'); // must not throw
		ASSERT_THROWS(calc(max, -1, '-'), std::overflow_error);
		calc(min, 0, '-'); // must not throw
		ASSERT_THROWS(calc(min, 1, '-'), std::overflow_error);
	}
	void knows_modulo() {
		ASSERT_EQUAL(5, calc(15, 10, '%'));
		ASSERT_EQUAL(-5, calc(-15, 10, '%'));
	}
	void throws_when_modulo_zero() {
		ASSERT_THROWS(calc(10, 0, '%'), std::domain_error);
	}
	void throws_when_given_invalid_operator() {
		ASSERT_THROWS(calc(1, 1, '^'), std::runtime_error);
	}

	void takes_term_from_istream() {
		std::istringstream term_stream { "1+1" };
		int result = calc(term_stream);
		ASSERT_EQUAL(2, result);
	}

	const std::vector<std::string> invalid_terms {
        "foobar",
        "3+2-",
        "1",
        "8--",
        "*",
        "4%%6",
        "3//7",
	};

    void throws_when_given_invalid_term() {
		for(auto const term : invalid_terms) {
			std::istringstream term_stream { term };
			ASSERT_THROWS(calc(term_stream), std::exception); // TODO: more specific?
		}
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(multiplies_positive_numbers));
		s.push_back(CUTE(multiplies_negative_with_positive_number));
		s.push_back(CUTE(multiplies_negative_numbers));
		s.push_back(CUTE(recognizes_overflows_when_multiplying));
		s.push_back(CUTE(divides));
		s.push_back(CUTE(throws_when_dividing_by_zero));
		s.push_back(CUTE(adds));
		s.push_back(CUTE(recognizes_overflows_when_adding));
		s.push_back(CUTE(subtracts));
		s.push_back(CUTE(recognizes_overflows_when_subtracting));<commit_msg>split multiply overflow test into two tests<commit_after>#include "calc.h"
#include "sevensegment.h"
#include "pocketcalculator.h"

#include "cute.h"
#include "ide_listener.h"
#include "xml_listener.h"
#include "cute_runner.h"

#include <string>
#include <sstream>
#include <limits>
#include <algorithm>

namespace calc_tests {
	constexpr int max { std::numeric_limits<int>::max() },
				  min { std::numeric_limits<int>::min() };
	void multiplies_positive_numbers() {
		ASSERT_EQUAL(20, calc(4, 5, '*'));
	}
	void multiplies_negative_with_positive_number() {
		ASSERT_EQUAL(-30, calc(-6, 5, '*'));
	}
	void multiplies_negative_numbers() {
		ASSERT_EQUAL(20, calc(-4, -5, '*'));
	}
	void recognizes_overflows_when_multiplying() {
		ASSERT_THROWS(calc(4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(4, min/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, min/3, '*'), std::overflow_error);
	}
	void doesnt_overflow_near_limits() {
		calc(1, max, '*');
		calc(1, min, '*');
		calc(-1, max, '*');
		calc(-1, min+1, '*');
		calc(2, max/2, '*');
		calc(2, min/2, '*');
		calc(-2, max/2, '*');
		calc(-2, min/2+1, '*');
	}
	void divides() {
		ASSERT_EQUAL(5, calc(60, 12, '/'));
		ASSERT_EQUAL(-3, calc(9, -3, '/'));
	}
	void throws_when_dividing_by_zero() {
		ASSERT_THROWS(calc(1, 0, '/'), std::domain_error);
	}
	void adds() {
		ASSERT_EQUAL(5, calc(2, 3, '+'));
		ASSERT_EQUAL(-10, calc(-6, -4, '+'));
	}
	void recognizes_overflows_when_adding() {
		calc(max, 0, '+'); // must not throw
		ASSERT_THROWS(calc(max, 1, '+'), std::overflow_error);
		calc(min, 0, '+'); // must not throw
		ASSERT_THROWS(calc(min, -1, '+'), std::overflow_error);
	}
	void subtracts() {
		ASSERT_EQUAL(17, calc(20, 3, '-'));
		ASSERT_EQUAL(-5, calc(-2, 3, '-'));
	}
	void recognizes_overflows_when_subtracting() {
		calc(max, 0, '-'); // must not throw
		ASSERT_THROWS(calc(max, -1, '-'), std::overflow_error);
		calc(min, 0, '-'); // must not throw
		ASSERT_THROWS(calc(min, 1, '-'), std::overflow_error);
	}
	void knows_modulo() {
		ASSERT_EQUAL(5, calc(15, 10, '%'));
		ASSERT_EQUAL(-5, calc(-15, 10, '%'));
	}
	void throws_when_modulo_zero() {
		ASSERT_THROWS(calc(10, 0, '%'), std::domain_error);
	}
	void throws_when_given_invalid_operator() {
		ASSERT_THROWS(calc(1, 1, '^'), std::runtime_error);
	}

	void takes_term_from_istream() {
		std::istringstream term_stream { "1+1" };
		int result = calc(term_stream);
		ASSERT_EQUAL(2, result);
	}

	const std::vector<std::string> invalid_terms {
        "foobar",
        "3+2-",
        "1",
        "8--",
        "*",
        "4%%6",
        "3//7",
	};

    void throws_when_given_invalid_term() {
		for(auto const term : invalid_terms) {
			std::istringstream term_stream { term };
			ASSERT_THROWS(calc(term_stream), std::exception); // TODO: more specific?
		}
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(multiplies_positive_numbers));
		s.push_back(CUTE(multiplies_negative_with_positive_number));
		s.push_back(CUTE(multiplies_negative_numbers));
		s.push_back(CUTE(recognizes_overflows_when_multiplying));
		s.push_back(CUTE(doesnt_overflow_near_limits));
		s.push_back(CUTE(divides));
		s.push_back(CUTE(throws_when_dividing_by_zero));
		s.push_back(CUTE(adds));
		s.push_back(CUTE(recognizes_overflows_when_adding));
		s.push_back(CUTE(subtracts));
		s.push_back(CUTE(recognizes_overflows_when_subtracting));
{'fraction_non_alphanumeric': 0.19858365299498376, 'fraction_numerical': 0.027441723222189435, 'mean_word_length': 4.864186851211072, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2224789', 'n_tokens_mistral': 2934, 'n_tokens_neox': 2663, 'n_words': 416}