use DX::Solver;
use DX::SetOver;
use DX::Observer::FromCode;
+use DX::Action::FromCode;
use Test::Exception;
{
use Moo;
has path => (is => 'ro', required => 1);
- has info => (is => 'ro', required => 1);
+ has info => (is => 'ro');
package My::PathStatusInfo;
),
);
+my %empty = (
+ '.ssh' => My::PathStatus->new(
+ path => '.ssh'
+ )
+);
+
my %path_status;
my $solver = DX::Solver->new(
[ constrain => [ qw(PS P) ], sub { $_[0]->path eq $_[1] } ] ],
[ mode => [ qw(PS M) ],
[ constrain => [ qw(PS M) ],
- sub { $_[0]->info and $_[0]->info->mode eq $_[1] } ] ],
+ sub { $_[0]->info and $_[0]->info->mode eq $_[1] } ] ],
+ [ exists_path => [ qw(PS) ],
+ [ constrain => [ qw(PS) ],
+ sub {
+ $_[0]->info and ($_[0]->info->is_directory or $_[0]->info->is_file)
+ } ] ],
[ is_directory => [ qw(PS) ],
[ constrain => [ qw(PS) ],
sub { $_[0]->info and $_[0]->info->is_directory } ] ],
%path_status = %protos;
sub paths_for_simple {
- join ' ', map $_->{PS}->path, $solver->query(
+ join ' ', map $_->{PS}->bound_value->path, $solver->query(
[ qw(PS) ], [ path_status => 'PS' ], @_
)->results;
}
)->results
};
-is(join(' ', map $_->{PS}->path, @res), '.ssh');
+is(join(' ', map $_->{PS}->bound_value->path, @res), '.ssh');
delete $solver->rule_set->rules->{'path_status_at/2'};
[ path => qw(PS P) ],
);
-%path_status = ('.ssh/authorized_keys' => $protos{'.ssh/authorized_keys'});
+%path_status = ();
$ob_res{'.ssh'} = $protos{'.ssh'};
sub paths_for {
- join ' ', map $_->{PS}->path, $solver->query([ 'PS' ], @_)->results;
+ join ' ', map $_->{PS}->bound_value->path, $solver->query([ 'PS' ], @_)->results;
}
is(
lives_ok { paths_for([ path_status_at => 'PS', [ value => '.ssh' ] ]) }
'No observation required anymore';
+$path_status{'.ssh/authorized_keys'} = $protos{'.ssh/authorized_keys'};
+
+is(
+ paths_for([ path_status => 'PS' ], [ not => [ is_directory => 'PS' ] ]),
+ '.ssh/authorized_keys',
+ 'Negation'
+);
+
+$solver->add_rule(@$_) for (
+ [ directory_at => [ qw(PS P) ],
+ [ path_status_at => qw(PS P) ],
+ [ is_directory => 'PS' ] ],
+);
+
+%path_status = ();
+
+$ob_res{'.ssh'} = $empty{'.ssh'};
+
+#%path_status = %protos;
+
+$solver->{observation_policy} = sub { 1 };
+
+sub dot_ssh_query {
+ $solver->query([ 'PS' ], [ directory_at => 'PS' => [ value => '.ssh' ] ]);
+}
+
+is_deeply(
+ [ dot_ssh_query()->results ],
+ []
+);
+
+#::Dwarn(paths_for([ directory_at => 'PS', [ value => '.ssh' ] ]));
+
+$solver->add_rule(@$_) for (
+ [ is_directory => [ qw(PS) ],
+ [ not => [ exists_path => 'PS' ] ],
+ [ act => [ 'PS' ],
+ sub {
+ my ($ps_var) = @_;
+ my ($id, $value) = ($ps_var->id, $ps_var->bound_value);
+ DX::Action::FromCode->new(
+ expect => sub {
+ ($id => My::PathStatus->new(
+ path => $value->path,
+ info => My::PathStatusInfo->new(
+ is_directory => 1, mode => ''
+ )
+ ))
+ },
+ perform => sub {
+ $ob_res{$value->path} = $protos{$value->path};
+ (path_status => $value);
+ }
+ )
+ } ] ]
+);
+
+%path_status = ();
+
+@res = dot_ssh_query()->results;
+
+is(scalar(@res),1,'Single result');
+
+is($path_status{'.ssh'}, $empty{'.ssh'}, 'Empty observed');
+
+ok(my $action = $res[0]->{PS}->action);
+
+my ($type, $value) = $action->run;
+
+$solver->facts->{$type}->remove_value($value);
+
+ok(!$path_status{'.ssh'}, 'Empty retracted');
+
+@res = dot_ssh_query()->results;
+
+is(scalar(@res),1,'Single result');
+
+is($path_status{'.ssh'}, $protos{'.ssh'}, 'Created observed');
+
+ok(!$res[0]->{PS}->action, 'No action');
+
done_testing;