1   package com.atlassian.pageobjects.elements.mock;
2   
3   import com.atlassian.pageobjects.elements.query.AbstractTimedCondition;
4   import com.atlassian.pageobjects.elements.query.TimedCondition;
5   import com.atlassian.pageobjects.elements.query.util.Clock;
6   
7   import java.util.ArrayList;
8   import java.util.Arrays;
9   import java.util.List;
10  import java.util.concurrent.ConcurrentLinkedQueue;
11  import java.util.concurrent.atomic.AtomicInteger;
12  
13  /**
14   * Mock implementation of {@link com.atlassian.pageobjects.elements.query.TimedCondition}.
15   *
16   */
17  public class MockCondition extends AbstractTimedCondition implements TimedCondition
18  {
19      public static TimedCondition TRUE = new MockCondition(true);
20      public static TimedCondition FALSE = new MockCondition(false);
21  
22      public static MockCondition successAfter(int falseCount)
23      {
24          boolean[] results = new boolean[falseCount + 1];
25          Arrays.fill(results, false);
26          results[results.length-1] = true;
27          return new MockCondition(results);
28      }
29  
30      public static final int DEFAULT_INTERVAL = 50;
31      public static final long DEFAULT_TIMEOUT = 500;
32  
33      private final boolean[] results;
34      private final AtomicInteger count = new AtomicInteger();
35      private final AtomicInteger callCount = new AtomicInteger();
36      private volatile boolean limitReached = false;
37      private final ConcurrentLinkedQueue<Long> times = new ConcurrentLinkedQueue<Long>();
38  
39      public MockCondition(Clock clock, long interval, boolean... results)
40      {
41          super(clock, DEFAULT_TIMEOUT, interval);
42          this.results = results;
43      }
44  
45      public MockCondition(long interval, boolean... results)
46      {
47          super(DEFAULT_TIMEOUT, interval);
48          this.results = results;
49      }
50  
51      public MockCondition(boolean... results)
52      {
53          this(DEFAULT_INTERVAL, results);
54      }
55  
56      public MockCondition withClock(Clock clock)
57      {
58          return new MockCondition(clock, interval, results);
59      }
60  
61      public Boolean currentValue()
62      {
63          callCount.incrementAndGet();
64          if (limitReached)
65          {
66              return last();
67          }
68          else
69          {
70              return next();
71          }
72      }
73  
74      private boolean last()
75      {
76          boolean answer = results[results.length-1];
77          times.add(System.currentTimeMillis());
78          return answer;
79      }
80  
81      private boolean next()
82      {
83          int current = count.getAndIncrement();
84          if (current >= results.length -1)
85          {
86              limitReached = true;
87          }
88          if (current > results.length -1)
89          {
90              return last();
91          }
92          boolean answer = results[current];
93          times.add(System.currentTimeMillis());
94          return answer;
95      }
96  
97      public int callCount()
98      {
99          return callCount.get();
100     }
101 
102     public List<Long> times()
103     {
104         return new ArrayList<Long>(times);
105     }
106 
107     @Override
108     public String toString()
109     {
110         return "Mock Condition";
111     }
112 }