<commit_before>﻿using Mond.VirtualMachine;
using NUnit.Framework;

namespace Mond.Tests
{
    [TestFixture]
    public class MondValueTests
    {
        #region Operators

        private MondValue _left;
        private MondValue _right;

        [Test]
        public void OperatorAdd()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left + _right, new MondValue(10 + 5));

            _left = "abc";
            _right = "def";
            Assert.AreEqual(_left + _right, new MondValue("abc" + "def"));

            _left = "abc";
            _right = 123;
            Assert.AreEqual(_left + _right, new MondValue("abc" + 123));

            _left = 123;
            _right = "abc";
            Assert.AreEqual(_left + _right, new MondValue(123 + "abc"));

            _left = MondValue.Null;
            _right = "abc";
            Assert.AreEqual(_left + _right, new MondValue("null" + "abc")); // TODO: this shouldn't be allowed imo

            _left = MondValue.Null;
            _right = MondValue.Null;
            Assert.Throws<MondRuntimeException>(() => { _left += _right; });
        }

        [Test]
        public void OperatorSubtract()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left - _right, new MondValue(10 - 5));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left -= _right; });
        }

        [Test]
        public void OperatorMultiply()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left * _right, new MondValue(10 * 5));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left *= _right; });
        }

        [Test]
        public void OperatorDivide()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left / _right, new MondValue(10.0 / 7.0));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left /= _right; });
        }

        [Test]
        public void OperatorModulo()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left % _right, new MondValue(10.0 % 7.0));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left %= _right; });
        }

        [Test]
        public void OperatorNegate()
        {
            _left = 10;
            Assert.AreEqual(-_left, new MondValue(-10));

            _left = "10";
            Assert.Throws<MondRuntimeException>(() => { _left = -_left; });
        }

        [Test]
        public void OperatorEqualTo()
        {
            _left = 10;
            _right = 10;
            Assert.True(_left == _right);

            _left = 10;
            _right = 11;
            Assert.False(_left == _right);

            _left = "10";
            _right = 10;
            Assert.False(_left == _right); // no ty

            _left = MondValue.Null;
            _right = MondValue.Undefined;
            Assert.False(_left == _right);

            _left = new MondValue(MondValueType.Object);
            _right = _left;
            Assert.True(_left == _right);
        }

        [Test]
        public void OperatorGreaterThan()
        {
            _left = 11;
            _right = 10;
            Assert.True(_left > _right);

            _left = 10;
            _right = 10;
            Assert.False(_left > _right);

            _left = 9;
            _right = 10;
            Assert.False(_left > _right);

            _left = "a";
            _right = "b";
            Assert.False(_left > _right);

            _left = MondValue.Null;
            _right = 10;
            Assert.Throws<MondRuntimeException>(() => { var a = _left > _right; });
        }

        #endregion

        [Test]
        public void ImplicitBool()
        {
            var value = MondValue.Undefined;
            Assert.False(value);

            value = MondValue.Null;
            Assert.False(value);

            value = MondValue.False;
            Assert.False(value);

            value = MondValue.True;
            Assert.True(value);

            value = new MondValue(MondValueType.Object);
            Assert.True(value);
        }

        [Test]
        public void ObjectFieldIndexer()
        {
            var obj = new MondValue(MondValueType.Object);

            Assert.True(obj["undef"] == MondValue.Undefined);

            Assert.True(obj["setPrototype"] != MondValue.Undefined);

            obj["test"] = 123;
            Assert.True(obj["test"] == 123);

            obj[123] = "test";
            Assert.True(obj[123] == "test");
        }

        [Test]
        public void ArrayIndexer()
        {<commit_msg>Add missing MondValue operator tests<commit_after>﻿using System;
using Mond.VirtualMachine;
using NUnit.Framework;

namespace Mond.Tests
{
    [TestFixture]
    public class MondValueTests
    {
        #region Operators

        private MondValue _left;
        private MondValue _right;

        [Test]
        public void OperatorAdd()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left + _right, new MondValue(10 + 5));

            _left = "abc";
            _right = "def";
            Assert.AreEqual(_left + _right, new MondValue("abc" + "def"));

            _left = "abc";
            _right = 123;
            Assert.AreEqual(_left + _right, new MondValue("abc" + 123));

            _left = 123;
            _right = "abc";
            Assert.AreEqual(_left + _right, new MondValue(123 + "abc"));

            _left = MondValue.Null;
            _right = "abc";
            Assert.AreEqual(_left + _right, new MondValue("null" + "abc")); // TODO: this shouldn't be allowed imo

            _left = MondValue.Null;
            _right = MondValue.Null;
            Assert.Throws<MondRuntimeException>(() => { _left += _right; });
        }

        [Test]
        public void OperatorSubtract()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left - _right, new MondValue(10 - 5));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left -= _right; });
        }

        [Test]
        public void OperatorMultiply()
        {
            _left = 10;
            _right = 5;
            Assert.AreEqual(_left * _right, new MondValue(10 * 5));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left *= _right; });
        }

        [Test]
        public void OperatorDivide()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left / _right, new MondValue(10.0 / 7.0));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left /= _right; });
        }

        [Test]
        public void OperatorModulo()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left % _right, new MondValue(10.0 % 7.0));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left %= _right; });
        }

        [Test]
        public void OperatorPow()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left.Pow(_right), new MondValue(Math.Pow(10.0, 7.0)));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left = _left.Pow(_right); });
        }

        [Test]
        public void OperatorLShift()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left.LShift(_right), new MondValue(10 << 7));

            _left = 10.0;
            Assert.AreEqual(_left << 7, new MondValue(10 << 7));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left = _left.LShift(_right); });

            _left = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left = _left.LShift(_right); });
        }

        [Test]
        public void OperatorRShift()
        {
            _left = 10.0;
            _right = 2.0;
            Assert.AreEqual(_left.RShift(_right), new MondValue(10 >> 2));

            _left = 10.0;
            Assert.AreEqual(_left >> 2, new MondValue(10 >> 2));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left = _left.RShift(_right); });

            _left = "abc";
            _right = 2.0;
            Assert.Throws<MondRuntimeException>(() => { _left = _left.RShift(_right); });
        }

        [Test]
        public void OperatorAnd()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left & _right, new MondValue(10 & 7));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left &= _right; });
        }

        [Test]
        public void OperatorOr()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left | _right, new MondValue(10 | 7));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left |= _right; });
        }

        [Test]
        public void OperatorXor()
        {
            _left = 10.0;
            _right = 7.0;
            Assert.AreEqual(_left ^ _right, new MondValue(10 ^ 7));

            _left = 123;
            _right = "abc";
            Assert.Throws<MondRuntimeException>(() => { _left ^= _right; });
        }

        [Test]
        public void OperatorNegate()
        {
            _left = 10;
            Assert.AreEqual(-_left, new MondValue(-10));

            _left = "10";
            Assert.Throws<MondRuntimeException>(() => { _left = -_left; });
        }

        [Test]
        public void OperatorNot()
        {
            _left = 10;
            Assert.AreEqual(~_left, new MondValue(~10));

            _left = "10";
            Assert.Throws<MondRuntimeException>(() => { _left = ~_left; });
        }

        [Test]
        public void OperatorEqualTo()
        {
            _left = 10;
            _right = 10;
            Assert.True(_left == _right);

            _left = 10;
            _right = 11;
            Assert.False(_left == _right);

            _left = "10";
            _right = 10;
            Assert.False(_left == _right); // no ty

            _left = MondValue.Null;
            _right = MondValue.Undefined;
            Assert.False(_left == _right);

            _left = new MondValue(MondValueType.Object);
            _right = _left;
            Assert.True(_left == _right);
        }

        [Test]
        public void OperatorNotEqualTo()
        {
            _left = 10;
            _right = 11;

            Assert.True(_left != _right);
        }

        [Test]
        public void OperatorGreaterThan()
        {
            _left = 11;
            _right = 10;
            Assert.True(_left > _right);

            _left = 10;
            _right = 10;
            Assert.False(_left > _right);

            _left = 9;
            _right = 10;
            Assert.False(_left > _right);

            _left = "a";
            _right = "b";
            Assert.False(_left > _right);

            _left = MondValue.Null;
            _right = 10;
            Assert.Throws<MondRuntimeException>(() => { var a = _left > _right; });
        }

        [Test]
        public void OperatorGreaterThanOrEqual()
        {
            _left = 11;
            _right = 10;
            Assert.True(_left >= _right);

            _left = 11;
            _right = 11;
            Assert.True(_left >= _right);

            _left = 11;
            _right = 12;
            Assert.False(_left >= _right);
        }

        [Test]
        public void OperatorLessThan()
        {
            _left = 9;
            _right = 10;
            Assert.True(_left < _right);

            _left = 10;
            _right = 10;
            Assert.False(_left < _right);

            _left = 11;
            _right = 10;
            Assert.False(_left < _right);
        }

        [Test]
        public void OperatorLessThanOrEqual()
        {
            _left = 9;
            _right = 10;
            Assert.True(_left <= _right);

            _left = 10;
            _right = 10;
            Assert.True(_left <= _right);

            _left = 11;
            _right = 10;
            Assert.False(_left <= _right);
        }

        #endregion

        [Test]
        public void ImplicitBool()
        {
            var value = MondValue.Undefined;
            Assert.False(value);

            value = MondValue.Null;
            Assert.False(value);

            value = MondValue.False;
            Assert.False(value);

            value = MondValue.True;
            Assert.True(value);

            value = 0;
            Assert.True(value);

            value = 1;
            Assert.True(value);

            value = double.NaN;
            Assert.False(value);

            value = "hello";
            Assert.True(value);

            value = new MondValue(MondValueType.Object);
            Assert.True(value);

            value = new MondValue(MondValueType.Array);
            Assert.True(value);

            value = new MondFunction((state, arguments) => MondValue.Undefined);
            Assert.True(value);
        }

        [Test]
        public void ObjectFieldIndexer()
        {
            var obj = new MondValue(MondValueType.Object);

            Assert.True(obj["undef"] == MondValue.Undefined);

            Assert.True(obj["setPrototype"] != MondValue.Undefined);

            obj["test"] = 123;
            Assert.True(obj["test"] == 123);

            obj[123] = "test";
            Assert.True(obj[123] == "test");
        }

        [Test]
        public void ArrayIndexer()
        {
{'fraction_non_alphanumeric': 0.12160633484162896, 'fraction_numerical': 0.02403846153846154, 'mean_word_length': 1.3380165289256198, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '6316300', 'n_tokens_mistral': 4373, 'n_tokens_neox': 3952, 'n_words': 849}