You are here

public function AdvAggJavaScriptTestCase::testJavaScriptAlwaysUsejQuery in Advanced CSS/JS Aggregation 7.2

Test the 'javascript_always_use_jquery' variable.

File

tests/advagg.test, line 813
Tests for advagg.module.

Class

AdvAggJavaScriptTestCase
Tests for the JavaScript system.

Code

public function testJavaScriptAlwaysUsejQuery() {

  // The default front page of the site should use jQuery and other standard
  // scripts and settings.
  advagg_test_reset_statics();
  $GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
  $GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
  $GLOBALS['conf']['advagg_force_https_path'] = FALSE;
  $GLOBALS['conf']['advagg_mod_js_footer'] = 0;
  $this
    ->drupalGet('');
  $this
    ->assertRaw('misc/jquery.js', 'Default behavior: The front page of the site includes jquery.js.');
  $this
    ->assertRaw('misc/drupal.js', 'Default behavior: The front page of the site includes drupal.js.');
  $this
    ->assertRaw('Drupal.settings', 'Default behavior: The front page of the site includes Drupal settings.');
  $this
    ->assertRaw('basePath', 'Default behavior: The front page of the site includes the basePath Drupal setting.');

  //
  // The default front page should not use jQuery and other standard scripts
  // and settings when the 'javascript_always_use_jquery' variable is set to
  // FALSE.
  advagg_test_reset_statics();
  variable_set('javascript_always_use_jquery', FALSE);
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->drupalGet('');
  $this
    ->assertNoRaw('misc/jquery.js', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include jquery.js.');
  $this
    ->assertNoRaw('misc/drupal.js', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include drupal.js.');
  $this
    ->assertNoRaw('Drupal.settings', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include Drupal settings.');
  $this
    ->assertNoRaw('basePath', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include the basePath Drupal setting.');
  variable_del('javascript_always_use_jquery');

  //
  // When only settings have been added via drupal_add_js(), drupal_get_js()
  // should still return jQuery and other standard scripts and settings.
  advagg_test_reset_statics();
  drupal_add_js(array(
    'testJavaScriptSetting' => 'test',
  ), 'setting');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'testJavaScriptSetting') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes the added Drupal settings.');

  //
  // When only settings have been added via drupal_add_js() and the
  // 'javascript_always_use_jquery' variable is set to FALSE, drupal_get_js()
  // should not return jQuery and other standard scripts and settings, nor
  // should it return the requested settings (since they cannot actually be
  // added to the page without jQuery).
  advagg_test_reset_statics();
  variable_set('javascript_always_use_jquery', FALSE);
  drupal_add_js(array(
    'testJavaScriptSetting' => 'test',
  ), 'setting');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'testJavaScriptSetting') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include the added Drupal settings.');
  variable_del('javascript_always_use_jquery');

  //
  // When a regular file has been added via drupal_add_js(), drupal_get_js()
  // should return jQuery and other standard scripts and settings.
  advagg_test_reset_statics();
  drupal_add_js('misc/collapse.js');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the custom file.');

  //
  // When a regular file has been added via drupal_add_js() and the
  // 'javascript_always_use_jquery' variable is set to FALSE, drupal_get_js()
  // should still return jQuery and other standard scripts and settings
  // (since the file is assumed to require jQuery by default).
  advagg_test_reset_statics();
  variable_set('javascript_always_use_jquery', FALSE);
  drupal_add_js('misc/collapse.js');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the custom file.');
  variable_del('javascript_always_use_jquery');

  //
  // When a file that does not require jQuery has been added via
  // drupal_add_js(), drupal_get_js() should still return jQuery and other
  // standard scripts and settings by default.
  advagg_test_reset_statics();
  drupal_add_js('misc/collapse.js', array(
    'requires_jquery' => FALSE,
  ));
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the custom file.');

  //
  // When a file that does not require jQuery has been added via
  // drupal_add_js() and the 'javascript_always_use_jquery' variable is set
  // to FALSE, drupal_get_js() should not return jQuery and other standard
  // scripts and setting, but it should still return the requested file.
  advagg_test_reset_statics();
  variable_set('javascript_always_use_jquery', FALSE);
  drupal_add_js('misc/collapse.js', array(
    'requires_jquery' => FALSE,
  ));
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the custom file.');
  variable_del('javascript_always_use_jquery');

  //
  // When 'javascript_always_use_jquery' is set to FALSE and a file that does
  // not require jQuery is added, followed by one that does, drupal_get_js()
  // should return jQuery and other standard scripts and settings, in
  // addition to both of the requested files.
  advagg_test_reset_statics();
  variable_set('javascript_always_use_jquery', FALSE);
  drupal_add_js('misc/collapse.js', array(
    'requires_jquery' => FALSE,
  ));
  drupal_add_js('misc/ajax.js');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes jquery.js.');
  $this
    ->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes drupal.js.');
  $this
    ->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes Drupal.settings.');
  $this
    ->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the basePath Drupal setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the first custom file.');
  $this
    ->assertTrue(strpos($javascript, 'misc/ajax.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the second custom file.');
  variable_del('javascript_always_use_jquery');

  //
  // Tests JavaScript aggregation when files are added to a different scope.
  advagg_test_reset_statics();

  // Enable JavaScript aggregation.
  variable_set('preprocess_js', 1);

  // Add two JavaScript files to the current request and build the cache.
  drupal_add_js('misc/ajax.js');
  drupal_add_js('misc/autocomplete.js');
  $js_items = drupal_add_js();
  drupal_build_js_cache(array(
    'misc/ajax.js' => $js_items['misc/ajax.js'],
    'misc/autocomplete.js' => $js_items['misc/autocomplete.js'],
  ));

  // Store the expected key for the first item in the cache.
  $cache = array_keys(variable_get('drupal_js_cache_files', array()));
  $expected_key = $cache[0];

  // Reset variables and add a file in a different scope first.
  variable_del('drupal_js_cache_files');
  advagg_test_reset_statics();
  drupal_add_js('some/custom/javascript_file.js', array(
    'scope' => 'footer',
  ));
  drupal_add_js('misc/ajax.js');
  drupal_add_js('misc/autocomplete.js');

  // Rebuild the cache.
  $js_items = drupal_add_js();
  drupal_build_js_cache(array(
    'misc/ajax.js' => $js_items['misc/ajax.js'],
    'misc/autocomplete.js' => $js_items['misc/autocomplete.js'],
  ));

  // Compare the expected key for the first file to the current one.
  $cache = array_keys(variable_get('drupal_js_cache_files', array()));
  $key = $cache[0];
  $this
    ->assertEqual($key, $expected_key, 'JavaScript aggregation is not affected by ordering in different scopes.');
  variable_set('preprocess_js', 0);

  //
  // Test JavaScript ordering.
  advagg_test_reset_statics();

  // Add a bunch of JavaScript in strange ordering.
  drupal_add_js('(function($){alert("Weight 5 #1");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => 5,
  ));
  drupal_add_js('(function($){alert("Weight 0 #1");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
  ));
  drupal_add_js('(function($){alert("Weight 0 #2");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
  ));
  drupal_add_js('(function($){alert("Weight -8 #1");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => -8,
  ));
  drupal_add_js('(function($){alert("Weight -8 #2");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => -8,
  ));
  drupal_add_js('(function($){alert("Weight -8 #3");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => -8,
  ));
  drupal_add_js('http://example.com/example.js?Weight -5 #1', array(
    'type' => 'external',
    'scope' => 'footer',
    'weight' => -5,
  ));
  drupal_add_js('(function($){alert("Weight -8 #4");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => -8,
  ));
  drupal_add_js('(function($){alert("Weight 5 #2");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => 5,
  ));
  drupal_add_js('(function($){alert("Weight 0 #3");})(jQuery);', array(
    'type' => 'inline',
    'scope' => 'footer',
  ));

  // Construct the expected result from the regex.
  $expected = array(
    "-8 #1",
    "-8 #2",
    "-8 #3",
    "-8 #4",
    // -5 #1: The external script.
    "-5 #1",
    "0 #1",
    "0 #2",
    "0 #3",
    "5 #1",
    "5 #2",
  );

  // Retrieve the rendered JavaScript and test against the regex.
  $render_array = advagg_get_js('footer');
  $js = drupal_render($render_array);
  $matches = array();
  if (preg_match_all('/Weight\\s([-0-9]+\\s[#0-9]+)/', $js, $matches)) {
    $result = $matches[1];
  }
  else {
    $result = array();
  }
  $this
    ->assertIdentical($result, $expected, 'JavaScript is added in the expected weight order.');

  //
  // Test default JavaScript is empty.
  advagg_test_reset_statics();
  $this
    ->assertEqual(array(), drupal_add_js(), 'Default JavaScript is empty.');

  //
  // Test drupal_get_js() for JavaScript settings.
  advagg_test_reset_statics();

  // Only the second of these two entries should appear in Drupal.settings.
  drupal_add_js(array(
    'commonTest' => 'commonTestShouldNotAppear',
  ), 'setting');
  drupal_add_js(array(
    'commonTest' => 'commonTestShouldAppear',
  ), 'setting');

  // All three of these entries should appear in Drupal.settings.
  drupal_add_js(array(
    'commonTestArray' => array(
      'commonTestValue0',
    ),
  ), 'setting');
  drupal_add_js(array(
    'commonTestArray' => array(
      'commonTestValue1',
    ),
  ), 'setting');
  drupal_add_js(array(
    'commonTestArray' => array(
      'commonTestValue2',
    ),
  ), 'setting');

  // Only the second of these two entries should appear in Drupal.settings.
  drupal_add_js(array(
    'commonTestArray' => array(
      'key' => 'commonTestOldValue',
    ),
  ), 'setting');
  drupal_add_js(array(
    'commonTestArray' => array(
      'key' => 'commonTestNewValue',
    ),
  ), 'setting');
  $render_array = advagg_get_js('header');
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'basePath') > 0, 'Rendered JavaScript header returns basePath setting.');
  $this
    ->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, 'Rendered JavaScript header includes jQuery.');
  $this
    ->assertTrue(strpos($javascript, 'pathPrefix') > 0, 'Rendered JavaScript header returns pathPrefix setting.');

  // Test whether drupal_add_js can be used to override a previous setting.
  $this
    ->assertTrue(strpos($javascript, 'commonTestShouldAppear') > 0, 'Rendered JavaScript header returns custom setting.');
  $this
    ->assertTrue(strpos($javascript, 'commonTestShouldNotAppear') === FALSE, 'drupal_add_js() correctly overrides a custom setting.');

  // Test whether drupal_add_js can be used to add numerically indexed values
  // to an array.
  $array_values_appear = strpos($javascript, 'commonTestValue0') > 0 && strpos($javascript, 'commonTestValue1') > 0 && strpos($javascript, 'commonTestValue2') > 0;
  $this
    ->assertTrue($array_values_appear, 'drupal_add_js() correctly adds settings to the end of an indexed array.');

  // Test whether drupal_add_js can be used to override the entry for an
  // existing key in an associative array.
  $associative_array_override = strpos($javascript, 'commonTestNewValue') > 0 && strpos($javascript, 'commonTestOldValue') === FALSE;
  $this
    ->assertTrue($associative_array_override, 'drupal_add_js() correctly overrides settings within an associative array.');

  //
  // Test rendering an external JavaScript file.
  advagg_test_reset_statics();
  $GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
  $GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
  $GLOBALS['conf']['advagg_force_https_path'] = FALSE;
  $external = 'http://example.com/example.js';
  drupal_add_js($external, 'external');
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);

  // Local files have a base_path() prefix, external files should not.
  $this
    ->assertTrue(strpos($javascript, 'src="' . $external) > 0, 'Rendering an external JavaScript file.');

  //
  // Test drupal_get_js() with a footer scope.
  advagg_test_reset_statics();
  $inline = 'jQuery(function () { });';
  drupal_add_js($inline, array(
    'type' => 'inline',
    'scope' => 'footer',
  ));
  $render_array = advagg_get_js('footer');
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, $inline) > 0, 'Rendered JavaScript footer returns the inline code.');

  //
  // Ensures that vertical-tabs.js is included before collapse.js.
  advagg_test_reset_statics();
  $this
    ->drupalGet('form_test/vertical-tabs');
  $position1 = strpos($this->content, 'misc/vertical-tabs.js');
  $position2 = strpos($this->content, 'misc/collapse.js');
  $this
    ->assertTrue($position1 !== FALSE && $position2 !== FALSE && $position1 < $position2, 'vertical-tabs.js is included before collapse.js');

  //
  // Test rendering the JavaScript with a file's weight above jQuery's.
  advagg_test_reset_statics();

  // JavaScript files are sorted first by group, then by the 'every_page'
  // flag, then by weight (see drupal_sort_css_js()), so to test the effect of
  // weight, we need the other two options to be the same.
  drupal_add_js('misc/collapse.js', array(
    'group' => JS_LIBRARY,
    'every_page' => TRUE,
    'weight' => -21,
  ));
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), 'Rendering a JavaScript file above jQuery.');

  //
  // Test altering a JavaScript's weight via hook_js_alter().
  advagg_test_reset_statics();

  // Add both tableselect.js and simpletest.js, with a larger weight on
  // SimpleTest.
  drupal_add_js('misc/tableselect.js');
  drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array(
    'weight' => 9999,
  ));

  // Render the JavaScript, testing if simpletest.js was altered to be before
  // tableselect.js. See simpletest_js_alter() to see where this alteration
  // takes place.
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'simpletest.js') < strpos($javascript, 'misc/tableselect.js'), 'Altering JavaScript weight through the alter hook.');

  //
  // Adds a library to the page and tests for both its JavaScript and its CSS.
  advagg_test_reset_statics();
  $result = drupal_add_library('system', 'farbtastic');
  $this
    ->assertTrue($result !== FALSE, 'Library was added without errors.');
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $render_array = advagg_get_css();
  $styles = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), 'JavaScript of library was added to the page.');
  $this
    ->assertTrue(strpos($styles, 'misc/farbtastic/farbtastic.css'), 'Stylesheet of library was added to the page.');

  //
  // Adds a JavaScript library to the page and alters it.
  advagg_test_reset_statics();

  // Verify that common_test altered the title of Farbtastic.
  $library = drupal_get_library('system', 'farbtastic');
  $this
    ->assertEqual($library['title'], 'Farbtastic: Altered Library', 'Registered libraries were altered.');

  // common_test_library_alter() also added a dependency on jQuery Form.
  drupal_add_library('system', 'farbtastic');
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, 'misc/jquery.form.js'), 'Altered library dependencies are added to the page.');

  //
  // Tests non-existing libraries.
  advagg_test_reset_statics();
  $result = drupal_get_library('unknown', 'unknown');
  $this
    ->assertFalse($result, 'Unknown library returned FALSE.');
  advagg_test_reset_statics();
  $result = drupal_add_library('unknown', 'unknown');
  $this
    ->assertFalse($result, 'Unknown library returned FALSE.');
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, 'unknown') === FALSE, 'Unknown library was not added to the page.');

  //
  // Tests the addition of libraries through the #attached['library']
  // property.
  advagg_test_reset_statics();
  $element['#attached']['library'][] = array(
    'system',
    'farbtastic',
  );
  drupal_render($element);
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), 'The attached_library property adds the additional libraries.');

  //
  // Test #attached functionality in children elements.
  advagg_test_reset_statics();

  // The cache system is turned off for POST requests.
  $request_method = $_SERVER['REQUEST_METHOD'];
  $_SERVER['REQUEST_METHOD'] = 'GET';

  // Create an element with a child and subchild.  Each element loads a
  // different JavaScript file using #attached.
  $parent_js = drupal_get_path('module', 'user') . '/user.js';
  $child_js = drupal_get_path('module', 'color') . '/color.js';
  $subchild_js = drupal_get_path('module', 'book') . '/book.js';
  $element = array(
    '#type' => 'fieldset',
    '#cache' => array(
      'keys' => array(
        'simpletest',
        'drupal_render',
        'children_attached',
      ),
    ),
    '#attached' => array(
      'js' => array(
        $parent_js,
      ),
    ),
    '#title' => 'Parent',
  );
  $element['child'] = array(
    '#type' => 'fieldset',
    '#attached' => array(
      'js' => array(
        $child_js,
      ),
    ),
    '#title' => 'Child',
  );
  $element['child']['subchild'] = array(
    '#attached' => array(
      'js' => array(
        $subchild_js,
      ),
    ),
    '#markup' => 'Subchild',
  );

  // Render the element and verify the presence of #attached JavaScript.
  drupal_render($element);
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, $parent_js), 'The element #attached JavaScript was included.');
  $this
    ->assertTrue(strpos($scripts, $child_js), 'The child #attached JavaScript was included.');
  $this
    ->assertTrue(strpos($scripts, $subchild_js), 'The subchild #attached JavaScript was included.');

  // Load the element from cache and verify the presence of the #attached
  // JavaScript.
  advagg_test_reset_statics();
  $this
    ->assertTrue(drupal_render_cache_get($element), 'The element was retrieved from cache.');
  $render_array = advagg_get_js();
  $scripts = drupal_render($render_array);
  $this
    ->assertTrue(strpos($scripts, $parent_js), 'The element #attached JavaScript was included when loading from cache.');
  $this
    ->assertTrue(strpos($scripts, $child_js), 'The child #attached JavaScript was included when loading from cache.');
  $this
    ->assertTrue(strpos($scripts, $subchild_js), 'The subchild #attached JavaScript was included when loading from cache.');
  $_SERVER['REQUEST_METHOD'] = $request_method;

  //
  // Tests the localisation of JavaScript libraries. Verifies that the
  // datepicker can be localized.
  advagg_test_reset_statics();
  drupal_add_library('system', 'ui.datepicker');
  $GLOBALS['conf']['advagg_mod_js_footer'] = 0;
  $render_array = advagg_get_js();
  $javascript = drupal_render($render_array);
  $this
    ->assertTrue(strpos($javascript, 'locale.datepicker.js'), 'locale.datepicker.js added to scripts.');

  //
  // Functional tests for JavaScript parsing for translatable strings.
  // Tests parsing js files for translatable strings.
  advagg_test_reset_statics();
  $filename = drupal_get_path('module', 'locale_test') . '/locale_test.js';

  // Parse the file to look for source strings.
  _locale_parse_js_file($filename);

  // Get all of the source strings that were found.
  $source_strings = db_select('locales_source', 's')
    ->fields('s', array(
    'source',
    'context',
  ))
    ->condition('s.location', $filename)
    ->execute()
    ->fetchAllKeyed();

  // List of all strings that should be in the file.
  $test_strings = array(
    "Standard Call t" => '',
    "Whitespace Call t" => '',
    "Single Quote t" => '',
    "Single Quote \\'Escaped\\' t" => '',
    "Single Quote Concat strings t" => '',
    "Double Quote t" => '',
    "Double Quote \\\"Escaped\\\" t" => '',
    "Double Quote Concat strings t" => '',
    "Context !key Args t" => "Context string",
    "Context Unquoted t" => "Context string unquoted",
    "Context Single Quoted t" => "Context string single quoted",
    "Context Double Quoted t" => "Context string double quoted",
    "Standard Call plural" => '',
    "Standard Call @count plural" => '',
    "Whitespace Call plural" => '',
    "Whitespace Call @count plural" => '',
    "Single Quote plural" => '',
    "Single Quote @count plural" => '',
    "Single Quote \\'Escaped\\' plural" => '',
    "Single Quote \\'Escaped\\' @count plural" => '',
    "Double Quote plural" => '',
    "Double Quote @count plural" => '',
    "Double Quote \\\"Escaped\\\" plural" => '',
    "Double Quote \\\"Escaped\\\" @count plural" => '',
    "Context !key Args plural" => "Context string",
    "Context !key Args @count plural" => "Context string",
    "Context Unquoted plural" => "Context string unquoted",
    "Context Unquoted @count plural" => "Context string unquoted",
    "Context Single Quoted plural" => "Context string single quoted",
    "Context Single Quoted @count plural" => "Context string single quoted",
    "Context Double Quoted plural" => "Context string double quoted",
    "Context Double Quoted @count plural" => "Context string double quoted",
  );

  // Assert that all strings were found properly.
  foreach ($test_strings as $str => $context) {
    $args = array(
      '%source' => $str,
      '%context' => $context,
    );

    // Make sure that the string was found in the file.
    $this
      ->assertTrue(isset($source_strings[$str]), format_string('Found source string: %source', $args));

    // Make sure that the proper context was matched.
    $this
      ->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, strlen($context) > 0 ? format_string('Context for %source is %context', $args) : format_string('Context for %source is blank', $args));
  }
  $this
    ->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');

  //
  // Adds a language and checks that the JavaScript translation files are
  // properly created and rebuilt on deletion.
  $user = $this
    ->drupalCreateUser(array(
    'translate interface',
    'administer languages',
    'access administration pages',
  ));
  $this
    ->drupalLogin($user);
  $langcode = 'xx';

  // The English name for the language. This will be translated.
  $name = $this
    ->randomName(16);

  // The native name for the language.
  $native = $this
    ->randomName(16);

  // The domain prefix.
  $prefix = $langcode;

  // Add custom language.
  $edit = array(
    'langcode' => $langcode,
    'name' => $name,
    'native' => $native,
    'prefix' => $prefix,
    'direction' => '0',
  );
  $this
    ->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
  drupal_static_reset('language_list');

  // Build the JavaScript translation file.
  $this
    ->drupalGet('admin/config/regional/translate/translate');

  // Retrieve the id of the first string available in the {locales_source}
  // table and translate it.
  $query = db_select('locales_source', 'l');
  $query
    ->addExpression('min(l.lid)', 'lid');
  $result = $query
    ->condition('l.location', '%.js%', 'LIKE')
    ->condition('l.textgroup', 'default')
    ->execute();
  $url = 'admin/config/regional/translate/edit/' . $result
    ->fetchObject()->lid;
  $edit = array(
    'translations[' . $langcode . ']' => $this
      ->randomName(),
  );
  $this
    ->drupalPost($url, $edit, t('Save translations'));

  // Trigger JavaScript translation parsing and building.
  require_once DRUPAL_ROOT . '/includes/locale.inc';
  _locale_rebuild_js($langcode);

  // Retrieve the JavaScript translation hash code for the custom language to
  // check that the translation file has been properly built.
  $file = db_select('languages', 'l')
    ->fields('l', array(
    'javascript',
  ))
    ->condition('language', $langcode)
    ->execute()
    ->fetchObject();
  $js_file = 'public://' . variable_get('locale_js_directory', 'languages') . '/' . $langcode . '_' . $file->javascript . '.js';
  $this
    ->assertTrue($result = file_exists($js_file), format_string('JavaScript file created: %file', array(
    '%file' => $result ? $js_file : 'not found',
  )));

  // Test JavaScript translation rebuilding.
  file_unmanaged_delete($js_file);
  $this
    ->assertTrue($result = !file_exists($js_file), format_string('JavaScript file deleted: %file', array(
    '%file' => $result ? $js_file : 'found',
  )));
  cache_clear_all();
  _locale_rebuild_js($langcode);
  $this
    ->assertTrue($result = file_exists($js_file), format_string('JavaScript file rebuilt: %file', array(
    '%file' => $result ? $js_file : 'not found',
  )));
}