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

Code lenses to switch between bicep and JSON module source #12762

Merged
merged 2 commits into from Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/Bicep.Core.UnitTests/Assertions/CodeLensAssertions.cs
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Linq;
using System.Reactive.Subjects;
using Bicep.Core.UnitTests.Registry;
using FluentAssertions;
using FluentAssertions.Primitives;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

namespace Bicep.Core.UnitTests.Assertions;

public static class CodeLensAssertionsExtensions
{
public static CodeLensAssertions Should(this CodeLens codeLens)
{
return new CodeLensAssertions(codeLens);
}
}

public class CodeLensAssertions : ObjectAssertions<CodeLens, CodeLensAssertions>
{
public CodeLensAssertions(CodeLens subject)
: base(subject)
{
}

protected override string Identifier => nameof(CodeLens);

public AndConstraint<CodeLensAssertions> HaveCommandTitle(string title, string because = "", params object[] becauseArgs)
{
Subject.Command.Should().NotBeNull("Code lens command should not be null");
Subject.Command!.Title.Should().Be(title, because, becauseArgs);

return new(this);
}

public AndConstraint<CodeLensAssertions> HaveCommandName(string commandName, string because = "", params object[] becauseArgs)
{
Subject.Command.Should().NotBeNull("Code lens command should not be null");
Subject.Command!.Name.Should().Be(commandName, because, becauseArgs);

return new(this);
}

public AndConstraint<CodeLensAssertions> HaveCommandArguments(params string[] commandArguments)
{
Subject.Command.Should().NotBeNull("Code lens command should not be null");
Subject.Command!.Arguments.Should().NotBeNull("Command args should not be null");
var actualCommandArguments = Subject.CommandArguments();
actualCommandArguments.Should().BeEquivalentTo(commandArguments);

return new(this);
}

public AndConstraint<CodeLensAssertions> HaveNoCommandArguments()
{
Subject.CommandArguments().Should().BeEmpty("Command should have no arguments");

return new(this);
}

public AndConstraint<CodeLensAssertions> HaveRange(Range range, string because = "", params object[] becauseArgs)
{
Subject.Range.Should().Be(range, because, becauseArgs);

return new(this);
}


}
25 changes: 19 additions & 6 deletions src/Bicep.Core.UnitTests/BicepTestConstants.cs
Expand Up @@ -2,21 +2,24 @@
// Licensed under the MIT License.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using Azure.Core.Pipeline;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Bicep.Core.Analyzers.Linter;
using Bicep.Core.Configuration;
using Bicep.Core.Diagnostics;
using Bicep.Core.Extensions;
using Bicep.Core.Features;
using Bicep.Core.FileSystem;
using Bicep.Core.Json;
using Bicep.Core.Registry;
using Bicep.Core.Registry.Oci;
using Bicep.Core.Semantics.Namespaces;
using Bicep.Core.TypeSystem;
using Bicep.Core.SourceCode;
using Bicep.Core.TypeSystem.Providers;
using Bicep.Core.TypeSystem.Providers.Az;
using Bicep.Core.UnitTests.Configuration;
using Bicep.Core.UnitTests.Features;
using Bicep.Core.UnitTests.Mock;
Expand Down Expand Up @@ -85,7 +88,7 @@ public static class BicepTestConstants

public static IEnvironment EmptyEnvironment = new TestEnvironment(ImmutableDictionary<string, string?>.Empty);

public static readonly IModuleRestoreScheduler ModuleRestoreScheduler = CreateMockModuleRestoreScheduler();
public static readonly IModuleRestoreScheduler ModuleRestoreScheduler = CreateMockModuleDispatcherAndRestoreScheduler().moduleRestoreScheduler;

public static RootConfiguration CreateMockConfiguration(Dictionary<string, object>? customConfigurationData = null, string? configurationPath = null)
{
Expand Down Expand Up @@ -128,10 +131,20 @@ public static IConfigurationManager CreateConfigurationManager(Func<RootConfigur
public static IFeatureProviderFactory CreateFeatureProviderFactory(FeatureProviderOverrides featureOverrides, IConfigurationManager? configurationManager = null)
=> new OverriddenFeatureProviderFactory(new FeatureProviderFactory(configurationManager ?? CreateFilesystemConfigurationManager()), featureOverrides);

private static IModuleRestoreScheduler CreateMockModuleRestoreScheduler()
public static (IModuleDispatcher moduleDispatcher, IModuleRestoreScheduler moduleRestoreScheduler) CreateMockModuleDispatcherAndRestoreScheduler(IArtifactRegistry[]? artifactRegistries = null)
{
var moduleDispatcher = StrictMock.Of<IModuleDispatcher>();
return new ModuleRestoreScheduler(moduleDispatcher.Object);
moduleDispatcher.Setup(x => x.RestoreModules(It.IsAny<ImmutableArray<ArtifactReference>>(), It.IsAny<bool>())).
ReturnsAsync(true);
moduleDispatcher.Setup(x => x.PruneRestoreStatuses());

MockRepository repository = new(MockBehavior.Strict);
var provider = repository.Create<IArtifactRegistryProvider>();

moduleDispatcher.Setup(m => m.TryGetModuleSources(It.IsAny<ArtifactReference>())).Returns((ArtifactReference reference) =>
(artifactRegistries ?? new IArtifactRegistry[] { }).Select(r => r.TryGetSource(reference)).FirstOrDefault(s => s is not null));

return (moduleDispatcher.Object, new ModuleRestoreScheduler(moduleDispatcher.Object));
}

public static Mock<ITelemetryProvider> CreateMockTelemetryProvider()
Expand Down
15 changes: 15 additions & 0 deletions src/Bicep.Core.UnitTests/Extensions/CodeLensExtensions.cs
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Linq;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

namespace Bicep.Core.UnitTests.Assertions;

public static class CodeLensExtensions
{
public static string[]? CommandArguments(this CodeLens codeLens)
{
return codeLens.Command?.Arguments?.Children().Select(token => token.ToString()).ToArray();
}
}
2 changes: 1 addition & 1 deletion src/Bicep.Core.UnitTests/Utils/OciModuleRegistryHelper.cs
Expand Up @@ -67,7 +67,7 @@ public static OciArtifactReference CreateModuleReference(string registry, string
}
}

// public a new (real) OciArtifactRegistry instance with an empty on-disk cache that can push and pull modules
// create a new (real) OciArtifactRegistry instance with an empty on-disk cache that can push and pull modules
public static (OciArtifactRegistry, MockRegistryBlobClient) CreateModuleRegistry(
Uri parentModuleUri,
IFeatureProvider featureProvider)
Expand Down
2 changes: 1 addition & 1 deletion src/Bicep.Core/Navigation/IArtifactReferenceSyntax.cs
Expand Up @@ -6,7 +6,7 @@
namespace Bicep.Core.Navigation;

/// <summary>
/// Objects that implement IArtifactReferenceSyntax, contain syntax that can reference a foregin artifact, the artifact address
/// Objects that implement IArtifactReferenceSyntax, contain syntax that can reference a foreign artifact, the artifact address
/// is returned by `TryGetPath` and `SourceSyntax` contains the source syntax object to use for error propagation.
/// </summary>
public interface IArtifactReferenceSyntax
Expand Down
7 changes: 6 additions & 1 deletion src/Bicep.Core/Registry/DefaultArtifactRegistryProvider.cs
Expand Up @@ -29,7 +29,12 @@ public DefaultArtifactRegistryProvider(IServiceProvider serviceProvider, IFileRe
this.serviceProvider = serviceProvider;
}

// NOTE: The templateUri affects how module aliases are resolved, by determining how the bicepconfig.json is located, which contains alias definitions
/// <summary>
/// Gets the registries available for module references inside a given template URI.
/// </summary>
/// <param name="templateUri">URI of the Bicep template source code which contains the module references.
/// This is needed to determine the appropriate bicepconfig.json (which contains module alias definitions) and features provider to bind to</param>
/// <returns></returns>
public ImmutableArray<IArtifactRegistry> Registries(Uri templateUri)
{
var configuration = configurationManager.GetConfiguration(templateUri);
Expand Down
2 changes: 1 addition & 1 deletion src/Bicep.Core/Utils/Result.cs
Expand Up @@ -43,7 +43,7 @@ public bool IsSuccess([NotNullWhen(true)] out TSuccess? success, [NotNullWhen(fa

/// <summary>
/// Returns the succcessful result, assuming success. Throws an exception if not.
/// This should only be called if you'e already verified that the result is successful.
/// This should only be called if you've already verified that the result is successful.
/// </summary>
public TSuccess Unwrap()
=> TryUnwrap() ?? throw new InvalidOperationException("Cannot unwrap a failed result.");
Expand Down