<commit_before>package com.jayway.android.robotium.core.impl;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.app.Instrumentation;
import android.util.Log;
import android.widget.TextView;

/**
 * This class contains various search methods. Examples are: searchForEditTextWithTimeout(),
 * searchForTextWithTimeout(), searchForButtonWithTimeout().
 * 
 * @author <NAME>, <EMAIL>
 * 
 */

public class Searcher {
	
	private final ViewFetcher viewFetcher;
	private final Scroller scroller;
	private final Instrumentation inst;
    private final Sleeper sleeper;
	private final int TIMEOUT = 5000;
	private final String LOG_TAG = "Robotium";
	
    /**
     * Constructs this object.
     *
     * @param viewFetcher the {@code ViewFetcher} instance.
     * @param scroller the {@code Scroller} instance.
     * @param inst the {@code Instrumentation} instance.
     * @param sleeper the {@code Sleeper} instance.
     */
    public Searcher(ViewFetcher viewFetcher, Scroller scroller, Instrumentation inst, Sleeper sleeper) {
        this.viewFetcher = viewFetcher;
        this.scroller = scroller;
        this.inst = inst;
        this.sleeper = sleeper;
    }


	/**
	 * Searches for a {@code View} with the given regex string and returns {@code true} if the
	 * searched {@code Button} is found a given number of times. Will automatically scroll when needed.
	 *
	 * @param viewClass what kind of {@code View} to search for, e.g. {@code Button.class} or {@code TextView.class}
	 * @param regex the text to search for. The parameter <strong>will</strong> be interpreted as a regular expression.
	 * @param expectedMinimumNumberOfMatches the minimum number of matches expected to be found. {@code 0} matches means that one or more
	 * matches are expected to be found
	 * @param scroll whether scrolling should be performed
	 * @return {@code true} if a {@code View} of the specified class with the given text is found a given number of
	 * times, and {@code false} if it is not found
	 *
	 */
	public boolean searchWithTimeoutFor(Class<? extends TextView> viewClass, String regex, int expectedMinimumNumberOfMatches, boolean scroll) {
		final long endTime = System.currentTimeMillis() + TIMEOUT;

		while (System.currentTimeMillis() < endTime) {
			sleeper.sleep();
			final boolean foundAnyMatchingView = searchFor(viewClass, regex, expectedMinimumNumberOfMatches, scroll);
			if (foundAnyMatchingView){
				return true;
			}
		}

		return false;
	}


	/**
	 * Searches for a {@code View} with the given regex string and returns {@code true} if the
	 * searched {@code View} is found a given number of times
	 *
	 * @param viewClass what kind of {@code View} to search for, e.g. {@code Button.class} or {@code TextView.class}
	 * @param regex the text to search for. The parameter <strong>will</strong> be interpreted as a regular expression.
	 * @param expectedMinimumNumberOfMatches the minimum number of matches expected to be found. {@code 0} matches means that one or more
	 * matches are expected to be found.
	 * @param scroll whether scrolling should be performed
	 * @return {@code true} if a view of the specified class with the given text is found a given number of times.
	 * {@code false} if it is not found.
	 *
	 */
	public <T extends TextView> boolean searchFor(Class<T> viewClass, String regex, int expectedMinimumNumberOfMatches, boolean scroll) {
		inst.waitForIdleSync();

		if(expectedMinimumNumberOfMatches == 0) {
			expectedMinimumNumberOfMatches = 1;
		}
		int matchesFound = 0;

		List<T> views = viewFetcher.getCurrentViews(viewClass);

		final Pattern pattern = Pattern.compile(regex);
		for(T view : views){
			final Matcher matcher = pattern.matcher(view.getText().toString());
			if (matcher.find()){
				matchesFound++;
			}
			if (matchesFound == expectedMinimumNumberOfMatches) {
				return true;
			}
		}

		if (scroll && scroller.scroll(Scroller.Direction.DOWN)) {
			sleeper.sleep();
			return searchFor(viewClass, regex, expectedMinimumNumberOfMatches, scroll);
		} else {
			if (matchesFound > 0) {
				Log.d(LOG_TAG, " There are only " + matchesFound + " matches of " + regex);
			}
			return false;
		}
	}


}<commit_msg>Searcher: Enable searching for text in a collection of pre-fetched Views, instead of only by Type.<commit_after>package com.jayway.android.robotium.core.impl;

import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.app.Instrumentation;
import android.util.Log;
import android.widget.TextView;

/**
 * This class contains various search methods. Examples are: searchForEditTextWithTimeout(),
 * searchForTextWithTimeout(), searchForButtonWithTimeout().
 * 
 * @author <NAME>, <EMAIL>
 * 
 */

public class Searcher {
	
	private final ViewFetcher viewFetcher;
	private final Scroller scroller;
	private final Instrumentation inst;
    private final Sleeper sleeper;
	private final int TIMEOUT = 5000;
	private final String LOG_TAG = "Robotium";
	
    /**
     * Constructs this object.
     *
     * @param viewFetcher the {@code ViewFetcher} instance.
     * @param scroller the {@code Scroller} instance.
     * @param inst the {@code Instrumentation} instance.
     * @param sleeper the {@code Sleeper} instance.
     */
    public Searcher(ViewFetcher viewFetcher, Scroller scroller, Instrumentation inst, Sleeper sleeper) {
        this.viewFetcher = viewFetcher;
        this.scroller = scroller;
        this.inst = inst;
        this.sleeper = sleeper;
    }


	/**
	 * Searches for a {@code View} with the given regex string and returns {@code true} if the
	 * searched {@code Button} is found a given number of times. Will automatically scroll when needed.
	 *
	 * @param viewClass what kind of {@code View} to search for, e.g. {@code Button.class} or {@code TextView.class}
	 * @param regex the text to search for. The parameter <strong>will</strong> be interpreted as a regular expression.
	 * @param expectedMinimumNumberOfMatches the minimum number of matches expected to be found. {@code 0} matches means that one or more
	 * matches are expected to be found
	 * @param scroll whether scrolling should be performed
	 * @return {@code true} if a {@code View} of the specified class with the given text is found a given number of
	 * times, and {@code false} if it is not found
	 *
	 */
	public boolean searchWithTimeoutFor(Class<? extends TextView> viewClass, String regex, int expectedMinimumNumberOfMatches, boolean scroll) {
		final long endTime = System.currentTimeMillis() + TIMEOUT;

		while (System.currentTimeMillis() < endTime) {
			sleeper.sleep();
			final boolean foundAnyMatchingView = searchFor(viewClass, regex, expectedMinimumNumberOfMatches, scroll);
			if (foundAnyMatchingView){
				return true;
			}
		}

		return false;
	}


    /**
     * Searches for a {@code View} with the given regex string and returns {@code true} if the
     * searched {@code View} is found a given number of times
     *
     * @param viewClass what kind of {@code View} to search for, e.g. {@code Button.class} or {@code TextView.class}
     * @param regex the text to search for. The parameter <strong>will</strong> be interpreted as a regular expression.
     * @param expectedMinimumNumberOfMatches the minimum number of matches expected to be found. {@code 0} matches means that one or more
     * matches are expected to be found.
     * @param scroll whether scrolling should be performed
     * @return {@code true} if a view of the specified class with the given text is found a given number of times.
     * {@code false} if it is not found.
     *
     */
    public <T extends TextView> boolean searchFor(Class<T> viewClass, String regex, int expectedMinimumNumberOfMatches, boolean scroll) {
        List<T> views = viewFetcher.getCurrentViews(viewClass);
        return searchFor(views, regex, expectedMinimumNumberOfMatches, scroll);
    }

	/**
	 * Searches for a {@code View} with the given regex string and returns {@code true} if the
	 * searched {@code View} is found a given number of times
	 *
	 * @param views which views to search
	 * @param regex the text to search for. The parameter <strong>will</strong> be interpreted as a regular expression.
	 * @param expectedMinimumNumberOfMatches the minimum number of matches expected to be found. {@code 0} matches means that one or more
	 * matches are expected to be found.
	 * @param scroll whether scrolling should be performed
	 * @return {@code true} if a view of the specified class with the given text is found a given number of times.
	 * {@code false} if it is not found.
	 *
	 */
	public <T extends TextView> boolean searchFor(Collection<T> views, String regex, int expectedMinimumNumberOfMatches, boolean scroll) {
		inst.waitForIdleSync();

		if(expectedMinimumNumberOfMatches == 0) {
			expectedMinimumNumberOfMatches = 1;
		}
		int matchesFound = 0;

		final Pattern pattern = Pattern.compile(regex);
		for(T view : views){
			final Matcher matcher = pattern.matcher(view.getText().toString());
			if (matcher.find()){
				matchesFound++;
			}
			if (matchesFound == expectedMinimumNumberOfMatches) {
				return true;
			}
		}

		if (scroll && scroller.scroll(Scroller.Direction.DOWN)) {
			sleeper.sleep();
			return searchFor(views, regex, expectedMinimumNumberOfMatches, scroll);
		} else {
			if (matchesFound > 0) {
				Log.d(LOG_TAG, " There are only " + matchesFound + " matches of " + regex);
			}
			return false;
		}
	}


}
{'fraction_non_alphanumeric': 0.09222689075630253, 'fraction_numerical': 0.0022058823529411764, 'mean_word_length': 3.774824473420261, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6544222', 'n_tokens_mistral': 2866, 'n_tokens_neox': 2632, 'n_words': 1031}