@@ -65,6 +65,11 @@ enum CommandKind {
6565 /// Checks the path doesn't exist.
6666 HasNotPath ,
6767
68+ /// `//@ !has <path> <value>`
69+ ///
70+ /// Checks the path exists, but doesn't have the given value.
71+ HasNotValue { value : String } ,
72+
6873 /// `//@ is <path> <value>`
6974 ///
7075 /// Check the path is the given value.
@@ -128,10 +133,11 @@ impl CommandKind {
128133 [ _path, value] => Self :: HasValue { value : value. clone ( ) } ,
129134 _ => panic ! ( "`//@ has` must have 2 or 3 arguments, but got {args:?}" ) ,
130135 } ,
131- ( "has" , true ) => {
132- assert_eq ! ( args. len( ) , 1 , "args={args:?}" ) ;
133- Self :: HasNotPath
134- }
136+ ( "has" , true ) => match args {
137+ [ _path] => Self :: HasNotPath ,
138+ [ _path, value] => Self :: HasNotValue { value : value. clone ( ) } ,
139+ _ => panic ! ( "`//@ !has` must have 2 or 3 arguments, but got {args:?}" ) ,
140+ } ,
135141
136142 ( _, false ) if KNOWN_DIRECTIVE_NAMES . contains ( & command_name) => {
137143 return None ;
@@ -223,6 +229,19 @@ fn check_command(command: &Command, cache: &mut Cache) -> Result<(), String> {
223229 return Err ( format ! ( "matched to {matches:?}, which didn't contain {want_value:?}" ) ) ;
224230 }
225231 }
232+ CommandKind :: HasNotValue { value } => {
233+ let wantnt_value = string_to_value ( value, cache) ;
234+ if matches. contains ( & wantnt_value. as_ref ( ) ) {
235+ return Err ( format ! (
236+ "matched to {matches:?}, which contains unwanted {wantnt_value:?}"
237+ ) ) ;
238+ } else if matches. is_empty ( ) {
239+ return Err ( format ! (
240+ "got no matches, but expected some matched (not containing {wantnt_value:?}"
241+ ) ) ;
242+ }
243+ }
244+
226245 CommandKind :: Is { value } => {
227246 let want_value = string_to_value ( value, cache) ;
228247 let matched = get_one ( & matches) ?;
0 commit comments