def _testAPISchema(self, api_schema_graph):
   self.assertEqual(LookupResult(True, None),
                    api_schema_graph.Lookup('tabs', 'properties',
                                            'TAB_PROPERTY_ONE'))
   self.assertEqual(LookupResult(True, None),
                    api_schema_graph.Lookup('tabs', 'types', 'Tab'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'functions', 'get',
                                           'parameters', 'tab'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'functions', 'get',
                                           'parameters', 'tabId'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'functions', 'get',
                                           'parameters', 'tab', 'type'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'events',
                                           'onActivated', 'parameters',
                                           'activeInfo'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'events', 'onUpdated',
                                           'parameters', 'updateInfo'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'properties',
                                           'lowercase', 'properties',
                                           'one', 'value'))
   self.assertEqual(LookupResult(True, None),
                   api_schema_graph.Lookup('tabs', 'properties',
                                           'lowercase', 'properties',
                                           'two', 'description'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('windows'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('tabs', 'properties',
                                            'TAB_PROPERTY_DEUX'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('tabs', 'events', 'onActivated',
                                            'parameters', 'callback'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('tabs', 'functions', 'getById',
                                            'parameters', 'tab'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('tabs', 'functions', 'get',
                                            'parameters', 'type'))
   self.assertEqual(LookupResult(False, None),
                    api_schema_graph.Lookup('tabs', 'properties',
                                            'lowercase', 'properties',
                                            'two', 'value'))
 def testSubtractSuperset(self):
   difference = APISchemaGraph(API_SCHEMA).Subtract(APISchemaGraph({
     'tabs': {
       'namespace': {},
       'properties': {
         'lowercase': {
           'properties': {
             'one': { 'value': {} },
             'two': { 'description': {} }
           }
         },
         'TAB_PROPERTY_ONE': { 'value': {} },
         'TAB_PROPERTY_TWO': {},
         'TAB_PROPERTY_THREE': {}
       },
       'types': {
         'Tab': {
           'id': {},
           'properties': {
             'id': {},
             'url': {}
           }
         },
         'UpdateInfo': {}
       },
       'functions': {
         'get': {
           'name': {},
           'parameters': {
             'tab': { 'name': {},
                      'type': {},
                      'description': {}
                    },
             'tabId': { 'name': {} }
           }
         },
         'getById': {
           'parameters': {
             'tabId': {}
           }
         }
       },
       'events': {
         'onActivated': {
           'name': {},
           'parameters': {
             'activeInfo': { 'name': {} }
           }
         },
         'onUpdated': {
           'name': {},
           'parameters': {
             'updateInfo': { 'name': {} }
           }
         },
         'onClicked': {
           'name': {},
           'parameters': {
             'clickInfo': {}
           }
         }
       }
     }
   }))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'properties',
                                      'TAB_PROPERTY_TWO'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'properties'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'types', 'Tab', 'properties',
                                      'url'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'types', 'Tab', 'properties',
                                      'id'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'events', 'onUpdated',
                                      'parameters', 'updateInfo'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'properties',
                                      'TAB_PROPERTY_ONE'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('tabs', 'functions', 'get',
                                      'parameters', 'tabId'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('events', 'onUpdated', 'parameters',
                                      'updateInfo'))
  def testUpdate(self):
    result = APISchemaGraph(API_SCHEMA)
    to_add = APISchemaGraph({
      'tabs': {
        'properties': {
          'TAB_PROPERTY_THREE': { 'description': 'better than two' },
          'TAB_PROPERTY_FOUR': { 'value': 4 }
        },
        'functions': {
        'get': {
          'name': {},
          'parameters': {
            'tab': {
              'type': {},
              'name': {},
              'description': {},
              'surprise': {}
            }
          }
        },
          'getAllInWindow': {
            'parameters': {
              'windowId': { 'type': 'object' }
            }
          }
        }
      }
    })
    result.Update(to_add, lambda _: 'first')
    # Looking up elements that were originally available in |result|. Because
    # of this, no |annotation| object should be attached to the LookupResult
    # object.
    self.assertEqual(LookupResult(True, None),
                     result.Lookup('tabs'))
    self.assertEqual(LookupResult(True, None),
                     result.Lookup('tabs', 'functions', 'get',
                                   'parameters'))
    self.assertEqual(LookupResult(True, None),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_ONE'))
    self.assertEqual(LookupResult(True, None),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_ONE'))
    self.assertEqual(LookupResult(True, None),
                     result.Lookup('tabs', 'functions', 'get',
                                   'parameters', 'tabId'))

    # Looking up elements that were just added to |result|.
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_THREE'))
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_FOUR'))
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'functions', 'getAllInWindow',
                                   'parameters', 'windowId'))
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'functions', 'get', 'parameters',
                                   'tab', 'surprise'))

    to_add = APISchemaGraph({
      'tabs': {
        'properties': {
          'TAB_PROPERTY_FIVE': { 'description': 'stayin\' alive' }
        },
        'functions': {
          'getAllInWindow': {
            'parameters': {
              'callback': { 'type': 'function' }
            }
          }
        }
      }
    })
    result.Update(to_add, lambda _: 'second')
    # Looking up the second group of elements added to |result|.
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_FOUR'))
    self.assertEqual(LookupResult(True, 'second'),
                     result.Lookup('tabs', 'properties',
                                   'TAB_PROPERTY_FIVE'))
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'functions',
                                   'getAllInWindow', 'parameters',
                                   'windowId'))
    self.assertEqual(LookupResult(True, 'second'),
                     result.Lookup('tabs', 'functions',
                                   'getAllInWindow', 'parameters',
                                   'callback'))
    self.assertEqual(LookupResult(True, 'first'),
                     result.Lookup('tabs', 'functions',
                                   'getAllInWindow'))
 def testSubtractDisjointSet(self):
   difference = APISchemaGraph(API_SCHEMA).Subtract(APISchemaGraph({
     'contextMenus': {
       'properties': {
         'CONTEXT_MENU_PROPERTY_ONE': {}
       },
       'types': {
         'Menu': {
           'properties': {
             'id': {},
             'width': {}
           }
         }
       },
       'functions': {
         'get': {
           'parameters': {
             'callback': {}
           }
         }
       },
       'events': {
         'onClicked': {
           'parameters': {
             'clickInfo': {}
           }
         },
         'onUpdated': {
           'parameters': {
             'updateInfo': {}
           }
         }
       }
     }
   }))
   self.assertEqual(LookupResult(True, None),
                    difference.Lookup('tabs', 'properties',
                                     'TAB_PROPERTY_ONE'))
   self.assertEqual(LookupResult(True, None),
                   difference.Lookup('tabs', 'functions', 'get',
                                     'parameters', 'tab'))
   self.assertEqual(LookupResult(True, None),
                    difference.Lookup('tabs', 'events', 'onUpdated',
                                     'parameters', 'updateInfo'))
   self.assertEqual(LookupResult(True, None),
                    difference.Lookup('tabs', 'functions', 'get',
                                     'parameters', 'tabId'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'properties',
                                      'CONTEXT_MENU_PROPERTY_ONE'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'types', 'Menu'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'types', 'Menu',
                                      'properties', 'id'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'functions'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'events', 'onClicked',
                                      'parameters', 'clickInfo'))
   self.assertEqual(LookupResult(False, None),
                    difference.Lookup('contextMenus', 'events', 'onUpdated',
                                      'parameters', 'updateInfo'))