@@ -9,7 +9,7 @@ use std::io::{Read, Seek};
99use std:: path:: { Path , PathBuf } ;
1010use std:: time:: Duration ;
1111use tmc_langs_framework:: {
12- nom:: { branch, bytes, character, combinator, error:: VerboseError , sequence, IResult } ,
12+ nom:: { branch, bytes, character, combinator, error:: VerboseError , multi , sequence, IResult } ,
1313 LanguagePlugin , TmcCommand , TmcError , { ExerciseDesc , RunResult , TestDesc } ,
1414} ;
1515use tmc_langs_util:: file_util;
@@ -142,46 +142,73 @@ impl LanguagePlugin for RPlugin {
142142 vec ! [ PathBuf :: from( "tests" ) ]
143143 }
144144
145- fn points_parser ( i : & str ) -> IResult < & str , & str , VerboseError < & str > > {
146- let test_parser = sequence:: delimited (
145+ fn points_parser ( i : & str ) -> IResult < & str , Vec < & str > , VerboseError < & str > > {
146+ let mut test_parser = sequence:: preceded (
147147 sequence:: tuple ( (
148148 bytes:: complete:: tag ( "test" ) ,
149149 character:: complete:: multispace0,
150150 character:: complete:: char ( '(' ) ,
151- bytes:: complete:: take_until ( "," ) ,
152- bytes:: complete:: take_until ( "\" " ) ,
153- ) ) ,
154- sequence:: delimited (
155- character:: complete:: char ( '"' ) ,
156- bytes:: complete:: is_not ( "\" " ) ,
157- character:: complete:: char ( '"' ) ,
158- ) ,
159- sequence:: tuple ( (
160151 character:: complete:: multispace0,
161- character :: complete :: char ( ')' ) ,
152+ arg_parser ,
162153 ) ) ,
154+ c_parser,
163155 ) ;
164- let points_for_all_tests_parser = sequence:: delimited (
156+ let points_for_all_tests_parser = sequence:: preceded (
165157 sequence:: tuple ( (
166158 bytes:: complete:: tag ( "points_for_all_tests" ) ,
167159 character:: complete:: multispace0,
168160 character:: complete:: char ( '(' ) ,
169- bytes:: complete:: take_until ( "\" " ) ,
170- ) ) ,
171- sequence:: delimited (
172- character:: complete:: char ( '"' ) ,
173- bytes:: complete:: is_not ( "\" " ) ,
174- character:: complete:: char ( '"' ) ,
175- ) ,
176- sequence:: tuple ( (
177161 character:: complete:: multispace0,
178- character:: complete:: char ( ')' ) ,
179162 ) ) ,
163+ c_parser,
180164 ) ;
181- combinator:: map (
182- branch:: alt ( ( test_parser, points_for_all_tests_parser) ) ,
183- str:: trim,
184- ) ( i)
165+
166+ // todo: currently cannot handle function calls with multiple parameters, probably not a problem
167+ fn arg_parser ( i : & str ) -> IResult < & str , & str , VerboseError < & str > > {
168+ combinator:: value (
169+ "" ,
170+ sequence:: tuple ( (
171+ bytes:: complete:: take_till ( |c : char | c == ',' ) ,
172+ character:: complete:: char ( ',' ) ,
173+ character:: complete:: multispace0,
174+ ) ) ,
175+ ) ( i)
176+ }
177+
178+ fn c_parser ( i : & str ) -> IResult < & str , Vec < & str > , VerboseError < & str > > {
179+ combinator:: map (
180+ sequence:: tuple ( (
181+ character:: complete:: char ( 'c' ) ,
182+ character:: complete:: multispace0,
183+ character:: complete:: char ( '(' ) ,
184+ character:: complete:: multispace0,
185+ multi:: separated_list1 (
186+ sequence:: tuple ( (
187+ character:: complete:: multispace0,
188+ character:: complete:: char ( ',' ) ,
189+ character:: complete:: multispace0,
190+ ) ) ,
191+ string_parser,
192+ ) ,
193+ character:: complete:: multispace0,
194+ character:: complete:: char ( ')' ) ,
195+ ) ) ,
196+ |t| t. 4 ,
197+ ) ( i)
198+ }
199+
200+ fn string_parser ( i : & str ) -> IResult < & str , & str , VerboseError < & str > > {
201+ combinator:: map (
202+ sequence:: tuple ( (
203+ character:: complete:: char ( '"' ) ,
204+ bytes:: complete:: is_not ( "\" " ) ,
205+ character:: complete:: char ( '"' ) ,
206+ ) ) ,
207+ |r| str:: trim ( r. 1 ) ,
208+ ) ( i)
209+ }
210+
211+ branch:: alt ( ( test_parser, points_for_all_tests_parser) ) ( i)
185212 }
186213}
187214
@@ -466,14 +493,14 @@ test("sample", c("r1.1"), {
466493 expect_true(areEqual(res, res_correct))
467494})
468495"# ;
469- assert_eq ! ( RPlugin :: points_parser( target) . unwrap( ) . 1 , "W1A.1.2" ) ;
496+ assert_eq ! ( RPlugin :: points_parser( target) . unwrap( ) . 1 [ 0 ] , "W1A.1.2" ) ;
470497
471498 let target = r#"test ( "1d and 1e are solved correctly", c ( " W1A.1.2 " ) , {
472499 expect_equivalent(z, z_correct, tolerance=1e-5)
473500 expect_true(areEqual(res, res_correct))
474501})
475502"# ;
476- assert_eq ! ( RPlugin :: points_parser( target) . unwrap( ) . 1 , "W1A.1.2" ) ;
503+ assert_eq ! ( RPlugin :: points_parser( target) . unwrap( ) . 1 [ 0 ] , "W1A.1.2" ) ;
477504 }
478505
479506 #[ test]
510537 let points = RPlugin :: get_available_points ( temp. path ( ) ) . unwrap ( ) ;
511538 assert_eq ! ( points, & [ "r1" ] ) ;
512539 }
540+
541+ #[ test]
542+ fn parses_multiple_points ( ) {
543+ init ( ) ;
544+
545+ let temp = tempfile:: tempdir ( ) . unwrap ( ) ;
546+ file_to (
547+ & temp,
548+ "tests/testthat/testExercise.R" ,
549+ r#"
550+ something
551+ test("some test", c("r1", "r2", "r3"))
552+ etc
553+ "# ,
554+ ) ;
555+
556+ let points = RPlugin :: get_available_points ( temp. path ( ) ) . unwrap ( ) ;
557+ assert_eq ! ( points, & [ "r1" , "r2" , "r3" ] ) ;
558+ }
513559}
0 commit comments