text:
package com.mopub.mraid;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Environment;
import android.provider.CalendarContract;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;

import com.mopub.common.test.support.SdkTestRunner;
import com.mopub.mobileads.test.support.FileUtils;
import com.mopub.mobileads.test.support.TestHttpResponseWithHeaders;
import com.mopub.mobileads.test.support.ThreadUtils;
import com.mopub.mraid.MraidNativeCommandHandler.MraidCommandFailureListener;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlertDialog;
import org.robolectric.shadows.ShadowEnvironment;
import org.robolectric.shadows.ShadowLog;
import org.robolectric.shadows.ShadowToast;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static android.content.DialogInterface.BUTTON_NEGATIVE;
import static android.content.DialogInterface.BUTTON_POSITIVE;
import static com.mopub.mraid.MraidNativeCommandHandler.ANDROID_CALENDAR_CONTENT_TYPE;
import static java.io.File.separator;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.stub;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Robolectric.shadowOf;

@RunWith(SdkTestRunner.class)
public class MraidNativeCommandHandlerTest {
    private static final String IMAGE_URI_VALUE = "file://tmp/expectedFile.jpg";
    private static final int TIME_TO_PAUSE_FOR_NETWORK = 300;
    private static final String FAKE_IMAGE_DATA = "imageFileData";
    //XXX: Robolectric or JUNIT doesn't support the correct suffix ZZZZZ in the parse pattern, so replacing xx:xx with xxxx for time.
    private static final String CALENDAR_START_TIME = "2013-08-14T20:00:00-0000";

    @Mock MraidCommandFailureListener mraidCommandFailureListener;
    private MraidNativeCommandHandler subject;
    private Context context;
    private Map<String, String> params;

    private File expectedFile;
    private File pictureDirectory;
    private File fileWithoutExtension;
    private TestHttpResponseWithHeaders response;

    @Before
    public void setUp() throws Exception {
        subject = new MraidNativeCommandHandler();
        context = Robolectric.buildActivity(Activity.class).create().get();

        FileUtils.copyFile("etc/expectedFile.jpg", "/tmp/expectedFile.jpg");
        expectedFile = new File(Environment.getExternalStorageDirectory(), "Pictures" + separator + "expectedFile.jpg");
        pictureDirectory = new File(Environment.getExternalStorageDirectory(), "Pictures");
        fileWithoutExtension = new File(pictureDirectory, "file");
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_withActivityContext_shouldDisplayAlertDialog() throws Exception {
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);

        subject.storePicture(context, IMAGE_URI_VALUE, mraidCommandFailureListener);

        AlertDialog alertDialog = ShadowAlertDialog.getLatestAlertDialog();
        ShadowAlertDialog shadowAlertDialog = shadowOf(alertDialog);

        assertThat(alertDialog.isShowing());

        assertThat(shadowAlertDialog.getTitle()).isEqualTo("Save Image");
        assertThat(shadowAlertDialog.getMessage()).isEqualTo("Download image to Picture gallery?");
        assertThat(shadowAlertDialog.isCancelable()).isTrue();

        assertThat(alertDialog.getButton(BUTTON_POSITIVE).hasOnClickListeners());
        assertThat(alertDialog.getButton(BUTTON_NEGATIVE)).isNotNull();
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_whenOkayClicked_shouldDownloadImage() throws Exception {
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);
        Robolectric.addPendingHttpResponse(response);

        subject.storePicture(context, IMAGE_URI_VALUE, mraidCommandFailureListener);

        ShadowAlertDialog.getLatestAlertDialog().getButton(BUTTON_POSITIVE).performClick();
        ThreadUtils.pause(TIME_TO_PAUSE_FOR_NETWORK);

        assertThat(expectedFile.exists()).isTrue();
        assertThat(expectedFile.length()).isEqualTo(FAKE_IMAGE_DATA.length());
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_whenCancelClicked_shouldDismissDialog() throws Exception {
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);

        subject.storePicture(context, IMAGE_URI_VALUE, mraidCommandFailureListener);

        AlertDialog alertDialog = ShadowAlertDialog.getLatestAlertDialog();
        ShadowAlertDialog shadowAlertDialog = shadowOf(alertDialog);

        alertDialog.getButton(BUTTON_NEGATIVE).performClick();
        assertThat(shadowAlertDialog.hasBeenDismissed()).isTrue();

        assertThat(expectedFile.exists()).isFalse();
        assertThat(expectedFile.length()).isEqualTo(0);
    }

    @Ignore("MRAID 2.0")
    @Test
    public void showUserDownloadImageAlert_withAppContext_shouldToastAndDownloadImage() throws Exception {
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);
        Robolectric.addPendingHttpResponse(response);

        assertThat(ShadowToast.shownToastCount()).isEqualTo(0);

        subject.storePicture(context.getApplicationContext(), IMAGE_URI_VALUE, mraidCommandFailureListener);
        ThreadUtils.pause(TIME_TO_PAUSE_FOR_NETWORK);

        assertThat(ShadowToast.shownToastCount()).isEqualTo(1);
        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo("Downloading image to Picture gallery...");

        Robolectric.runUiThreadTasks();

        assertThat(expectedFile.exists()).isTrue();
        assertThat(expectedFile.length()).isEqualTo(FAKE_IMAGE_DATA.length());
    }

    @Ignore("MRAID 2.0")
    @Test
    public void showUserDownloadImageAlert_withAppContext_whenDownloadImageFails_shouldDisplayFailureToastAndNotDownloadImage() throws Exception {
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);
        Robolectric.addPendingHttpResponse(response);

        assertThat(ShadowToast.shownToastCount()).isEqualTo(0);

        subject.storePicture(context, "this is an invalid image url and cannot be downloaded", mraidCommandFailureListener);
        ThreadUtils.pause(TIME_TO_PAUSE_FOR_NETWORK);

        assertThat(ShadowToast.shownToastCount()).isEqualTo(1);
        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo("Downloading image to Picture gallery...");

        Robolectric.runUiThreadTasks();

        assertThat(ShadowToast.shownToastCount()).isEqualTo(2);
        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo("Image failed to download.");

        assertThat(expectedFile.exists()).isFalse();
        assertThat(expectedFile.length()).isEqualTo(0);
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_whenStorePictureNotSupported_shouldFireErrorEvent_andNotToastNorAlertDialog() throws Exception {
        Robolectric.getShadowApplication().denyPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE);

        subject.storePicture(context, "http://image.jpg", mraidCommandFailureListener);

        assertThat(ShadowToast.shownToastCount()).isEqualTo(0);
        assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNull();
        verify(mraidCommandFailureListener).onFailure(any(MraidCommandException.class));
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_withMimeTypeAndNoFileExtension_shouldSavePictureWithMimeType() throws Exception {
        String fileNameWithNoExtension = "https://www.somewhere.com/images/blah/file";

        assertThatMimeTypeWasAddedCorrectly(
                fileNameWithNoExtension,
                "image/jpg",
                "file.jpg",
                ".jpg");
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_withMultipleContentTypesAndNoFileExtension_shouldSavePictureWithMimeType() throws Exception {
        String fileNameWithNoExtension = "https://www.somewhere.com/images/blah/file";

        assertThatMimeTypeWasAddedCorrectly(
                fileNameWithNoExtension,
                "text/html; image/png",
                "file.png",
                ".png");
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_withMimeTypeAndFileExtension_shouldSavePictureWithFileExtension() throws Exception {
        String fileNameWithExtension = "https://www.somewhere.com/images/blah/file.extension";

        assertThatMimeTypeWasAddedCorrectly(
                fileNameWithExtension,
                "image/extension",
                "file.extension",
                ".extension");

        assertThat((expectedFile.getName()).endsWith(".extension.extension")).isFalse();
    }

    @Ignore("Mraid 2.0")
    @Test
    public void showUserDownloadImageAlert_withHttpUri_shouldRequestPictureFromNetwork() throws Exception {
        response = new TestHttpResponseWithHeaders(200, "OK");
        downloadImageForPendingResponse("https://www.google.com/images/srpr/logo4w.png", response);

        HttpUriRequest latestRequest = (HttpUriRequest) Robolectric.getLatestSentHttpRequest();
        assertThat(latestRequest.getURI()).isEqualTo(URI.create("https://www.google.com/images/srpr/logo4w.png"));
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withMinimumValidParams_atLeastICS_shouldCreateEventIntent() throws Exception {
        setupCalendarParams();

        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener, never()).onFailure(any(MraidCommandException.class));

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();

        assertThat(intent.getType()).isEqualTo(ANDROID_CALENDAR_CONTENT_TYPE);
        assertThat(intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK).isNotEqualTo(0);
        assertThat(intent.getStringExtra(CalendarContract.Events.TITLE)).isNotNull();
        assertThat(intent.getLongExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, -1)).isNotEqualTo(-1);
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withoutSecondsOnStartDate_atLeastICS_shouldCreateEventIntent() throws Exception {
        setupCalendarParams();
        params.put("start", "2012-12-21T00:00-0500");

        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener, never()).onFailure(any(MraidCommandException.class));

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();

        assertThat(intent.getType()).isEqualTo(ANDROID_CALENDAR_CONTENT_TYPE);
        assertThat(intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK).isNotEqualTo(0);
        assertThat(intent.getStringExtra(CalendarContract.Events.TITLE)).isNotNull();
        assertThat(intent.getLongExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, -1)).isNotEqualTo(-1);
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withDailyRecurrence_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "daily");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getType()).isEqualTo(ANDROID_CALENDAR_CONTENT_TYPE);
        assertThat(intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK).isNotEqualTo(0);
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=DAILY;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withDailyRecurrence_withInterval_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "daily");
        params.put("interval", "2");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=DAILY;INTERVAL=2;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=WEEKLY;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_withInterval_withOutWeekday_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");
        params.put("interval", "7");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=WEEKLY;INTERVAL=7;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_onAllWeekDays_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");
        params.put("daysInWeek", "0,1,2,3,4,5,6");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_onDuplicateWeekDays_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");
        params.put("daysInWeek", "3,2,3,3,7,0");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=WEEKLY;BYDAY=WE,TU,SU;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_withInterval_withWeekDay_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");
        params.put("interval", "1");
        params.put("daysInWeek", "1");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withDailyRecurrence_withWeeklyRecurrence_withMonthlyOccurence_shouldCreateDailyCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "daily");
        params.put("frequency", "daily");
        params.put("frequency", "daily");
        params.put("interval", "2");
        params.put("daysInWeek", "1");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=DAILY;INTERVAL=2;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withMonthlyRecurrence_withOutInterval_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "monthly");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=MONTHLY;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withMonthlyRecurrence_withInterval_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "monthly");
        params.put("interval", "2");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=MONTHLY;INTERVAL=2;");
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void createCalendarEvent_withMonthlyRecurrence_withOutInterval_withDaysOfMonth_shouldCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "monthly");
        params.put("daysInMonth", "2,-15");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();
        assertThat(intent.getStringExtra(CalendarContract.Events.RRULE)).isEqualTo("FREQ=MONTHLY;BYMONTHDAY=2,-15;");
    }

    @Ignore("Mraid 2.0")
    @Test
    public void createCalendarEvent_withMonthlyRecurrence_withInvalidDaysOfMonth_shouldNotCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "monthly");
        params.put("daysInMonth", "55");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();

        assertThat(intent).isNull();
        assertThat(ShadowLog.getLogs().size()).isEqualTo(1);
    }

    @Ignore("Mraid 2.0")
    @Test
    public void createCalendarEvent_withWeeklyRecurrence_withInvalidDaysOfWeek_shouldNotCreateCalendarIntent() throws Exception {
        setupCalendarParams();
        params.put("frequency", "weekly");
        params.put("daysInWeek", "-1,20");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();

        assertThat(intent).isNull();
        assertThat(ShadowLog.getLogs().size()).isEqualTo(1);
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.HONEYCOMB_MR2)
    @Test
    public void createCalendarEvent_beforeIcs_shouldFireErrorEvent() throws Exception {
        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener).onFailure(any(MraidCommandException.class));
    }

    @Ignore("Mraid 2.0")
    @Test
    public void createCalendarEvent_withInvalidDate_shouldFireErrorEvent() throws Exception {
        params.put("start", "2013-08-14T09:00.-08:00");
        params.put("description", "Some Event");

        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener).onFailure(any(MraidCommandException.class));
    }

    @Ignore("Mraid 2.0")
    @Test
    public void createCalendarEvent_withMissingParameters_shouldFireErrorEvent() throws Exception {
        //it needs a start time
        params.put("description", "Some Event");

        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener).onFailure(any(MraidCommandException.class));
    }

    @Ignore("Mraid 2.0")
    @Test
    public void createCalendarEvent_withNullDate_shouldFireErrorEvent() throws Exception {
        params.put("start", null);
        params.put("description", "Some Event");

        subject.createCalendarEvent(context, params);

        verify(mraidCommandFailureListener).onFailure(any(MraidCommandException.class));
    }

    @Ignore("Mraid 2.0")
    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void
    createCalendarEvent_withValidParamsAllExceptRecurrence_atLeastICS_shouldCreateEventIntent() throws Exception {
        setupCalendarParams();
        params.put("location", "my house");
        params.put("end", "2013-08-14T22:01:01-0000");
        params.put("summary", "some description actually");
        params.put("transparency", "transparent");

        subject.createCalendarEvent(context, params);

        Intent intent = Robolectric.getShadowApplication().getNextStartedActivity();

        assertThat(intent.getType()).isEqualTo(ANDROID_CALENDAR_CONTENT_TYPE);
        assertThat(intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK).isNotEqualTo(0);
        assertThat(intent.getStringExtra(CalendarContract.Events.TITLE)).isNotNull();
        assertThat(intent.getStringExtra(CalendarContract.Events.DESCRIPTION)).isNotNull();
        assertThat(intent.getStringExtra(CalendarContract.Events.EVENT_LOCATION)).isNotNull();
        assertThat(intent.getLongExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, -1)).isNotEqualTo(-1);
        assertThat(intent.getLongExtra(CalendarContract.EXTRA_EVENT_END_TIME, -1)).isNotEqualTo(-1);
        assertThat(intent.getIntExtra(CalendarContract.Events.AVAILABILITY, -1)).isEqualTo(CalendarContract.Events.AVAILABILITY_FREE);
    }

    @Test
    public void isTelAvailable_whenCanAcceptIntent_shouldReturnTrue() throws Exception {
        context = createMockContextWithSpecificIntentData("tel", null, null, "android.intent.action.DIAL");

        assertThat(subject.isTelAvailable(context)).isTrue();
    }

    @Test
    public void isTelAvailable_whenCanNotAcceptIntent_shouldReturnFalse() throws Exception {
        context = createMockContextWithSpecificIntentData("", null, null, "android.intent.action.DIAL");

        assertThat(subject.isTelAvailable(context)).isFalse();
    }

    @Test
    public void isSmsAvailable_whenCanAcceptIntent_shouldReturnTrue() throws Exception {
        context = createMockContextWithSpecificIntentData("sms", null, null, "android.intent.action.VIEW");

        assertThat(subject.isSmsAvailable(context)).isTrue();
    }

    @Test
    public void isSmsAvailable_whenCanNotAcceptIntent_shouldReturnFalse() throws Exception {
        context = createMockContextWithSpecificIntentData("", null, null, "android.intent.action.VIEW");

        assertThat(subject.isSmsAvailable(context)).isFalse();
    }

    @Test
    public void isStorePictureAvailable_whenPermissionDeclaredAndMediaMounted_shouldReturnTrue() throws Exception {
        Robolectric.getShadowApplication().grantPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        ShadowEnvironment.setExternalStorageState(Environment.MEDIA_MOUNTED);

        assertThat(subject.isStorePictureSupported(context)).isTrue();
    }

    @Test
    public void isStorePictureAvailable_whenPermissionDenied_shouldReturnFalse() throws Exception {
        Robolectric.getShadowApplication().denyPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        ShadowEnvironment.setExternalStorageState(Environment.MEDIA_MOUNTED);

        assertThat(subject.isStorePictureSupported(context)).isFalse();
    }

    @Test
    public void isStorePictureAvailable_whenMediaUnmounted_shouldReturnFalse() throws Exception {
        Robolectric.getShadowApplication().grantPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        ShadowEnvironment.setExternalStorageState(Environment.MEDIA_UNMOUNTED);

        assertThat(subject.isStorePictureSupported(context)).isFalse();
    }

    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void isCalendarAvailable_atLeastIcs_shouldReturnTrue() throws Exception {
        context = createMockContextWithSpecificIntentData(null, null, ANDROID_CALENDAR_CONTENT_TYPE, "android.intent.action.INSERT");
        assertThat(subject.isCalendarAvailable(context)).isTrue();
    }

    @Config(reportSdk = Build.VERSION_CODES.HONEYCOMB_MR2)
    @Test
    public void isCalendarAvailable_beforeIcs_shouldReturnFalse() throws Exception {
        context = createMockContextWithSpecificIntentData(null, null, ANDROID_CALENDAR_CONTENT_TYPE, "android.intent.action.INSERT");
        assertThat(subject.isCalendarAvailable(context)).isFalse();
    }

    @Config(reportSdk = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Test
    public void isCalendarAvailable_atLeastIcs_butCanNotAcceptIntent_shouldReturnFalse() throws
            Exception {
        context = createMockContextWithSpecificIntentData(null, null, "vnd.android.cursor.item/NOPE", "android.intent.action.INSERT");
        assertThat(subject.isCalendarAvailable(context)).isFalse();
    }

    @TargetApi(11)
    @Test
    public void isInlineVideoAvailable_whenViewsAreHardwareAccelerated_whenWindowIsHardwareAccelerated_whenApiLevelIsAtLeastHoneycombMR1_shouldReturnTrue() throws Exception {
        Activity activity = Robolectric.buildActivity(Activity.class).create().get();
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

        View mockView = mock(View.class);
        when(mockView.isHardwareAccelerated()).thenReturn(true);
        when(mockView.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);

        assertThat(subject.isInlineVideoAvailable(activity, mockView)).isTrue();
    }

    @TargetApi(11)
    @Test
    public void isInlineVideoAvailable_whenViewsAreHardwareAccelerated_whenWindowIsNotHardwareAccelerated_whenApiLevelIsAtLeastHoneycombMR1_shouldReturnFalse() throws Exception {
        Activity activity = Robolectric.buildActivity(Activity.class).create().get();

        View mockView = mock(View.class);
        when(mockView.isHardwareAccelerated()).thenReturn(true);
        when(mockView.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);

        assertThat(subject.isInlineVideoAvailable(activity, mockView)).isFalse();
    }

    @Config(reportSdk = Build.VERSION_CODES.HONEYCOMB)
    @TargetApi(11)
    @Test
    public void isInlineVideoAvailable_whenViewsAreHardwareAccelerated_whenWindowIsHardwareAccelerated_whenApiLevelIsLessThanHoneycombMR1_shouldReturnFalse() throws Exception {
        Activity activity = Robolectric.buildActivity(Activity.class).create().get();
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

        View mockView = mock(View.class);
        when(mockView.isHardwareAccelerated()).thenReturn(true);
        when(mockView.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);

        assertThat(subject.isInlineVideoAvailable(activity, mockView)).isFalse();
    }

    @TargetApi(11)
    @Test
    public void isInlineVideoAvailable_whenViewsAreNotHardwareAccelerated_whenWindowIsHardwareAccelerated_whenApiLevelIsAtLeastHoneycombMR1_shouldReturnFalse() throws Exception {
        Activity activity = Robolectric.buildActivity(Activity.class).create().get();
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

        View mockView = mock(View.class);
        when(mockView.isHardwareAccelerated()).thenReturn(false);
        when(mockView.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);

        assertThat(subject.isInlineVideoAvailable(activity, mockView)).isFalse();
    }

    @TargetApi(11)
    @Test
    public void isInlineVideoAvailable_whenViewParentIsNotHardwareAccelerated_whenWindowIsHardwareAccelerated_whenApiLevelIsAtLeastHoneycombMR1_shouldReturnFalse() throws Exception {
        Activity activity = Robolectric.buildActivity(Activity.class).create().get();
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

        // ViewParent
        LinearLayout mockLinearLayout = mock(LinearLayout.class);
        when(mockLinearLayout.isHardwareAccelerated()).thenReturn(false);
        when(mockLinearLayout.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);

        // View
        View mockView = mock(View.class);
        when(mockView.isHardwareAccelerated()).thenReturn(true);
        when(mockView.getLayerType()).thenReturn(View.LAYER_TYPE_HARDWARE);
        when(mockView.getParent()).thenReturn(mockLinearLayout);

        assertThat(subject.isInlineVideoAvailable(activity, mockView)).isFalse();
    }

    private static Context createMockContextWithSpecificIntentData(final String scheme, final String componentName, final String type, final String action) {
        Context context = mock(Context.class);
        PackageManager packageManager = mock(PackageManager.class);

        List<ResolveInfo> resolveInfos = new ArrayList<ResolveInfo>();
        resolveInfos.add(new ResolveInfo());

        stub(context.getPackageManager()).toReturn(packageManager);

        BaseMatcher intentWithSpecificData = new BaseMatcher() {
            // check that the specific intent has the special data, i.e. "tel:", or a component name, or string type, based on a particular data

            @Override
            public boolean matches(Object item) {
                if (item != null && item instanceof Intent ){
                    boolean result = action != null || type != null || componentName != null || scheme != null;
                    if (action != null) {
                        if (((Intent) item).getAction() != null) {
                            result = result && action.equals(((Intent) item).getAction());
                        }
                    }

                    if (type != null) {
                        if (((Intent) item).getType() != null) {
                            result = result && type.equals(((Intent) item).getType());
                        }
                    }

                    if (componentName != null) {
                        if (((Intent) item).getComponent() != null) {
                            result = result && componentName.equals(((Intent) item).getComponent().getClassName());
                        }
                    }

                    if (scheme != null) {
                        if (((Intent) item).getData() != null) {
                            result = result && scheme.equals(((Intent) item).getData().getScheme());
                        }
                    }
                    return result;
                }
                return false;
            }

            @Override
            public void describeTo(Description description) {

            }
        };

        // It is okay to query with specific intent or nothing, because by default, none of the query would normally any resolveInfo anyways
        stub(packageManager.queryIntentActivities((Intent) argThat(intentWithSpecificData), eq(0))).toReturn(resolveInfos);
        return context;
    }

    private void downloadImageForPendingResponse(String uri, HttpResponse response) throws Exception {
        Robolectric.addPendingHttpResponse(response);

        subject.storePicture(context, uri, mraidCommandFailureListener);

        ThreadUtils.pause(TIME_TO_PAUSE_FOR_NETWORK);
    }

    private void assertThatMimeTypeWasAddedCorrectly(String originalFileName, String contentType,
            String expectedFileName, String expectedExtension) throws Exception {
        expectedFile = new File(pictureDirectory, expectedFileName);
        response = new TestHttpResponseWithHeaders(200, FAKE_IMAGE_DATA);
        response.addHeader(MraidNativeCommandHandler.MIME_TYPE_HEADER, contentType);

        downloadImageForPendingResponse(originalFileName, response);

        assertThat(expectedFile.exists()).isTrue();
        assertThat(expectedFile.getName()).endsWith(expectedExtension);
        assertThat(fileWithoutExtension.exists()).isFalse();
    }

    private void setupCalendarParams() {
        //we need mock Context so that we can validate that isCalendarAvailable() is true
        Context mockContext = createMockContextWithSpecificIntentData(null,
                null, ANDROID_CALENDAR_CONTENT_TYPE, "android.intent.action.INSERT");

        //but a mock context does't know how to startActivity(), so we stub it to use ShadowContext for starting activity
        doAnswer(new Answer<Void>() {
            public Void answer(InvocationOnMock invocation) throws Throwable {
                if (!(invocation.getArguments()[0] instanceof Intent)) {
                    throw new ClassCastException("For some reason you are not passing the calendar intent properly");
                }
                Context shadowContext = Robolectric.getShadowApplication().getApplicationContext();
                shadowContext.startActivity((Intent) invocation.getArguments()[0]);
                return null;
            }
        }).when(mockContext).startActivity(any(Intent.class));

        params.put("description", "Some Event");
        params.put("start", CALENDAR_START_TIME);
    }
}


text:
{-# LANGUAGE PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Lex
-- Copyright   :  Ben Gamari 2015-2019
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- This module contains a simple lexer supporting quoted strings

module Distribution.Lex (
        tokenizeQuotedWords
 ) where

import Prelude ()
import Distribution.Compat.Prelude

newtype DList a = DList ([a] -> [a])

runDList :: DList a -> [a]
runDList (DList run) = run []

singleton :: a -> DList a
singleton a = DList (a:)

instance Monoid (DList a) where
  mempty = DList id
  mappend = (<>)

instance Semigroup (DList a) where
  DList a <> DList b = DList (a . b)

tokenizeQuotedWords :: String -> [String]
tokenizeQuotedWords = filter (not . null) . go False mempty
  where
    go :: Bool        -- ^ in quoted region
       -> DList Char  -- ^ accumulator
       -> String      -- ^ string to be parsed
       -> [String]    -- ^ parse result
    go _ accum []
      | [] <- accum' = []
      | otherwise    = [accum']
      where accum' = runDList accum

    go False  accum (c:cs)
      | isSpace c = runDList accum : go False mempty cs
      | c == '"'  = go True accum cs

    go True   accum (c:cs)
      | c == '"'  = go False accum cs

    go quoted accum (c:cs)
                  = go quoted (accum `mappend` singleton c) cs

redpajama_set_name: RedPajamaGithub


text:
@interface NewViewController : UIViewController

@property (nonatomic, strong) UILabel       *label;
@property (nonatomic, strong) UITableView   *rightSidebarView;

@end


text:
> This is mainly to generate a new name based on the module `decimal-to-any`

## Methods
- [generate](#generate)
- [setAlphabet](#setalphabet)
- [reset](#reset)

### generate

> This will generate a new name

**rcs.nameGenerator.generate()**

Example:

```js
const rcs = require('rcs-core');
const newName = rcs.nameGenerator.generate();
```

### setAlphabet

> Customize the used alphabet

**rcs.nameGenerator.setAlphabet(alphabet)**

Parameters:
- alphabet `<String>`

Example:

```js
const rcs = require('rcs-core');

rcs.nameGenerator.setAlphabet('abcde');

const newName = rcs.nameGenerator.generate(); // 'a'
```

### reset

> Starts the alphabet at the first letter

**rcs.nameGenerator.reset()**

Usage:

```js
const rcs = require('rcs-core');

rcs.nameGenerator.reset();
```


text:
(function() {
/** code for recognition of script path */
var myScript = $("script:last")[0].src;
var ownComponentName = "org.scn.community.basics.ValiInput";
var _readScriptPath = function () {
	var scriptInfo = org_scn_community_basics.readOwnScriptAccess(myScript, ownComponentName);
	return scriptInfo.myScriptPath;
};
/** end of path recognition */

sap.ui.commons.TextField.extend(ownComponentName, {

	metadata: {
        properties: {
              "DValue": {type: "string"},
              "DValidState": {type: "string"},
              "DTooltip": {type: "string"},
              "DValidation": {type: "string"},
              "DLength": {type: "int"},
              "DNumber": {type: "float"},
              "DDefault": {type: "String"},
        }
	},

  	initDesignStudio: function() {
		var that = this;
		this._ownScript = _readScriptPath();

		this.addStyleClass("scn-pack-ValiField");

		this.attachChange(function() {
			if(that.getDValidation() == "custom") {
				that.setDValue(that.getValue());
				that.fireDesignStudioPropertiesChanged(["DValue"]);

				that.fireDesignStudioEvent("onChanged");
			} else {
				that._validatePrivate(that.getValue());

				if(that._DValid == "None") {
					that.setDValue(that.getValue());
					that.fireDesignStudioPropertiesChanged(["DValue"]);

					that.fireDesignStudioEvent("onChanged");
				}
			}
		});

		that.formValidator = new FormValidator("", []);
		that.formValidator._fillDefaults();

		this.attachLiveChange(that._validate);

		this.onAfterRendering = function() {
			var jqThis = that.$();
		};
  	},

	renderer: {},

	afterDesignStudioUpdate : function() {
		var that = this;

		var value = that.getDValue();
		var tooltip = that.getDTooltip();

		var validState = that.getDValidState();
		var validationMode = that.getDValidation();

		if(validationMode == "custom") {
			that._DValid = validState;

			that.setValueState(sap.ui.core.ValueState[validState]);
		}

		this.setValue(value);

		var validationInfo = that._getMessage();

		if(tooltip != "") {
			that.setTooltip(tooltip + " | " + validationInfo);
		} else {
			that.setTooltip(validationInfo);
		}
	},

	_validate : function (oEvent) {
		var liveValue = oEvent.getParameters().liveValue;

		this._validatePrivate(liveValue);
	},

	_validatePrivate : function (iValue) {
		var that = this;

		// client validation
		var validationMode = that.getDValidation();

		var valid = false;
		var preparedHook = {'value': iValue};

		if(iValue != "") {
			if(validationMode == "none"){
				that._DValid = "None";
				// nothing to do
			} else if(validationMode.indexOf("length") > -1){
				valid = that.formValidator._hooks[validationMode](preparedHook, this.getDLength());
			} else if(validationMode.indexOf("than") > -1){
				valid = that.formValidator._hooks[validationMode](preparedHook, this.getDNumber());
			} else if(validationMode.indexOf("default") > -1){
				valid = that.formValidator._hooks[validationMode](preparedHook, this.getDDefault());
			} else if(validationMode == "custom") {
				// nothing to do
			} else {
				valid = that.formValidator._hooks[validationMode](preparedHook);
			}
		} else {
			valid = true;
		}

		if(validationMode != "none" && validationMode != "custom") {
			if(!valid) {
				that._DValid = "Error";
			} else {
				that._DValid = "None";
			}
			that.setValueState(sap.ui.core.ValueState[that._DValid]);
		}
	},

	_getMessage : function () {
		var that = this;

		var validationMode = that.getDValidation();

		var validationMessage = "";
		validationMessage = that.formValidator.messages[validationMode];
		if(validationMode == "none" || validationMode == "custom") {
			validationMessage = "";
		}
		if(validationMessage == undefined) {
			validationMessage = "";
		}

		validationMessage = validationMessage.replace("%s field ", "value ");

		if(validationMode.indexOf("length") > -1){
			validationMessage = validationMessage.replace("%s", this.getDLength());
		} else if(validationMode.indexOf("than") > -1){
			validationMessage = validationMessage.replace("%s", this.getDNumber());
		} else if(validationMode.indexOf("default") > -1){
			validationMessage = validationMessage.replace("%s", this.getDefault());
		}

		return validationMessage;
	},

});
})();


text: HOCR Specification Python Parser