<commit_before>package org.jtrim2.property;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.jtrim2.concurrent.Tasks;
import org.jtrim2.event.ListenerRef;
import org.jtrim2.executor.SyncTaskExecutor;
import org.jtrim2.testutils.JTrimTests;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class PropertyOfPropertyTest
extends
        JTrimTests<PropertyOfPropertyTest.TestFactory<MutableProperty<String>, String>> {

    public PropertyOfPropertyTest() {
        super(Arrays.asList(
                PropertyOfProperty::new,
                PropertyFactory::propertyOfProperty
        ));
    }

    private void doTest(Consumer<TestProperty> testTask) throws Exception {
        testAll(factory -> {
            testTask.accept(new TestProperty(factory));
        });
    }

    @Test
    public void testNestedValueChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            property.assertValue("");

            verifyZeroInteractions(listener);

            property.setNestedValue("b");
            property.assertValue("b");
            verify(listener, only()).run();

            listenerRef.unregister();

            property.setNestedValue("c");
            property.assertValue("c");

            verify(listener, only()).run();
        });
    }

    @Test
    public void testNestedPropertyChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            property.setNestedProperty("a");
            property.assertValue("a");
            verify(listener, only()).run();

            listenerRef.unregister();

            property.setNestedProperty("b");
            property.assertValue("b");

            verify(listener, only()).run();
        });
    }

    @Test
    public void testNestedPropertyChangesPreviousUntracked() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            MutableProperty<String> prevNestedProperty = property.setNestedProperty("a");
            verify(listener, only()).run();

            prevNestedProperty.setValue("x");
            property.assertValue("a");
            verify(listener, only()).run();

            listenerRef.unregister();
        });
    }

    @Test
    public void testNestedPropertyAndNestedValueChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            property.setNestedProperty("a");
            property.assertValue("a");
            verify(listener, only()).run();

            property.setNestedValue("b");
            property.assertValue("b");
            verify(listener, times(2)).run();

            listenerRef.unregister();

            property.setNestedValue("c");
            property.assertValue("c");

            property.setNestedProperty("d");
            property.assertValue("d");

            verify(listener, times(2)).run();
        });
    }

    @Test
    public void testConcurrent() throws Exception {
        int threadCount = getThreadCount();
        int subPropertyCount = Math.max(2, threadCount / 2);
        int listenerCount = Math.max(2, threadCount - subPropertyCount);

        doTest(property -> {
            for (int tryIndex = 0; tryIndex < 100; tryIndex++) {
                PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

                List<String> keys = IntStream
                        .range(0, subPropertyCount)
                        .mapToObj(index -> "Key." + index)
                        .collect(Collectors.toList());

                Map<String, MutableProperty<String>> nestedProperties = new LinkedHashMap<>();
                keys.forEach(key -> {
                    MutableProperty<String> nestedProperty = PropertyFactory.memProperty(key + ".NewValue");
                    nestedProperties.put(key, nestedProperty);
                });

                List<Runnable> tasks = new ArrayList<>();<commit_msg>Removed unnecessary code from PropertyOfPropertyTest.<commit_after>package org.jtrim2.property;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.jtrim2.concurrent.Tasks;
import org.jtrim2.event.ListenerRef;
import org.jtrim2.executor.SyncTaskExecutor;
import org.jtrim2.testutils.JTrimTests;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class PropertyOfPropertyTest
extends
        JTrimTests<PropertyOfPropertyTest.TestFactory<MutableProperty<String>, String>> {

    public PropertyOfPropertyTest() {
        super(Arrays.asList(
                PropertyOfProperty::new,
                PropertyFactory::propertyOfProperty
        ));
    }

    private void doTest(Consumer<TestProperty> testTask) throws Exception {
        testAll(factory -> {
            testTask.accept(new TestProperty(factory));
        });
    }

    @Test
    public void testNestedValueChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            property.assertValue("");

            verifyZeroInteractions(listener);

            property.setNestedValue("b");
            property.assertValue("b");
            verify(listener, only()).run();

            listenerRef.unregister();

            property.setNestedValue("c");
            property.assertValue("c");

            verify(listener, only()).run();
        });
    }

    @Test
    public void testNestedPropertyChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            property.setNestedProperty("a");
            property.assertValue("a");
            verify(listener, only()).run();

            listenerRef.unregister();

            property.setNestedProperty("b");
            property.assertValue("b");

            verify(listener, only()).run();
        });
    }

    @Test
    public void testNestedPropertyChangesPreviousUntracked() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            MutableProperty<String> prevNestedProperty = property.setNestedProperty("a");
            verify(listener, only()).run();

            prevNestedProperty.setValue("x");
            property.assertValue("a");
            verify(listener, only()).run();

            listenerRef.unregister();
        });
    }

    @Test
    public void testNestedPropertyAndNestedValueChanges() throws Exception {
        doTest(property -> {
            PropertySource<String> propertyOfProperty = property.getPropertyOfProperty();

            Runnable listener = mock(Runnable.class);
            ListenerRef listenerRef = propertyOfProperty.addChangeListener(listener);

            verifyZeroInteractions(listener);

            property.setNestedProperty("a");
            property.assertValue("a");
            verify(listener, only()).run();

            property.setNestedValue("b");
            property.assertValue("b");
            verify(listener, times(2)).run();

            listenerRef.unregister();

            property.setNestedValue("c");
            property.assertValue("c");

            property.setNestedProperty("d");
            property.assertValue("d");

            verify(listener, times(2)).run();
        });
    }

    @Test
    public void testConcurrent() throws Exception {
        int threadCount = getThreadCount();
        int subPropertyCount = Math.max(2, threadCount / 2);
        int listenerCount = Math.max(2, threadCount - subPropertyCount);

        doTest(property -> {
            for (int tryIndex = 0; tryIndex < 100; tryIndex++) {
                List<String> keys = IntStream
                        .range(0, subPropertyCount)
                        .mapToObj(index -> "Key." + index)
                        .collect(Collectors.toList());

                Map<String, MutableProperty<String>> nestedProperties = new LinkedHashMap<>();
                keys.forEach(key -> {
                    MutableProperty<String> nestedProperty = PropertyFactory.memProperty(key + ".NewValue");
                    nestedProperties.put(key, nestedProperty);
                });

                List<Runnable> tasks = new ArrayList<>();
{'fraction_non_alphanumeric': 0.10884611737934957, 'fraction_numerical': 0.002844410732909832, 'mean_word_length': 2.499668214996682, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 52, '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': '423778', 'n_tokens_mistral': 2644, 'n_tokens_neox': 2528, 'n_words': 458}