public void Necessary_dependsOn_statements_are_not_removed_for_modules()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

module modB 'modb.bicep' = {
  name: 'modB'
  dependsOn: [
    resA
  ]
}";

            var(_, _, compilation) = CompilationHelper.Compile(("main.bicep", bicepFile));
            var rewriter = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            PrintHelper.PrintAndCheckForParseErrors(newProgramSyntax).Should().Be(
                @"resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

module modB 'modb.bicep' = {
  name: 'modB'
  dependsOn: [
    resA
  ]
}");
        }
        public void Necessary_dependsOn_statements_are_not_removed()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

resource resB 'My.Rp/resB@2020-01-01' = {
  name: 'resB'
  dependsOn: [
    resA
  ]
}";

            var compilation = CompilationHelper.CreateCompilation(("main.bicep", bicepFile));
            var rewriter    = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            PrintHelper.PrettyPrint(newProgramSyntax).Should().Be(
                @"resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

resource resB 'My.Rp/resB@2020-01-01' = {
  name: 'resB'
  dependsOn: [
    resA
  ]
}");
        }
        public void ProgramSyntax_is_not_modified_if_no_changes_are_applied()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}";

            var(_, _, compilation) = CompilationHelper.Compile(("main.bicep", bicepFile));
            var rewriter = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            // Reference equality check to ensure we're not regenerating syntax unnecessarily
            newProgramSyntax.Should().BeSameAs(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);
        }
        public void ProgramSyntax_is_not_modified_if_no_changes_are_applied()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}";

            var compilation = CompilationHelper.CreateCompilation(("main.bicep", bicepFile));
            var rewriter    = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            // Check that the two references are exactly the same
            newProgramSyntax.Should().BeSameAs(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);
        }
        public void Unnecessary_dependsOn_statements_are_removed()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

resource resB 'My.Rp/resB@2020-01-01' = {
  name: 'resB'
  properties: {
    resA: resA.name
  }
  dependsOn: [
    resA
  ]
}

var varA = resA.name
var varB = {
  resA: varA
  resB: resB.name
}

resource resC 'My.Rp/resB@2020-01-01' = {
  name: 'resC'
  properties: {
    resA: varB
  }
  dependsOn: [
    resA
    resB
  ]
}";

            var(_, _, compilation) = CompilationHelper.Compile(("main.bicep", bicepFile));
            var rewriter = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            PrintHelper.PrintAndCheckForParseErrors(newProgramSyntax).Should().Be(
                @"resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

resource resB 'My.Rp/resB@2020-01-01' = {
  name: 'resB'
  properties: {
    resA: resA.name
  }
}

var varA = resA.name
var varB = {
  resA: varA
  resB: resB.name
}

resource resC 'My.Rp/resB@2020-01-01' = {
  name: 'resC'
  properties: {
    resA: varB
  }
}");
        }
        public void Unneccessary_dependsOn_statements_are_removed_for_modules()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

module modB 'modb.bicep' = {
  name: 'modB'
  params: {
    resA: resA.name
  }
  dependsOn: [
    resA
  ]
}

var varA = resA.name
var varB = {
  resA: varA
  modB: modB.name
}

module modC 'modC.bicep' = {
  name: 'modC'
  params: {
    resA: varB
  }
  dependsOn: [
    resA
    modB
  ]
}";

            var(_, _, compilation) = CompilationHelper.Compile(("main.bicep", bicepFile));
            var rewriter = new DependsOnRemovalRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SourceFileGrouping.EntryPoint.ProgramSyntax);

            PrintHelper.PrintAndCheckForParseErrors(newProgramSyntax).Should().Be(
                @"resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
}

module modB 'modb.bicep' = {
  name: 'modB'
  params: {
    resA: resA.name
  }
}

var varA = resA.name
var varB = {
  resA: varA
  modB: modB.name
}

module modC 'modC.bicep' = {
  name: 'modC'
  params: {
    resA: varB
  }
}");
        }