Skip to content

Switch compatible/incompatible/other/none license detection for known/unknown/none#4041

Open
daveverwer wants to merge 7 commits intomainfrom
remove-compat-incompat-licenses
Open

Switch compatible/incompatible/other/none license detection for known/unknown/none#4041
daveverwer wants to merge 7 commits intomainfrom
remove-compat-incompat-licenses

Conversation

@daveverwer
Copy link
Copy Markdown
Member

As the title says, this removes the old incompatible/compatible license categorisation and also cleans up the other case into known, unknown, and none.

The biggest impact of this change is on search filtering by license. There is a migration which consolidates incompatible/compatible into known in the scoring struct, and also one which converts other to unknown in both the scoring data and also in the repositories table. The incompatible/compatible migration is not able to be rolled back perfectly, but will roll back into a state that would then be corrected as future analysis cycles happen.

There are UI changes, too, including a new license icon.

Known license

Known License

Unknown license

Unknown License

No license found

No License Found

Comment thread Tests/AppTests/LicenseTests.swift
let filter = try LicenseSearchFilter(expression: .init(operator: .is, value: "other"))
let filter = try LicenseSearchFilter(expression: .init(operator: .is, value: "unknown"))
#expect(filter.key == .license)
#expect(filter.predicate == .init(operator: .in,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I found a slightly larger problem with these tests while fixing up this test. I noticed that no matter what value is passed to bindableValue in this #expect, the test passes based on the number of parameters passed in, not the value of the parameters.

So, for example, this code passes:

            #expect(filter.predicate == .init(operator: .in,
                                              bindableValue: .array(["nonsense"]),
                                              displayValue: "unknown"))

And this code fails:

            #expect(filter.predicate == .init(operator: .in,
                                              bindableValue: .array(["utter", "nonsense"]),
                                              displayValue: "unknown"))

This is because the == override on App.SearchFilter.Predicate.BoundValue is calling renderGenericSQL, which when a single value is passed in, renders $1 for both sides of the equality operator. This does test something, but in a very misleading way.

However, the lines below:

            // test view representation
            #expect(filter.viewModel.description == "license is unknown")

            // test sql representation
            #expect(app.db.renderSQL(filter.leftHandSide) == #""license""#)
            #expect(app.db.renderSQL(filter.sqlOperator) == "IN")
            #expect(app.db.binds(filter.rightHandSide) == ["unknown"])

As I understand it, these lines should fully test what the predicate check does, but in a better way. It still covers displayValue (via the description expectation), leftHandSide, and sqlOperator.

I believe the best thing to do is to remove this .predicate check, which is what I have done here.

It’s also worth noting that we have many other tests throughout the rest of this file, so if we decide that what I did here by removing this test is correct, I’ll open another PR after it’s merged to fix the remainder of the tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, that's bad, I see what went wrong here. I abused the SQL rendering to work around the any making BoundValue hard to make equatable.

It's still not ideal but I've fixed it (will push the changes in a second) so that we correctly distinguish between .value() and .array(). Since this is just for test assertion purposes we can get away with it.

The #expect(filter.predicate == ... assertion is worth keeping in my opinion, because it shows that we're parsing the input values into proper intermediate types. Otherwise bindableValue wouldn't be checked anywhere, I believe.

Comment thread Sources/App/Core/Score.swift
Comment thread Sources/App/Migrations/084/UpdateScoreDetailsLicenseKind.swift Outdated
let filter = try LicenseSearchFilter(expression: .init(operator: .is, value: "other"))
let filter = try LicenseSearchFilter(expression: .init(operator: .is, value: "unknown"))
#expect(filter.key == .license)
#expect(filter.predicate == .init(operator: .in,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, that's bad, I see what went wrong here. I abused the SQL rendering to work around the any making BoundValue hard to make equatable.

It's still not ideal but I've fixed it (will push the changes in a second) so that we correctly distinguish between .value() and .array(). Since this is just for test assertion purposes we can get away with it.

The #expect(filter.predicate == ... assertion is worth keeping in my opinion, because it shows that we're parsing the input values into proper intermediate types. Otherwise bindableValue wouldn't be checked anywhere, I believe.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants