< Summary

Class:Azure.AI.FormRecognizer.Models.FormField
Assembly:Azure.AI.FormRecognizer
File(s):C:\Git\azure-sdk-for-net\sdk\formrecognizer\Azure.AI.FormRecognizer\src\FormField.cs
Covered lines:43
Uncovered lines:6
Coverable lines:49
Total lines:136
Line coverage:87.7% (43 of 49)
Covered branches:20
Total branches:26
Branch coverage:76.9% (20 of 26)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-100%100%
.ctor(...)-100%100%
get_Name()-100%100%
get_LabelData()-100%100%
get_ValueData()-100%100%
get_Value()-100%100%
get_Confidence()-100%100%
ConvertTextReferences(...)-100%100%
.cctor()-100%100%
ResolveTextReference(...)-50%25%

File(s)

C:\Git\azure-sdk-for-net\sdk\formrecognizer\Azure.AI.FormRecognizer\src\FormField.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Globalization;
 7using System.Text.RegularExpressions;
 8
 9namespace Azure.AI.FormRecognizer.Models
 10{
 11    /// <summary>
 12    /// Represents a field recognized in an input form.
 13    /// </summary>
 14    public class FormField
 15    {
 57616        internal FormField(string name, int pageNumber, KeyValuePair field, IReadOnlyList<ReadResult> readResults)
 17        {
 57618            Confidence = field.Confidence;
 57619            Name = name;
 20
 57621            BoundingBox labelBoundingBox = field.Key.BoundingBox == null ? default : new BoundingBox(field.Key.BoundingB
 57622            IReadOnlyList<FormElement> labelFormElement = field.Key.Elements != null
 57623                ? ConvertTextReferences(field.Key.Elements, readResults)
 57624                : new List<FormElement>();
 57625            LabelData = new FieldData(field.Key.Text, pageNumber, labelBoundingBox, labelFormElement);
 26
 57627            BoundingBox valueBoundingBox = field.Value.BoundingBox == null ? default : new BoundingBox(field.Value.Bound
 57628            IReadOnlyList<FormElement> valueFormElement = field.Value.Elements != null
 57629                ? ConvertTextReferences(field.Value.Elements, readResults)
 57630                : new List<FormElement>();
 57631            ValueData = new FieldData(field.Value.Text, pageNumber, valueBoundingBox, valueFormElement);
 32
 57633            Value = new FieldValue(new FieldValue_internal(field.Value.Text), readResults);
 57634        }
 35
 73636        internal FormField(string name, FieldValue_internal fieldValue, IReadOnlyList<ReadResult> readResults)
 37        {
 73638            Confidence = fieldValue.Confidence ?? Constants.DefaultConfidenceValue;
 73639            Name = name;
 73640            LabelData = null;
 41
 42            // Bounding box, page and text are not returned by the service in two scenarios:
 43            //   - When this field is global and not associated with a specific page (e.g. ReceiptType).
 44            //   - When this field is a collection, such as a list or dictionary.
 45            //
 46            // In these scenarios we do not set a ValueData.
 47
 73648            if (fieldValue.BoundingBox.Count == 0 && fieldValue.Page == null && fieldValue.Text == null)
 49            {
 9650                ValueData = null;
 51            }
 52            else
 53            {
 64054                IReadOnlyList<FormElement> FormElement = ConvertTextReferences(fieldValue.Elements, readResults);
 55
 56                // TODO: FormEnum<T> ?
 64057                BoundingBox boundingBox = new BoundingBox(fieldValue.BoundingBox);
 58
 64059                ValueData = new FieldData(fieldValue.Text, fieldValue.Page.Value, boundingBox, FormElement);
 60            }
 61
 73662            Value = new FieldValue(fieldValue, readResults);
 73663        }
 64
 65        /// <summary>
 66        /// Canonical name; uniquely identifies a field within the form.
 67        /// </summary>
 100068        public string Name { get; }
 69
 70        /// <summary>
 71        /// Contains the text, bounding box and content of the label of the field in the form.
 72        /// </summary>
 106473        public FieldData LabelData { get; }
 74
 75        /// <summary>
 76        /// Contains the text, bounding box and content of the value of the field in the form.
 77        /// </summary>
 109678        public FieldData ValueData { get; }
 79
 80        /// <summary>
 81        /// The strongly-typed value of this <see cref="FormField"/>.
 82        /// </summary>
 33683        public FieldValue Value { get; }
 84
 85        /// <summary>
 86        /// Measures the degree of certainty of the recognition result. Value is between [0.0, 1.0].
 87        /// </summary>
 200088        public float Confidence { get; }
 89
 90        internal static IReadOnlyList<FormElement> ConvertTextReferences(IReadOnlyList<string> references, IReadOnlyList
 91        {
 324092            List<FormElement> FormElement = new List<FormElement>();
 1709693            foreach (var reference in references)
 94            {
 530895                FormElement.Add(ResolveTextReference(readResults, reference));
 96            }
 324097            return FormElement;
 98        }
 99
 2100        private static Regex _wordRegex = new Regex(@"/readResults/(?<pageIndex>\d*)/lines/(?<lineIndex>\d*)/words/(?<wo
 2101        private static Regex _lineRegex = new Regex(@"/readResults/(?<pageIndex>\d*)/lines/(?<lineIndex>\d*)$", RegexOpt
 102
 103        private static FormElement ResolveTextReference(IReadOnlyList<ReadResult> readResults, string reference)
 104        {
 105            // TODO: Add additional validations here.
 106            // https://github.com/Azure/azure-sdk-for-net/issues/10363
 107
 108            // Example: the following should result in PageIndex = 3, LineIndex = 7, WordIndex = 12
 109            // "#/analyzeResult/readResults/3/lines/7/words/12" from DocumentResult
 110            // "#/readResults/3/lines/7/words/12" from PageResult
 111
 112            // Word Reference
 5308113            var wordMatch = _wordRegex.Match(reference);
 5308114            if (wordMatch.Success && wordMatch.Groups.Count == 4)
 115            {
 5308116                int pageIndex = int.Parse(wordMatch.Groups["pageIndex"].Value, CultureInfo.InvariantCulture);
 5308117                int lineIndex = int.Parse(wordMatch.Groups["lineIndex"].Value, CultureInfo.InvariantCulture);
 5308118                int wordIndex = int.Parse(wordMatch.Groups["wordIndex"].Value, CultureInfo.InvariantCulture);
 119
 5308120                return new FormWord(readResults[pageIndex].Lines[lineIndex].Words[wordIndex], pageIndex + 1);
 121            }
 122
 123            // Line Reference
 0124            var lineMatch = _lineRegex.Match(reference);
 0125            if (lineMatch.Success && lineMatch.Groups.Count == 3)
 126            {
 0127                int pageIndex = int.Parse(lineMatch.Groups["pageIndex"].Value, CultureInfo.InvariantCulture);
 0128                int lineIndex = int.Parse(lineMatch.Groups["lineIndex"].Value, CultureInfo.InvariantCulture);
 129
 0130                return new FormLine(readResults[pageIndex].Lines[lineIndex], pageIndex + 1);
 131            }
 132
 0133            throw new InvalidOperationException($"Failed to parse element reference: {reference}");
 134        }
 135    }
 136}