예제 #1
0
        public void IteratesIDictionaryKV()
        {
            dynamic dict = new ExpandoObject(); // Implements IDictionary<string, object>, but not IDictionary

            dict.k1 = 1;
            dict.k2 = "v2";
            var actual   = DictionaryIterator.Iterate((object)dict).OrderBy(x => x.Key).ToList();
            var expected = new List <KeyValuePair <object, object> >()
            {
                new KeyValuePair <object, object>("k1", 1),
                new KeyValuePair <object, object>("k2", "v2"),
            };

            Assert.Equal(expected, actual);
        }
예제 #2
0
        public void IteratesIDictionary()
        {
            var dict = new Hashtable()
            {
                { "k1", 1 },
                { "k2", "v2" }
            };
            var actual   = DictionaryIterator.Iterate(dict).OrderBy(x => x.Key).ToList();
            var expected = new List <KeyValuePair <object, object> >()
            {
                new KeyValuePair <object, object>("k1", 1),
                new KeyValuePair <object, object>("k2", "v2"),
            };

            Assert.Equal(expected, actual);
        }
예제 #3
0
        /// <summary>
        /// Validates the bucket file, and returns the result.
        /// </summary>
        /// <param name="file">The bucket file.</param>
        /// <returns>A tuple containing the warnings, publish errors and errors.</returns>
        public (string[] Warnings, string[] PublishErrors, string[] Errors) Validate(string file)
        {
            var          warnings      = new List <string>();
            var          publishErrors = new List <string>();
            var          errors        = new List <string>();
            ConfigBucket manifest;

            try
            {
                var jsonFile = new JsonFile(file, fileSystem, io);
                if (!jsonFile.IsValidate(out IList <string> errorMessages))
                {
                    errors.AddRange(errorMessages);
                    return(warnings.ToArray(), publishErrors.ToArray(), errors.ToArray());
                }

                manifest = jsonFile.Read <ConfigBucket>();
            }
#pragma warning disable CA1031
            catch (System.Exception ex)
#pragma warning restore CA1031
            {
                errors.Add(ex.Message);
                return(warnings.ToArray(), publishErrors.ToArray(), errors.ToArray());
            }

            if (!string.IsNullOrEmpty(manifest.Name))
            {
                var matched = Regex.Match(manifest.Name, Factory.RegexPackageName, RegexOptions.IgnoreCase);
                if (!matched.Success && !Regex.IsMatch(manifest.Name, $"^{Factory.RegexPackageNameIllegal}$"))
                {
                    var illegalChars = Regex.Replace(manifest.Name, Factory.RegexPackageNameIllegal, string.Empty);
                    errors.Add($"The name is invalid. \"{illegalChars}\" is not allowed in package names.");
                }
                else if (!matched.Success)
                {
                    errors.Add($"Names can only begin with a letter, and multiple \"/\" different provide are not allowed.");
                }
                else if (string.IsNullOrEmpty(matched.Groups["provide"].Value))
                {
                    warnings.Add($"It is recommended to add a provider name to the package (e.g. provide-name/package-name).");
                }

                if (manifest.Name != manifest.Name.ToLower())
                {
                    var suggestName = Str.LowerDashes(manifest.Name);
                    publishErrors.Add($"Name \"{manifest.Name}\" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using \"{suggestName}\" instead.");
                }
            }

            if (manifest.Licenses == null || manifest.Licenses.Length <= 0)
            {
                warnings.Add("No license specified, it is recommended to do so. For closed-source software you may use \"proprietary\" as license.");
            }

            if ((manifest.Requires != null && manifest.Requires.Count > 0) &&
                (manifest.RequiresDev != null && manifest.RequiresDev.Count > 0))
            {
                var requiresOverrides = manifest.Requires.Keys.Intersect(manifest.RequiresDev.Keys).ToArray();
                var plural            = (requiresOverrides.Length > 1) ? "are" : "is";
                var message           = string.Join(", ", requiresOverrides);
                warnings.Add($"{message} {plural} required both in require and require-dev, this can lead to unexpected behavior.");
            }

            var iterator = new DictionaryIterator <string, string>(manifest.Requires, manifest.RequiresDev);
            foreach (var item in iterator)
            {
                if (item.Value.IndexOf('#') == -1)
                {
                    continue;
                }

                warnings.Add($"The package \"{item.Key}\" is pointing to a commit-ref, this is bad practice and can cause unforeseen issues.");
            }

            var loader = new LoaderValidating(new LoaderPackage());
            try
            {
                loader.Load(manifest);
            }
            catch (InvalidPackageException ex)
            {
                errors.AddRange(ex.GetErrors());
            }

            warnings.AddRange(loader.GetWarnings());
            return(warnings.ToArray(), publishErrors.ToArray(), errors.ToArray());
        }
예제 #4
0
 public void CanIterateIDictionaryKVSubclass()
 {
     Assert.True(DictionaryIterator.CanIterate(typeof(Dictionary <int, int>)));
 }
예제 #5
0
 public void CanIterateIDictionarySubclass()
 {
     Assert.True(DictionaryIterator.CanIterate(typeof(Hashtable)));
 }
예제 #6
0
 public void CanIterateIDictionary()
 {
     Assert.True(DictionaryIterator.CanIterate(typeof(IDictionary)));
 }