mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
switched to xunit
This commit is contained in:
450
.editorconfig
450
.editorconfig
@@ -1,50 +1,127 @@
|
|||||||
# Top-most EditorConfig file
|
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
# use unix newline characters
|
# All files
|
||||||
end_of_line = lf
|
|
||||||
|
|
||||||
[*.cs]
|
|
||||||
dotnet_naming_rule.methods_must_be_camel_case.severity = warning
|
|
||||||
dotnet_naming_rule.methods_must_be_camel_case.symbols = private_methods
|
|
||||||
dotnet_naming_rule.methods_must_be_camel_case.style = camel_case_style
|
|
||||||
|
|
||||||
dotnet_naming_symbols.private_methods.applicable_kinds = method
|
|
||||||
dotnet_naming_symbols.private_methods.applicable_accessibilities = private
|
|
||||||
|
|
||||||
dotnet_naming_style.camel_case_style.capitalization = camel_case
|
|
||||||
dotnet_diagnostic.CA2254.severity = none
|
|
||||||
|
|
||||||
[*.razor]
|
|
||||||
indent_style = ignore
|
|
||||||
indent_size = ignore
|
|
||||||
|
|
||||||
|
|
||||||
# Default settings:
|
|
||||||
# A newline ending every file
|
|
||||||
# Use 4 spaces as indentation
|
|
||||||
[*]
|
[*]
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
trim_trailing_whitespace = true
|
end_of_line = lf
|
||||||
|
|
||||||
[project.json]
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# Generated code
|
|
||||||
[*{_AssemblyInfo.cs,.notsupported.cs}]
|
|
||||||
generated_code = true
|
|
||||||
|
|
||||||
# C# files
|
# C# files
|
||||||
[*.cs]
|
[*.cs]
|
||||||
|
tab_width = 2
|
||||||
|
insert_final_newline = false
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
|
||||||
|
# Organize usings
|
||||||
|
dotnet_separate_import_directive_groups = true
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
file_header_template = unset
|
||||||
|
|
||||||
|
# this. and Me. preferences
|
||||||
|
dotnet_style_qualification_for_event = false:silent
|
||||||
|
dotnet_style_qualification_for_field = false:silent
|
||||||
|
dotnet_style_qualification_for_method = false:silent
|
||||||
|
dotnet_style_qualification_for_property = false:silent
|
||||||
|
|
||||||
|
# Language keywords vs BCL types preferences
|
||||||
|
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||||
|
dotnet_style_predefined_type_for_member_access = true:silent
|
||||||
|
|
||||||
|
# Parentheses preferences
|
||||||
|
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||||
|
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||||
|
|
||||||
|
# Modifier preferences
|
||||||
|
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||||
|
|
||||||
|
# Expression-level preferences
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||||
|
dotnet_style_prefer_auto_properties = true:suggestion
|
||||||
|
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||||
|
|
||||||
|
# Field preferences
|
||||||
|
dotnet_style_readonly_field = true:warning
|
||||||
|
|
||||||
|
# Parameter preferences
|
||||||
|
dotnet_code_quality_unused_parameters = all:suggestion
|
||||||
|
|
||||||
|
# Suppression preferences
|
||||||
|
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||||
|
|
||||||
|
#### C# Coding Conventions ####
|
||||||
|
[*.cs]
|
||||||
|
|
||||||
|
# var preferences
|
||||||
|
csharp_style_var_elsewhere = false:silent
|
||||||
|
csharp_style_var_for_built_in_types = false:silent
|
||||||
|
csharp_style_var_when_type_is_apparent = false:silent
|
||||||
|
|
||||||
|
# Expression-bodied members
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_lambdas = true:suggestion
|
||||||
|
csharp_style_expression_bodied_local_functions = false:silent
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
|
||||||
|
# Pattern matching preferences
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_prefer_not_pattern = true:suggestion
|
||||||
|
csharp_style_prefer_pattern_matching = true:silent
|
||||||
|
csharp_style_prefer_switch_expression = true:suggestion
|
||||||
|
|
||||||
|
# Null-checking preferences
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
|
||||||
|
# Modifier preferences
|
||||||
|
csharp_prefer_static_local_function = true:warning
|
||||||
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
|
||||||
|
|
||||||
|
# Code-block preferences
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
csharp_prefer_simple_using_statement = true:suggestion
|
||||||
|
|
||||||
|
# Expression-level preferences
|
||||||
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_prefer_index_operator = true:suggestion
|
||||||
|
csharp_style_prefer_range_operator = true:suggestion
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||||
|
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||||
|
|
||||||
|
# 'using' directive preferences
|
||||||
|
csharp_using_directive_placement = outside_namespace:silent
|
||||||
|
|
||||||
|
#### C# Formatting Rules ####
|
||||||
|
|
||||||
# New line preferences
|
# New line preferences
|
||||||
csharp_new_line_before_open_brace = all
|
|
||||||
csharp_new_line_before_else = true
|
|
||||||
csharp_new_line_before_catch = true
|
csharp_new_line_before_catch = true
|
||||||
|
csharp_new_line_before_else = true
|
||||||
csharp_new_line_before_finally = true
|
csharp_new_line_before_finally = true
|
||||||
csharp_new_line_before_members_in_object_initializers = true
|
|
||||||
csharp_new_line_before_members_in_anonymous_types = true
|
csharp_new_line_before_members_in_anonymous_types = true
|
||||||
|
csharp_new_line_before_members_in_object_initializers = true
|
||||||
|
csharp_new_line_before_open_brace = all
|
||||||
csharp_new_line_between_query_expression_clauses = true
|
csharp_new_line_between_query_expression_clauses = true
|
||||||
|
|
||||||
# Indentation preferences
|
# Indentation preferences
|
||||||
@@ -52,100 +129,8 @@ csharp_indent_block_contents = true
|
|||||||
csharp_indent_braces = false
|
csharp_indent_braces = false
|
||||||
csharp_indent_case_contents = true
|
csharp_indent_case_contents = true
|
||||||
csharp_indent_case_contents_when_block = true
|
csharp_indent_case_contents_when_block = true
|
||||||
csharp_indent_switch_labels = true
|
|
||||||
csharp_indent_labels = one_less_than_current
|
csharp_indent_labels = one_less_than_current
|
||||||
|
csharp_indent_switch_labels = true
|
||||||
# Modifier preferences
|
|
||||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
|
||||||
|
|
||||||
# avoid this. unless absolutely necessary
|
|
||||||
dotnet_style_qualification_for_field = false:suggestion
|
|
||||||
dotnet_style_qualification_for_property = false:suggestion
|
|
||||||
dotnet_style_qualification_for_method = false:suggestion
|
|
||||||
dotnet_style_qualification_for_event = false:suggestion
|
|
||||||
|
|
||||||
# Types: use keywords instead of BCL types, and permit var only when the type is clear
|
|
||||||
# csharp_style_var_for_built_in_types = false:suggestion
|
|
||||||
csharp_style_var_when_type_is_apparent = false:none
|
|
||||||
# csharp_style_var_elsewhere = false:suggestion
|
|
||||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
|
||||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
|
||||||
|
|
||||||
# name all constant fields using PascalCase
|
|
||||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
|
||||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
|
||||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
|
||||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
|
||||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
|
||||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
|
||||||
|
|
||||||
# static fields should have s_ prefix
|
|
||||||
# dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
|
|
||||||
# dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
|
|
||||||
# dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
|
|
||||||
# dotnet_naming_symbols.static_fields.applicable_kinds = field
|
|
||||||
# dotnet_naming_symbols.static_fields.required_modifiers = static
|
|
||||||
# dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
|
|
||||||
# dotnet_naming_style.static_prefix_style.required_prefix = s_
|
|
||||||
# dotnet_naming_style.static_prefix_style.capitalization = camel_case
|
|
||||||
|
|
||||||
# internal and private fields should be _camelCase
|
|
||||||
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
|
|
||||||
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
|
|
||||||
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
|
|
||||||
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
|
||||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
|
||||||
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
|
||||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
|
||||||
|
|
||||||
# Code style defaults
|
|
||||||
csharp_using_directive_placement = outside_namespace:suggestion
|
|
||||||
dotnet_sort_system_directives_first = true
|
|
||||||
csharp_prefer_braces = true:silent
|
|
||||||
csharp_preserve_single_line_blocks = true:none
|
|
||||||
csharp_preserve_single_line_statements = false:none
|
|
||||||
csharp_prefer_static_local_function = true:suggestion
|
|
||||||
csharp_prefer_simple_using_statement = false:none
|
|
||||||
csharp_style_prefer_switch_expression = true:suggestion
|
|
||||||
dotnet_style_readonly_field = true:suggestion
|
|
||||||
|
|
||||||
# Expression-level preferences
|
|
||||||
dotnet_style_object_initializer = true:suggestion
|
|
||||||
dotnet_style_collection_initializer = true:suggestion
|
|
||||||
dotnet_style_explicit_tuple_names = true:suggestion
|
|
||||||
dotnet_style_coalesce_expression = true:suggestion
|
|
||||||
dotnet_style_null_propagation = true:suggestion
|
|
||||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
|
||||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
|
||||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
|
||||||
dotnet_style_prefer_auto_properties = true:suggestion
|
|
||||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
|
||||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
|
||||||
csharp_prefer_simple_default_expression = true:suggestion
|
|
||||||
|
|
||||||
# Expression-bodied members
|
|
||||||
csharp_style_expression_bodied_methods = true:silent
|
|
||||||
csharp_style_expression_bodied_constructors = true:silent
|
|
||||||
csharp_style_expression_bodied_operators = true:silent
|
|
||||||
csharp_style_expression_bodied_properties = true:silent
|
|
||||||
csharp_style_expression_bodied_indexers = true:silent
|
|
||||||
csharp_style_expression_bodied_accessors = true:silent
|
|
||||||
csharp_style_expression_bodied_lambdas = true:silent
|
|
||||||
csharp_style_expression_bodied_local_functions = true:silent
|
|
||||||
|
|
||||||
# Pattern matching
|
|
||||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
|
||||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
|
||||||
csharp_style_inlined_variable_declaration = true:suggestion
|
|
||||||
|
|
||||||
# Null checking preferences
|
|
||||||
csharp_style_throw_expression = true:suggestion
|
|
||||||
csharp_style_conditional_delegate_call = true:suggestion
|
|
||||||
|
|
||||||
# Other features
|
|
||||||
csharp_style_prefer_index_operator = false:none
|
|
||||||
csharp_style_prefer_range_operator = false:none
|
|
||||||
csharp_style_pattern_local_over_anonymous_function = false:none
|
|
||||||
|
|
||||||
# Space preferences
|
# Space preferences
|
||||||
csharp_space_after_cast = false
|
csharp_space_after_cast = false
|
||||||
@@ -155,7 +140,7 @@ csharp_space_after_dot = false
|
|||||||
csharp_space_after_keywords_in_control_flow_statements = true
|
csharp_space_after_keywords_in_control_flow_statements = true
|
||||||
csharp_space_after_semicolon_in_for_statement = true
|
csharp_space_after_semicolon_in_for_statement = true
|
||||||
csharp_space_around_binary_operators = before_and_after
|
csharp_space_around_binary_operators = before_and_after
|
||||||
csharp_space_around_declaration_statements = do_not_ignore
|
csharp_space_around_declaration_statements = false
|
||||||
csharp_space_before_colon_in_inheritance_clause = true
|
csharp_space_before_colon_in_inheritance_clause = true
|
||||||
csharp_space_before_comma = false
|
csharp_space_before_comma = false
|
||||||
csharp_space_before_dot = false
|
csharp_space_before_dot = false
|
||||||
@@ -171,34 +156,193 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
|
|||||||
csharp_space_between_parentheses = false
|
csharp_space_between_parentheses = false
|
||||||
csharp_space_between_square_brackets = false
|
csharp_space_between_square_brackets = false
|
||||||
|
|
||||||
# C++ Files
|
# Wrapping preferences
|
||||||
[*.{cpp,h,in}]
|
csharp_preserve_single_line_blocks = true
|
||||||
curly_bracket_next_line = true
|
csharp_preserve_single_line_statements = true
|
||||||
indent_brace_style = Allman
|
|
||||||
|
|
||||||
# Xml project files
|
#### Naming styles ####
|
||||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
|
[*.{cs,vb}]
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.{csproj,vbproj,proj,nativeproj,locproj}]
|
# Naming rules
|
||||||
charset = utf-8
|
|
||||||
|
|
||||||
# Xml build files
|
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
|
||||||
[*.builds]
|
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
|
||||||
indent_size = 2
|
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
# Xml files
|
dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
|
||||||
[*.{xml,stylecop,resx,ruleset}]
|
dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
|
||||||
indent_size = 2
|
dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
|
||||||
|
|
||||||
# Xml config files
|
dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
|
||||||
[*.{props,targets,config,nuspec}]
|
dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
|
||||||
indent_size = 2
|
dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
|
||||||
|
|
||||||
# YAML config files
|
dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
|
||||||
[*.{yml,yaml}]
|
dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
|
||||||
indent_size = 2
|
dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
|
||||||
|
dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.events_should_be_pascalcase.symbols = events
|
||||||
|
dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
|
||||||
|
dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
|
||||||
|
dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
|
||||||
|
dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
|
||||||
|
dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_fields_should_be_s_camelcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.private_fields_should_be_s_camelcase.symbols = private_fields
|
||||||
|
dotnet_naming_rule.private_fields_should_be_s_camelcase.style = camelcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
|
||||||
|
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
|
||||||
|
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
|
||||||
|
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
|
||||||
|
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
|
||||||
|
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
|
||||||
|
dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
|
||||||
|
dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
|
||||||
|
|
||||||
|
# Symbol specifications
|
||||||
|
|
||||||
|
dotnet_naming_symbols.interfaces.applicable_kinds = interface
|
||||||
|
dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.interfaces.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.enums.applicable_kinds = enum
|
||||||
|
dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.enums.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.events.applicable_kinds = event
|
||||||
|
dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.events.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.methods.applicable_kinds = method
|
||||||
|
dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.methods.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.properties.applicable_kinds = property
|
||||||
|
dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.properties.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.public_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
|
||||||
|
dotnet_naming_symbols.public_fields.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.private_fields.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.private_static_fields.required_modifiers = static
|
||||||
|
|
||||||
|
dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
|
||||||
|
dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.types_and_namespaces.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||||
|
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
|
||||||
|
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.type_parameters.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.private_constant_fields.required_modifiers = const
|
||||||
|
|
||||||
|
dotnet_naming_symbols.local_variables.applicable_kinds = local
|
||||||
|
dotnet_naming_symbols.local_variables.applicable_accessibilities = local
|
||||||
|
dotnet_naming_symbols.local_variables.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.local_constants.applicable_kinds = local
|
||||||
|
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
|
||||||
|
dotnet_naming_symbols.local_constants.required_modifiers = const
|
||||||
|
|
||||||
|
dotnet_naming_symbols.parameters.applicable_kinds = parameter
|
||||||
|
dotnet_naming_symbols.parameters.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.parameters.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
|
||||||
|
dotnet_naming_symbols.public_constant_fields.required_modifiers = const
|
||||||
|
|
||||||
|
dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
|
||||||
|
dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
|
||||||
|
|
||||||
|
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
|
||||||
|
|
||||||
|
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
|
||||||
|
dotnet_naming_symbols.local_functions.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.local_functions.required_modifiers =
|
||||||
|
|
||||||
|
# Naming styles
|
||||||
|
|
||||||
|
dotnet_naming_style.pascalcase.required_prefix =
|
||||||
|
dotnet_naming_style.pascalcase.required_suffix =
|
||||||
|
dotnet_naming_style.pascalcase.word_separator =
|
||||||
|
dotnet_naming_style.pascalcase.capitalization = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_style.ipascalcase.required_prefix = I
|
||||||
|
dotnet_naming_style.ipascalcase.required_suffix =
|
||||||
|
dotnet_naming_style.ipascalcase.word_separator =
|
||||||
|
dotnet_naming_style.ipascalcase.capitalization = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_style.tpascalcase.required_prefix = T
|
||||||
|
dotnet_naming_style.tpascalcase.required_suffix =
|
||||||
|
dotnet_naming_style.tpascalcase.word_separator =
|
||||||
|
dotnet_naming_style.tpascalcase.capitalization = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_style.camelcase.required_prefix =
|
||||||
|
dotnet_naming_style.camelcase.required_suffix =
|
||||||
|
dotnet_naming_style.camelcase.word_separator =
|
||||||
|
dotnet_naming_style.camelcase.capitalization = camel_case
|
||||||
|
|
||||||
|
dotnet_naming_style.s_camelcase.required_prefix = s_
|
||||||
|
dotnet_naming_style.s_camelcase.required_suffix =
|
||||||
|
dotnet_naming_style.s_camelcase.word_separator =
|
||||||
|
dotnet_naming_style.s_camelcase.capitalization = camel_case
|
||||||
|
|
||||||
# Shell scripts
|
|
||||||
[*.sh]
|
|
||||||
end_of_line = lf
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using CanvasModel.EnrollmentTerms;
|
|||||||
|
|
||||||
public class DeserializationTests
|
public class DeserializationTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestTerm()
|
public void TestTerm()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
public class CalendarMonthTests
|
public class CalendarMonthTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCalendarMonthCanGetFirstWeek()
|
public void TestCalendarMonthCanGetFirstWeek()
|
||||||
{
|
{
|
||||||
var month = new CalendarMonth(2023, 2);
|
var month = new CalendarMonth(2023, 2);
|
||||||
@@ -12,7 +12,7 @@ public class CalendarMonthTests
|
|||||||
month.Weeks.First().Should().BeEquivalentTo(expectedFirstWeek);
|
month.Weeks.First().Should().BeEquivalentTo(expectedFirstWeek);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanGetAnotherMonthsFirstWeek()
|
public void TestCanGetAnotherMonthsFirstWeek()
|
||||||
{
|
{
|
||||||
var month = new CalendarMonth(2023, 4);
|
var month = new CalendarMonth(2023, 4);
|
||||||
@@ -24,7 +24,7 @@ public class CalendarMonthTests
|
|||||||
month.Weeks.First().Should().BeEquivalentTo(expectedFirstWeek);
|
month.Weeks.First().Should().BeEquivalentTo(expectedFirstWeek);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCorrectNumberOfWeeks()
|
public void TestCorrectNumberOfWeeks()
|
||||||
{
|
{
|
||||||
var month = new CalendarMonth(2023, 4);
|
var month = new CalendarMonth(2023, 4);
|
||||||
@@ -32,7 +32,7 @@ public class CalendarMonthTests
|
|||||||
month.Weeks.Count().Should().Be(6);
|
month.Weeks.Count().Should().Be(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestLastWeekIsCorrect()
|
public void TestLastWeekIsCorrect()
|
||||||
{
|
{
|
||||||
var month = new CalendarMonth(2023, 4);
|
var month = new CalendarMonth(2023, 4);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// public class ConfigurationTests
|
// public class ConfigurationTests
|
||||||
// {
|
// {
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestCanCreateConfigFromTermAndDays()
|
// public void TestCanCreateConfigFromTermAndDays()
|
||||||
// {
|
// {
|
||||||
// DateTime startAt = new DateTime(2022, 1, 1);
|
// DateTime startAt = new DateTime(2022, 1, 1);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// public class ModuleTests
|
// public class ModuleTests
|
||||||
// {
|
// {
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void CanAddModule()
|
// public void CanAddModule()
|
||||||
// {
|
// {
|
||||||
// var manager = new ModuleManager();
|
// var manager = new ModuleManager();
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
// manager.Modules.First().Should().Be(module);
|
// manager.Modules.First().Should().Be(module);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void CanAddAssignmentToCorrectModule()
|
// public void CanAddAssignmentToCorrectModule()
|
||||||
// {
|
// {
|
||||||
// var manager = new ModuleManager();
|
// var manager = new ModuleManager();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// public class SemesterPlannerTests
|
// public class SemesterPlannerTests
|
||||||
// {
|
// {
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestCanCreatePlanner()
|
// public void TestCanCreatePlanner()
|
||||||
// {
|
// {
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
// semester.Months.Count().Should().Be(1);
|
// semester.Months.Count().Should().Be(1);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestNewPlannerHasCorrectNumberOfMonths()
|
// public void TestNewPlannerHasCorrectNumberOfMonths()
|
||||||
// {
|
// {
|
||||||
// var config = new SemesterCalendarConfig(
|
// var config = new SemesterCalendarConfig(
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
// semester.Months.Count().Should().Be(2);
|
// semester.Months.Count().Should().Be(2);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestNewPlannerHandlesTermsThatWrapYears()
|
// public void TestNewPlannerHandlesTermsThatWrapYears()
|
||||||
// {
|
// {
|
||||||
// var config = new SemesterCalendarConfig(
|
// var config = new SemesterCalendarConfig(
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
// semester.Months.Count().Should().Be(2);
|
// semester.Months.Count().Should().Be(2);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestSemesterGetsCorrectMonths()
|
// public void TestSemesterGetsCorrectMonths()
|
||||||
// {
|
// {
|
||||||
// var config = new SemesterCalendarConfig(
|
// var config = new SemesterCalendarConfig(
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestMonthsCanWrapYears()
|
// public void TestMonthsCanWrapYears()
|
||||||
// {
|
// {
|
||||||
// var config = new SemesterCalendarConfig(
|
// var config = new SemesterCalendarConfig(
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
// semester.Months.Last().Year.Should().Be(2023);
|
// semester.Months.Last().Year.Should().Be(2023);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public void TestSemesterTracksDaysOfWeek()
|
// public void TestSemesterTracksDaysOfWeek()
|
||||||
// {
|
// {
|
||||||
// DayOfWeek[] days = new DayOfWeek[] { DayOfWeek.Monday };
|
// DayOfWeek[] days = new DayOfWeek[] { DayOfWeek.Monday };
|
||||||
|
|||||||
@@ -9,15 +9,25 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="akka.testkit" Version="1.5.18" />
|
||||||
|
<PackageReference Include="Akka.TestKit.Xunit2" Version="1.5.18" />
|
||||||
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||||
<PackageReference Include="Moq" Version="4.18.4" />
|
<PackageReference Include="Moq" Version="4.18.4" />
|
||||||
<PackageReference Include="nsubstitute" Version="5.1.0" />
|
<PackageReference Include="nsubstitute" Version="5.1.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NSubstitute.Analyzers.CSharp" Version="1.0.17">
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
</PackageReference>
|
||||||
<PackageReference Include="RestSharp" Version="108.0.3" />
|
<PackageReference Include="xunit" Version="2.7.0" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using LocalModels;
|
|||||||
|
|
||||||
public class AssignmentMarkdownTests
|
public class AssignmentMarkdownTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseAssignmentSettings()
|
public void TestCanParseAssignmentSettings()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
@@ -24,7 +24,7 @@ public class AssignmentMarkdownTests
|
|||||||
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
||||||
parsedAssignment.Should().BeEquivalentTo(assignment);
|
parsedAssignment.Should().BeEquivalentTo(assignment);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void AssignmentWithEmptyRubric_CanBeParsed()
|
public void AssignmentWithEmptyRubric_CanBeParsed()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
@@ -43,7 +43,7 @@ public class AssignmentMarkdownTests
|
|||||||
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
||||||
parsedAssignment.Should().BeEquivalentTo(assignment);
|
parsedAssignment.Should().BeEquivalentTo(assignment);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void AssignmentWithEmptySubmissionTypes_CanBeParsed()
|
public void AssignmentWithEmptySubmissionTypes_CanBeParsed()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
@@ -66,7 +66,7 @@ public class AssignmentMarkdownTests
|
|||||||
parsedAssignment.Should().BeEquivalentTo(assignment);
|
parsedAssignment.Should().BeEquivalentTo(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void AssignmentWithoutLockAtDate_CanBeParsed()
|
public void AssignmentWithoutLockAtDate_CanBeParsed()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
@@ -89,7 +89,7 @@ public class AssignmentMarkdownTests
|
|||||||
parsedAssignment.Should().BeEquivalentTo(assignment);
|
parsedAssignment.Should().BeEquivalentTo(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void AssignmentWithoutDescription_CanBeParsed()
|
public void AssignmentWithoutDescription_CanBeParsed()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
@@ -111,7 +111,7 @@ public class AssignmentMarkdownTests
|
|||||||
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
var parsedAssignment = LocalAssignment.ParseMarkdown(assignmentMarkdown);
|
||||||
parsedAssignment.Should().BeEquivalentTo(assignment);
|
parsedAssignment.Should().BeEquivalentTo(assignment);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void Assignments_CanHaveThreeDashes()
|
public void Assignments_CanHaveThreeDashes()
|
||||||
{
|
{
|
||||||
var assignment = new LocalAssignment()
|
var assignment = new LocalAssignment()
|
||||||
|
|||||||
@@ -5,14 +5,13 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using NUnit.Framework.Internal;
|
|
||||||
|
|
||||||
public class FileStorageTests
|
public class FileStorageTests
|
||||||
{
|
{
|
||||||
private IFileStorageManager fileManager { get; set; }
|
private FileStorageManager fileManager { get; set; }
|
||||||
|
|
||||||
|
|
||||||
private static string setupTempDirectory()
|
public FileStorageTests()
|
||||||
{
|
{
|
||||||
var tempDirectory = Path.GetTempPath();
|
var tempDirectory = Path.GetTempPath();
|
||||||
var storageDirectory = tempDirectory + "fileStorageTests";
|
var storageDirectory = tempDirectory + "fileStorageTests";
|
||||||
@@ -29,14 +28,6 @@ public class FileStorageTests
|
|||||||
dir.Delete(true);
|
dir.Delete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return storageDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void SetUp()
|
|
||||||
{
|
|
||||||
var storageDirectory = setupTempDirectory();
|
|
||||||
|
|
||||||
var fileManagerLogger = new MyLogger<FileStorageManager>(NullLogger<FileStorageManager>.Instance);
|
var fileManagerLogger = new MyLogger<FileStorageManager>(NullLogger<FileStorageManager>.Instance);
|
||||||
var markdownLoaderLogger = new MyLogger<CourseMarkdownLoader>(NullLogger<CourseMarkdownLoader>.Instance);
|
var markdownLoaderLogger = new MyLogger<CourseMarkdownLoader>(NullLogger<CourseMarkdownLoader>.Instance);
|
||||||
var markdownSaverLogger = new MyLogger<MarkdownCourseSaver>(NullLogger<MarkdownCourseSaver>.Instance);
|
var markdownSaverLogger = new MyLogger<MarkdownCourseSaver>(NullLogger<MarkdownCourseSaver>.Instance);
|
||||||
@@ -52,7 +43,7 @@ public class FileStorageTests
|
|||||||
fileManager = new FileStorageManager(fileManagerLogger, markdownLoader, markdownSaver, otherLogger, fileConfiguration);
|
fileManager = new FileStorageManager(fileManagerLogger, markdownLoader, markdownSaver, otherLogger, fileConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task EmptyCourse_CanBeSavedAndLoaded()
|
public async Task EmptyCourse_CanBeSavedAndLoaded()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new LocalCourse
|
LocalCourse testCourse = new LocalCourse
|
||||||
@@ -69,7 +60,7 @@ public class FileStorageTests
|
|||||||
loadedCourse.Should().BeEquivalentTo(testCourse);
|
loadedCourse.Should().BeEquivalentTo(testCourse);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task CourseSettings_CanBeSavedAndLoaded()
|
public async Task CourseSettings_CanBeSavedAndLoaded()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
@@ -95,7 +86,7 @@ public class FileStorageTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task EmptyCourseModules_CanBeSavedAndLoaded()
|
public async Task EmptyCourseModules_CanBeSavedAndLoaded()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
@@ -119,7 +110,7 @@ public class FileStorageTests
|
|||||||
loadedCourse.Modules.Should().BeEquivalentTo(testCourse.Modules);
|
loadedCourse.Modules.Should().BeEquivalentTo(testCourse.Modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task CourseModules_WithAssignments_CanBeSavedAndLoaded()
|
public async Task CourseModules_WithAssignments_CanBeSavedAndLoaded()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
@@ -160,7 +151,7 @@ public class FileStorageTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task CourseModules_WithQuizzes_CanBeSavedAndLoaded()
|
public async Task CourseModules_WithQuizzes_CanBeSavedAndLoaded()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
@@ -204,7 +195,7 @@ public class FileStorageTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task MarkdownStorage_FullyPopulated_DoesNotLoseData()
|
public async Task MarkdownStorage_FullyPopulated_DoesNotLoseData()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
@@ -271,7 +262,7 @@ public class FileStorageTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public async Task MarkdownStorage_CanPersistPages()
|
public async Task MarkdownStorage_CanPersistPages()
|
||||||
{
|
{
|
||||||
LocalCourse testCourse = new()
|
LocalCourse testCourse = new()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using LocalModels;
|
|||||||
|
|
||||||
public class PageMarkdownTests
|
public class PageMarkdownTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParsePage()
|
public void TestCanParsePage()
|
||||||
{
|
{
|
||||||
var page = new LocalCoursePage
|
var page = new LocalCoursePage
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using LocalModels;
|
|||||||
|
|
||||||
public class MatchingTests
|
public class MatchingTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanParseMatchingQuestion()
|
public void CanParseMatchingQuestion()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -29,7 +29,7 @@ Match the following terms & definitions
|
|||||||
firstQuestion.Answers.First().MatchedText.Should().Be("a single command to be executed");
|
firstQuestion.Answers.First().MatchedText.Should().Be("a single command to be executed");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanCreateMarkdownForMatchingQuesiton()
|
public void CanCreateMarkdownForMatchingQuesiton()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -59,7 +59,7 @@ Match the following terms & definitions
|
|||||||
^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)";
|
^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)";
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void WhitespaceIsOptional()
|
public void WhitespaceIsOptional()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using LocalModels;
|
|||||||
public class MultipleAnswersTests
|
public class MultipleAnswersTests
|
||||||
{
|
{
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void QuzMarkdownIncludesMultipleAnswerQuestion()
|
public void QuzMarkdownIncludesMultipleAnswerQuestion()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -43,7 +43,7 @@ oneline question
|
|||||||
markdown.Should().Contain(expectedQuestionString);
|
markdown.Should().Contain(expectedQuestionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanParseQuestionWithMultipleAnswers()
|
public void CanParseQuestionWithMultipleAnswers()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -81,7 +81,7 @@ Which events are triggered when the user clicks on an input field?
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanUseBracesInAnswerFormultipleAnswer()
|
public void CanUseBracesInAnswerFormultipleAnswer()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuestion = @"
|
var rawMarkdownQuestion = @"
|
||||||
@@ -95,7 +95,7 @@ Which events are triggered when the user clicks on an input field?
|
|||||||
question.Answers.Count().Should().Be(2);
|
question.Answers.Count().Should().Be(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanUseBracesInAnswerFormultipleAnswer_MultiLine()
|
public void CanUseBracesInAnswerFormultipleAnswer_MultiLine()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuestion = @"
|
var rawMarkdownQuestion = @"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using LocalModels;
|
|||||||
|
|
||||||
public class MultipleChoiceTests
|
public class MultipleChoiceTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void QuzMarkdownIncludesMultipleChoiceQuestion()
|
public void QuzMarkdownIncludesMultipleChoiceQuestion()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -58,7 +58,7 @@ endline
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void LetterOptionalForMultipleChoice()
|
public void LetterOptionalForMultipleChoice()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using LocalModels;
|
|||||||
public class QuizDeterministicChecks
|
public class QuizDeterministicChecks
|
||||||
{
|
{
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_EmptyQuiz()
|
public void SerializationIsDeterministic_EmptyQuiz()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -23,7 +23,7 @@ public class QuizDeterministicChecks
|
|||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_ShowCorrectAnswers()
|
public void SerializationIsDeterministic_ShowCorrectAnswers()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -43,7 +43,7 @@ public class QuizDeterministicChecks
|
|||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_ShortAnswer()
|
public void SerializationIsDeterministic_ShortAnswer()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -71,7 +71,7 @@ public class QuizDeterministicChecks
|
|||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_Essay()
|
public void SerializationIsDeterministic_Essay()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -99,7 +99,7 @@ public class QuizDeterministicChecks
|
|||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_MultipleAnswer()
|
public void SerializationIsDeterministic_MultipleAnswer()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -138,7 +138,7 @@ public class QuizDeterministicChecks
|
|||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_MultipleChoice()
|
public void SerializationIsDeterministic_MultipleChoice()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -176,7 +176,7 @@ public class QuizDeterministicChecks
|
|||||||
var parsedQuiz = LocalQuiz.ParseMarkdown(quizMarkdown);
|
var parsedQuiz = LocalQuiz.ParseMarkdown(quizMarkdown);
|
||||||
parsedQuiz.Should().BeEquivalentTo(quiz);
|
parsedQuiz.Should().BeEquivalentTo(quiz);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void SerializationIsDeterministic_Matching()
|
public void SerializationIsDeterministic_Matching()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using LocalModels;
|
|||||||
// try to follow syntax from https://github.com/gpoore/text2qti
|
// try to follow syntax from https://github.com/gpoore/text2qti
|
||||||
public class QuizMarkdownTests
|
public class QuizMarkdownTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanSerializeQuizToMarkdown()
|
public void CanSerializeQuizToMarkdown()
|
||||||
{
|
{
|
||||||
var quiz = new LocalQuiz()
|
var quiz = new LocalQuiz()
|
||||||
@@ -37,7 +37,7 @@ this is my description in markdown
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseMarkdownQuizWithNoQuestions()
|
public void TestCanParseMarkdownQuizWithNoQuestions()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = new StringBuilder();
|
var rawMarkdownQuiz = new StringBuilder();
|
||||||
@@ -68,7 +68,7 @@ this is my description in markdown
|
|||||||
quiz.AllowedAttempts.Should().Be(-1);
|
quiz.AllowedAttempts.Should().Be(-1);
|
||||||
quiz.Description.Should().Be(expectedDescription.ToString());
|
quiz.Description.Should().Be(expectedDescription.ToString());
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseMarkdownQuizPassword()
|
public void TestCanParseMarkdownQuizPassword()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ this is my description in markdown
|
|||||||
quiz.Password.Should().Be(password);
|
quiz.Password.Should().Be(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseMarkdownQuiz_CanConfigureToShowCorrectAnswers()
|
public void TestCanParseMarkdownQuiz_CanConfigureToShowCorrectAnswers()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = new StringBuilder();
|
var rawMarkdownQuiz = new StringBuilder();
|
||||||
@@ -118,7 +118,7 @@ this is my description in markdown
|
|||||||
quiz.showCorrectAnswers.Should().BeFalse();
|
quiz.showCorrectAnswers.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseQuizWithQuestions()
|
public void TestCanParseQuizWithQuestions()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -159,7 +159,7 @@ b) false
|
|||||||
firstQuestion.Answers.ElementAt(1).Text.Should().Contain("endline");
|
firstQuestion.Answers.ElementAt(1).Text.Should().Contain("endline");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanParseMultipleQuestions()
|
public void CanParseMultipleQuestions()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -192,7 +192,7 @@ b) false
|
|||||||
secondQuestion.QuestionType.Should().Be(QuestionType.MULTIPLE_CHOICE);
|
secondQuestion.QuestionType.Should().Be(QuestionType.MULTIPLE_CHOICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void ShortAnswerToMarkdown_IsCorrect()
|
public void ShortAnswerToMarkdown_IsCorrect()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -220,7 +220,7 @@ Which events are triggered when the user clicks on an input field?
|
|||||||
short_answer";
|
short_answer";
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void NegativePoints_IsAllowed()
|
public void NegativePoints_IsAllowed()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -244,7 +244,7 @@ short answer
|
|||||||
var firstQuestion = quiz.Questions.First();
|
var firstQuestion = quiz.Questions.First();
|
||||||
firstQuestion.Points.Should().Be(-4);
|
firstQuestion.Points.Should().Be(-4);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void FloatingPointPoints_IsAllowed()
|
public void FloatingPointPoints_IsAllowed()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using LocalModels;
|
|||||||
|
|
||||||
public class TextAnswerTests
|
public class TextAnswerTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanParseEssay()
|
public void CanParseEssay()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -28,7 +28,7 @@ essay
|
|||||||
firstQuestion.Text.Should().NotContain("essay");
|
firstQuestion.Text.Should().NotContain("essay");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void CanParseShortAnswer()
|
public void CanParseShortAnswer()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -54,7 +54,7 @@ short answer
|
|||||||
firstQuestion.Text.Should().NotContain("short answer");
|
firstQuestion.Text.Should().NotContain("short answer");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void ShortAnswerToMarkdown_IsCorrect()
|
public void ShortAnswerToMarkdown_IsCorrect()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
@@ -83,7 +83,7 @@ short_answer";
|
|||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void EssayQuestionToMarkdown_IsCorrect()
|
public void EssayQuestionToMarkdown_IsCorrect()
|
||||||
{
|
{
|
||||||
var rawMarkdownQuiz = @"
|
var rawMarkdownQuiz = @"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using LocalModels;
|
|||||||
public class RubricMarkdownTests
|
public class RubricMarkdownTests
|
||||||
{
|
{
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseOneItem()
|
public void TestCanParseOneItem()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -17,7 +17,7 @@ public class RubricMarkdownTests
|
|||||||
rubric.First().Points.Should().Be(2);
|
rubric.First().Points.Should().Be(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseMultipleItems()
|
public void TestCanParseMultipleItems()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -32,7 +32,7 @@ public class RubricMarkdownTests
|
|||||||
rubric.ElementAt(1).Points.Should().Be(3);
|
rubric.ElementAt(1).Points.Should().Be(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseSinglePoint()
|
public void TestCanParseSinglePoint()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -45,7 +45,7 @@ public class RubricMarkdownTests
|
|||||||
rubric.First().Points.Should().Be(1);
|
rubric.First().Points.Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseSingleExtraCredit_LowerCase()
|
public void TestCanParseSingleExtraCredit_LowerCase()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -57,7 +57,7 @@ public class RubricMarkdownTests
|
|||||||
rubric.First().Label.Should().Be("(extra credit) this is the task");
|
rubric.First().Label.Should().Be("(extra credit) this is the task");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseSingleExtraCredit_UpperCase()
|
public void TestCanParseSingleExtraCredit_UpperCase()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -69,7 +69,7 @@ public class RubricMarkdownTests
|
|||||||
rubric.First().Label.Should().Be("(Extra Credit) this is the task");
|
rubric.First().Label.Should().Be("(Extra Credit) this is the task");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseFloatingPointNubmers()
|
public void TestCanParseFloatingPointNubmers()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -79,7 +79,7 @@ public class RubricMarkdownTests
|
|||||||
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
||||||
rubric.First().Points.Should().Be(1.5);
|
rubric.First().Points.Should().Be(1.5);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseNegativeNubmers()
|
public void TestCanParseNegativeNubmers()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
@@ -89,7 +89,7 @@ public class RubricMarkdownTests
|
|||||||
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
||||||
rubric.First().Points.Should().Be(-2.0);
|
rubric.First().Points.Should().Be(-2.0);
|
||||||
}
|
}
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanParseNegativeFloatingPointNubmers()
|
public void TestCanParseNegativeFloatingPointNubmers()
|
||||||
{
|
{
|
||||||
var rawRubric = @"
|
var rawRubric = @"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
// public class ICanvasServiceTests
|
// public class ICanvasServiceTests
|
||||||
// {
|
// {
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public async Task CanReadCanvasSemesters()
|
// public async Task CanReadCanvasSemesters()
|
||||||
// {
|
// {
|
||||||
// var expectedTerms = new EnrollmentTermModel[] {
|
// var expectedTerms = new EnrollmentTermModel[] {
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
// canvasTerms.Should().BeEquivalentTo(expectedTerms);
|
// canvasTerms.Should().BeEquivalentTo(expectedTerms);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// [Test]
|
// [Fact]
|
||||||
// public async Task CanGetActiveTerms()
|
// public async Task CanGetActiveTerms()
|
||||||
// {
|
// {
|
||||||
// var expectedTerms = new EnrollmentTermModel[] {
|
// var expectedTerms = new EnrollmentTermModel[] {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
global using System.Text.Json;
|
global using System.Text.Json;
|
||||||
global using FluentAssertions;
|
global using FluentAssertions;
|
||||||
global using NUnit.Framework;
|
global using Xunit;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Management.Web.Pages.Course.CourseCalendar;
|
|||||||
|
|
||||||
public class MonthDetailTests
|
public class MonthDetailTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Fact]
|
||||||
public void TestCanGetMonthName()
|
public void TestCanGetMonthName()
|
||||||
{
|
{
|
||||||
var calendarMonth = new CalendarMonth(2022, 2);
|
var calendarMonth = new CalendarMonth(2022, 2);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Akka" Version="1.5.20" />
|
||||||
|
<PackageReference Include="Akka.DependencyInjection" Version="1.5.20" />
|
||||||
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||||
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
||||||
<PackageReference Include="Markdig" Version="0.31.0" />
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
global using System.ComponentModel.DataAnnotations;
|
global using System.ComponentModel.DataAnnotations;
|
||||||
global using System.Text.Json;
|
global using System.Text.Json;
|
||||||
global using System.Text.Json.Serialization;
|
global using System.Text.Json.Serialization;
|
||||||
|
|
||||||
global using CanvasModel;
|
global using CanvasModel;
|
||||||
global using CanvasModel.Courses;
|
global using CanvasModel.Courses;
|
||||||
global using CanvasModel.EnrollmentTerms;
|
global using CanvasModel.EnrollmentTerms;
|
||||||
|
|
||||||
global using LocalModels;
|
global using LocalModels;
|
||||||
|
|
||||||
global using Management.Planner;
|
global using Management.Planner;
|
||||||
global using Management.Services;
|
global using Management.Services;
|
||||||
global using Management.Services.Canvas;
|
global using Management.Services.Canvas;
|
||||||
global using Management.Web.Shared;
|
global using Management.Web.Shared;
|
||||||
global using Management.Web.Shared.Components;
|
global using Management.Web.Shared.Components;
|
||||||
|
|
||||||
using dotenv.net;
|
using dotenv.net;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
using Microsoft.AspNetCore.ResponseCompression;
|
using Microsoft.AspNetCore.ResponseCompression;
|
||||||
|
|
||||||
using OpenTelemetry;
|
using OpenTelemetry;
|
||||||
using OpenTelemetry.Logs;
|
using OpenTelemetry.Logs;
|
||||||
using OpenTelemetry.Metrics;
|
using OpenTelemetry.Metrics;
|
||||||
@@ -69,25 +75,40 @@ builder.Services.AddServerSideBlazor();
|
|||||||
|
|
||||||
builder.Services.AddLogging();
|
builder.Services.AddLogging();
|
||||||
|
|
||||||
builder.Services.AddScoped(typeof(MyLogger<>));
|
builder.Services.AddSingleton(typeof(MyLogger<>));
|
||||||
|
|
||||||
builder.Services.AddScoped<IWebRequestor, WebRequestor>();
|
// stateless services
|
||||||
builder.Services.AddScoped<CanvasServiceUtils>();
|
builder.Services.AddSingleton<IWebRequestor, WebRequestor>();
|
||||||
builder.Services.AddScoped<ICanvasAssignmentService, CanvasAssignmentService>();
|
builder.Services.AddSingleton<CanvasServiceUtils>();
|
||||||
builder.Services.AddScoped<ICanvasCoursePageService, CanvasCoursePageService>();
|
builder.Services.AddSingleton<ICanvasAssignmentService, CanvasAssignmentService>();
|
||||||
builder.Services.AddScoped<ICanvasAssignmentGroupService, CanvasAssignmentGroupService>();
|
builder.Services.AddSingleton<ICanvasCoursePageService, CanvasCoursePageService>();
|
||||||
builder.Services.AddScoped<ICanvasQuizService, CanvasQuizService>();
|
builder.Services.AddSingleton<ICanvasAssignmentGroupService, CanvasAssignmentGroupService>();
|
||||||
builder.Services.AddScoped<ICanvasModuleService, CanvasModuleService>();
|
builder.Services.AddSingleton<ICanvasQuizService, CanvasQuizService>();
|
||||||
builder.Services.AddScoped<ICanvasService, CanvasService>();
|
builder.Services.AddSingleton<ICanvasModuleService, CanvasModuleService>();
|
||||||
|
builder.Services.AddSingleton<ICanvasService, CanvasService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<MarkdownCourseSaver>();
|
builder.Services.AddSingleton<MarkdownCourseSaver>();
|
||||||
builder.Services.AddScoped<CourseMarkdownLoader>();
|
builder.Services.AddSingleton<CourseMarkdownLoader>();
|
||||||
builder.Services.AddScoped<IFileStorageManager>(sp =>
|
|
||||||
|
builder.Services.AddSingleton<FileStorageManager>();
|
||||||
|
|
||||||
|
// one actor system, maybe different actor for different pages?
|
||||||
|
builder.Services.AddSingleton<AkkaService>();
|
||||||
|
builder.Services.AddHostedService(sp => sp.GetRequiredService<AkkaService>());
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: need to handle scoped requirements
|
||||||
|
builder.Services.AddSingleton(sp =>
|
||||||
{
|
{
|
||||||
var manager = ActivatorUtilities.CreateInstance<FileStorageManager>(sp);
|
var akka = sp.GetRequiredService<AkkaService>();
|
||||||
var logger = sp.GetRequiredService<ILogger<FileStorageManagerCached>>();
|
return new CanvasQueue(akka.CanvasQueueActor ?? throw new Exception("Canvas queue actor not properly created"));
|
||||||
return new FileStorageManagerCached(manager, logger);
|
|
||||||
});
|
});
|
||||||
|
builder.Services.AddSingleton<IFileStorageManager>(sp =>
|
||||||
|
{
|
||||||
|
var akka = sp.GetRequiredService<AkkaService>();
|
||||||
|
return new LocalStorageCache(akka.StorageActor ?? throw new Exception("Canvas queue actor not properly created"));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddScoped<CoursePlanner>();
|
builder.Services.AddScoped<CoursePlanner>();
|
||||||
builder.Services.AddScoped<AssignmentEditorContext>();
|
builder.Services.AddScoped<AssignmentEditorContext>();
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
loadingTerms = true;
|
loadingTerms = true;
|
||||||
terms = await canvas.GetCurrentTermsFor();
|
terms = await canvas.GetCurrentTermsFor();
|
||||||
loadingTerms = false;
|
loadingTerms = false;
|
||||||
directoriesNotUsed = fileStorageManager.GetEmptyDirectories();
|
directoriesNotUsed = await fileStorageManager.GetEmptyDirectories();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveNewCourse()
|
private async Task SaveNewCourse()
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Akka" Version="1.5.20" />
|
||||||
|
<PackageReference Include="Akka.DependencyInjection" Version="1.5.20" />
|
||||||
<PackageReference Include="Markdig" Version="0.31.0" />
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.3" />
|
||||||
@@ -16,4 +18,7 @@
|
|||||||
<PackageReference Include="YamlDotNet" Version="13.1.1" />
|
<PackageReference Include="YamlDotNet" Version="13.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
9
Management/Services/Actors/CanvasQueue.cs
Normal file
9
Management/Services/Actors/CanvasQueue.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Akka.Actor;
|
||||||
|
|
||||||
|
using Management.Services.Canvas;
|
||||||
|
|
||||||
|
public class CanvasQueue(IActorRef canvasQueueActor)
|
||||||
|
{
|
||||||
|
private readonly IActorRef canvasQueueActor = canvasQueueActor;
|
||||||
|
|
||||||
|
}
|
||||||
18
Management/Services/Actors/CanvasQueueActor.cs
Normal file
18
Management/Services/Actors/CanvasQueueActor.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Akka.Actor;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
public class CanvasQueueActor : ReceiveActor
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
private readonly IServiceScope scope;
|
||||||
|
private readonly ILogger<CanvasQueueActor> logger;
|
||||||
|
|
||||||
|
public CanvasQueueActor(IServiceProvider serviceProviderArg)
|
||||||
|
{
|
||||||
|
serviceProvider = serviceProviderArg;
|
||||||
|
scope = serviceProvider.CreateScope();
|
||||||
|
logger = scope.ServiceProvider.GetRequiredService<ILogger<CanvasQueueActor>>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
61
Management/Services/Actors/LocalStorageActor.cs
Normal file
61
Management/Services/Actors/LocalStorageActor.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using Akka.Actor;
|
||||||
|
|
||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
public class LocalStorageActor : ReceiveActor
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
private readonly IServiceScope scope;
|
||||||
|
private readonly ILogger<CanvasQueueActor> logger;
|
||||||
|
private readonly FileStorageManager storage;
|
||||||
|
|
||||||
|
private DateTime? cacheTime { get; set; } = null;
|
||||||
|
private IEnumerable<LocalCourse>? cachedCourses { get; set; } = null;
|
||||||
|
private readonly int cacheSeconds = 2;
|
||||||
|
|
||||||
|
public LocalStorageActor(IServiceProvider serviceProviderArg)
|
||||||
|
{
|
||||||
|
serviceProvider = serviceProviderArg;
|
||||||
|
scope = serviceProvider.CreateScope();
|
||||||
|
logger = scope.ServiceProvider.GetRequiredService<ILogger<CanvasQueueActor>>();
|
||||||
|
storage = scope.ServiceProvider.GetRequiredService<FileStorageManager>();
|
||||||
|
|
||||||
|
Receive<EmptyDirectoryAsk>(m =>
|
||||||
|
{
|
||||||
|
storage
|
||||||
|
.GetEmptyDirectories()
|
||||||
|
.PipeTo(Sender);
|
||||||
|
});
|
||||||
|
|
||||||
|
ReceiveAsync<SavedCoursesAsk>(async m =>
|
||||||
|
{
|
||||||
|
var secondsFromLastLoad = (DateTime.Now - cacheTime)?.Seconds;
|
||||||
|
|
||||||
|
if (cachedCourses != null && secondsFromLastLoad < cacheSeconds)
|
||||||
|
{
|
||||||
|
logger.LogInformation("returning cached courses from file");
|
||||||
|
Sender.Tell(cachedCourses);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedCourses = await storage.LoadSavedCourses();
|
||||||
|
cacheTime = DateTime.Now;
|
||||||
|
Sender.Tell(cachedCourses);
|
||||||
|
});
|
||||||
|
|
||||||
|
ReceiveAsync<SaveCoursesRequest>(async m =>
|
||||||
|
{
|
||||||
|
cacheTime = null;
|
||||||
|
cachedCourses = null;
|
||||||
|
await storage.SaveCourseAsync(m.Course, m.PreviouslyStoredCourse);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record EmptyDirectoryAsk();
|
||||||
|
public record SavedCoursesAsk();
|
||||||
|
|
||||||
|
public record SaveCoursesRequest(LocalCourse Course, LocalCourse? PreviouslyStoredCourse);
|
||||||
|
public record SaveCoursesResponseSuccess();
|
||||||
23
Management/Services/Actors/LocalStorageCache.cs
Normal file
23
Management/Services/Actors/LocalStorageCache.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Akka.Actor;
|
||||||
|
|
||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
public class LocalStorageCache(IActorRef storageActor) : IFileStorageManager
|
||||||
|
{
|
||||||
|
private readonly IActorRef storageActor = storageActor;
|
||||||
|
|
||||||
|
public async Task<IEnumerable<string>> GetEmptyDirectories()
|
||||||
|
{
|
||||||
|
return await storageActor.Ask<IEnumerable<string>>(new EmptyDirectoryAsk());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<LocalCourse>> LoadSavedCourses()
|
||||||
|
{
|
||||||
|
return await storageActor.Ask<IEnumerable<LocalCourse>>(new SavedCoursesAsk());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveCourseAsync(LocalCourse course, LocalCourse? previouslyStoredCourse)
|
||||||
|
{
|
||||||
|
await storageActor.Ask<SaveCoursesResponseSuccess>(new SaveCoursesRequest(course, previouslyStoredCourse));
|
||||||
|
}
|
||||||
|
}
|
||||||
60
Management/Services/AkkaService.cs
Normal file
60
Management/Services/AkkaService.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
using Akka.Actor;
|
||||||
|
using Akka.DependencyInjection;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace Management.Services;
|
||||||
|
|
||||||
|
|
||||||
|
public class AkkaService(
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
IHostApplicationLifetime appLifetime,
|
||||||
|
IConfiguration configuration
|
||||||
|
) : IHostedService
|
||||||
|
{
|
||||||
|
private ActorSystem? actorSystem;
|
||||||
|
private readonly IConfiguration configuration = configuration;
|
||||||
|
private readonly IServiceProvider serviceProvider = serviceProvider;
|
||||||
|
private readonly IHostApplicationLifetime applicationLifetime = appLifetime;
|
||||||
|
public IActorRef? CanvasQueueActor { get; private set; }
|
||||||
|
public IActorRef? StorageActor { get; private set; }
|
||||||
|
|
||||||
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var bootstrap = BootstrapSetup.Create();
|
||||||
|
var dependencyInjectionSetup = DependencyResolverSetup.Create(serviceProvider);
|
||||||
|
|
||||||
|
var mergedSystemSetup = bootstrap.And(dependencyInjectionSetup);
|
||||||
|
|
||||||
|
actorSystem = ActorSystem.Create("canavas-management-actor-system", mergedSystemSetup);
|
||||||
|
|
||||||
|
var canvasQueueProps = DependencyResolver.For(actorSystem).Props<CanvasQueueActor>();
|
||||||
|
CanvasQueueActor = actorSystem.ActorOf(canvasQueueProps, "canvasQueue");
|
||||||
|
var localStorageProps = DependencyResolver.For(actorSystem).Props<LocalStorageActor>();
|
||||||
|
StorageActor = actorSystem.ActorOf(localStorageProps, "localStorage");
|
||||||
|
|
||||||
|
// crash if the actor system crashes, awaiting never returns...
|
||||||
|
actorSystem.WhenTerminated.ContinueWith(tr =>
|
||||||
|
{
|
||||||
|
applicationLifetime.StopApplication();
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||||
|
|
||||||
|
|
||||||
|
// public void Tell(object message)
|
||||||
|
// {
|
||||||
|
// userSessionSupervisor?.Tell(message);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Task<T> Ask<T>(object message)
|
||||||
|
// {
|
||||||
|
// return userSessionSupervisor.Ask<T>(message);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ using CanvasModel.Courses;
|
|||||||
using CanvasModel.EnrollmentTerms;
|
using CanvasModel.EnrollmentTerms;
|
||||||
using CanvasModel.Modules;
|
using CanvasModel.Modules;
|
||||||
using CanvasModel.Pages;
|
using CanvasModel.Pages;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
namespace Management.Services.Canvas;
|
namespace Management.Services.Canvas;
|
||||||
@@ -35,7 +34,7 @@ public class CanvasService(
|
|||||||
ICanvasQuizService Quizzes,
|
ICanvasQuizService Quizzes,
|
||||||
ICanvasCoursePageService Pages,
|
ICanvasCoursePageService Pages,
|
||||||
MyLogger<ICanvasService> logger
|
MyLogger<ICanvasService> logger
|
||||||
):ICanvasService
|
) : ICanvasService
|
||||||
{
|
{
|
||||||
private readonly IWebRequestor webRequestor = webRequestor;
|
private readonly IWebRequestor webRequestor = webRequestor;
|
||||||
private readonly CanvasServiceUtils utils = utils;
|
private readonly CanvasServiceUtils utils = utils;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using LocalModels;
|
using LocalModels;
|
||||||
using Management.Services;
|
using Management.Services;
|
||||||
|
|
||||||
public class FileStorageManager : IFileStorageManager
|
public class FileStorageManager
|
||||||
{
|
{
|
||||||
private readonly MyLogger<FileStorageManager> logger;
|
private readonly MyLogger<FileStorageManager> logger;
|
||||||
private readonly CourseMarkdownLoader _courseMarkdownLoader;
|
private readonly CourseMarkdownLoader _courseMarkdownLoader;
|
||||||
@@ -39,7 +39,7 @@ public class FileStorageManager : IFileStorageManager
|
|||||||
return await _courseMarkdownLoader.LoadSavedCourses();
|
return await _courseMarkdownLoader.LoadSavedCourses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetEmptyDirectories()
|
public async Task<IEnumerable<string>> GetEmptyDirectories()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(_basePath))
|
if (!Directory.Exists(_basePath))
|
||||||
throw new DirectoryNotFoundException($"Cannot get empty directories, {_basePath} does not exist");
|
throw new DirectoryNotFoundException($"Cannot get empty directories, {_basePath} does not exist");
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
// using System.Diagnostics.CodeAnalysis;
|
||||||
using LocalModels;
|
// using LocalModels;
|
||||||
|
|
||||||
public class FileStorageManagerCached : IFileStorageManager
|
// public class FileStorageManagerCached : IFileStorageManager
|
||||||
{
|
// {
|
||||||
private readonly FileStorageManager manager;
|
// private readonly FileStorageManager manager;
|
||||||
|
|
||||||
private readonly object cacheLock = new object(); // Lock object for synchronization
|
// private readonly object cacheLock = new object(); // Lock object for synchronization
|
||||||
|
|
||||||
|
|
||||||
private DateTime? cacheTime { get; set; } = null;
|
// private DateTime? cacheTime { get; set; } = null;
|
||||||
private IEnumerable<LocalCourse>? cachedCourses { get; set; } = null;
|
// private IEnumerable<LocalCourse>? cachedCourses { get; set; } = null;
|
||||||
private ILogger<FileStorageManagerCached> logger { get; }
|
// private ILogger<FileStorageManagerCached> logger { get; }
|
||||||
|
|
||||||
private readonly int cacheSeconds = 2;
|
// private readonly int cacheSeconds = 2;
|
||||||
public FileStorageManagerCached(FileStorageManager manager, ILogger<FileStorageManagerCached> logger)
|
// public FileStorageManagerCached(FileStorageManager manager, ILogger<FileStorageManagerCached> logger)
|
||||||
{
|
// {
|
||||||
this.manager = manager;
|
// this.manager = manager;
|
||||||
this.logger = logger;
|
// this.logger = logger;
|
||||||
}
|
// }
|
||||||
public IEnumerable<string> GetEmptyDirectories()
|
// public Task<IEnumerable<string>> GetEmptyDirectories()
|
||||||
{
|
// {
|
||||||
return manager.GetEmptyDirectories();
|
// return manager.GetEmptyDirectories();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public async Task<IEnumerable<LocalCourse>> LoadSavedCourses()
|
// public async Task<IEnumerable<LocalCourse>> LoadSavedCourses()
|
||||||
{
|
// {
|
||||||
|
|
||||||
var secondsFromLastLoad = (DateTime.Now - cacheTime)?.Seconds;
|
// var secondsFromLastLoad = (DateTime.Now - cacheTime)?.Seconds;
|
||||||
|
|
||||||
if (cachedCourses != null && secondsFromLastLoad < cacheSeconds)
|
// if (cachedCourses != null && secondsFromLastLoad < cacheSeconds)
|
||||||
{
|
// {
|
||||||
logger.LogInformation("returning cached courses from file");
|
// logger.LogInformation("returning cached courses from file");
|
||||||
return cachedCourses;
|
// return cachedCourses;
|
||||||
}
|
// }
|
||||||
|
|
||||||
cachedCourses = await manager.LoadSavedCourses();
|
// cachedCourses = await manager.LoadSavedCourses();
|
||||||
cacheTime = DateTime.Now;
|
// cacheTime = DateTime.Now;
|
||||||
return cachedCourses;
|
// return cachedCourses;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public async Task SaveCourseAsync(LocalCourse course, LocalCourse? previouslyStoredCourse)
|
// public async Task SaveCourseAsync(LocalCourse course, LocalCourse? previouslyStoredCourse)
|
||||||
{
|
// {
|
||||||
// race condition...
|
// // race condition...
|
||||||
cacheTime = null;
|
// cacheTime = null;
|
||||||
cachedCourses = null;
|
// cachedCourses = null;
|
||||||
await manager.SaveCourseAsync(course, previouslyStoredCourse);
|
// await manager.SaveCourseAsync(course, previouslyStoredCourse);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ public interface IFileStorageManager
|
|||||||
{
|
{
|
||||||
Task SaveCourseAsync(LocalCourse course, LocalCourse? previouslyStoredCourse);
|
Task SaveCourseAsync(LocalCourse course, LocalCourse? previouslyStoredCourse);
|
||||||
Task<IEnumerable<LocalCourse>> LoadSavedCourses();
|
Task<IEnumerable<LocalCourse>> LoadSavedCourses();
|
||||||
IEnumerable<string> GetEmptyDirectories();
|
Task<IEnumerable<string>> GetEmptyDirectories();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user