<commit_before>package xtraitj.tests

import com.google.inject.Inject
import org.apache.log4j.ConsoleAppender
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.log4j.spi.LoggingEvent
import org.eclipse.xtext.junit4.InjectWith
import org.eclipse.xtext.junit4.XtextRunner
import org.eclipse.xtext.junit4.util.ParseHelper
import org.eclipse.xtext.junit4.validation.ValidationTestHelper
import org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import xtraitj.XtraitjInjectorProvider
import xtraitj.xtraitj.TJProgram

import static org.junit.Assert.*

@RunWith(typeof(XtextRunner))
@InjectWith(typeof(XtraitjInjectorProvider))
class XtraitjSmokeTest {
	@Inject extension ParseHelper<TJProgram>
	@Inject extension ValidationTestHelper
	
	private final static Logger LOG = Logger.getLogger(JvmModelAssociator);

	/**
	 * JvmModelAssociator does not throw exceptions but logs possible
	 * errors; we use this class to record possible error events
	 */
	static class LogListener extends ConsoleAppender {
		
		val public events = newArrayList()
		
		override doAppend(LoggingEvent event) {
			if (event.getLevel == Level.ERROR) {
				events += event
			}
		}
		
	}
	
	var LogListener logListener

	@Before
	def void createAppender() {
		logListener = new LogListener => [
			LOG.addAppender(it)
		]
	}

	@After
	def void removeAppender() {
		LOG.removeAppender(logListener)
	}
	
	@Test def void testEmptyOperations() {
		'''
		trait T {
			
		}
		
		class C uses T[] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testNoMemberInRenameYet() {
		'''
		trait T {
			
		}
		
		class C uses T[rename ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testNoMemberInRenameFieldYet() {
		'''
		trait T {
			
		}
		
		class C uses T[rename field ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testRenameIncompleteMethod() {
		'''
		trait T {
			String m
		}
		
		class C uses T[rename m ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testReferenceToNonExistentTrait() {
		'''
		trait T {
			String m
		}
		
		trait T2 uses T1 {
			
		}
		'''.parseAndValidate
	}

	@Test def void testReferenceToNonExistentTraitWithOperations() {
		'''
		trait T {
			String m
		}
		
		trait T2 uses T1[rename m ] {
			
		}
		'''.parseAndValidate<commit_msg>other smoke tests for alteration operations <commit_after>package xtraitj.tests

import com.google.inject.Inject
import org.apache.log4j.ConsoleAppender
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.log4j.spi.LoggingEvent
import org.eclipse.xtext.junit4.InjectWith
import org.eclipse.xtext.junit4.XtextRunner
import org.eclipse.xtext.junit4.util.ParseHelper
import org.eclipse.xtext.junit4.validation.ValidationTestHelper
import org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import xtraitj.XtraitjInjectorProvider
import xtraitj.xtraitj.TJProgram

import static org.junit.Assert.*

@RunWith(typeof(XtextRunner))
@InjectWith(typeof(XtraitjInjectorProvider))
class XtraitjSmokeTest {
	@Inject extension ParseHelper<TJProgram>
	@Inject extension ValidationTestHelper
	
	private final static Logger LOG = Logger.getLogger(JvmModelAssociator);

	/**
	 * JvmModelAssociator does not throw exceptions but logs possible
	 * errors; we use this class to record possible error events
	 */
	static class LogListener extends ConsoleAppender {
		
		val public events = newArrayList()
		
		override doAppend(LoggingEvent event) {
			if (event.getLevel == Level.ERROR) {
				events += event
			}
		}
		
	}
	
	var LogListener logListener

	@Before
	def void createAppender() {
		logListener = new LogListener => [
			LOG.addAppender(it)
		]
	}

	@After
	def void removeAppender() {
		LOG.removeAppender(logListener)
	}
	
	@Test def void testEmptyOperations() {
		'''
		trait T {
			
		}
		
		class C uses T[] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testNoMemberInRenameYet() {
		'''
		trait T {
			
		}
		
		class C uses T[rename ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testNoMemberInRenameFieldYet() {
		'''
		trait T {
			
		}
		
		class C uses T[rename field ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testRenameIncompleteMethod() {
		'''
		trait T {
			String m
		}
		
		class C uses T[rename m ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testRenameNonExistantMethod() {
		'''
		trait T {
			void m() {}
		}
		
		class C uses T[rename foo to bar] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testNoMemberInHideYet() {
		'''
		trait T {
			
		}
		
		class C uses T[hide ] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testHideNonExistantMethod() {
		'''
		trait T {
			void m() {}
		}
		
		class C uses T[hide foo] {
			
		}
		'''.parseAndValidate
	}

	@Test def void testReferenceToNonExistentTrait() {
		'''
		trait T {
			String m
		}
		
		trait T2 uses T1 {
			
		}
		'''.parseAndValidate
	}

	@Test def void testReferenceToNonExistentTraitWithOperations() {
		'''
		trait T {
			String m
		}
		
		trait T2 uses T1[rename m ] {
			
		}
		'''.parseAndValidate
{'fraction_non_alphanumeric': 0.10045836516424751, 'fraction_numerical': 0.004583651642475172, 'mean_word_length': 3.3245251857968623, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7585872', 'n_tokens_mistral': 2033, 'n_tokens_neox': 1799, 'n_words': 404}