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

BP-586: As a developer I want the code generator to support input with numbers so I can use that in generated components #52

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public PasswordFormControlBuilder PasswordFormControl<TProperty>(Expression<Func
return GetOrCreateBuilder(propertyExpression.GetPropertyInfo(), propertyInfo => new PasswordFormControlBuilder(propertyInfo));
}

public NumberFormControlBuilder NumberFormControl<TProperty>(Expression<Func<T, TProperty>> propertyExpression)
{
return GetOrCreateBuilder(propertyExpression.GetPropertyInfo(), propertyInfo => new NumberFormControlBuilder(propertyInfo));
}

public CheckboxFormControlBuilder CheckboxFormControl<TProperty>(Expression<Func<T, TProperty>> propertyExpression)
{
return GetOrCreateBuilder(propertyExpression.GetPropertyInfo(), propertyInfo => new CheckboxFormControlBuilder(propertyInfo));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Enigmatry.Entry.CodeGeneration.Configuration.Form.Controls;

public class NumberFormControl : InputControlBase
{
public override string Type => "number";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Reflection;

namespace Enigmatry.Entry.CodeGeneration.Configuration.Form.Controls;

public class NumberFormControlBuilder : InputControlBuilderBase<NumberFormControl, NumberFormControlBuilder>
{
public NumberFormControlBuilder(PropertyInfo propertyInfo) : base(propertyInfo)
{
}

public NumberFormControlBuilder(string propertyName) : base(propertyName)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public PasswordFormControlBuilder PasswordFormControl<TProperty>(Expression<Func
return _formGroup.PasswordFormControl(propertyExpression);
}

public NumberFormControlBuilder NumberFormControl<TProperty>(Expression<Func<T, TProperty>> propertyExpression)
{
return _formGroup.NumberFormControl(propertyExpression);
}

public CheckboxFormControlBuilder CheckboxFormControl<TProperty>(Expression<Func<T, TProperty>> propertyExpression)
{
return _formGroup.CheckboxFormControl(propertyExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pattern: /[A-Z]/,
validation: {
messages: {
required: (err, field) => $localize `:@@CUSTOM_VALIDATION_MESSAGE_TRANSLATION_ID:CUSTOM_VALIDATION_MESSAGE`,
maxlength: (err, field) => $localize `:@@CUSTOM_VALIDATION_MESSAGE_TRANSLATION_ID:CUSTOM_VALIDATION_MESSAGE`
maxLength: (err, field) => $localize `:@@CUSTOM_VALIDATION_MESSAGE_TRANSLATION_ID:CUSTOM_VALIDATION_MESSAGE`
}
},
asyncValidators: { validation: [ 'uniqueName', 'isEnsured' ] },
Expand Down Expand Up @@ -233,9 +233,6 @@ className: `entry-money-field entry-input`,
description: ``,
attributes: { },
hidden: !true,
type: 'number',
max: 999.99 - 0.1,

typeFormatDef: { name: 'number' }
},
},
Expand All @@ -255,10 +252,10 @@ className: `entry-amount-field entry-input`,
label: $localize `:@@test.mock-edit.amount.label:Amount`,
placeholder: $localize `:@@test.mock-edit.amount.placeholder:Amount`,
description: $localize `:@@test.mock-edit.amount.hint:Don't panic if it is 0`,
type: 'number',
attributes: { },
hidden: !true,
required: true,
type: 'number',
min: 0 + 1,
max: 100,

Expand Down Expand Up @@ -700,4 +697,3 @@ pattern: (err, field) => $localize `:@@validators.pattern.emailAddress:Invalid e
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ import { CustomValidatorsService, customValidatorsFactory } from 'src/app/shared
FormlyModule.forChild(
{
validationMessages: [
{ name: 'maxlength', message: (err, field) => $localize `:@@validators.maxLength:${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.maxLength}:max-value: characters` },
{ name: 'maxLength', message: (err, field) => $localize `:@@validators.maxLength:${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.maxLength}:max-value: characters` },
{ name: 'pattern', message: (err, field) => $localize `:@@validators.pattern:${field?.templateOptions?.label}:property-name: is not in valid format` },
{ name: 'max', message: (err, field) => $localize `:@@validators.max:${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.max}:max-value:` },
{ name: 'required', message: (err, field) => $localize `:@@validators.required:${field?.templateOptions?.label}:property-name: is required` }
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ public void SetUp()
}

[TestCase(nameof(FormMock.Name), ExpectedResult = "required: true,maxLength: 50,pattern: /[A-Z]/,")]
[TestCase(nameof(FormMock.Money), ExpectedResult = "type: 'number',max: 999.99 - 0.1,")]
[TestCase(nameof(FormMock.Amount), ExpectedResult = "required: true,type: 'number',min: 0 + 1,max: 100,")]
[TestCase(nameof(FormMock.Amount), ExpectedResult = "required: true,min: 0 + 1,max: 100,")]
[TestCase(nameof(FormMock.Email1), ExpectedResult = "pattern: /^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/,maxLength: 50,")]
[TestCase(nameof(FormMock.Email2), ExpectedResult = "pattern: /^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/,maxLength: 50,")]
public string AddValidationTemplateOptions(string propertyName)
{
var formControl = _formComponent.FormControlsOfType<FormControl>().Single(x => x.PropertyName == propertyName.Camelize());
return _htmlHelper.AddValidationTemplateOptions(formControl)?.ToString()?.Replace("\r\n", "") ?? "";
return _htmlHelper.AddValidationTemplateOptions(formControl).ToString()?.Replace("\r\n", "") ?? "";
}

[TestCase(nameof(FormMock.Name), ExpectedResult = "modelOptions: { updateOn: 'blur' },")]
Expand All @@ -48,7 +47,7 @@ public string AddValidationTemplateOptions(string propertyName)
public string AddModelOptions(string propertyName)
{
var formControl = _formComponent.FormControlsOfType<FormControl>().Single(x => x.PropertyName == propertyName.Camelize());
return _htmlHelper.AddModelOptions(formControl)?.ToString()?.Replace("\r\n", "") ?? "";
return _htmlHelper.AddModelOptions(formControl).ToString()?.Replace("\r\n", "") ?? "";
}

[TestCase(nameof(FormMock.Name), ExpectedResult = "asyncValidators: { validation: [ 'nameValidator' ] },")]
Expand All @@ -59,7 +58,7 @@ public string AddModelOptions(string propertyName)
public string AddAsyncValidators(string propertyName)
{
var formControl = _formComponent.FormControlsOfType<FormControl>().Single(x => x.PropertyName == propertyName.Camelize());
return _htmlHelper.AddAsyncValidators(formControl)?.ToString()?.Replace("\r\n", "") ?? "";
return _htmlHelper.AddAsyncValidators(formControl).ToString()?.Replace("\r\n", "") ?? "";
}

[TestCase(nameof(FormMock.Name), ExpectedResult =
Expand All @@ -73,22 +72,21 @@ public string AddAsyncValidators(string propertyName)
public string AddCustomValidationMessages(string propertyName)
{
var formControl = _formComponent.FormControlsOfType<FormControl>().Single(x => x.PropertyName == propertyName.Camelize());
return _htmlHelper.AddCustomValidationMessages(formControl, true)?.ToString()?.Replace("\r\n", "") ?? "";
return _htmlHelper.AddCustomValidationMessages(formControl, true).ToString()?.Replace("\r\n", "") ?? "";
}

[TestCase(ExpectedResult =
"{ name: 'maxLength', message: (err, field) => $localize `:@@validators.maxLength:${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.maxLength}:max-value: characters` }," +
"{ name: 'pattern', message: (err, field) => $localize `:@@validators.pattern:${field?.templateOptions?.label}:property-name: is not in valid format` }," +
"{ name: 'max', message: (err, field) => $localize `:@@validators.max:${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.max}:max-value:` }," +
"{ name: 'required', message: (err, field) => $localize `:@@validators.required:${field?.templateOptions?.label}:property-name: is required` }")]
public string AddCommonValidationMessages() =>
_htmlHelper.AddCommonValidationMessages(_featureModule, true)?.ToString()?.Replace("\r\n", "") ?? "";
_htmlHelper.AddCommonValidationMessages(_featureModule, true).ToString()?.Replace("\r\n", "") ?? "";

[TestCase("src/app/custom-path", ExpectedResult = "import { CustomValidatorsService, customValidatorsFactory } from 'src/app/custom-path';")]
public string ImportValidators(string path) =>
_htmlHelper.ImportValidators(_featureModule, path)?.ToString()?.Replace("\r\n", "") ?? "";
_htmlHelper.ImportValidators(_featureModule, path).ToString()?.Replace("\r\n", "") ?? "";

[TestCase(ExpectedResult = "CustomValidatorsService,{ provide: FORMLY_CONFIG, multi: true, useFactory: customValidatorsFactory, deps: [ CustomValidatorsService ] }")]
public string AddFromValidationProvider() =>
_htmlHelper.AddFromValidationProvider(_featureModule)?.ToString()?.Replace("\r\n", "") ?? "";
_htmlHelper.AddFromValidationProvider(_featureModule).ToString()?.Replace("\r\n", "") ?? "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void Configure(FormComponentBuilder<FormMock> builder)
.WithPlaceholder("Money");

formGroup
.FormControl(x => x.Amount)
.NumberFormControl(x => x.Amount)
.WithLabel("Amount")
.WithPlaceholder("Amount")
.WithHint("Don't panic if it is 0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ public FormMockValidationConfiguration()
.WithMessage(Constants.CustomValidationMessage, Constants.CustomValidationMessageTranslationId)
.Match(new Regex("/[A-Z]/"));

RuleFor(x => x.Money)
.LessThen(999.99M);

RuleFor(x => x.Amount)
.IsRequired()
.GreaterThen(0)
Expand All @@ -33,4 +30,4 @@ public FormMockValidationConfiguration()
.EmailAddress()
.MaxLength(50);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ public void GreaterThen()

_validationConfiguration.ValidationRules.Should().HaveCount(3);

AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MinIntField, false);
AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MinDoubleField, false);
AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MinByteField, false);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MinIntField, false);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MinDoubleField, false);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MinByteField, false);
}

[Test]
Expand All @@ -186,9 +186,9 @@ public void GreaterOrEqualTo()

_validationConfiguration.ValidationRules.Should().HaveCount(3);

AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MinIntField, true);
AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MinDoubleField, true);
AssertNumbercMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MinByteField, true);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MinIntField, true);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MinDoubleField, true);
AssertNumericMinValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MinByteField, true);
}

[Test]
Expand All @@ -206,9 +206,9 @@ public void LessThen()

_validationConfiguration.ValidationRules.Should().HaveCount(3);

AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MaxIntField, false);
AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MaxDoubleField, false);
AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MaxByteField, false);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MaxIntField, false);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MaxDoubleField, false);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MaxByteField, false);
}

[Test]
Expand All @@ -226,9 +226,9 @@ public void LessOrEqualTo()

_validationConfiguration.ValidationRules.Should().HaveCount(3);

AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MaxIntField, true);
AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MaxDoubleField, true);
AssertNumbercMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MaxByteField, true);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.IntField)), MaxIntField, true);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.DoubleField)), MaxDoubleField, true);
AssertNumericMaxValidationRule(GetRuleByPropertyName(nameof(ValidationMockModel.ByteField)), MaxByteField, true);
}

[Test]
Expand All @@ -240,8 +240,8 @@ public void EqualToInt()

_validationConfiguration.ValidationRules.Should().HaveCount(2);

AssertNumbercMinValidationRule(GetRuleByFormlyRuleName("min"), MinIntField, true);
AssertNumbercMaxValidationRule(GetRuleByFormlyRuleName("max"), MinIntField, true);
AssertNumericMinValidationRule(GetRuleByFormlyRuleName("min"), MinIntField, true);
AssertNumericMaxValidationRule(GetRuleByFormlyRuleName("max"), MinIntField, true);
}

[Test]
Expand All @@ -253,8 +253,8 @@ public void EqualToDouble()

_validationConfiguration.ValidationRules.Should().HaveCount(2);

AssertNumbercMinValidationRule(GetRuleByFormlyRuleName("min"), MinDoubleField, true);
AssertNumbercMaxValidationRule(GetRuleByFormlyRuleName("max"), MinDoubleField, true);
AssertNumericMinValidationRule(GetRuleByFormlyRuleName("min"), MinDoubleField, true);
AssertNumericMaxValidationRule(GetRuleByFormlyRuleName("max"), MinDoubleField, true);
}

[TestCase("MESSAGE", "")]
Expand Down Expand Up @@ -286,7 +286,7 @@ public void InvalidWithMessage()
.WithMessage($"{nameof(ValidationMockModel.IntField)} validation message cannot be empty.");
}

private static void AssertNumbercMinValidationRule<T>(IFormlyValidationRule rule, T value, bool isEqual)
private static void AssertNumericMinValidationRule<T>(IFormlyValidationRule rule, T value, bool isEqual)
{
rule.FormlyRuleName
.Should().Be("min");
Expand All @@ -295,12 +295,12 @@ private static void AssertNumbercMinValidationRule<T>(IFormlyValidationRule rule
rule.MessageTranslationId
.Should().Be("validators.min");
rule.FormlyTemplateOptions
.Should().BeEquivalentTo("type: 'number'", $"min: {String.Format(CultureInfo.InvariantCulture, "{0}", value)}{(isEqual ? "" : $" + {GetIncrement<T>()}")}");
.Should().BeEquivalentTo($"min: {String.Format(CultureInfo.InvariantCulture, "{0}", value)}{(isEqual ? "" : $" + {GetIncrement<T>()}")}");
rule.FormlyValidationMessage
.Should().Be("${field?.templateOptions?.label}:property-name: value should be more than ${field?.templateOptions?.min}:min-value:");
}

private static void AssertNumbercMaxValidationRule<T>(IFormlyValidationRule rule, T value, bool isEqual)
private static void AssertNumericMaxValidationRule<T>(IFormlyValidationRule rule, T value, bool isEqual)
{
rule.FormlyRuleName
.Should().Be("max");
Expand All @@ -309,7 +309,7 @@ private static void AssertNumbercMaxValidationRule<T>(IFormlyValidationRule rule
rule.MessageTranslationId
.Should().Be("validators.max");
rule.FormlyTemplateOptions
.Should().BeEquivalentTo("type: 'number'", $"max: {String.Format(CultureInfo.InvariantCulture, "{0}", value)}{(isEqual ? "" : $" - {GetIncrement<T>()}")}");
.Should().BeEquivalentTo($"max: {String.Format(CultureInfo.InvariantCulture, "{0}", value)}{(isEqual ? "" : $" - {GetIncrement<T>()}")}");
rule.FormlyValidationMessage
.Should().Be("${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.max}:max-value:");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Enigmatry.Entry.CodeGeneration.Validation.ValidationRules;

public class GreaterOrEqualToValidationRule<T> : NumbericValidationRule<T>
public class GreaterOrEqualToValidationRule<T> : NumericValidationRule<T>
where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{
public GreaterOrEqualToValidationRule(T value, PropertyInfo propertyInfo, LambdaExpression expression)
Expand All @@ -14,13 +14,11 @@ public GreaterOrEqualToValidationRule(T value, PropertyInfo propertyInfo, Lambda
public override string FormlyRuleName => "min";

public override string[] FormlyTemplateOptions =>
new[]
{
"type: 'number'",
$"{FormlyRuleName}: {RuleAsString}"
};
[
$"{FormlyRuleName}: {RuleAsString}"
];

public override string FormlyValidationMessage => HasCustomMessage
? CustomMessage
: "${field?.templateOptions?.label}:property-name: value should be more than ${field?.templateOptions?.min}:min-value:";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Enigmatry.Entry.CodeGeneration.Validation.ValidationRules;

public class GreaterThenValidationRule<T> : NumbericValidationRule<T>
public class GreaterThenValidationRule<T> : NumericValidationRule<T>
where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{
public GreaterThenValidationRule(T value, PropertyInfo propertyInfo, LambdaExpression expression)
Expand All @@ -14,13 +14,11 @@ public GreaterThenValidationRule(T value, PropertyInfo propertyInfo, LambdaExpre
public override string FormlyRuleName => "min";

public override string[] FormlyTemplateOptions =>
new[]
{
"type: 'number'",
$"{FormlyRuleName}: {RuleAsString} + {Increment}"
};
[
$"{FormlyRuleName}: {RuleAsString} + {Increment}"
];

public override string FormlyValidationMessage => HasCustomMessage
? CustomMessage
: "${field?.templateOptions?.label}:property-name: value should be more than ${field?.templateOptions?.min}:min-value:";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Enigmatry.Entry.CodeGeneration.Validation.ValidationRules;

public class LessOrEqualToValidationRule<T> : NumbericValidationRule<T>
public class LessOrEqualToValidationRule<T> : NumericValidationRule<T>
where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{
public LessOrEqualToValidationRule(T value, PropertyInfo propertyInfo, LambdaExpression expression)
Expand All @@ -14,13 +14,11 @@ public LessOrEqualToValidationRule(T value, PropertyInfo propertyInfo, LambdaExp
public override string FormlyRuleName => "max";

public override string[] FormlyTemplateOptions =>
new[]
{
"type: 'number'",
$"{FormlyRuleName}: {RuleAsString}"
};
[
$"{FormlyRuleName}: {RuleAsString}"
];

public override string FormlyValidationMessage => HasCustomMessage
? CustomMessage
: "${field?.templateOptions?.label}:property-name: value should be less than ${field?.templateOptions?.max}:max-value:";
}
}
Loading
Loading