Skip to content

Conversation

@dimitrijjedich
Copy link
Collaborator

💡🤔 Idea

Since every logic, method and class serve a single process, namly the sorting of numbers, the test ware easily written. But since the basicly all test the same functionality, the tests evolve to be a copy of a copy of a copy...

This may or may not lead to some inconsistency in the future and therefor not the perfect condition to have results that match accross the board on every testrun and deliver comparable values accross the different algorithms used.

🔍🕵️ Basics

Since the easiest test for a sorting algorithm is to randomize a array and compare it to the original, the most simple solution would be to do exactly this. This leads to two simple problems:

  1. The results would not be repeatable. This stems from the fact, that every randomized array will generate a different result and may favor one algorithm over the other or do the same even for diffent runs of the same algorithm. This risk could be reduced by running the test over many iterations and taking the average over the runtime.
  2. A wise men once told me, that there should be no logic in tests. I will hope that something like range(1,9) would be approved by him but it should be kept to a minimum.

🔬📈 Path to and Solution

The best way to provide data to the tests was already impelemented. Hardcoding arrays and providing them to the classes to expect a result-array that is either also hard coded or expected to be the previously mentioned range(x,y) ist simple but effective. Just make sure to use the same array in every test and there is no problem.
This howevery violates the DRY Principle and like this and having the fact in mind, that some day or time in the future the data which are used for test would have to change, this PR was born.

🎯 Focus on the basics

Since the best way to test was already implemented, the only thing left to do is to collect the data in one place and distribute it among the tests. This was how it startet and The now called CustomDataProvider was implemented. But keeping it simple should have been just the beginning.

1️⃣ Iteration

Write a method that returns a bunch of predefined arrays and be done with it. Generating a permutation of every combination of the numbers between 1 and 9 proved to be more difficult then initially expected. 362880 elements more difficult to be exact (definetly not recommend trying to copy paste that stuff using PHPStrom). But the generation worked:

#!/bin/bash

perl -e '
    use List::Util qw(shuffle);
    sub permute {
        my ($items, $perm) = @_;
        unless (@$items) {
            print "[[", join(",", @$perm), "]],\n";
        } else {
            for my $i (0 .. $#$items) {
                permute([@$items[0..$i-1, $i+1..$#$items]], [@$perm, $items->[$i]]);
            }
        }
    }
    permute([1..9], []);
' > permutations.txt

After that it was as simple as retrieving random lines from permutations.txt and dumping them into the return of the method.
Here the command for that with 10 arrays:

awk 'BEGIN {srand()} {print rand(), $0}' permutations.txt | sort -n | head -n 10 | cut -d' ' -f2- >

And since nobody likes to instantioate that thing, just make them static to beginn with.

2️⃣ Make it fancy

But what if we would like to have variance in our provided data? Maybe have different test pipelines, small once that give imidiate feedback while developing? The thing should provide a level of compfort. Allow the method to take a number and return array sizes based on that. But nobody whats to write endless amount of static code into his project, just so someone may want a dataprovider with 1337 elements just to be funny. So downhill we go:

  1. Allow array sizes to be the power of 10 and to some math magic to ensure that this always happens instead of trusting the developer
  2. Make sure that there is a limit (I never planed on going beyond 1000 elements)
  3. Try to make it some kind of facade with a bunch of private methods that are called dynamicly

3️⃣ Go absolutly bonkers

With the implementation for a dataprovider that returns array in the range of 1 to 9 in sizes of 1, 10 and 1000 done the next logical step was clear. Make the numbers to up Up Up
There we have it. The methods oneToNine, oneToNineNine and oneToNineNineNine where there and my sleep was gone.

🪦💀 Final words

The feature nobody asked for in overdone is done. If it makes any sence is for you to diced and for me to sleep over. Sadness and sorrow to the fellows of oneToNineNine and oneToNineNineNine which got only a single array to provide but that should be fixable if I am allowed to push such stuff.

Until then happy review and Good Night 🌃

❗This PR may contain formatting and typing fixes that may have been done in a state that is not leagally allowed to be called "awake", but happend anyway and should be reviewed with the appropriate suspiciousness

@dimitrijjedich dimitrijjedich self-assigned this Nov 22, 2024
- 10 and 100 of values from 1 to 99
- 10 fo values from 1 to 999
@sonarqubecloud
Copy link

@dimitrijjedich
Copy link
Collaborator Author

🤦 Overcomplicate Stuff

You could write fancy scripts and trow magical awk commands onto files that are so large that they crash your IDE. Or just stick to the basics. May i present the new version of "I need arrays":

$numbers = range(1, 999); // Create an array of numbers from 1 to 999
for ($i=0; $i<10; $i++) {
    shuffle($numbers); // Randomly shuffle the array
    print_r(json_encode([$numbers]). ","); // Print the array inside an array and add a comma
}

Copy the output and add it to an array and return it. Autoformatting will make it pretty in the end and everything takes less then a few secods.

"Use the right tool for the job!"
   - Someone wise probably

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants