github.com/bitrise-io/go-xamarin@v0.0.0-20211005113058-bf60a8bae851/analyzers/project/project_test.go (about)

     1  package project
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/bitrise-io/go-utils/fileutil"
    10  	"github.com/bitrise-io/go-utils/pathutil"
    11  	"github.com/bitrise-io/go-xamarin/constants"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func tmpProjectWithContentInDir(t *testing.T, content, dir string) string {
    16  	pth := filepath.Join(dir, "project.csproj")
    17  	require.NoError(t, fileutil.WriteStringToFile(pth, content))
    18  	return pth
    19  }
    20  
    21  func tmpProjectWithContent(t *testing.T, content string) string {
    22  	tmpDir, err := pathutil.NormalizedOSTempDirPath("__xamarin-builder-test__")
    23  	require.NoError(t, err)
    24  	return tmpProjectWithContentInDir(t, content, tmpDir)
    25  }
    26  
    27  func stringSliceContainsOnly(slice []string, item ...string) bool {
    28  	if len(slice) != len(item) {
    29  		return false
    30  	}
    31  
    32  	testMap := map[string]bool{}
    33  	for _, i := range slice {
    34  		testMap[i] = false
    35  	}
    36  	for _, e := range item {
    37  		_, ok := testMap[e]
    38  		if !ok {
    39  			return false
    40  		}
    41  		testMap[e] = true
    42  	}
    43  	for _, ok := range testMap {
    44  		if !ok {
    45  			return false
    46  		}
    47  	}
    48  	return true
    49  }
    50  
    51  func TestAnalyzeProject(t *testing.T) {
    52  	t.Log("xamarin uitest test ID test - all IDs should be upper case")
    53  	{
    54  		pth := tmpProjectWithContent(t, xamarinUITestProjectContent)
    55  		defer func() {
    56  			require.NoError(t, os.Remove(pth))
    57  		}()
    58  
    59  		project, err := analyzeProject(pth)
    60  		require.NoError(t, err)
    61  
    62  		require.Equal(t, "BA48743D-06F3-4D2D-ACFD-EE2642CE155A", project.ID)
    63  		require.Equal(t, true, stringSliceContainsOnly(project.ReferredProjectIDs, "90F3C584-FD69-4926-9903-6B9771847782"))
    64  	}
    65  
    66  	t.Log("relative path test")
    67  	{
    68  		currentDir, err := pathutil.CurrentWorkingDirectoryAbsolutePath()
    69  		require.NoError(t, err)
    70  		defer func() {
    71  			require.NoError(t, os.Chdir(currentDir))
    72  		}()
    73  
    74  		tmpDir := filepath.Join(currentDir, "__xamarin-builder-test__")
    75  		require.NoError(t, os.MkdirAll(tmpDir, 0777))
    76  		defer func() {
    77  			require.NoError(t, os.RemoveAll(tmpDir))
    78  		}()
    79  
    80  		pth := tmpProjectWithContentInDir(t, iosTestProjectContent, tmpDir)
    81  		defer func() {
    82  			require.NoError(t, os.Remove(pth))
    83  		}()
    84  		dir := filepath.Dir(pth)
    85  		base := filepath.Base(pth)
    86  
    87  		require.NoError(t, os.Chdir(dir))
    88  
    89  		project, err := analyzeProject(base)
    90  		require.NoError(t, err)
    91  		require.Equal(t, pth, project.Pth)
    92  
    93  		config, ok := project.Configs["Debug|iPhoneSimulator"]
    94  		require.Equal(t, true, ok)
    95  		require.Equal(t, "Debug", config.Configuration)
    96  		require.Equal(t, "iPhoneSimulator", config.Platform)
    97  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Debug"), config.OutputDir)
    98  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "i386"))
    99  		require.Equal(t, false, config.BuildIpa)
   100  		require.Equal(t, false, config.SignAndroid)
   101  		require.Equal(t, "", project.ManifestPth)
   102  	}
   103  
   104  	t.Log("ios test")
   105  	{
   106  		pth := tmpProjectWithContent(t, iosTestProjectContent)
   107  		defer func() {
   108  			require.NoError(t, os.Remove(pth))
   109  		}()
   110  		dir := filepath.Dir(pth)
   111  		fileName := filepath.Base(pth)
   112  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   113  
   114  		project, err := analyzeProject(pth)
   115  		require.NoError(t, err)
   116  
   117  		require.Equal(t, pth, project.Pth)
   118  		require.Equal(t, fileName, project.Name)
   119  
   120  		require.Equal(t, "90F3C584-FD69-4926-9903-6B9771847782", project.ID)
   121  		require.Equal(t, constants.SDKIOS, project.SDK)
   122  		require.Equal(t, "exe", project.OutputType)
   123  		require.Equal(t, "CreditCardValidator.iOS", project.AssemblyName)
   124  
   125  		require.Equal(t, constants.TestFrameworkUnknown, project.TestFramework)
   126  		require.Equal(t, true, stringSliceContainsOnly(project.ReferredProjectIDs, "99A825A6-6F99-4B94-9F65-E908A6347F1E"))
   127  
   128  		require.Equal(t, "", project.ManifestPth)
   129  		require.Equal(t, false, project.AndroidApplication)
   130  
   131  		// Configs
   132  		config, ok := project.Configs["Debug|iPhoneSimulator"]
   133  		require.Equal(t, true, ok)
   134  		require.Equal(t, "Debug", config.Configuration)
   135  		require.Equal(t, "iPhoneSimulator", config.Platform)
   136  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Debug"), config.OutputDir)
   137  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "i386"))
   138  		require.Equal(t, false, config.BuildIpa)
   139  		require.Equal(t, false, config.SignAndroid)
   140  
   141  		config, ok = project.Configs["Release|iPhone"]
   142  		require.Equal(t, true, ok)
   143  		require.Equal(t, "Release", config.Configuration)
   144  		require.Equal(t, "iPhone", config.Platform)
   145  		require.Equal(t, filepath.Join(dir, "bin/iPhone/Release"), config.OutputDir)
   146  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "ARMv7", "ARM64"))
   147  		require.Equal(t, true, config.BuildIpa)
   148  		require.Equal(t, false, config.SignAndroid)
   149  
   150  		config, ok = project.Configs["Release|iPhoneSimulator"]
   151  		require.Equal(t, true, ok)
   152  		require.Equal(t, "Release", config.Configuration)
   153  		require.Equal(t, "iPhoneSimulator", config.Platform)
   154  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Release"), config.OutputDir)
   155  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "i386"))
   156  		require.Equal(t, false, config.BuildIpa)
   157  		require.Equal(t, false, config.SignAndroid)
   158  
   159  		config, ok = project.Configs["Debug|iPhone"]
   160  		require.Equal(t, true, ok)
   161  		require.Equal(t, "Debug", config.Configuration)
   162  		require.Equal(t, "iPhone", config.Platform)
   163  		require.Equal(t, filepath.Join(dir, "bin/iPhone/Debug"), config.OutputDir)
   164  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "ARMv7", "ARM64"))
   165  		require.Equal(t, false, config.BuildIpa)
   166  		require.Equal(t, false, config.SignAndroid)
   167  	}
   168  
   169  	t.Log("android test")
   170  	{
   171  		androidTest(t, androidTestProjectContent)
   172  		androidTest(t, androidTestProjectUnformattedContent)
   173  		androidTest(t, androidTestProjectContentWithRedefine)
   174  	}
   175  
   176  	t.Log("mac test")
   177  	{
   178  		pth := tmpProjectWithContent(t, macTestProjectContent)
   179  		defer func() {
   180  			require.NoError(t, os.Remove(pth))
   181  		}()
   182  		dir := filepath.Dir(pth)
   183  		fileName := filepath.Base(pth)
   184  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   185  
   186  		project, err := analyzeProject(pth)
   187  		require.NoError(t, err)
   188  
   189  		require.Equal(t, pth, project.Pth)
   190  		require.Equal(t, fileName, project.Name)
   191  
   192  		require.Equal(t, "4DA5EAC6-6F80-4FEC-AF81-194210F10B51", project.ID)
   193  		require.Equal(t, constants.SDKMacOS, project.SDK)
   194  		require.Equal(t, "exe", project.OutputType)
   195  		require.Equal(t, "Hello_Mac", project.AssemblyName)
   196  
   197  		require.Equal(t, constants.TestFrameworkUnknown, project.TestFramework)
   198  		require.Equal(t, 0, len(project.ReferredProjectIDs))
   199  
   200  		require.Equal(t, "", project.ManifestPth)
   201  		require.Equal(t, false, project.AndroidApplication)
   202  
   203  		// Configs
   204  		config, ok := project.Configs["Debug|AnyCPU"]
   205  		require.Equal(t, true, ok)
   206  		require.Equal(t, "Debug", config.Configuration)
   207  		require.Equal(t, "AnyCPU", config.Platform)
   208  		require.Equal(t, filepath.Join(dir, "bin/Debug"), config.OutputDir)
   209  		require.Equal(t, 0, len(config.MtouchArchs))
   210  		require.Equal(t, false, config.BuildIpa)
   211  		require.Equal(t, false, config.SignAndroid)
   212  
   213  		config, ok = project.Configs["Release|AnyCPU"]
   214  		require.Equal(t, true, ok)
   215  		require.Equal(t, "Release", config.Configuration)
   216  		require.Equal(t, "AnyCPU", config.Platform)
   217  		require.Equal(t, filepath.Join(dir, "bin/Release"), config.OutputDir)
   218  		require.Equal(t, 0, len(config.MtouchArchs))
   219  		require.Equal(t, false, config.BuildIpa)
   220  		require.Equal(t, false, config.SignAndroid)
   221  	}
   222  
   223  	t.Log("tv os test")
   224  	{
   225  		pth := tmpProjectWithContent(t, tvTestProjectContent)
   226  		defer func() {
   227  			require.NoError(t, os.Remove(pth))
   228  		}()
   229  		dir := filepath.Dir(pth)
   230  		fileName := filepath.Base(pth)
   231  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   232  
   233  		project, err := analyzeProject(pth)
   234  		require.NoError(t, err)
   235  
   236  		require.Equal(t, pth, project.Pth)
   237  		require.Equal(t, fileName, project.Name)
   238  
   239  		require.Equal(t, "51D9C362-2997-4029-B38F-06C36F17056E", project.ID)
   240  		require.Equal(t, constants.SDKTvOS, project.SDK)
   241  		require.Equal(t, "exe", project.OutputType)
   242  		require.Equal(t, "tvos", project.AssemblyName)
   243  
   244  		require.Equal(t, constants.TestFrameworkUnknown, project.TestFramework)
   245  		require.Equal(t, 0, len(project.ReferredProjectIDs))
   246  
   247  		require.Equal(t, "", project.ManifestPth)
   248  		require.Equal(t, false, project.AndroidApplication)
   249  
   250  		// Configs
   251  		config, ok := project.Configs["Debug|iPhoneSimulator"]
   252  		require.Equal(t, true, ok)
   253  		require.Equal(t, "Debug", config.Configuration)
   254  		require.Equal(t, "iPhoneSimulator", config.Platform)
   255  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Debug"), config.OutputDir)
   256  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "x86_64"))
   257  		require.Equal(t, false, config.BuildIpa)
   258  		require.Equal(t, false, config.SignAndroid)
   259  
   260  		config, ok = project.Configs["Release|iPhone"]
   261  		require.Equal(t, true, ok)
   262  		require.Equal(t, "Release", config.Configuration)
   263  		require.Equal(t, "iPhone", config.Platform)
   264  		require.Equal(t, filepath.Join(dir, "bin/iPhone/Release"), config.OutputDir)
   265  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "ARM64"))
   266  		require.Equal(t, false, config.BuildIpa)
   267  		require.Equal(t, false, config.SignAndroid)
   268  
   269  		config, ok = project.Configs["Release|iPhoneSimulator"]
   270  		require.Equal(t, true, ok)
   271  		require.Equal(t, "Release", config.Configuration)
   272  		require.Equal(t, "iPhoneSimulator", config.Platform)
   273  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Release"), config.OutputDir)
   274  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "x86_64"))
   275  		require.Equal(t, false, config.BuildIpa)
   276  		require.Equal(t, false, config.SignAndroid)
   277  
   278  		config, ok = project.Configs["Debug|iPhone"]
   279  		require.Equal(t, true, ok)
   280  		require.Equal(t, "Debug", config.Configuration)
   281  		require.Equal(t, "iPhone", config.Platform)
   282  		require.Equal(t, filepath.Join(dir, "bin/iPhone/Debug"), config.OutputDir)
   283  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "ARM64"))
   284  		require.Equal(t, false, config.BuildIpa)
   285  		require.Equal(t, false, config.SignAndroid)
   286  	}
   287  
   288  	t.Log("xamarin uitest test")
   289  	{
   290  		pth := tmpProjectWithContent(t, xamarinUITestProjectContent)
   291  		defer func() {
   292  			require.NoError(t, os.Remove(pth))
   293  		}()
   294  		dir := filepath.Dir(pth)
   295  		fileName := filepath.Base(pth)
   296  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   297  
   298  		project, err := analyzeProject(pth)
   299  		require.NoError(t, err)
   300  
   301  		require.Equal(t, pth, project.Pth)
   302  		require.Equal(t, fileName, project.Name)
   303  
   304  		require.Equal(t, "BA48743D-06F3-4D2D-ACFD-EE2642CE155A", project.ID)
   305  		require.Equal(t, constants.SDKUnknown, project.SDK)
   306  		require.Equal(t, "library", project.OutputType)
   307  		require.Equal(t, "CreditCardValidator.iOS.UITests", project.AssemblyName)
   308  
   309  		require.Equal(t, constants.TestFrameworkXamarinUITest, project.TestFramework)
   310  		require.Equal(t, true, stringSliceContainsOnly(project.ReferredProjectIDs, "90F3C584-FD69-4926-9903-6B9771847782"))
   311  
   312  		require.Equal(t, "", project.ManifestPth)
   313  		require.Equal(t, false, project.AndroidApplication)
   314  
   315  		// Configs
   316  		config, ok := project.Configs["Debug|AnyCPU"]
   317  		require.Equal(t, true, ok)
   318  		require.Equal(t, "Debug", config.Configuration)
   319  		require.Equal(t, "AnyCPU", config.Platform)
   320  		require.Equal(t, filepath.Join(dir, "bin/Debug"), config.OutputDir)
   321  		require.Equal(t, 0, len(config.MtouchArchs))
   322  		require.Equal(t, false, config.BuildIpa)
   323  		require.Equal(t, false, config.SignAndroid)
   324  
   325  		config, ok = project.Configs["Release|AnyCPU"]
   326  		require.Equal(t, true, ok)
   327  		require.Equal(t, "Release", config.Configuration)
   328  		require.Equal(t, "AnyCPU", config.Platform)
   329  		require.Equal(t, filepath.Join(dir, "bin/Release"), config.OutputDir)
   330  		require.Equal(t, 0, len(config.MtouchArchs))
   331  		require.Equal(t, false, config.BuildIpa)
   332  		require.Equal(t, false, config.SignAndroid)
   333  	}
   334  
   335  	t.Log("nunit test")
   336  	{
   337  		pth := tmpProjectWithContent(t, nunitTestProjectContent)
   338  		defer func() {
   339  			require.NoError(t, os.Remove(pth))
   340  		}()
   341  		dir := filepath.Dir(pth)
   342  		fileName := filepath.Base(pth)
   343  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   344  
   345  		project, err := analyzeProject(pth)
   346  		require.NoError(t, err)
   347  
   348  		require.Equal(t, pth, project.Pth)
   349  		require.Equal(t, fileName, project.Name)
   350  
   351  		require.Equal(t, "ED150913-76EB-446F-8B78-DC77E5795703", project.ID)
   352  		require.Equal(t, constants.SDKUnknown, project.SDK)
   353  		require.Equal(t, "library", project.OutputType)
   354  		require.Equal(t, "CreditCardValidator.iOS.NunitTests", project.AssemblyName)
   355  
   356  		require.Equal(t, constants.TestFrameworkNunitTest, project.TestFramework)
   357  		require.Equal(t, 0, len(project.ReferredProjectIDs))
   358  
   359  		require.Equal(t, "", project.ManifestPth)
   360  		require.Equal(t, false, project.AndroidApplication)
   361  
   362  		// Configs
   363  		config, ok := project.Configs["Debug|AnyCPU"]
   364  		require.Equal(t, true, ok)
   365  		require.Equal(t, "Debug", config.Configuration)
   366  		require.Equal(t, "AnyCPU", config.Platform)
   367  		require.Equal(t, filepath.Join(dir, "bin/Debug"), config.OutputDir)
   368  		require.Equal(t, 0, len(config.MtouchArchs))
   369  		require.Equal(t, false, config.BuildIpa)
   370  		require.Equal(t, false, config.SignAndroid)
   371  
   372  		config, ok = project.Configs["Release|AnyCPU"]
   373  		require.Equal(t, true, ok)
   374  		require.Equal(t, "Release", config.Configuration)
   375  		require.Equal(t, "AnyCPU", config.Platform)
   376  		require.Equal(t, filepath.Join(dir, "bin/Release"), config.OutputDir)
   377  		require.Equal(t, 0, len(config.MtouchArchs))
   378  		require.Equal(t, false, config.BuildIpa)
   379  		require.Equal(t, false, config.SignAndroid)
   380  	}
   381  
   382  	t.Log("nunit lite test")
   383  	{
   384  		pth := tmpProjectWithContent(t, nunitLiteTestProjectContent)
   385  		defer func() {
   386  			require.NoError(t, os.Remove(pth))
   387  		}()
   388  		dir := filepath.Dir(pth)
   389  		fileName := filepath.Base(pth)
   390  		fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   391  
   392  		project, err := analyzeProject(pth)
   393  		require.NoError(t, err)
   394  
   395  		require.Equal(t, pth, project.Pth)
   396  		require.Equal(t, fileName, project.Name)
   397  
   398  		require.Equal(t, "95615CA5-0D75-4389-A6E0-78309A686712", project.ID)
   399  		require.Equal(t, constants.SDKIOS, project.SDK)
   400  		require.Equal(t, "exe", project.OutputType)
   401  		require.Equal(t, "CreditCardValidator.iOS.NunitLiteTests", project.AssemblyName)
   402  
   403  		require.Equal(t, constants.TestFrameworkNunitLiteTest, project.TestFramework)
   404  		require.Equal(t, 0, len(project.ReferredProjectIDs))
   405  
   406  		require.Equal(t, "", project.ManifestPth)
   407  		require.Equal(t, false, project.AndroidApplication)
   408  
   409  		// Configs
   410  		config, ok := project.Configs["Debug|iPhoneSimulator"]
   411  		require.Equal(t, true, ok)
   412  		require.Equal(t, "Debug", config.Configuration)
   413  		require.Equal(t, "iPhoneSimulator", config.Platform)
   414  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Debug"), config.OutputDir)
   415  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "i386"))
   416  		require.Equal(t, false, config.BuildIpa)
   417  		require.Equal(t, false, config.SignAndroid)
   418  
   419  		config, ok = project.Configs["Release|iPhone"]
   420  		require.Equal(t, true, ok)
   421  		require.Equal(t, "Release", config.Configuration)
   422  		require.Equal(t, "iPhone", config.Platform)
   423  		require.Equal(t, filepath.Join(dir, "bin/iPhone/Release"), config.OutputDir)
   424  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "ARMv7", "ARM64"))
   425  		require.Equal(t, false, config.BuildIpa)
   426  		require.Equal(t, false, config.SignAndroid)
   427  
   428  		config, ok = project.Configs["Release|iPhoneSimulator"]
   429  		require.Equal(t, true, ok)
   430  		require.Equal(t, "Release", config.Configuration)
   431  		require.Equal(t, "iPhoneSimulator", config.Platform)
   432  		require.Equal(t, filepath.Join(dir, "bin/iPhoneSimulator/Release"), config.OutputDir)
   433  		require.Equal(t, true, stringSliceContainsOnly(config.MtouchArchs, "i386"))
   434  		require.Equal(t, false, config.BuildIpa)
   435  		require.Equal(t, false, config.SignAndroid)
   436  	}
   437  }
   438  
   439  func androidTest(t *testing.T, contentPth string) {
   440  	pth := tmpProjectWithContent(t, contentPth)
   441  	defer func() {
   442  		require.NoError(t, os.Remove(pth))
   443  	}()
   444  	dir := filepath.Dir(pth)
   445  	fileName := filepath.Base(pth)
   446  	fileName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
   447  
   448  	project, err := analyzeProject(pth)
   449  	require.NoError(t, err)
   450  
   451  	require.Equal(t, pth, project.Pth)
   452  	require.Equal(t, fileName, project.Name)
   453  
   454  	require.Equal(t, "9D1D32A3-D13F-4F23-B7D4-EF9D52B06E60", project.ID)
   455  	require.Equal(t, constants.SDKAndroid, project.SDK)
   456  	require.Equal(t, "library", project.OutputType)
   457  	require.Equal(t, "CreditCardValidator.Droid", project.AssemblyName)
   458  
   459  	require.Equal(t, constants.TestFrameworkUnknown, project.TestFramework)
   460  	require.Equal(t, true, stringSliceContainsOnly(project.ReferredProjectIDs, "99A825A6-6F99-4B94-9F65-E908A6347F1E"))
   461  
   462  	require.Equal(t, filepath.Join(dir, "Properties/AndroidManifest.xml"), project.ManifestPth)
   463  	require.Equal(t, true, project.AndroidApplication)
   464  
   465  	// Configs
   466  	config, ok := project.Configs["Debug|AnyCPU"]
   467  	require.Equal(t, true, ok)
   468  	require.Equal(t, "Debug", config.Configuration)
   469  	require.Equal(t, "AnyCPU", config.Platform)
   470  	require.Equal(t, filepath.Join(dir, "bin/Debug"), config.OutputDir)
   471  	require.Equal(t, 0, len(config.MtouchArchs))
   472  	require.Equal(t, false, config.BuildIpa)
   473  	require.Equal(t, false, config.SignAndroid)
   474  
   475  	config, ok = project.Configs["Release|AnyCPU"]
   476  	require.Equal(t, true, ok)
   477  	require.Equal(t, "Release", config.Configuration)
   478  	require.Equal(t, "AnyCPU", config.Platform)
   479  	require.Equal(t, filepath.Join(dir, "bin/Release"), config.OutputDir)
   480  	require.Equal(t, 0, len(config.MtouchArchs))
   481  	require.Equal(t, false, config.BuildIpa)
   482  	require.Equal(t, true, config.SignAndroid)
   483  }