@@ -207,3 +207,84 @@ def test_raises_parser_error_on_file_that_contains_errors_in_strict_mode():
207207
208208def test_parser_error_str ():
209209 assert str (fluent .ParserError ) == "<class 'rustfluent.ParserError'>"
210+
211+
212+ # Attribute access tests
213+
214+
215+ def test_basic_attribute_access ():
216+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
217+ assert bundle .get_translation ("welcome-message.title" ) == "Welcome to our site"
218+
219+
220+ def test_regular_message_still_works_with_attributes ():
221+ """Test that accessing the main message value still works when it has attributes."""
222+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
223+ assert bundle .get_translation ("welcome-message" ) == "Welcome!"
224+
225+
226+ def test_multiple_attributes_on_same_message ():
227+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
228+ assert bundle .
get_translation (
"login-input.placeholder" )
== "[email protected] " 229+ assert bundle .get_translation ("login-input.aria-label" ) == "Login input value"
230+ assert bundle .get_translation ("login-input.title" ) == "Type your login email"
231+
232+
233+ def test_attribute_with_variables ():
234+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
235+ result = bundle .get_translation ("greeting.formal" , variables = {"name" : "Alice" })
236+ assert result == f"Hello, { BIDI_OPEN } Alice{ BIDI_CLOSE } "
237+
238+
239+ def test_attribute_with_variables_use_isolating_off ():
240+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
241+ result = bundle .get_translation (
242+ "greeting.informal" ,
243+ variables = {"name" : "Bob" },
244+ use_isolating = False ,
245+ )
246+ assert result == "Hi Bob!"
247+
248+
249+ def test_attribute_on_message_without_main_value ():
250+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
251+ assert bundle .get_translation ("form-button.submit" ) == "Submit Form"
252+ assert bundle .get_translation ("form-button.cancel" ) == "Cancel"
253+ assert bundle .get_translation ("form-button.reset" ) == "Reset Form"
254+
255+
256+ def test_message_without_value_raises_error ():
257+ """Test that accessing a message without a value (only attributes) raises an error."""
258+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
259+ with pytest .raises (ValueError , match = "form-button - Message has no value" ):
260+ bundle .get_translation ("form-button" )
261+
262+
263+ def test_missing_message_with_attribute_syntax_raises_error ():
264+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
265+ with pytest .raises (ValueError , match = "nonexistent not found" ):
266+ bundle .get_translation ("nonexistent.title" )
267+
268+
269+ def test_missing_attribute_raises_error ():
270+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
271+ with pytest .raises (
272+ ValueError ,
273+ match = "welcome-message.nonexistent - Attribute 'nonexistent' not found on message 'welcome-message'" ,
274+ ):
275+ bundle .get_translation ("welcome-message.nonexistent" )
276+
277+
278+ @pytest .mark .parametrize (
279+ "identifier,expected" ,
280+ (
281+ ("welcome-message" , "Welcome!" ),
282+ ("welcome-message.title" , "Welcome to our site" ),
283+ ("welcome-message.aria-label" , "Welcome greeting" ),
284+ ("login-input" , "Email" ),
285+ ("login-input.placeholder" , "[email protected] " ), 286+ ),
287+ )
288+ def test_attribute_and_message_access_parameterized (identifier , expected ):
289+ bundle = fluent .Bundle ("en" , [data_dir / "attributes.ftl" ])
290+ assert bundle .get_translation (identifier ) == expected
0 commit comments