Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parallel-letter-frequency: Sync tests & add missing #2050

Merged
merged 9 commits into from
Mar 9, 2025

Conversation

ellnix
Copy link
Contributor

@ellnix ellnix commented Mar 3, 2025

The tests are unique and not really in sync with problem-specifications, however they test the same behavior so it should be fine? I thought I'd make a PR before making a template since it might make sense to keep the bespoke tests that we have now. Would like any input on this.

The tests I added were missing, but they are just convenience tests for students to be able to iterate their solution, so I think this is appropriate:

[no important files changed]

The tests are unique and not really in sync with problem-specifications,
however they test the same behavior so it should be fine?

The tests I added were missing, but they are just convenience tests for
students to be able to iterate their solution, so I think this is
appropriate:

[no important files changed]
@ellnix ellnix requested a review from senekor March 3, 2025 19:32
Copy link
Contributor

github-actions bot commented Mar 3, 2025

This PR touches files which potentially affect the outcome of the tests of an exercise. This will cause all students' solutions to affected exercises to be re-tested.

If this PR does not affect the result of the test (or, for example, adds an edge case that is not worth rerunning all tests for), please add the following to the merge-commit message which will stops student's tests from re-running. Please copy-paste to avoid typos.

[no important files changed]

For more information, refer to the documentation. If you are unsure whether to add the message or not, please ping @exercism/maintainers-admin in a comment. Thank you!

@senekor
Copy link
Contributor

senekor commented Mar 3, 2025

I don't really understand. Where are the three additional tests coming from? Do you propose a second PR later with a template?

In general, I'd be in favor of adopting the tests from problem-specifications after checking that the tested behavior is the same.

Making the TDD experience more granular for students doesn't seem like a compelling enough argument for me to introduce custom tests. Usually that makes sense if they are inherently Rust-specific or somehow needed to preserve backwards-compatibility with an existing exercise design.

@ellnix
Copy link
Contributor Author

ellnix commented Mar 3, 2025

I don't really understand. Where are the three additional tests coming from? Do you propose a second PR later with a template?

I should have been clearer, those tests are in problem-specifications but not in Rust. I would probably just add a commit to this PR for the template, don't want to add too much noise to the repo.

This is the rename:

[818031be-49dc-4675-b2f9-c4047f638a2a]
description = "one text with one letter"

These are the new tests:

[c0b81d1b-940d-4cea-9f49-8445c69c17ae]
description = "one text with multiple letters"

[708ff1e0-f14a-43fd-adb5-e76750dcf108]
description = "two texts with one letter"

[1b5c28bb-4619-4c9d-8db9-a4bb9c3bdca0]
description = "two texts with multiple letters"

In general, I'd be in favor of adopting the tests from problem-specifications after checking that the tested behavior is the same.

Alright, so I'm assuming I should go ahead and make a template for this test?

@senekor
Copy link
Contributor

senekor commented Mar 3, 2025

Ah, got it. Yeah, a template sounds good.

@ellnix
Copy link
Contributor Author

ellnix commented Mar 9, 2025

@senekor I attempted this a couple days ago and I don't honestly think a template is worth it, there's tests with very long text, and also a test with repeating text which would add like 30 lines alone.

Test with repeating text
{
      "uuid": "adf8e57b-8e54-4483-b6b8-8b32c115884c",
      "description": "many small texts",
      "scenarios": ["concurrent"],
      "property": "calculateFrequencies",
      "input": {
        "texts": [
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc",
          "abbccc"
        ]
      },
      "expected": {
        "a": 50,
        "b": 100,
        "c": 150
      }
    }

Keeping the text from being long and unwieldy would require as much code in Tera as there is in the test file itself. I think the way we have it with the texts hoisted at the top makes the most sense.

@senekor
Copy link
Contributor

senekor commented Mar 9, 2025

That's ok, but in that case we need to make sure that tests.toml actually matches our manually-maintained tests. For example, tests.toml currently contains the following:

[adf8e57b-8e54-4483-b6b8-8b32c115884c]
description = "many small texts"

That's the unwieldy test you posted. If we don't include this test, then it must be marked as excluded with a justification in tests.toml.

One advantage the templates give us is that they automatically make sure all the tests that are declared as included in tests.toml are in fact included.

If we're gonna maintain the mapping manually, we should add a comment above every test with its UUID or something so we can easily trace that work in the future.

I'm open to alternatives, but what we shouldn't do is add a tests.toml file that contains incorrect information about which tests are actually implemented and which aren't.

Copy link
Contributor

@senekor senekor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you can re-request a review :)

@ellnix ellnix requested a review from senekor March 9, 2025 16:06
Copy link
Contributor

@senekor senekor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant re-request when you think I should take another look at the code 😄

@ellnix
Copy link
Contributor Author

ellnix commented Mar 9, 2025

Oh lmao, I thought for some reason you wanted to go through the request-response workflow again for some reason, my bad. I did a git reset --hard on that attempt to add the template because I felt like I wasn't getting anywhere. I got a notification from github about your request for changes but not the first message you sent, and it scrolled past it 😫

I'm open to alternatives, but what we shouldn't do is add a tests.toml file that contains incorrect information about which tests are actually implemented and which aren't.

That test is actually present, and it's just a call to vec! instead of all those lines.

#[test]
#[ignore]
fn many_times_same_text() {
    let v = vec!["abc"; 1000];
    let mut hm = HashMap::new();
    hm.insert('a', 1000);
    hm.insert('b', 1000);
    hm.insert('c', 1000);
    assert_eq!(frequency::frequency(&v[..], 4), hm);
}

If we're gonna maintain the mapping manually, we should add a comment above every test with its UUID or something so we can easily trace that work in the future.

I think this would be really confusing since students see those comments. Since tests.toml should keep all arbitrary pairs, we can add a rust_fn = many_times_same_text key or similar. That would also be much easier to parse in CI, wherein we could try to match every entry in tests.toml with a function matching the description or rust_fn.

@senekor
Copy link
Contributor

senekor commented Mar 9, 2025

Since tests.toml should keep all arbitrary pairs, we can add a rust_fn = many_times_same_text key or similar.

Great idea!

That would also be much easier to parse in CI, wherein we could try to match every entry in tests.toml with a function matching the description or rust_fn.

Also a great idea! But I'm not gonna block this PR on it. If you want to do it, go ahead, otherwise feel free to leave it for later. My main concern is that I don't want maintainers to have to do the manual work of matching up tests.toml with the actual tests over and over. With the addtional key in tests.toml, that's pretty much covered for me.

Comment on lines +46 to +48
[7b1da046-701b-41fc-813e-dcfb5ee51813]
description = "combination of lower- and uppercase letters, punctuation and white space"
rust_fn = "all_three_anthems_1_worker"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt it was appropriate to match tests based on the behavior under test, not necessarily the exact content of the input.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, the input of "combination of lower- and uppercase letters, punctuation and white space" is this:

      "input": {
        "texts": [
          "There, peeping among the cloud-wrack above a dark tower high up in the mountains, Sam saw a white star twinkle for a while. The beauty of it smote his heart, as he looked up out of the forsaken land, and hope returned to him. For like a shaft, clear and cold, the thought pierced him that in the end, the shadow was only a small and passing thing: there was light and high beauty forever beyond its reach."
        ]
      },

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. If we're maintaining the tests manually, we might as well grant ourselves the flexibility a template would lack. Behavior is what counts.

@@ -129,3 +177,183 @@ fn non_integer_multiple_of_threads() {
hm.insert('c', 999);
assert_eq!(frequency::frequency(&v[..], 4), hm);
}

const DOSTOEVSKY: [&str; 4] = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This text is really large so I thought I'd have it after all the tests that work without it so the file is easier to skim. I can understand the argument for having all of the constants defined at the top though.

I don't feel strongly in either case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about putting all the texts at the very bottom below the last test? That seems consistent and most conducive to skimming the file. If users want to read the actual texts to understand a test case, they will have to move around the file one way or the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea, since they are constants anyway we have that flexibility.

Copy link
Contributor Author

@ellnix ellnix Mar 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented: 4d0bcfc

@ellnix ellnix requested a review from senekor March 9, 2025 21:54
@@ -129,3 +177,183 @@ fn non_integer_multiple_of_threads() {
hm.insert('c', 999);
assert_eq!(frequency::frequency(&v[..], 4), hm);
}

const DOSTOEVSKY: [&str; 4] = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about putting all the texts at the very bottom below the last test? That seems consistent and most conducive to skimming the file. If users want to read the actual texts to understand a test case, they will have to move around the file one way or the other.

Comment on lines +46 to +48
[7b1da046-701b-41fc-813e-dcfb5ee51813]
description = "combination of lower- and uppercase letters, punctuation and white space"
rust_fn = "all_three_anthems_1_worker"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. If we're maintaining the tests manually, we might as well grant ourselves the flexibility a template would lack. Behavior is what counts.

Copy link
Contributor

@senekor senekor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@ellnix ellnix merged commit 4bbbdeb into exercism:main Mar 9, 2025
10 checks passed
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