-
Notifications
You must be signed in to change notification settings - Fork 114
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
📊 🦶 Metrics Services Rewrites #1098
📊 🦶 Metrics Services Rewrites #1098
Conversation
angular -> ts migration for metrics-mappings and metrics-factory The datasets have their own files, there is a customhelper, a methelper, and a footprint helper Tested in the emulator and dashboard still behaves as expected
I was using the wrong function when I first converted
there is a similar function for the footprint, lets make sure they have different names
first pass of tests over the footprintHelper getFootprintForMetrics is one of the main functions, used to calculate displayed values for the dashboard screen
since we've changed the way fallback labels are handled, everything should be custom now. This means that we're not using the carbon values from the set country, but rather from the labels
after we take out the angular modules, we need to take out all the references to them as well
since we no longer rely on a set country for carbon calculations, but rather custom or default label configurations, we can take out the option to set it from the profile
we need to initialize the footprints before we can call them, accomplish this by calling the initialization function from the metrics tab once the app config is loaded
we no longer store user's height/weight/etc because we are not calculating calories burned, for that reason the code related to storing user's data or calculating calories is not needed we will keep MET handling so we can bin activity into high/med/low intensity later not currently using the "highestMET" calculation code, so commenting that out for now
I have now removed the calorie code and the fallback dataset code (keeping a singular fallback until I can test a few configs and be convinced that we ALWAYS use custom) according to the discussion in the issue. I have also noticed a few more parts of the code that aren't used:
These four methods are currently not used by our code, I see two options for me to proceed: (1) if we don't anticipate adding it back, take the code out or (2) keep the code and write tests for it if we anticipate wanting it in the app in a future update. |
needed to include methods for clearing out the local variables, so added parameter to be able to set useCuston to false, and to clearHighest
I think I've sufficiently convinced myself that we'll always use the values in |
This code should never be used at this point -- labels will default to those in the sample file, which means that they are "walk, bike, ect" -- custom labels rather than the default "WALKING, BICYCLING, etc" Since the labels are always some version of custom (even the fallback) those values will always be used over the country-specific fallback values
At this point, the files are rewritten and tested, ending with only 4 instead of the proposed 5 since we no longer are using the country-specific fallbacks. The only thing that would remain to be done is testing the unused functions I mentioned above:
Thoughts on removing vs keeping and testing? @JGreenlee @shankari |
I don't think we should keep unused code around when it is not clear that we want to restore it. |
Not sure what happened, but the dashboard is no longer initializing properly (with the footprint dataset) and that screen is erroring out completely. I'll work on debugging more in the morning |
…rics-services-rewrite
dataset was not initialized in time from metricsTab, lifting the call up to App fixed this issue
This wooorks now, but there's still lots of errors. I think it's ready for a preliminary review, as the errors seem to be the same ones I'm seeing on the dashboardErrorsSmall.mov |
…rics-services-rewrite
www/js/metrics/footprintHelper.ts
Outdated
|
||
//variables for the highest footprint in the set and if using custom | ||
let highestFootprint = 0; | ||
let useCustom = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided this will always be true, right?
So we can remove this variable, along with setUseCustomFootprint
, and simplify logic in a bunch of places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember thinking about doing this, but then was worried about what would happen if we hadn't initialized the custom footprint yet, you're right that we are always going to be custom at this point (either deployer-specified or from the sample custom files). I'm going to reevaluate and try and pull this out, but might end up needing some error handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was less complex than I thought it would be. I elected to check that the custom footprint is defined before returning it in 'getFootprint`, that way we can still catch if the custom footprint is broken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering now if we should apply the same treatment to the METs ... we still need the dataset, since it's what we pull from for met-equivalents but if the labels are always custom then the mets should also always be custom...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concluded yes, the custom mets are populated when we initialized the custom dataset helper, and if they are not defined for some reason we can still fall back to the standard.
fixed typo, made single line, and added to horizontal chart as well e-mission#1098 (comment)
CustomMetricsHelper -> customMetricsHelper
removing the "is custom" variable for the footprint, and all references checking that footprint gotten is defined before returning, if not defined will throw an error
even though its an acronym, it is less confusing to have the name be lowercase since it is not a component
logDebug/logWarn instead of the console equivalents
logWarn in footprintHelper
www/js/metrics/footprintHelper.ts
Outdated
footprint['SUBWAY']) / | ||
6) * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I had misread that
Maybe there's something we can do with the formatting to prevent confusion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and pushed the change, with the way prettier chose to format the two, this is a line shorter! e626f6e
making sure the log statements here are thoughtful, renaming the input params to label options in the initialization code
The divisor being on it's own line was confusing, so now we are adding the vehicle modes and then dividing this should make the fact that it's an average more clear, and is one line shorter!
similar to the footprint, we will always use the custom METs, since the labels are custom (either deployer specified or our sample set) The custom mets are set up in the initialization of the custom dataset helper if the custom mets return undefined, will fall back to the standard mets
www/__tests__/metHelper.test.ts
Outdated
initCustomDatasetHelper(getConfig()); | ||
await new Promise((r) => setTimeout(r, 500)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with the setTimeout here? Wouldn't it be more 'proper' to do:
initCustomDatasetHelper(getConfig()); | |
await new Promise((r) => setTimeout(r, 500)); | |
const appConfig = await getConfig(); | |
initCustomDatasetHelper(appConfig); |
(Or is there some reason this wouldn't work?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be cleaner/more proper to me, but I just tried it and it did not work - I think that's because appConfig is not the only async element of this workflow chain, it also calls getLabelOptions
which is async.
getLabelOptions(newConfig).then((labelOptions)
what I can do though is set it up so that this function can be awaiting in the tests 51f6ece
This is much cleaner in testing, and still allows us to not hold up the app for it to load during initialization (because we don't care about the timing of the actual initialization)
www/__mocks__/cordovaMocks.ts
Outdated
if (key == 'config/app_ui_config') { | ||
return new Promise<any>((rs, rj) => | ||
setTimeout(() => { | ||
rs(fakeSurveyConfig); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting that some of this has since been changed in your other PR – I think it should all work out fine but just keep an eye on it
in testing the initCustomDatasets function, I was calling it and then setting a timeout to wait for it to run, now I await getting the config, then await initialization double checked the Jest tests and running in the emulator - still going smoothly!
There is no right or wrong here, but it's a bit cleaner and more consistent with the rest of the codebase if we generally follow this: i) for short one-liners, use const and declare an arrow function ii) for longer functions, use the traditional 'function' declaration also replaced some uses of 'var' with 'const' or 'let' added AppConfig type to initCustomDatasetHelper and replaced a console statement with logDebug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## service_rewrite_2023 #1098 +/- ##
========================================================
+ Coverage 56.44% 58.80% +2.35%
========================================================
Files 22 26 +4
Lines 1311 1420 +109
Branches 296 320 +24
========================================================
+ Hits 740 835 +95
- Misses 571 585 +14
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I didn't check the arithmetic in the tests. @Abby-Wheelis can you confirm that you checked them manually and they are correct? It would be helpful to add comments with the manual calculations for verification and in case the tests fail. I am not going to hold up the merge for this, but please deal with it next.
- codecov has flagged new code that is not covered by tests, please handle them in a follow-on cleanup.
const fullUrl = `${window['$rootScope'].connectUrl}/${path}`; | ||
data['aggregate'] = true; | ||
const fullUrl = `${serverConnConfig.connectUrl}/${path}`; | ||
query['aggregate'] = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so we don't store the connection config in the rootScope anymore since there is no rootScope.
result += footprint[mode] * mtokm(userMetrics[i].values); | ||
} else if (mode == 'IN_VEHICLE') { | ||
const sum = | ||
footprint['CAR'] + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: I first thought that we should be able to cache the value for IN_VEHICLE
instead of recomputing it every time. But then I realized that this may actually want/need to be different for different time ranges given the upcoming change that takes the grid mix into account. Would be interesting to see what this looks like after that is done.
walk: expect.any(Object), | ||
bike: expect.any(Object), | ||
bikeshare: expect.any(Object), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you are not checking against the actual numbers? These are going to be the same numbers as in fakeLabels.json
, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably did not do this originally, because I was mostly trying to test the keys. The default keys are WALKING
, BICYCLING
, etc, while the custom keys are walk
, bike
, etc.
I updated the footprint test, since that is a single value, but I have not updated the MET testing, since those objects are complex (some are speed dependent, etc), and taking the time to copy them over from fakeLabels.json
seems like it would do more to test the test than the code, but I'll add a note about checking the keys!
from review, adding the calculations in comments with the tests helps to make the arithmetic more credible e-mission#1098 (review)
To address these services, rewriting into 5 files:
carbonDatasets.ts
metDataset.ts
customMetricsHelper.ts
footprintHelper.ts
metHelper.ts
We need to make decisions about the country-divided carbon datasets and what to do about MET calculations see here. With these pending design decisions in mind, I plan to work with the footprint code cleanup and testing first.