public void GetDescriptionAndText_WithMissingCommentInInput_ReturnsEmptyDescriptionAndValidText()
        {
            ResourceSnippetsProvider resourceSnippetsProvider = new ResourceSnippetsProvider();

            string template = @"resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = {
  name: '${1:dnsZone}'
  location: 'global'
  tags: {
    displayName: '${1:dnsZone}'
  }
}";

            (string description, string text) = resourceSnippetsProvider.GetDescriptionAndText(template);

            string expectedText = @"resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = {
  name: '${1:dnsZone}'
  location: 'global'
  tags: {
    displayName: '${1:dnsZone}'
  }
}";

            Assert.IsTrue(description.Equals(string.Empty));
            Assert.AreEqual(expectedText, text);
        }
        public void GetDescriptionAndText_WithValidInput_ReturnsDescriptionAndText()
        {
            ResourceSnippetsProvider resourceSnippetsProvider = new ResourceSnippetsProvider();

            string template = @"// DNS Zone
resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = {
  name: '${1:dnsZone}'
  location: 'global'
  tags: {
    displayName: '${1:dnsZone}'
  }
}";

            (string description, string text) = resourceSnippetsProvider.GetDescriptionAndText(template);

            string expectedText = @"resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = {
  name: '${1:dnsZone}'
  location: 'global'
  tags: {
    displayName: '${1:dnsZone}'
  }
}";

            Assert.AreEqual("DNS Zone", description);
            Assert.AreEqual(expectedText, text);
        }
        public void GetDescriptionAndText_WithOnlyWhitespaceInput_ReturnsEmptyDescriptionAndText()
        {
            ResourceSnippetsProvider resourceSnippetsProvider = new ResourceSnippetsProvider();

            (string description, string text) = resourceSnippetsProvider.GetDescriptionAndText("   ");

            Assert.IsTrue(description.Equals(string.Empty));
            Assert.IsTrue(text.Equals(string.Empty));
        }
        public void GetDescriptionAndText_WithCommentAndMissingDeclarations_ReturnsEmptyDescriptionAndText()
        {
            ResourceSnippetsProvider resourceSnippetsProvider = new ResourceSnippetsProvider();

            string template = @"// DNS Zone";

            (string description, string text) = resourceSnippetsProvider.GetDescriptionAndText(template);

            Assert.IsTrue(description.Equals(string.Empty));
            Assert.IsTrue(text.Equals(string.Empty));
        }
        public void DeclarationSnippetsShouldBeValid()
        {
            var grouping    = SyntaxTreeGroupingFactory.CreateFromText(string.Empty);
            var compilation = new Compilation(TestResourceTypeProvider.Create(), grouping);

            compilation.GetEntrypointSemanticModel().GetAllDiagnostics().Should().BeEmpty();

            ResourceSnippetsProvider resourceSnippetsProvider = new ResourceSnippetsProvider();

            var provider = new BicepCompletionProvider(new FileResolver(), resourceSnippetsProvider);

            var completions = provider.GetFilteredCompletions(compilation, BicepCompletionContext.Create(compilation, 0));

            var snippetCompletions = completions
                                     .Where(c => c.Kind == CompletionItemKind.Snippet)
                                     .OrderBy(c => c.Label)
                                     .ToList();

            IEnumerable <ResourceSnippet> resourceSnippets = resourceSnippetsProvider.GetResourceSnippets();

            snippetCompletions.Should().OnlyContain(c => c.Kind == CompletionItemKind.Snippet && c.InsertTextFormat == InsertTextFormat.Snippet);
            snippetCompletions.Should().OnlyContain(c => c.InsertTextFormat == InsertTextFormat.Snippet);
            snippetCompletions.Should().OnlyContain(c => LanguageConstants.DeclarationKeywords.Contains(c.Label) || resourceSnippets.Any(rs => rs.Name == c.Label));
            snippetCompletions.Should().OnlyContain(c => c.Documentation !.HasMarkupContent && c.Documentation.MarkupContent !.Kind == MarkupKind.Markdown);

            var snippetsByDetail = snippetCompletions.Where(c => c.Detail != null).ToImmutableDictionaryExcludingNull(c => c.Detail, StringComparer.Ordinal);

            var replacementsByDetail = new Dictionary <string, IList <string> >
            {
                ["Module declaration"]    = new[] { string.Empty, "myModule", "./empty.bicep" },
                ["Parameter declaration"] = new[] { string.Empty, "myParam", "string" },
                ["Parameter declaration with default value"] = new[] { string.Empty, "myParam", "string", "'myDefault'" },
                ["Parameter declaration with default and allowed values"] = new[] { string.Empty, "myParam", "string", "'myDefault'", "'val1'\n'val2'" },
                ["Parameter declaration with options"] = new[] { string.Empty, "myParam", "string", "default: 'myDefault'\nsecure: true" },
                ["Secure string parameter"]            = new[] { string.Empty, "myParam" },
                ["Variable declaration"]            = new[] { "'stringVal'", "myVariable" },
                ["Resource with defaults"]          = new[] { "prop1: 'val1'", "myResource", "myProvider", "myType", "2020-01-01", "'parent'", "'West US'" },
                ["Child Resource with defaults"]    = new[] { "prop1: 'val1'", "myResource", "myProvider", "myType", "myChildType", "2020-01-01", "'parent/child'" },
                ["Resource without defaults"]       = new[] { "properties: {\nprop1: 'val1'\n}", "myResource", "myProvider", "myType", "2020-01-01", "'parent'" },
                ["Child Resource without defaults"] = new[] { "properties: {\nprop1: 'val1'\n}", "myResource", "myProvider", "myType", "myChildType", "2020-01-01", "'parent/child'" },
                ["Output declaration"]         = new[] { "'stringVal'", "myOutput", "string" },
                ["Kubernetes Service Cluster"] = new[] { "aksCluster", "1.5", "prefix", "2", "Standard_All", "userName", "keyData", "appId", "test" },
                ["Application Security Group"] = new[] { "myApplicationSecurityGroup" },
                ["Automation Account"]         = new[] { "myAutomationAccount", "Basic" },
                ["Availability Set"]           = new[] { "availabilitySet", "availabilitySet" },
                ["Container Group"]            = new[] { "myContainerGroup", "container", "image", "80", "1", "4", "Linux", "TCP", "80" },
                ["Container Registry"]         = new[] { "myContainerRegistry", "Basic", "true" },
                ["Cosmos DB Database Account"] = new[] { "myCosmosDBAccount", "MongoDB", "session", "1", "5", "location", "0", "filter", "false", "EnableTable" },
                ["Data Lake Store Account"]    = new[] { "myDataLakeStore", "Consumption", "Enabled" },
                ["DNS Zone"]          = new[] { "dnsZone" },
                ["Public IP Address"] = new[] { "192.168.1.10", "192.168.1.10", "dnsName" },
                ["Public IP Prefix"]  = new[] { "publicIpPrefix", "28" }
            };

            snippetsByDetail.Keys.Should().BeEquivalentTo(replacementsByDetail.Keys);

            foreach (var(detail, completion) in snippetsByDetail)
            {
                // validate snippet
                var snippet = new Snippet(completion.TextEdit !.NewText);

                // if we don't have placeholders, why is it a snippet?
                snippet.Placeholders.Should().NotBeEmpty();

                // documentation should have the snippet without placeholders
                completion.Documentation !.MarkupContent !.Value.Should().Contain(snippet.FormatDocumentation());

                // perform the sample replacement
                var replacements = replacementsByDetail[detail !];