Skip to content

Commit

Permalink
resolve merge conflicts by merging upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
Abby Wheelis committed Oct 20, 2023
2 parents b480279 + d032ed1 commit 1138d29
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 118 deletions.
56 changes: 56 additions & 0 deletions www/__tests__/useImperialConfig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { convertDistance, convertSpeed, formatForDisplay } from '../js/config/useImperialConfig';


// This mock is required, or else the test will dive into the import chain of useAppConfig.ts and fail when it gets to the root
jest.mock('../js/useAppConfig', () => {
return jest.fn(() => ({
appConfig: {
use_imperial: false
},
loading: false
}));
});

describe('formatForDisplay', () => {
it('should round to the nearest integer when value is >= 100', () => {
expect(formatForDisplay(105)).toBe('105');
expect(formatForDisplay(119.01)).toBe('119');
expect(formatForDisplay(119.91)).toBe('120');
});

it('should round to 3 significant digits when 1 <= value < 100', () => {
expect(formatForDisplay(7.02)).toBe('7.02');
expect(formatForDisplay(9.6262)).toBe('9.63');
expect(formatForDisplay(11.333)).toBe('11.3');
expect(formatForDisplay(99.99)).toBe('100');
});

it('should round to 2 decimal places when value < 1', () => {
expect(formatForDisplay(0.07178)).toBe('0.07');
expect(formatForDisplay(0.08978)).toBe('0.09');
expect(formatForDisplay(0.75)).toBe('0.75');
expect(formatForDisplay(0.001)).toBe('0');
expect(formatForDisplay(0.006)).toBe('0.01');
expect(formatForDisplay(0.00001)).toBe('0');
});
});

describe('convertDistance', () => {
it('should convert meters to kilometers by default', () => {
expect(convertDistance(1000, false)).toBe(1);
});

it('should convert meters to miles when imperial flag is true', () => {
expect(convertDistance(1609.34, true)).toBeCloseTo(1); // Approximately 1 mile
});
});

describe('convertSpeed', () => {
it('should convert meters per second to kilometers per hour by default', () => {
expect(convertSpeed(10, false)).toBe(36);
});

it('should convert meters per second to miles per hour when imperial flag is true', () => {
expect(convertSpeed(6.7056, true)).toBeCloseTo(15); // Approximately 15 mph
});
});
2 changes: 0 additions & 2 deletions www/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ import './js/services.js';
import './js/i18n-utils.js';
import './js/main.js';
import './js/survey/input-matcher.js';
import './js/survey/multilabel/infinite_scroll_filters.js';
import './js/survey/multilabel/multi-label-ui.js';
import './js/diary.js';
import './js/diary/services.js';
import './js/survey/enketo/infinite_scroll_filters.js';
import './js/survey/enketo/enketo-trip-button.js';
import './js/survey/enketo/enketo-add-note-button.js';
import './js/control/emailService.js';
Expand Down
4 changes: 2 additions & 2 deletions www/js/config/useImperialConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export const formatForDisplay = (value: number): string => {
return Intl.NumberFormat(i18next.language, opts).format(value);
}

const convertDistance = (distMeters: number, imperial: boolean): number => {
export const convertDistance = (distMeters: number, imperial: boolean): number => {
if (imperial)
return (distMeters / 1000) * KM_TO_MILES;
return distMeters / 1000;
}

const convertSpeed = (speedMetersPerSec: number, imperial: boolean): number => {
export const convertSpeed = (speedMetersPerSec: number, imperial: boolean): number => {
if (imperial)
return speedMetersPerSec * MPS_TO_KMPH * KM_TO_MILES;
return speedMetersPerSec * MPS_TO_KMPH;
Expand Down
3 changes: 1 addition & 2 deletions www/js/diary.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import LabelTab from './diary/LabelTab';

angular.module('emission.main.diary',['emission.main.diary.services',
'emission.survey.multilabel.buttons',
'emission.survey.multilabel.infscrollfilters',
'emission.survey.enketo.add-note-button',
'emission.survey.enketo.trip.infscrollfilters',
'emission.survey.enketo.trip.button',
'emission.plugin.logger'])

.config(function($stateProvider) {
Expand Down
4 changes: 2 additions & 2 deletions www/js/diary/LabelTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ const LabelTab = () => {
// https://github.com/e-mission/e-mission-docs/issues/894
if (appConfig.survey_info?.buttons == undefined) {
// initalize filters
const tripFilterFactory = getAngularService(surveyOpt.filter);
const allFalseFilters = tripFilterFactory.configuredFilters.map((f, i) => ({
const tripFilter = surveyOpt.filter;
const allFalseFilters = tripFilter.map((f, i) => ({
...f, state: (i == 0 ? true : false) // only the first filter will have state true on init
}));
setFilterInputs(allFalseFilters);
Expand Down
40 changes: 0 additions & 40 deletions www/js/survey/enketo/infinite_scroll_filters.js

This file was deleted.

38 changes: 38 additions & 0 deletions www/js/survey/enketo/infinite_scroll_filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* The general structure of this code is that all the timeline information for
* a particular day is retrieved from the Timeline factory and put into the scope.
* For best performance, all data should be loaded into the in-memory timeline,
* and in addition to writing to storage, the data should be written to memory.
* All UI elements should only use $scope variables.
*/

import i18next from "i18next";
import { getAngularService } from "../../angular-react-helper";

const unlabeledCheck = (t) => {
try {
const EnketoTripButtonService = getAngularService("EnketoTripButtonService");
const etbsSingleKey = EnketoTripButtonService.SINGLE_KEY;
return typeof t.userInput[etbsSingleKey] === 'undefined';
}
catch (e) {
console.log("Error in retrieving EnketoTripButtonService: ", e);
}
}

const UNLABELED = {
key: "unlabeled",
text: i18next.t("diary.unlabeled"),
filter: unlabeledCheck
}

const TO_LABEL = {
key: "to_label",
text: i18next.t("diary.to-label"),
filter: unlabeledCheck
}

export const configuredFilters = [
TO_LABEL,
UNLABELED
];
67 changes: 0 additions & 67 deletions www/js/survey/multilabel/infinite_scroll_filters.js

This file was deleted.

58 changes: 58 additions & 0 deletions www/js/survey/multilabel/infinite_scroll_filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* The general structure of this code is that all the timeline information for
* a particular day is retrieved from the Timeline factory and put into the scope.
* For best performance, all data should be loaded into the in-memory timeline,
* and in addition to writing to storage, the data should be written to memory.
* All UI elements should only use $scope variables.
*/

import i18next from "i18next";

const unlabeledCheck = (t) => {
return t.INPUTS
.map((inputType, index) => !t.userInput[inputType])
.reduce((acc, val) => acc || val, false);
}

const invalidCheck = (t) => {
const retVal =
(t.userInput['MODE'] && t.userInput['MODE'].value === 'pilot_ebike') &&
(!t.userInput['REPLACED_MODE'] ||
t.userInput['REPLACED_MODE'].value === 'pilot_ebike' ||
t.userInput['REPLACED_MODE'].value === 'same_mode');
return retVal;
}

const toLabelCheck = (trip) => {
if (trip.expectation) {
console.log(trip.expectation.to_label)
return trip.expectation.to_label && unlabeledCheck(trip);
} else {
return true;
}
}

const UNLABELED = {
key: "unlabeled",
text: i18next.t("diary.unlabeled"),
filter: unlabeledCheck,
width: "col-50"
}

const INVALID_EBIKE = {
key: "invalid_ebike",
text: i18next.t("diary.invalid-ebike"),
filter: invalidCheck
}

const TO_LABEL = {
key: "to_label",
text: i18next.t("diary.to-label"),
filter: toLabelCheck,
width: "col-50"
}

export const configuredFilters = [
TO_LABEL,
UNLABELED
];
9 changes: 6 additions & 3 deletions www/js/survey/survey.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
type SurveyOption = { filter: string, service: string, elementTag: string }
import { configuredFilters as multilabelConfiguredFilters } from "./multilabel/infinite_scroll_filters";
import { configuredFilters as enketoConfiguredFilters } from "./enketo/infinite_scroll_filters";

type SurveyOption = { filter: Array<any>, service: string, elementTag: string }
export const SurveyOptions: {[key: string]: SurveyOption} = {
MULTILABEL: {
filter: "MultiLabelInfScrollFilters",
filter: multilabelConfiguredFilters,
service: "MultiLabelService",
elementTag: "multilabel"
},
ENKETO: {
filter: "EnketoTripInfScrollFilters",
filter: enketoConfiguredFilters,
service: "EnketoTripButtonService",
elementTag: "enketo-trip-button"
}
Expand Down

0 comments on commit 1138d29

Please sign in to comment.