package org.eclipse.e4.languages.javascript.test;

import org.eclipse.e4.internal.languages.javascript.JSRequireBundle;
import org.eclipse.e4.internal.languages.javascript.JSVersionRange;

import junit.framework.TestCase;

public class JSRequireTest extends TestCase {

	public JSRequireTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		//
	}

	protected void tearDown() throws Exception {
		//
	}

	public void testNullHeader() {

		try {
			new JSRequireBundle(null);
		} catch (IllegalArgumentException e) {
			return;
		}
		fail();
	}

	public void testNameAndEmptyVersionRange() {
		JSRequireBundle jsRequire = new JSRequireBundle("a.a");
		assertEquals("a.a", jsRequire.getName());
		assertEquals(JSVersionRange.emptyRange, jsRequire.getBundleVersionRange());
		assertEquals(0, jsRequire.getAttributes().size());
		assertEquals(0, jsRequire.getDirectives().size());
		assertEquals(false, jsRequire.isOptional());
	}

	public void testNameAndVersion() {
		JSRequireBundle jsRequire = new JSRequireBundle("a.a;bundle-version=1.2.1");
		assertEquals("a.a", jsRequire.getName());
		assertEquals(new JSVersionRange("1.2.1"), jsRequire.getBundleVersionRange());
		assertEquals(1, jsRequire.getAttributes().size());
		assertEquals(0, jsRequire.getDirectives().size());
		assertEquals(false, jsRequire.isOptional());
	}

	public void testIsOptional() {
		JSRequireBundle jsRequire = new JSRequireBundle("a.a;bundle-version=1.2.1;resolution:=optional");
		assertEquals("a.a", jsRequire.getName());
		assertEquals(new JSVersionRange("1.2.1"), jsRequire.getBundleVersionRange());
		assertEquals(1, jsRequire.getAttributes().size());
		assertEquals(1, jsRequire.getDirectives().size());
		assertEquals(true, jsRequire.isOptional());
	}
}
