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

Console app on convert #2089

Merged
merged 20 commits into from
Dec 31, 2024
Merged

Conversation

logan-keede
Copy link
Contributor

@logan-keede logan-keede commented Dec 18, 2024

Describe your changes in detail

I have added prompt that asks whether the given app is console_app and adds corresponding configuration to pyproject.toml.
also provides corresponding override by the name of console_app

What problem does this change solve?

It addresses the need to manually change pyproject.toml when converting console apps.

If this PR relates to an issue, include Refs #XXX or Fixes #XXX

Fixes #1900

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

This is definitely on the right track; two comments inline regarding the implementation.

There's also a need for tests. Briefcase has 100% branch coverage, and any new feature requires tests of that new feature. The Briefcase contribution guide (in the docs) has pointers on how to set up a local testing environment.

If you need any pointers on these points, let us know and I'll do what I can to help.

):
return {
"gui_framework": "None",
"pyproject_table_briefcase_app_extra_content": "\nconsole_app = true\n",
Copy link
Member

Choose a reason for hiding this comment

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

If this is a feature we're going to rely on, we should probably add console_app as a feature in the Briefcase template itself, rather than slipping it into "extra" content.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

alright, I will make a commit there first. should I open an issue first?
Thanks for the guidance.

Copy link
Member

Choose a reason for hiding this comment

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

There's no need for a separate issue; you can use Refs beeware/briefcase#1234 syntax to reference an issue or PR in a separate project.

src/briefcase/commands/convert.py Show resolved Hide resolved
@logan-keede logan-keede marked this pull request as draft December 19, 2024 11:22
@logan-keede
Copy link
Contributor Author

logan-keede commented Dec 19, 2024

There's also a need for tests. Briefcase has 100% branch coverage, and any new feature requires tests of that new feature. The Briefcase contribution guide (in the docs) has pointers on how to set up a local testing environment.

image

Hi, I get this error in coverage test, but I can not completely understand what I am doing wrong. I would be grateful if you can point me in right direction.

My analysis:-
The self.values that is being poped does not seem to be under my control, because all coverage test pass if I set self.input.tool=DummyConsole("") at
conftest.py#L26 which seems to be equivalent of empty input instead of previous no input at all.
This no input at all does not bother other test case since we are using overrides, (like build_app_context) but this particular test is referred as def test_overrides_are_not_used(convert_command): which adds to my confusion.

Possible solution:-

  1. use DummyConsole('') but since input.tools is used by other tests, it may effect coverage quality?
  2. add Overrides in this test(for new feature console_app) and change function name.
  3. other?

Thanks,
logan

@freakboy3742
Copy link
Member

Hi, I get this error in coverage test, but I can not completely understand what I am doing wrong. I would be grateful if you can point me in right direction.

The underlying issue is that as a result of the changes you've made, the test in question is now asking for user input. This input is controllable, in multiple ways - see the tests for test_input_* in the same folder.

However, in this case, the test is misleadingly named, and it should be verifying that overrides are being used - so, your option 2.

@logan-keede logan-keede marked this pull request as ready for review December 26, 2024 19:41
@logan-keede
Copy link
Contributor Author

I believe I have aptly addressed the requested changes, let me know if I am wrong or more changes are required.
Thanks!!!

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

This is getting pretty close; a couple of minor issues flagged inline, several of which are tied to the exact form of the template.

The only additional detail that needs to be modified is the handling of console mode for new apps. At present, the Console bootstrap (briefcase.bootstraps.console) includes console_app = true as a hard-coded string in the pyproject_table_briefcase_app_extra_content configuration. For consistency, this should probably be handled as a boolean flag on the bootstrap itself (by subclassing extra_context()) that will be passed down to the bootstrap template.

Comment on lines 4 to 5
assert out["gui_framework"] == "None"
assert overrides["gui_framework"] == "Toga"
Copy link
Member

Choose a reason for hiding this comment

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

This changes the test quite a bit - it goes from checking the entire contents of the dictionary, to checking one specific field in the dictionary. If the method adds additional fields, the test won't raise this as a failure.

src/briefcase/commands/convert.py Outdated Show resolved Hide resolved
changes/1900.feature.rst Outdated Show resolved Hide resolved
Comment on lines 626 to 628
console_app = "true"
else:
console_app = "false"
Copy link
Member

Choose a reason for hiding this comment

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

Matching the changes I made to the template - should this be a string, or a boolean? I suspect it should be a boolean. input_console_app is already outputting a boolean.

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 think, it should be string since making console_app a boolean renders console_app in pyproject.toml to True instead of true, or is it case insensitive?

Copy link
Member

Choose a reason for hiding this comment

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

TOML parsing is case sensitive; I'd argue this means the template should use {{ "True" if console_app else "False" }}. The template context should be "pure" data; the template then renders that context as necessary to produce valid TOML.

def test_overrides_are_used_for_GUI(convert_command):
overrides = {"console_app": "GUI"}
out = convert_command.build_gui_context({}, overrides)
assert out["console_app"] == "false"
Copy link
Member

Choose a reason for hiding this comment

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

There should also be a test of the two "normal" cases, where user input is provided.

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

Getting close; most of the issues now stem from the exact value being put into the template context

Comment on lines 626 to 628
console_app = "true"
else:
console_app = "false"
Copy link
Member

Choose a reason for hiding this comment

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

TOML parsing is case sensitive; I'd argue this means the template should use {{ "True" if console_app else "False" }}. The template context should be "pure" data; the template then renders that context as necessary to produce valid TOML.

default=None,
options=["GUI", "Console"],
override_value=None,
)
Copy link
Member

Choose a reason for hiding this comment

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

This validates that the method is called; but doesn't validate the return value of the method being invoked.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, test_input_is_used_GUI and test_input_is_used_Console are supposed to validate returned value(just below this function), I saw that other input functions had similar test to check if the function is being called properly, so I added one for this one too.

Copy link
Member

Choose a reason for hiding this comment

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

Sure - my point is that this test is incomplete. If you're invoking a function, you should be ensuring that the return value is what you expect.

However, the test itself is actually redundant. We don't actually care if select_option is invoked - that's testing a specific implementation detail. What we care about is the "black box" behavior - that if the user types 1/0 after invoking the method, a False/True value is returned; for bonus points, we can also check the default, and error handling options. Those outcomes are established by the subsequent tests (which can be parameterised to account for the other input options).

assert out == {"gui_framework": "None"}
assert overrides == {"gui_framework": "Toga"}
assert out == {"gui_framework": "None", "console_app": "true"}
assert overrides["gui_framework"] == "Toga"
Copy link
Member

Choose a reason for hiding this comment

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

I mentioned this in a previous review, but this is changing the nature of the assertion from a full dictionary to a single key.

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

Thanks for those updates - other than a couple of minor issues that I've updated manually, this looks great! Thanks for the contribution!

default=None,
options=["GUI", "Console"],
override_value=None,
)
Copy link
Member

Choose a reason for hiding this comment

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

Sure - my point is that this test is incomplete. If you're invoking a function, you should be ensuring that the return value is what you expect.

However, the test itself is actually redundant. We don't actually care if select_option is invoked - that's testing a specific implementation detail. What we care about is the "black box" behavior - that if the user types 1/0 after invoking the method, a False/True value is returned; for bonus points, we can also check the default, and error handling options. Those outcomes are established by the subsequent tests (which can be parameterised to account for the other input options).

@@ -598,12 +615,19 @@ def build_gui_context(
context: dict[str, str],
project_overrides: dict[str, str],
) -> dict[str, str]:
# We must set the GUI-framework to None here since the convert-command uses the new-command
# We must set the GUI-framework to None here since the convert-command uses the new-commandcd
Copy link
Member

Choose a reason for hiding this comment

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

Looks like a window focus typo.

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

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

Wait - I just realised I missed something - the handling of console_app in the console app bootstrap. One more small update to come.

@freakboy3742 freakboy3742 merged commit aa1f5d9 into beeware:main Dec 31, 2024
49 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.

Ask user if the app is a console app during conversion
2 participants