@@ -45,6 +45,231 @@ public function testCustomCurrencyCodesOverride()
4545 self ::assertValidationRuleFailed ($ rule , 'EUR ' );
4646 }
4747
48+ /**
49+ * Test constructor with includeDefaultCurrencyCodes parameter.
50+ *
51+ * @since 1.1.0
52+ */
53+ public function testConstructorWithIncludeDefaultCurrencyCodes ()
54+ {
55+ // Test with custom codes and includeDefaultCurrencyCodes = true
56+ $ customCodes = ['XYZ ' , 'ABC ' , 'DEF ' ];
57+ $ rule = new Currency ($ customCodes , true );
58+
59+ // Custom codes should pass
60+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
61+ self ::assertValidationRulePassed ($ rule , 'ABC ' );
62+ self ::assertValidationRulePassed ($ rule , 'def ' ); // case insensitive
63+
64+ // Standard codes should also pass when including defaults
65+ self ::assertValidationRulePassed ($ rule , 'USD ' );
66+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
67+ self ::assertValidationRulePassed ($ rule , 'JPY ' );
68+
69+ // Invalid codes should still fail
70+ self ::assertValidationRuleFailed ($ rule , 'INVALID ' );
71+ self ::assertValidationRuleFailed ($ rule , 'ZZZ ' );
72+ }
73+
74+ /**
75+ * Test constructor with includeDefaultCurrencyCodes = false (explicit).
76+ *
77+ * @since 1.1.0
78+ */
79+ public function testConstructorWithIncludeDefaultCurrencyCodesFalse ()
80+ {
81+ // Test with custom codes and includeDefaultCurrencyCodes = false (explicit)
82+ $ customCodes = ['XYZ ' , 'ABC ' , 'DEF ' ];
83+ $ rule = new Currency ($ customCodes , false );
84+
85+ // Custom codes should pass
86+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
87+ self ::assertValidationRulePassed ($ rule , 'ABC ' );
88+ self ::assertValidationRulePassed ($ rule , 'def ' ); // case insensitive
89+
90+ // Standard codes should fail when not including defaults
91+ self ::assertValidationRuleFailed ($ rule , 'USD ' );
92+ self ::assertValidationRuleFailed ($ rule , 'EUR ' );
93+ self ::assertValidationRuleFailed ($ rule , 'JPY ' );
94+ }
95+
96+ /**
97+ * Test constructor with empty custom codes and includeDefaultCurrencyCodes = true.
98+ *
99+ * @since 1.1.0
100+ */
101+ public function testConstructorWithEmptyCustomCodesAndIncludeDefaults ()
102+ {
103+ // Test with empty custom codes and includeDefaultCurrencyCodes = true
104+ $ rule = new Currency ([], true );
105+
106+ // Should behave like default constructor (only default codes)
107+ self ::assertValidationRulePassed ($ rule , 'USD ' );
108+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
109+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
110+ }
111+
112+ /**
113+ * Test constructor with null custom codes and includeDefaultCurrencyCodes = true.
114+ *
115+ * @since 1.1.0
116+ */
117+ public function testConstructorWithNullCustomCodesAndIncludeDefaults ()
118+ {
119+ // Test with null custom codes and includeDefaultCurrencyCodes = true
120+ $ rule = new Currency (null , true );
121+
122+ // Should behave like default constructor (only default codes)
123+ self ::assertValidationRulePassed ($ rule , 'USD ' );
124+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
125+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
126+ }
127+
128+ /**
129+ * Test fromString method with basic functionality.
130+ *
131+ * @since 1.1.0
132+ */
133+ public function testFromStringBasic ()
134+ {
135+ // Test empty string returns default rule
136+ $ rule = Currency::fromString ('' );
137+ self ::assertValidationRulePassed ($ rule , 'USD ' );
138+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
139+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
140+
141+ // Test null returns default rule
142+ $ rule = Currency::fromString (null );
143+ self ::assertValidationRulePassed ($ rule , 'USD ' );
144+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
145+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
146+
147+ // Test whitespace only returns default rule
148+ $ rule = Currency::fromString (' ' );
149+ self ::assertValidationRulePassed ($ rule , 'USD ' );
150+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
151+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
152+ }
153+
154+ /**
155+ * Test fromString method with custom currency codes only.
156+ *
157+ * @since 1.1.0
158+ */
159+ public function testFromStringCustomCodesOnly ()
160+ {
161+ // Test custom codes without include_defaults
162+ $ rule = Currency::fromString ('XYZ,ABC,DEF ' );
163+
164+ // Custom codes should pass
165+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
166+ self ::assertValidationRulePassed ($ rule , 'ABC ' );
167+ self ::assertValidationRulePassed ($ rule , 'DEF ' );
168+ self ::assertValidationRulePassed ($ rule , 'def ' ); // case insensitive
169+
170+ // Standard codes should fail
171+ self ::assertValidationRuleFailed ($ rule , 'USD ' );
172+ self ::assertValidationRuleFailed ($ rule , 'EUR ' );
173+ }
174+
175+ /**
176+ * Test fromString method with custom currency codes and include_defaults.
177+ *
178+ * @since 1.1.0
179+ */
180+ public function testFromStringWithIncludeDefaults ()
181+ {
182+ // Test custom codes with include_defaults
183+ $ rule = Currency::fromString ('XYZ,ABC,DEF|include_defaults ' );
184+
185+ // Custom codes should pass
186+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
187+ self ::assertValidationRulePassed ($ rule , 'ABC ' );
188+ self ::assertValidationRulePassed ($ rule , 'DEF ' );
189+ self ::assertValidationRulePassed ($ rule , 'def ' ); // case insensitive
190+
191+ // Standard codes should also pass
192+ self ::assertValidationRulePassed ($ rule , 'USD ' );
193+ self ::assertValidationRulePassed ($ rule , 'EUR ' );
194+ self ::assertValidationRulePassed ($ rule , 'JPY ' );
195+
196+ // Invalid codes should still fail
197+ self ::assertValidationRuleFailed ($ rule , 'INVALID ' );
198+ self ::assertValidationRuleFailed ($ rule , 'ZZZ ' );
199+ }
200+
201+ /**
202+ * Test fromString method with various include_defaults formats.
203+ *
204+ * @since 1.1.0
205+ */
206+ public function testFromStringIncludeDefaultsFormats ()
207+ {
208+ // Test different case variations of include_defaults
209+ $ variations = [
210+ 'XYZ,ABC|include_defaults ' ,
211+ 'XYZ,ABC|INCLUDE_DEFAULTS ' ,
212+ 'XYZ,ABC|Include_Defaults ' ,
213+ 'XYZ,ABC| include_defaults ' , // with spaces
214+ 'XYZ,ABC| INCLUDE_DEFAULTS ' , // with more spaces
215+ ];
216+
217+ foreach ($ variations as $ variation ) {
218+ $ rule = Currency::fromString ($ variation );
219+
220+ // Should include both custom and default codes
221+ self ::assertValidationRulePassed ($ rule , 'XYZ ' , "Failed for variation: $ variation " );
222+ self ::assertValidationRulePassed ($ rule , 'USD ' , "Failed for variation: $ variation " );
223+ }
224+ }
225+
226+ /**
227+ * Test fromString method with invalid include_defaults format.
228+ *
229+ * @since 1.1.0
230+ */
231+ public function testFromStringInvalidIncludeDefaultsFormat ()
232+ {
233+ // Test invalid include_defaults format (should be treated as custom codes only)
234+ $ rule = Currency::fromString ('XYZ,ABC|invalid_flag ' );
235+
236+ // Custom codes should pass
237+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
238+ self ::assertValidationRulePassed ($ rule , 'ABC ' );
239+
240+ // Standard codes should fail (include_defaults not properly specified)
241+ self ::assertValidationRuleFailed ($ rule , 'USD ' );
242+ self ::assertValidationRuleFailed ($ rule , 'EUR ' );
243+ }
244+
245+ /**
246+ * Test fromString method edge cases.
247+ *
248+ * @since 1.1.0
249+ */
250+ public function testFromStringEdgeCases ()
251+ {
252+ // Test single currency code
253+ $ rule = Currency::fromString ('XYZ ' );
254+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
255+ self ::assertValidationRuleFailed ($ rule , 'USD ' );
256+
257+ // Test single currency code with include_defaults
258+ $ rule = Currency::fromString ('XYZ|include_defaults ' );
259+ self ::assertValidationRulePassed ($ rule , 'XYZ ' );
260+ self ::assertValidationRulePassed ($ rule , 'USD ' );
261+
262+ // Test empty custom codes with include_defaults
263+ $ rule = Currency::fromString ('|include_defaults ' );
264+ self ::assertValidationRulePassed ($ rule , 'USD ' );
265+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
266+
267+ // Test only pipe with include_defaults
268+ $ rule = Currency::fromString ('|include_defaults ' );
269+ self ::assertValidationRulePassed ($ rule , 'USD ' );
270+ self ::assertValidationRuleFailed ($ rule , 'XYZ ' );
271+ }
272+
48273 /**
49274 * Test that obsolete currency codes no longer pass validation.
50275 *
0 commit comments