Skip to content

Instantly share code, notes, and snippets.

@mrward
Last active February 6, 2018 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrward/0c6f15ac2d781d1c154b76766e87c505 to your computer and use it in GitHub Desktop.
Save mrward/0c6f15ac2d781d1c154b76766e87c505 to your computer and use it in GitHub Desktop.

Xamarin Forms 2.4 - .NET Standard - VS Mac Tests

Pre-requisites

.NET Standard project with Xamarin.Forms 2.4 NuGet package installed.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard1.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" />
  </ItemGroup>

</Project>

Tests covered by VS Mac Unit Tests

1) Add ContentPage with xaml

Expected result

  • Project file not modified.
  • MyPage.xaml.cs is nested under MyPage.xaml in Solution window
  • Project compiles without any errors
  • .xaml file has a BuildAction of EmbeddedResource
  • .xaml file has the Generator property set to MSBuild:UpdateDesignTimeXaml

2) Add ContentPage with xaml then close and re-open solution

Expected result

  • Project file not modified.
  • MyPage.xaml.cs is nested under MyPage.xaml in Solution window
  • No duplicate files shown in Solution window
  • Project compiles without any errors
  • .xaml file has a BuildAction of EmbeddedResource
  • .xaml file has the Generator property set to MSBuild:UpdateDesignTimeXaml

Manual Tests - not covered by VS Mac Unit Tests

1) Add ContentPage with xaml then set Copy to Output Directory for .xaml.cs file

Expected result

  • Update item added to project file for .xaml.cs file
  <ItemGroup>
    <Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="MyPage.xaml.cs">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Compile>
  </ItemGroup>

Note that the Condition should not be added but currently it is. This is another bug.

Actual result

  • OK

2) Add ContentPage with xaml then set Copy to Output Directory for .xaml file

Expected result

  • Update item added to project file for .cs file
  <ItemGroup>
    <EmbeddedResource Update="MyPage.xaml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </EmbeddedResource>
  </ItemGroup>

Actual result

OK - Update item added

3) Add ContentPage with xaml then change build action to None for .xaml file.

Expected result

  • Using the solution pad the Build actions does not show None for .NET Core/.NET Standard projects. Other project types are not affected (e.g. PCL projects).

  • Ignore information below when testing

Project xml shown below is not the expected behaviour (not valid but kept as information).

 <ItemGroup>
    <EmbeddedResource Remove="MyPage.xaml" />
  </ItemGroup>
  
  <ItemGroup>
    <None Include="MyPage.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
    </None>
  </ItemGroup>

However the above will not work since Xamarin.Forms 2.4 NuGet package has a <None Remove="**\*.xaml" Condition="'$(EnableDefaultNoneItems)'=='True'" /> in its Xamarin.Forms.DefaultItems.targets which will be included after the None items in the project file so the .xaml file will be removed.

Trying this in Visual Studio 2017 on Windows and Visual Studio shows an error message:

One or more values are invalid. Cannot add 'Page1.xaml' to the project, because the path is explicitly excluded from the project (...Xamarin.Forms.DefaultItems.targets (12,3)).

Line 12 of the Xamarin.Forms.DefaultItems.targets is:

<None Remove="**\*.xaml" Condition="'$(EnableDefaultNoneItems)'=='True'" />

So it looks like Visual Studio 2017 is smart enough to realise that it is not possible to add the Page.xaml file as a None item because the None file glob is added after the project items have been taken into account.

In Visual Studio 2017 if you change the build action to Content then that works. However Visual Studio adds a Content Include item that has no other metadata properties defined.

Actual result

  • None build action is not available.

4) Add ContentPage with xaml then change build action to None for .xaml.cs file.

  • Project file updated.
    • Compile Remove item added for .xaml.cs file.
    • None Include item added for .xaml.cs file.

Expected result

  <ItemGroup>
    <Compile Remove="MyPage.xaml.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="MyPage.xaml.cs" Condition=" '$(EnableDefaultCompileItems)' == 'true' ">
      <DependentUpon>MyPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </None>
  </ItemGroup>
  • Note the Condition should not be added but currently is.

Actual result

  • OK - Compile Remove item and None Include item added.

5) Add ContentPage with xaml and then change Generator for .xaml file.

  • Change the Generator in Properties to 'MSBuild:UpdateDesignTimeXaml2'

Expected result

  • Project file updated.
    • EmbeddedResource Update item added for .xaml file.
  <ItemGroup>
    <EmbeddedResource Update="MyPage.xaml">
      <Generator>MSBuild:UpdateDesignTimeXaml2</Generator>
    </EmbeddedResource>
  </ItemGroup>

Actual result

  • OK - Update item added.

6) Add ContentPage with xaml and then remove and delete .xaml file

  • From Solution window right click the file, select Remove, then Delete.

Expected result

  • Project file not changed.

Actual result

  • OK - project file unchanged.

7) Add ContentPage with xaml and then remove and delete .xaml.cs file

  • From Solution window right click the file, select Remove, then Delete.

Expected result

  • Project file not changed.

Actual result

  • OK - project file unchanged.

8) Add ContentPage with xaml and then remove .xaml but do not delete .xaml file

Expected result

  • Project file updated.
    • EmbeddedResource Remove item added for .xaml file.
    • Compile Remove item added for .xaml.cs file.
  <ItemGroup>
    <Compile Remove="MyPage.xaml.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Remove="MyPage.xaml" />
  </ItemGroup>

Actual result

  • OK

9) Add ContentPage with xaml and then remove .xaml.cs file but do not delete .xaml.cs file

Expected result

  • Compile Remove item added for .cs file in project.
  <ItemGroup>
    <Compile Remove="MyPage.xaml.cs" />
  </ItemGroup>

Actual result

  • OK

10) Add ContentPage with xaml. Then both .xaml and .xaml.cs file removed from the project but not deleted. Then edit .csproj and remove associated MSBuild items

Expected result

  • Both files appear in Solution window - nested.

Actual result

  • OK Both files appear in Solution window - nested.

11) Add ContentPage with xaml then rename .xaml file

Expected result

  • The .xaml.cs file is renamed automatically.
  • The project file is not changed.

Below is information about possible solutions and problems - please ignore for testing.

  • Simplest solution here would be for the dependent .xaml.cs file to be renamed automatically.
  • Visual Studio on Windows does this. However it also adds a redundant Compile with a DependentUpon MSBuild item.
  • Current VS Mac should add an Update item for the .xaml.cs file.
  <ItemGroup>
   <Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="MyPage.xaml.cs">
     <DependentUpon>MyPage2.xaml</DependentUpon>
   </Compile>
 </ItemGroup>
  • Condition should not be added but is currently being added.

Do not think the nesting being lost after a reload can be fixed when the .xaml file and the .xaml.cs file have different names. Xamarin.Forms has a Xamarin.Forms.DefaultItems.targets file which will be imported right at the end of the project. It contains:

 <Compile Update="**\*.xaml$(DefaultLanguageSourceExtension)" DependentUpon="%(Filename)" SubType="Code" />

So this overrides any DependentUpon information defined in the project file (.csproj) so nesting can never work if the filenames are different.

Actual result

  • OK - xaml.cs file is renamed automatically.
  • Project file is not modified.

12) Add ContentPage with xaml then rename .xaml.cs file

Expected result

  • Rename menu not available for .xaml.cs files in .NET Core projects if they depend on a .xaml file.
  • Visual Studio 2017 does not allow the .xaml.cs file to be renamed. You can only rename the .xaml file.

Information below can be ignored for testing.

Xamarin.Forms has a Xamarin.Forms.DefaultItems.targets file which will be imported right at the end of the project. It contains:

 <Compile Update="**\*.xaml$(DefaultLanguageSourceExtension)" DependentUpon="%(Filename)" SubType="Code" />

So this overrides any DependentUpon information defined in the project file (.csproj) so nesting can never work if the filenames are different.

Actual result

  • OK - Rename menu not available

13) Add ContentPage with xaml then remove .xaml file but do not delete it, then include it back in the project

Expected result

<Project Sdk="Microsoft.NET.Sdk">

 <PropertyGroup>
   <TargetFramework>netstandard1.0</TargetFramework>
 </PropertyGroup>

 <ItemGroup>
   <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" />
 </ItemGroup>

 <ItemGroup>
   <Compile Remove="MyPage.xaml.cs" />
 </ItemGroup>
</Project>

Actual result

  • OK

14) Add ContentPage with xaml then remove .xaml.cs file but do not delete it, then include it back in the project

Expected result

<Project Sdk="Microsoft.NET.Sdk">

 <PropertyGroup>
   <TargetFramework>netstandard1.0</TargetFramework>
 </PropertyGroup>

 <ItemGroup>
   <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" />
 </ItemGroup>

</Project>

Actual result

  • OK. Remove item added for .xaml.cs file initially, then removed again after file is added back.

15) Copy or move App.xaml from existing PCL or Shared project to .NET Standard project

  • Create a new Xamarin.Forms Blank project template.
  • Add a new .NET Standard project to the solution.
  • Install Xamarin.Forms NuGet package into the .NET Standard project.
  • Select App.xaml in solution explorer and use Copy/Cut menu options or keyboard shortcut.
  • Select .NET Standard project and use Paste menu option or keyboard shortcut.

Expected result

  • Project file has no items.
<Project Sdk="Microsoft.NET.Sdk">

 <PropertyGroup>
   <TargetFramework>netstandard1.0</TargetFramework>
 </PropertyGroup>

 <ItemGroup>
   <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" />
 </ItemGroup>

</Project>
  • The original problem was that the PCL and Shared project define their App.xaml files without any extra metadata so the project model was adding a new include item for the copied .xaml file.
  • If the EmbeddedResource in the PCL or shared project was defined as the following then the copy/move works as expected in older VS Mac versions.
    <EmbeddedResource Include="MyPage.xaml">
     <SubType>Designer</SubType>
     <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
   </EmbeddedResource>

Actual result

  • OK.

Previously an include item was added for the EmbeddedResource which resulted in a build error due to a duplicate .xaml file.

16) Remove .xaml but do not delete from .NET Standard project with just a .xaml and .xaml.cs file (no other files)

  • Create a .NET Standard project that uses Xamarin.Forms with just a .xaml and a .xaml.cs file. No other files in the project.
  • Remove .xaml and .xaml.cs file from the Solution window but do not delete

Expected result

  • Remove item added for .xaml file and for .xaml.cs file.
  <Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard1.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Remove="MyPage.xaml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Remove="MyPage.xaml.cs" />
  </ItemGroup>
</Project>

Actual result

  • OK

All previous tests but reloading the solution after adding the initial ContentPage with xaml.

A1) Add ContentPage with xaml, close/re-open solution, then set Copy to Output Directory for .xaml.cs file

Expected result

  • Update item added to project file for .xaml.cs file

Actual result

  • OK.

A2) Add ContentPage with xaml, close/re-open solution, then set Copy to Output Directory for .xaml file

Expected result

  • Update item added to project file for .xaml file

Actual result

  • OK

A3) Add ContentPage with xaml, close/re-open solution, then change build action to None for .xaml file.

Expected result

  • Solution pad's Build Action context menu does not show None for .xaml files.

Actual result

  • Not possible to change build action to None.

A4) Add ContentPage with xaml, close/re-open solution, then change build action to None for .xaml.cs file.

  • Project file updated.
    • Compile Remove item added for .xaml.cs file.
    • None Include item added for .xaml.cs file.

Actual result

  • OK

A5) Add ContentPage with xaml, close/re-open solution, and then change Generator for .xaml file.

Expected result

  • Change the Generator in Properties to 'MSBuild:UpdateDesignTimeXaml2'

Expected result

  • Project file updated.
  • EmbeddedResource Update item added for .xaml file.

Actual result

  • OK

A6) Add ContentPage with xaml, close/re-open solution, and then remove and delete .xaml file

  • From Solution window right click the file, select Remove, then Delete.

Expected result

  • Project file not changed.

Actual result

  • OK

A7) Add ContentPage with xaml, close/re-open solution, and then remove and delete .xaml.cs file

  • From Solution window right click the file, select Remove, then Delete.

Expected result

  • Project file not changed.

Actual result

  • OK

A8) Add ContentPage with xaml, close/re-open solution, and then remove .xaml but do not delete .xaml file

Expected result

  • Project file updated.
    • EmbeddedResource Remove item added for .xaml file.
    • Compile Remove item added for .cs file.

Actual result

  • OK.
    • EmbeddedResource Remove item added for .xaml file.
    • Compile Remove item added for .xaml.cs file.

A9) Add ContentPage with xaml, close/re-open solution, and then remove .xaml.cs file but do not delete .cs file

Expected result

  • Compile Remove item added for .xaml.cs file in project.

Actual result

  • OK

A10) Add ContentPage with xaml, close/re-open solution. Then both .xaml and .cs file removed from the project but not deleted. Close/re-open solution. Then edit .csproj and remove associated MSBuild items

Expected result

  • Both files appear in Solution window - nested.

Actual result

  • OK.

A11) Add ContentPage with xaml then rename .xaml file

Expected result

  • xaml file renamed and .xaml.cs file automatically renamed.
  • Project file not modified.

Actual result

  • OK

A12) Add ContentPage with xaml then rename .xaml.cs file

Expected result

  • Rename menu option is not available for .xaml.cs file.

Actual result

  • Rename menu option is not available for .xaml.cs. file

A13) Add ContentPage with xaml then remove .xaml file but do not delete it, then include it back in the project

Expected result

  • Project file has Remove .xaml item removed.

Actual result

  • Remove item for .xaml file remains in project file.

A14) Add ContentPage with xaml, reload project, then remove .xaml.cs file but do not delete it, then include it back in the project

Expected result

  • Project file has Remove .xaml.cs item removed.

Actual result

  • OK.

A15) Copy or move App.xaml from existing PCL or Shared project to .NET Standard project

  • Select App.xaml in solution explorer and use Copy/Cut menu options or keyboard shortcut.
  • Select .NET Standard project and use Paste menu option or keyboard shortcut.

Expected result

  • Project file has no items.

Actual result

  • OK

A16) Remove .xaml but do not delete from .NET Standard project with just a .xaml and .xaml.cs file (no other files)

  • Create a .NET Standard project that uses Xamarin.Forms with just a .xaml and a .xaml.cs file. No other files in the project.
  • Remove .xaml and .xaml.cs file from the Solution window but do not delete

Expected result

  • Remove item added for .xaml file and for .xaml.cs file.

Actual result

  • OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment