@@ -28,6 +28,7 @@ import (
2828 "github.com/arduino/arduino-cli/internal/integrationtest"
2929 "github.com/arduino/go-paths-helper"
3030 "github.com/stretchr/testify/require"
31+ "go.bug.st/testifyjson/requirejson"
3132 "golang.org/x/exp/slices"
3233)
3334
@@ -63,6 +64,8 @@ func TestCompileOfProblematicSketches(t *testing.T) {
6364 require .NoError (t , err )
6465 _ , _ , err = cli .Run ("lib" , "install" , "CapacitiveSensor@0.5" )
6566 require .NoError (t , err )
67+ _ , _ , err = cli .Run ("lib" , "install" , "FastLED@3.1.0" )
68+ require .NoError (t , err )
6669
6770 // Install custom hardware required for tests
6871 customHwDir , err := paths .New (".." , "testdata" , "user_hardware" ).Abs ()
@@ -99,12 +102,24 @@ func TestCompileOfProblematicSketches(t *testing.T) {
99102 {"SketchNoFunctionsTwoFiles" , testBuilderSketchNoFunctionsTwoFiles },
100103 {"SketchWithClassAndMethodSubstring" , testBuilderSketchWithClassAndMethodSubstring },
101104 {"SketchThatChecksIfSPIHasTransactions" , tryBuildAvrLeonardo },
105+ {"SketchThatChecksIfSPIHasTransactionsAndIncludesMissingEthernet" , testBuilderSketchThatChecksIfSPIHasTransactionsAndIncludesMissingEthernet },
102106 {"SketchWithDependendLibraries" , tryBuildAvrLeonardo },
103107 {"SketchWithFunctionPointer" , tryBuildAvrLeonardo },
104108 {"USBHostExample" , testBuilderUSBHostExample },
105109 {"SketchWithConflictingLibraries" , testBuilderSketchWithConflictingLibraries },
106110 {"SketchLibraryProvidesAllIncludes" , testBuilderSketchLibraryProvidesAllIncludes },
107111 {"UserHardware" , testBuilderWithUserHardware },
112+ {"SketchThatIncludesArduinoH" , testBuilderSketchThatIncludesArduinoH },
113+ {"SketchWithStaticAsserts" , testBuilderSketchWithStaticAsserts },
114+ {"SketchWithEnumClass" , testBuilderSketchWithEnumClass },
115+ {"SketchWithExternC" , testBuilderSketchWithExternC },
116+ {"SketchWithMultilinePrototypes" , testBuilderSketchWithMultilinePrototypes },
117+ {"SketchWithExternCMultiline" , testBuilderSketchWithExternCMultiline },
118+ {"SketchWithMultilineTemplate" , testBuilderSketchWithMultilineTemplate },
119+ {"SketchWithFakeFunctionPointer" , testBuilderSketchWithFakeFunctionPointer },
120+ {"SketchWithMinMaxDefinitions" , testBuilderSketchWithMinMaxDefinitions },
121+ {"SketchWithFastledsLibrary" , testBuilderSketchWithFastledsLibrary },
122+ {"SketchClassFunction" , testBuilderSketchClassFunction },
108123 }.Run (t , env , cli )
109124}
110125
@@ -613,6 +628,179 @@ func tryBuildAvrLeonardo(t *testing.T, env *integrationtest.Environment, cli *in
613628 require .NoError (t , err )
614629}
615630
631+ func testBuilderSketchThatIncludesArduinoH (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
632+ t .Run ("Build" , func (t * testing.T ) {
633+ // Build
634+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
635+ require .NoError (t , err )
636+ })
637+
638+ t .Run ("Preprocess" , func (t * testing.T ) {
639+ // Preprocess
640+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
641+ require .NoError (t , err )
642+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
643+ })
644+ }
645+
646+ func testBuilderSketchWithStaticAsserts (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
647+ t .Run ("Build" , func (t * testing.T ) {
648+ // Build
649+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
650+ require .NoError (t , err )
651+ })
652+
653+ t .Run ("Preprocess" , func (t * testing.T ) {
654+ // Preprocess
655+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
656+ require .NoError (t , err )
657+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
658+ })
659+ }
660+
661+ func testBuilderSketchWithEnumClass (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
662+ t .Run ("Build" , func (t * testing.T ) {
663+ // Build
664+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
665+ require .NoError (t , err )
666+ })
667+
668+ t .Run ("Preprocess" , func (t * testing.T ) {
669+ // Preprocess
670+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
671+ require .NoError (t , err )
672+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
673+ })
674+ }
675+
676+ func testBuilderSketchWithExternC (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
677+ t .Run ("Build" , func (t * testing.T ) {
678+ // Build
679+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
680+ require .NoError (t , err )
681+ })
682+
683+ t .Run ("Preprocess" , func (t * testing.T ) {
684+ // Preprocess
685+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
686+ require .NoError (t , err )
687+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
688+ })
689+ }
690+
691+ func testBuilderSketchWithMultilinePrototypes (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
692+ t .Run ("Build" , func (t * testing.T ) {
693+ // Build
694+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
695+ require .NoError (t , err )
696+ })
697+
698+ t .Run ("Preprocess" , func (t * testing.T ) {
699+ // Preprocess
700+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
701+ require .NoError (t , err )
702+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
703+ })
704+ }
705+
706+ func testBuilderSketchWithExternCMultiline (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
707+ t .Run ("Build" , func (t * testing.T ) {
708+ // Build
709+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
710+ require .NoError (t , err )
711+ })
712+
713+ t .Run ("Preprocess" , func (t * testing.T ) {
714+ // Preprocess
715+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
716+ require .NoError (t , err )
717+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
718+ })
719+ }
720+
721+ func testBuilderSketchWithMultilineTemplate (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
722+ t .Run ("Build" , func (t * testing.T ) {
723+ // Build
724+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
725+ require .NoError (t , err )
726+ })
727+
728+ t .Run ("Preprocess" , func (t * testing.T ) {
729+ // Preprocess
730+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
731+ require .NoError (t , err )
732+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
733+ })
734+ }
735+
736+ func testBuilderSketchWithFakeFunctionPointer (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
737+ t .Run ("Build" , func (t * testing.T ) {
738+ // Build
739+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
740+ require .NoError (t , err )
741+ })
742+
743+ t .Run ("Preprocess" , func (t * testing.T ) {
744+ // Preprocess
745+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
746+ require .NoError (t , err )
747+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
748+ })
749+ }
750+
751+ func testBuilderSketchWithMinMaxDefinitions (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
752+ t .Run ("Build" , func (t * testing.T ) {
753+ // Build
754+ _ , err := tryBuild (t , env , cli , "arduino:samd:arduino_zero_native" )
755+ require .NoError (t , err )
756+ })
757+
758+ t .Run ("Preprocess" , func (t * testing.T ) {
759+ // Preprocess
760+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:samd:arduino_zero_native" )
761+ require .NoError (t , err )
762+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
763+ })
764+ }
765+
766+ func testBuilderSketchWithFastledsLibrary (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
767+ t .Run ("Build" , func (t * testing.T ) {
768+ // Build
769+ _ , err := tryBuild (t , env , cli , "arduino:samd:arduino_zero_native" )
770+ require .NoError (t , err )
771+ })
772+
773+ t .Run ("Preprocess" , func (t * testing.T ) {
774+ // Preprocess
775+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:samd:arduino_zero_native" )
776+ require .NoError (t , err )
777+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
778+ })
779+ }
780+
781+ func testBuilderSketchClassFunction (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
782+ t .Run ("Build" , func (t * testing.T ) {
783+ // Build
784+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
785+ require .NoError (t , err )
786+ })
787+
788+ t .Run ("Preprocess" , func (t * testing.T ) {
789+ // Preprocess
790+ sketchPath , preprocessedSketch , err := tryPreprocess (t , env , cli , "arduino:avr:leonardo" )
791+ require .NoError (t , err )
792+ comparePreprocessGoldenFile (t , sketchPath , preprocessedSketch )
793+ })
794+ }
795+
796+ func testBuilderSketchThatChecksIfSPIHasTransactionsAndIncludesMissingEthernet (t * testing.T , env * integrationtest.Environment , cli * integrationtest.ArduinoCLI ) {
797+ t .Run ("Build" , func (t * testing.T ) {
798+ // Build
799+ _ , err := tryBuild (t , env , cli , "arduino:avr:leonardo" )
800+ require .Error (t , err )
801+ })
802+ }
803+
616804type builderOutput struct {
617805 CompilerOut string `json:"compiler_out"`
618806 CompilerErr string `json:"compiler_err"`
@@ -765,3 +953,88 @@ func TestCoreCaching(t *testing.T) {
765953 require .NoError (t , err )
766954 require .NotEqual (t , coreStatBefore .ModTime (), coreStatAfterTouch .ModTime ())
767955}
956+
957+ func TestMergeSketchWithBootloader (t * testing.T ) {
958+ env , cli := integrationtest .CreateArduinoCLIWithEnvironment (t )
959+ defer env .CleanUp ()
960+
961+ sketchPath , err := paths .New ("testdata" , "SketchWithMergedSketchAndBootloader" ).Abs ()
962+ require .NoError (t , err )
963+
964+ // Install Arduino AVR Boards
965+ _ , _ , err = cli .Run ("core" , "install" , "arduino:avr@1.8.6" )
966+ require .NoError (t , err )
967+
968+ buildPath , err := paths .MkTempDir ("" , "arduino-integration-test" )
969+ require .NoError (t , err )
970+ defer buildPath .RemoveAll ()
971+
972+ // Build first time
973+ _ , _ , err = cli .Run ("compile" , "-b" , "arduino:avr:uno" , "--build-path" , buildPath .String (), sketchPath .String ())
974+ require .NoError (t , err )
975+
976+ bytes , err := buildPath .Join ("SketchWithMergedSketchAndBootloader.ino.with_bootloader.hex" ).ReadFile ()
977+ require .NoError (t , err )
978+ mergedSketchHex := string (bytes )
979+
980+ require .Contains (t , mergedSketchHex , ":100000000C9434000C9446000C9446000C9446006A\n " )
981+ require .True (t , strings .HasSuffix (mergedSketchHex , ":00000001FF\n " ))
982+ }
983+
984+ func TestBuildOptionsFile (t * testing.T ) {
985+ env , cli := integrationtest .CreateArduinoCLIWithEnvironment (t )
986+ defer env .CleanUp ()
987+
988+ sketchPath := cli .CopySketch ("sketch_simple" )
989+ defer sketchPath .RemoveAll ()
990+
991+ _ , _ , err := cli .Run ("core" , "install" , "arduino:avr@1.8.6" )
992+ require .NoError (t , err )
993+
994+ buildPath , err := paths .MkTempDir ("" , "arduino-integration-test" )
995+ require .NoError (t , err )
996+ defer buildPath .RemoveAll ()
997+
998+ // Build first time
999+ _ , _ , err = cli .Run ("compile" , "-b" , "arduino:avr:uno" , "--build-path" , buildPath .String (), sketchPath .String ())
1000+ require .NoError (t , err )
1001+
1002+ exist , err := buildPath .Join ("build.options.json" ).ExistCheck ()
1003+ require .NoError (t , err )
1004+ require .True (t , exist )
1005+
1006+ buildOptionsBytes , err := buildPath .Join ("build.options.json" ).ReadFile ()
1007+ require .NoError (t , err )
1008+
1009+ requirejson .Query (t , buildOptionsBytes , "keys" , `[
1010+ "additionalFiles",
1011+ "builtInToolsFolders",
1012+ "compiler.optimization_flags",
1013+ "customBuildProperties",
1014+ "fqbn",
1015+ "hardwareFolders",
1016+ "otherLibrariesFolders",
1017+ "sketchLocation"
1018+ ]` )
1019+ requirejson .Query (t , buildOptionsBytes , ".fqbn" , `"arduino:avr:uno"` )
1020+ requirejson .Query (t , buildOptionsBytes , ".customBuildProperties" , `"build.warn_data_percentage=75"` )
1021+
1022+ // Recompiling a second time should provide the same result
1023+ _ , _ , err = cli .Run ("compile" , "-b" , "arduino:avr:uno" , "--build-path" , buildPath .String (), sketchPath .String ())
1024+ require .NoError (t , err )
1025+
1026+ buildOptionsBytes , err = buildPath .Join ("build.options.json" ).ReadFile ()
1027+ require .NoError (t , err )
1028+ requirejson .Query (t , buildOptionsBytes , ".customBuildProperties" , `"build.warn_data_percentage=75"` )
1029+
1030+ // Recompiling with a new build option must produce a new `build.options.json`
1031+ _ , _ , err = cli .Run ("compile" , "-b" , "arduino:avr:uno" , "--build-path" , buildPath .String (),
1032+ "--build-property" , "custom=prop" ,
1033+ sketchPath .String (),
1034+ )
1035+ require .NoError (t , err )
1036+
1037+ buildOptionsBytes , err = buildPath .Join ("build.options.json" ).ReadFile ()
1038+ require .NoError (t , err )
1039+ requirejson .Query (t , buildOptionsBytes , ".customBuildProperties" , `"custom=prop,build.warn_data_percentage=75"` )
1040+ }
0 commit comments