text:
SpecBegin(ARInternalShareValidator);

__block ARInternalShareValidator *sut;
__block NSURL *facebookURL, *twitterURL, *linkedInURL;

before(^{
    sut = [[ARInternalShareValidator alloc] init];
    facebookURL = [NSURL URLWithString:@"https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.artsy.net%2Farticle%2Fnicholas-o-brien-are-algorithms-conceptual-art-s-next-frontier"];

    twitterURL = [NSURL URLWithString:@"https://twitter.com/intent/tweet?original_referer=https%3A%2F%2Fm.artsy.net%2Fmagazine&text=Why%20Brilliant%20African-American%20Painter%20Alma%20Thomas%20Wasn%E2%80%99t%20Discovered%20Until%20Age%2075%20@Artsy&url=https://m.artsy.net/article/editorial-why-brilliant-african-american-painter-alma-thomas-wasnt"];

    linkedInURL =  [NSURL URLWithString:@"https://linkedin/share/share?url=https%3A%2F%2Fwww.artsy.net%2Farticle%2Fnicholas-o-brien-are-algorithms-conceptual-art-s-next-frontier&via=artsy"];
});

describe(@"correctly handles social URLs", ^{

    it(@"facebook", ^{
        expect([sut isSocialSharingURL:facebookURL]).to.beTruthy();
        expect([sut isFacebookShareURL:facebookURL]).to.beTruthy();

        expect([sut isTwitterShareURL:facebookURL]).to.beFalsy();
    });

    it(@"twitter", ^{
        expect([sut isSocialSharingURL:twitterURL]).to.beTruthy();
        expect([sut isTwitterShareURL:twitterURL]).to.beTruthy();

        expect([sut isFacebookShareURL:twitterURL]).to.beFalsy();
    });

    it(@"linkedin", ^{
        expect([sut isSocialSharingURL:linkedInURL]).to.beFalsy();
        expect([sut isFacebookShareURL:linkedInURL]).to.beFalsy();

        expect([sut isTwitterShareURL:linkedInURL]).to.beFalsy();
    });
});

describe(@"correctly pulls out the name", ^{

    it(@"twitter", ^{
        expect([sut nameBeingSharedInURL:twitterURL]).to.equal(@"Why Brilliant African-American Painter Alma Thomas Wasn't Discovered Until Age 75 @Artsy");
    });

    it(@"facebook", ^{
        expect([sut nameBeingSharedInURL:facebookURL]).to.beFalsy();
    });

    it(@"linkedin", ^{
        expect([sut nameBeingSharedInURL:linkedInURL]).to.beFalsy();
    });

});

describe(@"correctly pulls out the address", ^{

    it(@"twitter", ^{
        expect([sut addressBeingSharedFromShareURL:twitterURL]).to.equal(@"https://m.artsy.net/article/editorial-why-brilliant-african-american-painter-alma-thomas-wasnt");
    });

    it(@"facebook", ^{
        expect([sut addressBeingSharedFromShareURL:facebookURL]).to.equal(@"https://www.artsy.net/article/nicholas-o-brien-are-algorithms-conceptual-art-s-next-frontier");
    });

    it(@"linkedin", ^{
        expect([sut addressBeingSharedFromShareURL:linkedInURL]).to.beFalsy();
    });
});

SpecEnd;


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Uses of Class org.red5.server.api.stream.support.SimplePlayItem (Red5 :: Common server classes 1.0.7-SNAPSHOT API)</title>
<meta name="date" content="2016-02-18">
<link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Uses of Class
org.red5.server.api.stream.support.SimplePlayItem

Packages that use SimplePlayItem

Package
Description

org.red5.server.api.stream.support

Uses of SimplePlayItem in org.red5.server.api.stream.support

Methods in org.red5.server.api.stream.support that return SimplePlayItem

Modifier and Type
Method and Description

static SimplePlayItem
SimplePlayItem.build(String name)

Builder for SimplePlayItem

static SimplePlayItem
SimplePlayItem.build(String name,
     long start,
     long length)

Builder for SimplePlayItem

Methods in org.red5.server.api.stream.support with parameters of type SimplePlayItem

Modifier and Type
Method and Description

int
SimplePlayItem.compareTo(SimplePlayItem that)

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Copyright © 2005–2016 Red5. All rights reserved.

redpajama_set_name: RedPajamaGithub


text:
package com.rackspacecloud.blueflood.outputs.handlers;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.rackspacecloud.blueflood.exceptions.InvalidRequestException;
import com.rackspacecloud.blueflood.exceptions.SerializationException;
import com.rackspacecloud.blueflood.http.HTTPRequestWithDecodedQueryParams;
import com.rackspacecloud.blueflood.http.HttpRequestHandler;
import com.rackspacecloud.blueflood.http.HttpResponder;
import com.rackspacecloud.blueflood.io.Constants;
import com.rackspacecloud.blueflood.outputs.formats.MetricData;
import com.rackspacecloud.blueflood.outputs.serializers.BasicRollupsOutputSerializer;
import com.rackspacecloud.blueflood.outputs.serializers.JSONBasicRollupsOutputSerializer;
import com.rackspacecloud.blueflood.outputs.serializers.BasicRollupsOutputSerializer.MetricStat;
import com.rackspacecloud.blueflood.outputs.utils.PlotRequestParser;
import com.rackspacecloud.blueflood.rollup.Granularity;
import com.rackspacecloud.blueflood.tracker.Tracker;
import com.rackspacecloud.blueflood.types.Locator;
import com.rackspacecloud.blueflood.types.Resolution;
import com.rackspacecloud.blueflood.outputs.utils.RollupsQueryParams;
import com.rackspacecloud.blueflood.utils.Metrics;
import com.codahale.metrics.Timer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.http.*;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class HttpRollupsQueryHandler extends RollupHandler
            implements MetricDataQueryInterface<MetricData>, HttpRequestHandler {
    private static final Logger log = LoggerFactory.getLogger(HttpRollupsQueryHandler.class);

    private final BasicRollupsOutputSerializer<JSONObject> serializer;
    private final Gson gson;           // thread-safe
    private final JsonParser parser;   // thread-safe
    private final Timer httpMetricsFetchTimer = Metrics.timer(HttpRollupsQueryHandler.class,
            "Handle HTTP request for metrics");

    public HttpRollupsQueryHandler() {
        this.serializer = new JSONBasicRollupsOutputSerializer();
        this.gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
        this.parser = new JsonParser();
    }

    private JSONObject GetDataByPoints(String tenantId,
                                      String metric,
                                      long from,
                                      long to,
                                      int points,
                                      Set<MetricStat> stats) throws SerializationException {
        return serializer.transformRollupData(GetDataByPoints(tenantId, metric, from, to, points), stats);
    }

    private JSONObject GetDataByResolution(String tenantId,
                                      String metric,
                                      long from,
                                      long to,
                                      Resolution resolution,
                                      Set<MetricStat> stats) throws SerializationException {
        return serializer.transformRollupData(GetDataByResolution(tenantId, metric, from, to, resolution), stats);
    }

    @Override
    public MetricData GetDataByPoints(String tenantId,
                                      String metric,
                                      long from,
                                      long to,
                                      int points) throws SerializationException {
        rollupsByPointsMeter.mark();
        Granularity g = Granularity.granularityFromPointsInInterval(tenantId, from, to, points);
        return getRollupByGranularity(tenantId, Arrays.asList(metric), from, to, g).get(Locator.createLocatorFromPathComponents(tenantId, metric));
    }

    @Override
    public MetricData GetDataByResolution(String tenantId,
                                          String metric,
                                          long from,
                                          long to,
                                          Resolution resolution) throws SerializationException {
        rollupsByGranularityMeter.mark();
        if (resolution == null) {
            resolution = Resolution.FULL;
        }
        Granularity g = Granularity.granularities()[resolution.getValue()];
        return getRollupByGranularity(tenantId, Arrays.asList(metric), from, to, g).get(Locator.createLocatorFromPathComponents(tenantId, metric));
    }

    @Override
    public void handle(ChannelHandlerContext ctx, HttpRequest request) {

        Tracker.track(request);

        final String tenantId = request.getHeader("tenantId");
        final String metricName = request.getHeader("metricName");

        if (!(request instanceof HTTPRequestWithDecodedQueryParams)) {
            sendResponse(ctx, request, "Missing query params: from, to, points",
                    HttpResponseStatus.BAD_REQUEST);
            return;
        }

        HTTPRequestWithDecodedQueryParams requestWithParams = (HTTPRequestWithDecodedQueryParams) request;

        final Timer.Context httpMetricsFetchTimerContext = httpMetricsFetchTimer.time();
        try {
            RollupsQueryParams params = PlotRequestParser.parseParams(requestWithParams.getQueryParams());

            JSONObject metricData;
            if (params.isGetByPoints()) {
                metricData = GetDataByPoints(tenantId, metricName, params.getRange().getStart(),
                        params.getRange().getStop(), params.getPoints(), params.getStats());
            } else if (params.isGetByResolution()) {
                metricData = GetDataByResolution(tenantId, metricName, params.getRange().getStart(),
                        params.getRange().getStop(), params.getResolution(), params.getStats());
            } else {
                throw new InvalidRequestException("Invalid rollups query. Neither points nor resolution specified.");
            }

            final JsonElement element = parser.parse(metricData.toString());
            final String jsonStringRep = gson.toJson(element);
            sendResponse(ctx, request, jsonStringRep, HttpResponseStatus.OK);
        } catch (InvalidRequestException e) {
            // let's not log the full exception, just the message.
            log.warn(e.getMessage());
            sendResponse(ctx, request, e.getMessage(), HttpResponseStatus.BAD_REQUEST);
        } catch (SerializationException e) {
            log.error(e.getMessage(), e);
            sendResponse(ctx, request, e.getMessage(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            sendResponse(ctx, request, e.getMessage(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
        } finally {
            httpMetricsFetchTimerContext.stop();
        }
    }

    private void sendResponse(ChannelHandlerContext channel, HttpRequest request, String messageBody,
                             HttpResponseStatus status) {

        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status);

        if (messageBody != null && !messageBody.isEmpty()) {
            response.setContent(ChannelBuffers.copiedBuffer(messageBody, Constants.DEFAULT_CHARSET));
        }

        Tracker.trackResponse(request, response);
        HttpResponder.respond(channel, request, response);
    }
}


text:
<?php

namespace Kunstmaan\NodeSearchBundle\Search;

use Doctrine\ORM\EntityManager;
use Elastica\Query;
use Elastica\Query\BoolQuery;
use Elastica\Query\MatchQuery;
use Elastica\Query\QueryString;
use Elastica\Query\Term;
use Elastica\Util;
use Kunstmaan\AdminBundle\Entity\BaseUser;
use Kunstmaan\AdminBundle\Helper\DomainConfigurationInterface;
use Kunstmaan\NodeBundle\Entity\Node;
use Kunstmaan\NodeSearchBundle\Entity\NodeSearch;
use Kunstmaan\NodeSearchBundle\Helper\SearchBoostInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

/**
 * Default node searcher implementation
 */
class NodeSearcher extends AbstractElasticaSearcher
{
    /**
     * @var TokenStorageInterface
     */
    protected $tokenStorage = null;

    /**
     * @var DomainConfigurationInterface
     */
    protected $domainConfiguration;

    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * @var bool
     */
    protected $useMatchQueryForTitle = false;

    public function setTokenStorage(TokenStorageInterface $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function setDomainConfiguration(DomainConfigurationInterface $domainConfiguration)
    {
        $this->domainConfiguration = $domainConfiguration;
    }

    public function setEntityManager(EntityManager $em)
    {
        $this->em = $em;
    }

    /**
     * @param bool $useMatchQueryForTitle
     */
    public function setUseMatchQueryForTitle($useMatchQueryForTitle)
    {
        $this->useMatchQueryForTitle = $useMatchQueryForTitle;
    }

    /**
     * @param mixed  $query
     * @param string $type
     *
     * @return mixed|void
     */
    public function defineSearch($query, $type)
    {
        $query = Util::escapeTerm($query);

        $elasticaQueryString = new MatchQuery();
        $elasticaQueryString
            ->setFieldMinimumShouldMatch('content', '80%')
            ->setFieldQuery('content', $query);

        if ($this->useMatchQueryForTitle) {
            $elasticaQueryTitle = new MatchQuery();
            $elasticaQueryTitle
                ->setFieldQuery('title', $query)
                ->setFieldMinimumShouldMatch('title', '80%')
                ->setFieldBoost('title', 2)
            ;
        } else {
            $elasticaQueryTitle = new QueryString();
            $elasticaQueryTitle
              ->setDefaultField('title')
              ->setQuery($query);
        }

        $elasticaQueryBool = new BoolQuery();
        $elasticaQueryBool
            ->addShould($elasticaQueryTitle)
            ->addShould($elasticaQueryString)
            ->setMinimumShouldMatch(1);

        $this->applySecurityFilter($elasticaQueryBool);

        if (!\is_null($type)) {
            $elasticaQueryType = new Term();
            $elasticaQueryType->setTerm('type', $type);
            $elasticaQueryBool->addMust($elasticaQueryType);
        }

        $rootNode = $this->domainConfiguration->getRootNode();
        if (!\is_null($rootNode)) {
            $elasticaQueryRoot = new Term();
            $elasticaQueryRoot->setTerm('root_id', $rootNode->getId());
            $elasticaQueryBool->addMust($elasticaQueryRoot);
        }

        $rescore = new \Elastica\Rescore\Query();
        $rescore->setRescoreQuery($this->getPageBoosts());

        $this->query->setQuery($elasticaQueryBool);
        $this->query->setRescore($rescore);
        $this->query->setHighlight(
            [
                'pre_tags' => ['<strong>'],
                'post_tags' => ['</strong>'],
                'fields' => [
                    'content' => [
                        'fragment_size' => 150,
                        'number_of_fragments' => 3,
                    ],
                ],
            ]
        );
    }

    /**
     * Filter search results so only documents that are viewable by the current
     * user will be returned...
     *
     * @param \Elastica\Query\BoolQuery $elasticaQueryBool
     */
    protected function applySecurityFilter($elasticaQueryBool)
    {
        $roles = $this->getCurrentUserRoles();

        $elasticaQueryRoles = new Query\Terms('view_roles', $roles);
        $elasticaQueryBool->addMust($elasticaQueryRoles);
    }

    /**
     * @return array
     */
    protected function getCurrentUserRoles()
    {
        $roles = [];
        if (!\is_null($this->tokenStorage)) {
            $token = $this->tokenStorage->getToken();
            $user = $token instanceof TokenInterface ? $token->getUser() : null;
            if ($user instanceof BaseUser) {
                $roles = $user->getRoles();
            }
        }

        // Anonymous access should always be available for both anonymous & logged in users
        if (!\in_array('IS_AUTHENTICATED_ANONYMOUSLY', $roles, true)) {
            $roles[] = 'IS_AUTHENTICATED_ANONYMOUSLY';
        }

        // Return a re-indexed array to make sure the array keys are incremental and don't skip a number. Otherwise
        // this causes issues in ES7.
        return array_values($roles);
    }

    /**
     * Apply PageType specific and Page specific boosts
     *
     * @return \Elastica\Query\BoolQuery
     */
    protected function getPageBoosts()
    {
        $rescoreQueryBool = new BoolQuery();

        // Apply page type boosts
        $pageClasses = $this->em->getRepository(Node::class)->findAllDistinctPageClasses();
        foreach ($pageClasses as $pageClass) {
            $page = new $pageClass['refEntityName']();

            if ($page instanceof SearchBoostInterface) {
                $elasticaQueryTypeBoost = new QueryString();
                $elasticaQueryTypeBoost
                    ->setBoost($page->getSearchBoost())
                    ->setDefaultField('page_class')
                    ->setQuery(addslashes($pageClass['refEntityName']));

                $rescoreQueryBool->addShould($elasticaQueryTypeBoost);
            }
        }

        // Apply page specific boosts
        $nodeSearches = $this->em->getRepository(NodeSearch::class)->findAll();
        foreach ($nodeSearches as $nodeSearch) {
            $elasticaQueryNodeId = new QueryString();
            $elasticaQueryNodeId
                ->setBoost($nodeSearch->getBoost())
                ->setDefaultField('node_id')
                ->setQuery($nodeSearch->getNode()->getId());

            $rescoreQueryBool->addShould($elasticaQueryNodeId);
        }

        return $rescoreQueryBool;
    }
}


text:
public class Test
{
    private int x<caret>, y, z;
}


text:
'use strict'

module.exports = function barOptions(req, res, next) {
    res.header('name', 'bar');
    res.header('method', 'opts');
    res.send(200);
    next();
};


text:
package org.sgine.ui

import style.Stylized
import org.powerscala.event.ActionEvent
import org.sgine.input.event.{KeyDownEvent, MousePressEvent}
import org.sgine.input.Key

/**
 * @author Matt Hicks <mhicks@sgine.org>
 */
class Button extends AbstractContainer with Stylized with Focusable {
  def this(text: String) = {
    this()
    this.text := text
  }

  protected[ui] val background = new Scale9() {
    override def name = "background"
    mouseEnabled := false
    size.algorithm := null
    includeInLayout := false
  }
  addChild(background)

  protected[ui] val label = new Label() {
    override def name = "label"
    mouseEnabled := false
    location.z := 0.01
  }
  addChild(label)

  val text = label.text

  onChange(size.width, size.height) {
    background.size(size.width(), size.height())
  }

  listeners.synchronous {
    case evt: MousePressEvent => {
      requestFocus()
      fire(ActionEvent("click"))
    }
    case evt: KeyDownEvent if (evt.key == Key.Enter || evt.key == Key.Space) => fire(ActionEvent("click"))
  }
}


text:
cask "quicksilver" do
  version "1.6.1"
  sha256 "abc2c084913f95d3036a0cfe696bf9cd4b9fd0d6c3c16bec6e4a98ae600492c8"

  url "https://qsapp.com/archives/downloads/Quicksilver%20#{version}.dmg"
  appcast "https://qsapp.com/archives/"
  name "Quicksilver"
  homepage "https://qsapp.com/"

  auto_updates true

  app "Quicksilver.app"

  zap trash: [
    "~/Library/Preferences/com.blacktree.Quicksilver.plist",
    "~/Library/Application Support/Quicksilver",
  ]
end


text:
using Ivvy.API.Json;
using Newtonsoft.Json;

namespace Ivvy.API.Venue.Bookings
{
    public class ConfirmBookingRoomReservationResult : ISerializable
    {
        public enum Errors
        {
            Unknown = 0,
            AlreadyConfirmed = 1,
            IsCancelled = 2,
            NoRooms = 3,
            GroupCannotConfirmAvailability = 4,
            GroupNotEnoughRooms = 5,
            UnknownChannelError1 = 6,
            IndividualRoomsError = 7,
            UnknownChannelError2 = 8,
            CanBeEditedFlag = 9,
        }

        /// <summary>
        /// Indicates success or failure of the api action.
        /// </summary>
        [JsonProperty("success")]
        public bool Success
        {
            get; set;
        }

        /// <summary>
        /// The error code on failure.
        /// </summary>
        [JsonProperty("errorType")]
        public Errors? ErrorType
        {
            get; set;
        }
    }
}


text:
version: **v0.12.1** |
[v0.11.3](https://github.com/kenjis/ci-phpunit-test/blob/v0.11.3/docs/FunctionAndClassReference.md) |
[v0.10.1](https://github.com/kenjis/ci-phpunit-test/blob/v0.10.1/docs/FunctionAndClassReference.md) |
[v0.9.1](https://github.com/kenjis/ci-phpunit-test/blob/v0.9.1/docs/FunctionAndClassReference.md) |
[v0.8.2](https://github.com/kenjis/ci-phpunit-test/blob/v0.8.2/docs/FunctionAndClassReference.md) |
[v0.7.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.7.0/docs/FunctionAndClassReference.md) |
[v0.6.2](https://github.com/kenjis/ci-phpunit-test/blob/v0.6.2/docs/FunctionAndClassReference.md) |
[v0.5.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.5.0/docs/FunctionAndClassReference.md) |
[v0.4.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.4.0/docs/FunctionAndClassReference.md) |
[v0.3.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.3.0/docs/FunctionAndClassReference.md) |
[v0.2.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.2.0/docs/FunctionAndClassReference.md)

## Function/Class Reference

- [*function* `reset_instance()`](#function-reset_instance)
- [*function* `set_is_cli($return)`](#function-set_is_clireturn)
- [*function* `load_class_instance($classname, $instance)`](#function-load_class_instanceclassname-instance)
- [*class* TestCase](#class-testcase)
	- [`TestCase::resetInstance()`](#testcaseresetinstance)
	- [`TestCase::request($method, $argv, $params = [])`](#testcaserequestmethod-argv-params--)
		- [`request->setHeader()`](#request-setheader)
		- [`request->setCallable()`](#request-setcallable)
		- [`request->addCallable()`](#request-addcallable)
		- [`request->setCallablePreConstructor()`](#request-setcallablepreconstructor)
		- [`request->addCallablePreConstructor()`](#request-addcallablepreconstructor)
		- [`request->enableHooks()`](#request-enablehooks)
	- [`TestCase::ajaxRequest($method, $argv, $params = [])`](#testcaseajaxrequestmethod-argv-params--)
	- [`TestCase::assertResponseCode($code)`](#testcaseassertresponsecodecode)
	- [`TestCase::assertRedirect($uri, $code = null)`](#testcaseassertredirecturi-code--null)
	- [`TestCase::assertResponseHeader($name, $value)`](#testcaseassertresponseheadername-value)
	- [`TestCase::assertResponseCookie($name, $value, $allow_duplicate = false)`](#testcaseassertresponsecookiename-value-allow_duplicate--false)
	- [`TestCase::getDouble($classname, $params, $enable_constructor = false)`](#testcasegetdoubleclassname-params-enable_constructor--false)
	- [`TestCase::verifyInvoked($mock, $method, $params)`](#testcaseverifyinvokedmock-method-params)
	- [`TestCase::verifyInvokedOnce($mock, $method, $params)`](#testcaseverifyinvokedoncemock-method-params)
	- [`TestCase::verifyInvokedMultipleTimes($mock, $method, $times, $params)`](#testcaseverifyinvokedmultipletimesmock-method-times-params)
	- [`TestCase::verifyNeverInvoked($mock, $method, $params)`](#testcaseverifyneverinvokedmock-method-params)
	- [`TestCase::warningOff()`](#testcasewarningoff)
	- [`TestCase::warningOn()`](#testcasewarningon)
- [*class* ReflectionHelper](#class-reflectionhelper)
	- [`ReflectionHelper::getPrivateProperty($obj, $property)`](#reflectionhelpergetprivatepropertyobj-property)
	- [`ReflectionHelper::setPrivateProperty($obj, $property, $value)`](#reflectionhelpersetprivatepropertyobj-property-value)
	- [`ReflectionHelper::getPrivateMethodInvoker($obj, $method)`](#reflectionhelpergetprivatemethodinvokerobj-method)
- [*class* MonkeyPatch](#class-monkeypatch)
	- [`MonkeyPatch::patchFunction($function, $return_value, $class_method)`](#monkeypatchpatchfunctionfunction-return_value-class_method)
	- [`MonkeyPatch::resetFunctions()`](#monkeypatchresetfunctions)
	- [`MonkeyPatch::patchMethod($classname, $params)`](#monkeypatchpatchmethodclassname-params)
	- [`MonkeyPatch::resetMethods()`](#monkeypatchresetmethods)
	- [`MonkeyPatch::patchConstant($constant, $value, $class_method)`](#monkeypatchpatchconstantconstant-value-class_method)
	- [`MonkeyPatch::resetConstants()`](#monkeypatchresetconstants)
	- [`MonkeyPatch::verifyInvoked($class_method, $params)`](#monkeypatchverifyinvokedclass_method-params)
	- [`MonkeyPatch::verifyInvokedOnce($class_method, $params)`](#monkeypatchverifyinvokedonceclass_method-params)
	- [`MonkeyPatch::verifyInvokedMultipleTimes($class_method, $times, $params)`](#monkeypatchverifyinvokedmultipletimesclass_method-times-params)
	- [`MonkeyPatch::verifyNeverInvoked($class_method, $params)`](#monkeypatchverifyneverinvokedclass_method-params)

### *function* `reset_instance()`

Resets CodeIgniter instance. You must create a new controller instance after calling this function.

~~~php
reset_instance();
$controller = new Welcome();
$this->CI =& get_instance();
~~~

Normally, you don't have to use this function. Use [`TestCase::resetInstance()`](#testcaseresetinstance) method instead.

**Note:** Before you create a new controller instance, `get_instance()` returns `CIPHPUnitTestNullCodeIgniter` object.

### *function* `set_is_cli($return)`

| param   | type | description         |
|---------|------|---------------------|
|`$return`| bool | return value to set |

Sets return value of `is_cli()` function.

~~~php
set_is_cli(FALSE);
~~~

### *function* `load_class_instance($classname, $instance)`

| param      | type   | description     |
|------------|--------|-----------------|
|`$classname`| string | class name      |
|`$instance` | object | object instance |

Injects an instance directly into `load_class()` function.

~~~php
$email = $this->getMockBuilder('CI_Email')
	->setMethods(['send'])
	->getMock();
$email->method('send')
	->willReturn(TRUE);
load_class_instance('email', $email);
~~~

### *class* TestCase

#### `TestCase::resetInstance()`

Resets CodeIgniter instance and assign new CodeIgniter instance as `$this->CI`.

~~~php
public function setUp()
{
	$this->resetInstance();
	$this->CI->load->model('Category_model');
	$this->obj = $this->CI->Category_model;
}
~~~

**Note:** When you call [$this->request()](#testcaserequestmethod-argv-params--), you don't have to use this method. Because `$this->request()` resets CodeIgniter instance internally.

**Upgrade Note for v0.6.0**

Before v0.6.0, we write `setUp()` method like this:

~~~php
public function setUp()
{
	$this->CI =& get_instance();
	$this->CI->load->model('Category_model');
	$this->obj = $this->CI->Category_model;
}
~~~

When you use the way, you use the same CodeIgniter instance and the same `Category_model` instance in every test method.

In contrast, if you use `$this->resetInstance()`, it resets CodeIgniter instance and `Category_model`. So you use new CodeIgniter instance and new `Category_model` instance in every test method.

#### `TestCase::request($method, $argv, $params = [])`

| param     | type         | description                                   |
|-----------|--------------|-----------------------------------------------|
|`$method`  | string       | HTTP method                                   |
|`$argv`    | array/string | controller, method [, arg1, ...] / URI string |
|`$params`  | array/string | POST params or GET params / raw_input_stream  |

`returns` (string) output strings (view)

Runs a controller method or make a request to URI string, after `reset_instance()`.

If you want to invoke routing, specify URI string:

~~~php
$output = $this->request('GET', 'products/shoes/show/123');
~~~

You could add query string in URI string:

~~~php
$output = $this->request('GET', 'users/detail?name=John+O%27Reilly');
~~~

If you want to make POST request:

~~~php
$output = $this->request(
	'POST',
	'form/index',
	['name' => 'John Smith', 'email' => 'john@example.com']
);
~~~

If you want to call a controller method directly:

~~~php
$output = $this->request('GET', ['Form', 'index']);
~~~

**Note:** If you pass an array to the 2nd argument, it does not invoke routing, `_remap()` and `_output()` methods.

##### `request->setHeader()`

Sets HTTP request header.

~~~php
$this->request->setHeader('Accept', 'application/csv');
~~~

##### `request->setCallable()`

Sets (and resets) a function (callable) to run after controller instantiation.

~~~php
$this->request->setCallable(
	function ($CI) {
		$CI->load->library('user_agent');
	};
);
$output = $this->request('GET', ['Bbs', 'index']);
~~~

You can set one callable with `$this->request->setCallable()`. If you want to add more than one callable, you can use `$this->request->addCallable()` below.

##### `request->addCallable()`

Adds a function (callable) to run after controller instantiation.

~~~php
$this->request->addCallable(
	function ($CI) {
		$CI->load->library('user_agent');
	};
);
$output = $this->request('GET', ['Bbs', 'index']);
~~~

##### `request->setCallablePreConstructor()`

Sets (and resets) a function to run before controller instantiation.

~~~php
$this->request->setCallablePreConstructor(
	function () {
		// Get mock object
		$auth = $this->getDouble(
			'Ion_auth', ['logged_in' => TRUE]
		);
		// Inject mock object
		load_class_instance('ion_auth', $auth);
	}
);
~~~

##### `request->addCallablePreConstructor()`

Adds a function (callable) to run before controller instantiation.

~~~php
$this->request->addCallablePreConstructor(
	function () {
		// Get mock object
		$auth = $this->getDouble(
			'Ion_auth', ['logged_in' => TRUE]
		);
		// Inject mock object
		load_class_instance('ion_auth', $auth);
	}
);
~~~

##### `request->enableHooks()`

If you want to enable hooks, call `$this->request->enableHooks()` method. It enables only `pre_controller`, `post_controller_constructor`, `post_controller` and `display_override` hooks.

~~~php
$this->request->enableHooks();
$output = $this->request('GET', 'products/shoes/show/123');
~~~

#### `TestCase::ajaxRequest($method, $argv, $params = [])`

| param     | type         | description                                   |
|-----------|--------------|-----------------------------------------------|
|`$method`  | string       | HTTP method                                   |
|`$argv`    | array/string | controller, method [, arg1, ...] / URI string |
|`$params`  | array/string | POST params or GET params / raw_input_stream  |

`returns` (string) output strings

The same as `TestCase::request()`, but this makes an Ajax request. This adds only `$_SERVER['HTTP_X_REQUESTED_WITH']`.

~~~php
$output = $this->ajaxRequest('GET', 'api/books');
~~~

#### `TestCase::assertResponseCode($code)`

| param   | type | description      |
|---------|------|------------------|
|`$code`  | int  | HTTP status code |

Checks for a specific response code in your controller tests.

~~~php
$this->assertResponseCode(200);
~~~

#### `TestCase::assertRedirect($uri, $code = null)`

| param   | type   | description      |
|---------|--------|------------------|
|`$uri`   | string | URI to redirect  |
|`$code`  | int    | HTTP status code |

Checks if `redirect()` is called in your controller tests.

~~~php
$this->assertRedirect('auth/login');
~~~

#### `TestCase::assertResponseHeader($name, $value)`

| param   | type   | description  |
|---------|--------|--------------|
|`$name`  | string | header name  |
|`$value` | string | header value |

Checks for a specific response header in your controller tests.

~~~php
$this->assertResponseHeader(
	'Content-Type', 'application/csv; charset=utf-8'
);
~~~

**Note:** This method can only assert headers set by `$this->output->set_header()` method.

#### `TestCase::assertResponseCookie($name, $value, $allow_duplicate = false)`

| param             | type         | description                           |
|-------------------|--------------|---------------------------------------|
|`$name`            | string       | cookie name                           |
|`$value`           | string/array | cookie value / array of cookie params |
|`$allow_duplicate` | bool         | whether to allow duplicated cookies   |

Checks for a specific response cookie in your controller tests.

~~~php
$this->assertResponseCookie('cookie-name', 'cookie value');
~~~

You can also check cookie params.

~~~php
$this->assertResponseCookie(
	'cookie-name',
	[
		'value'  => 'cookie value',
		'domain' => '.example.com',
		'path'   => '/',
		'secure' => TRUE,
		'httponly' => TRUE,
	]
);
~~~

**Note:** This method can only assert cookies set by `$this->input->set_cooke()` method.

#### `TestCase::getDouble($classname, $params, $enable_constructor = false)`

| param               | type    | description                   |
|---------------------|---------|-------------------------------|
|`$classname`         | string  | class name                    |
|`$params`            | array   | [method_name => return_value] |
|`$enable_constructor`| bool    | enable constructor or not     |

`returns` (object) PHPUnit mock object

Gets PHPUnit mock object.

~~~php
$email = $this->getMockBuilder('CI_Email')
	->disableOriginalConstructor()
	->setMethods(['send'])
	->getMock();
$email->method('send')
	->willReturn(TRUE);
~~~

You could write code above like below:

~~~php
$email = $this->getDouble('CI_Email', ['send' => TRUE]);
~~~

**Upgrade Note for v0.10.0**

v0.10.0 has changed the default behavior of `$this->getDouble()` and disabled original constructor. If the change causes errors, update your test code like below:

*before:*
~~~php
$validation = $this->getDouble('CI_Form_validation', ['run' => TRUE]);
~~~

↓

*after:*
~~~php
$validation = $this->getDouble('CI_Form_validation', ['run' => TRUE], TRUE);
~~~

#### `TestCase::verifyInvoked($mock, $method, $params)`

| param   | type   | description         |
|---------|--------|---------------------|
|`$mock`  | object | PHPUnit mock object |
|`$method`| string | method name         |
|`$params`| array  | arguments           |

Verifies a method was invoked at least once.

~~~php
$loader->expects($this->atLeastOnce())
	->method('view')
	->with(
		['shop_confirm', $this->anything(), TRUE]
	);
~~~

You could write code above like below:

~~~php
$this->verifyInvoked(
	$loader,
	'view',
	[
		['shop_confirm', $this->anything(), TRUE]
	]
);
~~~

#### `TestCase::verifyInvokedOnce($mock, $method, $params)`

| param   | type   | description         |
|---------|--------|---------------------|
|`$mock`  | object | PHPUnit mock object |
|`$method`| string | method name         |
|`$params`| array  | arguments           |

Verifies that method was invoked only once.

~~~php
$loader->expects($this->once())
	->method('view')
	->with(
		['shop_confirm', $this->anything(), TRUE]
	);
~~~

You could write code above like below:

~~~php
$this->verifyInvokedOnce(
	$loader,
	'view',
	[
		['shop_confirm', $this->anything(), TRUE]
	]
);
~~~

#### `TestCase::verifyInvokedMultipleTimes($mock, $method, $times, $params)`

| param   | type   | description         |
|---------|--------|---------------------|
|`$mock`  | object | PHPUnit mock object |
|`$method`| string | method name         |
|`$times` | int    | times               |
|`$params`| array  | arguments           |

Verifies that method was called exactly $times times.

~~~php
$loader->expects($this->exactly(2))
	->method('view')
	->withConsecutive(
		['shop_confirm', $this->anything(), TRUE],
		['shop_tmpl_checkout', $this->anything()]
	);
~~~

You could write code above like below:

~~~php
$this->verifyInvokedMultipleTimes(
	$loader,
	'view',
	2,
	[
		['shop_confirm', $this->anything(), TRUE],
		['shop_tmpl_checkout', $this->anything()]
	]
);
~~~

#### `TestCase::verifyNeverInvoked($mock, $method, $params)`

| param   | type   | description         |
|---------|--------|---------------------|
|`$mock`  | object | PHPUnit mock object |
|`$method`| string | method name         |
|`$params`| array  | arguments           |

Verifies that method was not called.

~~~php
$loader->expects($this->never())
	->method('view')
	->with(
		['shop_confirm', $this->anything(), TRUE]
	);
~~~

You could write code above like below:

~~~php
$this->verifyNeverInvoked(
	$loader,
	'view',
	[
		['shop_confirm', $this->anything(), TRUE]
	]
);
~~~

#### `TestCase::warningOff()`

Turns off WARNING and Notice in PHP error reporting.

~~~php
$this->warningOff();
$output = $this->request('GET', 'api/example/users');
$this->warningOn();
~~~

#### `TestCase::warningOn()`

Restores PHP error reporting.

~~~php
$this->warningOn();
~~~

### *class* ReflectionHelper

This class provides helper methods to access private or protected properties and methods.

But generally it is not recommended to test non-public properties or methods, so think twice before you use methods in this class.

#### ReflectionHelper::getPrivateProperty($obj, $property)

| param     | type          | description         |
|-----------|---------------|---------------------|
|`$obj`     | object/string | object / class name |
|`$property`| string        | property name       |

`returns` (mixed) property value

Gets private or protected property value.

~~~php
$obj = new SomeClass();
$private_propery = ReflectionHelper::getPrivateProperty(
	$obj,
	'private_propery',
);
~~~

#### ReflectionHelper::setPrivateProperty($obj, $property, $value)

| param     | type          | description         |
|-----------|---------------|---------------------|
|`$obj`     | object/string | object / class name |
|`$property`| string        | property name       |
|`$value`   | mixed         | value               |

Sets private or protected property value.

~~~php
$obj = new SomeClass();
ReflectionHelper::setPrivateProperty(
	$obj,
	'private_propery',
	'new value'
);
~~~

#### ReflectionHelper::getPrivateMethodInvoker($obj, $method)

| param   | type          | description         |
|---------|---------------|---------------------|
|`$obj`   | object/string | object / class name |
|`$method`| string        | method name         |

`returns` (closure) method invoker

Gets private or protected method invoker.

~~~php
$obj = new SomeClass();
$method = ReflectionHelper::getPrivateMethodInvoker(
	$obj, 'privateMethod'
);
$this->assertEquals(
	'return value of the privateMethod() method', $method()
);
~~~

### *class* MonkeyPatch

To use this class, you have to enable monkey patching. See [How to Write Tests](HowToWriteTests.md#monkey-patching).

#### `MonkeyPatch::patchFunction($function, $return_value, $class_method)`

| param         | type   | description                                    |
|---------------|--------|------------------------------------------------|
|`$function`    | string | function name to patch                         |
|`$return_value`| mixed  | return value / callback                        |
|`$class_method`| string | class::method or classname to apply this patch |

Replaces function on the fly.

If `$class_method` is present, the patch is applied to the functions only in the class method or in the class.

There are some known limitations. See [How to Write Tests](HowToWriteTests.md#patching-functions) for details.

~~~php
MonkeyPatch::patchFunction('mt_rand', 100, 'Welcome::index');
~~~

#### `MonkeyPatch::resetFunctions()`

Resets all patched functions.

This method is called on `TestCase::tearDown()` by default. So you don't have to call it normally.

#### `MonkeyPatch::patchMethod($classname, $params)`

| param       | type   | description                   |
|-------------|--------|-------------------------------|
|`$classname` | string | class name to patch           |
|`$params`    | array  | [method_name => return_value] |

Replaces method in user-defined class on the fly.

~~~php
MonkeyPatch::patchMethod(
	'Category_model',
	['get_category_list' => [(object) ['name' => 'Nothing']]]
);
~~~

#### `MonkeyPatch::resetMethods()`

Resets all patched class methods.

This method is called on `TestCase::tearDown()` by default. So you don't have to call it normally.

#### `MonkeyPatch::patchConstant($constant, $value, $class_method)`

| param         | type   | description                                    |
|---------------|--------|------------------------------------------------|
|`$constant`    | string | constant name to patch                         |
|`$value`       | mixed  | value                                          |
|`$class_method`| string | class::method or classname to apply this patch |

Replaces constant value on the fly.

If `$class_method` is present, the patch is applied to the constants only in the class method or in the class.

There are some known limitations. See [How to Write Tests](HowToWriteTests.md#patching-constants) for details.

~~~php
MonkeyPatch::patchConstant('ENVIRONMENT', 'development', 'Welcome::index');
~~~

#### `MonkeyPatch::resetConstants()`

Resets all patched constants.

This method is called on `TestCase::tearDown()` by default. So you don't have to call it normally.

#### `MonkeyPatch::verifyInvoked($class_method, $params)`

| param         | type   | description              |
|---------------|--------|--------------------------|
|`$class_method`| string | class::method / function |
|`$params`      | array  | arguments                |

Verifies a patched class method or a patched function was invoked at least once.

~~~php
MonkeyPatch::verifyInvoked(
	'Ion_auth_model::login', ['foo', 'bar']
);
~~~

#### `MonkeyPatch::verifyInvokedOnce($class_method, $params)`

| param         | type   | description              |
|---------------|--------|--------------------------|
|`$class_method`| string | class::method / function |
|`$params`      | array  | arguments                |

Verifies that patched class method or a patched function was invoked only once.

~~~php
MonkeyPatch::verifyInvokedOnce(
	'CI_Input::post', ['id']
);
~~~

#### `MonkeyPatch::verifyInvokedMultipleTimes($class_method, $times, $params)`

| param         | type   | description              |
|---------------|--------|--------------------------|
|`$class_method`| string | class::method / function |
|`$times`       | int    | times                    |
|`$params`      | array  | arguments                |

Verifies that patched method or a patched function was called exactly $times times.

~~~php
MonkeyPatch::verifyInvokedMultipleTimes(
	'CI_Input::post', 2
);
~~~

#### `MonkeyPatch::verifyNeverInvoked($class_method, $params)`

| param         | type   | description              |
|---------------|--------|--------------------------|
|`$class_method`| string | class::method / function |
|`$params`      | array  | arguments                |

Verifies that patched method or a patched function was not called.

~~~php
MonkeyPatch::verifyNeverInvoked(
	'Ion_auth_model::login', ['username', 'PHS/DL1m6OMYg']
);
~~~


text:
<?php

namespace MS\Sentry\Monitor\Migration;

use Doctrine\DBAL\Connection;

class EventTable
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * @param Connection $connection
     */
    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }

    /**
     */
    public function create()
    {
        $createTableSql = 'CREATE TABLE IF NOT EXISTS events (
            organisation TEXT,
            project TEXT,
            event_id INTEGER,
            created TEXT,
            UNIQUE(organisation, project, event_id, created)
        )';

        $this->connection->executeQuery($createTableSql);
    }
}


text:
package adapt.model.ejb;

import java.util.ArrayList;
import java.util.List;

import adapt.model.AbstractElement;

public class EntityBean extends AbstractElement {

	protected List<AbstractAttribute> attributes = new ArrayList<AbstractAttribute>();
	protected Class<?> entityClass;

	public EntityBean() {
	}

	public EntityBean(String name, String label) {
		super(name, label);
	}

	public void add(AbstractAttribute attribute) {
		attributes.add(attribute);
	}

	public void remove(AbstractAttribute attribute) {
		attributes.remove(attribute);
	}

	public List<AbstractAttribute> getAttributes() {
		return attributes;
	}

	public void setAttributes(List<AbstractAttribute> attributes) {
		this.attributes = attributes;
	}

	public Class<?> getEntityClass() {
		return entityClass;
	}

	public void setEntityClass(Class<?> ejbClass) {
		this.entityClass = ejbClass;
	}

	@Override
	public String toString() {
		return "EntityBean [entityClass=" + entityClass + "]";
	}
}


text:
.subjectcleaner-setting-listitem {
  border-left: none;
  border-right: none;
  border: solid 0px;
  border-radius: 0px;
  margin: 0px;
}

.subjectcleaner-setting-checkbox {
  display: block;
  text-align: center;
  margin-top: 4px;
}


text:
/*
 * @author: zhifu.wang@renren-inc.com
 */
@unit-test-expecteds {
    0: unknown html tag "diva" found in "diva"
    0: unknown html tag "ffda" found in "ffda"
    0: unknown html tag "ffda" found in ".test ffda"
    0: unknown html tag "ffda" found in "ffda.test"
    0: unknown html tag "ffda" found in ".test div, ffda"
    0: unknown html tag "ffda" found in ".test ffda, .testb ffda"
    0: unknown html tag "ffda" found in ".testa .testb .testc ffda.testd"
    0: unknown html tag "ffda" found in ".testa ffda:hover"
    0: unknown html tag "ffda" found in ".testa ffda.test-class:hover"
    0: should not set style for html tag in "button, input[type=button]"
    0: do not use low performance selector ">" in "details:not([open]) > *:not(summary)"
    0: unknown html tag "fff" found in "fff::selection"
    0: unknown html tag "fff" found in "fff.class::selection"
    0: should not put "HTMLtag" and ".class" together in "div.class::selection"

    1: "* + html .input-button, * + html .input-submit, *html, *+html, .test #fuck-id, .test #fuck-idb, diva, .test ffda, ffda.test, .test div, ffda, .test ffda, .testb ffda, .testa .testb .testc ffda.testd, .testa ffda:hover, .testa ffda.test-class:hover" contains the same rules in "FEDUnknownHTMLTagName.css"
    1: "button, input[type=button], details:not([open]) > *:not(summary)" contains the same rules in "FEDUnknownHTMLTagName.css"
    1: "::selection, fff::selection, fff.class::selection, div.class::selection" contains the same rules in "FEDUnknownHTMLTagName.css"
}

@keyframes 'wobble' {
    0% {
      left: 100px;
    }
    40% {
      left: 150px;
    }
    100% {
      left: 100px;
    }
}

::selection {
    color: red;
}

fff::selection {
    color: red;
}

fff.class::selection {
    color: red;
}

div.class::selection {
    color: red;
}

* + html .input-button,
* + html .input-submit {
    width: 100px;
}

*html {
    width: 100px;
}

*+html {
    width: 100px;
}

button,
input[type=button] {
    width: 20px;
}

details:not([open]) > *:not(summary) {
    width: 20px;
}

@media screen and (-webkit-min-device-pixel-ratio:0) {
    width: 200px;
}

.test #fuck-id {
    width: 100px;
}

.test #fuck-idb {
    width: 100px;
}

diva {
    width: 100px;
}

ffda {
    border: 1px solid red;
}

.test ffda {
    width: 100px;
}

ffda.test {
    width: 100px;
}

.test div,
ffda {
    width: 100px;
}

.test ffda,
.testb ffda {
    width: 100px;
}

.testa .testb .testc ffda.testd {
    width: 100px;
}

.testa ffda:hover {
    width: 100px;
}

.testa ffda.test-class:hover {
    width: 100px;
}


text:
package org.apache.solr.store.blockcache;

import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.solr.common.util.SuppressForbidden;

/**
 * @lucene.experimental
 */
public class BlockCacheLocation {

  private int block;
  private int bankId;
  private long lastAccess;
  private long accesses = -1;
  private AtomicBoolean removed = new AtomicBoolean(false);

  public BlockCacheLocation() {
    touch();
  }

  public void setBlock(int block) {
    this.block = block;
  }

  public void setBankId(int bankId) {
    this.bankId = bankId;
  }

  public int getBlock() {
    return block;
  }

  public int getBankId() {
    return bankId;
  }

  @SuppressForbidden(reason = "Need currentTimeMillis, only used by unused getLastAccess")
  public void touch() {
    lastAccess = System.currentTimeMillis();
    accesses++;
  }

  public long getLastAccess() {
    return lastAccess;
  }

  public long getNumberOfAccesses() {
    return accesses;
  }

  public boolean isRemoved() {
    return removed.get();
  }

  public void setRemoved(boolean removed) {
    this.removed.set(removed);
  }

}


text:
using UnityEngine;
using System.Collections;

public class Obstacle : MonoBehaviour {

	[HideInInspector]
	public GameObject activeObject;

	public float deleteDistance;
	public float timeBetweenDeleteChecks;

	// Use this for initialization
	void Start () {
		InvokeRepeating("CheckForDelete", timeBetweenDeleteChecks, timeBetweenDeleteChecks);
	}

	// Update is called once per frame
	void Update () {
	}

	void CheckForDelete() {
		if(activeObject != null && Vector2.Distance(activeObject.transform.position, transform.position) > deleteDistance) {
			Destroy(gameObject);
		}
	}

	void OnTriggerEnter2D(Collider2D coll) {
		if( coll.gameObject.tag == "Pod" ) {
			Status st = GameObject.FindObjectOfType<Status>();
			if( st != null ) {
				st.HasHitAnObstacle();
			}
			PodMovement pm = coll.gameObject.GetComponent<PodMovement>();
			if( pm != null ) {
				pm.OnHitObstacle();
			}
		}
	}
}


text:
namespace blink {

TrailerReader::TrailerReader(base::span<const uint8_t> span)
    : iterator_(span) {}

TrailerReader::~TrailerReader() = default;

base::expected<bool, TrailerReader::Error> TrailerReader::SkipToTrailer() {
  DCHECK_EQ(iterator_.position(), 0u);

  auto invalid_header = [this]() {
    iterator_.TruncateTo(0);
    return base::unexpected(Error::kInvalidHeader);
  };
  auto no_trailer = [this]() {
    iterator_.TruncateTo(0);
    return false;
  };

  // We expect to see a version tag. If we see one, proceed.
  // If we don't, maybe it's an old serialized value. If we see nothing at all,
  // this message is apparently blank?
  const uint8_t* byte = iterator_.Object<uint8_t>();
  if (!byte)
    return invalid_header();
  if (*byte != kVersionTag)
    return no_trailer();

  // Read the version as a varint. If it overflows or doesn't terminate, that's
  // a problem.
  uint32_t version = 0;
  unsigned version_shift = 0;
  do {
    byte = iterator_.Object<uint8_t>();
    if (!byte || version_shift >= sizeof(version) * 8)
      return invalid_header();
    version |= (*byte & 0x7F) << version_shift;
    version_shift += 7;
  } while (*byte & 0x80);

  // Validate the version number.
  if (version < kMinWireFormatVersion)
    return no_trailer();
  if (version > SerializedScriptValue::kWireFormatVersion)
    return invalid_header();

  // We expect to see a tag indicating the trailer offset.
  byte = iterator_.Object<uint8_t>();
  if (!byte || *byte != kTrailerOffsetTag)
    return invalid_header();

  // Here and below, note that we cannot simply call BufferIterator::Object for
  // uint64_t, since that would require proper alignment to avoid undefined
  // behavior.
  uint64_t trailer_offset = 0;
  if (auto offset_raw = iterator_.CopyObject<uint64_t>())
    trailer_offset = base::NetToHost64(*offset_raw);
  else
    return invalid_header();

  uint32_t trailer_size = 0;
  if (auto size_raw = iterator_.CopyObject<uint32_t>())
    trailer_size = base::NetToHost32(*size_raw);
  else
    return invalid_header();

  // If there's no trailer, we're done here.
  if (trailer_size == 0 && trailer_offset == 0)
    return no_trailer();

  // Otherwise, validate that its offset and size are sensible.
  if (trailer_offset < iterator_.position() ||
      base::ClampAdd(trailer_offset, trailer_size) > iterator_.total_size()) {
    return invalid_header();
  }

  iterator_.Seek(static_cast<size_t>(trailer_offset));
  iterator_.TruncateTo(trailer_size);
  return true;
}

base::expected<void, TrailerReader::Error> TrailerReader::Read() {
  while (const uint8_t* tag = iterator_.Object<uint8_t>()) {
    if (*tag != kTrailerRequiresInterfacesTag)
      return base::unexpected(Error::kInvalidTrailer);
    if (required_exposed_interfaces_.size())
      return base::unexpected(Error::kInvalidTrailer);

    uint32_t num_exposed = 0;
    if (auto num_exposed_raw = iterator_.CopyObject<uint32_t>())
      num_exposed = base::NetToHost32(*num_exposed_raw);
    else
      return base::unexpected(Error::kInvalidTrailer);

    auto exposed_raw = iterator_.Span<uint8_t>(num_exposed);
    if (exposed_raw.size() != num_exposed)
      return base::unexpected(Error::kInvalidTrailer);

    required_exposed_interfaces_.Grow(num_exposed);
    std::transform(exposed_raw.begin(), exposed_raw.end(),
                   required_exposed_interfaces_.begin(), [](uint8_t raw) {
                     return static_cast<SerializationTag>(raw);
                   });
  }
  return {};
}

}  // namespace blink


text:
"""
Makefile functions.
"""

import parser, util
import subprocess, os, logging
from globrelative import glob
from cStringIO import StringIO

log = logging.getLogger('pymake.data')

class Function(object):
    """
    An object that represents a function call. This class is always subclassed
    with the following methods and attributes:

    minargs = minimum # of arguments
    maxargs = maximum # of arguments (0 means unlimited)

    def resolve(self, makefile, variables, fd, setting)
        Calls the function
        calls fd.write() with strings
    """

    __slots__ = ('_arguments', 'loc')

    def __init__(self, loc):
        self._arguments = []
        self.loc = loc
        assert self.minargs > 0

    def __getitem__(self, key):
        return self._arguments[key]

    def setup(self):
        argc = len(self._arguments)

        if argc < self.minargs:
            raise data.DataError("Not enough arguments to function %s, requires %s" % (self.name, self.minargs), self.loc)

        assert self.maxargs == 0 or argc <= self.maxargs, "Parser screwed up, gave us too many args"

    def append(self, arg):
        assert isinstance(arg, (data.Expansion, data.StringExpansion))
        self._arguments.append(arg)

    def __len__(self):
        return len(self._arguments)

class VariableRef(Function):
    __slots__ = ('vname', 'loc')

    def __init__(self, loc, vname):
        self.loc = loc
        assert isinstance(vname, (data.Expansion, data.StringExpansion))
        self.vname = vname

    def setup(self):
        assert False, "Shouldn't get here"

    def resolve(self, makefile, variables, fd, setting):
        vname = self.vname.resolvestr(makefile, variables, setting)
        if vname in setting:
            raise data.DataError("Setting variable '%s' recursively references itself." % (vname,), self.loc)

        flavor, source, value = variables.get(vname)
        if value is None:
            log.debug("%s: variable '%s' was not set" % (self.loc, vname))
            return

        value.resolve(makefile, variables, fd, setting + [vname])

class SubstitutionRef(Function):
    """$(VARNAME:.c=.o) and $(VARNAME:%.c=%.o)"""

    __slots__ = ('loc', 'vname', 'substfrom', 'substto')

    def __init__(self, loc, varname, substfrom, substto):
        self.loc = loc
        self.vname = varname
        self.substfrom = substfrom
        self.substto = substto

    def setup(self):
        assert False, "Shouldn't get here"

    def resolve(self, makefile, variables, fd, setting):
        vname = self.vname.resolvestr(makefile, variables, setting)
        if vname in setting:
            raise data.DataError("Setting variable '%s' recursively references itself." % (vname,), self.loc)

        substfrom = self.substfrom.resolvestr(makefile, variables, setting)
        substto = self.substto.resolvestr(makefile, variables, setting)

        flavor, source, value = variables.get(vname)
        if value is None:
            log.debug("%s: variable '%s' was not set" % (self.loc, vname))
            return

        f = data.Pattern(substfrom)
        if not f.ispattern():
            f = data.Pattern('%' + substfrom)
            substto = '%' + substto

        fd.write(' '.join([f.subst(substto, word, False)
                           for word in value.resolvesplit(makefile, variables, setting + [vname])]))

class SubstFunction(Function):
    name = 'subst'
    minargs = 3
    maxargs = 3

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        s = self._arguments[0].resolvestr(makefile, variables, setting)
        r = self._arguments[1].resolvestr(makefile, variables, setting)
        d = self._arguments[2].resolvestr(makefile, variables, setting)
        fd.write(d.replace(s, r))

class PatSubstFunction(Function):
    name = 'patsubst'
    minargs = 3
    maxargs = 3

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        s = self._arguments[0].resolvestr(makefile, variables, setting)
        r = self._arguments[1].resolvestr(makefile, variables, setting)

        p = data.Pattern(s)
        fd.write(' '.join([p.subst(r, word, False)
                           for word in self._arguments[2].resolvesplit(makefile, variables, setting)]))

class StripFunction(Function):
    name = 'strip'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        util.joiniter(fd, self._arguments[0].resolvesplit(makefile, variables, setting))

class FindstringFunction(Function):
    name = 'findstring'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        s = self._arguments[0].resolvestr(makefile, variables, setting)
        r = self._arguments[1].resolvestr(makefile, variables, setting)
        if r.find(s) == -1:
            return
        fd.write(s)

class FilterFunction(Function):
    name = 'filter'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        plist = [data.Pattern(p)
                 for p in self._arguments[0].resolvesplit(makefile, variables, setting)]

        fd.write(' '.join([w for w in self._arguments[1].resolvesplit(makefile, variables, setting)
                           if util.any((p.match(w) for p in plist))]))

class FilteroutFunction(Function):
    name = 'filter-out'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        plist = [data.Pattern(p)
                 for p in self._arguments[0].resolvesplit(makefile, variables, setting)]

        fd.write(' '.join([w for w in self._arguments[1].resolvesplit(makefile, variables, setting)
                           if not util.any((p.match(w) for p in plist))]))

class SortFunction(Function):
    name = 'sort'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        d = list(self._arguments[0].resolvesplit(makefile, variables, setting))
        d.sort()
        util.joiniter(fd, d)

class WordFunction(Function):
    name = 'word'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        n = self._arguments[0].resolvestr(makefile, variables, setting)
        # TODO: provide better error if this doesn't convert
        n = int(n)
        words = list(self._arguments[1].resolvesplit(makefile, variables, setting))
        if n < 1 or n > len(words):
            return
        fd.write(words[n - 1])

class WordlistFunction(Function):
    name = 'wordlist'
    minargs = 3
    maxargs = 3

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        nfrom = self._arguments[0].resolvestr(makefile, variables, setting)
        nto = self._arguments[1].resolvestr(makefile, variables, setting)
        # TODO: provide better errors if this doesn't convert
        nfrom = int(nfrom)
        nto = int(nto)

        words = list(self._arguments[2].resolvesplit(makefile, variables, setting))

        if nfrom < 1:
            nfrom = 1
        if nto < 1:
            nto = 1

        util.joiniter(fd, words[nfrom - 1:nto])

class WordsFunction(Function):
    name = 'words'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        fd.write(str(len(self._arguments[0].resolvesplit(makefile, variables, setting))))

class FirstWordFunction(Function):
    name = 'firstword'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        l = self._arguments[0].resolvesplit(makefile, variables, setting)
        if len(l):
            fd.write(l[0])

class LastWordFunction(Function):
    name = 'lastword'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        l = self._arguments[0].resolvesplit(makefile, variables, setting)
        if len(l):
            fd.write(l[-1])

def pathsplit(path, default='./'):
    """
    Splits a path into dirpart, filepart on the last slash. If there is no slash, dirpart
    is ./
    """
    dir, slash, file = util.strrpartition(path, '/')
    if dir == '':
        return default, file

    return dir + slash, file

class DirFunction(Function):
    name = 'dir'
    minargs = 1
    maxargs = 1

    def resolve(self, makefile, variables, fd, setting):
        fd.write(' '.join([pathsplit(path)[0]
                           for path in self._arguments[0].resolvesplit(makefile, variables, setting)]))

class NotDirFunction(Function):
    name = 'notdir'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        fd.write(' '.join([pathsplit(path)[1]
                           for path in self._arguments[0].resolvesplit(makefile, variables, setting)]))

class SuffixFunction(Function):
    name = 'suffix'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    @staticmethod
    def suffixes(words):
        for w in words:
            dir, file = pathsplit(w)
            base, dot, suffix = util.strrpartition(file, '.')
            if base != '':
                yield dot + suffix

    def resolve(self, makefile, variables, fd, setting):
        util.joiniter(fd, self.suffixes(self._arguments[0].resolvesplit(makefile, variables, setting)))

class BasenameFunction(Function):
    name = 'basename'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    @staticmethod
    def basenames(words):
        for w in words:
            dir, file = pathsplit(w, '')
            base, dot, suffix = util.strrpartition(file, '.')
            if dot == '':
                base = suffix

            yield dir + base

    def resolve(self, makefile, variables, fd, setting):
        util.joiniter(fd, self.basenames(self._arguments[0].resolvesplit(makefile, variables, setting)))

class AddSuffixFunction(Function):
    name = 'addprefix'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        suffix = self._arguments[0].resolvestr(makefile, variables, setting)

        fd.write(' '.join([w + suffix for w in self._arguments[1].resolvesplit(makefile, variables, setting)]))

class AddPrefixFunction(Function):
    name = 'addsuffix'
    minargs = 2
    maxargs = 2

    def resolve(self, makefile, variables, fd, setting):
        prefix = self._arguments[0].resolvestr(makefile, variables, setting)

        fd.write(' '.join([prefix + w for w in self._arguments[1].resolvesplit(makefile, variables, setting)]))

class JoinFunction(Function):
    name = 'join'
    minargs = 2
    maxargs = 2

    __slots__ = Function.__slots__

    @staticmethod
    def iterjoin(l1, l2):
        for i in xrange(0, max(len(l1), len(l2))):
            i1 = i < len(l1) and l1[i] or ''
            i2 = i < len(l2) and l2[i] or ''
            yield i1 + i2

    def resolve(self, makefile, variables, fd, setting):
        list1 = list(self._arguments[0].resolvesplit(makefile, variables, setting))
        list2 = list(self._arguments[1].resolvesplit(makefile, variables, setting))

        util.joiniter(fd, self.iterjoin(list1, list2))

class WildcardFunction(Function):
    name = 'wildcard'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        patterns = self._arguments[0].resolvesplit(makefile, variables, setting)

        fd.write(' '.join([x.replace('\\','/')
                           for p in patterns
                           for x in glob(makefile.workdir, p)]))

    __slots__ = Function.__slots__

class RealpathFunction(Function):
    name = 'realpath'
    minargs = 1
    maxargs = 1

    def resolve(self, makefile, variables, fd, setting):
        fd.write(' '.join([os.path.realpath(os.path.join(makefile.workdir, path)).replace('\\', '/')
                           for path in self._arguments[0].resolvesplit(makefile, variables, setting)]))

class AbspathFunction(Function):
    name = 'abspath'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        assert os.path.isabs(makefile.workdir)
        fd.write(' '.join([util.normaljoin(makefile.workdir, path).replace('\\', '/')
                           for path in self._arguments[0].resolvesplit(makefile, variables, setting)]))

class IfFunction(Function):
    name = 'if'
    minargs = 1
    maxargs = 3

    __slots__ = Function.__slots__

    def setup(self):
        Function.setup(self)
        self._arguments[0].lstrip()
        self._arguments[0].rstrip()

    def resolve(self, makefile, variables, fd, setting):
        condition = self._arguments[0].resolvestr(makefile, variables, setting)

        if len(condition):
            self._arguments[1].resolve(makefile, variables, fd, setting)
        elif len(self._arguments) > 2:
            return self._arguments[2].resolve(makefile, variables, fd, setting)

class OrFunction(Function):
    name = 'or'
    minargs = 1
    maxargs = 0

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        for arg in self._arguments:
            r = arg.resolvestr(makefile, variables, setting)
            if r != '':
                fd.write(r)
                return

class AndFunction(Function):
    name = 'and'
    minargs = 1
    maxargs = 0

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        r = ''

        for arg in self._arguments:
            r = arg.resolvestr(makefile, variables, setting)
            if r == '':
                return

        fd.write(r)

class ForEachFunction(Function):
    name = 'foreach'
    minargs = 3
    maxargs = 3

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        vname = self._arguments[0].resolvestr(makefile, variables, setting)
        e = self._arguments[2]

        v = data.Variables(parent=variables)
        firstword = True

        for w in self._arguments[1].resolvesplit(makefile, variables, setting):
            if firstword:
                firstword = False
            else:
                fd.write(' ')

            v.set(vname, data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, w)
            e.resolve(makefile, v, fd, setting)

class CallFunction(Function):
    name = 'call'
    minargs = 1
    maxargs = 0

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        vname = self._arguments[0].resolvestr(makefile, variables, setting)
        if vname in setting:
            raise data.DataError("Recursively setting variable '%s'" % (vname,))

        v = data.Variables(parent=variables)
        v.set('0', data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, vname)
        for i in xrange(1, len(self._arguments)):
            param = self._arguments[i].resolvestr(makefile, variables, setting)
            v.set(str(i), data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, param)

        flavor, source, e = variables.get(vname)

        if e is None:
            return

        if flavor == data.Variables.FLAVOR_SIMPLE:
            log.warning("%s: calling variable '%s' which is simply-expanded" % (self.loc, vname))

        # but we'll do it anyway
        e.resolve(makefile, v, fd, setting + [vname])

class ValueFunction(Function):
    name = 'value'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        varname = self._arguments[0].resolvestr(makefile, variables, setting)

        flavor, source, value = variables.get(varname, expand=False)
        if value is not None:
            fd.write(value)

class EvalFunction(Function):
    name = 'eval'
    minargs = 1
    maxargs = 1

    def resolve(self, makefile, variables, fd, setting):
        if makefile.parsingfinished:
            # GNU make allows variables to be set by recursive expansion during
            # command execution. This seems really dumb to me, so I don't!
            raise data.DataError("$(eval) not allowed via recursive expansion after parsing is finished", self.loc)

        stmts = parser.parsestring(self._arguments[0].resolvestr(makefile, variables, setting),
                                   'evaluation from %s' % self.loc)
        stmts.execute(makefile)

class OriginFunction(Function):
    name = 'origin'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        vname = self._arguments[0].resolvestr(makefile, variables, setting)

        flavor, source, value = variables.get(vname)
        if source is None:
            r = 'undefined'
        elif source == data.Variables.SOURCE_OVERRIDE:
            r = 'override'

        elif source == data.Variables.SOURCE_MAKEFILE:
            r = 'file'
        elif source == data.Variables.SOURCE_ENVIRONMENT:
            r = 'environment'
        elif source == data.Variables.SOURCE_COMMANDLINE:
            r = 'command line'
        elif source == data.Variables.SOURCE_AUTOMATIC:
            r = 'automatic'
        elif source == data.Variables.SOURCE_IMPLICIT:
            r = 'default'

        fd.write(r)

class FlavorFunction(Function):
    name = 'flavor'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        varname = self._arguments[0].resolvestr(makefile, variables, setting)

        flavor, source, value = variables.get(varname)
        if flavor is None:
            r = 'undefined'
        elif flavor == data.Variables.FLAVOR_RECURSIVE:
            r = 'recursive'
        elif flavor == data.Variables.FLAVOR_SIMPLE:
            r = 'simple'
        fd.write(r)

class ShellFunction(Function):
    name = 'shell'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        #TODO: call this once up-front somewhere and save the result?
        shell, msys = util.checkmsyscompat()
        cline = self._arguments[0].resolvestr(makefile, variables, setting)

        log.debug("%s: running shell command '%s'" % (self.loc, cline))
        if msys:
            cline = [shell, "-c", cline]
        p = subprocess.Popen(cline, shell=not msys, stdout=subprocess.PIPE, cwd=makefile.workdir)
        stdout, stderr = p.communicate()

        stdout = stdout.replace('\r\n', '\n')
        if stdout.endswith('\n'):
            stdout = stdout[:-1]
        stdout = stdout.replace('\n', ' ')

        fd.write(stdout)

class ErrorFunction(Function):
    name = 'error'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        v = self._arguments[0].resolvestr(makefile, variables, setting)
        raise data.DataError(v, self.loc)

class WarningFunction(Function):
    name = 'warning'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        v = self._arguments[0].resolvestr(makefile, variables, setting)
        log.warning(v)

class InfoFunction(Function):
    name = 'info'
    minargs = 1
    maxargs = 1

    __slots__ = Function.__slots__

    def resolve(self, makefile, variables, fd, setting):
        v = self._arguments[0].resolvestr(makefile, variables, setting)
        log.info(v)

functionmap = {
    'subst': SubstFunction,
    'patsubst': PatSubstFunction,
    'strip': StripFunction,
    'findstring': FindstringFunction,
    'filter': FilterFunction,
    'filter-out': FilteroutFunction,
    'sort': SortFunction,
    'word': WordFunction,
    'wordlist': WordlistFunction,
    'words': WordsFunction,
    'firstword': FirstWordFunction,
    'lastword': LastWordFunction,
    'dir': DirFunction,
    'notdir': NotDirFunction,
    'suffix': SuffixFunction,
    'basename': BasenameFunction,
    'addsuffix': AddSuffixFunction,
    'addprefix': AddPrefixFunction,
    'join': JoinFunction,
    'wildcard': WildcardFunction,
    'realpath': RealpathFunction,
    'abspath': AbspathFunction,
    'if': IfFunction,
    'or': OrFunction,
    'and': AndFunction,
    'foreach': ForEachFunction,
    'call': CallFunction,
    'value': ValueFunction,
    'eval': EvalFunction,
    'origin': OriginFunction,
    'flavor': FlavorFunction,
    'shell': ShellFunction,
    'error': ErrorFunction,
    'warning': WarningFunction,
    'info': InfoFunction,
}

import data


text:
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/notification_dispatcher_mojo.h"

#include <set>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/cancelable_callback.h"
#include "base/containers/flat_set.h"
#include "base/metrics/histogram_functions.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "chrome/browser/notifications/mac_notification_provider_factory.h"
#include "chrome/browser/notifications/notification_platform_bridge_mac_utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"

namespace {

// The initial delay for restarting the notification service. An exponential
// backoff will double this value whenever the OneShotTimer reschedules.
constexpr base::TimeDelta kInitialServiceRestartTimerDelay =
    base::Milliseconds(500);
// Maximum delay between restart attempts. We don't want this to be too low to
// avoid heavy resource usage but also not too high keep notifications working.
constexpr base::TimeDelta kMaximumServiceRestartTimerDelay = base::Seconds(256);
// If the service ran for more than this time we will reset the restart delay to
// |kInitialServiceRestartTimerDelay|.
constexpr base::TimeDelta kServiceRestartTimerResetDelay = base::Seconds(10);

}  // namespace

NotificationDispatcherMojo::NotificationDispatcherMojo(
    std::unique_ptr<MacNotificationProviderFactory> provider_factory)
    : provider_factory_(std::move(provider_factory)),
      next_service_restart_timer_delay_(kInitialServiceRestartTimerDelay) {
  // Force start the notification service once so we show the permission request
  // to users on the first start of Chrome.
  // TODO(crbug.com/1129366): Find a better time to ask for permissions.
  CheckIfNotificationsRemaining();
}

NotificationDispatcherMojo::~NotificationDispatcherMojo() = default;

void NotificationDispatcherMojo::DisplayNotification(
    NotificationHandler::Type notification_type,
    Profile* profile,
    const message_center::Notification& notification) {
  no_notifications_checker_.Cancel();
  GetOrCreateService()->DisplayNotification(
      CreateMacNotification(notification_type, profile, notification));
}

void NotificationDispatcherMojo::CloseNotificationWithId(
    const MacNotificationIdentifier& identifier) {
  if (HasNoDisplayedNotifications())
    return;

  GetOrCreateService()->CloseNotification(
      mac_notifications::mojom::NotificationIdentifier::New(
          identifier.notification_id,
          mac_notifications::mojom::ProfileIdentifier::New(
              identifier.profile_id, identifier.incognito)));
  CheckIfNotificationsRemaining();
}

void NotificationDispatcherMojo::CloseNotificationsWithProfileId(
    const std::string& profile_id,
    bool incognito) {
  if (HasNoDisplayedNotifications())
    return;

  GetOrCreateService()->CloseNotificationsForProfile(
      mac_notifications::mojom::ProfileIdentifier::New(profile_id, incognito));
  CheckIfNotificationsRemaining();
}

void NotificationDispatcherMojo::CloseAllNotifications() {
  if (HasNoDisplayedNotifications())
    return;

  if (service_)
    service_->CloseAllNotifications();
  OnServiceDisconnectedGracefully(/*gracefully=*/true);
}

void NotificationDispatcherMojo::GetDisplayedNotificationsForProfileId(
    const std::string& profile_id,
    bool incognito,
    GetDisplayedNotificationsCallback callback) {
  if (HasNoDisplayedNotifications()) {
    std::move(callback).Run(/*notification_ids=*/{},
                            /*supports_synchronization=*/true);
    return;
  }

  no_notifications_checker_.Cancel();
  GetOrCreateService()->GetDisplayedNotifications(
      mac_notifications::mojom::ProfileIdentifier::New(profile_id, incognito),
      base::BindOnce(&NotificationDispatcherMojo::DispatchGetNotificationsReply,
                     base::Unretained(this), std::move(callback)));
}

void NotificationDispatcherMojo::GetAllDisplayedNotifications(
    GetAllDisplayedNotificationsCallback callback) {
  if (HasNoDisplayedNotifications()) {
    std::move(callback).Run(/*notification_ids=*/{});
    return;
  }

  no_notifications_checker_.Cancel();
  GetOrCreateService()->GetDisplayedNotifications(
      /*profile=*/nullptr,
      base::BindOnce(
          &NotificationDispatcherMojo::DispatchGetAllNotificationsReply,
          base::Unretained(this), std::move(callback)));
}

void NotificationDispatcherMojo::OnNotificationAction(
    mac_notifications::mojom::NotificationActionInfoPtr info) {
  ProcessMacNotificationResponse(/*is_alert=*/!provider_factory_->in_process(),
                                 std::move(info));
  CheckIfNotificationsRemaining();
}

void NotificationDispatcherMojo::CheckIfNotificationsRemaining() {
  no_notifications_checker_.Reset(base::BindOnce(
      &NotificationDispatcherMojo::OnServiceDisconnectedGracefully,
      base::Unretained(this), /*gracefully=*/true));

  // This block will be called with all displayed notifications. If there are
  // none left we close the mojo connection (only if the callback has not been
  // canceled yet).
  // TODO(crbug.com/1127306): Revisit this for the UNNotification API as we need
  // to keep the process running during the initial permission request.
  GetOrCreateService()->GetDisplayedNotifications(
      /*profile=*/nullptr,
      base::BindOnce(
          [](base::OnceClosure disconnect_closure,
             std::vector<mac_notifications::mojom::NotificationIdentifierPtr>
                 notifications) {
            if (notifications.empty())
              std::move(disconnect_closure).Run();
          },
          no_notifications_checker_.callback()));
}

void NotificationDispatcherMojo::OnServiceDisconnectedGracefully(
    bool gracefully) {
  base::TimeDelta elapsed = base::TimeTicks::Now() - service_start_time_;

  // Log utility process runtime metrics to UMA.
  if (service_ && !provider_factory_->in_process()) {
    base::UmaHistogramCustomTimes("Notifications.macOS.ServiceProcessRuntime",
                                  elapsed, base::Milliseconds(100),
                                  base::Hours(8),
                                  /*buckets=*/50);
    if (!gracefully) {
      base::UmaHistogramCustomTimes("Notifications.macOS.ServiceProcessKilled",
                                    elapsed, base::Milliseconds(100),
                                    base::Hours(8),
                                    /*buckets=*/50);
    }
  }

  // If the service ran for more than 10 seconds or completed successfully we
  // restore the next delay to the initial value. If it failed sooner than that
  // then double the next time until we hit a maximum value so we don't end up
  // restarting it a lot.
  if (elapsed > kServiceRestartTimerResetDelay || gracefully)
    next_service_restart_timer_delay_ = kInitialServiceRestartTimerDelay;
  else if (next_service_restart_timer_delay_ < kMaximumServiceRestartTimerDelay)
    next_service_restart_timer_delay_ = next_service_restart_timer_delay_ * 2;

  if (!gracefully) {
    // Calling CheckIfNotificationsRemaining() will force a new connection
    // attempt. base::Unretained(this) is safe here because |this| owns
    // |service_restart_timer_|.
    service_restart_timer_.Start(
        FROM_HERE, next_service_restart_timer_delay_,
        base::BindOnce(
            &NotificationDispatcherMojo::CheckIfNotificationsRemaining,
            base::Unretained(this)));
  } else {
    service_restart_timer_.AbandonAndStop();
  }

  no_notifications_checker_.Cancel();
  provider_.reset();
  service_.reset();
  handler_.reset();
}

bool NotificationDispatcherMojo::HasNoDisplayedNotifications() const {
  return !service_ && !service_restart_timer_.IsRunning();
}

mac_notifications::mojom::MacNotificationService*
NotificationDispatcherMojo::GetOrCreateService() {
  if (!service_) {
    service_restart_timer_.AbandonAndStop();
    service_start_time_ = base::TimeTicks::Now();
    provider_ = provider_factory_->LaunchProvider();
    provider_.set_disconnect_handler(base::BindOnce(
        &NotificationDispatcherMojo::OnServiceDisconnectedGracefully,
        base::Unretained(this), /*gracefully=*/false));
    provider_->BindNotificationService(service_.BindNewPipeAndPassReceiver(),
                                       handler_.BindNewPipeAndPassRemote());
  }
  return service_.get();
}

void NotificationDispatcherMojo::DispatchGetNotificationsReply(
    GetDisplayedNotificationsCallback callback,
    std::vector<mac_notifications::mojom::NotificationIdentifierPtr>
        notifications) {
  std::set<std::string> notification_ids;

  for (const auto& notification : notifications)
    notification_ids.insert(notification->id);

  // Check if there are any notifications left after this.
  if (notification_ids.empty())
    CheckIfNotificationsRemaining();

  std::move(callback).Run(std::move(notification_ids),
                          /*supports_synchronization=*/true);
}

void NotificationDispatcherMojo::DispatchGetAllNotificationsReply(
    GetAllDisplayedNotificationsCallback callback,
    std::vector<mac_notifications::mojom::NotificationIdentifierPtr>
        notifications) {
  std::vector<MacNotificationIdentifier> notification_ids;

  for (const auto& notification : notifications) {
    notification_ids.push_back({notification->id, notification->profile->id,
                                notification->profile->incognito});
  }

  // Check if there are any notifications left after this.
  if (notification_ids.empty())
    CheckIfNotificationsRemaining();

  // Initialize the base::flat_set via a std::vector to avoid N^2 runtime.
  base::flat_set<MacNotificationIdentifier> identifiers(
      std::move(notification_ids));
  std::move(callback).Run(std::move(identifiers));
}


text:
#ifndef SIDECAR_GUI_BSCOPE_XYWIDGET_H // -*- C++ -*-
#define SIDECAR_GUI_BSCOPE_XYWIDGET_H

#include <vector>

#include "QtCore/QPointF"
#include "QtOpenGL/QGLWidget"

#include "GUI/Utils.h"

#include "Color3.h"
#include "History.h"
#include "XYView.h"

namespace Logger {
class Log;
}
namespace SideCar {
namespace GUI {

class BugPlotEmitterSettings;
class PhantomCursorImaging;
class PlotPositionFunctor;
class TargetPlotImaging;
class VertexGenerator;
class VideoSampleCountTransform;

namespace ESScope {

class GridImaging;
class History;
class RadarSettings;
class VideoImaging;
class ViewSettings;

class XYWidget : public QGLWidget {
    Q_OBJECT
    using Super = QGLWidget;

public:
    static Logger::Log& Log();

    /** Obtain the OpenGL configuration we want to use.

        \return OpenGL format
    */
    static QGLFormat GetGLFormat();

    /** Constructor.

        \param parent parent object
    */
    XYWidget(XYView* parent, ViewSettings* viewSettings, PlotPositionFunctor* plotPositionFunctor);

    ~XYWidget();

    void localToRealWorld(int x, int y, GLdouble& alpha, GLdouble& beta) const;

    void setGridPositions(const std::vector<float>& alpha, const std::vector<float>& beta);

    double getXScaling() const { return xScaling_; }
    double getYScaling() const { return yScaling_; }
    double getXYScaling() const { return xyScaling_; }

    virtual int getXScans() const = 0;
    virtual int getYScans() const = 0;
    virtual double getXMinMin() const = 0;
    virtual double getXMaxMax() const = 0;
    virtual double getYMinMin() const = 0;
    virtual double getYMaxMax() const = 0;

    QPointF getPendingBugPlot() const;

    void clearPendingBugPlot() { pendingBugPlot_ = QPoint(); }

signals:

    void cursorMoved(double x, double y);

    void bugged();

public slots:

    void setSlaveAlpha(double value);

    void redraw();

    void clear();

protected slots:

    virtual void alphasChanged(const AlphaIndices& indices) = 0;

    void generateVertices();

private slots:

    void makeGridLines();

    void scansChanged(int alphaScans, int betaScans, int rangeScans);

    void viewSettingsChanged();

protected:
    enum ListIndex { kGridLines = 0, kNumLists };

    enum VBOIndex { kVertices = 0, kColors, kNumVBOs };

    GLuint getDisplayList(int index) const { return displayLists_ + index; }

    void initializeGL();

    void makeBuffers();

    void paintGL();

    void updateColors(int offset);

    void resizeGL(int width, int height);

    void setViewTransform();

    void mousePressEvent(QMouseEvent* event);

    void mouseMoveEvent(QMouseEvent* event);

    void mouseReleaseEvent(QMouseEvent* event);

    void keyPressEvent(QKeyEvent* event);

    void wheelEvent(QWheelEvent* event);

    void enterEvent(QEvent* event);

    void leaveEvent(QEvent* event);

    virtual void fillColors() = 0;

    void centerAtCursor();

    void changeZoom(int factor);

    GLuint vbos_[kNumVBOs];
    XYView* parent_;
    ViewSettings* viewSettings_;
    PlotPositionFunctor* plotPositionFunctor_;
    VideoSampleCountTransform* videoSampleCountTransform_;
    VideoImaging* videoImaging_;
    RadarSettings* radarSettings_;
    TargetPlotImaging* extractionsImaging_;
    TargetPlotImaging* rangeTruthsImaging_;
    TargetPlotImaging* bugPlotsImaging_;
    BugPlotEmitterSettings* bugPlotEmitterSettings_;
    GridImaging* gridImaging_;
    PhantomCursorImaging* phantomCursorImaging_;
    History* history_;
    int xScans_, yScans_, gridSize_;
    double xScaling_;
    double yScaling_;
    double xyScaling_;
    GLuint displayLists_;
    QPoint lastMouse_;
    QPoint pendingBugPlot_;
    GLdouble lastMouseX_;
    GLdouble lastMouseY_;
    std::vector<float> hGridPositions_;
    std::vector<float> vGridPositions_;
    QuadColorVector colors_;
    Color clearColor_;
    QPoint magStartPos_;
    double magStartX_;
    double magStartY_;
    double magEndX_;
    double magEndY_;
    double slaveAlpha_;
    bool rubberBanding_;
    bool underMouse_;
};

} // end namespace ESScope
} // end namespace GUI
} // end namespace SideCar

/** \file
 */

#endif