or via backtracking
Matt S Trout [Mon, 20 Jan 2014 13:47:48 +0000 (13:47 +0000)]
t/basic.t

index c65b4ad..5d62f1d 100644 (file)
--- a/t/basic.t
+++ b/t/basic.t
@@ -19,7 +19,7 @@ my @shells = qw(csh bash);
 
 my %shells = (
   bash => { map +($_ => 1),
-             qw(joe.example.com kitty.scsys.co.uk pryde.scsys.co.uk) },
+             qw(joe.example.com kitty.scsys.co.uk) },
   csh => { map +($_ => 1),
              qw(jim.example.com joe.example.com bob.example.com) },
 );
@@ -111,14 +111,16 @@ is_deeply(
   'Complex stream'
 );
 
-my $inner_op = make_op(FromCode->new(
+my $pop_stack = FromCode->new(
   code => sub {
     my ($self, $state) = @_;
     my @stack = @{$state->return_stack};
     my $top = pop @stack;
     $state->but(return_stack => \@stack, next_op => $top);
   }
-));
+);
+
+my $inner_op = make_op($pop_stack);
 
 my $call_op = FromCode->new(
   code => sub {
@@ -159,4 +161,91 @@ is_deeply(
   'Call stream'
 );
 
+my $has_csh = FromCode->new(
+  code => test_values([ 'S' ], sub { $shells{csh}{$_[0]} }),
+  next => $pop_stack
+);
+my $has_bash = FromCode->new(
+  code => test_values([ 'S' ], sub { $shells{bash}{$_[0]} }),
+  next => $pop_stack
+);
+
+my $or_code = sub {
+  my ($self, $state) = @_;
+  my $var = DX::Var->new(id => 'OR')->with_stream(
+    my $stream = ArrayStream->from_array($has_csh, $has_bash)
+  );
+  my $inner_or = FromCode->new(
+    code => sub { $_[1]->then($var->bound_value) }
+  );
+  $state->but(
+    return_stack => [ @{$state->return_stack}, $self->next ],
+    next_op => $inner_or
+  )->mark_choice($var);
+};
+
+my $top_or = FromCode->new(
+  code => bind_array(S => \@servers),
+  next => FromCode->new(code => $or_code),
+);
+
+my $orstream = DX::ResultStream->new(
+  for_state => make_state([ qw(S) ], $top_or)
+);
+
+is_deeply(
+  [ $orstream->results ],
+  [
+    {
+      S => "kitty.scsys.co.uk"
+    },
+    {
+      S => "jim.example.com"
+    },
+    {
+      S => "joe.example.com"
+    },
+    {
+      S => "joe.example.com"
+    },
+    {
+      S => "bob.example.com"
+    }
+  ],
+  'Or stream'
+);
+
+my $top_or_2 = FromCode->new(
+  code => bind_array(S => \@servers),
+  next => FromCode->new(
+    code => $or_code,
+    next => FromCode->new(
+      code => test_values([ 'S' ], sub { $_[0] =~ /\.example\.com$/ }),
+    ),
+  ),
+);
+
+my $orstream_2 = DX::ResultStream->new(
+  for_state => make_state([ qw(S) ], $top_or_2)
+);
+
+is_deeply(
+  [ $orstream_2->results ],
+  [
+    {
+      S => "jim.example.com"
+    },
+    {
+      S => "joe.example.com"
+    },
+    {
+      S => "joe.example.com"
+    },
+    {
+      S => "bob.example.com"
+    }
+  ],
+  'Or stream'
+);
+
 done_testing;