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

Adding pubspec support for survey validator #106

Merged
merged 7 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/contextual-json-validator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,27 @@ permissions:
jobs:
contextual-json-validate:
runs-on: ubuntu-latest
defaults:
run:
working-directory: surveys/survey-validator
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f

- run: dart surveys/validator/json-validator.dart
- run: dart pub get
- run: dart run

analyze:
runs-on: ubuntu-latest
defaults:
run:
working-directory: surveys/validator
working-directory: surveys/survey-validator
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f

- run: dart pub get

- name: Verify formatting
run: dart format --output=none --set-exit-if-changed .

Expand Down
4 changes: 4 additions & 0 deletions surveys/contextual-survey-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"description": "Help improve Flutter's release builds with this 3-question survey!",
"snoozeForMinutes": 7200,
"samplingRate": 0.1,
"excludeDashTools": [
"flutter-tool",
"dart-tool"
],
"conditions": [
{
"field": "logFileStats.recordCount",
Expand Down
3 changes: 3 additions & 0 deletions surveys/survey-validator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/
30 changes: 30 additions & 0 deletions surveys/survey-validator/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
9 changes: 9 additions & 0 deletions surveys/survey-validator/bin/survey_validator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'dart:io';

import 'package:survey_validator/survey_validator.dart' as survey_validator;

void main(List<String> arguments) {
final contextualSurveyFile = File('../contextual-survey-metadata.json');

survey_validator.checkJson(contextualSurveyFile);
}
eliasyishak marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,8 +1,58 @@
import 'dart:convert';
import 'dart:io';

void main() {
final contextualSurveyFile = File('surveys/contextual-survey-metadata.json');
import 'package:unified_analytics/unified_analytics.dart';

/// The allowed action strings for a given button
const allowedButtonActions = {
'accept',
'dismiss',
'snooze',
};

/// The allowed operators for a given condition item
const allowedConditionOperators = {
'>=',
'<=',
'>',
'<',
'==',
'!=',
};

/// Required keys for the button object
const buttonRequiredKeys = [
'buttonText',
'action',
'url',
'promptRemainsVisible',
];

/// Required keys for the condition object
const conditionRequiredKeys = [
'field',
'operator',
'value',
];

/// The top level keys that must exist for each json object
/// in the array
const requiredKeys = {
'uniqueId',
'startDate',
'endDate',
'description',
'snoozeForMinutes',
'samplingRate',
'conditions',
'buttons',
'excludeDashTools',
};

/// The valid dash tools stored in the [DashTool] enum
Set<String> get validDashTools => DashTool.values.map((e) => e.label).toSet();

void checkJson(File contextualSurveyFile) {
final jsonContents = jsonDecode(contextualSurveyFile.readAsStringSync());

if (jsonContents is! List) {
Expand All @@ -18,7 +68,8 @@ void main() {
// Ensure that the number of keys found in each object is correct
if (surveyObject.keys.length != requiredKeys.length) {
throw ArgumentError(
'There should only be ${requiredKeys.length} keys per survey object');
'There should only be ${requiredKeys.length} keys per survey object\n'
'The required keys are: ${requiredKeys.join(', ')}');
}

// Ensure that the keys themselves match what has been defined
Expand All @@ -35,6 +86,7 @@ void main() {
final description = surveyObject['description'] as String;
final snoozeForMinutes = surveyObject['snoozeForMinutes'] as int;
final samplingRate = surveyObject['samplingRate'] as double;
final excludeDashToolsList = surveyObject['excludeDashTools'] as List;
final conditionList = surveyObject['conditions'] as List;
final buttonList = surveyObject['buttons'] as List;

Expand Down Expand Up @@ -62,6 +114,20 @@ void main() {
throw ArgumentError('Sampling rate must be between 0 and 1 inclusive');
}

// Validation on the array containing dash tools to exclude
for (final excludeDashTool in excludeDashToolsList) {
if (excludeDashTool is! String) {
throw ArgumentError(
'Each dash tool in the exclude list must be a string');
}

if (!validDashTools.contains(excludeDashTool)) {
throw ArgumentError(
'The excluded dash tool: "$excludeDashTool" is not valid\n'
'Valid dash tools are: ${validDashTools.join(', ')}');
}
}

// Validation on the condition array
for (final conditionObject in conditionList) {
if (conditionObject is! Map) {
Expand Down Expand Up @@ -136,48 +202,3 @@ void main() {
}
}
}

/// The allowed action strings for a given button
const allowedButtonActions = {
'accept',
'dismiss',
'snooze',
};

/// The allowed operators for a given condition item
const allowedConditionOperators = {
'>=',
'<=',
'>',
'<',
'==',
'!=',
};

/// Required keys for the button object
const buttonRequiredKeys = [
'buttonText',
'action',
'url',
'promptRemainsVisible',
];

/// Required keys for the condition object
const conditionRequiredKeys = [
'field',
'operator',
'value',
];

/// The top level keys that must exist for each json object
/// in the array
const requiredKeys = {
'uniqueId',
'startDate',
'endDate',
'description',
'snoozeForMinutes',
'samplingRate',
'conditions',
'buttons',
};
Loading