Skip to content

Use the private setter pattern on SessionGenerator.currentSession #4785

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

Merged
merged 2 commits into from
Mar 16, 2023

Conversation

mrober
Copy link
Contributor

@mrober mrober commented Mar 15, 2023

This is more Kotlin idiomatic. Also made some properties val instead of var, I think this is cleaner.

sessionIndex,
)
var currentSession =
SessionDetails(sessionId = "", firstSessionId = "", collectEvents, sessionIndex = -1)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we still need this default instance? Would it make sense to make currentSession nullable or lateinit?

Copy link
Contributor

Choose a reason for hiding this comment

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

It mostly depends on preference. Do you want to deal with nulls in the classes that use this, or assume that what you get is valid?

I think we've designed this class to always return a valid currentSession, so I lean towards keeping it not nullable.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need a default instance. That does not serve anything. SessionGenerator should generate session only when there is a need.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I changed it to lateinit not nullable. This will let us avoid the null check, but we have to guarantee we call generateNewSession() before accessing it.

}

val currentSession: SessionDetails
get() = thisSession
private fun generateSessionId() = UUID.randomUUID().toString().replace("-", "").lowercase()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might not be worth it, but if we made this an interface like SessionIdGenerator and passed in, we could make the unit tests deterministic. Then have a seperate test to validate the generated session ids. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I like that idea. 2 suggestions:

  • You can pass in a function to the constructor instead of making a SessionIdGenerator class with a generate() method. Only reason is a function might be lighter weight.
  • This class / function that we pass in should only return the UUID.randomUUID() part of this statement. This SessionGenerator should be responsible for toString and .replaceing it so we can assert that the dashes are removed in tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

A separate interface just for sessionId sounds like an overkill. Do you think this structure is not testable? I think with the SessionDetails structure and generateNewSession, we should be able to cover all scenarios for testing.

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 was concerned about the randomness in the tests, and asserts on individual fields of the SessionDetails data class to avoid a big assert on the entire object since it contained randomness.

I played around with this. I made it take a function, not an interface, in the ctor. I left one test with the random UUIDs to verify it generates valid session ids.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Mar 15, 2023

Coverage Report 1

Affected Products

  • firebase-sessions

    Overall coverage changed from ? (8acde15) to 25.93% (35359fe) by ?.

    FilenameBase (8acde15)Merge (35359fe)Diff
    FirebaseSessions.kt?0.00%?
    FirebaseSessionsRegistrar.kt?0.00%?
    SessionEvent.kt?100.00%?
    SessionEvents.kt?72.00%?
    SessionGenerator.kt?0.00%?
    SessionInitiator.kt?0.00%?
    WallClock.kt?0.00%?

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/u8GmmQW8tm.html

@github-actions
Copy link
Contributor

github-actions bot commented Mar 15, 2023

Unit Test Results

  8 files    8 suites   19s ⏱️
13 tests 13 ✔️ 0 💤 0
26 runs  26 ✔️ 0 💤 0

Results for commit 6b6ab5f.

♻️ This comment has been updated with latest results.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Mar 15, 2023

Size Report 1

Affected Products

  • base

    TypeBase (8acde15)Merge (35359fe)Diff
    apk (aggressive)?8.39 kB? (?)
    apk (release)?8.65 kB? (?)
  • firebase-encoders-json

    TypeBase (8acde15)Merge (35359fe)Diff
    aar?11.3 kB? (?)
    apk (aggressive)?24.0 kB? (?)
    apk (release)?596 kB? (?)
  • firebase-sessions

    TypeBase (8acde15)Merge (35359fe)Diff
    aar?23.8 kB? (?)
    apk (aggressive)?138 kB? (?)
    apk (release)?1.66 MB? (?)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/vgmPVD3aff.html

sessionIndex,
)
var currentSession =
SessionDetails(sessionId = "", firstSessionId = "", collectEvents, sessionIndex = -1)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need a default instance. That does not serve anything. SessionGenerator should generate session only when there is a need.

)
var currentSession =
SessionDetails(sessionId = "", firstSessionId = "", collectEvents, sessionIndex = -1)
private set
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this not associated with any var/val? Felt like a hanging private set.

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 is the setter for currentSession, I think it looks more clear now that we removed the default instance.

}

val currentSession: SessionDetails
get() = thisSession
private fun generateSessionId() = UUID.randomUUID().toString().replace("-", "").lowercase()
Copy link
Contributor

Choose a reason for hiding this comment

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

A separate interface just for sessionId sounds like an overkill. Do you think this structure is not testable? I think with the SessionDetails structure and generateNewSession, we should be able to cover all scenarios for testing.

Copy link
Contributor

@samedson samedson left a comment

Choose a reason for hiding this comment

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

LGTM!

@mrober mrober merged commit 0ea9884 into firebase-sessions Mar 16, 2023
@mrober mrober deleted the sessions-generator branch March 16, 2023 20:59
@firebase firebase locked and limited conversation to collaborators Apr 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants