/*
Copyright 2014 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cache

import (
	"sync"
	"time"

	"k8s.io/apimachinery/pkg/util/clock"
	"k8s.io/klog"
)

// ExpirationCache implements the store interface
//	1. All entries are automatically time stamped on insert
//		a. The key is computed based off the original item/keyFunc
//		b. The value inserted under that key is the timestamped item
//	2. Expiration happens lazily on read based on the expiration policy
//      a. No item can be inserted into the store while we're expiring
//		   *any* item in the cache.
//	3. Time-stamps are stripped off unexpired entries before return
// Note that the ExpirationCache is inherently slower than a normal
// threadSafeStore because it takes a write lock every time it checks if
// an item has expired.
type ExpirationCache struct {
	cacheStorage     ThreadSafeStore
	keyFunc          KeyFunc
	clock            clock.Clock
	expirationPolicy ExpirationPolicy
	// expirationLock is a write lock used to guarantee that we don't clobber
	// newly inserted objects because of a stale expiration timestamp comparison
	expirationLock sync.Mutex
}

// ExpirationPolicy dictates when an object expires. Currently only abstracted out
// so unittests don't rely on the system clock.
type ExpirationPolicy interface {
	IsExpired(obj *TimestampedEntry) bool
}

// TTLPolicy implements a ttl based ExpirationPolicy.
type TTLPolicy struct {
	//	 >0: Expire entries with an age > ttl
	//	<=0: Don't expire any entry
	TTL time.Duration

	// Clock used to calculate ttl expiration
	Clock clock.Clock
}

// IsExpired returns true if the given object is older than the ttl, or it can't
// determine its age.
func (p *TTLPolicy) IsExpired(obj *TimestampedEntry) bool {
	return p.TTL > 0 && p.Clock.Since(obj.Timestamp) > p.TTL
}

// TimestampedEntry is the only type allowed in a ExpirationCache.
// Keep in mind that it is not safe to share timestamps between computers.
// Behavior may be inconsistent if you get a timestamp from the API Server and
// use it on the client machine as part of your ExpirationCache.
type TimestampedEntry struct {
	Obj       interface{}
	Timestamp time.Time
	key       string
}

// getTimestampedEntry returns the TimestampedEntry stored under the given key.
func (c *ExpirationCache) getTimestampedEntry(key string) (*TimestampedEntry, bool) {
	item, _ := c.cacheStorage.Get(key)
	if tsEntry, ok := item.(*TimestampedEntry); ok {
		return tsEntry, true
	}
	return nil, false
}

// getOrExpire retrieves the object from the TimestampedEntry if and only if it hasn't
// already expired. It holds a write lock across deletion.
func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) {
	// Prevent all inserts from the time we deem an item as "expired" to when we
	// delete it, so an un-expired item doesn't sneak in under the same key, just
	// before the Delete.
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	timestampedItem, exists := c.getTimestampedEntry(key)
	if !exists {
		return nil, false
	}
	if c.expirationPolicy.IsExpired(timestampedItem) {
		klog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.Obj)
		c.cacheStorage.Delete(key)
		return nil, false
	}
	return timestampedItem.Obj, true
}

// GetByKey returns the item stored under the key, or sets exists=false.
func (c *ExpirationCache) GetByKey(key string) (interface{}, bool, error) {
	obj, exists := c.getOrExpire(key)
	return obj, exists, nil
}

// Get returns unexpired items. It purges the cache of expired items in the
// process.
func (c *ExpirationCache) Get(obj interface{}) (interface{}, bool, error) {
	key, err := c.keyFunc(obj)
	if err != nil {
		return nil, false, KeyError{obj, err}
	}
	obj, exists := c.getOrExpire(key)
	return obj, exists, nil
}

// List retrieves a list of unexpired items. It purges the cache of expired
// items in the process.
func (c *ExpirationCache) List() []interface{} {
	items := c.cacheStorage.List()

	list := make([]interface{}, 0, len(items))
	for _, item := range items {
		key := item.(*TimestampedEntry).key
		if obj, exists := c.getOrExpire(key); exists {
			list = append(list, obj)
		}
	}
	return list
}

// ListKeys returns a list of all keys in the expiration cache.
func (c *ExpirationCache) ListKeys() []string {
	return c.cacheStorage.ListKeys()
}

// Add timestamps an item and inserts it into the cache, overwriting entries
// that might exist under the same key.
func (c *ExpirationCache) Add(obj interface{}) error {
	key, err := c.keyFunc(obj)
	if err != nil {
		return KeyError{obj, err}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()

	c.cacheStorage.Add(key, &TimestampedEntry{obj, c.clock.Now(), key})
	return nil
}

// Update has not been implemented yet for lack of a use case, so this method
// simply calls `Add`. This effectively refreshes the timestamp.
func (c *ExpirationCache) Update(obj interface{}) error {
	return c.Add(obj)
}

// Delete removes an item from the cache.
func (c *ExpirationCache) Delete(obj interface{}) error {
	key, err := c.keyFunc(obj)
	if err != nil {
		return KeyError{obj, err}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Delete(key)
	return nil
}

// Replace will convert all items in the given list to TimestampedEntries
// before attempting the replace operation. The replace operation will
// delete the contents of the ExpirationCache `c`.
func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error {
	items := make(map[string]interface{}, len(list))
	ts := c.clock.Now()
	for _, item := range list {
		key, err := c.keyFunc(item)
		if err != nil {
			return KeyError{item, err}
		}
		items[key] = &TimestampedEntry{item, ts, key}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Replace(items, resourceVersion)
	return nil
}

// Resync will touch all objects to put them into the processing queue
func (c *ExpirationCache) Resync() error {
	return c.cacheStorage.Resync()
}

// NewTTLStore creates and returns a ExpirationCache with a TTLPolicy
func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store {
	return NewExpirationStore(keyFunc, &TTLPolicy{ttl, clock.RealClock{}})
}

// NewExpirationStore creates and returns a ExpirationCache for a given policy
func NewExpirationStore(keyFunc KeyFunc, expirationPolicy ExpirationPolicy) Store {
	return &ExpirationCache{
		cacheStorage:     NewThreadSafeStore(Indexers{}, Indices{}),
		keyFunc:          keyFunc,
		clock:            clock.RealClock{},
		expirationPolicy: expirationPolicy,
	}
}

{'repo_name': 'monzo/egress-operator', 'stars': '128', 'repo_language': 'Go', 'file_name': 'zz_generated.deepcopy.go', 'mime_type': 'text/plain', 'hash': 8575542636947297714, 'source_dataset': 'data'}


<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
	_class = "CParticleSystemDefinition"
	m_bShouldHitboxesFallbackToRenderBounds = false
	m_nMaxParticles = 64
	m_flCullRadius = 90.0
	m_flMaxDrawDistance = 2000.0
	m_flNoDrawTimeToGoToSleep = 2.0
	m_Renderers =
	[
		{
			_class = "C_OP_RenderSprites"
			VisibilityInputs =
			{
				m_flInputMin = 1.0
			}
			m_nSequenceCombineMode = "SEQUENCE_COMBINE_MODE_USE_SEQUENCE_0"
			m_flStartFadeSize = 0.675
			m_flEndFadeSize = 0.75
			m_flMaxSize = 0.85
			m_flOverbrightFactor = 1.5
			m_flAddSelfAmount = 2.0
			m_bBlendFramesSeq0 = false
			m_bSaturateColorPreAlphaBlend = false
			m_hTexture = resource:"materials/particle/spray1/spray1.vtex"
			m_flAnimationRate2 = 0.1
			m_flAnimationRate = 2.0
		},
	]
	m_Operators =
	[
		{
			_class = "C_OP_BasicMovement"
			m_fDrag = 0.015
			m_Gravity = [ 0.0, 0.0, -600.0 ]
		},
		{
			_class = "C_OP_Decay"
			m_nOpEndCapState = 0
		},
		{
			_class = "C_OP_FadeIn"
			m_flFadeInTimeMax = 0.5
		},
		{
			_class = "C_OP_FadeOut"
			m_flFadeOutTimeMax = 0.5
			m_flFadeOutTimeMin = 0.5
			m_bEaseInAndOut = false
			m_flFadeBias = 0.75
		},
		{
			_class = "C_OP_AlphaDecay"
			m_nOpEndCapState = 1
		},
		{
			_class = "C_OP_RampScalarLinearSimple"
			m_nOpEndCapState = 1
			m_nField = 16
			m_Rate = -2.0
			m_flEndTime = 99999.0
		},
		{
			_class = "C_OP_InterpolateRadius"
			m_flEndScale = 1.5
		},
		{
			_class = "C_OP_LockToBone"
			m_flLifeTimeFadeEnd = 0.35
		},
	]
	m_Initializers =
	[
		{
			_class = "C_INIT_RandomSequence"
			m_nSequenceMax = 2
		},
		{
			_class = "C_INIT_RandomYawFlip"
		},
		{
			_class = "C_INIT_RandomRotation"
		},
		{
			_class = "C_INIT_RandomAlpha"
			m_nAlphaMax = 132
			m_nAlphaMin = 32
		},
		{
			_class = "C_INIT_RandomLifeTime"
			m_fLifetimeMax = 1.0
			m_fLifetimeMin = 0.5
		},
		{
			_class = "C_INIT_RandomColor"
			m_ColorMax = [ 128, 3, 3, 255 ]
			m_ColorMin = [ 128, 3, 3, 255 ]
			m_TintMin = [ 21, 27, 15, 255 ]
			m_TintMax = [ 85, 108, 60, 255 ]
		},
		{
			_class = "C_INIT_RandomRadius"
			m_flRadiusMax = 64.0
			m_flRadiusMin = 24.0
		},
		{
			_class = "C_INIT_RandomTrailLength"
			m_flMaxLength = 0.5
			m_flMinLength = 0.5
		},
		{
			_class = "C_INIT_PositionOffset"
			m_OffsetMax = [ 0.0, 0.0, 32.0 ]
		},
		{
			_class = "C_INIT_CreateOnModel"
			m_vecDirectionBias = [ 0.0, 0.0, 0.5 ]
		},
		{
			_class = "C_INIT_InitialVelocityNoise"
			m_vecOutputMin = [ -64.0, -64.0, 132.0 ]
			m_vecOutputMax = [ 64.0, 64.0, 264.0 ]
		},
	]
	m_Emitters =
	[
		{
			_class = "C_OP_NoiseEmitter"
			m_flOutputMax = 18.0
			m_flOutputMin = 1.0
			m_flNoiseScale = 1.0
			m_flOpFadeOscillatePeriod = 1.0
			m_flOpEndFadeOutTime = 0.2
			m_flOpStartFadeOutTime = 0.1
		},
		{
			_class = "C_OP_ContinuousEmitter"
			m_flEmitRate = 3.0
		},
		{
			_class = "C_OP_InstantaneousEmitter"
			m_nParticlesToEmit = 10
		},
	]
	m_ForceGenerators =
	[
		{
			_class = "C_OP_AttractToControlPoint"
			m_fForceAmount = -150.0
			m_fFalloffPower = 0.0
		},
	]
}

{'repo_name': 'MNoya/DotaCraft', 'stars': '110', 'repo_language': 'Lua', 'file_name': 'addon_english.txt', 'mime_type': 'text/plain', 'hash': -757463907596858060, 'source_dataset': 'data'}


// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Debug = debug.Debug;

function listener(event, exec_state, event_data, data) {
  if (event == Debug.DebugEvent.Break) {
    exec_state.prepareStep(Debug.StepAction.StepNext);
  }
};

Debug.setListener(listener);

var statement = "";
for (var i = 0; i < 1024; i++) statement += "z";
statement = 'with(0)' + statement + '=function foo(){}';

debugger;
eval(statement);

{'repo_name': 'ayojs/ayo', 'stars': '1707', 'repo_language': 'JavaScript', 'file_name': 'fitblk.c', 'mime_type': 'text/x-c', 'hash': -4055908079780352647, 'source_dataset': 'data'}


//-------------------------------------------------------------------------
// SerpParser
//
// Given HTML from a Google page it will return

SeerJs.GoogleSerpParser = function(html, options) {
  init();

  function init() {
    var temp = html;
    html = temp.replace(/\n|\r/g, '');
  }

  function extractTags(haystack, start, end) {
    var retval = [];
    var temp = haystack.split(start);
    var i = 0;
    var len = temp.length;
    if (len > 0) {
      while (i < len) {
        var endIndex = temp[i].indexOf(end);
        if (endIndex > 0) {
          // console.log(endIndex);
          var content = temp[i].substr(0, endIndex);
          // console.log('pushing --- ' + content)
          if (content != '...') { retval.push(content); }
        }
        i++;
      }
      return (retval.length == 1) ? retval[0].toString() : retval;
    } else {
      return false;
    }
  }

  function eachTag(section, tag, block) {
    var temp = section.split(tag), i = 0, len = temp.length;
    if (len > 0) {
      while (i < len) {
        block(temp[i]);
        i++;
      }
    }
  }

  function organicSection() {
    var z = html;
    return html.match(
        /

(.*)<\/ol><\/div><\/div>/
        )[1].toString();
  }

  function extractOrganicResult(serp) {
    var temp;
    temp = {
      'title'   : extractTags(serp, '
', '
').removeTags().unescapeHTML(),
      'url'     : extractTags(serp, '/url?q=', '&sa'),
      'desc'    : extractTags(serp, '
', '
').removeTags().unescapeHTML(),
      'cite'    : extractTags(serp, '', '').toString().removeTags().unescapeHTML(),
      'bolded'  : extractTags(serp, '', '').toString(),
      'cache'   : 'http:' + extractTags(serp, '"flc"> - Cached')
    };
    temp = handleUniversalResult(serp, temp);
    return temp;
  }

  function handleUniversalResult(serp, result) {
    if (options['showUniversal']) {
      if (result['url'].length === 0) {
        result['url'] = 'http://www.google.com/' + extractTags(serp, '')[1];
      }
    }
    return result;
  }

  return {

    all: function() {
      var results = [], result;
      eachTag(organicSection(), '
', function(serp) {
        if (serp.length ) {
          var result = extractOrganicResult(serp);
          if (result['url'].length > 0) { results.push(result); }
        }
      });
      return results;
    }

  };
};

{'repo_name': 'chrisle/seer.js', 'stars': '199', 'repo_language': 'JavaScript', 'file_name': 'seer.js', 'mime_type': 'text/plain', 'hash': -8186728558646348119, 'source_dataset': 'data'}


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

[
  {
    "namespace": "tabs",
    "dependencies": [ "extension", "windows" ],
    "types": [
      {
        "id": "Tab",
        "type": "object",
        "properties": {
          "id": {"type": "integer", "minimum": 0, "description": "The ID of the tab. Tab IDs are unique within a browser session."},
          "index": {"type": "integer", "minimum": 0, "description": "The zero-based index of the tab within its window."},
          "windowId": {"type": "integer", "minimum": 0, "description": "The ID of the window the tab is contained within."},
          "openerTabId": {"type": "integer", "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab, if any. This will only be present if the opener tab still exists."},
          "selected": {"type": "boolean", "description": "Whether the tab is selected.", "nodoc": true},
          "highlighted": {"type": "boolean", "description": "Whether the tab is highlighted."},
          "active": {"type": "boolean", "description": "Whether the tab is active in its window."},
          "pinned": {"type": "boolean", "description": "Whether the tab is pinned."},
          "url": {"type": "string", "description": "The URL the tab is displaying."},
          "title": {"type": "string", "optional": true, "description": "The title of the tab. This may not be available if the tab is loading."},
          "favIconUrl": {"type": "string", "optional": true, "description": "The URL of the tab's favicon. This may not be available if the tab is loading."},
          "status": {"type": "string", "optional": true, "description": "Either loading or complete."},
          "incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."}
        }
      }
    ],
    "functions": [
      {
        "name": "get",
        "type": "function",
        "description": "Retrieves details about the specified tab.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0
          },
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {"name": "tab", "$ref": "Tab"}
            ]
          }
        ]
      },
      {
        "name": "getCurrent",
        "type": "function",
        "description": "Gets the tab that this script call is being made from. May be undefined if called from a non-tab context (for example: a background page or popup view).",
        "parameters": [
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {
                "name": "tab",
                "$ref": "Tab",
                "optional": true
              }
            ]
          }
        ]
      },
      {
        "name": "connect",
        "nocompile": true,
        "type": "function",
        "description": "Connects to the content script(s) in the specified tab. The chrome.extension.onConnect event is fired in each content script running in the specified tab for the current extension. For more details, see Content Script Messaging.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0
          },
          {
            "type": "object",
            "name": "connectInfo",
            "properties": {
              "name": { "type": "string", "optional": true, "description": "Will be passed into onConnect for content scripts that are listening for the connection event." }
            },
            "optional": true
          }
        ],
        "returns": {
          "$ref": "Port",
          "description": "A port that can be used to communicate with the content scripts running in the specified tab. The port's onDisconnect event is fired if the tab closes or does not exist. "
        }
      },
      {
        "name": "sendRequest",
        "nodoc": true,
        "nocompile": true,
        "type": "function",
        "description": "Deprecated: Please use sendMessage.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0
          },
          {
            "type": "any",
            "name": "request"
          },
          {
            "type": "function",
            "name": "responseCallback",
            "optional": true,
            "parameters": [
              {
                "name": "response",
                "type": "any",
                "description": "The JSON response object sent by the handler of the request. If an error occurs while connecting to the specified tab, the callback will be called with no arguments and chrome.extension.lastError will be set to the error message."
              }
            ]
          }
        ]
      },
      {
        "name": "sendMessage",
        "nocompile": true,
        "type": "function",
        "description": "Sends a single message to the content script(s) in the specified tab, with an optional callback to run when a response is sent back.  The chrome.extension.onMessage event is fired in each content script running in the specified tab for the current extension.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0
          },
          {
            "type": "any",
            "name": "message"
          },
          {
            "type": "function",
            "name": "responseCallback",
            "optional": true,
            "parameters": [
              {
                "name": "response",
                "type": "any",
                "description": "The JSON response object sent by the handler of the message. If an error occurs while connecting to the specified tab, the callback will be called with no arguments and chrome.extension.lastError will be set to the error message."
              }
            ]
          }
        ]
      },
      {
        "name": "getSelected",
        "nodoc": true,
        "type": "function",
        "description": "Deprecated. Please use query({'active': true}). Gets the tab that is selected in the specified window.",
        "parameters": [
          {
            "type": "integer",
            "name": "windowId",
            "minimum": -2,
            "optional": true,
            "description": "Defaults to the current window."
          },
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {"name": "tab", "$ref": "Tab"}
            ]
          }
        ]
      },
      {
        "name": "getAllInWindow",
        "type": "function",
        "nodoc": true,
        "description": "Deprecated. Please use query({'windowId': windowId}). Gets details about all tabs in the specified window.",
        "parameters": [
          {
            "type": "integer",
            "name": "windowId",
            "minimum": -2,
            "optional": true,
            "description": "Defaults to the current window."
            },
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {"name": "tabs", "type": "array", "items": { "$ref": "Tab" } }
            ]
          }
        ]
      },
      {
        "name": "create",
        "type": "function",
        "description": "Creates a new tab. Note: This function can be used without requesting the 'tabs' permission in the manifest.",
        "parameters": [
          {
            "type": "object",
            "name": "createProperties",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": -2,
                "optional": true,
                "description": "The window to create the new tab in. Defaults to the current window."
              },
              "index": {
                "type": "integer",
                "minimum": 0,
                "optional": true,
                "description": "The position the tab should take in the window. The provided value will be clamped to between zero and the number of tabs in the window."
              },
              "url": {
                "type": "string",
                "optional": true,
                "description": "The URL to navigate the tab to initially. Fully-qualified URLs must include a scheme (i.e. 'http://www.google.com', not 'www.google.com'). Relative URLs will be relative to the current page within the extension. Defaults to the New Tab Page."
              },
              "active": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should become the active tab in the window. Defaults to <var>true</var>"
              },
              "selected": {
                "nodoc": true,
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should become the selected tab in the window. Defaults to <var>true</var>"
              },
              "pinned": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should be pinned. Defaults to <var>false</var>"
              },
              "openerTabId": {
                "type": "integer",
                "minimum": 0,
                "optional": true,
                "description": "The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as the newly created tab."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "optional": true,
            "parameters": [
              {
                "name": "tab",
                "$ref": "Tab",
                "description": "Details about the created tab. Will contain the ID of the new tab."
              }
            ]
          }
        ]
      },
      {
        "name": "query",
        "type": "function",
        "description": "Gets all tabs that have the specified properties, or all tabs if no properties are specified.",
        "parameters": [
          {
            "type": "object",
            "name": "queryInfo",
            "properties": {
              "active": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tabs are active in their windows."
              },
              "pinned": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tabs are pinned."
              },
              "highlighted": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tabs are highlighted."
              },
              "currentWindow": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tabs are in the current window."
              },
              "lastFocusedWindow": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tabs are in the last focused window."
              },
              "status": {
                "type": "string",
                "optional": true,
                "enum": ["loading", "complete"],
                "description": "Whether the tabs have completed loading."
              },
              "title": {
                "type": "string",
                "optional": true,
                "description": "Match page titles against a pattern."
              },
              "url": {
                "type": "string",
                "optional": true,
                "description": "Match tabs against a URL pattern."
              },
              "windowId": {
                "type": "integer",
                "optional": true,
                "minimum": -2,
                "description": "The ID of the parent window, or chrome.windows.WINDOW_ID_CURRENT for the current window."
              },
              "windowType": {
                "type": "string",
                "optional": true,
                "enum": ["normal", "popup", "panel", "app"],
                "description": "The type of window the tabs are in."
              },
              "index": {
                "type": "integer",
                "optional": true,
                "minimum": 0,
                "description": "The position of the tabs within their windows."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {
                "name": "result",
                "type": "array",
                "items": {
                  "$ref": "Tab"
                }
              }
            ]
          }
        ]
      },
      {
        "name": "highlight",
        "type": "function",
        "description": "Highlights the given tabs.",
        "parameters": [
          {
            "type": "object",
            "name": "highlightInfo",
            "properties": {
               "windowId": {
                 "type": "integer",
                 "description": "The window that contains the tabs.",
                 "minimum": -2
               },
               "tabs": {
                 "description": "One or more tab indices to highlight.",
                 "choices": [
                   {"type": "array", "items": {"type": "integer", "minimum": 0}},
                   {"type": "integer"}
                 ]
               }
             }
           },
           {
             "type": "function",
             "name": "callback",
             "parameters": [
               {
                 "name": "window",
                 "$ref": "Window",
                 "description": "Contains details about the window whose tabs were highlighted."
               }
             ]
           }
        ]
      },
      {
        "name": "update",
        "type": "function",
        "description": "Modifies the properties of a tab. Properties that are not specified in <var>updateProperties</var> are not modified. Note: This function can be used without requesting the 'tabs' permission in the manifest.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0,
            "optional": true,
            "description": "Defaults to the selected tab of the current window."
          },
          {
            "type": "object",
            "name": "updateProperties",
            "properties": {
              "url": {
                "type": "string",
                "optional": true,
                "description": "A URL to navigate the tab to."
              },
              "active": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should be active."
              },
              "highlighted": {
                "type": "boolean",
                "optional": true,
                "description": "Adds or removes the tab from the current selection."
              },
              "selected": {
                "nodoc": true,
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should be selected."
              },
              "pinned": {
                "type": "boolean",
                "optional": true,
                "description": "Whether the tab should be pinned."
              },
              "openerTabId": {
                "type": "integer",
                "minimum": 0,
                "optional": true,
                "description": "The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as this tab."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "optional": true,
            "parameters": [
              {
                "name": "tab",
                "$ref": "Tab",
                "optional": true,
                "description": "Details about the updated tab, or null if the 'tabs' permission has not been requested."
              }
            ]
          }
        ]
      },
      {
        "name": "move",
        "type": "function",
        "description": "Moves one or more tabs to a new position within its window, or to a new window. Note that tabs can only be moved to and from normal (window.type === \"normal\") windows.",
        "parameters": [
          {
            "name": "tabIds",
            "description": "The tab or list of tabs to move.",
            "choices": [
              {"type": "integer", "minimum": 0},
              {"type": "array", "items": {"type": "integer", "minimum": 0}}
            ]
          },
          {
            "type": "object",
            "name": "moveProperties",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": -2,
                "optional": true,
                "description": "Defaults to the window the tab is currently in."
              },
              "index": {
                "type": "integer",
                "minimum": 0,
                "description": "The position to move the window to. The provided value will be clamped to between zero and the number of tabs in the window."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "optional": true,
            "parameters": [
              {
                "name": "tabs",
                "description": "Details about the moved tabs.",
                "choices": [
                  {"$ref": "Tab"},
                  {"type": "array", "items": {"$ref": "Tab"}}
                ]
              }
            ]
          }
        ]
      },
      {
        "name": "reload",
        "type": "function",
        "description": "Reload a tab.",
        "parameters": [
          {"type": "integer", "name": "tabId", "optional": true, "description": "The ID of the tab to reload; defaults to the selected tab of the current window."},
          {
            "type": "object",
            "name": "reloadProperties",
            "optional": true,
            "properties": {
              "bypassCache": {
                "type": "boolean",
                "optional": true,
                "description": "Whether using any local cache. Default is false."
              }
            }
          },
          {"type": "function", "name": "callback", "optional": true, "parameters": []}
        ]
      },
      {
        "name": "remove",
        "type": "function",
        "description": "Closes one or more tabs. Note: This function can be used without requesting the 'tabs' permission in the manifest.",
        "parameters": [
          {
            "name": "tabIds",
            "description": "The tab or list of tabs to close.",
            "choices": [
              {"type": "integer", "minimum": 0},
              {"type": "array", "items": {"type": "integer", "minimum": 0}}
            ]
          },
          {"type": "function", "name": "callback", "optional": true, "parameters": []}
        ]
      },
      {
        "name": "detectLanguage",
        "type": "function",
        "description": "Detects the primary language of the content in a tab.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0,
            "optional": true,
            "description": "Defaults to the active tab of the current window."
          },
          {
            "type": "function",
            "name": "callback",
            "parameters": [
              {
                "type": "string",
                "name": "language",
                "description": "An ISO language code such as en or fr. For a complete list of languages supported by this method, see kLanguageInfoTable. The 2nd to 4th columns will be checked and the first non-NULL value will be returned except for Simplified Chinese for which zh-CN will be returned. For an unknown language, und will be returned."
              }
            ]
          }
        ]
      },
      {
        "name": "captureVisibleTab",
        "type": "function",
        "description": "Captures the visible area of the currently active tab in the specified window. You must have host permission for the URL displayed by the tab.",
        "parameters": [
          {
            "type": "integer",
            "name": "windowId",
            "minimum": -2,
            "optional": true,
            "description": "The target window. Defaults to the current window."
          },
          {
            "type": "object",
            "name": "options",
            "optional": true,
            "description": "Set parameters of image capture, such as the format of the resulting image.",
            "properties": {
              "format": {
                "type": "string",
                "optional": true,
                "enum": ["jpeg", "png"],
                "description": "The format of the resulting image.  Default is jpeg."
              },
              "quality": {
                "type": "integer",
                "optional": true,
                "minimum": 0,
                "maximum": 100,
                "description": "When format is 'jpeg', controls the quality of the resulting image.  This value is ignored for PNG images.  As quality is decreased, the resulting image will have more visual artifacts, and the number of bytes needed to store it will decrease."
              }
            }
          },
          {
            "type": "function", "name": "callback", "parameters": [
              {"type": "string", "name": "dataUrl", "description": "A data URL which encodes an image of the visible area of the captured tab. May be assigned to the 'src' property of an HTML Image element for display."}
            ]
          }
        ]
      },
      {
        "name": "executeScript",
        "type": "function",
        "description": "Injects JavaScript code into a page. For details, see the programmatic injection section of the content scripts doc.",
        "parameters": [
          {"type": "integer", "name": "tabId", "optional": true, "description": "The ID of the tab in which to run the script; defaults to the active tab of the current window."},
          {
            "type": "object",
            "name": "details",
            "description": "Details of the script to run. Either the code or the file property must be set, but both may not be set at the same time.",
            "properties": {
              "code": {"type": "string", "optional": true, "description": "JavaScript code to execute."},
              "file": {"type": "string", "optional": true, "description": "JavaScript file to execute."},
              "allFrames": {"type": "boolean", "optional": true, "description": "If allFrames is true, this function injects script into all frames of current page. By default, it's false and script is injected only into the top main frame."},
              "runAt": {
                "type": "string",
                "optional": true,
                "enum": ["document_start", "document_end", "document_idle"],
                "description": "The soonest that the script will be injected into the tab. Defaults to \"document_idle\"."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "optional": true,
            "description": "Called after all the JavaScript has been executed.",
            "parameters": []
          }
        ]
      },
      {
        "name": "insertCSS",
        "type": "function",
        "description": "Injects CSS into a page. For details, see the programmatic injection section of the content scripts doc.",
        "parameters": [
          {"type": "integer", "name": "tabId", "optional": true, "description": "The ID of the tab in which to insert the CSS; defaults to the active tab of the current window."},
          {
            "type": "object",
            "name": "details",
            "description": "Details of the CSS text to insert. Either the code or the file property must be set, but both may not be set at the same time.",
            "properties": {
              "code": {"type": "string", "optional": true, "description": "CSS code to be injected."},
              "file": {"type": "string", "optional": true, "description": "CSS file to be injected."},
              "allFrames": {"type": "boolean", "optional": true, "description": "If allFrames is true, this function injects CSS text into all frames of current page. By default, it's false and CSS is injected only into the top main frame."},
              "runAt": {
                "type": "string",
                "optional": true,
                "enum": ["document_start", "document_end", "document_idle"],
                "description": "The soonest that the CSS will be injected into the tab. Defaults to \"document_idle\"."
              }
            }
          },
          {
            "type": "function",
            "name": "callback",
            "optional": true,
            "description": "Called when all the CSS has been inserted.",
            "parameters": []
          }
        ]
      }
    ],
    "events": [
      {
        "name": "onCreated",
        "type": "function",
        "description": "Fired when a tab is created. Note that the tab's URL may not be set at the time this event fired, but you can listen to onUpdated events to be notified when a URL is set.",
        "parameters": [
          {
            "$ref": "Tab",
            "name": "tab",
            "description": "Details of the tab that was created."
          }
        ]
      },
      {
        "name": "onUpdated",
        "type": "function",
        "description": "Fired when a tab is updated.",
        "parameters": [
          {"type": "integer", "name": "tabId", "minimum": 0},
          {
            "type": "object",
            "name": "changeInfo",
            "description": "Lists the changes to the state of the tab that was updated.",
            "properties": {
              "status": {
                "type": "string",
                "optional": true,
                "description": "The status of the tab. Can be either loading or complete."
              },
              "url": {
                "type": "string",
                "optional": true,
                "description": "The tab's URL if it has changed."
              },
              "pinned": {
                "type": "boolean",
                "optional": true,
                "description": "The tab's new pinned state."
              }
            }
          },
          {
            "$ref": "Tab",
            "name": "tab",
            "description": "Gives the state of the tab that was updated."
          }
        ]
      },
      {
        "name": "onMoved",
        "type": "function",
        "description": "Fired when a tab is moved within a window. Only one move event is fired, representing the tab the user directly moved. Move events are not fired for the other tabs that must move in response. This event is not fired when a tab is moved between windows. For that, see onDetached.",
        "parameters": [
          {"type": "integer", "name": "tabId", "minimum": 0},
          {
            "type": "object",
            "name": "moveInfo",
            "properties": {
              "windowId": {"type": "integer", "minimum": 0},
              "fromIndex": {"type": "integer", "minimum": 0},
              "toIndex": {"type": "integer", "minimum": 0}
            }
          }
        ]
      },
      {
        "name": "onSelectionChanged",
        "nodoc": true,
        "type": "function",
        "description": "Deprecated. Please use onActivated.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0,
            "description": "The ID of the tab that has become active."
          },
          {
            "type": "object",
            "name": "selectInfo",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": 0,
                "description": "The ID of the window the selected tab changed inside of."
              }
            }
          }
        ]
      },
      {
        "name": "onActiveChanged",
        "nodoc": true,
        "type": "function",
        "description": "Deprecated. Please use onActivated.",
        "parameters": [
          {
            "type": "integer",
            "name": "tabId",
            "minimum": 0,
            "description": "The ID of the tab that has become active."
          },
          {
            "type": "object",
            "name": "selectInfo",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": 0,
                "description": "The ID of the window the selected tab changed inside of."
              }
            }
          }
        ]
      },
      {
        "name": "onActivated",
        "type": "function",
        "description": "Fires when the active tab in a window changes. Note that the tab's URL may not be set at the time this event fired, but you can listen to onUpdated events to be notified when a URL is set.",
        "parameters": [
          {
            "type": "object",
            "name": "activeInfo",
            "properties": {
              "tabId": {
                "type": "integer",
                "minimum": 0,
                "description": "The ID of the tab that has become active."
              },
              "windowId": {
                "type": "integer",
                "minimum": 0,
                "description": "The ID of the window the active tab changed inside of."
              }
            }
          }
        ]
      },
      {
        "name": "onHighlightChanged",
        "type": "function",
        "nodoc": true,
        "description": "Deprecated. Please use onHighlighted.",
        "parameters": [
          {
            "type": "object",
            "name": "selectInfo",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": 0,
                "description": "The window whose tabs changed."
              },
              "tabIds": {
                "type": "array",
                "name": "tabIds",
                "items": {"type": "integer", "minimum": 0},
                "description": "All highlighted tabs in the window."
              }
            }
          }
        ]
      },
      {
        "name": "onHighlighted",
        "type": "function",
        "description": "Fired when the highlighted or selected tabs in a window changes.",
        "parameters": [
          {
            "type": "object",
            "name": "highlightInfo",
            "properties": {
              "windowId": {
                "type": "integer",
                "minimum": 0,
                "description": "The window whose tabs changed."
              },
              "tabIds": {
                "type": "array",
                "name": "tabIds",
                "items": {"type": "integer", "minimum": 0},
                "description": "All highlighted tabs in the window."
              }
            }
          }
        ]
      },
      {
        "name": "onDetached",
        "type": "function",
        "description": "Fired when a tab is detached from a window, for example because it is being moved between windows.",
        "parameters": [
          {"type": "integer", "name": "tabId", "minimum": 0},
          {
            "type": "object",
            "name": "detachInfo",
            "properties": {
              "oldWindowId": {"type": "integer", "minimum": 0},
              "oldPosition": {"type": "integer", "minimum": 0}
            }
          }
        ]
      },
      {
        "name": "onAttached",
        "type": "function",
        "description": "Fired when a tab is attached to a window, for example because it was moved between windows.",
        "parameters": [
          {"type": "integer", "name": "tabId", "minimum": 0},
          {
            "type": "object",
            "name": "attachInfo",
            "properties": {
              "newWindowId": {"type": "integer", "minimum": 0},
              "newPosition": {"type": "integer", "minimum": 0}
            }
          }
        ]
      },
      {
        "name": "onRemoved",
        "type": "function",
        "description": "Fired when a tab is closed. Note: A listener can be registered for this event without requesting the 'tabs' permission in the manifest.",
        "parameters": [
          {"type": "integer", "name": "tabId", "minimum": 0},
          {
            "type": "object",
            "name": "removeInfo",
            "properties": {
              "isWindowClosing": {"type": "boolean", "description": "True when the tab is being closed because its window is being closed." }
            }
          }
        ]
      }
    ]
  }
]

{'repo_name': 'adobe/chromium', 'stars': '179', 'repo_language': 'C++', 'file_name': 'webkit_version.py', 'mime_type': 'text/x-python', 'hash': 424317090129621820, 'source_dataset': 'data'}


import { ArtifactNode } from '../utils/ArtifactUtils';
import {
  experimentsById,
  runInfosByUuid,
  paramsByRunUuid,
  tagsByRunUuid,
  artifactsByRunUuid,
  artifactRootUriByRunUuid,
  experimentTagsByExperimentId,
  getParams,
  getRunTags,
  getRunInfo,
  getExperiments,
  getExperiment,
  getExperimentTags,
  apis,
  rootReducer,
  getApis,
  getArtifacts,
  getSharedParamKeysByRunUuids,
  getAllParamKeysByRunUuids,
  getArtifactRootUri,
} from './Reducers';
import { mockExperiment, mockRunInfo } from '../utils/test-utils/ReduxStoreFixtures';
import { RunTag, RunInfo, Param, Experiment, ExperimentTag } from '../sdk/MlflowMessages';
import {
  LIST_EXPERIMENTS_API,
  GET_EXPERIMENT_API,
  GET_RUN_API,
  SEARCH_RUNS_API,
  LOAD_MORE_RUNS_API,
  SET_TAG_API,
  DELETE_TAG_API,
  LIST_ARTIFACTS_API,
  SET_EXPERIMENT_TAG_API,
} from '../actions';
import { fulfilled, pending, rejected } from '../../common/utils/ActionUtils';
import { deepFreeze } from '../../common/utils/TestUtils';

describe('test experimentsById', () => {
  test('should set up initial state correctly', () => {
    expect(experimentsById(undefined, {})).toEqual({});
  });

  test('listExperiments correctly updates empty state', () => {
    const experimentA = mockExperiment('experiment01', 'experimentA');
    const experimentB = mockExperiment('experiment02', 'experimentB');
    const state = undefined;
    const action = {
      type: fulfilled(LIST_EXPERIMENTS_API),
      payload: {
        experiments: [experimentA.toJSON(), experimentB.toJSON()],
      },
    };
    const new_state = experimentsById(state, action);
    expect(new_state).toEqual({
      [experimentA.experiment_id]: experimentA,
      [experimentB.experiment_id]: experimentB,
    });
  });

  test('listExperiments correctly updates state', () => {
    const newA = mockExperiment('experiment01', 'experimentA');
    const newB = mockExperiment('experiment02', 'experimentB');
    const preserved = mockExperiment('experiment03', 'still exists');
    const removed = mockExperiment('experiment04', 'removed');
    const replacedOld = mockExperiment('experiment05', 'replacedOld');
    const replacedNew = mockExperiment('experiment05', 'replacedNew');
    const state = deepFreeze({
      [preserved.getExperimentId()]: preserved,
      [removed.getExperimentId()]: removed,
      [replacedOld.getExperimentId()]: replacedOld,
    });
    const action = {
      type: fulfilled(LIST_EXPERIMENTS_API),
      payload: {
        experiments: [preserved.toJSON(), newA.toJSON(), newB.toJSON(), replacedNew.toJSON()],
      },
    };
    const new_state = experimentsById(state, action);
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [preserved.getExperimentId()]: preserved,
      [newA.getExperimentId()]: newA,
      [newB.getExperimentId()]: newB,
      [replacedNew.getExperimentId()]: replacedNew,
    });
  });

  test('getExperiment correctly updates empty state', () => {
    const experimentA = mockExperiment('experiment01', 'experimentA');
    const state = {};
    const action = {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: experimentA.toJSON(),
      },
    };
    const new_state = experimentsById(state, action);
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [experimentA.experiment_id]: experimentA,
    });
  });

  test('getExperiment correctly updates non empty state', () => {
    const preserved = mockExperiment('experiment03', 'still exists');
    const replacedOld = mockExperiment('experiment05', 'replacedOld');
    const replacedNew = mockExperiment('experiment05', 'replacedNew');
    const state = deepFreeze({
      [preserved.getExperimentId()]: preserved,
      [replacedOld.getExperimentId()]: replacedOld,
    });
    const action = {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: replacedNew.toJSON(),
      },
    };
    const new_state = experimentsById(state, action);
    // make sure the reducer did not modify the original state
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [preserved.getExperimentId()]: preserved,
      [replacedNew.getExperimentId()]: replacedNew,
    });
  });
});

describe('test runInfosByUuid', () => {
  test('should set up initial state correctly', () => {
    expect(runInfosByUuid(undefined, {})).toEqual({});
  });
  test('search api with no payload', () => {
    expect(
      runInfosByUuid(undefined, {
        type: fulfilled(SEARCH_RUNS_API),
      }),
    ).toEqual({});
  });
  test('load more with no payload', () => {
    expect(
      runInfosByUuid(undefined, {
        type: fulfilled(LOAD_MORE_RUNS_API),
      }),
    ).toEqual({});
  });

  test('getRunApi correctly updates state', () => {
    const runA = mockRunInfo('run01', '1');
    const runB = mockRunInfo('run01', '2');
    const actionA = {
      type: fulfilled(GET_RUN_API),
      payload: {
        run: {
          info: runA.toJSON(),
        },
      },
    };
    const new_state_0 = deepFreeze(runInfosByUuid(undefined, actionA));
    expect(new_state_0).toEqual({
      [runA.getRunUuid()]: runA,
    });
    const actionB = {
      type: fulfilled(GET_RUN_API),
      payload: {
        run: {
          info: runB.toJSON(),
        },
      },
    };
    const new_state_1 = runInfosByUuid(new_state_0, actionB);
    expect(new_state_1).not.toEqual(new_state_0);
    expect(new_state_1).toEqual({
      [runB.getRunUuid()]: runB,
    });
  });

  test('searchRunApi correctly updates empty state', () => {
    const runA = mockRunInfo('run01');
    const runB = mockRunInfo('run02');
    const state = undefined;
    const action = {
      type: fulfilled(SEARCH_RUNS_API),
      payload: {
        runs: [{ info: runA.toJSON() }, { info: runB.toJSON() }],
      },
    };
    const new_state = deepFreeze(runInfosByUuid(state, action));
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [runA.getRunUuid()]: runA,
      [runB.getRunUuid()]: runB,
    });
  });

  test('searchRunApi correctly updates state', () => {
    const preserved = mockRunInfo('still exists');
    const replacedOld = mockRunInfo('replaced', 'old');
    const replacedNew = mockRunInfo('replaced', 'new');
    const removed = mockRunInfo('removed');
    const newRun = mockRunInfo('new');
    const state = deepFreeze({
      [preserved.getRunUuid()]: preserved,
      [replacedOld.getRunUuid()]: replacedOld,
      [removed.getRunUuid()]: removed,
    });
    const action = {
      type: fulfilled(SEARCH_RUNS_API),
      payload: {
        runs: [
          { info: preserved.toJSON() },
          { info: replacedNew.toJSON() },
          { info: newRun.toJSON() },
        ],
      },
    };
    const new_state = runInfosByUuid(state, action);
    // make sure the reducer did not modify the original state
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [preserved.getRunUuid()]: preserved,
      [replacedNew.getRunUuid()]: replacedNew,
      [newRun.getRunUuid()]: newRun,
    });
  });

  test('searchRunApi correctly handles rejected search call', () => {
    const preserved = mockRunInfo('still exists');
    const replacedOld = mockRunInfo('replaced', 'old');
    const removed = mockRunInfo('removed');
    const state = deepFreeze({
      [preserved.getRunUuid()]: preserved,
      [replacedOld.getRunUuid()]: replacedOld,
      [removed.getRunUuid()]: removed,
    });
    const action = {
      type: rejected(SEARCH_RUNS_API),
      payload: undefined,
    };
    const new_state = runInfosByUuid(state, action);
    // make sure the reducer did not modify the original state
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({});
  });

  test('test load more runs', () => {
    const preserved = mockRunInfo('still exists');
    const replacedOld = mockRunInfo('replaced', 'old');
    const replacedNew = mockRunInfo('replaced', 'new');
    const removed = mockRunInfo('removed');
    const newRun = mockRunInfo('new');
    const state = deepFreeze({
      [preserved.getRunUuid()]: preserved,
      [replacedOld.getRunUuid()]: replacedOld,
      [removed.getRunUuid()]: removed,
    });
    const action = {
      type: fulfilled(LOAD_MORE_RUNS_API),
      payload: {
        runs: [
          { info: preserved.toJSON() },
          { info: replacedNew.toJSON() },
          { info: newRun.toJSON() },
        ],
      },
    };
    const new_state = runInfosByUuid(state, action);
    // make sure the reducer did not modify the original state
    expect(new_state).not.toEqual(state);
    expect(new_state).toEqual({
      [preserved.getRunUuid()]: preserved,
      [removed.getRunUuid()]: removed,
      [replacedNew.getRunUuid()]: replacedNew,
      [newRun.getRunUuid()]: newRun,
    });
  });
});

describe('test params(tags)ByRunUuid', () => {
  const key1 = 'key1';
  const key2 = 'key2';
  const key3 = 'key3';

  test('should set up initial state correctly', () => {
    expect(paramsByRunUuid(undefined, {})).toEqual({});
    expect(tagsByRunUuid(undefined, {})).toEqual({});
  });

  function newParamOrTag(tagOrParam, props) {
    if (tagOrParam === 'params') {
      return Param.fromJs(props);
    } else {
      return RunTag.fromJs(props);
    }
  }

  function newState(paramOrTag, state) {
    const res = {};
    for (const runId of Object.keys(state)) {
      res[runId] = {};
      for (const key of Object.keys(state[runId])) {
        // res[runId][key] = newParamOrTag(paramOrTag, state[runId][key])
        res[runId][key] = newParamOrTag(paramOrTag, state[runId][key]);
      }
    }
    return res;
  }

  const val1 = {
    key: key1,
    value: 'abc',
  };
  const val1_2 = {
    key: key1,
    value: 'xyz',
  };
  const val2 = {
    key: key2,
    value: 'efg',
  };
  const val3 = {
    key: key3,
    value: 'ijk',
  };

  function reduceAndTest(reducer, initial_state, expected_state, action) {
    const new_state = reducer(initial_state, action);
    expect(new_state).not.toEqual(initial_state);
    expect(new_state).toEqual(expected_state);
  }

  test('getRunApi updates empty state correctly', () => {
    const empty_state = { run01: {} };
    const expected_state = {
      run01: {
        key1: val1,
        key2: val2,
        key3: val3,
      },
    };

    function new_action(paramOrTag, vals) {
      return {
        type: fulfilled(GET_RUN_API),
        payload: {
          run: {
            info: mockRunInfo('run01', 'experiment01').toJSON(),
            data: {
              [paramOrTag]: vals,
            },
          },
        },
      };
    }

    reduceAndTest(
      paramsByRunUuid,
      undefined,
      newState('params', empty_state),
      new_action('params', undefined),
    );
    reduceAndTest(
      tagsByRunUuid,
      undefined,
      newState('tags', empty_state),
      new_action('tags'),
      undefined,
    );
    reduceAndTest(
      paramsByRunUuid,
      undefined,
      newState('params', expected_state),
      new_action('params', [val1, val2, val3]),
    );
    reduceAndTest(
      tagsByRunUuid,
      undefined,
      newState('tags', expected_state),
      new_action('tags', [val1, val2, val3]),
    );
  });

  test('getRunApi updates non empty state correctly', () => {
    const initial_state = deepFreeze({
      run01: {
        key1: val1,
        key2: val2,
        key3: val3,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    });
    const expected_state = {
      run01: {
        key1: val1,
        key3: val3,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    };

    function new_action(paramOrTag) {
      return {
        type: fulfilled(GET_RUN_API),
        payload: {
          run: {
            info: mockRunInfo('run01', 'experiment01').toJSON(),
            data: {
              [paramOrTag]: [val1, val3],
            },
          },
        },
      };
    }

    reduceAndTest(
      paramsByRunUuid,
      newState('params', initial_state),
      newState('params', expected_state),
      new_action('params'),
    );
    reduceAndTest(
      tagsByRunUuid,
      newState('tags', initial_state),
      newState('tags', expected_state),
      new_action('tags'),
    );
  });

  test('search runs and load more apis updates non empty state correctly', () => {
    const initial_state = deepFreeze({
      run01: {
        key1: val1,
        key2: val2,
        key3: val3,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    });
    const expected_state = {
      run01: {
        key1: val1_2,
        key3: val3,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
      run03: {
        key3: val3,
      },
      run04: {},
    };

    function new_action(paramOrTag, action_type) {
      return {
        type: fulfilled(action_type),
        payload: {
          runs: [
            {
              info: mockRunInfo('run01').toJSON(),
              data: { [paramOrTag]: [val1_2, val3] },
            },
            {
              info: mockRunInfo('run03').toJSON(),
              data: { [paramOrTag]: [val3] },
            },
            {
              info: mockRunInfo('run04').toJSON(),
              data: { [paramOrTag]: undefined },
            },
          ],
        },
      };
    }

    const reducers = {
      params: paramsByRunUuid,
      tags: tagsByRunUuid,
    };
    for (const paramOrTag of ['params', 'tags']) {
      for (const action_type of [SEARCH_RUNS_API, LOAD_MORE_RUNS_API]) {
        reduceAndTest(
          reducers[paramOrTag],
          newState(paramOrTag, initial_state),
          newState(paramOrTag, expected_state),
          new_action(paramOrTag, action_type),
        );
      }
    }
  });

  test('setTagApi updates empty state correctly', () => {
    const expected_state = {
      run01: {
        key1: val1,
      },
    };

    function new_action() {
      return {
        type: fulfilled(SET_TAG_API),
        meta: {
          runUuid: 'run01',
          key: key1,
          value: val1.value,
        },
      };
    }

    reduceAndTest(tagsByRunUuid, undefined, newState('tags', expected_state), new_action('tags'));
  });

  test('setTagApi updates non empty state correctly', () => {
    const initial_state = deepFreeze({
      run01: {
        key1: val1,
        key2: val2,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    });
    const expected_state = {
      run01: {
        key1: val1_2,
        key2: val2,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    };

    function new_action() {
      return {
        type: fulfilled(SET_TAG_API),
        meta: {
          runUuid: 'run01',
          key: key1,
          value: val1_2.value,
        },
      };
    }

    reduceAndTest(
      tagsByRunUuid,
      newState('tags', initial_state),
      newState('tags', expected_state),
      new_action(),
    );
  });

  test('deleteTagApi works with empty state', () => {
    const expected_state = {};

    function new_action() {
      return {
        type: fulfilled(DELETE_TAG_API),
        meta: {
          runUuid: 'run01',
          key: key1,
        },
      };
    }

    reduceAndTest(tagsByRunUuid, undefined, newState('tags', expected_state), new_action());
  });

  test('setTagApi updates non empty state correctly', () => {
    const initial_state = deepFreeze({
      run01: {
        key1: val1,
        key2: val2,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    });
    const expected_state = {
      run01: {
        key2: val2,
      },
      run02: {
        key1: val1,
        key2: val2,
      },
    };

    function new_action() {
      return {
        type: fulfilled(DELETE_TAG_API),
        meta: {
          runUuid: 'run01',
          key: key1,
        },
      };
    }

    reduceAndTest(
      tagsByRunUuid,
      newState('tags', initial_state),
      newState('tags', expected_state),
      new_action(),
    );
  });
});

describe('test artifactsByRunUuid', () => {
  test('artifacts get populated with empty query path', () => {
    const action0 = {
      type: fulfilled(LIST_ARTIFACTS_API),
      meta: {
        runUuid: 'run01',
      },
      payload: {
        files: [
          {
            path: 'root/dir1/file1',
            is_dir: false,
          },
          {
            path: 'root/dir1',
            is_dir: true,
          },
          {
            path: 'root/dir2/file2',
            is_dir: false,
          },
        ],
      },
    };
    const state1 = artifactsByRunUuid(undefined, action0);

    const dir1 = Object.assign(new ArtifactNode(), {
      children: [],
      fileInfo: {
        is_dir: true,
        path: 'root/dir1',
      },
      isLoaded: false,
      isRoot: false,
    });

    const file1 = Object.assign(new ArtifactNode(), {
      children: undefined,
      fileInfo: {
        is_dir: false,
        path: 'root/dir1/file1',
      },
      isLoaded: false,
      isRoot: false,
    });

    const file2 = Object.assign(new ArtifactNode(), {
      children: undefined,
      fileInfo: {
        is_dir: false,
        path: 'root/dir2/file2',
      },
      isLoaded: false,
      isRoot: false,
    });
    const expected_root = Object.assign(new ArtifactNode(), {
      children: {
        dir1: dir1,
        file1: file1,
        file2: file2,
      },
      fileInfo: undefined,
      isLoaded: true,
      isRoot: true,
    });
    expect(state1).toEqual({
      run01: expected_root,
    });
    const action1 = {
      type: fulfilled(LIST_ARTIFACTS_API),
      meta: {
        runUuid: 'run02',
      },
      payload: {
        files: [],
      },
    };
    const state2 = artifactsByRunUuid(state1, action1);
    expect(state2).toEqual({
      run01: expected_root,
      run02: Object.assign(new ArtifactNode(), {
        children: {},
        fileInfo: undefined,
        isLoaded: true,
        isRoot: true,
      }),
    });
    const action2 = {
      type: fulfilled(LIST_ARTIFACTS_API),
      meta: {
        runUuid: 'run01',
      },
      payload: {
        files: [
          {
            path: 'root/dir1/file1',
            is_dir: false,
          },
          {
            path: 'root/dir1',
            is_dir: true,
          },
        ],
      },
    };
    const state3 = artifactsByRunUuid(state2, action2);
    expect(state3).toEqual({
      run01: Object.assign(new ArtifactNode(), {
        children: {
          dir1: dir1,
          file1: file1,
        },
        fileInfo: undefined,
        isLoaded: true,
        isRoot: true,
      }),
      run02: Object.assign(new ArtifactNode(), {
        children: {},
        fileInfo: undefined,
        isLoaded: true,
        isRoot: true,
      }),
    });
  });
  test('artifacts get populated with query path', () => {
    const file2 = Object.assign(new ArtifactNode(), {
      children: undefined,
      fileInfo: {
        is_dir: false,
        path: 'dir1/dir2/file2',
      },
      isLoaded: false,
      isRoot: false,
    });
    const dir2 = Object.assign(new ArtifactNode(), {
      children: { file2: file2 },
      fileInfo: {
        is_dir: true,
        path: 'dir1/dir2',
      },
      isLoaded: false,
      isRoot: false,
    });
    const file1 = Object.assign(new ArtifactNode(), {
      children: undefined,
      fileInfo: {
        is_dir: false,
        path: 'dir1/file1',
      },
      isLoaded: false,
      isRoot: false,
    });
    const dir1 = Object.assign(new ArtifactNode(), {
      children: { dir2: dir2, file1: file1 },
      fileInfo: {
        is_dir: true,
        path: 'dir1',
      },
      isLoaded: true,
      isRoot: false,
    });
    const inital_root = Object.assign(new ArtifactNode(), {
      children: {
        dir1: dir1,
      },
      fileInfo: undefined,
      isLoaded: true,
      isRoot: true,
    });

    const initial_state = deepFreeze({
      run01: inital_root,
    });
    const action0 = {
      type: fulfilled(LIST_ARTIFACTS_API),
      meta: {
        runUuid: 'run01',
        path: 'dir1/dir2',
      },
      payload: {
        files: [
          {
            path: 'dir1/dir2/file3',
            is_dir: false,
          },
          {
            path: 'dir1/dir2/file4',
            is_dir: false,
          },
          {
            path: 'dir1/dir2/dir3',
            is_dir: true,
          },
        ],
      },
    };
    const next_state = artifactsByRunUuid(initial_state, action0);
    expect(next_state).not.toEqual(initial_state);
    const file3 = Object.assign(new ArtifactNode(), {
      fileInfo: {
        is_dir: false,
        path: 'dir1/dir2/file3',
      },
      isLoaded: false,
      isRoot: false,
    });
    const file4 = Object.assign(new ArtifactNode(), {
      fileInfo: {
        is_dir: false,
        path: 'dir1/dir2/file4',
      },
      isLoaded: false,
      isRoot: false,
    });

    const dir3 = Object.assign(new ArtifactNode(), {
      children: [],
      fileInfo: {
        is_dir: true,
        path: 'dir1/dir2/dir3',
      },
      isLoaded: false,
      isRoot: false,
    });
    const dir2_2 = Object.assign(new ArtifactNode(), {
      children: { dir3: dir3, file3: file3, file4: file4 },
      fileInfo: {
        is_dir: true,
        path: 'dir1/dir2',
      },
      isLoaded: true,
      isRoot: false,
    });
    const dir1_2 = Object.assign(new ArtifactNode(), {
      children: { dir2: dir2_2, file1: file1 },
      fileInfo: {
        is_dir: true,
        path: 'dir1',
      },
      isLoaded: true,
      isRoot: false,
    });
    expect(next_state).toEqual({
      run01: Object.assign(new ArtifactNode(), {
        children: {
          dir1: dir1_2,
        },
        fileInfo: undefined,
        isLoaded: true,
        isRoot: true,
      }),
    });
  });
});
describe('test artifactRootUriByRunUuid', () => {
  test('artifactRootUriByRunUuid', () => {
    const state1 = artifactRootUriByRunUuid(undefined, {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
        runUuid: 'run01',
      },
      payload: {
        run: {
          info: {
            run_uuid: 'run01',
            experiment_id: '1',
            artifact_uri: 'some/path',
          },
          data: {},
        },
      },
    });
    expect(state1).toEqual({
      run01: 'some/path',
    });
    const state2 = artifactRootUriByRunUuid(state1, {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
        runUuid: 'run02',
      },
      payload: {
        run: {
          info: {
            run_uuid: 'run02',
            experiment_id: '1',
            artifact_uri: 'some/other/path',
          },
          data: {},
        },
      },
    });
    expect(state2).toEqual({
      run01: 'some/path',
      run02: 'some/other/path',
    });
    const state3 = artifactRootUriByRunUuid(state2, {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
        runUuid: 'run02',
      },
      payload: {
        run: {
          info: {
            run_uuid: 'run02',
            experiment_id: '1',
            artifact_uri: 'some/other/updated/path',
          },
          data: {},
        },
      },
    });
    expect(state3).toEqual({
      run01: 'some/path',
      run02: 'some/other/updated/path',
    });
  });
});

describe('test experimentTagsByExperimentId', () => {
  const tag1 = { key: 'key1', value: 'value1' };
  const tag2 = { key: 'key2', value: 'value2' };
  const tag1_2 = { key: 'key1', value: 'value1_2' };
  test('get experiment api', () => {
    const empty_state = experimentTagsByExperimentId(undefined, {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: {
          experiment_id: 'experiment01',
        },
      },
    });
    expect(empty_state).toEqual({
      experiment01: {},
    });
    const state0 = experimentTagsByExperimentId(undefined, {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: {
          experiment_id: 'experiment01',
          tags: [tag1, tag2],
        },
      },
    });
    expect(state0).toEqual({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1),
        key2: ExperimentTag.fromJs(tag2),
      },
    });
    const state1 = experimentTagsByExperimentId(state0, {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: {
          experiment_id: 'experiment02',
          tags: [tag1],
        },
      },
    });
    expect(state1).toEqual({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1),
        key2: ExperimentTag.fromJs(tag2),
      },
      experiment02: {
        key1: ExperimentTag.fromJs(tag1),
      },
    });
    const state2 = experimentTagsByExperimentId(state1, {
      type: fulfilled(GET_EXPERIMENT_API),
      payload: {
        experiment: {
          experiment_id: 'experiment01',
          tags: [tag1_2],
        },
      },
    });
    expect(state2).toEqual({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1_2),
      },
      experiment02: {
        key1: ExperimentTag.fromJs(tag1),
      },
    });
  });
  test('set experiment tag api', () => {
    const initial_state = deepFreeze({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1),
        key2: ExperimentTag.fromJs(tag2),
      },
    });
    const state0 = experimentTagsByExperimentId(initial_state, {
      type: fulfilled(SET_EXPERIMENT_TAG_API),
      meta: {
        experimentId: 'experiment02',
        key: 'key1',
        value: 'value1',
      },
    });
    expect(state0).toEqual({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1),
        key2: ExperimentTag.fromJs(tag2),
      },
      experiment02: {
        key1: ExperimentTag.fromJs(tag1),
      },
    });
    const state1 = experimentTagsByExperimentId(state0, {
      type: fulfilled(SET_EXPERIMENT_TAG_API),
      meta: {
        experimentId: 'experiment01',
        key: 'key1',
        value: 'value1_2',
      },
    });
    expect(state1).toEqual({
      experiment01: {
        key1: ExperimentTag.fromJs(tag1_2),
        key2: ExperimentTag.fromJs(tag2),
      },
      experiment02: {
        key1: ExperimentTag.fromJs(tag1),
      },
    });
  });
});

describe('test public accessors', () => {
  function new_action({ type, id = 'a', runUuid = 'run01', payload = 'data' }) {
    return {
      type: type,
      meta: {
        id: id,
        runUuid: runUuid,
      },
      payload: payload,
    };
  }

  test('Experiments', () => {
    const A = Experiment.fromJs({
      experiment_id: 'a',
      name: 'A',
      tags: [{ name: 'a', value: 'A' }, 'b'],
    });
    const B = Experiment.fromJs({
      experiment_id: 'b',
      name: 'B',
    });

    const action = new_action({
      type: fulfilled(LIST_EXPERIMENTS_API),
      payload: { experiments: [A.toJSON(), B.toJSON()] },
    });
    const state = rootReducer(undefined, action);
    expect(state.entities.experimentTagsByExperimentId).toEqual({});
    expect(getExperiments(state)).toEqual([A, B]);
    expect(getExperiment(A.experiment_id, state)).toEqual(A);
    expect(getExperimentTags(B.experiment_id, state)).toEqual({});
    expect(getExperimentTags(A.experiment_id, state)).toEqual({});
  });

  test('tags, params and runinfo', () => {
    const key1 = 'key1';
    const key2 = 'key2';
    const key3 = 'key3';
    const val1 = {
      key: key1,
      value: 'abc',
    };
    const val2 = {
      key: key2,
      value: 'efg',
    };

    const val3 = {
      key: key3,
      value: 'ijk',
    };
    const action0 = new_action({
      type: fulfilled(GET_RUN_API),
      payload: {
        run: {
          info: RunInfo.fromJs({
            runUuid: 'run05',
            experiment_id: 'experiment01',
            artifact_uri: 'artifact_uri',
          }).toJSON(),
          data: {},
        },
      },
    });
    const state0 = rootReducer(undefined, action0);
    expect(getParams('run01', state0)).toEqual({});
    expect(getRunTags('run01', state0)).toEqual({});
    const action1 = {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
      },
      payload: {
        run: {
          info: mockRunInfo('run01', 'experiment01', 'articfact_uri').toJSON(),
          data: {
            params: [val1, val2],
            tags: [val2, val3],
          },
        },
      },
    };
    const state = rootReducer(undefined, action1);
    expect(getParams('run01', state)).toEqual({
      key1: Param.fromJs({ key: 'key1', value: 'abc' }),
      key2: Param.fromJs({ key: 'key2', value: 'efg' }),
    });
    expect(getRunTags('run01', state)).toEqual({
      key2: RunTag.fromJs({ key: 'key2', value: 'efg' }),
      key3: RunTag.fromJs({ key: 'key3', value: 'ijk' }),
    });
    expect(getRunInfo('run05', state)).toEqual(undefined);
    expect(getRunInfo('run01', state)).toEqual(
      RunInfo.fromJs({
        artifact_uri: 'articfact_uri',
        end_time: undefined,
        experiment_id: 'experiment01',
        lifecycle_stage: undefined,
        run_uuid: 'run01',
        start_time: undefined,
        status: undefined,
        user_id: undefined,
      }),
    );
  });

  test('get apis', () => {
    const state0 = rootReducer(
      undefined,
      new_action({
        type: pending(GET_RUN_API),
        id: 'a',
      }),
    );
    const state1 = rootReducer(
      state0,
      new_action({
        type: pending(GET_RUN_API),
        id: 'b',
      }),
    );
    const state2 = rootReducer(
      state1,
      new_action({
        type: pending(GET_RUN_API),
        id: 'c',
      }),
    );
    expect(getApis([], undefined)).toEqual([]);
    expect(getApis(['a', 'b'], state2)).toEqual([
      { id: 'a', active: true },
      { id: 'b', active: true },
    ]);
    expect(getApis(['a', 'b', 'c'], state2)).toEqual([
      { id: 'a', active: true },
      { id: 'b', active: true },
      { id: 'c', active: true },
    ]);
    expect(getApis(['c', 'a'], state2)).toEqual([
      { id: 'c', active: true },
      { id: 'a', active: true },
    ]);
  });

  test('get artifact root', () => {
    const state0 = rootReducer(undefined, {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
        runUuid: 'run01',
      },
      payload: {
        run: {
          info: {
            run_uuid: 'run01',
            experiment_id: '1',
            artifact_uri: 'some/path',
          },
          data: {},
        },
      },
    });
    expect(getArtifactRootUri('run01', state0)).toEqual('some/path');
  });

  test('get artifacts', () => {
    const state0 = rootReducer(
      undefined,
      new_action({
        type: fulfilled(LIST_ARTIFACTS_API),
        runUuid: 'run01',
        payload: {
          files: [
            {
              path: 'file1',
              is_dir: false,
            },
          ],
        },
      }),
    );
    expect(getArtifacts('run01', state0)).toEqual(
      Object.assign(new ArtifactNode(), {
        children: {
          file1: Object.assign(new ArtifactNode(), {
            children: undefined,
            fileInfo: { is_dir: false, path: 'file1' },
            isLoaded: false,
            isRoot: false,
          }),
        },
        fileInfo: undefined,
        isLoaded: true,
        isRoot: true,
      }),
    );
  });

  test('getSharedParamKeysByRunUuids', () => {
    const runA = RunInfo.fromJs({
      run_uuid: 'run01',
      experiment_id: '1',
    });
    const runB = RunInfo.fromJs({
      run_uuid: 'run02',
      experiment_id: '1',
    });
    const actionA = {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
      },
      payload: {
        run: {
          info: runA.toJSON(),
          data: {
            params: [
              {
                key: 'A',
                value: 'a',
              },
              {
                key: 'B',
                value: 'b',
              },
            ],
          },
        },
      },
    };
    const actionB = {
      type: fulfilled(GET_RUN_API),
      meta: {
        id: 'a',
      },
      payload: {
        run: {
          info: runB.toJSON(),
          data: {
            params: [
              {
                key: 'B',
                value: 'b',
              },
              {
                key: 'C',
                value: 'c',
              },
            ],
          },
        },
      },
    };
    const state0 = rootReducer(undefined, actionA);
    const state1 = rootReducer(state0, actionB);
    expect(getSharedParamKeysByRunUuids(['run01', 'run02'], state1)).toEqual(['B']);
    expect(getAllParamKeysByRunUuids(['run01', 'run02'], state1)).toEqual(['A', 'B', 'C']);
  });
});

describe('test apis', () => {
  function new_action(t, id = 'a') {
    return {
      type: t,
      meta: {
        id: id,
      },
      payload: 'payload',
    };
  }

  test('all action states', () => {
    const state0 = apis(undefined, new_action(pending(GET_RUN_API)));
    expect(state0).toEqual({
      a: {
        id: 'a',
        active: true,
      },
    });
    const state1 = apis(state0, new_action(fulfilled(GET_RUN_API)));
    expect(state1).toEqual({
      a: {
        id: 'a',
        active: false,
        data: 'payload',
      },
    });
    const state2 = apis(state0, new_action(rejected(GET_RUN_API)));
    expect(state2).toEqual({
      a: {
        id: 'a',
        active: false,
        error: 'payload',
      },
    });
  });
});

{'repo_name': 'mlflow/mlflow', 'stars': '6938', 'repo_language': 'Python', 'file_name': 'config.yml', 'mime_type': 'text/plain', 'hash': 3500208804309742903, 'source_dataset': 'data'}


# expect.installTheme(...)

Install a [MagicPen](https://github.com/sunesimonsen/magicpen) theme into the expect instance,
so that it's used when rendering error messages and diffs.

Proxies through to [magicPen.installTheme](https://github.com/sunesimonsen/magicpen#installthemetheme-installthemeformat-theme-installthemeformats-theme). See the documentation there.

Example:

```js
expect.installTheme({
  styles: {
    ugliness: 'yellow',
    jsKeyword: 'ugliness',
  },
});

expect(function foo() {}, 'to throw', 'bar');
```

```output
expected function foo() {} to throw 'bar'
  expected function foo() {} to throw
    did not throw
```

{'repo_name': 'unexpectedjs/unexpected', 'stars': '332', 'repo_language': 'JavaScript', 'file_name': 'expect.spec.js', 'mime_type': 'text/plain', 'hash': 6264468020200723935, 'source_dataset': 'data'}


<?php

namespace Drupal\file\Plugin\migrate\process\d6;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @MigrateProcessPlugin(
 *   id = "d6_cck_file"
 * )
 */
class CckFile extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  /**
   * The migration process plugin, configured for lookups in d6_file.
   *
   * @var \Drupal\migrate\Plugin\MigrateProcessInterface
   */
  protected $migrationPlugin;

  /**
   * Constructs a CckFile plugin instance.
   *
   * @param array $configuration
   *   The plugin configuration.
   * @param string $plugin_id
   *   The plugin ID.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
   *   The current migration.
   * @param \Drupal\migrate\Plugin\MigrateProcessInterface $migration_plugin
   *   An instance of the 'migration' process plugin.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrateProcessInterface $migration_plugin) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->migration = $migration;
    $this->migrationPlugin = $migration_plugin;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
    // Configure the migration process plugin to look up migrated IDs from
    // a d6 file migration.
    $migration_plugin_configuration = $configuration + [
      'migration' => 'd6_file',
      'source' => ['fid'],
    ];

    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $migration,
      $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_plugin_configuration, $migration)
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $options = unserialize($value['data']);

    // Try to look up the ID of the migrated file. If one cannot be found, it
    // means the file referenced by the current field item did not migrate for
    // some reason -- file migration is notoriously brittle -- and we do NOT
    // want to send invalid file references into the field system (it causes
    // fatals), so return an empty item instead.
    if ($fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property)) {
      return [
        'target_id' => $fid,
        'display' => $value['list'],
        'description' => isset($options['description']) ? $options['description'] : '',
        'alt' => isset($options['alt']) ? $options['alt'] : '',
        'title' => isset($options['title']) ? $options['title'] : '',
      ];
    }
    else {
      return [];
    }
  }

}

{'repo_name': 'fossasia/phimpme-drupal', 'stars': '1111', 'repo_language': 'PHP', 'file_name': 'jquery.ui.datepicker.css', 'mime_type': 'text/plain', 'hash': -3249872462053115735, 'source_dataset': 'data'}


//
//  AppDelegate.swift
//  VividDemo
//
//  Created by YuAo on 1/30/16.
//  Copyright © 2016 YuAo. All rights reserved.
//

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true
    }

}

{'repo_name': 'YuAo/Vivid', 'stars': '449', 'repo_language': 'Objective-C', 'file_name': 'Main.storyboard', 'mime_type': 'text/xml', 'hash': -2211656213167653846, 'source_dataset': 'data'}


/** <title>GSModelLoaderFactory</title>

   <abstract>Model loader framework</abstract>

   Copyright (C) 1997, 1999 Free Software Foundation, Inc.

   Author:  Gregory John Casamento <greg_casamento@yahoo.com>
   Date: 2005

   This file is part of the GNUstep GUI Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; see the file COPYING.LIB.
   If not, see <http://www.gnu.org/licenses/> or write to the
   Free Software Foundation, 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#import "config.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSString.h>

#import "GNUstepGUI/GSModelLoaderFactory.h"

@implementation GSModelLoader
+ (NSString *) type
{
  return nil;
}

+ (float) priority
{
  return 0.0;
}

- (BOOL) loadModelData: (NSData *)data
     externalNameTable: (NSDictionary *)context
              withZone: (NSZone *)zone
{
  [NSException raise: NSInternalInconsistencyException
	       format: @"Abstract model loader."];
  return NO;
}

- (BOOL) loadModelFile: (NSString *)fileName
     externalNameTable: (NSDictionary *)context
              withZone: (NSZone *)zone
{
  NSData *data = [self dataForFile: fileName];

  if (data != nil)
    {
      BOOL loaded = [self loadModelData: data
                      externalNameTable: context
                               withZone: zone];
      if (!loaded)
        NSLog(@"Could not load Nib file: %@", fileName);
      return loaded;
    }
  else
    {
      return NO;
    }
}

- (NSData *) dataForFile: (NSString *)fileName
{
  return [NSData dataWithContentsOfFile: fileName];
}

+ (NSComparisonResult) _comparePriority: (Class)loader
{
  NSComparisonResult result = NSOrderedSame;

  if ([self priority] < [loader priority])
    {
      result = NSOrderedAscending;
    }
  if ([self priority] > [loader priority])
    {
      result = NSOrderedDescending;
    }

  return result;
}
@end

static NSMutableDictionary *_modelMap = nil;

@implementation GSModelLoaderFactory
+ (void) initialize
{
  NSArray *classes = GSObjCAllSubclassesOfClass([GSModelLoader class]);
  NSEnumerator *en = [classes objectEnumerator];
  Class cls = nil;

  while ((cls = [en nextObject]) != nil)
    {
      [self registerModelLoaderClass: cls];
    }
}

+ (void) registerModelLoaderClass: (Class)aClass
{
  if (_modelMap == nil)
    {
      _modelMap = [[NSMutableDictionary alloc] initWithCapacity: 5];
    }

  [_modelMap setObject: aClass forKey: (NSString *)[aClass type]];
}

+ (Class)classForType: (NSString *)type
{
  return [_modelMap objectForKey: type];
}

+ (NSArray *) supportedTypes
{
  NSArray *objectArray = [_modelMap allValues];
  NSArray *sortedArray = [objectArray sortedArrayUsingSelector:
					    @selector(_comparePriority:)];
  NSEnumerator *oen = [sortedArray objectEnumerator];
  Class cls = nil;
  NSMutableArray *types = [[NSMutableArray alloc] init];

  while ((cls = [oen nextObject]) != nil)
    {
      [types addObject: [cls type]];
    }

  return AUTORELEASE(types);
}

+ (NSString *) supportedModelFileAtPath: (NSString *)modelPath
{
  NSString *result = nil;
  NSFileManager	*mgr = [NSFileManager defaultManager];
  NSString *ext = [modelPath pathExtension];

  if ([ext isEqual: @""])
    {
      NSArray *objectArray = [_modelMap allValues];
      NSArray *sortedArray = [objectArray sortedArrayUsingSelector:
					    @selector(_comparePriority:)];
      NSEnumerator *oen = [sortedArray objectEnumerator];
      Class cls = nil;

      while ((cls = [oen nextObject]) != nil && result == nil)
	{
	  NSString *path = [modelPath stringByAppendingPathExtension:
					(NSString *)[cls type]];
	  if ([mgr isReadableFileAtPath: path])
	    {
	      result = path;
	    }
	}
    }
  else
    {
      if ([_modelMap objectForKey: ext] != nil)
	{
	  if ([mgr isReadableFileAtPath: modelPath])
	    {
	      result = modelPath;
	    }
	}
    }

  return result;
}

+ (GSModelLoader *) modelLoaderForFileType: (NSString *)type
{
  Class aClass = [GSModelLoaderFactory classForType: type];
  GSModelLoader *loader = nil;

  if (aClass != nil)
    {
      loader = AUTORELEASE([[aClass alloc] init]);
    }
  else
    {
      [NSException raise: NSInternalInconsistencyException
		   format: @"Unable to find model loader class."];
    }

  return loader;
}

+ (GSModelLoader *) modelLoaderForFileName: (NSString *)modelPath
{
  NSString *path = [GSModelLoaderFactory supportedModelFileAtPath: modelPath];
  GSModelLoader *result = nil;

  if (path != nil)
    {
      NSString *ext = [path pathExtension];
      result = [self modelLoaderForFileType: ext];
    }

  return result;
}
@end

{'repo_name': 'gnustep/libs-gui', 'stars': '124', 'repo_language': 'Objective-C', 'file_name': 'testcopy.m', 'mime_type': 'text/x-objective-c', 'hash': -8577748581883257717, 'source_dataset': 'data'}


#!/usr/bin/env python

# Copyright (c) 2016 The Khronos Group Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and/or associated documentation files (the
# "Materials"), to deal in the Materials without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Materials, and to
# permit persons to whom the Materials are furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Materials.
#
# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

"""
  Generator for fboinvalidate* tests.
  This file needs to be run in its folder.
"""

import sys

_DO_NOT_EDIT_WARNING = """

"""

_HTML_TEMPLATE = """

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL FBO Invalidate Conformance Tests</title>
<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>

<canvas id="canvas" width="128" height="128"> </canvas>

"""

_GROUPS = [
    'default',
    'whole',
    'sub',
    'format',
    'target',
]

_GROUP_TEST_COUNTS = [
    1,
    1,
    1,
    3,
    1
]

def GenerateFilename(group, count, index):
  """Generate test filename."""
  filename = group
  assert index >= 0 and index < count
  if count > 1:
    index_str = str(index)
    if index < 10:
      index_str = "0" + index_str
    filename += "_" + index_str
  filename += ".html"
  return filename

def WriteTest(filename, start, end):
  """Write one test."""
  file = open(filename, "wb")
  file.write(_DO_NOT_EDIT_WARNING)
  file.write(_HTML_TEMPLATE % {
    'start': start,
    'end': end
  })
  file.close

def GenerateTests():
  """Generate all tests."""
  assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
  test_index = 0
  filelist = []
  for ii in range(len(_GROUPS)):
    group = _GROUPS[ii]
    count = _GROUP_TEST_COUNTS[ii]
    for index in range(count):
      filename = GenerateFilename(group, count, index)
      filelist.append(filename)
      WriteTest(filename, test_index, test_index + 1)
      test_index += 1
  return filelist

def GenerateTestList(filelist):
  file = open("00_test_list.txt", "wb")
  file.write('\n'.join(filelist))
  file.close

def main(argv):
  """This is the main function."""
  filelist = GenerateTests()
  GenerateTestList(filelist)

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))

{'repo_name': 'KhronosGroup/WebGL', 'stars': '1716', 'repo_language': 'HTML', 'file_name': 'smoothstep_float_vert_xvary_edgeconstquarter.vert', 'mime_type': 'text/plain', 'hash': -6717186357371834845, 'source_dataset': 'data'}


libsodium._crypto_stream_chacha20_xor_ic(output_message_address, input_message_address, input_message_length, 0, nonce_address, nonce_increment, 0, key_address)

{'repo_name': 'jedisct1/libsodium.js', 'stars': '575', 'repo_language': 'HTML', 'file_name': 'core6.html', 'mime_type': 'text/html', 'hash': -8077917820876219963, 'source_dataset': 'data'}